/* --------------------------------- purpose -- for dense storage *pnrow with mtx->nrow *pncol with mtx->ncol *pinc1 with row increment *pinc2 with column increment *pentries with mtx->entries created -- 98may01, cca --------------------------------- */ void SubMtx_denseInfo ( SubMtx *mtx, int *pnrow, int *pncol, int *pinc1, int *pinc2, double **pentries ) { double *dbuffer ; int nint ; /* --------------- check the input --------------- */ if ( mtx == NULL || pnrow == NULL || pncol == NULL || pinc1 == NULL || pinc2 == NULL || pentries == NULL ) { fprintf(stderr, "\n fatal error in SubMtx_denseInfo(%p,%p,%p,%p,%p,%p)" "\n bad input\n", mtx, pnrow, pncol, pinc1, pinc2, pentries) ; exit(-1) ; } if ( ! (SUBMTX_IS_REAL(mtx) || SUBMTX_IS_COMPLEX(mtx)) ) { fprintf(stderr, "\n fatal error in SubMtx_denseInfo(%p,%p,%p,%p,%p,%p)" "\n bad type %d, must be SPOOLES_REAL or SPOOLES_COMPLEX\n", mtx, pnrow, pncol, pinc1, pinc2, pentries, mtx->type) ; exit(-1) ; } if ( ! (SUBMTX_IS_DENSE_ROWS(mtx) || SUBMTX_IS_DENSE_COLUMNS(mtx)) ) { fprintf(stderr, "\n fatal error in SubMtx_denseInfo(%p,%p,%p,%p,%p,%p)" "\n bad mode %d" "\n must be SUBMTX_DENSE_ROWS or SUBMTX_DENSE_COLUMNS\n", mtx, pnrow, pncol, pinc1, pinc2, pentries, mtx->mode) ; exit(-1) ; } *pnrow = mtx->nrow ; *pncol = mtx->ncol ; if ( SUBMTX_IS_DENSE_ROWS(mtx) ) { *pinc1 = mtx->ncol ; *pinc2 = 1 ; } else { *pinc1 = 1 ; *pinc2 = mtx->nrow ; } dbuffer = mtx->wrkDV.vec ; nint = 7 + mtx->nrow + mtx->ncol ; if ( sizeof(int) == sizeof(double) ) { *pentries = dbuffer + nint ; } else if ( 2*sizeof(int) == sizeof(double) ) { *pentries = dbuffer + (nint+1)/2 ; } return ; }
/* ---------------------------------------------------------------- purpose -- for each L_{bnd{J},J} matrix, remove from hash table, split into their L_{K,J} submatrices and insert into the hash table. created -- 98may04, cca ---------------------------------------------------------------- */ void FrontMtx_splitLowerMatrices ( FrontMtx *frontmtx, int msglvl, FILE *msgFile ) { SubMtx *mtxLJ, *mtxLJJ, *mtxLKJ ; SubMtxManager *manager ; double *entLJ, *entLKJ ; int count, first, ii, inc1, inc2, irow, jj, J, K, nbytes, ncolLJ, ncolLKJ, nentLJ, nentLKJ, neqns, nfront, nJ, nrowJ, nrowLJ, nrowLKJ, offset, v ; int *colindLJ, *colindLKJ, *rowmap, *indicesLJ, *indicesLKJ, *locmap, *rowindJ, *rowindLJ, *rowindLKJ, *sizesLJ, *sizesLKJ ; I2Ohash *lowerhash ; /* --------------- check the input --------------- */ if ( frontmtx == NULL || (msglvl > 0 && msgFile == NULL) ) { fprintf(stderr, "\n fatal error in FrontMtx_splitLowerMatrices(%p,%d,%p)" "\n bad input\n", frontmtx, msglvl, msgFile) ; spoolesFatal(); } nfront = FrontMtx_nfront(frontmtx) ; neqns = FrontMtx_neqns(frontmtx) ; lowerhash = frontmtx->lowerhash ; manager = frontmtx->manager ; /* -------------------------------- construct the row and local maps -------------------------------- */ rowmap = IVinit(neqns, -1) ; locmap = IVinit(neqns, -1) ; for ( J = 0 ; J < nfront ; J++ ) { if ( (nJ = FrontMtx_frontSize(frontmtx, J)) > 0 ) { FrontMtx_rowIndices(frontmtx, J, &nrowJ, &rowindJ) ; if ( nrowJ > 0 && rowindJ != NULL ) { for ( ii = 0 ; ii < nJ ; ii++ ) { v = rowindJ[ii] ; rowmap[v] = J ; locmap[v] = ii ; } } } } if ( msglvl > 2 ) { fprintf(msgFile, "\n\n rowmap[]") ; IVfprintf(msgFile, neqns, rowmap) ; fprintf(msgFile, "\n\n locmap[]") ; IVfprintf(msgFile, neqns, locmap) ; fflush(msgFile) ; } /* --------------------------------------------- move the L_{J,J} matrices into the hash table --------------------------------------------- */ for ( J = 0 ; J < nfront ; J++ ) { if ( (mtxLJJ = FrontMtx_lowerMtx(frontmtx, J, J)) != NULL ) { I2Ohash_insert(frontmtx->lowerhash, J, J, mtxLJJ) ; } } /* ------------------------------------------------------------ now split the L_{bnd{J},J} matrices into L_{K,J} matrices. note: columns of L_{bnd{J},J} are assumed to be in ascending order with respect to the column ordering of the matrix. ------------------------------------------------------------ */ for ( J = 0 ; J < nfront ; J++ ) { mtxLJ = FrontMtx_lowerMtx(frontmtx, nfront, J) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n ### J = %d, mtxLJ = %p", J, mtxLJ) ; fflush(msgFile) ; } if ( mtxLJ != NULL ) { if ( msglvl > 2 ) { SubMtx_writeForHumanEye(mtxLJ, msgFile) ; fflush(msgFile) ; } SubMtx_columnIndices(mtxLJ, &ncolLJ, &colindLJ) ; SubMtx_rowIndices(mtxLJ, &nrowLJ, &rowindLJ) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n column indices for J") ; IVfprintf(msgFile, ncolLJ, colindLJ) ; fprintf(msgFile, "\n row indices for LJ") ; IVfprintf(msgFile, nrowLJ, rowindLJ) ; fflush(msgFile) ; } if ( (K = rowmap[rowindLJ[0]]) == rowmap[rowindLJ[nrowLJ-1]] ) { if ( msglvl > 2 ) { fprintf(msgFile, "\n front %d supports only %d", J, K) ; fflush(msgFile) ; } /* ------------------------------------------------- L_{bnd{J},J} is one submatrix, bnd{J} \subseteq K set row and column indices and change column id ------------------------------------------------- */ IVramp(ncolLJ, colindLJ, 0, 1) ; for ( ii = 0 ; ii < nrowLJ ; ii++ ) { rowindLJ[ii] = locmap[rowindLJ[ii]] ; } /* mtxLJ->rowid = K ; */ SubMtx_setFields(mtxLJ, mtxLJ->type, mtxLJ->mode, K, J, mtxLJ->nrow, mtxLJ->ncol, mtxLJ->nent) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n ## inserting L(%d,%d) ", K, J) ; SubMtx_writeForHumanEye(mtxLJ, msgFile) ; fflush(msgFile) ; } I2Ohash_insert(lowerhash, K, J, (void *) mtxLJ) ; } else { /* ----------------------------------- split L_{bnd{J},J} into submatrices ----------------------------------- */ nJ = FrontMtx_frontSize(frontmtx, J) ; if ( SUBMTX_IS_DENSE_ROWS(mtxLJ) ) { SubMtx_denseInfo(mtxLJ, &nrowLJ, &ncolLJ, &inc1, &inc2, &entLJ) ; } else if ( SUBMTX_IS_SPARSE_ROWS(mtxLJ) ) { SubMtx_sparseRowsInfo(mtxLJ, &nrowLJ, &nentLJ, &sizesLJ, &indicesLJ, &entLJ) ; offset = 0 ; count = sizesLJ[0] ; } first = 0 ; K = rowmap[rowindLJ[0]] ; for ( irow = 1 ; irow <= nrowLJ ; irow++ ) { if ( msglvl > 2 ) { fprintf(msgFile, "\n irow = %d", irow) ; if ( irow < nrowLJ ) { fprintf(msgFile, ", rowmap[%d] = %d", rowindLJ[irow], rowmap[rowindLJ[irow]]); } fflush(msgFile) ; } if ( irow == nrowLJ || K != rowmap[rowindLJ[irow]] ) { nrowLKJ = irow - first ; if ( SUBMTX_IS_DENSE_ROWS(mtxLJ) ) { nentLKJ = nJ*nrowLKJ ; } else if ( SUBMTX_IS_SPARSE_ROWS(mtxLJ) ) { if ( count == 0 ) { goto no_entries ; } nentLKJ = count ; } nbytes = SubMtx_nbytesNeeded(mtxLJ->type, mtxLJ->mode, nrowLKJ, nJ, nentLKJ) ; mtxLKJ = SubMtxManager_newObjectOfSizeNbytes(manager, nbytes) ; SubMtx_init(mtxLKJ, mtxLJ->type, mtxLJ->mode, K, J, nrowLKJ, nJ, nentLKJ) ; if ( SUBMTX_IS_DENSE_ROWS(mtxLJ) ) { SubMtx_denseInfo(mtxLKJ, &nrowLKJ, &ncolLKJ, &inc1, &inc2, &entLKJ) ; if ( FRONTMTX_IS_REAL(frontmtx) ) { DVcopy(nentLKJ, entLKJ, entLJ + first*nJ) ; } else if ( FRONTMTX_IS_COMPLEX(frontmtx) ) { DVcopy(2*nentLKJ, entLKJ, entLJ + 2*first*nJ) ; } } else if ( SUBMTX_IS_SPARSE_ROWS(mtxLJ) ) { SubMtx_sparseRowsInfo(mtxLKJ, &nrowLKJ, &nentLKJ, &sizesLKJ, &indicesLKJ, &entLKJ) ; IVcopy(nrowLKJ, sizesLKJ, sizesLJ + first) ; IVcopy(nentLKJ, indicesLKJ, indicesLJ + offset) ; if ( FRONTMTX_IS_REAL(frontmtx) ) { DVcopy(nentLKJ, entLKJ, entLJ + offset) ; } else if ( FRONTMTX_IS_COMPLEX(frontmtx) ) { DVcopy(2*nentLKJ, entLKJ, entLJ + 2*offset) ; } count = 0 ; offset += nentLKJ ; } /* ------------------------------------- initialize the row and column indices ------------------------------------- */ SubMtx_rowIndices(mtxLKJ, &nrowLKJ, &rowindLKJ) ; for ( ii = 0, jj = first ; ii < nrowLKJ ; ii++, jj++ ) { rowindLKJ[ii] = locmap[rowindLJ[jj]] ; } SubMtx_columnIndices(mtxLKJ, &ncolLKJ, &colindLKJ) ; IVramp(ncolLKJ, colindLKJ, 0, 1) ; /* ---------------------------------- insert L_{K,J} into the hash table ---------------------------------- */ if ( msglvl > 2 ) { fprintf(msgFile, "\n\n ## inserting L(%d,%d) ", K, J) ; SubMtx_writeForHumanEye(mtxLKJ, msgFile) ; fflush(msgFile) ; } I2Ohash_insert(lowerhash, K, J, (void *) mtxLKJ) ; /* ----------------------------------- we jump to here if there were no entries to be stored in the matrix. ----------------------------------- */ no_entries : /* ---------------------------------------------------- reset first and K to new first location and front id ---------------------------------------------------- */ first = irow ; if ( irow < nrowLJ ) { K = rowmap[rowindLJ[irow]] ; } } if ( irow < nrowLJ && SUBMTX_IS_SPARSE_ROWS(mtxLJ) ) { count += sizesLJ[irow] ; } } /* -------------------------------------------- give L_{bnd{J},J} back to the matrix manager -------------------------------------------- */ SubMtxManager_releaseObject(manager, mtxLJ) ; } } } /* ------------------------ free the working storage ------------------------ */ IVfree(rowmap) ; IVfree(locmap) ; return ; }