繁体   English   中英

将矩阵提升到c中的幂

[英]raise a Matrix to the power in c

试图将矩阵提升到p的幂,但我没有发现错误。 任何人都可以帮助解释这个问题吗? 我刚刚开始用C编程,所以非常感谢你的帮助。 用户应该输入一个矩阵,它应该被提升到p的幂。

int main() {
    int n, p;
    printf("Number of Rows/Colums of square matrix: ");
    scanf("%d", &n);
    printf("to the power of: ");
    scanf("%d", &p);
    int m[n][n];
    int r[n][n];

    printf("Elements\n");
    for (int b = 0; b < n; b++) {
        for (int d = 0; d < n; d++) {
            printf("[%d][%d] = ", b + 1, d + 1);
            scanf("%d", &m[b][d]);
        }
    }

    int sum = 0;
    for (int i = 0; i < p; i++) {
        for (int b = 0; b < n; b++) {
            for (int d = 0; d < n; d++) {
                for (int k = 0; k < n; k++) {
                    sum += m[b][k] * m[k][d];
                }
                r[b][d] = sum;
                sum = 1;
            }
        }

        for (int b = 0; b < n; b++) {
            for (int d = 0; d < n; d++) {
                m[b][d] = r[b][d];
                r[b][d] = 0;
            }
        }
    }

    printf("RESULT:-\n");

    for (int c = 0; c < n; c++) {
        for (int d = 0; d < n; d++) {
            printf("%d   ", m[c][d]);
        }
        printf("\n");
    }

    getch();
    return 0;
}

您的程序逻辑在几个级别上都是错误的。

这是你纠正的程序。 仍然有改进的余地(将代码分解为函数,使用更好的变量命名,使用比粗体矩阵乘法更有效的算法,正确处理p为0的情况),但我尽可能地坚持使用原来错误的实施。

这是方法:我们有三个矩阵: r结果, m是用户提供的矩阵, temp是临时矩阵。

  1. 最初我们将m复制到r ,这是p = 1的结果
  2. 我们重复步骤3和4 p - 1
  3. 我们将rm相乘并将结果放入temp
  4. 我们将temp复制到r
  5. 现在r包含m提高到的功率p

#include <stdio.h>

int main() {
  int n, p;
  printf("Numer of Rows/Colums of sq matrix: ");
  scanf("%d", &n);
  printf("to the power of: ");
  scanf("%d", &p);
  int m[n][n];
  int r[n][n];
  int temp[n][n];

  printf("Elements\n");
  for (int b = 0; b < n; b++) {
    for (int d = 0; d < n; d++) {
      printf("[%d][%d] = ", b + 1, d + 1);
      scanf("%d", &m[b][d]);
    }
  }

  // r = m
  // temp = m
  for (int b = 0; b < n; b++) {
    for (int d = 0; d < n; d++) {
      r[b][d]   = m[b][d];
    }
  }

  for (int i = 0; i < p - 1; i++)  // p - 1 because for p = 1, r already 
  {                                // contains the result
    int sum = 0;

    // temp = r * m
    for (int b = 0; b < n; b++)
    {
      for (int d = 0; d < n; d++)
      {
        for (int k = 0; k < n; k++)
        {
          sum += m[b][k] * r[k][d];
        }
        temp[b][d] = sum;
        sum = 0;
      }
    }

    // r = temp
    for (int b = 0; b < n; b++) {
      for (int d = 0; d < n; d++) {
        r[b][d] = temp[b][d];
      }
    }
  }

  printf("RESULT:\n");

  for (int c = 0; c < n; c++)
  {
    for (int d = 0; d < n; d++)
    {
      printf("%d   ", r[c][d]);
    }
    printf("\n");
  }

  return 0;
}

我认为你的代码中存在各种逻辑问题。

外环是错误的,因为你循环一次减去电量。

其次,您需要一个缓冲矩阵,就像编写代码一样。

另一个问题是,当您将行/列值相乘时,始终使用原始矩阵。 这在逻辑上是错误的,您需要将当前功率计算的矩阵乘以原始矩阵。

我也不明白为什么你将sum变量重置为1而不是0。

这样的事情应该有效:

#include <stdio.h>

int main() {
int n, p;
printf("Numer of Rows/Colums of sq matrix: ");
scanf("%d", &n);
printf("to the power of: ");
scanf("%d", &p);
int m[n][n];
int r[n][n];
int tmp[n][n];

printf("Elements\n");
for ( int b = 0 ; b < n ; b++ ) {
    for ( int d = 0 ; d < n ; d++ ) {
        printf("[%d][%d] = ", b+1, d+1);
        scanf("%d", &m[b][d]);
        r[b][d] = m[b][d];
    }
}

int sum = 0;
//you loop 1 time less of the power
for (int i = 0; i < p - 1; i++)
{
    for ( int b = 0 ; b < n ; b++ )
    {
        for (int d = 0 ; d < n ; d++ )
        {
            for (int k = 0 ; k < n ; k++ )
            {
                sum += r[b][k]*m[k][d];
            }
            tmp[b][d] = sum;
            sum = 0;
        }
    }

    for ( int b = 0 ; b < n ; b++ ) {
        for ( int d = 0 ; d < n ; d++ ) {
            //m[b][d] = r[b][d];
            r[b][d] = tmp[b][d];
        }
    }
}

printf("RESULT:-\n");

for (int c = 0 ; c < n ; c++ )
{
    for (int d = 0 ; d < n ; d++ )
    {
        printf("%d   ", r[c][d]);
    }
    printf("\n");
}

getchar();
return 0;
}

我只想指出,这个解决方案可能不适用于p <1

我建议你将这个复杂的问题分解成更小的问题。

创建较小的函数,测试它们以确保它们正常工作,然后进行下一步调用,直到完成整个集合。

你需要从一个矩阵开始: a[m][n] 它所持有的值应该是整数,浮点数,双精度数吗? 确保您可以创建不同大小的矩阵。 您对行和列的限制应该是什么?

从读取和写入矩阵的方法开始。

接下来是一起将多个两个基质结合在一起的方法: c[m][n] = a[m][k]*b[k][n] a的列数与b的行数匹配,或者无法相乘。

将矩阵提升为整数幂p > 1意味着将起始矩阵乘以p次。 你能看出一个要求是起始矩阵必须是正方形吗? (#rows ==#columns)如果不是这样,你就不能提升到整数幂。

你需要一个循环来提升p次幂。 每次循环时c = mult(a, b)您将调用矩阵乘法c = mult(a, b) 每次传递将获取前一次调用的输出并使其成为调用中的第一个矩阵: c = mult(c, b)

如果你以这种方式攻击问题,你应该能够解决它。 在继续之前,请务必仔细测试每个步骤。

这称为分解。 它是解决问题的基础,特别是计算机科学。

您的代码中存在多个问题:

  • 你应该使用临时矩阵t来计算r * m的结果,并在下一步之前将其复制到r
  • sum应重新初始化为0或更好,在k循环之前初始化为0

这是一个更正版本:

#include <stdio.h>

int main() {
    int n, p;
    printf("Number of Rows/Colums of square matrix: ");
    if (scanf("%d", &n) != 1 || n <= 0)
        return 1;
    printf("to the power of: ");
    if (scanf("%d", &p) != 1 || p < 0)
        return 1;

    int m[n][n];
    int r[n][n];
    int t[n][n];

    printf("Elements\n");
    for (int b = 0; b < n; b++) {
        for (int d = 0; d < n; d++) {
            printf("[%d][%d] = ", b + 1, d + 1);
            if (scanf("%d", &m[b][d]) != 1)
                return 1;
            r[b][d] = b == d; // initialize r to identity matrix
        }
    }
    for (int i = 0; i < p; i++) {
        for (int b = 0; b < n; b++) {
            for (int d = 0; d < n; d++) {
                int sum = 0;
                for (int k = 0; k < n; k++) {
                    sum += r[b][k] * m[k][d];
                }
                t[b][d] = sum;
            }
        }
        for (int b = 0; b < n; b++) {
            for (int d = 0; d < n; d++) {
                r[b][d] = t[b][d];
            }
        }
    }

    printf("RESULT:\n");
    for (int c = 0; c < n; c++) {
        for (int d = 0; d < n; d++) {
            printf("%3d ", r[c][d]);
        }
        printf("\n");
    }
    return 0;
}

笔记:

  • 上述代码适用于正幂,包括产生单位矩阵的0

  • 但请注意,对于大功率,此方法效率低,无论如何, int很可能会溢出大功率。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM