ScaledMatrixSpace::ScaledMatrixSpace( const SmartPtr<const Vector>& row_scaling, bool row_scaling_reciprocal, const SmartPtr<const MatrixSpace>& unscaled_matrix_space, const SmartPtr<const Vector>& column_scaling, bool column_scaling_reciprocal) : MatrixSpace(unscaled_matrix_space->NRows(), unscaled_matrix_space->NCols()), unscaled_matrix_space_(unscaled_matrix_space) { if (IsValid(row_scaling)) { row_scaling_ = row_scaling->MakeNewCopy(); if (row_scaling_reciprocal) { row_scaling_->ElementWiseReciprocal(); } } else { row_scaling_ = NULL; } if (IsValid(column_scaling)) { column_scaling_ = column_scaling->MakeNewCopy(); if (column_scaling_reciprocal) { column_scaling_->ElementWiseReciprocal(); } } else { column_scaling_ = NULL; } }
inline Index Matrix::NCols() const { return owner_space_->NCols(); }
ESymSolverStatus LowRankAugSystemSolver::UpdateFactorization( 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& proto_rhs_x, const Vector& proto_rhs_s, const Vector& proto_rhs_c, const Vector& proto_rhs_d, bool check_NegEVals, Index numberOfNegEVals ) { DBG_START_METH("LowRankAugSystemSolver::UpdateFactorization", dbg_verbosity); DBG_ASSERT(W_factor == 0.0 || W_factor == 1.0); ESymSolverStatus retval = SYMSOLVER_SUCCESS; // Get the low update information out of W const LowRankUpdateSymMatrix* LR_W = static_cast<const LowRankUpdateSymMatrix*>(W); DBG_ASSERT(LR_W); DBG_PRINT_MATRIX(2, "LR_W", *LR_W); SmartPtr<const Vector> B0; SmartPtr<const MultiVectorMatrix> V; SmartPtr<const MultiVectorMatrix> U; if( W_factor == 1.0 ) { V = LR_W->GetV(); U = LR_W->GetU(); B0 = LR_W->GetDiag(); } SmartPtr<const Matrix> P_LM = LR_W->P_LowRank(); SmartPtr<const VectorSpace> LR_VecSpace = LR_W->LowRankVectorSpace(); if( IsNull(B0) ) { SmartPtr<Vector> zero_B0 = (IsValid(P_LM)) ? LR_VecSpace->MakeNew() : proto_rhs_x.MakeNew(); zero_B0->Set(0.0); B0 = GetRawPtr(zero_B0); } // set up the Hessian for the underlying augmented system solver // without the low-rank update if( IsValid(P_LM) && LR_W->ReducedDiag() ) { DBG_ASSERT(IsValid(B0)); SmartPtr<Vector> fullx = proto_rhs_x.MakeNew(); P_LM->MultVector(1., *B0, 0., *fullx); Wdiag_->SetDiag(*fullx); } else { Wdiag_->SetDiag(*B0); DBG_PRINT_VECTOR(2, "B0", *B0); } SmartPtr<MultiVectorMatrix> Vtilde1_x; if( IsValid(V) ) { SmartPtr<MultiVectorMatrix> V_x; Index nV = V->NCols(); //DBG_PRINT((1, "delta_x = %e\n", delta_x)); //DBG_PRINT_MATRIX(2, "V", *V); retval = SolveMultiVector(D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c, J_d, D_d, delta_d, proto_rhs_x, proto_rhs_s, proto_rhs_c, proto_rhs_d, *V, P_LM, V_x, Vtilde1_, Vtilde1_x, check_NegEVals, numberOfNegEVals); if( retval != SYMSOLVER_SUCCESS ) { Jnlst().Printf(J_DETAILED, J_SOLVE_PD_SYSTEM, "LowRankAugSystemSolver: SolveMultiVector returned retval = %d for V.\n", retval); return retval; } //DBG_PRINT_MATRIX(2, "Vtilde1_x", *Vtilde1_x); SmartPtr<DenseSymMatrixSpace> M1space = new DenseSymMatrixSpace(nV); SmartPtr<DenseSymMatrix> M1 = M1space->MakeNewDenseSymMatrix(); M1->FillIdentity(); M1->HighRankUpdateTranspose(1., *Vtilde1_x, *V_x, 1.); //DBG_PRINT_MATRIX(2, "M1", *M1); SmartPtr<DenseGenMatrixSpace> J1space = new DenseGenMatrixSpace(nV, nV); J1_ = J1space->MakeNewDenseGenMatrix(); bool retchol = J1_->ComputeCholeskyFactor(*M1); // M1 must be positive definite! //DBG_ASSERT(retchol); if( !retchol ) { Jnlst().Printf(J_DETAILED, J_SOLVE_PD_SYSTEM, "LowRankAugSystemSolver: Cholesky for M1 returned error!\n"); retval = SYMSOLVER_WRONG_INERTIA; num_neg_evals_++; return retval; } } else { Vtilde1_ = NULL; J1_ = NULL; } if( IsValid(U) ) { Index nU = U->NCols(); SmartPtr<MultiVectorMatrix> U_x; SmartPtr<MultiVectorMatrix> Utilde1; SmartPtr<MultiVectorMatrix> Utilde1_x; SmartPtr<MultiVectorMatrix> Utilde2_x; retval = SolveMultiVector(D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c, J_d, D_d, delta_d, proto_rhs_x, proto_rhs_s, proto_rhs_c, proto_rhs_d, *U, P_LM, U_x, Utilde1, Utilde1_x, check_NegEVals, numberOfNegEVals); if( retval != SYMSOLVER_SUCCESS ) { Jnlst().Printf(J_DETAILED, J_SOLVE_PD_SYSTEM, "LowRankAugSystemSolver: SolveMultiVector returned retval = %d for U.\n", retval); return retval; } if( IsNull(Vtilde1_) ) { Utilde2_ = Utilde1; Utilde2_x = Utilde1_x; } else { Index nV = Vtilde1_->NCols(); SmartPtr<DenseGenMatrixSpace> Cspace = new DenseGenMatrixSpace(nV, nU); SmartPtr<DenseGenMatrix> C = Cspace->MakeNewDenseGenMatrix(); C->HighRankUpdateTranspose(1., *Vtilde1_x, *U_x, 0.); J1_->CholeskySolveMatrix(*C); Utilde2_ = Utilde1; Utilde2_->AddRightMultMatrix(-1, *Vtilde1_, *C, 1.); Utilde2_x = Utilde1_x->MakeNewMultiVectorMatrix(); for( Index i = 0; i < Utilde1_x->NCols(); i++ ) { const CompoundVector* cvec = static_cast<const CompoundVector*>(GetRawPtr(Utilde2_->GetVector(i))); DBG_ASSERT(cvec); Utilde2_x->SetVector(i, *cvec->GetComp(0)); } } SmartPtr<DenseSymMatrixSpace> M2space = new DenseSymMatrixSpace(nU); SmartPtr<DenseSymMatrix> M2 = M2space->MakeNewDenseSymMatrix(); M2->FillIdentity(); M2->HighRankUpdateTranspose(-1., *Utilde2_x, *U_x, 1.); SmartPtr<DenseGenMatrixSpace> J2space = new DenseGenMatrixSpace(nU, nU); J2_ = J2space->MakeNewDenseGenMatrix(); //DBG_PRINT_MATRIX(2, "M2", *M2); bool retchol = J2_->ComputeCholeskyFactor(*M2); if( !retchol ) { Jnlst().Printf(J_DETAILED, J_SOLVE_PD_SYSTEM, "LowRankAugSystemSolver: Cholesky for M2 returned error.\n"); retval = SYMSOLVER_WRONG_INERTIA; num_neg_evals_++; return retval; } } else { J2_ = NULL; Utilde2_ = NULL; } return retval; }