ESymSolverStatus Ma27TSolverInterface::Backsolve(Index nrhs, double *rhs_vals) { DBG_START_METH("Ma27TSolverInterface::Backsolve",dbg_verbosity); IpData().TimingStats().LinearSystemBackSolve().Start(); ipfint N=dim_; double* W = new double[maxfrt_]; ipfint* IW1 = new ipfint[nsteps_]; // For each right hand side, call MA27CD for(Index irhs=0; irhs<nrhs; irhs++) { if (DBG_VERBOSITY()>=2) { for (Index i=0; i<dim_; i++) { DBG_PRINT((2, "rhs[%5d] = %23.15e\n", i, rhs_vals[irhs*dim_+i])); } } F77_FUNC(ma27cd,MA27CD)(&N, a_, &la_, iw_, &liw_, W, &maxfrt_, &rhs_vals[irhs*dim_], IW1, &nsteps_, icntl_, cntl_); if (DBG_VERBOSITY()>=2) { for (Index i=0; i<dim_; i++) { DBG_PRINT((2, "sol[%5d] = %23.15e\n", i, rhs_vals[irhs*dim_+i])); } } } delete [] W; delete [] IW1; IpData().TimingStats().LinearSystemBackSolve().End(); return SYMSOLVER_SUCCESS; }
ESymSolverStatus Ma57TSolverInterface::Backsolve( Index nrhs, double *rhs_vals) { DBG_START_METH("Ma27TSolverInterface::Backsolve",dbg_verbosity); if (HaveIpData()) { IpData().TimingStats().LinearSystemBackSolve().Start(); } ipfint n = dim_; ipfint job = 1; ipfint nrhs_X = nrhs; ipfint lrhs = n; ipfint lwork; double* work; lwork = n * nrhs; work = new double[lwork]; // For each right hand side, call MA57CD // XXX MH: MA57 can do several RHSs; just do one solve... // AW: Ok is the following correct? if (DBG_VERBOSITY()>=2) { for (Index irhs=0; irhs<nrhs; irhs++) { for (Index i=0; i<dim_; i++) { DBG_PRINT((2, "rhs[%2d,%5d] = %23.15e\n", irhs, i, rhs_vals[irhs*dim_+i])); } } } F77_FUNC (ma57cd, MA57CD) (&job, &n, wd_fact_, &wd_lfact_, wd_ifact_, &wd_lifact_, &nrhs_X, rhs_vals, &lrhs, work, &lwork, wd_iwork_, wd_icntl_, wd_info_); if (wd_info_[0] != 0) Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error in MA57CD: %d.\n", wd_info_[0]); if (DBG_VERBOSITY()>=2) { for (Index irhs=0; irhs<nrhs; irhs++) { for (Index i=0; i<dim_; i++) { DBG_PRINT((2, "sol[%2d,%5d] = %23.15e\n", irhs, i, rhs_vals[irhs*dim_+i])); } } } delete [] work; if (HaveIpData()) { IpData().TimingStats().LinearSystemBackSolve().End(); } return SYMSOLVER_SUCCESS; }
void TripletToCSRConverter::ConvertValues(Index nonzeros_triplet, const Number* a_triplet, Index nonzeros_compressed, Number* a_compressed) { DBG_START_METH("TSymLinearSolver::ConvertValues", dbg_verbosity); DBG_ASSERT(initialized_); DBG_ASSERT(nonzeros_triplet_==nonzeros_triplet); DBG_ASSERT(nonzeros_compressed_==nonzeros_compressed); for (Index i=0; i<nonzeros_compressed_; i++) { a_compressed[i] = a_triplet[ipos_first_[i]]; } for (Index i=0; i<num_doubles_; i++) { a_compressed[ipos_double_compressed_[i]] += a_triplet[ipos_double_triplet_[i]]; } if (DBG_VERBOSITY()>=2) { for (Index i=0; i<nonzeros_triplet; i++) { DBG_PRINT((2, "atriplet[%5d] = %24.16e\n", i, a_triplet[i])); } for (Index i=0; i<nonzeros_compressed; i++) { DBG_PRINT((2, "acompre[%5d] = %24.16e\n", i, a_compressed[i])); } } }
void TSymLinearSolver::GiveMatrixToSolver(bool new_matrix, const SymMatrix& sym_A) { DBG_START_METH("TSymLinearSolver::GiveMatrixToSolver",dbg_verbosity); DBG_PRINT((1,"new_matrix = %d\n",new_matrix)); double* pa = solver_interface_->GetValuesArrayPtr(); double* atriplet; if (matrix_format_!=SparseSymLinearSolverInterface::Triplet_Format) { atriplet = new double[nonzeros_triplet_]; } else { atriplet = pa; } //DBG_PRINT_MATRIX(3, "Aunscaled", sym_A); TripletHelper::FillValues(nonzeros_triplet_, sym_A, atriplet); if (DBG_VERBOSITY()>=3) { for (Index i=0; i<nonzeros_triplet_; i++) { DBG_PRINT((3, "KKTunscaled(%6d,%6d) = %24.16e\n", airn_[i], ajcn_[i], atriplet[i])); } } if (use_scaling_) { IpData().TimingStats().LinearSystemScaling().Start(); DBG_ASSERT(scaling_factors_); if (new_matrix || just_switched_on_scaling_) { // only compute scaling factors if the matrix has not been // changed since the last call to this method bool retval = scaling_method_->ComputeSymTScalingFactors(dim_, nonzeros_triplet_, airn_, ajcn_, atriplet, scaling_factors_); if (!retval) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Error during computation of scaling factors.\n"); THROW_EXCEPTION(ERROR_IN_LINEAR_SCALING_METHOD, "scaling_method_->ComputeSymTScalingFactors returned false.") } // complain if not in debug mode if (Jnlst().ProduceOutput(J_MOREVECTOR, J_LINEAR_ALGEBRA)) { for (Index i=0; i<dim_; i++) { Jnlst().Printf(J_MOREVECTOR, J_LINEAR_ALGEBRA, "scaling factor[%6d] = %22.17e\n", i, scaling_factors_[i]); } } just_switched_on_scaling_ = false; }
void CachedResults<T>::DebugPrintCachedResults() const { #ifdef IP_DEBUG_CACHE DBG_START_METH("CachedResults<T>::DebugPrintCachedResults", dbg_verbosity); if (DBG_VERBOSITY()>=2 ) { if (!cached_results_) { DBG_PRINT((2,"Currentlt no cached results:\n")); } else { typename std::list< DependentResult<T>* >::const_iterator iter; DBG_PRINT((2,"Current set of cached results:\n")); for (iter = cached_results_->begin(); iter != cached_results_->end(); iter++) { DBG_PRINT((2," DependentResult:0x%x\n", (*iter))); } } } #endif }
/* inline methods */ inline Observer::~Observer() { #ifdef IP_DEBUG_OBSERVER DBG_START_METH("Observer::~Observer", dbg_verbosity); if (DBG_VERBOSITY()>=1) { for (Index i=0; i<(Index)subjects_.size(); i++) { DBG_PRINT((1,"subjects_[%d] = 0x%x\n", i, subjects_[i])); } } #endif // Detach all subjects for (Int i=(Int)(subjects_.size()-1); i>=0; i--) { #ifdef IP_DEBUG_OBSERVER DBG_PRINT((1,"About to detach subjects_[%d] = 0x%x\n", i, subjects_[i])); #endif RequestDetach(NT_All, subjects_[i]); } }
bool Mc19TSymScalingMethod::ComputeSymTScalingFactors(Index n, Index nnz, const ipfint* airn, const ipfint* ajcn, const double* a, double* scaling_factors) { DBG_START_METH("Mc19TSymScalingMethod::ComputeSymTScalingFactors", dbg_verbosity); if (DBG_VERBOSITY()>=2) { for (Index i=0; i<nnz; i++) { DBG_PRINT((2, "%5d A[%5d,%5d] = %23.15e\n", i, airn[i], ajcn[i], a[i])); } } // First copy the symmetric matrix into an unsymmetric (MA28) // format matrix ipfint* AIRN2 = new ipfint[2*nnz]; ipfint* AJCN2 = new ipfint[2*nnz]; double* A2 = new double[2*nnz]; ipfint nnz2=0; for (Index i=0; i<nnz; i++) { if (airn[i]==ajcn[i]) { AIRN2[nnz2] = airn[i]; AJCN2[nnz2] = ajcn[i]; /* // ToDo decide if there should be a cut-off for small values in A // probably based on maximal element in A // DELETEME if (fabs(a[i])<1e-10) { A2[nnz2] = 0.; } else { A2[nnz2] = a[i]; } */ A2[nnz2] = a[i]; nnz2++; } else { AIRN2[nnz2] = airn[i]; AJCN2[nnz2] = ajcn[i]; /* // DELETEME if (fabs(a[i])<1e-10) { A2[nnz2] = 0.; } else { A2[nnz2] = a[i]; } */ A2[nnz2] = a[i]; nnz2++; AIRN2[nnz2] = ajcn[i]; AJCN2[nnz2] = airn[i]; /* // DELETEME if (fabs(a[i])<1e-10) { A2[nnz2] = 0.; } else { A2[nnz2] = a[i]; } */ A2[nnz2] = a[i]; nnz2++; } } if (DBG_VERBOSITY()>=3) { for (Index i=0; i<nnz2; i++) { DBG_PRINT((3, "A2[%5d] = %23.15e\n", i, A2[i])); } } // Call MC19 to get the scaling factors (for the matrix in the // general format) float* R = new float[n]; float* C = new float[n]; float* W = new float[5*n]; F77_FUNC(mc19ad,MC19AD)(&n, &nnz2, A2, AIRN2, AJCN2, R, C, W); delete[] W; if (DBG_VERBOSITY()>=3) { for (Index i=0; i<n; i++) { DBG_PRINT((3, "R[%5d] = %23.15e C[%5d] = %23.15e\n", i, R[i], i, C[i])); } } // Get the symmetric scaling factors as mean of the general ones // If some of the entries in A2 are too large, the scaling factors // are NaN. Here, we check for this and return no scaling factors // if that is the case Number sum=0.; for (Index i=0; i<n; i++) { scaling_factors[i] = exp((double)((R[i]+C[i])/2.)); sum += scaling_factors[i]; } if (!IsFiniteNumber(sum)) { Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, "Scaling factors are invalid - setting them all to 1.\n"); for (Index i=0; i<n; i++) { scaling_factors[i] = 1.; } } if (DBG_VERBOSITY()>=2) { for (Index i=0; i<n; i++) { DBG_PRINT((2, "scaling_factors[%5d] = %23.15e\n", i, scaling_factors[i])); } } // Clean up delete[] C; delete[] R; delete[] A2; delete[] AIRN2; delete[] AJCN2; return true; }
Index TripletToCSRConverter::InitializeConverter(Index dim, Index nonzeros, const Index* airn, const Index* ajcn) { DBG_START_METH("TSymLinearSolver::InitializeStructure", dbg_verbosity); DBG_ASSERT(dim>0); DBG_ASSERT(nonzeros>0); delete[] ia_; delete[] ja_; delete[] ipos_first_; delete[] ipos_double_triplet_; delete[] ipos_double_compressed_; dim_ = dim; nonzeros_triplet_ = nonzeros; // Create a list with all triplet entries std::list<TripletEntry> entry_list(nonzeros); std::list<TripletEntry>::iterator list_iterator = entry_list.begin(); for (Index i=0; i<nonzeros; i++) { list_iterator->Set(airn[i], ajcn[i], i); list_iterator++; } DBG_ASSERT(list_iterator == entry_list.end()); if (DBG_VERBOSITY()>=2) { for (Index i=0; i<nonzeros; i++) { DBG_PRINT((2, "airn[%5d] = %5d acjn[%5d] = %5d\n", i, airn[i], i, ajcn[i])); } } // sort the list entry_list.sort(); // Now got through the list and compute ipos_ arrays and the // number of elements in the compressed format Index* ja_tmp = new Index[nonzeros]; // overestimate memory requirement Index* rc_tmp = NULL; if (hf_ == Full_Format) { rc_tmp = new Index[dim_+1]; } ia_ = new Index[dim_+1]; Index* ipos_first_tmp = new Index[nonzeros]; // overestimate memory requirement Index* ipos_double_triplet_tmp = new Index[nonzeros]; // overestimate memory requirement Index* ipos_double_compressed_tmp = new Index[nonzeros]; // overestimate memory requirement Index nonzeros_compressed_full = 0; nonzeros_compressed_ = 0; Index cur_row = 1; if (hf_ == Full_Format) { // Zero row counts for (Index i=0; i<dim_+1; i++) { rc_tmp[i] = 0; } } // Take care of possible emply rows list_iterator = entry_list.begin(); while (cur_row < list_iterator->IRow()) { ia_[cur_row-1] = 0; cur_row++; } ia_[cur_row-1] = 0; ja_tmp[0] = list_iterator->JCol(); ipos_first_tmp[0] = list_iterator->PosTriplet(); if (hf_ == Full_Format) { // Count in both lower and upper triangles. Count diagonal only once. nonzeros_compressed_full++; rc_tmp[cur_row-1]++; if (cur_row!=list_iterator->JCol()) { nonzeros_compressed_full++; rc_tmp[list_iterator->JCol()-1]++; } } list_iterator++; Index idouble = 0; Index idouble_full = 0; while (list_iterator != entry_list.end()) { Index irow = list_iterator->IRow(); Index jcol = list_iterator->JCol(); if (cur_row == irow && ja_tmp[nonzeros_compressed_] == jcol) { // This element appears repeatedly, add to the double list ipos_double_triplet_tmp[idouble] = list_iterator->PosTriplet(); ipos_double_compressed_tmp[idouble] = nonzeros_compressed_; idouble++; idouble_full++; if (hf_==Full_Format && irow!=jcol) { idouble_full++; } } else { // This is a new element if (hf_==Full_Format) { // Count in both lower and upper triangles. Count diagonal only once. nonzeros_compressed_full++; rc_tmp[jcol-1]++; if (irow!=jcol) { nonzeros_compressed_full++; rc_tmp[irow-1]++; } } nonzeros_compressed_++; ja_tmp[nonzeros_compressed_] = jcol; ipos_first_tmp[nonzeros_compressed_] = list_iterator->PosTriplet(); if (cur_row != irow) { // this is in a new row ia_[cur_row] = nonzeros_compressed_; cur_row++; } } list_iterator++; } nonzeros_compressed_++; for (Index i=cur_row; i<=dim_; i++) { ia_[i] = nonzeros_compressed_; } DBG_ASSERT(idouble == nonzeros_triplet_-nonzeros_compressed_); // Now copy the ja_tmp array to the (shorter) final one and make // sure that the correct offset is used if (hf_==Triangular_Format) { ja_ = new Index[nonzeros_compressed_]; if (offset_==0) { for (Index i=0; i<nonzeros_compressed_; i++) { ja_[i] = ja_tmp[i] - 1; } } else { for (Index i=0; i<nonzeros_compressed_; i++) { ja_[i] = ja_tmp[i]; } for (Index i=0; i<=dim_; i++) { ia_[i] = ia_[i] + 1; } } delete[] ja_tmp; // Reallocate memory for the "first" array ipos_first_ = new Index[nonzeros_compressed_]; for (Index i=0; i<nonzeros_compressed_; i++) { ipos_first_[i] = ipos_first_tmp[i]; } delete[] ipos_first_tmp; // Reallocate memory for the "double" arrays ipos_double_triplet_ = new Index[idouble]; ipos_double_compressed_ = new Index[idouble]; for (Index i=0; i<idouble; i++) { ipos_double_triplet_[i] = ipos_double_triplet_tmp[i]; ipos_double_compressed_[i] = ipos_double_compressed_tmp[i]; } delete[] ipos_double_triplet_tmp; delete[] ipos_double_compressed_tmp; num_doubles_ = nonzeros_triplet_ - nonzeros_compressed_; } else { // hf_==Full_Format // Setup ia_tmp to contain insert position for column i as ia_tmp[i+1] Index *ia_tmp = new Index[dim_+1]; ia_tmp[0] = 0; ia_tmp[1] = 0; for (Index i=1; i<dim_; i++) { ia_tmp[i+1] = ia_tmp[i] + rc_tmp[i-1]; } delete[] rc_tmp; // Loop over elements of matrix, copying them and duplicating as required ja_ = new Index[nonzeros_compressed_full]; ipos_first_ = new Index[nonzeros_compressed_full]; ipos_double_triplet_ = new Index[idouble_full]; ipos_double_compressed_ = new Index[idouble_full]; Index jd1=0; // Entry into ipos_double_compressed_tmp Index jd2=0; // Entry into ipos_double_compressed_ for (Index i=0; i<dim_; i++) { for (Index j=ia_[i]; j<ia_[i+1]; j++) { Index jrow = ja_tmp[j]-1; ja_[ia_tmp[i+1]] = jrow + offset_; ipos_first_[ia_tmp[i+1]] = ipos_first_tmp[j]; while (jd1<idouble && j==ipos_double_compressed_tmp[jd1]) { ipos_double_triplet_[jd2] = ipos_double_triplet_tmp[jd1]; ipos_double_compressed_[jd2] = ia_tmp[i+1]; jd2++; if (jrow!=i) { ipos_double_triplet_[jd2] = ipos_double_triplet_tmp[jd1]; ipos_double_compressed_[jd2] = ia_tmp[jrow+1]; } jd1++; } ia_tmp[i+1]++; if (jrow!=i) { ja_[ia_tmp[jrow+1]] = i + offset_; ipos_first_[ia_tmp[jrow+1]] = ipos_first_tmp[j]; ia_tmp[jrow+1]++; } } } delete[] ja_tmp; delete[] ipos_first_tmp; delete[] ipos_double_triplet_tmp; delete[] ipos_double_compressed_tmp; // Copy ia_tmp to ia_ with offset_ adjustment for (Index i=0; i<dim_+1; i++) { ia_[i] = ia_tmp[i] + offset_; } delete[] ia_tmp; // Set nonzeros_compressed_ to correct size nonzeros_compressed_ = nonzeros_compressed_full; num_doubles_ = idouble_full; } initialized_ = true; if (DBG_VERBOSITY()>=2) { for (Index i=0; i<=dim_; i++) { DBG_PRINT((2, "ia[%5d] = %5d\n", i, ia_[i])); } for (Index i=0; i<nonzeros_compressed_; i++) { DBG_PRINT((2, "ja[%5d] = %5d ipos_first[%5d] = %5d\n", i, ja_[i], i, ipos_first_[i])); } for (Index i=0; i<nonzeros_triplet_-nonzeros_compressed_; i++) { DBG_PRINT((2, "ipos_double_triplet[%5d] = %5d ipos_double_compressed[%5d] = %5d\n", i, ipos_double_triplet_[i], i, ipos_double_compressed_[i])); } } return nonzeros_compressed_; }
Index TripletToCSRConverter::InitializeConverter(Index dim, Index nonzeros, const Index* airn, const Index* ajcn) { DBG_START_METH("TSymLinearSolver::InitializeStructure", dbg_verbosity); DBG_ASSERT(dim>0); DBG_ASSERT(nonzeros>0); delete[] ia_; delete[] ja_; delete[] ipos_first_; delete[] ipos_double_triplet_; delete[] ipos_double_compressed_; dim_ = dim; nonzeros_triplet_ = nonzeros; // Create a list with all triplet entries std::list<TripletEntry> entry_list(nonzeros); std::list<TripletEntry>::iterator list_iterator = entry_list.begin(); for (Index i=0; i<nonzeros; i++) { list_iterator->Set(airn[i], ajcn[i], i); ++list_iterator; } DBG_ASSERT(list_iterator == entry_list.end()); if (DBG_VERBOSITY()>=2) { for (Index i=0; i<nonzeros; i++) { DBG_PRINT((2, "airn[%5d] = %5d acjn[%5d] = %5d\n", i, airn[i], i, ajcn[i])); } } // sort the list entry_list.sort(); // Now got through the list and compute ipos_ arrays and the // number of elements in the compressed format Index* ja_tmp = new Index[nonzeros]; // overestimate memory requirement ia_ = new Index[dim_+1]; Index* ipos_first_tmp = new Index[nonzeros]; // overestimate memory requirement Index* ipos_double_triplet_tmp = new Index[nonzeros]; // overestimate memory requirement Index* ipos_double_compressed_tmp = new Index[nonzeros]; // overestimate memory requirement nonzeros_compressed_ = 0; Index cur_row = 1; // The first element must be the first diagonal element list_iterator = entry_list.begin(); DBG_ASSERT(list_iterator->IRow()==1); DBG_ASSERT(list_iterator->JCol()==1); ia_[0] = 0; ja_tmp[0] = 1; ipos_first_tmp[0] = list_iterator->PosTriplet(); ++list_iterator; Index idouble = 0; while (list_iterator != entry_list.end()) { Index irow = list_iterator->IRow(); Index jcol = list_iterator->JCol(); if (cur_row == irow && ja_tmp[nonzeros_compressed_] == jcol) { // This element appears repeatedly, add to the double list ipos_double_triplet_tmp[idouble] = list_iterator->PosTriplet(); ipos_double_compressed_tmp[idouble] = nonzeros_compressed_; idouble++; } else { // This is a new element nonzeros_compressed_++; ja_tmp[nonzeros_compressed_] = jcol; ipos_first_tmp[nonzeros_compressed_] = list_iterator->PosTriplet(); if (cur_row != irow) { // this is in a new row // make sure that the diagonal element is given and that no // row is omitted DBG_ASSERT(irow==jcol); DBG_ASSERT(cur_row+1==irow); ia_[cur_row] = nonzeros_compressed_; cur_row++; } } ++list_iterator; } nonzeros_compressed_++; ia_[dim_] = nonzeros_compressed_; DBG_ASSERT(cur_row == dim_); DBG_ASSERT(idouble == nonzeros_triplet_-nonzeros_compressed_); // Now copy the ja_tmp array to the (shorter) final one and make // sure that the correct offset is used ja_ = new Index[nonzeros_compressed_]; if (offset_==0) { for (Index i=0; i<nonzeros_compressed_; i++) { ja_[i] = ja_tmp[i] - 1; } } else { for (Index i=0; i<nonzeros_compressed_; i++) { ja_[i] = ja_tmp[i]; } for (Index i=0; i<=dim_; i++) { ia_[i] = ia_[i] + 1; } } delete[] ja_tmp; // Reallocate memory for the "first" array ipos_first_ = new Index[nonzeros_compressed_]; for (Index i=0; i<nonzeros_compressed_; i++) { ipos_first_[i] = ipos_first_tmp[i]; } delete[] ipos_first_tmp; // Reallocate memory for the "double" arrays ipos_double_triplet_ = new Index[idouble]; ipos_double_compressed_ = new Index[idouble]; for (Index i=0; i<idouble; i++) { ipos_double_triplet_[i] = ipos_double_triplet_tmp[i]; ipos_double_compressed_[i] = ipos_double_compressed_tmp[i]; } delete[] ipos_double_triplet_tmp; delete[] ipos_double_compressed_tmp; initialized_ = true; if (DBG_VERBOSITY()>=2) { for (Index i=0; i<=dim_; i++) { DBG_PRINT((2, "ia[%5d] = %5d\n", i, ia_[i])); } for (Index i=0; i<nonzeros_compressed_; i++) { DBG_PRINT((2, "ja[%5d] = %5d ipos_first[%5d] = %5d\n", i, ja_[i], i, ipos_first_[i])); } for (Index i=0; i<nonzeros_triplet_-nonzeros_compressed_; i++) { DBG_PRINT((2, "ipos_double_triplet[%5d] = %5d ipos_double_compressed[%5d] = %5d\n", i, ipos_double_triplet_[i], i, ipos_double_compressed_[i])); } } return nonzeros_compressed_; }