I want to "stretch" a one-dimensional float array into a bigger array.
//expected behaviour
float[] initialArray = {2.0, 6.5, 2.0}
float[] biggerArray = resample(initialArray, 7 /*new size*/)
//output: {2.0, 3.5, 5.0, 6.5, 5.0, 3.5, 2.0}
The new values should propobaly be calculated from linear interpolation of the previous array values but i can't figure out how to achieve that.
Any hint ?
Lets the length of a source array is N, and the length of a destination array is M where N < M and N > 1.
You can calculate the new index of the source i-th element by the formula:
j = i * (M - 1)/(N - 1);
When i == 0 then j == 0; and when i == N - 1 then j == M - 1. The external loop can looks like this:
float[] source = ...;
float[] destination = ...;
destination[0] = source[0];
for (int i = 1; i < source.Length; i++)
{
int j = i * (destination.Length - 1)/(source.Length - 1);
destination[j] = source[i];
// interpolation
}
To interpolation you should calculate intermediate values for each pair (source[i - 1], source[i]). You'll need to store previous value of j:
destination[0] = source[0];
int jPrevious = 0;
for (int i = 1; i < source.Length; i++)
{
int j = i * (destination.Length - 1)/(source.Length - 1);
Interpolate(destination, jPrevious, j, source[i - 1], source[i]);
jPrevious = j;
}
private static void Interpolate(float[] destination, int destFrom, int destTo, float valueFrom, float valueTo)
{
int destLength = destTo - destFrom;
float valueLength = valueTo - valueFrom;
for (int i = 0; i <= destLength; i++)
destination[destFrom + i] = valueFrom + (valueLength * i)/destLength;
}
This one works for both if source size is larger than destination and vice versa.
private double[] Resample(double[] source, int n)
{
//n destination length
int m = source.Length; //source length
double[] destination = new double[n];
destination[0] = source[0];
destination[n-1] = source[m-1];
for (int i = 1; i < n-1; i++)
{
double jd = ((double)i * (double)(m - 1) / (double)(n - 1));
int j = (int)jd;
destination[i] = source[j] + (source[j + 1] - source[j]) * (jd - (double)j);
}
return destination;
}
You can use List<float>:
float[] initialArray = { 2.0f, 6.5f, 2.0f };
List<float> initialArrayTemp = ToListFloat(initialArray);
private List<float> ToListFloat(float[] array)
{
List<float> list = new List<float>();
for (int i = 0; i < array.Length; i++)
{
list.Add(array[i]);
}
return list;
}
Now your array is a dynamic array and you can add your new nodes anywhere of your Array by using Insert() method.
As soon as you need a new static array, use below:
float[] newInitialArray = initialArrayTemp.ToArray();
Related
I'm trying to implement FFT, using butterfly notation with decimation in spatial domain. I have two separated functions, one to calculate the FFT on 1D array, and the other that applies the first function over columns of the image, puts these columns in a temporary array, and then computes the FFT of rows in the temporary array.
Here is the code
public static Complex[] FFT(Complex[] input)
{
// Get the length of the input array
int n = input.Length;
Complex I = new Complex(0, 1);
// Check if the input has a length of 1
if (n == 1)
{
return input;
}
// Split the input into even and odd elements
Complex[] even = new Complex[n / 2];
Complex[] odd = new Complex[n / 2];
for (int i = 0; i < n; i++)
{
if (i % 2 == 0)
{
even[i / 2] = input[i];
}
else
{
odd[(i - 1) / 2] = input[i];
}
}
// Compute the FFT of the even and odd elements
Complex[] evenFFT = FFT(even);
Complex[] oddFFT = FFT(odd);
// Combine the FFT of the even and odd elements using the butterfly notation
Complex[] output = new Complex[n];
for (int i = 0; i < n / 2; i++)
{
Complex w = Complex.Exp(-2 * I * Math.PI * i / n);
output[i] = evenFFT[i] + w * oddFFT[i];
output[i + n / 2] = evenFFT[i] - w * oddFFT[i];
}
return output;
}
public static Complex[,] FFT2D(Complex[,] input)
{
int N = input.GetLength(0);
int M = input.GetLength(1);
Complex[,] output = new Complex[128, 128];
Complex[,] columnsFFT = new Complex[128, 128];
//Perform FFT over the columns of the input
for(int i = 0; i < M; i++)
{
//Put all the values from i'th column in the tempColumn variable
var tempColumn = new Complex[128];
for(int j = 0; j < N; j++)
{
tempColumn[j] = input[j, i];
}
//Calculate the FFT of i'th column
tempColumn = FFT(tempColumn);
//Assign the column to columnsFFT, after calculating its FFT
for(int z = 0; z < 128; z++)
{
columnsFFT[z, i] = tempColumn[z];
}
}
//Perform FFT over the rows of the columnsFFT
for(int i = 0; i < N; i++)
{
//Put the values from i'th row in tempRow, so we can perform the FFT on its entirety
var tempRow = new Complex[128];
for(int j = 0; j < M; j++)
{
tempRow[j] = columnsFFT[i, j];
}
//Calculate the FFT on tempRow
tempRow = FFT(tempRow);
//Assign the tempRow to the output
for(int z = 0; z < M; z++)
{
if (i == 0)
Console.WriteLine(tempRow[z].Real);
output[i, z] = tempRow[z];
}
}
return output;
}
The problem that i have is that it simply doesn't work, or i think it doesn't, based on the image output i get.
Input image
Output
What is it that i'm doing wrong here?
I have to calculate the spectrum values of an audio.
I used aForge's FFT in Sources/Math/FourierTransform.cs and I used an example of sampling with 16 samples as used in this video to check the results with excel (I tested the results in a spreadsheet like in the video).
FFT:
public enum Direction
{
Forward = 1,
Backward = -1
};
private const int minLength = 2;
private const int maxLength = 16384;
private const int minBits = 1;
private const int maxBits = 14;
private static int[][] reversedBits = new int[maxBits][];
private static Complex[,][] complexRotation = new Complex[maxBits, 2][];
static void Main(string[] args)
{
var Data = new Complex[16];
Data[0] = new Complex(0, 0);
Data[1] = new Complex((float)0.998027, 0);
Data[2] = new Complex((float)0.125333, 0);
Data[3] = new Complex((float)-0.98229, 0);
Data[4] = new Complex((float)-0.24869, 0);
Data[5] = new Complex((float)0.951057, 0);
Data[6] = new Complex((float)0.368125, 0);
Data[7] = new Complex((float)-0.90483, 0);
Data[8] = new Complex((float)-0.48175, 0);
Data[9] = new Complex((float)0.844328, 0);
Data[10] = new Complex((float)0.587785, 0);
Data[11] = new Complex((float)-0.77051, 0);
Data[12] = new Complex((float)-0.68455, 0);
Data[13] = new Complex((float)0.684547, 0);
Data[14] = new Complex((float)0.770513, 0);
Data[15] = new Complex((float)-0.58779, 0);
FFT(Data, Direction.Forward);
for (int a = 0; a <= Data.Length - 1; a++)
{
Console.WriteLine(Data[a].Re.ToString());
}
Console.ReadLine();
}
public static void FFT(Complex[] data, Direction direction)
{
int n = data.Length;
int m = Tools.Log2(n);
// reorder data first
ReorderData(data);
// compute FFT
int tn = 1, tm;
for (int k = 1; k <= m; k++)
{
Complex[] rotation = GetComplexRotation(k, direction);
tm = tn;
tn <<= 1;
for (int i = 0; i < tm; i++)
{
Complex t = rotation[i];
for (int even = i; even < n; even += tn)
{
int odd = even + tm;
Complex ce = data[even];
Complex co = data[odd];
double tr = co.Re * t.Re - co.Im * t.Im;
double ti = co.Re * t.Im + co.Im * t.Re;
data[even].Re += tr;
data[even].Im += ti;
data[odd].Re = ce.Re - tr;
data[odd].Im = ce.Im - ti;
}
}
}
if (direction == Direction.Forward)
{
for (int i = 0; i < n; i++)
{
data[i].Re /= (double)n;
data[i].Im /= (double)n;
}
}
}
private static int[] GetReversedBits(int numberOfBits)
{
if ((numberOfBits < minBits) || (numberOfBits > maxBits))
throw new ArgumentOutOfRangeException();
// check if the array is already calculated
if (reversedBits[numberOfBits - 1] == null)
{
int n = Tools.Pow2(numberOfBits);
int[] rBits = new int[n];
// calculate the array
for (int i = 0; i < n; i++)
{
int oldBits = i;
int newBits = 0;
for (int j = 0; j < numberOfBits; j++)
{
newBits = (newBits << 1) | (oldBits & 1);
oldBits = (oldBits >> 1);
}
rBits[i] = newBits;
}
reversedBits[numberOfBits - 1] = rBits;
}
return reversedBits[numberOfBits - 1];
}
private static Complex[] GetComplexRotation(int numberOfBits, Direction direction)
{
int directionIndex = (direction == Direction.Forward) ? 0 : 1;
// check if the array is already calculated
if (complexRotation[numberOfBits - 1, directionIndex] == null)
{
int n = 1 << (numberOfBits - 1);
double uR = 1.0;
double uI = 0.0;
double angle = System.Math.PI / n * (int)direction;
double wR = System.Math.Cos(angle);
double wI = System.Math.Sin(angle);
double t;
Complex[] rotation = new Complex[n];
for (int i = 0; i < n; i++)
{
rotation[i] = new Complex(uR, uI);
t = uR * wI + uI * wR;
uR = uR * wR - uI * wI;
uI = t;
}
complexRotation[numberOfBits - 1, directionIndex] = rotation;
}
return complexRotation[numberOfBits - 1, directionIndex];
}
// Reorder data for FFT using
private static void ReorderData(Complex[] data)
{
int len = data.Length;
// check data length
if ((len < minLength) || (len > maxLength) || (!Tools.IsPowerOf2(len)))
throw new ArgumentException("Incorrect data length.");
int[] rBits = GetReversedBits(Tools.Log2(len));
for (int i = 0; i < len; i++)
{
int s = rBits[i];
if (s > i)
{
Complex t = data[i];
data[i] = data[s];
data[s] = t;
}
}
}
These are the results after the transformation:
Output FFT results: Excel FFT results:
0,0418315622955561 0,669305
0,0533257974328085 0,716163407
0,137615673627316 0,908647001
0,114642731070279 1,673453043
0,234673940537634 7,474988602
0,0811255020953362 0,880988382
0,138088891589122 0,406276784
0,0623766891658306 0,248854492
0,0272978749126196 0,204227
0,0124250144575261 0,248854492
0,053787064184711 0,406276784
0,00783331226557493 0,880988382
0,0884368745610118 7,474988602
0,0155431246384978 1,673453043
0,0301093757152557 0,908647001
0 0,716163407
The results are not at all similar. Where is it wrong?
Is the implementation of complex (Data) wrong or is the FFT method wrong or other?
Thanks in advance!
First, the resulting FFT is a complex function in general. You're only displaying the real parts in your code but the thing you're comparing to is displaying the magnitudes, so of course they're going to be different: you're comparing apples to oranges.
When you use magnitudes and compare apples to apples, you should get this:
for (int a = 0; a <= Data.Length - 1; a++)
{
Console.WriteLine(Data[a].Magnitude.ToString());
}
...
0.0418315622955561
0.0447602132472683
0.0567904388057513
0.104590813761862
0.46718679147454
0.0550617784710375
0.025392294285886
0.0155534081359397
0.0127641875296831
0.0155534081359397
0.025392294285886
0.0550617784710375
0.46718679147454
0.104590813761862
0.0567904388057513
0.0447602132472683
That looks a little better -- it has the same symmetry property as the Excel output and there appear to be peaks in the same locations.
It almost looks like the scale is off. If I divide each element by the corresponding element from the Excel output, I get:
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
So your results are pretty much correct, just off by a scaling factor.
You're dividing everything by n in the last step of your FFT:
if (direction == Direction.Forward)
{
for (int i = 0; i < n; i++)
{
data[i].Re /= (double)n;
data[i].Im /= (double)n;
}
}
This is conventionally done for the inverse transform, not the forward transform.
In summary, changing the output from Data[a].Re to Data[a].Magnitude and changing the condition at the end of FFT from if (direction == Direction.Forward) to if (direction == Direction.Backward), I get this output:
0.669304996728897
0.716163411956293
0.908647020892022
1.67345302018979
7.47498866359264
0.880988455536601
0.406276708574176
0.248854530175035
0.20422700047493
0.248854530175035
0.406276708574176
0.880988455536601
7.47498866359264
1.67345302018979
0.908647020892022
0.716163411956293
which matches the Excel output.
I have an array that takes a 2D array as input, and flips it. For example:
The input:
0 1 0
0 2 0
0 3 4
The output:
0 3 4
0 2 0
0 1 0
Attached is the method
static double[,] flipArray(double[,] inputArray) {
for (int i = 0; i < (inputArray.Length / 2); i++) {
double temp = inputArray[i,0];
inputArray[i, 0] = inputArray[inputArray.GetLength(0)-i-1,0];
inputArray[inputArray.GetLength(0)-i-1,0] = temp;
}
return inputArray;
}
The error I receive as a result is this:
I am effectively taking the first row, and reversing the order of that, and returning the reversed-row array. Perhaps it is my misunderstanding of some basic syntax of C# as I am primarily a Java developer. Thank you!
Second Edit:
public static void flipInPlace(Object[][] theArray) {
for(int i = 0; i < (theArray.length / 2); i++) {
Object[] temp = theArray[i];
theArray[i] = theArray[theArray.length - i - 1];
theArray[theArray.length - i - 1] = temp;
}
}
The method above was adapted from the above Java method from this thread.
double[,] indicates an array, but you only need to store a single value. Make temp a simple double:
static double[,] flipArray(double[,] inputArray) {
for (int i = 0; i < (inputArray.Length / 2); i++) {
double temp = inputArray[i,0];
inputArray[inputArray.Length - i - 1,0] = temp;
}
return inputArray;
}
But you still have more issues in your code. You'll have to loop through both the rows an the columns. Plus, you'll need to use GetLength(n) instead of just Length. In the end, it should look a bit like this:
static double[,] flipArray(double[,] inputArray) {
int height = inputArray.GetLength(0);
int width = inputArray.GetLength(1);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height / 2; j++) {
double temp = inputArray[j, i];
inputArray[j, i] = inputArray[height - j - 1, i];
inputArray[height - j - 1, i] = temp;
}
}
return inputArray;
}
To get the described result, I would think you'd want something to the effect of this, grabbing each each sub-array rather than an individual element, and remembering to set the value at inputArray[i] as well as inputArray[inputArray.Length - i - 1]:
static double[,] flipArray(double[,] inputArray) {
for (int i = 0; i < (inputArray.Length / 2); i++) {
double[] temp = inputArray[i];
inputArray[i] = inputArray[inputArray.Length - i - 1];
inputArray[inputArray.Length - i - 1] = temp;
}
return inputArray;
}
I have an 8 X 8 matrix. Now, The below coordinates are occupied
{ 6, 3 }, { 5, 5 }, { 3, 3 }.... What needs to be done is that, I need to build straight line
through these points and needs to count how many coordinates they have touched?
My program so far stands as
private static void GetCount(int[,] Positions)
{
int rcount = 8;
int firstRow = Positions[0, 0];
for (int i = 1; i < Positions.Length/2; i++)
{
int currentRow = Positions[i, 0];
if (currentRow != firstRow)
{
rcount += 8;
firstRow = currentRow;
}
}
int cCount = 8;
int firstCol = Positions[0, 1];
for (int i = 1; i < Positions.Length / 2; i++)
{
int currentCol = Positions[i, 1];
if (currentCol != firstCol)
{
cCount += 8;
firstCol = currentCol;
}
}
int totalCount = rcount - cCount;
Console.WriteLine(totalCount);
}
And I am invoking it as
GetCount(new int[,] { { 6, 3 }, { 5, 5 }, { 3, 3 } });
The output will be 40 here. (count will be 24 for each 3 unique rows i.e. 6,5,3 and count will be 16 for 2 unique columns i.e. 3 and 5... So, the total count is 24+16 = 40)
But I am getting the output as 48.
Also is it possible to do the porgram using one single loop?
I am using C# 1.0
Edited
This does work
List<int> lstRows = new List<int>();
List<int> lstCols = new List<int>();
int count = 0;
//Get the unique rows and columns
for (int i = 0; i < marinePositions.Length / 2; i++)
{
if (!lstRows.Contains(marinePositions[i, 0])) lstRows.Add(Positions[i, 0]);
if (!lstCols.Contains(marinePositions[i, 1])) lstCols.Add(Positions[i, 1]);
}
//get row count
for (int i = 0; i < lstRows.Count; i++) count += 8;
//get column count
for (int i = 0; i < lstCols.Count; i++) count += 8;
Console.WriteLine(count);
But need a much better one.. if possible using linq/lambda and no loop
Please help
Here u go... but this in is LINQ and not C# 1.0 which is way too old.. not sure why are you using such old version of the language:
private static void GetCount(int[,] Positions)
{
List<int> x = new List<int>();
List<int> y = new List<int>();
for (int i = 0; i < Positions.Length/2; i++)
{
x.Add(Positions[i, 0]);
y.Add(Positions[i, 1]);
}
int result = (x.Distinct().Count() * 8) + (y.Distinct().Count() * 8);
Console.WriteLine(result);
}
No loops magic:
private static void GetCount(int[,] Positions)
{
var range = Enumerable.Range(0, Positions.Length / 2);
var result = (range.Select(i => Positions[i, 0]).Distinct().Count() * 8) +
(range.Select(i => Positions[i, 1]).Distinct().Count() * 8);
Console.WriteLine(result);
}
CORRECTIONS:
1-
int cCount = 8;
To:
int cCount = 0;
2-
int totalCount = rcount - cCount;
To:
int totalCount = rcount + cCount;
The program should work fine now.
I'm trying to convert this MATLAB function into c#
but my results are not as expected.
MATLAB:
function check=CRC8(xa);
% xa is array of bits to be transmitted (column vector)
% Generates 8-bit CRC check with g(x) = x^8 + x^2 +x + 1
xae = [xa;0;0;0;0;0;0;0;0]; % Append 8 zeros to array containing bit-stream
g8x = [1;0;0;0;0;0;1;1;1] ; % Generator polynomial
xsa=xae(1:9);
for i=1:length(xa)
if xsa(1) = = g8x(1), xsa = xor(xsa,g8x); end;
xsa(1:8)=xsa(2:9);
if i<length(xa) xsa(9)=xae(i+9); end;
end;
check = xsa(1:8); % 8 bit CRC column vector
return;
C#
public static int[] checkCRC8(int[] xa)
{
int[] g8x = { 1, 0, 0, 0, 0, 0, 1, 1, 1 };
int[] xae = new int[xa.Length + 8];
xa.CopyTo(xae, 0);
//add zeros
for (int i = xa.Length; i < xae.Length; i++)
{
xae[i] = 0;
}
int[] xsa = new int[8];
for (int i = 0; i < 8; i++)
{
xsa[i] = xae[i];
}
for (int i = 0; i < xa.Length; i++)
{
if (xsa[0] == g8x[0])
{
//xor xsa with g8x
for (int j = 0; j < xsa.Length; j++)
{
xsa[j] = xsa[j] ^ g8x[j];
}
}
//shift array elements left
for (int j = 0; j < xsa.Length - 1; j++)
{
xsa[j] = xsa[j + 1];
}
if (i < xa.Length)
{
xsa[xsa.Length - 1] = xae[i + 8];
}
}
return xsa;
}
}
The matlab ranges like in xsa = xae(1:9) are inclusive, so xsa should have nine elements instead of eight. Also, since your i is already zero based, I think the last if should compare against xa.Length-1 and use the array element at i+9 instead of i+8:
if (i < xa.Length - 1)
{
xsa[xsa.Length - 1] = xae[i + 9];
}