Matrix.cpp
上传用户:weigute
上传日期:2007-03-02
资源大小:1287k
文件大小:71k
源码类别:

数学计算

开发平台:

Visual C++

  1. //////////////////////////////////////////////////////////////////////
  2. // Matrix.cpp
  3. //
  4. // 操作矩阵的类 CMatrix 的实现文件
  5. //
  6. // 周长发编制, 2002/8
  7. //////////////////////////////////////////////////////////////////////
  8. #include "stdafx.h"
  9. #include "Matrix.h"
  10. #ifdef _DEBUG
  11. #undef THIS_FILE
  12. static char THIS_FILE[]=__FILE__;
  13. #define new DEBUG_NEW
  14. #endif
  15. //////////////////////////////////////////////////////////////////////
  16. // Construction/Destruction
  17. //////////////////////////////////////////////////////////////////////
  18. //////////////////////////////////////////////////////////////////////
  19. // 基本构造函数
  20. //////////////////////////////////////////////////////////////////////
  21. CMatrix::CMatrix()
  22. {
  23. m_nNumColumns = 1;
  24. m_nNumRows = 1;
  25. m_pData = NULL;
  26. BOOL bSuccess = Init(m_nNumRows, m_nNumColumns);
  27. ASSERT(bSuccess);
  28. }
  29. //////////////////////////////////////////////////////////////////////
  30. // 指定行列构造函数
  31. //
  32. // 参数:
  33. // 1. int nRows - 指定的矩阵行数
  34. // 2. int nCols - 指定的矩阵列数
  35. //////////////////////////////////////////////////////////////////////
  36. CMatrix::CMatrix(int nRows, int nCols)
  37. {
  38. m_nNumRows = nRows;
  39. m_nNumColumns = nCols;
  40. m_pData = NULL;
  41. BOOL bSuccess = Init(m_nNumRows, m_nNumColumns);
  42. ASSERT(bSuccess);
  43. }
  44. //////////////////////////////////////////////////////////////////////
  45. // 指定值构造函数
  46. //
  47. // 参数:
  48. // 1. int nRows - 指定的矩阵行数
  49. // 2. int nCols - 指定的矩阵列数
  50. // 3. double value[] - 一维数组,长度为nRows*nCols,存储矩阵各元素的值
  51. //////////////////////////////////////////////////////////////////////
  52. CMatrix::CMatrix(int nRows, int nCols, double value[])
  53. {
  54. m_nNumRows = nRows;
  55. m_nNumColumns = nCols;
  56. m_pData = NULL;
  57. BOOL bSuccess = Init(m_nNumRows, m_nNumColumns);
  58. ASSERT(bSuccess);
  59. SetData(value);
  60. }
  61. //////////////////////////////////////////////////////////////////////
  62. // 方阵构造函数
  63. //
  64. // 参数:
  65. // 1. int nSize - 方阵行列数
  66. //////////////////////////////////////////////////////////////////////
  67. CMatrix::CMatrix(int nSize)
  68. {
  69. m_nNumRows = nSize;
  70. m_nNumColumns = nSize;
  71. m_pData = NULL;
  72. BOOL bSuccess = Init(nSize, nSize);
  73. ASSERT (bSuccess);
  74. }
  75. //////////////////////////////////////////////////////////////////////
  76. // 方阵构造函数
  77. //
  78. // 参数:
  79. // 1. int nSize - 方阵行列数
  80. // 2. double value[] - 一维数组,长度为nRows*nRows,存储方阵各元素的值
  81. //////////////////////////////////////////////////////////////////////
  82. CMatrix::CMatrix(int nSize, double value[])
  83. {
  84. m_nNumRows = nSize;
  85. m_nNumColumns = nSize;
  86. m_pData = NULL;
  87. BOOL bSuccess = Init(nSize, nSize);
  88. ASSERT (bSuccess);
  89. SetData(value);
  90. }
  91. //////////////////////////////////////////////////////////////////////
  92. // 拷贝构造函数
  93. //
  94. // 参数:
  95. // 1. const CMatrix& other - 源矩阵
  96. //////////////////////////////////////////////////////////////////////
  97. CMatrix::CMatrix(const CMatrix& other)
  98. {
  99. m_nNumColumns = other.GetNumColumns();
  100. m_nNumRows = other.GetNumRows();
  101. m_pData = NULL;
  102. BOOL bSuccess = Init(m_nNumRows, m_nNumColumns);
  103. ASSERT(bSuccess);
  104. // copy the pointer
  105. memcpy(m_pData, other.m_pData, sizeof(double)*m_nNumColumns*m_nNumRows);
  106. }
  107. //////////////////////////////////////////////////////////////////////
  108. // 析构函数
  109. //////////////////////////////////////////////////////////////////////
  110. CMatrix::~CMatrix()
  111. {
  112. if (m_pData)
  113. {
  114. delete[] m_pData;
  115. m_pData = NULL;
  116. }
  117. }
  118. //////////////////////////////////////////////////////////////////////
  119. // 初始化函数
  120. //
  121. // 参数:
  122. // 1. int nRows - 指定的矩阵行数
  123. // 2. int nCols - 指定的矩阵列数
  124. //
  125. // 返回值:BOOL 型,初始化是否成功
  126. //////////////////////////////////////////////////////////////////////
  127. BOOL CMatrix::Init(int nRows, int nCols)
  128. {
  129. if (m_pData)
  130. {
  131. delete[] m_pData;
  132. m_pData = NULL;
  133. }
  134. m_nNumRows = nRows;
  135. m_nNumColumns = nCols;
  136. int nSize = nCols*nRows;
  137. if (nSize < 0)
  138. return FALSE;
  139. // 分配内存
  140. m_pData = new double[nSize];
  141. if (m_pData == NULL)
  142. return FALSE; // 内存分配失败
  143. if (IsBadReadPtr(m_pData, sizeof(double) * nSize))
  144. return FALSE;
  145. // 将各元素值置0
  146. memset(m_pData, 0, sizeof(double) * nSize);
  147. return TRUE;
  148. }
  149. //////////////////////////////////////////////////////////////////////
  150. // 将方阵初始化为单位矩阵
  151. //
  152. // 参数:
  153. // 1. int nSize - 方阵行列数
  154. //
  155. // 返回值:BOOL 型,初始化是否成功
  156. //////////////////////////////////////////////////////////////////////
  157. BOOL CMatrix::MakeUnitMatrix(int nSize)
  158. {
  159. if (! Init(nSize, nSize))
  160. return FALSE;
  161. for (int i=0; i<nSize; ++i)
  162. for (int j=0; j<nSize; ++j)
  163. if (i == j)
  164. SetElement(i, j, 1);
  165. return TRUE;
  166. }
  167. //////////////////////////////////////////////////////////////////////
  168. // 将字符串转化为矩阵的值
  169. //
  170. // 参数:
  171. // 1. CString s - 数字和分隔符构成的字符串
  172. // 2. const CString& sDelim - 数字之间的分隔符,默认为空格
  173. // 3. BOOL bLineBreak - 行与行之间是否有回车换行符,默认为真(有换行符)
  174. //         当该参数为FALSE时,所有元素值都在一行中输入,字符串的第一个
  175. //         数值应为矩阵的行数,第二个数值应为矩阵的列数
  176. //
  177. // 返回值:BOOL 型,转换是否成功
  178. //////////////////////////////////////////////////////////////////////
  179. BOOL CMatrix::FromString(CString s, const CString& sDelim /*= " "*/, BOOL bLineBreak /*= TRUE*/)
  180. {
  181. if (s.IsEmpty())
  182. return FALSE;
  183. // 分行处理
  184. if (bLineBreak)
  185. {
  186. CTokenizer tk(s, "rn");
  187. CStringList ListRow;
  188. CString sRow;
  189. while (tk.Next(sRow))
  190. {
  191. sRow.TrimLeft();
  192. sRow.TrimRight();
  193. if (sRow.IsEmpty())
  194. break;
  195. ListRow.AddTail(sRow);
  196. }
  197. // 行数
  198. m_nNumRows = ListRow.GetCount();
  199. sRow = ListRow.GetHead();
  200. CTokenizer tkRow(sRow, sDelim);
  201. CString sElement;
  202. // 列数
  203. m_nNumColumns = 0;
  204. while (tkRow.Next(sElement))
  205. {
  206. m_nNumColumns++;
  207. }
  208. // 初始化矩阵
  209. if (! Init(m_nNumRows, m_nNumColumns))
  210. return FALSE;
  211. // 设置值
  212. POSITION pos = ListRow.GetHeadPosition();
  213. for (int i=0; i<m_nNumRows; i++)
  214. {
  215. sRow = ListRow.GetNext(pos);
  216. int j = 0;
  217. CTokenizer tkRow(sRow, sDelim);
  218. while (tkRow.Next(sElement))
  219. {
  220. sElement.TrimLeft();
  221. sElement.TrimRight();
  222. double v = atof(sElement);
  223. SetElement(i, j++, v);
  224. }
  225. }
  226. return TRUE;
  227. }
  228. // 不分行(单行)处理
  229. CTokenizer tk(s, sDelim);
  230. CString sElement;
  231. // 行数
  232. tk.Next(sElement);
  233. sElement.TrimLeft();
  234. sElement.TrimRight();
  235. m_nNumRows = atoi(sElement);
  236. // 列数
  237. tk.Next(sElement);
  238. sElement.TrimLeft();
  239. sElement.TrimRight();
  240. m_nNumColumns = atoi(sElement);
  241. // 初始化矩阵
  242. if (! Init(m_nNumRows, m_nNumColumns))
  243. return FALSE;
  244. // 设置值
  245. int i = 0, j = 0;
  246. while (tk.Next(sElement))
  247. {
  248. sElement.TrimLeft();
  249. sElement.TrimRight();
  250. double v = atof(sElement);
  251. SetElement(i, j++, v);
  252. if (j == m_nNumColumns)
  253. {
  254. j = 0;
  255. i++;
  256. if (i == m_nNumRows)
  257. break;
  258. }
  259. }
  260. return TRUE;
  261. }
  262. //////////////////////////////////////////////////////////////////////
  263. // 将矩阵各元素的值转化为字符串
  264. //
  265. // 参数:
  266. // 1. const CString& sDelim - 数字之间的分隔符,默认为空格
  267. // 2 BOOL bLineBreak - 行与行之间是否有回车换行符,默认为真(有换行符)
  268. //
  269. // 返回值:CString 型,转换得到的字符串
  270. //////////////////////////////////////////////////////////////////////
  271. CString CMatrix::ToString(const CString& sDelim /*= " "*/, BOOL bLineBreak /*= TRUE*/) const
  272. {
  273. CString s="";
  274. for (int i=0; i<m_nNumRows; ++i)
  275. {
  276. for (int j=0; j<m_nNumColumns; ++j)
  277. {
  278. CString ss;
  279. ss.Format("%f", GetElement(i, j));
  280. s += ss;
  281. if (bLineBreak)
  282. {
  283. if (j != m_nNumColumns-1)
  284. s += sDelim;
  285. }
  286. else
  287. {
  288. if (i != m_nNumRows-1 || j != m_nNumColumns-1)
  289. s += sDelim;
  290. }
  291. }
  292. if (bLineBreak)
  293. if (i != m_nNumRows-1)
  294. s += "rn";
  295. }
  296. return s;
  297. }
  298. //////////////////////////////////////////////////////////////////////
  299. // 将矩阵指定行中各元素的值转化为字符串
  300. //
  301. // 参数:
  302. // 1. int nRow - 指定的矩阵行,nRow = 0表示第一行
  303. // 2. const CString& sDelim - 数字之间的分隔符,默认为空格
  304. //
  305. // 返回值:CString 型,转换得到的字符串
  306. //////////////////////////////////////////////////////////////////////
  307. CString CMatrix::RowToString(int nRow, const CString& sDelim /*= " "*/) const
  308. {
  309. CString s = "";
  310. if (nRow >= m_nNumRows)
  311. return s;
  312. for (int j=0; j<m_nNumColumns; ++j)
  313. {
  314. CString ss;
  315. ss.Format("%f", GetElement(nRow, j));
  316. s += ss;
  317. if (j != m_nNumColumns-1)
  318. s += sDelim;
  319. }
  320. return s;
  321. }
  322. //////////////////////////////////////////////////////////////////////
  323. // 将矩阵指定列中各元素的值转化为字符串
  324. //
  325. // 参数:
  326. // 1. int nCol - 指定的矩阵行,nCol = 0表示第一列
  327. // 2. const CString& sDelim - 数字之间的分隔符,默认为空格
  328. //
  329. // 返回值:CString 型,转换得到的字符串
  330. //////////////////////////////////////////////////////////////////////
  331. CString CMatrix::ColToString(int nCol, const CString& sDelim /*= " "*/) const
  332. {
  333. CString s = "";
  334. if (nCol >= m_nNumColumns)
  335. return s;
  336. for (int i=0; i<m_nNumRows; ++i)
  337. {
  338. CString ss;
  339. ss.Format("%f", GetElement(i, nCol));
  340. s += ss;
  341. if (i != m_nNumRows-1)
  342. s += sDelim;
  343. }
  344. return s;
  345. }
  346. //////////////////////////////////////////////////////////////////////
  347. // 设置矩阵各元素的值
  348. //
  349. // 参数:
  350. // 1. double value[] - 一维数组,长度为m_nNumColumns*m_nNumRows,存储
  351. //                     矩阵各元素的值
  352. //
  353. // 返回值:无
  354. //////////////////////////////////////////////////////////////////////
  355. void CMatrix::SetData(double value[])
  356. {
  357. // empty the memory
  358. memset(m_pData, 0, sizeof(double) * m_nNumColumns*m_nNumRows);
  359. // copy data
  360. memcpy(m_pData, value, sizeof(double)*m_nNumColumns*m_nNumRows);
  361. }
  362. //////////////////////////////////////////////////////////////////////
  363. // 设置指定元素的值
  364. //
  365. // 参数:
  366. // 1. int nRows - 指定的矩阵行数
  367. // 2. int nCols - 指定的矩阵列数
  368. // 3. double value - 指定元素的值
  369. //
  370. // 返回值:BOOL 型,说明设置是否成功
  371. //////////////////////////////////////////////////////////////////////
  372. BOOL CMatrix::SetElement(int nRow, int nCol, double value)
  373. {
  374. if (nCol < 0 || nCol >= m_nNumColumns || nRow < 0 || nRow >= m_nNumRows)
  375. return FALSE; // array bounds error
  376. if (m_pData == NULL)
  377. return FALSE; // bad pointer error
  378. m_pData[nCol + nRow * m_nNumColumns] = value;
  379. return TRUE;
  380. }
  381. //////////////////////////////////////////////////////////////////////
  382. // 设置指定元素的值
  383. //
  384. // 参数:
  385. // 1. int nRows - 指定的矩阵行数
  386. // 2. int nCols - 指定的矩阵列数
  387. //
  388. // 返回值:double 型,指定元素的值
  389. //////////////////////////////////////////////////////////////////////
  390. double CMatrix::GetElement(int nRow, int nCol) const
  391. {
  392. ASSERT(nCol >= 0 && nCol < m_nNumColumns && nRow >= 0 && nRow < m_nNumRows); // array bounds error
  393. ASSERT(m_pData); // bad pointer error
  394. return m_pData[nCol + nRow * m_nNumColumns] ;
  395. }
  396. //////////////////////////////////////////////////////////////////////
  397. // 获取矩阵的列数
  398. //
  399. // 参数:无
  400. //
  401. // 返回值:int 型,矩阵的列数
  402. //////////////////////////////////////////////////////////////////////
  403. int CMatrix::GetNumColumns() const
  404. {
  405. return m_nNumColumns;
  406. }
  407. //////////////////////////////////////////////////////////////////////
  408. // 获取矩阵的行数
  409. //
  410. // 参数:无
  411. //
  412. // 返回值:int 型,矩阵的行数
  413. //////////////////////////////////////////////////////////////////////
  414. int CMatrix::GetNumRows() const
  415. {
  416. return m_nNumRows;
  417. }
  418. //////////////////////////////////////////////////////////////////////
  419. // 获取矩阵的数据
  420. //
  421. // 参数:无
  422. //
  423. // 返回值:double型指针,指向矩阵各元素的数据缓冲区
  424. //////////////////////////////////////////////////////////////////////
  425. double* CMatrix::GetData() const
  426. {
  427. return m_pData;
  428. }
  429. //////////////////////////////////////////////////////////////////////
  430. // 获取指定行的向量
  431. //
  432. // 参数:
  433. // 1. int nRows - 指定的矩阵行数
  434. // 2.  double* pVector - 指向向量中各元素的缓冲区
  435. //
  436. // 返回值:int 型,向量中元素的个数,即矩阵的列数
  437. //////////////////////////////////////////////////////////////////////
  438. int CMatrix::GetRowVector(int nRow, double* pVector) const
  439. {
  440. if (pVector == NULL)
  441. delete pVector;
  442. pVector = new double[m_nNumColumns];
  443. ASSERT(pVector != NULL);
  444. for (int j=0; j<m_nNumColumns; ++j)
  445. pVector[j] = GetElement(nRow, j);
  446. return m_nNumColumns;
  447. }
  448. //////////////////////////////////////////////////////////////////////
  449. // 获取指定列的向量
  450. //
  451. // 参数:
  452. // 1. int nCols - 指定的矩阵列数
  453. // 2.  double* pVector - 指向向量中各元素的缓冲区
  454. //
  455. // 返回值:int 型,向量中元素的个数,即矩阵的行数
  456. //////////////////////////////////////////////////////////////////////
  457. int CMatrix::GetColVector(int nCol, double* pVector) const
  458. {
  459. if (pVector == NULL)
  460. delete pVector;
  461. pVector = new double[m_nNumRows];
  462. ASSERT(pVector != NULL);
  463. for (int i=0; i<m_nNumRows; ++i)
  464. pVector[i] = GetElement(i, nCol);
  465. return m_nNumRows;
  466. }
  467. //////////////////////////////////////////////////////////////////////
  468. // 重载运算符=,给矩阵赋值
  469. //
  470. // 参数:
  471. // 1. const CMatrix& other - 用于给矩阵赋值的源矩阵
  472. //
  473. // 返回值:CMatrix型的引用,所引用的矩阵与other相等
  474. //////////////////////////////////////////////////////////////////////
  475. CMatrix& CMatrix::operator=(const CMatrix& other)
  476. {
  477. if (&other != this)
  478. {
  479. BOOL bSuccess = Init(other.GetNumRows(), other.GetNumColumns());
  480. ASSERT(bSuccess);
  481. // copy the pointer
  482. memcpy(m_pData, other.m_pData, sizeof(double)*m_nNumColumns*m_nNumRows);
  483. }
  484. // finally return a reference to ourselves
  485. return *this ;
  486. }
  487. //////////////////////////////////////////////////////////////////////
  488. // 重载运算符==,判断矩阵是否相等
  489. //
  490. // 参数:
  491. // 1. const CMatrix& other - 用于比较的矩阵
  492. //
  493. // 返回值:BOOL 型,两个矩阵相等则为TRUE,否则为FALSE
  494. //////////////////////////////////////////////////////////////////////
  495. BOOL CMatrix::operator==(const CMatrix& other) const
  496. {
  497. // 首先检查行列数是否相等
  498. if (m_nNumColumns != other.GetNumColumns() || m_nNumRows != other.GetNumRows())
  499. return FALSE;
  500. for (int i=0; i<m_nNumRows; ++i)
  501. {
  502. for (int j=0; j<m_nNumColumns; ++j)
  503. {
  504. if (GetElement(i, j) != other.GetElement(i, j))
  505. return FALSE;
  506. }
  507. }
  508. return TRUE;
  509. }
  510. //////////////////////////////////////////////////////////////////////
  511. // 重载运算符!=,判断矩阵是否不相等
  512. //
  513. // 参数:
  514. // 1. const CMatrix& other - 用于比较的矩阵
  515. //
  516. // 返回值:BOOL 型,两个不矩阵相等则为TRUE,否则为FALSE
  517. //////////////////////////////////////////////////////////////////////
  518. BOOL CMatrix::operator!=(const CMatrix& other) const
  519. {
  520. return !(*this == other);
  521. }
  522. //////////////////////////////////////////////////////////////////////
  523. // 重载运算符+,实现矩阵的加法
  524. //
  525. // 参数:
  526. // 1. const CMatrix& other - 与指定矩阵相加的矩阵
  527. //
  528. // 返回值:CMatrix型,指定矩阵与other相加之和
  529. //////////////////////////////////////////////////////////////////////
  530. CMatrix CMatrix::operator+(const CMatrix& other) const
  531. {
  532. // 首先检查行列数是否相等
  533. ASSERT (m_nNumColumns == other.GetNumColumns() && m_nNumRows == other.GetNumRows());
  534. // 构造结果矩阵
  535. CMatrix result(*this) ; // 拷贝构造
  536. // 矩阵加法
  537. for (int i = 0 ; i < m_nNumRows ; ++i)
  538. {
  539. for (int j = 0 ; j <  m_nNumColumns; ++j)
  540. result.SetElement(i, j, result.GetElement(i, j) + other.GetElement(i, j)) ;
  541. }
  542. return result ;
  543. }
  544. //////////////////////////////////////////////////////////////////////
  545. // 重载运算符-,实现矩阵的减法
  546. //
  547. // 参数:
  548. // 1. const CMatrix& other - 与指定矩阵相减的矩阵
  549. //
  550. // 返回值:CMatrix型,指定矩阵与other相减之差
  551. //////////////////////////////////////////////////////////////////////
  552. CMatrix CMatrix::operator-(const CMatrix& other) const
  553. {
  554. // 首先检查行列数是否相等
  555. ASSERT (m_nNumColumns == other.GetNumColumns() && m_nNumRows == other.GetNumRows());
  556. // 构造目标矩阵
  557. CMatrix result(*this) ; // copy ourselves
  558. // 进行减法操作
  559. for (int i = 0 ; i < m_nNumRows ; ++i)
  560. {
  561. for (int j = 0 ; j <  m_nNumColumns; ++j)
  562. result.SetElement(i, j, result.GetElement(i, j) - other.GetElement(i, j)) ;
  563. }
  564. return result ;
  565. }
  566. //////////////////////////////////////////////////////////////////////
  567. // 重载运算符*,实现矩阵的数乘
  568. //
  569. // 参数:
  570. // 1. double value - 与指定矩阵相乘的实数
  571. //
  572. // 返回值:CMatrix型,指定矩阵与value相乘之积
  573. //////////////////////////////////////////////////////////////////////
  574. CMatrix CMatrix::operator*(double value) const
  575. {
  576. // 构造目标矩阵
  577. CMatrix result(*this) ; // copy ourselves
  578. // 进行数乘
  579. for (int i = 0 ; i < m_nNumRows ; ++i)
  580. {
  581. for (int j = 0 ; j <  m_nNumColumns; ++j)
  582. result.SetElement(i, j, result.GetElement(i, j) * value) ;
  583. }
  584. return result ;
  585. }
  586. //////////////////////////////////////////////////////////////////////
  587. // 重载运算符*,实现矩阵的乘法
  588. //
  589. // 参数:
  590. // 1. const CMatrix& other - 与指定矩阵相乘的矩阵
  591. //
  592. // 返回值:CMatrix型,指定矩阵与other相乘之积
  593. //////////////////////////////////////////////////////////////////////
  594. CMatrix CMatrix::operator*(const CMatrix& other) const
  595. {
  596. // 首先检查行列数是否符合要求
  597. ASSERT (m_nNumColumns == other.GetNumRows());
  598. // construct the object we are going to return
  599. CMatrix result(m_nNumRows, other.GetNumColumns()) ;
  600. // 矩阵乘法,即
  601. //
  602. // [A][B][C]   [G][H]     [A*G + B*I + C*K][A*H + B*J + C*L]
  603. // [D][E][F] * [I][J] =   [D*G + E*I + F*K][D*H + E*J + F*L]
  604. //             [K][L]
  605. //
  606. double value ;
  607. for (int i = 0 ; i < result.GetNumRows() ; ++i)
  608. {
  609. for (int j = 0 ; j < other.GetNumColumns() ; ++j)
  610. {
  611. value = 0.0 ;
  612. for (int k = 0 ; k < m_nNumColumns ; ++k)
  613. {
  614. value += GetElement(i, k) * other.GetElement(k, j) ;
  615. }
  616. result.SetElement(i, j, value) ;
  617. }
  618. }
  619. return result ;
  620. }
  621. //////////////////////////////////////////////////////////////////////
  622. // 复矩阵的乘法
  623. //
  624. // 参数:
  625. // 1. const CMatrix& AR - 左边复矩阵的实部矩阵
  626. // 2. const CMatrix& AI - 左边复矩阵的虚部矩阵
  627. // 3. const CMatrix& BR - 右边复矩阵的实部矩阵
  628. // 4. const CMatrix& BI - 右边复矩阵的虚部矩阵
  629. // 5. CMatrix& CR - 乘积复矩阵的实部矩阵
  630. // 6. CMatrix& CI - 乘积复矩阵的虚部矩阵
  631. //
  632. // 返回值:BOOL型,复矩阵乘法是否成功
  633. //////////////////////////////////////////////////////////////////////
  634. BOOL CMatrix::CMul(const CMatrix& AR, const CMatrix& AI, const CMatrix& BR, const CMatrix& BI, CMatrix& CR, CMatrix& CI) const
  635. {
  636. // 首先检查行列数是否符合要求
  637. if (AR.GetNumColumns() != AI.GetNumColumns() ||
  638. AR.GetNumRows() != AI.GetNumRows() ||
  639. BR.GetNumColumns() != BI.GetNumColumns() ||
  640. BR.GetNumRows() != BI.GetNumRows() ||
  641. AR.GetNumColumns() != BR.GetNumRows())
  642. return FALSE;
  643. // 构造乘积矩阵实部矩阵和虚部矩阵
  644. CMatrix mtxCR(AR.GetNumRows(), BR.GetNumColumns()), mtxCI(AR.GetNumRows(), BR.GetNumColumns());
  645. // 复矩阵相乘
  646.     for (int i=0; i<AR.GetNumRows(); ++i)
  647. {
  648.     for (int j=0; j<BR.GetNumColumns(); ++j)
  649. {
  650. double vr = 0;
  651. double vi = 0;
  652.             for (int k =0; k<AR.GetNumColumns(); ++k)
  653. {
  654.                 double p = AR.GetElement(i, k) * BR.GetElement(k, j);
  655.                 double q = AI.GetElement(i, k) * BI.GetElement(k, j);
  656.                 double s = (AR.GetElement(i, k) + AI.GetElement(i, k)) * (BR.GetElement(k, j) + BI.GetElement(k, j));
  657.                 vr += p - q;
  658.                 vi += s - p - q;
  659. }
  660.             mtxCR.SetElement(i, j, vr);
  661.             mtxCI.SetElement(i, j, vi);
  662.         }
  663. }
  664. CR = mtxCR;
  665. CI = mtxCI;
  666. return TRUE;
  667. }
  668. //////////////////////////////////////////////////////////////////////
  669. // 矩阵的转置
  670. //
  671. // 参数:无
  672. //
  673. // 返回值:CMatrix型,指定矩阵转置矩阵
  674. //////////////////////////////////////////////////////////////////////
  675. CMatrix CMatrix::Transpose() const
  676. {
  677. // 构造目标矩阵
  678. CMatrix Trans(m_nNumColumns, m_nNumRows);
  679. // 转置各元素
  680. for (int i = 0 ; i < m_nNumRows ; ++i)
  681. {
  682. for (int j = 0 ; j < m_nNumColumns ; ++j)
  683. Trans.SetElement(j, i, GetElement(i, j)) ;
  684. }
  685. return Trans;
  686. }
  687. //////////////////////////////////////////////////////////////////////
  688. // 实矩阵求逆的全选主元高斯-约当法
  689. //
  690. // 参数:无
  691. //
  692. // 返回值:BOOL型,求逆是否成功
  693. //////////////////////////////////////////////////////////////////////
  694. BOOL CMatrix::InvertGaussJordan()
  695. {
  696. int *pnRow, *pnCol,i,j,k,l,u,v;
  697.     double d = 0, p = 0;
  698. // 分配内存
  699.     pnRow = new int[m_nNumColumns];
  700.     pnCol = new int[m_nNumColumns];
  701. if (pnRow == NULL || pnCol == NULL)
  702. return FALSE;
  703. // 消元
  704.     for (k=0; k<=m_nNumColumns-1; k++)
  705.     { 
  706. d=0.0;
  707.         for (i=k; i<=m_nNumColumns-1; i++)
  708. {
  709. for (j=k; j<=m_nNumColumns-1; j++)
  710. l=i*m_nNumColumns+j; p=fabs(m_pData[l]);
  711. if (p>d) 
  712. d=p; 
  713. pnRow[k]=i; 
  714. pnCol[k]=j;
  715. }
  716. }
  717. }
  718.         
  719. // 失败
  720. if (d == 0.0)
  721. {
  722. delete[] pnRow;
  723. delete[] pnCol;
  724. return FALSE;
  725. }
  726.         if (pnRow[k] != k)
  727. {
  728. for (j=0; j<=m_nNumColumns-1; j++)
  729. u=k*m_nNumColumns+j; 
  730. v=pnRow[k]*m_nNumColumns+j;
  731. p=m_pData[u]; 
  732. m_pData[u]=m_pData[v]; 
  733. m_pData[v]=p;
  734. }
  735. }
  736.         
  737. if (pnCol[k] != k)
  738. {
  739. for (i=0; i<=m_nNumColumns-1; i++)
  740.             { 
  741. u=i*m_nNumColumns+k; 
  742. v=i*m_nNumColumns+pnCol[k];
  743. p=m_pData[u]; 
  744. m_pData[u]=m_pData[v]; 
  745. m_pData[v]=p;
  746.             }
  747. }
  748.         l=k*m_nNumColumns+k;
  749.         m_pData[l]=1.0/m_pData[l];
  750.         for (j=0; j<=m_nNumColumns-1; j++)
  751. {
  752. if (j != k)
  753.             { 
  754. u=k*m_nNumColumns+j; 
  755. m_pData[u]=m_pData[u]*m_pData[l];
  756. }
  757. }
  758.         for (i=0; i<=m_nNumColumns-1; i++)
  759. {
  760. if (i!=k)
  761. {
  762. for (j=0; j<=m_nNumColumns-1; j++)
  763. {
  764. if (j!=k)
  765. u=i*m_nNumColumns+j;
  766. m_pData[u]=m_pData[u]-m_pData[i*m_nNumColumns+k]*m_pData[k*m_nNumColumns+j];
  767. }
  768.                 }
  769. }
  770. }
  771.         for (i=0; i<=m_nNumColumns-1; i++)
  772. {
  773. if (i!=k)
  774.             { 
  775. u=i*m_nNumColumns+k; 
  776. m_pData[u]=-m_pData[u]*m_pData[l];
  777. }
  778. }
  779.     }
  780.     // 调整恢复行列次序
  781.     for (k=m_nNumColumns-1; k>=0; k--)
  782.     { 
  783. if (pnCol[k]!=k)
  784. {
  785. for (j=0; j<=m_nNumColumns-1; j++)
  786.             { 
  787. u=k*m_nNumColumns+j; 
  788. v=pnCol[k]*m_nNumColumns+j;
  789. p=m_pData[u]; 
  790. m_pData[u]=m_pData[v]; 
  791. m_pData[v]=p;
  792.             }
  793. }
  794.         if (pnRow[k]!=k)
  795. {
  796. for (i=0; i<=m_nNumColumns-1; i++)
  797.             { 
  798. u=i*m_nNumColumns+k; 
  799. v=i*m_nNumColumns+pnRow[k];
  800. p=m_pData[u]; 
  801. m_pData[u]=m_pData[v]; 
  802. m_pData[v]=p;
  803.             }
  804. }
  805.     }
  806. // 清理内存
  807. delete[] pnRow;
  808. delete[] pnCol;
  809. // 成功返回
  810. return TRUE;
  811. }
  812. //////////////////////////////////////////////////////////////////////
  813. // 复矩阵求逆的全选主元高斯-约当法
  814. //
  815. // 参数:
  816. // 1. CMatrix& mtxImag - 复矩阵的虚部矩阵,当前矩阵为复矩阵的实部
  817. //
  818. // 返回值:BOOL型,求逆是否成功
  819. //////////////////////////////////////////////////////////////////////
  820. BOOL CMatrix::InvertGaussJordan(CMatrix& mtxImag)
  821. {
  822. int *pnRow,*pnCol,i,j,k,l,u,v,w;
  823.     double p,q,s,t,d,b;
  824. // 分配内存
  825.     pnRow = new int[m_nNumColumns];
  826.     pnCol = new int[m_nNumColumns];
  827. if (pnRow == NULL || pnCol == NULL)
  828. return FALSE;
  829. // 消元
  830.     for (k=0; k<=m_nNumColumns-1; k++)
  831.     { 
  832. d=0.0;
  833.         for (i=k; i<=m_nNumColumns-1; i++)
  834. {
  835. for (j=k; j<=m_nNumColumns-1; j++)
  836. u=i*m_nNumColumns+j;
  837. p=m_pData[u]*m_pData[u]+mtxImag.m_pData[u]*mtxImag.m_pData[u];
  838. if (p>d) 
  839. d=p; 
  840. pnRow[k]=i; 
  841. pnCol[k]=j;
  842. }
  843. }
  844. }
  845. // 失败
  846.         if (d == 0.0)
  847.         { 
  848. delete[] pnRow;
  849. delete[] pnCol;
  850.             return(0);
  851.         }
  852.         if (pnRow[k]!=k)
  853. {
  854. for (j=0; j<=m_nNumColumns-1; j++)
  855.             { 
  856. u=k*m_nNumColumns+j; 
  857. v=pnRow[k]*m_nNumColumns+j;
  858. t=m_pData[u]; 
  859. m_pData[u]=m_pData[v]; 
  860. m_pData[v]=t;
  861. t=mtxImag.m_pData[u]; 
  862. mtxImag.m_pData[u]=mtxImag.m_pData[v]; 
  863. mtxImag.m_pData[v]=t;
  864.             }
  865. }
  866.         if (pnCol[k]!=k)
  867. {
  868. for (i=0; i<=m_nNumColumns-1; i++)
  869.             { 
  870. u=i*m_nNumColumns+k; 
  871. v=i*m_nNumColumns+pnCol[k];
  872. t=m_pData[u]; 
  873. m_pData[u]=m_pData[v]; 
  874. m_pData[v]=t;
  875. t=mtxImag.m_pData[u]; 
  876. mtxImag.m_pData[u]=mtxImag.m_pData[v]; 
  877. mtxImag.m_pData[v]=t;
  878.             }
  879. }
  880.         l=k*m_nNumColumns+k;
  881.         m_pData[l]=m_pData[l]/d; mtxImag.m_pData[l]=-mtxImag.m_pData[l]/d;
  882.         for (j=0; j<=m_nNumColumns-1; j++)
  883. {
  884. if (j!=k)
  885.             { 
  886. u=k*m_nNumColumns+j;
  887. p=m_pData[u]*m_pData[l]; 
  888. q=mtxImag.m_pData[u]*mtxImag.m_pData[l];
  889. s=(m_pData[u]+mtxImag.m_pData[u])*(m_pData[l]+mtxImag.m_pData[l]);
  890. m_pData[u]=p-q; 
  891. mtxImag.m_pData[u]=s-p-q;
  892.             }
  893. }
  894.         for (i=0; i<=m_nNumColumns-1; i++)
  895. {
  896. if (i!=k)
  897.             { 
  898. v=i*m_nNumColumns+k;
  899. for (j=0; j<=m_nNumColumns-1; j++)
  900. {
  901. if (j!=k)
  902. u=k*m_nNumColumns+j;  
  903. w=i*m_nNumColumns+j;
  904. p=m_pData[u]*m_pData[v]; 
  905. q=mtxImag.m_pData[u]*mtxImag.m_pData[v];
  906. s=(m_pData[u]+mtxImag.m_pData[u])*(m_pData[v]+mtxImag.m_pData[v]);
  907. t=p-q; 
  908. b=s-p-q;
  909. m_pData[w]=m_pData[w]-t;
  910. mtxImag.m_pData[w]=mtxImag.m_pData[w]-b;
  911. }
  912. }
  913.             }
  914. }
  915.         for (i=0; i<=m_nNumColumns-1; i++)
  916. {
  917. if (i!=k)
  918.             { 
  919. u=i*m_nNumColumns+k;
  920. p=m_pData[u]*m_pData[l]; 
  921. q=mtxImag.m_pData[u]*mtxImag.m_pData[l];
  922. s=(m_pData[u]+mtxImag.m_pData[u])*(m_pData[l]+mtxImag.m_pData[l]);
  923. m_pData[u]=q-p; 
  924. mtxImag.m_pData[u]=p+q-s;
  925.             }
  926. }
  927.     }
  928.     // 调整恢复行列次序
  929.     for (k=m_nNumColumns-1; k>=0; k--)
  930.     { 
  931. if (pnCol[k]!=k)
  932. {
  933. for (j=0; j<=m_nNumColumns-1; j++)
  934.             { 
  935. u=k*m_nNumColumns+j; 
  936. v=pnCol[k]*m_nNumColumns+j;
  937. t=m_pData[u]; 
  938. m_pData[u]=m_pData[v]; 
  939. m_pData[v]=t;
  940. t=mtxImag.m_pData[u]; 
  941. mtxImag.m_pData[u]=mtxImag.m_pData[v]; 
  942. mtxImag.m_pData[v]=t;
  943.             }
  944. }
  945.         if (pnRow[k]!=k)
  946. {
  947. for (i=0; i<=m_nNumColumns-1; i++)
  948.             { 
  949. u=i*m_nNumColumns+k; 
  950. v=i*m_nNumColumns+pnRow[k];
  951. t=m_pData[u]; 
  952. m_pData[u]=m_pData[v]; 
  953. m_pData[v]=t;
  954. t=mtxImag.m_pData[u]; 
  955. mtxImag.m_pData[u]=mtxImag.m_pData[v]; 
  956. mtxImag.m_pData[v]=t;
  957.             }
  958. }
  959.     }
  960. // 清理内存
  961. delete[] pnRow;
  962. delete[] pnCol;
  963. // 成功返回
  964. return TRUE;
  965. }
  966. //////////////////////////////////////////////////////////////////////
  967. // 对称正定矩阵的求逆
  968. //
  969. // 参数:无
  970. //
  971. // 返回值:BOOL型,求逆是否成功
  972. //////////////////////////////////////////////////////////////////////
  973. BOOL CMatrix::InvertSsgj()
  974. int i, j ,k, m;
  975.     double w, g, *pTmp;
  976. // 临时内存
  977.     pTmp = new double[m_nNumColumns];
  978. // 逐列处理
  979.     for (k=0; k<=m_nNumColumns-1; k++)
  980.     { 
  981. w=m_pData[0];
  982.         if (w == 0.0)
  983.         { 
  984. delete[] pTmp;
  985. return FALSE;
  986. }
  987.         m=m_nNumColumns-k-1;
  988.         for (i=1; i<=m_nNumColumns-1; i++)
  989.         { 
  990. g=m_pData[i*m_nNumColumns]; 
  991. pTmp[i]=g/w;
  992.             if (i<=m) 
  993. pTmp[i]=-pTmp[i];
  994.             for (j=1; j<=i; j++)
  995.               m_pData[(i-1)*m_nNumColumns+j-1]=m_pData[i*m_nNumColumns+j]+g*pTmp[j];
  996.         }
  997.         m_pData[m_nNumColumns*m_nNumColumns-1]=1.0/w;
  998.         for (i=1; i<=m_nNumColumns-1; i++)
  999. m_pData[(m_nNumColumns-1)*m_nNumColumns+i-1]=pTmp[i];
  1000.     }
  1001. // 行列调整
  1002.     for (i=0; i<=m_nNumColumns-2; i++)
  1003. for (j=i+1; j<=m_nNumColumns-1; j++)
  1004. m_pData[i*m_nNumColumns+j]=m_pData[j*m_nNumColumns+i];
  1005. // 临时内存清理
  1006. delete[] pTmp;
  1007. return TRUE;
  1008. }
  1009. //////////////////////////////////////////////////////////////////////
  1010. // 托伯利兹矩阵求逆的埃兰特方法
  1011. //
  1012. // 参数:无
  1013. //
  1014. // 返回值:BOOL型,求逆是否成功
  1015. //////////////////////////////////////////////////////////////////////
  1016. BOOL CMatrix::InvertTrench()
  1017. int i,j,k;
  1018.     double a,s,*t,*tt,*c,*r,*p;
  1019. // 上三角元素
  1020. t = new double[m_nNumColumns];
  1021. // 下三角元素
  1022. tt = new double[m_nNumColumns];
  1023. // 上、下三角元素赋值
  1024. for (i=0; i<m_nNumColumns; ++i)
  1025. {
  1026. t[i] = GetElement(0, i);
  1027.     tt[i] = GetElement(i, 0);
  1028. }
  1029. // 临时缓冲区
  1030. c = new double[m_nNumColumns];
  1031. r = new double[m_nNumColumns];
  1032. p = new double[m_nNumColumns];
  1033. // 非Toeplitz矩阵,返回
  1034.     if (t[0] == 0.0)
  1035.     { 
  1036. delete[] t;
  1037. delete[] tt;
  1038. delete[] c;
  1039. delete[] r;
  1040. delete[] p;
  1041. return FALSE;
  1042.     }
  1043.     a=t[0]; 
  1044. c[0]=tt[1]/t[0]; 
  1045. r[0]=t[1]/t[0];
  1046.     for (k=0; k<=m_nNumColumns-3; k++)
  1047.     { 
  1048. s=0.0;
  1049.         for (j=1; j<=k+1; j++)
  1050. s=s+c[k+1-j]*tt[j];
  1051.         s=(s-tt[k+2])/a;
  1052. for (i=0; i<=k; i++)
  1053. p[i]=c[i]+s*r[k-i];
  1054.         c[k+1]=-s;
  1055.         s=0.0;
  1056.         for (j=1; j<=k+1; j++)
  1057.           s=s+r[k+1-j]*t[j];
  1058.         
  1059. s=(s-t[k+2])/a;
  1060.         for (i=0; i<=k; i++)
  1061.         { 
  1062. r[i]=r[i]+s*c[k-i];
  1063.             c[k-i]=p[k-i];
  1064.         }
  1065.         r[k+1]=-s;
  1066. a=0.0;
  1067.         for (j=1; j<=k+2; j++)
  1068.           a=a+t[j]*c[j-1];
  1069.         a=t[0]-a;
  1070. // 求解失败
  1071.         if (a == 0.0)
  1072. delete[] t;
  1073. delete[] tt;
  1074. delete[] c;
  1075. delete[] r;
  1076. delete[] p;
  1077. return FALSE;
  1078. }
  1079.     }
  1080.     m_pData[0]=1.0/a;
  1081.     for (i=0; i<=m_nNumColumns-2; i++)
  1082.     { 
  1083. k=i+1; 
  1084. j=(i+1)*m_nNumColumns;
  1085.         m_pData[k]=-r[i]/a; 
  1086. m_pData[j]=-c[i]/a;
  1087.     }
  1088.    for (i=0; i<=m_nNumColumns-2; i++)
  1089. {
  1090. for (j=0; j<=m_nNumColumns-2; j++)
  1091. k=(i+1)*m_nNumColumns+j+1;
  1092. m_pData[k]=m_pData[i*m_nNumColumns+j]-c[i]*m_pData[j+1];
  1093. m_pData[k]=m_pData[k]+c[m_nNumColumns-j-2]*m_pData[m_nNumColumns-i-1];
  1094. }
  1095. }
  1096.     // 临时内存清理
  1097. delete[] t;
  1098. delete[] tt;
  1099. delete[] c;
  1100. delete[] r;
  1101. delete[] p;
  1102. return TRUE;
  1103. }
  1104.                                                
  1105. //////////////////////////////////////////////////////////////////////
  1106. // 求行列式值的全选主元高斯消去法
  1107. //
  1108. // 参数:无
  1109. //
  1110. // 返回值:double型,行列式的值
  1111. //////////////////////////////////////////////////////////////////////
  1112. double CMatrix::DetGauss()
  1113. int i,j,k,is,js,l,u,v;
  1114.     double f,det,q,d;
  1115.     
  1116. // 初值
  1117. f=1.0; 
  1118. det=1.0;
  1119.     
  1120. // 消元
  1121. for (k=0; k<=m_nNumColumns-2; k++)
  1122.     { 
  1123. q=0.0;
  1124.         for (i=k; i<=m_nNumColumns-1; i++)
  1125. {
  1126. for (j=k; j<=m_nNumColumns-1; j++)
  1127. l=i*m_nNumColumns+j; 
  1128. d=fabs(m_pData[l]);
  1129. if (d>q) 
  1130. q=d; 
  1131. is=i; 
  1132. js=j;
  1133. }
  1134. }
  1135. }
  1136.         if (q == 0.0)
  1137.         { 
  1138. det=0.0; 
  1139. return(det);
  1140. }
  1141.         
  1142. if (is!=k)
  1143.         { 
  1144. f=-f;
  1145.             for (j=k; j<=m_nNumColumns-1; j++)
  1146.             { 
  1147. u=k*m_nNumColumns+j; 
  1148. v=is*m_nNumColumns+j;
  1149.                 d=m_pData[u]; 
  1150. m_pData[u]=m_pData[v]; 
  1151. m_pData[v]=d;
  1152.             }
  1153.         }
  1154.         
  1155. if (js!=k)
  1156.         { 
  1157. f=-f;
  1158.             for (i=k; i<=m_nNumColumns-1; i++)
  1159.             {
  1160. u=i*m_nNumColumns+js; 
  1161. v=i*m_nNumColumns+k;
  1162.                 d=m_pData[u]; 
  1163. m_pData[u]=m_pData[v]; 
  1164. m_pData[v]=d;
  1165.             }
  1166.         }
  1167.         l=k*m_nNumColumns+k;
  1168.         det=det*m_pData[l];
  1169.         for (i=k+1; i<=m_nNumColumns-1; i++)
  1170.         { 
  1171. d=m_pData[i*m_nNumColumns+k]/m_pData[l];
  1172.             for (j=k+1; j<=m_nNumColumns-1; j++)
  1173.             { 
  1174. u=i*m_nNumColumns+j;
  1175.                 m_pData[u]=m_pData[u]-d*m_pData[k*m_nNumColumns+j];
  1176.             }
  1177.         }
  1178.     }
  1179.     
  1180. // 求值
  1181. det=f*det*m_pData[m_nNumColumns*m_nNumColumns-1];
  1182.     return(det);
  1183. }
  1184. //////////////////////////////////////////////////////////////////////
  1185. // 求矩阵秩的全选主元高斯消去法
  1186. //
  1187. // 参数:无
  1188. //
  1189. // 返回值:int型,矩阵的秩
  1190. //////////////////////////////////////////////////////////////////////
  1191. int CMatrix::RankGauss()
  1192. int i,j,k,nn,is,js,l,ll,u,v;
  1193.     double q,d;
  1194.     
  1195. // 秩小于等于行列数
  1196. nn = m_nNumRows;
  1197.     if (m_nNumRows >= m_nNumColumns) 
  1198. nn = m_nNumColumns;
  1199.     k=0;
  1200. // 消元求解
  1201.     for (l=0; l<=nn-1; l++)
  1202.     { 
  1203. q=0.0;
  1204.         for (i=l; i<=m_nNumRows-1; i++)
  1205. {
  1206. for (j=l; j<=m_nNumColumns-1; j++)
  1207. ll=i*m_nNumColumns+j; 
  1208. d=fabs(m_pData[ll]);
  1209. if (d>q) 
  1210. q=d; 
  1211. is=i; 
  1212. js=j;
  1213. }
  1214. }
  1215. }
  1216.         if (q == 0.0) 
  1217. return(k);
  1218.         k=k+1;
  1219.         if (is!=l)
  1220.         { 
  1221. for (j=l; j<=m_nNumColumns-1; j++)
  1222.             { 
  1223. u=l*m_nNumColumns+j; 
  1224. v=is*m_nNumColumns+j;
  1225.                 d=m_pData[u]; 
  1226. m_pData[u]=m_pData[v]; 
  1227. m_pData[v]=d;
  1228.             }
  1229.         }
  1230.         if (js!=l)
  1231.         { 
  1232. for (i=l; i<=m_nNumRows-1; i++)
  1233.             { 
  1234. u=i*m_nNumColumns+js; 
  1235. v=i*m_nNumColumns+l;
  1236.                 d=m_pData[u]; 
  1237. m_pData[u]=m_pData[v]; 
  1238. m_pData[v]=d;
  1239.             }
  1240.         }
  1241.         
  1242. ll=l*m_nNumColumns+l;
  1243.         for (i=l+1; i<=m_nNumColumns-1; i++)
  1244.         { 
  1245. d=m_pData[i*m_nNumColumns+l]/m_pData[ll];
  1246.             for (j=l+1; j<=m_nNumColumns-1; j++)
  1247.             { 
  1248. u=i*m_nNumColumns+j;
  1249.                 m_pData[u]=m_pData[u]-d*m_pData[l*m_nNumColumns+j];
  1250.             }
  1251.         }
  1252.     }
  1253.     
  1254. return(k);
  1255. }
  1256. //////////////////////////////////////////////////////////////////////
  1257. // 对称正定矩阵的乔里斯基分解与行列式的求值
  1258. //
  1259. // 参数:
  1260. // 1. double* dblDet - 返回行列式的值
  1261. //
  1262. // 返回值:BOOL型,求解是否成功
  1263. //////////////////////////////////////////////////////////////////////
  1264. BOOL CMatrix::DetCholesky(double* dblDet)
  1265. int i,j,k,u,l;
  1266.     double d;
  1267.     
  1268. // 不满足求解要求
  1269. if (m_pData[0] <= 0.0)
  1270. return FALSE;
  1271. // 乔里斯基分解
  1272.     m_pData[0]=sqrt(m_pData[0]);
  1273.     d=m_pData[0];
  1274.     for (i=1; i<=m_nNumColumns-1; i++)
  1275.     { 
  1276. u=i*m_nNumColumns; 
  1277. m_pData[u]=m_pData[u]/m_pData[0];
  1278. }
  1279.     
  1280. for (j=1; j<=m_nNumColumns-1; j++)
  1281.     { 
  1282. l=j*m_nNumColumns+j;
  1283.         for (k=0; k<=j-1; k++)
  1284.         { 
  1285. u=j*m_nNumColumns+k; 
  1286. m_pData[l]=m_pData[l]-m_pData[u]*m_pData[u];
  1287. }
  1288.         
  1289. if (m_pData[l] <= 0.0)
  1290. return FALSE;
  1291.         m_pData[l]=sqrt(m_pData[l]);
  1292.         d=d*m_pData[l];
  1293.         
  1294. for (i=j+1; i<=m_nNumColumns-1; i++)
  1295.         { 
  1296. u=i*m_nNumColumns+j;
  1297.             for (k=0; k<=j-1; k++)
  1298. m_pData[u]=m_pData[u]-m_pData[i*m_nNumColumns+k]*m_pData[j*m_nNumColumns+k];
  1299.             
  1300. m_pData[u]=m_pData[u]/m_pData[l];
  1301.         }
  1302.     }
  1303.     
  1304. // 行列式求值
  1305. *dblDet=d*d;
  1306.     
  1307. // 下三角矩阵
  1308.     for (i=0; i<=m_nNumColumns-2; i++)
  1309. for (j=i+1; j<=m_nNumColumns-1; j++)
  1310. m_pData[i*m_nNumColumns+j]=0.0;
  1311. return TRUE;
  1312. }
  1313. //////////////////////////////////////////////////////////////////////
  1314. // 矩阵的三角分解,分解成功后,原矩阵将成为Q矩阵
  1315. //
  1316. // 参数:
  1317. // 1. CMatrix& mtxL - 返回分解后的L矩阵
  1318. // 2. CMatrix& mtxU - 返回分解后的U矩阵
  1319. //
  1320. // 返回值:BOOL型,求解是否成功
  1321. //////////////////////////////////////////////////////////////////////
  1322. BOOL CMatrix::SplitLU(CMatrix& mtxL, CMatrix& mtxU)
  1323. int i,j,k,w,v,ll;
  1324.     
  1325. // 初始化结果矩阵
  1326. if (! mtxL.Init(m_nNumColumns, m_nNumColumns) ||
  1327. ! mtxU.Init(m_nNumColumns, m_nNumColumns))
  1328. return FALSE;
  1329. for (k=0; k<=m_nNumColumns-2; k++)
  1330.     { 
  1331. ll=k*m_nNumColumns+k;
  1332. if (m_pData[ll] == 0.0)
  1333. return FALSE;
  1334.         for (i=k+1; i<=m_nNumColumns-1; i++)
  1335. w=i*m_nNumColumns+k; 
  1336. m_pData[w]=m_pData[w]/m_pData[ll];
  1337. }
  1338.         for (i=k+1; i<=m_nNumColumns-1; i++)
  1339.         { 
  1340. w=i*m_nNumColumns+k;
  1341.             for (j=k+1; j<=m_nNumColumns-1; j++)
  1342.             { 
  1343. v=i*m_nNumColumns+j;
  1344.                 m_pData[v]=m_pData[v]-m_pData[w]*m_pData[k*m_nNumColumns+j];
  1345.             }
  1346.         }
  1347.     }
  1348.     
  1349. for (i=0; i<=m_nNumColumns-1; i++)
  1350.     {
  1351. for (j=0; j<i; j++)
  1352.         { 
  1353. w=i*m_nNumColumns+j; 
  1354. mtxL.m_pData[w]=m_pData[w]; 
  1355. mtxU.m_pData[w]=0.0;
  1356. }
  1357.         w=i*m_nNumColumns+i;
  1358.         mtxL.m_pData[w]=1.0; 
  1359. mtxU.m_pData[w]=m_pData[w];
  1360.         
  1361. for (j=i+1; j<=m_nNumColumns-1; j++)
  1362.         { 
  1363. w=i*m_nNumColumns+j; 
  1364. mtxL.m_pData[w]=0.0; 
  1365. mtxU.m_pData[w]=m_pData[w];
  1366. }
  1367.     }
  1368. return TRUE;
  1369. }
  1370. //////////////////////////////////////////////////////////////////////
  1371. // 一般实矩阵的QR分解,分解成功后,原矩阵将成为R矩阵
  1372. //
  1373. // 参数:
  1374. // 1. CMatrix& mtxQ - 返回分解后的Q矩阵
  1375. //
  1376. // 返回值:BOOL型,求解是否成功
  1377. //////////////////////////////////////////////////////////////////////
  1378. BOOL CMatrix::SplitQR(CMatrix& mtxQ)
  1379. int i,j,k,l,nn,p,jj;
  1380.     double u,alpha,w,t;
  1381.     
  1382. if (m_nNumRows < m_nNumColumns)
  1383. return FALSE;
  1384. // 初始化Q矩阵
  1385. if (! mtxQ.Init(m_nNumRows, m_nNumRows))
  1386. return FALSE;
  1387. // 对角线元素单位化
  1388.     for (i=0; i<=m_nNumRows-1; i++)
  1389. {
  1390. for (j=0; j<=m_nNumRows-1; j++)
  1391. l=i*m_nNumRows+j; 
  1392. mtxQ.m_pData[l]=0.0;
  1393. if (i==j) 
  1394. mtxQ.m_pData[l]=1.0;
  1395. }
  1396. }
  1397. // 开始分解
  1398.     nn=m_nNumColumns;
  1399.     if (m_nNumRows == m_nNumColumns) 
  1400. nn=m_nNumRows-1;
  1401.     for (k=0; k<=nn-1; k++)
  1402.     { 
  1403. u=0.0; 
  1404. l=k*m_nNumColumns+k;
  1405.         for (i=k; i<=m_nNumRows-1; i++)
  1406.         { 
  1407. w=fabs(m_pData[i*m_nNumColumns+k]);
  1408.             if (w>u) 
  1409. u=w;
  1410.         }
  1411.         
  1412. alpha=0.0;
  1413.         for (i=k; i<=m_nNumRows-1; i++)
  1414.         { 
  1415. t=m_pData[i*m_nNumColumns+k]/u; 
  1416. alpha=alpha+t*t;
  1417. }
  1418.         if (m_pData[l]>0.0) 
  1419. u=-u;
  1420.         alpha=u*sqrt(alpha);
  1421.         if (alpha == 0.0)
  1422. return FALSE;
  1423.         u=sqrt(2.0*alpha*(alpha-m_pData[l]));
  1424.         if ((u+1.0)!=1.0)
  1425.         { 
  1426. m_pData[l]=(m_pData[l]-alpha)/u;
  1427.             for (i=k+1; i<=m_nNumRows-1; i++)
  1428.             { 
  1429. p=i*m_nNumColumns+k; 
  1430. m_pData[p]=m_pData[p]/u;
  1431. }
  1432.             
  1433. for (j=0; j<=m_nNumRows-1; j++)
  1434.             { 
  1435. t=0.0;
  1436.                 for (jj=k; jj<=m_nNumRows-1; jj++)
  1437. t=t+m_pData[jj*m_nNumColumns+k]*mtxQ.m_pData[jj*m_nNumRows+j];
  1438.                 for (i=k; i<=m_nNumRows-1; i++)
  1439.                 { 
  1440. p=i*m_nNumRows+j; 
  1441. mtxQ.m_pData[p]=mtxQ.m_pData[p]-2.0*t*m_pData[i*m_nNumColumns+k];
  1442. }
  1443.             }
  1444.             
  1445. for (j=k+1; j<=m_nNumColumns-1; j++)
  1446.             { 
  1447. t=0.0;
  1448.                 
  1449. for (jj=k; jj<=m_nNumRows-1; jj++)
  1450. t=t+m_pData[jj*m_nNumColumns+k]*m_pData[jj*m_nNumColumns+j];
  1451.                 
  1452. for (i=k; i<=m_nNumRows-1; i++)
  1453.                 { 
  1454. p=i*m_nNumColumns+j; 
  1455. m_pData[p]=m_pData[p]-2.0*t*m_pData[i*m_nNumColumns+k];
  1456. }
  1457.             }
  1458.             
  1459. m_pData[l]=alpha;
  1460.             for (i=k+1; i<=m_nNumRows-1; i++)
  1461. m_pData[i*m_nNumColumns+k]=0.0;
  1462.         }
  1463.     }
  1464.     
  1465. // 调整元素
  1466. for (i=0; i<=m_nNumRows-2; i++)
  1467. {
  1468. for (j=i+1; j<=m_nNumRows-1;j++)
  1469. p=i*m_nNumRows+j; 
  1470. l=j*m_nNumRows+i;
  1471. t=mtxQ.m_pData[p]; 
  1472. mtxQ.m_pData[p]=mtxQ.m_pData[l]; 
  1473. mtxQ.m_pData[l]=t;
  1474. }
  1475. }
  1476. return TRUE;
  1477. }
  1478. //////////////////////////////////////////////////////////////////////
  1479. // 一般实矩阵的奇异值分解,分解成功后,原矩阵对角线元素就是矩阵的奇异值
  1480. //
  1481. // 参数:
  1482. // 1. CMatrix& mtxU - 返回分解后的U矩阵
  1483. // 2. CMatrix& mtxV - 返回分解后的V矩阵
  1484. // 3. double eps - 计算精度,默认值为0.000001
  1485. //
  1486. // 返回值:BOOL型,求解是否成功
  1487. //////////////////////////////////////////////////////////////////////
  1488. BOOL CMatrix::SplitUV(CMatrix& mtxU, CMatrix& mtxV, double eps /*= 0.000001*/)
  1489. int i,j,k,l,it,ll,kk,ix,iy,mm,nn,iz,m1,ks;
  1490.     double d,dd,t,sm,sm1,em1,sk,ek,b,c,shh,fg[2],cs[2];
  1491.     double *s,*e,*w;
  1492. int m = m_nNumRows;
  1493. int n = m_nNumColumns;
  1494. // 初始化U, V矩阵
  1495. if (! mtxU.Init(m, m) || ! mtxV.Init(n, n))
  1496. return FALSE;
  1497. // 临时缓冲区
  1498. int ka = max(m, n) + 1;
  1499.     s = new double[ka];
  1500.     e = new double[ka];
  1501.     w = new double[ka];
  1502. // 指定迭代次数为60
  1503.     it=60; 
  1504. k=n;
  1505.     if (m-1<n) 
  1506. k=m-1;
  1507.     l=m;
  1508.     if (n-2<m) 
  1509. l=n-2;
  1510.     if (l<0) 
  1511. l=0;
  1512. // 循环迭代计算
  1513.     ll=k;
  1514.     if (l>k) 
  1515. ll=l;
  1516.     if (ll>=1)
  1517.     { 
  1518. for (kk=1; kk<=ll; kk++)
  1519.         { 
  1520. if (kk<=k)
  1521.             { 
  1522. d=0.0;
  1523.                 for (i=kk; i<=m; i++)
  1524.                 { 
  1525. ix=(i-1)*n+kk-1; 
  1526. d=d+m_pData[ix]*m_pData[ix];
  1527. }
  1528.                 s[kk-1]=sqrt(d);
  1529.                 if (s[kk-1]!=0.0)
  1530.                 { 
  1531. ix=(kk-1)*n+kk-1;
  1532.                     if (m_pData[ix]!=0.0)
  1533.                     { 
  1534. s[kk-1]=fabs(s[kk-1]);
  1535.                         if (m_pData[ix]<0.0) 
  1536. s[kk-1]=-s[kk-1];
  1537.                     }
  1538.                     
  1539. for (i=kk; i<=m; i++)
  1540.                     { 
  1541. iy=(i-1)*n+kk-1;
  1542.                         m_pData[iy]=m_pData[iy]/s[kk-1];
  1543.                     }
  1544.                     
  1545. m_pData[ix]=1.0+m_pData[ix];
  1546.                 }
  1547.                 
  1548. s[kk-1]=-s[kk-1];
  1549.             }
  1550.             
  1551. if (n>=kk+1)
  1552.             { 
  1553. for (j=kk+1; j<=n; j++)
  1554.                 { 
  1555. if ((kk<=k)&&(s[kk-1]!=0.0))
  1556.                     { 
  1557. d=0.0;
  1558.                         for (i=kk; i<=m; i++)
  1559.                         { 
  1560. ix=(i-1)*n+kk-1;
  1561.                             iy=(i-1)*n+j-1;
  1562.                             d=d+m_pData[ix]*m_pData[iy];
  1563.                         }
  1564.                         
  1565. d=-d/m_pData[(kk-1)*n+kk-1];
  1566.                         for (i=kk; i<=m; i++)
  1567.                         { 
  1568. ix=(i-1)*n+j-1;
  1569.                             iy=(i-1)*n+kk-1;
  1570.                             m_pData[ix]=m_pData[ix]+d*m_pData[iy];
  1571.                         }
  1572.                     }
  1573.                     
  1574. e[j-1]=m_pData[(kk-1)*n+j-1];
  1575.                 }
  1576.             }
  1577.             
  1578. if (kk<=k)
  1579.             { 
  1580. for (i=kk; i<=m; i++)
  1581.                 { 
  1582. ix=(i-1)*m+kk-1; 
  1583. iy=(i-1)*n+kk-1;
  1584.                     mtxU.m_pData[ix]=m_pData[iy];
  1585.                 }
  1586.             }
  1587.             
  1588. if (kk<=l)
  1589.             { 
  1590. d=0.0;
  1591.                 for (i=kk+1; i<=n; i++)
  1592. d=d+e[i-1]*e[i-1];
  1593.                 
  1594. e[kk-1]=sqrt(d);
  1595.                 if (e[kk-1]!=0.0)
  1596.                 { 
  1597. if (e[kk]!=0.0)
  1598.                     { 
  1599. e[kk-1]=fabs(e[kk-1]);
  1600.                         if (e[kk]<0.0) 
  1601. e[kk-1]=-e[kk-1];
  1602.                     }
  1603.                     for (i=kk+1; i<=n; i++)
  1604.                       e[i-1]=e[i-1]/e[kk-1];
  1605.                     
  1606. e[kk]=1.0+e[kk];
  1607.                 }
  1608.                 
  1609. e[kk-1]=-e[kk-1];
  1610.                 if ((kk+1<=m)&&(e[kk-1]!=0.0))
  1611.                 { 
  1612. for (i=kk+1; i<=m; i++) 
  1613. w[i-1]=0.0;
  1614.                     
  1615. for (j=kk+1; j<=n; j++)
  1616. for (i=kk+1; i<=m; i++)
  1617. w[i-1]=w[i-1]+e[j-1]*m_pData[(i-1)*n+j-1];
  1618.                     
  1619. for (j=kk+1; j<=n; j++)
  1620. {
  1621. for (i=kk+1; i<=m; i++)
  1622.                         { 
  1623. ix=(i-1)*n+j-1;
  1624. m_pData[ix]=m_pData[ix]-w[i-1]*e[j-1]/e[kk];
  1625.                         }
  1626. }
  1627.                 }
  1628.                 
  1629. for (i=kk+1; i<=n; i++)
  1630.                   mtxV.m_pData[(i-1)*n+kk-1]=e[i-1];
  1631.             }
  1632.         }
  1633.     }
  1634.     
  1635. mm=n;
  1636.     if (m+1<n) 
  1637. mm=m+1;
  1638.     if (k<n) 
  1639. s[k]=m_pData[k*n+k];
  1640.     if (m<mm) 
  1641. s[mm-1]=0.0;
  1642.     if (l+1<mm) 
  1643. e[l]=m_pData[l*n+mm-1];
  1644.     e[mm-1]=0.0;
  1645.     nn=m;
  1646.     if (m>n) 
  1647. nn=n;
  1648.     if (nn>=k+1)
  1649.     { 
  1650. for (j=k+1; j<=nn; j++)
  1651.         { 
  1652. for (i=1; i<=m; i++)
  1653. mtxU.m_pData[(i-1)*m+j-1]=0.0;
  1654.             mtxU.m_pData[(j-1)*m+j-1]=1.0;
  1655.         }
  1656.     }
  1657.     
  1658. if (k>=1)
  1659.     { 
  1660. for (ll=1; ll<=k; ll++)
  1661.         { 
  1662. kk=k-ll+1; 
  1663. iz=(kk-1)*m+kk-1;
  1664.             if (s[kk-1]!=0.0)
  1665.             { 
  1666. if (nn>=kk+1)
  1667. {
  1668. for (j=kk+1; j<=nn; j++)
  1669. d=0.0;
  1670. for (i=kk; i<=m; i++)
  1671. ix=(i-1)*m+kk-1;
  1672. iy=(i-1)*m+j-1;
  1673. d=d+mtxU.m_pData[ix]*mtxU.m_pData[iy]/mtxU.m_pData[iz];
  1674. }
  1675. d=-d;
  1676. for (i=kk; i<=m; i++)
  1677. ix=(i-1)*m+j-1;
  1678. iy=(i-1)*m+kk-1;
  1679. mtxU.m_pData[ix]=mtxU.m_pData[ix]+d*mtxU.m_pData[iy];
  1680. }
  1681. }
  1682. }
  1683.                   
  1684. for (i=kk; i<=m; i++)
  1685. ix=(i-1)*m+kk-1; 
  1686. mtxU.m_pData[ix]=-mtxU.m_pData[ix];
  1687. }
  1688. mtxU.m_pData[iz]=1.0+mtxU.m_pData[iz];
  1689. if (kk-1>=1)
  1690. {
  1691. for (i=1; i<=kk-1; i++)
  1692. mtxU.m_pData[(i-1)*m+kk-1]=0.0;
  1693. }
  1694. }
  1695.             else
  1696.             { 
  1697. for (i=1; i<=m; i++)
  1698. mtxU.m_pData[(i-1)*m+kk-1]=0.0;
  1699.                 mtxU.m_pData[(kk-1)*m+kk-1]=1.0;
  1700.             }
  1701. }
  1702.     }
  1703.     for (ll=1; ll<=n; ll++)
  1704.     { 
  1705. kk=n-ll+1; 
  1706. iz=kk*n+kk-1;
  1707.         
  1708. if ((kk<=l)&&(e[kk-1]!=0.0))
  1709.         { 
  1710. for (j=kk+1; j<=n; j++)
  1711.             { 
  1712. d=0.0;
  1713.                 for (i=kk+1; i<=n; i++)
  1714.                 { 
  1715. ix=(i-1)*n+kk-1; 
  1716. iy=(i-1)*n+j-1;
  1717.                     d=d+mtxV.m_pData[ix]*mtxV.m_pData[iy]/mtxV.m_pData[iz];
  1718.                 }
  1719.                 
  1720. d=-d;
  1721.                 for (i=kk+1; i<=n; i++)
  1722.                 { 
  1723. ix=(i-1)*n+j-1; 
  1724. iy=(i-1)*n+kk-1;
  1725.                     mtxV.m_pData[ix]=mtxV.m_pData[ix]+d*mtxV.m_pData[iy];
  1726.                 }
  1727.             }
  1728.         }
  1729.         
  1730. for (i=1; i<=n; i++)
  1731. mtxV.m_pData[(i-1)*n+kk-1]=0.0;
  1732.         
  1733. mtxV.m_pData[iz-n]=1.0;
  1734.     }
  1735.     
  1736. for (i=1; i<=m; i++)
  1737. for (j=1; j<=n; j++)
  1738. m_pData[(i-1)*n+j-1]=0.0;
  1739.     
  1740. m1=mm; 
  1741. it=60;
  1742.     while (TRUE)
  1743.     { 
  1744. if (mm==0)
  1745.         { 
  1746. ppp(m_pData,e,s,mtxV.m_pData,m,n);
  1747.             return TRUE;
  1748.         }
  1749.         if (it==0)
  1750.         { 
  1751. ppp(m_pData,e,s,mtxV.m_pData,m,n);
  1752.             return FALSE;
  1753.         }
  1754.         
  1755. kk=mm-1;
  1756. while ((kk!=0)&&(fabs(e[kk-1])!=0.0))
  1757.         { 
  1758. d=fabs(s[kk-1])+fabs(s[kk]);
  1759.             dd=fabs(e[kk-1]);
  1760.             if (dd>eps*d) 
  1761. kk=kk-1;
  1762.             else 
  1763. e[kk-1]=0.0;
  1764.         }
  1765.         
  1766. if (kk==mm-1)
  1767.         { 
  1768. kk=kk+1;
  1769.             if (s[kk-1]<0.0)
  1770.             { 
  1771. s[kk-1]=-s[kk-1];
  1772.                 for (i=1; i<=n; i++)
  1773.                 { 
  1774. ix=(i-1)*n+kk-1; 
  1775. mtxV.m_pData[ix]=-mtxV.m_pData[ix];}
  1776. }
  1777. while ((kk!=m1)&&(s[kk-1]<s[kk]))
  1778. d=s[kk-1]; 
  1779. s[kk-1]=s[kk]; 
  1780. s[kk]=d;
  1781. if (kk<n)
  1782. {
  1783. for (i=1; i<=n; i++)
  1784. ix=(i-1)*n+kk-1; 
  1785. iy=(i-1)*n+kk;
  1786. d=mtxV.m_pData[ix]; 
  1787. mtxV.m_pData[ix]=mtxV.m_pData[iy]; 
  1788. mtxV.m_pData[iy]=d;
  1789. }
  1790. }
  1791. if (kk<m)
  1792. {
  1793. for (i=1; i<=m; i++)
  1794. ix=(i-1)*m+kk-1; 
  1795. iy=(i-1)*m+kk;
  1796. d=mtxU.m_pData[ix]; 
  1797. mtxU.m_pData[ix]=mtxU.m_pData[iy]; 
  1798. mtxU.m_pData[iy]=d;
  1799. }
  1800. }
  1801. kk=kk+1;
  1802.             }
  1803.             
  1804. it=60;
  1805.             mm=mm-1;
  1806.         }
  1807.         else
  1808.         { 
  1809. ks=mm;
  1810.             while ((ks>kk)&&(fabs(s[ks-1])!=0.0))
  1811.             { 
  1812. d=0.0;
  1813.                 if (ks!=mm) 
  1814. d=d+fabs(e[ks-1]);
  1815.                 if (ks!=kk+1) 
  1816. d=d+fabs(e[ks-2]);
  1817.                 
  1818. dd=fabs(s[ks-1]);
  1819.                 if (dd>eps*d) 
  1820. ks=ks-1;
  1821.                 else 
  1822. s[ks-1]=0.0;
  1823.             }
  1824.             
  1825. if (ks==kk)
  1826.             { 
  1827. kk=kk+1;
  1828.                 d=fabs(s[mm-1]);
  1829.                 t=fabs(s[mm-2]);
  1830.                 if (t>d) 
  1831. d=t;
  1832.                 
  1833. t=fabs(e[mm-2]);
  1834.                 if (t>d) 
  1835. d=t;
  1836.                 
  1837. t=fabs(s[kk-1]);
  1838.                 if (t>d) 
  1839. d=t;
  1840.                 
  1841. t=fabs(e[kk-1]);
  1842.                 if (t>d) 
  1843. d=t;
  1844.                 
  1845. sm=s[mm-1]/d; 
  1846. sm1=s[mm-2]/d;
  1847.                 em1=e[mm-2]/d;
  1848.                 sk=s[kk-1]/d; 
  1849. ek=e[kk-1]/d;
  1850.                 b=((sm1+sm)*(sm1-sm)+em1*em1)/2.0;
  1851.                 c=sm*em1; 
  1852. c=c*c; 
  1853. shh=0.0;
  1854.                 if ((b!=0.0)||(c!=0.0))
  1855.                 { 
  1856. shh=sqrt(b*b+c);
  1857.                     if (b<0.0) 
  1858. shh=-shh;
  1859.                     shh=c/(b+shh);
  1860.                 }
  1861.                 
  1862. fg[0]=(sk+sm)*(sk-sm)-shh;
  1863.                 fg[1]=sk*ek;
  1864.                 for (i=kk; i<=mm-1; i++)
  1865.                 { 
  1866. sss(fg,cs);
  1867.                     if (i!=kk) 
  1868. e[i-2]=fg[0];
  1869.                     fg[0]=cs[0]*s[i-1]+cs[1]*e[i-1];
  1870.                     e[i-1]=cs[0]*e[i-1]-cs[1]*s[i-1];
  1871.                     fg[1]=cs[1]*s[i];
  1872.                     s[i]=cs[0]*s[i];
  1873.                     if ((cs[0]!=1.0)||(cs[1]!=0.0))
  1874. {
  1875. for (j=1; j<=n; j++)
  1876.                         { 
  1877. ix=(j-1)*n+i-1;
  1878. iy=(j-1)*n+i;
  1879. d=cs[0]*mtxV.m_pData[ix]+cs[1]*mtxV.m_pData[iy];
  1880. mtxV.m_pData[iy]=-cs[1]*mtxV.m_pData[ix]+cs[0]*mtxV.m_pData[iy];
  1881. mtxV.m_pData[ix]=d;
  1882.                         }
  1883. }
  1884.                     sss(fg,cs);
  1885.                     s[i-1]=fg[0];
  1886.                     fg[0]=cs[0]*e[i-1]+cs[1]*s[i];
  1887.                     s[i]=-cs[1]*e[i-1]+cs[0]*s[i];
  1888.                     fg[1]=cs[1]*e[i];
  1889.                     e[i]=cs[0]*e[i];
  1890.                     if (i<m)
  1891. {
  1892. if ((cs[0]!=1.0)||(cs[1]!=0.0))
  1893. {
  1894. for (j=1; j<=m; j++)
  1895. ix=(j-1)*m+i-1;
  1896. iy=(j-1)*m+i;
  1897. d=cs[0]*mtxU.m_pData[ix]+cs[1]*mtxU.m_pData[iy];
  1898. mtxU.m_pData[iy]=-cs[1]*mtxU.m_pData[ix]+cs[0]*mtxU.m_pData[iy];
  1899. mtxU.m_pData[ix]=d;
  1900. }
  1901. }
  1902. }
  1903.                 }
  1904.                 
  1905. e[mm-2]=fg[0];
  1906.                 it=it-1;
  1907.             }
  1908.             else
  1909.             { 
  1910. if (ks==mm)
  1911.                 { 
  1912. kk=kk+1;
  1913.                     fg[1]=e[mm-2]; 
  1914. e[mm-2]=0.0;
  1915.                     for (ll=kk; ll<=mm-1; ll++)
  1916.                     { 
  1917. i=mm+kk-ll-1;
  1918.                         fg[0]=s[i-1];
  1919.                         sss(fg,cs);
  1920.                         s[i-1]=fg[0];
  1921.                         if (i!=kk)
  1922.                         { 
  1923. fg[1]=-cs[1]*e[i-2];
  1924.                             e[i-2]=cs[0]*e[i-2];
  1925.                         }
  1926.                         
  1927. if ((cs[0]!=1.0)||(cs[1]!=0.0))
  1928. {
  1929. for (j=1; j<=n; j++)
  1930.                             { 
  1931. ix=(j-1)*n+i-1;
  1932. iy=(j-1)*n+mm-1;
  1933. d=cs[0]*mtxV.m_pData[ix]+cs[1]*mtxV.m_pData[iy];
  1934. mtxV.m_pData[iy]=-cs[1]*mtxV.m_pData[ix]+cs[0]*mtxV.m_pData[iy];
  1935. mtxV.m_pData[ix]=d;
  1936.                             }
  1937. }
  1938.                     }
  1939.                 }
  1940.                 else
  1941.                 { 
  1942. kk=ks+1;
  1943.                     fg[1]=e[kk-2];
  1944.                     e[kk-2]=0.0;
  1945.                     for (i=kk; i<=mm; i++)
  1946.                     { 
  1947. fg[0]=s[i-1];
  1948.                         sss(fg,cs);
  1949.                         s[i-1]=fg[0];
  1950.                         fg[1]=-cs[1]*e[i-1];
  1951.                         e[i-1]=cs[0]*e[i-1];
  1952.                         if ((cs[0]!=1.0)||(cs[1]!=0.0))
  1953. {
  1954. for (j=1; j<=m; j++)
  1955.                             { 
  1956. ix=(j-1)*m+i-1;
  1957. iy=(j-1)*m+kk-2;
  1958. d=cs[0]*mtxU.m_pData[ix]+cs[1]*mtxU.m_pData[iy];
  1959. mtxU.m_pData[iy]=-cs[1]*mtxU.m_pData[ix]+cs[0]*mtxU.m_pData[iy];
  1960. mtxU.m_pData[ix]=d;
  1961.                             }
  1962. }
  1963.                     }
  1964.                 }
  1965.             }
  1966.         }
  1967.     }
  1968.     
  1969. return TRUE;
  1970. }
  1971. //////////////////////////////////////////////////////////////////////
  1972. // 内部函数,由SplitUV函数调用
  1973. //////////////////////////////////////////////////////////////////////
  1974. void CMatrix::ppp(double a[], double e[], double s[], double v[], int m, int n)
  1975. int i,j,p,q;
  1976.     double d;
  1977.     if (m>=n) 
  1978. i=n;
  1979.     else 
  1980. i=m;
  1981.     for (j=1; j<=i-1; j++)
  1982.     { 
  1983. a[(j-1)*n+j-1]=s[j-1];
  1984.         a[(j-1)*n+j]=e[j-1];
  1985.     }
  1986.     
  1987. a[(i-1)*n+i-1]=s[i-1];
  1988.     if (m<n) 
  1989. a[(i-1)*n+i]=e[i-1];
  1990.     
  1991. for (i=1; i<=n-1; i++)
  1992. {
  1993. for (j=i+1; j<=n; j++)
  1994. p=(i-1)*n+j-1; 
  1995. q=(j-1)*n+i-1;
  1996. d=v[p]; 
  1997. v[p]=v[q]; 
  1998. v[q]=d;
  1999. }
  2000. }
  2001. }
  2002. //////////////////////////////////////////////////////////////////////
  2003. // 内部函数,由SplitUV函数调用
  2004. //////////////////////////////////////////////////////////////////////
  2005. void CMatrix::sss(double fg[2], double cs[2])
  2006. double r,d;
  2007.     
  2008. if ((fabs(fg[0])+fabs(fg[1]))==0.0)
  2009.     { 
  2010. cs[0]=1.0; 
  2011. cs[1]=0.0; 
  2012. d=0.0;
  2013. }
  2014.     else 
  2015.     { 
  2016. d=sqrt(fg[0]*fg[0]+fg[1]*fg[1]);
  2017.         if (fabs(fg[0])>fabs(fg[1]))
  2018.         { 
  2019. d=fabs(d);
  2020.             if (fg[0]<0.0) 
  2021. d=-d;
  2022.         }
  2023.         if (fabs(fg[1])>=fabs(fg[0]))
  2024.         { 
  2025. d=fabs(d);
  2026.             if (fg[1]<0.0) 
  2027. d=-d;
  2028.         }
  2029.         
  2030. cs[0]=fg[0]/d; 
  2031. cs[1]=fg[1]/d;
  2032.     }
  2033.     
  2034. r=1.0;
  2035.     if (fabs(fg[0])>fabs(fg[1])) 
  2036. r=cs[1];
  2037.     else if (cs[0]!=0.0) 
  2038. r=1.0/cs[0];
  2039.     fg[0]=d; 
  2040. fg[1]=r;
  2041. }
  2042. //////////////////////////////////////////////////////////////////////
  2043. // 求广义逆的奇异值分解法,分解成功后,原矩阵对角线元素就是矩阵的奇异值
  2044. //
  2045. // 参数:
  2046. // 1. CMatrix& mtxAP - 返回原矩阵的广义逆矩阵
  2047. // 2. CMatrix& mtxU - 返回分解后的U矩阵
  2048. // 3. CMatrix& mtxV - 返回分解后的V矩阵
  2049. // 4. double eps - 计算精度,默认值为0.000001
  2050. //
  2051. // 返回值:BOOL型,求解是否成功
  2052. //////////////////////////////////////////////////////////////////////
  2053. BOOL CMatrix::GInvertUV(CMatrix& mtxAP, CMatrix& mtxU, CMatrix& mtxV, double eps /*= 0.000001*/)
  2054. int i,j,k,l,t,p,q,f;
  2055. // 调用奇异值分解
  2056.     if (! SplitUV(mtxU, mtxV, eps))
  2057. return FALSE;
  2058. int m = m_nNumRows;
  2059. int n = m_nNumColumns;
  2060. // 初始化广义逆矩阵
  2061. if (! mtxAP.Init(n, m))
  2062. return FALSE;
  2063. // 计算广义逆矩阵
  2064.     j=n;
  2065.     if (m<n) 
  2066. j=m;
  2067.     j=j-1;
  2068.     k=0;
  2069.     while ((k<=j)&&(m_pData[k*n+k]!=0.0)) 
  2070. k=k+1;
  2071.     k=k-1;
  2072.     for (i=0; i<=n-1; i++)
  2073. {
  2074. for (j=0; j<=m-1; j++)
  2075. t=i*m+j;
  2076. mtxAP.m_pData[t]=0.0;
  2077. for (l=0; l<=k; l++)
  2078. f=l*n+i; 
  2079. p=j*m+l; 
  2080. q=l*n+l;
  2081. mtxAP.m_pData[t]=mtxAP.m_pData[t]+mtxV.m_pData[f]*mtxU.m_pData[p]/m_pData[q];
  2082. }
  2083. }
  2084. }
  2085.     return TRUE;
  2086. }
  2087. //////////////////////////////////////////////////////////////////////
  2088. // 约化对称矩阵为对称三对角阵的豪斯荷尔德变换法
  2089. //
  2090. // 参数:
  2091. // 1. CMatrix& mtxQ - 返回豪斯荷尔德变换的乘积矩阵Q
  2092. // 2. CMatrix& mtxT - 返回求得的对称三对角阵
  2093. // 3. double dblB[] - 一维数组,长度为矩阵的阶数,返回对称三对角阵的主对角线元素
  2094. // 4. double dblC[] - 一维数组,长度为矩阵的阶数,前n-1个元素返回对称三对角阵的次对角线元素
  2095. //
  2096. // 返回值:BOOL型,求解是否成功
  2097. //////////////////////////////////////////////////////////////////////
  2098. BOOL CMatrix::MakeSymTri(CMatrix& mtxQ, CMatrix& mtxT, double dblB[], double dblC[])
  2099. int i,j,k,u;
  2100.     double h,f,g,h2;
  2101.     
  2102. // 初始化矩阵Q和T
  2103. if (! mtxQ.Init(m_nNumColumns, m_nNumColumns) ||
  2104. ! mtxT.Init(m_nNumColumns, m_nNumColumns))
  2105. return FALSE;
  2106. if (dblB == NULL || dblC == NULL)
  2107. return FALSE;
  2108. for (i=0; i<=m_nNumColumns-1; i++)
  2109. {
  2110. for (j=0; j<=m_nNumColumns-1; j++)
  2111. u=i*m_nNumColumns+j; 
  2112. mtxQ.m_pData[u]=m_pData[u];
  2113. }
  2114. }
  2115.     for (i=m_nNumColumns-1; i>=1; i--)
  2116.     { 
  2117. h=0.0;
  2118.         if (i>1)
  2119. {
  2120. for (k=0; k<=i-1; k++)
  2121.             { 
  2122. u=i*m_nNumColumns+k; 
  2123. h=h+mtxQ.m_pData[u]*mtxQ.m_pData[u];
  2124. }
  2125. }
  2126.         if (h == 0.0)
  2127.         { 
  2128. dblC[i]=0.0;
  2129.             if (i==1) 
  2130. dblC[i]=mtxQ.m_pData[i*m_nNumColumns+i-1];
  2131.             dblB[i]=0.0;
  2132.         }
  2133.         else
  2134.         { 
  2135. dblC[i]=sqrt(h);
  2136.             u=i*m_nNumColumns+i-1;
  2137.             if (mtxQ.m_pData[u]>0.0) 
  2138. dblC[i]=-dblC[i];
  2139.             h=h-mtxQ.m_pData[u]*dblC[i];
  2140.             mtxQ.m_pData[u]=mtxQ.m_pData[u]-dblC[i];
  2141.             f=0.0;
  2142.             for (j=0; j<=i-1; j++)
  2143.             { 
  2144. mtxQ.m_pData[j*m_nNumColumns+i]=mtxQ.m_pData[i*m_nNumColumns+j]/h;
  2145.                 g=0.0;
  2146.                 for (k=0; k<=j; k++)
  2147. g=g+mtxQ.m_pData[j*m_nNumColumns+k]*mtxQ.m_pData[i*m_nNumColumns+k];
  2148. if (j+1<=i-1)
  2149. for (k=j+1; k<=i-1; k++)
  2150. g=g+mtxQ.m_pData[k*m_nNumColumns+j]*mtxQ.m_pData[i*m_nNumColumns+k];
  2151.                 dblC[j]=g/h;
  2152.                 f=f+g*mtxQ.m_pData[j*m_nNumColumns+i];
  2153.             }
  2154.             
  2155. h2=f/(h+h);
  2156.             for (j=0; j<=i-1; j++)
  2157.             { 
  2158. f=mtxQ.m_pData[i*m_nNumColumns+j];
  2159.                 g=dblC[j]-h2*f;
  2160.                 dblC[j]=g;
  2161.                 for (k=0; k<=j; k++)
  2162.                 { 
  2163. u=j*m_nNumColumns+k;
  2164.                     mtxQ.m_pData[u]=mtxQ.m_pData[u]-f*dblC[k]-g*mtxQ.m_pData[i*m_nNumColumns+k];
  2165.                 }
  2166.             }
  2167.             
  2168. dblB[i]=h;
  2169.         }
  2170.     }
  2171.     
  2172. for (i=0; i<=m_nNumColumns-2; i++) 
  2173. dblC[i]=dblC[i+1];
  2174.     
  2175. dblC[m_nNumColumns-1]=0.0;
  2176.     dblB[0]=0.0;
  2177.     for (i=0; i<=m_nNumColumns-1; i++)
  2178.     { 
  2179. if ((dblB[i]!=0.0)&&(i-1>=0))
  2180. {
  2181. for (j=0; j<=i-1; j++)
  2182.             { 
  2183. g=0.0;
  2184. for (k=0; k<=i-1; k++)
  2185. g=g+mtxQ.m_pData[i*m_nNumColumns+k]*mtxQ.m_pData[k*m_nNumColumns+j];
  2186. for (k=0; k<=i-1; k++)
  2187.                 { 
  2188. u=k*m_nNumColumns+j;
  2189. mtxQ.m_pData[u]=mtxQ.m_pData[u]-g*mtxQ.m_pData[k*m_nNumColumns+i];
  2190.                 }
  2191.             }
  2192. }
  2193.         u=i*m_nNumColumns+i;
  2194.         dblB[i]=mtxQ.m_pData[u]; mtxQ.m_pData[u]=1.0;
  2195.         if (i-1>=0)
  2196. {
  2197. for (j=0; j<=i-1; j++)
  2198.             { 
  2199. mtxQ.m_pData[i*m_nNumColumns+j]=0.0; 
  2200. mtxQ.m_pData[j*m_nNumColumns+i]=0.0;
  2201. }
  2202. }
  2203.     }
  2204.     // 构造对称三对角矩阵
  2205.     for (i=0; i<m_nNumColumns; ++i)
  2206. {
  2207.     for (j=0; j<m_nNumColumns; ++j)
  2208. {
  2209.             mtxT.SetElement(i, j, 0);
  2210.             k = i - j;
  2211.             if (k == 0) 
  2212.             mtxT.SetElement(i, j, dblB[j]);
  2213. else if (k == 1)
  2214.             mtxT.SetElement(i, j, dblC[j]);
  2215. else if (k == -1)
  2216.             mtxT.SetElement(i, j, dblC[i]);
  2217.         }
  2218.     }
  2219. return TRUE;
  2220. }
  2221. //////////////////////////////////////////////////////////////////////
  2222. // 实对称三对角阵的全部特征值与特征向量的计算
  2223. //
  2224. // 参数:
  2225. // 1. double dblB[] - 一维数组,长度为矩阵的阶数,传入对称三对角阵的主对角线元素;
  2226. //    返回时存放全部特征值。
  2227. // 2. double dblC[] - 一维数组,长度为矩阵的阶数,前n-1个元素传入对称三对角阵的次对角线元素
  2228. // 3. CMatrix& mtxQ - 如果传入单位矩阵,则返回实对称三对角阵的特征值向量矩阵;
  2229. //    如果传入MakeSymTri函数求得的矩阵A的豪斯荷尔德变换的乘积矩阵Q,则返回矩阵A的
  2230. //    特征值向量矩阵。其中第i列为与数组dblB中第j个特征值对应的特征向量。
  2231. // 4. int nMaxIt - 迭代次数,默认值为60
  2232. // 5. double eps - 计算精度,默认值为0.000001
  2233. //
  2234. // 返回值:BOOL型,求解是否成功
  2235. //////////////////////////////////////////////////////////////////////
  2236. BOOL CMatrix::SymTriEigenv(double dblB[], double dblC[], CMatrix& mtxQ, int nMaxIt /*= 60*/, double eps /*= 0.000001*/)
  2237. {
  2238. int i,j,k,m,it,u,v;
  2239.     double d,f,h,g,p,r,e,s;
  2240.     
  2241. // 初值
  2242. int n = mtxQ.GetNumColumns();
  2243. dblC[n-1]=0.0; 
  2244. d=0.0; 
  2245. f=0.0;
  2246.     
  2247. // 迭代计算
  2248. for (j=0; j<=n-1; j++)
  2249.     { 
  2250. it=0;
  2251.         h=eps*(fabs(dblB[j])+fabs(dblC[j]));
  2252.         if (h>d) 
  2253. d=h;
  2254.         
  2255. m=j;
  2256.         while ((m<=n-1)&&(fabs(dblC[m])>d)) 
  2257. m=m+1;
  2258.         
  2259. if (m!=j)
  2260.         { 
  2261. do
  2262.             { 
  2263. if (it==nMaxIt)
  2264. return FALSE;
  2265.                 it=it+1;
  2266.                 g=dblB[j];
  2267.                 p=(dblB[j+1]-g)/(2.0*dblC[j]);
  2268.                 r=sqrt(p*p+1.0);
  2269.                 if (p>=0.0) 
  2270. dblB[j]=dblC[j]/(p+r);
  2271.                 else 
  2272. dblB[j]=dblC[j]/(p-r);
  2273.                 
  2274. h=g-dblB[j];
  2275.                 for (i=j+1; i<=n-1; i++)
  2276. dblB[i]=dblB[i]-h;
  2277.                 
  2278. f=f+h; 
  2279. p=dblB[m]; 
  2280. e=1.0; 
  2281. s=0.0;
  2282.                 for (i=m-1; i>=j; i--)
  2283.                 { 
  2284. g=e*dblC[i]; 
  2285. h=e*p;
  2286.                     if (fabs(p)>=fabs(dblC[i]))
  2287.                     { 
  2288. e=dblC[i]/p; 
  2289. r=sqrt(e*e+1.0);
  2290.                         dblC[i+1]=s*p*r; 
  2291. s=e/r; 
  2292. e=1.0/r;
  2293.                     }
  2294.                     else
  2295. e=p/dblC[i]; 
  2296. r=sqrt(e*e+1.0);
  2297.                         dblC[i+1]=s*dblC[i]*r;
  2298.                         s=1.0/r; 
  2299. e=e/r;
  2300.                     }
  2301.                     
  2302. p=e*dblB[i]-s*g;
  2303.                     dblB[i+1]=h+s*(e*g+s*dblB[i]);
  2304.                     for (k=0; k<=n-1; k++)
  2305.                     { 
  2306. u=k*n+i+1; 
  2307. v=u-1;
  2308.                         h=mtxQ.m_pData[u]; 
  2309. mtxQ.m_pData[u]=s*mtxQ.m_pData[v]+e*h;
  2310.                         mtxQ.m_pData[v]=e*mtxQ.m_pData[v]-s*h;
  2311.                     }
  2312.                 }
  2313.                 
  2314. dblC[j]=s*p; 
  2315. dblB[j]=e*p;
  2316.             
  2317. } while (fabs(dblC[j])>d);
  2318.         }
  2319.         
  2320. dblB[j]=dblB[j]+f;
  2321.     }
  2322.     
  2323. for (i=0; i<=n-1; i++)
  2324.     { 
  2325. k=i; 
  2326. p=dblB[i];
  2327.         if (i+1<=n-1)
  2328.         { 
  2329. j=i+1;
  2330.             while ((j<=n-1)&&(dblB[j]<=p))
  2331.             { 
  2332. k=j; 
  2333. p=dblB[j]; 
  2334. j=j+1;
  2335. }
  2336.         }
  2337.         if (k!=i)
  2338.         { 
  2339. dblB[k]=dblB[i]; 
  2340. dblB[i]=p;
  2341.             for (j=0; j<=n-1; j++)
  2342.             { 
  2343. u=j*n+i; 
  2344. v=j*n+k;
  2345.                 p=mtxQ.m_pData[u]; 
  2346. mtxQ.m_pData[u]=mtxQ.m_pData[v]; 
  2347. mtxQ.m_pData[v]=p;
  2348.             }
  2349.         }
  2350.     }
  2351.     
  2352. return TRUE;
  2353. }
  2354. //////////////////////////////////////////////////////////////////////
  2355. // 约化一般实矩阵为赫申伯格矩阵的初等相似变换法
  2356. //
  2357. // 参数:无
  2358. //
  2359. // 返回值:无
  2360. //////////////////////////////////////////////////////////////////////
  2361. void CMatrix::MakeHberg()
  2362. int i,j,k,u,v;
  2363.     double d,t;
  2364.     for (k=1; k<=m_nNumColumns-2; k++)
  2365.     { 
  2366. d=0.0;
  2367.         for (j=k; j<=m_nNumColumns-1; j++)
  2368.         { 
  2369. u=j*m_nNumColumns+k-1; 
  2370. t=m_pData[u];
  2371.             if (fabs(t)>fabs(d))
  2372.             { 
  2373. d=t; 
  2374. i=j;
  2375. }
  2376.         }
  2377.         
  2378. if (d != 0.0)
  2379.         { 
  2380. if (i!=k)
  2381.             { 
  2382. for (j=k-1; j<=m_nNumColumns-1; j++)
  2383.                 { 
  2384. u=i*m_nNumColumns+j; 
  2385. v=k*m_nNumColumns+j;
  2386.                     t=m_pData[u]; 
  2387. m_pData[u]=m_pData[v]; 
  2388. m_pData[v]=t;
  2389.                 }
  2390.                 
  2391. for (j=0; j<=m_nNumColumns-1; j++)
  2392.                 { 
  2393. u=j*m_nNumColumns+i; 
  2394. v=j*m_nNumColumns+k;
  2395.                     t=m_pData[u]; 
  2396. m_pData[u]=m_pData[v]; 
  2397. m_pData[v]=t;
  2398.                 }
  2399.             }
  2400.             
  2401. for (i=k+1; i<=m_nNumColumns-1; i++)
  2402.             { 
  2403. u=i*m_nNumColumns+k-1; 
  2404. t=m_pData[u]/d; 
  2405. m_pData[u]=0.0;
  2406.                 for (j=k; j<=m_nNumColumns-1; j++)
  2407.                 { 
  2408. v=i*m_nNumColumns+j;
  2409.                     m_pData[v]=m_pData[v]-t*m_pData[k*m_nNumColumns+j];
  2410.                 }
  2411.                 
  2412. for (j=0; j<=m_nNumColumns-1; j++)
  2413.                 { 
  2414. v=j*m_nNumColumns+k;
  2415.                     m_pData[v]=m_pData[v]+t*m_pData[j*m_nNumColumns+i];
  2416.                 }
  2417.             }
  2418.         }
  2419.     }
  2420. }
  2421. //////////////////////////////////////////////////////////////////////
  2422. // 求赫申伯格矩阵全部特征值的QR方法
  2423. //
  2424. // 参数:
  2425. // 1. double dblU[] - 一维数组,长度为矩阵的阶数,返回时存放特征值的实部
  2426. // 2. double dblV[] - 一维数组,长度为矩阵的阶数,返回时存放特征值的虚部
  2427. // 3. int nMaxIt - 迭代次数,默认值为60
  2428. // 4. double eps - 计算精度,默认值为0.000001
  2429. //
  2430. // 返回值:BOOL型,求解是否成功
  2431. //////////////////////////////////////////////////////////////////////
  2432. BOOL CMatrix::HBergEigenv(double dblU[], double dblV[], int nMaxIt /*= 60*/, double eps /*= 0.000001*/)
  2433. int m,it,i,j,k,l,ii,jj,kk,ll;
  2434.     double b,c,w,g,xy,p,q,r,x,s,e,f,z,y;
  2435.     
  2436. int n = m_nNumColumns;
  2437. it=0; 
  2438. m=n;
  2439.     while (m!=0)
  2440.     { 
  2441. l=m-1;
  2442.         while ((l>0)&&(fabs(m_pData[l*n+l-1]) > 
  2443. eps*(fabs(m_pData[(l-1)*n+l-1])+fabs(m_pData[l*n+l])))) 
  2444.   l=l-1;
  2445.         ii=(m-1)*n+m-1; 
  2446. jj=(m-1)*n+m-2;
  2447.         kk=(m-2)*n+m-1; 
  2448. ll=(m-2)*n+m-2;
  2449.         if (l==m-1)
  2450.         { 
  2451. dblU[m-1]=m_pData[(m-1)*n+m-1]; 
  2452. dblV[m-1]=0.0;
  2453.             m=m-1; 
  2454. it=0;
  2455.         }
  2456.         else if (l==m-2)
  2457.         { 
  2458. b=-(m_pData[ii]+m_pData[ll]);
  2459.             c=m_pData[ii]*m_pData[ll]-m_pData[jj]*m_pData[kk];
  2460.             w=b*b-4.0*c;
  2461.             y=sqrt(fabs(w));
  2462.             if (w>0.0)
  2463.             { 
  2464. xy=1.0;
  2465.                 if (b<0.0) 
  2466. xy=-1.0;
  2467.                 dblU[m-1]=(-b-xy*y)/2.0;
  2468.                 dblU[m-2]=c/dblU[m-1];
  2469.                 dblV[m-1]=0.0; dblV[m-2]=0.0;
  2470.             }
  2471.             else
  2472.             { 
  2473. dblU[m-1]=-b/2.0; 
  2474. dblU[m-2]=dblU[m-1];
  2475.                 dblV[m-1]=y/2.0; 
  2476. dblV[m-2]=-dblV[m-1];
  2477.             }
  2478.             
  2479. m=m-2; 
  2480. it=0;
  2481.         }
  2482.         else
  2483.         { 
  2484. if (it>=nMaxIt)
  2485. return FALSE;
  2486.             it=it+1;
  2487.             for (j=l+2; j<=m-1; j++)
  2488. m_pData[j*n+j-2]=0.0;
  2489.             for (j=l+3; j<=m-1; j++)
  2490. m_pData[j*n+j-3]=0.0;
  2491.             for (k=l; k<=m-2; k++)
  2492.             { 
  2493. if (k!=l)
  2494.                 { 
  2495. p=m_pData[k*n+k-1]; 
  2496. q=m_pData[(k+1)*n+k-1];
  2497.                     r=0.0;
  2498.                     if (k!=m-2) 
  2499. r=m_pData[(k+2)*n+k-1];
  2500.                 }
  2501.                 else
  2502.                 { 
  2503. x=m_pData[ii]+m_pData[ll];
  2504.                     y=m_pData[ll]*m_pData[ii]-m_pData[kk]*m_pData[jj];
  2505.                     ii=l*n+l; 
  2506. jj=l*n+l+1;
  2507.                     kk=(l+1)*n+l; 
  2508. ll=(l+1)*n+l+1;
  2509.                     p=m_pData[ii]*(m_pData[ii]-x)+m_pData[jj]*m_pData[kk]+y;
  2510.                     q=m_pData[kk]*(m_pData[ii]+m_pData[ll]-x);
  2511.                     r=m_pData[kk]*m_pData[(l+2)*n+l+1];
  2512.                 }
  2513.                 
  2514. if ((fabs(p)+fabs(q)+fabs(r))!=0.0)
  2515.                 { 
  2516. xy=1.0;
  2517.                     if (p<0.0) 
  2518. xy=-1.0;
  2519.                     s=xy*sqrt(p*p+q*q+r*r);
  2520.                     if (k!=l) 
  2521. m_pData[k*n+k-1]=-s;
  2522.                     e=-q/s; 
  2523. f=-r/s; 
  2524. x=-p/s;
  2525.                     y=-x-f*r/(p+s);
  2526.                     g=e*r/(p+s);
  2527.                     z=-x-e*q/(p+s);
  2528.                     for (j=k; j<=m-1; j++)
  2529.                     { 
  2530. ii=k*n+j; 
  2531. jj=(k+1)*n+j;
  2532.                         p=x*m_pData[ii]+e*m_pData[jj];
  2533.                         q=e*m_pData[ii]+y*m_pData[jj];
  2534.                         r=f*m_pData[ii]+g*m_pData[jj];
  2535.                         if (k!=m-2)
  2536.                         { 
  2537. kk=(k+2)*n+j;
  2538.                             p=p+f*m_pData[kk];
  2539.                             q=q+g*m_pData[kk];
  2540.                             r=r+z*m_pData[kk]; 
  2541. m_pData[kk]=r;
  2542.                         }
  2543.                         
  2544. m_pData[jj]=q; m_pData[ii]=p;
  2545.                     }
  2546.                     
  2547. j=k+3;
  2548.                     if (j>=m-1) 
  2549. j=m-1;
  2550.                     
  2551. for (i=l; i<=j; i++)
  2552.                     { 
  2553. ii=i*n+k; 
  2554. jj=i*n+k+1;
  2555.                         p=x*m_pData[ii]+e*m_pData[jj];
  2556.                         q=e*m_pData[ii]+y*m_pData[jj];
  2557.                         r=f*m_pData[ii]+g*m_pData[jj];
  2558.                         if (k!=m-2)
  2559.                         { 
  2560. kk=i*n+k+2;
  2561.                             p=p+f*m_pData[kk];
  2562.                             q=q+g*m_pData[kk];
  2563.                             r=r+z*m_pData[kk]; 
  2564. m_pData[kk]=r;
  2565.                         }
  2566.                         
  2567. m_pData[jj]=q; 
  2568. m_pData[ii]=p;
  2569.                     }
  2570.                 }
  2571.             }
  2572.         }
  2573.     }
  2574.     
  2575. return TRUE;
  2576. }
  2577. //////////////////////////////////////////////////////////////////////
  2578. // 求实对称矩阵特征值与特征向量的雅可比法
  2579. //
  2580. // 参数:
  2581. // 1. double dblEigenValue[] - 一维数组,长度为矩阵的阶数,返回时存放特征值
  2582. // 2. CMatrix& mtxEigenVector - 返回时存放特征向量矩阵,其中第i列为与
  2583. //    数组dblEigenValue中第j个特征值对应的特征向量
  2584. // 3. int nMaxIt - 迭代次数,默认值为60
  2585. // 4. double eps - 计算精度,默认值为0.000001
  2586. //
  2587. // 返回值:BOOL型,求解是否成功
  2588. //////////////////////////////////////////////////////////////////////
  2589. BOOL CMatrix::JacobiEigenv(double dblEigenValue[], CMatrix& mtxEigenVector, int nMaxIt /*= 60*/, double eps /*= 0.000001*/)
  2590. int i,j,p,q,u,w,t,s,l;
  2591.     double fm,cn,sn,omega,x,y,d;
  2592.     
  2593. if (! mtxEigenVector.Init(m_nNumColumns, m_nNumColumns))
  2594. return FALSE;
  2595. l=1;
  2596.     for (i=0; i<=m_nNumColumns-1; i++)
  2597.     { 
  2598. mtxEigenVector.m_pData[i*m_nNumColumns+i]=1.0;
  2599.         for (j=0; j<=m_nNumColumns-1; j++)
  2600. if (i!=j) 
  2601. mtxEigenVector.m_pData[i*m_nNumColumns+j]=0.0;
  2602.     }
  2603.     
  2604. while (TRUE)
  2605.     { 
  2606. fm=0.0;
  2607.         for (i=1; i<=m_nNumColumns-1; i++)
  2608. {
  2609. for (j=0; j<=i-1; j++)
  2610. d=fabs(m_pData[i*m_nNumColumns+j]);
  2611. if ((i!=j)&&(d>fm))
  2612. fm=d; 
  2613. p=i; 
  2614. q=j;
  2615. }
  2616. }
  2617. }
  2618.         if (fm<eps)
  2619. {
  2620. for (i=0; i<m_nNumColumns; ++i)
  2621. dblEigenValue[i] = GetElement(i,i);
  2622. return TRUE;
  2623. }
  2624.         if (l>nMaxIt)  
  2625. return FALSE;
  2626.         
  2627. l=l+1;
  2628.         u=p*m_nNumColumns+q; 
  2629. w=p*m_nNumColumns+p; 
  2630. t=q*m_nNumColumns+p; 
  2631. s=q*m_nNumColumns+q;
  2632.         x=-m_pData[u]; 
  2633. y=(m_pData[s]-m_pData[w])/2.0;
  2634.         omega=x/sqrt(x*x+y*y);
  2635.         if (y<0.0) 
  2636. omega=-omega;
  2637.         sn=1.0+sqrt(1.0-omega*omega);
  2638.         sn=omega/sqrt(2.0*sn);
  2639.         cn=sqrt(1.0-sn*sn);
  2640.         fm=m_pData[w];
  2641.         m_pData[w]=fm*cn*cn+m_pData[s]*sn*sn+m_pData[u]*omega;
  2642.         m_pData[s]=fm*sn*sn+m_pData[s]*cn*cn-m_pData[u]*omega;
  2643.         m_pData[u]=0.0; 
  2644. m_pData[t]=0.0;
  2645.         for (j=0; j<=m_nNumColumns-1; j++)
  2646. {
  2647. if ((j!=p)&&(j!=q))
  2648. u=p*m_nNumColumns+j; w=q*m_nNumColumns+j;
  2649. fm=m_pData[u];
  2650. m_pData[u]=fm*cn+m_pData[w]*sn;
  2651. m_pData[w]=-fm*sn+m_pData[w]*cn;
  2652. }
  2653. }
  2654.         for (i=0; i<=m_nNumColumns-1; i++)
  2655. {
  2656. if ((i!=p)&&(i!=q))
  2657.             { 
  2658. u=i*m_nNumColumns+p; 
  2659. w=i*m_nNumColumns+q;
  2660. fm=m_pData[u];
  2661. m_pData[u]=fm*cn+m_pData[w]*sn;
  2662. m_pData[w]=-fm*sn+m_pData[w]*cn;
  2663.             }
  2664. }
  2665.         for (i=0; i<=m_nNumColumns-1; i++)
  2666.         { 
  2667. u=i*m_nNumColumns+p; 
  2668. w=i*m_nNumColumns+q;
  2669.             fm=mtxEigenVector.m_pData[u];
  2670.             mtxEigenVector.m_pData[u]=fm*cn+mtxEigenVector.m_pData[w]*sn;
  2671.             mtxEigenVector.m_pData[w]=-fm*sn+mtxEigenVector.m_pData[w]*cn;
  2672.         }
  2673.     }
  2674.     
  2675. for (i=0; i<m_nNumColumns; ++i)
  2676. dblEigenValue[i] = GetElement(i,i);
  2677. return TRUE;
  2678. }
  2679. //////////////////////////////////////////////////////////////////////
  2680. // 求实对称矩阵特征值与特征向量的雅可比过关法
  2681. //
  2682. // 参数:
  2683. // 1. double dblEigenValue[] - 一维数组,长度为矩阵的阶数,返回时存放特征值
  2684. // 2. CMatrix& mtxEigenVector - 返回时存放特征向量矩阵,其中第i列为与
  2685. //    数组dblEigenValue中第j个特征值对应的特征向量
  2686. // 3. double eps - 计算精度,默认值为0.000001
  2687. //
  2688. // 返回值:BOOL型,求解是否成功
  2689. //////////////////////////////////////////////////////////////////////
  2690. BOOL CMatrix::JacobiEigenv2(double dblEigenValue[], CMatrix& mtxEigenVector, double eps /*= 0.000001*/)
  2691. int i,j,p,q,u,w,t,s;
  2692.     double ff,fm,cn,sn,omega,x,y,d;
  2693.     
  2694. if (! mtxEigenVector.Init(m_nNumColumns, m_nNumColumns))
  2695. return FALSE;
  2696. for (i=0; i<=m_nNumColumns-1; i++)
  2697.     { 
  2698. mtxEigenVector.m_pData[i*m_nNumColumns+i]=1.0;
  2699.         for (j=0; j<=m_nNumColumns-1; j++)
  2700. if (i!=j) 
  2701. mtxEigenVector.m_pData[i*m_nNumColumns+j]=0.0;
  2702.     }
  2703.     
  2704. ff=0.0;
  2705.     for (i=1; i<=m_nNumColumns-1; i++)
  2706. {
  2707. for (j=0; j<=i-1; j++)
  2708. d=m_pData[i*m_nNumColumns+j]; 
  2709. ff=ff+d*d; 
  2710. }
  2711. }
  2712.     ff=sqrt(2.0*ff);
  2713. Loop_0:
  2714.     
  2715. ff=ff/(1.0*m_nNumColumns);
  2716. Loop_1:
  2717.     for (i=1; i<=m_nNumColumns-1; i++)
  2718. {
  2719. for (j=0; j<=i-1; j++)
  2720.         { 
  2721. d=fabs(m_pData[i*m_nNumColumns+j]);
  2722.             if (d>ff)
  2723.             { 
  2724. p=i; 
  2725. q=j;
  2726.                 goto Loop_2;
  2727.             }
  2728.         }
  2729. }
  2730.         
  2731. if (ff<eps) 
  2732. {
  2733. for (i=0; i<m_nNumColumns; ++i)
  2734. dblEigenValue[i] = GetElement(i,i);
  2735. return TRUE;
  2736. }
  2737.     
  2738. goto Loop_0;
  2739. Loop_2: 
  2740. u=p*m_nNumColumns+q; 
  2741. w=p*m_nNumColumns+p; 
  2742. t=q*m_nNumColumns+p; 
  2743. s=q*m_nNumColumns+q;
  2744.     x=-m_pData[u]; 
  2745. y=(m_pData[s]-m_pData[w])/2.0;
  2746.     omega=x/sqrt(x*x+y*y);
  2747.     if (y<0.0) 
  2748. omega=-omega;
  2749.     
  2750. sn=1.0+sqrt(1.0-omega*omega);
  2751.     sn=omega/sqrt(2.0*sn);
  2752.     cn=sqrt(1.0-sn*sn);
  2753.     fm=m_pData[w];
  2754.     m_pData[w]=fm*cn*cn+m_pData[s]*sn*sn+m_pData[u]*omega;
  2755.     m_pData[s]=fm*sn*sn+m_pData[s]*cn*cn-m_pData[u]*omega;
  2756.     m_pData[u]=0.0; m_pData[t]=0.0;
  2757.     
  2758. for (j=0; j<=m_nNumColumns-1; j++)
  2759. {
  2760. if ((j!=p)&&(j!=q))
  2761. u=p*m_nNumColumns+j; 
  2762. w=q*m_nNumColumns+j;
  2763. fm=m_pData[u];
  2764. m_pData[u]=fm*cn+m_pData[w]*sn;
  2765. m_pData[w]=-fm*sn+m_pData[w]*cn;
  2766. }
  2767. }
  2768.     for (i=0; i<=m_nNumColumns-1; i++)
  2769.     {
  2770. if ((i!=p)&&(i!=q))
  2771.         { 
  2772. u=i*m_nNumColumns+p; 
  2773. w=i*m_nNumColumns+q;
  2774. fm=m_pData[u];
  2775. m_pData[u]=fm*cn+m_pData[w]*sn;
  2776. m_pData[w]=-fm*sn+m_pData[w]*cn;
  2777.         }
  2778. }
  2779.     
  2780. for (i=0; i<=m_nNumColumns-1; i++)
  2781.     { 
  2782. u=i*m_nNumColumns+p; 
  2783. w=i*m_nNumColumns+q;
  2784.         fm=mtxEigenVector.m_pData[u];
  2785.         mtxEigenVector.m_pData[u]=fm*cn+mtxEigenVector.m_pData[w]*sn;
  2786.         mtxEigenVector.m_pData[w]=-fm*sn+mtxEigenVector.m_pData[w]*cn;
  2787. }
  2788. goto Loop_1;
  2789. }