1
\$\begingroup\$

I've just written a recursive matrix multiplication and I want to know my mistakes or problems. Is there a better way doing this?

public static double[,] Multiply(double[,] a, double[,] b, int rowA,int colA,int rowB,int colB, double[,] c)
{
    double[,] result = new double[a.GetLength(0), b.GetLength(1)];

    if (c != null)
        result = c;

    result[rowA, colB] += a[rowA, colA] * b[rowB, colB];

    colA += 1;
    rowB += 1;
    if (colA >= a.GetLength(1))
    {
        colA = 0;
        rowB = 0;
        rowA += 1;
        if(rowA >= a.GetLength(0))
        {
            rowA = 0;
            colB += 1;
        }
    }

    if (colB >= b.GetLength(1))
        return result;

    return Multiply(a, b, rowA, colA, rowB, colB, result);
}

Edit: The rowA, colA variables are the indices for the element of the first matrix which is multiplied by the [rowB, colB] element of the second matrix. Then we increase colA and rowB so we can multiply the next elements of the matrices.

When the colA reaches the end of the matrix (it is obvious that rowB has also reached the end of the second matrix) we reset them to 0 and move to the next row of the first matrix. when we reach the last row of the first matrix we move to the next column of the second matrix by increasing colB by 1; We then set rowA to 0 so that the multiplication begins from the first row of the first matrix again.

Finally, if colB exceeds the end column of the second matrix we have finished multiplying and we return our result.

Edit 2:

public static double[,] Multiply(double[,] a, double[,] b, int rowA,int colA,int rowB,int colB, double[,] c)
{
    double[,] result;
    if (c != null)
        result = c;
    else
        result = new double[a.GetLength(0), b.GetLength(1)];

    result[rowA, colB] += a[rowA, colA] * b[rowB, colB];

    colA += 1;
    rowB += 1;
    if (colA >= a.GetLength(1))
    {
        colA = 0;
        rowB = 0;
        rowA += 1;
        if(rowA >= a.GetLength(0))
        {
            rowA = 0;
            colB += 1;
        }
    }

    if (colB >= b.GetLength(1))
        return result;

    return Multiply(a, b, rowA, colA, rowB, colB, result);
}
\$\endgroup\$
  • \$\begingroup\$ Could you explain what the rowA and other similar variables are actually for? It's hard to figure it out. Their names are not the best ones. \$\endgroup\$ – t3chb0t Jan 20 '18 at 22:04
  • \$\begingroup\$ @t3chb0t They are actually counters. I've edited my post and tried to explain the code. \$\endgroup\$ – KooKoo Jan 21 '18 at 0:06
2
\$\begingroup\$

You're allocating a new result matrix every time, then almost always throwing it away. Only allocate one if the passed in c matrix is null.

Since you're recursion comes at the end (tail recursion), this could be changed over from recursion to a loop. If your matrix is too large, the recursion depth will be too deep and you'll run out of stack space. This won't happen with a loop.

\$\endgroup\$
  • \$\begingroup\$ for the second part of your answer, the problem should be solved using recursion. and this is the reason I posted it here. I've done this using three for loops many times. but this is the first time I am using recursion to do the multiplication. and I'm not really sure if my solution is good. thanks \$\endgroup\$ – KooKoo Jan 21 '18 at 13:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.