bool IndexPCalculator::GetSchurMatrix(const SmartPtr<const SchurData>& B, SmartPtr<Matrix>& S) { DBG_START_METH("IndexPCalculator::GetSchurMatrix", dbg_verbosity); bool retval = true; Number* S_values; if (!IsValid(S)) { if ( B==data_A() ) { SmartPtr<DenseSymMatrixSpace> S_sym_space = new DenseSymMatrixSpace(B->GetNRowsAdded()); SmartPtr<DenseSymMatrix> dS = new DenseSymMatrix(GetRawPtr(S_sym_space)); S_values = dS->Values(); S = GetRawPtr(dS); } else { SmartPtr<DenseGenMatrixSpace> S_sym_space = new DenseGenMatrixSpace(B->GetNRowsAdded(), B->GetNRowsAdded()); SmartPtr<DenseGenMatrix> dS = new DenseGenMatrix(GetRawPtr(S_sym_space)); S_values = dS->Values(); S = GetRawPtr(dS); } } else { // Try DenseGenMatrix - if NULL, try DenseSymMatrix SmartPtr<DenseGenMatrix> dS_gen = dynamic_cast<DenseGenMatrix*>(GetRawPtr(S)); if (!IsValid(dS_gen)) { SmartPtr<DenseSymMatrix> dS_sym = dynamic_cast<DenseSymMatrix*>(GetRawPtr(S)); S_values = dS_sym->Values(); } else { S_values = dS_gen->Values(); } } /* DenseGenMatrix* dS = static_cast<DenseGenMatrix*>(&S); DBG_ASSERT(dynamic_cast<const DenseGenMatrix*>(&S)); */ // Check whether data_A was changed from the outside if (ncols_!=data_A()->GetNRowsAdded()) { ncols_ = data_A()->GetNRowsAdded(); ComputeP(); } /* DBG_ASSERT(dS->NRows()==dS->NCols()); DBG_ASSERT(dS->NRows()==data_A()->GetNRowsAdded()); */ std::vector<Index> indices; std::vector<Number> factors; // Compute S = B^T*P from indices, factors and P const std::vector<Index>* data_A_idx = dynamic_cast<const IndexSchurData*>(GetRawPtr(data_A()))->GetColIndices(); const std::vector<Index>* data_B_idx = dynamic_cast<const IndexSchurData*>(GetRawPtr(B))->GetColIndices(); Index col_count = 0; for (std::vector<Index>::const_iterator a_it=data_A_idx->begin(); a_it!=data_A_idx->end(); ++a_it) { cols_[*a_it]->GetSchurMatrixRows(data_B_idx, S_values+col_count*ncols_); col_count++; } return retval; }
/* The functions SchurSolve do IFT step, if S_==NULL, and DenseGenSchurDriver otherwise. */ bool DenseGenSchurDriver::SchurSolve(SmartPtr<IteratesVector> lhs, // new left hand side will be stored here SmartPtr<const IteratesVector> rhs, // rhs r_s SmartPtr<Vector> delta_u, // should be (u_p - u_0) WATCH OUT FOR THE SIGN! I like it this way, so that u_0+delta_u = u_p, but victor always used it the other way round, so be careful. At the end, delta_nu is saved in here. SmartPtr<IteratesVector> sol) // the vector K^(-1)*r_s which usually should have been computed before. { DBG_START_METH("DenseGenSchurDriver::SchurSolve", dbg_verbosity); DBG_ASSERT(IsValid(S_)); bool retval; // set up rhs of equation (3.48a) SmartPtr<Vector> delta_rhs = delta_u->MakeNew(); data_B()->Multiply(*sol, *delta_rhs); delta_rhs->Print(Jnlst(),J_VECTOR,J_USER1,"delta_rhs"); delta_rhs->Scal(-1.0); delta_rhs->Axpy(1.0, *delta_u); delta_rhs->Print(Jnlst(),J_VECTOR,J_USER1,"rhs 3.48a"); // solve equation (3.48a) for delta_nu SmartPtr<DenseVector> delta_nu = dynamic_cast<DenseVector*>(GetRawPtr(delta_rhs))->MakeNewDenseVector(); delta_nu->Copy(*delta_rhs); S_->LUSolveVector(*delta_nu); // why is LUSolveVector not bool?? delta_nu->Print(Jnlst(),J_VECTOR,J_USER1,"delta_nu"); // solve equation (3.48b) for lhs (=delta_s) SmartPtr<IteratesVector> new_rhs = lhs->MakeNewIteratesVector(); data_A()->TransMultiply(*delta_nu, *new_rhs); new_rhs->Axpy(-1.0, *rhs); new_rhs->Scal(-1.0); new_rhs->Print(Jnlst(),J_VECTOR,J_USER1,"new_rhs"); retval = backsolver_->Solve(lhs, ConstPtr(new_rhs)); return retval; }
void main(void) { data_B(); data_A(); //P0 = 0x11; while(1); }
bool IndexPCalculator::InitializeImpl(const OptionsList& options, const std::string& prefix) { DBG_START_METH("IndexPCalculator::InitializeImpl", dbg_verbosity); SmartPtr<const IteratesVector> iv = IpData().curr(); nrows_ = 0; for (Index i=0; i<iv->NComps(); ++i) { nrows_+=iv->GetComp(i)->Dim(); } data_A()->Print(Jnlst(),J_VECTOR,J_USER1,"PCalc SchurData"); return true; }
bool IndexPCalculator::ComputeP() { DBG_START_METH("IndexPCalculator::ComputeP", dbg_verbosity); bool retval = true; // 1. check whether all columns needed by data_A() are in map cols_ - we suppose data_A is IndexSchurData const std::vector<Index>* p2col_idx = dynamic_cast<const IndexSchurData*>(GetRawPtr(data_A()))->GetColIndices(); Index col; Number* col_values = NULL; Index curr_dim, curr_schur_row=0; SmartPtr<const DenseVector> comp_vec; const Number* comp_values; std::map< Index, SmartPtr<PColumn> >::iterator find_it; SmartPtr<IteratesVector> col_vec = IpData().curr()->MakeNewIteratesVector(); SmartPtr<IteratesVector> sol_vec = col_vec->MakeNewIteratesVector(); for (std::vector<Index>::const_iterator col_it=p2col_idx->begin(); col_it!=p2col_idx->end(); ++col_it){ col = *col_it; find_it = cols_.find(col); if (find_it==cols_.end()) { // column is in data_A but not in P-matrix ->create data_A()->GetRow(curr_schur_row, *col_vec); retval = Solver()->Solve(sol_vec, ConstPtr(col_vec)); DBG_ASSERT(retval); /* This part is for displaying norm2(I_z*K^(-1)*I_1) */ DBG_PRINT((dbg_verbosity,"\ncurr_schur_row=%d, ",curr_schur_row)); DBG_PRINT((dbg_verbosity,"norm2(z)=%23.16e\n",sol_vec->x()->Nrm2())); /* end displaying norm2 */ DBG_ASSERT(col_values== NULL); col_values = new Number[nrows_]; curr_dim = 0; for (Index j=0; j<sol_vec->NComps(); ++j) { comp_vec = dynamic_cast<const DenseVector*>(GetRawPtr(sol_vec->GetComp(j))); comp_values = comp_vec->Values(); IpBlasDcopy(comp_vec->Dim(), comp_values, 1, col_values+curr_dim,1); curr_dim += comp_vec->Dim(); } cols_[col] = new PColumn(nrows_, col_values); col_values = NULL; } curr_schur_row++; } return retval; }