从Matlab到C的简单循环

时间:2015-04-02 10:19:42

标签: c matlab

我不明白Matlab循环和C循环返回的结果的差异通常在同一数据上做同样的事情。

我有10x20矩阵A。我想将主要对角线中U的元素转换为1,以便在高斯消除后执行。 地点:[L,U]=lu(A);U成为:

   0.1368   -0.1831    0.2229   -0.1102    0.0237    0.0724    0.0097   -0.0590    0.0742    0.0836   -0.1148   -0.0389    0.0032 -0.2092   -0.0133    0.0113    0.0494   -0.0007   -0.0024   -0.0003
         0    0.2487   -0.2608   -0.0076    0.0697    0.0335    0.0024    0.0027   -0.1263    0.3665   -0.1246   -0.1955    0.0654  0.2732    0.0212   -0.0244    0.0145    0.0374   -0.0957    0.0127
         0         0   -0.5718    0.4439   -0.0553   -0.1313   -0.1151    0.1725   -0.0155   -0.3116    0.4280    0.1212    0.0924 -0.1510    0.0227   -0.3462   -0.1306    0.1031   -0.0078    0.0416
         0         0         0    0.1224   -0.2076   -0.0533   -0.0677    0.0962    0.4135   -0.3085   -0.0207    0.1658    0.0220  -0.0361    0.0635   -0.1223    0.0278   -0.1148    0.0411    0.0112
         0         0         0         0   -0.3676    0.1208   -0.0234   -0.0232    0.4959   -0.1270   -0.0314   -0.0972   -0.1205    0.1481    0.0666    0.3555    0.0318   -0.0913    0.0504   -0.0501
         0         0         0         0         0   -0.3659   -0.0429    0.3930    0.0195   -0.3283    0.2049    0.0088    0.0897 -0.2473    0.1311   -0.3701   -0.0830    0.3607   -0.0637    0.0428
         0         0         0         0         0         0   -0.2582    0.6541    0.2277   -0.7171    0.1867   -0.4331   -0.1861  -0.2769    0.2611   -0.5129   -0.0875    0.5092    0.2567    0.0184
         0         0         0         0         0         0         0   -0.7277   -0.0765    0.4402   -0.1556    0.9241   -0.3925  0.2518   -0.3771    0.3988    0.0929   -0.8337    0.3939   -0.0683
         0         0         0         0         0         0         0         0    0.0705    0.9474   -0.0785   -0.6134    0.2469 -0.0357    0.0697    0.0778    0.0168    0.2910   -0.3742    0.0273
         0         0         0         0         0         0         0         0         0    0.0281   -0.2726    0.0465   -0.5293 0.3433   -0.1291    0.6124    0.0566   -0.0398    0.3456   -0.1152

C中的LU分解给了我以下矩阵U1

 u1=[ 0.1368 -0.1831 0.2229 -0.1102 0.0237 0.0724 0.0097 -0.0590 0.0742 0.0836 -0.1148 -0.0389 0.0032 -0.2092 -0.0133 0.0113 0.0494 -0.0007 -0.0024 -0.0003
 0.0000 0.2488 -0.2609 -0.0075 0.0698 0.0334 0.0023 0.0027 -0.1263 0.3665 -0.1246 -0.1955 0.0654 0.2733 0.0212 -0.0244 0.0145 0.0375 -0.0958 0.0127
 0.0000 0.0000 -0.5718 0.4439 -0.0554 -0.1313 -0.1150 0.1725 -0.0155 -0.3116 0.4280 0.1212 0.0925 -0.1510 0.0227 -0.3462 -0.1306 0.1031 -0.0078 0.0416
 0.0000 0.0000 0.0000 0.1225 -0.2076 -0.0533 -0.0677 0.0963 0.4135 -0.3086 -0.0206 0.1658 0.0220 -0.0361 0.0635 -0.1224 0.0279 -0.1148 0.0412 0.0112
 0.0000 0.0000 0.0000 0.0000 -0.3675 0.1208 -0.0234 -0.0232 0.4957 -0.1269 -0.0314 -0.0972 -0.1205 0.1480 0.0666 0.3555 0.0318 -0.0912 0.0504 -0.0501
 0.0000 0.0000 0.0000 0.0000 0.0000 -0.3660 -0.0428 0.3931 0.0195 -0.3284 0.2050 0.0089 0.0897 -0.2474 0.1311 -0.3702 -0.0829 0.3607 -0.0636 0.0428
 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 -0.2581 0.6541 0.2275 -0.7170 0.1870 -0.4333 -0.1860 -0.2769 0.2610 -0.5127 -0.0874 0.5094 0.2568 0.0184
 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 -0.7278 -0.0766 0.4404 -0.1556  0.9241 -0.3925 0.2518 -0.3772 0.3988 0.0928 -0.8337 0.3938 -0.0684
 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0705 0.9475 -0.0785 -0.6135 0.2470 -0.0356 0.0698 0.0780 0.0167 0.2911 -0.3744 0.0273
 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0290 -0.2727 0.0458 -0.5290 0.3431 -0.1290 0.6125 0.0566 -0.0393 0.3451 -0.1151]



max(max(u-u1))= 7.0775e-04 Which is acceptable

之后,为了将主要对角线的元素转换为1,我在Matlab中运行以下循环:

>> for i=1:size(U,1)
U(i,:)=U(i,:)/U(i,i);
end

我得到了U的梯形形式如下:

 U_echelon=[ 1.0000   -1.3385    1.6294   -0.8056    0.1732    0.5292    0.0709   -0.4313    0.5424    0.6111   -0.8392   -0.2844    0.0234 -1.5292   -0.0972    0.0826    0.3611   -0.0051   -0.0175   -0.0022
             0    1.0000   -1.0488   -0.0306    0.2804    0.1345    0.0095    0.0107   -0.5077    1.4736   -0.5010   -0.7862    0.2631 1.0986    0.0852   -0.0982    0.0583    0.1504   -0.3849    0.0511
             0         0    1.0000   -0.7763    0.0968    0.2296    0.2012   -0.3016    0.0271    0.5448   -0.7485   -0.2119   -0.1617 0.2640   -0.0397    0.6054    0.2284   -0.1803    0.0136   -0.0728
             0         0         0    1.0000   -1.6962   -0.4357   -0.5529    0.7861    3.3779   -2.5205   -0.1694    1.3545    0.1795 -0.2946    0.5188   -0.9994    0.2275   -0.9377    0.3355    0.0912
             0         0         0         0    1.0000   -0.3287    0.0637    0.0632   -1.3490    0.3454    0.0855    0.2643    0.3279 -0.4029   -0.1811   -0.9670   -0.0866    0.2484   -0.1372    0.1364
             0         0         0         0         0    1.0000    0.1171   -1.0740   -0.0534    0.8970   -0.5600   -0.0240   -0.2450 0.6759   -0.3582    1.0113    0.2267   -0.9858    0.1741   -0.1168
             0         0         0         0         0         0    1.0000   -2.5332   -0.8816    2.7771   -0.7231    1.6774    0.7205 1.0725   -1.0110    1.9864    0.3388   -1.9721   -0.9941   -0.0711
             0         0         0         0         0         0         0    1.0000    0.1052   -0.6050    0.2138   -1.2699    0.5394 -0.3460    0.5182   -0.5480   -0.1276    1.1456   -0.5413    0.0938
             0         0         0         0         0         0         0         0    1.0000   13.4320   -1.1132   -8.6966    3.5007 -0.5059    0.9883    1.1031    0.2379    4.1258   -5.3060    0.3872
             0         0         0         0         0         0         0         0         0    1.0000   -9.7045    1.6557  -18.8440 12.2202   -4.5954   21.8012    2.0146   -1.4151   12.3054   -4.0999

在C中调用相同的函数如下:

void echelon(float *U, int m, int n)
{
        int i,j;
        float piv,s;
        //'convert elements in major diagonal to 1
        for (i=0;i<m;i++)
        {
                piv=U[i*n+i];
                s=1.0f/piv;
                for(j=0;j<n;j++)
                {
                        U[i*n+j]=U[i*n+j]*s;
                }
        }
}

并给了我U1_echelon如下:

 1.0000   -1.3390    1.6295   -0.8057    0.1735    0.5297    0.0709   -0.4312    0.5426    0.6111   -0.8392   -0.2845    0.0234 -1.5296   -0.0971    0.0827    0.3608   -0.0054   -0.0174   -0.0019
         0    1.0000   -1.0487   -0.0303    0.2804    0.1344    0.0093    0.0107   -0.5078    1.4733   -0.5007   -0.7860    0.2629 1.0986    0.0853   -0.0982    0.0582    0.1507   -0.3850    0.0509
         0         0    1.0000   -0.7763    0.0968    0.2296    0.2011   -0.3016    0.0271    0.5449   -0.7485   -0.2119   -0.1618 0.2642   -0.0397    0.6054    0.2284   -0.1803    0.0136   -0.0728
         0         0         0    1.0000   -1.6950   -0.4355   -0.5524    0.7859    3.3759   -2.5195   -0.1685    1.3537    0.1799 -0.2950    0.5184   -0.9991    0.2278   -0.9371    0.3360    0.0913
         0         0         0         0    1.0000   -0.3287    0.0637    0.0632   -1.3490    0.3453    0.0854    0.2645    0.3279 -0.4028   -0.1812   -0.9672   -0.0866    0.2483   -0.1372    0.1363
         0         0         0         0         0    1.0000    0.1169   -1.0739   -0.0532    0.8972   -0.5601   -0.0243   -0.2451 0.6758   -0.3581    1.0113    0.2266   -0.9855    0.1738   -0.1169
         0         0         0         0         0         0    1.0000   -2.5344   -0.8814    2.7784   -0.7245    1.6788    0.7207 1.0731   -1.0114    1.9865    0.3387   -1.9738   -0.9951   -0.0712
         0         0         0         0         0         0         0    1.0000    0.1052   -0.6052    0.2138   -1.2697    0.5393 -0.3460    0.5183   -0.5480   -0.1275    1.1454   -0.5411    0.0940
         0         0         0         0         0         0         0         0    1.0000   13.4420   -1.1134   -8.7041    3.5044 -0.5050    0.9898    1.1063    0.2372    4.1303   -5.3121    0.3875
         0         0         0         0         0         0         0         0         0    1.0000   -9.4048    1.5779  -18.2462 11.8343   -4.4474   21.1248    1.9516   -1.3555   11.9038   -3.9710 




 max(max(U_echelon-U1_echelon))= 0.6764

我无法弄清楚错误在哪里。

1 个答案:

答案 0 :(得分:2)

0.67的差异来自最大数字21.8,相对差异约为3%。如果你看最后一行,所有数字都会下降约3%。

现在,在运行echelon函数之前,先查看第一步的输出。请注意,最后一行的第一个元素在Matlab中为0.0281,在C中为0.0290,这相差3%。因此,在矩阵上运行echelon之前,错误已经存在。

因此,我的结论是你应该看看LU分解是否存在精度问题的根源,而不是echelon函数。