void nlEndRow() { NLRowColumn* af = &nlCurrentContext->af ; NLRowColumn* al = &nlCurrentContext->al ; NLRowColumn* xl = &nlCurrentContext->xl ; NLSparseMatrix* M = &nlCurrentContext->M ; NLdouble* b = nlCurrentContext->b ; NLuint nf = af->size ; NLuint nl = al->size ; NLuint current_row = nlCurrentContext->current_row ; NLuint i ; NLuint j ; NLdouble S ; nlTransition(NL_STATE_ROW, NL_STATE_MATRIX) ; if(nlCurrentContext->normalize_rows) { nlNormalizeRow(nlCurrentContext->row_scaling) ; } else { nlScaleRow(nlCurrentContext->row_scaling) ; } // if least_squares : we want to solve // A'A x = A'b // if(nlCurrentContext->least_squares) { if(!nlCurrentContext->matrix_already_set) { for(i=0; i<nf; i++) { for(j=0; j<nf; j++) { nlSparseMatrixAdd( M, af->coeff[i].index, af->coeff[j].index, af->coeff[i].value * af->coeff[j].value ) ; } } } S = - nlCurrentContext->right_hand_side ; for(j=0; j<nl; j++) { S += al->coeff[j].value * xl->coeff[j].value ; } for(i=0; i<nf; i++) { b[af->coeff[i].index] -= af->coeff[i].value * S ; } } else { if(!nlCurrentContext->matrix_already_set) { for(i=0; i<nf; i++) { nlSparseMatrixAdd( M, current_row, af->coeff[i].index, af->coeff[i].value ) ; } } b[current_row] = -nlCurrentContext->right_hand_side ; for(i=0; i<nl; i++) { b[current_row] -= al->coeff[i].value * xl->coeff[i].value ; } } nlCurrentContext->current_row++ ; nlCurrentContext->right_hand_side = 0.0 ; nlCurrentContext->row_scaling = 1.0 ; }
void nlEndMatrix() { nlTransition(NL_STATE_MATRIX, NL_STATE_MATRIX_CONSTRUCTED) ; nlRowColumnDestroy(&nlCurrentContext->af) ; nlCurrentContext->alloc_af = NL_FALSE ; nlRowColumnDestroy(&nlCurrentContext->al) ; nlCurrentContext->alloc_al = NL_FALSE ; nlRowColumnDestroy(&nlCurrentContext->xl) ; nlCurrentContext->alloc_al = NL_FALSE ; if(!nlCurrentContext->least_squares) { nl_assert( nlCurrentContext->current_row == nlCurrentContext->n ) ; } if((nlCurrentContext->solver == NL_CHOLMOD_EXT || // or any other direct solver nlCurrentContext->solver == NL_SUPERLU_EXT || nlCurrentContext->solver == NL_PERM_SUPERLU_EXT || nlCurrentContext->solver == NL_SYMMETRIC_SUPERLU_EXT) && nlCurrentContext->direct_solver_context == NULL) { nlCurrentContext->factorize_func() ; } }
void nlBeginSystem() { nlTransition(NL_STATE_INITIAL, NL_STATE_SYSTEM) ; nl_assert(nlCurrentContext->nb_variables > 0) ; nlCurrentContext->variable = NL_NEW_ARRAY( NLVariable, nlCurrentContext->nb_variables ) ; nlCurrentContext->alloc_variable = NL_TRUE ; }
NLboolean nlSolve() { NLboolean result ; NLdouble start_time = nlCurrentTime() ; nlCheckState(NL_STATE_SYSTEM_CONSTRUCTED) ; nlCurrentContext->elapsed_time = 0 ; result = nlCurrentContext->solver_func() ; nlVectorToVariables() ; nlCurrentContext->elapsed_time = nlCurrentTime() - start_time ; nlTransition(NL_STATE_SYSTEM_CONSTRUCTED, NL_STATE_SOLVED) ; return result ; }
void nlEndRow() { NLRowColumn* af = &nlCurrentContext->af ; NLRowColumn* al = &nlCurrentContext->al ; NLRowColumn* xl = &nlCurrentContext->xl ; NLSparseMatrix* M = &nlCurrentContext->M ; NLdouble* b = nlCurrentContext->b ; NLuint nf = af->size ; NLuint nl = al->size ; NLuint current_row = nlCurrentContext->current_row ; NLuint i ; NLuint j ; NLdouble S ; nlTransition(NL_STATE_ROW, NL_STATE_MATRIX) ; if(nlCurrentContext->normalize_rows) { nlNormalizeRow(nlCurrentContext->row_scaling) ; } else { nlScaleRow(nlCurrentContext->row_scaling) ; } if(nlCurrentContext->least_squares) { for(i=0; i<nf; i++) { for(j=0; j<nf; j++) { nlSparseMatrixAdd( M, af->coeff[i].index, af->coeff[j].index, af->coeff[i].value * af->coeff[j].value ) ; } } S = -nlCurrentContext->right_hand_side ; for(j=0; j<nl; j++) { S += al->coeff[j].value * xl->coeff[j].value ; } for(i=0; i<nf; i++) { b[ af->coeff[i].index ] -= af->coeff[i].value * S ; } } else { for(i=0; i<nf; i++) { nlSparseMatrixAdd( M, current_row, af->coeff[i].index, af->coeff[i].value ) ; } b[current_row] = nlCurrentContext->right_hand_side ; /* [Bruno] Fixed RHS bug in non-least-squares mode*/ for(i=0; i<nl; i++) { b[current_row] -= al->coeff[i].value * xl->coeff[i].value ; } } nlCurrentContext->current_row++ ; nlCurrentContext->right_hand_side = 0.0 ; nlCurrentContext->row_scaling = 1.0 ; }
void nlReset(NLboolean keep_matrix) { switch(nlCurrentContext->state) { case NL_STATE_SOLVED: nlTransition(NL_STATE_SOLVED, NL_STATE_SYSTEM) ; case NL_STATE_SYSTEM: { NLuint i ; if(keep_matrix) { for(i=0; i<nlCurrentContext->n; i++) { nlCurrentContext->x[i] = 0 ; nlCurrentContext->b[i] = 0 ; } nlCurrentContext->matrix_already_set = NL_TRUE ; } else { if(nlCurrentContext->alloc_M) { nlSparseMatrixDestroy(&nlCurrentContext->M) ; nlCurrentContext->alloc_M = NL_FALSE ; } if(nlCurrentContext->alloc_x) { NL_DELETE_ARRAY(nlCurrentContext->x) ; nlCurrentContext->alloc_x = NL_FALSE ; } if(nlCurrentContext->alloc_b) { NL_DELETE_ARRAY(nlCurrentContext->b) ; nlCurrentContext->alloc_b = NL_FALSE ; } for(i=0; i<nlCurrentContext->nb_variables; i++) { nlUnlockVariable(i); } nlCurrentContext->matrix_already_set = NL_FALSE ; if( nlCurrentContext->solver == NL_CHOLMOD_EXT || // or any other direct solver nlCurrentContext->solver == NL_SUPERLU_EXT || nlCurrentContext->solver == NL_PERM_SUPERLU_EXT || nlCurrentContext->solver == NL_SYMMETRIC_SUPERLU_EXT) { nlCurrentContext->clear_factor_func() ; } } } break ; case NL_STATE_INITIAL: { // this is an authorized state for reset // but there is nothing to do.. } break ; default: { nl_assert_not_reached ; } } }
void nlEndMatrix() { nlTransition(NL_STATE_MATRIX, NL_STATE_MATRIX_CONSTRUCTED) ; nlRowColumnDestroy(&nlCurrentContext->af) ; nlCurrentContext->alloc_af = NL_FALSE ; nlRowColumnDestroy(&nlCurrentContext->al) ; nlCurrentContext->alloc_al = NL_FALSE ; nlRowColumnDestroy(&nlCurrentContext->xl) ; nlCurrentContext->alloc_al = NL_FALSE ; if(!nlCurrentContext->least_squares) { nl_assert( nlCurrentContext->current_row == nlCurrentContext->n ) ; } }
void nlBeginRow() { nlTransition(NL_STATE_MATRIX, NL_STATE_ROW) ; nlRowColumnZero(&nlCurrentContext->af) ; nlRowColumnZero(&nlCurrentContext->al) ; nlRowColumnZero(&nlCurrentContext->xl) ; }
void nlBeginMatrix() { NLuint i ; NLuint n = 0 ; NLenum storage = NL_MATRIX_STORE_ROWS ; nlTransition(NL_STATE_SYSTEM, NL_STATE_MATRIX) ; if(!nlCurrentContext->matrix_already_set) { for(i=0; i<nlCurrentContext->nb_variables; i++) { if(!nlCurrentContext->variable[i].locked) { nlCurrentContext->variable[i].index = n ; n++ ; } else { nlCurrentContext->variable[i].index = ~0 ; } } nlCurrentContext->n = n ; /* SSOR preconditioner requires rows and columns */ if(nlCurrentContext->preconditioner == NL_PRECOND_SSOR) { storage = (storage | NL_MATRIX_STORE_COLUMNS) ; } /* a least squares problem results in a symmetric matrix */ if(nlCurrentContext->least_squares && !nlSolverIsCNC(nlCurrentContext->solver)) { nlCurrentContext->symmetric = NL_TRUE ; } if(nlCurrentContext->symmetric) { storage = (storage | NL_MATRIX_STORE_SYMMETRIC) ; } /* SuperLU storage does not support symmetric storage */ if( nlCurrentContext->solver == NL_SUPERLU_EXT || nlCurrentContext->solver == NL_PERM_SUPERLU_EXT || nlCurrentContext->solver == NL_SYMMETRIC_SUPERLU_EXT ) { storage = (storage & ~NL_MATRIX_STORE_SYMMETRIC) ; } /* CHOLMOD storage requires columns */ if(nlCurrentContext->solver == NL_CHOLMOD_EXT) { storage = (storage & ~NL_MATRIX_STORE_ROWS) ; storage = (storage | NL_MATRIX_STORE_COLUMNS) ; } nlSparseMatrixConstruct(&nlCurrentContext->M, n, n, storage) ; nlCurrentContext->alloc_M = NL_TRUE ; nlCurrentContext->x = NL_NEW_ARRAY(NLdouble, n) ; nlCurrentContext->alloc_x = NL_TRUE ; nlCurrentContext->b = NL_NEW_ARRAY(NLdouble, n) ; nlCurrentContext->alloc_b = NL_TRUE ; nlVariablesToVector() ; nlRowColumnConstruct(&nlCurrentContext->af) ; nlCurrentContext->alloc_af = NL_TRUE ; nlRowColumnConstruct(&nlCurrentContext->al) ; nlCurrentContext->alloc_al = NL_TRUE ; nlRowColumnConstruct(&nlCurrentContext->xl) ; nlCurrentContext->alloc_xl = NL_TRUE ; nlCurrentContext->current_row = 0 ; } else { nl_assert(nlCurrentContext->alloc_M) ; nl_assert(nlCurrentContext->alloc_x) ; nl_assert(nlCurrentContext->alloc_b) ; nlRowColumnConstruct(&nlCurrentContext->af) ; nlCurrentContext->alloc_af = NL_TRUE ; nlRowColumnConstruct(&nlCurrentContext->al) ; nlCurrentContext->alloc_al = NL_TRUE ; nlRowColumnConstruct(&nlCurrentContext->xl) ; nlCurrentContext->alloc_xl = NL_TRUE ; nlCurrentContext->current_row = 0 ; } }
void nlEndSystem() { nlTransition(NL_STATE_MATRIX_CONSTRUCTED, NL_STATE_SYSTEM_CONSTRUCTED) ; }