Ejemplo n.º 1
0
int main (int, const char **)
{
  typedef float               ScalarType;     //feel free to change this to 'double' if supported by your hardware
  typedef boost::numeric::ublas::matrix<ScalarType>              MatrixType;
  typedef boost::numeric::ublas::vector<ScalarType>              VectorType;
  typedef viennacl::matrix<ScalarType, viennacl::column_major>   VCLMatrixType;
  typedef viennacl::vector<ScalarType>                           VCLVectorType;

  //
  // Create vectors and matrices with data, cf. http://tutorial.math.lamar.edu/Classes/LinAlg/QRDecomposition.aspx
  //
  VectorType ublas_b(4);
  ublas_b(0) = -4;
  ublas_b(1) =  2;
  ublas_b(2) =  5;
  ublas_b(3) = -1;

  MatrixType ublas_A(4, 3);
  MatrixType Q = boost::numeric::ublas::zero_matrix<ScalarType>(4, 4);
  MatrixType R = boost::numeric::ublas::zero_matrix<ScalarType>(4, 3);

  ublas_A(0, 0) =  2; ublas_A(0, 1) = -1; ublas_A(0, 2) =  1;
  ublas_A(1, 0) =  1; ublas_A(1, 1) = -5; ublas_A(1, 2) =  2;
  ublas_A(2, 0) = -3; ublas_A(2, 1) =  1; ublas_A(2, 2) = -4;
  ublas_A(3, 0) =  1; ublas_A(3, 1) = -1; ublas_A(3, 2) =  1;

  //
  // Setup the matrix in ViennaCL:
  //
  VCLVectorType vcl_b(ublas_b.size());
  VCLMatrixType vcl_A(ublas_A.size1(), ublas_A.size2());

  viennacl::copy(ublas_b, vcl_b);
  viennacl::copy(ublas_A, vcl_A);



  //////////// Part 1: Use Boost.uBLAS for all computations ////////////////

  std::cout << "--- Boost.uBLAS ---" << std::endl;
  std::vector<ScalarType> ublas_betas = viennacl::linalg::inplace_qr(ublas_A);  //computes the QR factorization

  // compute modified RHS of the minimization problem:
  // b' := Q^T b
  viennacl::linalg::inplace_qr_apply_trans_Q(ublas_A, ublas_betas, ublas_b);

  // Final step: triangular solve: Rx = b'', where b'' are the first three entries in b'
  // We only need the upper left square part of A, which defines the upper triangular matrix R
  boost::numeric::ublas::range ublas_range(0, 3);
  boost::numeric::ublas::matrix_range<MatrixType> ublas_R(ublas_A, ublas_range, ublas_range);
  boost::numeric::ublas::vector_range<VectorType> ublas_b2(ublas_b, ublas_range);
  boost::numeric::ublas::inplace_solve(ublas_R, ublas_b2, boost::numeric::ublas::upper_tag());

  std::cout << "Result: " << ublas_b2 << std::endl;

  //////////// Part 2: Use ViennaCL types for BLAS 3 computations, but use Boost.uBLAS for the panel factorization ////////////////

  std::cout << "--- ViennaCL (hybrid implementation)  ---" << std::endl;
  std::vector<ScalarType> hybrid_betas = viennacl::linalg::inplace_qr(vcl_A);

  // compute modified RHS of the minimization problem:
  // b := Q^T b
  viennacl::linalg::inplace_qr_apply_trans_Q(vcl_A, hybrid_betas, vcl_b);

  // Final step: triangular solve: Rx = b'.
  // We only need the upper part of A such that R is a square matrix
  viennacl::range vcl_range(0, 3);
  viennacl::matrix_range<VCLMatrixType> vcl_R(vcl_A, vcl_range, vcl_range);
  viennacl::vector_range<VCLVectorType> vcl_b2(vcl_b, vcl_range);
  viennacl::linalg::inplace_solve(vcl_R, vcl_b2, viennacl::linalg::upper_tag());

  std::cout << "Result: " << vcl_b2 << std::endl;



  //
  //  That's it.
  //
  std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl;

  return EXIT_SUCCESS;
}
Ejemplo n.º 2
0
/**
*  The minimization problem of finding x such that \f$ \Vert Ax - b \Vert \f$ is solved as follows:
*   - Compute the QR-factorization of A = QR.
*   - Compute \f$ b' = Q^{\mathrm{T}} b \f$ for the equivalent minimization problem \f$ \Vert Rx - Q^{\mathrm{T}} b \f$.
*   - Solve the triangular system \f$ \tilde{R} x = b' \f$, where \f$ \tilde{R} \f$ is the upper square matrix of R.
*
**/
int main (int, const char **)
{
    typedef float               ScalarType;     //feel free to change this to 'double' if supported by your hardware

    typedef boost::numeric::ublas::matrix<ScalarType>              MatrixType;
    typedef boost::numeric::ublas::vector<ScalarType>              VectorType;
    typedef viennacl::matrix<ScalarType, viennacl::column_major>   VCLMatrixType;
    typedef viennacl::vector<ScalarType>                           VCLVectorType;

    /**
    *  Create vectors and matrices with data:
    **/
    VectorType ublas_b(4);
    ublas_b(0) = -4;
    ublas_b(1) =  2;
    ublas_b(2) =  5;
    ublas_b(3) = -1;

    MatrixType ublas_A(4, 3);

    ublas_A(0, 0) =  2;
    ublas_A(0, 1) = -1;
    ublas_A(0, 2) =  1;
    ublas_A(1, 0) =  1;
    ublas_A(1, 1) = -5;
    ublas_A(1, 2) =  2;
    ublas_A(2, 0) = -3;
    ublas_A(2, 1) =  1;
    ublas_A(2, 2) = -4;
    ublas_A(3, 0) =  1;
    ublas_A(3, 1) = -1;
    ublas_A(3, 2) =  1;

    /**
    * Setup the matrix and vector with ViennaCL objects and copy the data from the uBLAS objects:
    **/
    VCLVectorType vcl_b(ublas_b.size());
    VCLMatrixType vcl_A(ublas_A.size1(), ublas_A.size2());

    viennacl::copy(ublas_b, vcl_b);
    viennacl::copy(ublas_A, vcl_A);


    /**
    * <h2>Option 1: Using Boost.uBLAS</h2>
    *
    * The implementation in ViennaCL accepts both uBLAS and ViennaCL types.
    * We start with a single-threaded implementation using Boost.uBLAS.
    **/

    std::cout << "--- Boost.uBLAS ---" << std::endl;
    /**
    * The first (and computationally most expensive) step is to compute the QR factorization of A.
    * Since we do not need A later, we directly overwrite A with the householder reflectors and the upper triangular matrix R.
    * The returned vector holds the scalar coefficients (betas) for the Householder reflections \f$ I - \beta v v^{\mathrm{T}} \f$
    **/
    std::vector<ScalarType> ublas_betas = viennacl::linalg::inplace_qr(ublas_A);

    /**
    * Compute the modified RHS of the minimization problem from the QR factorization, but do not form \f$ Q^{\mathrm{T}} \f$ explicitly:
    * b' := Q^T b
    **/
    viennacl::linalg::inplace_qr_apply_trans_Q(ublas_A, ublas_betas, ublas_b);

    /**
    * Final step: triangular solve: Rx = b'', where b'' are the first three entries in b'
    * We only need the upper left square part of A, which defines the upper triangular matrix R
    **/
    boost::numeric::ublas::range ublas_range(0, 3);
    boost::numeric::ublas::matrix_range<MatrixType> ublas_R(ublas_A, ublas_range, ublas_range);
    boost::numeric::ublas::vector_range<VectorType> ublas_b2(ublas_b, ublas_range);
    boost::numeric::ublas::inplace_solve(ublas_R, ublas_b2, boost::numeric::ublas::upper_tag());

    std::cout << "Result: " << ublas_b2 << std::endl;

    /**
    *  <h2>Option 2: Use ViennaCL types</h2>
    *
    *  ViennaCL is used for the computationally intensive BLAS 3 computations.
    *  Boost.uBLAS is used for the panel factorization on the host (CPU).
    */

    std::cout << "--- ViennaCL (hybrid implementation)  ---" << std::endl;
    std::vector<ScalarType> hybrid_betas = viennacl::linalg::inplace_qr(vcl_A);

    /**
    * compute modified RHS of the minimization problem: \f$ b' := Q^T b \f$
    **/
    viennacl::linalg::inplace_qr_apply_trans_Q(vcl_A, hybrid_betas, vcl_b);

    /**
    * Final step: triangular solve: Rx = b'.
    * We only need the upper part of A such that R is a square matrix
    **/
    viennacl::range vcl_range(0, 3);
    viennacl::matrix_range<VCLMatrixType> vcl_R(vcl_A, vcl_range, vcl_range);
    viennacl::vector_range<VCLVectorType> vcl_b2(vcl_b, vcl_range);
    viennacl::linalg::inplace_solve(vcl_R, vcl_b2, viennacl::linalg::upper_tag());

    std::cout << "Result: " << vcl_b2 << std::endl;

    /**
    *  That's it.
    **/
    std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl;

    return EXIT_SUCCESS;
}