C 如何在Ax=b中生成非常大的非奇异矩阵a?

C 如何在Ax=b中生成非常大的非奇异矩阵a?,c,matrix,linear-algebra,C,Matrix,Linear Algebra,我用雅可比方法求解线性代数方程组Ax=b,但采用人工输入。我想分析大型系统解算器的性能。是否有任何方法生成矩阵A,即非奇异矩阵? 我在这里附上我的代码 #include<stdio.h> #include<stdlib.h> #include<math.h> #define TOL = 0.0001 void main() { int size,i,j,k = 0; printf("\n enter the number of equations:

我用雅可比方法求解线性代数方程组Ax=b,但采用人工输入。我想分析大型系统解算器的性能。是否有任何方法生成矩阵A,即非奇异矩阵? 我在这里附上我的代码

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

#define TOL = 0.0001

void main()
{
  int size,i,j,k = 0;
  printf("\n enter the number of equations: ");
  scanf("%d",&size);
  double reci = 0.0;
  double *x = (double *)malloc(size*sizeof(double));
  double *x_old = (double *)malloc(size*sizeof(double));

  double *b = (double *)malloc(size*sizeof(double));
  double *coeffMat = (double *)malloc(size*size*sizeof(double));

  printf("\n Enter the coefficient matrix: \n");

  for(i = 0; i < size; i++)
  {
    for(j = 0; j < size; j++)
    {
      printf(" coeffMat[%d][%d] = ",i,j);
      scanf("%lf",&coeffMat[i*size+j]);
      printf("\n");
      //coeffMat[i*size+j] = 1.0;
    }
  }

  printf("\n Enter the b vector: \n");

  for(i = 0; i < size; i++)
  {
    x[i] = 0.0;
    printf(" b[%d] = ",i);
    scanf("%lf",&b[i]);    
  }

  double sum = 0.0;

  while(k < size)
  {

    for(i = 0; i < size; i++)
    {
      x_old[i] = x[i];
    }

    for(i = 0; i < size; i++)
    {
      sum = 0.0;
      for(j = 0; j < size; j++)
      {
        if(i != j)
        {
          sum += (coeffMat[i * size + j] * x_old[j] );
        }
      }

      x[i] = (b[i] -sum) / coeffMat[i * size + i];

    }

    k = k+1;
  }

  printf("\n Solution is: ");

  for(i = 0; i < size; i++)
  {
    printf(" x[%d] = %lf \n ",i,x[i]);
  } 
}
#包括
#包括
#包括
#定义TOL=0.0001
void main()
{
整数大小,i,j,k=0;
printf(“\n输入公式数:”);
scanf(“%d”,大小(&S);
双累进系数=0.0;
double*x=(double*)malloc(size*sizeof(double));
double*x_old=(double*)malloc(size*sizeof(double));
double*b=(double*)malloc(size*sizeof(double));
double*coeffMat=(double*)malloc(size*size*sizeof(double));
printf(“\n输入系数矩阵:\n”);
对于(i=0;i
评论中提到了哪种方法可能是正确的(至少在原则上,并且是完全通用的)

然而,您可能没有处理“非常大”的矩阵(例如,因为您的程序使用了幼稚的算法,并且因为您没有在具有大量RAM的大型超级计算机上运行它)。因此,生成具有随机系数的矩阵并随后测试其非奇异性的简单方法可能就足够了

非常大的矩阵会有几十亿个系数,你需要一台功能强大的超级计算机,比如TB级的RAM。你可能没有,如果你有,你的程序可能会运行太长时间(你没有任何并行性),可能会给出非常错误的结果(阅读更多),所以你不在乎

按照当前的硬件标准,一百万个系数(例如1024*1024)的矩阵被认为很小(足以在当前的笔记本电脑或台式机上测试代码,甚至可以测试一些并行实现),并且随机生成其中一些系数(并计算其行列式以测试它们是否奇异)就足够了,而且容易实现。您甚至可以生成它们和/或使用一些外部工具检查它们的规律性,例如,等等。一旦您的程序计算出一个解x0,您可以使用一些工具(或编写另一个程序)来计算Ax0-b,并检查它是否非常接近0向量(在某些情况下,您可能会感到失望或惊讶,因为这很重要)

你需要一些足够好的东西,也许像那些被认为已经过时的东西一样简单(你应该找到并使用更好的东西);您可以使用一些随机源(例如Linux上的
/dev/uradom
)为其种子

顺便说一句,用所有警告和调试信息编译代码(例如,
gcc-Wall-Wextra-g
)。您的
#define TOL=0.0001
可能是错误的(应该是
#define TOL 0.0001
const double TOL=0.0001;
)。使用调试器(
gdb
)&。在基准测试时添加优化(
-O2-mcpu=native
)。阅读每个已使用函数的文档,尤其是来自。从
scanf
检查结果计数。。。在C99中,您不应该强制转换malloc的结果,但是您忘记了测试它的失败,因此代码:

double *b = malloc(size*sizeof(double));
if (!b) {perror("malloc b"); exit(EXIT_FAILURE); };
您宁愿使用
\n
结束而不是开始
printf
控制字符串,因为
stdout
通常(并非总是!)行缓冲。另请参见
fflush

你可能还应该读一些基本的线性代数教科书


请注意,实际上编写健壮高效的程序来反转矩阵或求解线性系统是一门很难的艺术(我一点也不知道:它有编程问题、算法问题和数学问题;读一些书)。你仍然可以获得一个博士学位,然后用你的一生来研究它。请理解您需要(或许多其他东西)。

这是一个有点希思·罗宾逊的故事,但这里是我用过的。我不知道这些矩阵是如何“随机”的,特别是我不知道它们遵循什么分布

其思想是生成矩阵的奇异值分解。(以下称为A,假设为nxn)

将A初始化为所有0

然后生成n个正数,用随机符号将它们放在A的对角线上。我发现能够控制这些正数中最大值与最小值的比率很有用。该比率将是矩阵的条件数

然后重复n次:生成一个随机的n向量f,将左侧的a乘以Householder反射器I-2*f*f'/(f'*f)。注意,这可以比通过形成反射器矩阵和进行正规乘法更有效地进行;事实上,编写一个给定f和a的例程将就地更新a是很容易的

重复上述步骤,但在右侧进行乘法运算


至于生成测试数据,一个简单的方法是选择一个x0,然后生成b=a*x0。不要期望从你的解决者那里得到确切的回报;即使它表现得非常好,您也会发现,随着条件数的增加,错误会越来越大。

-我认为这就是Linpack基准测试所使用的。您的解算器应该能够检测奇异性,奇异矩阵应该是测试套件的一部分。谢谢。我还有其他问题,我们如何检查索尔