TestEMatrix.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. /*
  2. * NICE-Core - efficient algebra and computer vision methods
  3. * - libbasicvector - A simple vector library
  4. * See file License for license information.
  5. */
  6. #ifdef NICE_USELIB_CPPUNIT
  7. #include "TestEMatrix.h"
  8. #include <string>
  9. #include <iostream>
  10. #include <stdexcept>
  11. #include <core/basics/cppunitex.h>
  12. #include "core/vector/MatrixT.h"
  13. #include "core/vector/CheckedVectorT.h"
  14. #include "core/vector/CheckedMatrixT.h"
  15. #include "core/vector/Eigen.h"
  16. #include "core/vector/Algorithms.h"
  17. #ifdef NICE_USELIB_LINAL
  18. #include "LinAl/eigen.h"
  19. #endif
  20. CPPUNIT_TEST_SUITE_REGISTRATION( TestEMatrix );
  21. using namespace NICE;
  22. using namespace std;
  23. void TestEMatrix::setUp() {
  24. }
  25. void TestEMatrix::tearDown() {
  26. }
  27. void TestEMatrix::testAccess() {
  28. MatrixT<double> m(10, 7, 5.4);
  29. CPPUNIT_ASSERT_EQUAL(5.4, m(0, 3));
  30. CPPUNIT_ASSERT_EQUAL(5.4, m(9, 6));
  31. }
  32. void TestEMatrix::testConst() {
  33. const char* data = "abcdef";
  34. MatrixT<char> v(data, 2, 3);
  35. CPPUNIT_ASSERT_EQUAL(2u, (uint)v.rows());
  36. CPPUNIT_ASSERT_EQUAL(3u, (uint)v.cols());
  37. for (unsigned int i = 0; i < v.rows(); i++) {
  38. for (unsigned int j = 0; j < v.cols(); j++) {
  39. // column major
  40. CPPUNIT_ASSERT_EQUAL(data[j*2+i], v(i, j));
  41. // // row major
  42. // CPPUNIT_ASSERT_EQUAL(data[i*3+j], v(i, j));
  43. }
  44. }
  45. }
  46. void TestEMatrix::testCopy() {
  47. const char data[] = "fkepw.xja8";
  48. unsigned int size = strlen(data);
  49. unsigned int rows = size / 2;
  50. unsigned int cols = 2;
  51. MatrixT<char> v(data, rows, cols);
  52. MatrixT<char> w(v);
  53. MatrixT<char> x(w);
  54. CPPUNIT_ASSERT_EQUAL(rows, (uint)v.rows());
  55. CPPUNIT_ASSERT_EQUAL(cols, (uint)v.cols());
  56. CPPUNIT_ASSERT_EQUAL(rows, (uint)w.rows());
  57. CPPUNIT_ASSERT_EQUAL(cols, (uint)w.cols());
  58. CPPUNIT_ASSERT_EQUAL(rows, (uint)x.rows());
  59. CPPUNIT_ASSERT_EQUAL(cols, (uint)x.cols());
  60. for (unsigned int i = 0; i < v.rows(); i++) {
  61. for (unsigned int j = 0; j < v.cols(); j++) {
  62. // column major
  63. CPPUNIT_ASSERT_EQUAL(data[j*rows+i], v(i, j));
  64. CPPUNIT_ASSERT_EQUAL(data[j*rows+i], w(i, j));
  65. CPPUNIT_ASSERT_EQUAL(data[j*rows+i], x(i, j));
  66. // // row major
  67. // CPPUNIT_ASSERT_EQUAL(data[i*cols+j], v(i, j));
  68. // CPPUNIT_ASSERT_EQUAL(data[i*cols+j], w(i, j));
  69. // CPPUNIT_ASSERT_EQUAL(data[i*cols+j], x(i, j));
  70. }
  71. }
  72. }
  73. void TestEMatrix::testExternal() {
  74. char data[] = "1234567890";
  75. unsigned int size = strlen(data);
  76. unsigned int rows = size / 5;
  77. unsigned int cols = 5;
  78. MatrixT<char> v(data, rows, cols, MatrixBase::external);
  79. data[5] = 'A';
  80. v(0, 3) = 'B';
  81. CPPUNIT_ASSERT_EQUAL(rows, (uint)v.rows());
  82. CPPUNIT_ASSERT_EQUAL(cols, (uint)v.cols());
  83. for (unsigned int i = 0; i < v.rows(); i++) {
  84. for (unsigned int j = 0; j < v.cols(); j++) {
  85. // column major
  86. CPPUNIT_ASSERT_EQUAL(data[j*rows+i], v(i, j));
  87. // // row major
  88. // CPPUNIT_ASSERT_EQUAL(data[i*cols+j], v(i, j));
  89. }
  90. }
  91. // column major
  92. CPPUNIT_ASSERT_EQUAL('A', v(1, 2));
  93. CPPUNIT_ASSERT_EQUAL('B', data[6]);
  94. // // row major
  95. // CPPUNIT_ASSERT_EQUAL('A', v(1, 0));
  96. // CPPUNIT_ASSERT_EQUAL('B', data[3]);
  97. }
  98. void TestEMatrix::testAssignment() {
  99. const char data[] = "fkepw.xja8";
  100. int size = strlen(data);
  101. unsigned int rows = size / 5;
  102. unsigned int cols = 5;
  103. MatrixT<char> a(data, rows, cols);
  104. std::auto_ptr<const MatrixT<char> >
  105. b(MatrixT<char>::createConst(data, rows, cols));
  106. MatrixT<char> t(a);
  107. MatrixT<char> u;
  108. u = a;
  109. MatrixT<char> v = a;
  110. MatrixT<char> w(*b);
  111. MatrixT<char> x;
  112. x = *b;
  113. MatrixT<char> y = *b;
  114. for (unsigned int i = 0; i < v.rows(); i++) {
  115. for (unsigned int j = 0; j < v.cols(); j++) {
  116. // column major
  117. CPPUNIT_ASSERT_EQUAL(data[j*rows+i], t(i, j));
  118. CPPUNIT_ASSERT_EQUAL(data[j*rows+i], u(i, j));
  119. CPPUNIT_ASSERT_EQUAL(data[j*rows+i], v(i, j));
  120. CPPUNIT_ASSERT_EQUAL(data[j*rows+i], w(i, j));
  121. CPPUNIT_ASSERT_EQUAL(data[j*rows+i], x(i, j));
  122. CPPUNIT_ASSERT_EQUAL(data[j*rows+i], y(i, j));
  123. // // row major
  124. // CPPUNIT_ASSERT_EQUAL(data[i*cols+j], t(i, j));
  125. // CPPUNIT_ASSERT_EQUAL(data[i*cols+j], u(i, j));
  126. // CPPUNIT_ASSERT_EQUAL(data[i*cols+j], v(i, j));
  127. // CPPUNIT_ASSERT_EQUAL(data[i*cols+j], w(i, j));
  128. // CPPUNIT_ASSERT_EQUAL(data[i*cols+j], x(i, j));
  129. // CPPUNIT_ASSERT_EQUAL(data[i*cols+j], y(i, j));
  130. }
  131. }
  132. u = 'o';
  133. for (unsigned int i = 0; i < v.rows(); i++) {
  134. for (unsigned int j = 0; j < v.cols(); j++) {
  135. CPPUNIT_ASSERT_EQUAL('o', u(i, j));
  136. }
  137. }
  138. MatrixT<int> ev[3];
  139. ev[0]=MatrixT<int>(2, 2);
  140. ev[1]=MatrixT<int>(3, 3);
  141. ev[2]=MatrixT<int>(4, 4);
  142. MatrixT<MatrixT<int> > eev(ev,3,1);
  143. MatrixT<MatrixT<int> > copy_eev = eev;
  144. for (unsigned int i = 0; i < eev.rows(); i++) {
  145. for (unsigned int j = 0; j < eev.cols(); j++) {
  146. CPPUNIT_ASSERT_EQUAL(eev(i, j), copy_eev(i, j));
  147. }
  148. }
  149. }
  150. void TestEMatrix::testArithmetics() {
  151. MatrixT<float> v(2, 10);
  152. for (unsigned int i = 0; i < v.rows(); i++) {
  153. for (unsigned int j = 0; j < v.cols(); j++) {
  154. v(i, j) = 100.0 - float(i+j);
  155. }
  156. }
  157. MatrixT<float> w(v);
  158. w *= 3.0;
  159. w -= v;
  160. for (unsigned int i = 0; i < v.rows(); i++) {
  161. for (unsigned int j = 0; j < v.cols(); j++) {
  162. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(2.0f * v(i, j), w(i, j), 1E-20);
  163. }
  164. }
  165. MatrixT<float> a(3, 1);
  166. MatrixT<float> b(3, 1);
  167. MatrixT<float> c(3, 1);
  168. for (unsigned int i = 0; i < a.rows(); i++) {
  169. a(i, 0) = float(i);
  170. b(i, 0) = float(i + 1);
  171. c(i, 0) = float(i + 2);
  172. }
  173. MatrixT<float> m(3, 1);
  174. m = 0.0f;
  175. m += a;
  176. m += b;
  177. m += c;
  178. m /= 3.0f;
  179. for (unsigned int i = 0; i < m.rows(); i++) {
  180. CPPUNIT_ASSERT_EQUAL(float(i + 1), m(i, 0));
  181. }
  182. }
  183. void TestEMatrix::testRangeChecks() {
  184. CheckedMatrixT<double> v(10, 10, 4.5);
  185. CPPUNIT_ASSERT_EQUAL(4.5, v(0, 0));
  186. CPPUNIT_ASSERT_EQUAL(4.5, v(9, 9));
  187. CPPUNIT_ASSERT_THROW(v(-1, 0), std::out_of_range);
  188. CPPUNIT_ASSERT_THROW(v(0, -1), std::out_of_range);
  189. CPPUNIT_ASSERT_THROW(v(10, 0), std::out_of_range);
  190. CPPUNIT_ASSERT_THROW(v(0, 10), std::out_of_range);
  191. v(9, 9) = 5.1;
  192. CheckedMatrixT<double> w(v.getDataPointer(), v.rows(), v.cols());
  193. CPPUNIT_ASSERT_EQUAL(4.5, w(0, 0));
  194. CPPUNIT_ASSERT_EQUAL(5.1, w(9, 9));
  195. CPPUNIT_ASSERT_THROW(w(-1, 0), std::out_of_range);
  196. CPPUNIT_ASSERT_THROW(w(0, -1), std::out_of_range);
  197. CPPUNIT_ASSERT_THROW(w(10, 0), std::out_of_range);
  198. CPPUNIT_ASSERT_THROW(w(0, 10), std::out_of_range);
  199. }
  200. void TestEMatrix::testEqual() {
  201. MatrixT<double> v(10, 10, 4.5);
  202. MatrixT<double> w(10, 10, 4.5);
  203. MatrixT<double> x(10, 10, 4.5);
  204. MatrixT<double> y(9, 10, 4.5);
  205. MatrixT<double> z;
  206. x(9,9)=4.7;
  207. CPPUNIT_ASSERT(z==z);
  208. CPPUNIT_ASSERT(!(z!=z));
  209. CPPUNIT_ASSERT(v==w);
  210. CPPUNIT_ASSERT(!(v!=w));
  211. CPPUNIT_ASSERT(v!=x);
  212. CPPUNIT_ASSERT(!(v==x));
  213. CPPUNIT_ASSERT_THROW(x==y, std::invalid_argument);
  214. CPPUNIT_ASSERT_THROW(x!=y, std::invalid_argument);
  215. }
  216. void TestEMatrix::testTranspose() {
  217. {
  218. const char data[] = "fkepw.xja";
  219. unsigned int rows = 3;
  220. unsigned int cols = 3;
  221. MatrixT<char> a(data, rows, cols);
  222. MatrixT<char> b(data, rows, cols);
  223. a.transposeInplace();
  224. for (unsigned int i = 0; i < a.rows(); i++) {
  225. for (unsigned int j = 0; j < a.cols(); j++) {
  226. CPPUNIT_ASSERT_EQUAL(a(i, j), b(j, i));
  227. }
  228. }
  229. MatrixT<char> c = a.transpose();
  230. CPPUNIT_ASSERT_EQUAL(a.rows(), c.cols());
  231. CPPUNIT_ASSERT_EQUAL(a.cols(), c.rows());
  232. for (unsigned int i = 0; i < a.rows(); i++) {
  233. for (unsigned int j = 0; j < a.cols(); j++) {
  234. CPPUNIT_ASSERT_EQUAL(a(i, j), c(j, i));
  235. }
  236. }
  237. //std::stringstream inout; inout << c << "!=" << a.transpose();
  238. //CPPUNIT_COND_STREAM(!(a==c), inout.str());
  239. MatrixT<char> d(data, 2, 3);
  240. MatrixT<char> e = d.transpose();
  241. CPPUNIT_ASSERT_EQUAL(d.rows(), e.cols());
  242. CPPUNIT_ASSERT_EQUAL(d.cols(), e.rows());
  243. for (unsigned int i = 0; i < d.rows(); i++) {
  244. for (unsigned int j = 0; j < d.cols(); j++) {
  245. CPPUNIT_ASSERT_EQUAL(d(i, j), e(j, i));
  246. }
  247. }
  248. // test operator, time inefficient :)
  249. for (unsigned int i = 0; i < a.rows(); i++) {
  250. for (unsigned int j = 0; j < a.cols(); j++) {
  251. CPPUNIT_ASSERT_EQUAL(a(i,j), (!a)(j,i));
  252. }
  253. }
  254. }
  255. {
  256. const float data[] = {13.0f,15.0f,17.0f,18.0f,1.0f,2.0f,3.0f,4.0f,5.0f};
  257. unsigned int rows = 3;
  258. unsigned int cols = 3;
  259. MatrixT<float> a(data, rows, cols);
  260. MatrixT<float> b(data, rows, cols);
  261. a.transposeInplace();
  262. for (unsigned int i = 0; i < a.rows(); i++) {
  263. for (unsigned int j = 0; j < a.cols(); j++) {
  264. CPPUNIT_ASSERT_EQUAL(a(i, j), b(j, i));
  265. }
  266. }
  267. MatrixT<float> c = a.transpose();
  268. CPPUNIT_ASSERT_EQUAL(a.rows(), c.cols());
  269. CPPUNIT_ASSERT_EQUAL(a.cols(), c.rows());
  270. for (unsigned int i = 0; i < a.rows(); i++) {
  271. for (unsigned int j = 0; j < a.cols(); j++) {
  272. CPPUNIT_ASSERT_EQUAL(a(i, j), c(j, i));
  273. }
  274. }
  275. //std::stringstream inout; inout << c << "!=" << a.transpose();
  276. //CPPUNIT_COND_STREAM(!(a==c), inout.str());
  277. MatrixT<float> d(data, 2, 3);
  278. MatrixT<float> e = d.transpose();
  279. CPPUNIT_ASSERT_EQUAL(d.rows(), e.cols());
  280. CPPUNIT_ASSERT_EQUAL(d.cols(), e.rows());
  281. for (unsigned int i = 0; i < d.rows(); i++) {
  282. for (unsigned int j = 0; j < d.cols(); j++) {
  283. CPPUNIT_ASSERT_EQUAL(d(i, j), e(j, i));
  284. }
  285. }
  286. }
  287. }
  288. void TestEMatrix::testMultiply() {
  289. MatrixT<double> a(2,3);
  290. MatrixT<double> b(3,2);
  291. MatrixT<double> d(3,1);
  292. for (unsigned int i = 0; i < a.rows(); i++) {
  293. for (unsigned int j = 0; j < a.cols(); j++) {
  294. a(i, j) = i+j;
  295. }
  296. }
  297. for (unsigned int i = 0; i < b.rows(); i++) {
  298. for (unsigned int j = 0; j < b.cols(); j++) {
  299. b(i, j) = (int)i - (int)j;
  300. }
  301. }
  302. {
  303. MatrixT<double> m;
  304. CPPUNIT_ASSERT_THROW(m.multiply(d, a), Exception);
  305. CPPUNIT_ASSERT_THROW(m=d*a, Exception);
  306. }
  307. {
  308. MatrixT<double> m;
  309. CPPUNIT_ASSERT_THROW(m.multiply(a, d, true), Exception);
  310. }
  311. {
  312. MatrixT<double> m;
  313. CPPUNIT_ASSERT_THROW(m.multiply(b, d), Exception);
  314. CPPUNIT_ASSERT_THROW(m=b*d, Exception);
  315. }
  316. {
  317. MatrixT<double> m;
  318. CPPUNIT_ASSERT_THROW(m.multiply(d, b), Exception);
  319. CPPUNIT_ASSERT_THROW(m=d*b, Exception);
  320. }
  321. {
  322. MatrixT<double> m(2,1);
  323. CPPUNIT_ASSERT_NO_THROW(m.multiply(a, d));
  324. CPPUNIT_ASSERT_NO_THROW(m=a*d);
  325. }
  326. {
  327. MatrixT<double> m(1,2);
  328. CPPUNIT_ASSERT_NO_THROW(m.multiply(d, a, true, true));
  329. }
  330. {
  331. MatrixT<double> m(1,2);
  332. CPPUNIT_ASSERT_NO_THROW(m.multiply(d, b, true, false));
  333. }
  334. {
  335. MatrixT<double> m(2,2);
  336. CPPUNIT_ASSERT_NO_THROW(m.multiply(a, a, false, true));
  337. }
  338. MatrixT<double> m;
  339. m.multiply(a, b);
  340. // assumes that the operator== is working correctly
  341. CPPUNIT_ASSERT( m == a*b );
  342. CPPUNIT_ASSERT_EQUAL(2u, (uint)m.cols());
  343. CPPUNIT_ASSERT_EQUAL(2u, (uint)m.rows());
  344. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(5.0, m(0, 0), 1E-20);
  345. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(2.0, m(0, 1), 1E-20);
  346. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(8.0, m(1, 0), 1E-20);
  347. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(2.0, m(1, 1), 1E-20);
  348. float array[]= {0.8385,0.6946,0.1730,0.1365,0.2844,0.5155
  349. ,0.5681,0.6213,0.9797,0.0118,0.4692,0.3340
  350. ,0.3704,0.7948,0.2714,0.8939,0.0648,0.4329
  351. ,0.7027,0.9568,0.2523,0.1991,0.9883,0.2259
  352. ,0.5466,0.5226,0.8757,0.2987,0.5828,0.5798
  353. ,0.4449,0.8801,0.7373,0.6614,0.4235,0.7604};
  354. MatrixT<float> c(array,6,6);
  355. {
  356. MatrixT<float> m;
  357. m.multiply(c, c);
  358. double checksum=0;
  359. for(int i=0;i<6;i++)
  360. for(int j=0;j<6;j++) {
  361. checksum += m(i,j);
  362. checksum*=3.0;
  363. }
  364. std::stringstream inout; inout << checksum << endl << c << "*" << c << "=" << m;
  365. CPPUNIT_COND_STREAM(abs(checksum-3.72091e+17)/3.72091e+17<1e-6, inout.str());
  366. }
  367. {
  368. MatrixT<float> m;
  369. m.multiply(c, c, false, true);
  370. double checksum=0;
  371. for(int i=0;i<6;i++)
  372. for(int j=0;j<6;j++) {
  373. checksum += m(i,j);
  374. checksum*=3.0;
  375. }
  376. std::stringstream inout; inout << checksum << endl << c << "*" << c.transpose() << "=" << m;
  377. CPPUNIT_COND_STREAM(abs(checksum-4.92936e+17)/4.92936e+17<1e-6, inout.str());
  378. }
  379. {
  380. MatrixT<float> m;
  381. m.multiply(c, c, true, true);
  382. double checksum=0;
  383. for(int i=0;i<6;i++)
  384. for(int j=0;j<6;j++) {
  385. checksum += m(i,j);
  386. checksum*=3.0;
  387. }
  388. std::stringstream inout; inout << checksum << endl << c.transpose() << "*" << c.transpose() << "=" << m;
  389. CPPUNIT_COND_STREAM(abs(checksum-3.7386e+17)/3.7386e+17<1e-6, inout.str());
  390. }
  391. {
  392. MatrixT<float> m;
  393. m.multiply(c, c, true, false);
  394. double checksum=0;
  395. for(int i=0;i<6;i++)
  396. for(int j=0;j<6;j++) {
  397. checksum += m(i,j);
  398. checksum*=3.0;
  399. }
  400. std::stringstream inout; inout << checksum << endl << c.transpose() << "*" << c << " =" << m;
  401. CPPUNIT_COND_STREAM(abs(checksum-3.4161e+17)/3.4161e+17<1e-6, inout.str());
  402. }
  403. }
  404. void TestEMatrix::testDet() {
  405. #ifdef NICE_USELIB_IPP
  406. MatrixT<float> a(20,20);
  407. a.setIdentity();
  408. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(1.0,det(a), 1E-6);
  409. MatrixT<float> b(20,20,0.0);
  410. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0,det(b), 1E-6);
  411. float array[]= {0.8385,0.6946,0.1730,0.1365,0.2844,0.5155
  412. ,0.5681,0.6213,0.9797,0.0118,0.4692,0.3340
  413. ,0.3704,0.7948,0.2714,0.8939,0.0648,0.4329
  414. ,0.7027,0.9568,0.2523,0.1991,0.9883,0.2259
  415. ,0.5466,0.5226,0.8757,0.2987,0.5828,0.5798
  416. ,0.4449,0.8801,0.7373,0.6614,0.4235,0.7604};
  417. MatrixT<float> c(array,6,6);
  418. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0498667,det(c), 1E-6);
  419. #endif
  420. }
  421. void TestEMatrix::testEigenValues() {
  422. VectorT<float> buffer(3);
  423. MatrixT<float> b(3,3,0.0f);
  424. float data[][3]= {{1.00861, 2.17143, 2.90536},
  425. {9.01223, 2.17129, 1.90898},
  426. {8.01585, 2.17114, 9.9126},
  427. {7.01947, 2.171, 8.91622},
  428. {6.02309, 2.17086, 7.91984},
  429. {5.02671, 2.17071, 6.92346},
  430. {4.03033, 2.17057, 5.92708},
  431. {3.03396, 2.17042, 4.93071},
  432. {2.03758, 2.17028, 3.93433},
  433. {1.0412, 2.17013, 2.93795}};
  434. for(int i=0;i<10;i++) {
  435. //buffer = VectorT<float>::UniformRandom(3,1.0,10.0,i);
  436. buffer = VectorT<float>(data[i], 3, VectorBase::external);
  437. //std::cerr << buffer << std::endl;
  438. MatrixT<float> x(buffer.getDataPointer(),3,1,MatrixBase::external);
  439. MatrixT<float> a(3,3);
  440. a.multiply(x,x,false,true);
  441. b+=a;
  442. }
  443. MatrixT<double> evecs;
  444. VectorT<double> evals;
  445. MatrixT<double> I;
  446. #ifdef NICE_USELIB_IPP
  447. {
  448. float array[]= {11,4,14,4,-1,10,14,10,8};
  449. MatrixT<float> c(array,3,3);
  450. eigenvalues(c,&buffer);
  451. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0,27-buffer(0), 2E-6);
  452. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0,buffer(1), 2E-6);
  453. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0,-9-buffer(2), 1E-6);
  454. }
  455. {
  456. eigenvalues(b,&buffer);
  457. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(677.0, buffer(0), 5);
  458. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(40.07, buffer(1), 3);
  459. // CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(674.32794189453, buffer(0), 1E-4);
  460. // CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(37.728626251220, buffer(1), 1E-4);
  461. double array[]= {292,101,295,104,48,122,295,122,384};
  462. MatrixT<double> c(array,3,3);
  463. eigenvectorvalues(c,evecs,evals);
  464. I.multiply(evecs,evecs.transpose());
  465. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, 1.0-det(I), 2E-15);
  466. }
  467. #endif
  468. #ifdef NICE_USELIB_LINAL
  469. {
  470. double array[]= {292,101,295,101,48,122,295,122,384};
  471. MatrixT<double> c(array,3,3);
  472. evals= VectorT<double>(3,0.0);
  473. evecs= MatrixT<double>(3,3,0.0);
  474. LinAl::MatrixCF<double> lc = c.linal();
  475. LinAl::VectorCC<double> levals = evals.linalCol();
  476. LinAl::MatrixCF<double> levecs = evecs.linal();
  477. eigensym(lc, levals, levecs, 3);
  478. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(677.0, levals(0,0), 5);
  479. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(40.07, levals(1,0), 1.1);
  480. I.multiply(evecs,evecs.transpose());
  481. double d = LinAl::det(I.linal());
  482. CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, 1.0-d, 2E-15);
  483. }
  484. #endif
  485. }
  486. #endif