/* --------------------------------------- purpose -- solve (I + A^T) X = B, where (1) A is strictly lower triangular (2) X overwrites B (B) B has mode SUBMTX_DENSE_COLUMNS created -- 98may01, cca --------------------------------------- */ static void solveSparseRows ( SubMtx *mtxA, SubMtx *mtxB ) { double ai, ar, bi0, bi1, bi2, br0, br1, br2 ; double *colB0, *colB1, *colB2, *entriesA, *entriesB ; int colstart, ii, iloc, inc1, inc2, jcolA, jcolB, jj, kk, ncolB, nentA, nrowA, nrowB, rloc, size ; int *indicesA, *sizesA ; /* ---------------------------------------------------- extract the pointer and dimensions from two matrices ---------------------------------------------------- */ SubMtx_sparseRowsInfo(mtxA, &nrowA, &nentA, &sizesA, &indicesA, &entriesA) ; SubMtx_denseInfo(mtxB, &nrowB, &ncolB, &inc1, &inc2, &entriesB) ; #if MYDEBUG > 0 fprintf(stdout, "\n nrowA = %d, ncolA = %d", nrowA, nentA) ; fflush(stdout) ; #endif colB0 = entriesB ; for ( jcolB = 0 ; jcolB < ncolB - 2 ; jcolB += 3 ) { colB1 = colB0 + 2*nrowB ; colB2 = colB1 + 2*nrowB ; #if MYDEBUG > 0 fprintf(stdout, "\n jcolB = %d", jcolB) ; fflush(stdout) ; #endif for ( jcolA = nrowA - 1, colstart = nentA ; jcolA >= 0 ; jcolA-- ) { if ( (size = sizesA[jcolA]) > 0 ) { colstart -= size ; rloc = 2*jcolA ; iloc = rloc + 1 ; br0 = colB0[rloc] ; bi0 = colB0[iloc] ; br1 = colB1[rloc] ; bi1 = colB1[iloc] ; br2 = colB2[rloc] ; bi2 = colB2[iloc] ; for ( ii = 0, kk = colstart ; ii < size ; ii++, kk++ ) { ar = entriesA[2*kk] ; ai = entriesA[2*kk+1] ; jj = indicesA[kk] ; rloc = 2*jj ; iloc = rloc + 1 ; colB0[rloc] -= ar*br0 + ai*bi0 ; colB0[iloc] -= ar*bi0 - ai*br0 ; colB1[rloc] -= ar*br1 + ai*bi1 ; colB1[iloc] -= ar*bi1 - ai*br1 ; colB2[rloc] -= ar*br2 + ai*bi2 ; colB2[iloc] -= ar*bi2 - ai*br2 ; } } } colB0 = colB2 + 2*nrowB ; } if ( jcolB == ncolB - 2 ) { colB1 = colB0 + 2*nrowB ; #if MYDEBUG > 0 fprintf(stdout, "\n jcolB = %d", jcolB) ; fflush(stdout) ; #endif for ( jcolA = nrowA - 1, colstart = nentA ; jcolA >= 0 ; jcolA-- ) { if ( (size = sizesA[jcolA]) > 0 ) { colstart -= size ; rloc = 2*jcolA ; iloc = rloc + 1 ; br0 = colB0[rloc] ; bi0 = colB0[iloc] ; br1 = colB1[rloc] ; bi1 = colB1[iloc] ; for ( ii = 0, kk = colstart ; ii < size ; ii++, kk++ ) { ar = entriesA[2*kk] ; ai = entriesA[2*kk+1] ; jj = indicesA[kk] ; rloc = 2*jj ; iloc = rloc + 1 ; colB0[rloc] -= ar*br0 + ai*bi0 ; colB0[iloc] -= ar*bi0 - ai*br0 ; colB1[rloc] -= ar*br1 + ai*bi1 ; colB1[iloc] -= ar*bi1 - ai*br1 ; } } } } else if ( jcolB == ncolB - 1 ) { #if MYDEBUG > 0 fprintf(stdout, "\n jcolB = %d", jcolB) ; fflush(stdout) ; #endif for ( jcolA = nrowA - 1, colstart = nentA ; jcolA >= 0 ; jcolA-- ) { if ( (size = sizesA[jcolA]) > 0 ) { colstart -= size ; rloc = 2*jcolA ; iloc = rloc + 1 ; br0 = colB0[rloc] ; bi0 = colB0[iloc] ; for ( ii = 0, kk = colstart ; ii < size ; ii++, kk++ ) { ar = entriesA[2*kk] ; ai = entriesA[2*kk+1] ; jj = indicesA[kk] ; rloc = 2*jj ; iloc = rloc + 1 ; colB0[rloc] -= ar*br0 + ai*bi0 ; colB0[iloc] -= ar*bi0 - ai*br0 ; } } } } return ; }
/* ------------------------------------------------- purpose -- to return a pointer to the location of matrix entry (irow,jcol) if present. if entry (irow,jcol) is not present then *ppValue is NULL else entry (irow,jcol) is present then *ppValue is the location of the matrix entry endif created -- 98may01, cca ------------------------------------------------- */ void SubMtx_locationOfRealEntry ( SubMtx *mtx, int irow, int jcol, double **ppValue ) { /* --------------- check the input --------------- */ if ( mtx == NULL || irow < 0 || irow >= mtx->nrow || jcol < 0 || jcol >= mtx->ncol || ppValue == NULL ) { fprintf(stderr, "\n fatal error in SubMtx_locationOfRealEntry(%p,%d,%d,%p)" "\n bad input\n", mtx, irow, jcol, ppValue) ; exit(-1) ; } if ( ! SUBMTX_IS_REAL(mtx) ) { fprintf(stderr, "\n fatal error in SubMtx_locationOfRealEntry(%p,%d,%d,%p)" "\n bad type %d, must be SPOOLES_REAL\n", mtx, irow, jcol, ppValue, mtx->type) ; exit(-1) ; } *ppValue = NULL ; switch ( mtx->mode ) { case SUBMTX_DENSE_ROWS : case SUBMTX_DENSE_COLUMNS : { double *entries ; int inc1, inc2, ncol, nrow, offset ; SubMtx_denseInfo(mtx, &nrow, &ncol, &inc1, &inc2, &entries) ; if ( irow >= 0 && irow < nrow && jcol >= 0 && jcol < ncol ) { offset = irow*inc1 + jcol*inc2 ; *ppValue = entries + offset ; } } break ; case SUBMTX_SPARSE_ROWS : { double *entries ; int ii, jj, nent, nrow, offset, *indices, *sizes ; SubMtx_sparseRowsInfo(mtx, &nrow, &nent, &sizes, &indices, &entries); if ( irow >= 0 && irow < nrow ) { for ( ii = offset = 0 ; ii < irow ; ii++ ) { offset += sizes[ii] ; } for ( ii = 0, jj = offset ; ii < sizes[irow] ; ii++, jj++ ) { if ( indices[jj] == jcol ) { *ppValue = entries + jj ; break ; } } } } break ; case SUBMTX_SPARSE_COLUMNS : { double *entries ; int ii, jj, nent, ncol, offset, *indices, *sizes ; SubMtx_sparseColumnsInfo(mtx, &ncol, &nent, &sizes, &indices, &entries) ; if ( jcol >= 0 && jcol < ncol ) { for ( ii = offset = 0 ; ii < jcol ; ii++ ) { offset += sizes[ii] ; } for ( ii = 0, jj = offset ; ii < sizes[jcol] ; ii++, jj++ ) { if ( indices[jj] == irow ) { *ppValue = entries + jj ; break ; } } } } break ; case SUBMTX_SPARSE_TRIPLES : { double *entries ; int ii, nent, *colids, *rowids ; SubMtx_sparseTriplesInfo(mtx, &nent, &rowids, &colids, &entries) ; for ( ii = 0 ; ii < nent ; ii++ ) { if ( irow == rowids[ii] && jcol == colids[ii] ) { *ppValue = entries + ii ; break ; } } } break ; case SUBMTX_DENSE_SUBROWS : { double *entries ; int ii, joff, nent, nrow, offset, *firstlocs, *sizes ; SubMtx_denseSubrowsInfo(mtx, &nrow, &nent, &firstlocs, &sizes, &entries) ; if ( irow >= 0 && irow < nrow && sizes[irow] != 0 ) { for ( ii = offset = 0 ; ii < irow ; ii++ ) { offset += sizes[ii] ; } if ( 0 <= (joff = jcol - firstlocs[irow]) && joff < sizes[irow] ) { offset += joff ; *ppValue = entries + offset ; break ; } } } break ; case SUBMTX_DENSE_SUBCOLUMNS : { double *entries ; int ii, ioff, nent, ncol, offset, *firstlocs, *sizes ; SubMtx_denseSubcolumnsInfo(mtx, &ncol, &nent, &firstlocs, &sizes, &entries) ; if ( jcol >= 0 && jcol < ncol && sizes[jcol] != 0 ) { for ( ii = offset = 0 ; ii < jcol ; ii++ ) { offset += sizes[jcol] ; } if ( 0 <= (ioff = irow - firstlocs[jcol]) && ioff < sizes[jcol] ) { offset += ioff ; *ppValue = entries + offset ; break ; } } } break ; case SUBMTX_DIAGONAL : { double *entries ; int ncol ; if ( irow >= 0 && jcol >= 0 && irow == jcol ) { SubMtx_diagonalInfo(mtx, &ncol, &entries) ; if ( irow < ncol && jcol < ncol ) { *ppValue = entries + irow ; } } } break ; case SUBMTX_BLOCK_DIAGONAL_SYM : case SUBMTX_BLOCK_DIAGONAL_HERM : { double *entries ; int ii, ipivot, jrow, kk, m, ncol, nent, size ; int *pivotsizes ; if ( irow >= 0 && jcol >= 0 ) { SubMtx_blockDiagonalInfo(mtx, &ncol, &nent, &pivotsizes, &entries) ; if ( irow < ncol && jcol < ncol ) { for ( jrow = ipivot = kk = 0 ; jrow <= irow ; ipivot++ ) { size = m = pivotsizes[ipivot] ; for ( ii = 0 ; ii < m ; ii++, jrow++ ) { if ( jrow == irow ) { if ( jrow - irow > m - ii ) { kk = -1 ; } else { kk += jrow - irow ; } } else { kk += size-- ; } } } if ( kk != -1 ) { *ppValue = entries + kk ; } } } } break ; default : fprintf(stderr, "\n fatal error in SubMtx_locationOfRealEntry(%p,%d,%d,%p)" "\n bad mode %d", mtx, irow, jcol, ppValue, mtx->mode) ; exit(-1) ; break ; } return ; }
/* ------------------------------------------------------- purpose -- to find matrix entry (irow,jcol) if present. return value -- if entry (irow,jcol) is not present then *pReal and *pImag are 0.0 return value is -1 else entry (irow,jcol) is present then (*pReal,*pImag) is the matrix entry return value is offset into entries array endif created -- 98may01, cca ------------------------------------------------------- */ int SubMtx_complexEntry ( SubMtx *mtx, int irow, int jcol, double *pReal, double *pImag ) { /* --------------- check the input --------------- */ if ( mtx == NULL || irow < 0 || irow >= mtx->nrow || jcol < 0 || jcol >= mtx->ncol || pReal == NULL || pImag == NULL ) { fprintf(stderr, "\n fatal error in SubMtx_complexEntry(%p,%d,%d,%p,%p)" "\n bad input\n", mtx, irow, jcol, pReal, pImag) ; exit(-1) ; } if ( ! SUBMTX_IS_COMPLEX(mtx) ) { fprintf(stderr, "\n fatal error in SubMtx_complexEntry(%p,%d,%d,%p,%p)" "\n bad type %d, must be SPOOLES_COMPLEX\n", mtx, irow, jcol, pReal, pImag, mtx->type) ; exit(-1) ; } *pReal = *pImag = 0 ; switch ( mtx->mode ) { case SUBMTX_DENSE_ROWS : case SUBMTX_DENSE_COLUMNS : { double *entries ; int inc1, inc2, ncol, nrow, offset ; SubMtx_denseInfo(mtx, &nrow, &ncol, &inc1, &inc2, &entries) ; if ( irow < 0 || irow >= nrow || jcol < 0 || jcol >= ncol ) { return(-1) ; } offset = irow*inc1 + jcol*inc2 ; *pReal = entries[2*offset] ; *pImag = entries[2*offset+1] ; return(offset) ; } break ; case SUBMTX_SPARSE_ROWS : { double *entries ; int ii, jj, nent, nrow, offset, *indices, *sizes ; SubMtx_sparseRowsInfo(mtx, &nrow, &nent, &sizes, &indices, &entries) ; if ( irow < 0 || irow >= nrow ) { return(-1) ; } for ( ii = offset = 0 ; ii < irow ; ii++ ) { offset += sizes[ii] ; } for ( ii = 0, jj = offset ; ii < sizes[irow] ; ii++, jj++ ) { if ( indices[jj] == jcol ) { *pReal = entries[2*jj] ; *pImag = entries[2*jj+1] ; return(jj) ; } } return(-1) ; } break ; case SUBMTX_SPARSE_COLUMNS : { double *entries ; int ii, jj, nent, ncol, offset, *indices, *sizes ; SubMtx_sparseColumnsInfo(mtx, &ncol, &nent, &sizes, &indices, &entries) ; if ( jcol < 0 || jcol >= ncol ) { return(-1) ; } for ( ii = offset = 0 ; ii < jcol ; ii++ ) { offset += sizes[ii] ; } for ( ii = 0, jj = offset ; ii < sizes[jcol] ; ii++, jj++ ) { if ( indices[jj] == irow ) { *pReal = entries[2*jj] ; *pImag = entries[2*jj+1] ; return(jj) ; } } return(-1) ; } break ; case SUBMTX_SPARSE_TRIPLES : { double *entries ; int ii, nent, *colids, *rowids ; SubMtx_sparseTriplesInfo(mtx, &nent, &rowids, &colids, &entries) ; for ( ii = 0 ; ii < nent ; ii++ ) { if ( irow == rowids[ii] && jcol == colids[ii] ) { *pReal = entries[2*ii] ; *pImag = entries[2*ii+1] ; return(ii) ; } } return(-1) ; } break ; case SUBMTX_DENSE_SUBROWS : { double *entries ; int ii, joff, nent, nrow, offset, *firstlocs, *sizes ; SubMtx_denseSubrowsInfo(mtx, &nrow, &nent, &firstlocs, &sizes, &entries) ; if ( irow < 0 || irow >= nrow || sizes[irow] == 0 ) { return(-1) ; } for ( ii = offset = 0 ; ii < irow ; ii++ ) { offset += sizes[ii] ; } if ( 0 <= (joff = jcol - firstlocs[irow]) && joff < sizes[irow] ) { offset += joff ; *pReal = entries[2*offset] ; *pImag = entries[2*offset+1] ; return(offset) ; } return(-1) ; } break ; case SUBMTX_DENSE_SUBCOLUMNS : { double *entries ; int ii, ioff, nent, ncol, offset, *firstlocs, *sizes ; SubMtx_denseSubcolumnsInfo(mtx, &ncol, &nent, &firstlocs, &sizes, &entries) ; if ( jcol < 0 || jcol >= ncol || sizes[jcol] == 0 ) { return(-1) ; } for ( ii = offset = 0 ; ii < jcol ; ii++ ) { offset += sizes[ii] ; } if ( 0 <= (ioff = irow - firstlocs[jcol]) && ioff < sizes[jcol] ) { offset += ioff ; *pReal = entries[2*offset] ; *pImag = entries[2*offset+1] ; return(offset) ; } return(-1) ; } break ; case SUBMTX_DIAGONAL : { double *entries ; int ncol ; if ( irow < 0 || jcol < 0 || irow != jcol ) { return(-1) ; } SubMtx_diagonalInfo(mtx, &ncol, &entries) ; if ( irow >= ncol || jcol >= ncol ) { return(-1) ; } *pReal = entries[2*irow] ; *pImag = entries[2*irow+1] ; return(irow) ; } break ; case SUBMTX_BLOCK_DIAGONAL_SYM : { double *entries ; int ii, ipivot, jrow, kk, m, ncol, nent, size ; int *pivotsizes ; if ( irow < 0 || jcol < 0 ) { return(-1) ; } if ( irow > jcol ) { ii = irow ; irow = jcol ; jcol = ii ; } SubMtx_blockDiagonalInfo(mtx, &ncol, &nent, &pivotsizes, &entries) ; if ( irow >= ncol || jcol >= ncol ) { return(-1) ; } for ( jrow = ipivot = kk = 0 ; jrow <= irow ; ipivot++ ) { size = m = pivotsizes[ipivot] ; for ( ii = 0 ; ii < m ; ii++, jrow++ ) { if ( jrow == irow ) { if ( jcol - irow > m - ii - 1 ) { return(-1) ; } else { kk += jcol - irow ; *pReal = entries[2*kk] ; *pImag = entries[2*kk+1] ; return(kk) ; } } else { kk += size-- ; } } } return(kk) ; } break ; case SUBMTX_BLOCK_DIAGONAL_HERM : { double sign ; double *entries ; int ii, ipivot, jrow, kk, m, ncol, nent, size ; int *pivotsizes ; if ( irow < 0 || jcol < 0 ) { return(-1) ; } if ( irow > jcol ) { ii = irow ; irow = jcol ; jcol = ii ; sign = -1.0 ; } else { sign = 1.0 ; } SubMtx_blockDiagonalInfo(mtx, &ncol, &nent, &pivotsizes, &entries) ; if ( irow >= ncol || jcol >= ncol ) { return(-1) ; } for ( jrow = ipivot = kk = 0 ; jrow <= irow ; ipivot++ ) { size = m = pivotsizes[ipivot] ; for ( ii = 0 ; ii < m ; ii++, jrow++ ) { if ( jrow == irow ) { if ( jcol - irow > m - ii - 1 ) { return(-1) ; } else { kk += jcol - irow ; *pReal = entries[2*kk] ; *pImag = sign*entries[2*kk+1] ; return(kk) ; } } else { kk += size-- ; } } } return(kk) ; } break ; default : fprintf(stderr, "\n fatal error in SubMtx_complexEntry(%p,%d,%d,%p,%p)" "\n bad mode %d", mtx, irow, jcol, pReal, pImag, mtx->mode) ; exit(-1) ; break ; } return(-1) ; }
/* ---------------------------------------------------------------- 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 ; }