1 /* testFactor.c */
2
3 #include "../FrontMtx.h"
4 #include "../../Drand.h"
5 #include "../../SymbFac.h"
6 #include "../../timings.h"
7 #include "../../misc.h"
8
9 /*--------------------------------------------------------------------*/
10
11 int
main(int argc,char * argv[])12 main ( int argc, char *argv[] )
13 /*
14 -----------------------------------------------------
15 test the factor method for a grid matrix
16 (1) read in an InpMtx object
17 (2) read in an ETree object
18 (3) create a solution matrix object
19 (4) multiply the solution with the matrix
20 to get a right hand side matrix object
21 (5) factor the matrix
22 (6) solve the system
23
24 created -- 98sep05, cca
25 -----------------------------------------------------
26 */
27 {
28 char *etreeFileName, *mtxFileName ;
29 Chv *chv, *rootchv ;
30 ChvManager *chvmanager ;
31 DenseMtx *mtxB, *mtxX, *mtxZ ;
32 double one[2] = { 1.0, 0.0 } ;
33 FrontMtx *frontmtx ;
34 InpMtx *mtxA ;
35 SubMtxManager *mtxmanager ;
36 double cputotal, droptol, factorops ;
37 double cpus[9] ;
38 Drand drand ;
39 double nops, tau, t1, t2 ;
40 ETree *frontETree ;
41 FILE *msgFile ;
42 int error, loc, lockflag, msglvl, neqns, nrhs, nzf,
43 pivotingflag, rc, seed, sparsityflag, symmetryflag,
44 type ;
45 int stats[6] ;
46 IV *newToOldIV, *oldToNewIV ;
47 IVL *symbfacIVL ;
48
49 if ( argc != 13 ) {
50 fprintf(stdout,
51 "\n\n usage : %s msglvl msgFile mtxFile etreeFile"
52 "\n seed symmetryflag sparsityflag "
53 "\n pivotingflag tau droptol lockflag nrhs"
54 "\n msglvl -- message level"
55 "\n msgFile -- message file"
56 "\n mtxFile -- file to read in InpMtx matrix object"
57 "\n etreeFile -- file to read in ETree front tree object"
58 "\n seed -- random number seed"
59 "\n symmetryflag -- symmetry flag"
60 "\n 0 --> symmetric "
61 "\n 1 --> hermitian"
62 "\n 2 --> nonsymmetric"
63 "\n sparsityflag -- sparsity flag"
64 "\n 0 --> store dense fronts"
65 "\n 1 --> store sparse fronts, use droptol to drop entries"
66 "\n pivotingflag -- pivoting flag"
67 "\n 0 --> do not pivot"
68 "\n 1 --> enable pivoting"
69 "\n tau -- upper bound on factor entries"
70 "\n used only with pivoting"
71 "\n droptol -- lower bound on factor entries"
72 "\n used only with sparse fronts"
73 "\n lockflag -- flag to specify lock status"
74 "\n 0 --> mutex lock is not allocated or initialized"
75 "\n 1 --> mutex lock is allocated and it can synchronize"
76 "\n only threads in this process."
77 "\n 2 --> mutex lock is allocated and it can synchronize"
78 "\n only threads in this and other processes."
79 "\n nrhs -- # of right hand sides"
80 "\n", argv[0]) ;
81 return(-1) ;
82 }
83 msglvl = atoi(argv[1]) ;
84 if ( strcmp(argv[2], "stdout") == 0 ) {
85 msgFile = stdout ;
86 } else if ( (msgFile = fopen(argv[2], "a")) == NULL ) {
87 fprintf(stderr, "\n fatal error in %s"
88 "\n unable to open file %s\n",
89 argv[0], argv[2]) ;
90 return(-1) ;
91 }
92 mtxFileName = argv[3] ;
93 etreeFileName = argv[4] ;
94 seed = atoi(argv[5]) ;
95 symmetryflag = atoi(argv[6]) ;
96 sparsityflag = atoi(argv[7]) ;
97 pivotingflag = atoi(argv[8]) ;
98 tau = atof(argv[9]) ;
99 droptol = atof(argv[10]) ;
100 lockflag = atoi(argv[11]) ;
101 nrhs = atoi(argv[12]) ;
102 fprintf(msgFile,
103 "\n %s "
104 "\n msglvl -- %d"
105 "\n msgFile -- %s"
106 "\n mtxFileName -- %s"
107 "\n etreeFileName -- %s"
108 "\n seed -- %d"
109 "\n symmetryflag -- %d"
110 "\n sparsityflag -- %d"
111 "\n pivotingflag -- %d"
112 "\n tau -- %e"
113 "\n droptol -- %e"
114 "\n lockflag -- %d"
115 "\n nrhs -- %d"
116 "\n",
117 argv[0], msglvl, argv[2], mtxFileName, etreeFileName,
118 seed, symmetryflag, sparsityflag, pivotingflag,
119 tau, droptol, lockflag, nrhs) ;
120 fflush(msgFile) ;
121 /*
122 --------------------------------------
123 initialize the random number generator
124 --------------------------------------
125 */
126 Drand_setDefaultFields(&drand) ;
127 Drand_init(&drand) ;
128 Drand_setSeed(&drand, seed) ;
129 /*
130 Drand_setUniform(&drand, 0.0, 1.0) ;
131 */
132 Drand_setNormal(&drand, 0.0, 1.0) ;
133 /*
134 -------------------------
135 read in the InpMtx object
136 -------------------------
137 */
138 if ( strcmp(mtxFileName, "none") == 0 ) {
139 fprintf(msgFile, "\n no file to read from") ;
140 exit(0) ;
141 }
142 mtxA = InpMtx_new() ;
143 MARKTIME(t1) ;
144 rc = InpMtx_readFromFile(mtxA, mtxFileName) ;
145 MARKTIME(t2) ;
146 fprintf(msgFile, "\n CPU %8.3f : read in mtxA from file %s",
147 t2 - t1, mtxFileName) ;
148 if ( rc != 1 ) {
149 fprintf(msgFile,
150 "\n return value %d from InpMtx_readFromFile(%p,%s)",
151 rc, mtxA, mtxFileName) ;
152 exit(-1) ;
153 }
154 type = mtxA->inputMode ;
155 neqns = 1 + IVmax(mtxA->nent, InpMtx_ivec1(mtxA), &loc) ;
156 if ( INPMTX_IS_BY_ROWS(mtxA) ) {
157 fprintf(msgFile, "\n matrix coordinate type is rows") ;
158 } else if ( INPMTX_IS_BY_COLUMNS(mtxA) ) {
159 fprintf(msgFile, "\n matrix coordinate type is columns") ;
160 } else if ( INPMTX_IS_BY_CHEVRONS(mtxA) ) {
161 fprintf(msgFile, "\n matrix coordinate type is chevrons") ;
162 } else {
163 fprintf(msgFile, "\n\n, error, bad coordinate type") ;
164 exit(-1) ;
165 }
166 if ( INPMTX_IS_RAW_DATA(mtxA) ) {
167 fprintf(msgFile, "\n matrix storage mode is raw data\n") ;
168 } else if ( INPMTX_IS_SORTED(mtxA) ) {
169 fprintf(msgFile, "\n matrix storage mode is sorted\n") ;
170 } else if ( INPMTX_IS_BY_VECTORS(mtxA) ) {
171 fprintf(msgFile, "\n matrix storage mode is by vectors\n") ;
172 } else {
173 fprintf(msgFile, "\n\n, error, bad storage mode") ;
174 exit(-1) ;
175 }
176 {
177 int maxcol, maxrow, mincol, minrow ;
178 InpMtx_range(mtxA, &mincol, &maxcol, &minrow, &maxrow) ;
179 fprintf(msgFile, "\n range of entries = [%d, %d] x [%d,%d]",
180 minrow, maxrow, mincol, maxcol) ;
181 }
182 /*
183 {
184 int nent = InpMtx_nent(mtxA) ;
185 double *dvec = InpMtx_dvec(mtxA) ;
186 Drand *drand ;
187
188 drand = Drand_new() ;
189 Drand_setUniform(drand, 0., 1.) ;
190 Drand_fillDvector(drand, nent, dvec) ;
191 }
192 */
193 if ( msglvl > 1 ) {
194 fprintf(msgFile, "\n\n after reading InpMtx object from file %s",
195 mtxFileName) ;
196 if ( msglvl == 2 ) {
197 InpMtx_writeStats(mtxA, msgFile) ;
198 } else {
199 InpMtx_writeForHumanEye(mtxA, msgFile) ;
200 }
201 fflush(msgFile) ;
202 }
203 /*
204 --------------------------------------------------------
205 generate the linear system
206 1. generate solution matrix and fill with random numbers
207 2. generate rhs matrix and fill with zeros
208 3. compute matrix-matrix multiply
209 --------------------------------------------------------
210 */
211 MARKTIME(t1) ;
212 mtxX = DenseMtx_new() ;
213 DenseMtx_init(mtxX, type, 0, -1, neqns, nrhs, 1, neqns) ;
214 DenseMtx_fillRandomEntries(mtxX, &drand) ;
215 mtxB = DenseMtx_new() ;
216 DenseMtx_init(mtxB, type, 1, -1, neqns, nrhs, 1, neqns) ;
217 DenseMtx_zero(mtxB) ;
218 fprintf(msgFile, "\n B and X initialized") ;
219 fflush(msgFile) ;
220 switch ( symmetryflag ) {
221 case SPOOLES_SYMMETRIC :
222 InpMtx_sym_mmm(mtxA, mtxB, one, mtxX) ;
223 break ;
224 case SPOOLES_HERMITIAN :
225 InpMtx_herm_mmm(mtxA, mtxB, one, mtxX) ;
226 break ;
227 case SPOOLES_NONSYMMETRIC :
228 InpMtx_nonsym_mmm(mtxA, mtxB, one, mtxX) ;
229 break ;
230 default :
231 break ;
232 }
233 fprintf(msgFile, "\n mvm done") ;
234 fflush(msgFile) ;
235 MARKTIME(t2) ;
236 fprintf(msgFile, "\n CPU %8.3f : set up the solution and rhs ",
237 t2 - t1) ;
238 if ( msglvl > 2 ) {
239 fprintf(msgFile, "\n\n original mtxX") ;
240 DenseMtx_writeForHumanEye(mtxX, msgFile) ;
241 fprintf(msgFile, "\n\n original mtxB") ;
242 DenseMtx_writeForHumanEye(mtxB, msgFile) ;
243 fflush(msgFile) ;
244 }
245 DenseMtx_writeToFile(mtxB, "rhs.densemtxb") ;
246 /*
247 InpMtx_writeForMatlab(mtxA, "A", msgFile) ;
248 DenseMtx_writeForMatlab(mtxX, "X", msgFile) ;
249 DenseMtx_writeForMatlab(mtxB, "B", msgFile) ;
250 */
251 /*
252 ------------------------
253 read in the ETree object
254 ------------------------
255 */
256 if ( strcmp(etreeFileName, "none") == 0 ) {
257 fprintf(msgFile, "\n no file to read from") ;
258 exit(0) ;
259 }
260 frontETree = ETree_new() ;
261 MARKTIME(t1) ;
262 rc = ETree_readFromFile(frontETree, etreeFileName) ;
263 MARKTIME(t2) ;
264 fprintf(msgFile, "\n CPU %8.3f : read in frontETree from file %s",
265 t2 - t1, etreeFileName) ;
266 if ( rc != 1 ) {
267 fprintf(msgFile, "\n return value %d from ETree_readFromFile(%p,%s)",
268 rc, frontETree, etreeFileName) ;
269 exit(-1) ;
270 }
271 ETree_leftJustify(frontETree) ;
272 if ( msglvl > 1 ) {
273 fprintf(msgFile, "\n\n after reading ETree object from file %s",
274 etreeFileName) ;
275 if ( msglvl == 2 ) {
276 ETree_writeStats(frontETree, msgFile) ;
277 } else {
278 ETree_writeForHumanEye(frontETree, msgFile) ;
279 }
280 }
281 fflush(msgFile) ;
282 /*
283 --------------------------------------------------
284 get the permutations, permute the matrix and the
285 front tree, and compute the symbolic factorization
286 --------------------------------------------------
287 */
288 MARKTIME(t1) ;
289 oldToNewIV = ETree_oldToNewVtxPerm(frontETree) ;
290 newToOldIV = ETree_newToOldVtxPerm(frontETree) ;
291 MARKTIME(t2) ;
292 fprintf(msgFile, "\n CPU %8.3f : get permutations", t2 - t1) ;
293 MARKTIME(t1) ;
294 ETree_permuteVertices(frontETree, oldToNewIV) ;
295 MARKTIME(t2) ;
296 fprintf(msgFile, "\n CPU %8.3f : permute front tree", t2 - t1) ;
297 MARKTIME(t1) ;
298 InpMtx_permute(mtxA, IV_entries(oldToNewIV), IV_entries(oldToNewIV)) ;
299 MARKTIME(t2) ;
300 fprintf(msgFile, "\n CPU %8.3f : permute mtxA", t2 - t1) ;
301 if ( symmetryflag == SPOOLES_SYMMETRIC
302 || symmetryflag == SPOOLES_HERMITIAN ) {
303 MARKTIME(t1) ;
304 InpMtx_mapToUpperTriangle(mtxA) ;
305 MARKTIME(t2) ;
306 fprintf(msgFile, "\n CPU %8.3f : map to upper triangle", t2 - t1) ;
307 }
308 if ( ! INPMTX_IS_BY_CHEVRONS(mtxA) ) {
309 MARKTIME(t1) ;
310 InpMtx_changeCoordType(mtxA, INPMTX_BY_CHEVRONS) ;
311 MARKTIME(t2) ;
312 fprintf(msgFile, "\n CPU %8.3f : change coordinate type", t2 - t1) ;
313 }
314 if ( INPMTX_IS_RAW_DATA(mtxA) ) {
315 MARKTIME(t1) ;
316 InpMtx_changeStorageMode(mtxA, INPMTX_SORTED) ;
317 MARKTIME(t2) ;
318 fprintf(msgFile, "\n CPU %8.3f : sort entries ", t2 - t1) ;
319 }
320 if ( INPMTX_IS_SORTED(mtxA) ) {
321 MARKTIME(t1) ;
322 InpMtx_changeStorageMode(mtxA, INPMTX_BY_VECTORS) ;
323 MARKTIME(t2) ;
324 fprintf(msgFile, "\n CPU %8.3f : convert to vectors ", t2 - t1) ;
325 }
326 MARKTIME(t1) ;
327 symbfacIVL = SymbFac_initFromInpMtx(frontETree, mtxA) ;
328 MARKTIME(t2) ;
329 fprintf(msgFile, "\n CPU %8.3f : symbolic factorization", t2 - t1) ;
330 MARKTIME(t1) ;
331 DenseMtx_permuteRows(mtxB, oldToNewIV) ;
332 MARKTIME(t2) ;
333 fprintf(msgFile, "\n CPU %8.3f : permute rhs", t2 - t1) ;
334 /*
335 DenseMtx_writeForMatlab(mtxB, "Bhat", msgFile) ;
336 */
337 /*
338 ------------------------------
339 initialize the FrontMtx object
340 ------------------------------
341 */
342 MARKTIME(t1) ;
343 frontmtx = FrontMtx_new() ;
344 mtxmanager = SubMtxManager_new() ;
345 SubMtxManager_init(mtxmanager, lockflag, 0) ;
346 FrontMtx_init(frontmtx, frontETree, symbfacIVL,
347 type, symmetryflag, sparsityflag, pivotingflag,
348 lockflag, 0, NULL, mtxmanager, msglvl, msgFile) ;
349 MARKTIME(t2) ;
350 fprintf(msgFile, "\n\n CPU %8.3f : initialize the front matrix",
351 t2 - t1) ;
352 if ( msglvl > 1 ) {
353 fprintf(msgFile,
354 "\n nendD = %d, nentL = %d, nentU = %d",
355 frontmtx->nentD, frontmtx->nentL, frontmtx->nentU) ;
356 }
357 if ( msglvl > 2 ) {
358 fprintf(msgFile, "\n front matrix initialized") ;
359 FrontMtx_writeForHumanEye(frontmtx, msgFile) ;
360 fflush(msgFile) ;
361 }
362 SubMtxManager_writeForHumanEye(mtxmanager, msgFile) ;
363 /*
364 -----------------
365 factor the matrix
366 -----------------
367 */
368 nzf = ETree_nFactorEntries(frontETree, symmetryflag) ;
369 factorops = ETree_nFactorOps(frontETree, type, symmetryflag) ;
370 fprintf(msgFile,
371 "\n %d factor entries, %.0f factor ops, %8.3f ratio",
372 nzf, factorops, factorops/nzf) ;
373 IVzero(6, stats) ;
374 DVzero(9, cpus) ;
375 chvmanager = ChvManager_new() ;
376 ChvManager_init(chvmanager, lockflag, 1) ;
377 MARKTIME(t1) ;
378 rootchv = FrontMtx_factorInpMtx(frontmtx, mtxA, tau, droptol,
379 chvmanager, &error, cpus,
380 stats, msglvl, msgFile) ;
381 MARKTIME(t2) ;
382 fprintf(msgFile, "\n\n CPU %8.3f : factor matrix, %8.3f mflops",
383 t2 - t1, 1.e-6*factorops/(t2-t1)) ;
384 if ( rootchv != NULL ) {
385 fprintf(msgFile, "\n\n factorization did not complete") ;
386 for ( chv = rootchv ; chv != NULL ; chv = chv->next ) {
387 fprintf(stdout, "\n chv %d, nD = %d, nL = %d, nU = %d",
388 chv->id, chv->nD, chv->nL, chv->nU) ;
389 }
390 }
391 if ( error >= 0 ) {
392 fprintf(msgFile, "\n\n error encountered at front %d\n", error) ;
393 exit(-1) ;
394 }
395 fprintf(msgFile,
396 "\n %8d pivots, %8d pivot tests, %8d delayed rows and columns",
397 stats[0], stats[1], stats[2]) ;
398 if ( frontmtx->rowadjIVL != NULL ) {
399 fprintf(msgFile,
400 "\n %d entries in rowadjIVL", frontmtx->rowadjIVL->tsize) ;
401 }
402 if ( frontmtx->coladjIVL != NULL ) {
403 fprintf(msgFile,
404 ", %d entries in coladjIVL", frontmtx->coladjIVL->tsize) ;
405 }
406 if ( frontmtx->upperblockIVL != NULL ) {
407 fprintf(msgFile,
408 "\n %d fronts, %d entries in upperblockIVL",
409 frontmtx->nfront, frontmtx->upperblockIVL->tsize) ;
410 }
411 if ( frontmtx->lowerblockIVL != NULL ) {
412 fprintf(msgFile,
413 ", %d entries in lowerblockIVL",
414 frontmtx->lowerblockIVL->tsize) ;
415 }
416 fprintf(msgFile,
417 "\n %d entries in D, %d entries in L, %d entries in U",
418 stats[3], stats[4], stats[5]) ;
419 fprintf(msgFile, "\n %d locks", frontmtx->nlocks) ;
420 if ( FRONTMTX_IS_SYMMETRIC(frontmtx)
421 || FRONTMTX_IS_HERMITIAN(frontmtx) ) {
422 int nneg, npos, nzero ;
423
424 FrontMtx_inertia(frontmtx, &nneg, &nzero, &npos) ;
425 fprintf(msgFile,
426 "\n %d negative, %d zero and %d positive eigenvalues",
427 nneg, nzero, npos) ;
428 fflush(msgFile) ;
429 }
430 cputotal = cpus[8] ;
431 if ( cputotal > 0.0 ) {
432 fprintf(msgFile,
433 "\n initialize fronts %8.3f %6.2f"
434 "\n load original entries %8.3f %6.2f"
435 "\n update fronts %8.3f %6.2f"
436 "\n assemble postponed data %8.3f %6.2f"
437 "\n factor fronts %8.3f %6.2f"
438 "\n extract postponed data %8.3f %6.2f"
439 "\n store factor entries %8.3f %6.2f"
440 "\n miscellaneous %8.3f %6.2f"
441 "\n total time %8.3f",
442 cpus[0], 100.*cpus[0]/cputotal,
443 cpus[1], 100.*cpus[1]/cputotal,
444 cpus[2], 100.*cpus[2]/cputotal,
445 cpus[3], 100.*cpus[3]/cputotal,
446 cpus[4], 100.*cpus[4]/cputotal,
447 cpus[5], 100.*cpus[5]/cputotal,
448 cpus[6], 100.*cpus[6]/cputotal,
449 cpus[7], 100.*cpus[7]/cputotal, cputotal) ;
450 }
451 SubMtxManager_writeForHumanEye(mtxmanager, msgFile) ;
452 ChvManager_writeForHumanEye(chvmanager, msgFile) ;
453 if ( msglvl > 2 ) {
454 fprintf(msgFile, "\n\n front factor matrix") ;
455 FrontMtx_writeForHumanEye(frontmtx, msgFile) ;
456 }
457 /*
458 fprintf(msgFile, "\n L = eye(%d,%d) ;", neqns, neqns) ;
459 fprintf(msgFile, "\n U = eye(%d,%d) ;", neqns, neqns) ;
460 fprintf(msgFile, "\n D = zeros(%d,%d) ;", neqns, neqns) ;
461 FrontMtx_writeForMatlab(frontmtx, "L", "D", "U", msgFile) ;
462 */
463 /*
464 ------------------------------
465 post-process the factor matrix
466 ------------------------------
467 */
468 MARKTIME(t1) ;
469 FrontMtx_postProcess(frontmtx, msglvl, msgFile) ;
470 MARKTIME(t2) ;
471 fprintf(msgFile, "\n\n CPU %8.3f : post-process the matrix", t2 - t1) ;
472 if ( msglvl > 2 ) {
473 fprintf(msgFile, "\n\n front factor matrix after post-processing") ;
474 FrontMtx_writeForHumanEye(frontmtx, msgFile) ;
475 }
476 fprintf(msgFile, "\n\n after post-processing") ;
477 SubMtxManager_writeForHumanEye(frontmtx->manager, msgFile) ;
478 /*
479 ----------------
480 solve the system
481 ----------------
482 */
483 neqns = mtxB->nrow ;
484 nrhs = mtxB->ncol ;
485 mtxZ = DenseMtx_new() ;
486 DenseMtx_init(mtxZ, type, 0, 0, neqns, nrhs, 1, neqns) ;
487 DenseMtx_zero(mtxZ) ;
488 if ( type == SPOOLES_REAL ) {
489 nops = frontmtx->nentD + 2*frontmtx->nentU ;
490 if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
491 nops += 2*frontmtx->nentL ;
492 } else {
493 nops += 2*frontmtx->nentU ;
494 }
495 } else if ( type == SPOOLES_COMPLEX ) {
496 nops = 8*frontmtx->nentD + 8*frontmtx->nentU ;
497 if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
498 nops += 8*frontmtx->nentL ;
499 } else {
500 nops += 8*frontmtx->nentU ;
501 }
502 }
503 nops *= nrhs ;
504 if ( msglvl > 2 ) {
505 fprintf(msgFile, "\n\n rhs") ;
506 DenseMtx_writeForHumanEye(mtxB, msgFile) ;
507 fflush(stdout) ;
508 }
509 DVzero(6, cpus) ;
510 MARKTIME(t1) ;
511 FrontMtx_solve(frontmtx, mtxZ, mtxB, mtxmanager,
512 cpus, msglvl, msgFile) ;
513 MARKTIME(t2) ;
514 fprintf(msgFile, "\n\n CPU %8.3f : solve the system, %.3f mflops",
515 t2 - t1, 1.e-6*nops/(t2 - t1)) ;
516 cputotal = t2 - t1 ;
517 if ( cputotal > 0.0 ) {
518 fprintf(msgFile,
519 "\n set up solves %8.3f %6.2f"
520 "\n load rhs and store solution %8.3f %6.2f"
521 "\n forward solve %8.3f %6.2f"
522 "\n diagonal solve %8.3f %6.2f"
523 "\n backward solve %8.3f %6.2f"
524 "\n total time %8.3f",
525 cpus[0], 100.*cpus[0]/cputotal,
526 cpus[1], 100.*cpus[1]/cputotal,
527 cpus[2], 100.*cpus[2]/cputotal,
528 cpus[3], 100.*cpus[3]/cputotal,
529 cpus[4], 100.*cpus[4]/cputotal, cputotal) ;
530 }
531 if ( msglvl > 2 ) {
532 fprintf(msgFile, "\n\n computed solution") ;
533 DenseMtx_writeForHumanEye(mtxZ, msgFile) ;
534 fflush(stdout) ;
535 }
536 /*
537 DenseMtx_writeForMatlab(mtxZ, "Xhat", msgFile) ;
538 */
539 /*
540 -------------------------------------------------------------
541 permute the computed solution back into the original ordering
542 -------------------------------------------------------------
543 */
544 MARKTIME(t1) ;
545 DenseMtx_permuteRows(mtxZ, newToOldIV) ;
546 MARKTIME(t2) ;
547 fprintf(msgFile, "\n CPU %8.3f : permute solution", t2 - t1) ;
548 if ( msglvl > 2 ) {
549 fprintf(msgFile, "\n\n permuted solution") ;
550 DenseMtx_writeForHumanEye(mtxZ, msgFile) ;
551 fflush(stdout) ;
552 }
553 /*
554 -----------------
555 compute the error
556 -----------------
557 */
558 DenseMtx_sub(mtxZ, mtxX) ;
559 fprintf(msgFile, "\n\n maxabs error = %12.4e", DenseMtx_maxabs(mtxZ)) ;
560 if ( msglvl > 2 ) {
561 fprintf(msgFile, "\n\n error") ;
562 DenseMtx_writeForHumanEye(mtxZ, msgFile) ;
563 fflush(stdout) ;
564 }
565 fprintf(msgFile, "\n\n after solve") ;
566 SubMtxManager_writeForHumanEye(frontmtx->manager, msgFile) ;
567 /*
568 ------------------------
569 free the working storage
570 ------------------------
571 */
572 IV_free(oldToNewIV) ;
573 IV_free(newToOldIV) ;
574 InpMtx_free(mtxA) ;
575 DenseMtx_free(mtxX) ;
576 DenseMtx_free(mtxB) ;
577 DenseMtx_free(mtxZ) ;
578 FrontMtx_free(frontmtx) ;
579 ETree_free(frontETree) ;
580 IVL_free(symbfacIVL) ;
581 ChvManager_free(chvmanager) ;
582 SubMtxManager_free(mtxmanager) ;
583
584 fprintf(msgFile, "\n") ;
585 fclose(msgFile) ;
586
587 return(1) ; }
588
589 /*--------------------------------------------------------------------*/
590