Converting fft to ifft in C# - c#

I have a working FFT, but my question is how do I convert it into an IFFT?
I was told that an IFFT should be just like the FFT that you are using.
so how do I make an ifft from a fft i c#?
I was told there should only be a few changes made to get the ifft.
I tried to do it myself, but I am not getting the same values back that I put in...
so I made an array of values and put it in to the fft and then the ifft and I can not getting the same values I put in...
so I do not think I changed it the right way.
this is the FFT I have:
public Complex[] FFT(Complex[] x )
{
int N2 = x.Length;
Complex[] X = new Complex[N2];
if (N2 == 1)
{
return x;
}
Complex[] odd = new Complex[N2 / 2];
Complex[] even = new Complex[N2 / 2];
Complex[] Y_Odd = new Complex[N2 / 2];
Complex[] Y_Even = new Complex[N2 / 2];
for (int t = 0; t < N2 / 2; t++)
{
even[t] = x[t * 2];
odd[t] = x[(t * 2) + 1];
}
Y_Even = FFT(even);
Y_Odd = FFT(odd);
Complex temp4;
for (int k = 0; k < (N2 / 2); k++)
{
temp4 = Complex1(k, N2);
X[k] = Y_Even[k] + (Y_Odd[k] * temp4);
X[k + (N2 / 2)] = Y_Even[k] - (Y_Odd[k] * temp4);
}
return X;
}
public Complex Complex1(int K, int N3)
{
Complex W = Complex.Pow((Complex.Exp(-1 * Complex.ImaginaryOne * (2.0 * Math.PI / N3))), K);
return W;
}

Depending on the FFT, you may have to scale the entire complex vector (multiply either the input or result vector, not both) by 1/N (the length of the FFT). But this scale factor differs between FFT libraries (some already include a 1/sqrt(N) factor).
Then take the complex conjugate of the input vector, FFT it, and do another complex conjugate to get the IFFT result. This is equivalent to doing an FFT using -i instead of i for the basis vector exponent.
Also, normally, one does not get the same values out of a computed IFFT(FFT()) as went in, as arithmetic rounding adds at least some low level numerical noise to the result.

Related

How to calculate normal distribution kernal for 1d gaussian filter

I need to apply a 1d gaussian filter to a list of floats in c#, ie, to smooth a graph.
I got as far as simply averaging each value with n neighbors, but the result wasn't quite right and so I discovered that I need to apply a normal distribution weight to the contributions of the values per iteration.
I can't find a library like scipy that has a function for this, and I don't quite understand the algebraic formulas I have found for computing a gaussian kernal. Examples are generally geared towards a 2D implementation for images.
Can anyone suggest the modifications that would need to be made to the following code to achieve the proper gaussian effect?
public static List<float> MeanFloats(List<float> floats, int width)
{
List<float> results = new List<float>();
if (width % 2 == 0)
width -= 1; // make sure width is odd
int halfWidthMinus1 = width / 2; // width is known to be odd, divide by 2 will round down
for (int i = 0; i < floats.Count; i++) // iterate through all floats in list
{
float result = 0;
for (int j = 0; j < width; j++)
{
var index = i - halfWidthMinus1 + j;
index = math.max(index, 0); // clamp index - the first and last elements of the list will be used when the algorithm tries to access outside the bounds of the list
index = math.min(index, floats.Count-1);
result += floats[index]; // multiply with kernal here??
}
result /= width; // calculate mean
results.Add(result);
}
return results;
}
If relevant this is for use in a Unity game.
A 1-dimensional Gaussian Kernel is defined as
where sigma is the standard deviation of your list, and x is the index distance.
You then create a kernel by filling each of its array slots with a multiplier. Here is an (untested) example:
private static float[] GaussianKernel(int width, float sigma)
{
float[] kernel = new float[width + 1 + width];
for (int i = -width; i <= width; i++)
{
kernel[width + i] = Mathf.Exp(-(i * i) / (2 * sigma * sigma)) / (Math.PI * 2 * sigma * sigma);
}
return kernel;
}
In your smoothing function you apply this multiplier to the floats[index] value. Finally, before adding the result, instead of dividing it by the width, you divide it by the total sum of the kernel weights (the values of the kernel array).
You could compile the values of the current kernel weight during each iteration in your j-loop weightSum += kernel[j].

Inverse FFT in C#

I am writing an application for procedural audiofiles, I have to analyze my new file, get its frequency spectrum and change it in its calculated.
I want to do this with the Fast Fourier Transform (FFT). This is my recursive C# FFT:
void ft(float n, ref Complex[] f)
{
if (n > 1)
{
Complex[] g = new Complex[(int) n / 2];
Complex[] u = new Complex[(int) n / 2];
for (int i = 0; i < n / 2; i++)
{
g[i] = f[i * 2];
u[i] = f[i * 2 + 1];
}
ft(n / 2, ref g);
ft(n / 2, ref u);
for (int i = 0; i < n / 2; i++)
{
float a = i;
a = -2.0f * Mathf.PI * a / n;
float cos = Mathf.Cos(a);
float sin = Mathf.Sin(a);
Complex c1 = new Complex(cos, sin);
c1 = Complex.Multiply(u[i], c1);
f[i] = Complex.Add(g[i], c1);
f[i + (int) n / 2] = Complex.Subtract(g[i], c1);
}
}
}
The inspiring example was
I then compared my results with those from wolframalpha for the same input 0.6,0.7,0.8,0.9 but the results aren't be the same. My results are twice as big than Wolfram's and the imaginary part are the -2 times of Wolfram's.
Also, wiki indicates that the inverse of FFT can be computed with
But I compare inputs and outputs and they are different.
Has anyone an idea what's wrong?
Different implementations often use different definitions of the Discrete Fourier Transform (DFT), with correspondingly different results. The correspondence between implementations is usually fairly trivial (such as a scaling factor).
More specifically, your implementation is based on the following definition of the DFT:
On the other hand, Wolfram alpha by default uses a definition, which after adjusting to 0-based indexing looks like:
Correspondingly, it is possible to transform the result of your implementation to match Wolfram alpha's with:
void toWolframAlphaDefinition(ref Complex[] f)
{
float scaling = (float)(1.0/Math.Sqrt(f.Length));
for (int i = 0; i < f.Length; i++)
{
f[i] = scaling * Complex.Conjugate(f[i]);
}
}
Now as far as computing the inverse DFT using the forward transform, a direct implementation of the formula
you provided would be:
void inverseFt(ref Complex[] f)
{
for (int i = 0; i < f.Length; i++)
{
f[i] = Complex.Conjugate(f[i]);
}
ft(f.Length, ref f);
float scaling = (float)(1.0 / f.Length);
for (int i = 0; i < f.Length; i++)
{
f[i] = scaling * Complex.Conjugate(f[i]);
}
}
Calling ft on the original sequence 0.6, 0.7, 0.8, 0.9 should thus get you the transformed sequence 3, -0.2+0.2j, -0.2, -0.2-0.2j.
Further calling inverseFt on this transform sequence should then bring you back to your original sequence 0.6, 0.7, 0.8, 0.9 (within some reasonable floating point error), as shown in this live demo.

C# Can LinearRegression code from Math.NET Numerics be made faster?

I need to do multiple linear regression efficiently. I am trying to use the Math.NET Numerics package but it seems slow - perhaps it is the way I have coded it? For this example I have only simple (1 x value) regression.
I have this snippet:
public class barData
{
public double[] Xs;
public double Mid;
public double Value;
}
public List<barData> B;
var xdata = B.Select(x=>x.Xs[0]).ToArray();
var ydata = B.Select(x => x.Mid).ToArray();
var X = DenseMatrix.CreateFromColumns(new[] { new DenseVector(xdata.Length, 1), new DenseVector(xdata) });
var y = new DenseVector(ydata);
var p = X.QR().Solve(y);
var b = p[0];
var a = p[1];
B[0].Value = (a * (B[0].Xs[0])) + b;
This runs about 20x SLOWER than this pure C#:
double xAvg = 0;
double yAvg = 0;
int n = -1;
for (int x = Length - 1; x >= 0; x--)
{
n++;
xAvg += B[x].Xs[0];
yAvg += B[x].Mid;
}
xAvg = xAvg / B.Count;
yAvg = yAvg / B.Count;
double v1 = 0;
double v2 = 0;
n = -1;
for (int x = Length - 1; x >= 0; x--)
{
n++;
v1 += (B[x].Xs[0] - xAvg) * (B[x].Mid - yAvg);
v2 += (B[x].Xs[0] - xAvg) * (B[x].Xs[0] - xAvg);
}
double a = v1 / v2;
double b = yAvg - a * xAvg;
B[0].Value = (a * B[Length - 1].Xs[0]) + b;
ALSO if Math.NET is the issue, then if anyone knows simple way to alter my pure code for multiple Xs I would be grateful of some help
Using a QR decomposition is a very generic approach that can deliver least squares regression solutions to any function with linear parameters, no matter how complicated it is. It is therefore not surprising that it cannot compete with a very specific straight implementation (on computation time), especially not in the simple case of y:x->a+b*x. Unfortunately Math.NET Numerics does not provide direct regression routines yet you could use instead.
However, there are still a couple things you can try for better speed:
Use thin instead of full QR decompositon, i.e. pass QRMethod.Thin to the QR method
Use our native MKL provider (much faster QR, but no longer purely managed code)
Tweak threading, e.g. try to disable multi-threading completely (Control.ConfigureSingleThread()) or tweak its parameters
If the data set is very large there are also more efficient ways to build the matrix, but that's likely not very relevant beside of the QR (-> perf analysis!).

How can i import System.Windows in C# [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Hello i have copied this FFT implementation, but it says there is nothing like System.Windows How can i make this code work? Allready got the answer I just wanted to edit this post so it is usefull now to somebody.
Source:
http://gerrybeauregard.wordpress.com/2011/04/01/an-fft-in-c/
Code::
using System;
using System.Net;
namespace FFT {
public class FFT2 {
// Element for linked list in which we store the
// input/output data. We use a linked list because
// for sequential access it's faster than array index.
class FFTElement {
public double re = 0.0; // Real component
public double im = 0.0; // Imaginary component
public FFTElement next; // Next element in linked list
public uint revTgt; // Target position post bit-reversal
}
private uint m_logN = 0; // log2 of FFT size
private uint m_N = 0; // FFT size
private FFTElement[] m_X; // Vector of linked list elements
/**
*
*/
public FFT2() {
}
/**
* Initialize class to perform FFT of specified size.
*
* #param logN Log2 of FFT length. e.g. for 512 pt FFT, logN = 9.
*/
public void init(
uint logN) {
m_logN = logN;
m_N = (uint)(1 << (int)m_logN);
// Allocate elements for linked list of complex numbers.
m_X = new FFTElement[m_N];
for (uint k = 0; k < m_N; k++)
m_X[k] = new FFTElement();
// Set up "next" pointers.
for (uint k = 0; k < m_N - 1; k++)
m_X[k].next = m_X[k + 1];
// Specify target for bit reversal re-ordering.
for (uint k = 0; k < m_N; k++)
m_X[k].revTgt = BitReverse(k, logN);
}
/**
* Performs in-place complex FFT.
*
* #param xRe Real part of input/output
* #param xIm Imaginary part of input/output
* #param inverse If true, do an inverse FFT
*/
public void run(
double[] xRe,
double[] xIm,
bool inverse = false) {
uint numFlies = m_N >> 1; // Number of butterflies per sub-FFT
uint span = m_N >> 1; // Width of the butterfly
uint spacing = m_N; // Distance between start of sub-FFTs
uint wIndexStep = 1; // Increment for twiddle table index
// Copy data into linked complex number objects
// If it's an IFFT, we divide by N while we're at it
FFTElement x = m_X[0];
uint k = 0;
double scale = inverse ? 1.0 / m_N : 1.0;
while (x != null) {
x.re = scale * xRe[k];
x.im = scale * xIm[k];
x = x.next;
k++;
}
// For each stage of the FFT
for (uint stage = 0; stage < m_logN; stage++) {
// Compute a multiplier factor for the "twiddle factors".
// The twiddle factors are complex unit vectors spaced at
// regular angular intervals. The angle by which the twiddle
// factor advances depends on the FFT stage. In many FFT
// implementations the twiddle factors are cached, but because
// array lookup is relatively slow in C#, it's just
// as fast to compute them on the fly.
double wAngleInc = wIndexStep * 2.0 * Math.PI / m_N;
if (inverse == false)
wAngleInc *= -1;
double wMulRe = Math.Cos(wAngleInc);
double wMulIm = Math.Sin(wAngleInc);
for (uint start = 0; start < m_N; start += spacing) {
FFTElement xTop = m_X[start];
FFTElement xBot = m_X[start + span];
double wRe = 1.0;
double wIm = 0.0;
// For each butterfly in this stage
for (uint flyCount = 0; flyCount < numFlies; ++flyCount) {
// Get the top & bottom values
double xTopRe = xTop.re;
double xTopIm = xTop.im;
double xBotRe = xBot.re;
double xBotIm = xBot.im;
// Top branch of butterfly has addition
xTop.re = xTopRe + xBotRe;
xTop.im = xTopIm + xBotIm;
// Bottom branch of butterly has subtraction,
// followed by multiplication by twiddle factor
xBotRe = xTopRe - xBotRe;
xBotIm = xTopIm - xBotIm;
xBot.re = xBotRe * wRe - xBotIm * wIm;
xBot.im = xBotRe * wIm + xBotIm * wRe;
// Advance butterfly to next top & bottom positions
xTop = xTop.next;
xBot = xBot.next;
// Update the twiddle factor, via complex multiply
// by unit vector with the appropriate angle
// (wRe + j wIm) = (wRe + j wIm) x (wMulRe + j wMulIm)
double tRe = wRe;
wRe = wRe * wMulRe - wIm * wMulIm;
wIm = tRe * wMulIm + wIm * wMulRe;
}
}
numFlies >>= 1; // Divide by 2 by right shift
span >>= 1;
spacing >>= 1;
wIndexStep <<= 1; // Multiply by 2 by left shift
}
// The algorithm leaves the result in a scrambled order.
// Unscramble while copying values from the complex
// linked list elements back to the input/output vectors.
x = m_X[0];
while (x != null) {
uint target = x.revTgt;
xRe[target] = x.re;
xIm[target] = x.im;
x = x.next;
}
}
/**
* Do bit reversal of specified number of places of an int
* For example, 1101 bit-reversed is 1011
*
* #param x Number to be bit-reverse.
* #param numBits Number of bits in the number.
*/
private uint BitReverse(
uint x,
uint numBits) {
uint y = 0;
for (uint i = 0; i < numBits; i++) {
y <<= 1;
y |= x & 0x0001;
x >>= 1;
}
return y;
}
}
}
System.Windows is the Windows Presentation Foundation namespace. The article is assuming you have a WPF application. If you don't have one, you can create one from Visual Studio from File > New Project > ... > Windows > WPF Application.
WPF is a way of creating graphical desktop applications for MS Windows. If you come from a command-line OS you may be more comfortable making a Windows Console application.
If you want to learn how to create a WPF application you need a WPF tutorial.

How to generate a square wave using C#?

I would like to generate a digital signal, which'll then be used to implement an ASK(Amplitude Shift Keying) Signal.
Let's say the message bits are 10110, data rate : 3.9 Khz & amplitude A.
What would be the best way to generate a Square signal(Digital).
I tried the following code, but the outcome is not a desired one.
double[] x = new double[1000];
double[] y = new double[1000];
double freq = 3900.0;
for (int k = 0; k < y.Length; k++)
{
x[k] = k;
y[k] = (4 / Math.PI) * (((Math.Sin(((2 * k) - 1) * (2 * Math.PI * freq))) / ((2 * k) - 1)));
}
// Plot Square Wave
plotSquare(x, y, Msg);
The easiest way I can think of is to set y to be sign of a sine wave, making allowances for when it equals zero. I don't know if C# has the triple-operator, but something like this might work:
y[k] = Math.Sin(freq * k)>=0?A:-1*A;
Math.Sin is useful for sine wave, but a square wave should be far, far simpler (i.e. signal is 'high' for a period, then 'low' for a period). If you have a Math.Sin anywhere, you are generate a sine wave, not a square wave. Bearing in mind a square wave can be generated with a condition (is x>y) and a sine wave needs a full mathematical operation, it's far more efficient, too.
C#'s Iterator Block support comes to mind:
IEnumerable<Tuple<double, double>> SquareWave(double freq, double lowAmp, double highAmp)
{
for (var x = 0.0; true; x += 1.0)
{
var y = ((int)(x / freq) % 2) == 0 ? lowAmp : highAmp;
yield return Tuple.Create(x, y);
}
}
use like this:
foreach(var t in SquareWave(10, -5, 5).Take(30))
Console.WriteLine("X: {0:0.0}/Y: {1:0.0}", t.Item1, t.Item2);

Categories