/// \brief Compute QR factorization [Q,R] = qr(A,0). /// /// \param A [in/out] On input: the multivector to factor. /// Overwritten with garbage on output. /// /// \param Q [out] On output: the (explicitly stored) Q factor in /// the QR factorization of the (input) multivector A. /// /// \param R [out] On output: the R factor in the QR factorization /// of the (input) multivector A. /// /// \param forceNonnegativeDiagonal [in] If true, then (if /// necessary) do extra work (modifying both the Q and R /// factors) in order to force the R factor to have a /// nonnegative diagonal. /// /// \warning Currently, this method only works if A and Q have the /// same communicator and row distribution ("Map," in Petra /// terms) as those of the multivector given to this adapter /// instance's constructor. Otherwise, the result of this /// method is undefined. void factorExplicit (MV& A, MV& Q, dense_matrix_type& R, const bool forceNonnegativeDiagonal=false) { TEUCHOS_TEST_FOR_EXCEPTION (! A.isConstantStride (), std::invalid_argument, "TsqrAdaptor::" "factorExplicit: Input MultiVector A must have constant stride."); TEUCHOS_TEST_FOR_EXCEPTION (! Q.isConstantStride (), std::invalid_argument, "TsqrAdaptor::" "factorExplicit: Input MultiVector Q must have constant stride."); prepareTsqr (Q); // Finish initializing TSQR. // FIXME (mfh 16 Jan 2016) Currently, TSQR is a host-only // implementation. A.template sync<Kokkos::HostSpace> (); A.template modify<Kokkos::HostSpace> (); Q.template sync<Kokkos::HostSpace> (); Q.template modify<Kokkos::HostSpace> (); auto A_view = A.template getLocalView<Kokkos::HostSpace> (); auto Q_view = Q.template getLocalView<Kokkos::HostSpace> (); scalar_type* const A_ptr = reinterpret_cast<scalar_type*> (A_view.ptr_on_device ()); scalar_type* const Q_ptr = reinterpret_cast<scalar_type*> (Q_view.ptr_on_device ()); const bool contiguousCacheBlocks = false; tsqr_->factorExplicitRaw (A_view.dimension_0 (), A_view.dimension_1 (), A_ptr, A.getStride (), Q_ptr, Q.getStride (), R.values (), R.stride (), contiguousCacheBlocks, forceNonnegativeDiagonal); }
/// \brief Rank-revealing decomposition /// /// Using the R factor and explicit Q factor from /// factorExplicit(), compute the singular value decomposition /// (SVD) of R: \f$R = U \Sigma V^*\f$. If R is full rank (with /// respect to the given relative tolerance \c tol), do not modify /// Q or R. Otherwise, compute \f$Q := Q \cdot U\f$ and \f$R := /// \Sigma V^*\f$ in place. If R was modified, then it may not /// necessarily be upper triangular on output. /// /// \param Q [in/out] On input: explicit Q factor computed by /// factorExplicit(). (Must be an orthogonal resp. unitary /// matrix.) On output: If R is of full numerical rank with /// respect to the tolerance tol, Q is unmodified. Otherwise, Q /// is updated so that the first \c rank columns of Q are a /// basis for the column space of A (the original matrix whose /// QR factorization was computed by factorExplicit()). The /// remaining columns of Q are a basis for the null space of A. /// /// \param R [in/out] On input: N by N upper triangular matrix /// with leading dimension LDR >= N. On output: if input is /// full rank, R is unchanged on output. Otherwise, if \f$R = U /// \Sigma V^*\f$ is the SVD of R, on output R is overwritten /// with \f$\Sigma \cdot V^*\f$. This is also an N by N matrix, /// but it may not necessarily be upper triangular. /// /// \param tol [in] Relative tolerance for computing the numerical /// rank of the matrix R. /// /// \return Rank \f$r\f$ of R: \f$ 0 \leq r \leq N\f$. int revealRank (MV& Q, dense_matrix_type& R, const magnitude_type& tol) { TEUCHOS_TEST_FOR_EXCEPTION (! Q.isConstantStride (), std::invalid_argument, "TsqrAdaptor::" "revealRank: Input MultiVector Q must have constant stride."); prepareTsqr (Q); // Finish initializing TSQR. // FIXME (mfh 18 Oct 2010) Check Teuchos::Comm<int> object in Q // to make sure it is the same communicator as the one we are // using in our dist_tsqr_type implementation. Q.template sync<Kokkos::HostSpace> (); Q.template modify<Kokkos::HostSpace> (); auto Q_view = Q.template getLocalView<Kokkos::HostSpace> (); scalar_type* const Q_ptr = reinterpret_cast<scalar_type*> (Q_view.ptr_on_device ()); const bool contiguousCacheBlocks = false; return tsqr_->revealRankRaw (Q_view.dimension_0 (), Q_view.dimension_1 (), Q_ptr, Q.getStride (), R.values (), R.stride (), tol, contiguousCacheBlocks); }