LUSOLmat *LUSOL_matcreate(int dim, int nz) { LUSOLmat *newm; newm = (LUSOLmat *) LUSOL_CALLOC(1, sizeof(*newm)); if(newm != NULL) { newm->a = (REAL *) LUSOL_MALLOC((nz+1)*sizeof(REAL)); newm->lenx = (int *) LUSOL_MALLOC((dim+1)*sizeof(int)); newm->indx = (int *) LUSOL_MALLOC((dim+1)*sizeof(int)); newm->indr = (int *) LUSOL_MALLOC((nz+1)*sizeof(int)); newm->indc = (int *) LUSOL_MALLOC((nz+1)*sizeof(int)); if((newm->a == NULL) || (newm->lenx == NULL) || (newm->indx == NULL) || (newm->indr == NULL) || (newm->indc == NULL)) LUSOL_matfree(&newm); } return(newm); }
LUSOLrec *LUSOL_create(FILE *outstream, int msgfil, int pivotmodel, int updatelimit) { LUSOLrec *newLU; newLU = (LUSOLrec *) LUSOL_CALLOC(1, sizeof(*newLU)); if(newLU == NULL) return( newLU ); newLU->luparm[LUSOL_IP_SCALAR_NZA] = LUSOL_MULT_nz_a; newLU->outstream = outstream; newLU->luparm[LUSOL_IP_PRINTUNIT] = msgfil; newLU->luparm[LUSOL_IP_PRINTLEVEL] = LUSOL_MSG_SINGULARITY; LUSOL_setpivotmodel(newLU, pivotmodel, LUSOL_PIVTOL_DEFAULT); newLU->parmlu[LUSOL_RP_GAMMA] = LUSOL_DEFAULT_GAMMA; newLU->parmlu[LUSOL_RP_ZEROTOLERANCE] = 3.0e-13; newLU->parmlu[LUSOL_RP_SMALLDIAG_U] = /*3.7e-11;*/ newLU->parmlu[LUSOL_RP_EPSDIAG_U] = 3.7e-11; newLU->parmlu[LUSOL_RP_COMPSPACE_U] = 3.0e+0; newLU->luparm[LUSOL_IP_MARKOWITZ_MAXCOL] = 5; newLU->parmlu[LUSOL_RP_MARKOWITZ_CONLY] = 0.3e+0; newLU->parmlu[LUSOL_RP_MARKOWITZ_DENSE] = 0.5e+0; newLU->parmlu[LUSOL_RP_SMARTRATIO] = LUSOL_DEFAULT_SMARTRATIO; #ifdef ForceRowBasedL0 newLU->luparm[LUSOL_IP_ACCELERATION] = LUSOL_BASEORDER; #endif newLU->luparm[LUSOL_IP_KEEPLU] = TRUE; newLU->luparm[LUSOL_IP_UPDATELIMIT] = updatelimit; init_BLAS(); return( newLU ); }
/* Create a row-based version of L0. This makes it possible to solve L0'x=h (btran) faster for sparse h, since we only run down the columns of L0' (rows of LO) for which the corresponding entry in h is non-zero. */ MYBOOL LU1L0(LUSOLrec *LUSOL, LUSOLmat **mat, int *inform) { MYBOOL status = FALSE; int K, L, LL, L1, L2, LENL0, NUML0, I; int *lsumr; /* Assume success */ *inform = LUSOL_INFORM_LUSUCCESS; /* Check if there is anything worth doing */ if(mat == NULL) return( status ); if(*mat != NULL) LUSOL_matfree(mat); NUML0 = LUSOL->luparm[LUSOL_IP_COLCOUNT_L0]; LENL0 = LUSOL->luparm[LUSOL_IP_NONZEROS_L0]; if((NUML0 == 0) || (LENL0 == 0) || (LUSOL->luparm[LUSOL_IP_ACCELERATION] == LUSOL_BASEORDER) || ((LUSOL->luparm[LUSOL_IP_ACCELERATION] & LUSOL_ACCELERATE_L0) == 0)) return( status ); /* Allocate temporary array */ lsumr = (int *) LUSOL_CALLOC((LUSOL->m+1), sizeof(*lsumr)); if(lsumr == NULL) { *inform = LUSOL_INFORM_NOMEMLEFT; return( status ); } /* Compute non-zero counts by permuted row index (order is unimportant) */ K = 0; L2 = LUSOL->lena; L1 = L2-LENL0+1; for(L = L1; L <= L2; L++) { I = LUSOL->indc[L]; lsumr[I]++; if(lsumr[I] == 1) K++; } LUSOL->luparm[LUSOL_IP_ROWCOUNT_L0] = K; /* Check if we should apply "smarts" before proceeding to the row matrix creation */ if((LUSOL->luparm[LUSOL_IP_ACCELERATION] & LUSOL_AUTOORDER) && ((REAL) LUSOL->luparm[LUSOL_IP_ROWCOUNT_L0] / #if 0 LUSOL->luparm[LUSOL_IP_COLCOUNT_L0] #else LUSOL->m #endif > LUSOL->parmlu[LUSOL_RP_SMARTRATIO])) goto Finish; /* We are Ok to create the new matrix object */ *mat = LUSOL_matcreate(LUSOL->m, LENL0); if(*mat == NULL) { *inform = LUSOL_INFORM_NOMEMLEFT; goto Finish; } /* Cumulate row counts to get vector offsets; first row is leftmost (stick with Fortran array offset for consistency) */ (*mat)->lenx[0] = 1; for(K = 1; K <= LUSOL->m; K++) { (*mat)->lenx[K] = (*mat)->lenx[K-1] + lsumr[K]; lsumr[K] = (*mat)->lenx[K-1]; } /* Map the matrix into row order by permuted index; Note: The first permuted row is located leftmost in the array. The column order is irrelevant, since the indeces will refer to constant / resolved values of V[] during solve. */ L2 = LUSOL->lena; L1 = L2-LENL0+1; for(L = L1; L <= L2; L++) { I = LUSOL->indc[L]; LL = lsumr[I]++; (*mat)->a[LL] = LUSOL->a[L]; (*mat)->indr[LL] = LUSOL->indr[L]; (*mat)->indc[LL] = I; } /* Pack row starting positions, and set mapper from original index to packed */ I = 0; for(L = 1; L <= LUSOL->m; L++) { K = LUSOL->ip[L]; if((*mat)->lenx[K] > (*mat)->lenx[K-1]) { I++; (*mat)->indx[I] = K; } } /* Confirm that everything went well */ status = TRUE; /* Clean up */ Finish: FREE(lsumr); return( status ); }
/* Create a column-based version of U. This makes it possible to solve Ux=h (ftran) faster for sparse h, since we only run down the rows of U (columns of U') for which the corresponding entry in h is non-zero. */ MYBOOL LU1U0(LUSOLrec *LUSOL, LUSOLmat **mat, int *inform) { MYBOOL status = FALSE; int K, L, LL, LENU, NUMU, J; int *lsumc; /* Assume success */ *inform = LUSOL_INFORM_LUSUCCESS; /* Check if there is anything worth doing */ if(mat == NULL) return( status ); if(*mat != NULL) LUSOL_matfree(mat); NUMU = LUSOL->luparm[LUSOL_IP_RANK_U]; LENU = LUSOL->luparm[LUSOL_IP_NONZEROS_U]; if((NUMU == 0) || (LENU == 0) || (LUSOL->luparm[LUSOL_IP_ACCELERATION] == LUSOL_BASEORDER) || ((LUSOL->luparm[LUSOL_IP_ACCELERATION] & LUSOL_ACCELERATE_U) == 0)) return( status ); /* Allocate temporary array */ lsumc = (int *) LUSOL_CALLOC((LUSOL->n+1), sizeof(*lsumc)); if(lsumc == NULL) { *inform = LUSOL_INFORM_NOMEMLEFT; return( status ); } /* Compute non-zero counts by permuted column index (order is unimportant) */ for(L = 1; L <= LENU; L++) { J = LUSOL->indr[L]; lsumc[J]++; } /* Check if we should apply "smarts" before proceeding to the column matrix creation */ if((LUSOL->luparm[LUSOL_IP_ACCELERATION] & LUSOL_AUTOORDER) && ((LPSREAL) sqrt((LPSREAL) NUMU/LENU) > LUSOL->parmlu[LUSOL_RP_SMARTRATIO])) goto Finish; /* We are Ok to create the new matrix object */ *mat = LUSOL_matcreate(LUSOL->n, LENU); if(*mat == NULL) { *inform = LUSOL_INFORM_NOMEMLEFT; goto Finish; } /* Cumulate row counts to get vector offsets; first column is leftmost (stick with Fortran array offset for consistency) */ (*mat)->lenx[0] = 1; for(K = 1; K <= LUSOL->n; K++) { (*mat)->lenx[K] = (*mat)->lenx[K-1] + lsumc[K]; lsumc[K] = (*mat)->lenx[K-1]; } /* Map the matrix into column order by permuted index; Note: The first permuted column is located leftmost in the array. The row order is irrelevant, since the indeces will refer to constant / resolved values of V[] during solve. */ for(L = 1; L <= LENU; L++) { J = LUSOL->indr[L]; LL = lsumc[J]++; (*mat)->a[LL] = LUSOL->a[L]; (*mat)->indr[LL] = J; (*mat)->indc[LL] = LUSOL->indc[L]; } /* Pack column starting positions, and set mapper from original index to packed */ J = 0; for(L = 1; L <= LUSOL->n; L++) { K = LUSOL->iq[L]; #if 1 /* Deactivate to produce a full-rank version (implicit unit diagonals) */ if((*mat)->lenx[K] > (*mat)->lenx[K-1]) #endif { J++; (*mat)->indx[J] = K; } } /* Confirm that everything went well */ status = TRUE; /* Clean up */ Finish: FREE(lsumc); return( status ); }