How to multiply a matrix in C#? - c#

I cannot get this method to work. It intends to multiply a matrix by a given one. Could someone help me to correct it please?
class Matriz
{
public double[,] structure;
//Other class methods
public void multiplyBy(Matrix m)
{
if (this.structure.GetLength(1) == m.structure.GetLength(0))
{
Matriz resultant = new Matriz(this.structure.GetLength(0), m.structure.GetLength(1));
for (int i = 0; i < this.structure.GetLength(0) - 1; i++)
{
for (int j = 0; j < m.structure.GetLength(1) - 1; j++)
{
resultant.structure[i, j] = 0;
for (int z = 0; z < this.structure.GetLength(1) - 1; z++)
{
resultant.structure[i, j] += this.structure[i, z] * m.structure[z, j];
}
}
}
this.structure= resultant.structure;
}
else
{
Console.WriteLine("Selected matrixs cannot be multiply");
}
}
}

Read this MSDN Magazine article by James McCaffrey and use the code below as an extension method. They use a jagged array which is more convenient and sometimes faster than a 2D array. Change any data[i][j] to data[i,j] to make the code work with a 2D array.
public static double[] MatrixProduct(this double[][] matrixA,
double[] vectorB)
{
int aRows=matrixA.Length; int aCols=matrixA[0].Length;
int bRows=vectorB.Length;
if (aCols!=bRows)
throw new Exception("Non-conformable matrices in MatrixProduct");
double[] result=new double[aRows];
for (int i=0; i<aRows; ++i) // each row of A
for (int k=0; k<aCols; ++k)
result[i]+=matrixA[i][k]*vectorB[k];
return result;
}
public static double[][] MatrixProduct(this double[][] matrixA,
double[][] matrixB)
{
int aRows=matrixA.Length; int aCols=matrixA[0].Length;
int bRows=matrixB.Length; int bCols=matrixB[0].Length;
if (aCols!=bRows)
throw new Exception("Non-conformable matrices in MatrixProduct");
double[][] result=MatrixCreate(aRows, bCols);
for (int i=0; i<aRows; ++i) // each row of A
for (int j=0; j<bCols; ++j) // each col of B
for (int k=0; k<aCols; ++k)
result[i][j]+=matrixA[i][k]*matrixB[k][j];
return result;
}
public static double[][] MatrixCreate(int rows, int cols)
{
// creates a matrix initialized to all 0.0s
// do error checking here?
double[][] result=new double[rows][];
for (int i=0; i<rows; ++i)
result[i]=new double[cols];
// auto init to 0.0
return result;
}

This is the modified version of my method, as far as I've been testing this approach works fine.
public void multiplicarPor(Matriz m)
{
if (this.estructura.GetLength(1) == m.estructura.GetLength(0))
{
Matriz resultante = new Matriz(this.estructura.GetLength(0), m.estructura.GetLength(1));
for (int i = 0; i < this.estructura.GetLength(0); i++)
{
for (int j = 0; j < m.estructura.GetLength(1); j++)
{
resultante.estructura[i, j] = 0;
for (int z = 0; z < this.estructura.GetLength(1); z++)
{
resultante.estructura[i, j] += this.estructura[i, z] * m.estructura[z, j];
}
}
}
this.estructura = resultante.estructura;
}
else
{
Console.WriteLine("No se pueden multiplicar estas matrices");
}
}

Related

how can i sort a matrix's each row from smallest to largest and then find the matrix's peak value?

i need to write a program that takes 1 to 100 integers randomly, then i need to take this program's transpose, then I need to sort this matrix (each row in itself) from smallest to largest.
and finally, i need to find this matrix's peak value. here is what i have written for the program. for now, it creates a random matrix (20x5) and then it takes its transpose. can you help me with finding its peak value and then sort its each row?
PS.: using classes is mandatory!
using System;
namespace my_matrix;
class Program
{
public int[,] Create(int[,] myarray, int Row, int Clm)
{
Random value = new Random();
myarray = new int[Row, Clm];
int i = 0;
int j = 0;
while (i < Row)
{
while (j < Clm)
{
myarray[i, j] = value.Next(1, 100);
j++;
}
i++;
j = 0;
}
return myarray;
}
public int[,] Print(int[,] myarray, int Row, int Clm)
{
Console.WriteLine("=====ARRAY=====");
for (int a = 0; a < Row; a++)
{
for (int b = 0; b < Clm; b++)
{
Console.Write(myarray[a, b] + " ");
}
Console.WriteLine();
}
return null;
}
public int[,] Transpose(int[,] myarray, int Row, int Clm)
{
for (int b = 0; b < Clm; b++)
{
for (int a = 0; a < Row; a++)
{
Console.Write(myarray[a, b] + " ");
}
Console.WriteLine();
}
return myarray;
}
public int[,] Print_Transpose(int[,] myarray, int Row, int Clm)
{
Console.WriteLine("=====TRANSPOSE=====");
for (int b = 0; b < Clm; b++)
{
for (int a = 0; a < Row; a++)
{
Console.Write(myarray[a, b] + " ");
}
Console.WriteLine();
}
return null;
}
static void Main(string[] args)
{
Program x = new Program();
int[,] myarray = new int[20, 5];
int[,] a = x.Create(myarray, 20, 5);
x.Print(a, 20, 5);
x.Print_Transpose(a, 20, 5);
}
}
i don't know how to make a class which sorta each row from smallest to largest and also i dont know how to create a class which finds the matrix's peak value.
You can run over the array, keeping the maxNum:
public int getMax(int[,] fromArray)
{
int maxNum = 0;
for (int b = 0; b < fromArray.GetUpperBound(1); b++)
{
for (int a = 0; a < fromArray.GetUpperBound(0); a++)
{
if (maxNum < fromArray[a,b])
{
maxNum = fromArray[a, b];
}
}
}
return maxNum;
}
Call the function like:
Console.Write("Max number = {0:D}", x.getMax (a));
If you want a sort method, you can place all values in a List, sort them and convert back to array.
public int[] SortArray(int[,] fromArray)
{
List<int> newList = new List<int>(fromArray.Length);
for (int b = 0; b < fromArray.GetUpperBound(1); b++)
{
for (int a = 0; a < fromArray.GetUpperBound(0); a++)
{
newList.Add (fromArray[a, b]);
}
}
newList.Sort();
return newList.ToArray<int>();
}

How to invert double[,] in C#

I am making a program, where I need to calculate linear regression, but I got stuck at inversion of a matrix.
I have
double[,] location = new double[3,3];
It was then filled with numbers, but then I do not know, how to count the inverse matrix for it like in Linear algebra.
I searched for a solution on the internet, but there was some Matrix class that I dont know how to convert my double[,] to.
So, do you know some elegant way to inverse double[,] like the inversion of matrixes in Linear algebra?
Here you have a working example, just copy the entire code into a console project and run it.
I took it from this link https://jamesmccaffrey.wordpress.com/2015/03/06/inverting-a-matrix-using-c/
using System;
using System.Collections.Generic;
using System.Linq;
namespace matrixExample
{
class Program
{
static void Main(string[] args)
{
double[][] m = new double[][] { new double[] { 7, 2, 1 }, new double[] { 0, 3, -1 }, new double[] { -3, 4, 2 } };
double[][] inv = MatrixInverse(m);
//printing the inverse
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
Console.Write(Math.Round(inv[i][j], 1).ToString().PadLeft(5, ' ') + "|");
Console.WriteLine();
}
}
static double[][] MatrixCreate(int rows, int cols)
{
double[][] result = new double[rows][];
for (int i = 0; i < rows; ++i)
result[i] = new double[cols];
return result;
}
static double[][] MatrixIdentity(int n)
{
// return an n x n Identity matrix
double[][] result = MatrixCreate(n, n);
for (int i = 0; i < n; ++i)
result[i][i] = 1.0;
return result;
}
static double[][] MatrixProduct(double[][] matrixA, double[][] matrixB)
{
int aRows = matrixA.Length; int aCols = matrixA[0].Length;
int bRows = matrixB.Length; int bCols = matrixB[0].Length;
if (aCols != bRows)
throw new Exception("Non-conformable matrices in MatrixProduct");
double[][] result = MatrixCreate(aRows, bCols);
for (int i = 0; i < aRows; ++i) // each row of A
for (int j = 0; j < bCols; ++j) // each col of B
for (int k = 0; k < aCols; ++k) // could use k less-than bRows
result[i][j] += matrixA[i][k] * matrixB[k][j];
return result;
}
static double[][] MatrixInverse(double[][] matrix)
{
int n = matrix.Length;
double[][] result = MatrixDuplicate(matrix);
int[] perm;
int toggle;
double[][] lum = MatrixDecompose(matrix, out perm,
out toggle);
if (lum == null)
throw new Exception("Unable to compute inverse");
double[] b = new double[n];
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
if (i == perm[j])
b[j] = 1.0;
else
b[j] = 0.0;
}
double[] x = HelperSolve(lum, b);
for (int j = 0; j < n; ++j)
result[j][i] = x[j];
}
return result;
}
static double[][] MatrixDuplicate(double[][] matrix)
{
// allocates/creates a duplicate of a matrix.
double[][] result = MatrixCreate(matrix.Length, matrix[0].Length);
for (int i = 0; i < matrix.Length; ++i) // copy the values
for (int j = 0; j < matrix[i].Length; ++j)
result[i][j] = matrix[i][j];
return result;
}
static double[] HelperSolve(double[][] luMatrix, double[] b)
{
// before calling this helper, permute b using the perm array
// from MatrixDecompose that generated luMatrix
int n = luMatrix.Length;
double[] x = new double[n];
b.CopyTo(x, 0);
for (int i = 1; i < n; ++i)
{
double sum = x[i];
for (int j = 0; j < i; ++j)
sum -= luMatrix[i][j] * x[j];
x[i] = sum;
}
x[n - 1] /= luMatrix[n - 1][n - 1];
for (int i = n - 2; i >= 0; --i)
{
double sum = x[i];
for (int j = i + 1; j < n; ++j)
sum -= luMatrix[i][j] * x[j];
x[i] = sum / luMatrix[i][i];
}
return x;
}
static double[][] MatrixDecompose(double[][] matrix, out int[] perm, out int toggle)
{
// Doolittle LUP decomposition with partial pivoting.
// rerturns: result is L (with 1s on diagonal) and U;
// perm holds row permutations; toggle is +1 or -1 (even or odd)
int rows = matrix.Length;
int cols = matrix[0].Length; // assume square
if (rows != cols)
throw new Exception("Attempt to decompose a non-square m");
int n = rows; // convenience
double[][] result = MatrixDuplicate(matrix);
perm = new int[n]; // set up row permutation result
for (int i = 0; i < n; ++i) { perm[i] = i; }
toggle = 1; // toggle tracks row swaps.
// +1 -greater-than even, -1 -greater-than odd. used by MatrixDeterminant
for (int j = 0; j < n - 1; ++j) // each column
{
double colMax = Math.Abs(result[j][j]); // find largest val in col
int pRow = j;
//for (int i = j + 1; i less-than n; ++i)
//{
// if (result[i][j] greater-than colMax)
// {
// colMax = result[i][j];
// pRow = i;
// }
//}
// reader Matt V needed this:
for (int i = j + 1; i < n; ++i)
{
if (Math.Abs(result[i][j]) > colMax)
{
colMax = Math.Abs(result[i][j]);
pRow = i;
}
}
// Not sure if this approach is needed always, or not.
if (pRow != j) // if largest value not on pivot, swap rows
{
double[] rowPtr = result[pRow];
result[pRow] = result[j];
result[j] = rowPtr;
int tmp = perm[pRow]; // and swap perm info
perm[pRow] = perm[j];
perm[j] = tmp;
toggle = -toggle; // adjust the row-swap toggle
}
// --------------------------------------------------
// This part added later (not in original)
// and replaces the 'return null' below.
// if there is a 0 on the diagonal, find a good row
// from i = j+1 down that doesn't have
// a 0 in column j, and swap that good row with row j
// --------------------------------------------------
if (result[j][j] == 0.0)
{
// find a good row to swap
int goodRow = -1;
for (int row = j + 1; row < n; ++row)
{
if (result[row][j] != 0.0)
goodRow = row;
}
if (goodRow == -1)
throw new Exception("Cannot use Doolittle's method");
// swap rows so 0.0 no longer on diagonal
double[] rowPtr = result[goodRow];
result[goodRow] = result[j];
result[j] = rowPtr;
int tmp = perm[goodRow]; // and swap perm info
perm[goodRow] = perm[j];
perm[j] = tmp;
toggle = -toggle; // adjust the row-swap toggle
}
// --------------------------------------------------
// if diagonal after swap is zero . .
//if (Math.Abs(result[j][j]) less-than 1.0E-20)
// return null; // consider a throw
for (int i = j + 1; i < n; ++i)
{
result[i][j] /= result[j][j];
for (int k = j + 1; k < n; ++k)
{
result[i][k] -= result[i][j] * result[j][k];
}
}
} // main j column loop
return result;
}
}
}
I guess this is what you are looking for:
static double[][] MatrixInverse(double[][] matrix)
{
// assumes determinant is not 0
// that is, the matrix does have an inverse
int n = matrix.Length;
double[][] result = MatrixCreate(n, n); // make a copy of matrix
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
result[i][j] = matrix[i][j];
double[][] lum; // combined lower & upper
int[] perm;
int toggle;
toggle = MatrixDecompose(matrix, out lum, out perm);
double[] b = new double[n];
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
if (i == perm[j])
b[j] = 1.0;
else
b[j] = 0.0;
double[] x = Helper(lum, b); //
for (int j = 0; j < n; ++j)
result[j][i] = x[j];
}
return result;
}
See Test Run - Matrix Inversion Using C# for reference.

matrix, sub matrix with greatest sum

The task:
1. Make a matrix n by m and fill it with data from console.
2. Find the 3*3 sub matrix with the greatest sum.
{
static int[,] ArrayReadConsole()
{
Console.WriteLine("please enter n:");
int n;
n = Int32.Parse(Console.ReadLine());
Console.WriteLine("please enter m:");
int m;
m = Int32.Parse(Console.ReadLine());
int[,] data = new int[n, m];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
Console.WriteLine("please enter a new value");
int number;
number = Int32.Parse(Console.ReadLine());
data[i, j] = number;
}
}
return data;
}
static void SumOfPlatform(int[,] data)
{
int sum =0;
int x = 0;
int y = 0;
int maxSum = 0;
for (int i = 0; i < data.GetLength(0) - 2; i++)
{
for (int j = 0; j < data.GetLength(1) - 2; j++)
{
for (int k = 0; k < 3; k++)
{
for (int l = 0; l < 3; l++)
{
sum =+ data[i + k, j + l];
}
}
if (maxSum < sum)
{
maxSum = sum;
x = i;
y = j;
}
sum =0;
}
}
Console.WriteLine("Sum: {0}\nPosition: {1} {2}",maxSum,x,y );
}
static void Main()
{
int[,] data = ArrayReadConsole();
SumOfPlatform(data);
}
}
}
I wrote that code but something went wrong... It doesn't find position or sum of the matrix I enter. I know that 4x for loop is a bad idea just I didn't want to make another method just for that. Any idea why it doesn't work?
Your Code for SumOfPlatform is working with only change from =+ to +=
static void SumOfPlatform(int[,] data)
{
int sum = 0;
int x = 0;
int y = 0;
int maxSum = 0;
for (int i = 0; i < data.GetLength(0) - 2; i++)
{
for (int j = 0; j < data.GetLength(1) - 2; j++)
{
for (int k = 0; k < 3; k++)
{
for (int l = 0; l < 3; l++)
{
sum += data[i + k, j + l]; //only Change
}
}
if (maxSum < sum)
{
maxSum = sum;
x = i;
y = j;
}
sum = 0;
}
}
Console.WriteLine("Sum: {0}\nPosition: {1} {2}", maxSum, x, y);
}
static void Main(string[] args)
{
// int[,] data = ArrayReadConsole();
int[,] data = new int[,]
{
{1,4,6,7,3,5,7,4 },
{1,4,5,3,3,5,4,4 },
{1,1,6,2,1,5,7,4 },
{1,3,6,3,3,5,2,4 },
{1,4,6,2,3,5,3,4 },
{1,4,2,2,3,5,3,4 },
{1,4,3,3,3,5,2,4 },
{1,4,4,3,3,5,2,4 }
};
SumOfPlatform(data);
}

Method for Sorting 2D Matricies, How can i make the method generic?

public static void Sort2DArray(int[,] matrix)
{
var numb = new int[matrix.GetLength(0) * matrix.GetLength(1)];
int i = 0;
foreach (var n in matrix)
{
numb[i] = n;
i++;
}
Array.Sort(numb);
int k = 0;
for (i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
matrix[i, j] = numb[k];
k++;
}
}
}
I'm curious how can I make this method generic. I wish that it could sort double matrices, string matrices and so on and so forth.
You can use IComparable interface as a generic type T specifier.
See those links
How to Sort 2D Array in C#
How do I sort a two-dimensional array in C#?
http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=151
I have solved it. the method looks like this:
public static void Sort2DArray<T>(T[,] matrix)
{
var numb = new T[matrix.GetLength(0) * matrix.GetLength(1)];
int i = 0;
foreach (var n in matrix)
{
numb[i] = n;
i++;
}
Array.Sort(numb);
int k = 0;
for (i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
matrix[i, j] = numb[k];
k++;
}
}
}

Extension method for fill rectangular array in C#

I want write extension method for fill multidimensional rectangular array. I know how to do it for the array with a fixed number of measurements:
public static void Fill<T>(this T[] source, T value)
{
for (int i = 0; i < source.Length; i++)
source[i] = value;
}
public static void Fill<T>(this T[,] source, T value)
{
for (int i = 0; i < source.GetLength(0); i++)
for (int j = 0; j < source.GetLength(1); j++)
source[i, j] = value;
}
public static void Fill<T>(this T[,,] source, T value)
{
for (int i = 0; i < source.GetLength(0); i++)
for (int j = 0; j < source.GetLength(1); j++)
for (int k = 0; k < source.GetLength(2); k++)
source[i, j, k] = value;
}
Can I write one fill-method for all multidimensional rectangular array?
You can change the fixed dimension parameter to an Array parameter so you can put the extension on any Array. Then I used recursion to iterate through each position of the array.
public static void Fill<T>(this Array source, T value)
{
Fill(0, source, new long[source.Rank], value);
}
static void Fill<T>(int dimension, Array array, long[] indexes, T value)
{
var lowerBound = array.GetLowerBound(dimension);
var upperBound = array.GetUpperBound(dimension);
for (int i = lowerBound; i <= upperBound; i++)
{
indexes[dimension] = i;
if (dimension < array.Rank - 1)
{
Fill(dimension + 1, array, indexes, value);
}
else
{
array.SetValue(value, indexes);
}
}
}
Here's a solution that does not use recursion (and is less complex):
public static void FillFlex<T>(this Array source, T value)
{
bool complete = false;
int[] indices = new int[source.Rank];
int index = source.GetLowerBound(0);
int totalElements = 1;
for (int i = 0; i < source.Rank; i++)
{
indices[i] = source.GetLowerBound(i);
totalElements *= source.GetLength(i);
}
indices[indices.Length - 1]--;
complete = totalElements == 0;
while (!complete)
{
index++;
int rank = source.Rank;
indices[rank - 1]++;
for (int i = rank - 1; i >= 0; i--)
{
if (indices[i] > source.GetUpperBound(i))
{
if (i == 0)
{
complete = true;
return;
}
for (int j = i; j < rank; j++)
{
indices[j] = source.GetLowerBound(j);
}
indices[i - 1]++;
}
}
source.SetValue(value, indices);
}
}
This is modeled from the System.Array.ArrayEnumerator. This implementation should have a similar level of correctness as ArrayEnumerator and (based on a few spot checks) appears to function fine.

Categories