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\$
2
  • \$\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, 2018 at 22:04
  • \$\begingroup\$ @t3chb0t They are actually counters. I've edited my post and tried to explain the code. \$\endgroup\$
    – KooKoo
    Jan 21, 2018 at 0:06

1 Answer 1

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\$
1
  • \$\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, 2018 at 13:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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