$include_dir="/home/hyper-archives/ublas/include"; include("$include_dir/msg-header.inc") ?>
From:  James N. Knight (nate_at_[hidden])
Date: 2006-10-13 01:43:46
I just realized all this has already been done.  The specializations are in numeric/traits/ublas_vector2.hpp.  
I should have read the docs more carefully.  If you include this file you can call the lapack and blas 
functions with a vector in place of a matrix.  It treats the vector as a matrix of size nx1 or 1xn.
Nate
 James N. Knight wrote:
> I think a more general way to handle this is to place something like
> 
>   // Added by nate
>   template <typename T, typename A>
>   inline
>   typename vector_traits<ublas::vector<T,A> >::pointer matrix_storage (ublas::vector<T,A>& m) {
>     return vector_traits<ublas::vector<T,A> >::storage (m);
>   }
> 
>   template <typename T, typename A>
>   inline
>   int matrix_size1 (ublas::vector<T,A>& m) { return vector_traits<ublas::vector<T,A> >::size (m); }
> 
>   template <typename T, typename A>
>   inline
>   int matrix_size2 (ublas::vector<T,A>& m) { return 1; }
> 
>   template <typename T, typename A>
>   inline
>   int leading_dimension (ublas::vector<T,A>& m) {
>     return vector_traits<ublas::vector<T,A> >::size (m);
>   }
>   //
> 
> in the numeric/traits/ublas_vector.hpp file.  Its should go in the boost::numeric::bindings::traits namespace.
> You might need to add a few more specializations to make everything work.
> 
> Specifically, I have to compile the following with -DBOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK because I'm not sure how to specialize matrix_structure for a vector.  Any ideas?
> 
> #include <boost/numeric/ublas/vector.hpp>
> #include <boost/numeric/ublas/matrix.hpp>
> #include <boost/numeric/ublas/io.hpp>
> 
> #include <boost/numeric/bindings/traits/ublas_matrix.hpp>
> #include <boost/numeric/bindings/traits/ublas_symmetric.hpp>
> #include <boost/numeric/bindings/traits/ublas_vector.hpp>
> 
> #include <boost/numeric/bindings/lapack/gesv.hpp>
> 
> 
> namespace ublas = boost::numeric::ublas;
> namespace lapack = boost::numeric::bindings::lapack;
> 
> int main(){
>         typedef ublas::matrix<double, ublas::column_major> matrix;
> 
>         matrix P(2,2);
> 
>         P(0,0) = 2;
>         P(0,1) = 0;
>         P(1,0) = 1;
>         P(1,1) = 1;
> 
>         ublas::vector<double> b(2);
> 
>         b(0) = 5;
>         b(1) = 8;
> 
>         lapack::gesv(P,b);
> 
>         std::cout << b << std::endl;
> }
> 
> Hope this helps.  
> 
> Nate
> 
> 
> Paul Thompson wrote:
>> On Friday 13 October 2006 12:29, Nico Galoppo wrote:
>>> Hi all,
>>>
>>> Often, when using the ATLAS bindings such as gesv(A,B) to solve a system A
>>> X = B, I only want to solve a system with one rhs, ie. A x = b. I find that
>>> I first have to copy my vector to a matrix and then copy the result back to
>>> a vector.
>>>
>>> Has anyone ever worked on a matrix proxy of a vector, such that this copy
>>> is not necessary anymore?
>>>
>>> Thanks!
>>>
>>> --nico
>>
>> Yes,  I achieved this for the LAPACK-ATLAS Cholesky solver.   I added a 
>> template specialisation for ublas::vector<T,A>  at the point where it becomes 
>> necessary to call traits to get the assumed parameters.   So then I used 
>> vector traits to get the necessary terms before calling the C ATLAS function.
>>
>> It doesn't pretend to represent a vector-as-a-matrix.  It does result in some 
>> code duplication.  Perhaps a neater solution exists?? 
>>
>> Also I only wrote it for boost::numeric::ublas::vector<T,A>  not all the 
>> vectors supported by the bindings traits.
>>
>> This type of mod would be suitable for the LAPACK-ATLAS gesv I suppose.
>>
>> The modified clapack.hpp is attached.   More details below.
>>
>> Hope it helps!
>>
>> Paul T.
>>
>>
>>
>>
>>
>>
>> In more detail:
>>
>> template <typename SymmA, typename MatrB> 
>> 	int potrs (SymmA const& a, MatrB& b)
>>
>> was specialised to:
>>
>> template <typename SymmA, typename T, typename A>
>>         int potrs (SymmA const& a, boost::numeric::ublas::vector<T,A> & v) 
>>
>> and:
>>
>>
>> template <typename SymmA, typename MatrB>
>> int potrs (CBLAS_UPLO const uplo, SymmA const& a, MatrB& b)
>>
>> was specialised to:
>>
>> template <typename SymmA, typename T,typename A>
>> int potrs (CBLAS_UPLO const uplo, SymmA const& a, 
>> boost::numeric::ublas::vector<T,A> & v)
>>
>>
>> Users can still use the same interface,  eg:
>> cholesky_substitute (SymmA const& a, MatrB& b) { return potrs (a, b); }
>> still works.   The template parameter MatrB ends up as a ublas::vector
>>
>>
>>
>> ------------------------------------------------------------------------
>>
>> /*
>>  * 
>>  * Copyright (c) Kresimir Fresl 2002 
>>  *
>>  * Permission to copy, modify, use and distribute this software 
>>  * for any non-commercial or commercial purpose is granted provided 
>>  * that this license appear on all copies of the software source code.
>>  *
>>  * Author assumes no responsibility whatsoever for its use and makes 
>>  * no guarantees about its quality, correctness or reliability.
>>  *
>>  * Author acknowledges the support of the Faculty of Civil Engineering, 
>>  * University of Zagreb, Croatia.
>>  *
>>  */
>>
>> #ifndef BOOST_NUMERIC_BINDINGS_CLAPACK_HPP
>> #define BOOST_NUMERIC_BINDINGS_CLAPACK_HPP
>>
>> #include <cassert>
>> #include <new>
>>
>> #include <boost/numeric/bindings/traits/traits.hpp>
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>> #  include <boost/numeric/bindings/traits/detail/symm_herm_traits.hpp>
>> #endif 
>> #include <boost/numeric/bindings/atlas/cblas_enum.hpp>
>>
>> // see libs/numeric/bindings/atlas/doc/index.html, section 2.5.2
>> //#define BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>>
>> #include <boost/numeric/bindings/atlas/clapack_overloads.hpp>
>>
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>> #  include <boost/static_assert.hpp>
>> #  include <boost/type_traits/same_traits.hpp>
>> #endif
>>
>>
>> namespace boost { namespace numeric { namespace bindings { 
>>
>>   namespace atlas {
>>
>>     /////////////////////////////////////////////////////////////////////
>>     //
>>     // general system of linear equations A * X = B
>>     // 
>>     /////////////////////////////////////////////////////////////////////
>>
>>     // gesv(): 'driver' function 
>>     //
>>     // [comments from 'clapack_dgesv.c':]
>>     /* clapack_xgesv computes the solution to a system of linear equations
>>      *   A * X = B,
>>      * where A is an N-by-N matrix and X and B are N-by-NRHS matrices.
>>      */
>>     // [but ATLAS FAQ says:]
>>     /* What's the deal with the RHS in the row-major factorization/solves?
>>      * Most users are confused by the row major factorization and related 
>>      * solves. The right-hand side vectors are probably the biggest source 
>>      * of confusion. The RHS array does not represent a matrix in the 
>>      * mathematical sense, it is instead a pasting together of the various 
>>      * RHS into one array for calling convenience. As such, RHS vectors are 
>>      * always stored contiguously, regardless of the row/col major that is 
>>      * chosen. This means that ldb/ldx is always independent of NRHS, and 
>>      * dependant on N, regardless of the row/col major setting. 
>>      */ 
>>     // That is, it seems that, if B is row-major, it should be NRHS-by-N, 
>>     // and RHS vectors should be its rows, not columns. 
>>     //
>>     // [comments from 'clapack_dgesv.c':]
>>     /* The LU factorization used to factor A is dependent on the Order 
>>      * parameter, as detailed in the leading comments of clapack_dgetrf.
>>      * The factored form of A is then used to solve the system of equations 
>>      *   A * X = B.
>>      * A is overwritten with the appropriate LU factorization, and B [...]
>>      * is overwritten with the solution X on output.
>>      */
>>     // If B is row-major, solution vectors are its rows. 
>>     template <typename MatrA, typename MatrB, typename IVec>
>>     inline
>>     int gesv (MatrA& a, IVec& ipiv, MatrB& b) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrA>::matrix_structure, 
>>         traits::general_t
>>       >::value)); 
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrB>::matrix_structure, 
>>         traits::general_t
>>       >::value)); 
>>
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrA>::ordering_type,
>>         typename traits::matrix_traits<MatrB>::ordering_type
>>       >::value)); 
>> #endif 
>>
>>       CBLAS_ORDER const stor_ord
>>         = enum_cast<CBLAS_ORDER const>
>>         (storage_order<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>            typename traits::matrix_traits<MatrA>::ordering_type
>> #else
>>            typename MatrA::orientation_category 
>> #endif 
>>          >::value); 
>>
>>       int const n = traits::matrix_size1 (a);
>>       int const nrhs = stor_ord == CblasColMajor
>>         ? traits::matrix_size2 (b)
>>         : traits::matrix_size1 (b); 
>>       assert (n == traits::matrix_size2 (a)); 
>>       assert (n == (stor_ord == CblasColMajor
>>                     ? traits::matrix_size1 (b)
>>                     : traits::matrix_size2 (b))); 
>>       assert (n == traits::vector_size (ipiv)); 
>>
>>       return detail::gesv (stor_ord, n, nrhs, 
>>                            traits::matrix_storage (a), 
>>                            traits::leading_dimension (a),
>>                            traits::vector_storage (ipiv),  
>>                            traits::matrix_storage (b),
>>                            traits::leading_dimension (b));
>>     }
>>
>>     template <typename MatrA, typename MatrB>
>>     inline
>>     int gesv (MatrA& a, MatrB& b) {
>>       // with 'internal' pivot vector
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrA>::matrix_structure, 
>>         traits::general_t
>>       >::value)); 
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrB>::matrix_structure, 
>>         traits::general_t
>>       >::value)); 
>>
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrA>::ordering_type,
>>         typename traits::matrix_traits<MatrB>::ordering_type
>>       >::value)); 
>> #endif 
>>
>>       CBLAS_ORDER const stor_ord
>>         = enum_cast<CBLAS_ORDER const>
>>         (storage_order<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>            typename traits::matrix_traits<MatrA>::ordering_type
>> #else
>>            typename MatrA::orientation_category 
>> #endif 
>>          >::value); 
>>
>>       int const n = traits::matrix_size1 (a);
>>       int const nrhs = stor_ord == CblasColMajor
>>         ? traits::matrix_size2 (b)
>>         : traits::matrix_size1 (b); 
>>       assert (n == traits::matrix_size2 (a)); 
>>       assert (n == (stor_ord == CblasColMajor
>>                     ? traits::matrix_size1 (b)
>>                     : traits::matrix_size2 (b))); 
>>
>>       int *ipiv = new (std::nothrow) int[n]; 
>>       int ierr = -101;  
>>       // clapack_dgesv() errors: 
>>       //   if (ierr == 0), successful
>>       //   if (ierr < 0), the -ierr argument had an illegal value
>>       //   -- we will use -101 if allocation fails
>>       //   if (ierr > 0), U(i-1,i-1) (or L(i-1,i-1)) is exactly zero 
>>  
>>       if (ipiv) {
>>         ierr = detail::gesv (stor_ord, n, nrhs, 
>>                              traits::matrix_storage (a), 
>>                              traits::leading_dimension (a),
>>                              ipiv,  
>>                              traits::matrix_storage (b),
>>                              traits::leading_dimension (b));
>>         delete[] ipiv; 
>>       }
>>       return ierr; 
>>     }
>>
>>     template <typename MatrA, typename MatrB>
>>     inline
>>     int lu_solve (MatrA& a, MatrB& b) {
>>       return gesv (a, b); 
>>     }
>>
>>
>>     // getrf(): LU factorization of A
>>     // [comments from 'clapack_dgetrf.c':]
>>     /* Computes one of two LU factorizations based on the setting of 
>>      * the Order parameter, as follows:
>>      * ---------------------------------------------------------------
>>      *                     Order == CblasColMajor
>>      * Column-major factorization of form
>>      *   A = P * L * U
>>      * where P is a row-permutation matrix, L is lower triangular with
>>      * unit diagonal elements (lower trapezoidal if M > N), and U is 
>>      * upper triangular (upper trapezoidal if M < N).
>>      * ---------------------------------------------------------------
>>      *                     Order == CblasRowMajor
>>      * Row-major factorization of form
>>      *   A = P * L * U
>>      * where P is a column-permutation matrix, L is lower triangular 
>>      * (lower trapezoidal if M > N), and U is upper triangular with 
>>      * unit diagonals (upper trapezoidal if M < N).
>>      */
>>     template <typename MatrA, typename IVec> 
>>     inline
>>     int getrf (MatrA& a, IVec& ipiv) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrA>::matrix_structure, 
>>         traits::general_t
>>       >::value)); 
>> #endif 
>>
>>       CBLAS_ORDER const stor_ord
>>         = enum_cast<CBLAS_ORDER const>
>>         (storage_order<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>            typename traits::matrix_traits<MatrA>::ordering_type
>> #else
>>            typename MatrA::orientation_category 
>> #endif 
>>          >::value); 
>>
>>       int const m = traits::matrix_size1 (a);
>>       int const n = traits::matrix_size2 (a); 
>>       assert (traits::vector_size (ipiv) == (m < n ? m : n)); 
>>
>>       return detail::getrf (stor_ord, m, n, 
>>                             traits::matrix_storage (a), 
>>                             traits::leading_dimension (a),
>>                             traits::vector_storage (ipiv)); 
>>     }
>>
>>     template <typename MatrA, typename IVec> 
>>     inline
>>     int lu_factor (MatrA& a, IVec& ipiv) {
>>       return getrf (a, ipiv); 
>>     }
>>
>>
>>     // getrs(): solves a system of linear equations
>>     //          A * X = B  or  A' * X = B
>>     //          using the LU factorization previously computed by getrf()
>>     template <typename MatrA, typename MatrB, typename IVec>
>>     inline
>>     int getrs (CBLAS_TRANSPOSE const Trans, 
>>                MatrA const& a, IVec const& ipiv, MatrB& b) 
>>     {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrA>::matrix_structure, 
>>         traits::general_t
>>       >::value)); 
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrB>::matrix_structure, 
>>         traits::general_t
>>       >::value)); 
>>
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrA>::ordering_type,
>>         typename traits::matrix_traits<MatrB>::ordering_type
>>       >::value)); 
>> #endif 
>>
>>       assert (Trans == CblasNoTrans 
>>               || Trans == CblasTrans 
>>               || Trans == CblasConjTrans); 
>>
>>       CBLAS_ORDER const stor_ord
>>         = enum_cast<CBLAS_ORDER const>
>>         (storage_order<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>            typename traits::matrix_traits<MatrA>::ordering_type
>> #else
>>            typename MatrA::orientation_category 
>> #endif 
>>          >::value); 
>>
>>       int const n = traits::matrix_size1 (a);
>>       int const nrhs = stor_ord == CblasColMajor
>>         ? traits::matrix_size2 (b)
>>         : traits::matrix_size1 (b); 
>>       assert (n == traits::matrix_size2 (a)); 
>>       assert (n == (stor_ord == CblasColMajor
>>                     ? traits::matrix_size1 (b)
>>                     : traits::matrix_size2 (b))); 
>>       assert (n == traits::vector_size (ipiv)); 
>>       
>>       return detail::getrs (stor_ord, Trans, n, nrhs, 
>> #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
>>                             traits::matrix_storage (a), 
>> #else
>>                             traits::matrix_storage_const (a), 
>> #endif 
>>                             traits::leading_dimension (a),
>> #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
>>                             traits::vector_storage (ipiv),  
>> #else
>>                             traits::vector_storage_const (ipiv),  
>> #endif
>>                             traits::matrix_storage (b),
>>                             traits::leading_dimension (b)); 
>>     }
>>
>>     // getrs(): solves A * X = B (after getrf())
>>     template <typename MatrA, typename MatrB, typename IVec>
>>     inline
>>     int getrs (MatrA const& a, IVec const& ipiv, MatrB& b) {
>>       return getrs (CblasNoTrans, a, ipiv, b); 
>>     }
>>
>>     template <typename MatrA, typename MatrB, typename IVec>
>>     inline
>>     int lu_substitute (MatrA const& a, IVec const& ipiv, MatrB& b) {
>>       return getrs (CblasNoTrans, a, ipiv, b); 
>>     }
>>
>>
>>     // getri(): computes the inverse of a matrix A 
>>     //          using the LU factorization previously computed by getrf() 
>>     template <typename MatrA, typename IVec> 
>>     inline
>>     int getri (MatrA& a, IVec const& ipiv) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrA>::matrix_structure, 
>>         traits::general_t
>>       >::value)); 
>> #endif 
>>
>>       CBLAS_ORDER const stor_ord
>>         = enum_cast<CBLAS_ORDER const>
>>         (storage_order<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>            typename traits::matrix_traits<MatrA>::ordering_type
>> #else
>>            typename MatrA::orientation_category 
>> #endif 
>>          >::value); 
>>
>>       int const n = traits::matrix_size1 (a);
>>       assert (n == traits::matrix_size2 (a)); 
>>       assert (traits::vector_size (ipiv) == n); 
>>
>>       return detail::getri (stor_ord, n, 
>>                             traits::matrix_storage (a), 
>>                             traits::leading_dimension (a),
>> #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
>>                             traits::vector_storage (ipiv)
>> #else
>>                             traits::vector_storage_const (ipiv)
>> #endif
>>                             ); 
>>     }
>>
>>     template <typename MatrA, typename IVec> 
>>     inline
>>     int lu_invert (MatrA& a, IVec& ipiv) {
>>       return getri (a, ipiv); 
>>     }
>>
>>
>>
>>     /////////////////////////////////////////////////////////////////////
>>     //
>>     // system of linear equations A * X = B
>>     // with A symmetric or Hermitian positive definite matrix
>>     //
>>     /////////////////////////////////////////////////////////////////////
>>
>> #ifndef BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>>     // posv(): 'driver' function 
>>     //
>>     // [from 'dposv.f' (slightly edited):]
>>     /* XPOSV computes the solution to a system of linear equations
>>      *    A * X = B,
>>      * where A is an N-by-N symmetric/Hermitian positive definite matrix 
>>      * and X and B are N-by-NRHS matrices. [See also comments of gesv().]
>>      *
>>      * A -- On entry, the symmetric/Hermitian matrix A.  
>>      * If UPLO = 'U', the leading N-by-N upper triangular part of A 
>>      * contains the upper triangular part of the matrix A, and the 
>>      * strictly lower triangular part of A is not referenced.  
>>      * If UPLO = 'L', the leading N-by-N lower triangular part of A 
>>      * contains the lower triangular part of the matrix A, and the 
>>      * strictly upper triangular part of A is not referenced.
>>      *
>>      * On exit, if INFO = 0, the factor U or L from the Cholesky
>>      * factorization A = U**T*U or A = L*L**T
>>      * [or A = U**H*U or A = L*L**H]. 
>>      *
>>      * B -- On entry, the right hand side matrix B.
>>      * On exit, if INFO = 0, the solution matrix X.
>>      */
>>     namespace detail {
>>
>>       template <typename SymmA, typename MatrB>
>>       inline
>>       int posv (CBLAS_UPLO const uplo, SymmA& a, MatrB& b) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>>         BOOST_STATIC_ASSERT((boost::is_same<
>>           typename traits::matrix_traits<SymmA>::ordering_type,
>>           typename traits::matrix_traits<MatrB>::ordering_type
>>         >::value)); 
>> #endif 
>>
>>         CBLAS_ORDER const stor_ord
>>           = enum_cast<CBLAS_ORDER const>
>>           (storage_order<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>             typename traits::matrix_traits<SymmA>::ordering_type
>> #else
>>             typename SymmA::orientation_category 
>> #endif 
>>            >::value); 
>>
>>         int const n = traits::matrix_size1 (a);
>>         int const nrhs = stor_ord == CblasColMajor
>>           ? traits::matrix_size2 (b)
>>           : traits::matrix_size1 (b); 
>>         assert (n == traits::matrix_size2 (a)); 
>>         assert (n == (stor_ord == CblasColMajor
>>                       ? traits::matrix_size1 (b)
>>                       : traits::matrix_size2 (b))); 
>>
>>         return posv (stor_ord, uplo, n, nrhs, 
>>                      traits::matrix_storage (a), 
>>                      traits::leading_dimension (a),
>>                      traits::matrix_storage (b),
>>                      traits::leading_dimension (b));
>>       }
>>
>>     } // detail 
>>
>>     template <typename SymmA, typename MatrB>
>>     inline
>>     int posv (CBLAS_UPLO const uplo, SymmA& a, MatrB& b) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<SymmA>::matrix_structure, 
>>         traits::general_t
>>       >::value));
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrB>::matrix_structure, 
>>         traits::general_t
>>       >::value));
>> #endif
>>       assert (uplo == CblasUpper || uplo == CblasLower); 
>>       return detail::posv (uplo, a, b); 
>>     }
>>
>>     template <typename SymmA, typename MatrB>
>>     inline
>>     int posv (SymmA& a, MatrB& b) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>>       typedef typename traits::matrix_traits<SymmA>::value_type val_t;
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<SymmA>::matrix_structure, 
>>         typename traits::detail::symm_herm_t<val_t>::type
>>       >::value)); 
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrB>::matrix_structure, 
>>         traits::general_t
>>       >::value)); 
>> #endif 
>>
>>       CBLAS_UPLO const uplo
>>         = enum_cast<CBLAS_UPLO const>
>>         (uplo_triang<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>           typename traits::matrix_traits<SymmA>::uplo_type
>> #else
>>           typename SymmA::packed_category 
>> #endif 
>>          >::value); 
>>       
>>       return detail::posv (uplo, a, b); 
>>     }
>>
>>     template <typename SymmA, typename MatrB>
>>     inline
>>     int cholesky_solve (SymmA& a, MatrB& b) { return posv (a, b); }
>> #endif // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>>
>>
>>     // potrf(): Cholesky factorization of A 
>>     namespace detail {
>>
>>       template <typename SymmA>
>>       inline
>>       int potrf (CBLAS_UPLO const uplo, SymmA& a) {
>>
>>         CBLAS_ORDER const stor_ord
>>           = enum_cast<CBLAS_ORDER const>
>>           (storage_order<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>             typename traits::matrix_traits<SymmA>::ordering_type
>> #else
>>             typename SymmA::orientation_category 
>> #endif 
>>            >::value); 
>>
>>         int const n = traits::matrix_size1 (a);
>>         assert (n == traits::matrix_size2 (a)); 
>>
>>         return potrf (stor_ord, uplo, n, 
>>                       traits::matrix_storage (a), 
>>                       traits::leading_dimension (a));
>>       }
>>
>>     } // detail 
>>
>>     template <typename SymmA>
>>     inline
>>     int potrf (CBLAS_UPLO const uplo, SymmA& a) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<SymmA>::matrix_structure, 
>>         traits::general_t
>>       >::value));
>> #endif
>>       assert (uplo == CblasUpper || uplo == CblasLower); 
>>       return detail::potrf (uplo, a); 
>>     } 
>>
>>     template <typename SymmA>
>>     inline
>>     int potrf (SymmA& a) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>>       typedef typename traits::matrix_traits<SymmA>::value_type val_t;
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<SymmA>::matrix_structure, 
>>         typename traits::detail::symm_herm_t<val_t>::type
>>       >::value)); 
>> #endif 
>>
>>       CBLAS_UPLO const uplo
>>         = enum_cast<CBLAS_UPLO const>
>>         (uplo_triang<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>           typename traits::matrix_traits<SymmA>::uplo_type
>> #else
>>           typename SymmA::packed_category 
>> #endif 
>>          >::value); 
>>       
>>       return detail::potrf (uplo, a); 
>>     }
>>
>>     template <typename SymmA>
>>     inline
>>     int cholesky_factor (SymmA& a) { return potrf (a); }
>>
>>
>>
>>     
>>     
>>     
>>     
>>     
>>     
>>     
>>     namespace detail
>>     {
>>     
>>             
>>             
>>         
>>         //! potrs specialisation for one RHS as a boost::numeric::ublas::vector
>>         /*!
>>             \author Paul Thompson
>>             \date   06-10-06
>>         
>>             \todo Perhaps the input argument should be templated to accept other vector types than boost::numeric::ublas::vector<T,A> ?
>>         */
>>     template <typename SymmA, typename T,typename A>
>>         inline
>>         int potrs (CBLAS_UPLO const uplo, SymmA const& a, boost::numeric::ublas::vector<T,A> & v) 
>>       {
>>
>>         CBLAS_ORDER const stor_ord
>>           = enum_cast<CBLAS_ORDER const>
>>           (storage_order<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>             typename traits::matrix_traits<SymmA>::ordering_type
>> #else
>>             typename SymmA::orientation_category 
>> #endif 
>>            >::value); 
>>
>>         int const n = traits::matrix_size1 (a);
>>         int const nrhs = 1;         //! We know there's only one RHS for a vector
>>         assert (n == traits::matrix_size2 (a)); 
>>         assert (n == traits::vector_size(v)); 
>>
>>         int ldb = traits::vector_size(v);
>>         
>> #ifndef BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>>         return potrs (stor_ord, uplo, n, nrhs, 
>> #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
>>                       traits::matrix_storage (a), 
>> #else
>>                       traits::matrix_storage_const (a), 
>> #endif 
>>                       traits::leading_dimension (a),
>>                       traits::vector_storage (v),
>>                       ldb);
>> #else // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>>         int ierr; 
>>         if (stor_ord == CblasColMajor)
>>           ierr = potrs (stor_ord, uplo, n, nrhs, 
>> #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
>>                         traits::matrix_storage (a), 
>> #else
>>                         traits::matrix_storage_const (a), 
>> #endif 
>>                         traits::leading_dimension (a),
>>                         traits::vector_storage (v),
>>                         ldb);
>>         else // ATLAS bug with CblasRowMajor 
>>           ierr = potrs_bug (stor_ord, uplo, n, nrhs, 
>> #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
>>                             traits::matrix_storage (a), 
>> #else
>>                             traits::matrix_storage_const (a), 
>> #endif 
>>                             traits::leading_dimension (a),
>>                             traits::vector_storage (v),
>>                             ldb);
>>         return ierr; 
>> #endif // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>>       }
>>       //potrs detailed
>>     
>>     
>>     
>>     
>>     
>>     
>>     
>>     
>>     
>>     
>>     
>>     
>>     // potrs(): solves a system of linear equations A * X = B
>>     //          using the Cholesky factorization computed by potrf()
>>     
>>
>>       template <typename SymmA, typename MatrB>
>>       inline
>>       int potrs (CBLAS_UPLO const uplo, SymmA const& a, MatrB& b) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>>         BOOST_STATIC_ASSERT((boost::is_same<
>>           typename traits::matrix_traits<SymmA>::ordering_type,
>>           typename traits::matrix_traits<MatrB>::ordering_type
>>         >::value)); 
>> #endif 
>>
>>         CBLAS_ORDER const stor_ord
>>           = enum_cast<CBLAS_ORDER const>
>>           (storage_order<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>             typename traits::matrix_traits<SymmA>::ordering_type
>> #else
>>             typename SymmA::orientation_category 
>> #endif 
>>            >::value); 
>>
>>         int const n = traits::matrix_size1 (a);
>>         int const nrhs = stor_ord == CblasColMajor
>>           ? traits::matrix_size2 (b)
>>           : traits::matrix_size1 (b); 
>>         assert (n == traits::matrix_size2 (a)); 
>>         assert (n == (stor_ord == CblasColMajor
>>                       ? traits::matrix_size1 (b)
>>                       : traits::matrix_size2 (b))); 
>>
>> #ifndef BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>>         return potrs (stor_ord, uplo, n, nrhs, 
>> #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
>>                       traits::matrix_storage (a), 
>> #else
>>                       traits::matrix_storage_const (a), 
>> #endif 
>>                       traits::leading_dimension (a),
>>                       traits::matrix_storage (b),
>>                       traits::leading_dimension (b));
>> #else // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>>         int ierr; 
>>         if (stor_ord == CblasColMajor)
>>           ierr = potrs (stor_ord, uplo, n, nrhs, 
>> #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
>>                         traits::matrix_storage (a), 
>> #else
>>                         traits::matrix_storage_const (a), 
>> #endif 
>>                         traits::leading_dimension (a),
>>                         traits::matrix_storage (b),
>>                         traits::leading_dimension (b));
>>         else // ATLAS bug with CblasRowMajor 
>>           ierr = potrs_bug (stor_ord, uplo, n, nrhs, 
>> #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
>>                             traits::matrix_storage (a), 
>> #else
>>                             traits::matrix_storage_const (a), 
>> #endif 
>>                             traits::leading_dimension (a),
>>                             traits::matrix_storage (b),
>>                             traits::leading_dimension (b));
>>         return ierr; 
>> #endif // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>>       }
>>
>>     } // detail 
>>
>>     template <typename SymmA, typename MatrB>
>>     inline
>>     int potrs (CBLAS_UPLO const uplo, SymmA const& a, MatrB& b) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<SymmA>::matrix_structure, 
>>         traits::general_t
>>       >::value));
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrB>::matrix_structure, 
>>         traits::general_t
>>       >::value));
>> #endif
>>       assert (uplo == CblasUpper || uplo == CblasLower); 
>>       return detail::potrs (uplo, a, b); 
>>     }
>>
>>     
>>     
>>     
>>     
>>     
>>     
>>     
>>     
>>     
>>     template <typename SymmA, typename T, typename A>
>>     inline
>>         int potrs (SymmA const& a, boost::numeric::ublas::vector<T,A> & v) 
>>     {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>>       typedef typename traits::matrix_traits<SymmA>::value_type val_t;
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<SymmA>::matrix_structure, 
>>         typename traits::detail::symm_herm_t<val_t>::type
>>       >::value)); 
>> #endif 
>>
>>       CBLAS_UPLO const uplo
>>         = enum_cast<CBLAS_UPLO const>
>>         (uplo_triang<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>           typename traits::matrix_traits<SymmA>::uplo_type
>> #else
>>           typename SymmA::packed_category 
>> #endif 
>>          >::value); 
>>       
>>       return detail::potrs<SymmA, T, A> (uplo, a, v); 
>>     }
>>     
>>     
>>     
>>     
>>     
>>     
>>     
>>     
>>     template <typename SymmA, typename MatrB>
>>     inline
>>     int potrs (SymmA const& a, MatrB& b) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>>       typedef typename traits::matrix_traits<SymmA>::value_type val_t;
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<SymmA>::matrix_structure, 
>>         typename traits::detail::symm_herm_t<val_t>::type
>>       >::value)); 
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<MatrB>::matrix_structure, 
>>         traits::general_t
>>       >::value)); 
>> #endif 
>>
>>       CBLAS_UPLO const uplo
>>         = enum_cast<CBLAS_UPLO const>
>>         (uplo_triang<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>           typename traits::matrix_traits<SymmA>::uplo_type
>> #else
>>           typename SymmA::packed_category 
>> #endif 
>>          >::value); 
>>       
>>       return detail::potrs (uplo, a, b); 
>>     }
>>
>>     template <typename SymmA, typename MatrB>
>>     inline 
>>     int cholesky_substitute (SymmA const& a, MatrB& b) { return potrs (a, b); }
>>
>>
>> #ifdef BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>>     // posv(): 'driver' function 
>>     template <typename SymmA, typename MatrB>
>>     inline
>>     int posv (CBLAS_UPLO const uplo, SymmA& a, MatrB& b) {
>>       int ierr = potrf (uplo, a); 
>>       if (ierr == 0)
>>         ierr = potrs (uplo, a, b);
>>       return ierr; 
>>     }
>>
>>     template <typename SymmA, typename MatrB>
>>     inline
>>     int posv (SymmA& a, MatrB& b) {
>>       int ierr = potrf (a); 
>>       if (ierr == 0)
>>         ierr = potrs (a, b);
>>       return ierr; 
>>     }
>>
>>     template <typename SymmA, typename MatrB>
>>     inline
>>     int cholesky_solve (SymmA& a, MatrB& b) {
>>       return posv (a, b); 
>>     }
>> #endif // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG 
>>
>>
>>     // potri(): computes the inverse of a symmetric or Hermitian positive 
>>     //          definite matrix A using the Cholesky factorization 
>>     //          previously computed by potrf() 
>>     namespace detail {
>>
>>       template <typename SymmA>
>>       inline
>>       int potri (CBLAS_UPLO const uplo, SymmA& a) {
>>
>>         CBLAS_ORDER const stor_ord
>>           = enum_cast<CBLAS_ORDER const>
>>           (storage_order<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>             typename traits::matrix_traits<SymmA>::ordering_type
>> #else
>>             typename SymmA::orientation_category 
>> #endif 
>>            >::value); 
>>
>>         int const n = traits::matrix_size1 (a);
>>         assert (n == traits::matrix_size2 (a)); 
>>
>>         return potri (stor_ord, uplo, n, 
>>                       traits::matrix_storage (a), 
>>                       traits::leading_dimension (a));
>>       }
>>
>>     } // detail 
>>
>>     template <typename SymmA>
>>     inline
>>     int potri (CBLAS_UPLO const uplo, SymmA& a) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<SymmA>::matrix_structure, 
>>         traits::general_t
>>       >::value));
>> #endif
>>       assert (uplo == CblasUpper || uplo == CblasLower); 
>>       return detail::potri (uplo, a); 
>>     } 
>>
>>     template <typename SymmA>
>>     inline
>>     int potri (SymmA& a) {
>> #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>>       typedef typename traits::matrix_traits<SymmA>::value_type val_t;
>>       BOOST_STATIC_ASSERT((boost::is_same<
>>         typename traits::matrix_traits<SymmA>::matrix_structure, 
>>         typename traits::detail::symm_herm_t<val_t>::type
>>       >::value)); 
>> #endif 
>>
>>       CBLAS_UPLO const uplo
>>         = enum_cast<CBLAS_UPLO const>
>>         (uplo_triang<
>> #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>>           typename traits::matrix_traits<SymmA>::uplo_type
>> #else
>>           typename SymmA::packed_category 
>> #endif 
>>          >::value); 
>>       
>>       return detail::potri (uplo, a); 
>>     }
>>
>>     template <typename SymmA>
>>     inline
>>     int cholesky_invert (SymmA& a) { return potri (a); }
>>
>>
>>   } // namespace atlas
>>
>> }}} 
>>
>> #endif // BOOST_NUMERIC_BINDINGS_CLAPACK_HPP
>>
>>
>> ------------------------------------------------------------------------
>>
>> 563,653d562
>> < 
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     namespace detail
>> <     {
>> <     
>> <             
>> <             
>> <         
>> <         //! potrs specialisation for one RHS as a boost::numeric::ublas::vector
>> <         /*!
>> <             \author Paul Thompson
>> <             \date   06-10-06
>> <         
>> <             \todo Perhaps the input argument should be templated to accept other vector types than boost::numeric::ublas::vector<T,A> ?
>> <         */
>> <     template <typename SymmA, typename T,typename A>
>> <         inline
>> <         int potrs (CBLAS_UPLO const uplo, SymmA const& a, boost::numeric::ublas::vector<T,A> & v) 
>> <       {
>> < 
>> <         CBLAS_ORDER const stor_ord
>> <           = enum_cast<CBLAS_ORDER const>
>> <           (storage_order<
>> < #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>> <             typename traits::matrix_traits<SymmA>::ordering_type
>> < #else
>> <             typename SymmA::orientation_category 
>> < #endif 
>> <            >::value); 
>> < 
>> <         int const n = traits::matrix_size1 (a);
>> <         int const nrhs = 1;         //! We know there's only one RHS for a vector
>> <         assert (n == traits::matrix_size2 (a)); 
>> <         assert (n == traits::vector_size(v)); 
>> < 
>> <         int ldb = traits::vector_size(v);
>> <         
>> < #ifndef BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>> <         return potrs (stor_ord, uplo, n, nrhs, 
>> < #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
>> <                       traits::matrix_storage (a), 
>> < #else
>> <                       traits::matrix_storage_const (a), 
>> < #endif 
>> <                       traits::leading_dimension (a),
>> <                       traits::vector_storage (v),
>> <                       ldb);
>> < #else // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>> <         int ierr; 
>> <         if (stor_ord == CblasColMajor)
>> <           ierr = potrs (stor_ord, uplo, n, nrhs, 
>> < #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
>> <                         traits::matrix_storage (a), 
>> < #else
>> <                         traits::matrix_storage_const (a), 
>> < #endif 
>> <                         traits::leading_dimension (a),
>> <                         traits::vector_storage (v),
>> <                         ldb);
>> <         else // ATLAS bug with CblasRowMajor 
>> <           ierr = potrs_bug (stor_ord, uplo, n, nrhs, 
>> < #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
>> <                             traits::matrix_storage (a), 
>> < #else
>> <                             traits::matrix_storage_const (a), 
>> < #endif 
>> <                             traits::leading_dimension (a),
>> <                             traits::vector_storage (v),
>> <                             ldb);
>> <         return ierr; 
>> < #endif // BOOST_NUMERIC_BINDINGS_ATLAS_POTRF_BUG
>> <       }
>> <       //potrs detailed
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> 656c565
>> <     
>> ---
>>>     namespace detail {
>> 742,788d650
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     //! potrs specialisation for one RHS as a boost::numeric::ublas::vector
>> <     /*!
>> <         \author Paul Thompson
>> <         \date   06-10-06
>> <         
>> <         \todo Perhaps the input argument should be templated to accept other vector types than boost::numeric::ublas::vector<T,A> ?
>> <     */
>> <     template <typename SymmA, typename T, typename A>
>> <     inline
>> <         int potrs (SymmA const& a, boost::numeric::ublas::vector<T,A> & v) 
>> <     {
>> < #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
>> <       typedef typename traits::matrix_traits<SymmA>::value_type val_t;
>> <       BOOST_STATIC_ASSERT((boost::is_same<
>> <         typename traits::matrix_traits<SymmA>::matrix_structure, 
>> <         typename traits::detail::symm_herm_t<val_t>::type
>> <       >::value)); 
>> < #endif 
>> < 
>> <       CBLAS_UPLO const uplo
>> <         = enum_cast<CBLAS_UPLO const>
>> <         (uplo_triang<
>> < #ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
>> <           typename traits::matrix_traits<SymmA>::uplo_type
>> < #else
>> <           typename SymmA::packed_category 
>> < #endif 
>> <          >::value); 
>> <       
>> <       return detail::potrs<SymmA, T, A> (uplo, a, v); 
>> <     }
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>> <     
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> ublas mailing list
>> ublas_at_[hidden]
>> http://listarchives.boost.org/mailman/listinfo.cgi/ublas
> _______________________________________________
> ublas mailing list
> ublas_at_[hidden]
> http://listarchives.boost.org/mailman/listinfo.cgi/ublas