使用lapack库求逆矩阵

来源:互联网 发布:js如何取整数 编辑:程序博客网 时间:2024/05/21 06:46

废话不多说,直接上代码:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include <string>  
  2. #include "lapacke.h"  
  3. #include "lapack_aux.h"  
  4.   
  5. int main(int argc,char** argv)  
  6. {  
  7.     setlocale(LC_ALL,"");  
  8.     double a[] =   
  9.     {  
  10.         3,-1,-1,  
  11.         4,-2,-1,  
  12.         -3,2,1  
  13.     };  
  14.     int m = 3;  
  15.     int n = 3;  
  16.     int lda = 3;  
  17.     int ipiv[3];  
  18.     int info;  
  19.     print_matrix("a",m,n,a,lda);      
  20.     info = LAPACKE_dgetrf(LAPACK_ROW_MAJOR,m,n,a,lda,ipiv);  
  21.     print_matrix("a",m,n,a,lda);  
  22.   
  23.     info = LAPACKE_dgetri(LAPACK_ROW_MAJOR,m,a,lda,ipiv);  
  24.     print_matrix("a",m,n,a,lda);  
  25.     return 0;  
  26. }  
输出结果如下:


也可以使用下面的方法:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include <string>  
  2. #include "lapacke.h"  
  3. #include "lapack_aux.h"  
  4.   
  5. int main(int argc,char** argv)  
  6. {  
  7.     setlocale(LC_ALL,"");  
  8.     double a[] =   
  9.     {  
  10.         3,4,-3,  
  11.         -1,-2,2,  
  12.         -1,-1,1  
  13.     };  
  14.   
  15.     int m = 3;  
  16.     int n = 3;  
  17.     int lda = 3;  
  18.     int ipiv[3];  
  19.     int info;  
  20.     print_matrix("a",m,n,a,lda);      
  21.     LAPACK_dgetrf(&m,&n,a,&lda,ipiv,&info);  
  22.     print_matrix("a",m,n,a,lda);  
  23.   
  24.     double *b = new double[m]();  
  25.     //求普通矩阵的逆矩阵  
  26.     LAPACK_dgetri(&m,a,&lda,ipiv,b,&n,&info);  
  27.     print_matrix("inv(a)",m,n,a,lda);  
  28.     return 0;  
  29. }  

输出结果如下:


这种方法的好处在于API接口的定义和对应的Fortran接口一致,比如dgetri,我们可以在双精度的函数说明(http://www.netlib.org/lapack/double/)文档中找到dgetri.f,打开这个Fortran文件,就可以知道相应的参数的含义了。

不过这里要注意存储矩阵时,两种方法之间的区别。第一种方法中,我们可以通过主序告诉lapack的接口我们的矩阵是以行为主序的,也就是在数组中,这个矩阵是按行存储的,对于一个3x3矩阵,输入的9个元素,前3个数是矩阵的第一行,紧接着是矩阵的第二行,最后是矩阵的第三行,而第二种方法中,没有主序这个参数,研究发现,Fortran默认是以列为主序的,也就是说我们在用数组输入一个3x3矩阵时,前3个数表示第1列,再3个数为第2列,最后3个数为第3列。因此在给定矩阵的时候,我们需要按列输入。因此方法2中的数组a,以列为主序,表示的矩阵实际上是这样的:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1.  3    -1    -1  
  2.  4    -2    -1  
  3. -3     2     1  

这相当于把第一种方法中的主序改为LAPACK_COL_MAJOR,如下:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include <string>  
  2. #include "lapacke.h"  
  3. #include "lapack_aux.h"  
  4.   
  5. int main(int argc,char** argv)  
  6. {  
  7.     setlocale(LC_ALL,"");  
  8.     double a[] =   
  9.     {  
  10.         3,4,-3,  
  11.         -1,-2,2,  
  12.         -1,-1,1  
  13.     };  
  14.     int m = 3;  
  15.     int n = 3;  
  16.     int lda = 3;  
  17.     int ipiv[3];  
  18.     int info;  
  19.     print_matrix("a",m,n,a,lda);      
  20.     info = LAPACKE_dgetrf(LAPACK_COL_MAJOR,m,n,a,lda,ipiv);  
  21.     print_matrix("a",m,n,a,lda);  
  22.   
  23.     info = LAPACKE_dgetri(LAPACK_COL_MAJOR,m,a,lda,ipiv);  
  24.     print_matrix("a",m,n,a,lda);  
  25.     return 0;  
  26. }  

最后,我们在Matlab中验证一下,如下:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. >>  a = [3,4,-3,-1,-2,2,-1,-1,1]  
  2.   
  3. a =  
  4.   
  5.      3     4    -3    -1    -2     2    -1    -1     1  
  6.   
  7. >>  a = reshape(a,3,3)  
  8.   
  9. a =  
  10.   
  11.      3    -1    -1  
  12.      4    -2    -1  
  13.     -3     2     1  
  14.   
  15. >> inv(a)  
  16.   
  17. ans =  
  18.   
  19.      0     1     1  
  20.      1     0     1  
  21.     -2     3     2  

可见我们的计算结果好Matlab的结果一致。

附辅助函数:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include <stdio.h>  
  2. #include "lapack_aux.h"  
  3.   
  4. /* Auxiliary routine: printing a matrix */  
  5. void print_matrix( char* desc, lapack_int m, lapack_int n, double* a, lapack_int lda )  
  6. {  
  7.     lapack_int i, j;  
  8.     printf( "\n %s\n", desc );  
  9.     for( i = 0; i < m; i++ )  
  10.     {  
  11.         for( j = 0; j < n; j++ ) printf( " %6.2f", a[i*lda+j] );  
  12.         printf( "\n" );  
  13.     }  
  14. }  

参考文件:

http://blog.csdn.net/kevinzhangyang/article/details/6859246
http://blog.csdn.net/daiyuchao/article/details/2026173
http://blog.csdn.net/daiyuchao/article/details/2026162
http://www.cnblogs.com/xunxun1982/archive/2010/05/12/1734001.html
http://www.cnblogs.com/xunxun1982/archive/2010/05/13/1734809.html
http://hi.baidu.com/data2009/item/50bce0704cf57a14d0dcb3e8
http://blog.sina.com.cn/s/blog_40b056950100htpt.html
http://blog.csdn.net/cleverysm/article/details/1925553
http://blog.csdn.net/cleverysm/article/details/1925549
http://www.cnblogs.com/Jedimaster/archive/2008/06/22/1227656.html

0 0
原创粉丝点击