void nlDeleteContext(NLContext context_in) { __NLContext* context = (__NLContext*)(context_in); if(__nlCurrentContext == context) { __nlCurrentContext = NULL; } if(context->alloc_M) { __nlSparseMatrixDestroy(&context->M); } if(context->alloc_af) { __nlRowColumnDestroy(&context->af); } if(context->alloc_al) { __nlRowColumnDestroy(&context->al); } if(context->alloc_variable) { __NL_DELETE_ARRAY(context->variable); } if(context->alloc_x) { __NL_DELETE_ARRAY(context->x); } if(context->alloc_b) { __NL_DELETE_ARRAY(context->b); } if (context->slu.alloc_slu) { __nlFree_SUPERLU(context); } #ifdef NL_PARANOID __NL_CLEAR(__NLContext, context); #endif __NL_DELETE(context); }
static void __nlFree_SUPERLU(__NLContext *context) { Destroy_SuperNode_Matrix(&(context->slu.L)); Destroy_CompCol_Matrix(&(context->slu.U)); StatFree(&(context->slu.stat)); __NL_DELETE_ARRAY(context->slu.perm_r); __NL_DELETE_ARRAY(context->slu.perm_c); context->slu.alloc_slu = NL_FALSE; }
static void __nlSparseMatrixDestroy(__NLSparseMatrix* M) { NLuint i; __NL_DELETE_ARRAY(M->diag); if(M->storage & __NL_ROWS) { for(i=0; i<M->m; i++) { __nlRowColumnDestroy(&(M->row[i])); } __NL_DELETE_ARRAY(M->row); } if(M->storage & __NL_COLUMNS) { for(i=0; i<M->n; i++) { __nlRowColumnDestroy(&(M->column[i])); } __NL_DELETE_ARRAY(M->column); } #ifdef NL_PARANOID __NL_CLEAR(__NLSparseMatrix,M); #endif }
void nlDeleteContext(NLContext context_in) { __NLContext* context = (__NLContext*)(context_in); int i; if(__nlCurrentContext == context) { __nlCurrentContext = NULL; } if(context->alloc_M) { __nlSparseMatrixDestroy(&context->M); } if(context->alloc_MtM) { __nlSparseMatrixDestroy(&context->MtM); } if(context->alloc_variable) { for(i=0; i<context->nb_variables; i++) { if(context->variable[i].a) { __nlRowColumnDestroy(context->variable[i].a); __NL_DELETE(context->variable[i].a); } } __NL_DELETE_ARRAY(context->variable); } if(context->alloc_b) { __NL_DELETE_ARRAY(context->b); } if(context->alloc_Mtb) { __NL_DELETE_ARRAY(context->Mtb); } if(context->alloc_x) { __NL_DELETE_ARRAY(context->x); } if (context->slu.alloc_slu) { __nlFree_SUPERLU(context); } #ifdef NL_PARANOID __NL_CLEAR(__NLContext, context); #endif __NL_DELETE(context); }
static void __nlRowColumnClear(__NLRowColumn* c) { c->size = 0; c->capacity = 0; __NL_DELETE_ARRAY(c->coeff); }
static void __nlRowColumnDestroy(__NLRowColumn* c) { __NL_DELETE_ARRAY(c->coeff); #ifdef NL_PARANOID __NL_CLEAR(__NLRowColumn, c); #endif }
/* Here is a driver inspired by A. Sheffer's "cow flattener". */ static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation) { /* OpenNL Context */ __NLSparseMatrix* M = (context->least_squares)? &context->MtM: &context->M; NLuint n = context->n; NLuint nnz = __nlSparseMatrixNNZ(M); /* number of non-zero coeffs */ /* Compressed Row Storage matrix representation */ NLint *xa = __NL_NEW_ARRAY(NLint, n+1); NLfloat *rhs = __NL_NEW_ARRAY(NLfloat, n); NLfloat *a = __NL_NEW_ARRAY(NLfloat, nnz); NLint *asub = __NL_NEW_ARRAY(NLint, nnz); NLint *etree = __NL_NEW_ARRAY(NLint, n); /* SuperLU variables */ SuperMatrix At, AtP; NLint info, panel_size, relax; superlu_options_t options; /* Temporary variables */ NLuint i, jj, count; __nl_assert(!(M->storage & __NL_SYMMETRIC)); __nl_assert(M->storage & __NL_ROWS); __nl_assert(M->m == M->n); /* Convert M to compressed column format */ for(i=0, count=0; i<n; i++) { __NLRowColumn *Ri = M->row + i; xa[i] = count; for(jj=0; jj<Ri->size; jj++, count++) { a[count] = Ri->coeff[jj].value; asub[count] = Ri->coeff[jj].index; } } xa[n] = nnz; /* Free M, don't need it anymore at this point */ __nlSparseMatrixClear(M); /* Create superlu A matrix transposed */ sCreate_CompCol_Matrix( &At, n, n, nnz, a, asub, xa, SLU_NC, /* Colum wise, no supernode */ SLU_S, /* floats */ SLU_GE /* general storage */ ); /* Set superlu options */ set_default_options(&options); options.ColPerm = MY_PERMC; options.Fact = DOFACT; StatInit(&(context->slu.stat)); panel_size = sp_ienv(1); /* sp_ienv give us the defaults */ relax = sp_ienv(2); /* Compute permutation and permuted matrix */ context->slu.perm_r = __NL_NEW_ARRAY(NLint, n); context->slu.perm_c = __NL_NEW_ARRAY(NLint, n); if ((permutation == NULL) || (*permutation == -1)) { get_perm_c(3, &At, context->slu.perm_c); if (permutation) memcpy(permutation, context->slu.perm_c, sizeof(NLint)*n); } else memcpy(context->slu.perm_c, permutation, sizeof(NLint)*n); sp_preorder(&options, &At, context->slu.perm_c, etree, &AtP); /* Decompose into L and U */ sgstrf(&options, &AtP, relax, panel_size, etree, NULL, 0, context->slu.perm_c, context->slu.perm_r, &(context->slu.L), &(context->slu.U), &(context->slu.stat), &info); /* Cleanup */ Destroy_SuperMatrix_Store(&At); Destroy_CompCol_Permuted(&AtP); __NL_DELETE_ARRAY(etree); __NL_DELETE_ARRAY(xa); __NL_DELETE_ARRAY(rhs); __NL_DELETE_ARRAY(a); __NL_DELETE_ARRAY(asub); context->slu.alloc_slu = NL_TRUE; return (info == 0); }
/* Here is a driver inspired by A. Sheffer's "cow flattener". */ static NLboolean __nlSolve_SUPERLU( NLboolean do_perm) { /* OpenNL Context */ __NLSparseMatrix* M = &(__nlCurrentContext->M); NLfloat* b = __nlCurrentContext->b; NLfloat* x = __nlCurrentContext->x; /* Compressed Row Storage matrix representation */ NLuint n = __nlCurrentContext->n; NLuint nnz = __nlSparseMatrixNNZ(M); /* Number of Non-Zero coeffs */ NLint* xa = __NL_NEW_ARRAY(NLint, n+1); NLfloat* rhs = __NL_NEW_ARRAY(NLfloat, n); NLfloat* a = __NL_NEW_ARRAY(NLfloat, nnz); NLint* asub = __NL_NEW_ARRAY(NLint, nnz); /* Permutation vector */ NLint* perm_r = __NL_NEW_ARRAY(NLint, n); NLint* perm = __NL_NEW_ARRAY(NLint, n); /* SuperLU variables */ SuperMatrix A, B; /* System */ SuperMatrix L, U; /* Inverse of A */ NLint info; /* status code */ DNformat *vals = NULL; /* access to result */ float *rvals = NULL; /* access to result */ /* SuperLU options and stats */ superlu_options_t options; SuperLUStat_t stat; /* Temporary variables */ __NLRowColumn* Ri = NULL; NLuint i,jj,count; __nl_assert(!(M->storage & __NL_SYMMETRIC)); __nl_assert(M->storage & __NL_ROWS); __nl_assert(M->m == M->n); /* * Step 1: convert matrix M into SuperLU compressed column * representation. * ------------------------------------------------------- */ count = 0; for(i=0; i<n; i++) { Ri = &(M->row[i]); xa[i] = count; for(jj=0; jj<Ri->size; jj++) { a[count] = Ri->coeff[jj].value; asub[count] = Ri->coeff[jj].index; count++; } } xa[n] = nnz; /* Save memory for SuperLU */ __nlSparseMatrixClear(M); /* * Rem: symmetric storage does not seem to work with * SuperLU ... (->deactivated in main SLS::Solver driver) */ sCreate_CompCol_Matrix( &A, n, n, nnz, a, asub, xa, SLU_NR, /* Row_wise, no supernode */ SLU_S, /* floats */ SLU_GE /* general storage */ ); /* Step 2: create vector */ sCreate_Dense_Matrix( &B, n, 1, b, n, SLU_DN, /* Fortran-type column-wise storage */ SLU_S, /* floats */ SLU_GE /* general */ ); /* Step 3: get permutation matrix * ------------------------------ * com_perm: 0 -> no re-ordering * 1 -> re-ordering for A^t.A * 2 -> re-ordering for A^t+A * 3 -> approximate minimum degree ordering */ get_perm_c(do_perm ? 3 : 0, &A, perm); /* Step 4: call SuperLU main routine * --------------------------------- */ set_default_options(&options); options.ColPerm = MY_PERMC; StatInit(&stat); sgssv(&options, &A, perm, perm_r, &L, &U, &B, &stat, &info); /* Step 5: get the solution * ------------------------ * Fortran-type column-wise storage */ vals = (DNformat*)B.Store; rvals = (float*)(vals->nzval); if(info == 0) { for(i = 0; i < n; i++){ x[i] = rvals[i]; } } /* Step 6: cleanup * --------------- */ /* * For these two ones, only the "store" structure * needs to be deallocated (the arrays have been allocated * by us). */ Destroy_SuperMatrix_Store(&A); Destroy_SuperMatrix_Store(&B); /* * These ones need to be fully deallocated (they have been * allocated by SuperLU). */ Destroy_SuperNode_Matrix(&L); Destroy_CompCol_Matrix(&U); StatFree(&stat); __NL_DELETE_ARRAY(xa); __NL_DELETE_ARRAY(rhs); __NL_DELETE_ARRAY(a); __NL_DELETE_ARRAY(asub); __NL_DELETE_ARRAY(perm_r); __NL_DELETE_ARRAY(perm); return (info == 0); }