How to generate a square wave using C#? - 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);

Related

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.

B-spline algorithm

I have code for drawing Bezier curves. Is it posible to modify this code for drawing B-Spline curves?
Here is my code using DeCasteljau algorithm:
private Point getPoint(int r, int i, double t)
{
if (r == 0) return points[i];
Point p1 = getPoint(r - 1, i, t);
Point p2 = getPoint(r - 1, i + 1, t);
return new Point((int)((1 - t) * p1.X + t * p2.X), (int)((1 - t) * p1.Y + t * p2.Y));
}
I found this code for B-Spline curves. It looks similar to my code, but I have XY points and there are only numbers. I don't know how to modify my code. I tried something but it doesn't work.
private double BasisFunction(int k, int i, ParameterCollection u, double t){
if(k==0)
{
if((u[i]<=t) && (t<=u[i+1]))
return 1;
else
return 0;
}
else
{
double memb1, memb2;
if(u[i+k]==u[i])
memb1 = 0;
else
memb1 = ((t-u[i])/(u[i+k]-u[i]))*BasisFunction(k-1, i, u, t);
if(u[i+k+1]==u[i+1])
memb2 = 0;
else
memb2 = ((u[i+k+1]-t)/(u[i+k+1]-u[i+1]))*BasisFunction(k-1, i+1, u, t);
return memb1+memb2;
}
}
Please help.
The function BasisFunction() is for computing the value of B-spline basis function N(n,i)(t), where n is degree and i ranges from 0 to (m-1) with m is the number of control points. So, to use this function, you need to define the following for your B-spline:
degree.
m control points, denoting them as P[i][2] with i=0~(m-1)
knot sequence. This is the input "ParameterCollection" to the BasisFunction. You need to have (m+degree+1) knots in the knot sequence and the knot values need to be monotonically non-decreasing. An example of knot sequence for degree 3 B-spline with 5 control points is [0,0,0,0,u0,1,1,1,1], where u0 is any value between [0,1].
Then you can evaluate any point on the B-spline curve at parameter t by something like:
double point[2]={0.0}; // point on the B-spline curve
for (int ii=0; ii < m; ii++) // loop thru all control points
{
double basisVal = BasisFunction(degree, ii, knotSequence, t);
point[0] += P[ii][0]*basisVal;
point[1] += P[ii][1]*basisVal;
}

How to find the largest eigenvector of a matrix?

I am trying to implement this without success and I have to do this without using external modules numpy, etc. There are 3 modules in the app I am coding this, Python and C#, C++ but no other fancy libraries other than standard ones.
On a separate application, I used numpy's svd and it works very accurately. So I am using it to match my results. My method is PCA and everything is good up to this point. But after I calculate my symmetric covariance matrix, I don't know how to find the largest eigenvector.
The data set is always 3d points, x, y and z.
vector center;
for(point p in points):
center += p;
center /= points.count;
sumxx = 0;
sumxy = 0;
sumxz = 0;
sumyy = 0;
sumyz = 0;
sumzz = 0;
for(point p in points):
vector s = p - center;
sumxx += s.x * s.x;
sumxy += s.x * s.y;
sumxz += s.x * s.z;
sumyy += s.y * s.y;
sumyz += s.y * s.z;
sumzz += s.z * s.z;
matrix3 mat = invert(matrix3(sumxx, sumxy, sumxz, sumxy, sumyy, sumyz, sumxz, sumyz, sumzz));
vector n;
if (determinant(mat) > 0)
normal = find_largest_eigenvalue
Let us recap what you are asking, to clarify :
Find an eigenvector of a matrix mat
This eigenvector should be associated with the largest eigenvalue of the matrix
The matrix is the symmetric covariance matrix of a principal component analysis. In particular, it is symmetric.
Your matrix is square of size 3 by 3, as shown in your code by matrix3 mat = ... and confirmed in a (now deleted) comment.
Under these very specific circumstances, the following answer applies. However tmyklebu warns against numerical instability of this approach for some pathological matrices, typically when r is close to -1.
Alright, lets start with a bit of reading from wikipedia's page on Characteristic polynomials
In linear algebra, the characteristic polynomial of a square matrix is a polynomial, which is invariant under matrix similarity and has the eigenvalues as roots.
blah blah blah, let's skip directly to the 3x3 matrix section in the page on Eigenvalue algorithms.
If A is a 3×3 matrix, then its characteristic equation can be expressed as:
Followed a few lines later by (more or less) this pseudo-code, for symmetric matrices (which you say you have, if I'm not mistaken -- otherwise you might have complex eigenvalues) :
p1 = A(1,2)^2 + A(1,3)^2 + A(2,3)^2
if (p1 == 0)
% A is diagonal.
eig1 = A(1,1)
eig2 = A(2,2)
eig3 = A(3,3)
else
q = (A(1,1) + A(2,2) + A(3,3)) / 3
p2 = (A(1,1) - q)^2 + (A(2,2) - q)^2 + (A(3,3) - q)^2 + 2 * p1
p = sqrt(p2 / 6)
B = (1 / p) * (A - q * I) % I is the identity matrix
r = determinant(B) / 2
% In exact arithmetic for a symmetric matrix -1 <= r <= 1
% but computation error can leave it slightly outside this range.
if (r <= -1)
phi = pi / 3
elseif (r >= 1)
phi = 0
else
phi = acos(r) / 3
end
% the eigenvalues satisfy eig3 <= eig2 <= eig1
eig1 = q + 2 * p * cos(phi)
eig3 = q + 2 * p * cos(phi + (2*pi/3))
eig2 = 3 * q - eig1 - eig3 % since trace(A) = eig1 + eig2 + eig3
end
So you want max(eig1,eig2,eig3) in the first case, eig1 in the second case. Let us call e this largest eigenvalue.
For the eigenvector, you can now just solve (A-e*I)x=0
There are different algorithms for finding eigenvalues. Some work from smallest to largest, like QR; others work from largest to smallest, like power iteration or Jacobi-Davidson.
Maybe a switch of algorithm is what you want. Try power method and see if that helps.
https://scicomp.stackexchange.com/questions/1681/what-is-the-fastest-way-to-calculate-the-largest-eigenvalue-of-a-general-matrix

Converting fft to ifft in 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.

How to "flatten" or "index" 3D-array in 1D array?

I am trying to flatten 3D array into 1D array for "chunk" system in my game. It's a 3D-block game and basically I want the chunk system to be almost identical to Minecraft's system (however, this isn't Minecraft clone by any measure). In my previous 2D-games I have accessed the flattened array with following algorithm:
Tiles[x + y * WIDTH]
However, this obviously doesn't work with 3D since it's missing the Z-axis. I have no idea how to implement this sort of algorithm in 3D-space. Width, height and depth are all constants (and width is just as large as height).
Is it just x + y*WIDTH + Z*DEPTH ? I am pretty bad with math and I am just beginning 3D-programming so I am pretty lost :|
PS. The reason for this is that I am looping and getting stuff by index from it quite a lot. I know that 1D arrays are faster than multi-dimensional arrays (for reasons I cant remember :P ). Even though this may not be necessary, I want as good performance as possible :)
Here is a solution in Java that gives you both:
from 3D to 1D
from 1D to 3D
Below is a graphical illustration of the path I chose to traverse the 3D matrix, the cells are numbered in their traversal order:
Conversion functions:
public int to1D( int x, int y, int z ) {
return (z * xMax * yMax) + (y * xMax) + x;
}
public int[] to3D( int idx ) {
final int z = idx / (xMax * yMax);
idx -= (z * xMax * yMax);
final int y = idx / xMax;
final int x = idx % xMax;
return new int[]{ x, y, z };
}
The algorithm is mostly the same. If you have a 3D array Original[HEIGHT, WIDTH, DEPTH] then you could turn it into Flat[HEIGHT * WIDTH * DEPTH] by
Flat[x + WIDTH * (y + DEPTH * z)] = Original[x, y, z]
As an aside, you should prefer arrays of arrays over multi-dimensional arrays in .NET. The performance differences are significant
I think the above needs a little correction. Lets say you have a HEIGHT of 10, and a WIDTH of 90, single dimensional array will be 900. By the above logic, if you are at the last element on the array 9 + 89*89, obviously this is greater than 900. The correct algorithm is:
Flat[x + HEIGHT* (y + WIDTH* z)] = Original[x, y, z], assuming Original[HEIGHT,WIDTH,DEPTH]
Ironically if you the HEIGHT>WIDTH you will not experience an overflow, just complete bonkers results ;)
x + y*WIDTH + Z*WIDTH*DEPTH. Visualize it as a rectangular solid: first you traverse along x, then each y is a "line" width steps long, and each z is a "plane" WIDTH*DEPTH steps in area.
You're almost there. You need to multiply Z by WIDTH and DEPTH:
Tiles[x + y*WIDTH + Z*WIDTH*DEPTH] = elements[x][y][z]; // or elements[x,y,z]
TL;DR
The correct answer can be written various ways, but I like it best when it can be written in a way that is very easy to understand and visualize. Here is the exact answer:
(width * height * z) + (width * y) + x
TS;DR
Visualize it:
someNumberToRepresentZ + someNumberToRepresentY + someNumberToRepresentX
someNumberToRepresentZ indicates which matrix we are on (depth). To know which matrix we are on, we have to know how big each matrix is. A matrix is 2d sized as width * height, simple. The question to ask is "how many matrices are before the matrix I'm on?" The answer is z:
someNumberToRepresentZ = width * height * z
someNumberToRepresentY indicates which row we are on (height). To know which row we are on, we have to know how big each row is: Each row is 1d, sized as width. The question to ask is "how many rows are before the row I'm on?". The answer is y:
someNumberToRepresentY = width * y
someNumberToRepresentX indicates which column we are on (width). To know which column we are on we simply use x:
someNumberToRepresentX = x
Our visualization then of
someNumberToRepresentZ + someNumberToRepresentY + someNumberToRepresentX
Becomes
(width * height * z) + (width * y) + x
The forward and reverse transforms of Samuel Kerrien above are almost correct. A more concise (R-based) transformation maps are included below with an example (the "a %% b" is the modulo operator representing the remainder of the division of a by b):
dx=5; dy=6; dz=7 # dimensions
x1=1; y1=2; z1=3 # 3D point example
I = dx*dy*z1+dx*y1+x1; I # corresponding 2D index
# [1] 101
x= I %% dx; x # inverse transform recovering the x index
# [1] 1
y = ((I - x)/dx) %% dy; y # inverse transform recovering the y index
# [1] 2
z= (I-x -dx*y)/(dx*dy); z # inverse transform recovering the z index
# [1] 3
Mind the division (/) and module (%%) operators.
The correct Algorithm is:
Flat[ x * height * depth + y * depth + z ] = elements[x][y][z]
where [WIDTH][HEIGHT][DEPTH]
To better understand description of 3D array in 1D array would be ( I guess Depth in best answer is meant Y size)
IndexArray = x + y * InSizeX + z * InSizeX * InSizeY;
IndexArray = x + InSizeX * (y + z * InSizeY);
m[x][y][z] = data[xYZ + yZ + z]
x-picture:
0-YZ
.
.
x-YZ
y-picture
0-Z
.
.
.
y-Z
summing up, it should be : targetX*YZ + targetY*Z + targetZ
In case, somebody is interested to flatten an nD (2D, 3D, 4D, ...) array to 1D, I wrote the below code. For example, if the size of the array in different dimensions is stored in the sizes array:
# pseudo code
sizes = {size_x, size_y, size_z,...};
This recursive function gives you the series of {1, size_x, size_x*size_y, size_x*size_y*size_z, ...}
// i: number of the term
public int GetCoeff(int i){
if (i==0)
return 1;
return sizes[i-1]*GetCoeff(i-1);
}
So, we have to multiply nD indexes by their corresponding series term and sum them to get {ix + iy*size_x + iz*size_x*size_y, ...}:
// indexNd: {ix, iy, iz, ...}
public int GetIndex1d(int[] indexNd){
int sum =0;
for (var i=0; i<indexNd.Length;i++)
sum += indexNd[i]*GetCoeff(i);
return sum;
}
In this code I assumed, the nD array is contiguous in memory along firstly x, then y, z, ... . So probably you call your array-like arr[z,y,x]. But, if you call them the other way, arr[x,y,z] then z is the fastest index and we like to calculate iz + iy*size_z + ix* size_z*size_y. In this case, the below function gives us the series {1, size_z, size_z*size_y, ...}:
// Dims is dimension of array, like 3 for 3D
public int GetReverseCoeff(int i){
if (i==0)
return 1;
return sizes[Dims-i]*GetReverseCoeff(i-1);
}
The coefficients are stored in the right order:
public void SetCoeffs(){
for (int i=0;i<Dims;i++)
coeffs[Dims-i-1] = GetReverseCoeff(i);
}
The 1D index is calculated the same as before except coeffs array is used:
// indexNd: {ix, iy, iz, ...}
public int GetIndex1d(int[] indexNd){
int sum =0;
for (var i=0; i<indexNd.Length;i++)
sum += indexNd[i]*coeffs[i];
return sum;
}
Samuel Kerrien's answer to python :
def to1D(crds,dims):
x,y,z=crds
xMax,yMax,zMax=dims
return (z * xMax * yMax) + (y * xMax) + x
def to3D(idx,dims):
xMax,yMax,zMax=dims
z = idx // (xMax * yMax)
idx -= (z * xMax * yMax)
y = idx // xMax
x = idx % xMax
return x, y, z

Categories