How can I multiply two matrices in C#? - c#

Like described in the title, is there some library in the Microsoft framework which allows to multiply two matrices or do I have to write my own method to do this? // I've got an answer to this by now
Second question:
I wrote this multi class with a MultiplyMatrix method but it doesn't work like I want to. Can anyone help and tell where I made a mistake?
class multi
{
public void MultiplyMatrix(double[,] _A, double[,] _B, int _n, int _m, int _r)
{
int n, m, r;
double si;
n = _n;
m = _m;
r = _r;
double[,] A = new double[n, m];
double[,] B = new double[m, r];
double[,] C = new double[n, r];
A = _A;
B = _B;
try
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < r; j++)
{
si = 0;
for (int k = 0; k < m; k++)
{
si += A[i, m + k] + B[k, r + j];
}
C[i, r + j] = si;
}
}
for (int i = 0; i < C.Length; i++)
{
for (int j = 0; j < C.Length; j++)
{
Console.Write(C[i, j]+" ");
if (j % 3 == 0)
Console.WriteLine();
}
}
}
catch (IndexOutOfRangeException) { } // I always get this exception
}
}
I forgot to tell: I want to make a webservice to multiply on it.
Thanks:)

Multiplication of 2 matrixes:
public double[,] MultiplyMatrix(double[,] A, double[,] B)
{
int rA = A.GetLength(0);
int cA = A.GetLength(1);
int rB = B.GetLength(0);
int cB = B.GetLength(1);
if (cA != rB)
{
Console.WriteLine("Matrixes can't be multiplied!!");
}
else
{
double temp = 0;
double[,] kHasil = new double[rA, cB];
for (int i = 0; i < rA; i++)
{
for (int j = 0; j < cB; j++)
{
temp = 0;
for (int k = 0; k < cA; k++)
{
temp += A[i, k] * B[k, j];
}
kHasil[i, j] = temp;
}
}
return kHasil;
}
}

Whilst there's no built in Maths framework to do this in .NET (could use XNA's Maths library), there is a Matrix in the System.Windows.Media namespace. The Matrix structure has a Multiply method which takes in another Matrix and outputs a Matrix.
Matrix matrix1 = new Matrix(5, 10, 15, 20, 25, 30);
Matrix matrix2 = new Matrix(2, 4, 6, 8, 10, 12);
// matrixResult is equal to (70,100,150,220,240,352)
Matrix matrixResult = Matrix.Multiply(matrix1, matrix2);
// matrixResult2 is also
// equal to (70,100,150,220,240,352)
Matrix matrixResult2 = matrix1 * matrix2;
This is mainly used for 2D transformation:
Represents a 3x3 affine transformation
matrix used for transformations in 2-D
space.
but if it suits your needs, then there's no need for any third party libraries.

Although you can multiply matrices by an iterative approach (for loops), performing the calculations with linear algebra will clean up your code and will give you performance gains that are several times faster!
There is a free library available in nuget - MathNet.Numerics. It makes it extremely easy to multiply matrices:
Matrix<double> a = DenseMatrix.OfArray(new double[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } });
Matrix<double> b = DenseMatrix.OfArray(new double[,] { { 1 }, { 2 }, { 3 } });
Matrix<double> result = a * b;
It has no dependencies and can be used in .net core 2.0, making it an excellent choice to avoid iterative matrix multiplication techniques and take advantage of linear algebra.

There is nothing built into .NET. You will have to write the multiplication yourself or use some third party library. I've blogged about one way to achieve this comparing two different implementations : a standard naive algorithm and one using unsafe code.

CSML - C# Matrix Library - is a compact and lightweight package for numerical linear algebra. Many matrix operations known from Matlab, Scilab and Co. are implemented.
See this!

There are no such built in libraries. Unless you are using XNA - it has a Matrix class, though it is limited and designed for 3D games.
There are many matrix libraries for .NET though.

namespace matrix_multiplication
{
class Program
{
static void Main(string[] args)
{
int i, j;
int[,] a = new int[2, 2];
Console.WriteLine("Enter no for 2*2 matrix");
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
a[i, j] = int.Parse(Console.ReadLine());
}
}
Console.WriteLine("First matrix is:");
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
Console.Write(a[i,j]+"\t");
}
Console.WriteLine();
}
int[,] b = new int[2, 2];
Console.WriteLine("Enter no for 2*2 matrix");
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
b[i, j] = int.Parse(Console.ReadLine());
}
}
Console.WriteLine("second matrix is:");
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
Console.Write(b[i, j] + "\t");
}
Console.WriteLine();
}
Console.WriteLine("Matrix multiplication is:");
int[,] c = new int[2, 2];
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
c[i,j]=0;
for (int k = 0; k < 2; k++)
{
c[i, j] += a[i, k] * b[k, j];
}
}
}
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
Console.Write(c[i, j]+"\t");
}
Console.WriteLine();
}
Console.ReadKey();
}
}
}
output
Enter no for 2*2 matrix
8
7
6
0
First matrix is:
8 7
6 0
Enter no for 2*2 matrix
4
3
2
1
second matrix is:
4 3
2 1
Matrix multiplication is:
46 31
24 18

Below is the method to multiply int[3,4] matrix with int[4,3] matrix, it has time complexity of O(n cube) or Cubic time
class Program
{
static void Main(string[] args)
{
MultiplyMatrix();
}
static void MultiplyMatrix()
{
int[,] metrix1 = new int[3,4] { { 1, 2,3,2 }, { 3, 4,5,6 }, { 5, 6,8,4 } };
int[,] metrix2 = new int[4, 3] { { 2, 5, 3 }, { 4, 5, 1 }, { 8, 7, 9 }, { 3, 7, 2 } };
int[,] metrixMultplied = new int[3, 3];
for (int row = 0; row < 3; row++)
{
for (int col = 0; col < 3; col++)
{
for(int i=0;i<4;i++)
{
metrixMultplied[row, col] = metrixMultplied[row, col] + metrix1[row, i] * metrix2[i, col];
}
Console.Write(metrixMultplied[row, col] + ", ");
}
Console.WriteLine();
}
Console.ReadLine();
}
}

Here is my code : 4*4 matrix
for (int i = 0; i < 4; i++)
{
int column = 0;
while (column < 4)
{
int count = 0;
for (int j = 0; j < 4; j++)
{
matrixResult[i, column] += Convert.ToInt32(matrixR[i, j] * matrixT[count, column]);
count = count + 1;
}
column = column + 1;
}
}

If you have a helper to generate, iterate and populate an int[,] matrix like this one:
public class VisitMatrix{
public static int[,] execute(int rows, int columns, Func<int, int, int> fn)
{
int[,] result = new int[rows, columns];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
result[i, j] = fn(i, j);
}
}
return result;
}
}
Now matrix multiplication is as trivial as doing (supposing m1.GetLength(1) == m2.GetLength(0)):
public class MultiplyMatrices{
public static int[,] execute(int[,] m1, int[,] m2, int modulus = 10)
{
return VisitMatrix.execute(m1.GetLength(0), m2.GetLength(1), (i, j) =>
Enumerable.Range(0, m1.GetLength(1)-1)
.Select(k => m1[i, k] * m2[k, j])
.Aggregate(0, (a, b) => a + b, e => e % modulus)
}
}

Related

Initialize 2 dimensional array inside nested loop

I am working on an issue where i need to Declare a two - dimensional array named multiplicationTable
that contains 4 elements by 4 elements.Initialize it in
a nested loop to contain elements that equal to the value
that is the product of the two index values for
each element. In a second nested loop, display the values
in the console output, with column elements separated with
commas, and row elements separated with carriage returns. This is what i have so far, for some reason can't wrap my brain around the solution! Any help would be appreciated!.
double[,] multiplicationTable = new double[4, 4];// { {1,2,3,4 }, {5,6,7,8 }, {9,10,11,12 }, {13,14,15,16 } };
for (int i = 0; i < multiplicationTable.GetLength(0); i++)
{
for (int j = 0; j < multiplicationTable.GetLength(1); j++)
{
double d = multiplicationTable[i, j];
if (j < multiplicationTable.GetLength(1) - 1)
{
Console.Write(d + ",");
}
else
{
Console.Write(d);
}
}
Console.Write("\n");
}
Console.ReadKey();
double[,] multiplicationTable = new double[4, 4];
for (int i = 0; i < multiplicationTable.GetLength(0); i++)
{
for (int j = 0; j < multiplicationTable.GetLength(1); j++)
{
multiplicationTable[i, j] = i * j;
double d = multiplicationTable[i, j];
if (j < multiplicationTable.GetLength(1) - 1)
{
Console.Write(d + ",");
}
else
{
Console.Write(d);
}
}
Console.Write("\n");
}
Console.ReadKey();
Why not try to solve this with String.Join method? It is easy to use and will save you a lot of if-else statements. Here it is how it will look like with this method:
double[,] multiplicationTable = new double[4, 4] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
for (int i = 0; i < multiplicationTable.GetLength(0); i++)
{
var temp = new string[4];
for (int j = 0; j < multiplicationTable.GetLength(1); j++)
{
temp[j] = multiplicationTable[i, j].ToString();
}
Console.WriteLine(string.Join(",", temp));
}
Console.ReadKey();
double[,] multiplicationTable = new double[4, 4];
for (int i = 0; i < multiplicationTable.GetLength(0); i++)
{
var temp = new string[multiplicationTable.GetLength(0)];
for (int j = 0; j < multiplicationTable.GetLength(1); j++)
{
multiplicationTable[i, j] = i * j;
temp[j] = multiplicationTable[i, j].ToString();
}
Console.WriteLine(string.Join(",", temp));
}

rotate a 4x4 array by 180 degrees c#

hi i need to know how to rotate an array by 180 degrees in place. currently i can get it to rotate 90 degrees but just cannot get it to rotate any further. If anyone can help me that would be great as I've been stuck on this question for a couple of days now. Thanks, here is my code:
namespace Question_2_1_
{
class Program
{
static void Main(string[] args)
{
int[,] array = new int[4, 4] {
{ 1,2,3,4 },
{ 5,6,7,8 },
{ 9,0,1,2 },
{ 3,4,5,6 } };
int[,] rotated = RotateMatrix(array, 4);
var rowCount = array.GetLength(0);
var colCount = array.GetLength(1);
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < colCount; j++)
{
Console.Write(String.Format("{0}", rotated[i, j]));
}
Console.Write(Environment.NewLine);
}
Console.ReadLine();
}
static int[,] RotateMatrix(int[,] matrix, int n)
{
int[,] ret = new int[n, n];
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
ret[i, j] = matrix[n - j - 1, i];
}
}
return ret;
}
}
}
You say you want to rotate in-place, but your rotate method returns a new array. Rotating in-place means you modify the matrix itself, without creating a new one.
But, if you're rotating 90 degrees, you can of course only rotate in-place if the matrix is square.
However, you can always rotate in-place if you're rotating 180 degrees. Let's take a non-square matrix:
{ a, b, c, d, e, f },
{ g, h ,i, j, k, l },
{ m, n, o, p, q, r }
If we rotate it 180 degrees, we end up with:
{ r, q, p, o, n, m },
{ l, k, j, i, h, g },
{ f, e, d, c, b, a }
You can see that an item at [r, c] ends up at [#rows - r - 1, #columns - c - 1]. (0-based of course),
so b at [0, 1] ends up at [3 - 0 - 1, 6 - 1 - 1]
The method you can use is: first swap a and r, then b and q, etc.
This is similar to reversing a 1-dimensional array, just in 2 dimensions.
Just as when reversing a 1-dimensional array, we only go halfway:
the last 2 items we swap are i and j.
I made the method generic, so you can rotate any matrix with it.
static void Rotate180<T>(T[,] matrix) {
int rowCount = matrix.GetLength(0), columnCount = matrix.GetLength(1);
int max = rowCount * columnCount / 2, m = 0;
for (int r = 0; ; ++r) {
for (int c = 0; c < columnCount; ++c) {
Swap(matrix, r, c, rowCount - r - 1, columnCount - c - 1);
if (++m >= max) return;
}
}
}
static void Swap<T>(T[,] matrix, int r1, int c1, int r2, int c2) {
T temp = matrix[r1, c1];
matrix[r1, c1] = matrix[r2, c2];
matrix[r2, c2] = temp;
}
The answer you're looking for is:
ret[i, j] = [n - (i + 1), n - j - 1];
However, this is not in-place as you're creating an entirely different array "ret"
Do it with reversing the columns first, and then the rows.
class Program
{
static void Main(string[] args)
{
var A = new int[,] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
RotateMatrix180(ref A);
// A = {{16,15,14,.. }, .. , { ..3,2,1} }
}
public static void RotateMatrix180<T>(ref T[,] matrix)
{
int n = matrix.GetLength(0), m = matrix.GetLength(1);
if(n!=m) { /* error */ }
for(int i = 0; i<n; i++)
{
for(int j = 0; j<n/2; j++)
{
T temp = matrix[i, j];
matrix[i, j]=matrix[i,n-j-1];
matrix[i, n-j-1]=temp;
}
}
for(int i = 0; i<n/2; i++)
{
for(int j = 0; j<n; j++)
{
T temp = matrix[i, j];
matrix[i, j]=matrix[n-i-1, j];
matrix[n-i-1, j]=temp;
}
}
}
}
PS. I added the ref keyword to make it obvious the function modifies the existing array. The code will work the same without it, because arrays are always reference types.

Neural network [ocr]

I come looking for general tips about the program I'm writing now.
The goal is:
Use neural network program to recognize 3 letters [D,O,M] (or display "nothing is recognized" if i input anything other than those 3).
Here's what I have so far:
A class for my single neuron
public class neuron
{
double[] weights;
public neuron()
{
weights = null;
}
public neuron(int size)
{
weights = new double[size + 1];
Random r = new Random();
for (int i = 0; i <= size; i++)
{
weights[i] = r.NextDouble() / 5 - 0.1;
}
}
public double output(double[] wej)
{
double s = 0.0;
for (int i = 0; i < weights.Length; i++) s += weights[i] * wej[i];
s = 1 / (1 + Math.Exp(s));
return s;
}
}
A class for a layer:
public class layer
{
neuron[] tab;
public layer()
{
tab = null;
}
public layer(int numNeurons, int numInputs)
{
tab = new neuron[numNeurons];
for (int i = 0; i < numNeurons; i++)
{
tab[i] = new neuron(numInputs);
}
}
public double[] compute(double[] wejscia)
{
double[] output = new double[tab.Length + 1];
output[0] = 1;
for (int i = 1; i <= tab.Length; i++)
{
output[i] = tab[i - 1].output(wejscia);
}
return output;
}
}
And finally a class for a network
public class network
{
layer[] layers = null;
public network(int numLayers, int numInputs, int[] npl)
{
layers = new layer[numLayers];
for (int i = 0; i < numLayers; i++)
{
layers[i] = new layer(npl[i], (i == 0) ? numInputs : (npl[i - 1]));
}
}
double[] compute(double[] inputs)
{
double[] output = layers[0].compute(inputs);
for (int i = 1; i < layers.Length; i++)
{
output = layers[i].compute(output);
}
return output;
}
}
Now for the algorythm I chose:
I have a picture box, size 200x200, where you can draw a letter (or read one from jpg file).
I then convert it to my first array(get the whole picture) and 2nd one(cut the non relevant background around it) like so:
Bitmap bmp2 = new Bitmap(this.pictureBox1.Image);
int[,] binaryfrom = new int[bmp2.Width, bmp2.Height];
int minrow=0, maxrow=0, mincol=0, maxcol=0;
for (int i = 0; i < bmp2.Height; i++)
{
for (int j = 0; j < bmp2.Width; j++)
{
if (bmp2.GetPixel(j, i).R == 0)
{
binaryfrom[i, j] = 1;
if (minrow == 0) minrow = i;
if (maxrow < i) maxrow = i;
if (mincol == 0) mincol = j;
else if (mincol > j) mincol = j;
if (maxcol < j) maxcol = j;
}
else
{
binaryfrom[i, j] = 0;
}
}
}
int[,] boundaries = new int[binaryfrom.GetLength(0)-minrow-(binaryfrom.GetLength(0)-(maxrow+1)),binaryfrom.GetLength(1)-mincol-(binaryfrom.GetLength(1)-(maxcol+1))];
for(int i = 0; i < boundaries.GetLength(0); i++)
{
for(int j = 0; j < boundaries.GetLength(1); j++)
{
boundaries[i, j] = binaryfrom[i + minrow, j + mincol];
}
}
And convert it to my final array of 12x8 like so (i know I could shorten this a fair bit, but wanted to have every step in different loop so I can see what went wrong easier[if anything did]):
int[,] finalnet = new int[12, 8];
int k = 1;
int l = 1;
for (int i = 0; i < finalnet.GetLength(0); i++)
{
for (int j = 0; j < finalnet.GetLength(1); j++)
{
finalnet[i, j] = 0;
}
}
while (k <= finalnet.GetLength(0))
{
while (l <= finalnet.GetLength(1))
{
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * (k - 1); i < (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * k; i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * (l - 1); j < (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * l; j++)
{
if (boundaries[i, j] == 1) finalnet[k-1, l-1] = 1;
}
}
l++;
}
l = 1;
k++;
}
int a = boundaries.GetLength(0);
int b = finalnet.GetLength(1);
if((a%b) != 0){
k = 1;
while (k <= finalnet.GetLength(1))
{
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * finalnet.GetLength(0); i < boundaries.GetLength(0); i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * (k - 1); j < (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * k; j++)
{
if (boundaries[i, j] == 1) finalnet[finalnet.GetLength(0) - 1, k - 1] = 1;
}
}
k++;
}
}
if (boundaries.GetLength(1) % finalnet.GetLength(1) != 0)
{
k = 1;
while (k <= finalnet.GetLength(0))
{
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * (k - 1); i < (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * k; i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * finalnet.GetLength(1); j < boundaries.GetLength(1); j++)
{
if (boundaries[i, j] == 1) finalnet[k - 1, finalnet.GetLength(1) - 1] = 1;
}
}
k++;
}
for (int i = (int)(boundaries.GetLength(0) / finalnet.GetLength(0)) * finalnet.GetLength(0); i < boundaries.GetLength(0); i++)
{
for (int j = (int)(boundaries.GetLength(1) / finalnet.GetLength(1)) * finalnet.GetLength(1); j < boundaries.GetLength(1); j++)
{
if (boundaries[i, j] == 1) finalnet[finalnet.GetLength(0) - 1, finalnet.GetLength(1) - 1] = 1;
}
}
}
The result is a 12x8 (I can change it in the code to get it from some form controls) array of 0 and 1, where 1 form the rough shape of a letter you drawn.
Now my questions are:
Is this a correct algorythm?
Is my function
1/(1+Math.Exp(x))
good one to use here?
What should be the topology? 2 or 3 layers, and if 3, how many neurons in hidden layer? I have 96 inputs (every field of the finalnet array), so should I also take 96 neurons in the first layer? Should I have 3 neurons in the final layer or 4(to take into account the "not recognized" case), or is it not necessary?
Thank you for your help.
EDIT: Oh, and I forgot to add, I'm gonna train my network using Backpropagation algorythm.
You may need 4 layers at least to get accurate results using back propagation method. 1 input, 2 middle layers, and an output layer.
12 * 8 matrix is too small(and you may end up in data loss which will result in total failure) - try some thing 16 * 16. If you want to reduce the size then you have to peel out the outer layers of black pixels further.
Think about training the network with your reference characters.
Remember that you have to feed back the output back to the input layer again and iterate it multiple times.
A while back I created a neural net to recognize digits 0-9 (python, sorry), so based on my (short) experience, 3 layers are ok and 96/50/3 topology will probably do a good job. As for the output layer, it's your choice; you can either backpropagate all 0s when the input image is not a D, O or M or use the fourth output neuron to indicate that the letter was not recognized. I think that the first option would be the best one because it's simpler (shorter training time, less problems debugging the net...), you just need to apply a threshold under which you classify the image as 'not recognized'.
I also used the sigmoid as activation function, I didn't try others but it worked :)

Creating a 3x3 Matrix and ordering numbers in a vortex from smaller to bigger

i would like to create a 3x3 matrix with input numbers and then orders number from smaller to bigger and place it in the matrix like a vortex like : 1,2,3,4,5,6,7,8,9 and place number 1 to 0.0 position,2 to 0.1, 3 to 0.2, 4 to 1.2, 5 to 2.2, 6 to 2.1, 7 to 2.0, 8 to 1.0 and 9 to 1.1.
const int MATRIX_ROWS = 3;
const int MATRIX_COLUMNS = 3;
List<int> l = new List<int>(l);
double[,] matrix = new double[MATRIX_ROWS, MATRIX_COLUMNS];
for (int i = 0; i < MATRIX_ROWS * MATRIX_COLUMNS; ++i)
{
int input;
Console.Write("Enter value");
while (!int.TryParse(Console.ReadLine(), out input))
{
Console.Write("Enter correct value!");
}
l.Add(input);
}
l.Sort();
for (int i = 0; i < MATRIX_ROWS; i++)
{
for (int j = 0; j < MATRIX_COLUMNS; j++)
{
matrix[i, j] = l[i * 3 + j];
}
I start like that to get input numbers and i would like help for the second part.
this will present you with the "vortex like" result for the matrix:
List<int> nums = new List<int>();
double[,] matrix = new double[3,3];
for (int i = 0; i < 9; ++i)
{
double input;
Console.Write("Enter value");
while (!double.TryParse(Console.ReadLine(), out input))
{
Console.Write("Enter correct value!");
}
nums.Add(int.Parse(input.ToString()));
}
nums.Sort();
int block = 0;
int[] order = new int[] { 0, 1, 2, 2, 2, 1, 0, 0, 1 };
for (int i = 0 ; i < order.Length; i++)
{
switch (block)
{
case 0:
matrix[block, order[i]] = nums[i];
if (i == 2)
block = 1;
break;
case 1:
if (i < order.Length - 3)
{
matrix[block, order[i]] = nums[i];
block = 2;
}
else
matrix[block, order[i]] = nums[i];
break;
case 2:
if(i == order.Length - 3)
{
matrix[block, order[i]] = nums[i];
block = 1;
}
else
matrix[block, order[i]] = nums[i];
break;
}
}
Console.WriteLine("The Resulting Matrix is:");
for (int row = 0, col = 0; row < 3; row++)
{
Console.WriteLine("row " + row + ": {0} - {1} - {2}", matrix[row, col], matrix[row, col + 1], matrix[row, col + 2]);
col = 0;
}
EDIT:now it displays the results.
As I see it - you can declare a List<int> l somewhere at the beginning, read the whole data by l.Add(x); then perform l.Sort() and after the data is sorted - populate your matrix. Let me know if you have further questions.
So you will get something like
const int MATRIX_ROWS = 3;
const int MATRIX_COLUMNS = 3;
List<int> l = new List<int>();
double[,] matrix = new double[MATRIX_ROWS, MATRIX_COLUMNS];
for (int i = 0; i < MATRIX_ROWS * MATRIX_COLUMNS; ++i)
{
double input;
Console.Write("Enter value");
while (!double.TryParse(Console.ReadLine(), out input))
{
Console.Write("Enter correct value!");
}
l.Add(input);
}
l.Sort();
for (int i = 0; i < MATRIX_ROWS; i++)
{
for (int j = 0; j < MATRIX_COLUMNS; j++)
{
matrix[i, j] = l[i*3 + j];
}
}

Unstable calculation error

I need to calculate matrix: ( X^(T) * X )^(-1).
Legend for the code&comments:
x is double[,] array;
xT - transposed matrix
^(-1) - inverted matrix
Every time i generate new random matrix to work with it and i found out that program is very unstable, because it isn't working properly with any input data. I'm sure about that because i need to get Identity matrix in the end if everything's fine, but sometimes i get a totally terrible Ineverted matrix so i don't get an Identity matrix. I'm dissappointes because i always use the same type of data and do not convert anything. Compiler is MVS 2010. Hope You will help me.
Here is my Program.cs:
static void Main(string[] args)
{
Matrix x = new Matrix(5, 4);
//Matrix temp = new Matrix(x.Row, x.Col);
//double[] y = new double[x.Row];
//double[] b = new double[x.Row];
//this data isn't calculated correctly. used for debugging
x.MatrixX[0, 0] = 7; x.MatrixX[0, 1] = 6; x.MatrixX[0, 2] = 5; x.MatrixX[0, 3] = 8;
x.MatrixX[1, 0] = 7; x.MatrixX[1, 1] = 5; x.MatrixX[1, 2] = 8; x.MatrixX[1, 3] = 5;
x.MatrixX[2, 0] = 6; x.MatrixX[2, 1] = 8; x.MatrixX[2, 2] = 6; x.MatrixX[2, 3] = 8;
x.MatrixX[3, 0] = 8; x.MatrixX[3, 1] = 5; x.MatrixX[3, 2] = 8; x.MatrixX[3, 3] = 7;
x.MatrixX[4, 0] = 8; x.MatrixX[4, 1] = 5; x.MatrixX[4, 2] = 6; x.MatrixX[4, 3] = 7;
/*
7,00000 6,00000 5,00000 8,00000
7,00000 5,00000 8,00000 5,00000
6,00000 8,00000 6,00000 8,00000
8,00000 5,00000 8,00000 7,00000
8,00000 5,00000 6,00000 7,00000
*/
//random matrix generation
/*
Random rnd = new Random();
for (int i = 0; i < x.Row; i++)
for (int j = 0; j < x.Col; j++)
x.MatrixX[i, j] = rnd.Next(5, 10);
*/
/*i'm going to calculate: ( X^(T) * X )^(-1)
* 1. transpose X
* 2. multiply X and (1)
* 3. invert matrix (2)
* +4. i wanna check the results: Multilate of (2) and (3) = Identity_matrix.
* */
Matrix.Display(x);
//1
Matrix xt = Matrix.Transpose(x);
Matrix.Display(xt);
//2
Matrix xxt = Matrix.Multiply(x, xt);
Matrix.Display(xxt);
//3
Matrix xxtinv = Matrix.Invert(Matrix.Multiply(x, xt));
Matrix.Display(xxtinv);
//4
Console.WriteLine("Invert(xxt) * xxt. IdentityMatrix:");
Matrix IdentityMatrix = Matrix.Multiply(xxtinv, xxt);
Matrix.Display(IdentityMatrix);
Console.ReadKey();
}
And here is Matrix.cs with all functions:
public class Matrix
{
private double[,] matrix;
private int row;
private int col;
#region constructors
public Matrix(int Row, int Col)
{
this.row = Row;
this.col = Col;
matrix = new double[Row, Col];
}
public Matrix()
{
Random rnd = new Random();
Row = rnd.Next(3, 7);
Col = rnd.Next(3, 7);
matrix = new double[Row, Col];
for (int i = 0; i < Row; i++)
for (int j = 0; j < Col; j++)
matrix[i, j] = rnd.Next(5, 10);
}
public Matrix(Matrix a)
{
this.Col = a.Col;
this.Row = a.Row;
this.matrix = a.matrix;
}
#endregion
#region properties
public int Col
{
get { return col; }
set { col = value; }
}
public int Row
{
get { return row; }
set { row = value; }
}
public double[,] MatrixX
{
get { return matrix; }
set { matrix = value; }
}
#endregion
static public Matrix Transpose(Matrix array)
{
Matrix temp = new Matrix(array.Col, array.Row);
for (int i = 0; i < array.Row; i++)
for (int j = 0; j < array.Col; j++)
temp.matrix[j, i] = array.matrix[i, j];
return temp;
}
static public void Display(Matrix array)
{
for (int i = 0; i < array.Row; i++)
{
for (int j = 0; j < array.Col; j++)
Console.Write("{0,5:f2}\t", array.matrix[i, j]);
Console.WriteLine();
}
Console.WriteLine();
}
static public Matrix Multiply(Matrix a, Matrix b)
{
if (a.Col != b.Row) throw new Exception("multiplication is impossible: a.Col != b.Row");
Matrix r = new Matrix(a.Row, b.Col);
for (int i = 0; i < a.Row; i++)
{
for (int j = 0; j < b.Col; j++)
{
double sum = 0;
for (int k = 0; k < b.Row; k++)
sum += a.matrix[i, k] * b.matrix[k, j];
r.matrix[i, j] = sum;
}
}
return r;
}
static public Matrix Invert(Matrix a)
{
Matrix E = new Matrix(a.Row, a.Col);
double temp = 0;
int n = a.Row;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
E.matrix[i, j] = 0.0;
if (i == j)
E.matrix[i, j] = 1.0;
}
for (int k = 0; k < n; k++)
{
temp = a.matrix[k, k];
for (int j = 0; j < n; j++)
{
a.matrix[k, j] /= temp;
E.matrix[k, j] /= temp;
}
for (int i = k + 1; i < n; i++)
{
temp = a.matrix[i, k];
for (int j = 0; j < n; j++)
{
a.matrix[i, j] -= a.matrix[k, j] * temp;
E.matrix[i, j] -= E.matrix[k, j] * temp;
}
}
}
for (int k = n - 1; k > 0; k--)
{
for (int i = k - 1; i >= 0; i--)
{
temp = a.matrix[i, k];
for (int j = 0; j < n; j++)
{
a.matrix[i, j] -= a.matrix[k, j] * temp;
E.matrix[i, j] -= E.matrix[k, j] * temp;
}
}
}
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
a.matrix[i, j] = E.matrix[i, j];
}
return a;
}
}
In your example, the determinant of x * transpose(x) is zero. As a result, there is no inverse, which is probably why you're getting strange results.
I also note that your Inverse function modifies the matrix passed to it. This should probably be modified to avoid that.

Categories

Resources