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

Visual C++

  1. // Matrix.inl 矩阵模板类函数(方法)定义
  2. // Ver 1.0.0.0
  3. // 版权所有(C) 何渝, 2002
  4. // 最后修改: 2002.5.31
  5. #ifndef _MATRIX_INL
  6. #define _MATRIX_INL
  7. //矩阵乘法函数
  8. template <class _Tyout, class _Tylhs, class _Tyrhs> //最后结果在mOut中
  9. matrix<_Tyout>& MatrixMultiply(matrix<_Tyout>& mOut, const matrix<_Tylhs>& lhs, const matrix<_Tyrhs>& rhs)
  10. { //断定左边矩阵的列数与右边矩阵的行数相等
  11. Assert(lhs.GetColNum() == rhs.GetRowNum());
  12. //生成矩阵新对象,用lhs的行作为新阵的行数,用rhs的列数作为新阵的列数
  13. matrix<_Tyout> mTmp(lhs.GetRowNum(), rhs.GetColNum());
  14. for(size_t i = 0; i < mTmp.GetRowNum(); i ++)
  15. {
  16. for(size_t j = 0; j < mTmp.GetColNum(); j ++)
  17. {
  18. mTmp(i, j) = _Tyout(0); //赋初值0
  19. for(size_t k = 0; k < lhs.GetColNum(); k ++)
  20. {
  21. mTmp(i, j) += lhs(i, k) * rhs(k, j);
  22. }
  23. }
  24. }
  25. mOut = mTmp; //将最后结果转放入mOut矩阵中
  26. return mOut; //返回结果矩阵mOut
  27. }
  28. //输出矩阵函数 按一行一行进行输出
  29. template <class _Ty>
  30. void MatrixLinePrint(const matrix<_Ty>& mOut)
  31. {
  32. size_t sR, sC;
  33. sR=mOut.GetRowNum();
  34. sC=mOut.GetColNum();
  35. for(size_t stR=0; stR<mOut.GetRowNum(); stR++)
  36. {
  37. for(size_t stC=0; stC<mOut.GetColNum(); stC++)
  38. {
  39. cout.width(15); //元素对齐,让每个元素占15列
  40. cout << mOut(stR, stC) << ' ';
  41. }
  42. cout << endl;
  43. }
  44. }
  45. //输出矩阵函数 按指定行进行输出
  46. template <class _Ty>
  47. void MatrixLinePrint(const matrix<_Ty>& mOut, size_t LineNo)
  48. {
  49. size_t sR, sC;
  50. sR=mOut.GetRowNum();
  51. sC=mOut.GetColNum();
  52. for(size_t stC=0; stC<mOut.GetColNum(); stC++)
  53. {
  54. cout.width(15); //元素对齐,让每个元素占15列
  55. cout << mOut(LineNo, stC) << ' ';
  56. }
  57. cout << endl;
  58. }
  59. //矩阵转置 == 原阵在mIn,转置后的矩阵在mOut  ==
  60. template <class _Ty>
  61. void MatrixTranspose(matrix<_Ty>& mIn, matrix<_Ty>& mOut)
  62. {
  63. size_t sR, sC;
  64. sR = mIn.GetRowNum(); //取原矩阵行数
  65. sC = mIn.GetColNum(); //取原矩阵列数
  66. matrix<_Ty> mTemp(sC, sR); //生成一新阵,行数与列数与原阵互换
  67. for(size_t stC=0; stC<sC; stC++)
  68. for(size_t stR=0; stR<sR; stR++)
  69. mTemp(stC, stR) = mIn(stR, stC); //对新阵赋值
  70. mOut = mTemp; //返回新的转置阵
  71. }
  72. //判断矩阵对称
  73. template <class _Ty>
  74. bool MatrixSymmetry(const matrix<_Ty>& rhs)
  75. {
  76. bool bSy = true;
  77. size_t stRow = rhs.GetRowNum(); //取矩阵行数
  78. if(rhs.GetColNum() == stRow) // 必须是方阵
  79. {
  80. for(size_t i = 1; i < stRow; i ++) //判断是否对称
  81. for(size_t j = 0; j < i; j ++)
  82. if(FloatNotEqual((long double)rhs(i, j), (long double)rhs(j, i)))
  83. {
  84. bSy =  false;
  85. goto RET;
  86. }
  87. }
  88. else
  89. bSy = false;
  90. RET: return bSy; //矩阵对称
  91. }
  92. //判断矩阵对称正定
  93. template <class _Ty>
  94. int MatrixSymmetryRegular(const matrix<_Ty>& rhs, int sym)
  95. {
  96. long double ldDet;
  97. size_t i, j, k;
  98. size_t sC = rhs.GetColNum(); //矩阵列数
  99. size_t sR = rhs.GetRowNum(); //矩阵行数
  100. size_t stRank = sR; // 矩阵阶数
  101. if(stRank != rhs.GetRowNum())
  102. return int(-1); // 不是方阵
  103. if(sym > 0)
  104. if(MatrixSymmetry(rhs)==false)
  105. return int(-2); //rhs不是对称阵
  106. cout << " K = 1 t Determinant = " << rhs(0, 0) <<endl;
  107. for(k = 0; k < stRank; k ++) //若要判别半正定,负定,这句要修改
  108. {
  109. if(FloatEqual(rhs(k, k), 0)||rhs(k, k) < 0)
  110. return int(-3); //对角元不大于0,矩阵不是正定阵
  111. }
  112. for(k = 2; k <= sR; k++)
  113. {
  114. matrix<long double> m(k, k); //生成一matrix对象
  115. for(i=0; i<k; i++)
  116. for(j=0; j<k; j++)
  117. m(i, j) = (long double)rhs(i, j); //初始化
  118. ldDet = MatrixDeterminant(m); // 顺序主子式的值
  119. cout << " K = " << k << "t Determinant = " << ldDet << endl; 
  120. if(FloatEqual(ldDet,0) || ldDet < 0.0)
  121. return (0); //不是正定阵
  122. }
  123. if(sym == 1) return int(2); //矩阵为正定对称阵
  124. else  return int(1); //矩阵为正定阵
  125. }
  126. //全选主元法求矩阵行列式函数
  127. template <class _Ty>
  128. long double MatrixDeterminant(const matrix<_Ty>& rhs)
  129. {
  130. long double  MaxValue, tmp;
  131. size_t stRank = rhs.GetColNum(); // 矩阵阶数
  132. if(stRank != rhs.GetRowNum())
  133. return long double(0); //rhs不是方阵
  134. matrix<long double> m(stRank, stRank); //生成一matrix对象
  135. for(size_t i=0; i<stRank; i++)
  136. for(size_t j=0; j<stRank; j++)
  137. m(i, j) = (long double)rhs(i, j); //初始化
  138. size_t iSign, jSign; // 主元的位置标志
  139. long double Det(1); // 行列式的值
  140. int nSgn = 1; // 符号
  141. for(size_t k = 0; k < stRank - 1; k ++) // 全选主元
  142. {
  143. MaxValue = 0.0;
  144. for(i = k; i < stRank; i ++)
  145. {
  146. for(size_t j = k; j < stRank; j ++)
  147. {
  148. tmp = Abs(m(i, j)); //求m(i,j)绝对值
  149. if(tmp > MaxValue)
  150. {
  151. MaxValue = tmp;
  152. iSign = i; //记下主元位置
  153. jSign = j;
  154. }
  155. }
  156. }
  157. if(FloatEqual(MaxValue, 0)) //绝对值最大元素为0,行列式也为0
  158. return long double(0);
  159. if(iSign != k) //绝对值最大元素不在当前行
  160. {
  161. nSgn = -nSgn; //变换行列式符号
  162. for(size_t j = k; j < stRank; j ++) //交换行
  163. swap(m(k, j), m(iSign, j));
  164. }
  165. if(jSign != k) //绝对值最大元素不在当前列
  166. {
  167. nSgn = -nSgn; //变换行列式符号
  168. for(size_t i = k; i < stRank; i ++) //交换列
  169. swap(m(i, jSign), m(i, k));
  170. }
  171. Det *= m(k, k); //对角元相乘
  172. for(i = k + 1; i < stRank; i ++)
  173. {
  174. long double d(m(i, k) / m(k, k)); //消元因子
  175. for(size_t j = k + 1; j < stRank; j ++) //将主元下方元素消为0
  176. m(i, j) -= d * m(k, j); //当前主元行下行其余元素作变换
  177. }
  178. }
  179. return Det * nSgn * m(stRank - 1, stRank - 1); //返回行列式数值
  180. }
  181. //全选主元高斯(Gauss)消去法求一般矩阵的秩
  182. template <class _Ty> //返回值为秩数
  183. size_t MatrixRank(const matrix<_Ty>& rhs)
  184. {
  185. size_t iSign, jSign; //主元的位置标志
  186. size_t mRank = 0; //矩阵秩数
  187. size_t stRow = rhs.GetRowNum(); //取矩阵行数
  188. size_t stCol = rhs.GetColNum(); //取矩阵列数
  189. size_t ColRowMin = Min(stRow, stCol); //取行或列最小值
  190. matrix<_Ty> m(rhs); //生成一matrix对象,用rhs初始化
  191. for(size_t k = 0; k < ColRowMin; k ++)
  192. { // 全选主元
  193. long double MaxValue(0);
  194. for(size_t i = k; i < stRow; i ++)
  195. {
  196. for(size_t j = k; j < stCol; j ++)
  197. {
  198. long double tmp(Abs(m(i, j))); //求m(i,j)绝对值
  199. if(tmp > MaxValue)
  200. {
  201. MaxValue = tmp;
  202. iSign = i; //记下主元位置
  203. jSign = j;
  204. }
  205. }
  206. }
  207. //子阵元素绝对值最大者为0, 注意浮点数与0相等的定义,见comm.h
  208. if(FloatEqual(MaxValue, 0)) 
  209. break; //return mRank;
  210. else
  211. mRank++; //子阵元素绝对值最大者不为0,矩阵秩加1
  212. if(k ==(ColRowMin - 1)) //已到最后一行(列)
  213. break; //return mRank;
  214. if(iSign != k) //主元不在当前行
  215. {
  216. for(size_t j = k; j < stCol; j ++) //交换行元素
  217. swap(m(k, j), m(iSign, j));
  218. }
  219. if(jSign != k) //主元不在当前列
  220. {
  221. for(size_t i = k; i < stRow; i ++) //交换列元素
  222. swap(m(i, jSign), m(i, k));
  223. }
  224. for(i = k + 1; i < stRow; i ++)
  225. {
  226. const _Ty d(m(i, k) / m(k, k)); //消元因子
  227. for(size_t j = k + 1; j < stCol; j ++)
  228. m(i, j) -= d * m(k, j); //当前主元右下阵元素作变换
  229. }
  230. }
  231. return mRank;
  232. }
  233. //全选主元高斯-约当(Gauss-Jordan)法求矩阵逆
  234. template <class _Ty>
  235. int MatrixInversionGS(matrix<_Ty >& rhs)
  236. {
  237. size_t stRank = rhs.GetColNum(); // 矩阵阶数
  238. if(stRank != rhs.GetRowNum())
  239. return int(-1); //rhs不是方阵
  240. valarray<size_t> is(stRank); //行交换信息
  241. valarray<size_t> js(stRank); //列交换信息
  242. matrix<_Ty> m(rhs); //生成一matrix对象
  243. for(size_t k = 0; k < stRank; k++)
  244. { // 全选主元
  245. long double MaxValue(0);
  246. for(size_t i = k; i < stRank; i ++)
  247. {
  248. for(size_t j = k; j < stRank; j ++)
  249. {
  250. long double tmp(Abs(m(i, j))); //求m(i,j)绝对值
  251. if(tmp > MaxValue) //主元不在对角线上
  252. {
  253. MaxValue = tmp;
  254. is[k] = i; //记录主元行数
  255. js[k] = j; //记录主元列数
  256. }
  257. }
  258. }
  259. if(FloatEqual(MaxValue, 0)) 
  260. return int(0); //主元为0,矩阵奇异
  261. if(is[k] != k) //主元不在当前行
  262. {
  263. for(size_t j = 0; j < stRank; j ++) //交换行元素
  264. swap(m(k, j), m(is[k], j));
  265. }
  266. if(js[k] != k) //主元不在当前列
  267. {
  268. for(size_t i = 0; i < stRank; i ++) //交换列元素
  269. swap(m(i, k), m(i, js[k]));
  270. }
  271. m(k, k) = 1.0 / m(k, k); //主元倒数
  272. for(size_t j = 0; j < stRank; j ++)
  273. if(j != k)
  274. m(k, j) *= m(k, k);
  275. for(i = 0; i < stRank; i ++)
  276. if(i != k)
  277. for(size_t j = 0; j < stRank; j ++)
  278. if(j != k)
  279. m(i, j) = m(i, j) - m(i, k) * m(k, j);
  280. for(i = 0; i < stRank; i ++)
  281. if(i != k)
  282. m(i, k) = -m(i, k) * m(k, k);
  283. }
  284. for(int r = stRank - 1; r >= 0; r--)
  285. {
  286. if(js[r] != r)
  287. for(size_t j = 0; j < stRank; j ++)
  288. swap(m(r, j), m(js[r], j));
  289. if(is[r] != r)
  290. for(size_t i = 0; i < stRank; i ++)
  291. swap(m(i, r), m(i, is[r]));
  292. }
  293. rhs = m;
  294. return int(1);
  295. }
  296. //用“变量循环重新编号法”求对称正定矩阵逆
  297. //矩阵类型必须是浮点型
  298. template <class _Ty>
  299. int MatrixSymmetryRegularInversion(matrix<_Ty>& rhs)
  300. {
  301. int iSym = MatrixSymmetryRegular(rhs, 1); //判别是否对称正定
  302. if(iSym < 2)
  303. return (iSym); //rhs不是对称正定阵
  304. size_t stRank = rhs.GetColNum(); // 矩阵阶数
  305. matrix<_Ty> msr(rhs); //生成一matrix对象,用rhs初始化
  306. valarray<_Ty> b(stRank);
  307. for(size_t k=0; k<stRank; k++)
  308. {
  309. _Ty w= msr(0, 0);
  310. size_t m = stRank - k -1;
  311. for(size_t i = 1; i < stRank; i++)
  312. {
  313. _Ty g = msr(i, 0);
  314. b[i] = g / w;
  315. if(i <= m) b[i] = -b[i];
  316. for(size_t j = 1; j <= i; j ++)
  317. msr((i-1),(j-1)) = msr(i, j) + g * b[j];
  318. }
  319. msr(stRank-1, stRank-1) = 1.0 / w;
  320. for(i = 1; i < stRank; i ++)
  321. msr(stRank-1,(i-1)) =  b[i];
  322. }
  323. for(size_t i = 0; i < stRank-1; i ++)
  324. for(size_t j = i+1; j < stRank; j ++)
  325. msr(i,j) = msr(j, i);
  326. rhs = msr;
  327. return (iSym);
  328. }
  329. //特兰持(Trench)法求托伯利兹(Toeplitz)矩阵逆
  330. //矩阵类型必须是浮点型
  331. template <class _Ty>
  332. int MatrixToeplitzInversionTrench(const valarray<_Ty>& t, const valarray<_Ty>& tuo, matrix<_Ty>& rhs)
  333. {
  334. size_t stRank = rhs.GetColNum(); // 矩阵阶数
  335. if(stRank != rhs.GetRowNum())
  336. return int(-1); //rhs不是方阵
  337. if(FloatEqual(t[0], 0))
  338. return int(0);
  339. valarray<_Ty> c(stRank);
  340. valarray<_Ty> r(stRank);
  341. valarray<_Ty> p(stRank);
  342. _Ty a=t[0]; 
  343. c[0]=tuo[1]/t[0];
  344. r[0]=t[1]/t[0];
  345. matrix<_Ty> b(rhs);
  346. for(size_t k=0; k<=stRank-3; k++)
  347. {
  348. _Ty s=0.0;
  349. for(size_t j=1; j<=k+1; j++)
  350. s=s+c[k+1-j]*tuo[j];
  351. s=(s-tuo[k+2])/a;
  352. for(size_t i=0; i<=k; i++)
  353. p[i]=c[i]+s*r[k-i];
  354.         c[k+1]=-s;
  355.         s=0.0;
  356.         for(j=1; j<=k+1; j++)
  357. s=s+r[k+1-j]*t[j];
  358.         s=(s-t[k+2])/a;
  359.         for(i=0; i<=k; i++)
  360.         {
  361. r[i]=r[i]+s*c[k-i];
  362.             c[k-i]=p[k-i];
  363.         }
  364.         r[k+1]=-s;
  365. a=0.0;
  366.         for(j=1; j<=k+2; j++)
  367. a=a+t[j]*c[j-1];
  368.         a=t[0]-a;
  369. if(FloatEqual(a, 0))
  370. return int(0);
  371.     }
  372.     b(0,0)=1.0/a;
  373.     for(size_t i=0; i<stRank-1; i++)
  374.     {
  375. k=i+1;
  376.         b(0, k)=-r[i]/a;
  377. b(i+1,0)=-c[i]/a;
  378.     }
  379.     for(i=0; i<stRank-1; i++)
  380.     for(size_t j=0; j<stRank-1; j++)
  381.         b(i+1, j+1)=b(i,j)-c[i]*b(0,j+1)+c[stRank-j-2]*b(0,stRank-i-1);
  382. rhs = b;
  383.     
  384.     return int(1);
  385. }
  386. //实矩阵LU分解
  387. //矩阵必须是浮点型
  388. template <class _Ty>
  389. int MatrixLU(const matrix<_Ty>& rhs, matrix<_Ty>& lhs, matrix<_Ty>& uhs)
  390. {
  391. size_t stRank = rhs.GetColNum(); // 矩阵阶数
  392. if(stRank != rhs.GetRowNum())
  393. return int(-1); //rhs不是方阵
  394. matrix<_Ty> m(rhs);
  395. for(size_t k=0; k<stRank-1; k++)
  396. {
  397. if(FloatEqual(m(k,k),0))
  398. return int(0); //主元为0
  399. for(size_t i=k+1; i<stRank; i++)
  400. m(i,k) /= m(k,k);
  401. for(i=k+1; i<stRank; i++)
  402. for(size_t j=k+1; j<stRank; j++)
  403. m(i,j)=m(i,j)-m(i,k)*m(k,j);
  404. }
  405. //给上、下三角阵赋值
  406. for(size_t i=0; i<stRank; i++)
  407. {
  408. for(size_t j=0; j<i; j++)
  409. {
  410. lhs(i,j)=m(i,j);
  411. uhs(i,j)=0.0;
  412. }
  413. lhs(i,i)=1.0;
  414. uhs(i,i)=m(i,i);
  415. for(j=i+1; j<stRank; j++)
  416. {
  417. lhs(i,j)=0.0;
  418. uhs(i,j)=m(i,j);
  419. }
  420. }
  421. return (1); //分解成功
  422. }
  423. //用豪斯荷尔德(Householder)变换对一般m*n阶的实矩阵进行QR分解
  424. template <class _Ty>
  425. int MatrixQR(matrix<_Ty>& rhs, matrix<_Ty>& rhq)
  426. {
  427. size_t stRow = rhs.GetRowNum(); // 矩阵行数
  428. size_t stCol = rhs.GetColNum(); // 矩阵列数
  429. if(stRow < stCol)
  430. return (0); //行不能小于列
  431. for(size_t i=0; i<stRow; i++)
  432.     for(size_t j=0; j<stRow; j++)
  433.     { 
  434. rhq(i,j)=0.0;
  435.         if(i==j) rhq(i,j)=1.0;
  436.     }
  437. size_t nn=stCol;
  438.     
  439. if(stRow == stCol) nn=stRow-1;
  440. for(size_t k=0; k<nn; k++)
  441.     {
  442. _Ty u=0.0;
  443.         for(size_t i = k; i < stRow; i++)
  444.         { 
  445. _Ty w = Abs(rhs(i,k));
  446.             if(w > u) u = w;
  447.         }
  448.         _Ty alpha=0.0;
  449.         for(i = k; i < stRow; i++)
  450.         {
  451. _Ty t=rhs(i,k)/u;
  452. alpha=alpha+t*t;
  453. }
  454.         
  455. if(rhs(k,k)>0.0) u=-u;
  456.         
  457. alpha=u*sqrt(alpha);
  458.         
  459. if(FloatEqual(alpha,0.0)) return(0);
  460.         u=sqrt(2.0*alpha*(alpha-rhs(k,k)));
  461.         if(FloatNotEqual(u,0.0))
  462.         { 
  463. rhs(k,k)=(rhs(k,k)-alpha)/u;
  464.             
  465. for(i=k+1; i<stRow; i++)
  466.              rhs(i,k) /= u;
  467. for(size_t j=0; j<stRow; j++)
  468.             {
  469. _Ty t=0.0;
  470.                 for(size_t jj=k; jj<stRow; jj++)
  471. t=t+rhs(jj,k)*rhq(jj,j);
  472.                 for(i=k; i<stRow; i++)
  473. rhq(i,j)=rhq(i,j)-2.0*t*rhs(i,k);
  474.             }
  475.             
  476. for(j=k+1; j<stCol; j++)
  477.             { 
  478. _Ty t=0.0;
  479.             
  480. for(size_t jj=k; jj<stRow; jj++)
  481. t=t+rhs(jj,k)*rhs(jj,j);
  482.                 for(i=k; i<stRow; i++)
  483.              rhs(i,j)=rhs(i,j)-2.0*t*rhs(i,k);
  484. }
  485.             rhs(k,k)=alpha;
  486.             for(i=k+1; i<stRow; i++)
  487.               rhs(i,k)=0.0;
  488.           }
  489.     }
  490. for(i=0; i<stRow-1; i++)
  491. for(size_t j=i+1; j<stRow;j++)
  492. swap(rhq(i,j), rhq(j,i));
  493.     return (1);
  494. }
  495. //对称正定阵的乔里斯基(Cholesky)分解及求其行列式值
  496. //矩阵与返回值类型必须是浮点型
  497. template <class _Ty>
  498. long double MatrixSymmetryRegularCholesky(matrix<_Ty>& rhs)
  499. {
  500. int iReValue= MatrixSymmetryRegular(rhs, 1); //判别对称正定
  501. if(iReValue < 2)
  502. return long double(0); //rhs不是对称正定阵
  503. size_t stRank = rhs.GetColNum(); // 矩阵阶数
  504. matrix<_Ty> m(rhs); //生成一matrix对象,用rhs初始化
  505. long double Det = m(0,0); //计算行列式值
  506. m(0,0) = sqrt(m(0,0)); 
  507. for(size_t i=1; i<stRank; i++)
  508. m(i, 0) /= m(0, 0);
  509. for(size_t j=1; j<stRank; j++)
  510. {
  511. for(size_t k=0; k<j; k++)
  512. m(j,j) = m(j,j) - m(j,k) * m(j,k);
  513. Det *= m(j,j);
  514. m(j,j) = sqrt(m(j,j));
  515. for(i=j+1; i<stRank; i++)
  516. {
  517. for(k=0; k<j; k++)
  518. m(i,j) = m(i,j) -m(i,k) * m(j,k);
  519. m(i,j) /= m(j,j);
  520. }
  521. }
  522. for(i=0; i<stRank-1; i++)
  523.     for(j=i+1; j<stRank; j++)
  524. m(i,j)=0;
  525. rhs = m; //返回Cholesky阵,原矩阵将被复盖
  526. return Det; //返回行列式值
  527. }
  528. //一般实矩阵的奇异值分解
  529. template <class _Ty>
  530. int MatrixSingularValue(matrix<_Ty>& a, matrix<_Ty>& u, 
  531. matrix<_Ty>& v, _Ty eps)
  532. {
  533. int i, it(60), kk, mm, nn, m1, ks, ka;
  534.     _Ty d,dd,t,sm,sm1,em1,sk,ek,b,c,shh;
  535. int m = a.GetRowNum();
  536. int n = a.GetColNum();
  537. for(int j=0; j<m; j++) u(j, m-1) = _Ty(0);
  538. if(m > n) ka = m + 1;
  539. else ka = n + 1;
  540. valarray<_Ty> s(ka), e(ka), w(ka), fg(2), cs(2);
  541.     
  542. int k = n;
  543.     if(m-1<n) k=m-1;
  544.     int l = m;
  545.     if(n-2<m) l=n-2;
  546.     if(l<0) l=0;
  547.     int ll=k;
  548.     if(l>k) ll=l;
  549.     if(ll>=1)
  550.     { 
  551. for(kk=1; kk<=ll; kk++)
  552.         {
  553. if(kk<=k)
  554.             {
  555. d=0.0;
  556.                 for(i=kk; i<=m; i++)
  557. d=d+a(i-1,kk-1)*a(i-1,kk-1);
  558.                 s[kk-1]=sqrt(d);
  559.                 if(FloatNotEqual(s[kk-1],0.0))
  560.                 {
  561.                     if(FloatNotEqual(a(kk-1,kk-1),0.0))
  562.                     {
  563. s[kk-1]=Abs(s[kk-1]);
  564.                         if(a(kk-1,kk-1)<0.0) s[kk-1]=-s[kk-1];
  565.                     }
  566.                     for(i=kk; i<=m; i++) a(i-1,kk-1)=a(i-1,kk-1)/s[kk-1];
  567.                     a(kk-1,kk-1)=1.0+a(kk-1,kk-1);
  568.                 }
  569.                 s[kk-1]=-s[kk-1];
  570.             }
  571.             if(n>=kk+1)
  572.             { 
  573. for(j=kk+1; j<=n; j++)
  574.                 {
  575. if((kk<=k)&&(FloatNotEqual(s[kk-1],0.0)))
  576.                     {
  577. d=0.0;
  578.                         for(i=kk; i<=m; i++) d=d+a(i-1,kk-1)*a(i-1,j-1);
  579.                         d=-d/a(kk-1,kk-1);
  580.                         for(i=kk; i<=m; i++) a(i-1,j-1)=a(i-1,j-1)+d*a(i-1,kk-1);
  581.                     }
  582.                     e[j-1]=a(kk-1,j-1);
  583.                 }
  584.             }
  585.             if(kk<=k)
  586. for(i=kk; i<=m; i++) u(i-1,kk-1)=a(i-1,kk-1);
  587.             if(kk<=l)
  588.             { 
  589. d=0.0;
  590.                 for(i=kk+1; i<=n; i++)
  591.                   d=d+e[i-1]*e[i-1];
  592.                 e[kk-1]=sqrt(d);
  593.                 if(FloatNotEqual(e[kk-1],0.0))
  594.                 {
  595. if(FloatNotEqual(e[kk],0.0))
  596.                     {
  597. e[kk-1]=Abs(e[kk-1]);
  598.                         if(e[kk]<0.0) e[kk-1]=-e[kk-1];
  599.                     }
  600.                     for(i=kk+1; i<=n; i++)
  601.                       e[i-1]=e[i-1]/e[kk-1];
  602.                     e[kk]=1.0+e[kk];
  603.                 }
  604.                 e[kk-1]=-e[kk-1];
  605.                 if((kk+1<=m)&&(FloatNotEqual(e[kk-1],0.0)))
  606.                 { 
  607. for(i=kk+1; i<=m; i++) w[i-1]=0.0;
  608.                     for(j=kk+1; j<=n; j++)
  609.                       for(i=kk+1; i<=m; i++)
  610.                         w[i-1]=w[i-1]+e[j-1]*a(i-1,j-1);
  611.                     for(j=kk+1; j<=n; j++)
  612.                       for(i=kk+1; i<=m; i++)
  613.                           a(i-1,j-1)=a(i-1,j-1)-w[i-1]*e[j-1]/e[kk];
  614.                 }
  615.                 for(i=kk+1; i<=n; i++)
  616.                   v(i-1,kk-1)=e[i-1];
  617.             }
  618.         }
  619.     }
  620.     mm=n;
  621.     if(m+1<n) mm=m+1;
  622.     if(k<n) s[k]=a(k,k);
  623.     if(m<mm) s[mm-1]=0.0;
  624.     if(l+1<mm) e[l]=a(l,mm-1);
  625.     e[mm-1]=0.0;
  626.     nn=m;
  627.     if(m>n) nn=n;
  628.     if(nn>=k+1)
  629.     {
  630. for(j=k+1; j<=nn; j++)
  631.         {
  632. for(i=1; i<=m; i++) u(i-1,j-1)=0.0;
  633.             u(j-1,j-1)=1.0;
  634.         }
  635.     }
  636.     if(k>=1)
  637.     { 
  638. for(ll=1; ll<=k; ll++)
  639.         {
  640. kk=k-ll+1;
  641.             if(s[kk-1]!=0.0)
  642.             {
  643. if(nn>=kk+1)
  644.                   for(j=kk+1; j<=nn; j++)
  645.                   {
  646.   d=0.0;
  647.                       for(i=kk; i<=m; i++)
  648. d=d+u(i-1,kk-1)*u(i-1,j-1)/u(kk-1,kk-1);
  649.                       d=-d;
  650.                       for(i=kk; i<=m; i++)
  651.                           u(i-1,j-1)=u(i-1,j-1)+d*u(i-1,kk-1);
  652.                   }
  653.                   for(i=kk; i<=m; i++)
  654.   u(i-1,kk-1)=-u(i-1,kk-1);
  655.                   u(kk-1,kk-1)=1.0+u(kk-1,kk-1);
  656.                   if(kk-1>=1)
  657.                     for(i=1; i<kk; i++) u(i-1,kk-1)=0.0;
  658.             }
  659.             else
  660.             { 
  661. for(i=1; i<=m; i++) u(i-1,kk-1)=0.0;
  662.                 u(kk-1,kk-1)=1.0;
  663.             }
  664.         }
  665.     }
  666.     for(ll=1; ll<=n; ll++)
  667.     { 
  668. kk=n-ll+1; 
  669.         if((kk<=l)&&(e[kk-1]!=0.0))
  670.         {
  671. for(j=kk+1; j<=n; j++)
  672.             {
  673. d=0.0;
  674.                 for(i=kk+1; i<=n; i++)
  675.                     d=d+v(i-1,kk-1)*v(i-1,j-1)/v(kk,kk-1);
  676.                 d=-d;
  677.                 for(i=kk+1; i<=n; i++)
  678.                     v(i-1,j-1)=v(i-1,j-1)+d*v(i-1,kk-1);
  679.             }
  680.         }
  681.         for(i=1; i<=n; i++) v(i-1,kk-1)=0.0;
  682.         v(kk-1,kk-1)=1.0;
  683.     }
  684.     for(i=1; i<=m; i++)
  685. for(j=1; j<=n; j++) a(i-1,j-1)=0.0;
  686.     m1=mm; 
  687. it=60;
  688.     while(1)
  689.     { 
  690. if(mm==0)
  691.         {
  692. _MSV_1(a,e,s,v,m,n);
  693. return(1);
  694.         }
  695.         if(it==0)
  696.         { 
  697. _MSV_1(a,e,s,v,m,n);
  698. return(0);
  699.         }
  700.         kk=mm-1;
  701. while((kk!=0)&&(FloatNotEqual(e[kk-1],0.0)))
  702.     { 
  703. d=Abs(s[kk-1])+Abs(s[kk]);
  704.         dd=Abs(e[kk-1]);
  705.         if(dd>eps*d) kk=kk-1;
  706.         else e[kk-1]=0.0;
  707.     }
  708.     if(kk==mm-1)
  709.     {
  710. kk=kk+1;
  711.         if(s[kk-1]<0.0)
  712.         {
  713. s[kk-1]=-s[kk-1];
  714.             for(i=1; i<=n; i++) v(i-1,kk-1)=-v(i-1,kk-1);
  715.         }
  716.         while((kk!=m1)&&(s[kk-1]<s[kk]))
  717.         { 
  718. d=s[kk-1]; 
  719. s[kk-1]=s[kk];
  720. s[kk]=d;
  721.             if(kk<n)
  722.     for(i=1; i<=n; i++)
  723.                 {
  724.                   d=v(i-1,kk-1);
  725.   v(i-1,kk-1)=v(i-1,kk); 
  726.   v(i-1,kk)=d;
  727.                 }
  728.              if(kk<m)
  729.                   for(i=1; i<=m; i++)
  730.                   { 
  731.                       d=u(i-1,kk-1);
  732.   u(i-1,kk-1)=u(i-1,kk);
  733.   u(i-1,kk)=d;
  734.                   }
  735.                 kk=kk+1;
  736.             }
  737.             it=60;
  738.             mm=mm-1;
  739.         }
  740.         else
  741.         { 
  742. ks=mm;
  743.             while((ks>kk)&&(Abs(s[ks-1])!=0.0))
  744.             {
  745. d=0.0;
  746.                 if(ks!=mm) d=d+Abs(e[ks-1]);
  747.                 if(ks!=kk+1) d=d+Abs(e[ks-2]);
  748.                 dd=Abs(s[ks-1]);
  749.                 if(dd>eps*d) ks=ks-1;
  750.                 else s[ks-1]=0.0;
  751.             }
  752.             if(ks==kk)
  753.             { 
  754. kk=kk+1;
  755.                 d=Abs(s[mm-1]);
  756.                 t=Abs(s[mm-2]);
  757.                 if(t>d) d=t;
  758.                 t=Abs(e[mm-2]);
  759.                 if(t>d) d=t;
  760.                 t=Abs(s[kk-1]);
  761.                 if(t>d) d=t;
  762.                 t=Abs(e[kk-1]);
  763.                 if(t>d) d=t;
  764.                 sm=s[mm-1]/d; sm1=s[mm-2]/d;
  765.                 em1=e[mm-2]/d;
  766.                 sk=s[kk-1]/d; ek=e[kk-1]/d;
  767.                 b=((sm1+sm)*(sm1-sm)+em1*em1)/2.0;
  768.                 c=sm*em1; c=c*c; shh=0.0;
  769.                 if((b!=0.0)||(c!=0.0))
  770.                 {
  771. shh=sqrt(b*b+c);
  772.                     if(b<0.0) shh=-shh;
  773.                     shh=c/(b+shh);
  774.                 }
  775.                 fg[0]=(sk+sm)*(sk-sm)-shh;
  776.                 fg[1]=sk*ek;
  777.                 for(i=kk; i<=mm-1; i++)
  778.                 { 
  779. _MSV_2(fg,cs);
  780.                     if(i!=kk) e[i-2]=fg[0];
  781.                     fg[0]=cs[0]*s[i-1]+cs[1]*e[i-1];
  782.                     e[i-1]=cs[0]*e[i-1]-cs[1]*s[i-1];
  783.                     fg[1]=cs[1]*s[i];
  784.                     s[i]=cs[0]*s[i];
  785.                     if((cs[0]!=1.0)||(cs[1]!=0.0))
  786.                       for(j=1; j<=n; j++)
  787.                       {
  788.                           d=cs[0]*v(j-1,i-1)+cs[1]*v(j-1,i);
  789.                           v(j-1,i)=-cs[1]*v(j-1,i-1)+cs[0]*v(j-1,i);
  790.                           v(j-1,i-1)=d;
  791.                       }
  792.                     _MSV_2(fg,cs);
  793.                     s[i-1]=fg[0];
  794.                     fg[0]=cs[0]*e[i-1]+cs[1]*s[i];
  795.                     s[i]=-cs[1]*e[i-1]+cs[0]*s[i];
  796.                     fg[1]=cs[1]*e[i];
  797.                     e[i]=cs[0]*e[i];
  798.                     if(i<m)
  799.                       if((cs[0]!=1.0)||(cs[1]!=0.0))
  800.                         for(j=1; j<=m; j++)
  801.                         { 
  802.                             d=cs[0]*u(j-1,i-1)+cs[1]*u(j-1,i);
  803.                             u(j-1,i)=-cs[1]*u(j-1,i-1)+cs[0]*u(j-1,i);
  804.                             u(j-1,i-1)=d;
  805.                         }
  806.                 }
  807.                 e[mm-2]=fg[0];
  808.                 it=it-1;
  809.             }
  810.             else
  811.             { 
  812. if(ks==mm)
  813.                 {
  814. kk=kk+1;
  815.                     fg[1]=e[mm-2]; 
  816. e[mm-2]=0.0;
  817.                     for(ll=kk; ll<=mm-1; ll++)
  818.                     {
  819. i=mm+kk-ll-1;
  820.                         fg[0]=s[i-1];
  821.                         _MSV_2(fg,cs);
  822.                         s[i-1]=fg[0];
  823.                         if(i!=kk)
  824.                         {
  825. fg[1]=-cs[1]*e[i-2];
  826.                             e[i-2]=cs[0]*e[i-2];
  827.                         }
  828.                         if((cs[0]!=1.0)||(cs[1]!=0.0))
  829.                           for(j=1; j<=n; j++)
  830.                           { 
  831.                               d=cs[0]*v(j-1,i-1)+cs[1]*v(j-1,mm-1);
  832.                               v(j-1,mm-1)=-cs[1]*v(j-1,i-1)+cs[0]*v(j-1,mm-1);
  833.                               v(j-1,i-1)=d;
  834.                           }
  835.                     }
  836.                 }
  837.                 else
  838.                 { 
  839. kk=ks+1;
  840.                     fg[1]=e[kk-2];
  841.                     e[kk-2]=0.0;
  842.                     for(i=kk; i<=mm; i++)
  843.                     {
  844. fg[0]=s[i-1];
  845.                         _MSV_2(fg,cs);
  846.                         s[i-1]=fg[0];
  847.                         fg[1]=-cs[1]*e[i-1];
  848.                         e[i-1]=cs[0]*e[i-1];
  849.                         if((cs[0]!=1.0)||(cs[1]!=0.0))
  850.                           for(j=1; j<=m; j++)
  851.                           {
  852.                               d=cs[0]*u(j-1,i-1)+cs[1]*u(j-1,kk-2);
  853.                               u(j-1,kk-2)=-cs[1]*u(j-1,i-1)+cs[0]*u(j-1,kk-2);
  854.                               u(j-1,i-1)=d;
  855.                           }
  856.                     }
  857.                 }
  858.             }
  859.         }
  860.     }
  861.     return(1);
  862. }
  863. //一般实矩阵的奇异值分解辅助函数
  864. template <class _Ty>
  865. void _MSV_1(matrix<_Ty>& a, valarray<_Ty>& e, valarray<_Ty>& s, 
  866. matrix<_Ty>& v, int m, int n)
  867. {
  868. int i,j;
  869.     _Ty d;
  870.     if(m>=n) i=n;
  871.     else i=m;
  872.     for(j=1; j<i; j++)
  873.     {
  874. a(j-1,j-1)=s[j-1];
  875.         a(j-1,j)=e[j-1];
  876.     }
  877.     a(i-1,i-1)=s[i-1];
  878.     if(m<n) a(i-1,i)=e[i-1];
  879.     for(i=1; i<n; i++)
  880.     for(j=i+1; j<=n; j++)
  881.     { 
  882.         d=v(i-1,j-1);
  883. v(i-1,j-1)=v(j-1,i-1); 
  884. v(j-1,i-1)=d;
  885.     }
  886. }
  887. //一般实矩阵的奇异值分解辅助函数
  888. template <class _Ty>
  889. void _MSV_2(valarray<_Ty>& fg, valarray<_Ty>& cs)
  890. {
  891. _Ty r,d;
  892. r = Abs(fg[0])+Abs(fg[1]);
  893.     if(FloatEqual(r,0.0))
  894.     {
  895. cs[0]=1.0;
  896. cs[1]=0.0;
  897. d=0.0;
  898. }
  899.     else 
  900.     {
  901. d=sqrt(fg[0]*fg[0]+fg[1]*fg[1]);
  902.         if(Abs(fg[0])>Abs(fg[1]))
  903.         {
  904. d=Abs(d);
  905.             if(fg[0]<0.0) d=-d;
  906.         }
  907.         if(Abs(fg[1])>Abs(fg[0])||FloatEqual(Abs(fg[1]),Abs(fg[0])))
  908.         { 
  909. d=Abs(d);
  910.             if(fg[1]<0.0) d=-d;
  911.         }
  912.         cs[0]=fg[0]/d; 
  913. cs[1]=fg[1]/d;
  914.     }
  915.     r=1.0;
  916.     if(Abs(fg[0])>Abs(fg[1])) r=cs[1];
  917.     else
  918.       if(FloatNotEqual(cs[0],0.0)) r=1.0/cs[0];
  919.     fg[0]=d;
  920. fg[1]=r;
  921. }
  922. //广义逆的奇异值分解
  923. template <class _Ty>
  924. int GeneralizedInversionSingularValue(matrix<_Ty>& a, matrix<_Ty>& aa, 
  925. _Ty eps, matrix<_Ty>& u, matrix<_Ty>& v)
  926. {
  927. int k(0), l, ka;
  928. int m = a.GetRowNum();
  929. int n = a.GetColNum();
  930. if(m > n) ka = m + 1;
  931. else ka = n + 1;
  932.   
  933. int i=MatrixSingularValue(a,u,v,eps);
  934.     if (i<0) return(0);
  935.     int j = n;
  936.     if(m < n) j = m;
  937.     j = j - 1;
  938.     while((k<=j)&&(FloatNotEqual(a(k,k),0.0))) k = k + 1;
  939.     k = k - 1;
  940.     for(i=0; i<n; i++)
  941.     for(j=0; j<m; j++)
  942.     {
  943. aa(i,j)=0.0;
  944.         for(l=0; l<=k; l++)
  945.         {
  946.             aa(i,j)=aa(i,j)+v(l,i)*u(j,l)/a(l,l);
  947.         }
  948.     }
  949.     return(1);
  950. }
  951. #endif // _MATRIX_INL