Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm doing a project using key stimulation and I'm using two ways to display a key character on the screen. First I use Clipboard but using Clipboard sometimes is inconvenient so I try to use SendInput() to display the key character when user press any button on the keyboard. I follow the code tutorial but I didn't know how does the SendInput() function work ( I mean when I invoke SendInput() what will it work step by step?). Does anyone have experience about my case? Please explain clearly for me.
Thanks all!
private void SendUnicode(string _text)
{
if (IntPtr.Size == 4)
{
ViKey.INPUT[] input = new ViKey.INPUT[_text.Length * 2];
for (int i = 0; i < _text.Length; i++)
{
input[i * 2].type = 1;
input[i * 2].ki.wVk = 0;
input[i * 2].ki.wScan = (short)_text[i];
input[i * 2].ki.dwFlags = 4;
input[i * 2 + 1] = input[i * 2];
input[i * 2 + 1].ki.dwFlags = 6;
}
ViKey.SendInput((uint)input.Length, input, Marshal.SizeOf(input[0]));
return;
}
else
{
ViKey.INPUT64[] inputx64 = new ViKey.INPUT64[_text.Length * 2];
for (int i = 0; i < _text.Length; i++)
{
inputx64[i * 2].type = 1;
inputx64[i * 2].ki.wVk = 0;
inputx64[i * 2].ki.wScan = (short)_text[i];
inputx64[i * 2].ki.dwFlags = 4;
inputx64[i * 2 + 1] = inputx64[i * 2];
inputx64[i * 2 + 1].ki.dwFlags = 6;
}
ViKey.SendInput((uint)inputx64.Length, inputx64, Marshal.SizeOf(inputx64[0]));
}
}
All relevant information can be found in the documentation about the function.
The function returns the number of events that it successfully
inserted into the keyboard or mouse input stream. If the function
returns zero, the input was already blocked by another thread.
So how it works is that it inserts the events in the INPUT structures (which are fed to the function through the parameters) serially into the keyboard or mouse input stream and then returns the number of those events that are successfully inserted..
Related
I am trying to build a custom machine learning library in C# , I have researched fairly about the topic. My first example (XOR estimator) was a success, I was able to lower the average loss to almost cero. Then I tried to build a model to classify handwritten digits (using MNIST text database).The problem is ,no matter how I configure the model, I always get stuck on a certain average loss over the data set.Second problem, because the MNIST dataset is very large, the model takes a lot of time to compute, maybe I can use some advice on how to carry on the slowest parts of the algorithm (I am using stochastic gradient descent).I am going to show the main method that performs most of the work.
I have tried using MSE and CrossEntropy loss functions, also tanh , sigmoid , reLu and softPlus activation functions. The model I am trying to build is a 4 layer one. First layer, 784 input neurons ; Second , 16 neurons,sigmoid ; Third , 16 neurons , sigmoid and Output layer, 10 neurons (one hot encoded digits) with sigmoid. I am aware that the code below may not be a minimal reproducible example, but it represents the algorithm I am trying to figure. I have also uploaded the solution to GitHub, maybe somebody can give me a hand figuring the problem. This is the link https://github.com/juan-carvajal/MachineLearningFramework
Running the Main method of the app will first, execute the XOR classifier, that runs good. Then the MNIST classifier.
The model is best represented here:
DataSet dataSet = new DataSet("mnist2.txt", ' ', 10, false);
//This creates a model with batching=128 , learningRate=0.5 and
//CrossEntropy loss function
var p = new Perceptron(128, 0.5, ErrorFunction.CrossEntropy())
.Layer(784, ActivationFunction.Sigmoid())
.Layer(16, ActivationFunction.Sigmoid())
.Layer(16, ActivationFunction.Sigmoid())
.Layer(10, ActivationFunction.Sigmoid());
//1000 is the number of epochs
p.Train2(dataSet, 1000);
Actual Algorithm (stochastic gradiente descent):
Console.WriteLine("Initial Loss:"+ CalculateMeanErrorOverDataSet(dataSet));
for (int i = 0; i < epochs; i++)
{
//Shuffle the data in every step
dataSet.Shuffle();
List<DataRow> batch = dataSet.NextBatch(this.Batching);
//Gets random batch from the dataSet
int count = 0;
foreach (DataRow example in batch)
{
count++;
double[] result = this.FeedForward(example.GetFeatures());
double[] labels = example.GetLabels();
if (result.Length != labels.Length)
{
throw new Exception("Inconsistent array size, Incorrect implementation.");
}
else
{
//What follows is the calculation of the gradient for this example, every example affects the current gradient, then all those changes are averaged an every parameter is updated.
double error = CalculateExampleLost(example);
for (int l = this.Layers.Count - 1; l > 0; l--)
{
if (l == this.Layers.Count - 1)
{
for (int j = 0; j < this.Layers[l].CostDerivatives.Length; j++)
{
this.Layers[l].CostDerivatives[j] = ErrorFunction.GetDerivativeValue(labels[j], this.Layers[l].Activations[j]);
}
}
else
{
for (int j = 0; j < this.Layers[l].CostDerivatives.Length; j++)
{
double acum = 0;
for (int j2 = 0; j2 < Layers[l + 1].Size; j2++)
{
acum += Layers[l + 1].WeightMatrix[j2, j] * this.Layers[l+1].ActivationFunction.GetDerivativeValue(Layers[l + 1].WeightedSum[j2]) * Layers[l + 1].CostDerivatives[j2];
}
this.Layers[l].CostDerivatives[j] = acum;
}
}
for (int j = 0; j < this.Layers[l].Activations.Length; j++)
{
this.Layers[l].BiasVectorChangeRecord[j] += this.Layers[l].ActivationFunction.GetDerivativeValue(Layers[l].WeightedSum[j]) * Layers[l].CostDerivatives[j];
for (int k = 0; k < Layers[l].WeightMatrix.GetLength(1); k++)
{
this.Layers[l].WeightMatrixChangeRecord[j, k] += Layers[l - 1].Activations[k]
* this.Layers[l].ActivationFunction.GetDerivativeValue(Layers[l].WeightedSum[j])
* Layers[l].CostDerivatives[j];
}
}
}
}
}
TakeGradientDescentStep(batch.Count);
if ((i + 1) % (epochs / 10) == 0)
{
Console.WriteLine("Epoch " + (i + 1) + ", Avg.Loss:" + CalculateMeanErrorOverDataSet(dataSet));
}
}
This is an example of what the local minima looks like in the current model.
In my research I found out that similar models may archieve accuracy up to 90%. My model barely got 10%.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Does anyone have any idea why does this piece of C# code return x = 0 and y = 0 (ocassionally) :
public void NewPos()
{
int x = 0;
int y = 0;
while (lstPosition.Where(z => z.Position.X == x && z.Position.Y == y).Count() != 0) {
x = new Random().Next(4, 20) * 10;
y = new Random().Next(4, 20) * 10;
}
NewPos.X = x;
NewPos.Y = y;
Console.WriteLine(x + " - " + y );
}
You're not ever getting inside the while loop, although we can't tell what lstPosition is set to with the code you've provided. The where clause must be returning an empty set.
There's no way Random.Next(int, int) is returning zero in this situation.
Presumbably, you want to initalize x and y to a non-zero value.
You, probably, want something like this:
// Do not recreate random
// (otherwise you're going to have a badly skewed values);
// static instance is the simplest but not thread safe solution
private static Random s_Generator = new Random();
public void NewPos() {
// Just Any, not Where + Count
if (lstPosition.Any(z => z.Position.X == x && z.Position.Y == y)) {
// If we have such a point, resample it
NewPos.X = s_Generator.Next(4, 20) * 10;
NewPos.Y = s_Generator.Next(4, 20) * 10;
// Debug purpose only
Console.WriteLine(x + " - " + y );
}
}
I am attempting to use Lomont FFT in order to return complex numbers to build a spectrogram / spectral density chart using c#.
I am having trouble understanding how to return values from the class.
Here is the code I have put together thus far which appears to be working.
int read = 0;
Double[] data;
byte[] buffer = new byte[1024];
FileStream wave = new FileStream(args[0], FileMode.Open, FileAccess.Read);
read = wave.Read(buffer, 0, 44);
read = wave.Read(buffer, 0, 1024);
data = new Double[read];
for (int i = 0; i < read; i+=2)
{
data[i] = BitConverter.ToInt16(buffer, i) / 32768.0;
Console.WriteLine(data[i]);
}
LomontFFT LFFT = new LomontFFT();
LFFT.FFT(data, true);
What I am not clear on is, how to return/access the values from Lomont FFT implementation back into my application (console)?
Being pretty new to c# development, I'm thinking I am perhaps missing a fundamental aspect of understanding regarding how to retrieve processed values from the instance of the Lomont Class, or perhaps even calling it incorrectly.
Console.WriteLine(LFFT.A); // Returns 0
Console.WriteLine(LFFT.B); // Returns 1
I have been searching for a code snippet or explanation of how to do this, but so far have come up with nothing that I understand or explains this particular aspect of the issue I am facing. Any guidance would be greatly appreciated.
A subset of the results held in data array noted in the code above can be found below and based on my current understanding, appear to be valid:
0.00531005859375
0.0238037109375
0.041473388671875
0.0576171875
0.07183837890625
0.083465576171875
0.092193603515625
0.097625732421875
0.099639892578125
0.098114013671875
0.0931396484375
0.0848388671875
0.07354736328125
0.05963134765625
0.043609619140625
0.026031494140625
0.007476806640625
-0.011260986328125
-0.0296630859375
-0.047027587890625
-0.062713623046875
-0.076141357421875
-0.086883544921875
-0.09454345703125
-0.098785400390625
-0.0994873046875
-0.0966796875
-0.090362548828125
-0.080810546875
-0.06842041015625
-0.05352783203125
-0.036712646484375
-0.0185546875
What am I actually attempting to do? (perspective)
I am looking to load a wave file into a console application and return a spectrogram/spectral density chart/image as a jpg/png for further processing.
The wave files I am reading are mono in format
UPDATE 1
I Receive slightly different results depending on which FFT is used.
Using RealFFT
for (int i = 0; i < read; i+=2)
{
data[i] = BitConverter.ToInt16(buffer, i) / 32768.0;
//Console.WriteLine(data[i]);
}
LomontFFT LFFT = new LomontFFT();
LFFT.RealFFT(data, true);
for (int i = 0; i < buffer.Length / 2; i++)
{
System.Console.WriteLine("{0}",
Math.Sqrt(data[2 * i] * data[2 * i] + data[2 * i + 1] * data[2 * i + 1]));
}
Partial Result of RealFFT
0.314566983321381
0.625242818210924
0.30314888696868
0.118468857708093
0.0587697011760449
0.0369034115568654
0.0265842582236275
0.0207195964060356
0.0169601273233317
0.0143745438577886
0.012528799609089
0.0111831275153128
0.0102313284519146
0.00960198279358434
0.00920236001619566
Using FFT
for (int i = 0; i < read; i+=2)
{
data[i] = BitConverter.ToInt16(buffer, i) / 32768.0;
//Console.WriteLine(data[i]);
}
double[] bufferB = new double[2 * data.Length];
for (int i = 0; i < data.Length; i++)
{
bufferB[2 * i] = data[i];
bufferB[2 * i + 1] = 0;
}
LomontFFT LFFT = new LomontFFT();
LFFT.FFT(bufferB, true);
for (int i = 0; i < bufferB.Length / 2; i++)
{
System.Console.WriteLine("{0}",
Math.Sqrt(bufferB[2 * i] * bufferB[2 * i] + bufferB[2 * i + 1] * bufferB[2 * i + 1]));
}
Partial Result of FFT:
0.31456698332138
0.625242818210923
0.303148886968679
0.118468857708092
0.0587697011760447
0.0369034115568653
0.0265842582236274
0.0207195964060355
0.0169601273233317
0.0143745438577886
0.012528799609089
0.0111831275153127
0.0102313284519146
0.00960198279358439
0.00920236001619564
Looking at the LomontFFT.FFT documentation:
Compute the forward or inverse Fourier Transform of data, with
data containing complex valued data as alternating real and
imaginary parts. The length must be a power of 2. The data is
modified in place.
This tells us a few things. First the function is expecting complex-valued data whereas your data is real. A quick fix for this is to create another buffer of twice the size and setting all the imaginary parts to 0:
double[] buffer = new double[2*data.Length];
for (int i=0; i<data.Length; i++)
{
buffer[2*i] = data[i];
buffer[2*i+1] = 0;
}
The documentation also tells us that the computation is done in place. That means that after the call to FFT returns, the input array is replaced with the computed result. You could thus print the spectrum with:
LomontFFT LFFT = new LomontFFT();
LFFT.FFT(buffer, true);
for (int i = 0; i < buffer.Length/2; i++)
{
System.Console.WriteLine("{0}",
Math.Sqrt(buffer[2*i]*buffer[2*i]+buffer[2*i+1]*buffer[2*i+1]));
}
Note since your input data is real valued you could also use LomontFFT.RealFFT. In that case, given a slightly different packing rule, you would obtain the FFT results using:
LomontFFT LFFT = new LomontFFT();
LFFT.RealFFT(data, true);
System.Console.WriteLine("{0}", Math.Abs(data[0]);
for (int i = 1; i < data.Length/2; i++)
{
System.Console.WriteLine("{0}",
Math.Sqrt(data[2*i]*data[2*i]+data[2*i+1]*data[2*i+1]));
}
System.Console.WriteLine("{0}", Math.Abs(data[1]);
This would give you the non-redundant lower half of the spectrum (Unlike LomontFFT.FFT which provides the entire spectrum). Also, numerical differences on the order of double precision (around 1e-16 times the spectrum peak value) with respect to LomontFFT.FFT can be expected.
This question already has answers here:
C# Creating an array of arrays
(5 answers)
Closed 7 years ago.
I came across this strange IndexOutOfRangeException exception. The code I am working with was originally a C code, I have managed to translate it to C#
So I the followin loop gives me the error:
for (int i = 0; i < 6; i++)
{
L[0] = new double[]{ T[0] + rxp[0][i] - (p[0][i])
}
According to the 'Locals' tab, rxp has only 3 'children' with only 1 items / child.
So I guess the problem is here:
void getrxp()
{
for (int i = 0; i < 6; i++)
{
rxp[0] = new double[]{ M[0][0] * (re[0][i]) + M[0][1] * (re[1][i]) + M[0][2] * 0};
rxp[1] = new double[]{ M[1][0] * (re[0][i]) + M[1][1] * (re[1][i]) + M[1][2] * 0};
rxp[2] = new double[]{ M[2][0] * (re[0][i]) + M[2][1] * (re[1][i]) + M[2][2] * 0};
}
}
Am I getting this to to create a double rxp[3][6]; array wrong or there is something else?
The original code looks like this (C):
void getrxp()
{
for(int i=0;i<6;i++){
rxp[0][i] = M[0][0]*(re[0][i])+M[0][1]*(re[1][i])+M[0][2]*0;
rxp[1][i] = M[1][0]*(re[0][i])+M[1][1]*(re[1][i])+M[1][2]*0;
rxp[2][i] = M[2][0]*(re[0][i])+M[2][1]*(re[1][i])+M[2][2]*0;
}
}
If you are trying to create a 2-dimensional array, the syntax should be double [,] rxp = new double[3,6];. Here's the detailed documentation of Multidimensional Arrays at MSDN.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
i have a problem with arrays or something missed in these text..
my program works every 500ms and i want to read first 4 double values and take average of these values and then get next 4 double values and so on... i write something about this and can you pls look on this??
if (u_dcbus_pv_act[i] > 0 && i != 0)
{
u_dcbus_pv = u_dcbus_pv_act[i];
p_dcbus_pv = p_dcbus_pv_act[i];
}
if (i >= 3)
{
for (int j = 0; j < 4; j++)
{
total_u += u_dcbus_pv;
total_p += p_dcbus_pv;
}
average_u = total_u / 4;
average_p = total_p / 4;
u_dcbus_target = average_u;
p_dcbus_pv_avg = average_p;
}
from what I understand of your description, I would do it something like this:
/* add current samples to totals */
total_u += u_dcbus_pv_act[i];
total_p += p_dcbus_pv_act[i];
/* every fourth tick, calc average and reset totals */
if (i % 4 == 0)
{
average_u = total_u / 4;
average_p = total_p / 4;
total_u = 0;
total_p = 0;
}
u_dcbus_target = average_u;
p_dcbus_pv_avg = average_p;
i++;