2015-02-24 243 views
1

我想将matlab代码转换为C.为此,我将C代码与Intel MKL库连接起来,并包含“mkl_lapacke.h”。 Matlab代码包含:Lapack和Matlab之间的不同结果

>>A=mldivide(A1,A2)其中A1和A2都是正方形10x10实矩阵。 这可以被解释为系统A1 * X = A2

在C代码,我打电话Dgesv如下的溶液: info = LAPACKE_dgesv(LAPACK_ROW_MAJOR, n, nrhs, a, lda, ipiv,b, ldb); 其中LDA = 10,N = 10和nrhs = 10

问题是由Matlab和Lapack返回的10x10解决方案非常不同! 这里是A1 =一个代码和A2 = B

#include <stdlib.h> 
#include <stdio.h> 
#include "mkl_lapacke.h" 

/* Auxiliary routines prototypes */ 
extern void print_matrix(char* desc, MKL_INT m, MKL_INT n, double* a, MKL_INT lda); 
extern void print_int_vector(char* desc, MKL_INT n, MKL_INT* a); 

/* Parameters */ 
#define N 10 
#define NRHS 10 
#define LDA N 
#define LDB NRHS 

/* Main program */ 
int main() { 
     /* Locals */ 
     MKL_INT n = N, nrhs = NRHS, lda = LDA, ldb = LDB, info; 
     /* Local arrays */ 
     MKL_INT ipiv[N]; 
     double a[LDA*N] = { 
      -0.0091, 0.1024, -0.2640, -0.0956, 0.0635, -0.1776, 0.1257, 0.1048, -0.0869, 0.0106, 
    -0.0865, 0.2401, 0.0455, -0.0483, -0.2640, 0.3985, 0.1095, -0.2429, 0.1452, -0.0629, 
    -0.0428, 0.1669, -0.0239, -0.0877, -0.0893, 0.2085, -0.2095, -0.0423, 0.0712, 0.0051, 
    -0.0458, 0.0043, 0.3219, 0.1583, -0.1277, -0.0598, 0.2033, -0.1075, -0.0131, -0.0277, 
    -0.0597, 0.2190, 0.0053, 0.0084, -0.0741, -0.0993, 0.3048, -0.0046, -0.0718, -0.0055, 
    0.0538, -0.0734, -0.2116, -0.0733, 0.0203, 0.2163, 0.0991, -0.1309, 0.1299, -0.0564, 
    -0.0415, 0.1569, -0.0053, -0.0754, -0.0855, 0.1912, -0.2020, -0.0347, 0.0524, 0.0122, 
    0.0648, -0.1265, -0.1628, -0.0357, 0.0592, 0.1129, 0.0953, -0.0884, 0.0892, -0.0431, 
    0.0446, -0.2029, 0.1323, 0.0604, 0.0271, 0.1125, -0.1788, -0.0454, 0.0663, -0.0126, 
    0.0241, -0.1181, 0.1255, 0.0281, -0.0157, 0.1600, -0.2448, -0.0524, 0.0855, 0.0092,}; 
     double b[LDB*N] = { 
      -0.2225, -0.2789, 0.1338, -0.3709, -0.4954, -0.1445, -0.0116, 0.0254, 0.0118, 0.0098, 
    0.0362, -0.3659, -0.1204, -0.0500, 0.1276, -0.0473, -0.2388, 0.0701, -0.3668, -0.0480, 
    0.2351, 0.0922, -0.0670, -0.1074, 0.2423, -0.3811, 0.0791, -0.2176, -0.0391, 0.0532, 
    -0.0023, -0.2109, 0.0767, -0.1575, 0.2569, -0.1005, 0.2427, 0.3022, 0.0923, -0.0445, 
    0.4103, 0.3612, 0.0651, -0.0481, 0.1001, 0.5006, -0.1107, 0.3178, -0.0713, 0.4568, 
    0.1862, -0.3224, 0.0601, 0.1015, -0.2129, 0.0320, -0.1459, -0.0723, 0.3412, 0.0431, 
    0.1613, 0.3168, 0.0876, -0.0442, -0.2465, -0.1598, -0.1102, 0.2010, 0.0080, -0.0619, 
    0.0929, 0.1286, -0.2801, 0.0119, -0.1908, 0.0509, 0.2731, 0.1054, -0.1830, 0.0112, 
    -0.1971, -0.1049, -0.0354, 0.5010, 0.0685, -0.2606, 0.0225, 0.0164, -0.0140, -0.0002, 
    0.0452, -0.2061, 0.2058, 0.0156, 0.0198, -0.0294, 0.0453, -0.1110, 0.0098, 0.0145, 
     }; 

     /* Executable statements */ 
     printf("LAPACKE_dgesv (row-major, high-level) Example Program Results\n"); 
     /* Solve the equations A*X = B */ 
     info = LAPACKE_dgesv(LAPACK_ROW_MAJOR, n, nrhs, a, lda, ipiv, 
         b, ldb); 
     /* Check for the exact singularity */ 
     if(info > 0) { 
       printf("The diagonal element of the triangular factor of A,\n"); 
       printf("U(%i,%i) is zero, so that A is singular;\n", info, info); 
       printf("the solution could not be computed.\n"); 
       exit(1); 
     } 
     /* Print solution */ 
     print_matrix("Solution", n, nrhs, b, ldb); 
     /* Print details of LU factorization */ 
     print_matrix("Details of LU factorization", n, n, a, lda); 
     /* Print pivot indices */ 
     print_int_vector("Pivot indices", n, ipiv); 
     exit(0); 
} /* End of LAPACKE_dgesv Example */ 

/* Auxiliary routine: printing a matrix */ 
void print_matrix(char* desc, MKL_INT m, MKL_INT n, double* a, MKL_INT lda) { 
     MKL_INT i, j; 
     printf("\n %s\n", desc); 
     for(i = 0; i < m; i++) { 
       for(j = 0; j < n; j++) printf(" %6.2f", a[i*lda+j]); 
       printf("\n"); 
     } 
} 

/* Auxiliary routine: printing a vector of integers */ 
void print_int_vector(char* desc, MKL_INT n, MKL_INT* a) { 
     MKL_INT j; 
     printf("\n %s\n", desc); 
     for(j = 0; j < n; j++) printf(" %6i", a[j]); 
     printf("\n"); 
} 

通过dgesv返回的解决办法是:

LAPACKE_dgesv (row-major) 


1.0e+03 * 

    0.3270 -0.5215 0.0049 0.0619 -0.0199 -0.1558 2.9911 1.1247 -5.4283 5.2655 
    0.0751 -0.2225 0.1936 0.0490 -0.0678 -0.0201 0.2473 0.1422 -0.4608 0.7307 
    -0.0683 0.3846 -0.4393 -0.0885 0.1620 0.0024 0.2210 -0.0303 -0.3558 -0.2766 
    0.1779 -0.9302 1.0602 0.2237 -0.3761 -0.0056 -0.4986 0.0816 0.7990 0.7407 
    -0.1549 0.3202 -0.0615 -0.0345 0.0257 0.0775 -1.3939 -0.5276 2.5444 -2.5409 
    -0.0069 -0.0202 0.0594 0.0175 -0.0235 0.0140 -0.1871 -0.0481 0.3191 -0.2247 
    -0.0360 0.1518 -0.1521 -0.0332 0.0600 0.0122 -0.0471 -0.0597 0.0958 -0.3078 
    0.0675 -0.1360 0.0075 0.0220 0.0272 -0.0318 0.5894 0.1936 -1.0823 1.0735 
    -0.0129 0.0052 0.0142 -0.0096 0.0355 0.0096 -0.2460 -0.1281 0.4625 -0.4091 
    -0.0963 0.1961 -0.0244 -0.0417 -0.0032 0.0743 -0.8836 -0.3268 1.5972 -1.6047 

而利用Matlab返回的解决办法是:

1.0e+03 * 

    0.1224 -0.0783 -0.1534 -0.0092 0.0609 -0.0555 1.3240 0.4477 -2.3813 2.0963 
    0.0528 -0.1725 0.1739 0.0410 -0.0549 -0.0089 0.0615 0.0637 -0.1206 0.3758 
    -0.0706 0.3868 -0.4366 -0.0889 0.1543 0.0029 0.2127 -0.0271 -0.3417 -0.2905 
    0.1813 -0.9290 1.0499 0.2236 -0.3556 -0.0058 -0.4944 0.0666 0.7945 0.7407 
    -0.0576 0.1085 0.0151 -0.0005 -0.0141 0.0297 -0.6005 -0.2044 1.0941 -1.0311 
    0.0037 -0.0425 0.0664 0.0211 -0.0263 0.0088 -0.1006 -0.0141 0.1613 -0.0616 
    -0.0286 0.1352 -0.1456 -0.0306 0.0543 0.0082 0.0190 -0.0308 -0.0253 -0.1830 
    0.0264 -0.0438 -0.0292 0.0067 0.0455 -0.0119 0.2628 0.0591 -0.4845 0.4438 
    0.0037 -0.0281 0.0227 -0.0046 0.0308 0.0012 -0.1030 -0.0717 0.2019 -0.1450 
    -0.0352 0.0629 0.0242 -0.0202 -0.0285 0.0443 -0.3862 -0.1238 0.6877 -0.6572 
+1

答案如何不同?你能编辑你的文章以包含输入和输出矩阵吗?你确定你没有在一个程序中使用你想要的矩阵的转置吗? – eigenchris 2015-02-24 22:07:45

+1

没有看到你的矩阵和两者产生的输出,它是不可能回答你的问题。 – 2015-02-24 22:18:58

+0

我刚刚添加了代码和结果 – Didon 2015-02-24 22:38:28

回答

4

作为TroyHaskin指出,如果您按照以下步骤获得LAPACK结果:

a=[-0.0091, 0.1024, -0.2640, -0.0956, 0.0635, -0.1776, 0.1257, 0.1048, -0.0869, 0.0106, 
    -0.0865, 0.2401, 0.0455, -0.0483, -0.2640, 0.3985, 0.1095, -0.2429, 0.1452, -0.0629, 
    -0.0428, 0.1669, -0.0239, -0.0877, -0.0893, 0.2085, -0.2095, -0.0423, 0.0712, 0.0051, 
    -0.0458, 0.0043, 0.3219, 0.1583, -0.1277, -0.0598, 0.2033, -0.1075, -0.0131, -0.0277, 
    -0.0597, 0.2190, 0.0053, 0.0084, -0.0741, -0.0993, 0.3048, -0.0046, -0.0718, -0.0055, 
    0.0538, -0.0734, -0.2116, -0.0733, 0.0203, 0.2163, 0.0991, -0.1309, 0.1299, -0.0564, 
    -0.0415, 0.1569, -0.0053, -0.0754, -0.0855, 0.1912, -0.2020, -0.0347, 0.0524, 0.0122, 
    0.0648, -0.1265, -0.1628, -0.0357, 0.0592, 0.1129, 0.0953, -0.0884, 0.0892, -0.0431, 
    0.0446, -0.2029, 0.1323, 0.0604, 0.0271, 0.1125, -0.1788, -0.0454, 0.0663, -0.0126, 
    0.0241, -0.1181, 0.1255, 0.0281, -0.0157, 0.1600, -0.2448, -0.0524, 0.0855, 0.0092]; 


    b= [-0.2225, -0.2789, 0.1338, -0.3709, -0.4954, -0.1445, -0.0116, 0.0254, 0.0118, 0.0098, 
    0.0362, -0.3659, -0.1204, -0.0500, 0.1276, -0.0473, -0.2388, 0.0701, -0.3668, -0.0480, 
    0.2351, 0.0922, -0.0670, -0.1074, 0.2423, -0.3811, 0.0791, -0.2176, -0.0391, 0.0532, 
    -0.0023, -0.2109, 0.0767, -0.1575, 0.2569, -0.1005, 0.2427, 0.3022, 0.0923, -0.0445, 
    0.4103, 0.3612, 0.0651, -0.0481, 0.1001, 0.5006, -0.1107, 0.3178, -0.0713, 0.4568, 
    0.1862, -0.3224, 0.0601, 0.1015, -0.2129, 0.0320, -0.1459, -0.0723, 0.3412, 0.0431, 
    0.1613, 0.3168, 0.0876, -0.0442, -0.2465, -0.1598, -0.1102, 0.2010, 0.0080, -0.0619, 
    0.0929, 0.1286, -0.2801, 0.0119, -0.1908, 0.0509, 0.2731, 0.1054, -0.1830, 0.0112, 
    -0.1971, -0.1049, -0.0354, 0.5010, 0.0685, -0.2606, 0.0225, 0.0164, -0.0140, -0.0002, 
    0.0452, -0.2061, 0.2058, 0.0156, 0.0198, -0.0294, 0.0453, -0.1110, 0.0098, 0.0145]; 

a\b 

ans = 
    327.0114 -521.4858  4.9027  61.9130 -19.8927 -155.8372 2991.1079 1124.6681 -5428.3234 5265.5139 
    75.1284 -222.4563 193.6070  48.9504 -67.7640 -20.0595 247.2690 142.2035 -460.8152 730.6545 
    -68.2827 384.6219 -439.3150 -88.4497 162.0169  2.3759 221.0372 -30.3170 -355.8296 -276.5529 
    177.9446 -930.1793 1060.1675 223.6455 -376.0511  -5.6118 -498.6298  81.5657 799.0423 740.6989 
-154.9540 320.2519 -61.4950 -34.5545  25.7087  77.4924 -1393.8961 -527.6382 2544.4178 -2540.9034 
    -6.9249 -20.1575  59.3966  17.5369 -23.5432  14.0414 -187.0725 -48.1027 319.1279 -224.6643 
    -35.9941 151.8283 -152.0953 -33.1855  59.9649  12.1877 -47.0808 -59.6673  95.7806 -307.7863 
    67.5132 -136.0433  7.5317  21.9729  27.2220 -31.7538 589.3968 193.5591 -1082.2648 1073.4849 
    -12.9406  5.2063  14.1874  -9.5474  35.5088  9.6252 -245.9788 -128.1143 462.4924 -409.1096 
    -96.2949 196.1438 -24.3756 -41.7405  -3.1993  74.2884 -883.5854 -326.7665 1597.1577 -1604.6541 

重塑输入矢量到MATLAB阵列(假定列顺序),结果在不同的输入数组一个比你馈LAPACK:

av = [ -0.0091000 0.1024000 -0.2640000 -0.0956000 0.0635000 -0.1776000 0.1257000 0.1048000 -0.0869000 0.0106000 -0.0865000 0.2401000 0.0455000 -0.0483000 -0.2640000 0.3985000 0.1095000 -0.2429000 0.1452000 -0.0629000 -0.0428000 0.1669000 -0.0239000 -0.0877000 -0.0893000 0.2085000 -0.2095000 -0.0423000 0.0712000 0.0051000 -0.0458000 0.0043000 0.3219000 0.1583000 -0.1277000 -0.0598000 0.2033000 -0.1075000 -0.0131000 -0.0277000 -0.0597000 0.2190000 0.0053000 0.0084000 -0.0741000 -0.0993000 0.3048000 -0.0046000 -0.0718000 -0.0055000 0.0538000 -0.0734000 -0.2116000 -0.0733000 0.0203000 0.2163000 0.0991000 -0.1309000 0.1299000 -0.0564000 -0.0415000 0.1569000 -0.0053000 -0.0754000 -0.0855000 0.1912000 -0.2020000 -0.0347000 0.0524000 0.0122000 0.0648000 -0.1265000 -0.1628000 -0.0357000 0.0592000 0.1129000 0.0953000 -0.0884000 0.0892000 -0.0431000 0.0446000 -0.2029000 0.1323000 0.0604000 0.0271000 0.1125000 -0.1788000 -0.0454000 0.0663000 -0.0126000 0.0241000 -0.1181000 0.1255000 0.0281000 -0.0157000 0.1600000 -0.2448000 -0.0524000 0.0855000 0.0092000] 


reshape(av,10,10) 

ans = 

    -0.0091000 -0.0865000 -0.0428000 -0.0458000 -0.0597000 0.0538000 -0.0415000 0.0648000 0.0446000 0.0241000 
    0.1024000 0.2401000 0.1669000 0.0043000 0.2190000 -0.0734000 0.1569000 -0.1265000 -0.2029000 -0.1181000 
    -0.2640000 0.0455000 -0.0239000 0.3219000 0.0053000 -0.2116000 -0.0053000 -0.1628000 0.1323000 0.1255000 
    -0.0956000 -0.0483000 -0.0877000 0.1583000 0.0084000 -0.0733000 -0.0754000 -0.0357000 0.0604000 0.0281000 
    0.0635000 -0.2640000 -0.0893000 -0.1277000 -0.0741000 0.0203000 -0.0855000 0.0592000 0.0271000 -0.0157000 
    -0.1776000 0.3985000 0.2085000 -0.0598000 -0.0993000 0.2163000 0.1912000 0.1129000 0.1125000 0.1600000 
    0.1257000 0.1095000 -0.2095000 0.2033000 0.3048000 0.0991000 -0.2020000 0.0953000 -0.1788000 -0.2448000 
    0.1048000 -0.2429000 -0.0423000 -0.1075000 -0.0046000 -0.1309000 -0.0347000 -0.0884000 -0.0454000 -0.0524000 
    -0.0869000 0.1452000 0.0712000 -0.0131000 -0.0718000 0.1299000 0.0524000 0.0892000 0.0663000 0.0855000 
    0.0106000 -0.0629000 0.0051000 -0.0277000 -0.0055000 -0.0564000 0.0122000 -0.0431000 -0.0126000 0.0092000 

编辑:以获得相同的结果在lapack你有多种选择:

  1. 改变输入向量明确,例如见here关于如何改变顺序,基本上类似

    anew = a'(:); 
    

    ,其中a是在matlab矩阵形式的原始数据(未以矢量形式)。

  2. 更改告诉Lapack例程是否承担行或列顺序的标志。我的猜测是传递LAPACK_COLUMN_MAJOR而不是LAPACK_ROW_MAJOR到你的函数,但我不能担保这一点,因为我没有测试过它。

+0

好吧..我也有同样的结果,当我进入载体,如在Lapack ..现在的问题是,我希望lapack获得与matlab相同的结果,而不是相反。如何在Lapack中输入向量? – Didon 2015-02-25 15:41:44

+0

@Daphnée我对此添加了评论。 – 2015-02-25 20:32:08

相关问题