LinearEquation.inl
上传用户:fxromeo
上传日期:2010-04-08
资源大小:89k
文件大小:19k
开发平台:

Visual C++

  1. //LinearEquation.inl 线性方程(组)求解函数(方法)定义
  2. // Ver 1.0.0.0
  3. // 版权所有(C) 何渝, 2002
  4. // 最后修改: 2002.5.31
  5. #ifndef _LINEAREQUATION_INL
  6. #define _LINEAREQUATION_INL
  7. //全选主元高斯消去法
  8. template <class _Ty>
  9. int LE_TotalChoiceGauss(matrix<_Ty>& a, valarray<_Ty>& b)  
  10. long double MaxValue, tmp; //记录主元绝对值
  11. int l(1), i, j, is;
  12.     bool yn;
  13.     
  14. int n = a.GetColNum(); //方程组阶数
  15. valarray<int> js(n); //保存换列位置
  16.     
  17. for(int k = 0; k < n - 1; k++) //全选主元
  18. {
  19. MaxValue = 0.0; //给保存主元绝对值变量赋初值
  20.         
  21. for(i = k; i < n; i++)
  22. for(j = k; j < n; j++)
  23.             {
  24. tmp = Abs(a(i, j)); //求m(i,j)绝对值
  25. if(tmp > MaxValue) //发现一个更大的主元
  26. MaxValue = tmp; //保存新主元绝对值
  27. js[k] = j; //新主元所在列
  28. is = i; //新主元所在行
  29. }
  30.             }
  31. yn = FloatEqual(MaxValue, 0);
  32.         if(yn) l = 0; //主元为0
  33. else
  34. {
  35. if(js[k] != k) //换列
  36. for(i = 0; i < n; i++) swap(a(i, k), a(i, js[k]));
  37. if(is != k) //换行
  38. for (j = k; j < n; j++) swap(a(k, j), a(is, j));
  39. swap(b[k], b[is]); //方程组右边第k元素与第is元素交换
  40. }
  41. }
  42.         
  43. if(l == 0) //矩阵奇异(主元为0)
  44. {
  45. printf("fail 1n");
  46.             return 0; // 求解失败,返回0值
  47. }
  48.         
  49. MaxValue =  Abs(a(k, k));
  50.         for(j = k + 1; j < n; j++) a(k, j) /= a(k, k); //MaxValue;
  51.         
  52. b[k] /= a(k, k); //MaxValue;
  53.         for(i = k + 1; i < n; i++)
  54. {
  55. for(j = k + 1; j < n; j++)
  56. {
  57.                 a(i, j) = a(i, j) - a(i, k) * a(k, j);
  58. }
  59.             
  60. b[i] = b[i] - a(i, k) * b[k];
  61. }
  62. }
  63.     
  64. MaxValue = Abs(a((n - 1), (n - 1))); //主元
  65. yn = FloatEqual(MaxValue, 0);
  66.     if(yn) //主元为0
  67. {
  68. cout<<"fail 2"<<endl;
  69.         return(0); //求解失败,返回0值
  70. }
  71. b[n - 1] /= a((n - 1), (n - 1));//求解方程组右边X的解
  72.     for(i = n - 2; i >= 0; i--) //回代过程
  73. {
  74. _Ty t = 0.0;
  75.         
  76. for(j = i + 1; j < n; j++) t = t + a(i, j) * b[j];
  77.         
  78. b[i] = b[i] - t;
  79. }
  80.     
  81. js[n - 1] = n - 1; //X最后一个元素不用换
  82.     for(k = n - 2; k >= 0; k --) //k可以从n-2开始
  83. if(js[k] != k) //交换X的元素位置(由全选换列产生的)
  84. swap(b[k], b[js[k]]);
  85.     
  86. return(1); //方程组求解成功!
  87. }
  88. //全选主元高斯-约当消去法
  89. template <class _Ty>
  90. int LE_TotalChoiceGaussJordan(matrix<_Ty> & a, matrix<_Ty> & b)
  91. long double MaxValue, tmp; //主元绝对值
  92. int l(1), k, i, j, is;
  93. bool yn;
  94.     int n = a.GetColNum(); //方程组阶数
  95. int m = b.GetColNum(); //方程组右端常数向量的个数
  96. valarray<int> js(n);  
  97. for(k = 0; k < n; k++)
  98. {
  99. MaxValue = long double(0.0);
  100.         
  101. for(i = k; i < n; i++)
  102. for(j = k; j < n; j++)
  103.             {
  104. tmp = Abs( a(i, j) );
  105. if(tmp > MaxValue)
  106. MaxValue = tmp;
  107. js[k] = j;
  108. is = i;
  109. }
  110.             }
  111. yn = FloatEqual(MaxValue, 0);
  112. if(yn) l = 0; 
  113. else
  114. {
  115. if(js[k] != k)
  116. for(i = 0; i < n; i++)
  117. swap(a(i, k), a(i, js[k]));
  118. if(is != k)
  119. {
  120. for(j = k; j < n; j++)
  121. swap(a(k, j), a(is, j));
  122. for(j = 0; j < m; j++)
  123. swap(b(k, j), b(is, j));
  124. }
  125. }
  126. if(l == 0)
  127. {
  128. cout<<"fail"<<endl;
  129. return 0;
  130. }
  131. for(j = k + 1; j < n; j++)
  132. a(k, j) /= a(k, k);
  133. for(j = 0; j < m; j++)
  134. b(k, j) /= a(k, k);
  135. for(j = k + 1; j < n; j++)
  136. for(i = 0; i < n; i++)
  137. if(i != k)
  138. a(i, j) -= a(i, k) * a(k, j);
  139. for(j = 0; j < m; j++)
  140. for(i = 0; i< n; i++)
  141. if(i != k)
  142. b(i, j) -= a(i, k) * b(k, j);
  143. }
  144.     for(k = n - 1; k >= 0; k --)
  145. {
  146. if(js[k] != k)
  147. for(j = 0 ; j < m;  j++)
  148. swap(b(k, j), b(js[k], j));
  149. }
  150. return 1; //成功返回
  151. }
  152. //求解三对角线方程组的追赶法
  153. template <class _Ty>
  154. int LE_TridiagonalEquationGauss(valarray<_Ty>& b, valarray<_Ty>& d)
  155. {
  156. int j, k;
  157.     _Ty s;
  158. bool yn;
  159.     int n = d.size(); //方程组阶数
  160. //m为n阶三对角矩阵三条对角线上的元素个数,也是一维数组b的长度。
  161. //它的值应为m=3n-2, 在本函数中要对此值作检查
  162. int m = b.size();
  163.     if(m != (3 * n - 2)) //验证m是否等于3*n-2
  164. {
  165. cout << "Error!" << endl;
  166. return(-2);
  167. }
  168.     
  169. for(k = 0; k < n - 1; k++)
  170. {
  171. j = 3 * k;
  172. s = b[j];
  173. yn = FloatEqual(s, 0.0);
  174. if(yn) //主元为0
  175. {
  176. cout << "Fail!" << endl;
  177. return(0);
  178. }
  179.         b[j + 1] = b[j + 1] / s;
  180.         d[k] = d[k] / s;
  181.         b[j + 3] = b[j + 3] - b[j + 2] * b[j + 1];
  182.         d[k + 1] = d[k + 1] - b[j + 2] * d[k];
  183. }
  184.     
  185. s = b[3 * n - 3];
  186.     
  187. yn = FloatEqual(s, 0.0);
  188. if(yn) //主元为0
  189. {
  190. cout << "Fail!" << endl;
  191. return(0);
  192. }
  193.     
  194. d[n - 1] = d[n - 1] / s;
  195.     
  196. for(k = n - 2; k >= 0; k--)
  197. d[k] = d[k] - b[3 * k + 1] * d[k + 1];
  198.     
  199. return (2); //运算成功,正常返回
  200. }
  201. //一般带型方程组的求解
  202. template <class _Ty>
  203. int LE_StrapEquationGauss(matrix<_Ty>& b, matrix<_Ty>& d, int l, int il)
  204. {
  205. int ls, k, i, j, is, u, v, x, y, hh, xx, yy, xxx, yyy;
  206.     _Ty p, t, tt;
  207. bool yn;
  208.     
  209. int n = b.GetRowNum(); //矩阵b的行数
  210.     int nn = b.GetColNum();
  211. int mm = d.GetColNum(); //方程组右边常数向量的个数
  212.     if(il != (2 * l + 1)) //参数中半带宽l与带宽il的关系不对
  213. {
  214. cout<<"fail 1"<<endl;
  215. return(-2);
  216. }
  217.     
  218. ls = l;
  219.     
  220. for(k = 0; k < n - 1; k++)
  221. {
  222. p = 0.0;
  223.         for(i = k ; i <= ls; i++)
  224. {
  225. u = i * il;
  226. y = u % nn;  x = (u - y) / nn;
  227. t = Abs(b(x, y));
  228.             if(t > p) 
  229. p = t;
  230. is = i;
  231. }
  232. }
  233.         
  234. if( FloatEqual(p, 0.0) )
  235. {
  236. cout << "fail 2" << endl;
  237. return(0);
  238. }
  239.         
  240. for(j = 0; j < mm; j++)
  241. {
  242. u = k * mm + j;
  243. v = is * mm + j;
  244. y = u % mm;
  245. x = (u - y) / mm;
  246. yy = v % mm;
  247. xx = (v - yy) / mm;
  248.      tt = d(x, y);
  249. d(x, y) = d(xx, yy);
  250. d(xx, yy) = tt;
  251.         }
  252.         
  253. for(j = 0; j < il; j++)
  254. {
  255. u = k * il + j; 
  256. v = is * il + j;
  257.             y = u % nn;  
  258. x = (u - y) / nn;
  259. yy = v % nn; 
  260. xx = (v - yy) / nn;
  261.      tt = b(x, y);
  262. b(x, y) = b(xx, yy); 
  263. b(xx, yy) = tt;
  264. }
  265.         for(j = 0; j < mm; j++)
  266. {
  267. u = k * mm + j; v = k * il;
  268. y = u % mm;  x = (u - y) / mm;
  269.             yy = v % nn;  xx = (v - yy) / nn;
  270. d(x, y) = d(x, y) / b(xx, yy);
  271. }
  272.         for(j = 1; j < il; j++)
  273. {
  274. u = k * il + j;
  275. v = k * il;
  276. y = u % nn;  x = (u - y) / nn;
  277. yy = v % nn;  xx = (v - yy) / nn;
  278. b(x, y) = b(x, y) / b(xx, yy);
  279. }
  280.         
  281. for(i = k + 1; i <= ls; i++)
  282. {
  283.             hh = i * il;
  284.     y = hh % nn;
  285. x = (hh - y) / nn;
  286. t = b(x, y);
  287.             for(j = 0; j < mm; j++)
  288. {
  289. u = i * mm + j;
  290. v = k * mm + j;
  291. y = u % mm;
  292. x = (u - y) / mm;
  293. yy = v % mm;
  294. xx = (v - yy) / mm;    
  295.                 d(x, y) = d(x, y) - t * d(xx, yy);
  296. }
  297.             
  298. for(j = 1; j < il; j++)
  299. {
  300. u=i * il  +j;
  301. v = k * il + j;
  302. y = u % nn;  
  303. x = (u - y) / nn;
  304. yy = v % nn; 
  305. xx = (v - yy) / nn;
  306.                 yyy = (u - 1) % nn;  xxx = (u - yyy - 1) / nn;
  307.                 b(xxx, yyy) = b(x, y) - t * b(xx, yy);
  308. }
  309.             
  310. u = i * il + il - 1; 
  311. y = u % nn;  x = (u - y) / nn;
  312. b(x, y) = 0.0;
  313. }
  314.         
  315. if(ls != (n - 1)) ls++;
  316. }
  317.     
  318. u = (n - 1) * il; 
  319. y = u % nn;  
  320. x = (u - y) / nn;
  321. p = b(x, y);
  322.     
  323. yn = FloatEqual(p, 0.0);
  324. if(yn)
  325. {
  326. cout<<"fail 3"<<endl;
  327. return(0);
  328. }
  329.     
  330. for(j = 0; j < mm; j++)
  331. {
  332. u = (n - 1) * mm + j; 
  333. y = u % mm;  
  334. x = (u - y) / mm;
  335. d(x, y) = d(x, y) / p;
  336. }
  337.     ls = 1;
  338.     for(i = n  - 2; i >= 0; i--)
  339. {
  340. for(k = 0; k < mm; k++)
  341. u = i * mm + k;
  342.             for(j = 1; j <= ls; j++)
  343. {
  344. v = i * il +j;
  345. is = (i + j) * mm + k;
  346.                 y = u % mm;  
  347. x = (u - y) / mm;
  348. yy = v % nn;  
  349. xx = (v - yy) / nn;
  350.                 yyy = is % mm;  
  351. xxx = (is - yyy) / mm;
  352.                 d(x, y) = d(x, y) - b(xx, yy) * d(xxx, yyy);
  353. }
  354. }
  355.         if(ls != (il - 1)) ls++;
  356. }
  357.     
  358. return 2; //运算成功,正常返回
  359. }
  360. //求解对称方程组的分解法
  361. template <class _Ty>
  362. int LE_SymmetryEquation(matrix<_Ty>& a, matrix<_Ty>& c)
  363. {
  364. int i, j, k, k1, k2, k3;
  365.     _Ty p;
  366. bool yn;
  367. if(MatrixSymmetry(a)!=true)
  368. return (-1); //方程组不对称
  369.     
  370. int n = a.GetColNum(); //方程组阶数
  371. int m = c.GetColNum(); //方程组右边常数向量的个数
  372.     
  373. yn = FloatEqual(a(0,0), 0.0);
  374. if(yn) //主元为0
  375. {
  376. cout << "fail" << endl;
  377. return (-2);
  378. }
  379.     for(i = 1; i < n; i++)
  380. a(i, 0) /= a(0, 0);
  381.     for(i = 1; i < n - 1; i++)
  382. {
  383.         for(j = 1; j <= i; j++)
  384.             a(i, i) -= a(i, (j - 1)) * a(i, (j - 1)) * a((j - 1), (j - 1));
  385.         
  386. p = a(i,i);
  387.         yn = FloatEqual(p, 0.0);
  388. if(yn) //主元为0
  389. {
  390. cout<<"fail"<<endl;
  391. return (-2);
  392. }
  393.         
  394. for(k = i + 1; k < n; k++)
  395. {
  396.             for(j = 1; j <= i; j++)
  397. a(k, i) -= a(k, (j - 1)) * a(i,(j - 1)) * a((j - 1), (j - 1));
  398.             a(k, i) /= p;
  399. }
  400. }
  401.     
  402.     for(j = 1; j < n; j++)
  403.     a((n-1), (n-1)) -= a((n - 1), (j - 1)) * a((n - 1), (j - 1)) * a((j - 1), (j - 1));
  404.     
  405. p=a((n - 1), (n - 1));
  406.     yn = FloatEqual(p, 0.0);
  407. if(yn) //主元为0
  408. {
  409. cout<<"fail"<<endl;
  410. return (-2);
  411. }
  412.     
  413. for(j = 0; j < m; j++)
  414. for(i = 1; i < n; i++)
  415. for(k = 1; k <= i; k++)
  416. c(i, j) -= a(i, (k - 1)) * c((k - 1),j);
  417. for(i = 1; i < n; i++)
  418. for(j = i; j < n; j++)
  419.             a((i - 1), j) = a((i - 1), (i - 1)) * a(j, (i - 1));
  420.     
  421. for(j = 0; j < m; j++)  
  422.     {
  423. c((n - 1), j) /= p;
  424. for(k = 1; k < n; k++)
  425. {
  426. k1 = n - k; 
  427. k3 = k1 - 1; 
  428.             for(k2 = k1; k2 < n; k2++)
  429.                 c(k3, j) -= a(k3, k2) * c(k2, j);
  430. c(k3, j) /= a(k3, k3);
  431. }
  432. }
  433.     
  434. return (1); //运算成功,正常返回
  435. }
  436. //求解对称正定方程组的平方根法
  437. template <class _Ty>
  438. int LE_SymmetryRegularEuationSquareRoot(matrix<_Ty> & a, matrix<_Ty> & d)
  439. {
  440. int i, j, k;
  441. if(MatrixSymmetryRegular(a,1) != 2) //判别矩阵a是否对称正定
  442. return(-1); //矩阵a不对称正定
  443.     
  444. int n = a.GetColNum(); //方程组阶数
  445. int m = d.GetColNum(); //方程组右边常数向量的个数
  446. a(0,0) = sqrt( a(0, 0) );
  447.     for(j = 1; j < n; j++) a(0, j) /= a(0, 0);
  448.     
  449. for(i = 1; i < n; i++)
  450. {
  451.         for(j = 1; j <= i; j++)
  452.             a(i, i) = a(i, i) - a((j - 1), i) * a((j - 1), i);
  453.     
  454. a(i, i) = sqrt(a(i, i));
  455.         if(i != (n - 1))
  456. {
  457. for(j = i + 1; j < n; j++)
  458. {
  459.                 for(k = 1; k <= i; k++)
  460. a(i, j) -= a((k - 1), i) * a((k - 1), j);
  461.                 
  462. a(i, j) /= a(i, i);
  463. }
  464. }
  465. }
  466.     
  467. for(j = 0; j < m; j++)
  468. {
  469. d(0, j) = d(0, j) / a(0, 0);
  470.         for(i = 1; i < n; i++)
  471. {
  472.             for(k = 1; k <= i; k++)
  473. d(i, j) -= a((k - 1), i) * d((k - 1), j);
  474.             
  475. d(i, j) /= a(i, i);
  476. }
  477. }
  478.     
  479. for(j = 0; j < m; j++)
  480. {
  481.         d((n - 1), j) = d((n - 1), j) / a((n - 1), (n - 1));
  482. for(k = n - 1; k >= 1; k --)
  483. {
  484.     for(i = k; i < n; i++)
  485.         d((k - 1), j) -= a((k - 1), i) * d(i, j);
  486.         
  487.             d((k - 1), j) /= a((k - 1), (k - 1));
  488. }
  489. }
  490.     
  491. return (1); //运行成功,正常返回
  492. }
  493. //求解大型稀疏方程组的全选主元高斯-约当消去法
  494. template <class _Ty>
  495. int LE_SparseEuationTotalChoiceGaussJordan(matrix<_Ty> & a, valarray<_Ty> & b)
  496. int i, j, k, is;
  497.     _Ty d, t;
  498.     int n = a.GetColNum(); //方程组阶数
  499.     valarray<int> js(n);
  500.     for(k = 0; k < n; k++)
  501. d = 0.0;
  502.      for(i = k; i < n; i++)
  503. for(j = k; j < n; j++)
  504. {
  505. t = Abs(a(i, j));
  506. if(t > d)
  507. d = t;
  508. js[k] = j; 
  509. is = i;
  510. }
  511. }
  512. if( FloatEqual(d, 0.0) ) //主元为0
  513. {
  514. cout<<"fail 1"<<endl;
  515. return (0);
  516. }
  517. if(is != k)
  518. for(j = k; j < n; j++)
  519. {
  520. t = a(k, j);
  521. a(k, j) = a(is, j);
  522. a(is, j) = t;
  523. }
  524. t = b[k];
  525. b[k] = b[is];
  526. b[is] = t;
  527. }
  528. if(js[k] != k)
  529. for(i = 0; i < n; i++)
  530. {
  531. t = a(i, k);
  532. a(i, k) = a(i, js[k]); 
  533. a(i, js[k]) = t;
  534. }
  535. t = a(k, k);
  536. for(j = k + 1; j < n; j++)
  537. {
  538. if(a(k, j) != 0.0)
  539. a(k, j) = a(k, j) / t;
  540. }
  541. b[k] = b[k] / t;
  542. for(j = k + 1; j < n; j++)
  543. if(a(k, j) != 0.0)
  544. {
  545. for(i = 0; i < n; i++)
  546. {
  547. if((i != k) && (a(i, k) != 0.0))
  548. a(i, j) = a(i, j) - a(i, k) * a(k, j);
  549. }
  550. }
  551. }
  552. }
  553. for(i = 0; i <  n; i++)
  554. {
  555. if((i != k) && (a(i, k) != 0.0))
  556. b[i] = b[i] - a(i, k) * b[k];
  557. }
  558. }
  559. for(k = n - 1; k >= 0; k--)
  560. if(k != js[k])
  561. {
  562. t = b[k];
  563. b[k] = b[js[k]]; 
  564. b[js[k]] = t;
  565. }
  566.    
  567. return (1); //运行成功,正常返回
  568. }
  569. //求解托伯利兹方程组的列文逊方法
  570. template <class _Ty>
  571. int LE_ToeplitzEuationLevinson(valarray<_Ty>& t,  valarray<_Ty>& b, valarray<_Ty>& x)
  572. {
  573. int i, j, k;
  574.     _Ty a, beta, q, c, h;
  575. bool yn;
  576.     int n = t.size(); //方程组阶数
  577. valarray<_Ty> y(n);
  578. valarray<_Ty> s(n);
  579. a = t[0];
  580. yn = FloatEqual(a, 0.0);
  581.     if(yn)
  582. {
  583. cout << "fail 1" << endl;
  584. return(-1);
  585. }
  586.     
  587. y[0] = 1.0;
  588. x[0] = b[0] / a;
  589.     for(k = 1; k < n; k++)
  590. {
  591. beta = 0.0;
  592. q = 0.0;
  593.         
  594. for(j = 0; j < k; j++)
  595. {
  596. beta = beta + y[j] * t[j + 1];
  597.             q = q + x[j] * t[k - j];
  598. }
  599.         
  600. yn = FloatEqual(a, 0.0);
  601. if(yn)
  602. {
  603. cout << "fail 2" << endl;
  604. return(-1);
  605. }
  606.         
  607. c = -beta / a; 
  608. s[0] = c * y[k - 1]; 
  609. y[k] = y[k - 1];
  610.         
  611. if(k != 1)
  612. for(i = 1; i < k; i++)
  613. s[i] = y[i - 1] + c * y[k - i - 1];
  614. a = a + c * beta;
  615.         
  616. yn = FloatEqual(a, 0.0);
  617. if(yn)
  618. {
  619. cout << "fail 3" << endl;
  620. return (-1);
  621. }
  622.         h = (b[k] - q) / a;
  623.         
  624. for(i = 0; i < k ; i++)
  625. {
  626. x[i] = x[i] + h * s[i];
  627. y[i] = s[i];
  628. }
  629.         
  630. x[k] = h * y[k];
  631. }
  632.   
  633. return (1); //运行成功,正常返回
  634. }
  635. //高斯-赛德尔迭代
  636. template <class _Ty>
  637. int LE_GaussSeidelIteration(matrix<_Ty>& a, valarray<_Ty>& b, 
  638. valarray<_Ty>& x, _Ty eps)
  639. {
  640. int i, j;
  641.     _Ty p, t, s, q;
  642. int n = a.GetColNum(); //方程组阶数
  643.     
  644. for(i = 0; i < n; i++)
  645. {
  646. p = 0.0;
  647. x[i] = 0.0;
  648.         
  649. for(j = 0; j < n; j++)
  650. if(i != j)
  651. p = p + Abs(a(i, j));
  652.         
  653. if(p >= Abs(a(i, i)) ) //主对角线不占绝对优势
  654. {
  655. cout<<"fail 1"<<endl;
  656. return(-1);
  657. }
  658. }
  659.     
  660. p = eps + 1.0;
  661.     while(p > eps  || FloatEqual(p, eps))
  662. {
  663. p = 0.0;
  664.         for(i = 0; i < n; i++)
  665. {
  666. t = x[i];
  667. s = 0.0;
  668.             for(j = 0; j < n; j++)
  669. if(j != i) 
  670. s = s + a(i, j) * x[j];
  671. x[i] = (b[i] - s) / a(i, i);
  672.             q = Abs(x[i] - t) / (1.0 + Abs(x[i]));
  673.             if(q > p) p = q;
  674. }
  675. }
  676. return (1); //运行成功,正常返回
  677. }
  678.     
  679. //求解对称正定方程组的共轭梯度法
  680. template <class _Ty>
  681. int LE_SymmetryRegularEuationConjugateGradient(matrix<_Ty> & a, 
  682. valarray<_Ty> & b, _Ty eps, valarray<_Ty> & x)
  683. {
  684. int i, k;
  685.     _Ty  alpha, beta, d, e;
  686. if(MatrixSymmetryRegular(a,1) != 2) //判别矩阵a是否对称正定
  687. return(-1); //矩阵a不对称正定
  688.     
  689. int n = a.GetColNum(); //方程组阶数
  690.     valarray<_Ty> r(n);
  691.     
  692. matrix<double> q(n, 1);
  693.     matrix<double> p(n, 1);
  694. matrix<double> s(n, 1);
  695.     matrix<double> xx(n, 1);
  696.     
  697. for(i = 0; i < n; i++) 
  698. xx(i, 0) = x[i];
  699.     for(i = 0; i < n; i++)
  700. {
  701. xx(i,0) = 0.0;
  702. p(i, 0) = b[i];
  703. r[i] = b[i]; 
  704. }
  705.     
  706. i = 0;
  707.     while(i < n)
  708. {
  709. MatrixMultiply(s, a, p);
  710.         d = 0.0;
  711. e = 0.0;
  712.         
  713. for(k = 0; k < n; k++)
  714. {
  715. d = d + p(k, 0) * b[k];
  716. e = e + p(k, 0) * s(k,0); 
  717. }
  718.         
  719. alpha = d / e;
  720.         
  721. for(k = 0; k < n; k++)
  722. xx(k,0) = xx(k, 0) + alpha * p(k, 0);
  723.         
  724. MatrixMultiply(q, a, xx);
  725.         
  726. d = 0.0;
  727.         
  728. for(k = 0; k < n; k++)
  729. {
  730. r[k] = b[k] - q(k, 0);
  731. d = d + r[k] * s(k, 0);
  732. }
  733.         
  734. beta = d / e;
  735. d = 0.0;
  736.         
  737. for(k = 0; k < n; k++) d = d + r[k] * r[k];
  738.         
  739. d = sqrt(d);
  740.         
  741. if(d < eps) 
  742. {
  743. for(i = 0; i < n; i++) 
  744. x[i] = xx(i, 0);
  745. }
  746.         for(k = 0; k < n; k++) 
  747.   p(k, 0) = r[k] - beta * p(k, 0);
  748.         
  749. i++;
  750. }
  751. for(i = 0; i < n; i++) 
  752. x[i] = xx(i, 0);
  753. return (1); //运行成功,正常返回
  754. }
  755. //求解线性最小二乘问题的豪斯荷尔德变换法
  756. template <class _Ty>
  757. int LE_LinearLeastSquareHouseholder(matrix<_Ty>& a, valarray<_Ty>& b, matrix<_Ty>& q)
  758. {
  759. int i,j;
  760.     _Ty d;
  761.     int n = a.GetColNum(); //系数矩阵a的行数,m>=n
  762. int m = a.GetRowNum(); //系数矩阵a的列数,n<=m
  763.     
  764. valarray<_Ty> c(n);
  765.     i = MatrixQR(a, q); //一般m×n阶的实矩阵QR分解函数
  766.     if(i == 0)
  767. {
  768. return (-1);
  769. }
  770. for(i = 0; i < n; i++)
  771. {
  772. d = 0.0;
  773.         for(j = 0; j < m; j ++)
  774. d = d + q(j ,i) * b[j];
  775.         
  776. c[i] = d;
  777. }
  778.     
  779. b[n - 1] = c[n - 1] / a((n - 1), (n - 1));
  780.     for(i = n - 2; i >= 0; i--)
  781. {
  782. d = 0.0;
  783.         for(j = i + 1; j < n; j++)
  784. d = d + a(i,j) * b[j];
  785.         
  786. b[i] = (c[i] - d) / a(i, i);
  787. }
  788. return (1); //运行成功,正常返回
  789. }
  790. //求解线性最小二乘问题的广义逆法
  791. template <class _Ty>
  792. int LE_LinearLeastSquareGeneralizedInverse(matrix<_Ty>& a, 
  793. valarray<_Ty>& b, valarray<_Ty>& x, matrix<_Ty>& aa, 
  794. _Ty eps, matrix<_Ty>& u, matrix<_Ty>& v)
  795. {
  796. int i, j, ii;
  797.        
  798. int n = a.GetColNum(); //系数矩阵a的列数
  799. int m = a.GetRowNum(); //系数矩阵a的行数
  800.     
  801. int ka = (n > m) ? n : m;
  802. ka++;
  803. ii = GeneralizedInversionSingularValue(a, aa, eps, u, v);
  804.     
  805. if(ii < 0)  return(-1);
  806.     
  807. for(i = 0; i < n; i ++)
  808. {
  809. x[i] = 0.0;
  810.         for(j = 0; j < m; j ++)
  811. {
  812. x[i] += aa(i, j) * b[j];
  813. }
  814. }
  815.     
  816. return (1); //运行成功,正常返回
  817. }
  818. //病态方程组的求解
  819. template <class _Ty>
  820. int LE_IllConditionedEquation(matrix<_Ty> & a, valarray<_Ty> & b, _Ty eps, valarray<_Ty> & x)
  821. {
  822. int i(60), j, kk;
  823.     _Ty q, qq;
  824.     int n = a.GetColNum(); //方程组阶数
  825. matrix<_Ty> p(n, n);
  826. matrix<_Ty> ee(n, 1);
  827. matrix<_Ty> xx(n, 1);
  828. valarray<double> rr(n);
  829.     
  830. for(int k = 0; k < n; k++)
  831. for(j = 0; j < n; j++)
  832. p(k, j) = a(k, j);
  833. for(k = 0; k < n; k++) x[k] = b[k];
  834.     kk = LE_TotalChoiceGauss(p, x);
  835. for(int w = 0; w < n; w++) xx(w, 0) = x[w];  
  836. if(kk == 0)
  837. for( w = 0; w < n; w++) x[w] = xx(w, 0);
  838.     
  839. return 0;
  840. }
  841.     
  842. q = 1.0 + eps;
  843.     while(q > eps || FloatEqual(q, eps))
  844. {
  845. if(i == 0)
  846. for( w = 0; w < n; w++) x[w] = xx(w, 0);
  847. return 0;
  848. }
  849.         i--;        
  850. MatrixMultiply(ee, a, xx);
  851. for( w = 0; w < n; w++) x[w] = xx(w, 0);        
  852. for(k = 0; k < n; k++) rr[k] = b[k] - ee(k, 0);
  853.         for(k = 0; k < n; k++)
  854. for(j = 0; j < n; j++) p(k, j) = a(k, j);
  855. kk = LE_TotalChoiceGauss(p, rr);
  856.         if(kk == 0)
  857. for( w = 0; w < n; w++) x[w] = xx(w, 0);
  858. return 0;
  859. }
  860.         
  861. q = 0.0;
  862.         for(k = 0; k < n; k++)
  863. {
  864. qq = Abs(rr[k]) / (1.0 + Abs(x[k] + rr[k]));
  865.             if(qq > q) q = qq;
  866. }
  867.         
  868. for(k = 0; k < n; k++) xx(k, 0) = xx(k, 0) + rr[k];
  869. for(int w = 0; w < n; w++)  x[w] = xx(w, 0);     
  870. }
  871. for( w = 0; w < n; w++) x[w] = xx(w, 0);
  872. return (1); //运行成功,正常返回
  873. }
  874. #endif //_LINEAREQUATION_INL