计算矩阵的n次方

时间:2018-02-19 03:22:07

标签: c++ math matrix linear-algebra exponential

我试图优化我的代码来计算矩阵的n次幂。

在我拨打1 n次之前,这太慢了。问题是,它构建得很好,但是当我运行它时,我的退出值void multiplySquare(long long A[2][2], long long B[2][2]){ long long result[2][2]; for (int i = 0; i < 2; i++){ for (int j = 0; j < 2; j++){ result[i][j] = 0; for (int k = 0; k < 2; k++){ result[i][j] += A[i][k] * B[k][j]; } } } for (int i=0; i<2; i++){ for (int j=0; j<2; j++){ A[i][j] = result[i][j]; } } } void power(long long A[2][2], long long B[2][2], long long n){ if(n/2 != 0){ power(A, B, n/2); } if(n%2 != 0){ multiplySquare(A, B); } } 失败了。我相信我的算法是正确的,所以导致这种情况的原因是什么?

[编辑]添加了递归终止条件,但仍然存在相同的错误。

[再次编辑]我再次重新编写了递归部分,现在它似乎可以工作,但仅适用于{{1}}的某些输入。我不得不更多地玩弄它。任何帮助,将不胜感激。

{{1}}

3 个答案:

答案 0 :(得分:4)

有效计算数字N x次幂的算法是:

如果N为零,请返回1 如果N为1,请返回x 计算(N/2) - 权力。 y = x^(N/2)
如果N为偶数,请返回y*y
如果N为奇数,请返回x*y*y

如果您将该逻辑转换为您的案例,您将需要以下内容:

// Assuming that the result is returned in B.
void power(long long A[2][2], long long B[2][2], long long n)
{
   if ( n == 0 )
   {
      makeIdentity(B);
      return;
   }

   if ( n == 1 )
   {
      assign(A, B);  // Make B same as A.
      return;
   }

   power(A, B, n/2);

   multiplySquare(B, B);
   if(n % 2 != 0)
   {
      multiplySquare(B, A);
   }
}

答案 1 :(得分:4)

  

我试图优化我的代码来计算矩阵的n次幂。

由于您的目标是优化,因此考虑对角矩阵具有微不足道的n次幂,即主对角线元素的第n次幂可能是一件好事。

所以,首先你应该对你的矩阵进行对角化。一种方法是找到初始矩阵A的特征向量和特征值,并利用以下关系:

A = P D P -1

其中P是包含A,P -1 的(列)特征向量的矩阵  是它的逆,D是包含特征值的对角矩阵。

然后: n = P D n P -1

上述等式:

  1. 将A带到一个上升到n次幂的地方是微不足道的。
  2. 计算第n次幂。
  3. 返回A返回原始位置。

答案 2 :(得分:1)

看来你的片段不是你的目标。我猜想你的意思是这样的:

void power(long long A[2][2], long long B[2][2], long long n){
    if (n == 1) {
        multiplySquare(A, B);
    }
    else if(n % 2 == 0) {
        power(A, B, n / 2);
        multiplySquare(A, A);
    }
    else {
        power(A, B, (n - 1) / 2);
        multiplySquare(A, A);
        multiplySquare(A, B);
    }