Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
I wonder if anyone has a matrix multiplication algorithm made in SQL. I know you'll wonder why I need it: to compare the speed with C# algorithm and also to see the complexity associated with SQL script defining a matrix multiplication. I'm intending to move to SQL and define many methods I have already done in C# to SQL since I find it faster in my specific cases.
Thanks
public static double[,] MMult(double[,] matrixA, double[,] matrixB)
{
int n = matrixA.GetLength(0); //rows
int m = matrixA.GetLength(1); //columns
int a = matrixB.GetLength(0); //rows
int b = matrixB.GetLength(1); //columns
double[,] MM = new double[n, b];
if (m == a)
{
int k = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < b; j++)
{
while (k < m)
{
MM[i, j] += matrixA[i, k] * matrixB[k, j];
k++;
}
k = 0;
}
}
return MM;
}
else
{
MatrixDimensionsException ex = new MatrixDimensionsException(DateTime.Now,
"Columns of the first matrix is not equal to the rows of the second matrix!",
"Matrix-Multiplication Error Message");
throw ex;
}
}
static double[,] Multiply(double[,] matrixA, double[,] matrixB, int nPartitions)
{
int nrowsA = matrixA.GetLength(0);
int ncolsA = matrixA.GetLength(1);
int nrowsB = matrixB.GetLength(0);
int ncolsB = matrixB.GetLength(1);
double[,] resM = new double[nrowsA, ncolsB];
int rowPartitionSize = nrowsA / nPartitions;
Task[] tasks = new Task[nPartitions];
// I prefer to use this in case I want to add a scheduler later on, i.e. to restrict
// the degree of parallelism
TaskFactory factory = new TaskFactory();
Action<int, int> multiplier = new Action<int, int>
(
(int fromIndex, int toIndex) =>
{
for (int i = fromIndex; i < toIndex; i++)
{
for (int k = 0; k < ncolsB; k++)
{
double sum = 0;
for (int l = 0; l < nrowsB; l++)
{
sum += matrixA[i, l] * matrixB[l, k];
}
// locking shouldn't be required - no concurrent access to
// same element in array possible
resM[i, k] = sum;
}
}
}
);
for (int iTask = 0; iTask < nPartitions; iTask++)
{
int start = iTask * rowPartitionSize;
int end = (iTask + 1) * rowPartitionSize;
tasks[iTask] = factory.StartNew(() => multiplier(start, end));
}
Task.WaitAll(tasks );
return resM;
}
It should work, but assumes that the number of rows in matrixA are even.
Sticking to your example, this is a way to parallelize it. It's not perfect and could be improved. I just cooked this up so it isn't tested. It should work, but assumes that the number of rows in matrixA are even. Not difficult to generalise it.
Code:static double[,] Multiply(double[,] matrixA, double[,] matrixB, int nPartitions) { int nrowsA = matrixA.GetLength(0); int ncolsA = matrixA.GetLength(1); int nrowsB = matrixB.GetLength(0); int ncolsB = matrixB.GetLength(1); double[,] resM = new double[nrowsA, ncolsB]; int rowPartitionSize = nrowsA / nPartitions; Task[] tasks = new Task[nPartitions]; // I prefer to use this in case I want to add a scheduler later on, i.e. to restrict // the degree of parallelism TaskFactory factory = new TaskFactory(); Action<int, int> multiplier = new Action<int, int> ( (int fromIndex, int toIndex) => { for (int i = fromIndex; i < toIndex; i++) { for (int k = 0; k < ncolsB; k++) { double sum = 0; for (int l = 0; l < nrowsB; l++) { sum += matrixA[i, l] * matrixB[l, k]; } // locking shouldn't be required - no concurrent access to // same element in array possible resM[i, k] = sum; } } } ); for (int iTask = 0; iTask < nPartitions; iTask++) { int start = iTask * rowPartitionSize; int end = (iTask + 1) * rowPartitionSize; tasks[iTask] = factory.StartNew(() => multiplier(start, end)); } Task.WaitAll(tasks ); return resM; }