i've made a function for FFT using AForge. It seems to work but when i'm checking with my supervisor he says the output is not correct. He is using the PWelch function from MatLab. We've already found out we were using different windows but changing them didn't make a significant difference. So again, the function does work but according to my supervisor the output is incorrect. Please Help!
This is my Function, i hope anyone sees something that's wrong because i've been looking at it for allmost two weeks now. The DATA that goes into it is already made equidistant.
private void FastFoulierMethod()
{
int NFFT = 64;
int N_OVERLAP = 32;
int numberOfEpochs = samples.Count / NFFT;
int numberOfSamplesToSelectFromFFT = NFFT-1;
double[] dataaa = new double[samples.Count];
for (int i = 0; i < samples.Count - 1; i++)
{
dataaa[i] = samples[i].GetValue();//lijst met doubles die we gebruiken
}
double[,] pFrame = new double[numberOfEpochs, numberOfSamplesToSelectFromFFT];
// The first epoch in the page starts at index 0
int beginIndexOfEpoch = 0;
for (int i = 0; i < numberOfEpochs; i++)
{
// This will get the current epoch by retrieving samples from the sample list
// starting at 'beginIndex' with length 'NFFT'. This epoch will need to be detrended next.
List<double> smapletemp = new List<double>();
for (int x = beginIndexOfEpoch; x < beginIndexOfEpoch+NFFT; x++)
{
smapletemp.Add(dataaa[x]);
}
double[] epoch = smapletemp.ToArray();
if (epoch.Length == 0)
{
break;
}
// Create array of X-axis values 1,2,3,4 ... n
// which will be used to perform linear regression.
double[] xValues = new double[epoch.Length];
for (int j = 0; j < xValues.Length; j++)
{
xValues[j] = j;
}
// Perform linear regression on the epoch. This will result in some data that is used later.
Dictionary<String, double> linearRegressionData = math.performLinearRegression(xValues.ToList(), epoch.ToList());
// Detrend the epoch
for (int j = 0; j < epoch.Length; j++)
{
double intercept = linearRegressionData["Alpha"]; // Get the intercept from the data.
double slope = linearRegressionData["Beta"]; // Get the slope from the data.
//if (1 >= math.StdDev(epoch))
//{
epoch[j] = epoch[j] - intercept - (slope * j); // Detrend the epoch by subtracting the intercept and the slope * j.
//}
}
// Create Complex from the epoch for windowing and FFT processing.
Complex[] cmplx = new Complex[epoch.Length];
for (int j = 0; j < cmplx.Length; j++)
{
cmplx[j] = new Complex(epoch[j], 0);
}
// Perform Hann window function on the Complex.
math.hann(cmplx);
// Perform Fast Fourier Transform on the Complex.
FourierTransform.FFT(cmplx, FourierTransform.Direction.Backward);
// Create an array for all powers.
double[] powers = new double[cmplx.Length];
for (int j = 0; j < epoch.Length; j++)
{
powers[j] = cmplx[j].SquaredMagnitude;
}
// Add the powers to the power frame.
for (int j = 0; j < powers.Length-1; j++)
{
pFrame[i, j] = powers[j];
}
// Shift index for the next epoch.
beginIndexOfEpoch += NFFT - N_OVERLAP;
if ( beginIndexOfEpoch + NFFT > samples.Count)
{
break;
}
}
// Create an array for the nan-mean values of all epochs.
// Nan-mean calculates the mean of a set of doubles, ignoring NaN's.
double[] nanMeanValues = new double[numberOfSamplesToSelectFromFFT];
List<double[]> Y = new List<double[]>();
for (int i = 0; i < numberOfSamplesToSelectFromFFT; i++)
{
// The sum for calculating the mean.
double sum = 0.0;
// The number of elements (doubles) for calculating the mean.
int count = 0;
// For all epochs...
for (int j = 0; j < numberOfEpochs; j++)
{
// ...the mean for all doubles at index 'i' is calculated.
double sample = pFrame[j, i];
if (!Double.IsNaN(sample))
{
// Only take the double into account when it isn't a NaN.
sum += sample;
count++;
}
}
// Actually calculate the mean and add it to the array.
nanMeanValues[i] = sum / count;
}
// We now have the mean of all power arrays (or epochs).
// Create an array with Root Mean Square values.
double[] squareRootedNanMeans = new double[nanMeanValues.Length];
for (int i = 0; i < squareRootedNanMeans.Length; i++)
{
squareRootedNanMeans[i] = Math.Sqrt(nanMeanValues[i]);
}
Y.Add(squareRootedNanMeans);
It's been ages since I studied FFT's but, unless you academic assignment is to produce an fft function, I advise you to use some library. It is great to program your own stuff to learn, but if you need results, go for the sure thing.
You can use Alglib {http://www.alglib.net/fasttransforms/fft.php}, which has a free version.
Hope this helps.
Related
The network produces 1 x N x K tensor, where N is number of pixel positions and K is number of classes, each value represents score for a class at given position.
Current code to retrieve best class affinity for each position is working, but it is terribly slow and takes x4 more time, than the network run itself.
private int[,] GetClasses(List<DisposableNamedOnnxValue> output)
{
Tensor<float> outTensor = output.First().AsTensor<float>();
int[,] classes = new int[frameWidth,frameHeight];
for (int i = 0; i < frameWidth; ++i)
{
for (int j = 0; j < frameHeight; ++j)
{
int finalClass = 0;
float finalClassScore = 0;
for (int k = 0; k < nClasses; ++k)
{
float score = outTensor[0, i * frameHeight + j, k];
if (score > finalClassScore)
{
finalClassScore = score;
finalClass = k;
}
}
classes[i, j] = finalClass;
}
}
return classes;
}
Is there a better, faster way of doing this in Microsoft.ML ?
The solution I went with was to add argmax layer to the initial keras model. Keras output single value through argmax.
I've made a neural network in C# from scratch.
The problem is that when I try to train it for an XOR logic gate, it always converges to 0.5, instead of alternating between 0 and 1.
The neural network is made to work with a custumizable number of layers and nodes.
I've been over the theory countless of times, but I have no idea where the problem could be. I have excluded the bias in the backpropagation.
The backpropagation algorithm:
Neuralnetwork is constructed as follows:
nn.layerlist[x] = specific layer
nn.layerlist[x].network[y] = specific node
nn.layerlist[x].network[y].weight[z] = specific weight leading towards that node
public static NeuralNetwork Calculate(NeuralNetwork nn, List<double> Target, double LearningRate)
{
var OutputLayer = nn.LayerList.Count - 1;
var node = nn.LayerList[OutputLayer].Network[0];
List<List<double>> WeightList = new List<List<double>>();
List<double> Weights = new List<double>();
//Weightlist initialiseren
for (int i = 0; i < node.Weights.Count; i++)
Weights.Add(0);
// Door de laatste layer eerst gaan
for (int i = 0; i < Target.Count(); i++)
{
for (int j = 0; j < node.Weights.Count; j++)
{
var weight = nn.LayerList[OutputLayer].Network[i].Weights[j];
var outputcurrent = nn.LayerList[OutputLayer].Network[i].Value;
var OutputPrevious = nn.LayerList[OutputLayer - 1].Network[j].Value;
var Cost = (outputcurrent - Target[i]) * (outputcurrent * (1 - outputcurrent));
Weights[j] += Cost * weight;
weight = weight - (Cost * OutputPrevious * LearningRate);
nn.LayerList[OutputLayer].Network[i].Weights[j] = weight;
}
}
WeightList.Add(Weights);
int layercount = nn.LayerList.Count - 1;
//alle layers in reverse bijlangs gaan
for (int i = layercount; i > 0; i--)
{
var WeightsHidden = new List<double>();
for(int k = 0; k < 1000; k++) //TODO: Change this to something dynamic!
WeightsHidden.Add(0);
for (int j = 0; j < nn.LayerList[i].Network.Count; j++)
{
for (int k = 0; k < nn.LayerList[i].Network[j].Weights.Count; k++)
{
var weight = nn.LayerList[i].Network[j].Weights[k];
var outputcurrent = nn.LayerList[i].Network[j].Value;
var OutputPrevious = nn.LayerList[i - 1].Network[k].Value;
Console.WriteLine("Total Weights: {0}", WeightList[WeightList.Count - 1][k]);
var Cost = (outputcurrent * (1 - outputcurrent)) * WeightList[WeightList.Count - 1][k];
WeightsHidden[k] += Cost * weight;
weight = weight - (Cost * OutputPrevious * LearningRate);
nn.LayerList[i].Network[j].Weights[k] = weight;
}
}
WeightList.Add(WeightsHidden);
}
return nn;
}
}
The code is quite complex, but I have no idea how to format it in any other way.
I would like to neural network to put out the desired result like an XOR gate.
I've run into a stall trying to put together some code to average out 10x10 subarrays of a 2D multidimensional array.
Given a multidimensional array
var myArray = new byte[100, 100];
How should I go about creating 100 subarrays of 100 bytes (10x10) each.
Here are some examples of the value indexes the subarrays from the multidimensional would contain.
[x1,y1,x2,y2]
Subarray1[0,0][9,9]
Subarray2[10,10][19,19]
Subarray3[20,20][29,29]
Given these subarrays, I would then need to average the subarray values to create a byte[10,10] from the original byte[100,100].
I realize this is not unbelievably difficult, but after spending 4 days debugging very low-level code and now getting stuck on this would appreciate some fresh eyes.
Use this as a reference. I used ints just for ease of use. Code is untested. but the idea is there.
var rowSize = 100;
var colSize = 100;
var arr = new int[rowSize, colSize];
var r = new Random();
for (int i = 0; i < rowSize; i++)
for (int j = 0; j < colSize; j++)
arr[i, j] = r.Next(20);
for (var subcol = 0; subcol < colSize / 10; subcol++)
{
for (var subrow = 0; subrow < colSize/10; subrow++)
{
var startX = subcol*10;
var startY = subrow*10;
var avg = 0;
for (var x=0; x<10; x++)
for (var y = 0; y < 10; y++)
avg += arr[startX + x, startY + y];
avg /= 10*10;
Console.WriteLine(avg);
}
}
It looks like you're new to SO. Next time try to post your attempt at the problem; it's better to fix your code.
The only challenge is figuring out the function, that given the subarray index we're trying to populate, would give you the correct row and column indexes in your original 100x100 array; the rest would just be a matter of copying the values:
// psuedocode
// given a subarrayIndex of 0 to 99, these will calculate the correct indices
rowIndexIn100x100Array = (subarrayIndex / 10) * 10 + subArrayRowIndexToPopulate;
colIndexIn100x100Array = (subarrayIndex % 10) * 10 + subArrayColIndexToPopulate;
I'll leave it as an exercise to you to deduce why the above functions correctly calculate the indices.
With the above, we can easily map the values:
var subArrays = new List<byte[,]>();
for (int subarrayIndex = 0; subarrayIndex < 100; subarrayIndex++)
{
var subarray = new byte[10, 10];
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
{
int rowIndexIn100x100Array = (subarrayIndex / 10) * 10 + i;
int colIndexIn100x100Array = (subarrayIndex % 10) * 10 + j;
subarray[i, j] = originalArray[rowIndexIn100x100Array, colIndexIn100x100Array];
}
subArrays.Add(subarray);
}
Once we have the 10x10 arrays, calculating the average would be trivial using LINQ:
var averages = new byte[10, 10];
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
{
averages[i, j] = (byte)subArrays[(i * 10) + j].Cast<byte>().Average(b => b);
}
Fiddle.
I have a function that works for vector inputs but I need to run this on a cube. My impulse is I need to slice a vector out of the cube and then run it over a double for loop.
This is the pseudo code:
public static double[,,] cubefunction(double[,,] input)
{
int N = input.GetLength(0);
var outputvector = new double[N,N,N];
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
outputvector[1:N,i,j] = vectorfunction(input[1:N,i,j]);
}
}
return outputvector;
}
Obviously, 1:N is matlab notation to grab the entire row. Is there an equivalent in C#? Or how would I go about this without triple looping?
In a great many places in the software I write, there are three-dimensioned arrays of short or float, usually with several million elements. The data is best understood conceptually as a three-dimensioned array, since it describes values at regular locations in space.
I saw a mention elsewhere here that the .NET CLR is not terribly "performant" when it comes to traversing those arrays, for example, when computing new values and populating a second, equally sized and dimensioned array. If this is true, why is that so?
For reasons of readability I've not settled on the idea of using jagged arrays, yet, but if that's really the answer then I'm willing, but:
To get around this it's been proposed to me that I format the data as a single dimensioned array. For example, if my array has dimensions with magnitudes m, n, and o, then I would create a float[m*n*o] instead of a float[m,n,o], and write my own indexer to get to the correct array locations during traversal.
The specific use case is in parallelizing the traversal, such as:
Parallel.For(0,m)((x) => for(y=0,y<n,y++) { for(z=0,z<o,z++) doSomething(array(x,y,z)); });
Where in the single-indexed case there would be a Parallel.ForEach(myArray, (position) => doSomething(array(Position))) kind of thing going on instead of the nested for loops.
So, the question is, really, would that be any faster than relying on the CLR array indexing that's built in?
EDIT: I've supplied my own answer below, based on some timing tests. The code is included.
One huge thing to consider is the order of traversal. Memory caching is an important part of modern processor performance and cache misses can be (relatively) expensive. If you index the array across a 'long' dimension that results in crossing cache boundaries, you may cause frequent misses as part of indexing. As such, the order in which you index is important. This often means you want to take care in how you choose to order your indices.
Also, when copying, consider that multiple indexing requires computing the 'true' index to the underlying memory block using multiplication/addition. If you're just copying all elements, though, you could simply increment a single index and access each element without additional computation required.
There are also various condition checks that occur when accessing arrays by index (making the IndexOutOfRangeException possible), which requires more checks when you access via multiple indices. I believe (though I'm not entirely sure) that the jitter can sometimes optimize single dimensional array access using a simple loop by checking the range only once, rather than on every indexing operation.
I ran some timings and found that overall performance is that it makes little or no difference:
I used this code below. The timings I got were basically identical in each case:
public partial class Form1 : Form
{
int ArrayDim1 = 50;
int ArrayDim23 = 500;
int ParallelSplit = 50;
int DoSomethingSize = 100;
Double sqRoot = 0;
Single[, ,] multidim = null;
Single[] singleDim = null;
Single[][][] jagged = null;
ParallelOptions po = new ParallelOptions() { MaxDegreeOfParallelism = 36 };
public Form1()
{
InitializeComponent();
multidim = new Single[ArrayDim1, ArrayDim23, ArrayDim23];
for (int x = 0; x < ArrayDim1; x++)
for (int y = 0; y < ArrayDim23; y++)
for (int z = 0; z < ArrayDim23; z++)
multidim[x, y, z] = 1;
singleDim = new Single[ArrayDim1 * ArrayDim23 * ArrayDim23];
for (int i = 0; i < singleDim.Length; i++)
singleDim[i] = 1;
jagged = new Single[ArrayDim1][][];
for (int i = 0; i < ArrayDim1; i++)
{
jagged[i] = new Single[ArrayDim23][];
for (int j = 0; j < ArrayDim23; j++)
{
jagged[i][j] = new Single[ArrayDim23];
}
}
}
private void btnGO_Click(object sender, EventArgs e)
{
int loopcount = 1;
DateTime startTime = DateTime.Now;
for (int i = 0; i < loopcount; i++)
{
TestMultiDimArray(multidim);
}
textBox1.Text = DateTime.Now.Subtract(startTime).TotalMilliseconds.ToString("#,###");
startTime = DateTime.Now;
for (int i = 0; i < loopcount; i++)
{
TestSingleArrayClean(singleDim);
}
textBox2.Text = DateTime.Now.Subtract(startTime).TotalMilliseconds.ToString("#,###");
startTime = DateTime.Now;
for (int i = 0; i < loopcount; i++)
{
TestJaggedArray(jagged);
}
textBox3.Text = DateTime.Now.Subtract(startTime).TotalMilliseconds.ToString("#,###");
}
public void TestJaggedArray(Single[][][] multi)
{
Parallel.For(0, ArrayDim1, po, x =>
{
for (int y = 0; y < ArrayDim23; y++)
{
for (int z = 0; z < ArrayDim23; z++)
{
DoComplex();
multi[x][y][z] = Convert.ToSingle(Math.Sqrt(123412341));
}
}
});
}
public void TestMultiDimArray(Single[, ,] multi)
{
Parallel.For(0, ArrayDim1, po, x =>
{
for (int y = 0; y < ArrayDim23; y++)
{
for (int z = 0; z < ArrayDim23; z++)
{
DoComplex();
multi[x, y, z] = Convert.ToSingle(Math.Sqrt(123412341));
}
}
});
}
public void TestSingleArrayClean(Single[] single)
{
Parallel.For(0, single.Length, po, y =>
{
//System.Diagnostics.Debug.Print(y.ToString());
DoComplex();
single[y] = Convert.ToSingle(Math.Sqrt(123412341));
});
}
public void DoComplex()
{
for (int i = 0; i < DoSomethingSize; i++)
{
sqRoot = Math.Log(101.101);
}
}
}