我用C语言编写了大约1000行线性规划求解器(内点算法)的代码。我意识到我需要使用特征来计算矩阵的逆,所以现在我用C++运行代码(看起来运行得很好)。现在我有了一堆以C格式声明的数组,例如:
在我的程序中,我做了一堆矩阵计算,然后需要在某个点找到一个矩阵的逆,我们称之为矩阵
//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.关键部分在末尾,我需要在那里进行反相(滚动到底部--我已经对其进行了注释)。
您尝试过
你的提议似乎可以同时兼顾这两个问题?
右,
请问A后面的[0]是什么?
,指定