计算矩阵指数乘法和

时间:2013-10-29 03:08:24

标签: java algorithm matrix matrix-multiplication exponential

我遇到了以下问题:

对于给定的指数N,2x2矩阵A和极限L,递归计算矩阵S:

S = I + A + A ^ 2 + A ^ 3 + ... + A ^ N

其中我是单位矩阵。

如果矩阵S的任何元素大于或等于L.减去L直到它 低于L.

我的算法如下:

// Pre-condition: 
// Parameters:
// An integer indicating an exponent
// A 2d 2x2 integer array must exist as an instance attribute
// Post-condition: The matrix resulting from the sum of multiplied matrices 
// i.e. A^2 + A^1 + I
public int[][] computeMatrixSum(int exp)
{
    if(exp == 0)
    {
        return new int[][]
        {
            new int[]{ 1,0 },
            new int[]{ 0,1 }
        };
    }
    else
    {
        int[][] matrixB = new int[matrix.length][matrix[0].length];
        int[][] matrixC = new int[matrix.length][matrix[0].length];

        matrixB = matrix;

        for(int expC = exp; expC > 1; expC--)
        {
            // Multiply the matrix
            for(int i = 0; i < matrix.length; i++)
            {
                for(int k = 0; k < matrixB[0].length; k++)
                {
                    for(int j = 0; j < matrix[0].length; j++)
                    {
                        matrixC[i][k] += matrix[i][j] * matrixB[j][k];
                    }
                }
            }
            matrixB = matrixC;
            matrixC = new int[matrix.length][matrix[0].length];
        }

        // Recursively calculate the sum of the other matrix products
        int[][] tmpSum = computeMatrixSum(exp-1);

        int[][] matrixSum = new int[matrixB.length][matrixB[0].length];

        for(int row = 0; row < matrixB.length; row++)
        {
            for(int col = 0; col < matrixB[0].length; col++)
            {
                matrixSum[row][col] = matrixB[row][col] + tmpSum[row][col];
            }
        }

        return matrixSum;
    }
}

// Pre-condition:
// Parameters: 
// An integer indicating the exponent to apply on the matrix
// An integer indicating the limit of the elements of the 2d matrix sum
// An 2d 2x2 integer array must exist as an instance attribute
// Post-condition: The matrix resulting from the sum of multiplied matrices
// that has elements that are not greater than the given limit
// i.e. A^2 + A^1 + I
public int[][] solve(int exp,int limit)
{
        int[][] matrixSum = computeMatrixSum(exp);

        for(int row = 0; row < matrixSum.length; row++)
        {
            for(int col = 0; col < matrixSum.length; col++)
            {
                while(matrixSum[row][col] >= limit)
                    matrixSum[row][col] -= limit;
            }
        }

        return matrixSum;
}

我的算法有效。但是对于大的N值来说,它太慢了。这是因为当我乘以它时,我会不断重新计算所有指数的结果。

我不知道任何其他算法可以更有效地解决这个问题。

有人可以提出建议吗?

感谢。

2 个答案:

答案 0 :(得分:1)

您可以应用Horner's method将“单项形式转换为计算效率形式”,如多项式的示例herehere所示。您可以利用JScienceMatrix来简化编码。

答案 1 :(得分:1)

如果A-I是可逆的,那么你可以找到与几何序列完全相同的S,只记住你必须乘以逆而不是除以:

S = I + A + A^2 + A^3 + ... + A^N
AS = A + A^2 + A^3 + ... + A^N + A^{N+1}
AS-S = A^{N+1}-I
(A-I)S = A^{N+1}-I
S = (A-I)^{-1} (A^{N+1}-I)

如果N真的很大,那么你会想要exponentiate by squaring。尽管您可能希望使用模数运算符,但L减少很容易。

如果A-I是单数,则此方法不起作用,我能想到的最佳方法是使用A的{​​{3}}(这也适用于第一个如果你愿意的话。)