我在C中为线性编程求解器(内点算法)编写了大约1000行代码。我意识到我需要使用Eigen来计算矩阵逆,所以现在我用C ++运行我的代码(运行得很好,似乎)。现在我有一堆以C格式声明的数组,例如:A[30][30];
在我的程序中,我做了一堆矩阵计算,然后需要在某个点找到矩阵的逆矩阵,我们称之为矩阵L[30][30]
。要使用Eigen,我需要使用特殊的Eigen矩阵格式来调用函数m.inverse,如下所示:
//cout << "The inverse of L is:\n" << L.inverse() << endl;
我的目标是找到一种方法...任何方式,将我的数据从L获取到Eigen将接受的格式,这样我就能运行这个东西。我花了最后2个小时来研究这个并且没有提出任何建议。 :-(我对C很新,所以请尽可能彻底。我想要最简单的方法。我已经阅读了关于映射的内容,但我对指针的描述并不是很清楚(这似乎是有没有一种方法可以循环遍历每一行和每一行并将它们复制到一个特征矩阵中?
在我问的时候,我需要将得到的特征矩阵转回C阵列吗?这个过程将如何运作?在此先感谢您的帮助!我已经花了大约50-60个小时,这个星期到期了!这是我需要做的最后一件事,我将完成我的学期项目。这是一个数学课,所以编程方面对我来说有点模糊,但我学到了很多东西。
可能相关的信息: - 在Windows 10 i7处理器Sony VAIO上运行 - 使用C ++编写CodeBlocks,但最初用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 );
Map操作将现有的内存区域映射到Eigen的数据结构中。像这样的单行允许避免编写丑陋的矩阵创建代码,循环复制每个元素的顺序等。“
这似乎是一个很好的解决方案,但我对如何使用“双* X”表示“指向某些数据”做任何事都毫无头绪。我开始查找指针等等,它没有帮助澄清 - 我看到各种各样的事情指向多维数组似乎没有帮助。
我也不太了解第二行的格式。是否每个大写X都与之前的行中的矩阵* X相同?我需要为此声明/创建什么?或者是否有一种更简单的方法可以做到这一切?
EDIT2:这是我在我的程序中所拥有的,基本上 - 这显着缩小了,对不起,如果它仍然太长。
#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.关键部分是在最后,我需要采取反转(滚动到底部 - 我已经评论过了。)
答案 0 :(得分:0)
你试过吗?
Map<MatrixXd>(A[0],30,30).inverse()
?? - ggael你提出的建议似乎是同时做或两者兼而有之 什么?
是的,Map<MatrixXd>()
会返回调用方法MatrixXd
的特征inverse()
。
请问A之后[0]是什么?
[0]
是指定[]
- 元素的数组下标运算符0
; A[0]
是矩阵A[30][30]
的初始行,并转换为与您看到的A[0][0]
对应的X
指针。