master
Miloslav Ciz 6 months ago
parent 664cca6747
commit 3ca4661a3d

@ -4,7 +4,7 @@ Abstraction is an important concept in [programming](programming.md), [mathemati
In mainstream [programming](programming.md) education it is generally taught to "abstract as much as possible" because that's aligned with the [capitalist](capitalism.md) way of technology -- high abstraction is easy to handle for incompetent programming monkeys, it helps preventing them from making damage by employing billions of safety mechanisms, it also perpetuates the cult of never stopping layering of the abstraction sandwich, creating [bloat](bloat.md), [hype](hype.md), bullshit jobs, it makes computers slower, constantly outdated and so drives software [consumerism](consumerism.md). As with everything in capitalism, new abstractions are products hyped on grounds of immediate benefit: creating more comfort, being something new and "[modern](modern.md)", increasing "[productivity](productivity_cult.md)", lowering "barriers of entry" so that ANYONE CAN NOW BE A PROGRAMMER without even knowing anything about computers (try to imagine this e.g. in the field of medicine) etc. -- of course, long term negative effects are completely ignored. **This is extremely wrong.** It is basically why technology has been on such a huge downfall in the latest decades. Opposing this, [LRS](lrs.md) advocates to employ only as little abstraction as needed, so as to support [minimalism](minimalism.md). **Too much abstraction is bad.** For example a widely used general purpose programming language should basically only have as much abstraction as to allow [portability](portability.md), it should definitely NOT succumb high abstraction such as [object obsessed programming](oop.md).
In a more detailed view abstraction is not one-dimensional, we may abstract in different directions ("look at the issue from different angles"); for example [functional](functional.md), [logic](logic_paradigm.md) and [object](object.md) paradigms are different ways of abstracting from the low level, each one in different way. So the matter of abstracting is further complicated by trying to **choose the right abstraction** -- one kind of abstraction may work well for certain kinds of problems (i.e. solving these problems will become simple when applying this abstraction) but badly for other kinds of problems.
In a more detailed view abstraction is not one-dimensional, we may abstract in different directions ("look at the issue from different angles"); for example [functional](functional.md), [logic](logic_paradigm.md) and [object](object.md) paradigms are different ways of programming languages abstracting from the low level, each one in different way. So the matter of abstracting is further complicated by trying to **choose the right abstraction** -- one kind of abstraction may work well for certain kinds of problems (i.e. solving these problems will become simple when applying this abstraction) but badly for other kinds of problems. The art of choosing right abstraction ([model](model.md)) is important e.g. in designing computer [simulations](simulation.md) -- if we want so simulate e.g. human society, do we simulate individual people in it or just societies as whole entities? Do we simulate wars as a simple dice roll or do we let individual soldiers fight their own battles? Do we represent roads as actual surfaces on top of which cars move according to laws of physics, or do we simplify to something like mathematical graph connecting cities with mere abstract lines, or something in between like a cellular automaton maybe? Do we consider beings living on a round planet, with possibilities like meteor impacts and space flights, or do we simply consider people living on a flat 2D sheet of paper? Similar though has come to designing [games](game.md) (another kind of simulation).
Let's take a look at a possible division of a [computer](computer.md) to different levels of abstraction, from lowest to highest (keep in mind it's also possible to define the individual levels differently):

@ -1,16 +1,25 @@
# Fourier Transform
Fourier Transform (FT) is one of the most important [algorithms](algorithm.md) in [signal](signal.md) processing (and really in [computer science](compsci.md) and [mathematics](math.md) in general), which enables us to express and manipulate any signal (such as a sound or picture) in terms of [frequencies](frequency.md) it is composed of (rather than in terms of individual [samples](samples.md)). It is so important because frequencies (basically [sine](sine.md) waves) are actually THE important thing in signals, they allow us to detect things (voices, visual objects, chemical elements, ...), [compress](compression.md) signals, modify them in useful ways (e.g. filter out [noise](noise.md) of specific frequency band, enhance specific frequency bands, ...). There also exists an [optimized](optimization.md) version of FT called **Fast Fourier Transform** ([FFT](fft.md)) which does the same but much faster. For newcomers FT is typically not easy to understand, it takes time to wrap one's head around it, so don't worry if you feel dumb reading this.
Fourier Transform (FT) is one of the most important transformations/[algorithms](algorithm.md) in [signal](signal.md) processing (and really in [computer science](compsci.md) and [mathematics](math.md) in general), which enables us to express and manipulate a signal (such as a sound or picture) in terms of [frequencies](frequency.md) it is composed of (rather than in terms of individual [samples](samples.md)). It is so important because frequencies (basically [sine](sine.md) waves) are actually THE important thing in signals, they allow us to detect things (voices, visual objects, chemical elements, ...), [compress](compression.md) signals, modify them in useful ways (e.g. filter out [noise](noise.md) of specific frequency band, enhance specific frequency bands, ...). There also exists a related algorithms called **[Fast Fourier Transform](fft.md)** (FFT) which is able to compute one specific version of FT very quickly and so is often used in practice.
For newcomers FT is typically not easy to understand, it takes time to wrap one's head around it. There is also a very confusing terminology; there exist slightly different kinds of the Fourier Transform that are called by similar names, or sometimes all simply just "Fourier Transform" -- what programmers usually mean by FT is DFT or FFT. There also exist Fourier Transforms in higher dimensions (2D, 3D, ...) -- the base case is called one dimensional (because our input signal has one coordinate). All this will be explained below.
**What FT does in essence**: it transforms an input signal (which can also be seen as a [function](function.md)) from **time (also space) domain**, i.e. the usual representation that for each *x* says the sample value *f(x)*, to **frequency domain**, another function that for each frequency *f* says "how much of the frequency is present" (amplitude and phase). For example an FT of a simple sine wave will be a function with a single spike at the frequency of the sine wave. There is also an **inverse Fourier Transform** that does the opposite (transforms the signal from frequencies back to time samples). The time and frequency representations are EQUIVALENT in that either one can be used to represent the signal -- it turns out that even "weird" looking functions can be decomposed into just sums of many differently shifted and scaled sine waves. In the frequency domain we can usually do two important things we cannot do in time domain: firstly analyze what frequencies are present (which can help e.g. in [voice recognition](voice_recognition.md), [spectral analysis](spectral_analysis.md), earthquake detection, [music](music.md) etc.) and also MODIFY them (typicaly example is e.g. music [equalizer](equalizer.md) or [compression](compression.md) that removes or quantizes some frequencies); if we modify the frequencies, we may use the inverse FT to get back the "normal" (time representation) signal back. Some things are also easier to do in the frequency domain, for example [convolution](convolution.md) becomes mere multiplication.
FT is actually just one of many so called **[integral transforms](integral_transform.md)** that are all quite similar -- they always transform the signal to some other domain and back, they use similar equation but usually use a different kind of [function](function.md). Other integral transforms are for example **[discrete cosine transformation](dct.md)** (DCT) or **[wavelet transform](wavelet_transform.md)**. DCT is actually a bit simpler than FT, so if you are having hard time with FT, go check out DCT.
**What does FT do?** It transforms the input signal from **time (also space) domain** -- the usual representation as "array of samples capture in time" -- to **frequency domain** -- an "array of frequency amounts". There is also an **inverse Fourier Transform** that does the opposite (transforms the signal from frequencies back to time samples). The time and frequency representations are EQUIVALENT in that either one can be used to represent any signal, none is somehow more superior than the other -- it turns out that **any signal can be expressed as a sum of [sine](sine.md) waves of different frequencies** and so any signal can also be decomposed to them. In the frequency domain we can however usually do two important things we cannot do in time domain: analyze what frequencies are present (which can help e.g. in [voice recognition](voice_recognition.md), [spectral analysis](spectral_analysis.md), earthquake detection, [music](music.md) etc.) and also MODIFY them (typicaly example is e.g. music [equalizer](equalizer.md) or [compression](compression.md) that removes or quantizes some frequencies); if we modify the frequencies, we may use the inverse FT to get a "normal" (time representation) signal back. Some things are also easier to do in the frequency domain, for example [convolution](convolution.md) becomes mere multiplication.
**If you know [linear algebra](linear_algebra.md), this may help you understand what (D)FT really does:** Imagine the signal we work with is a POINT (we can also say a [vector](vector.md)) in many [dimensional](dimension.md) space; if for example we have a recorded sound that has 1000 samples, it is really a 1000 dimensional vector, a point in 1000 dimensional space, expressed as an "array" of 1000 numbers (vector components). A short note: since we consider a finite number of discrete samples here, we are actually dealing with what's called DISCRETE FT here, not the "vanilla" FT, but for now let's not diverge. (D)FT does nothing more than transforming from one vector [basis](basis.md) ("system of coordinates", "frame of reference") to another basis; i.e. by default the signal is expressed in time domain (our usual vector basis), the numbers in the sound "array" are such because we are viewing them from the time "frame of reference" -- (D)FT will NOT do anything with to the signal itself (it is a vector/point in space, which will stay where it is, the recorded sound itself will not change), it will merely express this same point/vector from a different "point of view"/"frame of reference" (set of basis vectors) -- that of frequencies. That's basically how all the integral transforms work, they just have to ensure the basis they are transforming to is orthogonal (i.e. kind of legit, "usable") of course.
FT is actually just one of many so called **[integral transforms](integral_transform.md)** that are all quite similar -- they always transform the signal to some other domain and back, they use similar equation but usually use a different [function](function.md). Other integral transforms are for example **[discrete cosine transformation](dct.md)** (DCT) or **[wavelet transform](wavelet_transform.md)**. DCT is actually a bit simpler than FT, so if you are having hard time with FT, go check out DCT.
## Details
**If you know [linear algebra](linear_algebra.md), this may help you understand what FT really does:** Imagine the signal we work with is a POINT (we can also say a [vector](vector.md)) in many [dimensional](dimension.md) space; if for example we have a recorded sound that has 1000 samples, it is really a 1000 dimensional vector, a point in 1000 dimensional space, expressed as an "array" of 1000 numbers (vector components). FT does nothing more than transforming from one vector [basis](basis.md) ("system of coordinates", "frame of reference") to another basis; i.e. by default the signal is expressed in time domain (out usual vector basis), the numbers in the sound "array" are such because we are viewing them from the time "frame of reference" -- FT will NOT do anything with to the signal itself (it is a vector/point in space, which will stay where it is, the recorded sound itself will not change), it will merely express this same point/vector from a different "point of view"/"frame of reference" (set of basis vectors) -- that of frequencies. That's basically how all the integral transforms work, they just have to ensure the basis they are transforming to is orthogonal (i.e. kind of legit, "usable") of course.
First let's make clearer the whole terminology around FT:
As if it wasn't hard enough, there are kind of many different types of FT. For starters FT can be done in any number of dimensions, 1D FT (e.g. for sounds) is of course the simplest, but there also exists 2D FT (used e.g. for pictures), 3D FT etc.
- **Fourier Series (FS)**: Transforms a PERIODIC (repeating) signal into a DISCRETE (non-continuous) spectrum. We can see this spectrum also as an infinite SERIES of coefficients *c0*, *c1*, *c2*, etc. The input signal can generally be [complex](complex_number.md), in which case the output spectrum also has negative part (*c-1*, *c-2*, *c-3* etc.) and shows us COMPLEX EXPONENTIALS (i.e. not mere sine waves) of the input signal; however if the input signal is [real](real_number.md) (probably most signals we practically deal with), the spectrum's negative part is symmetric to the positive part and the corresponding positive and negative complex exponentials always together give a sine wave, so for "normal" signals we can see the spectrum only being in the non-negative part and showing us the sine waves of the signal.
- **Fourier Transform (FT)**: Generalization of FS to work on any signal, not just periodic ones, i.e. FT takes a NON-PERIODIC signal and transforms it into a CONTINUOUS spectrum. This is achieved simply by considering the period of the signal to be infinite -- the spectrum now becomes continuous exactly because the input is non-periodic (this is a relationship that generally holds); since the output is continuous, we now rather see it as a function rather than a series. Same as with FS the input can be [complex](complex_number.md) (in which case the same implications apply), but we usually work with [real](real.md) signals.
- **Inverse Fourier Transform (IFT)**: Does the opposite of FT, i.e. transforms the signal back from frequency domain to time domain.
- **Discrete Time Fourier Transform (DTFT)** (not to be confused with DFT!): Fourier Transform for DISCRETE (non-continuous) input signals (e.g. sound pressure captured only at specific points in time) -- since the input is discrete, the spectrum will be PERIODIC (this is another relationship that generally holds).
- **Discrete Fourier Series (DFS)**: Version of FS for discrete (non-continuous) signals, transforms the input DISCRETE and PERIODIC signal to a spectrum (series of coefficients) of which there are infinitely many and are also PERIODIC (with the same period as the input signal).
- **Discrete Fourier Transform (DFT)** (not to be confused with DTFT!): Uses DFS to transform a FINITE DISCRETE signal to a FINITE DISCRETE spectrum (with the same period as the input) by simply "pretending" the finite input signal is actually repeating over and over and then, after the transform, only leaving in the first period of the result (since the rest is just repeating). **This is actually what programmers usually mean by Fourier Transform** because in computers we practically always only deal with finite discrete signals (i.e. [arrays](array.md) of data).
- **Fast Fourier Transform (FFT)**: Computes DFT (NOT FT!) that's faster than the [naive](naive.md) implementation, i.e. computing the equation that defines DFT as it's written has time complexity O(n^2) while FFT improves this to O(n * log(n)).
TODO: more, code, picture etc.
TODO: equations, more, code, pictures etc.
Loading…
Cancel
Save