1 /* QRutil.c */
2
3 #include "../FrontMtx.h"
4 #include "../../timings.h"
5
6 /*--------------------------------------------------------------------*/
7 /*
8 --------------------------------------------------------------------
9 purpose -- to setup two data structures for a QR serial
10 or multithreaded factorization
11
12 rowsIVL[J] -- list of rows of A to be assembled into front J
13 firstnz[irow] -- column with location of leading nonzero of row in A
14
15 created -- 98may29, cca
16 --------------------------------------------------------------------
17 */
18 void
FrontMtx_QR_setup(FrontMtx * frontmtx,InpMtx * mtxA,IVL ** prowsIVL,int ** pfirstnz,int msglvl,FILE * msgFile)19 FrontMtx_QR_setup (
20 FrontMtx *frontmtx,
21 InpMtx *mtxA,
22 IVL **prowsIVL,
23 int **pfirstnz,
24 int msglvl,
25 FILE *msgFile
26 ) {
27 int count, irow, jcol, J, loc, neqns, nfront, nrowA, rowsize ;
28 int *firstnz, *head, *link, *list, *rowind, *vtxToFront ;
29 IVL *rowsIVL ;
30 /*
31 ---------------
32 check the input
33 ---------------
34 */
35 if ( frontmtx == NULL || mtxA == NULL || prowsIVL == NULL
36 || pfirstnz == NULL || (msglvl > 0 && msgFile == NULL) ) {
37 fprintf(stderr, "\n fatal error in FrontMtx_QR_setup()"
38 "\n bad input\n") ;
39 exit(-1) ;
40 }
41 neqns = FrontMtx_neqns(frontmtx) ;
42 nfront = FrontMtx_nfront(frontmtx) ;
43 vtxToFront = ETree_vtxToFront(frontmtx->frontETree) ;
44 /*
45 ----------------------------------------------------------------
46 create the rowsIVL object,
47 list(J) = list of rows that are assembled in front J
48 firstnz[irowA] = first column with nonzero element in A(irowA,*)
49 ----------------------------------------------------------------
50 */
51 InpMtx_changeCoordType(mtxA, INPMTX_BY_ROWS) ;
52 InpMtx_changeStorageMode(mtxA, INPMTX_BY_VECTORS) ;
53 nrowA = 1 + IVmax(InpMtx_nent(mtxA), InpMtx_ivec1(mtxA), &loc) ;
54 if ( msglvl > 3 ) {
55 fprintf(msgFile, "\n nrowA = %d ", nrowA) ;
56 fflush(msgFile) ;
57 }
58 firstnz = IVinit(nrowA, -1) ;
59 head = IVinit(nfront, -1) ;
60 link = IVinit(nrowA, -1) ;
61 for ( irow = nrowA - 1 ; irow >= 0 ; irow-- ) {
62 InpMtx_vector(mtxA, irow, &rowsize, &rowind) ;
63 if ( rowsize > 0 ) {
64 firstnz[irow] = jcol = rowind[0] ;
65 J = vtxToFront[jcol] ;
66 link[irow] = head[J] ;
67 head[J] = irow ;
68 }
69 }
70 rowsIVL = IVL_new() ;
71 IVL_init2(rowsIVL, IVL_CHUNKED, nfront, nrowA) ;
72 list = IVinit(neqns, -1) ;
73 for ( J = 0 ; J < nfront ; J++ ) {
74 count = 0 ;
75 for ( irow = head[J] ; irow != -1 ; irow = link[irow] ) {
76 list[count++] = irow ;
77 }
78 if ( count > 0 ) {
79 IVL_setList(rowsIVL, J, count, list) ;
80 }
81 }
82 IVfree(head) ;
83 IVfree(link) ;
84 IVfree(list) ;
85 /*
86 ---------------------------
87 set the pointers for return
88 ---------------------------
89 */
90 *prowsIVL = rowsIVL ;
91 *pfirstnz = firstnz ;
92
93 return ; }
94
95 /*--------------------------------------------------------------------*/
96 /*
97 -----------------------------------------------
98 purpose -- visit front J during a serial
99 or multithreaded QR factorization
100
101 cpus[1] -- initialize and load staircase matrix
102 cpus[2] -- factor the matrix
103 cpus[3] -- scale and store factor entries
104 cpus[4] -- store update entries
105
106 created -- 98may28, cca
107 -----------------------------------------------
108 */
109 void
FrontMtx_QR_factorVisit(FrontMtx * frontmtx,int J,InpMtx * mtxA,IVL * rowsIVL,int firstnz[],ChvList * updlist,ChvManager * chvmanager,char status[],int colmap[],DV * workDV,double cpus[],double * pfacops,int msglvl,FILE * msgFile)110 FrontMtx_QR_factorVisit (
111 FrontMtx *frontmtx,
112 int J,
113 InpMtx *mtxA,
114 IVL *rowsIVL,
115 int firstnz[],
116 ChvList *updlist,
117 ChvManager *chvmanager,
118 char status[],
119 int colmap[],
120 DV *workDV,
121 double cpus[],
122 double *pfacops,
123 int msglvl,
124 FILE *msgFile
125 ) {
126 /*
127 ---------------
128 check the input
129 ---------------
130 */
131 if ( frontmtx == NULL || mtxA == NULL || rowsIVL == NULL
132 || firstnz == NULL || updlist == NULL || chvmanager == NULL
133 || status == NULL || colmap == NULL || workDV == NULL
134 || cpus == NULL || pfacops == NULL
135 || (msglvl > 0 && msgFile == NULL) ) {
136 fprintf(msgFile, "\n fatal error in FrontMtx_QR_factorVisit(%d)"
137 "\n bad input\n", J) ;
138 exit(-1) ;
139 }
140 /*
141 ------------------------------------------------------------
142 check to see if all incoming updates are present in the list
143 ------------------------------------------------------------
144 */
145 if ( ChvList_isCountZero(updlist, J) == 1 ) {
146 A2 *frontJ ;
147 Chv *firstchild, *updchv ;
148 double ops, t1, t2 ;
149 int K ;
150 /*
151 ----------------------------------------
152 everything is ready to factor this front
153 ----------------------------------------
154 */
155 firstchild = ChvList_getList(updlist, J) ;
156 /*
157 ----------------------------------------
158 initialize and load the staircase matrix
159 ----------------------------------------
160 */
161 MARKTIME(t1) ;
162 frontJ = FrontMtx_QR_assembleFront(frontmtx, J, mtxA, rowsIVL,
163 firstnz, colmap, firstchild,
164 workDV, msglvl, msgFile) ;
165 if ( firstchild != NULL ) {
166 ChvManager_releaseListOfObjects(chvmanager, firstchild) ;
167 }
168 MARKTIME(t2) ;
169 cpus[1] += t2 - t1 ;
170 if ( msglvl > 3 ) {
171 fprintf(msgFile, "\n\n after assembling front") ;
172 A2_writeForHumanEye(frontJ, msgFile) ;
173 fflush(msgFile) ;
174 }
175 /*
176 ---------------------------
177 factor the staircase matrix
178 ---------------------------
179 */
180 MARKTIME(t1) ;
181 ops = A2_QRreduce(frontJ, workDV, msglvl, msgFile) ;
182 *pfacops += ops ;
183 MARKTIME(t2) ;
184 cpus[2] += t2 - t1 ;
185 if ( msglvl > 3 ) {
186 fprintf(msgFile, "\n\n after factoring") ;
187 A2_writeForHumanEye(frontJ, msgFile) ;
188 fflush(msgFile) ;
189 }
190 /*
191 ----------------------------------
192 scale and store the factor entries
193 ----------------------------------
194 */
195 MARKTIME(t1) ;
196 FrontMtx_QR_storeFront(frontmtx, J, frontJ, msglvl, msgFile) ;
197 MARKTIME(t2) ;
198 cpus[3] += t2 - t1 ;
199 if ( msglvl > 3 ) {
200 fprintf(msgFile, "\n\n after storing factor entries") ;
201 A2_writeForHumanEye(frontJ, msgFile) ;
202 fflush(msgFile) ;
203 }
204 /*
205 -----------------------
206 store the update matrix
207 -----------------------
208 */
209 if ( (K = frontmtx->tree->par[J]) != -1 ) {
210 MARKTIME(t1) ;
211 updchv = FrontMtx_QR_storeUpdate(frontmtx, J, frontJ, chvmanager,
212 msglvl, msgFile) ;
213 ChvList_addObjectToList(updlist, updchv, K) ;
214 MARKTIME(t2) ;
215 cpus[4] += t2 - t1 ;
216 if ( msglvl > 3 ) {
217 fprintf(msgFile, "\n\n after storing update entries") ;
218 A2_writeForHumanEye(frontJ, msgFile) ;
219 fflush(msgFile) ;
220 }
221 }
222 /*
223 -------------------------
224 free the staircase matrix
225 -------------------------
226 */
227 A2_free(frontJ) ;
228 /*
229 -------------------------------------
230 set the status as finished and return
231 -------------------------------------
232 */
233 status[J] = 'F' ;
234 }
235 return ; }
236
237 /*--------------------------------------------------------------------*/
238 /*
239 --------------------------------------------------------------
240 purpose -- create and return an A2 object that contains rows
241 of A and rows from update matrices of the children.
242 the matrix may not be in staircase form
243
244 created -- 98may25, cca
245 --------------------------------------------------------------
246 */
247 A2 *
FrontMtx_QR_assembleFront(FrontMtx * frontmtx,int J,InpMtx * mtxA,IVL * rowsIVL,int firstnz[],int colmap[],Chv * firstchild,DV * workDV,int msglvl,FILE * msgFile)248 FrontMtx_QR_assembleFront (
249 FrontMtx *frontmtx,
250 int J,
251 InpMtx *mtxA,
252 IVL *rowsIVL,
253 int firstnz[],
254 int colmap[],
255 Chv *firstchild,
256 DV *workDV,
257 int msglvl,
258 FILE *msgFile
259 ) {
260 A2 *frontJ ;
261 Chv *chvI ;
262 double *rowI, *rowJ, *rowentA ;
263 int ii, irow, irowA, irowI, jcol, jj, jrow, ncolI, ncolJ,
264 nentA, nrowI, nrowJ, nrowFromA ;
265 int *colindA, *colindI, *colindJ, *map, *rowids, *rowsFromA ;
266 /*
267 ---------------
268 check the input
269 ---------------
270 */
271 if ( frontmtx == NULL || mtxA == NULL || rowsIVL == NULL
272 || (msglvl > 0 && msgFile == NULL) ) {
273 fprintf(stderr, "\n fatal error in FrontMtx_QR_assembleFront()"
274 "\n bad input\n") ;
275 exit(-1) ;
276 }
277 if ( msglvl > 3 ) {
278 fprintf(msgFile, "\n\n inside FrontMtx_QR_assembleFront(%d)", J) ;
279 fflush(msgFile) ;
280 }
281 /*
282 --------------------------------------------------
283 set up the map from global to local column indices
284 --------------------------------------------------
285 */
286 FrontMtx_columnIndices(frontmtx, J, &ncolJ, &colindJ) ;
287 for ( jcol = 0 ; jcol < ncolJ ; jcol++ ) {
288 colmap[colindJ[jcol]] = jcol ;
289 }
290 if ( msglvl > 3 ) {
291 fprintf(msgFile, "\n front %d's column indices", J) ;
292 IVfprintf(msgFile, ncolJ, colindJ) ;
293 fflush(msgFile) ;
294 }
295 /*
296 -------------------------------------------------
297 compute the size of the front and map the global
298 indices of the update matrices into local indices
299 -------------------------------------------------
300 */
301 IVL_listAndSize(rowsIVL, J, &nrowFromA, &rowsFromA) ;
302 nrowJ = nrowFromA ;
303 if ( msglvl > 3 ) {
304 fprintf(msgFile, "\n %d rows from A", nrowFromA) ;
305 fflush(msgFile) ;
306 }
307 for ( chvI = firstchild ; chvI != NULL ; chvI = chvI->next ) {
308 nrowJ += chvI->nD ;
309 Chv_columnIndices(chvI, &ncolI, &colindI) ;
310 for ( jcol = 0 ; jcol < ncolI ; jcol++ ) {
311 colindI[jcol] = colmap[colindI[jcol]] ;
312 }
313 if ( msglvl > 3 ) {
314 fprintf(msgFile, "\n %d rows from child %d", chvI->nD, chvI->id) ;
315 fflush(msgFile) ;
316 }
317 }
318 /*
319 ----------------------------------------------------------
320 get workspace for the rowids[nrowJ] and map[nrowJ] vectors
321 ----------------------------------------------------------
322 */
323 if ( sizeof(int) == sizeof(double) ) {
324 DV_setSize(workDV, 2*nrowJ) ;
325 } else if ( 2*sizeof(int) == sizeof(double) ) {
326 DV_setSize(workDV, nrowJ) ;
327 }
328 rowids = (int *) DV_entries(workDV) ;
329 map = rowids + nrowJ ;
330 IVramp(nrowJ, rowids, 0, 1) ;
331 IVfill(nrowJ, map, -1) ;
332 /*
333 -----------------------------------------------------------------
334 get the map from incoming rows to their place in the front matrix
335 -----------------------------------------------------------------
336 */
337 for ( irow = jrow = 0 ; irow < nrowFromA ; irow++, jrow++ ) {
338 irowA = rowsFromA[irow] ;
339 map[jrow] = colmap[firstnz[irowA]] ;
340 }
341 for ( chvI = firstchild ; chvI != NULL ; chvI = chvI->next ) {
342 nrowI = chvI->nD ;
343 Chv_columnIndices(chvI, &ncolI, &colindI) ;
344 for ( irow = 0 ; irow < nrowI ; irow++, jrow++ ) {
345 map[jrow] = colindI[irow] ;
346 }
347 }
348 IV2qsortUp(nrowJ, map, rowids) ;
349 for ( irow = 0 ; irow < nrowJ ; irow++ ) {
350 map[rowids[irow]] = irow ;
351 }
352 /*
353 ----------------------------
354 allocate the A2 front object
355 ----------------------------
356 */
357 frontJ = A2_new() ;
358 A2_init(frontJ, frontmtx->type, nrowJ, ncolJ, ncolJ, 1, NULL) ;
359 A2_zero(frontJ) ;
360 /*
361 ------------------------------------
362 load the original rows of the matrix
363 ------------------------------------
364 */
365 for ( jrow = 0 ; jrow < nrowFromA ; jrow++ ) {
366 irowA = rowsFromA[jrow] ;
367 rowJ = A2_row(frontJ, map[jrow]) ;
368 if ( A2_IS_REAL(frontJ) ) {
369 InpMtx_realVector(mtxA, irowA, &nentA, &colindA, &rowentA) ;
370 } else if ( A2_IS_COMPLEX(frontJ) ) {
371 InpMtx_complexVector(mtxA, irowA, &nentA, &colindA, &rowentA) ;
372 }
373 if ( msglvl > 3 ) {
374 fprintf(msgFile, "\n loading row %d", irowA) ;
375 fprintf(msgFile, "\n global indices") ;
376 IVfprintf(msgFile, nentA, colindA) ;
377 fflush(msgFile) ;
378 }
379 if ( A2_IS_REAL(frontJ) ) {
380 for ( ii = 0 ; ii < nentA ; ii++ ) {
381 jj = colmap[colindA[ii]] ;
382 rowJ[jj] = rowentA[ii] ;
383 }
384 } else if ( A2_IS_COMPLEX(frontJ) ) {
385 for ( ii = 0 ; ii < nentA ; ii++ ) {
386 jj = colmap[colindA[ii]] ;
387 rowJ[2*jj] = rowentA[2*ii] ;
388 rowJ[2*jj+1] = rowentA[2*ii+1] ;
389 }
390 }
391 }
392 if ( msglvl > 3 ) {
393 fprintf(msgFile, "\n after assembling rows of A") ;
394 A2_writeForHumanEye(frontJ, msgFile) ;
395 fflush(msgFile) ;
396 }
397 /*
398 ----------------------------------
399 load the updates from the children
400 ----------------------------------
401 */
402 for ( chvI = firstchild ; chvI != NULL ; chvI = chvI->next ) {
403 nrowI = chvI->nD ;
404 Chv_columnIndices(chvI, &ncolI, &colindI) ;
405 if ( msglvl > 3 ) {
406 fprintf(msgFile, "\n loading child %d", chvI->id) ;
407 fprintf(msgFile, "\n child's column indices") ;
408 IVfprintf(msgFile, ncolI, colindI) ;
409 Chv_writeForHumanEye(chvI, msgFile) ;
410 fflush(msgFile) ;
411 }
412 rowI = Chv_entries(chvI) ;
413 for ( irowI = 0 ; irowI < nrowI ; irowI++, jrow++ ) {
414 rowJ = A2_row(frontJ, map[jrow]) ;
415 if ( A2_IS_REAL(frontJ) ) {
416 for ( ii = irowI ; ii < ncolI ; ii++ ) {
417 jj = colindI[ii] ;
418 rowJ[jj] = rowI[ii] ;
419 }
420 rowI += ncolI - irowI - 1 ;
421 } else if ( A2_IS_COMPLEX(frontJ) ) {
422 for ( ii = irowI ; ii < ncolI ; ii++ ) {
423 jj = colindI[ii] ;
424 rowJ[2*jj] = rowI[2*ii] ;
425 rowJ[2*jj+1] = rowI[2*ii+1] ;
426 }
427 rowI += 2*(ncolI - irowI - 1) ;
428 }
429 }
430 if ( msglvl > 3 ) {
431 fprintf(msgFile, "\n after assembling child %d", chvI->id) ;
432 A2_writeForHumanEye(frontJ, msgFile) ;
433 fflush(msgFile) ;
434 }
435 }
436 return(frontJ) ; }
437
438 /*--------------------------------------------------------------------*/
439 /*
440 ----------------------------------------------------
441 store the factor entries of the reduced front matrix
442
443 created -- 98may25, cca
444 ----------------------------------------------------
445 */
446 void
FrontMtx_QR_storeFront(FrontMtx * frontmtx,int J,A2 * frontJ,int msglvl,FILE * msgFile)447 FrontMtx_QR_storeFront (
448 FrontMtx *frontmtx,
449 int J,
450 A2 *frontJ,
451 int msglvl,
452 FILE *msgFile
453 ) {
454 A2 tempA2 ;
455 double fac, ifac, imag, real, rfac ;
456 double *entDJJ, *entUJJ, *entUJN, *row ;
457 int inc1, inc2, irow, jcol, ncol, ncolJ, nD, nentD, nentUJJ,
458 nfront, nrow, nU ;
459 int *colind, *colindJ, *firstlocs, *sizes ;
460 SubMtx *mtx ;
461 /*
462 ---------------
463 check the input
464 ---------------
465 */
466 if ( frontmtx == NULL || frontJ == NULL
467 || (msglvl > 0 && msgFile == NULL) ) {
468 fprintf(stderr, "\n fatal error in FrontMtx_QR_storeFront()"
469 "\n bad input\n") ;
470 exit(-1) ;
471 }
472 nfront = FrontMtx_nfront(frontmtx) ;
473 FrontMtx_columnIndices(frontmtx, J, &ncolJ, &colindJ) ;
474 nrow = A2_nrow(frontJ) ;
475 ncol = A2_ncol(frontJ) ;
476 A2_setDefaultFields(&tempA2) ;
477 nD = FrontMtx_frontSize(frontmtx, J) ;
478 nU = ncol - nD ;
479 /*
480 --------------------------------------
481 scale the rows and square the diagonal
482 --------------------------------------
483 */
484 row = A2_entries(frontJ) ;
485 if ( A2_IS_REAL(frontJ) ) {
486 for ( irow = 0 ; irow < nD ; irow++ ) {
487 if ( row[irow] != 0.0 ) {
488 fac = 1./row[irow] ;
489 for ( jcol = irow + 1 ; jcol < ncol ; jcol++ ) {
490 row[jcol] *= fac ;
491 }
492 row[irow] = row[irow] * row[irow] ;
493 }
494 row += ncol ;
495 }
496 } else if ( A2_IS_COMPLEX(frontJ) ) {
497 for ( irow = 0 ; irow < nD ; irow++ ) {
498 real = row[2*irow] ; imag = row[2*irow+1] ;
499 if ( real != 0.0 || imag != 0.0 ) {
500 Zrecip(real, imag, &rfac, &ifac) ;
501 ZVscale(ncol - irow - 1, & row[2*irow+2], rfac, ifac) ;
502 row[2*irow] = real*real + imag*imag ;
503 row[2*irow+1] = 0.0 ;
504 }
505 row += 2*ncol ;
506 }
507 }
508 if ( msglvl > 3 ) {
509 fprintf(msgFile, "\n after scaling rows of A") ;
510 A2_writeForHumanEye(frontJ, msgFile) ;
511 fflush(msgFile) ;
512 }
513 /*
514 -------------------------
515 copy the diagonal entries
516 -------------------------
517 */
518 mtx = FrontMtx_diagMtx(frontmtx, J) ;
519 SubMtx_diagonalInfo(mtx, &nentD, &entDJJ) ;
520 A2_subA2(&tempA2, frontJ, 0, nD-1, 0, nD-1) ;
521 A2_copyEntriesToVector(&tempA2, nentD, entDJJ,
522 A2_DIAGONAL, A2_BY_ROWS) ;
523 SubMtx_columnIndices(mtx, &ncol, &colind) ;
524 IVcopy(nD, colind, colindJ) ;
525 if ( msglvl > 3 ) {
526 fprintf(msgFile, "\n diagonal factor matrix") ;
527 SubMtx_writeForHumanEye(mtx, msgFile) ;
528 fflush(msgFile) ;
529 }
530 if ( (mtx = FrontMtx_upperMtx(frontmtx, J, J)) != NULL ) {
531 /*
532 ------------------------
533 copy the U_{J,J} entries
534 ------------------------
535 */
536 SubMtx_denseSubcolumnsInfo(mtx, &nD, &nentUJJ,
537 &firstlocs, &sizes, &entUJJ) ;
538 A2_copyEntriesToVector(&tempA2, nentUJJ, entUJJ,
539 A2_STRICT_UPPER, A2_BY_COLUMNS) ;
540 SubMtx_columnIndices(mtx, &ncol, &colind) ;
541 IVcopy(nD, colind, colindJ) ;
542 if ( msglvl > 3 ) {
543 fprintf(msgFile, "\n UJJ factor matrix") ;
544 SubMtx_writeForHumanEye(mtx, msgFile) ;
545 fflush(msgFile) ;
546 }
547 }
548 if ( ncolJ > nD ) {
549 /*
550 -----------------------------
551 copy the U_{J,bnd{J}} entries
552 -----------------------------
553 */
554 mtx = FrontMtx_upperMtx(frontmtx, J, nfront) ;
555 SubMtx_denseInfo(mtx, &nD, &nU, &inc1, &inc2, &entUJN) ;
556 A2_subA2(&tempA2, frontJ, 0, nD-1, nD, ncolJ-1) ;
557 A2_copyEntriesToVector(&tempA2, nD*nU, entUJN,
558 A2_ALL_ENTRIES, A2_BY_COLUMNS) ;
559 SubMtx_columnIndices(mtx, &ncol, &colind) ;
560 IVcopy(nU, colind, colindJ + nD) ;
561 if ( msglvl > 3 ) {
562 fprintf(msgFile, "\n UJN factor matrix") ;
563 SubMtx_writeForHumanEye(mtx, msgFile) ;
564 fflush(msgFile) ;
565 }
566 }
567 return ; }
568
569 /*--------------------------------------------------------------------*/
570 /*
571 -------------------------------------------------
572 purpose -- to create and return a Chv object that
573 holds the update matrix for front J
574
575 created -- 98may25, cca
576 -------------------------------------------------
577 */
578 Chv *
FrontMtx_QR_storeUpdate(FrontMtx * frontmtx,int J,A2 * frontJ,ChvManager * chvmanager,int msglvl,FILE * msgFile)579 FrontMtx_QR_storeUpdate (
580 FrontMtx *frontmtx,
581 int J,
582 A2 *frontJ,
583 ChvManager *chvmanager,
584 int msglvl,
585 FILE *msgFile
586 ) {
587 A2 tempJ ;
588 Chv *chvJ ;
589 double *updent ;
590 int nbytes, ncolJ, ncolupd, nD, nent, nrowJ, nrowupd ;
591 int *colindJ, *updind ;
592 /*
593 -----------------------------------------------
594 compute the number of rows in the update matrix
595 -----------------------------------------------
596 */
597 nD = FrontMtx_frontSize(frontmtx, J) ;
598 FrontMtx_columnIndices(frontmtx, J, &ncolJ, &colindJ) ;
599 nrowJ = A2_nrow(frontJ) ;
600 nrowupd = ((nrowJ >= ncolJ) ? ncolJ : nrowJ) - nD ;
601 ncolupd = ncolJ - nD ;
602 if ( msglvl > 3 ) {
603 fprintf(msgFile, "\n\n inside FrontMtx_QR_storeUpdate(%d)", J) ;
604 fprintf(msgFile, "\n nD %d, nrowJ %d, nrowupd %d, ncolupd %d",
605 nD, nrowJ, nrowupd, ncolupd) ;
606 fflush(msgFile) ;
607 }
608 if ( nrowupd > 0 && ncolupd > 0 ) {
609 if ( FRONTMTX_IS_REAL(frontmtx) ) {
610 nbytes = Chv_nbytesNeeded(nrowupd, 0, ncolupd - nrowupd,
611 SPOOLES_REAL, SPOOLES_SYMMETRIC) ;
612 } else if ( FRONTMTX_IS_COMPLEX(frontmtx) ) {
613 nbytes = Chv_nbytesNeeded(nrowupd, 0, ncolupd - nrowupd,
614 SPOOLES_COMPLEX, SPOOLES_HERMITIAN) ;
615 }
616 chvJ = ChvManager_newObjectOfSizeNbytes(chvmanager, nbytes) ;
617 if ( FRONTMTX_IS_REAL(frontmtx) ) {
618 Chv_init(chvJ, J, nrowupd, 0, ncolupd - nrowupd,
619 SPOOLES_REAL, SPOOLES_SYMMETRIC) ;
620 } else if ( FRONTMTX_IS_COMPLEX(frontmtx) ) {
621 Chv_init(chvJ, J, nrowupd, 0, ncolupd - nrowupd,
622 SPOOLES_COMPLEX, SPOOLES_HERMITIAN) ;
623 }
624 Chv_columnIndices(chvJ, &ncolupd, &updind) ;
625 IVcopy(ncolupd, updind, colindJ + nD) ;
626 nent = Chv_nent(chvJ) ;
627 updent = Chv_entries(chvJ) ;
628 A2_setDefaultFields(&tempJ) ;
629 A2_subA2(&tempJ, frontJ, nD, nrowJ - 1, nD, ncolJ - 1) ;
630 A2_copyEntriesToVector(&tempJ, nent, updent, A2_UPPER, A2_BY_ROWS) ;
631 if ( msglvl > 3 ) {
632 fprintf(msgFile, "\n update matrix %d", J) ;
633 Chv_writeForHumanEye(chvJ, msgFile) ;
634 fflush(msgFile) ;
635 }
636 } else {
637 chvJ = NULL ;
638 }
639 return(chvJ) ; }
640
641 /*--------------------------------------------------------------------*/
642