# Noise

Noise in general is an undesirable [signal](signal.md) that's mixed in with useful signal and which we usually try to filter out, even though it can also be useful, especially e.g. in [procedural generation](procgen.md). Typical example of noise is flickering or static in video and audio signals, but it can also take a form of e.g. random errors in transferred texts, irrelevant links in web search results or imperfections in measuring of economic data. In measurements we often talk about [signal to noise ratio](snr.md) (SNR) -- the ratio that tells us how much noise there is in our data. While in engineering and scientific measurements noise is almost always something that's burdening us (e.g. [cosmic microwave background](cmb.md), the noise left over from the [Big Bang](big_bang.md), may interfere with our radio communication), in some fields such as [computer graphics](graphics.md) (and other computer [art](art.md)) or [cryptography](cryptography.md) we sometimes try to purposefully generate artificial noise -- e.g. in [procedural generation](procgen.md) noise is used to generate naturally looking terrain, clouds, textures etc.

```
 xxxx x    x  x    x  xx x xxx   x x x
 x        xxx  x x  x   xxxxxx     x
x xxxx x xxxx x  xxx  xx xxx xx    xxx
 xxx   xxx            xx  x xxx  x
x  x x  xxx x xxx  x x x xxx     x
  x xxx xx xxxxxx  xxx x xx x xx x
xxxxx x x x x x     x  xxxx xxx   x  x
xxxx    x  x  x xx  xx   xx  x    xx
      x  xxx  xxx x x   x xx  xx xxx
     xx xx  xxx x x xxx xxxxx  xxx x x
x  x xx x xxxx x xx xxx  x  x x  xx xx
 xx  xx    xxx x x xx  x    xx xx xx
   xx xx    x x x x xxx    xx   x xx x
xxx xx     xxxx x xx xx xxx x  x  x xx
xx x   xxx  x  xxx    xx x  x x     x
x x  xx x    x xxxxxx   x x  xxx
x      xxx     x x x x x x xx xxxxxxxx
x  xx x x xx x  xxxxxxxxx xxx  xxx  xx
x  xxxx xxx   x       x  x   xxx xxxxx
    xx   x  x x xxxxxx   x  xxx xxx
```

*2D binary white noise*

## Artificial Noise

In [computer science](compsci.md), especially e.g. in [computer graphics](graphics.md) or audio generation, we often want to generate artificial noise that looks like real noise, in order to be able to generate data that look like real world data. Noise may serve as a basis (first step, random initial state) for generating something or it may be used to distort or modulate other data, for example when drawing geometrical shapes we may want them to look as if written by hand in which case we want to make them imperfect, add a bit of noise to an otherwise perfect shape a computer would create. Adding noise can help make rendered pictures look more natural, it can help us model human speech that arises from noise created by our vocal cords, it can help AI train itself to filter out real life noise etc.

Normally we don't want our noise to be completely [random](randomness.md) but rather **[pseudorandom](pseudorandomness.md)** so that our programs stay [deterministic](determinism.md). Imagine for example we are generating terrain [heightmap](heightmap.md) based on a 2D noise -- if such function was truly random, the terrain in a certain place would be different every time we returned to that place again, but if the noise is pseudorandom ([seeded](seed.md) by the position coordinates), the terrain generated at any given coordinate will be always the same.

There are different types of noise characterized by their properties such as number of dimensions, [frequencies](frequency.md) they contain, [probability distribution](probability.md) of the values they contain etc. Basic division of noises may be this:

- by type/[algorithm](algorithm.md):
  - **value noises**: The simplest type of noise, it arises by generating a (pseudo)random value at each node of the spatial grid. Values in between grid nodes are obtained by [interpolation](interpolation.md).
  - **gradient noises**: More sophisticated than value noise, rather than a simple value it generates a [gradient](gradient.md) at each grid point. Specific algorithms/types of gradient noise are:
    - **[Perlin noise](perlin_noise.md)**: One of the most common and basic gradient noises, which however suffers from some [artifacts](artifact.md).
    - **[simplex noise](simplex_noise.md)**: A more sophisticated noise than Perlin noise, improves some of its properties, works with a [simplex](simplex.md) lattice of points rather than orthogonal grid.
    - ...
  - **spectral noises**: Noises that are generated in the [spectral domain](spectrum.md) (see [Fourier transform](fourier_transform.md)):
    - **[anisotropic noise](anisotropic_noise.md)**: Noise that has a specific orientation, can be used e.g. for water waves that go in one direction.
    - ...
  - **[convolution](convolution.md) noises**: Noises that use [convolution](convolution.md) of given kernel with some simpler noise to create a larger texture.
    - **[Gabor noise](gabor_noise.md)**
    - ...
  - other:
    - **[Voronoi](voronoi.md) noise**: Noise that looks like a "honeycomb" or structures created by living cells, it is created by generating random point coordinates and then assigning each space point (e.g. each pixel) a [distance](distance.md) to its closest point. Different random [point sampling](point_sampling.md) methods or distance functions can help change the look of the noise. Worley Noise is one type of Voronoi noise.
    - Combinations and modifications of standard noises: we may e.g. blend or [modulate](modulation.md) two noise functions to create a new complex type of noise.
    - **[midpoint displacement](midpoint_displacement.md)/[diamond square](diamond_square.md)**: Relatively simple [algorithms](algorithm.md) for generating [fractal](fractal.md) heightmaps, working on the principle of repeatedly subdividing a line (or in higher dimensions a square, cube etc.) and (pseudo)randomly displacing the generated point.
    - **[wavelet noise](wavelet_noise.md)**: Noise further improving some characteristics of Perlin noise.
    - unorthodox noises created e.g. by [cellular automata](cellular_automaton.md), AI etc.
    - ...
- by frequencies:
  - **[fractal noise](fractal_noise.md)**: Very important type of noise that similarly to [fractals](fractal.md) is composed of differently scaled versions of itself -- this noise looks like (and can be used to simulate) clouds, mountains and other structures found in nature. It is created by taking some basic noise function (e.g. Perlin noise or simplex noise) and overlaying (adding) multiple versions of it that differ by frequency and amplitude (just as e.g. mountains are composed of big and tall hills that have on them progressively smaller and less tall hills up to the microscopic level). These different individual layers are called octaves: *i*th octave has the amplitude *p^i* (where *p* is a constant from 0 to 1 called a persistence) and frequency of *2^i*.
   - **[white noise](white_noise)**: Noise containing "same amount of all frequencies" -- this is basically the simplest kind of noise we get when we generate a sequence of independent ([uncorrelated](correlation.md)) (pseudo)random numbers with uniform probability distribution.
   - **[pink noise](pink_noise.md)**: Energy density of frequencies decreases proportionally with 1/frequency, i.e. it basically has strong high frequencies and weak low frequencies.
   - **[blue noise](blue_noise.md)**
   - ...
- by other properties:
  - **symmetry/invariance** and other function properties: A noise may or may not be invariant against various operations such as shifting, rotation or scaling, i.e. when we apply this operation it will look basically the same. For example Perlin noise outputs value 0 at each grid point and is non-zero only between the grid point, so it is NOT invariant towards shifting. Noise functions are just mathematical [functions](function.md), so we may examine noises just as we examine functions (they may be continuous, bounded etc.).
  - **explicit vs implicit**: Values of an implicit noise can relatively simply and quickly be computed at any given point in space whereas explicit noises require processing as a whole and therefore storage of the whole generated noise in memory.
  - **tiling**: Similarly to [procedural](procgen.md) [textures](texture.md), a noise generated by an algorithm may be tiling, i.e. not having visible seams when repeated in certain dimensions. 
  - ...
  
```
           ..----..  
        .''        ''.  
    ..''              '.                      ..... 
''''                    '                 ..''     '''--..    
                         '.            .''                ''..    
                           '.       ..'                       '''     
                             ''...''                           

                             octave1
                                +
       ....                                    ...
..--'''    ''.        ..'''...              .''   ''-..    ..--''
              ''---'''        '''''---...-''           ''''

                             octave2
                                +

''-....----'''-...-'''-...-'''''''-----...-'''--..-'''-....---'''

                             octave3
                                =
           ..
        .''  '.       
      -'       ''.-'-.  
... ..                '                      -'''--...
   '                   ''                   '         .       
                         '-.              -'           -.. ..  .'   
                            -.          -'                '  ''      
                              '...-.--''                        
                                  
                           fractal noise


```

*1D fractal noise composed of 3 octaves*

## Code

A super simple "poor man's noise" that can be of use sometimes is **coin flip noise** which works simply like this: start with value 0, in each step output current value and randomly change it by +1 or -1. It's basically a [random walk](random_walk.md), a next best thing to the simplest [white noise](white_noise.md), so watch out, it will only work for most basic things, generalizing to a 2D noise will be awkward, you won't know how high or low the values will actually go, also the frequency properties probably won't be ideal. { Not sure actually what spectrum to expect, have to check that out, TODO. ~drummyfish } You may at least try to play around with changing the value even by more than one using e.g. [normal probability distribution](normal_distribution.md).

TODO: code for the above, maybe even a one liner for white noise

TODO: actual Perlin noise etc., also some nice noise that's just adding some random sine waves in a fractal fashion, like a one line formula