提问者:小点点

用带特征的C-style阵列求矩阵逆


我用C语言编写了大约1000行线性规划求解器(内点算法)的代码。我意识到我需要使用特征来计算矩阵的逆,所以现在我用C++运行代码(看起来运行得很好)。现在我有了一堆以C格式声明的数组,例如:

在我的程序中,我做了一堆矩阵计算,然后需要在某个点找到一个矩阵的逆,我们称之为矩阵。要使用特征,我需要让它以一种特殊的特征矩阵格式来调用函数m.inverse,如下所示:

//cout << "The inverse of L is:\n" << L.inverse() << endl;

我的目标是找到一条路。。。任何方法,把我的数据从L到Eigen会接受的格式,这样我就可以运行这个东西了。我花了两个小时研究这个问题,但一无所获。:-(我对C语言还是个新手,所以请尽可能深入。我想要最简单的方法。我读过关于映射的知识,但我不太清楚指针(它似乎是一个完整的部分)。有没有一种方法可以循环遍历每一行和每列,然后将它们复制到特征矩阵中?

当我问的时候,我是否需要将得到的特征矩阵转换回C数组?这一过程将如何运作?提前感谢您的任何帮助!我花了大约50-60个小时在这上面,这周就要交了!这是我需要做的最后一件事,我将完成我的学期项目。这是一门数学课,所以编程方面的东西对我来说有点模糊,但我学到了很多。

可能的相关信息:-运行在Windows 10 i7处理器Sony VAIO上-用C++中的代码块编译,但最初是用C编写的-这段代码都是在一个while循环中,可能会迭代10次左右。--每次迭代都需要为这个矩阵L计算矩阵逆,每次的数据都会不一样。

请救命!我愿意学习,但我需要指导,而且这门课是在线的,所以我几乎没有。提前谢谢你!

编辑-我看到了这一点,并试图实现它,但没有效果,但它似乎是解决办法,如果我能弄清楚这一点:

“假设您有一个数组,其大小为nRows x ncols。

double *X; // non-NULL pointer to some data

您可以使用映射功能创建nRows x nCols大小的双矩阵,如下所示:

MatrixXd eigenX = Map<MatrixXd>( X, nRows, nCols );

映射操作将现有存储器区域映射到特征数据结构中。像这样的单行允许避免编写矩阵创建的丑陋代码,用于循环,以良好的顺序复制每个元素等。“

这似乎是一个不错的解决方案,但我不知道如何使用“指向某些数据”的“双*X”。我开始查找指针之类的东西,但这并没有帮助我弄清楚-我看到了各种关于指向多维数组的东西,似乎没有帮助。

我也不太明白第二行的格式。是不是每个大写X都和前面一行中的矩阵*X一样?为此我需要声明/创建什么?或者有没有更简单的方法来完成这一切?

编辑2:这是我的程序中的内容,本质上--这是显着缩小的,抱歉,如果它仍然太长。

#include <iostream>
#include <Eigen/Dense>

using namespace Eigen;
using namespace std;

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

typedef Matrix<double, 30, 30> Matrix30d;

double L[30][30] ={{0}};
double Ax[30][30] = {{0}};          //[A] times [x]                                                        
double At[30][30] = {{0}};          //A transpose
double ct[30][30] = {{0}};         //c transpose                                                                   
double x[30][30] = {{0}};          //primal solution                                                                  
double w[30][30] = {{0}};          //omega, dual solution                                                                 
double s[30][30] = {{0}};          //dual slack                                                             
double u[30][30] = {{0}};          //[c]t - [A]t x [w] - [s]                                                                  
double Atxw[30][30] = {{0}};       //A transpose times omega                                                             
double t[30][30] = {{0}};          //RHS - [A]x[x]                                                              
double v[30][30] = {{0}};          //mu - xij * sij                                                               
double p[30][30] = {{0}};          //vij / xij                                                             
double D2[30][30] = {{0}};         //diagonal of xij/sij                                                               
double AD2[30][30] = {{0}};       //[A] x [D2]                                                                
double AD2xAt[30][30] = {{0}};      //[AD2] x [At]                                                           
double uminp[30][30] = {{0}};      //[u] - [p]                                                            
double AD2xuminp[30][30] = {{0}};    //[AD2] x [uminp]                                                         
double z[30][30] = {{0}};           //[AD2] x [uminp] + [t]                                                              
double Atxdw[30][30] = {{0}};      //[At] x [dw]                                                            
double xt[30][30] = {{0}};         //x transpose                                                            
double bt[30][30] = {{0}};        //b transpose                                                                
Matrix30d Inv;                  //C++ style matrix for Eigen, maybe needed?

int main(){

int r1;                      //rows of A
int c1;                      //columns of A                                                     
int i;                       //row and column counters
int j;                                                                             
int k;
double sum = 0;
double size;                 //size of square matrix being inverted [L]                                                         
double *pointer[30][30];

FILE *myLPproblem;                     

myLPproblem = fopen("LPproblem.txt", "r");   //Opens file and reads in data

float firstLine[4];
int Anz;

for (i = 0; i < 4; i++)
{
    fscanf(myLPproblem, "%f", &firstLine[i]);
}

r1 = firstLine[0];
c1 = firstLine[1];
Anz = firstLine[2];

double A[r1][c1];
double b[r1][1];
double c[1][c1];
int Ap[c1+1];
int Ai[Anz];
double Ax2[Anz];

for(i=0; i<r1; i++){
   for(j=0; j<c1; j++){
     A[i][j]=0;
   }
}

for (i = 0; i < (c1 + 1); i++)
{
    fscanf(myLPproblem, "%d", &Ap[i]);
}

for (i = 0; i < (Anz); i++)
{
    fscanf(myLPproblem, "%d", &Ai[i]);
}

for (i = 0; i < (Anz); i++)
{
    fscanf(myLPproblem, "%lf", &Ax2[i]);
}

for (i = 0; i < (r1); i++)
{
    fscanf(myLPproblem, "%lf", &b[i][0]);
}

for (i = 0; i < (c1); i++)
{
    fscanf(myLPproblem, "%lf", &c[0][i]);
}

fclose(myLPproblem);

int row;
double xval;
int Apj;
int Apj2;

for(j=0; j<c1; j++){

Apj = Ap[j];
Apj2 = Ap[j+1];

for(i=Apj; i<Apj2; i++){
    row = Ai[i];
    xval = Ax2[i];
    A[row][j] = xval;
}
}

size = r1;

for(i=0; i<c1; i++)                        //Create c transpose                                                            
{
    ct[i][0] = c[0][i];
}

for(i=0; i<r1; i++)                       //Create b transpose                                                        
{
    bt[i][0] = b[0][i];
}

for(i=0; i<c1; i++)                        //Create A transpose                                                          
   {
   for(j=0; j<r1; j++)
   {
    At[i][j] = A[j][i];
   }
}

while(1){                                   //Main loop for iterations

for (i = 0; i <= r1; i++) {               //Multiply [A] times [x]                                         
  for (j = 0; j <= 1; j++) {
     sum = 0;
     for (k = 0; k <= c1; k++) {
        sum = sum + A[i][k] * x[k][j];
     }
     Ax[i][j] = sum;
  }
}

sum = 0;                         //Multiply [At] times [w]                                                                   

for (i = 0; i <= c1; i++){
  for (j = 0; j <= 1; j++) {
     sum = 0;
     for (k = 0; k <= r1; k++) {
        sum = sum + At[i][k] * w[k][j];
     }
     Atxw[i][j] = sum;
  }
}

for(i=0; i<c1; i++)                 //Subtraction to create matrix u                                                  
{for(j=0; j<1; j++)
    {
     u[i][j] = (ct[i][j]) - (Atxw[i][j]) - (s[i][j]);
    }
}

for(i=0; i<r1; i++)                     //Subtraction to create matrix t                                                      
{for(j=0; j<1; j++)
    {
     t[i][j] = (b[i][j]) - (Ax[i][j]);
    }
}

for(i=0; i<c1; i++)              //Subtract and multiply to make matrix v                                                  
{for(j=0; j<1; j++)
    {
     v[i][j] = mu - x[i][j]*s[i][j];
    }
}

for(i=0; i<c1; i++)               //create matrix p                                                             
{for(j=0; j<1; j++)
    {
     p[i][j] = v[i][j] / x[i][j];
    }
}

for(i=0; i<c1; i++)                //create matrix D2                                                              
{for(j=0; j<c1; j++)
    {
     if(i == j){
     D2[i][j] = x[i][0] / s[i][0];
     }else{
     D2[i][j] = 0;
     }
    }
}

sum = 0;                                                                        

for (i = 0; i <= r1; i++) {           //Multiply [A] times [D2]
  for (j = 0; j <= c1; j++) {
     sum = 0;
     for (k = 0; k <= c1; k++) {
        sum = sum + A[i][k] * D2[k][j];
     }
     AD2[i][j] = sum;
  }
}

sum = 0;                                                                        

for (i = 0; i <= r1; i++) {     //Multiply [AD2] times [At], to be inverted!
  for (j = 0; j <= r1; j++) {
     sum = 0;
     for (k = 0; k <= c1; k++) {
        sum = sum + AD2[i][k] * At[k][j];
     }
     AD2xAt[i][j] = sum;
  }
}

//Here is where I need to calculate the inverse (and determinant probably)     of matrix AD2xAt.  I'd like to inverse to then be stored as [L]. 
//cout << "The determinant of AD2xAt is " << AD2xAt.determinant() << endl;
//cout << "The inverse of AD2xAt is:\n" << AD2xAt.inverse() << endl;

printf("\n\nThe inverse of AD2xAt, L, is : \n\n");   //print matrix L                               

 for (i=0; i<size; i++)
 {
     for (j=0; j<size; j++)
     {
         printf("%.3f\t",AD2xAt[i][j]);
     }
     printf("\n");
 }
}

return 0;
}

简单来说,它从一个文件中读取矩阵,计算一堆矩阵,然后需要将AD2xAt反相并存储为L.关键部分在末尾,我需要在那里进行反相(滚动到底部--我已经对其进行了注释)。


共1个答案

匿名用户

您尝试过(A0,30,30).inverse()/code>吗?? ggael

你的提议似乎可以同时兼顾这两个问题?

右,()/code>返回特征的,在该特征上调用方法

请问A后面的[0]是什么?

是数组下标运算符,指定是矩阵的初始行,转换为指向的指针,该指针对应于您看到的