PageRenderTime 54ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://code.google.com/p/inla/
C | 1552 lines | 1199 code | 237 blank | 116 comment | 336 complexity | c7979453979b059b559a44ba728da5a3 MD5 | raw file
  1. /*********************************************************/
  2. /* TAUCS */
  3. /* Author: Omer Meshar */
  4. /* This is a revised direct test tool that activates */
  5. /* multiple tests on taucs ( just like direct ) in order */
  6. /* to test the coverage of the direct tests. */
  7. /*********************************************************/
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <math.h>
  12. #include <assert.h>
  13. #ifndef WIN32
  14. #include <unistd.h>
  15. #include <pthread.h>
  16. #endif
  17. #include <taucs.h>
  18. extern int zscal_(int*, taucs_dcomplex*,
  19. double*, int*);
  20. extern int zaxpy_(int*,
  21. taucs_dcomplex*, double*, int*, double*,
  22. int*);
  23. /*********************************************************/
  24. /* */
  25. /*********************************************************/
  26. static double twonorm(int n, double* v)
  27. {
  28. double ssq, scale, absvi;
  29. int i;
  30. if (n==1) return fabs(v[0]);
  31. scale = 0.0;
  32. ssq = 1.0;
  33. for (i=0; i<n; i++) {
  34. if ( v[i] != 0 ) {
  35. absvi = fabs(v[i]);
  36. if (scale < absvi) {
  37. ssq = 1.0 + ssq * (scale/absvi)*(scale/absvi);
  38. scale = absvi;
  39. } else
  40. ssq = ssq + (absvi/scale)*(absvi/scale);
  41. }
  42. }
  43. return scale * sqrt( ssq );
  44. }
  45. #ifndef max
  46. #define max(x,y) ( ((x) > (y)) ? (x) : (y) )
  47. #endif
  48. int M,N; /* Size of matrix */
  49. /*********************************************************/
  50. /* */
  51. /*********************************************************/
  52. /*********************************************************/
  53. /* */
  54. /*********************************************************/
  55. int get_number_of_arguments( char * line )
  56. {
  57. int i, num_of_arguments = 0;
  58. int i_length = strlen(line);
  59. for ( i = 0; i<i_length; i++ )
  60. {
  61. if ( line[i] == ' ' )
  62. num_of_arguments++;
  63. }
  64. return num_of_arguments+1;
  65. }
  66. void get_arguments_length( char * line, int **arg_lengths, int num_of_args )
  67. {
  68. int i,i_length = 0, i_arg_num = 0;
  69. (*arg_lengths) = (int*)malloc(num_of_args * sizeof(int));
  70. for ( i=0; i<strlen(line); i++ )
  71. {
  72. if ( line[i] == ' ' )
  73. {
  74. (*arg_lengths)[i_arg_num++] = i_length;
  75. i_length = 0;
  76. }
  77. else
  78. {
  79. i_length++;
  80. }
  81. }
  82. (*arg_lengths)[i_arg_num++] = i_length-1;
  83. assert( i_arg_num == num_of_args );
  84. }
  85. void usage(int argc, char* argv[])
  86. {
  87. printf("%s OPTIONS\n",argv[0]);
  88. printf(" -help or -h or no arguments at all\n");
  89. printf(" this help\n");
  90. printf(" filename logfilename\n");
  91. printf(" activate list of direct tests listed in the file 'filename'\n");
  92. printf(" log the results in 'logfilename'\n");
  93. exit(0);
  94. }
  95. /*********************************************************/
  96. /* */
  97. /*********************************************************/
  98. #if 1
  99. int main(int argc, char* argv[])
  100. {
  101. int direct_main(int argc, char* argv[]);
  102. int iter_main(int argc, char* argv[]);
  103. FILE * file;
  104. char line[256];
  105. char ** arguments;
  106. int * argument_lengths, i, j, index, k;
  107. int num_of_arguments = 0;
  108. if ((argc == 1) ||((argc == 2) && !strncmp(argv[1],"-h",2)))
  109. usage(argc,argv);
  110. if ( argc == 3 )
  111. {
  112. taucs_logfile(argv[2]);
  113. file = fopen(argv[1], "r");
  114. if ( file == NULL )
  115. {
  116. printf("Could not open file %s. Type %s for usage instructions.\n",argv[1], argv[0]);
  117. exit(0);
  118. }
  119. while ( fgets(line, 256, file) )
  120. {
  121. /*printf("line is %s", line);*/
  122. index = 0;
  123. num_of_arguments = get_number_of_arguments( line );
  124. arguments = (char**) malloc(num_of_arguments * sizeof(char*));
  125. get_arguments_length( line, &argument_lengths, num_of_arguments );
  126. for ( i=0; i<num_of_arguments; i++ )
  127. {
  128. /*printf("argument %d is of length %d\n", i,argument_lengths[i]);*/
  129. arguments[i] = (char*) malloc(argument_lengths[i]+1 * sizeof(char));
  130. j = index; /*where to begin*/
  131. index += argument_lengths[i];/*where to end*/
  132. for ( k=0; j<index; j++, k++ )
  133. {
  134. arguments[i][k] = line[j];
  135. }
  136. arguments[i][k] = '\0';
  137. index++; /*space*/
  138. }
  139. /* activate the line*/
  140. printf("Activating line- %s\n",line);
  141. taucs_printf("*******************************\n");
  142. taucs_printf("log for activation - %s\n", line);
  143. if ( strcmp(arguments[0], "direct" ) == 0 )
  144. {
  145. direct_main(num_of_arguments,arguments);
  146. }
  147. else if ( strcmp(arguments[0], "iter" ) == 0 )
  148. {
  149. iter_main(num_of_arguments,arguments);
  150. }
  151. /* testing
  152. for ( i=0; i<num_of_arguments; i++ )
  153. {
  154. printf("%s ", arguments[i]);
  155. }
  156. printf("\n"); */
  157. /* free the allocated memory for this line */
  158. for ( i=0; i<num_of_arguments; i++ )
  159. {
  160. free(arguments[i]);
  161. }
  162. free(arguments);
  163. free(argument_lengths);
  164. }
  165. fclose(file);
  166. }
  167. else
  168. {
  169. printf("Illegal use. Type %s for usage instructions.\n",argv[0]);
  170. exit(0);
  171. }
  172. return 0;
  173. }
  174. #else
  175. struct arg { int c; char** v; };
  176. void* start_routine(void* varg) {
  177. struct arg* cv = (struct arg*) varg;
  178. int actual_main(int argc, char* argv[]);
  179. fprintf(stderr,"***3\n");
  180. (void) actual_main(cv->c, cv->v);
  181. fprintf(stderr,"***4\n");
  182. return NULL;
  183. }
  184. int main(int argc, char* argv[])
  185. {
  186. pthread_t thread;
  187. pthread_attr_t attr;
  188. struct arg cv;
  189. void* ret_val;
  190. void* (*start_routine)(void *);
  191. cv.c = argc;
  192. cv.v = argv;
  193. pthread_attr_init(&attr);
  194. fprintf(stderr,"***1\n");
  195. pthread_create(&thread, NULL, start_routine, (void*) &cv);
  196. fprintf(stderr,"***2\n");
  197. pthread_join(thread, NULL);
  198. return 0;
  199. }
  200. #endif
  201. /*********************************************************/
  202. /* */
  203. /*********************************************************/
  204. int direct_main(int argc, char* argv[])
  205. {
  206. double wtime_order;
  207. double wtime_permute;
  208. double wtime_factor;
  209. double wtime_solve;
  210. double ctime_factor;
  211. int i;
  212. double NormErr;
  213. taucs_ccs_matrix* A;
  214. taucs_ccs_matrix* PAPT;
  215. taucs_ccs_matrix* L;
  216. double* Xd = NULL;
  217. double* Bd = NULL;
  218. double* PXd;
  219. double* PBd;
  220. double* NXd;
  221. float* Xs = NULL;
  222. float* Bs = NULL;
  223. float* PXs;
  224. float* PBs;
  225. float* NXs;
  226. taucs_dcomplex* Xz = NULL;
  227. taucs_dcomplex* Bz = NULL;
  228. taucs_dcomplex* PXz;
  229. taucs_dcomplex* PBz;
  230. taucs_dcomplex* NXz;
  231. char* ordering = "metis";
  232. char* mat_type = "neumann";
  233. int* perm;
  234. int* invperm;
  235. int precision = TAUCS_DOUBLE;
  236. int ldlt_flag = 0;
  237. int snmf_flag = 0;
  238. int snll_flag = 0;
  239. int symb_flag = 0;
  240. int mesh2d_flag = 0,mesh2d_size = 0;
  241. int ooc_flag = 0;
  242. int panelize = 0;
  243. double memory_mb = -1.0;
  244. char* matrixfile = "/tmp/taucs.L";
  245. taucs_io_handle* oocL;
  246. int (*precond_fn)(void*,void* x,void* b);
  247. void* precond_args;
  248. /***********************************************************/
  249. /* Read arguments: log file, matrix, memory size, ooc name */
  250. /***********************************************************/
  251. A = NULL;
  252. for (i=1; i<argc; i++) {
  253. if (!strcmp(argv[i],"-single")) precision = TAUCS_SINGLE;
  254. if (!strcmp(argv[i],"-dcomplex")) precision = TAUCS_DCOMPLEX;
  255. if (!strcmp(argv[i],"-ldlt")) ldlt_flag = 1;
  256. if (!strcmp(argv[i],"-snmf")) snmf_flag = 1;
  257. if (!strcmp(argv[i],"-snll")) snll_flag = 1;
  258. if (!strcmp(argv[i],"-symb")) symb_flag = 1;
  259. if (!strcmp(argv[i],"-ooc")) ooc_flag = 1;
  260. if (!strcmp(argv[i],"-log") && i <= argc-1 ) {
  261. i++;
  262. taucs_logfile(argv[i]);
  263. }
  264. if (!strcmp(argv[i],"-panelize") && i <= argc-1) {
  265. i++;
  266. if (sscanf(argv[i],"%d",&panelize) != 1) {
  267. taucs_printf("0 (smart), 1 (in-core), or 2 (single supernode) follow -panelize argument\n");
  268. exit(1);
  269. }
  270. }
  271. if (!strcmp(argv[i],"-memory") && i <= argc-1) {
  272. i++;
  273. if (sscanf(argv[i],"%lf",&memory_mb) != 1) {
  274. taucs_printf("memory size in MB must follow -memory argument\n");
  275. exit(1);
  276. }
  277. }
  278. if (!strcmp(argv[i],"-matrixfile") && i <= argc-1 ) {
  279. i++;
  280. matrixfile = argv[i];
  281. }
  282. if (!strcmp(argv[i],"-ordering") && i <= argc-1 ) {
  283. i++;
  284. ordering = argv[i];
  285. }
  286. if (!strcmp(argv[i],"-mat_type") && i <= argc-1 ) {
  287. i++;
  288. mat_type = argv[i];
  289. }
  290. #if 0
  291. if (!strcmp(argv[i],"-hb") && i <= argc-1 ) {
  292. int nrows,ncols,nnz,j;
  293. char fname[256];
  294. char type[3];
  295. i++;
  296. for (j=0; j<256; j++) fname[j] = ' ';
  297. strcpy(fname,argv[i]);
  298. taucs_printf("main: reading HB matrix %s\n",argv[i]);
  299. ireadhb_(fname,type,&nrows,&ncols,&nnz);
  300. A = taucs_dccs_creagte(nrows,ncols,nnz);
  301. if (type[1] == 's' || type[1] == 'S')
  302. A->flags |= TAUCS_SYMMETRIC | TAUCS_LOWER;
  303. dreadhb_(fname,&nrows,&ncols,&nnz,
  304. A->colptr,A->rowind,A->values);
  305. /* make indices 0-based */
  306. for (j=0; j<=ncols; j++) ((A->colptr)[j])--;
  307. for (j=0; j<nnz; j++) ((A->rowind)[j])--;
  308. taucs_printf("main: done reading\n");
  309. }
  310. #endif
  311. if (!strcmp(argv[i],"-hb") && i <= argc-1) {
  312. i++;
  313. taucs_printf("main: reading hb matrix %s\n",argv[i]);
  314. switch (precision) {
  315. case TAUCS_SINGLE:
  316. A = taucs_ccs_read_hb (argv[i], TAUCS_SINGLE); break;
  317. case TAUCS_DOUBLE:
  318. A = taucs_ccs_read_hb (argv[i], TAUCS_DOUBLE); break;
  319. case TAUCS_DCOMPLEX:
  320. A = taucs_ccs_read_hb (argv[i], TAUCS_DCOMPLEX); break;
  321. default:
  322. taucs_printf("main: unknown precision\n");
  323. exit(1);
  324. }
  325. taucs_printf("main: done reading\n");
  326. }
  327. if (!strcmp(argv[i],"-mtx") && i <= argc-1) {
  328. i++;
  329. taucs_printf("main: reading mtx matrix %s\n",argv[i]);
  330. A = taucs_ccs_read_mtx (argv[i],TAUCS_SYMMETRIC | TAUCS_PATTERN);
  331. taucs_printf("main: done reading\n");
  332. }
  333. if (!strcmp(argv[i],"-ijv") && i <= argc-1) {
  334. printf(">>> ijv\n");
  335. i++;
  336. taucs_printf("main: reading ijv matrix %s\n",argv[i]);
  337. switch (precision) {
  338. case TAUCS_SINGLE:
  339. A = taucs_ccs_read_ijv (argv[i],TAUCS_SYMMETRIC | TAUCS_SINGLE); break;
  340. case TAUCS_DOUBLE:
  341. A = taucs_ccs_read_ijv (argv[i],TAUCS_SYMMETRIC | TAUCS_DOUBLE); break;
  342. case TAUCS_DCOMPLEX:
  343. A = taucs_ccs_read_ijv (argv[i],TAUCS_HERMITIAN | TAUCS_DCOMPLEX); break;
  344. default:
  345. taucs_printf("main: unknown precision\n");
  346. exit(1);
  347. }
  348. taucs_printf("main: done reading\n");
  349. }
  350. if (!strcmp(argv[i],"-ccs") && i <= argc-1) {
  351. i++;
  352. taucs_printf("main: reading ccs matrix %s\n",argv[i]);
  353. A = taucs_ccs_read_ccs (argv[i],TAUCS_SYMMETRIC);
  354. taucs_printf("main: done reading\n");
  355. }
  356. if (!strcmp(argv[i],"-mesh2d") && i <= argc-1) {
  357. mesh2d_flag = 1;
  358. taucs_printf("A is a mesh2d\n");
  359. i++;
  360. if (sscanf(argv[i],"%d",&mesh2d_size) != 1) {
  361. taucs_printf("mesh size (n, where the mesh is n-by-n) must follow -mesh2d argument\n");
  362. exit(1);
  363. }
  364. }
  365. if (!strcmp(argv[i],"-mesh3d") && i <= argc-3) {
  366. int X,Y,Z;
  367. taucs_printf("A is a mesh3d\n");
  368. if (sscanf(argv[i+1],"%d",&X) != 1
  369. || sscanf(argv[i+2],"%d",&Y) != 1
  370. || sscanf(argv[i+3],"%d",&Z) != 1) {
  371. taucs_printf("mesh size (X Y Z must follow -mesh3d argument\n");
  372. exit(1);
  373. }
  374. i += 3;
  375. taucs_printf("main: creating mesh\n");
  376. A = taucs_ccs_generate_mesh3d(X,Y,Z);
  377. }
  378. if (!strcmp(argv[i],"-n+rhs") && i <= argc-1) {
  379. FILE* f;
  380. int n,j,nnz;
  381. i++;
  382. taucs_printf("main: reading right-hand side %s\n",argv[i]);
  383. f=fopen(argv[i],"r");
  384. assert(f);
  385. fscanf(f,"%d",&n);
  386. Bd=(double*) malloc(n*sizeof(double));
  387. nnz = 0;
  388. for (j=0; j<n; j++) {
  389. fscanf(f,"%lg",(Bd)+j);
  390. if (Bd[j]) nnz++;
  391. }
  392. fclose(f);
  393. taucs_printf("main: done reading rhs, %d nonzeros\n",nnz);
  394. }
  395. }
  396. taucs_printf("Chosen Ordering: %s\n",ordering);
  397. if (mesh2d_flag)
  398. {
  399. taucs_printf("Matrix type is %s\n",mat_type);
  400. taucs_printf("Grid Size is %d\n",mesh2d_size);
  401. A = taucs_ccs_generate_mesh2d(mesh2d_size,mat_type);
  402. }
  403. if (!A) {
  404. taucs_printf("matrix argument not given or matrix file not found\n");
  405. usage(argc,argv);
  406. }
  407. N = M = A->n;
  408. /***********************************************************/
  409. /* Create exact solution, compute right-hand-side */
  410. /***********************************************************/
  411. if (A->flags & TAUCS_SINGLE) {
  412. if (! (Xs)) {
  413. Xs = (float*)malloc(N*sizeof(float));
  414. for(i=0; i<N; i++) (Xs)[i]=(float)((double)random()/RAND_MAX);
  415. } else
  416. taucs_printf("iter: not using a random X, already allocated\n");
  417. if (!(Bs)) {
  418. Bs = (float*)malloc(N*sizeof(float));
  419. taucs_ccs_times_vec(A,Xs,Bs);
  420. } else {
  421. double nan = taucs_get_nan();
  422. for(i=0; i<N; i++) Xs[i]= (float)nan;
  423. }
  424. NXs=(float*)malloc(N*sizeof(float));
  425. PXs=(float*)malloc(N*sizeof(float));
  426. PBs=(float*)malloc(N*sizeof(float));
  427. }
  428. if (A->flags & TAUCS_DOUBLE) {
  429. if (! (Xd)) {
  430. Xd =(double*)malloc(N*sizeof(double));
  431. for(i=0; i<N; i++) (Xd)[i]=(float)((double)random()/RAND_MAX);
  432. } else
  433. taucs_printf("iter: not using a random X, already allocated\n");
  434. if (!(Bd)) {
  435. Bd =(double*)malloc(N*sizeof(double));
  436. taucs_ccs_times_vec(A,Xd,Bd);
  437. } else {
  438. double nan = taucs_get_nan();
  439. for(i=0; i<N; i++) Xd[i]= (float)nan;
  440. }
  441. NXd=(double*)malloc(N*sizeof(double));
  442. PXd=(double*)malloc(N*sizeof(double));
  443. PBd=(double*)malloc(N*sizeof(double));
  444. }
  445. if (A->flags & TAUCS_DCOMPLEX) {
  446. if (!(Xz)) {
  447. double* p;
  448. taucs_printf("direct: creating a random dcomplex X\n");
  449. Xz =(taucs_dcomplex*)malloc(N*sizeof(taucs_dcomplex));
  450. p = (double*) Xz;
  451. for(i=0; i<2*N; i++) p[i] = (double)random()/RAND_MAX;
  452. } else
  453. taucs_printf("iter: not using a random X, already allocated\n");
  454. if (!(Bz)) {
  455. Bz =(taucs_dcomplex*)malloc(N*sizeof(taucs_dcomplex));
  456. taucs_ccs_times_vec(A,Xz,Bz);
  457. } else {
  458. double* p;
  459. double nan = taucs_get_nan();
  460. p = (double*) Xz;
  461. for(i=0; i<2*N; i++) p[i] = nan;
  462. }
  463. NXz=(taucs_dcomplex*)malloc(N*sizeof(taucs_dcomplex));
  464. PXz=(taucs_dcomplex*)malloc(N*sizeof(taucs_dcomplex));
  465. PBz=(taucs_dcomplex*)malloc(N*sizeof(taucs_dcomplex));
  466. }
  467. /***********************************************************/
  468. /* Compute column ordering */
  469. /***********************************************************/
  470. /***********************************************************/
  471. /* factor */
  472. /***********************************************************/
  473. {
  474. int n;
  475. double unit;
  476. n = A->n;
  477. unit = (n-1.)+n;
  478. wtime_order = taucs_wtime();
  479. taucs_ccs_order(A,&perm,&invperm,ordering);
  480. wtime_order = taucs_wtime() - wtime_order;
  481. taucs_printf("\tOrdering time = % 10.3f seconds\n",wtime_order);
  482. if (!perm) {
  483. taucs_printf("\tOrdering Failed\n");
  484. exit(1);
  485. }
  486. if (0) {
  487. int i;
  488. FILE* f;
  489. f=fopen("p.ijv","w");
  490. for (i=0; i<n; i++) fprintf(f,"%d\n",perm[i]+1);
  491. fclose(f);
  492. }
  493. if (A->flags & TAUCS_SYMMETRIC || A->flags & TAUCS_HERMITIAN) {
  494. wtime_permute = taucs_wtime();
  495. PAPT = taucs_ccs_permute_symmetrically(A,perm,invperm);
  496. wtime_permute = taucs_wtime() - wtime_permute;
  497. taucs_printf("\tPermute time = % 10.3f seconds\n",wtime_permute);
  498. }
  499. wtime_factor = taucs_wtime();
  500. ctime_factor = taucs_ctime();
  501. if (ldlt_flag) {
  502. L = taucs_ccs_factor_ldlt(PAPT);
  503. precond_args = L;
  504. precond_fn = taucs_ccs_solve_ldlt;
  505. } else if (snmf_flag) {
  506. /*taucs_ccs_matrix* C;*/
  507. L = taucs_ccs_factor_llt_mf(PAPT);
  508. precond_args = L;
  509. precond_fn = taucs_supernodal_solve_llt;
  510. {
  511. taucs_ccs_matrix* C;
  512. C = taucs_supernodal_factor_to_ccs(L);
  513. precond_args = C;
  514. precond_fn = taucs_ccs_solve_llt;
  515. }
  516. } else if (ooc_flag) {
  517. if (A->flags & TAUCS_SYMMETRIC || A->flags & TAUCS_HERMITIAN) {
  518. #define TESTING
  519. #ifdef TESTING
  520. int taucs_ooc_factor_llt_panelchoice(taucs_ccs_matrix* A,
  521. taucs_io_handle* handle,
  522. double memory,
  523. int panelization_method);
  524. oocL = taucs_io_create_multifile(matrixfile);
  525. assert(oocL);
  526. if (memory_mb == -1.0) memory_mb = taucs_available_memory_size()/1048576.0;
  527. taucs_ooc_factor_llt_panelchoice(PAPT, oocL, memory_mb*1048576.0,panelize);
  528. precond_args = oocL;
  529. precond_fn = taucs_ooc_solve_llt;
  530. #else
  531. /*int c;*/
  532. oocL = taucs_io_create_multifile(matrixfile);
  533. assert(oocL);
  534. if (memory_mb == -1.0) memory_mb = taucs_available_memory_size()/1048576.0;
  535. taucs_ooc_factor_llt(PAPT, oocL, memory_mb*1048576.0);
  536. precond_args = oocL;
  537. precond_fn = taucs_ooc_solve_llt;
  538. #endif
  539. } else {
  540. if (memory_mb == -1.0) memory_mb = taucs_available_memory_size()/1048576.0;
  541. oocL = taucs_io_create_multifile(matrixfile);
  542. taucs_ooc_factor_lu(A, perm, oocL, memory_mb*1048576.0);
  543. precond_args = matrixfile;
  544. precond_fn = NULL;
  545. }
  546. } else if (snll_flag) {
  547. L = taucs_ccs_factor_llt_ll(PAPT);
  548. precond_args = L;
  549. precond_fn = taucs_supernodal_solve_llt;
  550. } else if (symb_flag) {
  551. L = taucs_ccs_factor_llt_symbolic(PAPT);
  552. taucs_ccs_factor_llt_numeric(PAPT,L); /* should check error code */
  553. precond_args = L;
  554. precond_fn = taucs_supernodal_solve_llt;
  555. } else {
  556. L = taucs_ccs_factor_llt(PAPT,0.0,0);
  557. precond_args = L;
  558. precond_fn = taucs_ccs_solve_llt;
  559. }
  560. wtime_factor = taucs_wtime() - wtime_factor;
  561. ctime_factor = taucs_ctime() - ctime_factor;
  562. taucs_printf("\tFactor time = % 10.3f seconds ",wtime_factor);
  563. taucs_printf("(%.3f cpu time)\n",ctime_factor);
  564. }
  565. if (!L && !ooc_flag /* no L in ooc */) {
  566. taucs_printf("\tFactorization Failed\n");
  567. exit(1);
  568. }
  569. /***********************************************************/
  570. /* solve */
  571. /***********************************************************/
  572. if (!L) {
  573. taucs_printf("FACTORIZATION FAILED!\n");
  574. exit(1);
  575. }
  576. if (A->flags & TAUCS_SYMMETRIC || A->flags & TAUCS_HERMITIAN) {
  577. if (A->flags & TAUCS_DOUBLE)
  578. taucs_vec_permute(A->n,A->flags,Bd,PBd,perm);
  579. if (A->flags & TAUCS_SINGLE)
  580. taucs_vec_permute(A->n,A->flags,Bs,PBs,perm);
  581. if (A->flags & TAUCS_DCOMPLEX)
  582. taucs_vec_permute(A->n,A->flags,Bz,PBz,perm);
  583. wtime_solve = taucs_wtime();
  584. if (A->flags & TAUCS_DOUBLE)
  585. precond_fn(precond_args,PXd,PBd); /* direct solver */
  586. if (A->flags & TAUCS_SINGLE)
  587. precond_fn(precond_args,PXs,PBs); /* direct solver */
  588. if (A->flags & TAUCS_DCOMPLEX)
  589. precond_fn(precond_args,PXz,PBz); /* direct solver */
  590. #if 1
  591. if (A->flags & TAUCS_SINGLE) {
  592. taucs_sccs_times_vec_dacc(PAPT,PXs,NXs);
  593. for(i=0; i<(A->n); i++) NXs[i] -= PBs[i];
  594. precond_fn(precond_args,PBs,NXs); /* direct solver */
  595. for(i=0; i<(A->n); i++) PXs[i] -= PBs[i];
  596. }
  597. #endif
  598. wtime_solve = taucs_wtime() - wtime_solve;
  599. taucs_printf("\tSolve time = % 10.3f seconds\n",wtime_solve);
  600. if (A->flags & TAUCS_DOUBLE)
  601. taucs_vec_ipermute(A->n,A->flags,PXd,NXd,perm);
  602. if (A->flags & TAUCS_SINGLE)
  603. taucs_vec_ipermute(A->n,A->flags,PXs,NXs,perm);
  604. if (A->flags & TAUCS_DCOMPLEX)
  605. taucs_vec_ipermute(A->n,A->flags,PXz,NXz,perm);
  606. } else {
  607. taucs_ooc_solve_lu(oocL, NXd, Bd);
  608. }
  609. /***********************************************************/
  610. /* delete out-of-core matrices */
  611. /***********************************************************/
  612. if (ooc_flag) {
  613. taucs_io_delete(oocL);
  614. }
  615. /***********************************************************/
  616. /* Compute norm of forward error */
  617. /***********************************************************/
  618. if (A->flags & TAUCS_SINGLE) {
  619. float snrm2_();
  620. int one = 1;
  621. NormErr = 0.0;
  622. for(i=0; i<N; i++) NormErr = max(NormErr,fabs((NXs[i]-Xs[i])/Xs[i]));
  623. for(i=0; i<N; i++) PXs[i] = NXs[i]-Xs[i];
  624. taucs_printf("main: max relative error = %1.6e, 2-norm relative error %.2e \n",
  625. NormErr,
  626. snrm2_(&(A->n),PXs,&one)/snrm2_(&(A->n),Xs,&one));
  627. }
  628. if (A->flags & TAUCS_DOUBLE) {
  629. double dnrm2_();
  630. int one = 1;
  631. NormErr = 0.0;
  632. for(i=0; i<N; i++) NormErr = max(NormErr,fabs((NXd[i]-Xd[i])/Xd[i]));
  633. for(i=0; i<N; i++) PXd[i] = NXd[i]-Xd[i];
  634. taucs_printf("main: max relative error = %1.6e, 2-norm relative error %.2e \n",
  635. NormErr,
  636. dnrm2_(&(A->n),PXd,&one)/dnrm2_(&(A->n),Xd,&one));
  637. }
  638. if (A->flags & TAUCS_DCOMPLEX) {
  639. double dznrm2_();
  640. int one = 1;
  641. double* pX = (double*) Xz;
  642. double* pNX = (double*) NXz;
  643. double* pPX = (double*) PXz;
  644. taucs_dcomplex zzero = taucs_zzero_const;
  645. taucs_dcomplex zone = taucs_zone_const;
  646. taucs_dcomplex zmone = taucs_zneg_fn(taucs_zone_const);
  647. NormErr = 0.0;
  648. zscal_(&(A->n),&zzero,pPX,&one);
  649. zaxpy_(&(A->n),&zone ,pNX,&one,pPX,&one);
  650. zaxpy_(&(A->n),&zmone,pX ,&one,pPX,&one);
  651. taucs_printf("main: max relative error = %1.6e, 2-norm relative error %.2e \n",
  652. NormErr,
  653. dznrm2_(&(A->n),PXz,&one)/dznrm2_(&(A->n),Xz,&one));
  654. }
  655. /***********************************************************/
  656. /* Exit */
  657. /***********************************************************/
  658. taucs_printf("main: done\n");
  659. return 0;
  660. }
  661. int iter_main(int argc, char* argv[])
  662. {
  663. double wtime_order;
  664. double wtime_permute;
  665. double wtime_factor;
  666. double wtime_solve;
  667. double wtime_precond_create;
  668. double ctime_factor;
  669. int i,j;
  670. double NormErr;
  671. taucs_ccs_matrix* A;
  672. taucs_ccs_matrix* A_orig = NULL;
  673. taucs_ccs_matrix* PAPT;
  674. taucs_ccs_matrix* L;
  675. taucs_ccs_matrix* V;
  676. taucs_ccs_matrix* PVPT;
  677. double* X = NULL;
  678. double* B = NULL;
  679. double* PX;
  680. double* PB;
  681. double* NX;
  682. double* X_orig;
  683. double* B_orig;
  684. char* ordering = "metis";
  685. char* sg_command = "qqq";
  686. char* mat_type = "neumann";
  687. int* perm;
  688. int* invperm;
  689. int multifrontal_flag = 1;
  690. int modified_flag = 0;
  691. int icc_flag = 0;
  692. int sg_flag = 0;
  693. int vaidya_flag = 0;
  694. int stretch_flag = 0;
  695. int vaidya_icc_flag = 0;
  696. int contx_flag = 0;
  697. int recvaidya_flag = 0;
  698. int mesh2d_flag = 0,mesh2d_negative_flag=0,mesh2d_size = 0;
  699. int trick_flag = 0;
  700. double subgraphs = 1.0;
  701. double droptol = 0.0;
  702. int rnd,force_rnd=0;
  703. int seed = 123;
  704. double C = 0.25; /* constant factor reduction in rec vaidya */
  705. double epsilon=0.2;
  706. int nsmall=10000;
  707. int maxlevels=2;
  708. int innerits=2;
  709. double innerconv=0.01;
  710. double restol = 1e-8;
  711. int maxits = 10000;
  712. int (*precond_fn)(void*,void* x,void* b);
  713. void* precond_args;
  714. /***********************************************************/
  715. /* Read arguments: log file, matrix, memory size, ooc name */
  716. /***********************************************************/
  717. if ((argc == 1) ||((argc == 2) && !strncmp(argv[1],"-h",2)))
  718. usage(argc,argv);
  719. A = NULL;
  720. for (i=1; i<argc; i++) {
  721. if (!strcmp(argv[i],"-nomf")) multifrontal_flag = 0;
  722. if (!strcmp(argv[i],"-trick")) trick_flag = 1;
  723. if (!strcmp(argv[i],"-icc")) icc_flag = 1;
  724. if (!strcmp(argv[i],"-vaidya")) vaidya_flag = 1;
  725. if (!strcmp(argv[i],"-stretch")) stretch_flag = 1;
  726. if (!strcmp(argv[i],"-cont-x")) contx_flag = 1;
  727. if (!strcmp(argv[i],"-vaidya-icc")) vaidya_icc_flag = 1;
  728. if (!strcmp(argv[i],"-recvaidya")) recvaidya_flag = 1;
  729. if (!strcmp(argv[i],"-modified")) {modified_flag = 1;taucs_printf("Factoring will be Modified ICC\n");}
  730. if (!strcmp(argv[i],"-log") && i <= argc-1 ) {
  731. i++;
  732. taucs_logfile(argv[i]);
  733. }
  734. if (!strcmp(argv[i],"-ordering") && i <= argc-1 ) {
  735. i++;
  736. ordering = argv[i];
  737. }
  738. if (!strcmp(argv[i],"-sg") && i <= argc-2 ) {
  739. sg_flag = 1;
  740. i++;
  741. sg_command = argv[i];
  742. }
  743. if (!strcmp(argv[i],"-mat_type") && i <= argc-1 ) {
  744. i++;
  745. mat_type = argv[i];
  746. }
  747. if (!strcmp(argv[i],"-droptol") && i <= argc-1 ) {
  748. i++;
  749. if (sscanf(argv[i],"%lg",&droptol) != 1) {
  750. taucs_printf("main: -droptol must be followed by a real value\n");
  751. exit(1);
  752. }
  753. }
  754. if (!strcmp(argv[i],"-restol") && i <= argc-1 ) {
  755. i++;
  756. if (sscanf(argv[i],"%lg",&restol) != 1) {
  757. taucs_printf("main: -restol must be followed by a real value\n");
  758. exit(1);
  759. }
  760. }
  761. if (!strcmp(argv[i],"-maxits") && i <= argc-1 ) {
  762. i++;
  763. if (sscanf(argv[i],"%d",&maxits) != 1) {
  764. taucs_printf("main: -maxits must be followed by an integer value\n");
  765. exit(1);
  766. }
  767. }
  768. if (!strcmp(argv[i],"-c") && i <= argc-1 ) {
  769. i++;
  770. if (sscanf(argv[i],"%lg",&C) != 1) {
  771. taucs_printf("main: -c must be followed by a real value\n");
  772. exit(1);
  773. }
  774. }
  775. if (!strcmp(argv[i],"-epsilon") && i <= argc-1 ) {
  776. i++;
  777. if (sscanf(argv[i],"%lg",&epsilon) != 1) {
  778. taucs_printf("main: -epsilon must be followed by a real value\n");
  779. exit(1);
  780. }
  781. }
  782. if (!strcmp(argv[i],"-nsmall") && i <= argc-1 ) {
  783. i++;
  784. if (sscanf(argv[i],"%d",&nsmall) != 1) {
  785. taucs_printf("main: -nsmall must be followed by an integer\n");
  786. exit(1);
  787. }
  788. }
  789. if (!strcmp(argv[i],"-maxlevels") && i <= argc-1 ) {
  790. i++;
  791. if (sscanf(argv[i],"%d",&maxlevels) != 1) {
  792. taucs_printf("main: -maxlevels must be followed by an integer\n");
  793. exit(1);
  794. }
  795. }
  796. if (!strcmp(argv[i],"-innerits") && i <= argc-1 ) {
  797. i++;
  798. if (sscanf(argv[i],"%d",&innerits) != 1) {
  799. taucs_printf("main: -innerits must be followed by an integer\n");
  800. exit(1);
  801. }
  802. }
  803. if (!strcmp(argv[i],"-innerconv") && i <= argc-1 ) {
  804. i++;
  805. if (sscanf(argv[i],"%lg",&innerconv) != 1) {
  806. taucs_printf("main: -innerconv must be followed by a real value\n");
  807. exit(1);
  808. }
  809. }
  810. if (!strcmp(argv[i],"-seed") && i <= argc-1 ) {
  811. i++;
  812. if (sscanf(argv[i],"%d",&seed) != 1) {
  813. taucs_printf("main: -seed must be followed by an integer value\n");
  814. exit(1);
  815. }
  816. }
  817. if (!strcmp(argv[i],"-rnd") && i <= argc-1 ) {
  818. i++;
  819. if (sscanf(argv[i],"%d",&force_rnd) != 1) {
  820. taucs_printf("main: -rnd must be followed by an integer value\n");
  821. exit(1);
  822. }
  823. }
  824. if (!strcmp(argv[i],"-subgraphs") && i <= argc-1 ) {
  825. i++;
  826. if (sscanf(argv[i],"%lg",&subgraphs) != 1) {
  827. taucs_printf("main: -subgraphs must be followed by a real value\n");
  828. exit(1);
  829. }
  830. }
  831. if (!strcmp(argv[i],"-hb") && i <= argc-1 ) {
  832. int nrows,ncols,nnz,j;
  833. char fname[256];
  834. char type[3];
  835. i++;
  836. for (j=0; j<256; j++) fname[j] = ' ';
  837. strcpy(fname,argv[i]);
  838. taucs_printf("main: reading HB matrix %s\n",argv[i]);
  839. ireadhb_(fname,type,&nrows,&ncols,&nnz);
  840. A = taucs_dccs_create(nrows,ncols,nnz);
  841. if (type[1] == 's' || type[1] == 'S')
  842. A->flags = TAUCS_SYMMETRIC | TAUCS_LOWER | TAUCS_DOUBLE;
  843. dreadhb_(fname,&nrows,&ncols,&nnz,
  844. A->colptr,A->rowind,((double*)A->values.d));
  845. /* make indices 0-based */
  846. for (j=0; j<=ncols; j++) ((A->colptr)[j])--;
  847. for (j=0; j<nnz; j++) ((A->rowind)[j])--;
  848. taucs_printf("main: done reading\n");
  849. }
  850. if (!strcmp(argv[i],"-n+rhs") && i <= argc-1) {
  851. FILE* f;
  852. int n,j,nnz;
  853. i++;
  854. taucs_printf("main: reading right-hand side %s\n",argv[i]);
  855. f=fopen(argv[i],"r");
  856. assert(f);
  857. fscanf(f,"%d",&n);
  858. B=(double*) malloc(n*sizeof(double));
  859. nnz = 0;
  860. for (j=0; j<n; j++) {
  861. fscanf(f,"%lg",B+j);
  862. if (B[j]) nnz++;
  863. }
  864. fclose(f);
  865. taucs_printf("main: done reading rhs, %d nonzeros\n",nnz);
  866. }
  867. if (!strcmp(argv[i],"-mtx") && i <= argc-1) {
  868. i++;
  869. taucs_printf("main: reading mtx matrix %s\n",argv[i]);
  870. A = taucs_ccs_read_mtx (argv[i],TAUCS_SYMMETRIC);
  871. taucs_printf("main: done reading\n");
  872. }
  873. if (!strcmp(argv[i],"-ijv") && i <= argc-1) {
  874. i++;
  875. taucs_printf("main: reading ijv matrix %s\n",argv[i]);
  876. A = taucs_ccs_read_ijv (argv[i],TAUCS_SYMMETRIC);
  877. taucs_printf("main: done reading\n");
  878. }
  879. if (!strcmp(argv[i],"-ccs") && i <= argc-1) {
  880. i++;
  881. taucs_printf("main: reading ccs matrix %s\n",argv[i]);
  882. A = taucs_ccs_read_ccs (argv[i],TAUCS_SYMMETRIC);
  883. taucs_printf("main: done reading\n");
  884. }
  885. if (!strcmp(argv[i],"-mesh2d") && i <= argc-1) {
  886. mesh2d_flag = 1;
  887. taucs_printf("A is a mesh2d\n");
  888. i++;
  889. if (sscanf(argv[i],"%d",&mesh2d_size) != 1) {
  890. taucs_printf("mesh size (n, where the mesh is n-by-n) must follow -mesh2d argument\n");
  891. exit(1);
  892. }
  893. }
  894. if (!strcmp(argv[i],"-mesh2d_negative") && i <= argc-1) {
  895. mesh2d_negative_flag = 1;
  896. taucs_printf("A is a mesh2d_negative\n");
  897. i++;
  898. if (sscanf(argv[i],"%d",&mesh2d_size) != 1) {
  899. taucs_printf("mesh size (n, where the mesh is n-by-n) must follow -mesh2d_negative argument\n");
  900. exit(1);
  901. }
  902. }
  903. if (!strcmp(argv[i],"-mesh3d") && i <= argc-3) {
  904. int X,Y,Z;
  905. taucs_printf("A is a mesh3d\n");
  906. if (sscanf(argv[i+1],"%d",&X) != 1
  907. || sscanf(argv[i+2],"%d",&Y) != 1
  908. || sscanf(argv[i+3],"%d",&Z) != 1) {
  909. taucs_printf("mesh size (X Y Z must follow -mesh3d argument\n");
  910. exit(1);
  911. }
  912. i += 3;
  913. taucs_printf("main: creating mesh\n");
  914. A = taucs_ccs_generate_mesh3d(X,Y,Z);
  915. }
  916. if (!strcmp(argv[i],"-rrn") && i <= argc-5) {
  917. int X,Y,Z;
  918. double dp, rmin;
  919. if (sscanf(argv[i+1],"%d",&X) != 1
  920. || sscanf(argv[i+2],"%d",&Y) != 1
  921. || sscanf(argv[i+3],"%d",&Z) != 1
  922. || sscanf(argv[i+4],"%lg",&dp) != 1
  923. || sscanf(argv[i+5],"%lg",&rmin) != 1) {
  924. taucs_printf("mesh size (X Y Z dp rmin must follow -rrn argument\n");
  925. exit(1);
  926. }
  927. i += 5;
  928. taucs_printf("main: creating mesh %d\n",Y);
  929. A = taucs_ccs_generate_rrn(X,Y,Z,dp,rmin);
  930. taucs_printf("A is a random resistor network %d-by-%d-by-%d, drop prob=%.2e, rmin=%.2e\n",
  931. X,Y,Z,dp,rmin);
  932. }
  933. if (!strcmp(argv[i],"-discont") && i <= argc-4) {
  934. int x,y,z;
  935. double jump;
  936. if (sscanf(argv[i+1],"%d",&x) != 1
  937. || sscanf(argv[i+2],"%d",&y) != 1
  938. || sscanf(argv[i+3],"%d",&z) != 1
  939. || sscanf(argv[i+4],"%lg",&jump) != 1) {
  940. taucs_printf("mesh size (X Y Z jump must follow -discont argument\n");
  941. exit(1);
  942. }
  943. i += 4;
  944. taucs_printf("main: creating mesh\n",y);
  945. A = taucs_ccs_generate_discontinuous(x,y,z,jump);
  946. taucs_printf("A is a %d-by-%d-by-%d discontinuous Poisson problem, jump=%.2e\n",
  947. x,y,z,jump);
  948. if (contx_flag) {
  949. X = taucs_vec_generate_continuous(x,y,z,"default");
  950. taucs_printf("iter: using continuous solution\n");
  951. }
  952. }
  953. }
  954. srandom(seed);
  955. rnd = random();
  956. if (force_rnd)
  957. rnd = force_rnd;
  958. taucs_printf("Chosen Ordering: %s\n",ordering);
  959. if (mesh2d_flag)
  960. {
  961. taucs_printf("Matrix type is %s\n",mat_type);
  962. taucs_printf("Grid Size is %d\n",mesh2d_size);
  963. A = taucs_ccs_generate_mesh2d(mesh2d_size,mat_type);
  964. }
  965. if (mesh2d_negative_flag)
  966. {
  967. taucs_printf("Grid Size is %d\n",mesh2d_size);
  968. A = taucs_ccs_generate_mesh2d_negative(mesh2d_size);
  969. }
  970. /* A = symccs_read_ijv("/tmp/A.ijv"); */
  971. if (!A) {
  972. taucs_printf("matrix argument not given or matrix file not found\n");
  973. usage(argc,argv);
  974. }
  975. N = A->n;
  976. if (!X) {
  977. X=(double*)malloc(N*sizeof(double));
  978. for(i=0; i<N; i++) X[i]=(double)random()/RAND_MAX;
  979. } else
  980. taucs_printf("iter: not using a random X, already allocated\n");
  981. if (!B) {
  982. B=(double*)malloc(N*sizeof(double));
  983. taucs_ccs_times_vec(A,X,B);
  984. } else {
  985. for(i=0; i<N; i++) X[i]= taucs_get_nan();/*omer 0.0 / 0.0*/;
  986. }
  987. if ((sg_flag)&&(trick_flag==0))
  988. {
  989. for(i=0;i<A->n;i++)
  990. {
  991. for (j=A->colptr[i];j<A->colptr[i+1];j++)
  992. if ((A->rowind[j] != i)&&(((double*)A->values.d)[j]>0))
  993. {
  994. trick_flag = 1;
  995. break;
  996. }
  997. if (trick_flag) break;
  998. }
  999. }
  1000. if (trick_flag) {
  1001. int n;
  1002. int *tmp;
  1003. taucs_printf("Warning: augmenting to ensure nonpositive offdiagonals\n");
  1004. B_orig = B;
  1005. X_orig = X;
  1006. A_orig = A;
  1007. X = (double *)malloc(2*N*sizeof(double));
  1008. for(i=0;i<N;i++) {
  1009. X[i] = X_orig[i];
  1010. X[i+N] = -X_orig[i];
  1011. }
  1012. B = (double *)malloc(2*N*sizeof(double));
  1013. for(i=0;i<N;i++) {
  1014. B[i] = B_orig[i];
  1015. B[i+N] = -B_orig[i];
  1016. }
  1017. #if 1
  1018. {
  1019. taucs_ccs_matrix* A_tmp;
  1020. n=A->n;
  1021. A_tmp = taucs_dccs_create(2*n,2*n,2*(A->colptr[n]));
  1022. A_tmp->flags |= TAUCS_SYMMETRIC | TAUCS_LOWER;
  1023. tmp = (int *)calloc((2*n+1),sizeof(int));
  1024. for(i=0;i<n;i++)
  1025. {
  1026. for(j=A->colptr[i];j<A->colptr[i+1];j++)
  1027. {
  1028. if ((i == A->rowind[j])||(((double*)A->values.d)[j] < 0))
  1029. {
  1030. tmp[i]++;
  1031. tmp[i+n]++;
  1032. }
  1033. else
  1034. {
  1035. /* printf("WWW\n");exit(345); */
  1036. tmp[i]++;
  1037. tmp[A->rowind[j]]++;
  1038. }
  1039. }
  1040. }
  1041. A_tmp->colptr[0]=0;
  1042. for(i=0;i<2*n;i++)
  1043. A_tmp->colptr[i+1] = A_tmp->colptr[i] + tmp[i];
  1044. for(i=0;i<2*n;i++)
  1045. tmp[i] = A_tmp->colptr[i];
  1046. /* for(i=0;i<n;i++) */
  1047. /* printf("ZZZ %d %d\n",tmp[i],tmp[i+n]); */
  1048. /* exit(345); */
  1049. for(i=0;i<n;i++)
  1050. {
  1051. for(j=A->colptr[i];j<A->colptr[i+1];j++)
  1052. {
  1053. if ((i == A->rowind[j])||(((double*)A->values.d)[j] < 0))
  1054. {
  1055. A_tmp->rowind[tmp[i]]=A->rowind[j];
  1056. ((double*)A_tmp->values.d)[tmp[i]++]=((double*)A->values.d)[j];
  1057. A_tmp->rowind[tmp[i+n]]=A->rowind[j]+n;
  1058. ((double*)A_tmp->values.d)[tmp[i+n]++]=((double*)A->values.d)[j];
  1059. }
  1060. else
  1061. {
  1062. /* printf("WWW\n");exit(345); */
  1063. A_tmp->rowind[tmp[i]]=A->rowind[j]+n;
  1064. ((double*)A_tmp->values.d)[tmp[i]++]=-((double*)A->values.d)[j];
  1065. A_tmp->rowind[tmp[A->rowind[j]]]=i+n;
  1066. ((double*)A_tmp->values.d)[tmp[A->rowind[j]]++]=-((double*)A->values.d)[j];
  1067. }
  1068. }
  1069. }
  1070. /*
  1071. taucs_ccs_write_ijv(A,"A.ijv");
  1072. taucs_ccs_write_ijv(A_tmp,"Aaug.ijv");
  1073. */
  1074. free(tmp);
  1075. taucs_ccs_free(A);
  1076. A = A_tmp;
  1077. }
  1078. #else
  1079. A = taucs_ccs_augment_nonpositive_offdiagonals(A_orig);
  1080. #endif
  1081. }
  1082. N = M = A->n;
  1083. /***********************************************************/
  1084. /* Create exact solution, compute right-hand-side */
  1085. /***********************************************************/
  1086. NX=(double*)malloc(N*sizeof(double));
  1087. PX=(double*)malloc(N*sizeof(double));
  1088. PB=(double*)malloc(N*sizeof(double));
  1089. /***********************************************************/
  1090. /* Compute column ordering */
  1091. /***********************************************************/
  1092. /***********************************************************/
  1093. /* factor */
  1094. /***********************************************************/
  1095. if (icc_flag) {
  1096. int n;
  1097. double unit,curr;
  1098. n = A->n;
  1099. unit = (n-1.)+n;
  1100. taucs_printf("main: using incomplete Cholesky droptol=%lg modified=%d\n",
  1101. droptol,modified_flag);
  1102. wtime_order = taucs_wtime();
  1103. taucs_ccs_order(A,&perm,&invperm,ordering);
  1104. wtime_order = taucs_wtime() - wtime_order;
  1105. taucs_printf("\tOrdering time = % 10.3f seconds\n",wtime_order);
  1106. wtime_permute = taucs_wtime();
  1107. PAPT = taucs_ccs_permute_symmetrically(A,perm,invperm);
  1108. wtime_permute = taucs_wtime() - wtime_permute;
  1109. taucs_printf("\tPermute time = % 10.3f seconds\n",wtime_permute);
  1110. wtime_factor = taucs_wtime();
  1111. ctime_factor = taucs_ctime();
  1112. L = taucs_ccs_factor_llt(PAPT,droptol,modified_flag);
  1113. /* taucs_ccs_write_ijv(PAPT,"PAPT.ijv"); */
  1114. /* taucs_ccs_write_ijv(L,"L.ijv"); */
  1115. wtime_factor = taucs_wtime() - wtime_factor;
  1116. ctime_factor = taucs_ctime() - ctime_factor;
  1117. taucs_printf("\tFactor time = % 10.3f seconds ",wtime_factor);
  1118. taucs_printf("(%.3f cpu time)\n",ctime_factor);
  1119. curr = L->colptr[n];
  1120. taucs_printf("droptol = %1.20lf curr = %lf curr_ratio = %lf\n",droptol,curr,curr/unit);
  1121. precond_args = L;
  1122. precond_fn = taucs_ccs_solve_llt;
  1123. } else if (vaidya_flag) {
  1124. int n;
  1125. double unit,curr;
  1126. /*
  1127. int taucs_supernodal_solve_llt(void*,
  1128. double*, double*);
  1129. */
  1130. n = A->n;
  1131. unit = (n-1.)+n;
  1132. taucs_printf("main: using Vaidya # subgraphs requested=%lf\n",subgraphs);
  1133. taucs_printf("Chosen rnd: %d\n",rnd);
  1134. wtime_precond_create = taucs_wtime();
  1135. #if 1
  1136. V = taucs_amwb_preconditioner_create(A,
  1137. rnd /* random seed */,
  1138. subgraphs,
  1139. stretch_flag);
  1140. #else
  1141. V = taucs_amst_preconditioner_create(A,
  1142. rnd /* random seed */,
  1143. subgraphs);
  1144. #endif
  1145. /* taucs_ccs_write_ijv(A,"A.ijv"); */
  1146. /* taucs_ccs_write_ijv(V,"V.ijv"); */
  1147. wtime_precond_create = taucs_wtime() - wtime_precond_create;
  1148. taucs_printf("\tCreation time = % 10.3f seconds\n",wtime_precond_create);
  1149. wtime_order = taucs_wtime();
  1150. taucs_ccs_order(V,&perm,&invperm,ordering);
  1151. wtime_order = taucs_wtime() - wtime_order;
  1152. taucs_printf("\tOrdering time = % 10.3f seconds\n",wtime_order);
  1153. wtime_permute = taucs_wtime();
  1154. PAPT = taucs_ccs_permute_symmetrically(A,perm,invperm);
  1155. PVPT = taucs_ccs_permute_symmetrically(V,perm,invperm);
  1156. wtime_permute = taucs_wtime() - wtime_permute;
  1157. taucs_printf("\tPermute time = % 10.3f seconds\n",wtime_permute);
  1158. taucs_ccs_free(V);
  1159. wtime_factor = taucs_wtime();
  1160. if (multifrontal_flag) {
  1161. void* snL;
  1162. snL = taucs_ccs_factor_llt_mf(PVPT);
  1163. #if 1
  1164. L = taucs_supernodal_factor_to_ccs(snL);
  1165. taucs_supernodal_factor_free(snL);
  1166. precond_args = L;
  1167. precond_fn = taucs_ccs_solve_llt;
  1168. #else
  1169. L = snL;
  1170. precond_args = L;
  1171. precond_fn = taucs_supernodal_solve_llt;
  1172. #endif
  1173. } else {
  1174. L = taucs_ccs_factor_llt(PVPT,0.0,0);
  1175. precond_args = L;
  1176. precond_fn = taucs_ccs_solve_llt;
  1177. curr = L->colptr[n];
  1178. taucs_printf("subgraphs = %6.15lf curr = %lf curr_ratio = %lf\n",subgraphs,curr,curr/unit);fflush(stdout);
  1179. }
  1180. wtime_factor = taucs_wtime() - wtime_factor;
  1181. taucs_printf("\tFactor time = % 10.3f seconds\n",wtime_factor);
  1182. taucs_ccs_free(PVPT);
  1183. ((taucs_ccs_matrix *)precond_args)->flags |= TAUCS_DOUBLE;
  1184. } else if (recvaidya_flag) {
  1185. wtime_precond_create = taucs_wtime();
  1186. precond_args = taucs_recursive_amwb_preconditioner_create(A,
  1187. C,
  1188. epsilon,
  1189. nsmall,
  1190. maxlevels,
  1191. innerits,
  1192. innerconv,
  1193. &perm,&invperm);
  1194. precond_fn = taucs_recursive_amwb_preconditioner_solve;
  1195. wtime_precond_create = taucs_wtime() - wtime_precond_create;
  1196. taucs_printf("\tCreation time = % 10.3f seconds\n",wtime_precond_create);
  1197. wtime_permute = taucs_wtime();
  1198. PAPT = taucs_ccs_permute_symmetrically(A,perm,invperm);
  1199. wtime_permute = taucs_wtime() - wtime_permute;
  1200. taucs_printf("\tOrdering time = % 10.3f seconds\n",wtime_permute);
  1201. }
  1202. #ifdef SIVAN_5_DEC_2002_XXX
  1203. else if (sg_flag) {
  1204. int
  1205. taucs_sg_preconditioner_solve(void* vP,
  1206. double* Z,
  1207. double* R);
  1208. wtime_precond_create = taucs_wtime();
  1209. /* precond_args = taucs_multilevel_preconditioner_create(A, */
  1210. /* subgraphs, */
  1211. /* &perm,&invperm); */
  1212. precond_args = taucs_sg_preconditioner_create(A,&perm,&invperm,
  1213. ordering,sg_command);
  1214. if (!precond_args)
  1215. {
  1216. printf("Creating the preconditioner failed. Exiting.\n");
  1217. exit(345);
  1218. }
  1219. precond_fn = taucs_sg_preconditioner_solve;
  1220. wtime_precond_create = taucs_wtime() - wtime_precond_create;
  1221. taucs_printf("\tCreation time = % 10.3f seconds\n",wtime_precond_create);
  1222. wtime_permute = taucs_wtime();
  1223. PAPT = taucs_ccs_permute_symmetrically(A,perm,invperm);
  1224. wtime_permute = taucs_wtime() - wtime_permute;
  1225. taucs_printf("\tOrdering time = % 10.3f seconds\n",wtime_permute);
  1226. }
  1227. #endif
  1228. else {
  1229. precond_args = NULL;
  1230. precond_fn = NULL;
  1231. taucs_ccs_order(A,&perm,&invperm,"identity");
  1232. PAPT = A;
  1233. }
  1234. /*taucs_ccs_write_ijv(PAPT,"A.ijv",1);*/ /* 1 = complete the upper part */
  1235. /*taucs_ccs_write_ijv(L,"L.ijv",0);*/
  1236. /***********************************************************/
  1237. /* solve */
  1238. /***********************************************************/
  1239. for (i=0; i<A->n; i++) PB[i] = B[perm[i]];
  1240. for (i=0; i<A->n; i++) PX[i] = 0.0; /* initial guess */
  1241. wtime_solve = taucs_wtime();
  1242. #if 1
  1243. if (vaidya_icc_flag && vaidya_flag) {
  1244. taucs_ccs_matrix* L;
  1245. double* R;
  1246. double init_residual_reduction;
  1247. wtime_factor = taucs_wtime();
  1248. ctime_factor = taucs_ctime();
  1249. L = taucs_ccs_factor_llt(PAPT,1.0,0); /* unmodified ICC(0) */
  1250. wtime_factor = taucs_wtime() - wtime_factor;
  1251. ctime_factor = taucs_ctime() - ctime_factor;
  1252. taucs_printf("\tFactor time = % 10.3f seconds ",wtime_factor);
  1253. taucs_printf("(%.3f cpu time)\n",ctime_factor);
  1254. taucs_conjugate_gradients (PAPT,
  1255. taucs_ccs_solve_llt, L,
  1256. PX, PB,
  1257. 25, 1e-15);
  1258. R = (double*) malloc(A->n * sizeof(double));
  1259. taucs_ccs_times_vec(PAPT,PX,R);
  1260. for (i=0; i<A->n; i++) R[i] = PB[i] - R[i];
  1261. init_residual_reduction = twonorm(A->n,R)/twonorm(A->n,B);
  1262. taucs_printf("reduction by a factor of %.2e so far\n",init_residual_reduction);
  1263. free(R);
  1264. taucs_conjugate_gradients (PAPT,
  1265. precond_fn, precond_args,
  1266. PX, PB,
  1267. 10000, 1e-15 / init_residual_reduction);
  1268. } else
  1269. {
  1270. taucs_conjugate_gradients (PAPT,
  1271. precond_fn, precond_args,
  1272. PX, PB,
  1273. maxits, restol);
  1274. }
  1275. #else
  1276. precond_fn(precond_args,PX,PB); /* direct solver */
  1277. #endif
  1278. wtime_solve = taucs_wtime() - wtime_solve;
  1279. taucs_printf("\tSolve time = % 10.3f seconds\n",wtime_solve);
  1280. for (i=0; i<A->n; i++) NX[i] = PX[invperm[i]];
  1281. /***********************************************************/
  1282. /* delete out-of-core matrices */
  1283. /***********************************************************/
  1284. /***********************************************************/
  1285. /* extract solution from augmented system */
  1286. /***********************************************************/
  1287. if (0 && A_orig) {
  1288. /*
  1289. the first half of the elements of NX contains the
  1290. solution of the original system
  1291. */
  1292. taucs_ccs_free(A);
  1293. A = A_orig;
  1294. free(X);
  1295. X = X_orig;
  1296. free(B);
  1297. B = B_orig;
  1298. N = M = A->n;
  1299. }
  1300. /***********************************************************/
  1301. /* Compute norm of forward error */
  1302. /***********************************************************/
  1303. NormErr = 0.0;
  1304. for(i=0; i<N; i++) NormErr = max(NormErr,fabs((NX[i]-X[i])/X[i]));
  1305. taucs_printf("main: max relative error = %1.6e \n",NormErr);
  1306. for(i=0; i<N; i++) B[i] = NX[i]-X[i];
  1307. taucs_printf("main: ||computed X - X||/||X||=%.2e\n",twonorm(N,B)/twonorm(N,X));
  1308. /* for(i=0; i<N; i++) */
  1309. /* printf("QQQ %i %lf\n",i,NX[i]); */
  1310. /***********************************************************/
  1311. /* Exit */
  1312. /***********************************************************/
  1313. taucs_printf("main: done\n");
  1314. return 0;
  1315. }