Added boost header

This commit is contained in:
Christophe Riccio
2012-01-08 01:26:07 +00:00
parent 9c3faaca40
commit c7d752cdf8
8946 changed files with 1732316 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,502 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_BLAS_
#define _BOOST_UBLAS_BLAS_
#include <boost/numeric/ublas/traits.hpp>
namespace boost { namespace numeric { namespace ublas {
/** Interface and implementation of BLAS level 1
* This includes functions which perform \b vector-vector operations.
* More information about BLAS can be found at
* <a href="http://en.wikipedia.org/wiki/BLAS">http://en.wikipedia.org/wiki/BLAS</a>
*/
namespace blas_1 {
/** 1-Norm: \f$\sum_i |x_i|\f$ (also called \f$\mathcal{L}_1\f$ or Manhattan norm)
*
* \param v a vector or vector expression
* \return the 1-Norm with type of the vector's type
*
* \tparam V type of the vector (not needed by default)
*/
template<class V>
typename type_traits<typename V::value_type>::real_type
asum (const V &v) {
return norm_1 (v);
}
/** 2-Norm: \f$\sum_i |x_i|^2\f$ (also called \f$\mathcal{L}_2\f$ or Euclidean norm)
*
* \param v a vector or vector expression
* \return the 2-Norm with type of the vector's type
*
* \tparam V type of the vector (not needed by default)
*/
template<class V>
typename type_traits<typename V::value_type>::real_type
nrm2 (const V &v) {
return norm_2 (v);
}
/** Infinite-norm: \f$\max_i |x_i|\f$ (also called \f$\mathcal{L}_\infty\f$ norm)
*
* \param v a vector or vector expression
* \return the Infinite-Norm with type of the vector's type
*
* \tparam V type of the vector (not needed by default)
*/
template<class V>
typename type_traits<typename V::value_type>::real_type
amax (const V &v) {
return norm_inf (v);
}
/** Inner product of vectors \f$v_1\f$ and \f$v_2\f$
*
* \param v1 first vector of the inner product
* \param v2 second vector of the inner product
* \return the inner product of the type of the most generic type of the 2 vectors
*
* \tparam V1 type of first vector (not needed by default)
* \tparam V2 type of second vector (not needed by default)
*/
template<class V1, class V2>
typename promote_traits<typename V1::value_type, typename V2::value_type>::promote_type
dot (const V1 &v1, const V2 &v2) {
return inner_prod (v1, v2);
}
/** Copy vector \f$v_2\f$ to \f$v_1\f$
*
* \param v1 target vector
* \param v2 source vector
* \return a reference to the target vector
*
* \tparam V1 type of first vector (not needed by default)
* \tparam V2 type of second vector (not needed by default)
*/
template<class V1, class V2>
V1 & copy (V1 &v1, const V2 &v2)
{
return v1.assign (v2);
}
/** Swap vectors \f$v_1\f$ and \f$v_2\f$
*
* \param v1 first vector
* \param v2 second vector
*
* \tparam V1 type of first vector (not needed by default)
* \tparam V2 type of second vector (not needed by default)
*/
template<class V1, class V2>
void swap (V1 &v1, V2 &v2)
{
v1.swap (v2);
}
/** scale vector \f$v\f$ with scalar \f$t\f$
*
* \param v vector to be scaled
* \param t the scalar
* \return \c t*v
*
* \tparam V type of the vector (not needed by default)
* \tparam T type of the scalar (not needed by default)
*/
template<class V, class T>
V & scal (V &v, const T &t)
{
return v *= t;
}
/** Compute \f$v_1= v_1 + t.v_2\f$
*
* \param v1 target and first vector
* \param t the scalar
* \param v2 second vector
* \return a reference to the first and target vector
*
* \tparam V1 type of the first vector (not needed by default)
* \tparam T type of the scalar (not needed by default)
* \tparam V2 type of the second vector (not needed by default)
*/
template<class V1, class T, class V2>
V1 & axpy (V1 &v1, const T &t, const V2 &v2)
{
return v1.plus_assign (t * v2);
}
/** Performs rotation of points in the plane and assign the result to the first vector
*
* Each point is defined as a pair \c v1(i) and \c v2(i), being respectively
* the \f$x\f$ and \f$y\f$ coordinates. The parameters \c t1 and \t2 are respectively
* the cosine and sine of the angle of the rotation.
* Results are not returned but directly written into \c v1.
*
* \param t1 cosine of the rotation
* \param v1 vector of \f$x\f$ values
* \param t2 sine of the rotation
* \param v2 vector of \f$y\f$ values
*
* \tparam T1 type of the cosine value (not needed by default)
* \tparam V1 type of the \f$x\f$ vector (not needed by default)
* \tparam T2 type of the sine value (not needed by default)
* \tparam V2 type of the \f$y\f$ vector (not needed by default)
*/
template<class T1, class V1, class T2, class V2>
void rot (const T1 &t1, V1 &v1, const T2 &t2, V2 &v2)
{
typedef typename promote_traits<typename V1::value_type, typename V2::value_type>::promote_type promote_type;
vector<promote_type> vt (t1 * v1 + t2 * v2);
v2.assign (- t2 * v1 + t1 * v2);
v1.assign (vt);
}
}
/** \brief Interface and implementation of BLAS level 2
* This includes functions which perform \b matrix-vector operations.
* More information about BLAS can be found at
* <a href="http://en.wikipedia.org/wiki/BLAS">http://en.wikipedia.org/wiki/BLAS</a>
*/
namespace blas_2 {
/** \brief multiply vector \c v with triangular matrix \c m
*
* \param v a vector
* \param m a triangular matrix
* \return the result of the product
*
* \tparam V type of the vector (not needed by default)
* \tparam M type of the matrix (not needed by default)
*/
template<class V, class M>
V & tmv (V &v, const M &m)
{
return v = prod (m, v);
}
/** \brief solve \f$m.x = v\f$ in place, where \c m is a triangular matrix
*
* \param v a vector
* \param m a matrix
* \param C (this parameter is not needed)
* \return a result vector from the above operation
*
* \tparam V type of the vector (not needed by default)
* \tparam M type of the matrix (not needed by default)
* \tparam C n/a
*/
template<class V, class M, class C>
V & tsv (V &v, const M &m, C)
{
return v = solve (m, v, C ());
}
/** \brief compute \f$ v_1 = t_1.v_1 + t_2.(m.v_2)\f$, a general matrix-vector product
*
* \param v1 a vector
* \param t1 a scalar
* \param t2 another scalar
* \param m a matrix
* \param v2 another vector
* \return the vector \c v1 with the result from the above operation
*
* \tparam V1 type of first vector (not needed by default)
* \tparam T1 type of first scalar (not needed by default)
* \tparam T2 type of second scalar (not needed by default)
* \tparam M type of matrix (not needed by default)
* \tparam V2 type of second vector (not needed by default)
*/
template<class V1, class T1, class T2, class M, class V2>
V1 & gmv (V1 &v1, const T1 &t1, const T2 &t2, const M &m, const V2 &v2)
{
return v1 = t1 * v1 + t2 * prod (m, v2);
}
/** \brief Rank 1 update: \f$ m = m + t.(v_1.v_2^T)\f$
*
* \param m a matrix
* \param t a scalar
* \param v1 a vector
* \param v2 another vector
* \return a matrix with the result from the above operation
*
* \tparam M type of matrix (not needed by default)
* \tparam T type of scalar (not needed by default)
* \tparam V1 type of first vector (not needed by default)
* \tparam V2type of second vector (not needed by default)
*/
template<class M, class T, class V1, class V2>
M & gr (M &m, const T &t, const V1 &v1, const V2 &v2)
{
#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
return m += t * outer_prod (v1, v2);
#else
return m = m + t * outer_prod (v1, v2);
#endif
}
/** \brief symmetric rank 1 update: \f$m = m + t.(v.v^T)\f$
*
* \param m a matrix
* \param t a scalar
* \param v a vector
* \return a matrix with the result from the above operation
*
* \tparam M type of matrix (not needed by default)
* \tparam T type of scalar (not needed by default)
* \tparam V type of vector (not needed by default)
*/
template<class M, class T, class V>
M & sr (M &m, const T &t, const V &v)
{
#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
return m += t * outer_prod (v, v);
#else
return m = m + t * outer_prod (v, v);
#endif
}
/** \brief hermitian rank 1 update: \f$m = m + t.(v.v^H)\f$
*
* \param m a matrix
* \param t a scalar
* \param v a vector
* \return a matrix with the result from the above operation
*
* \tparam M type of matrix (not needed by default)
* \tparam T type of scalar (not needed by default)
* \tparam V type of vector (not needed by default)
*/
template<class M, class T, class V>
M & hr (M &m, const T &t, const V &v)
{
#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
return m += t * outer_prod (v, conj (v));
#else
return m = m + t * outer_prod (v, conj (v));
#endif
}
/** \brief symmetric rank 2 update: \f$ m=m+ t.(v_1.v_2^T + v_2.v_1^T)\f$
*
* \param m a matrix
* \param t a scalar
* \param v1 a vector
* \param v2 another vector
* \return a matrix with the result from the above operation
*
* \tparam M type of matrix (not needed by default)
* \tparam T type of scalar (not needed by default)
* \tparam V1 type of first vector (not needed by default)
* \tparam V2type of second vector (not needed by default)
*/
template<class M, class T, class V1, class V2>
M & sr2 (M &m, const T &t, const V1 &v1, const V2 &v2)
{
#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
return m += t * (outer_prod (v1, v2) + outer_prod (v2, v1));
#else
return m = m + t * (outer_prod (v1, v2) + outer_prod (v2, v1));
#endif
}
/** \brief hermitian rank 2 update: \f$m=m+t.(v_1.v_2^H) + v_2.(t.v_1)^H)\f$
*
* \param m a matrix
* \param t a scalar
* \param v1 a vector
* \param v2 another vector
* \return a matrix with the result from the above operation
*
* \tparam M type of matrix (not needed by default)
* \tparam T type of scalar (not needed by default)
* \tparam V1 type of first vector (not needed by default)
* \tparam V2type of second vector (not needed by default)
*/
template<class M, class T, class V1, class V2>
M & hr2 (M &m, const T &t, const V1 &v1, const V2 &v2)
{
#ifndef BOOST_UBLAS_SIMPLE_ET_DEBUG
return m += t * outer_prod (v1, conj (v2)) + type_traits<T>::conj (t) * outer_prod (v2, conj (v1));
#else
return m = m + t * outer_prod (v1, conj (v2)) + type_traits<T>::conj (t) * outer_prod (v2, conj (v1));
#endif
}
}
/** \brief Interface and implementation of BLAS level 3
* This includes functions which perform \b matrix-matrix operations.
* More information about BLAS can be found at
* <a href="http://en.wikipedia.org/wiki/BLAS">http://en.wikipedia.org/wiki/BLAS</a>
*/
namespace blas_3 {
/** \brief triangular matrix multiplication \f$m_1=t.m_2.m_3\f$ where \f$m_2\f$ and \f$m_3\f$ are triangular
*
* \param m1 a matrix for storing result
* \param t a scalar
* \param m2 a triangular matrix
* \param m3 a triangular matrix
* \return the matrix \c m1
*
* \tparam M1 type of the result matrix (not needed by default)
* \tparam T type of the scalar (not needed by default)
* \tparam M2 type of the first triangular matrix (not needed by default)
* \tparam M3 type of the second triangular matrix (not needed by default)
*
*/
template<class M1, class T, class M2, class M3>
M1 & tmm (M1 &m1, const T &t, const M2 &m2, const M3 &m3)
{
return m1 = t * prod (m2, m3);
}
/** \brief triangular solve \f$ m_2.x = t.m_1\f$ in place, \f$m_2\f$ is a triangular matrix
*
* \param m1 a matrix
* \param t a scalar
* \param m2 a triangular matrix
* \param C (not used)
* \return the \f$m_1\f$ matrix
*
* \tparam M1 type of the first matrix (not needed by default)
* \tparam T type of the scalar (not needed by default)
* \tparam M2 type of the triangular matrix (not needed by default)
* \tparam C (n/a)
*/
template<class M1, class T, class M2, class C>
M1 & tsm (M1 &m1, const T &t, const M2 &m2, C)
{
return m1 = solve (m2, t * m1, C ());
}
/** \brief general matrix multiplication \f$m_1=t_1.m_1 + t_2.m_2.m_3\f$
*
* \param m1 first matrix
* \param t1 first scalar
* \param t2 second scalar
* \param m2 second matrix
* \param m3 third matrix
* \return the matrix \c m1
*
* \tparam M1 type of the first matrix (not needed by default)
* \tparam T1 type of the first scalar (not needed by default)
* \tparam T2 type of the second scalar (not needed by default)
* \tparam M2 type of the second matrix (not needed by default)
* \tparam M3 type of the third matrix (not needed by default)
*/
template<class M1, class T1, class T2, class M2, class M3>
M1 & gmm (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2, const M3 &m3)
{
return m1 = t1 * m1 + t2 * prod (m2, m3);
}
/** \brief symmetric rank \a k update: \f$m_1=t.m_1+t_2.(m_2.m_2^T)\f$
*
* \param m1 first matrix
* \param t1 first scalar
* \param t2 second scalar
* \param m2 second matrix
* \return matrix \c m1
*
* \tparam M1 type of the first matrix (not needed by default)
* \tparam T1 type of the first scalar (not needed by default)
* \tparam T2 type of the second scalar (not needed by default)
* \tparam M2 type of the second matrix (not needed by default)
* \todo use opb_prod()
*/
template<class M1, class T1, class T2, class M2>
M1 & srk (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2)
{
return m1 = t1 * m1 + t2 * prod (m2, trans (m2));
}
/** \brief hermitian rank \a k update: \f$m_1=t.m_1+t_2.(m_2.m2^H)\f$
*
* \param m1 first matrix
* \param t1 first scalar
* \param t2 second scalar
* \param m2 second matrix
* \return matrix \c m1
*
* \tparam M1 type of the first matrix (not needed by default)
* \tparam T1 type of the first scalar (not needed by default)
* \tparam T2 type of the second scalar (not needed by default)
* \tparam M2 type of the second matrix (not needed by default)
* \todo use opb_prod()
*/
template<class M1, class T1, class T2, class M2>
M1 & hrk (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2)
{
return m1 = t1 * m1 + t2 * prod (m2, herm (m2));
}
/** \brief generalized symmetric rank \a k update: \f$m_1=t_1.m_1+t_2.(m_2.m3^T)+t_2.(m_3.m2^T)\f$
*
* \param m1 first matrix
* \param t1 first scalar
* \param t2 second scalar
* \param m2 second matrix
* \param m3 third matrix
* \return matrix \c m1
*
* \tparam M1 type of the first matrix (not needed by default)
* \tparam T1 type of the first scalar (not needed by default)
* \tparam T2 type of the second scalar (not needed by default)
* \tparam M2 type of the second matrix (not needed by default)
* \tparam M3 type of the third matrix (not needed by default)
* \todo use opb_prod()
*/
template<class M1, class T1, class T2, class M2, class M3>
M1 & sr2k (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2, const M3 &m3)
{
return m1 = t1 * m1 + t2 * (prod (m2, trans (m3)) + prod (m3, trans (m2)));
}
/** \brief generalized hermitian rank \a k update: * \f$m_1=t_1.m_1+t_2.(m_2.m_3^H)+(m_3.(t_2.m_2)^H)\f$
*
* \param m1 first matrix
* \param t1 first scalar
* \param t2 second scalar
* \param m2 second matrix
* \param m3 third matrix
* \return matrix \c m1
*
* \tparam M1 type of the first matrix (not needed by default)
* \tparam T1 type of the first scalar (not needed by default)
* \tparam T2 type of the second scalar (not needed by default)
* \tparam M2 type of the second matrix (not needed by default)
* \tparam M3 type of the third matrix (not needed by default)
* \todo use opb_prod()
*/
template<class M1, class T1, class T2, class M2, class M3>
M1 & hr2k (M1 &m1, const T1 &t1, const T2 &t2, const M2 &m2, const M3 &m3)
{
return m1 =
t1 * m1
+ t2 * prod (m2, herm (m3))
+ type_traits<T2>::conj (t2) * prod (m3, herm (m2));
}
}
}}}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,290 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_CONFIG_
#define _BOOST_UBLAS_CONFIG_
#include <cassert>
#include <cstddef>
#include <algorithm>
#include <limits>
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
// Microsoft Visual C++
#if defined (BOOST_MSVC) && ! defined (BOOST_STRICT_CONFIG)
// Version 6.0 and 7.0
#if BOOST_MSVC <= 1300
#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
#endif
// Version 7.1
#if BOOST_MSVC == 1310
// One of these workarounds is needed for MSVC 7.1 AFAIK
// (thanks to John Maddock and Martin Lauer).
#if !(defined(BOOST_UBLAS_NO_NESTED_CLASS_RELATION) || defined(BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION))
#define BOOST_UBLAS_NO_NESTED_CLASS_RELATION
#endif
#endif
#endif
// GNU Compiler Collection
#if defined (__GNUC__) && ! defined (BOOST_STRICT_CONFIG)
#if __GNUC__ >= 4 || (__GNUC__ >= 3 && __GNUC_MINOR__ >= 4)
// Specified by ABI definition see GCC bug id 9982
#define BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
#endif
#if __GNUC__ < 3
#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
#endif
#endif
// Intel Compiler
#if defined (BOOST_INTEL) && ! defined (BOOST_STRICT_CONFIG)
#if defined (BOOST_INTEL_LINUX) && (BOOST_INTEL_LINUX >= 800)
// By inspection of compiler results
#define BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
#endif
#if (BOOST_INTEL < 700)
#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
#endif
// Define swap for index_pair and triple.
#if (BOOST_INTEL <= 800)
namespace boost { namespace numeric { namespace ublas {
template<class C, class IC>
class indexed_iterator;
template<class V>
class index_pair;
template<class M>
class index_triple;
}}}
namespace std {
template<class V>
inline
void swap (boost::numeric::ublas::index_pair<V> i1, boost::numeric::ublas::index_pair<V> i2) {
i1.swap (i2);
}
template<class M>
inline
void swap (boost::numeric::ublas::index_triple<M> i1, boost::numeric::ublas::index_triple<M> i2) {
i1.swap (i2);
}
// iter_swap also needed for ICC on Itanium?
template<class C, class IC>
inline
void iter_swap (boost::numeric::ublas::indexed_iterator<C, IC> it1,
boost::numeric::ublas::indexed_iterator<C, IC> it2) {
swap (*it1, *it2);
}
}
#endif
#endif
// Comeau compiler - thanks to Kresimir Fresl
#if defined (__COMO__) && ! defined (BOOST_STRICT_CONFIG)
// Missing std::abs overloads for float types in <cmath> are in <cstdlib>
#if defined(__LIBCOMO__) && (__LIBCOMO_VERSION__ <= 31)
#include <cstdlib>
#endif
#endif
// HP aCC C++ compiler
#if defined (__HP_aCC) && ! defined (BOOST_STRICT_CONFIG)
# if (__HP_aCC >= 60000 )
# define BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
#endif
#endif
// SGI MIPSpro C++ compiler
#if defined (__sgi) && ! defined (BOOST_STRICT_CONFIG)
// Missing std::abs overloads for float types in <cmath> are in <cstdlib>
// This test should be library version specific.
#include <cstdlib>
#if __COMPILER_VERSION >=650
// By inspection of compiler results - thanks to Peter Schmitteckert
#define BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
#endif
#endif
// Metrowerks Codewarrior
#if defined (__MWERKS__) && ! defined (BOOST_STRICT_CONFIG)
// 8.x
#if __MWERKS__ <= 0x3003
#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
#endif
#endif
// Detect other compilers with serious defects - override by defineing BOOST_UBLAS_UNSUPPORTED_COMPILER=0
#ifndef BOOST_UBLAS_UNSUPPORTED_COMPILER
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_SFINAE) || defined(BOOST_NO_STDC_NAMESPACE)
#define BOOST_UBLAS_UNSUPPORTED_COMPILER 1
#endif
#endif
// Cannot continue with an unsupported compiler
#if defined(BOOST_UBLAS_UNSUPPORTED_COMPILER) && (BOOST_UBLAS_UNSUPPORTED_COMPILER != 0)
#error Your compiler and/or configuration is unsupported by this verions of uBLAS. Define BOOST_UBLAS_UNSUPPORTED_COMPILER=0 to override this message. Boost 1.32.0 includes uBLAS with support for many older compilers.
#endif
// Enable performance options in RELEASE mode
#if defined (NDEBUG) || defined (BOOST_UBLAS_NDEBUG)
#ifndef BOOST_UBLAS_INLINE
#define BOOST_UBLAS_INLINE inline
#endif
// Do not check sizes!
#define BOOST_UBLAS_USE_FAST_SAME
// NO runtime error checks with BOOST_UBLAS_CHECK macro
#ifndef BOOST_UBLAS_CHECK_ENABLE
#define BOOST_UBLAS_CHECK_ENABLE 0
#endif
// NO type compatibility numeric checks
#ifndef BOOST_UBLAS_TYPE_CHECK
#define BOOST_UBLAS_TYPE_CHECK 0
#endif
// Disable performance options in DEBUG mode
#else
#ifndef BOOST_UBLAS_INLINE
#define BOOST_UBLAS_INLINE
#endif
// Enable runtime error checks with BOOST_UBLAS_CHECK macro. Check bounds etc
#ifndef BOOST_UBLAS_CHECK_ENABLE
#define BOOST_UBLAS_CHECK_ENABLE 1
#endif
// Type compatibiltity numeric checks
#ifndef BOOST_UBLAS_TYPE_CHECK
#define BOOST_UBLAS_TYPE_CHECK 1
#endif
#endif
/*
* Type compatibility checks
* Control type compatibility numeric runtime checks for non dense matrices.
* Require additional storage and complexity
*/
#if BOOST_UBLAS_TYPE_CHECK
template <class Dummy>
struct disable_type_check
{
static bool value;
};
template <class Dummy>
bool disable_type_check<Dummy>::value = false;
#endif
#ifndef BOOST_UBLAS_TYPE_CHECK_EPSILON
#define BOOST_UBLAS_TYPE_CHECK_EPSILON (type_traits<real_type>::type_sqrt (std::numeric_limits<real_type>::epsilon ()))
#endif
#ifndef BOOST_UBLAS_TYPE_CHECK_MIN
#define BOOST_UBLAS_TYPE_CHECK_MIN (type_traits<real_type>::type_sqrt ( (std::numeric_limits<real_type>::min) ()))
#endif
/*
* General Configuration
*/
// Proxy shortcuts overload the alreadly heavily over used operator ()
//#define BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
// In order to simplify debugging is is possible to simplify expression template
// so they are restricted to a single operation
// #define BOOST_UBLAS_SIMPLE_ET_DEBUG
// Use invariant hoisting.
// #define BOOST_UBLAS_USE_INVARIANT_HOISTING
// Use Duff's device in element access loops
// #define BOOST_UBLAS_USE_DUFF_DEVICE
// Choose evaluation method for dense vectors and matrices
#if !(defined(BOOST_UBLAS_USE_INDEXING) || defined(BOOST_UBLAS_USE_ITERATING))
#define BOOST_UBLAS_USE_INDEXING
#endif
// #define BOOST_UBLAS_ITERATOR_THRESHOLD 0
// Use indexed iterators - unsupported implementation experiment
// #define BOOST_UBLAS_USE_INDEXED_ITERATOR
// Alignment of bounded_array type
#ifndef BOOST_UBLAS_BOUNDED_ARRAY_ALIGN
#define BOOST_UBLAS_BOUNDED_ARRAY_ALIGN
#endif
// Enable different sparse element proxies
#ifndef BOOST_UBLAS_NO_ELEMENT_PROXIES
// Sparse proxies prevent reference invalidation problems in expressions such as:
// a [1] = a [0] = 1 Thanks to Marc Duflot for spotting this.
// #define BOOST_UBLAS_STRICT_MAP_ARRAY
#define BOOST_UBLAS_STRICT_VECTOR_SPARSE
#define BOOST_UBLAS_STRICT_MATRIX_SPARSE
// Hermitian matrices use element proxies to allow assignment to conjugate triangle
#define BOOST_UBLAS_STRICT_HERMITIAN
#endif
// Define to configure special settings for reference returning members
// #define BOOST_UBLAS_REFERENCE_CONST_MEMBER
// #define BOOST_UBLAS_PROXY_CONST_MEMBER
// Include type declerations and functions
#include <boost/numeric/ublas/fwd.hpp>
#include <boost/numeric/ublas/detail/definitions.hpp>
#endif

View File

@@ -0,0 +1,212 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_DEFINITIONS_
#define _BOOST_UBLAS_DEFINITIONS_
namespace boost { namespace numeric { namespace ublas {
namespace detail {
/* Borrowed from boost/concept_checks.hpp
"inline" is used for ignore_unused_variable_warning()
to make sure there is no overhead with g++.
*/
template <class T> inline
void ignore_unused_variable_warning(const T&) {}
} // namespace detail
// Borrowed from Dave Abraham's noncopyable.
// I believe this should be part of utility.hpp one day...
namespace nonassignable_ // protection from unintended ADL
{
class nonassignable {
protected:
nonassignable () {}
~nonassignable () {}
private: // emphasize the following members are private
const nonassignable& operator= (const nonassignable &);
}; // nonassignable
}
typedef nonassignable_::nonassignable nonassignable;
// Assignment proxy.
// Provides temporary free assigment when LHS has no alias on RHS
template<class C>
class noalias_proxy:
private nonassignable {
public:
typedef typename C::closure_type closure_type;
BOOST_UBLAS_INLINE
noalias_proxy (C& lval):
nonassignable (), lval_ (lval) {}
BOOST_UBLAS_INLINE
noalias_proxy (const noalias_proxy& p):
nonassignable (), lval_ (p.lval_) {}
template <class E>
BOOST_UBLAS_INLINE
closure_type &operator= (const E& e) {
lval_.assign (e);
return lval_;
}
template <class E>
BOOST_UBLAS_INLINE
closure_type &operator+= (const E& e) {
lval_.plus_assign (e);
return lval_;
}
template <class E>
BOOST_UBLAS_INLINE
closure_type &operator-= (const E& e) {
lval_.minus_assign (e);
return lval_;
}
private:
closure_type lval_;
};
// Improve syntax of efficient assignment where no aliases of LHS appear on the RHS
// noalias(lhs) = rhs_expression
template <class C>
BOOST_UBLAS_INLINE
noalias_proxy<C> noalias (C& lvalue) {
return noalias_proxy<C> (lvalue);
}
template <class C>
BOOST_UBLAS_INLINE
noalias_proxy<const C> noalias (const C& lvalue) {
return noalias_proxy<const C> (lvalue);
}
// Possible future compatible syntax where lvalue possible has an unsafe alias on the RHS
// safe(lhs) = rhs_expression
template <class C>
BOOST_UBLAS_INLINE
C& safe (C& lvalue) {
return lvalue;
}
template <class C>
BOOST_UBLAS_INLINE
const C& safe (const C& lvalue) {
return lvalue;
}
// Dimension accessors
namespace dimension {
// Generic accessors
template<unsigned dimension>
struct dimension_properties {};
template<>
struct dimension_properties<1> {
template <class E>
BOOST_UBLAS_INLINE static
typename E::size_type size (const vector_expression<E> &e) {
return e ().size ();
}
template <class E>
BOOST_UBLAS_INLINE static
typename E::size_type size (const matrix_expression<E> &e) {
return e ().size1 ();
}
// Note: Index functions cannot deduce dependant template parameter V or M from i
template <class V>
BOOST_UBLAS_INLINE static
typename V::size_type index (const typename V::iterator &i) {
return i.index ();
}
template <class M>
BOOST_UBLAS_INLINE static
typename M::size_type index (const typename M::iterator1 &i) {
return i.index1 ();
}
template <class M>
BOOST_UBLAS_INLINE static
typename M::size_type index (const typename M::iterator2 &i) {
return i.index1 ();
}
};
template<>
struct dimension_properties<2> {
template <class E>
BOOST_UBLAS_INLINE static
typename E::size_type size (const vector_expression<E> &) {
return 1;
}
template <class E>
BOOST_UBLAS_INLINE static
typename E::size_type size (const matrix_expression<E> &e) {
return e ().size2 ();
}
template <class V>
BOOST_UBLAS_INLINE static
typename V::size_type index (const typename V::iterator &) {
return 1;
}
template <class M>
BOOST_UBLAS_INLINE static
typename M::size_type index (const typename M::iterator1 &i) {
return i.index2 ();
}
template <class M>
BOOST_UBLAS_INLINE static
typename M::size_type index (const typename M::iterator2 &i) {
return i.index2 ();
}
};
template<unsigned dimension, class E>
BOOST_UBLAS_INLINE
typename E::size_type size (const E& e) {
return dimension_properties<dimension>::size (e);
}
template<unsigned dimension, class I>
BOOST_UBLAS_INLINE
typename I::container_type::size_type
index (const I& i) {
typedef typename I::container_type container_type;
return dimension_properties<dimension>::template index<container_type> (i);
}
// Named accessors - just syntactic sugar
template<class V>
typename V::size_type num_elements (const V &v) {
return v.size ();
}
template<class M>
typename M::size_type num_rows (const M &m) {
return m.size1 ();
}
template<class M>
typename M::size_type num_columns (const M &m) {
return m.size2 ();
}
template<class MV>
typename MV::size_type num_non_zeros (const MV &mv) {
return mv.non_zeros ();
}
}
}}}
#endif

View File

@@ -0,0 +1,33 @@
//
// Copyright (c) 2000-2004
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
// this file should not contain any code, but the documentation
// global to all files
/** \namespace boost::numeric::ublas
\brief contains all important classes and functions of uBLAS
all ublas definitions ...
\todo expand this section
*/
/** \defgroup blas1 Level 1 BLAS
\brief level 1 basic linear algebra subroutines
*/
/** \defgroup blas2 Level 2 BLAS
\brief level 2 basic linear algebra subroutines
*/
/** \defgroup blas3 Level 3 BLAS
\brief level 3 basic linear algebra subroutines
*/

View File

@@ -0,0 +1,56 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_DUFF_
#define _BOOST_UBLAS_DUFF_
#define DD_SWITCH(n, d, r, expr) \
{ \
unsigned r = ((n) + (d) - 1) / (d); \
switch ((n) % (d)) { \
case 0: do { expr;
#define DD_CASE_I(i, expr) \
case (i): expr;
#define DD_WHILE(r) \
} while (-- (r) > 0); \
} \
}
#define DD_1T(n, d, r, expr) \
DD_WHILE(r)
#define DD_2T(n, d, r, expr) \
DD_CASE_I(1, expr) \
DD_1T(n, d, r, expr)
#define DD_3T(n, d, r, expr) \
DD_CASE_I(2, expr) \
DD_2T(n, d, r, expr)
#define DD_4T(n, d, r, expr) \
DD_CASE_I(3, expr) \
DD_3T(n, d, r, expr)
#define DD_5T(n, d, r, expr) \
DD_CASE_I(4, expr) \
DD_4T(n, d, r, expr)
#define DD_6T(n, d, r, expr) \
DD_CASE_I(5, expr) \
DD_5T(n, d, r, expr)
#define DD_7T(n, d, r, expr) \
DD_CASE_I(6, expr) \
DD_6T(n, d, r, expr)
#define DD_8T(n, d, r, expr) \
DD_CASE_I(7, expr) \
DD_7T(n, d, r, expr)
#define DD(n, d, r, expr) \
DD_SWITCH(n, d, r, expr) \
DD_##d##T(n, d, r, expr)
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,878 @@
//
// Copyright (c) 2002-2003
// Toon Knapen, Kresimir Fresl, Joerg Walter
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
#ifndef _BOOST_UBLAS_RAW_
#define _BOOST_UBLAS_RAW_
namespace boost { namespace numeric { namespace ublas { namespace raw {
// We need data_const() mostly due to MSVC 6.0.
// But how shall we write portable code otherwise?
template < typename V >
BOOST_UBLAS_INLINE
int size( const V &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
int size( const vector_reference<V> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
int size1( const M &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int size2( const M &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int size1( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int size2( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const M &m, row_major_tag ) ;
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const M &m, column_major_tag ) ;
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const M &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const matrix_reference<M> &m ) ;
template < typename V >
BOOST_UBLAS_INLINE
int stride( const V &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
int stride( const vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
int stride( const vector_slice<V> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride( const matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride( const matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const M &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const M &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const matrix_reference<M> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
int stride1( const c_matrix<T, M, N> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
int stride2( const c_matrix<T, M, N> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const matrix_slice<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const matrix_slice<M> &m ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::array_type::const_pointer data( const MV &mv ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::array_type::const_pointer data_const( const MV &mv ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::pointer data( MV &mv ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data( const vector_reference<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data_const( const vector_reference<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer data( vector_reference<V> &v ) ;
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::array_type::const_pointer data( const c_vector<T, N> &v ) ;
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::array_type::const_pointer data_const( const c_vector<T, N> &v ) ;
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::pointer data( c_vector<T, N> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data( const vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data( const vector_slice<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data_const( const vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data_const( const vector_slice<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer data( vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer data( vector_slice<V> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data_const( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_reference<M> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::array_type::const_pointer data( const c_matrix<T, M, N> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::array_type::const_pointer data_const( const c_matrix<T, M, N> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::pointer data( c_matrix<T, M, N> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data( const matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data( const matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data_const( const matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data_const( const matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data( const matrix_slice<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data_const( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer data_const( const matrix_slice<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_slice<M> &m ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::array_type::const_pointer base( const MV &mv ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::array_type::const_pointer base_const( const MV &mv ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::pointer base( MV &mv ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer base( const vector_reference<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer base_const( const vector_reference<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer base( vector_reference<V> &v ) ;
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::array_type::const_pointer base( const c_vector<T, N> &v ) ;
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::array_type::const_pointer base_const( const c_vector<T, N> &v ) ;
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::pointer base( c_vector<T, N> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer base( const vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer base( const vector_slice<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer base_const( const vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer base_const( const vector_slice<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer base( vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer base( vector_slice<V> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base_const( const matrix_reference<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_reference<M> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::array_type::const_pointer base( const c_matrix<T, M, N> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::array_type::const_pointer base_const( const c_matrix<T, M, N> &m ) ;
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::pointer base( c_matrix<T, M, N> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base( const matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base( const matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base_const( const matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base_const( const matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base( const matrix_slice<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base_const( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::array_type::const_pointer base_const( const matrix_slice<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_slice<M> &m ) ;
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::size_type start( const MV &mv ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::size_type start( const vector_range<V> &v ) ;
template < typename V >
BOOST_UBLAS_INLINE
typename V::size_type start( const vector_slice<V> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_row<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_column<M> &v ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_range<M> &m ) ;
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_slice<M> &m ) ;
template < typename V >
BOOST_UBLAS_INLINE
int size( const V &v ) {
return v.size() ;
}
template < typename V >
BOOST_UBLAS_INLINE
int size( const vector_reference<V> &v ) {
return size( v ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int size1( const M &m ) {
return m.size1() ;
}
template < typename M >
BOOST_UBLAS_INLINE
int size2( const M &m ) {
return m.size2() ;
}
template < typename M >
BOOST_UBLAS_INLINE
int size1( const matrix_reference<M> &m ) {
return size1( m.expression() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int size2( const matrix_reference<M> &m ) {
return size2( m.expression() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const M &m, row_major_tag ) {
return m.size2() ;
}
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const M &m, column_major_tag ) {
return m.size1() ;
}
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const M &m ) {
return leading_dimension( m, typename M::orientation_category() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int leading_dimension( const matrix_reference<M> &m ) {
return leading_dimension( m.expression() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
int stride( const V &v ) {
return 1 ;
}
template < typename V >
BOOST_UBLAS_INLINE
int stride( const vector_range<V> &v ) {
return stride( v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
int stride( const vector_slice<V> &v ) {
return v.stride() * stride( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride( const matrix_row<M> &v ) {
return stride2( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride( const matrix_column<M> &v ) {
return stride1( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const M &m ) {
typedef typename M::functor_type functor_type;
return functor_type::one1( m.size1(), m.size2() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const M &m ) {
typedef typename M::functor_type functor_type;
return functor_type::one2( m.size1(), m.size2() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const matrix_reference<M> &m ) {
return stride1( m.expression() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const matrix_reference<M> &m ) {
return stride2( m.expression() ) ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
int stride1( const c_matrix<T, M, N> &m ) {
return N ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
int stride2( const c_matrix<T, M, N> &m ) {
return 1 ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const matrix_range<M> &m ) {
return stride1( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride1( const matrix_slice<M> &m ) {
return m.stride1() * stride1( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const matrix_range<M> &m ) {
return stride2( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
int stride2( const matrix_slice<M> &m ) {
return m.stride2() * stride2( m.data() ) ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::array_type::array_type::const_pointer data( const MV &mv ) {
return &mv.data().begin()[0] ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::array_type::const_pointer data_const( const MV &mv ) {
return &mv.data().begin()[0] ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::pointer data( MV &mv ) {
return &mv.data().begin()[0] ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data( const vector_reference<V> &v ) {
return data( v.expression () ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data_const( const vector_reference<V> &v ) {
return data_const( v.expression () ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer data( vector_reference<V> &v ) {
return data( v.expression () ) ;
}
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::array_type::const_pointer data( const c_vector<T, N> &v ) {
return v.data() ;
}
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::array_type::const_pointer data_const( const c_vector<T, N> &v ) {
return v.data() ;
}
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::pointer data( c_vector<T, N> &v ) {
return v.data() ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data( const vector_range<V> &v ) {
return data( v.data() ) + v.start() * stride (v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data( const vector_slice<V> &v ) {
return data( v.data() ) + v.start() * stride (v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::array_type::const_pointer data_const( const vector_range<V> &v ) {
return data_const( v.data() ) + v.start() * stride (v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer data_const( const vector_slice<V> &v ) {
return data_const( v.data() ) + v.start() * stride (v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer data( vector_range<V> &v ) {
return data( v.data() ) + v.start() * stride (v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer data( vector_slice<V> &v ) {
return data( v.data() ) + v.start() * stride (v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data( const matrix_reference<M> &m ) {
return data( m.expression () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data_const( const matrix_reference<M> &m ) {
return data_const( m.expression () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_reference<M> &m ) {
return data( m.expression () ) ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::const_pointer data( const c_matrix<T, M, N> &m ) {
return m.data() ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::const_pointer data_const( const c_matrix<T, M, N> &m ) {
return m.data() ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::pointer data( c_matrix<T, M, N> &m ) {
return m.data() ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data( const matrix_row<M> &v ) {
return data( v.data() ) + v.index() * stride1( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data( const matrix_column<M> &v ) {
return data( v.data() ) + v.index() * stride2( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data_const( const matrix_row<M> &v ) {
return data_const( v.data() ) + v.index() * stride1( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data_const( const matrix_column<M> &v ) {
return data_const( v.data() ) + v.index() * stride2( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_row<M> &v ) {
return data( v.data() ) + v.index() * stride1( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_column<M> &v ) {
return data( v.data() ) + v.index() * stride2( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data( const matrix_range<M> &m ) {
return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data( const matrix_slice<M> &m ) {
return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data_const( const matrix_range<M> &m ) {
return data_const( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer data_const( const matrix_slice<M> &m ) {
return data_const( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_range<M> &m ) {
return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer data( matrix_slice<M> &m ) {
return data( m.data() ) + m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::const_pointer base( const MV &mv ) {
return &mv.data().begin()[0] ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::const_pointer base_const( const MV &mv ) {
return &mv.data().begin()[0] ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::array_type::pointer base( MV &mv ) {
return &mv.data().begin()[0] ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer base( const vector_reference<V> &v ) {
return base( v.expression () ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer base_const( const vector_reference<V> &v ) {
return base_const( v.expression () ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer base( vector_reference<V> &v ) {
return base( v.expression () ) ;
}
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::const_pointer base( const c_vector<T, N> &v ) {
return v.data() ;
}
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::array_type::const_pointer base_const( const c_vector<T, N> &v ) {
return v.data() ;
}
template < typename T, std::size_t N >
BOOST_UBLAS_INLINE
typename c_vector<T, N>::pointer base( c_vector<T, N> &v ) {
return v.data() ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer base( const vector_range<V> &v ) {
return base( v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer base( const vector_slice<V> &v ) {
return base( v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer base_const( const vector_range<V> &v ) {
return base_const( v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::const_pointer base_const( const vector_slice<V> &v ) {
return base_const( v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer base( vector_range<V> &v ) {
return base( v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::array_type::pointer base( vector_slice<V> &v ) {
return base( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base( const matrix_reference<M> &m ) {
return base( m.expression () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base_const( const matrix_reference<M> &m ) {
return base_const( m.expression () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_reference<M> &m ) {
return base( m.expression () ) ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::const_pointer base( const c_matrix<T, M, N> &m ) {
return m.data() ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::array_type::const_pointer base_const( const c_matrix<T, M, N> &m ) {
return m.data() ;
}
template < typename T, std::size_t M, std::size_t N >
BOOST_UBLAS_INLINE
typename c_matrix<T, M, N>::pointer base( c_matrix<T, M, N> &m ) {
return m.data() ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base( const matrix_row<M> &v ) {
return base( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base( const matrix_column<M> &v ) {
return base( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base_const( const matrix_row<M> &v ) {
return base_const( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base_const( const matrix_column<M> &v ) {
return base_const( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_row<M> &v ) {
return base( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_column<M> &v ) {
return base( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base( const matrix_range<M> &m ) {
return base( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base( const matrix_slice<M> &m ) {
return base( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base_const( const matrix_range<M> &m ) {
return base_const( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::const_pointer base_const( const matrix_slice<M> &m ) {
return base_const( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_range<M> &m ) {
return base( m.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::array_type::pointer base( matrix_slice<M> &m ) {
return base( m.data() ) ;
}
template < typename MV >
BOOST_UBLAS_INLINE
typename MV::size_type start( const MV &mv ) {
return 0 ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::size_type start( const vector_range<V> &v ) {
return v.start() * stride (v.data() ) ;
}
template < typename V >
BOOST_UBLAS_INLINE
typename V::size_type start( const vector_slice<V> &v ) {
return v.start() * stride (v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_row<M> &v ) {
return v.index() * stride1( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_column<M> &v ) {
return v.index() * stride2( v.data() ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_range<M> &m ) {
return m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
template < typename M >
BOOST_UBLAS_INLINE
typename M::size_type start( const matrix_slice<M> &m ) {
return m.start1() * stride1( m.data () ) + m.start2() * stride2( m.data () ) ;
}
}}}}
#endif

View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 2001-2003 Joel de Guzman
*
* Use, modification and distribution is subject to the Boost Software
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef _BOOST_UBLAS_NUMERICTYPE_DEDUCTION_
#define _BOOST_UBLAS_NUMERICTYPE_DEDUCTION_
// See original in boost-sandbox/boost/utility/type_deduction.hpp for comments
#include <boost/mpl/vector/vector20.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace numeric { namespace ublas {
struct error_cant_deduce_type {};
namespace type_deduction_detail
{
typedef char(&bool_value_type)[1];
typedef char(&float_value_type)[2];
typedef char(&double_value_type)[3];
typedef char(&long_double_value_type)[4];
typedef char(&char_value_type)[5];
typedef char(&schar_value_type)[6];
typedef char(&uchar_value_type)[7];
typedef char(&short_value_type)[8];
typedef char(&ushort_value_type)[9];
typedef char(&int_value_type)[10];
typedef char(&uint_value_type)[11];
typedef char(&long_value_type)[12];
typedef char(&ulong_value_type)[13];
typedef char(&x_value_type)[14];
typedef char(&y_value_type)[15];
typedef char(&cant_deduce_type)[16];
template <typename T, typename PlainT = typename remove_cv<T>::type>
struct is_basic
: mpl::or_<
typename mpl::or_<
is_same<PlainT, bool>
, is_same<PlainT, float>
, is_same<PlainT, double>
, is_same<PlainT, long double>
> ::type,
typename mpl::or_<
is_same<PlainT, char>
, is_same<PlainT, signed char>
, is_same<PlainT, unsigned char>
, is_same<PlainT, short>
, is_same<PlainT, unsigned short>
> ::type,
typename mpl::or_<
is_same<PlainT, int>
, is_same<PlainT, unsigned int>
, is_same<PlainT, long>
, is_same<PlainT, unsigned long>
> ::type
> {};
struct asymmetric;
template <typename X, typename Y>
cant_deduce_type
test(...); // The black hole !!!
template <typename X, typename Y>
bool_value_type
test(bool const&);
template <typename X, typename Y>
float_value_type
test(float const&);
template <typename X, typename Y>
double_value_type
test(double const&);
template <typename X, typename Y>
long_double_value_type
test(long double const&);
template <typename X, typename Y>
char_value_type
test(char const&);
template <typename X, typename Y>
schar_value_type
test(signed char const&);
template <typename X, typename Y>
uchar_value_type
test(unsigned char const&);
template <typename X, typename Y>
short_value_type
test(short const&);
template <typename X, typename Y>
ushort_value_type
test(unsigned short const&);
template <typename X, typename Y>
int_value_type
test(int const&);
template <typename X, typename Y>
uint_value_type
test(unsigned int const&);
template <typename X, typename Y>
long_value_type
test(long const&);
template <typename X, typename Y>
ulong_value_type
test(unsigned long const&);
template <typename X, typename Y>
typename disable_if<
is_basic<X>, x_value_type
>::type
test(X const&);
template <typename X, typename Y>
typename disable_if<
mpl::or_<
is_basic<Y>
, is_same<Y, asymmetric>
, is_same<const X, const Y>
>
, y_value_type
>::type
test(Y const&);
template <typename X, typename Y>
struct base_result_of
{
typedef typename remove_cv<X>::type x_type;
typedef typename remove_cv<Y>::type y_type;
typedef mpl::vector16<
mpl::identity<bool>
, mpl::identity<float>
, mpl::identity<double>
, mpl::identity<long double>
, mpl::identity<char>
, mpl::identity<signed char>
, mpl::identity<unsigned char>
, mpl::identity<short>
, mpl::identity<unsigned short>
, mpl::identity<int>
, mpl::identity<unsigned int>
, mpl::identity<long>
, mpl::identity<unsigned long>
, mpl::identity<x_type>
, mpl::identity<y_type>
, mpl::identity<error_cant_deduce_type>
>
types;
};
}}} } // namespace boost::numeric::ublas ::type_deduction_detail
#endif

View File

@@ -0,0 +1,33 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_TEMPORARY_
#define _BOOST_UBLAS_TEMPORARY_
namespace boost { namespace numeric { namespace ublas {
/// For the creation of temporary vectors in the assignment of proxies
template <class M>
struct vector_temporary_traits {
typedef typename M::vector_temporary_type type ;
};
/// For the creation of temporary vectors in the assignment of proxies
template <class M>
struct matrix_temporary_traits {
typedef typename M::matrix_temporary_type type ;
};
} } }
#endif

View File

@@ -0,0 +1,571 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_VECTOR_ASSIGN_
#define _BOOST_UBLAS_VECTOR_ASSIGN_
#include <boost/numeric/ublas/functional.hpp> // scalar_assign
// Required for make_conformant storage
#include <vector>
// Iterators based on ideas of Jeremy Siek
namespace boost { namespace numeric { namespace ublas {
namespace detail {
// Weak equality check - useful to compare equality two arbitary vector expression results.
// Since the actual expressions are unknown, we check for and arbitary error bound
// on the relative error.
// For a linear expression the infinity norm makes sense as we do not know how the elements will be
// combined in the expression. False positive results are inevitable for arbirary expressions!
template<class E1, class E2, class S>
BOOST_UBLAS_INLINE
bool equals (const vector_expression<E1> &e1, const vector_expression<E2> &e2, S epsilon, S min_norm) {
return norm_inf (e1 - e2) < epsilon *
std::max<S> (std::max<S> (norm_inf (e1), norm_inf (e2)), min_norm);
}
template<class E1, class E2>
BOOST_UBLAS_INLINE
bool expression_type_check (const vector_expression<E1> &e1, const vector_expression<E2> &e2) {
typedef typename type_traits<typename promote_traits<typename E1::value_type,
typename E2::value_type>::promote_type>::real_type real_type;
return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
}
// Make sparse proxies conformant
template<class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void make_conformant (V &v, const vector_expression<E> &e) {
BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
typedef typename V::size_type size_type;
typedef typename V::difference_type difference_type;
typedef typename V::value_type value_type;
// FIXME unbounded_array with push_back maybe better
std::vector<size_type> index;
typename V::iterator it (v.begin ());
typename V::iterator it_end (v.end ());
typename E::const_iterator ite (e ().begin ());
typename E::const_iterator ite_end (e ().end ());
if (it != it_end && ite != ite_end) {
size_type it_index = it.index (), ite_index = ite.index ();
while (true) {
difference_type compare = it_index - ite_index;
if (compare == 0) {
++ it, ++ ite;
if (it != it_end && ite != ite_end) {
it_index = it.index ();
ite_index = ite.index ();
} else
break;
} else if (compare < 0) {
increment (it, it_end, - compare);
if (it != it_end)
it_index = it.index ();
else
break;
} else if (compare > 0) {
if (*ite != value_type/*zero*/())
index.push_back (ite.index ());
++ ite;
if (ite != ite_end)
ite_index = ite.index ();
else
break;
}
}
}
while (ite != ite_end) {
if (*ite != value_type/*zero*/())
index.push_back (ite.index ());
++ ite;
}
for (size_type k = 0; k < index.size (); ++ k)
v (index [k]) = value_type/*zero*/();
}
}//namespace detail
// Explicitly iterating
template<template <class T1, class T2> class F, class V, class T>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void iterating_vector_assign_scalar (V &v, const T &t) {
typedef F<typename V::iterator::reference, T> functor_type;
typedef typename V::difference_type difference_type;
difference_type size (v.size ());
typename V::iterator it (v.begin ());
BOOST_UBLAS_CHECK (v.end () - it == size, bad_size ());
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
while (-- size >= 0)
functor_type::apply (*it, t), ++ it;
#else
DD (size, 4, r, (functor_type::apply (*it, t), ++ it));
#endif
}
// Explicitly case
template<template <class T1, class T2> class F, class V, class T>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void indexing_vector_assign_scalar (V &v, const T &t) {
typedef F<typename V::reference, T> functor_type;
typedef typename V::size_type size_type;
size_type size (v.size ());
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
for (size_type i = 0; i < size; ++ i)
functor_type::apply (v (i), t);
#else
size_type i (0);
DD (size, 4, r, (functor_type::apply (v (i), t), ++ i));
#endif
}
// Dense (proxy) case
template<template <class T1, class T2> class F, class V, class T>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign_scalar (V &v, const T &t, dense_proxy_tag) {
#ifdef BOOST_UBLAS_USE_INDEXING
indexing_vector_assign_scalar<F> (v, t);
#elif BOOST_UBLAS_USE_ITERATING
iterating_vector_assign_scalar<F> (v, t);
#else
typedef typename V::size_type size_type;
size_type size (v.size ());
if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
iterating_vector_assign_scalar<F> (v, t);
else
indexing_vector_assign_scalar<F> (v, t);
#endif
}
// Packed (proxy) case
template<template <class T1, class T2> class F, class V, class T>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign_scalar (V &v, const T &t, packed_proxy_tag) {
typedef F<typename V::iterator::reference, T> functor_type;
typedef typename V::difference_type difference_type;
typename V::iterator it (v.begin ());
difference_type size (v.end () - it);
while (-- size >= 0)
functor_type::apply (*it, t), ++ it;
}
// Sparse (proxy) case
template<template <class T1, class T2> class F, class V, class T>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign_scalar (V &v, const T &t, sparse_proxy_tag) {
typedef F<typename V::iterator::reference, T> functor_type;
typename V::iterator it (v.begin ());
typename V::iterator it_end (v.end ());
while (it != it_end)
functor_type::apply (*it, t), ++ it;
}
// Dispatcher
template<template <class T1, class T2> class F, class V, class T>
BOOST_UBLAS_INLINE
void vector_assign_scalar (V &v, const T &t) {
typedef typename V::storage_category storage_category;
vector_assign_scalar<F> (v, t, storage_category ());
}
template<class SC, bool COMPUTED, class RI>
struct vector_assign_traits {
typedef SC storage_category;
};
template<bool COMPUTED>
struct vector_assign_traits<dense_tag, COMPUTED, packed_random_access_iterator_tag> {
typedef packed_tag storage_category;
};
template<>
struct vector_assign_traits<dense_tag, false, sparse_bidirectional_iterator_tag> {
typedef sparse_tag storage_category;
};
template<>
struct vector_assign_traits<dense_tag, true, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<bool COMPUTED>
struct vector_assign_traits<dense_proxy_tag, COMPUTED, packed_random_access_iterator_tag> {
typedef packed_proxy_tag storage_category;
};
template<>
struct vector_assign_traits<dense_proxy_tag, false, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct vector_assign_traits<dense_proxy_tag, true, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct vector_assign_traits<packed_tag, false, sparse_bidirectional_iterator_tag> {
typedef sparse_tag storage_category;
};
template<>
struct vector_assign_traits<packed_tag, true, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<bool COMPUTED>
struct vector_assign_traits<packed_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct vector_assign_traits<sparse_tag, true, dense_random_access_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct vector_assign_traits<sparse_tag, true, packed_random_access_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct vector_assign_traits<sparse_tag, true, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
// Explicitly iterating
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void iterating_vector_assign (V &v, const vector_expression<E> &e) {
typedef F<typename V::iterator::reference, typename E::value_type> functor_type;
typedef typename V::difference_type difference_type;
difference_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));
typename V::iterator it (v.begin ());
BOOST_UBLAS_CHECK (v.end () - it == size, bad_size ());
typename E::const_iterator ite (e ().begin ());
BOOST_UBLAS_CHECK (e ().end () - ite == size, bad_size ());
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
while (-- size >= 0)
functor_type::apply (*it, *ite), ++ it, ++ ite;
#else
DD (size, 2, r, (functor_type::apply (*it, *ite), ++ it, ++ ite));
#endif
}
// Explicitly indexing
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void indexing_vector_assign (V &v, const vector_expression<E> &e) {
typedef F<typename V::reference, typename E::value_type> functor_type;
typedef typename V::size_type size_type;
size_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
for (size_type i = 0; i < size; ++ i)
functor_type::apply (v (i), e () (i));
#else
size_type i (0);
DD (size, 2, r, (functor_type::apply (v (i), e () (i)), ++ i));
#endif
}
// Dense (proxy) case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign (V &v, const vector_expression<E> &e, dense_proxy_tag) {
#ifdef BOOST_UBLAS_USE_INDEXING
indexing_vector_assign<F> (v, e);
#elif BOOST_UBLAS_USE_ITERATING
iterating_vector_assign<F> (v, e);
#else
typedef typename V::size_type size_type;
size_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));
if (size >= BOOST_UBLAS_ITERATOR_THRESHOLD)
iterating_vector_assign<F> (v, e);
else
indexing_vector_assign<F> (v, e);
#endif
}
// Packed (proxy) case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign (V &v, const vector_expression<E> &e, packed_proxy_tag) {
BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
typedef F<typename V::iterator::reference, typename E::value_type> functor_type;
typedef typename V::difference_type difference_type;
typedef typename V::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
vector<value_type> cv (v.size ());
indexing_vector_assign<scalar_assign> (cv, v);
indexing_vector_assign<F> (cv, e);
#endif
typename V::iterator it (v.begin ());
typename V::iterator it_end (v.end ());
typename E::const_iterator ite (e ().begin ());
typename E::const_iterator ite_end (e ().end ());
difference_type it_size (it_end - it);
difference_type ite_size (ite_end - ite);
if (it_size > 0 && ite_size > 0) {
difference_type size ((std::min) (difference_type (it.index () - ite.index ()), ite_size));
if (size > 0) {
ite += size;
ite_size -= size;
}
}
if (it_size > 0 && ite_size > 0) {
difference_type size ((std::min) (difference_type (ite.index () - it.index ()), it_size));
if (size > 0) {
it_size -= size;
if (!functor_type::computed) {
while (-- size >= 0) // zeroing
functor_type::apply (*it, value_type/*zero*/()), ++ it;
} else {
it += size;
}
}
}
difference_type size ((std::min) (it_size, ite_size));
it_size -= size;
ite_size -= size;
while (-- size >= 0)
functor_type::apply (*it, *ite), ++ it, ++ ite;
size = it_size;
if (!functor_type::computed) {
while (-- size >= 0) // zeroing
functor_type::apply (*it, value_type/*zero*/()), ++ it;
} else {
it += size;
}
#if BOOST_UBLAS_TYPE_CHECK
if (! disable_type_check<bool>::value)
BOOST_UBLAS_CHECK (detail::expression_type_check (v, cv),
external_logic ("external logic or bad condition of inputs"));
#endif
}
// Sparse case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign (V &v, const vector_expression<E> &e, sparse_tag) {
BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
typedef F<typename V::iterator::reference, typename E::value_type> functor_type;
BOOST_STATIC_ASSERT ((!functor_type::computed));
typedef typename V::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
vector<value_type> cv (v.size ());
indexing_vector_assign<scalar_assign> (cv, v);
indexing_vector_assign<F> (cv, e);
#endif
v.clear ();
typename E::const_iterator ite (e ().begin ());
typename E::const_iterator ite_end (e ().end ());
while (ite != ite_end) {
value_type t (*ite);
if (t != value_type/*zero*/())
v.insert_element (ite.index (), t);
++ ite;
}
#if BOOST_UBLAS_TYPE_CHECK
if (! disable_type_check<bool>::value)
BOOST_UBLAS_CHECK (detail::expression_type_check (v, cv),
external_logic ("external logic or bad condition of inputs"));
#endif
}
// Sparse proxy or functional case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_assign (V &v, const vector_expression<E> &e, sparse_proxy_tag) {
BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
typedef F<typename V::iterator::reference, typename E::value_type> functor_type;
typedef typename V::size_type size_type;
typedef typename V::difference_type difference_type;
typedef typename V::value_type value_type;
typedef typename V::reference reference;
#if BOOST_UBLAS_TYPE_CHECK
vector<value_type> cv (v.size ());
indexing_vector_assign<scalar_assign> (cv, v);
indexing_vector_assign<F> (cv, e);
#endif
detail::make_conformant (v, e);
typename V::iterator it (v.begin ());
typename V::iterator it_end (v.end ());
typename E::const_iterator ite (e ().begin ());
typename E::const_iterator ite_end (e ().end ());
if (it != it_end && ite != ite_end) {
size_type it_index = it.index (), ite_index = ite.index ();
while (true) {
difference_type compare = it_index - ite_index;
if (compare == 0) {
functor_type::apply (*it, *ite);
++ it, ++ ite;
if (it != it_end && ite != ite_end) {
it_index = it.index ();
ite_index = ite.index ();
} else
break;
} else if (compare < 0) {
if (!functor_type::computed) {
functor_type::apply (*it, value_type/*zero*/());
++ it;
} else
increment (it, it_end, - compare);
if (it != it_end)
it_index = it.index ();
else
break;
} else if (compare > 0) {
increment (ite, ite_end, compare);
if (ite != ite_end)
ite_index = ite.index ();
else
break;
}
}
}
if (!functor_type::computed) {
while (it != it_end) { // zeroing
functor_type::apply (*it, value_type/*zero*/());
++ it;
}
} else {
it = it_end;
}
#if BOOST_UBLAS_TYPE_CHECK
if (! disable_type_check<bool>::value)
BOOST_UBLAS_CHECK (detail::expression_type_check (v, cv),
external_logic ("external logic or bad condition of inputs"));
#endif
}
// Dispatcher
template<template <class T1, class T2> class F, class V, class E>
BOOST_UBLAS_INLINE
void vector_assign (V &v, const vector_expression<E> &e) {
typedef typename vector_assign_traits<typename V::storage_category,
F<typename V::reference, typename E::value_type>::computed,
typename E::const_iterator::iterator_category>::storage_category storage_category;
vector_assign<F> (v, e, storage_category ());
}
template<class SC, class RI>
struct vector_swap_traits {
typedef SC storage_category;
};
template<>
struct vector_swap_traits<dense_proxy_tag, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct vector_swap_traits<packed_proxy_tag, sparse_bidirectional_iterator_tag> {
typedef sparse_proxy_tag storage_category;
};
// Dense (proxy) case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_swap (V &v, vector_expression<E> &e, dense_proxy_tag) {
typedef F<typename V::iterator::reference, typename E::iterator::reference> functor_type;
typedef typename V::difference_type difference_type;
difference_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));
typename V::iterator it (v.begin ());
typename E::iterator ite (e ().begin ());
while (-- size >= 0)
functor_type::apply (*it, *ite), ++ it, ++ ite;
}
// Packed (proxy) case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_swap (V &v, vector_expression<E> &e, packed_proxy_tag) {
typedef F<typename V::iterator::reference, typename E::iterator::reference> functor_type;
typedef typename V::difference_type difference_type;
typename V::iterator it (v.begin ());
typename V::iterator it_end (v.end ());
typename E::iterator ite (e ().begin ());
typename E::iterator ite_end (e ().end ());
difference_type it_size (it_end - it);
difference_type ite_size (ite_end - ite);
if (it_size > 0 && ite_size > 0) {
difference_type size ((std::min) (difference_type (it.index () - ite.index ()), ite_size));
if (size > 0) {
ite += size;
ite_size -= size;
}
}
if (it_size > 0 && ite_size > 0) {
difference_type size ((std::min) (difference_type (ite.index () - it.index ()), it_size));
if (size > 0)
it_size -= size;
}
difference_type size ((std::min) (it_size, ite_size));
it_size -= size;
ite_size -= size;
while (-- size >= 0)
functor_type::apply (*it, *ite), ++ it, ++ ite;
}
// Sparse proxy case
template<template <class T1, class T2> class F, class V, class E>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void vector_swap (V &v, vector_expression<E> &e, sparse_proxy_tag) {
BOOST_UBLAS_CHECK (v.size () == e ().size (), bad_size ());
typedef F<typename V::iterator::reference, typename E::iterator::reference> functor_type;
typedef typename V::size_type size_type;
typedef typename V::difference_type difference_type;
typedef typename V::value_type value_type;
detail::make_conformant (v, e);
// FIXME should be a seperate restriction for E
detail::make_conformant (e (), v);
typename V::iterator it (v.begin ());
typename V::iterator it_end (v.end ());
typename E::iterator ite (e ().begin ());
typename E::iterator ite_end (e ().end ());
if (it != it_end && ite != ite_end) {
size_type it_index = it.index (), ite_index = ite.index ();
while (true) {
difference_type compare = it_index - ite_index;
if (compare == 0) {
functor_type::apply (*it, *ite);
++ it, ++ ite;
if (it != it_end && ite != ite_end) {
it_index = it.index ();
ite_index = ite.index ();
} else
break;
} else if (compare < 0) {
increment (it, it_end, - compare);
if (it != it_end)
it_index = it.index ();
else
break;
} else if (compare > 0) {
increment (ite, ite_end, compare);
if (ite != ite_end)
ite_index = ite.index ();
else
break;
}
}
}
#if BOOST_UBLAS_TYPE_CHECK
increment (ite, ite_end);
increment (it, it_end);
#endif
}
// Dispatcher
template<template <class T1, class T2> class F, class V, class E>
BOOST_UBLAS_INLINE
void vector_swap (V &v, vector_expression<E> &e) {
typedef typename vector_swap_traits<typename V::storage_category,
typename E::const_iterator::iterator_category>::storage_category storage_category;
vector_swap<F> (v, e, storage_category ());
}
}}}
#endif

View File

@@ -0,0 +1,65 @@
//
// Copyright (c) 2010
// David Bellot
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// And we acknowledge the support from all contributors.
/** \mainpage BOOST uBLAS: a Linear Algebra Library
*
* This is the API Reference Documentation.
*
* For introduction, documentations and tutorial, please refer
* to http://www.boost.org/doc/libs/1_44_0/libs/numeric/ublas/doc/index.htm
*
* \section main_classes Main classes
*
* \subsection listvector Vectors
* - \link #boost::numeric::ublas::vector vector \endlink
* - \link #boost::numeric::ublas::bounded_vector bounded_vector \endlink
* - \link #boost::numeric::ublas::zero_vector zero_vector \endlink
* - \link #boost::numeric::ublas::unit_vector unit_vector \endlink
* - \link #boost::numeric::ublas::scalar_vector scalar_vector \endlink
* - \link #boost::numeric::ublas::c_vector c_vector \endlink
* - \link #boost::numeric::ublas::vector_slice vector_slice \endlink
* - \link #boost::numeric::ublas::vector_range vector_range \endlink
* - \link #boost::numeric::ublas::vector_indirect vector_indirect \endlink
* - \link #boost::numeric::ublas::mapped_vector mapped_vector \endlink
* - \link #boost::numeric::ublas::compressed_vector compressed_vector \endlink
* - \link #boost::numeric::ublas::coordinate_vector coordinate_vector \endlink
* - \link #boost::numeric::ublas::matrix_row matrix_row \endlink
* - \link #boost::numeric::ublas::matrix_column matrix_column \endlink
*
* \subsection listmatrix Matrices
* - \link #boost::numeric::ublas::matrix matrix \endlink
* - \link #boost::numeric::ublas::banded_matrix banded_matrix \endlink
* - \link #boost::numeric::ublas::diagonal_matrix diagonal_matrix \endlink
* - \link #boost::numeric::ublas::banded_adaptor banded_adaptor \endlink
* - \link #boost::numeric::ublas::diagonal_adaptor diagonal_adaptor \endlink
* - \link #boost::numeric::ublas::hermitian_matrix hermitian_matrix \endlink
* - \link #boost::numeric::ublas::hermitian_adaptor hermitian_adaptor \endlink
* - \link #boost::numeric::ublas::symmetric_matrix symmetric_matrix \endlink
* - \link #boost::numeric::ublas::symmetric_adaptor symmetric_adaptor \endlink
* - \link #boost::numeric::ublas::triangular_matrix triangular_matrix \endlink
* - \link #boost::numeric::ublas::triangular_adaptor triangular_adaptor \endlink
* - \link #boost::numeric::ublas::vector_of_vector vector_of_vector \endlink
* - \link #boost::numeric::ublas::bounded_matrix bounded_matrix \endlink
* - \link #boost::numeric::ublas::zero_matrix zero_matrix \endlink
* - \link #boost::numeric::ublas::identity_matrix identity_matrix \endlink
* - \link #boost::numeric::ublas::scalar_matrix scalar_matrix \endlink
* - \link #boost::numeric::ublas::c_matrix c_matrix \endlink
* - \link #boost::numeric::ublas::matrix_vector_range matrix_vector_range \endlink
* - \link #boost::numeric::ublas::matrix_vector_slice matrix_vector_slice \endlink
* - \link #boost::numeric::ublas::matrix_vector_indirect matrix_vector_indirect \endlink
* - \link #boost::numeric::ublas::matrix_range matrix_range \endlink
* - \link #boost::numeric::ublas::matrix_slice matrix_slice \endlink
* - \link #boost::numeric::ublas::matrix_indirect matrix_indirect \endlink
* - \link #boost::numeric::ublas::mapped_matrix mapped_matrix \endlink
* - \link #boost::numeric::ublas::mapped_vector_of_mapped_vector mapped_vector_of_mapped_vector \endlink
* - \link #boost::numeric::ublas::compressed_matrix compressed_matrix \endlink
* - \link #boost::numeric::ublas::coordinate_matrix coordinate_matrix \endlink
* - \link #boost::numeric::ublas::generalized_vector_of_vector generalized_vector_of_vector \endlink
*/

View File

@@ -0,0 +1,303 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_EXCEPTION_
#define _BOOST_UBLAS_EXCEPTION_
#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
#include <stdexcept>
#else
#include <cstdlib>
#endif
#ifndef BOOST_UBLAS_NO_STD_CERR
#include <iostream>
#endif
#include <boost/numeric/ublas/detail/config.hpp>
namespace boost { namespace numeric { namespace ublas {
/** \brief Exception raised when a division by zero occurs
*/
struct divide_by_zero
#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
// Inherit from standard exceptions as requested during review.
: public std::runtime_error
{
explicit divide_by_zero (const char *s = "divide by zero") :
std::runtime_error (s) {}
void raise () {
throw *this;
}
#else
{
divide_by_zero ()
{}
explicit divide_by_zero (const char *)
{}
void raise () {
std::abort ();
}
#endif
};
/** \brief Expception raised when some interal errors occurs like computations errors, zeros values where you should not have zeros, etc...
*/
struct internal_logic
#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
// Inherit from standard exceptions as requested during review.
: public std::logic_error {
explicit internal_logic (const char *s = "internal logic") :
std::logic_error (s) {}
void raise () {
throw *this;
}
#else
{
internal_logic ()
{}
explicit internal_logic (const char *)
{}
void raise () {
std::abort ();
}
#endif
};
struct external_logic
#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
// Inherit from standard exceptions as requested during review.
: public std::logic_error {
explicit external_logic (const char *s = "external logic") :
std::logic_error (s) {}
// virtual const char *what () const throw () {
// return "exception: external logic";
// }
void raise () {
throw *this;
}
#else
{
external_logic ()
{}
explicit external_logic (const char *)
{}
void raise () {
std::abort ();
}
#endif
};
struct bad_argument
#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
// Inherit from standard exceptions as requested during review.
: public std::invalid_argument {
explicit bad_argument (const char *s = "bad argument") :
std::invalid_argument (s) {}
void raise () {
throw *this;
}
#else
{
bad_argument ()
{}
explicit bad_argument (const char *)
{}
void raise () {
std::abort ();
}
#endif
};
/**
*/
struct bad_size
#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
// Inherit from standard exceptions as requested during review.
: public std::domain_error {
explicit bad_size (const char *s = "bad size") :
std::domain_error (s) {}
void raise () {
throw *this;
}
#else
{
bad_size ()
{}
explicit bad_size (const char *)
{}
void raise () {
std::abort ();
}
#endif
};
struct bad_index
#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
// Inherit from standard exceptions as requested during review.
: public std::out_of_range {
explicit bad_index (const char *s = "bad index") :
std::out_of_range (s) {}
void raise () {
throw *this;
}
#else
{
bad_index ()
{}
explicit bad_index (const char *)
{}
void raise () {
std::abort ();
}
#endif
};
struct singular
#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
// Inherit from standard exceptions as requested during review.
: public std::runtime_error {
explicit singular (const char *s = "singular") :
std::runtime_error (s) {}
void raise () {
throw *this;
}
#else
{
singular ()
{}
explicit singular (const char *)
{}
void raise () {
std::abort ();
}
#endif
};
struct non_real
#if ! defined (BOOST_NO_EXCEPTIONS) && ! defined (BOOST_UBLAS_NO_EXCEPTIONS)
// Inherit from standard exceptions as requested during review.
: public std::domain_error {
explicit non_real (const char *s = "exception: non real") :
std::domain_error (s) {}
void raise () {
throw *this;
}
#else
{
non_real ()
{}
explicit non_real (const char *)
{}
void raise () {
std::abort ();
}
#endif
};
#if BOOST_UBLAS_CHECK_ENABLE
// Macros are equivilent to
// template<class E>
// BOOST_UBLAS_INLINE
// void check (bool expression, const E &e) {
// if (! expression)
// e.raise ();
// }
// template<class E>
// BOOST_UBLAS_INLINE
// void check_ex (bool expression, const char *file, int line, const E &e) {
// if (! expression)
// e.raise ();
// }
#ifndef BOOST_UBLAS_NO_STD_CERR
#define BOOST_UBLAS_CHECK_FALSE(e) \
std::cerr << "Check failed in file " << __FILE__ << " at line " << __LINE__ << ":" << std::endl; \
e.raise ();
#define BOOST_UBLAS_CHECK(expression, e) \
if (! (expression)) { \
std::cerr << "Check failed in file " << __FILE__ << " at line " << __LINE__ << ":" << std::endl; \
std::cerr << #expression << std::endl; \
e.raise (); \
}
#define BOOST_UBLAS_CHECK_EX(expression, file, line, e) \
if (! (expression)) { \
std::cerr << "Check failed in file " << (file) << " at line " << (line) << ":" << std::endl; \
std::cerr << #expression << std::endl; \
e.raise (); \
}
#else
#define BOOST_UBLAS_CHECK_FALSE(e) \
e.raise ();
#define BOOST_UBLAS_CHECK(expression, e) \
if (! (expression)) { \
e.raise (); \
}
#define BOOST_UBLAS_CHECK_EX(expression, file, line, e) \
if (! (expression)) { \
e.raise (); \
}
#endif
#else
// Macros are equivilent to
// template<class E>
// BOOST_UBLAS_INLINE
// void check (bool expression, const E &e) {}
// template<class E>
// BOOST_UBLAS_INLINE
// void check_ex (bool expression, const char *file, int line, const E &e) {}
#define BOOST_UBLAS_CHECK_FALSE(e)
#define BOOST_UBLAS_CHECK(expression, e)
#define BOOST_UBLAS_CHECK_EX(expression, file, line, e)
#endif
#ifndef BOOST_UBLAS_USE_FAST_SAME
// Macro is equivilent to
// template<class T>
// BOOST_UBLAS_INLINE
// const T &same_impl (const T &size1, const T &size2) {
// BOOST_UBLAS_CHECK (size1 == size2, bad_argument ());
// return (std::min) (size1, size2);
// }
// #define BOOST_UBLAS_SAME(size1, size2) same_impl ((size1), (size2))
// need two types here because different containers can have
// different size_types (especially sparse types)
template<class T1, class T2>
BOOST_UBLAS_INLINE
// Kresimir Fresl and Dan Muller reported problems with COMO.
// We better change the signature instead of libcomo ;-)
// const T &same_impl_ex (const T &size1, const T &size2, const char *file, int line) {
T1 same_impl_ex (const T1 &size1, const T2 &size2, const char *file, int line) {
BOOST_UBLAS_CHECK_EX (size1 == size2, file, line, bad_argument ());
return (size1 < size2)?(size1):(size2);
}
template<class T>
BOOST_UBLAS_INLINE
T same_impl_ex (const T &size1, const T &size2, const char *file, int line) {
BOOST_UBLAS_CHECK_EX (size1 == size2, file, line, bad_argument ());
return (std::min) (size1, size2);
}
#define BOOST_UBLAS_SAME(size1, size2) same_impl_ex ((size1), (size2), __FILE__, __LINE__)
#else
// Macros are equivilent to
// template<class T>
// BOOST_UBLAS_INLINE
// const T &same_impl (const T &size1, const T &size2) {
// return size1;
// }
// #define BOOST_UBLAS_SAME(size1, size2) same_impl ((size1), (size2))
#define BOOST_UBLAS_SAME(size1, size2) (size1)
#endif
}}}
#endif

View File

@@ -0,0 +1,316 @@
//
// Copyright (c) 2009
// Gunter Winkler
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//
#ifndef _BOOST_UBLAS_SPARSE_VIEW_
#define _BOOST_UBLAS_SPARSE_VIEW_
#include <boost/numeric/ublas/matrix_expression.hpp>
#include <boost/numeric/ublas/detail/matrix_assign.hpp>
#if BOOST_UBLAS_TYPE_CHECK
#include <boost/numeric/ublas/matrix.hpp>
#endif
#include <boost/next_prior.hpp>
#include <boost/type_traits/remove_cv.hpp>
namespace boost { namespace numeric { namespace ublas {
// view a chunk of memory as ublas array
template < class T >
class c_array_view
: public storage_array< c_array_view<T> > {
private:
typedef c_array_view<T> self_type;
typedef T * pointer;
public:
// TODO: think about a const pointer
typedef const pointer array_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T value_type;
typedef const T &const_reference;
typedef const T *const_pointer;
typedef const_pointer const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
//
// typedefs required by vector concept
//
typedef dense_tag storage_category;
typedef const vector_reference<const self_type> const_closure_type;
c_array_view(size_type size, array_type data) :
size_(size), data_(data)
{}
~c_array_view()
{}
//
// immutable methods of container concept
//
BOOST_UBLAS_INLINE
size_type size () const {
return size_;
}
BOOST_UBLAS_INLINE
const_reference operator [] (size_type i) const {
BOOST_UBLAS_CHECK (i < size_, bad_index ());
return data_ [i];
}
BOOST_UBLAS_INLINE
const_iterator begin () const {
return data_;
}
BOOST_UBLAS_INLINE
const_iterator end () const {
return data_ + size_;
}
BOOST_UBLAS_INLINE
const_reverse_iterator rbegin () const {
return const_reverse_iterator (end ());
}
BOOST_UBLAS_INLINE
const_reverse_iterator rend () const {
return const_reverse_iterator (begin ());
}
private:
size_type size_;
array_type data_;
};
/** \brief Present existing arrays as compressed array based
* sparse matrix.
* This class provides CRS / CCS storage layout.
*
* see also http://www.netlib.org/utk/papers/templates/node90.html
*
* \param L layout type, either row_major or column_major
* \param IB index base, use 0 for C indexing and 1 for
* FORTRAN indexing of the internal index arrays. This
* does not affect the operator()(int,int) where the first
* row/column has always index 0.
* \param IA index array type, e.g., int[]
* \param TA value array type, e.g., double[]
*/
template<class L, std::size_t IB, class IA, class JA, class TA>
class compressed_matrix_view:
public matrix_expression<compressed_matrix_view<L, IB, IA, JA, TA> > {
public:
typedef typename vector_view_traits<TA>::value_type value_type;
private:
typedef value_type &true_reference;
typedef value_type *pointer;
typedef const value_type *const_pointer;
typedef L layout_type;
typedef compressed_matrix_view<L, IB, IA, JA, TA> self_type;
public:
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
using matrix_expression<self_type>::operator ();
#endif
// ISSUE require type consistency check
// is_convertable (IA::size_type, TA::size_type)
typedef typename boost::remove_cv<typename vector_view_traits<JA>::value_type>::type index_type;
// for compatibility, should be removed some day ...
typedef index_type size_type;
// size_type for the data arrays.
typedef typename vector_view_traits<JA>::size_type array_size_type;
typedef typename vector_view_traits<JA>::difference_type difference_type;
typedef const value_type & const_reference;
// do NOT define reference type, because class is read only
// typedef value_type & reference;
typedef IA rowptr_array_type;
typedef JA index_array_type;
typedef TA value_array_type;
typedef const matrix_reference<const self_type> const_closure_type;
typedef matrix_reference<self_type> closure_type;
// FIXME: define a corresponding temporary type
// typedef compressed_vector<T, IB, IA, TA> vector_temporary_type;
// FIXME: define a corresponding temporary type
// typedef self_type matrix_temporary_type;
typedef sparse_tag storage_category;
typedef typename L::orientation_category orientation_category;
//
// private types for internal use
//
private:
typedef typename vector_view_traits<index_array_type>::const_iterator const_subiterator_type;
//
// Construction and destruction
//
private:
/// private default constructor because data must be filled by caller
BOOST_UBLAS_INLINE
compressed_matrix_view () { }
public:
BOOST_UBLAS_INLINE
compressed_matrix_view (index_type n_rows, index_type n_cols, array_size_type nnz
, const rowptr_array_type & iptr
, const index_array_type & jptr
, const value_array_type & values):
matrix_expression<self_type> (),
size1_ (n_rows), size2_ (n_cols),
nnz_ (nnz),
index1_data_ (iptr),
index2_data_ (jptr),
value_data_ (values) {
storage_invariants ();
}
BOOST_UBLAS_INLINE
compressed_matrix_view(const compressed_matrix_view& o) :
size1_(size1_), size2_(size2_),
nnz_(nnz_),
index1_data_(index1_data_),
index2_data_(index2_data_),
value_data_(value_data_)
{}
//
// implement immutable iterator types
//
class const_iterator1 {};
class const_iterator2 {};
typedef reverse_iterator_base1<const_iterator1> const_reverse_iterator1;
typedef reverse_iterator_base2<const_iterator2> const_reverse_iterator2;
//
// implement all read only methods for the matrix expression concept
//
//! return the number of rows
index_type size1() const {
return size1_;
}
//! return the number of columns
index_type size2() const {
return size2_;
}
//! return value at position (i,j)
value_type operator()(index_type i, index_type j) const {
const_pointer p = find_element(i,j);
if (!p) {
return zero_;
} else {
return *p;
}
}
private:
//
// private helper functions
//
const_pointer find_element (index_type i, index_type j) const {
index_type element1 (layout_type::index_M (i, j));
index_type element2 (layout_type::index_m (i, j));
const array_size_type itv = zero_based( index1_data_[element1] );
const array_size_type itv_next = zero_based( index1_data_[element1+1] );
const_subiterator_type it_start = boost::next(vector_view_traits<index_array_type>::begin(index2_data_),itv);
const_subiterator_type it_end = boost::next(vector_view_traits<index_array_type>::begin(index2_data_),itv_next);
const_subiterator_type it = find_index_in_row(it_start, it_end, element2) ;
if (it == it_end || *it != k_based (element2))
return 0;
return &value_data_ [it - vector_view_traits<index_array_type>::begin(index2_data_)];
}
const_subiterator_type find_index_in_row(const_subiterator_type it_start
, const_subiterator_type it_end
, index_type index) const {
return std::lower_bound( it_start
, it_end
, k_based (index) );
}
private:
void storage_invariants () const {
BOOST_UBLAS_CHECK (index1_data_ [layout_type::size_M (size1_, size2_)] == k_based (nnz_), external_logic ());
}
index_type size1_;
index_type size2_;
array_size_type nnz_;
const rowptr_array_type & index1_data_;
const index_array_type & index2_data_;
const value_array_type & value_data_;
static const value_type zero_;
BOOST_UBLAS_INLINE
static index_type zero_based (index_type k_based_index) {
return k_based_index - IB;
}
BOOST_UBLAS_INLINE
static index_type k_based (index_type zero_based_index) {
return zero_based_index + IB;
}
friend class iterator1;
friend class iterator2;
friend class const_iterator1;
friend class const_iterator2;
};
template<class L, std::size_t IB, class IA, class JA, class TA >
const typename compressed_matrix_view<L,IB,IA,JA,TA>::value_type
compressed_matrix_view<L,IB,IA,JA,TA>::zero_ = value_type/*zero*/();
template<class L, std::size_t IB, class IA, class JA, class TA >
compressed_matrix_view<L,IB,IA,JA,TA>
make_compressed_matrix_view(typename vector_view_traits<JA>::value_type n_rows
, typename vector_view_traits<JA>::value_type n_cols
, typename vector_view_traits<JA>::size_type nnz
, const IA & ia
, const JA & ja
, const TA & ta) {
return compressed_matrix_view<L,IB,IA,JA,TA>(n_rows, n_cols, nnz, ia, ja, ta);
}
}}}
#endif

View File

@@ -0,0 +1,507 @@
//
// Copyright (c) 2000-2010
// Joerg Walter, Mathias Koch. David Bellot
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_EXPRESSION_TYPE_
#define _BOOST_UBLAS_EXPRESSION_TYPE_
#include <boost/numeric/ublas/exception.hpp>
#include <boost/numeric/ublas/traits.hpp>
#include <boost/numeric/ublas/functional.hpp>
// Expression templates based on ideas of Todd Veldhuizen and Geoffrey Furnish
// Iterators based on ideas of Jeremy Siek
namespace boost { namespace numeric { namespace ublas {
/** \brief Base class for uBLAS statically derived expressions using the the Barton Nackman trick
*
* This is a NonAssignable class
* Directly implement nonassignable - simplifes debugging call trace!
*
* \tparam E an expression type
*/
template<class E>
class ublas_expression {
public:
typedef E expression_type;
/* E can be an incomplete type - to define the following we would need more template arguments
typedef typename E::type_category type_category;
typedef typename E::value_type value_type;
*/
protected:
ublas_expression () {}
~ublas_expression () {}
private:
const ublas_expression& operator= (const ublas_expression &);
};
/** \brief Base class for Scalar Expression models
*
* It does not model the Scalar Expression concept but all derived types should.
* The class defines a common base type and some common interface for all statically
* derived Scalar Expression classes.
*
* We implement the casts to the statically derived type.
*
* \tparam E an expression type
*/
template<class E>
class scalar_expression:
public ublas_expression<E> {
public:
typedef E expression_type;
typedef scalar_tag type_category;
BOOST_UBLAS_INLINE
const expression_type &operator () () const {
return *static_cast<const expression_type *> (this);
}
BOOST_UBLAS_INLINE
expression_type &operator () () {
return *static_cast<expression_type *> (this);
}
};
template<class T>
class scalar_reference:
public scalar_expression<scalar_reference<T> > {
typedef scalar_reference<T> self_type;
public:
typedef T value_type;
typedef const value_type &const_reference;
typedef typename boost::mpl::if_<boost::is_const<T>,
const_reference,
value_type &>::type reference;
typedef const self_type const_closure_type;
typedef const_closure_type closure_type;
// Construction and destruction
BOOST_UBLAS_INLINE
explicit scalar_reference (reference t):
t_ (t) {}
// Conversion
BOOST_UBLAS_INLINE
operator value_type () const {
return t_;
}
// Assignment
BOOST_UBLAS_INLINE
scalar_reference &operator = (const scalar_reference &s) {
t_ = s.t_;
return *this;
}
template<class AE>
BOOST_UBLAS_INLINE
scalar_reference &operator = (const scalar_expression<AE> &ae) {
t_ = ae;
return *this;
}
// Closure comparison
BOOST_UBLAS_INLINE
bool same_closure (const scalar_reference &sr) const {
return &t_ == &sr.t_;
}
private:
reference t_;
};
template<class T>
class scalar_value:
public scalar_expression<scalar_value<T> > {
typedef scalar_value<T> self_type;
public:
typedef T value_type;
typedef const value_type &const_reference;
typedef typename boost::mpl::if_<boost::is_const<T>,
const_reference,
value_type &>::type reference;
typedef const scalar_reference<const self_type> const_closure_type;
typedef scalar_reference<self_type> closure_type;
// Construction and destruction
BOOST_UBLAS_INLINE
scalar_value ():
t_ () {}
BOOST_UBLAS_INLINE
scalar_value (const value_type &t):
t_ (t) {}
BOOST_UBLAS_INLINE
operator value_type () const {
return t_;
}
// Assignment
BOOST_UBLAS_INLINE
scalar_value &operator = (const scalar_value &s) {
t_ = s.t_;
return *this;
}
template<class AE>
BOOST_UBLAS_INLINE
scalar_value &operator = (const scalar_expression<AE> &ae) {
t_ = ae;
return *this;
}
// Closure comparison
BOOST_UBLAS_INLINE
bool same_closure (const scalar_value &sv) const {
return this == &sv; // self closing on instances value
}
private:
value_type t_;
};
/** \brief Base class for Vector Expression models
*
* it does not model the Vector Expression concept but all derived types should.
* The class defines a common base type and some common interface for all
* statically derived Vector Expression classes.
* We implement the casts to the statically derived type.
*/
template<class E>
class vector_expression:
public ublas_expression<E> {
public:
static const unsigned complexity = 0;
typedef E expression_type;
typedef vector_tag type_category;
/* E can be an incomplete type - to define the following we would need more template arguments
typedef typename E::size_type size_type;
*/
BOOST_UBLAS_INLINE
const expression_type &operator () () const {
return *static_cast<const expression_type *> (this);
}
BOOST_UBLAS_INLINE
expression_type &operator () () {
return *static_cast<expression_type *> (this);
}
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
private:
// projection types
typedef vector_range<E> vector_range_type;
typedef vector_range<const E> const_vector_range_type;
typedef vector_slice<E> vector_slice_type;
typedef vector_slice<const E> const_vector_slice_type;
// vector_indirect_type will depend on the A template parameter
typedef basic_range<> default_range; // required to avoid range/slice name confusion
typedef basic_slice<> default_slice;
public:
BOOST_UBLAS_INLINE
const_vector_range_type operator () (const default_range &r) const {
return const_vector_range_type (operator () (), r);
}
BOOST_UBLAS_INLINE
vector_range_type operator () (const default_range &r) {
return vector_range_type (operator () (), r);
}
BOOST_UBLAS_INLINE
const_vector_slice_type operator () (const default_slice &s) const {
return const_vector_slice_type (operator () (), s);
}
BOOST_UBLAS_INLINE
vector_slice_type operator () (const default_slice &s) {
return vector_slice_type (operator () (), s);
}
template<class A>
BOOST_UBLAS_INLINE
const vector_indirect<const E, indirect_array<A> > operator () (const indirect_array<A> &ia) const {
return vector_indirect<const E, indirect_array<A> > (operator () (), ia);
}
template<class A>
BOOST_UBLAS_INLINE
vector_indirect<E, indirect_array<A> > operator () (const indirect_array<A> &ia) {
return vector_indirect<E, indirect_array<A> > (operator () (), ia);
}
BOOST_UBLAS_INLINE
const_vector_range_type project (const default_range &r) const {
return const_vector_range_type (operator () (), r);
}
BOOST_UBLAS_INLINE
vector_range_type project (const default_range &r) {
return vector_range_type (operator () (), r);
}
BOOST_UBLAS_INLINE
const_vector_slice_type project (const default_slice &s) const {
return const_vector_slice_type (operator () (), s);
}
BOOST_UBLAS_INLINE
vector_slice_type project (const default_slice &s) {
return vector_slice_type (operator () (), s);
}
template<class A>
BOOST_UBLAS_INLINE
const vector_indirect<const E, indirect_array<A> > project (const indirect_array<A> &ia) const {
return vector_indirect<const E, indirect_array<A> > (operator () (), ia);
}
template<class A>
BOOST_UBLAS_INLINE
vector_indirect<E, indirect_array<A> > project (const indirect_array<A> &ia) {
return vector_indirect<E, indirect_array<A> > (operator () (), ia);
}
#endif
};
/** \brief Base class for Vector container models
*
* it does not model the Vector concept but all derived types should.
* The class defines a common base type and some common interface for all
* statically derived Vector classes
* We implement the casts to the statically derived type.
*/
template<class C>
class vector_container:
public vector_expression<C> {
public:
static const unsigned complexity = 0;
typedef C container_type;
typedef vector_tag type_category;
BOOST_UBLAS_INLINE
const container_type &operator () () const {
return *static_cast<const container_type *> (this);
}
BOOST_UBLAS_INLINE
container_type &operator () () {
return *static_cast<container_type *> (this);
}
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
using vector_expression<C>::operator ();
#endif
};
/** \brief Base class for Matrix Expression models
*
* it does not model the Matrix Expression concept but all derived types should.
* The class defines a common base type and some common interface for all
* statically derived Matrix Expression classes
* We implement the casts to the statically derived type.
*/
template<class E>
class matrix_expression:
public ublas_expression<E> {
private:
typedef matrix_expression<E> self_type;
public:
static const unsigned complexity = 0;
typedef E expression_type;
typedef matrix_tag type_category;
/* E can be an incomplete type - to define the following we would need more template arguments
typedef typename E::size_type size_type;
*/
BOOST_UBLAS_INLINE
const expression_type &operator () () const {
return *static_cast<const expression_type *> (this);
}
BOOST_UBLAS_INLINE
expression_type &operator () () {
return *static_cast<expression_type *> (this);
}
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
private:
// projection types
typedef vector_range<E> vector_range_type;
typedef const vector_range<const E> const_vector_range_type;
typedef vector_slice<E> vector_slice_type;
typedef const vector_slice<const E> const_vector_slice_type;
typedef matrix_row<E> matrix_row_type;
typedef const matrix_row<const E> const_matrix_row_type;
typedef matrix_column<E> matrix_column_type;
typedef const matrix_column<const E> const_matrix_column_type;
typedef matrix_range<E> matrix_range_type;
typedef const matrix_range<const E> const_matrix_range_type;
typedef matrix_slice<E> matrix_slice_type;
typedef const matrix_slice<const E> const_matrix_slice_type;
// matrix_indirect_type will depend on the A template parameter
typedef basic_range<> default_range; // required to avoid range/slice name confusion
typedef basic_slice<> default_slice;
public:
BOOST_UBLAS_INLINE
const_matrix_row_type operator [] (std::size_t i) const {
return const_matrix_row_type (operator () (), i);
}
BOOST_UBLAS_INLINE
matrix_row_type operator [] (std::size_t i) {
return matrix_row_type (operator () (), i);
}
BOOST_UBLAS_INLINE
const_matrix_row_type row (std::size_t i) const {
return const_matrix_row_type (operator () (), i);
}
BOOST_UBLAS_INLINE
matrix_row_type row (std::size_t i) {
return matrix_row_type (operator () (), i);
}
BOOST_UBLAS_INLINE
const_matrix_column_type column (std::size_t j) const {
return const_matrix_column_type (operator () (), j);
}
BOOST_UBLAS_INLINE
matrix_column_type column (std::size_t j) {
return matrix_column_type (operator () (), j);
}
BOOST_UBLAS_INLINE
const_matrix_range_type operator () (const default_range &r1, const default_range &r2) const {
return const_matrix_range_type (operator () (), r1, r2);
}
BOOST_UBLAS_INLINE
matrix_range_type operator () (const default_range &r1, const default_range &r2) {
return matrix_range_type (operator () (), r1, r2);
}
BOOST_UBLAS_INLINE
const_matrix_slice_type operator () (const default_slice &s1, const default_slice &s2) const {
return const_matrix_slice_type (operator () (), s1, s2);
}
BOOST_UBLAS_INLINE
matrix_slice_type operator () (const default_slice &s1, const default_slice &s2) {
return matrix_slice_type (operator () (), s1, s2);
}
template<class A>
BOOST_UBLAS_INLINE
const matrix_indirect<const E, indirect_array<A> > operator () (const indirect_array<A> &ia1, const indirect_array<A> &ia2) const {
return matrix_indirect<const E, indirect_array<A> > (operator () (), ia1, ia2);
}
template<class A>
BOOST_UBLAS_INLINE
matrix_indirect<E, indirect_array<A> > operator () (const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
return matrix_indirect<E, indirect_array<A> > (operator () (), ia1, ia2);
}
BOOST_UBLAS_INLINE
const_matrix_range_type project (const default_range &r1, const default_range &r2) const {
return const_matrix_range_type (operator () (), r1, r2);
}
BOOST_UBLAS_INLINE
matrix_range_type project (const default_range &r1, const default_range &r2) {
return matrix_range_type (operator () (), r1, r2);
}
BOOST_UBLAS_INLINE
const_matrix_slice_type project (const default_slice &s1, const default_slice &s2) const {
return const_matrix_slice_type (operator () (), s1, s2);
}
BOOST_UBLAS_INLINE
matrix_slice_type project (const default_slice &s1, const default_slice &s2) {
return matrix_slice_type (operator () (), s1, s2);
}
template<class A>
BOOST_UBLAS_INLINE
const matrix_indirect<const E, indirect_array<A> > project (const indirect_array<A> &ia1, const indirect_array<A> &ia2) const {
return matrix_indirect<const E, indirect_array<A> > (operator () (), ia1, ia2);
}
template<class A>
BOOST_UBLAS_INLINE
matrix_indirect<E, indirect_array<A> > project (const indirect_array<A> &ia1, const indirect_array<A> &ia2) {
return matrix_indirect<E, indirect_array<A> > (operator () (), ia1, ia2);
}
#endif
};
#ifdef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
struct iterator1_tag {};
struct iterator2_tag {};
template<class I>
BOOST_UBLAS_INLINE
typename I::dual_iterator_type begin (const I &it, iterator1_tag) {
return it ().find2 (1, it.index1 (), 0);
}
template<class I>
BOOST_UBLAS_INLINE
typename I::dual_iterator_type end (const I &it, iterator1_tag) {
return it ().find2 (1, it.index1 (), it ().size2 ());
}
template<class I>
BOOST_UBLAS_INLINE
typename I::dual_reverse_iterator_type rbegin (const I &it, iterator1_tag) {
return typename I::dual_reverse_iterator_type (end (it, iterator1_tag ()));
}
template<class I>
BOOST_UBLAS_INLINE
typename I::dual_reverse_iterator_type rend (const I &it, iterator1_tag) {
return typename I::dual_reverse_iterator_type (begin (it, iterator1_tag ()));
}
template<class I>
BOOST_UBLAS_INLINE
typename I::dual_iterator_type begin (const I &it, iterator2_tag) {
return it ().find1 (1, 0, it.index2 ());
}
template<class I>
BOOST_UBLAS_INLINE
typename I::dual_iterator_type end (const I &it, iterator2_tag) {
return it ().find1 (1, it ().size1 (), it.index2 ());
}
template<class I>
BOOST_UBLAS_INLINE
typename I::dual_reverse_iterator_type rbegin (const I &it, iterator2_tag) {
return typename I::dual_reverse_iterator_type (end (it, iterator2_tag ()));
}
template<class I>
BOOST_UBLAS_INLINE
typename I::dual_reverse_iterator_type rend (const I &it, iterator2_tag) {
return typename I::dual_reverse_iterator_type (begin (it, iterator2_tag ()));
}
#endif
/** \brief Base class for Matrix container models
*
* it does not model the Matrix concept but all derived types should.
* The class defines a common base type and some common interface for all
* statically derived Matrix classes
* We implement the casts to the statically derived type.
*/
template<class C>
class matrix_container:
public matrix_expression<C> {
public:
static const unsigned complexity = 0;
typedef C container_type;
typedef matrix_tag type_category;
BOOST_UBLAS_INLINE
const container_type &operator () () const {
return *static_cast<const container_type *> (this);
}
BOOST_UBLAS_INLINE
container_type &operator () () {
return *static_cast<container_type *> (this);
}
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
using matrix_expression<C>::operator ();
#endif
};
}}}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,217 @@
//
// Copyright (c) 2000-2010
// Joerg Walter, Mathias Koch, David Bellot
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
/// \file fwd.hpp is essentially used to forward declare the main types
#ifndef BOOST_UBLAS_FWD_H
#define BOOST_UBLAS_FWD_H
#include <memory>
namespace boost { namespace numeric { namespace ublas {
// Storage types
template<class T, class ALLOC = std::allocator<T> >
class unbounded_array;
template<class T, std::size_t N, class ALLOC = std::allocator<T> >
class bounded_array;
template <class Z = std::size_t, class D = std::ptrdiff_t>
class basic_range;
template <class Z = std::size_t, class D = std::ptrdiff_t>
class basic_slice;
typedef basic_range<> range;
typedef basic_slice<> slice;
template<class A = unbounded_array<std::size_t> >
class indirect_array;
template<class I, class T, class ALLOC = std::allocator<std::pair<const I, T> > >
class map_std;
template<class I, class T, class ALLOC = std::allocator<std::pair<I, T> > >
class map_array;
// Expression types
struct scalar_tag {};
struct vector_tag {};
template<class E>
class vector_expression;
template<class C>
class vector_container;
template<class E>
class vector_reference;
struct matrix_tag {};
template<class E>
class matrix_expression;
template<class C>
class matrix_container;
template<class E>
class matrix_reference;
template<class V>
class vector_range;
template<class V>
class vector_slice;
template<class V, class IA = indirect_array<> >
class vector_indirect;
template<class M>
class matrix_row;
template<class M>
class matrix_column;
template<class M>
class matrix_vector_range;
template<class M>
class matrix_vector_slice;
template<class M, class IA = indirect_array<> >
class matrix_vector_indirect;
template<class M>
class matrix_range;
template<class M>
class matrix_slice;
template<class M, class IA = indirect_array<> >
class matrix_indirect;
template<class T, class A = unbounded_array<T> >
class vector;
template<class T, std::size_t N>
class bounded_vector;
template<class T = int, class ALLOC = std::allocator<T> >
class unit_vector;
template<class T = int, class ALLOC = std::allocator<T> >
class zero_vector;
template<class T = int, class ALLOC = std::allocator<T> >
class scalar_vector;
template<class T, std::size_t N>
class c_vector;
// Sparse vectors
template<class T, class A = map_std<std::size_t, T> >
class mapped_vector;
template<class T, std::size_t IB = 0, class IA = unbounded_array<std::size_t>, class TA = unbounded_array<T> >
class compressed_vector;
template<class T, std::size_t IB = 0, class IA = unbounded_array<std::size_t>, class TA = unbounded_array<T> >
class coordinate_vector;
// Matrix orientation type
struct unknown_orientation_tag {};
struct row_major_tag {};
struct column_major_tag {};
// Matrix storage layout parameterisation
template <class Z = std::size_t, class D = std::ptrdiff_t>
struct basic_row_major;
typedef basic_row_major<> row_major;
template <class Z = std::size_t, class D = std::ptrdiff_t>
struct basic_column_major;
typedef basic_column_major<> column_major;
template<class T, class L = row_major, class A = unbounded_array<T> >
class matrix;
template<class T, std::size_t M, std::size_t N, class L = row_major>
class bounded_matrix;
template<class T = int, class ALLOC = std::allocator<T> >
class identity_matrix;
template<class T = int, class ALLOC = std::allocator<T> >
class zero_matrix;
template<class T = int, class ALLOC = std::allocator<T> >
class scalar_matrix;
template<class T, std::size_t M, std::size_t N>
class c_matrix;
template<class T, class L = row_major, class A = unbounded_array<unbounded_array<T> > >
class vector_of_vector;
template<class T, class L = row_major, class A = vector<compressed_vector<T> > >
class generalized_vector_of_vector;
// Triangular matrix type
struct lower_tag {};
struct upper_tag {};
struct unit_lower_tag : public lower_tag {};
struct unit_upper_tag : public upper_tag {};
struct strict_lower_tag : public lower_tag {};
struct strict_upper_tag : public upper_tag {};
// Triangular matrix parameterisation
template <class Z = std::size_t>
struct basic_full;
typedef basic_full<> full;
template <class Z = std::size_t>
struct basic_lower;
typedef basic_lower<> lower;
template <class Z = std::size_t>
struct basic_upper;
typedef basic_upper<> upper;
template <class Z = std::size_t>
struct basic_unit_lower;
typedef basic_unit_lower<> unit_lower;
template <class Z = std::size_t>
struct basic_unit_upper;
typedef basic_unit_upper<> unit_upper;
template <class Z = std::size_t>
struct basic_strict_lower;
typedef basic_strict_lower<> strict_lower;
template <class Z = std::size_t>
struct basic_strict_upper;
typedef basic_strict_upper<> strict_upper;
// Special matrices
template<class T, class L = row_major, class A = unbounded_array<T> >
class banded_matrix;
template<class T, class L = row_major, class A = unbounded_array<T> >
class diagonal_matrix;
template<class T, class TRI = lower, class L = row_major, class A = unbounded_array<T> >
class triangular_matrix;
template<class M, class TRI = lower>
class triangular_adaptor;
template<class T, class TRI = lower, class L = row_major, class A = unbounded_array<T> >
class symmetric_matrix;
template<class M, class TRI = lower>
class symmetric_adaptor;
template<class T, class TRI = lower, class L = row_major, class A = unbounded_array<T> >
class hermitian_matrix;
template<class M, class TRI = lower>
class hermitian_adaptor;
// Sparse matrices
template<class T, class L = row_major, class A = map_std<std::size_t, T> >
class mapped_matrix;
template<class T, class L = row_major, class A = map_std<std::size_t, map_std<std::size_t, T> > >
class mapped_vector_of_mapped_vector;
template<class T, class L = row_major, std::size_t IB = 0, class IA = unbounded_array<std::size_t>, class TA = unbounded_array<T> >
class compressed_matrix;
template<class T, class L = row_major, std::size_t IB = 0, class IA = unbounded_array<std::size_t>, class TA = unbounded_array<T> >
class coordinate_matrix;
}}}
#endif

File diff suppressed because it is too large Load Diff

355
test/external/boost/numeric/ublas/io.hpp vendored Normal file
View File

@@ -0,0 +1,355 @@
//
// Copyright (c) 2000-2010
// Joerg Walter, Mathias Koch, David Bellot
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_IO_
#define _BOOST_UBLAS_IO_
// Only forward definition required to define stream operations
#include <iosfwd>
#include <sstream>
#include <boost/numeric/ublas/matrix_expression.hpp>
namespace boost { namespace numeric { namespace ublas {
/** \brief output stream operator for vector expressions
*
* Any vector expressions can be written to a standard output stream
* as defined in the C++ standard library. For example:
* \code
* vector<float> v1(3),v2(3);
* for(size_t i=0; i<3; i++)
* {
* v1(i) = i+0.2;
* v2(i) = i+0.3;
* }
* cout << v1+v2 << endl;
* \endcode
* will display the some of the 2 vectors like this:
* \code
* [3](0.5,2.5,4.5)
* \endcode
*
* \param os is a standard basic output stream
* \param v is a vector expression
* \return a reference to the resulting output stream
*/
template<class E, class T, class VE>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os,
const vector_expression<VE> &v) {
typedef typename VE::size_type size_type;
size_type size = v ().size ();
std::basic_ostringstream<E, T, std::allocator<E> > s;
s.flags (os.flags ());
s.imbue (os.getloc ());
s.precision (os.precision ());
s << '[' << size << "](";
if (size > 0)
s << v () (0);
for (size_type i = 1; i < size; ++ i)
s << ',' << v () (i);
s << ')';
return os << s.str ().c_str ();
}
/** \brief input stream operator for vectors
*
* This is used to feed in vectors with data stored as an ASCII representation
* from a standard input stream.
*
* From a file or any valid stream, the format is:
* \c [<vector size>](<data1>,<data2>,...<dataN>) like for example:
* \code
* [5](1,2.1,3.2,3.14,0.2)
* \endcode
*
* You can use it like this
* \code
* my_input_stream >> my_vector;
* \endcode
*
* You can only put data into a valid \c vector<> not a \c vector_expression
*
* \param is is a standard basic input stream
* \param v is a vector
* \return a reference to the resulting input stream
*/
template<class E, class T, class VT, class VA>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
vector<VT, VA> &v) {
typedef typename vector<VT, VA>::size_type size_type;
E ch;
size_type size;
if (is >> ch && ch != '[') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (is >> size >> ch && ch != ']') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (! is.fail ()) {
vector<VT, VA> s (size);
if (is >> ch && ch != '(') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (! is.fail ()) {
for (size_type i = 0; i < size; i ++) {
if (is >> s (i) >> ch && ch != ',') {
is.putback (ch);
if (i < size - 1)
is.setstate (std::ios_base::failbit);
break;
}
}
if (is >> ch && ch != ')') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
}
}
if (! is.fail ())
v.swap (s);
}
return is;
}
/** \brief output stream operator for matrix expressions
*
* it outpus the content of a \f$(M \times N)\f$ matrix to a standard output
* stream using the following format:
* \c[<rows>,<columns>]((<m00>,<m01>,...,<m0N>),...,(<mM0>,<mM1>,...,<mMN>))
*
* For example:
* \code
* matrix<float> m(3,3) = scalar_matrix<float>(3,3,1.0) - diagonal_matrix<float>(3,3,1.0);
* cout << m << endl;
* \encode
* will display
* \code
* [3,3]((0,1,1),(1,0,1),(1,1,0))
* \endcode
* This output is made for storing and retrieving matrices in a simple way but you can
* easily recognize the following:
* \f[ \left( \begin{array}{ccc} 1 & 1 & 1\\ 1 & 1 & 1\\ 1 & 1 & 1 \end{array} \right) - \left( \begin{array}{ccc} 1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1 \end{array} \right) = \left( \begin{array}{ccc} 0 & 1 & 1\\ 1 & 0 & 1\\ 1 & 1 & 0 \end{array} \right) \f]
*
* \param os is a standard basic output stream
* \param m is a matrix expression
* \return a reference to the resulting output stream
*/
template<class E, class T, class ME>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os,
const matrix_expression<ME> &m) {
typedef typename ME::size_type size_type;
size_type size1 = m ().size1 ();
size_type size2 = m ().size2 ();
std::basic_ostringstream<E, T, std::allocator<E> > s;
s.flags (os.flags ());
s.imbue (os.getloc ());
s.precision (os.precision ());
s << '[' << size1 << ',' << size2 << "](";
if (size1 > 0) {
s << '(' ;
if (size2 > 0)
s << m () (0, 0);
for (size_type j = 1; j < size2; ++ j)
s << ',' << m () (0, j);
s << ')';
}
for (size_type i = 1; i < size1; ++ i) {
s << ",(" ;
if (size2 > 0)
s << m () (i, 0);
for (size_type j = 1; j < size2; ++ j)
s << ',' << m () (i, j);
s << ')';
}
s << ')';
return os << s.str ().c_str ();
}
/** \brief input stream operator for matrices
*
* This is used to feed in matrices with data stored as an ASCII representation
* from a standard input stream.
*
* From a file or any valid standard stream, the format is:
* \c[<rows>,<columns>]((<m00>,<m01>,...,<m0N>),...,(<mM0>,<mM1>,...,<mMN>))
*
* You can use it like this
* \code
* my_input_stream >> my_matrix;
* \endcode
*
* You can only put data into a valid \c matrix<> not a \c matrix_expression
*
* \param is is a standard basic input stream
* \param m is a matrix
* \return a reference to the resulting input stream
*/
template<class E, class T, class MT, class MF, class MA>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
matrix<MT, MF, MA> &m) {
typedef typename matrix<MT, MF, MA>::size_type size_type;
E ch;
size_type size1, size2;
if (is >> ch && ch != '[') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (is >> size1 >> ch && ch != ',') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (is >> size2 >> ch && ch != ']') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (! is.fail ()) {
matrix<MT, MF, MA> s (size1, size2);
if (is >> ch && ch != '(') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (! is.fail ()) {
for (size_type i = 0; i < size1; i ++) {
if (is >> ch && ch != '(') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
break;
}
for (size_type j = 0; j < size2; j ++) {
if (is >> s (i, j) >> ch && ch != ',') {
is.putback (ch);
if (j < size2 - 1) {
is.setstate (std::ios_base::failbit);
break;
}
}
}
if (is >> ch && ch != ')') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
break;
}
if (is >> ch && ch != ',') {
is.putback (ch);
if (i < size1 - 1) {
is.setstate (std::ios_base::failbit);
break;
}
}
}
if (is >> ch && ch != ')') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
}
}
if (! is.fail ())
m.swap (s);
}
return is;
}
/** \brief special input stream operator for symmetric matrices
*
* This is used to feed in symmetric matrices with data stored as an ASCII
* representation from a standard input stream.
*
* You can simply write your matrices in a file or any valid stream and read them again
* at a later time with this function. The format is the following:
* \code [<rows>,<columns>]((<m00>,<m01>,...,<m0N>),...,(<mM0>,<mM1>,...,<mMN>)) \endcode
*
* You can use it like this
* \code
* my_input_stream >> my_symmetric_matrix;
* \endcode
*
* You can only put data into a valid \c symmetric_matrix<>, not in a \c matrix_expression
* This function also checks that input data form a valid symmetric matrix
*
* \param is is a standard basic input stream
* \param m is a \c symmetric_matrix
* \return a reference to the resulting input stream
*/
template<class E, class T, class MT, class MF1, class MF2, class MA>
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
symmetric_matrix<MT, MF1, MF2, MA> &m) {
typedef typename symmetric_matrix<MT, MF1, MF2, MA>::size_type size_type;
E ch;
size_type size1, size2;
MT value;
if (is >> ch && ch != '[') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (is >> size1 >> ch && ch != ',') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (is >> size2 >> ch && (size2 != size1 || ch != ']')) { // symmetric matrix must be square
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (! is.fail ()) {
symmetric_matrix<MT, MF1, MF2, MA> s (size1, size2);
if (is >> ch && ch != '(') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
} else if (! is.fail ()) {
for (size_type i = 0; i < size1; i ++) {
if (is >> ch && ch != '(') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
break;
}
for (size_type j = 0; j < size2; j ++) {
if (is >> value >> ch && ch != ',') {
is.putback (ch);
if (j < size2 - 1) {
is.setstate (std::ios_base::failbit);
break;
}
}
if (i <= j) {
// this is the first time we read this element - set the value
s(i,j) = value;
}
else if ( s(i,j) != value ) {
// matrix is not symmetric
is.setstate (std::ios_base::failbit);
break;
}
}
if (is >> ch && ch != ')') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
break;
}
if (is >> ch && ch != ',') {
is.putback (ch);
if (i < size1 - 1) {
is.setstate (std::ios_base::failbit);
break;
}
}
}
if (is >> ch && ch != ')') {
is.putback (ch);
is.setstate (std::ios_base::failbit);
}
}
if (! is.fail ())
m.swap (s);
}
return is;
}
}}}
#endif

351
test/external/boost/numeric/ublas/lu.hpp vendored Normal file
View File

@@ -0,0 +1,351 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_LU_
#define _BOOST_UBLAS_LU_
#include <boost/numeric/ublas/operation.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/triangular.hpp>
// LU factorizations in the spirit of LAPACK and Golub & van Loan
namespace boost { namespace numeric { namespace ublas {
/** \brief
*
* \tparam T
* \tparam A
*/
template<class T = std::size_t, class A = unbounded_array<T> >
class permutation_matrix:
public vector<T, A> {
public:
typedef vector<T, A> vector_type;
typedef typename vector_type::size_type size_type;
// Construction and destruction
BOOST_UBLAS_INLINE
explicit
permutation_matrix (size_type size):
vector<T, A> (size) {
for (size_type i = 0; i < size; ++ i)
(*this) (i) = i;
}
BOOST_UBLAS_INLINE
explicit
permutation_matrix (const vector_type & init)
: vector_type(init)
{ }
BOOST_UBLAS_INLINE
~permutation_matrix () {}
// Assignment
BOOST_UBLAS_INLINE
permutation_matrix &operator = (const permutation_matrix &m) {
vector_type::operator = (m);
return *this;
}
};
template<class PM, class MV>
BOOST_UBLAS_INLINE
void swap_rows (const PM &pm, MV &mv, vector_tag) {
typedef typename PM::size_type size_type;
typedef typename MV::value_type value_type;
size_type size = pm.size ();
for (size_type i = 0; i < size; ++ i) {
if (i != pm (i))
std::swap (mv (i), mv (pm (i)));
}
}
template<class PM, class MV>
BOOST_UBLAS_INLINE
void swap_rows (const PM &pm, MV &mv, matrix_tag) {
typedef typename PM::size_type size_type;
typedef typename MV::value_type value_type;
size_type size = pm.size ();
for (size_type i = 0; i < size; ++ i) {
if (i != pm (i))
row (mv, i).swap (row (mv, pm (i)));
}
}
// Dispatcher
template<class PM, class MV>
BOOST_UBLAS_INLINE
void swap_rows (const PM &pm, MV &mv) {
swap_rows (pm, mv, typename MV::type_category ());
}
// LU factorization without pivoting
template<class M>
typename M::size_type lu_factorize (M &m) {
typedef M matrix_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
matrix_type cm (m);
#endif
size_type singular = 0;
size_type size1 = m.size1 ();
size_type size2 = m.size2 ();
size_type size = (std::min) (size1, size2);
for (size_type i = 0; i < size; ++ i) {
matrix_column<M> mci (column (m, i));
matrix_row<M> mri (row (m, i));
if (m (i, i) != value_type/*zero*/()) {
value_type m_inv = value_type (1) / m (i, i);
project (mci, range (i + 1, size1)) *= m_inv;
} else if (singular == 0) {
singular = i + 1;
}
project (m, range (i + 1, size1), range (i + 1, size2)).minus_assign (
outer_prod (project (mci, range (i + 1, size1)),
project (mri, range (i + 1, size2))));
}
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (singular != 0 ||
detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
triangular_adaptor<matrix_type, upper> (m)),
cm), internal_logic ());
#endif
return singular;
}
// LU factorization with partial pivoting
template<class M, class PM>
typename M::size_type lu_factorize (M &m, PM &pm) {
typedef M matrix_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
matrix_type cm (m);
#endif
size_type singular = 0;
size_type size1 = m.size1 ();
size_type size2 = m.size2 ();
size_type size = (std::min) (size1, size2);
for (size_type i = 0; i < size; ++ i) {
matrix_column<M> mci (column (m, i));
matrix_row<M> mri (row (m, i));
size_type i_norm_inf = i + index_norm_inf (project (mci, range (i, size1)));
BOOST_UBLAS_CHECK (i_norm_inf < size1, external_logic ());
if (m (i_norm_inf, i) != value_type/*zero*/()) {
if (i_norm_inf != i) {
pm (i) = i_norm_inf;
row (m, i_norm_inf).swap (mri);
} else {
BOOST_UBLAS_CHECK (pm (i) == i_norm_inf, external_logic ());
}
value_type m_inv = value_type (1) / m (i, i);
project (mci, range (i + 1, size1)) *= m_inv;
} else if (singular == 0) {
singular = i + 1;
}
project (m, range (i + 1, size1), range (i + 1, size2)).minus_assign (
outer_prod (project (mci, range (i + 1, size1)),
project (mri, range (i + 1, size2))));
}
#if BOOST_UBLAS_TYPE_CHECK
swap_rows (pm, cm);
BOOST_UBLAS_CHECK (singular != 0 ||
detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
triangular_adaptor<matrix_type, upper> (m)), cm), internal_logic ());
#endif
return singular;
}
template<class M, class PM>
typename M::size_type axpy_lu_factorize (M &m, PM &pm) {
typedef M matrix_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
typedef vector<value_type> vector_type;
#if BOOST_UBLAS_TYPE_CHECK
matrix_type cm (m);
#endif
size_type singular = 0;
size_type size1 = m.size1 ();
size_type size2 = m.size2 ();
size_type size = (std::min) (size1, size2);
#ifndef BOOST_UBLAS_LU_WITH_INPLACE_SOLVE
matrix_type mr (m);
mr.assign (zero_matrix<value_type> (size1, size2));
vector_type v (size1);
for (size_type i = 0; i < size; ++ i) {
matrix_range<matrix_type> lrr (project (mr, range (0, i), range (0, i)));
vector_range<matrix_column<matrix_type> > urr (project (column (mr, i), range (0, i)));
urr.assign (solve (lrr, project (column (m, i), range (0, i)), unit_lower_tag ()));
project (v, range (i, size1)).assign (
project (column (m, i), range (i, size1)) -
axpy_prod<vector_type> (project (mr, range (i, size1), range (0, i)), urr));
size_type i_norm_inf = i + index_norm_inf (project (v, range (i, size1)));
BOOST_UBLAS_CHECK (i_norm_inf < size1, external_logic ());
if (v (i_norm_inf) != value_type/*zero*/()) {
if (i_norm_inf != i) {
pm (i) = i_norm_inf;
std::swap (v (i_norm_inf), v (i));
project (row (m, i_norm_inf), range (i + 1, size2)).swap (project (row (m, i), range (i + 1, size2)));
} else {
BOOST_UBLAS_CHECK (pm (i) == i_norm_inf, external_logic ());
}
project (column (mr, i), range (i + 1, size1)).assign (
project (v, range (i + 1, size1)) / v (i));
if (i_norm_inf != i) {
project (row (mr, i_norm_inf), range (0, i)).swap (project (row (mr, i), range (0, i)));
}
} else if (singular == 0) {
singular = i + 1;
}
mr (i, i) = v (i);
}
m.assign (mr);
#else
matrix_type lr (m);
matrix_type ur (m);
lr.assign (identity_matrix<value_type> (size1, size2));
ur.assign (zero_matrix<value_type> (size1, size2));
vector_type v (size1);
for (size_type i = 0; i < size; ++ i) {
matrix_range<matrix_type> lrr (project (lr, range (0, i), range (0, i)));
vector_range<matrix_column<matrix_type> > urr (project (column (ur, i), range (0, i)));
urr.assign (project (column (m, i), range (0, i)));
inplace_solve (lrr, urr, unit_lower_tag ());
project (v, range (i, size1)).assign (
project (column (m, i), range (i, size1)) -
axpy_prod<vector_type> (project (lr, range (i, size1), range (0, i)), urr));
size_type i_norm_inf = i + index_norm_inf (project (v, range (i, size1)));
BOOST_UBLAS_CHECK (i_norm_inf < size1, external_logic ());
if (v (i_norm_inf) != value_type/*zero*/()) {
if (i_norm_inf != i) {
pm (i) = i_norm_inf;
std::swap (v (i_norm_inf), v (i));
project (row (m, i_norm_inf), range (i + 1, size2)).swap (project (row (m, i), range (i + 1, size2)));
} else {
BOOST_UBLAS_CHECK (pm (i) == i_norm_inf, external_logic ());
}
project (column (lr, i), range (i + 1, size1)).assign (
project (v, range (i + 1, size1)) / v (i));
if (i_norm_inf != i) {
project (row (lr, i_norm_inf), range (0, i)).swap (project (row (lr, i), range (0, i)));
}
} else if (singular == 0) {
singular = i + 1;
}
ur (i, i) = v (i);
}
m.assign (triangular_adaptor<matrix_type, strict_lower> (lr) +
triangular_adaptor<matrix_type, upper> (ur));
#endif
#if BOOST_UBLAS_TYPE_CHECK
swap_rows (pm, cm);
BOOST_UBLAS_CHECK (singular != 0 ||
detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
triangular_adaptor<matrix_type, upper> (m)), cm), internal_logic ());
#endif
return singular;
}
// LU substitution
template<class M, class E>
void lu_substitute (const M &m, vector_expression<E> &e) {
typedef const M const_matrix_type;
typedef vector<typename E::value_type> vector_type;
#if BOOST_UBLAS_TYPE_CHECK
vector_type cv1 (e);
#endif
inplace_solve (m, e, unit_lower_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (triangular_adaptor<const_matrix_type, unit_lower> (m), e), cv1), internal_logic ());
vector_type cv2 (e);
#endif
inplace_solve (m, e, upper_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (triangular_adaptor<const_matrix_type, upper> (m), e), cv2), internal_logic ());
#endif
}
template<class M, class E>
void lu_substitute (const M &m, matrix_expression<E> &e) {
typedef const M const_matrix_type;
typedef matrix<typename E::value_type> matrix_type;
#if BOOST_UBLAS_TYPE_CHECK
matrix_type cm1 (e);
#endif
inplace_solve (m, e, unit_lower_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (triangular_adaptor<const_matrix_type, unit_lower> (m), e), cm1), internal_logic ());
matrix_type cm2 (e);
#endif
inplace_solve (m, e, upper_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (triangular_adaptor<const_matrix_type, upper> (m), e), cm2), internal_logic ());
#endif
}
template<class M, class PMT, class PMA, class MV>
void lu_substitute (const M &m, const permutation_matrix<PMT, PMA> &pm, MV &mv) {
swap_rows (pm, mv);
lu_substitute (m, mv);
}
template<class E, class M>
void lu_substitute (vector_expression<E> &e, const M &m) {
typedef const M const_matrix_type;
typedef vector<typename E::value_type> vector_type;
#if BOOST_UBLAS_TYPE_CHECK
vector_type cv1 (e);
#endif
inplace_solve (e, m, upper_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (e, triangular_adaptor<const_matrix_type, upper> (m)), cv1), internal_logic ());
vector_type cv2 (e);
#endif
inplace_solve (e, m, unit_lower_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (e, triangular_adaptor<const_matrix_type, unit_lower> (m)), cv2), internal_logic ());
#endif
}
template<class E, class M>
void lu_substitute (matrix_expression<E> &e, const M &m) {
typedef const M const_matrix_type;
typedef matrix<typename E::value_type> matrix_type;
#if BOOST_UBLAS_TYPE_CHECK
matrix_type cm1 (e);
#endif
inplace_solve (e, m, upper_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (e, triangular_adaptor<const_matrix_type, upper> (m)), cm1), internal_logic ());
matrix_type cm2 (e);
#endif
inplace_solve (e, m, unit_lower_tag ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (detail::expression_type_check (prod (e, triangular_adaptor<const_matrix_type, unit_lower> (m)), cm2), internal_logic ());
#endif
}
template<class MV, class M, class PMT, class PMA>
void lu_substitute (MV &mv, const M &m, const permutation_matrix<PMT, PMA> &pm) {
swap_rows (pm, mv);
lu_substitute (mv, m);
}
}}}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,851 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_OPERATION_
#define _BOOST_UBLAS_OPERATION_
#include <boost/numeric/ublas/matrix_proxy.hpp>
/** \file operation.hpp
* \brief This file contains some specialized products.
*/
// axpy-based products
// Alexei Novakov had a lot of ideas to improve these. Thanks.
// Hendrik Kueck proposed some new kernel. Thanks again.
namespace boost { namespace numeric { namespace ublas {
template<class V, class T1, class L1, class IA1, class TA1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const compressed_matrix<T1, L1, 0, IA1, TA1> &e1,
const vector_expression<E2> &e2,
V &v, row_major_tag) {
typedef typename V::size_type size_type;
typedef typename V::value_type value_type;
for (size_type i = 0; i < e1.filled1 () -1; ++ i) {
size_type begin = e1.index1_data () [i];
size_type end = e1.index1_data () [i + 1];
value_type t (v (i));
for (size_type j = begin; j < end; ++ j)
t += e1.value_data () [j] * e2 () (e1.index2_data () [j]);
v (i) = t;
}
return v;
}
template<class V, class T1, class L1, class IA1, class TA1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const compressed_matrix<T1, L1, 0, IA1, TA1> &e1,
const vector_expression<E2> &e2,
V &v, column_major_tag) {
typedef typename V::size_type size_type;
for (size_type j = 0; j < e1.filled1 () -1; ++ j) {
size_type begin = e1.index1_data () [j];
size_type end = e1.index1_data () [j + 1];
for (size_type i = begin; i < end; ++ i)
v (e1.index2_data () [i]) += e1.value_data () [i] * e2 () (j);
}
return v;
}
// Dispatcher
template<class V, class T1, class L1, class IA1, class TA1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const compressed_matrix<T1, L1, 0, IA1, TA1> &e1,
const vector_expression<E2> &e2,
V &v, bool init = true) {
typedef typename V::value_type value_type;
typedef typename L1::orientation_category orientation_category;
if (init)
v.assign (zero_vector<value_type> (e1.size1 ()));
#if BOOST_UBLAS_TYPE_CHECK
vector<value_type> cv (v);
typedef typename type_traits<value_type>::real_type real_type;
real_type verrorbound (norm_1 (v) + norm_1 (e1) * norm_1 (e2));
indexing_vector_assign<scalar_plus_assign> (cv, prod (e1, e2));
#endif
axpy_prod (e1, e2, v, orientation_category ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (norm_1 (v - cv) <= 2 * std::numeric_limits<real_type>::epsilon () * verrorbound, internal_logic ());
#endif
return v;
}
template<class V, class T1, class L1, class IA1, class TA1, class E2>
BOOST_UBLAS_INLINE
V
axpy_prod (const compressed_matrix<T1, L1, 0, IA1, TA1> &e1,
const vector_expression<E2> &e2) {
typedef V vector_type;
vector_type v (e1.size1 ());
return axpy_prod (e1, e2, v, true);
}
template<class V, class T1, class L1, class IA1, class TA1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const coordinate_matrix<T1, L1, 0, IA1, TA1> &e1,
const vector_expression<E2> &e2,
V &v, bool init = true) {
typedef typename V::size_type size_type;
typedef typename V::value_type value_type;
typedef L1 layout_type;
size_type size1 = e1.size1();
size_type size2 = e1.size2();
if (init) {
noalias(v) = zero_vector<value_type>(size1);
}
for (size_type i = 0; i < e1.nnz(); ++i) {
size_type row_index = layout_type::index_M( e1.index1_data () [i], e1.index2_data () [i] );
size_type col_index = layout_type::index_m( e1.index1_data () [i], e1.index2_data () [i] );
v( row_index ) += e1.value_data () [i] * e2 () (col_index);
}
return v;
}
template<class V, class E1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const matrix_expression<E1> &e1,
const vector_expression<E2> &e2,
V &v, packed_random_access_iterator_tag, row_major_tag) {
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename V::size_type size_type;
typename expression1_type::const_iterator1 it1 (e1 ().begin1 ());
typename expression1_type::const_iterator1 it1_end (e1 ().end1 ());
while (it1 != it1_end) {
size_type index1 (it1.index1 ());
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
typename expression1_type::const_iterator2 it2 (it1.begin ());
typename expression1_type::const_iterator2 it2_end (it1.end ());
#else
typename expression1_type::const_iterator2 it2 (boost::numeric::ublas::begin (it1, iterator1_tag ()));
typename expression1_type::const_iterator2 it2_end (boost::numeric::ublas::end (it1, iterator1_tag ()));
#endif
while (it2 != it2_end) {
v (index1) += *it2 * e2 () (it2.index2 ());
++ it2;
}
++ it1;
}
return v;
}
template<class V, class E1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const matrix_expression<E1> &e1,
const vector_expression<E2> &e2,
V &v, packed_random_access_iterator_tag, column_major_tag) {
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename V::size_type size_type;
typename expression1_type::const_iterator2 it2 (e1 ().begin2 ());
typename expression1_type::const_iterator2 it2_end (e1 ().end2 ());
while (it2 != it2_end) {
size_type index2 (it2.index2 ());
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
typename expression1_type::const_iterator1 it1 (it2.begin ());
typename expression1_type::const_iterator1 it1_end (it2.end ());
#else
typename expression1_type::const_iterator1 it1 (boost::numeric::ublas::begin (it2, iterator2_tag ()));
typename expression1_type::const_iterator1 it1_end (boost::numeric::ublas::end (it2, iterator2_tag ()));
#endif
while (it1 != it1_end) {
v (it1.index1 ()) += *it1 * e2 () (index2);
++ it1;
}
++ it2;
}
return v;
}
template<class V, class E1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const matrix_expression<E1> &e1,
const vector_expression<E2> &e2,
V &v, sparse_bidirectional_iterator_tag) {
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename V::size_type size_type;
typename expression2_type::const_iterator it (e2 ().begin ());
typename expression2_type::const_iterator it_end (e2 ().end ());
while (it != it_end) {
v.plus_assign (column (e1 (), it.index ()) * *it);
++ it;
}
return v;
}
// Dispatcher
template<class V, class E1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const matrix_expression<E1> &e1,
const vector_expression<E2> &e2,
V &v, packed_random_access_iterator_tag) {
typedef typename E1::orientation_category orientation_category;
return axpy_prod (e1, e2, v, packed_random_access_iterator_tag (), orientation_category ());
}
/** \brief computes <tt>v += A x</tt> or <tt>v = A x</tt> in an
optimized fashion.
\param e1 the matrix expression \c A
\param e2 the vector expression \c x
\param v the result vector \c v
\param init a boolean parameter
<tt>axpy_prod(A, x, v, init)</tt> implements the well known
axpy-product. Setting \a init to \c true is equivalent to call
<tt>v.clear()</tt> before <tt>axpy_prod</tt>. Currently \a init
defaults to \c true, but this may change in the future.
Up to now there are some specialisation for compressed
matrices that give a large speed up compared to prod.
\ingroup blas2
\internal
template parameters:
\param V type of the result vector \c v
\param E1 type of a matrix expression \c A
\param E2 type of a vector expression \c x
*/
template<class V, class E1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const matrix_expression<E1> &e1,
const vector_expression<E2> &e2,
V &v, bool init = true) {
typedef typename V::value_type value_type;
typedef typename E2::const_iterator::iterator_category iterator_category;
if (init)
v.assign (zero_vector<value_type> (e1 ().size1 ()));
#if BOOST_UBLAS_TYPE_CHECK
vector<value_type> cv (v);
typedef typename type_traits<value_type>::real_type real_type;
real_type verrorbound (norm_1 (v) + norm_1 (e1) * norm_1 (e2));
indexing_vector_assign<scalar_plus_assign> (cv, prod (e1, e2));
#endif
axpy_prod (e1, e2, v, iterator_category ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (norm_1 (v - cv) <= 2 * std::numeric_limits<real_type>::epsilon () * verrorbound, internal_logic ());
#endif
return v;
}
template<class V, class E1, class E2>
BOOST_UBLAS_INLINE
V
axpy_prod (const matrix_expression<E1> &e1,
const vector_expression<E2> &e2) {
typedef V vector_type;
vector_type v (e1 ().size1 ());
return axpy_prod (e1, e2, v, true);
}
template<class V, class E1, class T2, class IA2, class TA2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const vector_expression<E1> &e1,
const compressed_matrix<T2, column_major, 0, IA2, TA2> &e2,
V &v, column_major_tag) {
typedef typename V::size_type size_type;
typedef typename V::value_type value_type;
for (size_type j = 0; j < e2.filled1 () -1; ++ j) {
size_type begin = e2.index1_data () [j];
size_type end = e2.index1_data () [j + 1];
value_type t (v (j));
for (size_type i = begin; i < end; ++ i)
t += e2.value_data () [i] * e1 () (e2.index2_data () [i]);
v (j) = t;
}
return v;
}
template<class V, class E1, class T2, class IA2, class TA2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const vector_expression<E1> &e1,
const compressed_matrix<T2, row_major, 0, IA2, TA2> &e2,
V &v, row_major_tag) {
typedef typename V::size_type size_type;
for (size_type i = 0; i < e2.filled1 () -1; ++ i) {
size_type begin = e2.index1_data () [i];
size_type end = e2.index1_data () [i + 1];
for (size_type j = begin; j < end; ++ j)
v (e2.index2_data () [j]) += e2.value_data () [j] * e1 () (i);
}
return v;
}
// Dispatcher
template<class V, class E1, class T2, class L2, class IA2, class TA2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const vector_expression<E1> &e1,
const compressed_matrix<T2, L2, 0, IA2, TA2> &e2,
V &v, bool init = true) {
typedef typename V::value_type value_type;
typedef typename L2::orientation_category orientation_category;
if (init)
v.assign (zero_vector<value_type> (e2.size2 ()));
#if BOOST_UBLAS_TYPE_CHECK
vector<value_type> cv (v);
typedef typename type_traits<value_type>::real_type real_type;
real_type verrorbound (norm_1 (v) + norm_1 (e1) * norm_1 (e2));
indexing_vector_assign<scalar_plus_assign> (cv, prod (e1, e2));
#endif
axpy_prod (e1, e2, v, orientation_category ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (norm_1 (v - cv) <= 2 * std::numeric_limits<real_type>::epsilon () * verrorbound, internal_logic ());
#endif
return v;
}
template<class V, class E1, class T2, class L2, class IA2, class TA2>
BOOST_UBLAS_INLINE
V
axpy_prod (const vector_expression<E1> &e1,
const compressed_matrix<T2, L2, 0, IA2, TA2> &e2) {
typedef V vector_type;
vector_type v (e2.size2 ());
return axpy_prod (e1, e2, v, true);
}
template<class V, class E1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const vector_expression<E1> &e1,
const matrix_expression<E2> &e2,
V &v, packed_random_access_iterator_tag, column_major_tag) {
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename V::size_type size_type;
typename expression2_type::const_iterator2 it2 (e2 ().begin2 ());
typename expression2_type::const_iterator2 it2_end (e2 ().end2 ());
while (it2 != it2_end) {
size_type index2 (it2.index2 ());
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
typename expression2_type::const_iterator1 it1 (it2.begin ());
typename expression2_type::const_iterator1 it1_end (it2.end ());
#else
typename expression2_type::const_iterator1 it1 (boost::numeric::ublas::begin (it2, iterator2_tag ()));
typename expression2_type::const_iterator1 it1_end (boost::numeric::ublas::end (it2, iterator2_tag ()));
#endif
while (it1 != it1_end) {
v (index2) += *it1 * e1 () (it1.index1 ());
++ it1;
}
++ it2;
}
return v;
}
template<class V, class E1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const vector_expression<E1> &e1,
const matrix_expression<E2> &e2,
V &v, packed_random_access_iterator_tag, row_major_tag) {
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename V::size_type size_type;
typename expression2_type::const_iterator1 it1 (e2 ().begin1 ());
typename expression2_type::const_iterator1 it1_end (e2 ().end1 ());
while (it1 != it1_end) {
size_type index1 (it1.index1 ());
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
typename expression2_type::const_iterator2 it2 (it1.begin ());
typename expression2_type::const_iterator2 it2_end (it1.end ());
#else
typename expression2_type::const_iterator2 it2 (boost::numeric::ublas::begin (it1, iterator1_tag ()));
typename expression2_type::const_iterator2 it2_end (boost::numeric::ublas::end (it1, iterator1_tag ()));
#endif
while (it2 != it2_end) {
v (it2.index2 ()) += *it2 * e1 () (index1);
++ it2;
}
++ it1;
}
return v;
}
template<class V, class E1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const vector_expression<E1> &e1,
const matrix_expression<E2> &e2,
V &v, sparse_bidirectional_iterator_tag) {
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename V::size_type size_type;
typename expression1_type::const_iterator it (e1 ().begin ());
typename expression1_type::const_iterator it_end (e1 ().end ());
while (it != it_end) {
v.plus_assign (*it * row (e2 (), it.index ()));
++ it;
}
return v;
}
// Dispatcher
template<class V, class E1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const vector_expression<E1> &e1,
const matrix_expression<E2> &e2,
V &v, packed_random_access_iterator_tag) {
typedef typename E2::orientation_category orientation_category;
return axpy_prod (e1, e2, v, packed_random_access_iterator_tag (), orientation_category ());
}
/** \brief computes <tt>v += A<sup>T</sup> x</tt> or <tt>v = A<sup>T</sup> x</tt> in an
optimized fashion.
\param e1 the vector expression \c x
\param e2 the matrix expression \c A
\param v the result vector \c v
\param init a boolean parameter
<tt>axpy_prod(x, A, v, init)</tt> implements the well known
axpy-product. Setting \a init to \c true is equivalent to call
<tt>v.clear()</tt> before <tt>axpy_prod</tt>. Currently \a init
defaults to \c true, but this may change in the future.
Up to now there are some specialisation for compressed
matrices that give a large speed up compared to prod.
\ingroup blas2
\internal
template parameters:
\param V type of the result vector \c v
\param E1 type of a vector expression \c x
\param E2 type of a matrix expression \c A
*/
template<class V, class E1, class E2>
BOOST_UBLAS_INLINE
V &
axpy_prod (const vector_expression<E1> &e1,
const matrix_expression<E2> &e2,
V &v, bool init = true) {
typedef typename V::value_type value_type;
typedef typename E1::const_iterator::iterator_category iterator_category;
if (init)
v.assign (zero_vector<value_type> (e2 ().size2 ()));
#if BOOST_UBLAS_TYPE_CHECK
vector<value_type> cv (v);
typedef typename type_traits<value_type>::real_type real_type;
real_type verrorbound (norm_1 (v) + norm_1 (e1) * norm_1 (e2));
indexing_vector_assign<scalar_plus_assign> (cv, prod (e1, e2));
#endif
axpy_prod (e1, e2, v, iterator_category ());
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (norm_1 (v - cv) <= 2 * std::numeric_limits<real_type>::epsilon () * verrorbound, internal_logic ());
#endif
return v;
}
template<class V, class E1, class E2>
BOOST_UBLAS_INLINE
V
axpy_prod (const vector_expression<E1> &e1,
const matrix_expression<E2> &e2) {
typedef V vector_type;
vector_type v (e2 ().size2 ());
return axpy_prod (e1, e2, v, true);
}
template<class M, class E1, class E2, class TRI>
BOOST_UBLAS_INLINE
M &
axpy_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m, TRI,
dense_proxy_tag, row_major_tag) {
typedef M matrix_type;
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
matrix<value_type, row_major> cm (m);
typedef typename type_traits<value_type>::real_type real_type;
real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
indexing_matrix_assign<scalar_plus_assign> (cm, prod (e1, e2), row_major_tag ());
#endif
size_type size1 (e1 ().size1 ());
size_type size2 (e1 ().size2 ());
for (size_type i = 0; i < size1; ++ i)
for (size_type j = 0; j < size2; ++ j)
row (m, i).plus_assign (e1 () (i, j) * row (e2 (), j));
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
#endif
return m;
}
template<class M, class E1, class E2, class TRI>
BOOST_UBLAS_INLINE
M &
axpy_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m, TRI,
sparse_proxy_tag, row_major_tag) {
typedef M matrix_type;
typedef TRI triangular_restriction;
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
matrix<value_type, row_major> cm (m);
typedef typename type_traits<value_type>::real_type real_type;
real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
indexing_matrix_assign<scalar_plus_assign> (cm, prod (e1, e2), row_major_tag ());
#endif
typename expression1_type::const_iterator1 it1 (e1 ().begin1 ());
typename expression1_type::const_iterator1 it1_end (e1 ().end1 ());
while (it1 != it1_end) {
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
typename expression1_type::const_iterator2 it2 (it1.begin ());
typename expression1_type::const_iterator2 it2_end (it1.end ());
#else
typename expression1_type::const_iterator2 it2 (boost::numeric::ublas::begin (it1, iterator1_tag ()));
typename expression1_type::const_iterator2 it2_end (boost::numeric::ublas::end (it1, iterator1_tag ()));
#endif
while (it2 != it2_end) {
// row (m, it1.index1 ()).plus_assign (*it2 * row (e2 (), it2.index2 ()));
matrix_row<expression2_type> mr (e2 (), it2.index2 ());
typename matrix_row<expression2_type>::const_iterator itr (mr.begin ());
typename matrix_row<expression2_type>::const_iterator itr_end (mr.end ());
while (itr != itr_end) {
if (triangular_restriction::other (it1.index1 (), itr.index ()))
m (it1.index1 (), itr.index ()) += *it2 * *itr;
++ itr;
}
++ it2;
}
++ it1;
}
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
#endif
return m;
}
template<class M, class E1, class E2, class TRI>
BOOST_UBLAS_INLINE
M &
axpy_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m, TRI,
dense_proxy_tag, column_major_tag) {
typedef M matrix_type;
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
matrix<value_type, column_major> cm (m);
typedef typename type_traits<value_type>::real_type real_type;
real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
indexing_matrix_assign<scalar_plus_assign> (cm, prod (e1, e2), column_major_tag ());
#endif
size_type size1 (e2 ().size1 ());
size_type size2 (e2 ().size2 ());
for (size_type j = 0; j < size2; ++ j)
for (size_type i = 0; i < size1; ++ i)
column (m, j).plus_assign (e2 () (i, j) * column (e1 (), i));
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
#endif
return m;
}
template<class M, class E1, class E2, class TRI>
BOOST_UBLAS_INLINE
M &
axpy_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m, TRI,
sparse_proxy_tag, column_major_tag) {
typedef M matrix_type;
typedef TRI triangular_restriction;
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
matrix<value_type, column_major> cm (m);
typedef typename type_traits<value_type>::real_type real_type;
real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
indexing_matrix_assign<scalar_plus_assign> (cm, prod (e1, e2), column_major_tag ());
#endif
typename expression2_type::const_iterator2 it2 (e2 ().begin2 ());
typename expression2_type::const_iterator2 it2_end (e2 ().end2 ());
while (it2 != it2_end) {
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
typename expression2_type::const_iterator1 it1 (it2.begin ());
typename expression2_type::const_iterator1 it1_end (it2.end ());
#else
typename expression2_type::const_iterator1 it1 (boost::numeric::ublas::begin (it2, iterator2_tag ()));
typename expression2_type::const_iterator1 it1_end (boost::numeric::ublas::end (it2, iterator2_tag ()));
#endif
while (it1 != it1_end) {
// column (m, it2.index2 ()).plus_assign (*it1 * column (e1 (), it1.index1 ()));
matrix_column<expression1_type> mc (e1 (), it1.index1 ());
typename matrix_column<expression1_type>::const_iterator itc (mc.begin ());
typename matrix_column<expression1_type>::const_iterator itc_end (mc.end ());
while (itc != itc_end) {
if(triangular_restriction::other (itc.index (), it2.index2 ()))
m (itc.index (), it2.index2 ()) += *it1 * *itc;
++ itc;
}
++ it1;
}
++ it2;
}
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
#endif
return m;
}
// Dispatcher
template<class M, class E1, class E2, class TRI>
BOOST_UBLAS_INLINE
M &
axpy_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m, TRI, bool init = true) {
typedef typename M::value_type value_type;
typedef typename M::storage_category storage_category;
typedef typename M::orientation_category orientation_category;
typedef TRI triangular_restriction;
if (init)
m.assign (zero_matrix<value_type> (e1 ().size1 (), e2 ().size2 ()));
return axpy_prod (e1, e2, m, triangular_restriction (), storage_category (), orientation_category ());
}
template<class M, class E1, class E2, class TRI>
BOOST_UBLAS_INLINE
M
axpy_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
TRI) {
typedef M matrix_type;
typedef TRI triangular_restriction;
matrix_type m (e1 ().size1 (), e2 ().size2 ());
return axpy_prod (e1, e2, m, triangular_restriction (), true);
}
/** \brief computes <tt>M += A X</tt> or <tt>M = A X</tt> in an
optimized fashion.
\param e1 the matrix expression \c A
\param e2 the matrix expression \c X
\param m the result matrix \c M
\param init a boolean parameter
<tt>axpy_prod(A, X, M, init)</tt> implements the well known
axpy-product. Setting \a init to \c true is equivalent to call
<tt>M.clear()</tt> before <tt>axpy_prod</tt>. Currently \a init
defaults to \c true, but this may change in the future.
Up to now there are no specialisations.
\ingroup blas3
\internal
template parameters:
\param M type of the result matrix \c M
\param E1 type of a matrix expression \c A
\param E2 type of a matrix expression \c X
*/
template<class M, class E1, class E2>
BOOST_UBLAS_INLINE
M &
axpy_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m, bool init = true) {
typedef typename M::value_type value_type;
typedef typename M::storage_category storage_category;
typedef typename M::orientation_category orientation_category;
if (init)
m.assign (zero_matrix<value_type> (e1 ().size1 (), e2 ().size2 ()));
return axpy_prod (e1, e2, m, full (), storage_category (), orientation_category ());
}
template<class M, class E1, class E2>
BOOST_UBLAS_INLINE
M
axpy_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2) {
typedef M matrix_type;
matrix_type m (e1 ().size1 (), e2 ().size2 ());
return axpy_prod (e1, e2, m, full (), true);
}
template<class M, class E1, class E2>
BOOST_UBLAS_INLINE
M &
opb_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m,
dense_proxy_tag, row_major_tag) {
typedef M matrix_type;
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
matrix<value_type, row_major> cm (m);
typedef typename type_traits<value_type>::real_type real_type;
real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
indexing_matrix_assign<scalar_plus_assign> (cm, prod (e1, e2), row_major_tag ());
#endif
size_type size (BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ()));
for (size_type k = 0; k < size; ++ k) {
vector<value_type> ce1 (column (e1 (), k));
vector<value_type> re2 (row (e2 (), k));
m.plus_assign (outer_prod (ce1, re2));
}
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
#endif
return m;
}
template<class M, class E1, class E2>
BOOST_UBLAS_INLINE
M &
opb_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m,
dense_proxy_tag, column_major_tag) {
typedef M matrix_type;
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
#if BOOST_UBLAS_TYPE_CHECK
matrix<value_type, column_major> cm (m);
typedef typename type_traits<value_type>::real_type real_type;
real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
indexing_matrix_assign<scalar_plus_assign> (cm, prod (e1, e2), column_major_tag ());
#endif
size_type size (BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ()));
for (size_type k = 0; k < size; ++ k) {
vector<value_type> ce1 (column (e1 (), k));
vector<value_type> re2 (row (e2 (), k));
m.plus_assign (outer_prod (ce1, re2));
}
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
#endif
return m;
}
// Dispatcher
/** \brief computes <tt>M += A X</tt> or <tt>M = A X</tt> in an
optimized fashion.
\param e1 the matrix expression \c A
\param e2 the matrix expression \c X
\param m the result matrix \c M
\param init a boolean parameter
<tt>opb_prod(A, X, M, init)</tt> implements the well known
axpy-product. Setting \a init to \c true is equivalent to call
<tt>M.clear()</tt> before <tt>opb_prod</tt>. Currently \a init
defaults to \c true, but this may change in the future.
This function may give a speedup if \c A has less columns than
rows, because the product is computed as a sum of outer
products.
\ingroup blas3
\internal
template parameters:
\param M type of the result matrix \c M
\param E1 type of a matrix expression \c A
\param E2 type of a matrix expression \c X
*/
template<class M, class E1, class E2>
BOOST_UBLAS_INLINE
M &
opb_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m, bool init = true) {
typedef typename M::value_type value_type;
typedef typename M::storage_category storage_category;
typedef typename M::orientation_category orientation_category;
if (init)
m.assign (zero_matrix<value_type> (e1 ().size1 (), e2 ().size2 ()));
return opb_prod (e1, e2, m, storage_category (), orientation_category ());
}
template<class M, class E1, class E2>
BOOST_UBLAS_INLINE
M
opb_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2) {
typedef M matrix_type;
matrix_type m (e1 ().size1 (), e2 ().size2 ());
return opb_prod (e1, e2, m, true);
}
}}}
#endif

View File

@@ -0,0 +1,318 @@
/**
* -*- c++ -*-
*
* \file begin.hpp
*
* \brief The \c begin operation.
*
* Copyright (c) 2009, Marco Guazzone
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* \author Marco Guazzone, marco.guazzone@gmail.com
*/
#ifndef BOOST_NUMERIC_UBLAS_OPERATION_BEGIN_HPP
#define BOOST_NUMERIC_UBLAS_OPERATION_BEGIN_HPP
#include <boost/numeric/ublas/expression_types.hpp>
#include <boost/numeric/ublas/fwd.hpp>
#include <boost/numeric/ublas/traits/const_iterator_type.hpp>
#include <boost/numeric/ublas/traits/iterator_type.hpp>
namespace boost { namespace numeric { namespace ublas {
namespace detail {
/**
* \brief Auxiliary class for implementing the \c begin operation.
* \tparam CategoryT The expression category type (e.g., vector_tag).
* \tparam TagT The dimension type tag (e.g., tag::major).
* \tparam OrientationT The orientation category type (e.g., row_major_tag).
*/
template <typename CategoryT, typename TagT=void, typename OrientationT=void>
struct begin_impl;
/// \brief Specialization of \c begin_impl for iterating vector expressions.
template <>
struct begin_impl<vector_tag,void,void>
{
/**
* \brief Return an iterator to the first element of the given vector
* expression.
* \tparam ExprT A model of VectorExpression type.
* \param e A vector expression.
* \return An iterator over the given vector expression.
*/
template <typename ExprT>
static typename ExprT::iterator apply(ExprT& e)
{
return e.begin();
}
/**
* \brief Return a const iterator to the first element of the given vector
* expression.
* \tparam ExprT A model of VectorExpression type.
* \param e A vector expression.
* \return A const iterator to the first element of the given vector
* expression.
*/
template <typename ExprT>
static typename ExprT::const_iterator apply(ExprT const& e)
{
return e.begin();
}
};
/// \brief Specialization of \c begin_impl for iterating matrix expressions with
/// a row-major orientation over the major dimension.
template <>
struct begin_impl<matrix_tag,tag::major,row_major_tag>
{
/**
* \brief Return an iterator to the first element of the given row-major
* matrix expression over the major dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return An iterator over the major dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::iterator1 apply(ExprT& e)
{
return e.begin1();
}
/**
* \brief Return a const iterator to the first element of the given
* row-major matrix expression over the major dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return A const iterator over the major dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::const_iterator1 apply(ExprT const& e)
{
return e.begin1();
}
};
/// \brief Specialization of \c begin_impl for iterating matrix expressions with
/// a column-major orientation over the major dimension.
template <>
struct begin_impl<matrix_tag,tag::major,column_major_tag>
{
/**
* \brief Return an iterator to the first element of the given column-major
* matrix expression over the major dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return An iterator over the major dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::iterator2 apply(ExprT& e)
{
return e.begin2();
}
/**
* \brief Return a const iterator to the first element of the given
* column-major matrix expression over the major dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return A const iterator over the major dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::const_iterator2 apply(ExprT const& e)
{
return e.begin2();
}
};
/// \brief Specialization of \c begin_impl for iterating matrix expressions with
/// a row-major orientation over the minor dimension.
template <>
struct begin_impl<matrix_tag,tag::minor,row_major_tag>
{
/**
* \brief Return an iterator to the first element of the given row-major
* matrix expression over the minor dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return An iterator over the minor dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::iterator2 apply(ExprT& e)
{
return e.begin2();
}
/**
* \brief Return a const iterator to the first element of the given
* row-major matrix expression over the minor dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return A const iterator over the minor dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::const_iterator2 apply(ExprT const& e)
{
return e.begin2();
}
};
/// \brief Specialization of \c begin_impl for iterating matrix expressions with
/// a column-major orientation over the minor dimension.
template <>
struct begin_impl<matrix_tag,tag::minor,column_major_tag>
{
/**
* \brief Return an iterator to the first element of the given column-major
* matrix expression over the minor dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return An iterator over the minor dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::iterator1 apply(ExprT& e)
{
return e.begin1();
}
/**
* \brief Return a const iterator to the first element of the given
* column-major matrix expression over the minor dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return A const iterator over the minor dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::const_iterator1 apply(ExprT const& e)
{
return e.begin1();
}
};
} // Namespace detail
/**
* \brief An iterator to the first element of the given vector expression.
* \tparam ExprT A model of VectorExpression type.
* \param e A vector expression.
* \return An iterator to the first element of the given vector expression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
typename ExprT::iterator begin(vector_expression<ExprT>& e)
{
return detail::begin_impl<typename ExprT::type_category>::apply(e());
}
/**
* \brief A const iterator to the first element of the given vector expression.
* \tparam ExprT A model of VectorExpression type.
* \param e A vector expression.
* \return A const iterator to the first element of the given vector expression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
typename ExprT::const_iterator begin(vector_expression<ExprT> const& e)
{
return detail::begin_impl<typename ExprT::type_category>::apply(e());
}
/**
* \brief An iterator to the first element of the given matrix expression
* according to its orientation.
* \tparam DimTagT A dimension tag type (e.g., tag::major).
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return An iterator to the first element of the given matrix expression
* according to its orientation.
*/
template <typename TagT, typename ExprT>
BOOST_UBLAS_INLINE
typename iterator_type<ExprT,TagT>::type begin(matrix_expression<ExprT>& e)
{
return detail::begin_impl<typename ExprT::type_category, TagT, typename ExprT::orientation_category>::apply(e());
}
/**
* \brief A const iterator to the first element of the given matrix expression
* according to its orientation.
* \tparam TagT A dimension tag type (e.g., tag::major).
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return A const iterator to the first element of the given matrix expression
* according to its orientation.
*/
template <typename TagT, typename ExprT>
BOOST_UBLAS_INLINE
typename const_iterator_type<ExprT,TagT>::type begin(matrix_expression<ExprT> const& e)
{
return detail::begin_impl<typename ExprT::type_category, TagT, typename ExprT::orientation_category>::apply(e());
}
/**
* \brief An iterator to the first element over the dual dimension of the given
* iterator.
* \tparam IteratorT A model of Iterator type.
* \param it An iterator.
* \return An iterator to the first element over the dual dimension of the given
* iterator.
*/
template <typename IteratorT>
BOOST_UBLAS_INLINE
typename IteratorT::dual_iterator_type begin(IteratorT& it)
{
return it.begin();
}
/**
* \brief A const iterator to the first element over the dual dimension of the
* given iterator.
* \tparam IteratorT A model of Iterator type.
* \param it An iterator.
* \return A const iterator to the first element over the dual dimension of the
* given iterator.
*/
template <typename IteratorT>
BOOST_UBLAS_INLINE
typename IteratorT::dual_iterator_type begin(IteratorT const& it)
{
return it.begin();
}
}}} // Namespace boost::numeric::ublas
#endif // BOOST_NUMERIC_UBLAS_OPERATION_BEGIN_HPP

View File

@@ -0,0 +1,41 @@
/**
* -*- c++ -*-
*
* \file c_array.hpp
*
* \brief provides specializations of matrix and vector operations for c arrays and c matrices.
*
* Copyright (c) 2009, Gunter Winkler
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* \author Gunter Winkler (guwi17 at gmx dot de)
*/
#ifndef BOOST_NUMERIC_UBLAS_OPERATION_C_ARRAY_HPP
#define BOOST_NUMERIC_UBLAS_OPERATION_C_ARRAY_HPP
#include <boost/numeric/ublas/traits/c_array.hpp>
namespace boost { namespace numeric { namespace ublas {
namespace detail {
} // namespace boost::numeric::ublas::detail
template <typename T>
BOOST_UBLAS_INLINE
typename ExprT::const_iterator begin(vector_expression<ExprT> const& e)
{
return detail::begin_impl<typename ExprT::type_category>::apply(e());
}
}}} // Namespace boost::numeric::ublas
#endif

View File

@@ -0,0 +1,318 @@
/**
* -*- c++ -*-
*
* \file end.hpp
*
* \brief The \c end operation.
*
* Copyright (c) 2009, Marco Guazzone
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* \author Marco Guazzone, marco.guazzone@gmail.com
*/
#ifndef BOOST_NUMERIC_UBLAS_OPERATION_END_HPP
#define BOOST_NUMERIC_UBLAS_OPERATION_END_HPP
#include <boost/numeric/ublas/expression_types.hpp>
#include <boost/numeric/ublas/fwd.hpp>
#include <boost/numeric/ublas/traits/const_iterator_type.hpp>
#include <boost/numeric/ublas/traits/iterator_type.hpp>
namespace boost { namespace numeric { namespace ublas {
namespace detail {
/**
* \brief Auxiliary class for implementing the \c end operation.
* \tparam CategoryT The expression category type (e.g., vector_tag).
* \tparam TagT The dimension type tag (e.g., tag::major).
* \tparam OrientationT The orientation category type (e.g., row_major_tag).
*/
template <typename CategoryT, typename TagT=void, typename OrientationT=void>
struct end_impl;
/// \brief Specialization of \c end_impl for iterating vector expressions.
template <>
struct end_impl<vector_tag,void,void>
{
/**
* \brief Return an iterator to the last element of the given vector
* expression.
* \tparam ExprT A model of VectorExpression type.
* \param e A vector expression.
* \return An iterator over the given vector expression.
*/
template <typename ExprT>
static typename ExprT::iterator apply(ExprT& e)
{
return e.end();
}
/**
* \brief Return a const iterator to the last element of the given vector
* expression.
* \tparam ExprT A model of VectorExpression type.
* \param e A vector expression.
* \return A const iterator to the first element of the given vector
* expression.
*/
template <typename ExprT>
static typename ExprT::const_iterator apply(ExprT const& e)
{
return e.end();
}
};
/// \brief Specialization of \c end_impl for iterating matrix expressions with a
/// row-major orientation over the major dimension.
template <>
struct end_impl<matrix_tag,tag::major,row_major_tag>
{
/**
* \brief Return an iterator to the last element of the given row-major
* matrix expression over the major dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return An iterator over the major dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::iterator1 apply(ExprT& e)
{
return e.end1();
}
/**
* \brief Return a const iterator to the last element of the given row-major
* matrix expression over the major dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return A const iterator over the major dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::const_iterator1 apply(ExprT const& e)
{
return e.end1();
}
};
/// \brief Specialization of \c end_impl for iterating matrix expressions with a
/// column-major orientation over the major dimension.
template <>
struct end_impl<matrix_tag,tag::major,column_major_tag>
{
/**
* \brief Return an iterator to the last element of the given column-major
* matrix expression over the major dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return An iterator over the major dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::iterator2 apply(ExprT& e)
{
return e.end2();
}
/**
* \brief Return a const iterator to the last element of the given
* column-major matrix expression over the major dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return A const iterator over the major dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::const_iterator2 apply(ExprT const& e)
{
return e.end2();
}
};
/// \brief Specialization of \c end_impl for iterating matrix expressions with a
/// row-major orientation over the minor dimension.
template <>
struct end_impl<matrix_tag,tag::minor,row_major_tag>
{
/**
* \brief Return an iterator to the last element of the given row-major
* matrix expression over the minor dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return An iterator over the minor dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::iterator2 apply(ExprT& e)
{
return e.end2();
}
/**
* \brief Return a const iterator to the last element of the given
* row-minor matrix expression over the major dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return A const iterator over the minor dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::const_iterator2 apply(ExprT const& e)
{
return e.end2();
}
};
/// \brief Specialization of \c end_impl for iterating matrix expressions with a
/// column-major orientation over the minor dimension.
template <>
struct end_impl<matrix_tag,tag::minor,column_major_tag>
{
/**
* \brief Return an iterator to the last element of the given column-major
* matrix expression over the minor dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return An iterator over the minor dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::iterator1 apply(ExprT& e)
{
return e.end1();
}
/**
* \brief Return a const iterator to the last element of the given
* column-minor matrix expression over the major dimension.
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return A const iterator over the minor dimension of the given matrix
* expression.
*/
template <typename ExprT>
static typename ExprT::const_iterator1 apply(ExprT const& e)
{
return e.end1();
}
};
} // Namespace detail
/**
* \brief An iterator to the last element of the given vector expression.
* \tparam ExprT A model of VectorExpression type.
* \param e A vector expression.
* \return An iterator to the last element of the given vector expression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
typename ExprT::iterator end(vector_expression<ExprT>& e)
{
return detail::end_impl<typename ExprT::type_category>::apply(e());
}
/**
* \brief A const iterator to the last element of the given vector expression.
* \tparam ExprT A model of VectorExpression type.
* \param e A vector expression.
* \return A const iterator to the last element of the given vector expression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
typename ExprT::const_iterator end(vector_expression<ExprT> const& e)
{
return detail::end_impl<typename ExprT::type_category>::apply(e());
}
/**
* \brief An iterator to the last element of the given matrix expression
* according to its orientation.
* \tparam DimTagT A dimension tag type (e.g., tag::major).
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return An iterator to the last element of the given matrix expression
* according to its orientation.
*/
template <typename TagT, typename ExprT>
BOOST_UBLAS_INLINE
typename iterator_type<ExprT,TagT>::type end(matrix_expression<ExprT>& e)
{
return detail::end_impl<typename ExprT::type_category, TagT, typename ExprT::orientation_category>::apply(e());
}
/**
* \brief A const iterator to the last element of the given matrix expression
* according to its orientation.
* \tparam TagT A dimension tag type (e.g., tag::major).
* \tparam ExprT A model of MatrixExpression type.
* \param e A matrix expression.
* \return A const iterator to the last element of the given matrix expression
* according to its orientation.
*/
template <typename TagT, typename ExprT>
BOOST_UBLAS_INLINE
typename const_iterator_type<ExprT,TagT>::type end(matrix_expression<ExprT> const& e)
{
return detail::end_impl<typename ExprT::type_category, TagT, typename ExprT::orientation_category>::apply(e());
}
/**
* \brief An iterator to the last element over the dual dimension of the given
* iterator.
* \tparam IteratorT A model of Iterator type.
* \param it An iterator.
* \return An iterator to the last element over the dual dimension of the given
* iterator.
*/
template <typename IteratorT>
BOOST_UBLAS_INLINE
typename IteratorT::dual_iterator_type end(IteratorT& it)
{
return it.end();
}
/**
* \brief A const iterator to the last element over the dual dimension of the
* given iterator.
* \tparam IteratorT A model of Iterator type.
* \param it An iterator.
* \return A const iterator to the last element over the dual dimension of the
* given iterator.
*/
template <typename IteratorT>
BOOST_UBLAS_INLINE
typename IteratorT::dual_iterator_type end(IteratorT const& it)
{
return it.end();
}
}}} // Namespace boost::numeric::ublas
#endif // BOOST_NUMERIC_UBLAS_OPERATION_END_HPP

View File

@@ -0,0 +1,43 @@
/**
* -*- c++ -*-
*
* \file num_columns.hpp
*
* \brief The \c num_columns operation.
*
* Copyright (c) 2009, Marco Guazzone
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* \author Marco Guazzone, marco.guazzone@gmail.com
*/
#ifndef BOOST_NUMERIC_UBLAS_OPERATION_NUM_COLUMNS_HPP
#define BOOST_NUMERIC_UBLAS_OPERATION_NUM_COLUMNS_HPP
#include <boost/numeric/ublas/detail/config.hpp>
namespace boost { namespace numeric { namespace ublas {
/**
* \brief Return the number of columns.
* \tparam MatrixExprT A type which models the matrix expression concept.
* \param m A matrix expression.
* \return The number of columns.
*/
template <typename MatrixExprT>
BOOST_UBLAS_INLINE
typename MatrixExprT::size_type num_columns(MatrixExprT const& m)
{
return m.size2();
}
}}} // Namespace boost::numeric::ublas
#endif // BOOST_NUMERIC_UBLAS_OPERATION_NUM_COLUMNS_HPP

View File

@@ -0,0 +1,42 @@
/**
* -*- c++ -*-
*
* \file num_rows.hpp
*
* \brief The \c num_rows operation.
*
* Copyright (c) 2009, Marco Guazzone
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* \author Marco Guazzone, marco.guazzone@gmail.com
*/
#ifndef BOOST_NUMERIC_UBLAS_OPERATION_NUM_ROWS_HPP
#define BOOST_NUMERIC_UBLAS_OPERATION_NUM_ROWS_HPP
#include <boost/numeric/ublas/detail/config.hpp>
namespace boost { namespace numeric { namespace ublas {
/**
* \brief Return the number of rows.
* \tparam MatrixExprT A type which models the matrix expression concept.
* \param m A matrix expression.
* \return The number of rows.
*/
template <typename MatrixExprT>
BOOST_UBLAS_INLINE
typename MatrixExprT::size_type num_rows(MatrixExprT const& m)
{
return m.size1();
}
}}} // Namespace boost::numeric::ublas
#endif // BOOST_NUMERIC_UBLAS_OPERATION_NUM_ROWS_HPP

View File

@@ -0,0 +1,350 @@
/**
* \file size.hpp
*
* \brief The family of \c size operations.
*
* Copyright (c) 2009-2010, Marco Guazzone
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* \author Marco Guazzone, marco.guazzone@gmail.com
*/
#ifndef BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP
#define BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/if.hpp>
#include <boost/numeric/ublas/detail/config.hpp>
#include <boost/numeric/ublas/expression_types.hpp>
#include <boost/numeric/ublas/fwd.hpp>
#include <boost/numeric/ublas/tags.hpp>
#include <boost/numeric/ublas/traits.hpp>
#include <boost/utility/enable_if.hpp>
#include <cstddef>
namespace boost { namespace numeric { namespace ublas {
namespace detail { namespace /*<unnamed>*/ {
/// Define a \c has_size_type trait class.
BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type)
/**
* \brief Wrapper type-traits used in \c boost::lazy_enabled_if for getting the
* size type (see below).
* \tparam VectorT A vector type.
*/
template <typename VectorT>
struct vector_size_type
{
/// The size type.
typedef typename vector_traits<VectorT>::size_type type;
};
/**
* \brief Wrapper type-traits used in \c boost::lazy_enabled_if for getting the
* size type (see below).
* \tparam MatrixT A matrix type.
*/
template <typename MatrixT>
struct matrix_size_type
{
/// The size type.
typedef typename matrix_traits<MatrixT>::size_type type;
};
/**
* \brief Auxiliary class for computing the size of the given dimension for
* a container of the given category.
* \tparam Dim The dimension number (starting from 1).
* \tparam CategoryT The category type (e.g., vector_tag).
*/
template <std::size_t Dim, typename CategoryT>
struct size_by_dim_impl;
/**
* \brief Auxiliary class for computing the size of the given dimension for
* a container of the given category and with the given orientation.
* \tparam Dim The dimension number (starting from 1).
* \tparam CategoryT The category type (e.g., vector_tag).
* \tparam OrientationT The orientation category type (e.g., row_major_tag).
*/
template <typename TagT, typename CategoryT, typename OrientationT>
struct size_by_tag_impl;
/**
* \brief Specialization of \c size_by_dim_impl for computing the size of a
* vector.
*/
template <>
struct size_by_dim_impl<1, vector_tag>
{
/**
* \brief Compute the size of the given vector.
* \tparam ExprT A vector expression type.
* \pre ExprT must be a model of VectorExpression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
static typename vector_traits<ExprT>::size_type apply(vector_expression<ExprT> const& ve)
{
return ve().size();
}
};
/**
* \brief Specialization of \c size_by_dim_impl for computing the number of
* rows of a matrix
*/
template <>
struct size_by_dim_impl<1, matrix_tag>
{
/**
* \brief Compute the number of rows of the given matrix.
* \tparam ExprT A matrix expression type.
* \pre ExprT must be a model of MatrixExpression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
{
return me().size1();
}
};
/**
* \brief Specialization of \c size_by_dim_impl for computing the number of
* columns of a matrix
*/
template <>
struct size_by_dim_impl<2, matrix_tag>
{
/**
* \brief Compute the number of columns of the given matrix.
* \tparam ExprT A matrix expression type.
* \pre ExprT must be a model of MatrixExpression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
{
return me().size2();
}
};
/**
* \brief Specialization of \c size_by_tag_impl for computing the size of the
* major dimension of a row-major oriented matrix.
*/
template <>
struct size_by_tag_impl<tag::major, matrix_tag, row_major_tag>
{
/**
* \brief Compute the number of rows of the given matrix.
* \tparam ExprT A matrix expression type.
* \pre ExprT must be a model of MatrixExpression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
{
return me().size1();
}
};
/**
* \brief Specialization of \c size_by_tag_impl for computing the size of the
* minor dimension of a row-major oriented matrix.
*/
template <>
struct size_by_tag_impl<tag::minor, matrix_tag, row_major_tag>
{
/**
* \brief Compute the number of columns of the given matrix.
* \tparam ExprT A matrix expression type.
* \pre ExprT must be a model of MatrixExpression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
{
return me().size2();
}
};
/**
* \brief Specialization of \c size_by_tag_impl for computing the size of the
* leading dimension of a row-major oriented matrix.
*/
template <>
struct size_by_tag_impl<tag::leading, matrix_tag, row_major_tag>
{
/**
* \brief Compute the number of columns of the given matrix.
* \tparam ExprT A matrix expression type.
* \pre ExprT must be a model of MatrixExpression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
{
return me().size2();
}
};
/// \brief Specialization of \c size_by_tag_impl for computing the size of the
/// major dimension of a column-major oriented matrix.
template <>
struct size_by_tag_impl<tag::major, matrix_tag, column_major_tag>
{
/**
* \brief Compute the number of columns of the given matrix.
* \tparam ExprT A matrix expression type.
* \pre ExprT must be a model of MatrixExpression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
{
return me().size2();
}
};
/// \brief Specialization of \c size_by_tag_impl for computing the size of the
/// minor dimension of a column-major oriented matrix.
template <>
struct size_by_tag_impl<tag::minor, matrix_tag, column_major_tag>
{
/**
* \brief Compute the number of rows of the given matrix.
* \tparam ExprT A matrix expression type.
* \pre ExprT must be a model of MatrixExpression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
{
return me().size1();
}
};
/// \brief Specialization of \c size_by_tag_impl for computing the size of the
/// leading dimension of a column-major oriented matrix.
template <>
struct size_by_tag_impl<tag::leading, matrix_tag, column_major_tag>
{
/**
* \brief Compute the number of rows of the given matrix.
* \tparam ExprT A matrix expression type.
* \pre ExprT must be a model of MatrixExpression.
*/
template <typename ExprT>
BOOST_UBLAS_INLINE
static typename matrix_traits<ExprT>::size_type apply(matrix_expression<ExprT> const& me)
{
return me().size1();
}
};
/// \brief Specialization of \c size_by_tag_impl for computing the size of the
/// given dimension of a unknown oriented expression.
template <typename TagT, typename CategoryT>
struct size_by_tag_impl<TagT, CategoryT, unknown_orientation_tag>: size_by_tag_impl<TagT, CategoryT, row_major_tag>
{
// Empty
};
}} // Namespace detail::<unnamed>
/**
* \brief Return the number of columns.
* \tparam VectorExprT A type which models the vector expression concept.
* \param ve A vector expression.
* \return The length of the input vector expression.
*/
template <typename VectorExprT>
BOOST_UBLAS_INLINE
typename ::boost::lazy_enable_if_c<
detail::has_size_type<VectorExprT>::value,
detail::vector_size_type<VectorExprT>
>::type size(vector_expression<VectorExprT> const& ve)
{
return ve().size();
}
/**
* \brief Return the size of the given dimension for the given vector
* expression.
* \tparam Dim The dimension number (starting from 1).
* \tparam VectorExprT A vector expression type.
* \param ve A vector expression.
* \return The length of the input vector expression.
*/
template <std::size_t Dim, typename VectorExprT>
BOOST_UBLAS_INLINE
typename vector_traits<VectorExprT>::size_type size(vector_expression<VectorExprT> const& ve)
{
return detail::size_by_dim_impl<Dim, vector_tag>::template apply(ve);
}
/**
* \brief Return the size of the given dimension for the given matrix
* expression.
* \tparam Dim The dimension number (starting from 1).
* \tparam MatrixExprT A matrix expression type.
* \param e A matrix expression.
* \return The size of the input matrix expression associated to the dimension
* \a Dim.
*/
template <std::size_t Dim, typename MatrixExprT>
BOOST_UBLAS_INLINE
typename matrix_traits<MatrixExprT>::size_type size(matrix_expression<MatrixExprT> const& me)
{
return detail::size_by_dim_impl<Dim, matrix_tag>::template apply(me);
}
/**
* \brief Return the size of the given dimension tag for the given matrix
* expression.
* \tparam TagT The dimension tag type (e.g., tag::major).
* \tparam MatrixExprT A matrix expression type.
* \param e A matrix expression.
* \return The size of the input matrix expression associated to the dimension
* tag \a TagT.
*/
template <typename TagT, typename MatrixExprT>
BOOST_UBLAS_INLINE
typename ::boost::lazy_enable_if_c<
detail::has_size_type<MatrixExprT>::value,
detail::matrix_size_type<MatrixExprT>
>::type size(matrix_expression<MatrixExprT> const& me)
{
return detail::size_by_tag_impl<TagT, matrix_tag, typename matrix_traits<MatrixExprT>::orientation_category>::template apply(me);
}
}}} // Namespace boost::numeric::ublas
#endif // BOOST_NUMERIC_UBLAS_OPERATION_SIZE_HPP

View File

@@ -0,0 +1,266 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_OPERATION_BLOCKED_
#define _BOOST_UBLAS_OPERATION_BLOCKED_
#include <boost/numeric/ublas/traits.hpp>
#include <boost/numeric/ublas/detail/vector_assign.hpp> // indexing_vector_assign
#include <boost/numeric/ublas/detail/matrix_assign.hpp> // indexing_matrix_assign
namespace boost { namespace numeric { namespace ublas {
template<class V, typename V::size_type BS, class E1, class E2>
BOOST_UBLAS_INLINE
V
block_prod (const matrix_expression<E1> &e1,
const vector_expression<E2> &e2) {
typedef V vector_type;
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename V::size_type size_type;
typedef typename V::value_type value_type;
const size_type block_size = BS;
V v (e1 ().size1 ());
#if BOOST_UBLAS_TYPE_CHECK
vector<value_type> cv (v.size ());
typedef typename type_traits<value_type>::real_type real_type;
real_type verrorbound (norm_1 (v) + norm_1 (e1) * norm_1 (e2));
indexing_vector_assign<scalar_assign> (cv, prod (e1, e2));
#endif
size_type i_size = e1 ().size1 ();
size_type j_size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size ());
for (size_type i_begin = 0; i_begin < i_size; i_begin += block_size) {
size_type i_end = i_begin + (std::min) (i_size - i_begin, block_size);
// FIX: never ignore Martin Weiser's advice ;-(
#ifdef BOOST_UBLAS_NO_CACHE
vector_range<vector_type> v_range (v, range (i_begin, i_end));
#else
// vector<value_type, bounded_array<value_type, block_size> > v_range (i_end - i_begin);
vector<value_type> v_range (i_end - i_begin);
#endif
v_range.assign (zero_vector<value_type> (i_end - i_begin));
for (size_type j_begin = 0; j_begin < j_size; j_begin += block_size) {
size_type j_end = j_begin + (std::min) (j_size - j_begin, block_size);
#ifdef BOOST_UBLAS_NO_CACHE
const matrix_range<expression1_type> e1_range (e1 (), range (i_begin, i_end), range (j_begin, j_end));
const vector_range<expression2_type> e2_range (e2 (), range (j_begin, j_end));
v_range.plus_assign (prod (e1_range, e2_range));
#else
// const matrix<value_type, row_major, bounded_array<value_type, block_size * block_size> > e1_range (project (e1 (), range (i_begin, i_end), range (j_begin, j_end)));
// const vector<value_type, bounded_array<value_type, block_size> > e2_range (project (e2 (), range (j_begin, j_end)));
const matrix<value_type, row_major> e1_range (project (e1 (), range (i_begin, i_end), range (j_begin, j_end)));
const vector<value_type> e2_range (project (e2 (), range (j_begin, j_end)));
v_range.plus_assign (prod (e1_range, e2_range));
#endif
}
#ifndef BOOST_UBLAS_NO_CACHE
project (v, range (i_begin, i_end)).assign (v_range);
#endif
}
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (norm_1 (v - cv) <= 2 * std::numeric_limits<real_type>::epsilon () * verrorbound, internal_logic ());
#endif
return v;
}
template<class V, typename V::size_type BS, class E1, class E2>
BOOST_UBLAS_INLINE
V
block_prod (const vector_expression<E1> &e1,
const matrix_expression<E2> &e2) {
typedef V vector_type;
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename V::size_type size_type;
typedef typename V::value_type value_type;
const size_type block_size = BS;
V v (e2 ().size2 ());
#if BOOST_UBLAS_TYPE_CHECK
vector<value_type> cv (v.size ());
typedef typename type_traits<value_type>::real_type real_type;
real_type verrorbound (norm_1 (v) + norm_1 (e1) * norm_1 (e2));
indexing_vector_assign<scalar_assign> (cv, prod (e1, e2));
#endif
size_type i_size = BOOST_UBLAS_SAME (e1 ().size (), e2 ().size1 ());
size_type j_size = e2 ().size2 ();
for (size_type j_begin = 0; j_begin < j_size; j_begin += block_size) {
size_type j_end = j_begin + (std::min) (j_size - j_begin, block_size);
// FIX: never ignore Martin Weiser's advice ;-(
#ifdef BOOST_UBLAS_NO_CACHE
vector_range<vector_type> v_range (v, range (j_begin, j_end));
#else
// vector<value_type, bounded_array<value_type, block_size> > v_range (j_end - j_begin);
vector<value_type> v_range (j_end - j_begin);
#endif
v_range.assign (zero_vector<value_type> (j_end - j_begin));
for (size_type i_begin = 0; i_begin < i_size; i_begin += block_size) {
size_type i_end = i_begin + (std::min) (i_size - i_begin, block_size);
#ifdef BOOST_UBLAS_NO_CACHE
const vector_range<expression1_type> e1_range (e1 (), range (i_begin, i_end));
const matrix_range<expression2_type> e2_range (e2 (), range (i_begin, i_end), range (j_begin, j_end));
#else
// const vector<value_type, bounded_array<value_type, block_size> > e1_range (project (e1 (), range (i_begin, i_end)));
// const matrix<value_type, column_major, bounded_array<value_type, block_size * block_size> > e2_range (project (e2 (), range (i_begin, i_end), range (j_begin, j_end)));
const vector<value_type> e1_range (project (e1 (), range (i_begin, i_end)));
const matrix<value_type, column_major> e2_range (project (e2 (), range (i_begin, i_end), range (j_begin, j_end)));
#endif
v_range.plus_assign (prod (e1_range, e2_range));
}
#ifndef BOOST_UBLAS_NO_CACHE
project (v, range (j_begin, j_end)).assign (v_range);
#endif
}
#if BOOST_UBLAS_TYPE_CHECK
BOOST_UBLAS_CHECK (norm_1 (v - cv) <= 2 * std::numeric_limits<real_type>::epsilon () * verrorbound, internal_logic ());
#endif
return v;
}
template<class M, typename M::size_type BS, class E1, class E2>
BOOST_UBLAS_INLINE
M
block_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
row_major_tag) {
typedef M matrix_type;
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
const size_type block_size = BS;
M m (e1 ().size1 (), e2 ().size2 ());
#if BOOST_UBLAS_TYPE_CHECK
matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
typedef typename type_traits<value_type>::real_type real_type;
real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
indexing_matrix_assign<scalar_assign> (cm, prod (e1, e2), row_major_tag ());
disable_type_check<bool>::value = true;
#endif
size_type i_size = e1 ().size1 ();
size_type j_size = e2 ().size2 ();
size_type k_size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ());
for (size_type i_begin = 0; i_begin < i_size; i_begin += block_size) {
size_type i_end = i_begin + (std::min) (i_size - i_begin, block_size);
for (size_type j_begin = 0; j_begin < j_size; j_begin += block_size) {
size_type j_end = j_begin + (std::min) (j_size - j_begin, block_size);
// FIX: never ignore Martin Weiser's advice ;-(
#ifdef BOOST_UBLAS_NO_CACHE
matrix_range<matrix_type> m_range (m, range (i_begin, i_end), range (j_begin, j_end));
#else
// matrix<value_type, row_major, bounded_array<value_type, block_size * block_size> > m_range (i_end - i_begin, j_end - j_begin);
matrix<value_type, row_major> m_range (i_end - i_begin, j_end - j_begin);
#endif
m_range.assign (zero_matrix<value_type> (i_end - i_begin, j_end - j_begin));
for (size_type k_begin = 0; k_begin < k_size; k_begin += block_size) {
size_type k_end = k_begin + (std::min) (k_size - k_begin, block_size);
#ifdef BOOST_UBLAS_NO_CACHE
const matrix_range<expression1_type> e1_range (e1 (), range (i_begin, i_end), range (k_begin, k_end));
const matrix_range<expression2_type> e2_range (e2 (), range (k_begin, k_end), range (j_begin, j_end));
#else
// const matrix<value_type, row_major, bounded_array<value_type, block_size * block_size> > e1_range (project (e1 (), range (i_begin, i_end), range (k_begin, k_end)));
// const matrix<value_type, column_major, bounded_array<value_type, block_size * block_size> > e2_range (project (e2 (), range (k_begin, k_end), range (j_begin, j_end)));
const matrix<value_type, row_major> e1_range (project (e1 (), range (i_begin, i_end), range (k_begin, k_end)));
const matrix<value_type, column_major> e2_range (project (e2 (), range (k_begin, k_end), range (j_begin, j_end)));
#endif
m_range.plus_assign (prod (e1_range, e2_range));
}
#ifndef BOOST_UBLAS_NO_CACHE
project (m, range (i_begin, i_end), range (j_begin, j_end)).assign (m_range);
#endif
}
}
#if BOOST_UBLAS_TYPE_CHECK
disable_type_check<bool>::value = false;
BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
#endif
return m;
}
template<class M, typename M::size_type BS, class E1, class E2>
BOOST_UBLAS_INLINE
M
block_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
column_major_tag) {
typedef M matrix_type;
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
const size_type block_size = BS;
M m (e1 ().size1 (), e2 ().size2 ());
#if BOOST_UBLAS_TYPE_CHECK
matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
typedef typename type_traits<value_type>::real_type real_type;
real_type merrorbound (norm_1 (m) + norm_1 (e1) * norm_1 (e2));
indexing_matrix_assign<scalar_assign> (cm, prod (e1, e2), column_major_tag ());
disable_type_check<bool>::value = true;
#endif
size_type i_size = e1 ().size1 ();
size_type j_size = e2 ().size2 ();
size_type k_size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ());
for (size_type j_begin = 0; j_begin < j_size; j_begin += block_size) {
size_type j_end = j_begin + (std::min) (j_size - j_begin, block_size);
for (size_type i_begin = 0; i_begin < i_size; i_begin += block_size) {
size_type i_end = i_begin + (std::min) (i_size - i_begin, block_size);
// FIX: never ignore Martin Weiser's advice ;-(
#ifdef BOOST_UBLAS_NO_CACHE
matrix_range<matrix_type> m_range (m, range (i_begin, i_end), range (j_begin, j_end));
#else
// matrix<value_type, column_major, bounded_array<value_type, block_size * block_size> > m_range (i_end - i_begin, j_end - j_begin);
matrix<value_type, column_major> m_range (i_end - i_begin, j_end - j_begin);
#endif
m_range.assign (zero_matrix<value_type> (i_end - i_begin, j_end - j_begin));
for (size_type k_begin = 0; k_begin < k_size; k_begin += block_size) {
size_type k_end = k_begin + (std::min) (k_size - k_begin, block_size);
#ifdef BOOST_UBLAS_NO_CACHE
const matrix_range<expression1_type> e1_range (e1 (), range (i_begin, i_end), range (k_begin, k_end));
const matrix_range<expression2_type> e2_range (e2 (), range (k_begin, k_end), range (j_begin, j_end));
#else
// const matrix<value_type, row_major, bounded_array<value_type, block_size * block_size> > e1_range (project (e1 (), range (i_begin, i_end), range (k_begin, k_end)));
// const matrix<value_type, column_major, bounded_array<value_type, block_size * block_size> > e2_range (project (e2 (), range (k_begin, k_end), range (j_begin, j_end)));
const matrix<value_type, row_major> e1_range (project (e1 (), range (i_begin, i_end), range (k_begin, k_end)));
const matrix<value_type, column_major> e2_range (project (e2 (), range (k_begin, k_end), range (j_begin, j_end)));
#endif
m_range.plus_assign (prod (e1_range, e2_range));
}
#ifndef BOOST_UBLAS_NO_CACHE
project (m, range (i_begin, i_end), range (j_begin, j_end)).assign (m_range);
#endif
}
}
#if BOOST_UBLAS_TYPE_CHECK
disable_type_check<bool>::value = false;
BOOST_UBLAS_CHECK (norm_1 (m - cm) <= 2 * std::numeric_limits<real_type>::epsilon () * merrorbound, internal_logic ());
#endif
return m;
}
// Dispatcher
template<class M, typename M::size_type BS, class E1, class E2>
BOOST_UBLAS_INLINE
M
block_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2) {
typedef typename M::orientation_category orientation_category;
return block_prod<M, BS> (e1, e2, orientation_category ());
}
}}}
#endif

View File

@@ -0,0 +1,198 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_OPERATION_SPARSE_
#define _BOOST_UBLAS_OPERATION_SPARSE_
#include <boost/numeric/ublas/traits.hpp>
// These scaled additions were borrowed from MTL unashamedly.
// But Alexei Novakov had a lot of ideas to improve these. Thanks.
namespace boost { namespace numeric { namespace ublas {
template<class M, class E1, class E2, class TRI>
BOOST_UBLAS_INLINE
M &
sparse_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m, TRI,
row_major_tag) {
typedef M matrix_type;
typedef TRI triangular_restriction;
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
// ISSUE why is there a dense vector here?
vector<value_type> temporary (e2 ().size2 ());
temporary.clear ();
typename expression1_type::const_iterator1 it1 (e1 ().begin1 ());
typename expression1_type::const_iterator1 it1_end (e1 ().end1 ());
while (it1 != it1_end) {
size_type jb (temporary.size ());
size_type je (0);
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
typename expression1_type::const_iterator2 it2 (it1.begin ());
typename expression1_type::const_iterator2 it2_end (it1.end ());
#else
typename expression1_type::const_iterator2 it2 (boost::numeric::ublas::begin (it1, iterator1_tag ()));
typename expression1_type::const_iterator2 it2_end (boost::numeric::ublas::end (it1, iterator1_tag ()));
#endif
while (it2 != it2_end) {
// temporary.plus_assign (*it2 * row (e2 (), it2.index2 ()));
matrix_row<expression2_type> mr (e2 (), it2.index2 ());
typename matrix_row<expression2_type>::const_iterator itr (mr.begin ());
typename matrix_row<expression2_type>::const_iterator itr_end (mr.end ());
while (itr != itr_end) {
size_type j (itr.index ());
temporary (j) += *it2 * *itr;
jb = (std::min) (jb, j);
je = (std::max) (je, j);
++ itr;
}
++ it2;
}
for (size_type j = jb; j < je + 1; ++ j) {
if (temporary (j) != value_type/*zero*/()) {
// FIXME we'll need to extend the container interface!
// m.push_back (it1.index1 (), j, temporary (j));
// FIXME What to do with adaptors?
// m.insert (it1.index1 (), j, temporary (j));
if (triangular_restriction::other (it1.index1 (), j))
m (it1.index1 (), j) = temporary (j);
temporary (j) = value_type/*zero*/();
}
}
++ it1;
}
return m;
}
template<class M, class E1, class E2, class TRI>
BOOST_UBLAS_INLINE
M &
sparse_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m, TRI,
column_major_tag) {
typedef M matrix_type;
typedef TRI triangular_restriction;
typedef const E1 expression1_type;
typedef const E2 expression2_type;
typedef typename M::size_type size_type;
typedef typename M::value_type value_type;
// ISSUE why is there a dense vector here?
vector<value_type> temporary (e1 ().size1 ());
temporary.clear ();
typename expression2_type::const_iterator2 it2 (e2 ().begin2 ());
typename expression2_type::const_iterator2 it2_end (e2 ().end2 ());
while (it2 != it2_end) {
size_type ib (temporary.size ());
size_type ie (0);
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
typename expression2_type::const_iterator1 it1 (it2.begin ());
typename expression2_type::const_iterator1 it1_end (it2.end ());
#else
typename expression2_type::const_iterator1 it1 (boost::numeric::ublas::begin (it2, iterator2_tag ()));
typename expression2_type::const_iterator1 it1_end (boost::numeric::ublas::end (it2, iterator2_tag ()));
#endif
while (it1 != it1_end) {
// column (m, it2.index2 ()).plus_assign (*it1 * column (e1 (), it1.index1 ()));
matrix_column<expression1_type> mc (e1 (), it1.index1 ());
typename matrix_column<expression1_type>::const_iterator itc (mc.begin ());
typename matrix_column<expression1_type>::const_iterator itc_end (mc.end ());
while (itc != itc_end) {
size_type i (itc.index ());
temporary (i) += *it1 * *itc;
ib = (std::min) (ib, i);
ie = (std::max) (ie, i);
++ itc;
}
++ it1;
}
for (size_type i = ib; i < ie + 1; ++ i) {
if (temporary (i) != value_type/*zero*/()) {
// FIXME we'll need to extend the container interface!
// m.push_back (i, it2.index2 (), temporary (i));
// FIXME What to do with adaptors?
// m.insert (i, it2.index2 (), temporary (i));
if (triangular_restriction::other (i, it2.index2 ()))
m (i, it2.index2 ()) = temporary (i);
temporary (i) = value_type/*zero*/();
}
}
++ it2;
}
return m;
}
// Dispatcher
template<class M, class E1, class E2, class TRI>
BOOST_UBLAS_INLINE
M &
sparse_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m, TRI, bool init = true) {
typedef typename M::value_type value_type;
typedef TRI triangular_restriction;
typedef typename M::orientation_category orientation_category;
if (init)
m.assign (zero_matrix<value_type> (e1 ().size1 (), e2 ().size2 ()));
return sparse_prod (e1, e2, m, triangular_restriction (), orientation_category ());
}
template<class M, class E1, class E2, class TRI>
BOOST_UBLAS_INLINE
M
sparse_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
TRI) {
typedef M matrix_type;
typedef TRI triangular_restriction;
matrix_type m (e1 ().size1 (), e2 ().size2 ());
// FIXME needed for c_matrix?!
// return sparse_prod (e1, e2, m, triangular_restriction (), false);
return sparse_prod (e1, e2, m, triangular_restriction (), true);
}
template<class M, class E1, class E2>
BOOST_UBLAS_INLINE
M &
sparse_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2,
M &m, bool init = true) {
typedef typename M::value_type value_type;
typedef typename M::orientation_category orientation_category;
if (init)
m.assign (zero_matrix<value_type> (e1 ().size1 (), e2 ().size2 ()));
return sparse_prod (e1, e2, m, full (), orientation_category ());
}
template<class M, class E1, class E2>
BOOST_UBLAS_INLINE
M
sparse_prod (const matrix_expression<E1> &e1,
const matrix_expression<E2> &e2) {
typedef M matrix_type;
matrix_type m (e1 ().size1 (), e2 ().size2 ());
// FIXME needed for c_matrix?!
// return sparse_prod (e1, e2, m, full (), false);
return sparse_prod (e1, e2, m, full (), true);
}
}}}
#endif

View File

@@ -0,0 +1,26 @@
/**
* -*- c++ -*-
*
* \file operations.hpp
*
* \brief This header includes several headers from the operation directory.
*
* Copyright (c) 2009, Gunter Winkler
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* \author Gunter Winkler (guwi17 at gmx dot de)
*/
#ifndef BOOST_NUMERIC_UBLAS_OPERATIONS_HPP
#define BOOST_NUMERIC_UBLAS_OPERATIONS_HPP
#include <boost/numeric/ublas/operation/begin.hpp>
#include <boost/numeric/ublas/operation/end.hpp>
#include <boost/numeric/ublas/operation/num_columns.hpp>
#include <boost/numeric/ublas/operation/num_rows.hpp>
#include <boost/numeric/ublas/operation/size.hpp>
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,562 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_STORAGE_SPARSE_
#define _BOOST_UBLAS_STORAGE_SPARSE_
#include <map>
#include <boost/serialization/collection_size_type.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/numeric/ublas/storage.hpp>
namespace boost { namespace numeric { namespace ublas {
namespace detail {
template<class I, class T, class C>
BOOST_UBLAS_INLINE
I lower_bound (const I &begin, const I &end, const T &t, C compare) {
// t <= *begin <=> ! (*begin < t)
if (begin == end || ! compare (*begin, t))
return begin;
if (compare (*(end - 1), t))
return end;
return std::lower_bound (begin, end, t, compare);
}
template<class I, class T, class C>
BOOST_UBLAS_INLINE
I upper_bound (const I &begin, const I &end, const T &t, C compare) {
if (begin == end || compare (t, *begin))
return begin;
// (*end - 1) <= t <=> ! (t < *end)
if (! compare (t, *(end - 1)))
return end;
return std::upper_bound (begin, end, t, compare);
}
template<class P>
struct less_pair {
BOOST_UBLAS_INLINE
bool operator () (const P &p1, const P &p2) {
return p1.first < p2.first;
}
};
template<class T>
struct less_triple {
BOOST_UBLAS_INLINE
bool operator () (const T &t1, const T &t2) {
return t1.first.first < t2.first.first ||
(t1.first.first == t2.first.first && t1.first.second < t2.first.second);
}
};
}
#ifdef BOOST_UBLAS_STRICT_MAP_ARRAY
template<class A>
class sparse_storage_element:
public container_reference<A> {
public:
typedef A array_type;
typedef typename A::key_type index_type;
typedef typename A::mapped_type data_value_type;
// typedef const data_value_type &data_const_reference;
typedef typename type_traits<data_value_type>::const_reference data_const_reference;
typedef data_value_type &data_reference;
typedef typename A::value_type value_type;
typedef value_type *pointer;
// Construction and destruction
BOOST_UBLAS_INLINE
sparse_storage_element (array_type &a, pointer it):
container_reference<array_type> (a), it_ (it), i_ (it->first), d_ (it->second), dirty_ (false) {}
BOOST_UBLAS_INLINE
sparse_storage_element (array_type &a, index_type i):
container_reference<array_type> (a), it_ (), i_ (i), d_ (), dirty_ (false) {
pointer it = (*this) ().find (i_);
if (it == (*this) ().end ())
it = (*this) ().insert ((*this) ().end (), value_type (i_, d_));
d_ = it->second;
}
BOOST_UBLAS_INLINE
~sparse_storage_element () {
if (dirty_) {
if (! it_)
it_ = (*this) ().find (i_);
BOOST_UBLAS_CHECK (it_ != (*this) ().end (), internal_logic ());
it_->second = d_;
}
}
// Element access - only if data_const_reference is defined
BOOST_UBLAS_INLINE
typename data_value_type::data_const_reference
operator [] (index_type i) const {
return d_ [i];
}
// Assignment
BOOST_UBLAS_INLINE
sparse_storage_element &operator = (const sparse_storage_element &p) {
// Overide the implict copy assignment
d_ = p.d_;
dirty_ = true;
return *this;
}
template<class D>
BOOST_UBLAS_INLINE
sparse_storage_element &operator = (const D &d) {
d_ = d;
dirty_ = true;
return *this;
}
template<class D>
BOOST_UBLAS_INLINE
sparse_storage_element &operator += (const D &d) {
d_ += d;
dirty_ = true;
return *this;
}
template<class D>
BOOST_UBLAS_INLINE
sparse_storage_element &operator -= (const D &d) {
d_ -= d;
dirty_ = true;
return *this;
}
template<class D>
BOOST_UBLAS_INLINE
sparse_storage_element &operator *= (const D &d) {
d_ *= d;
dirty_ = true;
return *this;
}
template<class D>
BOOST_UBLAS_INLINE
sparse_storage_element &operator /= (const D &d) {
d_ /= d;
dirty_ = true;
return *this;
}
// Comparison
template<class D>
BOOST_UBLAS_INLINE
bool operator == (const D &d) const {
return d_ == d;
}
template<class D>
BOOST_UBLAS_INLINE
bool operator != (const D &d) const {
return d_ != d;
}
// Conversion
BOOST_UBLAS_INLINE
operator data_const_reference () const {
return d_;
}
// Swapping
BOOST_UBLAS_INLINE
void swap (sparse_storage_element p) {
if (this != &p) {
dirty_ = true;
p.dirty_ = true;
std::swap (d_, p.d_);
}
}
BOOST_UBLAS_INLINE
friend void swap (sparse_storage_element p1, sparse_storage_element p2) {
p1.swap (p2);
}
private:
pointer it_;
index_type i_;
data_value_type d_;
bool dirty_;
};
#endif
// Default map type is simply forwarded to std::map
// FIXME should use ALLOC for map but std::allocator of std::pair<const I, T> and std::pair<I,T> fail to compile
template<class I, class T, class ALLOC>
class map_std : public std::map<I, T /*, ALLOC */> {
public:
// Serialization
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */){
ar & serialization::make_nvp("base", boost::serialization::base_object< std::map<I, T /*, ALLOC */> >(*this));
}
};
// Map array
// Implementation requires pair<I, T> allocator definition (without const)
template<class I, class T, class ALLOC>
class map_array {
public:
typedef ALLOC allocator_type;
typedef typename ALLOC::size_type size_type;
typedef typename ALLOC::difference_type difference_type;
typedef std::pair<I,T> value_type;
typedef I key_type;
typedef T mapped_type;
typedef const value_type &const_reference;
typedef value_type &reference;
typedef const value_type *const_pointer;
typedef value_type *pointer;
// Iterators simply are pointers.
typedef const_pointer const_iterator;
typedef pointer iterator;
typedef const T &data_const_reference;
#ifndef BOOST_UBLAS_STRICT_MAP_ARRAY
typedef T &data_reference;
#else
typedef sparse_storage_element<map_array> data_reference;
#endif
// Construction and destruction
BOOST_UBLAS_INLINE
map_array (const ALLOC &a = ALLOC()):
alloc_(a), capacity_ (0), size_ (0) {
data_ = 0;
}
BOOST_UBLAS_INLINE
map_array (const map_array &c):
alloc_ (c.alloc_), capacity_ (c.size_), size_ (c.size_) {
if (capacity_) {
data_ = alloc_.allocate (capacity_);
std::uninitialized_copy (data_, data_ + capacity_, c.data_);
// capacity != size_ requires uninitialized_fill (size_ to capacity_)
}
else
data_ = 0;
}
BOOST_UBLAS_INLINE
~map_array () {
if (capacity_) {
std::for_each (data_, data_ + capacity_, static_destroy);
alloc_.deallocate (data_, capacity_);
}
}
private:
// Resizing - implicitly exposses uninitialized (but default constructed) mapped_type
BOOST_UBLAS_INLINE
void resize (size_type size) {
BOOST_UBLAS_CHECK (size_ <= capacity_, internal_logic ());
if (size > capacity_) {
const size_type capacity = size << 1;
BOOST_UBLAS_CHECK (capacity, internal_logic ());
pointer data = alloc_.allocate (capacity);
std::uninitialized_copy (data_, data_ + (std::min) (size, size_), data);
std::uninitialized_fill (data + (std::min) (size, size_), data + capacity, value_type ());
if (capacity_) {
std::for_each (data_, data_ + capacity_, static_destroy);
alloc_.deallocate (data_, capacity_);
}
capacity_ = capacity;
data_ = data;
}
size_ = size;
BOOST_UBLAS_CHECK (size_ <= capacity_, internal_logic ());
}
public:
// Reserving
BOOST_UBLAS_INLINE
void reserve (size_type capacity) {
BOOST_UBLAS_CHECK (size_ <= capacity_, internal_logic ());
// Reduce capacity_ if size_ allows
BOOST_UBLAS_CHECK (capacity >= size_, bad_size ());
pointer data;
if (capacity) {
data = alloc_.allocate (capacity);
std::uninitialized_copy (data_, data_ + size_, data);
std::uninitialized_fill (data + size_, data + capacity, value_type ());
}
else
data = 0;
if (capacity_) {
std::for_each (data_, data_ + capacity_, static_destroy);
alloc_.deallocate (data_, capacity_);
}
capacity_ = capacity;
data_ = data;
BOOST_UBLAS_CHECK (size_ <= capacity_, internal_logic ());
}
// Random Access Container
BOOST_UBLAS_INLINE
size_type size () const {
return size_;
}
BOOST_UBLAS_INLINE
size_type capacity () const {
return capacity_;
}
BOOST_UBLAS_INLINE
size_type max_size () const {
return 0; //TODO
}
BOOST_UBLAS_INLINE
bool empty () const {
return size_ == 0;
}
// Element access
BOOST_UBLAS_INLINE
data_reference operator [] (key_type i) {
#ifndef BOOST_UBLAS_STRICT_MAP_ARRAY
pointer it = find (i);
if (it == end ())
it = insert (end (), value_type (i, mapped_type (0)));
BOOST_UBLAS_CHECK (it != end (), internal_logic ());
return it->second;
#else
return data_reference (*this, i);
#endif
}
// Assignment
BOOST_UBLAS_INLINE
map_array &operator = (const map_array &a) {
if (this != &a) {
resize (a.size_);
std::copy (a.data_, a.data_ + a.size_, data_);
}
return *this;
}
BOOST_UBLAS_INLINE
map_array &assign_temporary (map_array &a) {
swap (a);
return *this;
}
// Swapping
BOOST_UBLAS_INLINE
void swap (map_array &a) {
if (this != &a) {
std::swap (capacity_, a.capacity_);
std::swap (data_, a.data_);
std::swap (size_, a.size_);
}
}
BOOST_UBLAS_INLINE
friend void swap (map_array &a1, map_array &a2) {
a1.swap (a2);
}
// Element insertion and deletion
// From Back Insertion Sequence concept
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
iterator push_back (iterator it, const value_type &p) {
if (size () == 0 || (it = end () - 1)->first < p.first) {
resize (size () + 1);
*(it = end () - 1) = p;
return it;
}
external_logic ().raise ();
return it;
}
// Form Unique Associative Container concept
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
std::pair<iterator,bool> insert (const value_type &p) {
iterator it = detail::lower_bound (begin (), end (), p, detail::less_pair<value_type> ());
if (it != end () && it->first == p.first)
return std::make_pair (it, false);
difference_type n = it - begin ();
resize (size () + 1);
it = begin () + n; // allow for invalidation
std::copy_backward (it, end () - 1, end ());
*it = p;
return std::make_pair (it, true);
}
// Form Sorted Associative Container concept
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
iterator insert (iterator hint, const value_type &p) {
return insert (p).first;
}
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void erase (iterator it) {
BOOST_UBLAS_CHECK (begin () <= it && it < end (), bad_index ());
std::copy (it + 1, end (), it);
resize (size () - 1);
}
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void erase (iterator it1, iterator it2) {
if (it1 == it2) return /* nothing to erase */;
BOOST_UBLAS_CHECK (begin () <= it1 && it1 < it2 && it2 <= end (), bad_index ());
std::copy (it2, end (), it1);
resize (size () - (it2 - it1));
}
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
void clear () {
resize (0);
}
// Element lookup
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
const_iterator find (key_type i) const {
const_iterator it (detail::lower_bound (begin (), end (), value_type (i, mapped_type (0)), detail::less_pair<value_type> ()));
if (it == end () || it->first != i)
it = end ();
return it;
}
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
iterator find (key_type i) {
iterator it (detail::lower_bound (begin (), end (), value_type (i, mapped_type (0)), detail::less_pair<value_type> ()));
if (it == end () || it->first != i)
it = end ();
return it;
}
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
const_iterator lower_bound (key_type i) const {
return detail::lower_bound (begin (), end (), value_type (i, mapped_type (0)), detail::less_pair<value_type> ());
}
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
iterator lower_bound (key_type i) {
return detail::lower_bound (begin (), end (), value_type (i, mapped_type (0)), detail::less_pair<value_type> ());
}
BOOST_UBLAS_INLINE
const_iterator begin () const {
return data_;
}
BOOST_UBLAS_INLINE
const_iterator end () const {
return data_ + size_;
}
BOOST_UBLAS_INLINE
iterator begin () {
return data_;
}
BOOST_UBLAS_INLINE
iterator end () {
return data_ + size_;
}
// Reverse iterators
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
BOOST_UBLAS_INLINE
const_reverse_iterator rbegin () const {
return const_reverse_iterator (end ());
}
BOOST_UBLAS_INLINE
const_reverse_iterator rend () const {
return const_reverse_iterator (begin ());
}
BOOST_UBLAS_INLINE
reverse_iterator rbegin () {
return reverse_iterator (end ());
}
BOOST_UBLAS_INLINE
reverse_iterator rend () {
return reverse_iterator (begin ());
}
// Allocator
allocator_type get_allocator () {
return alloc_;
}
// Serialization
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */){
serialization::collection_size_type s (size_);
ar & serialization::make_nvp("size",s);
if (Archive::is_loading::value) {
resize(s);
}
ar & serialization::make_array(data_, s);
}
private:
// Provide destroy as a non member function
BOOST_UBLAS_INLINE
static void static_destroy (reference p) {
(&p) -> ~value_type ();
}
ALLOC alloc_;
size_type capacity_;
pointer data_;
size_type size_;
};
namespace detail {
template<class A, class T>
struct map_traits {
typedef typename A::mapped_type &reference;
};
template<class I, class T, class ALLOC>
struct map_traits<map_array<I, T, ALLOC>, T > {
typedef typename map_array<I, T, ALLOC>::data_reference reference;
};
// reserve helpers for map_array and generic maps
// ISSUE should be in map_traits but want to use on all compilers
template<class M>
BOOST_UBLAS_INLINE
void map_reserve (M &/* m */, typename M::size_type /* capacity */) {
}
template<class I, class T, class ALLOC>
BOOST_UBLAS_INLINE
void map_reserve (map_array<I, T, ALLOC> &m, typename map_array<I, T, ALLOC>::size_type capacity) {
m.reserve (capacity);
}
template<class M>
struct map_capacity_traits {
typedef typename M::size_type type ;
type operator() ( M const& m ) const {
return m.size ();
}
} ;
template<class I, class T, class ALLOC>
struct map_capacity_traits< map_array<I, T, ALLOC> > {
typedef typename map_array<I, T, ALLOC>::size_type type ;
type operator() ( map_array<I, T, ALLOC> const& m ) const {
return m.capacity ();
}
} ;
template<class M>
BOOST_UBLAS_INLINE
typename map_capacity_traits<M>::type map_capacity (M const& m) {
return map_capacity_traits<M>() ( m );
}
}
}}}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
/**
* -*- c++ -*-
*
* \file tags.hpp
*
* \brief Tags.
*
* Copyright (c) 2009, Marco Guazzone
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* \author Marco Guazzone, marco.guazzone@gmail.com
*/
#ifndef BOOST_NUMERIC_UBLAS_TAG_HPP
#define BOOST_NUMERIC_UBLAS_TAG_HPP
namespace boost { namespace numeric { namespace ublas { namespace tag {
/// \brief Tag for the major dimension.
struct major {};
/// \brief Tag for the minor dimension.
struct minor {};
/// \brief Tag for the leading dimension.
struct leading {};
}}}} // Namespace boost::numeric::ublas::tag
#endif // BOOST_NUMERIC_UBLAS_TAG_HPP

View File

@@ -0,0 +1,744 @@
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// GeNeSys mbH & Co. KG in producing this work.
//
#ifndef _BOOST_UBLAS_TRAITS_
#define _BOOST_UBLAS_TRAITS_
#include <iterator>
#include <complex>
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/numeric/ublas/detail/config.hpp>
#include <boost/numeric/ublas/detail/iterator.hpp>
#include <boost/numeric/ublas/detail/returntype_deduction.hpp>
#include <boost/type_traits.hpp>
#include <complex>
#include <boost/typeof/typeof.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_float.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/mpl/and.hpp>
// anonymous namespace to avoid ADL issues
namespace {
template<class T> T boost_numeric_ublas_sqrt (const T& t) {
using namespace std;
// we'll find either std::sqrt or else another version via ADL:
return sqrt (t);
}
template<class T> T boost_numeric_ublas_abs (const T& t) {
using namespace std;
// we'll find either std::abs or else another version via ADL:
return abs (t);
}
}
namespace boost { namespace numeric { namespace ublas {
// Use Joel de Guzman's return type deduction
// uBLAS assumes a common return type for all binary arithmetic operators
template<class X, class Y>
struct promote_traits {
typedef type_deduction_detail::base_result_of<X, Y> base_type;
static typename base_type::x_type x;
static typename base_type::y_type y;
static const std::size_t size = sizeof (
type_deduction_detail::test<
typename base_type::x_type
, typename base_type::y_type
>(x + y) // Use x+y to stand of all the arithmetic actions
);
static const std::size_t index = (size / sizeof (char)) - 1;
typedef typename mpl::at_c<
typename base_type::types, index>::type id;
typedef typename id::type promote_type;
};
template<typename R, typename I>
typename boost::enable_if<
mpl::and_<
boost::is_float<R>,
boost::is_integral<I>
>,
std::complex<R> >::type inline operator+ (I in1, std::complex<R> const& in2 ) {
return R (in1) + in2;
}
template<typename R, typename I>
typename boost::enable_if<
mpl::and_<
boost::is_float<R>,
boost::is_integral<I>
>,
std::complex<R> >::type inline operator+ (std::complex<R> const& in1, I in2) {
return in1 + R (in2);
}
template<typename R, typename I>
typename boost::enable_if<
mpl::and_<
boost::is_float<R>,
boost::is_integral<I>
>,
std::complex<R> >::type inline operator- (I in1, std::complex<R> const& in2) {
return R (in1) - in2;
}
template<typename R, typename I>
typename boost::enable_if<
mpl::and_<
boost::is_float<R>,
boost::is_integral<I>
>,
std::complex<R> >::type inline operator- (std::complex<R> const& in1, I in2) {
return in1 - R (in2);
}
template<typename R, typename I>
typename boost::enable_if<
mpl::and_<
boost::is_float<R>,
boost::is_integral<I>
>,
std::complex<R> >::type inline operator* (I in1, std::complex<R> const& in2) {
return R (in1) * in2;
}
template<typename R, typename I>
typename boost::enable_if<
mpl::and_<
boost::is_float<R>,
boost::is_integral<I>
>,
std::complex<R> >::type inline operator* (std::complex<R> const& in1, I in2) {
return in1 * R(in2);
}
template<typename R, typename I>
typename boost::enable_if<
mpl::and_<
boost::is_float<R>,
boost::is_integral<I>
>,
std::complex<R> >::type inline operator/ (I in1, std::complex<R> const& in2) {
return R(in1) / in2;
}
template<typename R, typename I>
typename boost::enable_if<
mpl::and_<
boost::is_float<R>,
boost::is_integral<I>
>,
std::complex<R> >::type inline operator/ (std::complex<R> const& in1, I in2) {
return in1 / R (in2);
}
// Type traits - generic numeric properties and functions
template<class T>
struct type_traits;
// Define properties for a generic scalar type
template<class T>
struct scalar_traits {
typedef scalar_traits<T> self_type;
typedef T value_type;
typedef const T &const_reference;
typedef T &reference;
typedef T real_type;
typedef real_type precision_type; // we do not know what type has more precision then the real_type
static const unsigned plus_complexity = 1;
static const unsigned multiplies_complexity = 1;
static
BOOST_UBLAS_INLINE
real_type real (const_reference t) {
return t;
}
static
BOOST_UBLAS_INLINE
real_type imag (const_reference /*t*/) {
return 0;
}
static
BOOST_UBLAS_INLINE
value_type conj (const_reference t) {
return t;
}
static
BOOST_UBLAS_INLINE
real_type type_abs (const_reference t) {
return boost_numeric_ublas_abs (t);
}
static
BOOST_UBLAS_INLINE
value_type type_sqrt (const_reference t) {
// force a type conversion back to value_type for intgral types
return value_type (boost_numeric_ublas_sqrt (t));
}
static
BOOST_UBLAS_INLINE
real_type norm_1 (const_reference t) {
return self_type::type_abs (t);
}
static
BOOST_UBLAS_INLINE
real_type norm_2 (const_reference t) {
return self_type::type_abs (t);
}
static
BOOST_UBLAS_INLINE
real_type norm_inf (const_reference t) {
return self_type::type_abs (t);
}
static
BOOST_UBLAS_INLINE
bool equals (const_reference t1, const_reference t2) {
return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
(std::max) ((std::max) (self_type::norm_inf (t1),
self_type::norm_inf (t2)),
BOOST_UBLAS_TYPE_CHECK_MIN);
}
};
// Define default type traits, assume T is a scalar type
template<class T>
struct type_traits : scalar_traits <T> {
typedef type_traits<T> self_type;
typedef T value_type;
typedef const T &const_reference;
typedef T &reference;
typedef T real_type;
typedef real_type precision_type;
static const unsigned multiplies_complexity = 1;
};
// Define real type traits
template<>
struct type_traits<float> : scalar_traits<float> {
typedef type_traits<float> self_type;
typedef float value_type;
typedef const value_type &const_reference;
typedef value_type &reference;
typedef value_type real_type;
typedef double precision_type;
};
template<>
struct type_traits<double> : scalar_traits<double> {
typedef type_traits<double> self_type;
typedef double value_type;
typedef const value_type &const_reference;
typedef value_type &reference;
typedef value_type real_type;
typedef long double precision_type;
};
template<>
struct type_traits<long double> : scalar_traits<long double> {
typedef type_traits<long double> self_type;
typedef long double value_type;
typedef const value_type &const_reference;
typedef value_type &reference;
typedef value_type real_type;
typedef value_type precision_type;
};
// Define properties for a generic complex type
template<class T>
struct complex_traits {
typedef complex_traits<T> self_type;
typedef T value_type;
typedef const T &const_reference;
typedef T &reference;
typedef typename T::value_type real_type;
typedef real_type precision_type; // we do not know what type has more precision then the real_type
static const unsigned plus_complexity = 2;
static const unsigned multiplies_complexity = 6;
static
BOOST_UBLAS_INLINE
real_type real (const_reference t) {
return std::real (t);
}
static
BOOST_UBLAS_INLINE
real_type imag (const_reference t) {
return std::imag (t);
}
static
BOOST_UBLAS_INLINE
value_type conj (const_reference t) {
return std::conj (t);
}
static
BOOST_UBLAS_INLINE
real_type type_abs (const_reference t) {
return abs (t);
}
static
BOOST_UBLAS_INLINE
value_type type_sqrt (const_reference t) {
return sqrt (t);
}
static
BOOST_UBLAS_INLINE
real_type norm_1 (const_reference t) {
return self_type::type_abs (t);
// original computation has been replaced because a complex number should behave like a scalar type
// return type_traits<real_type>::type_abs (self_type::real (t)) +
// type_traits<real_type>::type_abs (self_type::imag (t));
}
static
BOOST_UBLAS_INLINE
real_type norm_2 (const_reference t) {
return self_type::type_abs (t);
}
static
BOOST_UBLAS_INLINE
real_type norm_inf (const_reference t) {
return self_type::type_abs (t);
// original computation has been replaced because a complex number should behave like a scalar type
// return (std::max) (type_traits<real_type>::type_abs (self_type::real (t)),
// type_traits<real_type>::type_abs (self_type::imag (t)));
}
static
BOOST_UBLAS_INLINE
bool equals (const_reference t1, const_reference t2) {
return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
(std::max) ((std::max) (self_type::norm_inf (t1),
self_type::norm_inf (t2)),
BOOST_UBLAS_TYPE_CHECK_MIN);
}
};
// Define complex type traits
template<>
struct type_traits<std::complex<float> > : complex_traits<std::complex<float> >{
typedef type_traits<std::complex<float> > self_type;
typedef std::complex<float> value_type;
typedef const value_type &const_reference;
typedef value_type &reference;
typedef float real_type;
typedef std::complex<double> precision_type;
};
template<>
struct type_traits<std::complex<double> > : complex_traits<std::complex<double> >{
typedef type_traits<std::complex<double> > self_type;
typedef std::complex<double> value_type;
typedef const value_type &const_reference;
typedef value_type &reference;
typedef double real_type;
typedef std::complex<long double> precision_type;
};
template<>
struct type_traits<std::complex<long double> > : complex_traits<std::complex<long double> > {
typedef type_traits<std::complex<long double> > self_type;
typedef std::complex<long double> value_type;
typedef const value_type &const_reference;
typedef value_type &reference;
typedef long double real_type;
typedef value_type precision_type;
};
#ifdef BOOST_UBLAS_USE_INTERVAL
// Define scalar interval type traits
template<>
struct type_traits<boost::numeric::interval<float> > : scalar_traits<boost::numeric::interval<float> > {
typedef type_traits<boost::numeric::interval<float> > self_type;
typedef boost::numeric::interval<float> value_type;
typedef const value_type &const_reference;
typedef value_type &reference;
typedef value_type real_type;
typedef boost::numeric::interval<double> precision_type;
};
template<>
struct type_traits<boost::numeric::interval<double> > : scalar_traits<boost::numeric::interval<double> > {
typedef type_traits<boost::numeric::interval<double> > self_type;
typedef boost::numeric::interval<double> value_type;
typedef const value_type &const_reference;
typedef value_type &reference;
typedef value_type real_type;
typedef boost::numeric::interval<long double> precision_type;
};
template<>
struct type_traits<boost::numeric::interval<long double> > : scalar_traits<boost::numeric::interval<long double> > {
typedef type_traits<boost::numeric::interval<long double> > self_type;
typedef boost::numeric::interval<long double> value_type;
typedef const value_type &const_reference;
typedef value_type &reference;
typedef value_type real_type;
typedef value_type precision_type;
};
#endif
// Storage tags -- hierarchical definition of storage characteristics
struct unknown_storage_tag {};
struct sparse_proxy_tag: public unknown_storage_tag {};
struct sparse_tag: public sparse_proxy_tag {};
struct packed_proxy_tag: public sparse_proxy_tag {};
struct packed_tag: public packed_proxy_tag {};
struct dense_proxy_tag: public packed_proxy_tag {};
struct dense_tag: public dense_proxy_tag {};
template<class S1, class S2>
struct storage_restrict_traits {
typedef S1 storage_category;
};
template<>
struct storage_restrict_traits<sparse_tag, dense_proxy_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct storage_restrict_traits<sparse_tag, packed_proxy_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct storage_restrict_traits<sparse_tag, sparse_proxy_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct storage_restrict_traits<packed_tag, dense_proxy_tag> {
typedef packed_proxy_tag storage_category;
};
template<>
struct storage_restrict_traits<packed_tag, packed_proxy_tag> {
typedef packed_proxy_tag storage_category;
};
template<>
struct storage_restrict_traits<packed_tag, sparse_proxy_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct storage_restrict_traits<packed_proxy_tag, sparse_proxy_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct storage_restrict_traits<dense_tag, dense_proxy_tag> {
typedef dense_proxy_tag storage_category;
};
template<>
struct storage_restrict_traits<dense_tag, packed_proxy_tag> {
typedef packed_proxy_tag storage_category;
};
template<>
struct storage_restrict_traits<dense_tag, sparse_proxy_tag> {
typedef sparse_proxy_tag storage_category;
};
template<>
struct storage_restrict_traits<dense_proxy_tag, packed_proxy_tag> {
typedef packed_proxy_tag storage_category;
};
template<>
struct storage_restrict_traits<dense_proxy_tag, sparse_proxy_tag> {
typedef sparse_proxy_tag storage_category;
};
// Iterator tags -- hierarchical definition of storage characteristics
struct sparse_bidirectional_iterator_tag : public std::bidirectional_iterator_tag {};
struct packed_random_access_iterator_tag : public std::random_access_iterator_tag {};
struct dense_random_access_iterator_tag : public packed_random_access_iterator_tag {};
// Thanks to Kresimir Fresl for convincing Comeau with iterator_base_traits ;-)
template<class IC>
struct iterator_base_traits {};
template<>
struct iterator_base_traits<std::forward_iterator_tag> {
template<class I, class T>
struct iterator_base {
typedef forward_iterator_base<std::forward_iterator_tag, I, T> type;
};
};
template<>
struct iterator_base_traits<std::bidirectional_iterator_tag> {
template<class I, class T>
struct iterator_base {
typedef bidirectional_iterator_base<std::bidirectional_iterator_tag, I, T> type;
};
};
template<>
struct iterator_base_traits<sparse_bidirectional_iterator_tag> {
template<class I, class T>
struct iterator_base {
typedef bidirectional_iterator_base<sparse_bidirectional_iterator_tag, I, T> type;
};
};
template<>
struct iterator_base_traits<std::random_access_iterator_tag> {
template<class I, class T>
struct iterator_base {
typedef random_access_iterator_base<std::random_access_iterator_tag, I, T> type;
};
};
template<>
struct iterator_base_traits<packed_random_access_iterator_tag> {
template<class I, class T>
struct iterator_base {
typedef random_access_iterator_base<packed_random_access_iterator_tag, I, T> type;
};
};
template<>
struct iterator_base_traits<dense_random_access_iterator_tag> {
template<class I, class T>
struct iterator_base {
typedef random_access_iterator_base<dense_random_access_iterator_tag, I, T> type;
};
};
template<class I1, class I2>
struct iterator_restrict_traits {
typedef I1 iterator_category;
};
template<>
struct iterator_restrict_traits<packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
typedef sparse_bidirectional_iterator_tag iterator_category;
};
template<>
struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag> {
typedef sparse_bidirectional_iterator_tag iterator_category;
};
template<>
struct iterator_restrict_traits<dense_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
typedef sparse_bidirectional_iterator_tag iterator_category;
};
template<>
struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, dense_random_access_iterator_tag> {
typedef sparse_bidirectional_iterator_tag iterator_category;
};
template<>
struct iterator_restrict_traits<dense_random_access_iterator_tag, packed_random_access_iterator_tag> {
typedef packed_random_access_iterator_tag iterator_category;
};
template<>
struct iterator_restrict_traits<packed_random_access_iterator_tag, dense_random_access_iterator_tag> {
typedef packed_random_access_iterator_tag iterator_category;
};
template<class I>
BOOST_UBLAS_INLINE
void increment (I &it, const I &it_end, typename I::difference_type compare, packed_random_access_iterator_tag) {
it += (std::min) (compare, it_end - it);
}
template<class I>
BOOST_UBLAS_INLINE
void increment (I &it, const I &/* it_end */, typename I::difference_type /* compare */, sparse_bidirectional_iterator_tag) {
++ it;
}
template<class I>
BOOST_UBLAS_INLINE
void increment (I &it, const I &it_end, typename I::difference_type compare) {
increment (it, it_end, compare, typename I::iterator_category ());
}
template<class I>
BOOST_UBLAS_INLINE
void increment (I &it, const I &it_end) {
#if BOOST_UBLAS_TYPE_CHECK
I cit (it);
while (cit != it_end) {
BOOST_UBLAS_CHECK (*cit == typename I::value_type/*zero*/(), internal_logic ());
++ cit;
}
#endif
it = it_end;
}
namespace detail {
// specialisation which define whether a type has a trivial constructor
// or not. This is used by array types.
template<typename T>
struct has_trivial_constructor : public boost::has_trivial_constructor<T> {};
template<typename T>
struct has_trivial_destructor : public boost::has_trivial_destructor<T> {};
template<typename FLT>
struct has_trivial_constructor<std::complex<FLT> > : public boost::true_type {};
template<typename FLT>
struct has_trivial_destructor<std::complex<FLT> > : public boost::true_type {};
}
/** \brief Traits class to extract type information from a constant matrix or vector CONTAINER.
*
*/
template < class E >
struct container_view_traits {
/// type of indices
typedef typename E::size_type size_type;
/// type of differences of indices
typedef typename E::difference_type difference_type;
/// storage category: \c unknown_storage_tag, \c dense_tag, \c packed_tag, ...
typedef typename E::storage_category storage_category;
/// type of elements
typedef typename E::value_type value_type;
/// const reference to an element
typedef typename E::const_reference const_reference;
/// type used in expressions to mark a reference to this class (usually a const container_reference<const E> or the class itself)
typedef typename E::const_closure_type const_closure_type;
};
/** \brief Traits class to extract additional type information from a mutable matrix or vector CONTAINER.
*
*/
template < class E >
struct mutable_container_traits {
/// reference to an element
typedef typename E::reference reference;
/// type used in expressions to mark a reference to this class (usually a container_reference<E> or the class itself)
typedef typename E::closure_type closure_type;
};
/** \brief Traits class to extract type information from a matrix or vector CONTAINER.
*
*/
template < class E >
struct container_traits
: container_view_traits<E>, mutable_container_traits<E> {
};
/** \brief Traits class to extract type information from a constant MATRIX.
*
*/
template < class MATRIX >
struct matrix_view_traits : container_view_traits <MATRIX> {
/// orientation of the matrix, either \c row_major_tag, \c column_major_tag or \c unknown_orientation_tag
typedef typename MATRIX::orientation_category orientation_category;
/// row iterator for the matrix
typedef typename MATRIX::const_iterator1 const_iterator1;
/// column iterator for the matrix
typedef typename MATRIX::const_iterator2 const_iterator2;
};
/** \brief Traits class to extract additional type information from a mutable MATRIX.
*
*/
template < class MATRIX >
struct mutable_matrix_traits
: mutable_container_traits <MATRIX> {
/// row iterator for the matrix
typedef typename MATRIX::iterator1 iterator1;
/// column iterator for the matrix
typedef typename MATRIX::iterator2 iterator2;
};
/** \brief Traits class to extract type information from a MATRIX.
*
*/
template < class MATRIX >
struct matrix_traits
: matrix_view_traits <MATRIX>, mutable_matrix_traits <MATRIX> {
};
/** \brief Traits class to extract type information from a VECTOR.
*
*/
template < class VECTOR >
struct vector_view_traits : container_view_traits <VECTOR> {
/// iterator for the VECTOR
typedef typename VECTOR::const_iterator const_iterator;
/// iterator pointing to the first element
static
const_iterator begin(const VECTOR & v) {
return v.begin();
}
/// iterator pointing behind the last element
static
const_iterator end(const VECTOR & v) {
return v.end();
}
};
/** \brief Traits class to extract type information from a VECTOR.
*
*/
template < class VECTOR >
struct mutable_vector_traits : mutable_container_traits <VECTOR> {
/// iterator for the VECTOR
typedef typename VECTOR::iterator iterator;
/// iterator pointing to the first element
static
iterator begin(VECTOR & v) {
return v.begin();
}
/// iterator pointing behind the last element
static
iterator end(VECTOR & v) {
return v.end();
}
};
/** \brief Traits class to extract type information from a VECTOR.
*
*/
template < class VECTOR >
struct vector_traits
: vector_view_traits <VECTOR>, mutable_vector_traits <VECTOR> {
};
// Note: specializations for T[N] and T[M][N] have been moved to traits/c_array.hpp
}}}
#endif

View File

@@ -0,0 +1,110 @@
/**
* -*- c++ -*-
*
* \file c_array.hpp
*
* \brief provides specializations of matrix and vector traits for c arrays and c matrices.
*
* Copyright (c) 2009, Gunter Winkler
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* \author Gunter Winkler (guwi17 at gmx dot de)
*/
#ifndef BOOST_NUMERIC_UBLAS_TRAITS_C_ARRAY_HPP
#define BOOST_NUMERIC_UBLAS_TRAITS_C_ARRAY_HPP
#include <boost/numeric/ublas/traits.hpp>
#include <boost/numeric/ublas/traits/const_iterator_type.hpp>
#include <boost/numeric/ublas/traits/iterator_type.hpp>
namespace boost { namespace numeric { namespace ublas {
namespace detail {
}
template < class T, int M, int N >
struct matrix_view_traits < T[M][N] > {
typedef T matrix_type[M][N];
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef row_major_tag orientation_category;
typedef dense_tag storage_category;
typedef T value_type;
typedef const T &const_reference;
typedef const T *const_pointer;
typedef const matrix_reference<const matrix_type> const_closure_type;
typedef T row_type[N];
typedef const row_type *const_iterator1;
typedef const_pointer const_iterator2;
};
template < class T, int M, int N >
struct mutable_matrix_traits < T[M][N] > {
typedef T matrix_type[M][N];
typedef T *reference;
typedef matrix_reference<matrix_type> closure_type;
};
template < class T, int N >
struct vector_view_traits < T[N] > {
typedef T vector_type[N];
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef dense_tag storage_category;
typedef T value_type;
typedef const T &const_reference;
typedef const T *const_pointer;
typedef const vector_reference<const vector_type> const_closure_type;
typedef const_pointer const_iterator;
/// iterator pointing to the first element
static
const_iterator begin(const vector_type & v) {
return & (v[0]);
}
/// iterator pointing behind the last element
static
const_iterator end(const vector_type & v) {
return & (v[N]);
}
};
template < class T, int N >
struct mutable_vector_traits < T[N] > {
typedef T &reference;
typedef T *pointer;
typedef vector_reference< T[N] > closure_type;
};
}}} // Namespace boost::numeric::ublas
#endif

View File

@@ -0,0 +1,127 @@
/**
* -*- c++ -*-
*
* \file const_iterator_type.hpp
*
* \brief Const iterator to a given container type.
*
* Copyright (c) 2009, Marco Guazzone
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* \author Marco Guazzone, marco.guazzone@gmail.com
*/
#ifndef BOOST_NUMERIC_UBLAS_TRAITS_CONST_ITERATOR_TYPE_HPP
#define BOOST_NUMERIC_UBLAS_TRAITS_CONST_ITERATOR_TYPE_HPP
#include <boost/numeric/ublas/fwd.hpp>
#include <boost/numeric/ublas/tags.hpp>
#include <boost/numeric/ublas/traits.hpp>
namespace boost { namespace numeric { namespace ublas {
namespace detail {
/**
* \brief Auxiliary class for retrieving the const iterator to the given
* matrix expression according its orientation and to the given dimension tag.
* \tparam MatrixT A model of MatrixExpression.
* \tparam TagT A dimension tag type (e.g., tag::major).
* \tparam OrientationT An orientation category type (e.g., row_major_tag).
*/
template <typename MatrixT, typename TagT, typename OrientationT>
struct const_iterator_type_impl;
/// \brief Specialization of \c const_iterator_type_impl for row-major oriented
/// matrices and over the major dimension.
template <typename MatrixT>
struct const_iterator_type_impl<MatrixT,tag::major,row_major_tag>
{
typedef typename matrix_view_traits<MatrixT>::const_iterator1 type;
};
/// \brief Specialization of \c const_iterator_type_impl for column-major
/// oriented matrices and over the major dimension.
template <typename MatrixT>
struct const_iterator_type_impl<MatrixT,tag::major,column_major_tag>
{
typedef typename matrix_view_traits<MatrixT>::const_iterator2 type;
};
/// \brief Specialization of \c const_iterator_type_impl for row-major oriented
/// matrices and over the minor dimension.
template <typename MatrixT>
struct const_iterator_type_impl<MatrixT,tag::minor,row_major_tag>
{
typedef typename matrix_view_traits<MatrixT>::const_iterator2 type;
};
/// \brief Specialization of \c const_iterator_type_impl for column-major
/// oriented matrices and over the minor dimension.
template <typename MatrixT>
struct const_iterator_type_impl<MatrixT,tag::minor,column_major_tag>
{
typedef typename matrix_view_traits<MatrixT>::const_iterator1 type;
};
} // Namespace detail
/**
* \brief A const iterator for the given container type over the given
* dimension.
* \tparam ContainerT A container expression type.
* \tparam TagT A dimension tag type (e.g., tag::major).
*/
template <typename ContainerT, typename TagT=void>
struct const_iterator_type;
/**
* \brief Specialization of \c const_iterator_type for vector expressions.
* \tparam VectorT A model of VectorExpression type.
*/
template <typename VectorT>
struct const_iterator_type<VectorT, void>
{
typedef typename vector_view_traits<VectorT>::const_iterator type;
};
/**
* \brief Specialization of \c const_iterator_type for matrix expressions and
* over the major dimension.
* \tparam MatrixT A model of MatrixExpression type.
*/
template <typename MatrixT>
struct const_iterator_type<MatrixT,tag::major>
{
typedef typename detail::const_iterator_type_impl<MatrixT,tag::minor,typename matrix_view_traits<MatrixT>::orientation_category>::type type;
};
/**
* \brief Specialization of \c const_iterator_type for matrix expressions and
* over the minor dimension.
* \tparam MatrixT A model of MatrixExpression type.
*/
template <typename MatrixT>
struct const_iterator_type<MatrixT,tag::minor>
{
typedef typename detail::const_iterator_type_impl<MatrixT,tag::minor,typename matrix_view_traits<MatrixT>::orientation_category>::type type;
};
}}} // Namespace boost::numeric::ublas
#endif // BOOST_NUMERIC_UBLAS_TRAITS_CONST_ITERATOR_TYPE_HPP

View File

@@ -0,0 +1,126 @@
/**
* -*- c++ -*-
*
* \file iterator_type.hpp
*
* \brief Iterator to a given container type.
*
* Copyright (c) 2009, Marco Guazzone
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* \author Marco Guazzone, marco.guazzone@gmail.com
*/
#ifndef BOOST_NUMERIC_UBLAS_TRAITS_ITERATOR_TYPE_HPP
#define BOOST_NUMERIC_UBLAS_TRAITS_ITERATOR_TYPE_HPP
#include <boost/numeric/ublas/fwd.hpp>
#include <boost/numeric/ublas/traits.hpp>
#include <boost/numeric/ublas/tags.hpp>
namespace boost { namespace numeric { namespace ublas {
namespace detail {
/**
* \brief Auxiliary class for retrieving the iterator to the given
* matrix expression according its orientation and to the given dimension tag.
* \tparam MatrixT A model of MatrixExpression.
* \tparam TagT A dimension tag type (e.g., tag::major).
* \tparam OrientationT An orientation category type (e.g., row_major_tag).
*/
template <typename MatrixT, typename TagT, typename OrientationT>
struct iterator_type_impl;
/// \brief Specialization of \c iterator_type_impl for row-major oriented
/// matrices and over the major dimension.
template <typename MatrixT>
struct iterator_type_impl<MatrixT,tag::major,row_major_tag>
{
typedef typename matrix_traits<MatrixT>::iterator1 type;
};
/// \brief Specialization of \c iterator_type_impl for column-major oriented
/// matrices and over the major dimension.
template <typename MatrixT>
struct iterator_type_impl<MatrixT,tag::major,column_major_tag>
{
typedef typename matrix_traits<MatrixT>::iterator2 type;
};
/// \brief Specialization of \c iterator_type_impl for row-major oriented
/// matrices and over the minor dimension.
template <typename MatrixT>
struct iterator_type_impl<MatrixT,tag::minor,row_major_tag>
{
typedef typename matrix_traits<MatrixT>::iterator2 type;
};
/// \brief Specialization of \c iterator_type_impl for column-major oriented
/// matrices and over the minor dimension.
template <typename MatrixT>
struct iterator_type_impl<MatrixT,tag::minor,column_major_tag>
{
typedef typename matrix_traits<MatrixT>::iterator1 type;
};
} // Namespace detail
/**
* \brief A iterator for the given container type over the given dimension.
* \tparam ContainerT A container expression type.
* \tparam TagT A dimension tag type (e.g., tag::major).
*/
template <typename ContainerT, typename TagT=void>
struct iterator_type;
/**
* \brief Specialization of \c iterator_type for vector expressions.
* \tparam VectorT A model of VectorExpression type.
*/
template <typename VectorT>
struct iterator_type<VectorT, void>
{
typedef typename vector_traits<VectorT>::iterator type;
};
/**
* \brief Specialization of \c iterator_type for matrix expressions and
* over the major dimension.
* \tparam MatrixT A model of MatrixExpression type.
*/
template <typename MatrixT>
struct iterator_type<MatrixT,tag::major>
{
typedef typename detail::iterator_type_impl<MatrixT,tag::major,typename matrix_traits<MatrixT>::orientation_category>::type type;
};
/**
* \brief Specialization of \c iterator_type for matrix expressions and
* over the minor dimension.
* \tparam MatrixT A model of MatrixExpression type.
*/
template <typename MatrixT>
struct iterator_type<MatrixT,tag::minor>
{
typedef typename detail::iterator_type_impl<MatrixT,tag::minor,typename matrix_traits<MatrixT>::orientation_category>::type type;
};
}}} // Namespace boost::numeric::ublas
#endif // BOOST_NUMERIC_UBLAS_TRAITS_ITERATOR_TYPE_HPP

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff