testILSSymmLqLanczos.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. /**
  2. * @file testILSSymmLqLanczos.cpp
  3. * @author Paul Bodesheim
  4. * @date 23/01/2012
  5. * @brief test routine for Iterative Linear Solver: symmetric LQ Method (SYMMLQ) using Lanczos vectors
  6. */
  7. #include "core/vector/MatrixT.h"
  8. #include "core/vector/VectorT.h"
  9. #include <stdio.h>
  10. #include <ctime>
  11. #include "iostream"
  12. #include "core/basics/Exception.h"
  13. #include "core/vector/Algorithms.h"
  14. // #include "core/algebra/ILSConjugateGradients.h"
  15. #include "core/algebra/GMStandard.h"
  16. #include "core/algebra/ILSSymmLqLanczos.h"
  17. using namespace std;
  18. using namespace NICE;
  19. int main(int argc, char* argv[])
  20. {
  21. int mySize = 20; // number of equations
  22. FILE * logfile;
  23. std::string logfilename;
  24. if ( argc < 2 )
  25. logfilename = "/home/bodesheim/testILS-SymmLq-Lanczos.log";
  26. else
  27. logfilename = argv[1];
  28. logfile = fopen(logfilename.c_str(), "w");
  29. // generate matrix A
  30. Matrix A(mySize,mySize,0.0);
  31. fprintf(logfile, "A:\n");
  32. for (uint i = 0; i < A.rows(); i++)
  33. {
  34. for (uint j = 0; j < A.cols(); j++)
  35. {
  36. if ( j == i ) A(i,j) = (i+1)+(j+1);
  37. else {
  38. A(i,j) = sqrt((i+1)*(j+1));
  39. }
  40. fprintf(logfile, "%f ",A(i,j));
  41. }
  42. fprintf(logfile, "\n");
  43. }
  44. // generate vector b (RHS of LS)
  45. Vector b(mySize,0.0);
  46. fprintf(logfile, "b:\n");
  47. for (uint i = 0; i < b.size(); i++)
  48. {
  49. b(i) = (i+1)*sqrt(i+1);
  50. fprintf(logfile, "%f ",b(i));
  51. }
  52. fprintf(logfile, "\n");
  53. // solve Ax = b
  54. Vector x(mySize,0.0);
  55. ILSSymmLqLanczos ils(true,mySize);
  56. //tic
  57. time_t start = clock();
  58. ils.solveLin(GMStandard(A),b,x);
  59. //toc
  60. float duration = (float) (clock() - start);
  61. std::cerr << "Time for solveLin: " << duration/CLOCKS_PER_SEC << std::endl;
  62. fprintf(logfile, "x:\n");
  63. for (uint i = 0; i < x.size(); i++)
  64. {
  65. fprintf(logfile, "%f ",x(i));
  66. }
  67. fprintf(logfile, "\n");
  68. // check result
  69. Vector Ax(mySize,0.0);
  70. Ax = A*x;
  71. fprintf(logfile, "A*x:\n");
  72. for (uint i = 0; i < Ax.size(); i++)
  73. {
  74. fprintf(logfile, "%f ",Ax(i));
  75. }
  76. fprintf(logfile, "\n");
  77. fclose(logfile);
  78. return 0;
  79. }
  80. // Algorithm without using class ILSConjugateGradientsLanczos works for 10x10 matrix A
  81. // int main(int argc, char* argv[])
  82. // {
  83. //
  84. // int mySize = 10; // number of equations
  85. // FILE * logfile;
  86. // std::string logfilename;
  87. //
  88. // if ( argc < 2 )
  89. // logfilename = "/home/bodesheim/testILS-SymmLq-Lanczos.log";
  90. // else
  91. // logfilename = argv[1];
  92. //
  93. // logfile = fopen(logfilename.c_str(), "w");
  94. //
  95. // // generate matrix A
  96. // Matrix A(mySize,mySize,0.0);
  97. // fprintf(logfile, "A:\n");
  98. // for (uint i = 0; i < A.rows(); i++)
  99. // {
  100. // for (uint j = 0; j < A.cols(); j++)
  101. // {
  102. // if ( j == i ) A(i,j) = (i+1)+(j+1);
  103. // else {
  104. //
  105. // A(i,j) = sqrt((i+1)*(j+1));
  106. // }
  107. //
  108. // fprintf(logfile, "%f ",A(i,j));
  109. // }
  110. // fprintf(logfile, "\n");
  111. // }
  112. //
  113. // // generate vector b (RHS of LS)
  114. // Vector b(mySize,0.0);
  115. // fprintf(logfile, "b:\n");
  116. // for (uint i = 0; i < b.size(); i++)
  117. // {
  118. // b(i) = (i+1)*sqrt(i+1);
  119. // fprintf(logfile, "%f ",b(i));
  120. // }
  121. // fprintf(logfile, "\n");
  122. //
  123. // // solve Ax = b
  124. // Vector x(mySize,0.0);
  125. // ILSSymmLqLanczos ils(true,mySize);
  126. //
  127. // //tic
  128. // time_t start = clock();
  129. // // ils.solveLin(GMStandard(A),b,x);
  130. //
  131. // uint maxIterations = (uint) mySize;
  132. // double minDelta = 1e-7;
  133. // bool verbose = true;
  134. // GMStandard gm(A);
  135. //
  136. // Matrix T(mySize,mySize,0.0);
  137. // Matrix L(mySize,mySize,0.0);
  138. // Matrix Q(mySize,mySize,0.0);
  139. // Matrix Q_tmp(mySize,mySize,0.0);
  140. //
  141. // for (int kk = 0; kk < mySize; kk++)
  142. // Q(kk,kk) = 1.0;
  143. //
  144. // if ( b.size() != gm.rows() ) {
  145. // fthrow(Exception, "Size of vector b (" << b.size() << ") mismatches with the size of the given GenericMatrix (" << gm.rows() << ").");
  146. // }
  147. //
  148. // if ( x.size() != gm.cols() )
  149. // {
  150. // x.resize(gm.cols());
  151. // x.set(0.0); // bad initial solution, but whatever
  152. // }
  153. //
  154. // // if ( verbose ) cerr << "initial solution: " << x << endl;
  155. //
  156. // // SYMMLQ-Method based on Lanczos vectors: implementation based on the following:
  157. // //
  158. // // C.C. Paige and M.A. Saunders: "Solution of sparse indefinite systems of linear equations". SIAM Journal on Numerical Analysis, p. 617--629, vol. 12, no. 4, 1975
  159. // //
  160. // // http://www.netlib.org/templates/templates.pdf
  161. // //
  162. //
  163. // // declare some helpers
  164. // double gamma = 0;
  165. // double gamma_bar = 0;
  166. // double alpha = 0; // alpha_j = v_j^T * A * v_j for new Lanczos vector v_j
  167. // double beta = b.normL2(); // beta_1 = norm(b), in general beta_j = norm(v_j) for new Lanczos vector v_j
  168. // double beta_next = 0; // beta_{j+1}
  169. // double c_new = 0;
  170. // double c_old = -1;
  171. // double s_new = 0;
  172. // double s_old = 0;
  173. // double z_new = 0;
  174. // double z_old = 0;
  175. // double z_older = 0;
  176. // double delta_new = 0;
  177. // double epsilon_new = 0;
  178. // double epsilon_next = 0;
  179. //
  180. // // init some helping vectors
  181. // Vector Av(b.size(),0.0); // Av = A * v_j
  182. // Vector Ac(b.size(),0.0); // Ac = A * c_j
  183. // // Vector r(b.size(),0.0); // current residual
  184. // Vector *v_new = new Vector(b.size(),0.0); // new Lanczos vector v_j
  185. // Vector *v_old = 0; // Lanczos vector of the iteration before: v_{j-1}
  186. // Vector *v_next = new Vector(b.size(),0.0); // Lanczos vector of the next iteration: v_{j+1}
  187. // Vector *w_new = new Vector(b.size(),0.0);
  188. // Vector *w_bar = new Vector(b.size(),0.0);
  189. // Vector x_L (b.size(),0.0);
  190. // Vector x_C (b.size(),0.0);
  191. //
  192. // // first iteration + initialization, where b will be used as the first Lanczos vector
  193. // *v_new = (1/beta)*b; // init v_1, v_1 = b / norm(b)
  194. // gm.multiply(Av,*v_new); // Av = A * v_1
  195. // alpha = v_new->scalarProduct(Av); // alpha_1 = v_1^T * A * v_1
  196. // gamma_bar = alpha; // (gamma_bar_1 is equal to alpha_1 in ILSConjugateGradientsLanczos)
  197. // *v_next = Av - (alpha*(*v_new));
  198. // beta_next = v_next->normL2();
  199. // v_next->normalizeL2();
  200. //
  201. // gamma = sqrt( (gamma_bar*gamma_bar) + (beta_next*beta_next) );
  202. // c_new = gamma_bar/gamma;
  203. // s_new = beta_next/gamma;
  204. //
  205. // z_new = beta/gamma;
  206. //
  207. // *w_bar = *v_new;
  208. //
  209. // *w_new = c_new*(*w_bar) + s_new*(*v_next);
  210. // *w_bar = s_new*(*w_bar) - c_new*(*v_next);
  211. //
  212. // x_L = z_new*(*w_new); // first approximation of x
  213. //
  214. // double delta = fabs(z_new) * w_new->normL2();
  215. // if ( verbose ) {
  216. // cerr << "ILSSymmLqLanczos: iteration 1 / " << maxIterations << endl;
  217. // if ( x.size() <= 20 )
  218. // cerr << "ILSSymmLqLanczos: current solution x_L: " << x_L << endl;
  219. // cerr << "ILSSymmLqLanczos: delta = " << delta << endl;
  220. // // cerr << "ILSSymmLqLanczos: residual = " << r.scalarProduct(r) << endl;
  221. // }
  222. //
  223. // T(0,0) = alpha;
  224. // L(0,0) = gamma;
  225. //
  226. // // start with second iteration
  227. // uint j = 2;
  228. // while (j <= maxIterations )
  229. // {
  230. //
  231. // // prepare next iteration
  232. // if ( v_old == 0 ) v_old = v_new;
  233. // else {
  234. //
  235. // delete v_old;
  236. // v_old = v_new;
  237. // }
  238. // v_new = v_next;
  239. // v_next = new Vector(b.size(),0.0);
  240. // beta = beta_next;
  241. // z_older = z_old;
  242. // z_old = z_new;
  243. // s_old = s_new;
  244. // epsilon_new = epsilon_next;
  245. //
  246. // gm.multiply(Av,*v_new);
  247. // alpha = v_new->scalarProduct(Av);
  248. // *v_next = Av - (alpha*(*v_new)) - (beta*(*v_old));
  249. // beta_next = v_next->normL2();
  250. // v_next->normalizeL2();
  251. //
  252. // gamma_bar = -c_old*s_new*beta - c_new*alpha;
  253. // delta_new = -c_old*c_new*beta + s_new*alpha;
  254. // /* epsilon_new = s_old*beta;*/
  255. // c_old = c_new;
  256. //
  257. // gamma = sqrt( (gamma_bar*gamma_bar) + (beta_next*beta_next) );
  258. // c_new = gamma_bar/gamma;
  259. // s_new = beta_next/gamma;
  260. //
  261. // z_new = - (delta_new*z_old + epsilon_new*z_older)/gamma;
  262. // epsilon_next = s_old*beta_next;
  263. //
  264. // // NOTE this update step is necessary before computing the new w_bar !!
  265. // x_C = x_L + (z_new/c_new)*(*w_bar); // update x
  266. //
  267. // *w_new = c_new*(*w_bar) + s_new*(*v_next);
  268. // *w_bar = s_new*(*w_bar) - c_new*(*v_next);
  269. //
  270. // x_L += z_new*(*w_new); // update x
  271. //
  272. // Vector tmp;
  273. // gm.multiply(tmp,x_C);
  274. // Vector res ( b - tmp );
  275. // double res_x_C = res.scalarProduct(res);
  276. //
  277. // gm.multiply(tmp,x_L);
  278. // res = b - tmp;
  279. // double res_x_L = res.scalarProduct(res);
  280. //
  281. // if ( res_x_L < res_x_C )
  282. // {
  283. // x = x_L;
  284. // if ( verbose )
  285. // cerr << "ILSSymmLqLanczos: x_L used with residual " << res_x_L << " < " << res_x_C << endl;
  286. //
  287. // } else
  288. // {
  289. //
  290. // x = x_C;
  291. // if ( verbose )
  292. // cerr << "ILSSymmLqLanczos: x_C used with residual " << res_x_C << " < " << res_x_L << endl;
  293. //
  294. // }
  295. //
  296. //
  297. // if ( verbose ) {
  298. // cerr << "ILSSymmLqLanczos: iteration " << j << " / " << maxIterations << endl;
  299. // if ( x.size() <= 20 )
  300. // {
  301. // cerr << "ILSSymmLqLanczos: current solution x_L: " << x_L << endl;
  302. // cerr << "ILSSymmLqLanczos: current solution x_C: " << x_C << endl;
  303. // }
  304. // }
  305. //
  306. // // store optimal x that produces smallest residual
  307. // // if (res < res_min) {
  308. // //
  309. // // x_opt = x;
  310. // // res_min = res;
  311. // // }
  312. //
  313. // // check convergence
  314. // delta = fabs(z_new) * w_new->normL2();
  315. // if ( verbose ) {
  316. // cerr << "ILSSymmLqLanczos: delta = " << delta << endl;
  317. // // cerr << "ILSSymmLqLanczos: residual = " << r.scalarProduct(r) << endl;
  318. // }
  319. //
  320. // if ( delta < minDelta ) {
  321. // if ( verbose )
  322. // cerr << "ILSSymmLqLanczos: small delta" << endl;
  323. // break;
  324. // }
  325. //
  326. // T(j-1,j-1) = alpha;
  327. // T(j-2,j-1) = beta;
  328. // T(j-1,j-2) = beta;
  329. //
  330. // L(j-1,j-1) = gamma;
  331. // L(j-1,j-2) = delta_new;
  332. // if (j >= 3)
  333. // L(j-1,j-3) = epsilon_new;
  334. //
  335. // Q_tmp = 0.0;
  336. // for (uint kk = 0; kk < mySize; kk++)
  337. // {
  338. // Q_tmp(kk,kk) = 1.0;
  339. // if (kk == j-2)
  340. // {
  341. // Q_tmp(kk,kk) = c_old;
  342. //
  343. // } else if (kk == j-1)
  344. // {
  345. // Q_tmp(kk,kk) = -c_old;
  346. // Q_tmp(kk-1,kk) = s_old;
  347. // Q_tmp(kk,kk-1) = s_old;
  348. // }
  349. //
  350. // }
  351. //
  352. // Matrix tmpQ(Q);
  353. // Q.multiply(tmpQ,Q_tmp);
  354. //
  355. // tmpQ.multiply(T,Q);
  356. //
  357. // fprintf(logfile, "\n iteration %i\n",j);
  358. // fprintf(logfile, "T:\n");
  359. // for (uint i = 0; i < T.rows(); i++)
  360. // {
  361. // for (uint j = 0; j < T.cols(); j++)
  362. // {
  363. // fprintf(logfile, "%f ",T(i,j));
  364. // }
  365. // fprintf(logfile, "\n");
  366. // }
  367. //
  368. // fprintf(logfile, "Q:\n");
  369. // for (uint i = 0; i < Q.rows(); i++)
  370. // {
  371. // for (uint j = 0; j < Q.cols(); j++)
  372. // {
  373. // fprintf(logfile, "%f ",Q(i,j));
  374. // }
  375. // fprintf(logfile, "\n");
  376. // }
  377. //
  378. // fprintf(logfile, "Q_tmp:\n");
  379. // for (uint i = 0; i < Q_tmp.rows(); i++)
  380. // {
  381. // for (uint j = 0; j < Q_tmp.cols(); j++)
  382. // {
  383. // fprintf(logfile, "%f ",Q_tmp(i,j));
  384. // }
  385. // fprintf(logfile, "\n");
  386. // }
  387. //
  388. // fprintf(logfile, "L:\n");
  389. // for (uint i = 0; i < L.rows(); i++)
  390. // {
  391. // for (uint j = 0; j < L.cols(); j++)
  392. // {
  393. // fprintf(logfile, "%f ",L(i,j));
  394. // }
  395. // fprintf(logfile, "\n");
  396. // }
  397. //
  398. // fprintf(logfile, "T*Q:\n");
  399. // for (uint i = 0; i < tmpQ.rows(); i++)
  400. // {
  401. // for (uint j = 0; j < tmpQ.cols(); j++)
  402. // {
  403. // fprintf(logfile, "%f ",tmpQ(i,j));
  404. // }
  405. // fprintf(logfile, "\n");
  406. // }
  407. // fprintf(logfile, "gamma_bar: %f\n",gamma_bar);
  408. //
  409. // j++;
  410. // }
  411. //
  412. // Vector tmp;
  413. // gm.multiply(tmp,x_C);
  414. // Vector res ( b - tmp );
  415. // double res_x_C = res.scalarProduct(res);
  416. //
  417. // gm.multiply(tmp,x_L);
  418. // res = b - tmp;
  419. // double res_x_L = res.scalarProduct(res);
  420. //
  421. // if ( res_x_L < res_x_C )
  422. // {
  423. // x = x_L;
  424. // if ( verbose )
  425. // cerr << "ILSSymmLqLanczos: x_L used with residual " << res_x_L << " < " << res_x_C << endl;
  426. //
  427. // } else
  428. // {
  429. //
  430. // x = x_C;
  431. // if ( verbose )
  432. // cerr << "ILSSymmLqLanczos: x_C used with residual " << res_x_C << " < " << res_x_L << endl;
  433. //
  434. // }
  435. //
  436. // delete v_new;
  437. // delete v_old;
  438. // delete v_next;
  439. // delete w_new;
  440. // delete w_bar;
  441. //
  442. //
  443. // //toc
  444. // float duration = (float) (clock() - start);
  445. // std::cerr << "Time for solveLin: " << duration/CLOCKS_PER_SEC << std::endl;
  446. //
  447. // fprintf(logfile, "x:\n");
  448. // for (uint i = 0; i < x.size(); i++)
  449. // {
  450. // fprintf(logfile, "%f ",x(i));
  451. // }
  452. // fprintf(logfile, "\n");
  453. //
  454. // // check result
  455. // Vector Ax(mySize,0.0);
  456. // Ax = A*x;
  457. // fprintf(logfile, "A*x:\n");
  458. // for (uint i = 0; i < Ax.size(); i++)
  459. // {
  460. // fprintf(logfile, "%f ",Ax(i));
  461. // }
  462. // fprintf(logfile, "\n");
  463. //
  464. // fclose(logfile);
  465. //
  466. // return 0;
  467. // }
  468. // CHOLESKY FACTORIZATION OF TRIDIAGONAL MATRIX T WORKS:
  469. // int main(int argc, char* argv[])
  470. // {
  471. //
  472. // FILE * logfile;
  473. // std::string logfilename;
  474. //
  475. // if ( argc < 2 )
  476. // logfilename = "/home/bodesheim/testILS-CGM-Lanczos.log";
  477. // else
  478. // logfilename = argv[1];
  479. //
  480. // logfile = fopen(logfilename.c_str(), "w");
  481. //
  482. // Matrix Tmatrix(5,5,0.0);
  483. // fprintf(logfile, "Tmatrix:\n");
  484. // for (uint i = 0; i < Tmatrix.rows(); i++)
  485. // {
  486. // for (uint j = 0; j < Tmatrix.cols(); j++)
  487. // {
  488. // if ( j == i ) Tmatrix(i,j) = (i+1)+(j+1);
  489. // else if ( j == (i+1) ) {
  490. //
  491. // Tmatrix(i,j) = sqrt((i+1)*(j+1));
  492. // Tmatrix(j,i) = Tmatrix(i,j);
  493. // }
  494. //
  495. // fprintf(logfile, "%f ",Tmatrix(i,j));
  496. // }
  497. // fprintf(logfile, "\n");
  498. // }
  499. //
  500. // Matrix Dmatrix(5,5,0.0);
  501. // Matrix Lmatrix(5,5,0.0);
  502. // Vector p(5,0.0);
  503. //
  504. // double beta = 2.4;
  505. // double d_new = 0;
  506. // double d_old = 0;
  507. // double l_new = 0;
  508. // double p_new = 0;
  509. // double p_old = 0;
  510. //
  511. // for (uint iter = 0; iter < Tmatrix.rows(); iter++)
  512. // {
  513. //
  514. // if ( iter == 0 ) {
  515. //
  516. // d_new = Tmatrix(iter,iter);
  517. // l_new = 1;
  518. // p_new = beta/d_new;
  519. //
  520. // } else {
  521. //
  522. // l_new = Tmatrix(iter,iter-1)/sqrt(d_old);
  523. // d_new = Tmatrix(iter,iter)-(l_new*l_new);
  524. //
  525. // l_new/=sqrt(d_old);
  526. // Lmatrix(iter,iter-1)=l_new;
  527. //
  528. // p_new = -p_old*l_new*d_old/d_new;
  529. //
  530. // }
  531. //
  532. // Dmatrix(iter,iter)=d_new;
  533. // Lmatrix(iter,iter)=1;
  534. // p(iter)=p_new;
  535. //
  536. // d_old = d_new;
  537. // p_old = p_new;
  538. // }
  539. //
  540. // fprintf(logfile, "Dmatrix:\n");
  541. // for (uint i = 0; i < Dmatrix.rows(); i++)
  542. // {
  543. // for (uint j = 0; j < Dmatrix.cols(); j++)
  544. // {
  545. // fprintf(logfile, "%f ",Dmatrix(i,j));
  546. // }
  547. // fprintf(logfile, "\n");
  548. // }
  549. //
  550. // fprintf(logfile, "Lmatrix:\n");
  551. // for (uint i = 0; i < Lmatrix.rows(); i++)
  552. // {
  553. // for (uint j = 0; j < Lmatrix.cols(); j++)
  554. // {
  555. // fprintf(logfile, "%f ",Lmatrix(i,j));
  556. // }
  557. // fprintf(logfile, "\n");
  558. // }
  559. //
  560. // Matrix LD(5,5,0.0);
  561. // Matrix LDL(5,5,0.0);
  562. // LD.multiply(Lmatrix,Dmatrix);
  563. // LDL.multiply(LD,Lmatrix.transpose());
  564. //
  565. // fprintf(logfile, "LDL:\n");
  566. // for (uint i = 0; i < LDL.rows(); i++)
  567. // {
  568. // for (uint j = 0; j < LDL.cols(); j++)
  569. // {
  570. // fprintf(logfile, "%f ",LDL(i,j));
  571. // }
  572. // fprintf(logfile, "\n");
  573. // }
  574. //
  575. // Vector result;
  576. // result.multiply(LD,p);
  577. //
  578. // fprintf(logfile, "result:\n");
  579. // for (uint i = 0; i < result.size(); i++)
  580. // {
  581. // fprintf(logfile, "%f ",result(i));
  582. // }
  583. //
  584. //
  585. // fclose(logfile);
  586. //
  587. // return 0;
  588. // }