Hi I was wondering how I could unit test the methods below:
public float calcNP()
{
int rowcount = dataGridView1.Rows.Count;
int[] colB = new int[rowcount];
float[] NP = new float[rowcount];
float avgNP = 0;
for (int i = 0; i < rowcount; i++)
{
colB[i] = Convert.ToInt32(dataGridView1.Rows[i].Cells[5].Value);
}
float min = colB.Min();
float max = colB.Max();
float a = 1, b = 10;
for (int i = 0; i < rowcount; i++)
{
NP[i] = (a + (colB[i] - min) * (b - a)) / (max - min);
avgNP = NP[i] + avgNP;
}
avgNP = (avgNP / rowcount) * 100;
return avgNP;
}
and also the following
public float calcIFact()
{
float ftp = calcFTP();
float NP = calcNP();
float IntFact = NP / ftp;
return IntFact;
}
and this
public float calcFTP()
{
float ftp = 0;
if (chkFTP.Checked == true)
{
// ftp =(float)Convert.ToDouble(txtFTP.Text)/100;
ftp = (float)Convert.ToDouble(txtFTP.Text);
}
if (chkFTP.Checked == false)
{
int rowcount = dataGridView1.Rows.Count;
int[] colB = new int[rowcount];
for (int i = 0; i < rowcount; i++)
{
colB[i] = Convert.ToInt32(dataGridView1.Rows[i].Cells[5].Value);
}
// ftp = colB.Max() / 100;
ftp = colB.Max();
}
If someone could give me some examples that would be great.
Basically just need some simple tests for the calculations
We are telling you to do this:
// New method, not depending on a gridview. Testable.
public float calcNP_pure(int[] colB)
{
float[] NP = new float[colB.Length];
float avgNP = 0;
float min = colB.Min();
float max = colB.Max();
float a = 1, b = 10;
for (int i = 0; i < rowcount; i++)
{
NP[i] = (a + (colB[i] - min) * (b - a)) / (max - min);
avgNP = NP[i] + avgNP;
}
avgNP = (avgNP / rowcount) * 100;
return avgNP;
}
// Not testable
public float calcNP()
{
int rowcount = dataGridView1.Rows.Count;
int[] colB = new int[rowcount];
for (int i = 0; i < rowcount; i++)
{
colB[i] = Convert.ToInt32(dataGridView1.Rows[i].Cells[5].Value);
}
return calcNP_pure(colB);
}
This new method should also go into a new class and not sit on a form or some other UI-element. The best practice is to program against interfaces and to inject required dependencies into the objects:
public interface INpCalculator
{
float CalcNP(int[] values);
}
public class NpCalculator : INpCalculator
{
public float CalcNP(int[] values)
{
...
return ...;
}
}
public partial class Form1 : Form
{
private INpCalculator _npCalculator;
public Form1(INpCalculator npCalculator)
{
InitializeComponent();
_npCalculator = npCalculator;
}
private float CalcNP()
{
int[] colB = dataGridView1.Rows
.Cast<DataGridViewRow>()
.Select(row => row.Cells[5].Value)
.ToArray();
return _npCalculator.CalcNP(colB);
}
}
Now the calculator is testable without the need to open any form:
[TestMethod]
public void TestNpCalculator()
{
// Arrange
var sut = new NpCalculator();
var values = new int[] { 12, 7, 15, 3 };
// Act
float result = sut.CalcNP(values);
// Assert
Assert.AreEqual(123.456f, result);
}
Btw: sut stands for "system under test".
In current state of the method, your unit tests are going to require manually create datagrid object and populate values as per your testing scenario. As suggested by Daniel, your method "public float calcNP()" should not use data grid, instead of that you can pass an array of integers to the method (pass only values which you are going to use in calculation)
Related
I'm want to implement the k-means clustering algorithm to clusterize a list of text files loaded from disk, and also using the silhouette method to determine the number of clusters.
The error I'm getting is System.ArgumentOutOfRangeException: 'Schema mismatch for input column 'Features': expected scalar or vector of String, got VarVector<Single> (Parameter 'inputSchema')'
How can I solve the problem?
Code
static void Main(string[] args)
{
// Load text files from disk
string[] filePaths = Directory.GetFiles("C:\\ExportedEmails\\", "*.txt");
string[] textFiles = filePaths.Select(File.ReadAllText).ToArray();
// Extract features from text files
var textData = textFiles.Select((text, index) =>
{
int startIndex = text.IndexOf("Description: ") + "Description: ".Length;
string description = text.Substring(startIndex);
return new TextData { Text = description, Index = index };
}).ToArray();
// Initialize the MLContext
var context = new MLContext();
// Convert data to IDataView
var data = context.Data.LoadFromEnumerable(textData);
// Initialize the variables to store the silhouette scores
var silhouetteScores = new double[10];
// Iter
for (int k = 2; k <= 10; k++)
{
// Create a new KMeansTrainer
var pipeline = context.Transforms.Text.FeaturizeText("Text", "Features")
.Append(context.Clustering.Trainers.KMeans(featureColumnName: "Features", numberOfClusters: k));
var model = pipeline.Fit(data);
var transformedData = model.Transform(data);
// Compute the silhouette score
var clusterAssignments = transformedData.GetColumn<uint>("PredictedLabel").ToArray();
var clusterCenters = transformedData.GetColumn<float[]>("Centroid").ToArray();
var features = transformedData.GetColumn<float[]>("Features").ToArray();
var silhouetteScore = ComputeSilhouetteScore(features, clusterAssignments, clusterCenters);
silhouetteScores[k - 2] = silhouetteScore;
}
// Find the number of clusters that maximizes the average silhouette score
int optimalClusters = 0;
double maxScore = double.MinValue;
for (int i = 0; i < silhouetteScores.Length; i++)
{
if (silhouetteScores[i] > maxScore)
{
maxScore = silhouetteScores[i];
optimalClusters = i + 2;
}
}
Console.WriteLine($"The optimal number of clusters is {optimalClusters}.");
}
private static double ComputeSilhouetteScore(float[][] features, uint[] clusterAssignments, float[][] clusterCenters)
{
double silhouetteScore = 0;
for (int i = 0; i < features.Length; i++)
{
var a = ComputeAverageDistance(features[i], clusterAssignments[i], features, clusterAssignments);
var b = ComputeMinimumDistance(features[i], clusterAssignments[i], clusterCenters);
silhouetteScore += (b - a) / Math.Max(a, b);
}
return silhouetteScore / features.Length;
}
private static double ComputeAverageDistance(float[] feature, uint clusterAssignment, float[][] features, uint[] clusterAssignments)
{
double distance = 0;
int count = 0;
for (int i = 0; i < features.Length; i++)
{
if (clusterAssignments[i] == clusterAssignment)
{
distance += Distance(feature, features[i]);
count++;
}
}
return distance / count;
}
private static double ComputeMinimumDistance(float[] feature, uint clusterAssignment, float[][] clusterCenters)
{
double minDistance = double.MaxValue;
for (int i = 0; i < clusterCenters.Length; i++)
{
if (i != clusterAssignment)
{
minDistance = Math.Min(minDistance, Distance(feature, clusterCenters[i]));
}
}
return minDistance;
}
private static double Distance(float[] feature1, float[] feature2)
{
double distance = 0;
for (int i = 0; i < feature1.Length; i++)
{
distance += Math.Pow(feature1[i] - feature2[i], 2);
}
return Math.Sqrt(distance);
}
class TextData
{
public string? Text { get; set; }
public float[] Features { get; set; }
public int Index { get; set; }
}
I believe the reason you're getting this error is you set the output column name to Text and input column name as Features in the FeaturizeText transform. I suspect you want the opposite. Take the Text column as input and generate a feature vector called Features which you can do by swapping the values in FeaturizeText or you can explicitly add parameter names (FeaturizeText(outputColumnName: "Features", inputColumnName:"Text")).
Check out the FeaturizeText documentation for more details.
Lets say a=x+y and b=2x-y and I want to plot a-b=0. I can manually rewrite this from (x+y)-(2x-y)=0 to y=.5x which makes it trivial to graph, but how do I rewrite it in code? Given x how do I calculate y if all I have is (x+y)-(2x-y)=0?
To be more specific, I am trying to graph the decision boundary of a neural network. I want to be able to change the layers and outputs at will, essentially changing the function I get as an output.
This is an example of an output I could get:
(x_1 w_2 + x_2 w_2 + b_1) w_7
+ (x_1 w_3 + x_2 w_4 + b_2) w_8
+ (x_1 w_5 + x_2 w_6 + b_3) w_9
+ b_4 (x_1 w_1 + x_2 w_2 + b_1) w_10
+ (x_1 w_3 + x_2 w_4 + b_2) w_11
+ (x_1 w_5 + x_2 w_6 + b_3) w_12
+ b_5
It's a 1 by 2 matrix and I know all values except x2 which is the y-axis. In order to draw the decision boundary I have to calculate a-b=0 where a and b both contain x and y. I can manually separate y to get y=... ,but that's not an option if the results in the output matrix change. How do I seperate/calculate the y?
I am using c# in Unity and passing the points on the graph into the LineRenderer.
Alright, I found the solution the same day of posting the question but had already been messing about for days. It turned out to be a math question after all.
Here's a link to the specific setup for the neural network using a linear activation: https://www.desmos.com/calculator/crmeebqnfb
I manually rewrote the matrix multiplication for this specific setup into a function and was looking for a way to do that for any size and number of invisible layers.
The solution I found is to separate the input matrix into x1 and x2 and separately do the matrix multiplication for them. The x1 value gets the biases added but the x2 doesn't and the first weight matrix has to be split in 2 so x1 can get multiplied with the first row and x2 with the second row.
If you then do the matrix multiplication from there you'll get two 2 matrices like this:
[firstx1answer secondx1answer] [firstx2answer secondx2answer]
And then you can put them into this function:
Edit for better clarification:
Maybe a bit confusing but here's my code. CreateDecisionBoundaryPoints is where this is implemented:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using System.IO;
using System;
[ExecuteAlways]
public class Controller : MonoBehaviour
{
public Transform LineRenderer;
public GameObject textPrefab;
public GameObject pointPrefab;
public Transform weightsUI;
public Transform biasesUI;
[Range(.001f, .1f)] public float delta;
public int numberOfHiddenLayers;
public bool debugWeightMatrices;
public bool debugBiasMatrices;
[HideInInspector] public string[] dataValues;
private void Start()
{
if (Application.isPlaying)
{
//read file
int numberOfLines;
dataValues = ReadData("D:\\Documents\\Unity Projects\\Learning Machine Learning\\Assets\\Data.csv", out numberOfLines);
int numOfOutputNeurons = CreatePointsUI(numberOfLines, dataValues);
//create layerSizes for example [2,3,2]
int[] layerSizes = new int[numberOfHiddenLayers + 2];
layerSizes[0] = (dataValues.Length / numberOfLines) - 1;
layerSizes[numberOfHiddenLayers + 1] = numOfOutputNeurons;
for (int i = 0; i < numberOfHiddenLayers; i++)
{
layerSizes[i+1] = Mathf.Max((dataValues.Length / numberOfLines) - 1, numOfOutputNeurons) + 1;
}
//create the actual matrices
List<float[,]> weights = new List<float[,]>();
List<float[]> biases = new List<float[]>();
MakeTheMatrices(layerSizes, out weights, out biases);
//fill weights with random values
RandomlyFillMatrices(weights);
//print matrices to make sure they're the right size and filled randomly
if (debugWeightMatrices)
Debug.Log(PrintMatrices(weights, "Weight Matrices"));
if (debugBiasMatrices)
Debug.Log(PrintMatrices(biases, "Bias Matrices"));
LineRenderer.GetComponent<DrawDecisionBoundary>().DrawLine(CreateDecisionBoundaryPoints(weights, biases, delta));
}
}
public struct OutputNeuronsAndColours
{
public string value;
public Color color;
public OutputNeuronsAndColours(string value, Color color)
{
this.value = value;
this.color = color;
}
}
public void DoTheWeightsStufUI(int weights)
{
int cwn = 0;
List<Transform> ws = new List<Transform>();
foreach (Transform child in weightsUI)
{
cwn++;
ws.Add(child);
}
int wta = weights - cwn;
for (int i = wta; i < 0; i++)
{
cwn--;
DestroyImmediate(ws[cwn].gameObject);
ws.RemoveAt(cwn);
}
for (int i = wta; i > 0; i--)
{
cwn++;
GameObject weight = Instantiate(textPrefab, weightsUI);
weight.GetComponentInChildren<TMP_Text>().SetText("W" + cwn.ToString());
}
}
public void DoTheBiasesStufUI(int biases)
{
int cbn = 0;
List<Transform> bs = new List<Transform>();
foreach (Transform child in biasesUI)
{
cbn++;
bs.Add(child);
}
int bta = biases - cbn;
for (int i = bta; i < 0; i++)
{
cbn--;
DestroyImmediate(bs[cbn].gameObject);
bs.RemoveAt(cbn);
}
for (int i = bta; i > 0; i--)
{
cbn++;
GameObject bias = Instantiate(textPrefab, biasesUI);
bias.GetComponentInChildren<TMP_Text>().SetText("B" + cbn.ToString());
}
}
string[] ReadData(string path, out int numberOfLines)
{
List<string> data_values = new List<string>();
StreamReader strReader = new StreamReader(path);
bool endOfFile = false;
int numOfLines = 0;
while (!endOfFile)
{
string data_string = strReader.ReadLine();
if (data_string == null)
{
endOfFile = true;
break;
}
else
numOfLines += 1;
data_values.AddRange(data_string.Split(','));
}
numberOfLines = numOfLines;
return data_values.ToArray();
}
int CreatePointsUI(int numberOfLines, string[] dataValues)
{
string[] possibleOutputs = new string[numberOfLines];
for (int i = 0; i < numberOfLines; i++)
{
possibleOutputs[i] = dataValues[(i * (dataValues.Length / numberOfLines)) + ((dataValues.Length / numberOfLines) - 1)];
}
List<OutputNeuronsAndColours> outputNeurons = new List<OutputNeuronsAndColours>(possibleOutputs.Length);
for (int i = 0; i < possibleOutputs.Length; i++)
{
bool contains = false;
for (int x = 0; x < outputNeurons.Count; x++)
{
if (possibleOutputs[i] == outputNeurons[x].value)
contains = true;
}
if (!contains)
outputNeurons.Add(new OutputNeuronsAndColours(possibleOutputs[i], new Color(UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f))));
}
for (int i = 0; i < numberOfLines; i++)
{
GameObject point = Instantiate(pointPrefab);
point.transform.position = new Vector2(float.Parse(dataValues[i * (dataValues.Length / numberOfLines)]), float.Parse(dataValues[(i * (dataValues.Length / numberOfLines)) + 1]));
foreach (OutputNeuronsAndColours value in outputNeurons)
{
if (value.value == dataValues[(i * (dataValues.Length / numberOfLines)) + ((dataValues.Length / numberOfLines) - 1)])
point.GetComponent<SpriteRenderer>().color = value.color;
}
}
return outputNeurons.Count;
}
public static void MakeTheMatrices(int[] layerSizes, out List<float[,]> weights, out List<float[]> biases)
{
List<float[,]> tempWeights = new List<float[,]>();
List<float[]> tempBiases = new List<float[]>();
for (int i = 0; i < layerSizes.Length - 1; i++)
{
tempWeights.Add(new float[layerSizes[i], layerSizes[i + 1]]);
}
for (int i = 1; i < layerSizes.Length; i++)
{
List<float> temp = new List<float>();
for (int x = 0; x < layerSizes[i]; x++)
temp.Add(0);
tempBiases.Add(temp.ToArray());
}
weights = tempWeights;
biases = tempBiases;
}
public static void RandomlyFillMatrices(List<float[,]> matrices)
{
foreach (float[,] matrix in matrices)
{
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int x = 0; x < matrix.GetLength(1); x++)
{
matrix[i, x] = UnityEngine.Random.Range(-3f, 3f);
}
}
}
}
public static string PrintMatrices(List<float[,]> matrices, string name = "Count")
{
string returnString = matrices.Count + " " + name;
foreach (float[,] matrix in matrices)
{
returnString += " (" + matrix.GetLength(0) + ", " + matrix.GetLength(1) + ")";
for (int i = 0; i < matrix.GetLength(0); i++)
{
string log = "";
if (i == 0)
log += "[";
else
log += " ";
for (int x = 0; x < matrix.GetLength(1); x++)
{
log += matrix[i, x];
if(x != matrix.GetLength(1) - 1)
log += " ";
}
if (i == matrix.GetLength(0) - 1)
log += "]";
Debug.Log(log);
}
}
return returnString;
}
public static string PrintMatrices(List<float[]> matrices, string name = "Count")
{
string returnString = matrices.Count + " " + name;
foreach (float[] matrix in matrices)
{
returnString += " (" + matrix.Length + ")";
string log = "[";
for (int i = 0; i < matrix.Length; i++)
{
log += matrix[i];
if (i != matrix.Length - 1)
log += " ";
}
log += "]";
Debug.Log(log);
}
return returnString;
}
private Vector3[] CreateDecisionBoundaryPoints(List<float[,]> weights, List<float[]> biases, float delta)
{
//check whether there are exactly 2 input neurons
if (weights[0].GetLength(0) != 2)
Debug.LogError("Not exactly 2 input neurons!");
//check whether there are exactly 2 output neurons
if (biases[biases.Count - 1].Length != 2)
Debug.LogError("Not exactly 2 output neurons!");
//create the values for the first layer
float[] weightsForFirstLayerX = new float[weights[0].GetLength(1)];
for (int i = 0; i < weights[0].GetLength(1); i++)
{
weightsForFirstLayerX[i] = weights[0][0, i];
}
float[] denominatorValuesFirstLayer = new float[weights[0].GetLength(1)];
for (int i = 0; i < weights[0].GetLength(1); i++)
{
denominatorValuesFirstLayer[i] = weights[0][1, i];
}
List<Vector3> pointsForGraph = new List<Vector3>();
//Calculate the y value(s) for each x with interval delta
for (float x = -.04f; x <= 1 + delta; x += delta)
{
float[] numeratorValuesFirstLayer = new float[weightsForFirstLayerX.Length];
for (int i = 0; i < weightsForFirstLayerX.Length; i++)
numeratorValuesFirstLayer[i] = x * weightsForFirstLayerX[i] + biases[0][i];
//get the row matrices for the decision boundary function
float[] numeratorResults = PassValuesThroughMatrices(numeratorValuesFirstLayer, weights, biases, true);
float[] denominatorResults = PassValuesThroughMatrices(denominatorValuesFirstLayer, weights, biases, false);
float y = (numeratorResults[1] - numeratorResults[0]) / (denominatorResults[0] - denominatorResults[1]);
pointsForGraph.Add(new Vector3(x, y, -1));
}
return pointsForGraph.ToArray();
}
private float[] PassValuesThroughMatrices(float[] values, List<float[,]> weights, List<float[]> biases, bool isNumerator)
{
float[] previousLayer = values;
//loop passing the previous layer values through the current layer: values = values * weights + biases
for (int i = 1; i < weights.Count; i++)
{
float[] temp = new float[weights[i].GetLength(1)];
//loop through the colums in the weight matrix
for (int v = 0; v < weights[i].GetLength(1); v++)
{
float value = 0;
//loop through the rows in the weight matrix
for (int b = 0; b < weights[i].GetLength(0); b++)
value += previousLayer[b] * weights[i][b, v];
if (isNumerator)
value += biases[i][v];
temp[v] = value;
}
previousLayer = temp;
}
//return the last itteration of values
return previousLayer;
}
}
I use this method and need return weights8spr, but I don't know how.
Can anybody help me? simplest return(weights8spr) don't work, because in input Im not give the double array.
public class Run {
public Run(List<dataVM2> TrainDataForStations)
{
double[] resultMAX1 = new double[] { 40.0, 1200.0, 100.0, 100.0, 10000.0 };
double[] resultMIN1 = new double[] { -50.0, 0.0, 0.0, 0.0, 0.0 };
double d1 = 0.0;
double d2 = 1.0;
int numItemsspr = TrainDataForStations.Count;
double[][] trainData = new double[numItemsspr][];
Random rnd = new Random(1);
double[][] MassiveDataspr8 = new double[numItemsspr][];
for (var i = 0; i < numItemsspr; ++i)
{
trainData[i] = new double[] { TrainDataForStations[i].TemperatureC1, TrainDataForStations[i].SolarRadiation1, TrainDataForStations[i].Wetness1, TrainDataForStations[i].WindSpeed1, TrainDataForStations[i].gen1 };
}
int maxcol = 0;
for (int i = 0; i < trainData.Length; i++)
{
if (trainData[i].Length > maxcol)
maxcol = trainData[i].Length;
}
//data normalization
for (int j = 0; j < MassiveDataspr8.Length; j++)
{
MassiveDataspr8[j] = new double[maxcol];
for (int i = 0; i < maxcol; i++)
{
MassiveDataspr8[j][i] = (((trainData[j][i] - resultMIN1[i]) * (d2 - d1)) / (resultMAX1[i] - resultMIN1[i])) + d1;
}
}
int NumInput = 4;
int NumHidden = 25;
int NumOutput = 1;
int rndSeed = 0;
NeuralNetworkData neuralform = new NeuralNetworkData(NumInput, NumHidden, NumOutput, rnd);
int maxEpochs = 1000;
double learnRate = 0.005;
double momentum = 0.001;
double[] weights8spr = new NeuralNetworkTrainer(neuralform, rnd).Train(MassiveDataspr8, maxEpochs, learnRate, momentum);
}
}
You are executing that code in the constructor of a class and you can't change the return type of a constructor.
You should create a method in the class and refactor the code a little.
public class Run
{
// default constructor not needed
public Run()
{
}
public double[] RunMethod(List<dataVM2> TrainDataForStations)
{
// put your code here
// ...
// return the double[]
return weights8spr;
}
}
And execute like:
var run = new Run();
var weights = run.RunMethod(listOfTrainDataForStations);
A method must have a return type. If it doesn't return a value, then this would be the pseudo type void, otherwise a real one.
public class StationsTrainer {
public double[] Run(List<dataVM2> TrainDataForStations)
{
...
double[] weights8spr = new NeuralNetworkTrainer(neuralform, rnd)
.Train(MassiveDataspr8, maxEpochs, learnRate, momentum);
return weights8spr;
}
}
And choose a better name for the class. E.g. StationsTrainer.
Here is code.
public class Adaline
{
private int _layer;
public int Layer { get { return _layer; } }
private int _epoch;
public int Epoch { get { return _epoch; } }
private double _error;
public double Error { get { return _error; } }
private double[] _weights;
public Adaline(int layer)
{
_layer = layer;
_weights = new double[layer];
Reset();
}
public void Reset()
{
Random r = new Random();
for (int i = 0; i < _layer; i++)
_weights[i] = r.NextDouble() - 0.5;
_error = 1;
}
public void Train(BasicTrainSet<double> trainset, double learnRate)
{
double ers = 0;
for(int p = 0; p < trainset.DataCount; p++)
{
double result = Compute(trainset.Input[p], true);
double error = trainset.Output[p] - result;
for (int i = 0; i < _weights.Length; i++)
{
_weights[i] += error * trainset.Input[p][i] * learnRate;
}
ers += Math.Abs(error);
}
_epoch++;
_error = ers;
}
public double Compute(double[] input, bool quan)
{
double result = 0;
for (int i = 0; i < _layer; i++)
result += Math.Tanh(_weights[i] * input[i]);
//double result = _weights.Zip(input, (a, b) => Math.Tanh(a * b)).Sum();
return quan ? (result >= 0 ? 1 : 0) : result;
}
}
When I tried to train and gate like this, it works like this.
Up four results are from this code
This is pretty weird, because there is not any problem with algorithm.
Weights are getting bigger and bigger. Where did i mistake?
In your code to compute the output of each neuron, you aren't applying the activation function correctly. You need to find the dot product between the weights and the inputs into each neuron then apply the activation function after. You are applying the activation function after each weighted accumulation, which is not correct.
Accumulate, then apply the activation function:
public double Compute(double[] input, bool quan)
{
double result = 0;
for (int i = 0; i < _layer; i++)
result += _weights[i] * input[i]; // Change - accumulate first
result = Math.Tanh(result); // Change - now apply activation function
return quan ? (result >= 0 ? 1 : 0) : result;
}
I am having issues with the output of the the result of a math calculation. I have a basic average of an array of double and I assign the result to a Label object, using the ToString() method. When I emulate the average, the label shows the correct value of 15.96 for example, but the same average of the same array, on my Galaxy S3 shows 159.6.
Is there anyone who know what's up and what can I do to make the S3 show the correct value?
Thank you all!
EDIT: passing the result to a label and adding the label to the grid:
double result = Math.Round(NP122.DoAverage(parameters), 2);
CustomLabel label = new CustomLabel();
label.ColNo = grid.ColumnDefinitions.IndexOf(c);
label.FontSize = 25;
label.TextColor = Color.Green;
if (result.ToString() == "NaN")
label.Text = "0";
else
label.Text = result.ToString();
label.IsVisible = true;
for (int i = 0; i < numberOfRows.Length + 2; i++) {
if(i == numberOfRows.Length +1)
Grid.SetRow(label, i);
}
Grid.SetColumn(label, grid.ColumnDefinitions.IndexOf(c));
listaRez.Add(label);
foreach (CustomLabel a in listaRez)
{
if (a.ColNo == grid.ColumnDefinitions.IndexOf(c))
{
grid.Children.Add(a);
}
}
EDIT 2: Custom function for NP122.DoAverage:
public static class NP122
{
public static double Vx, sx, Xm, kn, Xkinf, Xksup;
public static double sum;
public static double sumaProvizorie;
public static double[] valoriKn = new double[25];
public static double ValoareCaracteristicaSuperioara(double[] l)
{
Vx = 0;
sx = 0;
Xm = 0;
kn = 0;
Xkinf = 0;
Xksup = 0;
sum = 0;
sumaProvizorie = 0;
valoriKn[0] = 0;
//more here
valoriKn[24] = 0.35;
if (l.Length < 2 )
{
Xksup = 0;
Xkinf = 0;
}
else
{
Xm = (l.Sum()) / (l.Length);
for (int j = 0; j < l.Length; j++)
{
sumaProvizorie = Math.Round(Math.Pow((l[j] - Xm), 2), 2);
sum += sumaProvizorie;
}
kn = valoriKn[l.Length - 1];
double elements = (1.00 / (l.Length - 1));
double putere = sum;
sx = Math.Round(Math.Sqrt(elements * putere), 4);
Vx = sx / Xm;
Xksup = Xm * (1 + kn * Vx);
Xkinf = Xm * (1 - kn * Vx);
}
return Xksup;