PageRenderTime 60ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/extlibs/taucs-2.2--my-fix/progs/iter.c

https://code.google.com/p/inla/
C | 915 lines | 700 code | 128 blank | 87 comment | 182 complexity | eef6ad33cc515d3fba7d3f8f3b36b265 MD5 | raw file
  1. /*********************************************************/
  2. /* TAUCS */
  3. /* Author: Sivan Toledo and Doron Chen */
  4. /*********************************************************/
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <math.h>
  9. /*
  10. #include <sys/time.h>
  11. #include <sys/resource.h>
  12. #include <sys/timeb.h>
  13. */
  14. #ifndef WIN32
  15. #include <unistd.h>
  16. #endif
  17. #include <sys/types.h>
  18. #include <assert.h>
  19. #include <taucs.h>
  20. /*********************************************************/
  21. /* */
  22. /*********************************************************/
  23. static double twonorm(int n, double* v)
  24. {
  25. /*
  26. double norm;
  27. int i;
  28. for (i=0, norm=0.0; i<n; i++) norm += v[i]*v[i];
  29. norm = sqrt(norm);
  30. return norm;
  31. */
  32. double ssq, scale, absvi;
  33. int i;
  34. if (n==1) return fabs(v[0]);
  35. scale = 0.0;
  36. ssq = 1.0;
  37. for (i=0; i<n; i++) {
  38. if ( v[i] != 0 ) {
  39. absvi = fabs(v[i]);
  40. if (scale < absvi) {
  41. ssq = 1.0 + ssq * (scale/absvi)*(scale/absvi);
  42. scale = absvi;
  43. } else
  44. ssq = ssq + (absvi/scale)*(absvi/scale);
  45. }
  46. }
  47. return scale * sqrt( ssq );
  48. }
  49. /*********************************************************/
  50. /* */
  51. /*********************************************************/
  52. int M,N; /* Size of matrix */
  53. /*********************************************************/
  54. /* */
  55. /*********************************************************/
  56. void usage(int argc, char* argv[])
  57. {
  58. printf("%s OPTIONS\n",argv[0]);
  59. printf(" -help or -h or no arguments at all\n");
  60. printf(" this help\n");
  61. printf(" MATRIX OPTIONS:\n");
  62. printf(" -hb filename (matrix from Harwell-Boeing file)\n");
  63. printf(" -ijv ijvfilename (matrix from file)\n");
  64. printf(" -mtx mtxfilename (matrix from file)\n");
  65. printf(" -ccs ccsfilename (matrix from file)\n");
  66. printf(" -discont X Y Z jump (X-by-Y-by-Z poisson with discontinuous coeff.)\n");
  67. printf(" -rrn X Y Z dp rmin (X-by-Y-by-Z random resistor network)\n");
  68. printf(" -mesh3d X Y Z (X-by-Y-by-Z poisson problem)\n");
  69. printf(" -mesh2d n (n-by-n poisson problem)\n");
  70. printf(" -mat_type [anisotropic_y/anisotropic_x/dirichlet/neumann]\n");
  71. printf(" mat_type only applicable to -mesh2d\n");
  72. printf(" (3D meshes are always Neumann BC)\n");
  73. printf(" anisotropic problems are Neumann\n");
  74. printf(" RIGHT-HAND SIDE OPTIONS:\n");
  75. printf(" -n+rhs filename (order n followed by rhs, ascii)\n");
  76. printf(" GLOBAL PRECOND OPTIONS:\n");
  77. printf(" -icc\n");
  78. printf(" uses incomplete Cholesky\n");
  79. printf(" -vaidya\n");
  80. printf(" uses Vaidya\n");
  81. printf(" -stretch\n");
  82. printf(" uses Vaidya's preconditioner - starting with a low stretch tree\n");
  83. printf(" -recvaidya\n");
  84. printf(" uses recursive Vaidya\n");
  85. printf(" -sg argument\n");
  86. printf(" uses support-graph preconditioning\n");
  87. printf(" ICC PRECOND OPTIONS:\n");
  88. printf(" -modified\n");
  89. printf(" modified ICC; maintains rowsums; only for -icc\n");
  90. printf(" -droptol droptolerance\n");
  91. printf(" drop tolerance for icc and micc\n");
  92. printf(" -ordering [tree/metis/natural/genmmd/md/mmd/amd]\n");
  93. printf(" ordering to use\n");
  94. printf(" VAIDYA PRECOND OPTIONS:\n");
  95. printf(" -nomf\n");
  96. printf(" use column Cholesky instead of multifrontal\n");
  97. printf(" -subgraphs t\n");
  98. printf(" desired number of subgraphs for Vaidya\n");
  99. printf(" -seed s\n");
  100. printf(" seed for random-number generator; affects decomposition to subtrees\n");
  101. printf(" -rnd x\n");
  102. printf(" uses x INSTEAD of a random number to decompose to subtrees\n");
  103. printf(" we use this to repeat experiments deterministically\n");
  104. printf(" RECURSIVE VAIDYA PRECOND OPTIONS:\n");
  105. printf(" -c c -epsilon e -nsmall nsmall -maxlevels l -convratio r -innerits m\n");
  106. printf(" splits tree into about k=c*n^(1/(1+e)) subgraphs,\n");
  107. printf(" matrices smaller than nsmall are factored directly\n");
  108. printf(" preconditioner has at most l levels\n");
  109. printf(" inner solves reduce their residual by a factor of r\n");
  110. printf(" using at most m iterations\n");
  111. printf(" SUPPORT GRAPH PRECOND OPTIONS:\n");
  112. printf(" argument\n");
  113. printf(" use regular:XX:N\n");
  114. printf(" where XX is GM (Gremban-Miller), CT (Chen-Toledo) or VA (Vaidya)\n");
  115. printf(" and N is an integer, the number of subdomains in each partition\n");
  116. printf(" -subgraphs t\n");
  117. printf(" desired number of subgraphs for Vaidya\n");
  118. printf(" -seed s\n");
  119. printf(" seed for random-number generator; affects decomposition to subtrees\n");
  120. printf(" -rnd x\n");
  121. printf(" uses x INSTEAD of a random number to decompose to subtrees\n");
  122. printf(" we use this to repeat experiments deterministically\n");
  123. printf(" OTHER OPTIONS:\n");
  124. printf(" -log filename\n");
  125. printf(" write log into filename; can be stdout and stderr\n");
  126. exit(0);
  127. }
  128. /*********************************************************/
  129. /* */
  130. /*********************************************************/
  131. int main(int argc, char* argv[])
  132. {
  133. double wtime_order;
  134. double wtime_permute;
  135. double wtime_factor;
  136. double wtime_solve;
  137. double wtime_precond_create;
  138. double ctime_factor;
  139. int i,j;
  140. double NormErr;
  141. taucs_ccs_matrix* A;
  142. taucs_ccs_matrix* A_orig = NULL;
  143. taucs_ccs_matrix* PAPT;
  144. taucs_ccs_matrix* L;
  145. taucs_ccs_matrix* V;
  146. taucs_ccs_matrix* PVPT;
  147. double* X = NULL;
  148. double* B = NULL;
  149. double* PX;
  150. double* PB;
  151. double* NX;
  152. double* X_orig;
  153. double* B_orig;
  154. char* ordering = "metis";
  155. char* sg_command = "qqq";
  156. char* mat_type = "neumann";
  157. int* perm;
  158. int* invperm;
  159. int multifrontal_flag = 1;
  160. int modified_flag = 0;
  161. int icc_flag = 0;
  162. int sg_flag = 0;
  163. int vaidya_flag = 0;
  164. int stretch_flag = 0;
  165. int vaidya_icc_flag = 0;
  166. int contx_flag = 0;
  167. int recvaidya_flag = 0;
  168. int mesh2d_flag = 0,mesh2d_negative_flag=0,mesh2d_size = 0;
  169. int trick_flag = 0;
  170. double subgraphs = 1.0;
  171. double droptol = 0.0;
  172. int rnd,force_rnd=0;
  173. int seed = 123;
  174. double C = 0.25; /* constant factor reduction in rec vaidya */
  175. double epsilon=0.2;
  176. int nsmall=10000;
  177. int maxlevels=2;
  178. int innerits=2;
  179. double innerconv=0.01;
  180. double restol = 1e-8;
  181. int maxits = 10000;
  182. int (*precond_fn)(void*,void* x,void* b);
  183. void* precond_args;
  184. /***********************************************************/
  185. /* Read arguments: log file, matrix, memory size, ooc name */
  186. /***********************************************************/
  187. if ((argc == 1) ||((argc == 2) && !strncmp(argv[1],"-h",2)))
  188. usage(argc,argv);
  189. A = NULL;
  190. for (i=1; i<argc; i++) {
  191. if (!strcmp(argv[i],"-nomf")) multifrontal_flag = 0;
  192. if (!strcmp(argv[i],"-trick")) trick_flag = 1;
  193. if (!strcmp(argv[i],"-icc")) icc_flag = 1;
  194. if (!strcmp(argv[i],"-vaidya")) vaidya_flag = 1;
  195. if (!strcmp(argv[i],"-stretch")) stretch_flag = 1;
  196. if (!strcmp(argv[i],"-cont-x")) contx_flag = 1;
  197. if (!strcmp(argv[i],"-vaidya-icc")) vaidya_icc_flag = 1;
  198. if (!strcmp(argv[i],"-recvaidya")) recvaidya_flag = 1;
  199. if (!strcmp(argv[i],"-modified")) {modified_flag = 1;taucs_printf("Factoring will be Modified ICC\n");}
  200. if (!strcmp(argv[i],"-log") && i <= argc-1 ) {
  201. i++;
  202. taucs_logfile(argv[i]);
  203. }
  204. if (!strcmp(argv[i],"-ordering") && i <= argc-1 ) {
  205. i++;
  206. ordering = argv[i];
  207. }
  208. if (!strcmp(argv[i],"-sg") && i <= argc-2 ) {
  209. sg_flag = 1;
  210. i++;
  211. sg_command = argv[i];
  212. }
  213. if (!strcmp(argv[i],"-mat_type") && i <= argc-1 ) {
  214. i++;
  215. mat_type = argv[i];
  216. }
  217. if (!strcmp(argv[i],"-droptol") && i <= argc-1 ) {
  218. i++;
  219. if (sscanf(argv[i],"%lg",&droptol) != 1) {
  220. taucs_printf("main: -droptol must be followed by a real value\n");
  221. exit(1);
  222. }
  223. }
  224. if (!strcmp(argv[i],"-restol") && i <= argc-1 ) {
  225. i++;
  226. if (sscanf(argv[i],"%lg",&restol) != 1) {
  227. taucs_printf("main: -restol must be followed by a real value\n");
  228. exit(1);
  229. }
  230. }
  231. if (!strcmp(argv[i],"-maxits") && i <= argc-1 ) {
  232. i++;
  233. if (sscanf(argv[i],"%d",&maxits) != 1) {
  234. taucs_printf("main: -maxits must be followed by an integer value\n");
  235. exit(1);
  236. }
  237. }
  238. if (!strcmp(argv[i],"-c") && i <= argc-1 ) {
  239. i++;
  240. if (sscanf(argv[i],"%lg",&C) != 1) {
  241. taucs_printf("main: -c must be followed by a real value\n");
  242. exit(1);
  243. }
  244. }
  245. if (!strcmp(argv[i],"-epsilon") && i <= argc-1 ) {
  246. i++;
  247. if (sscanf(argv[i],"%lg",&epsilon) != 1) {
  248. taucs_printf("main: -epsilon must be followed by a real value\n");
  249. exit(1);
  250. }
  251. }
  252. if (!strcmp(argv[i],"-nsmall") && i <= argc-1 ) {
  253. i++;
  254. if (sscanf(argv[i],"%d",&nsmall) != 1) {
  255. taucs_printf("main: -nsmall must be followed by an integer\n");
  256. exit(1);
  257. }
  258. }
  259. if (!strcmp(argv[i],"-maxlevels") && i <= argc-1 ) {
  260. i++;
  261. if (sscanf(argv[i],"%d",&maxlevels) != 1) {
  262. taucs_printf("main: -maxlevels must be followed by an integer\n");
  263. exit(1);
  264. }
  265. }
  266. if (!strcmp(argv[i],"-innerits") && i <= argc-1 ) {
  267. i++;
  268. if (sscanf(argv[i],"%d",&innerits) != 1) {
  269. taucs_printf("main: -innerits must be followed by an integer\n");
  270. exit(1);
  271. }
  272. }
  273. if (!strcmp(argv[i],"-innerconv") && i <= argc-1 ) {
  274. i++;
  275. if (sscanf(argv[i],"%lg",&innerconv) != 1) {
  276. taucs_printf("main: -innerconv must be followed by a real value\n");
  277. exit(1);
  278. }
  279. }
  280. if (!strcmp(argv[i],"-seed") && i <= argc-1 ) {
  281. i++;
  282. if (sscanf(argv[i],"%d",&seed) != 1) {
  283. taucs_printf("main: -seed must be followed by an integer value\n");
  284. exit(1);
  285. }
  286. }
  287. if (!strcmp(argv[i],"-rnd") && i <= argc-1 ) {
  288. i++;
  289. if (sscanf(argv[i],"%d",&force_rnd) != 1) {
  290. taucs_printf("main: -rnd must be followed by an integer value\n");
  291. exit(1);
  292. }
  293. }
  294. if (!strcmp(argv[i],"-subgraphs") && i <= argc-1 ) {
  295. i++;
  296. if (sscanf(argv[i],"%lg",&subgraphs) != 1) {
  297. taucs_printf("main: -subgraphs must be followed by a real value\n");
  298. exit(1);
  299. }
  300. }
  301. if (!strcmp(argv[i],"-hb") && i <= argc-1 ) {
  302. int nrows,ncols,nnz,j;
  303. char fname[256];
  304. char type[3];
  305. i++;
  306. for (j=0; j<256; j++) fname[j] = ' ';
  307. strcpy(fname,argv[i]);
  308. taucs_printf("main: reading HB matrix %s\n",argv[i]);
  309. ireadhb_(fname,type,&nrows,&ncols,&nnz);
  310. A = taucs_dccs_create(nrows,ncols,nnz);
  311. if (type[1] == 's' || type[1] == 'S')
  312. A->flags = TAUCS_SYMMETRIC | TAUCS_LOWER | TAUCS_DOUBLE;
  313. dreadhb_(fname,&nrows,&ncols,&nnz,
  314. A->colptr,A->rowind,((double*)A->values.d));
  315. /* make indices 0-based */
  316. for (j=0; j<=ncols; j++) ((A->colptr)[j])--;
  317. for (j=0; j<nnz; j++) ((A->rowind)[j])--;
  318. taucs_printf("main: done reading\n");
  319. }
  320. if (!strcmp(argv[i],"-n+rhs") && i <= argc-1) {
  321. FILE* f;
  322. int n,j,nnz;
  323. i++;
  324. taucs_printf("main: reading right-hand side %s\n",argv[i]);
  325. f=fopen(argv[i],"r");
  326. assert(f);
  327. fscanf(f,"%d",&n);
  328. B=(double*) malloc(n*sizeof(double));
  329. nnz = 0;
  330. for (j=0; j<n; j++) {
  331. fscanf(f,"%lg",B+j);
  332. if (B[j]) nnz++;
  333. }
  334. fclose(f);
  335. taucs_printf("main: done reading rhs, %d nonzeros\n",nnz);
  336. }
  337. if (!strcmp(argv[i],"-mtx") && i <= argc-1) {
  338. i++;
  339. taucs_printf("main: reading mtx matrix %s\n",argv[i]);
  340. A = taucs_ccs_read_mtx (argv[i],TAUCS_SYMMETRIC);
  341. taucs_printf("main: done reading\n");
  342. }
  343. if (!strcmp(argv[i],"-ijv") && i <= argc-1) {
  344. i++;
  345. taucs_printf("main: reading ijv matrix %s\n",argv[i]);
  346. A = taucs_ccs_read_ijv (argv[i],TAUCS_SYMMETRIC);
  347. taucs_printf("main: done reading\n");
  348. }
  349. if (!strcmp(argv[i],"-ccs") && i <= argc-1) {
  350. i++;
  351. taucs_printf("main: reading ccs matrix %s\n",argv[i]);
  352. A = taucs_ccs_read_ccs (argv[i],TAUCS_SYMMETRIC);
  353. taucs_printf("main: done reading\n");
  354. }
  355. if (!strcmp(argv[i],"-mesh2d") && i <= argc-1) {
  356. mesh2d_flag = 1;
  357. taucs_printf("A is a mesh2d\n");
  358. i++;
  359. if (sscanf(argv[i],"%d",&mesh2d_size) != 1) {
  360. taucs_printf("mesh size (n, where the mesh is n-by-n) must follow -mesh2d argument\n");
  361. exit(1);
  362. }
  363. }
  364. if (!strcmp(argv[i],"-mesh2d_negative") && i <= argc-1) {
  365. mesh2d_negative_flag = 1;
  366. taucs_printf("A is a mesh2d_negative\n");
  367. i++;
  368. if (sscanf(argv[i],"%d",&mesh2d_size) != 1) {
  369. taucs_printf("mesh size (n, where the mesh is n-by-n) must follow -mesh2d_negative argument\n");
  370. exit(1);
  371. }
  372. }
  373. if (!strcmp(argv[i],"-mesh3d") && i <= argc-3) {
  374. int X,Y,Z;
  375. taucs_printf("A is a mesh3d\n");
  376. if (sscanf(argv[i+1],"%d",&X) != 1
  377. || sscanf(argv[i+2],"%d",&Y) != 1
  378. || sscanf(argv[i+3],"%d",&Z) != 1) {
  379. taucs_printf("mesh size (X Y Z must follow -mesh3d argument\n");
  380. exit(1);
  381. }
  382. i += 3;
  383. taucs_printf("main: creating mesh\n");
  384. A = taucs_ccs_generate_mesh3d(X,Y,Z);
  385. }
  386. if (!strcmp(argv[i],"-rrn") && i <= argc-5) {
  387. int X,Y,Z;
  388. double dp, rmin;
  389. if (sscanf(argv[i+1],"%d",&X) != 1
  390. || sscanf(argv[i+2],"%d",&Y) != 1
  391. || sscanf(argv[i+3],"%d",&Z) != 1
  392. || sscanf(argv[i+4],"%lg",&dp) != 1
  393. || sscanf(argv[i+5],"%lg",&rmin) != 1) {
  394. taucs_printf("mesh size (X Y Z dp rmin must follow -rrn argument\n");
  395. exit(1);
  396. }
  397. i += 5;
  398. taucs_printf("main: creating mesh %d\n",Y);
  399. A = taucs_ccs_generate_rrn(X,Y,Z,dp,rmin);
  400. taucs_printf("A is a random resistor network %d-by-%d-by-%d, drop prob=%.2e, rmin=%.2e\n",
  401. X,Y,Z,dp,rmin);
  402. }
  403. if (!strcmp(argv[i],"-discont") && i <= argc-4) {
  404. int x,y,z;
  405. double jump;
  406. if (sscanf(argv[i+1],"%d",&x) != 1
  407. || sscanf(argv[i+2],"%d",&y) != 1
  408. || sscanf(argv[i+3],"%d",&z) != 1
  409. || sscanf(argv[i+4],"%lg",&jump) != 1) {
  410. taucs_printf("mesh size (X Y Z jump must follow -discont argument\n");
  411. exit(1);
  412. }
  413. i += 4;
  414. taucs_printf("main: creating mesh\n",y);
  415. A = taucs_ccs_generate_discontinuous(x,y,z,jump);
  416. taucs_printf("A is a %d-by-%d-by-%d discontinuous Poisson problem, jump=%.2e\n",
  417. x,y,z,jump);
  418. if (contx_flag) {
  419. X = taucs_vec_generate_continuous(x,y,z,"default");
  420. taucs_printf("iter: using continuous solution\n");
  421. }
  422. }
  423. }
  424. srand(seed);
  425. rnd = rand();
  426. if (force_rnd)
  427. rnd = force_rnd;
  428. taucs_printf("Chosen Ordering: %s\n",ordering);
  429. if (mesh2d_flag)
  430. {
  431. taucs_printf("Matrix type is %s\n",mat_type);
  432. taucs_printf("Grid Size is %d\n",mesh2d_size);
  433. A = taucs_ccs_generate_mesh2d(mesh2d_size,mat_type);
  434. }
  435. if (mesh2d_negative_flag)
  436. {
  437. taucs_printf("Grid Size is %d\n",mesh2d_size);
  438. A = taucs_ccs_generate_mesh2d_negative(mesh2d_size);
  439. }
  440. /* A = symccs_read_ijv("/tmp/A.ijv"); */
  441. if (!A) {
  442. taucs_printf("matrix argument not given or matrix file not found\n");
  443. usage(argc,argv);
  444. }
  445. N = A->n;
  446. if (!X) {
  447. X=(double*)malloc(N*sizeof(double));
  448. for(i=0; i<N; i++) X[i]=(double)rand()/RAND_MAX;
  449. } else
  450. taucs_printf("iter: not using a random X, already allocated\n");
  451. if (!B) {
  452. B=(double*)malloc(N*sizeof(double));
  453. taucs_ccs_times_vec(A,X,B);
  454. } else {
  455. for(i=0; i<N; i++) X[i]= taucs_get_nan();/*omer 0.0 / 0.0*/;
  456. }
  457. if ((sg_flag)&&(trick_flag==0))
  458. {
  459. for(i=0;i<A->n;i++)
  460. {
  461. for (j=A->colptr[i];j<A->colptr[i+1];j++)
  462. if ((A->rowind[j] != i)&&(((double*)A->values.d)[j]>0))
  463. {
  464. trick_flag = 1;
  465. break;
  466. }
  467. if (trick_flag) break;
  468. }
  469. }
  470. if (trick_flag) {
  471. int n;
  472. int *tmp;
  473. taucs_printf("Warning: augmenting to ensure nonpositive offdiagonals\n");
  474. B_orig = B;
  475. X_orig = X;
  476. A_orig = A;
  477. X = (double *)malloc(2*N*sizeof(double));
  478. for(i=0;i<N;i++) {
  479. X[i] = X_orig[i];
  480. X[i+N] = -X_orig[i];
  481. }
  482. B = (double *)malloc(2*N*sizeof(double));
  483. for(i=0;i<N;i++) {
  484. B[i] = B_orig[i];
  485. B[i+N] = -B_orig[i];
  486. }
  487. #if 1
  488. {
  489. taucs_ccs_matrix* A_tmp;
  490. n=A->n;
  491. A_tmp = taucs_dccs_create(2*n,2*n,2*(A->colptr[n]));
  492. A_tmp->flags |= TAUCS_SYMMETRIC | TAUCS_LOWER;
  493. tmp = (int *)calloc((2*n+1),sizeof(int));
  494. for(i=0;i<n;i++)
  495. {
  496. for(j=A->colptr[i];j<A->colptr[i+1];j++)
  497. {
  498. if ((i == A->rowind[j])||(((double*)A->values.d)[j] < 0))
  499. {
  500. tmp[i]++;
  501. tmp[i+n]++;
  502. }
  503. else
  504. {
  505. /* printf("WWW\n");exit(345); */
  506. tmp[i]++;
  507. tmp[A->rowind[j]]++;
  508. }
  509. }
  510. }
  511. A_tmp->colptr[0]=0;
  512. for(i=0;i<2*n;i++)
  513. A_tmp->colptr[i+1] = A_tmp->colptr[i] + tmp[i];
  514. for(i=0;i<2*n;i++)
  515. tmp[i] = A_tmp->colptr[i];
  516. /* for(i=0;i<n;i++) */
  517. /* printf("ZZZ %d %d\n",tmp[i],tmp[i+n]); */
  518. /* exit(345); */
  519. for(i=0;i<n;i++)
  520. {
  521. for(j=A->colptr[i];j<A->colptr[i+1];j++)
  522. {
  523. if ((i == A->rowind[j])||(((double*)A->values.d)[j] < 0))
  524. {
  525. A_tmp->rowind[tmp[i]]=A->rowind[j];
  526. ((double*)A_tmp->values.d)[tmp[i]++]=((double*)A->values.d)[j];
  527. A_tmp->rowind[tmp[i+n]]=A->rowind[j]+n;
  528. ((double*)A_tmp->values.d)[tmp[i+n]++]=((double*)A->values.d)[j];
  529. }
  530. else
  531. {
  532. /* printf("WWW\n");exit(345); */
  533. A_tmp->rowind[tmp[i]]=A->rowind[j]+n;
  534. ((double*)A_tmp->values.d)[tmp[i]++]=-((double*)A->values.d)[j];
  535. A_tmp->rowind[tmp[A->rowind[j]]]=i+n;
  536. ((double*)A_tmp->values.d)[tmp[A->rowind[j]]++]=-((double*)A->values.d)[j];
  537. }
  538. }
  539. }
  540. /*
  541. taucs_ccs_write_ijv(A,"A.ijv");
  542. taucs_ccs_write_ijv(A_tmp,"Aaug.ijv");
  543. */
  544. free(tmp);
  545. taucs_ccs_free(A);
  546. A = A_tmp;
  547. }
  548. #else
  549. A = taucs_ccs_augment_nonpositive_offdiagonals(A_orig);
  550. #endif
  551. }
  552. N = M = A->n;
  553. /***********************************************************/
  554. /* Create exact solution, compute right-hand-side */
  555. /***********************************************************/
  556. NX=(double*)malloc(N*sizeof(double));
  557. PX=(double*)malloc(N*sizeof(double));
  558. PB=(double*)malloc(N*sizeof(double));
  559. /***********************************************************/
  560. /* Compute column ordering */
  561. /***********************************************************/
  562. /***********************************************************/
  563. /* factor */
  564. /***********************************************************/
  565. if (icc_flag) {
  566. int n;
  567. double unit,curr;
  568. n = A->n;
  569. unit = (n-1.)+n;
  570. taucs_printf("main: using incomplete Cholesky droptol=%lg modified=%d\n",
  571. droptol,modified_flag);
  572. wtime_order = taucs_wtime();
  573. taucs_ccs_order(A,&perm,&invperm,ordering);
  574. wtime_order = taucs_wtime() - wtime_order;
  575. taucs_printf("\tOrdering time = % 10.3f seconds\n",wtime_order);
  576. wtime_permute = taucs_wtime();
  577. PAPT = taucs_ccs_permute_symmetrically(A,perm,invperm);
  578. wtime_permute = taucs_wtime() - wtime_permute;
  579. taucs_printf("\tPermute time = % 10.3f seconds\n",wtime_permute);
  580. wtime_factor = taucs_wtime();
  581. ctime_factor = taucs_ctime();
  582. L = taucs_ccs_factor_llt(PAPT,droptol,modified_flag);
  583. /* taucs_ccs_write_ijv(PAPT,"PAPT.ijv"); */
  584. /* taucs_ccs_write_ijv(L,"L.ijv"); */
  585. wtime_factor = taucs_wtime() - wtime_factor;
  586. ctime_factor = taucs_ctime() - ctime_factor;
  587. taucs_printf("\tFactor time = % 10.3f seconds ",wtime_factor);
  588. taucs_printf("(%.3f cpu time)\n",ctime_factor);
  589. curr = L->colptr[n];
  590. taucs_printf("droptol = %1.20lf curr = %lf curr_ratio = %lf\n",droptol,curr,curr/unit);
  591. precond_args = L;
  592. precond_fn = taucs_ccs_solve_llt;
  593. } else if (vaidya_flag) {
  594. int n;
  595. double unit,curr;
  596. /*
  597. int taucs_supernodal_solve_llt(void*,
  598. double*, double*);
  599. */
  600. n = A->n;
  601. unit = (n-1.)+n;
  602. taucs_printf("main: using Vaidya # subgraphs requested=%lf\n",subgraphs);
  603. taucs_printf("Chosen rnd: %d\n",rnd);
  604. wtime_precond_create = taucs_wtime();
  605. #if 1
  606. V = taucs_amwb_preconditioner_create(A,
  607. rnd /* random seed */,
  608. subgraphs,
  609. stretch_flag);
  610. #else
  611. V = taucs_amst_preconditioner_create(A,
  612. rnd /* random seed */,
  613. subgraphs);
  614. #endif
  615. /* taucs_ccs_write_ijv(A,"A.ijv"); */
  616. /* taucs_ccs_write_ijv(V,"V.ijv"); */
  617. wtime_precond_create = taucs_wtime() - wtime_precond_create;
  618. taucs_printf("\tCreation time = % 10.3f seconds\n",wtime_precond_create);
  619. wtime_order = taucs_wtime();
  620. taucs_ccs_order(V,&perm,&invperm,ordering);
  621. wtime_order = taucs_wtime() - wtime_order;
  622. taucs_printf("\tOrdering time = % 10.3f seconds\n",wtime_order);
  623. wtime_permute = taucs_wtime();
  624. PAPT = taucs_ccs_permute_symmetrically(A,perm,invperm);
  625. PVPT = taucs_ccs_permute_symmetrically(V,perm,invperm);
  626. wtime_permute = taucs_wtime() - wtime_permute;
  627. taucs_printf("\tPermute time = % 10.3f seconds\n",wtime_permute);
  628. taucs_ccs_free(V);
  629. wtime_factor = taucs_wtime();
  630. if (multifrontal_flag) {
  631. void* snL;
  632. snL = taucs_ccs_factor_llt_mf(PVPT);
  633. #if 1
  634. L = taucs_supernodal_factor_to_ccs(snL);
  635. taucs_supernodal_factor_free(snL);
  636. precond_args = L;
  637. precond_fn = taucs_ccs_solve_llt;
  638. #else
  639. L = snL;
  640. precond_args = L;
  641. precond_fn = taucs_supernodal_solve_llt;
  642. #endif
  643. } else {
  644. L = taucs_ccs_factor_llt(PVPT,0.0,0);
  645. precond_args = L;
  646. precond_fn = taucs_ccs_solve_llt;
  647. curr = L->colptr[n];
  648. taucs_printf("subgraphs = %6.15lf curr = %lf curr_ratio = %lf\n",subgraphs,curr,curr/unit);fflush(stdout);
  649. }
  650. wtime_factor = taucs_wtime() - wtime_factor;
  651. taucs_printf("\tFactor time = % 10.3f seconds\n",wtime_factor);
  652. taucs_ccs_free(PVPT);
  653. ((taucs_ccs_matrix *)precond_args)->flags |= TAUCS_DOUBLE;
  654. } else if (recvaidya_flag) {
  655. wtime_precond_create = taucs_wtime();
  656. precond_args = taucs_recursive_amwb_preconditioner_create(A,
  657. C,
  658. epsilon,
  659. nsmall,
  660. maxlevels,
  661. innerits,
  662. innerconv,
  663. &perm,&invperm);
  664. precond_fn = taucs_recursive_amwb_preconditioner_solve;
  665. wtime_precond_create = taucs_wtime() - wtime_precond_create;
  666. taucs_printf("\tCreation time = % 10.3f seconds\n",wtime_precond_create);
  667. wtime_permute = taucs_wtime();
  668. PAPT = taucs_ccs_permute_symmetrically(A,perm,invperm);
  669. wtime_permute = taucs_wtime() - wtime_permute;
  670. taucs_printf("\tOrdering time = % 10.3f seconds\n",wtime_permute);
  671. }
  672. #ifdef SIVAN_5_DEC_2002_XXX
  673. else if (sg_flag) {
  674. int
  675. taucs_sg_preconditioner_solve(void* vP,
  676. double* Z,
  677. double* R);
  678. wtime_precond_create = taucs_wtime();
  679. /* precond_args = taucs_multilevel_preconditioner_create(A, */
  680. /* subgraphs, */
  681. /* &perm,&invperm); */
  682. precond_args = taucs_sg_preconditioner_create(A,&perm,&invperm,
  683. ordering,sg_command);
  684. if (!precond_args)
  685. {
  686. printf("Creating the preconditioner failed. Exiting.\n");
  687. exit(345);
  688. }
  689. precond_fn = taucs_sg_preconditioner_solve;
  690. wtime_precond_create = taucs_wtime() - wtime_precond_create;
  691. taucs_printf("\tCreation time = % 10.3f seconds\n",wtime_precond_create);
  692. wtime_permute = taucs_wtime();
  693. PAPT = taucs_ccs_permute_symmetrically(A,perm,invperm);
  694. wtime_permute = taucs_wtime() - wtime_permute;
  695. taucs_printf("\tOrdering time = % 10.3f seconds\n",wtime_permute);
  696. }
  697. #endif
  698. else {
  699. precond_args = NULL;
  700. precond_fn = NULL;
  701. taucs_ccs_order(A,&perm,&invperm,"identity");
  702. PAPT = A;
  703. }
  704. /*taucs_ccs_write_ijv(PAPT,"A.ijv",1);*/ /* 1 = complete the upper part */
  705. /*taucs_ccs_write_ijv(L,"L.ijv",0);*/
  706. /***********************************************************/
  707. /* solve */
  708. /***********************************************************/
  709. for (i=0; i<A->n; i++) PB[i] = B[perm[i]];
  710. for (i=0; i<A->n; i++) PX[i] = 0.0; /* initial guess */
  711. wtime_solve = taucs_wtime();
  712. #if 1
  713. if (vaidya_icc_flag && vaidya_flag) {
  714. taucs_ccs_matrix* L;
  715. double* R;
  716. double init_residual_reduction;
  717. wtime_factor = taucs_wtime();
  718. ctime_factor = taucs_ctime();
  719. L = taucs_ccs_factor_llt(PAPT,1.0,0); /* unmodified ICC(0) */
  720. wtime_factor = taucs_wtime() - wtime_factor;
  721. ctime_factor = taucs_ctime() - ctime_factor;
  722. taucs_printf("\tFactor time = % 10.3f seconds ",wtime_factor);
  723. taucs_printf("(%.3f cpu time)\n",ctime_factor);
  724. taucs_conjugate_gradients (PAPT,
  725. taucs_ccs_solve_llt, L,
  726. PX, PB,
  727. 25, 1e-15);
  728. R = (double*) malloc(A->n * sizeof(double));
  729. taucs_ccs_times_vec(PAPT,PX,R);
  730. for (i=0; i<A->n; i++) R[i] = PB[i] - R[i];
  731. init_residual_reduction = twonorm(A->n,R)/twonorm(A->n,B);
  732. taucs_printf("reduction by a factor of %.2e so far\n",init_residual_reduction);
  733. free(R);
  734. taucs_conjugate_gradients (PAPT,
  735. precond_fn, precond_args,
  736. PX, PB,
  737. 10000, 1e-15 / init_residual_reduction);
  738. } else
  739. {
  740. taucs_conjugate_gradients (PAPT,
  741. precond_fn, precond_args,
  742. PX, PB,
  743. maxits, restol);
  744. }
  745. #else
  746. precond_fn(precond_args,PX,PB); /* direct solver */
  747. #endif
  748. wtime_solve = taucs_wtime() - wtime_solve;
  749. taucs_printf("\tSolve time = % 10.3f seconds\n",wtime_solve);
  750. for (i=0; i<A->n; i++) NX[i] = PX[invperm[i]];
  751. /***********************************************************/
  752. /* delete out-of-core matrices */
  753. /***********************************************************/
  754. /***********************************************************/
  755. /* extract solution from augmented system */
  756. /***********************************************************/
  757. if (0 && A_orig) {
  758. /*
  759. the first half of the elements of NX contains the
  760. solution of the original system
  761. */
  762. taucs_ccs_free(A);
  763. A = A_orig;
  764. free(X);
  765. X = X_orig;
  766. free(B);
  767. B = B_orig;
  768. N = M = A->n;
  769. }
  770. /***********************************************************/
  771. /* Compute norm of forward error */
  772. /***********************************************************/
  773. NormErr = 0.0;
  774. for(i=0; i<N; i++) NormErr = max(NormErr,fabs((NX[i]-X[i])/X[i]));
  775. taucs_printf("main: max relative error = %1.6e \n",NormErr);
  776. for(i=0; i<N; i++) B[i] = NX[i]-X[i];
  777. taucs_printf("main: ||computed X - X||/||X||=%.2e\n",twonorm(N,B)/twonorm(N,X));
  778. /* for(i=0; i<N; i++) */
  779. /* printf("QQQ %i %lf\n",i,NX[i]); */
  780. /***********************************************************/
  781. /* Exit */
  782. /***********************************************************/
  783. taucs_printf("main: done\n");
  784. return 0;
  785. }