void LOCA::Homotopy::DeflatedGroup:: extractParameterComponent(bool use_transpose, const NOX::Abstract::MultiVector& v, NOX::Abstract::MultiVector::DenseMatrix& v_p) const { // cast v to an extended multi-vec const LOCA::MultiContinuation::ExtendedMultiVector& mc_v = dynamic_cast<const LOCA::MultiContinuation::ExtendedMultiVector&>(v); // get solution and parameter components Teuchos::RCP<const NOX::Abstract::MultiVector> mc_v_x = mc_v.getXMultiVec(); Teuchos::RCP<const NOX::Abstract::MultiVector::DenseMatrix> mc_v_p = mc_v.getScalars(); // If the underlying system isn't bordered, we're done if (!isBordered) { if (!use_transpose) v_p.assign(*mc_v_p); else for (int j=0; j<v_p.numCols(); j++) for (int i=0; i<v_p.numRows(); i++) v_p(i,j) = (*mc_v_p)(j,i); return; } int w = bordered_grp->getBorderedWidth(); if (!use_transpose) { // Split v_p into 2 block rows, the top to store mc_v_x_p and the bottom // to store mc_v_p int num_cols = v_p.numCols(); NOX::Abstract::MultiVector::DenseMatrix v_p_1(Teuchos::View, v_p, w, num_cols, 0, 0); NOX::Abstract::MultiVector::DenseMatrix v_p_2(Teuchos::View, v_p, 1, num_cols, w, 0); // Decompose mc_v_x bordered_grp->extractParameterComponent(use_transpose,*mc_v_x, v_p_1); v_p_2.assign(*mc_v_p); } else { // Split v_p into 2 block columns, the first to store mc_v_x_p^t and the // the second to store mc_v_p^T int num_rows = v_p.numRows(); NOX::Abstract::MultiVector::DenseMatrix v_p_1(Teuchos::View, v_p, num_rows, w, 0, 0); NOX::Abstract::MultiVector::DenseMatrix v_p_2(Teuchos::View, v_p, num_rows, 1, 0, w); // Decompose mc_v_x bordered_grp->extractParameterComponent(use_transpose,*mc_v_x, v_p_1); for (int j=0; j<1; j++) for (int i=0; i<num_rows; i++) v_p_2(i,j) = (*mc_v_p)(j,i); } }
void LOCA::Extended::MultiVector::multiply( double alpha, const LOCA::Extended::MultiVector& y, NOX::Abstract::MultiVector::DenseMatrix& b) const { // Verify dimensions are consistent if (y.numMultiVecRows != numMultiVecRows || y.numColumns != b.numRows() || y.numScalarRows != numScalarRows || numColumns != b.numCols()) globalData->locaErrorCheck->throwError( "LOCA::Extended::MultiVector::multiply()", "Size of supplied multivector/matrix is incompatible with this multivector"); // Zero out b b.putScalar(0.0); // Create temporary matrix to hold product for each multivec NOX::Abstract::MultiVector::DenseMatrix tmp(b); // Compute and sum products for each multivec for (int i=0; i<numMultiVecRows; i++) { multiVectorPtrs[i]->multiply(alpha, *(y.multiVectorPtrs[i]), tmp); b += tmp; } // Compute and add in product for scalars if (numScalarRows > 0) b.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, alpha, *y.scalarsPtr, *scalarsPtr, 1.0); }
int NOX::TestCompare::testMatrix( const NOX::Abstract::MultiVector::DenseMatrix& mat, const NOX::Abstract::MultiVector::DenseMatrix& mat_expected, double rtol, double atol, const std::string& name) { bool passed; NOX::Abstract::MultiVector::DenseMatrix tmp(mat_expected.numRows(), mat_expected.numCols()); for (int j=0; j<mat_expected.numCols(); j++) for (int i=0; i<mat_expected.numRows(); i++) tmp(i,j) = fabs(mat(i,j)-mat_expected(i,j)) / (atol + rtol * fabs(mat_expected(i,j))); double inf_norm = tmp.normInf(); if (inf_norm < 1) passed = true; else passed = false; if (utils.isPrintType(NOX::Utils::TestDetails)) { os << std::endl << "\tChecking " << name << ": "; if (passed) os << "Passed." << std::endl; else os << "Failed." << std::endl; os << "\t\tComputed norm: " << utils.sciformat(inf_norm) << std::endl << "\t\tRelative Tolerance: " << utils.sciformat(rtol) << std::endl << "\t\tAbsolute Tolerance: " << utils.sciformat(rtol) << std::endl; } if (passed) return 0; else return 1; }
void LOCA::BorderedSolver::HouseholderQR::applyCompactWY( const NOX::Abstract::MultiVector::DenseMatrix& Y1, const NOX::Abstract::MultiVector& Y2, const NOX::Abstract::MultiVector::DenseMatrix& T, NOX::Abstract::MultiVector::DenseMatrix& X1, NOX::Abstract::MultiVector& X2, bool isZeroX1, bool isZeroX2, bool useTranspose) const { if (isZeroX1 && isZeroX2) { X1.putScalar(0.0); X2.init(0.0); return; } int m = Y2.numVectors(); Teuchos::ETransp T_flag; if (useTranspose) T_flag = Teuchos::TRANS; else T_flag = Teuchos::NO_TRANS; NOX::Abstract::MultiVector::DenseMatrix tmp(m, X2.numVectors()); // Compute Y1^T*X1 + Y2^T*X2 if (!isZeroX2) X2.multiply(1.0, Y2, tmp); // Opportunity for optimization here since Y1 is a lower-triangular // matrix with unit diagonal if (!isZeroX2 && !isZeroX1) tmp.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, Y1, X1, 1.0); else if (!isZeroX1) tmp.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, Y1, X1, 0.0); // Compute op(T)*(Y1^T*X1 + Y2^T*X2) dblas.TRMM(Teuchos::LEFT_SIDE, Teuchos::UPPER_TRI, T_flag, Teuchos::NON_UNIT_DIAG, tmp.numRows(), tmp.numCols(), 1.0, T.values(), T.numRows(), tmp.values(), tmp.numRows()); // Compute X1 = X1 + Y1*op(T)*(Y1^T*X1 + Y2^T*X2) // Opportunity for optimization here since Y1 is a lower-triangular // matrix with unit diagonal if (isZeroX1) X1.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, Y1, tmp, 0.0); else X1.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, Y1, tmp, 1.0); // Compute X2 = X2 + Y1*op(T)*(Y1^T*X1 + Y2^T*X2) if (isZeroX2) X2.update(Teuchos::NO_TRANS, 1.0, Y2, tmp, 0.0); else X2.update(Teuchos::NO_TRANS, 1.0, Y2, tmp, 1.0); }
LOCA::MultiContinuation::ExtendedMultiVector::ExtendedMultiVector( const Teuchos::RCP<LOCA::GlobalData>& global_data, const NOX::Abstract::MultiVector& xVec, const NOX::Abstract::MultiVector::DenseMatrix& params) : LOCA::Extended::MultiVector(global_data, xVec.numVectors(), 1, params.numRows()) { LOCA::Extended::MultiVector::setMultiVectorPtr(0, xVec.clone(NOX::DeepCopy)); LOCA::Extended::MultiVector::getScalars()->assign(params); }
void LOCA::BorderedSolver::HouseholderQR::computeHouseholderVector( int col, const NOX::Abstract::MultiVector::DenseMatrix& A1, const NOX::Abstract::MultiVector& A2, NOX::Abstract::MultiVector::DenseMatrix& V1, NOX::Abstract::MultiVector& V2, double& beta) { double houseP = A1(col,col); V1(0,0) = 1.0; V2[0] = A2[col]; double sigma = A2[col].innerProduct(A2[col]); for (int i=col+1; i<A1.numRows(); i++) sigma += A1(i,col)*A1(i,col); if (sigma == 0.0) beta = 0.0; else { double mu = sqrt(houseP*houseP + sigma); if (houseP <= 0.0) houseP = houseP - mu; else houseP = -sigma / (houseP + mu); beta = 2.0*houseP*houseP/(sigma + houseP*houseP); V2.scale(1.0/houseP); for (int i=1; i<V1.numRows(); i++) V1(i,0) = A1(i+col,col) / houseP; } return; }
void NOX::Thyra::MultiVector:: multiply(double alpha, const NOX::Abstract::MultiVector& y, NOX::Abstract::MultiVector::DenseMatrix& b) const { const NOX::Thyra::MultiVector& yy = dynamic_cast<const NOX::Thyra::MultiVector&>(y); int m = b.numRows(); int n = b.numCols(); Teuchos::RCP< ::Thyra::MultiVectorBase<double> > bb = ::Thyra::createMembersView( yy.thyraMultiVec->domain(), RTOpPack::SubMultiVectorView<double>(0, m, 0, n, Teuchos::arcp(b.values(), 0, b.stride()*b.numCols(), false), b.stride() ) ); ::Thyra::apply(*yy.thyraMultiVec, ::Thyra::CONJTRANS, *thyraMultiVec, bb.ptr(), alpha, 0.0); }
NOX::Abstract::Group::ReturnType LOCA::BorderedSolver::LowerTriangularBlockElimination:: solve(Teuchos::ParameterList& params, const LOCA::BorderedSolver::AbstractOperator& op, const LOCA::MultiContinuation::ConstraintInterface& B, const NOX::Abstract::MultiVector::DenseMatrix& C, const NOX::Abstract::MultiVector* F, const NOX::Abstract::MultiVector::DenseMatrix* G, NOX::Abstract::MultiVector& X, NOX::Abstract::MultiVector::DenseMatrix& Y) const { string callingFunction = "LOCA::BorderedSolver::LowerTriangularBlockElimination::solve()"; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; NOX::Abstract::Group::ReturnType status; // Determine if X or Y is zero bool isZeroF = (F == NULL); bool isZeroG = (G == NULL); bool isZeroB = B.isDXZero(); bool isZeroX = isZeroF; bool isZeroY = isZeroG && (isZeroB || isZeroX); // First compute X if (isZeroX) X.init(0.0); else { // Solve X = J^-1 F, note F must be nonzero status = op.applyInverse(params, *F, X); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } // Now compute Y if (isZeroY) Y.putScalar(0.0); else { // Compute G - B^T*X and store in Y if (isZeroG) B.multiplyDX(-1.0, X, Y); else { Y.assign(*G); if (!isZeroB && !isZeroX) { NOX::Abstract::MultiVector::DenseMatrix T(Y.numRows(),Y.numCols()); B.multiplyDX(1.0, X, T); Y -= T; } } // Overwrite Y with Y = C^-1 * (G - B^T*X) NOX::Abstract::MultiVector::DenseMatrix M(C); int *ipiv = new int[M.numRows()]; Teuchos::LAPACK<int,double> L; int info; L.GETRF(M.numRows(), M.numCols(), M.values(), M.stride(), ipiv, &info); if (info != 0) { status = NOX::Abstract::Group::Failed; finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes( status, finalStatus, callingFunction); } L.GETRS('N', M.numRows(), Y.numCols(), M.values(), M.stride(), ipiv, Y.values(), Y.stride(), &info); delete [] ipiv; if (info != 0) { status = NOX::Abstract::Group::Failed; finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes( status, finalStatus, callingFunction); } } return finalStatus; }