void MultiVectorMatrix::AddRightMultMatrix(Number a, const MultiVectorMatrix& U, const Matrix& C, Number b) { DBG_ASSERT(NRows()==U.NRows()); DBG_ASSERT(U.NCols()==C.NRows()); DBG_ASSERT(NCols()==C.NCols()); if (b==0.) { FillWithNewVectors(); } // ToDo: For now, we simply use MatrixVector multiplications, but // we might be more efficient (at least in the non-parallel case) // if we used Level 3 Blas SmartPtr<const DenseVectorSpace> mydspace = new DenseVectorSpace(C.NRows()); SmartPtr<DenseVector> mydvec = mydspace->MakeNewDenseVector(); const DenseGenMatrix* dgm_C = static_cast<const DenseGenMatrix*>(&C); DBG_ASSERT(dynamic_cast<const DenseGenMatrix*>(&C)); for (Index i=0; i<NCols(); i++) { const Number* CValues = dgm_C->Values(); Number* myvalues = mydvec->Values(); for (Index j=0; j<U.NCols(); j++) { myvalues[j] = CValues[i*C.NRows() + j]; } U.MultVector(a, *mydvec, b, *Vec(i)); } ObjectChanged(); }
ESymSolverStatus LowRankAugSystemSolver::Solve( const SymMatrix* W, double W_factor, const Vector* D_x, double delta_x, const Vector* D_s, double delta_s, const Matrix* J_c, const Vector* D_c, double delta_c, const Matrix* J_d, const Vector* D_d, double delta_d, const Vector& rhs_x, const Vector& rhs_s, const Vector& rhs_c, const Vector& rhs_d, Vector& sol_x, Vector& sol_s, Vector& sol_c, Vector& sol_d, bool check_NegEVals, Index numberOfNegEVals ) { DBG_START_METH("LowRankAugSystemSolver::Solve", dbg_verbosity); ESymSolverStatus retval; if( first_call_ ) { DBG_ASSERT(IsNull(Wdiag_)); // Set up the diagonal matrix Wdiag_ Index dimx = rhs_x.Dim(); SmartPtr<DiagMatrixSpace> Wdiag_space = new DiagMatrixSpace(dimx); Wdiag_ = Wdiag_space->MakeNewDiagMatrix(); } // This might be used with a linear solver that cannot detect the // inertia. In that case, we should not asked for checking the // number of negative eigenvalues. if( !aug_system_solver_->ProvidesInertia() ) { check_NegEVals = false; } if( first_call_ || AugmentedSystemRequiresChange(W, W_factor, D_x, delta_x, D_s, delta_s, *J_c, D_c, delta_c, *J_d, D_d, delta_d) ) { retval = UpdateFactorization(W, W_factor, D_x, delta_x, D_s, delta_s, *J_c, D_c, delta_c, *J_d, D_d, delta_d, rhs_x, rhs_s, rhs_c, rhs_d, check_NegEVals, numberOfNegEVals); if( retval != SYMSOLVER_SUCCESS ) { return retval; } // Store the tags w_tag_ = W->GetTag(); w_factor_ = W_factor; if( D_x ) { d_x_tag_ = D_x->GetTag(); } else { d_x_tag_ = 0; } delta_x_ = delta_x; if( D_s ) { d_s_tag_ = D_s->GetTag(); } else { d_s_tag_ = 0; } delta_s_ = delta_s; if( J_c ) { j_c_tag_ = J_c->GetTag(); } else { j_c_tag_ = 0; } if( D_c ) { d_c_tag_ = D_c->GetTag(); } else { d_c_tag_ = 0; } delta_c_ = delta_c; if( J_d ) { j_d_tag_ = J_d->GetTag(); } else { j_d_tag_ = 0; } if( D_d ) { d_d_tag_ = D_d->GetTag(); } else { d_d_tag_ = 0; } delta_d_ = delta_d; first_call_ = false; } // Now solve the system for the given right hand side, using the // Sherman-Morrison formula with factorization information already // computed. retval = aug_system_solver_->Solve(GetRawPtr(Wdiag_), W_factor, D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c, J_d, D_d, delta_d, rhs_x, rhs_s, rhs_c, rhs_d, sol_x, sol_s, sol_c, sol_d, check_NegEVals, numberOfNegEVals); if( aug_system_solver_->ProvidesInertia() ) { num_neg_evals_ = aug_system_solver_->NumberOfNegEVals(); } if( retval != SYMSOLVER_SUCCESS ) { Jnlst().Printf(J_DETAILED, J_SOLVE_PD_SYSTEM, "LowRankAugSystemSolver: AugSystemSolver returned retval = %d for right hand side.\n", retval); return retval; } if( IsValid(Vtilde1_) || IsValid(Utilde2_) ) { // Create a CompoundVectors to store the right hand side and // solutions SmartPtr<CompoundVector> crhs = compound_sol_vecspace_->MakeNewCompoundVector(false); crhs->SetComp(0, rhs_x); crhs->SetComp(1, rhs_s); crhs->SetComp(2, rhs_c); crhs->SetComp(3, rhs_d); SmartPtr<CompoundVector> csol = compound_sol_vecspace_->MakeNewCompoundVector(false); csol->SetCompNonConst(0, sol_x); csol->SetCompNonConst(1, sol_s); csol->SetCompNonConst(2, sol_c); csol->SetCompNonConst(3, sol_d); if( IsValid(Utilde2_) ) { Index nU = Utilde2_->NCols(); SmartPtr<DenseVectorSpace> bUspace = new DenseVectorSpace(nU); SmartPtr<DenseVector> bU = bUspace->MakeNewDenseVector(); Utilde2_->TransMultVector(1., *crhs, 0., *bU); J2_->CholeskySolveVector(*bU); Utilde2_->MultVector(1., *bU, 1., *csol); } if( IsValid(Vtilde1_) ) { Index nV = Vtilde1_->NCols(); SmartPtr<DenseVectorSpace> bVspace = new DenseVectorSpace(nV); SmartPtr<DenseVector> bV = bVspace->MakeNewDenseVector(); Vtilde1_->TransMultVector(1., *crhs, 0., *bV); J1_->CholeskySolveVector(*bV); Vtilde1_->MultVector(-1., *bV, 1., *csol); } } return retval; }