C# Math.Net Matrix dimensions must agree - c#

I was trying to translate this python code for a Neural Network
https://gist.github.com/miloharper/c5db6590f26d99ab2670#file-main-py
in C#. I'm using the Math.Net Numerics for the matrixes and here is the code I've made so far in C#
using System;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics;
using MathNet.Numerics.LinearAlgebra.Double;
namespace NeuralNetwork
{
class Program
{
static void Main(string[] args)
{
NeuralNetwork NN = new NeuralNetwork();
Console.WriteLine("Random starting synaptic weights: ");
Console.WriteLine(NN.SynapticWeights);
Matrix<double> TrainingSetInput = DenseMatrix.OfArray(new double[,] { { 0, 0, 1 }, { 1, 1, 1 }, { 1, 0, 1 }, { 0, 1, 1 } });
Matrix<double> TrainingSetOutput = DenseMatrix.OfArray(new double[,] { { 0, 1, 1, 0 } }).Transpose();
NN.Train(TrainingSetInput, TrainingSetOutput, 10000);
Console.WriteLine("New synaptic weights after training: ");
Console.WriteLine(NN.SynapticWeights);
Console.WriteLine("Considering new situation {1, 0, 0} -> ?: ");
Console.WriteLine(NN.Think(DenseMatrix.OfArray(new double[,] { { 1, 0, 0 } })));
Console.ReadLine();
}
}
class NeuralNetwork
{
private Matrix<double> _SynapticWeights;
public NeuralNetwork()
{
_SynapticWeights = 2 * Matrix<double>.Build.Random(3, 1) - 1;
}
private Matrix<double> Sigmoid(Matrix<double> Input)
{
return 1 / (1 + Matrix<double>.Exp(-Input));
}
private Matrix<double> SigmoidDerivative(Matrix<double> Input)
{
return Input * (1 - Input); //NEW Exception here
}
public Matrix<double> Think(Matrix<double> Input)
{
return Sigmoid((Input * _SynapticWeights)); //Exception here (Solved)
}
public void Train(Matrix<double> TrainingInput, Matrix<double> TrainingOutput, int TrainingIterations)
{
for (int Index = 0; Index < TrainingIterations; Index++)
{
Matrix<double> Output = Think(TrainingInput);
Matrix<double> Error = TrainingOutput - Output;
Matrix<double> Adjustment = Matrix<double>.op_DotMultiply(TrainingInput.Transpose(), Error * SigmoidDerivative(Output));
_SynapticWeights += Adjustment;
}
}
public Matrix<double> SynapticWeights { get { return _SynapticWeights; } set { _SynapticWeights = value; } }
}
}
When I execute it, it shows an exception on line 53 (there is a comment at that line in the code). It says:
Matrix dimensions must agree: op1 is 4x3, op2 is 3x1
Did I copy it wrong or is it a problem with the MAth.Net library?
Thanks in advance :D

As far as I can see, the problem not in the library code. You are trying to perform an element-wise matrix multiplication with the use of op_DotMultiply function (line 53). In this case it is obvious from the error message that matrices cannot be multiplied due to difference in their size: the first one is 4x3, the second one is 3x1.
I can suggest to look at the size of these matrices: TrainingSetInput and _SynapticWeights (look at function Train, you are calling Think inside of it with the wrong sized matrices). Check if they are generated correctly. And also think if you really need an element-wise matrix multiplication or a usual multiplication.
If you need more info about matrix multiplications, you can use these links:
Element-wise:
https://en.wikipedia.org/wiki/Hadamard_product_(matrices)
Usual:
https://en.wikipedia.org/wiki/Matrix_multiplication

Related

Array.Clear(new [] {1,2,3}, 0, 2) outputs [1,z2,z3]

Edit: Changed System.Array.Clear(new[] {1,2,3}, 0, 2); to System.Array.Clear(numbers, 0, 2); but get the output [0, z0, z3] and was expecting [0,0,3]
I'm learning about C# and currently learning about arrays and Clear(). When trying to see what happens when using Clear(), I get this output:
I don't understand why this happens. Wasn't it supposed to be [0,0,3]?
My code looks like this:
Program.cs
namespace Introduction
{
internal class Program
{
/* MAIN FUNCTION */
public static void Main()
{
// RunControlFlow();
RunArrays();
}
/* ARRAYS */
public static void RunArrays()
{
// Var declaration
var array = new Arrays.Array();
array.Manipulation();
}
}
}
Arrays.cs
using System;
namespace Introduction.Arrays
{
public class Array
{
public void Manipulation()
{
var numbers = new[] {1, 2, 3};
System.Array.Clear(numbers, 0, 2);
Console.WriteLine("Manipulation | Clearing from index 0 to 2: [{0}]", string.Join(",z", numbers));
}
}
}
You are not passing the numbers array to the Clear method, you are creating a new array that has the same elements, but it's a completely different reference and has nothing to do with numbers. That is why the values in numbers stays unchanged:
Array.Clear(numbers, 0, 2);

Google OR-Tools TSP returning several solution

I've been recently working on finding more than just the optimal route using Google's OR-Tools. I have found an example in the repo, but this only solves for the optimal route, any idea how to generate more than just one solution for a set of points? I'm currently working with the DotNet version of the tool, any solution with any other language would be helpful!
public class tspParams : NodeEvaluator2
{
public static int[,] distanceMatrix =
{
{ 0, 20, 40, 10 },
{ 20, 0, 4, 55 },
{ 40, 4, 0, 2 },
{ 10, 55, 2, 0 }
};
public static int tsp_size
{
get { return distanceMatrix.GetUpperBound(0) + 1; }
}
public static int num_routes
{
get { return 1; }
}
public static int depot
{
get { return 0; }
}
public override long Run(int FromNode, int ToNode)
{
return distanceMatrix[FromNode, ToNode];
}
}
public class TSP
{
public static void PrintSolution(RoutingModel routing, Assignment solution)
{
Console.WriteLine("Distance of the route: {0}", solution.ObjectiveValue());
var index = routing.Start(0);
Console.WriteLine("Route for Vehicle 0:");
while (!routing.IsEnd(index))
{
Console.Write("{0} -> ", routing.IndexToNode(index));
var previousIndex = index;
index = solution.Value(routing.NextVar(index));
}
Console.WriteLine("{0}", routing.IndexToNode(index));
//Console.WriteLine("Calculated optimal route!");
}
public static void Solve()
{
// Create Routing Model
RoutingModel routing = new RoutingModel(
tspParams.tsp_size,
tspParams.num_routes,
tspParams.depot);
// Define weight of each edge
NodeEvaluator2 distanceEvaluator = new tspParams();
//protect callbacks from the GC
GC.KeepAlive(distanceEvaluator);
routing.SetArcCostEvaluatorOfAllVehicles(distanceEvaluator);
// Setting first solution heuristic (cheapest addition).
RoutingSearchParameters searchParameters = RoutingModel.DefaultSearchParameters();
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
Assignment solution = routing.SolveWithParameters(searchParameters);
PrintSolution(routing, solution);
}
}
Use AllSolutionCollector from the underlying CP solver. python code:
solver = routing.solver()
collector = solver.AllSolutionCollector()
for location_idx in range(len(data['time_windows'])):
index = manager.NodeToIndex(location_idx)
time_var = time_dimension.CumulVar(index)
next_var = routing.NextVar(index)
collector.Add(time_var)
collector.Add(next_var)
for v in range(data['num_vehicles']):
index = routing.Start(v)
time_var = time_dimension.CumulVar(index)
next_var = routing.NextVar(index)
collector.Add(time_var)
collector.Add(next_var)
index = routing.End(v)
time_var = time_dimension.CumulVar(index)
collector.Add(time_var)
routing.AddSearchMonitor(collector)
assignment = routing.SolveFromAssignmentWithParameters(initial_solution, search_parameters)
if assignment:
logger.info("solution count: %d", collector.SolutionCount())
for index in range(collector.SolutionCount()):
logger.info("solution index: %d", index)
self.print_solution(data, manager, routing, collector.Solution(index))
logger.info('final solution:')
self.print_solution(data, manager, routing, assignment)
else:
raise OptimizationInternalException("no solution found")

C# Double Variable is displayed without points

Im creating an two dimensional array and giving the user the chance to set there double variables. When i want to print out the result, it is shown without points
exp: user entry 3.45 -> 345
Conver.ToDouble doesnt function neither
the following code shows my "programm" nevermind exception handling
static void Main(string[] args)
{
double[,] Array = new double[,] { { 0, 0, 0}, { 0, 0, 0 }, { 0, 0, 0 } };
array Object = new array();
array[0,0] = Double.Parse(Console.ReadLine());
Console.WriteLine("Wert = {0}",intArray[0,0]);
Console.ReadKey();
}
}
Multiply the values by 100, and then use the following format string:
Console.WriteLine("Wert = {0:F0}",intArray[0,0] * 100);
Your code has a lot of errors as I found:
corrected code is:
static void Main(string[] args)
{
double[,] Array = new double[,] { { 0, 0, 0}, { 0, 0, 0 }, { 0, 0, 0 } };
//array Object = new array(); //no need of this because you are not using it any where
Array[0,0] = Double.Parse(Console.ReadLine()); //"array" doesn't exist, it should be "Array"
Console.WriteLine("Wert = {0}",Array[0,0]); //"intArray" has not been initialized, it should be "Array" in you case
Console.ReadKey();
}
Here is the output:
I hope it will work now.

Using array initializer

I have a class called Matrix : IEnumerable<double>, (classic, mathematical matrix. It is basically a 2D array with some goodies).
The class is immutable, so there is no way to change its values after instance creation.
If want to create a matrix with pre-existing values I have to pass an array to the constructor like this:
double[,] arr = new double[,]
{
{1,2,3}, {4,5,6}, {7,8,9}
};
Matrix m = new Matrix(arr);
Is there a way to turn it into this: (?)
Matrix m = new Matrix
{
{1,2,3}, {4,5,6}, {7,8,9}
};
Update:
Found a hack-ish way yo make it work. I'm not sure if this solution is advisable, but it works.
class Matrix : ICloneable, IEnumerable<double>
{
// Height & Width are initialized in a constructor beforehand.
/*
* Usage:
* var mat = new Matrix(3, 4)
* {
* {1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}
* };
*/
int rowIndex;
bool allowArrayInitializer;
double[,] tempData;
double[,] data;
public void Add(params double[] args)
{
if(!allowArrayInitializer)
throw new InvalidOperationException("Cannot use array initializer");
if(args.Length != Width || rowIndex >= Height)
throw new InvalidOperationException("Invalid array initializer.");
for(int i = 0; i < Width; i++)
tempData[i, rowIndex] = args[i];
if(++rowIndex == Height)
data = tempData;
}
}
Not if it’s immutable; that syntactic sugar is implemented using Add().
You will not able to do it via initializer but should be able to do it via parameterized constructor.
You can see the sample code below :
class Matrix : IEnumerable<double>
{
double[,] input;
public Matrix(double[,] inputArray)
{
input = inputArray;
}
public IEnumerator<double> GetEnumerator()
{
return (IEnumerator<double>)input.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return input.GetEnumerator();
}
}
In the main method :
static void Main(string[] args)
{
var m = new Matrix(new double[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } });
}
I hope this helps you!
instead of deriving from IEnumerable I would use a property:
class Matrix
{
public double[,] Arr { get; set; }
}
Matrix m = new Matrix
{
Arr = new double [,] { {1d,2d,3d}, { 4d,5d, 6d}}
};

Predicting data based on averages

I have GPS data entering a serial port on my PC every second. I have successfully processed the GPS data and the latitude and longitude are stored in separate arrays as floating point numbers.
double[] dlat = new double[100000]; //contains the latitude data
double[] dlon = new double[100000]; //contains the longitude data
Most of the time the latitude and longitude numbers remain the same as the GPS position only changes every 5 meters. When the either the latitude or longitude value in the arrays changes I want my program to predict based on averages the latitude or longitude for the the data points stored in between the changes. For example:
Let's say this is the contents of the latitude array:
2,2,2,2,2,17
I would want my program to change what is in the array to:
2,5,8,11,14,17
I've tried tackling the problem but my method doesn't work :-/ I am new to C#; there must be a better way of doing this. Here is the snippet of my code that attempts to do the prediction (the bit after ---GPS coordinate prediction--- is the bit that doesn't work):
string RxString;// where the raw serial data is stored
string mag;
double[] dmag = new double[100000];//magnetic data stored here
string lat;
double[] dlat = new double[100000];//latitude data stored here
string lon;
double[] dlon = new double[100000];//longitude data stored here
double average;//average step between change in latiude
int i; //pointer double array data;
int count;//counter for prediction code
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)//activates when port is open and data in buffer
{
RxString = serialPort1.ReadTo("\r\n");//read raw data from serial port into string
this.Invoke(new EventHandler(DisplayText));//invoke allows it to call function diplay text*/
if(RxString.StartsWith("G"))
{
lat = RxString.Split(',')[0].Substring(4);// extract latitude
this.Invoke(new EventHandler(DisplayText1));//invoke allows it to call function diplay text
dlat[i] = Convert.ToDouble(lat);//convert and store in double array
this.Invoke(new EventHandler(Form1_Load));//invoke allows it to call function
lon = RxString.Split(',')[2];// extract longitude
this.Invoke(new EventHandler(DisplayText2));//invoke allows it to call function diplay text
dlon[i] = Convert.ToDouble(lon);//covert and store in double array
this.Invoke(new EventHandler(Form1_Load));//invoke allows it to call function
mag = RxString.Split(',')[3].Substring(6).Trim();// extract magnetic data
this.Invoke(new EventHandler(DisplayText3));//invoke allows it to call function diplay text
dmag[i] = Convert.ToDouble(mag);//convert and store in double array
this.Invoke(new EventHandler(Form1_Load));//invoke allows it to call function
i++;
RxString = null;
/* -------------------------GPS coordinate prediction--------------------------------------------- */
if (i > 0)
{
if (dlat[i] == dlat[i - 1])
{
count++;
}
if (dlat[i] != dlat[i - 1])
{
double average = (dlat[i] - dlat[i - 1]) / (count);//average data step beween changed values
int firstAv = i - (count - 1);//position of first average
int lastAv = i - 1;//position of last average
for (int j = firstAv; j <= lastAv; i++)
{
dlat[j] = dlat[j - 1] + average;
}
count = 0;
}
}
if (i==0) count = 1;
}
The following works:
using System;
using System.Text;
namespace Practice
{
public class Hello
{
static double[] ldat = {2.0,2.0,2.00,2.0,2.0,17.0};
static double[] ldat2 = {2.0,3.0,4.00,4.0,7.0,19.0};
static double[] ldat3 = {0.0, 0.0, -5.0, -5.0, -11.0, -11.0, -20};
public static void Main(string[] args)
{
test(ldat);
test(ldat2);
test(ldat3);
}
public static void test(double[] array){
//Use Code from here.....
int firstEqualIndex = -1;
for(int i = 1; i < array.Length ; i ++)
{
if (i > 0)
{
if(array[i] == array[i - 1])
{
if(firstEqualIndex == -1)
{
firstEqualIndex = i - 1;
}
}
else //They are not equal
{
//Figure out the average.
if(firstEqualIndex >= 0)
{
double average = (array[i] - array[firstEqualIndex]) / (Double)((i - firstEqualIndex));
int k = 0;
for(int j = firstEqualIndex; j < i; j++)
{
array[j] += average * k;
k++;
}
firstEqualIndex = -1;
}
}
}
}
//..... to here.
StringBuilder builder = new StringBuilder();
foreach (double entry in array)
{
// Append each int to the StringBuilder overload.
builder.Append(entry).Append(", ");
}
string result = builder.ToString();
Console.WriteLine(result);
}
}
}
This test outputs
2, 5, 8, 11, 14, 17,
2, 3, 4, 5.5, 7, 19,
0, -2.5, -5, -8, -11, -15.5, -20,
Sorry about all the edits I am trying to make sure that the method works with additional test cases.
EDIT: Added a test for negative case.
I would formulate this problem in terms of signal processing. So if you have a signal f(t) (which could be your discretized latitude array for example), you want to create a new signal g(t) defined by
g(t) = E[f(z) | t-0.5*w <= z <= t+0.5*w]
where E is denoting the expected value (or average) and w is the width of your filter.
One of the benefits of modeling the problem this way is that you have a very concrete way of specifying your movement model. That is, how are you going to transform the data [0, 0, 0, 0, 1, 1, 1, 1]?
Should it be [0, 0, 0, 1/3, 2/3, 1, 1, 1]?
Or should it be [0, 1/7, 2/7, 3/7, 4/7, 5/7, 6/7, 1]?
Given that you know how much time passes between your samples, you can choose a w duration that specifies the model you want.
Another benefit is that, if you want a nonlinear movement model, you can easily extend to that too. In the example I gave above, I used a box filter to do the smoothing, but you could use something else to take into account the physical limitations on the acceleration/deceleration of whatever it is you're tracking. A filter shaped more like a Gaussian curve could accomplish that.

Categories

Resources