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(); }
void DenseSymMatrix::HighRankUpdateTranspose(Number alpha, const MultiVectorMatrix& V1, const MultiVectorMatrix& V2, Number beta) { DBG_ASSERT(Dim()==V1.NCols()); DBG_ASSERT(Dim()==V2.NCols()); DBG_ASSERT(beta==0. || initialized_); const Index dim = Dim(); if (beta==0.) { for (Index j=0; j<dim; j++) { for (Index i=j; i<dim; i++) { values_[i+j*dim] = alpha*V1.GetVector(i)->Dot(*V2.GetVector(j)); } } } else { for (Index j=0; j<dim; j++) { for (Index i=j; i<dim; i++) { values_[i+j*dim] = alpha*V1.GetVector(i)->Dot(*V2.GetVector(j)) + beta*values_[i+j*dim]; } } } initialized_ = true; ObjectChanged(); }
void MultiVectorMatrix::AddOneMultiVectorMatrix(Number a, const MultiVectorMatrix& mv1, Number c) { DBG_ASSERT(NRows()==mv1.NRows()); DBG_ASSERT(NCols()==mv1.NCols()); if (c==0.) { FillWithNewVectors(); } for (Index i=0; i<NCols(); i++) { Vec(i)->AddOneVector(a, *mv1.GetVector(i), c); } ObjectChanged(); }
ESymSolverStatus LowRankAugSystemSolver::SolveMultiVector( 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& proto_rhs_x, const Vector& proto_rhs_s, const Vector& proto_rhs_c, const Vector& proto_rhs_d, const MultiVectorMatrix& V, const SmartPtr<const Matrix>& P_LM, SmartPtr<MultiVectorMatrix>& V_x, SmartPtr<MultiVectorMatrix>& Vtilde, SmartPtr<MultiVectorMatrix>& Vtilde_x, bool check_NegEVals, Index numberOfNegEVals ) { DBG_START_METH("LowRankAugSystemSolver::SolveMultiVector", dbg_verbosity); ESymSolverStatus retval; Index nrhs = V.NCols(); DBG_ASSERT(nrhs > 0); SmartPtr<MultiVectorMatrixSpace> V_xspace = new MultiVectorMatrixSpace(nrhs, *proto_rhs_x.OwnerSpace()); V_x = V_xspace->MakeNewMultiVectorMatrix(); // Create the right hand sides std::vector<SmartPtr<const Vector> > rhs_xV(nrhs); std::vector<SmartPtr<const Vector> > rhs_sV(nrhs); std::vector<SmartPtr<const Vector> > rhs_cV(nrhs); std::vector<SmartPtr<const Vector> > rhs_dV(nrhs); for( Index i = 0; i < nrhs; i++ ) { if( IsNull(P_LM) ) { rhs_xV[i] = V.GetVector(i); DBG_ASSERT(rhs_xV[i]->Dim() == proto_rhs_x.Dim()); } else { SmartPtr<Vector> fullx = proto_rhs_x.MakeNew(); P_LM->MultVector(1., *V.GetVector(i), 0., *fullx); rhs_xV[i] = ConstPtr(fullx); } V_x->SetVector(i, *rhs_xV[i]); SmartPtr<Vector> tmp; tmp = proto_rhs_s.MakeNew(); tmp->Set(0.); rhs_sV[i] = ConstPtr(tmp); tmp = proto_rhs_c.MakeNew(); tmp->Set(0.); rhs_cV[i] = ConstPtr(tmp); tmp = proto_rhs_d.MakeNew(); tmp->Set(0.); rhs_dV[i] = ConstPtr(tmp); } // now get space for the solution std::vector<SmartPtr<Vector> > sol_xV(nrhs); std::vector<SmartPtr<Vector> > sol_sV(nrhs); std::vector<SmartPtr<Vector> > sol_cV(nrhs); std::vector<SmartPtr<Vector> > sol_dV(nrhs); for( Index i = 0; i < nrhs; i++ ) { sol_xV[i] = proto_rhs_x.MakeNew(); sol_sV[i] = proto_rhs_s.MakeNew(); sol_cV[i] = proto_rhs_c.MakeNew(); sol_dV[i] = proto_rhs_d.MakeNew(); } // Call the actual augmented system solver to obtain Vtilde retval = aug_system_solver_->MultiSolve(GetRawPtr(Wdiag_), 1.0, D_x, delta_x, D_s, delta_s, &J_c, D_c, delta_c, &J_d, D_d, delta_d, rhs_xV, rhs_sV, rhs_cV, rhs_dV, sol_xV, sol_sV, sol_cV, sol_dV, check_NegEVals, numberOfNegEVals); if( aug_system_solver_->ProvidesInertia() ) { num_neg_evals_ = aug_system_solver_->NumberOfNegEVals(); } if( retval != SYMSOLVER_SUCCESS ) { return retval; } // Pack the results into Vtilde if( IsNull(compound_sol_vecspace_) ) { Index dimx = proto_rhs_x.Dim(); Index dims = proto_rhs_s.Dim(); Index dimc = proto_rhs_c.Dim(); Index dimd = proto_rhs_d.Dim(); Index dimtot = dimx + dims + dimc + dimd; SmartPtr<CompoundVectorSpace> vecspace = new CompoundVectorSpace(4, dimtot); vecspace->SetCompSpace(0, *proto_rhs_x.OwnerSpace()); vecspace->SetCompSpace(1, *proto_rhs_s.OwnerSpace()); vecspace->SetCompSpace(2, *proto_rhs_c.OwnerSpace()); vecspace->SetCompSpace(3, *proto_rhs_d.OwnerSpace()); compound_sol_vecspace_ = ConstPtr(vecspace); } SmartPtr<MultiVectorMatrixSpace> V1space = new MultiVectorMatrixSpace(nrhs, *compound_sol_vecspace_); Vtilde = V1space->MakeNewMultiVectorMatrix(); Vtilde_x = V_xspace->MakeNewMultiVectorMatrix(); for( Index i = 0; i < nrhs; i++ ) { Vtilde_x->SetVector(i, *sol_xV[i]); SmartPtr<CompoundVector> cvec = compound_sol_vecspace_->MakeNewCompoundVector(false); cvec->SetCompNonConst(0, *sol_xV[i]); cvec->SetCompNonConst(1, *sol_sV[i]); cvec->SetCompNonConst(2, *sol_cV[i]); cvec->SetCompNonConst(3, *sol_dV[i]); Vtilde->SetVectorNonConst(i, *cvec); } return retval; }