Saturday, 25 November 2017

Matrix Multiplication

public static double[][] MatrixChainMultiply(List<double[][]> matrices)
{
    int[] p = new int[matrices.Count()+1];

    for (int i=0;i<=matrices.Count();i++)
    {
        if (i == 0)
        {
            p[0] = matrices[0].Length;
            p[1] = matrices[0][0].Length;
        }
        else
        {
            p[i] = matrices[i-1][0].Length;
        }
    }

    Tuple<int[][], int[][]> results = MatrixChainOrder(p);

    int[][] s = results.Item2;

    double[][] matrixmultiply =MultiplyOptimalParens(matrices, s, 1, matrices.Count());
    return matrixmultiply;
}

public static Tuple<int[][], int[][]> MatrixChainOrder(int[] p)
{
    int n = p.Length - 1;
    int[][] m = new int[n + 1][];
    int[][] s = new int[n + 1][];
    for (int i = 0; i <= n; i++)
    {
        m[i] = new int[n + 1];
        s[i] = new int[n + 1];
    }

    for (int i = 1; i <= n; i++)
    {
        m[i][i] = 0;
    }

    for (int l = 2; l <= n; l++)
    {
        for (int i = 1; i <= n - l + 1; i++)
        {
            int j = i + l - 1;
         
            m[i][j] = int.MaxValue; 
            for (int k = i; k <= j - 1; k++)
            {
                int q = m[i][k] + m[k + 1][j] + (p[i - 1] * p[k] * p[j]);
                if (q < m[i][j])
                {
                    m[i][j] = q;
                    s[i][j] = k;
                }
            }
        }
    }

    return Tuple.Create(m, s);
}

public static double[][] MultiplyOptimalParens(List<double[][]> matrices, int[][] s, int i, int j)
{
    double[][] matrix1;
    double[][] matrix2;
    if (i == j)
        return matrices[i - 1];
    else
    {
        matrix1 = MultiplyOptimalParens(matrices, s, i, s[i][j]);
        matrix2 = MultiplyOptimalParens(matrices, s, s[i][j] + 1, j);
        //multiply two matrices together
        double[][] multiply = MatrixMultiply(matrix1, matrix2);
        return multiply;
    }
}

public static double[][] MatrixMultiply(double[][] A, double[][] B)
{
    double[][] C = new double[A.Length][];
    for (int i = 0; i < A.GetLength(0); i++)
    {
        C[i] = new double[B[0].Length];
    }

    if (A[0].Length != B.Length)
    {
        throw new Exception("Incompatable Dimensions");
    }
    else
    {

        for (int i = 0; i <= A.Length - 1; i++)
        {
            for (int j = 0; j <= B[0].Length - 1; j++)
            {
                C[i][j] = 0;
                for (int k = 0; k <= A[0].Length - 1; k++)
                {
                    C[i][j] = C[i][j] + A[i][k] * B[k][j];
                }
            }
        }
    }

    return C;
}

No comments:

Post a Comment