mirror of
https://github.com/boostorg/ublas.git
synced 2026-02-21 03:22:14 +00:00
Merge branch 'feature/ublas00002_fixed_matrix' into ublas_develop
This commit is contained in:
@@ -59,4 +59,5 @@ SOURCES += \
|
||||
../../../test/num_columns.cpp \
|
||||
../../../test/concepts.cpp \
|
||||
../../../test/comp_mat_erase.cpp \
|
||||
../../../test/begin_end.cpp
|
||||
../../../test/begin_end.cpp \
|
||||
../../../test/test_fixed_containers.cpp
|
||||
|
||||
@@ -170,7 +170,7 @@ BOOST_UBLAS_INLINE vector_move_manip<T> move(T i) {
|
||||
*
|
||||
* \todo Doxygen has some problems with similar template functions. Correct that.
|
||||
*/
|
||||
template <std::size_t I>
|
||||
template <std::ptrdiff_t I>
|
||||
class static_vector_move_manip: public index_manipulator<static_vector_move_manip<I> > {
|
||||
public:
|
||||
template <typename V>
|
||||
@@ -198,8 +198,8 @@ public:
|
||||
*
|
||||
* \todo Doxygen has some problems with similar template functions. Correct that.
|
||||
*/
|
||||
template <std::size_t I>
|
||||
BOOST_UBLAS_INLINE static_vector_move_manip<I> move() {
|
||||
template <std::ptrdiff_t I>
|
||||
static_vector_move_manip<I> move() {
|
||||
return static_vector_move_manip<I>();
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ BOOST_UBLAS_INLINE matrix_move_to_manip<T> move_to(T i, T j) {
|
||||
*
|
||||
* \todo Doxygen has some problems with similar template functions. Correct that.
|
||||
*/
|
||||
template <std::size_t I, std::size_t J>
|
||||
template <std::size_t I,std::size_t J>
|
||||
class static_matrix_move_to_manip: public index_manipulator<static_matrix_move_to_manip<I, J> > {
|
||||
public:
|
||||
template <typename V, typename K>
|
||||
@@ -369,7 +369,7 @@ BOOST_UBLAS_INLINE matrix_move_manip<T> move(T i, T j) {
|
||||
*
|
||||
* \todo Doxygen has some problems with similar template functions. Correct that.
|
||||
*/
|
||||
template <std::size_t I, std::size_t J>
|
||||
template <std::ptrdiff_t I, std::ptrdiff_t J>
|
||||
class static_matrix_move_manip: public index_manipulator<static_matrix_move_manip<I, J> > {
|
||||
public:
|
||||
template <typename V, typename K>
|
||||
@@ -407,7 +407,7 @@ public:
|
||||
*
|
||||
* \todo Doxygen has some problems with similar template functions. Correct that.
|
||||
*/
|
||||
template <std::size_t I, std::size_t J>
|
||||
template <std::ptrdiff_t I, std::ptrdiff_t J>
|
||||
BOOST_UBLAS_INLINE static_matrix_move_manip<I, J> move() {
|
||||
return static_matrix_move_manip<I, J>();
|
||||
}
|
||||
@@ -804,7 +804,7 @@ namespace traverse_policy {
|
||||
l++; j++;
|
||||
if (l>=e().size2()) {
|
||||
l=0; k++; j=j0; i++;
|
||||
// It is assumed that the iteration starts from 0 and happens only using this function from within
|
||||
// It is assumed that the iteration starts from 0 and progresses only using this function from within
|
||||
// an assigner object.
|
||||
// Otherwise (i.e. if it is called outside the assigner object) apply2 should have been
|
||||
// outside the if statement.
|
||||
@@ -850,7 +850,7 @@ namespace traverse_policy {
|
||||
k++; i++;
|
||||
if (k>=e().size1()) {
|
||||
k=0; l++; i=i0; j++;
|
||||
// It is assumed that the iteration starts from 0 and happens only using this function from within
|
||||
// It is assumed that the iteration starts from 0 and progresses only using this function from within
|
||||
// an assigner object.
|
||||
// Otherwise (i.e. if it is called outside the assigner object) apply2 should have been
|
||||
// outside the if statement.
|
||||
|
||||
@@ -190,11 +190,11 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
|
||||
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_)
|
||||
size1_(o.size1_), size2_(o.size2_),
|
||||
nnz_(o.nnz_),
|
||||
index1_data_(o.index1_data_),
|
||||
index2_data_(o.index2_data_),
|
||||
value_data_(o.value_data_)
|
||||
{}
|
||||
|
||||
//
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef BOOST_UBLAS_CPP11
|
||||
#include <array>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace numeric { namespace ublas {
|
||||
|
||||
// Storage types
|
||||
@@ -88,6 +92,10 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
|
||||
template<class T, class A = unbounded_array<T> >
|
||||
class vector;
|
||||
#ifdef BOOST_UBLAS_CPP11
|
||||
template<class T, std::size_t N, class A = std::array<T, N> >
|
||||
class fixed_vector;
|
||||
#endif
|
||||
template<class T, std::size_t N>
|
||||
class bounded_vector;
|
||||
|
||||
@@ -125,6 +133,10 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
|
||||
template<class T, class L = row_major, class A = unbounded_array<T> >
|
||||
class matrix;
|
||||
#ifdef BOOST_UBLAS_CPP11
|
||||
template<class T, std::size_t M, std::size_t N, class L = row_major, class A = std::array<T, M*N> >
|
||||
class fixed_matrix;
|
||||
#endif
|
||||
template<class T, std::size_t M, std::size_t N, class L = row_major>
|
||||
class bounded_matrix;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,7 @@
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_float.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_unsigned.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
|
||||
// anonymous namespace to avoid ADL issues
|
||||
@@ -36,23 +37,120 @@ namespace {
|
||||
// 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;
|
||||
// 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);
|
||||
}
|
||||
// return abs (t);
|
||||
// }
|
||||
|
||||
template<typename T>
|
||||
typename boost::disable_if<
|
||||
boost::is_unsigned<T>, T >::type
|
||||
inline boost_numeric_ublas_abs (const T &t ) {
|
||||
using namespace std;
|
||||
return abs( t );
|
||||
}
|
||||
|
||||
// unsigned types are always non-negative
|
||||
template<> unsigned int boost_numeric_ublas_abs (const unsigned int& t) {
|
||||
return t;
|
||||
}
|
||||
//template<> inline unsigned int boost_numeric_ublas_abs (const unsigned int& t) {
|
||||
// return t;
|
||||
//}
|
||||
// unsigned types are always non-negative
|
||||
template<> unsigned long boost_numeric_ublas_abs (const unsigned long& t) {
|
||||
return t;
|
||||
}
|
||||
//template<> inline unsigned long boost_numeric_ublas_abs (const unsigned long& t) {
|
||||
// return t;
|
||||
//}
|
||||
|
||||
template<typename T>
|
||||
typename boost::enable_if<
|
||||
boost::is_unsigned<T>, T >::type
|
||||
inline boost_numeric_ublas_abs (const T &t ) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
namespace boost { namespace numeric { namespace ublas {
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Use Joel de Guzman's return type deduction
|
||||
// uBLAS assumes a common return type for all binary arithmetic operators
|
||||
template<class X, class Y>
|
||||
@@ -73,86 +171,6 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
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
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//
|
||||
// Copyright (c) 2000-2010
|
||||
// Joerg Walter, Mathias Koch, David Bellot
|
||||
// Copyright (c) 2014, Athanasios Iliopoulos
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -22,6 +23,10 @@
|
||||
#include <boost/serialization/collection_size_type.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
|
||||
#ifdef BOOST_UBLAS_CPP11
|
||||
#include <array>
|
||||
#include <initializer_list>
|
||||
#endif
|
||||
|
||||
// Iterators based on ideas of Jeremy Siek
|
||||
|
||||
@@ -793,6 +798,753 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
};
|
||||
|
||||
|
||||
#ifdef BOOST_UBLAS_CPP11
|
||||
/** \brief A dense vector of values of type \c T.
|
||||
*
|
||||
* For a \f$n\f$-dimensional vector \f$v\f$ and \f$0\leq i < n\f$ every element \f$v_i\f$ is mapped
|
||||
* to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c std::array.
|
||||
* Elements are constructed by \c A, which need not initialise their value.
|
||||
*
|
||||
* \tparam T type of the objects stored in the vector (like int, double, complex,...)
|
||||
* \tparam A The type of the storage array of the vector. Default is \c std::array<T>.
|
||||
*/
|
||||
template<class T, std::size_t N, class A>
|
||||
class fixed_vector:
|
||||
public vector_container<fixed_vector<T, N, A> > {
|
||||
|
||||
typedef fixed_vector<T, N, A> self_type;
|
||||
public:
|
||||
#ifdef BOOST_UBLAS_ENABLE_PROXY_SHORTCUTS
|
||||
using vector_container<self_type>::operator ();
|
||||
#endif
|
||||
|
||||
typedef typename A::size_type size_type;
|
||||
typedef typename A::difference_type difference_type;
|
||||
typedef T value_type;
|
||||
typedef typename type_traits<T>::const_reference const_reference;
|
||||
typedef T &reference;
|
||||
typedef T *pointer;
|
||||
typedef const T *const_pointer;
|
||||
typedef A array_type;
|
||||
typedef const vector_reference<const self_type> const_closure_type;
|
||||
typedef vector_reference<self_type> closure_type;
|
||||
typedef self_type vector_temporary_type;
|
||||
typedef dense_tag storage_category;
|
||||
|
||||
// Construction and destruction
|
||||
|
||||
/// \brief Constructor of a fixed_vector
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector ():
|
||||
vector_container<self_type> (),
|
||||
data_ () {}
|
||||
|
||||
/// \brief Constructor of a fixed_vector by copying from another container
|
||||
/// This type has the generic name \c array_typ within the vector definition.
|
||||
/// \param data container of type \c A
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector (const array_type &data):
|
||||
vector_container<self_type> (),
|
||||
data_ (data) {}
|
||||
|
||||
/// \brief Constructor of a fixed_vector with a predefined size and a unique initial value
|
||||
/// \param init value to assign to each element of the vector
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector (const value_type &init):
|
||||
vector_container<self_type> (),
|
||||
data_ () {
|
||||
data_.fill( init );
|
||||
}
|
||||
|
||||
/// \brief Copy-constructor of a fixed_vector
|
||||
/// \param v is the fixed_vector to be duplicated
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector (const fixed_vector &v):
|
||||
vector_container<self_type> (),
|
||||
data_ (v.data_) {}
|
||||
|
||||
/// \brief Copy-constructor of a vector from a vector_expression
|
||||
/// Depending on the vector_expression, this constructor can have the cost of the computations
|
||||
/// of the expression (trivial to say it, but it is to take into account in your complexity calculations).
|
||||
/// \param ae the vector_expression which values will be duplicated into the vector
|
||||
template<class AE>
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector (const vector_expression<AE> &ae):
|
||||
vector_container<self_type> (),
|
||||
data_ ( ) {
|
||||
vector_assign<scalar_assign> (*this, ae);
|
||||
}
|
||||
|
||||
/// \brief Construct a fixed_vector from a list of values
|
||||
/// The list should be included in curly braces. Typical syntax is:
|
||||
/// fixed_vector<double, 3> v = { 1, 2, 3 } or fixed_vector<double,3> v( {1, 2, 3} ) or fixed_vector<double,3> v( 1, 2, 3 )
|
||||
template <typename... Types>
|
||||
fixed_vector(value_type v0, Types... vrest) :
|
||||
vector_container<self_type> (),
|
||||
data_{ { v0, vrest... } } {}
|
||||
|
||||
// -----------------------
|
||||
// Random Access Container
|
||||
// -----------------------
|
||||
|
||||
/// \brief Return the maximum size of the data container.
|
||||
/// Return the upper bound (maximum size) on the data container. Depending on the container, it can be bigger than the current size of the vector.
|
||||
BOOST_UBLAS_INLINE
|
||||
size_type max_size () const {
|
||||
return data_.max_size ();
|
||||
}
|
||||
|
||||
/// \brief Return true if the vector is empty (\c size==0)
|
||||
/// \return \c true if empty, \c false otherwise
|
||||
BOOST_UBLAS_INLINE
|
||||
const bool &empty () const {
|
||||
return data_.empty();
|
||||
}
|
||||
|
||||
// ---------
|
||||
// Accessors
|
||||
// ---------
|
||||
|
||||
/// \brief Return the size of the vector
|
||||
BOOST_UBLAS_INLINE
|
||||
constexpr size_type size () const{ // should have a const after C++14
|
||||
return data_.size ();
|
||||
}
|
||||
|
||||
// -----------------
|
||||
// Storage accessors
|
||||
// -----------------
|
||||
|
||||
/// \brief Return a \c const reference to the container. Useful to access data directly for specific type of container.
|
||||
BOOST_UBLAS_INLINE
|
||||
const array_type &data () const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
/// \brief Return a reference to the container. Useful to speed-up write operations to the data in very specific case.
|
||||
BOOST_UBLAS_INLINE
|
||||
array_type &data () {
|
||||
return data_;
|
||||
}
|
||||
|
||||
// ---------------
|
||||
// Element support
|
||||
// ---------------
|
||||
|
||||
/// \brief Return a pointer to the element \f$i\f$
|
||||
/// \param i index of the element
|
||||
// XXX this semantic is not the one expected by the name of this method
|
||||
BOOST_UBLAS_INLINE
|
||||
pointer find_element (size_type i) {
|
||||
return const_cast<pointer> (const_cast<const self_type&>(*this).find_element (i));
|
||||
}
|
||||
|
||||
/// \brief Return a const pointer to the element \f$i\f$
|
||||
/// \param i index of the element
|
||||
// XXX this semantic is not the one expected by the name of this method
|
||||
BOOST_UBLAS_INLINE
|
||||
const_pointer find_element (size_type i) const {
|
||||
BOOST_UBLAS_CHECK (i < data_.size(), bad_index() ); // Since std:array doesn't check for bounds
|
||||
return & (data () [i]);
|
||||
}
|
||||
|
||||
// --------------
|
||||
// Element access
|
||||
// --------------
|
||||
|
||||
/// \brief Return a const reference to the element \f$i\f$
|
||||
/// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
|
||||
/// \param i index of the element
|
||||
BOOST_UBLAS_INLINE
|
||||
const_reference operator () (size_type i) const {
|
||||
BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
|
||||
return data () [i];
|
||||
}
|
||||
|
||||
/// \brief Return a reference to the element \f$i\f$
|
||||
/// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c[i]
|
||||
/// \param i index of the element
|
||||
BOOST_UBLAS_INLINE
|
||||
reference operator () (size_type i) {
|
||||
BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
|
||||
return data () [i];
|
||||
}
|
||||
|
||||
/// \brief Return a const reference to the element \f$i\f$
|
||||
/// \param i index of the element
|
||||
BOOST_UBLAS_INLINE
|
||||
const_reference operator [] (size_type i) const {
|
||||
BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
|
||||
return (*this) (i);
|
||||
}
|
||||
|
||||
/// \brief Return a reference to the element \f$i\f$
|
||||
/// \param i index of the element
|
||||
BOOST_UBLAS_INLINE
|
||||
reference operator [] (size_type i) {
|
||||
BOOST_UBLAS_CHECK (i < data_.size(), bad_index() );
|
||||
return (*this) (i);
|
||||
}
|
||||
|
||||
// ------------------
|
||||
// Element assignment
|
||||
// ------------------
|
||||
|
||||
/// \brief Set element \f$i\f$ to the value \c t
|
||||
/// \param i index of the element
|
||||
/// \param t reference to the value to be set
|
||||
// XXX semantic of this is to insert a new element and therefore size=size+1 ?
|
||||
BOOST_UBLAS_INLINE
|
||||
reference insert_element (size_type i, const_reference t) {
|
||||
BOOST_UBLAS_CHECK (i < data_.size(), bad_index ());
|
||||
return (data () [i] = t);
|
||||
}
|
||||
|
||||
/// \brief Set element \f$i\f$ to the \e zero value
|
||||
/// \param i index of the element
|
||||
BOOST_UBLAS_INLINE
|
||||
void erase_element (size_type i) {
|
||||
BOOST_UBLAS_CHECK (i < data_.size(), bad_index ());
|
||||
data () [i] = value_type/*zero*/();
|
||||
}
|
||||
|
||||
// -------
|
||||
// Zeroing
|
||||
// -------
|
||||
|
||||
/// \brief Clear the vector, i.e. set all values to the \c zero value.
|
||||
BOOST_UBLAS_INLINE
|
||||
void clear () {
|
||||
std::fill (data ().begin (), data ().end (), value_type/*zero*/());
|
||||
}
|
||||
|
||||
// Assignment
|
||||
#ifdef BOOST_UBLAS_MOVE_SEMANTICS
|
||||
|
||||
/// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
|
||||
/// \param v is the source vector
|
||||
/// \return a reference to a fixed_vector (i.e. the destination vector)
|
||||
/*! @note "pass by value" the key idea to enable move semantics */
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &operator = (fixed_vector v) {
|
||||
assign_temporary(v);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
/// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
|
||||
/// \param v is the source vector
|
||||
/// \return a reference to a vector (i.e. the destination vector)
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &operator = (const fixed_vector &v) {
|
||||
data () = v.data ();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \brief Assign a full fixed_vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector)
|
||||
/// Assign a full vector (\e RHS-vector) to the current fixed_vector (\e LHS-vector). This method does not create any temporary.
|
||||
/// \param v is the source vector container
|
||||
/// \return a reference to a vector (i.e. the destination vector)
|
||||
template<class C> // Container assignment without temporary
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &operator = (const vector_container<C> &v) {
|
||||
assign (v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
|
||||
/// \param v is the source vector
|
||||
/// \return a reference to a vector (i.e. the destination vector)
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &assign_temporary (fixed_vector &v) {
|
||||
swap ( v );
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Assign the result of a vector_expression to the vector
|
||||
/// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
|
||||
/// \tparam AE is the type of the vector_expression
|
||||
/// \param ae is a const reference to the vector_expression
|
||||
/// \return a reference to the resulting vector
|
||||
template<class AE>
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &operator = (const vector_expression<AE> &ae) {
|
||||
self_type temporary (ae);
|
||||
return assign_temporary (temporary);
|
||||
}
|
||||
|
||||
/// \brief Assign the result of a vector_expression to the vector
|
||||
/// Assign the result of a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
|
||||
/// \tparam AE is the type of the vector_expression
|
||||
/// \param ae is a const reference to the vector_expression
|
||||
/// \return a reference to the resulting vector
|
||||
template<class AE>
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &assign (const vector_expression<AE> &ae) {
|
||||
vector_assign<scalar_assign> (*this, ae);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// -------------------
|
||||
// Computed assignment
|
||||
// -------------------
|
||||
|
||||
/// \brief Assign the sum of the vector and a vector_expression to the vector
|
||||
/// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
|
||||
/// A temporary is created for the computations.
|
||||
/// \tparam AE is the type of the vector_expression
|
||||
/// \param ae is a const reference to the vector_expression
|
||||
/// \return a reference to the resulting vector
|
||||
template<class AE>
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &operator += (const vector_expression<AE> &ae) {
|
||||
self_type temporary (*this + ae);
|
||||
return assign_temporary (temporary);
|
||||
}
|
||||
|
||||
/// \brief Assign the sum of the vector and a vector_expression to the vector
|
||||
/// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
|
||||
/// No temporary is created. Computations are done and stored directly into the resulting vector.
|
||||
/// \tparam AE is the type of the vector_expression
|
||||
/// \param ae is a const reference to the vector_expression
|
||||
/// \return a reference to the resulting vector
|
||||
template<class C> // Container assignment without temporary
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &operator += (const vector_container<C> &v) {
|
||||
plus_assign (v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Assign the sum of the vector and a vector_expression to the vector
|
||||
/// Assign the sum of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
|
||||
/// No temporary is created. Computations are done and stored directly into the resulting vector.
|
||||
/// \tparam AE is the type of the vector_expression
|
||||
/// \param ae is a const reference to the vector_expression
|
||||
/// \return a reference to the resulting vector
|
||||
template<class AE>
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &plus_assign (const vector_expression<AE> &ae) {
|
||||
vector_assign<scalar_plus_assign> (*this, ae);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Assign the difference of the vector and a vector_expression to the vector
|
||||
/// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
|
||||
/// A temporary is created for the computations.
|
||||
/// \tparam AE is the type of the vector_expression
|
||||
/// \param ae is a const reference to the vector_expression
|
||||
template<class AE>
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &operator -= (const vector_expression<AE> &ae) {
|
||||
self_type temporary (*this - ae);
|
||||
return assign_temporary (temporary);
|
||||
}
|
||||
|
||||
/// \brief Assign the difference of the vector and a vector_expression to the vector
|
||||
/// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
|
||||
/// No temporary is created. Computations are done and stored directly into the resulting vector.
|
||||
/// \tparam AE is the type of the vector_expression
|
||||
/// \param ae is a const reference to the vector_expression
|
||||
/// \return a reference to the resulting vector
|
||||
template<class C> // Container assignment without temporary
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &operator -= (const vector_container<C> &v) {
|
||||
minus_assign (v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Assign the difference of the vector and a vector_expression to the vector
|
||||
/// Assign the difference of the vector and a vector_expression to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
|
||||
/// No temporary is created. Computations are done and stored directly into the resulting vector.
|
||||
/// \tparam AE is the type of the vector_expression
|
||||
/// \param ae is a const reference to the vector_expression
|
||||
/// \return a reference to the resulting vector
|
||||
template<class AE>
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &minus_assign (const vector_expression<AE> &ae) {
|
||||
vector_assign<scalar_minus_assign> (*this, ae);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Assign the product of the vector and a scalar to the vector
|
||||
/// Assign the product of the vector and a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
|
||||
/// No temporary is created. Computations are done and stored directly into the resulting vector.
|
||||
/// \tparam AE is the type of the vector_expression
|
||||
/// \param at is a const reference to the scalar
|
||||
/// \return a reference to the resulting vector
|
||||
template<class AT>
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &operator *= (const AT &at) {
|
||||
vector_assign_scalar<scalar_multiplies_assign> (*this, at);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Assign the division of the vector by a scalar to the vector
|
||||
/// Assign the division of the vector by a scalar to the vector. This is lazy-compiled and will be optimized out by the compiler on any type of expression.
|
||||
/// No temporary is created. Computations are done and stored directly into the resulting vector.
|
||||
/// \tparam AE is the type of the vector_expression
|
||||
/// \param at is a const reference to the scalar
|
||||
/// \return a reference to the resulting vector
|
||||
template<class AT>
|
||||
BOOST_UBLAS_INLINE
|
||||
fixed_vector &operator /= (const AT &at) {
|
||||
vector_assign_scalar<scalar_divides_assign> (*this, at);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// --------
|
||||
// Swapping
|
||||
// --------
|
||||
|
||||
/// \brief Swap the content of the vector with another vector
|
||||
/// \param v is the vector to be swapped with
|
||||
BOOST_UBLAS_INLINE
|
||||
void swap (fixed_vector &v) {
|
||||
if (this != &v) {
|
||||
data ().swap (v.data ());
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Swap the content of two vectors
|
||||
/// \param v1 is the first vector. It takes values from v2
|
||||
/// \param v2 is the second vector It takes values from v1
|
||||
BOOST_UBLAS_INLINE
|
||||
friend void swap (fixed_vector &v1, fixed_vector &v2) {
|
||||
v1.swap (v2);
|
||||
}
|
||||
|
||||
// Iterator types
|
||||
private:
|
||||
// Use the storage array iterator
|
||||
typedef typename A::const_iterator const_subiterator_type;
|
||||
typedef typename A::iterator subiterator_type;
|
||||
|
||||
public:
|
||||
#ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
||||
typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
|
||||
typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
|
||||
#else
|
||||
class const_iterator;
|
||||
class iterator;
|
||||
#endif
|
||||
|
||||
// --------------
|
||||
// Element lookup
|
||||
// --------------
|
||||
|
||||
/// \brief Return a const iterator to the element \e i
|
||||
/// \param i index of the element
|
||||
BOOST_UBLAS_INLINE
|
||||
const_iterator find (size_type i) const {
|
||||
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
||||
return const_iterator (*this, data ().begin () + i);
|
||||
#else
|
||||
return const_iterator (*this, i);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// \brief Return an iterator to the element \e i
|
||||
/// \param i index of the element
|
||||
BOOST_UBLAS_INLINE
|
||||
iterator find (size_type i) {
|
||||
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
||||
return iterator (*this, data ().begin () + i);
|
||||
#else
|
||||
return iterator (*this, i);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
||||
class const_iterator:
|
||||
public container_const_reference<fixed_vector>,
|
||||
public random_access_iterator_base<dense_random_access_iterator_tag,
|
||||
const_iterator, value_type, difference_type> {
|
||||
public:
|
||||
typedef typename fixed_vector::difference_type difference_type;
|
||||
typedef typename fixed_vector::value_type value_type;
|
||||
typedef typename fixed_vector::const_reference reference;
|
||||
typedef const typename fixed_vector::pointer pointer;
|
||||
|
||||
// ----------------------------
|
||||
// Construction and destruction
|
||||
// ----------------------------
|
||||
|
||||
|
||||
BOOST_UBLAS_INLINE
|
||||
const_iterator ():
|
||||
container_const_reference<self_type> (), it_ () {}
|
||||
BOOST_UBLAS_INLINE
|
||||
const_iterator (const self_type &v, const const_subiterator_type &it):
|
||||
container_const_reference<self_type> (v), it_ (it) {}
|
||||
BOOST_UBLAS_INLINE
|
||||
const_iterator (const typename self_type::iterator &it): // ISSUE vector:: stops VC8 using std::iterator here
|
||||
container_const_reference<self_type> (it ()), it_ (it.it_) {}
|
||||
|
||||
// ----------
|
||||
// Arithmetic
|
||||
// ----------
|
||||
|
||||
/// \brief Increment by 1 the position of the iterator
|
||||
/// \return a reference to the const iterator
|
||||
BOOST_UBLAS_INLINE
|
||||
const_iterator &operator ++ () {
|
||||
++ it_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Decrement by 1 the position of the iterator
|
||||
/// \return a reference to the const iterator
|
||||
BOOST_UBLAS_INLINE
|
||||
const_iterator &operator -- () {
|
||||
-- it_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Increment by \e n the position of the iterator
|
||||
/// \return a reference to the const iterator
|
||||
BOOST_UBLAS_INLINE
|
||||
const_iterator &operator += (difference_type n) {
|
||||
it_ += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Decrement by \e n the position of the iterator
|
||||
/// \return a reference to the const iterator
|
||||
BOOST_UBLAS_INLINE
|
||||
const_iterator &operator -= (difference_type n) {
|
||||
it_ -= n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Return the different in number of positions between 2 iterators
|
||||
BOOST_UBLAS_INLINE
|
||||
difference_type operator - (const const_iterator &it) const {
|
||||
BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
||||
return it_ - it.it_;
|
||||
}
|
||||
|
||||
/// \brief Dereference an iterator
|
||||
/// Dereference an iterator: a bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
|
||||
/// \return a const reference to the value pointed by the iterator
|
||||
BOOST_UBLAS_INLINE
|
||||
const_reference operator * () const {
|
||||
BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
|
||||
return *it_;
|
||||
}
|
||||
|
||||
/// \brief Dereference an iterator at the n-th forward value
|
||||
/// Dereference an iterator at the n-th forward value, that is the value pointed by iterator+n.
|
||||
/// A bounds' check is done before returning the value. A bad_index() expection is returned if out of bounds.
|
||||
/// \return a const reference
|
||||
BOOST_UBLAS_INLINE
|
||||
const_reference operator [] (difference_type n) const {
|
||||
return *(it_ + n);
|
||||
}
|
||||
|
||||
// Index
|
||||
/// \brief return the index of the element referenced by the iterator
|
||||
BOOST_UBLAS_INLINE
|
||||
size_type index () const {
|
||||
BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, bad_index ());
|
||||
return it_ - (*this) ().begin ().it_;
|
||||
}
|
||||
|
||||
// Assignment
|
||||
BOOST_UBLAS_INLINE
|
||||
/// \brief assign the value of an iterator to the iterator
|
||||
const_iterator &operator = (const const_iterator &it) {
|
||||
container_const_reference<self_type>::assign (&it ());
|
||||
it_ = it.it_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Comparison
|
||||
/// \brief compare the value of two itetarors
|
||||
/// \return true if they reference the same element
|
||||
BOOST_UBLAS_INLINE
|
||||
bool operator == (const const_iterator &it) const {
|
||||
BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
||||
return it_ == it.it_;
|
||||
}
|
||||
|
||||
|
||||
/// \brief compare the value of two iterators
|
||||
/// \return return true if the left-hand-side iterator refers to a value placed before the right-hand-side iterator
|
||||
BOOST_UBLAS_INLINE
|
||||
bool operator < (const const_iterator &it) const {
|
||||
BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
||||
return it_ < it.it_;
|
||||
}
|
||||
|
||||
private:
|
||||
const_subiterator_type it_;
|
||||
|
||||
friend class iterator;
|
||||
};
|
||||
#endif
|
||||
|
||||
/// \brief return an iterator on the first element of the vector
|
||||
BOOST_UBLAS_INLINE
|
||||
const_iterator begin () const {
|
||||
return find (0);
|
||||
}
|
||||
|
||||
/// \brief return an iterator after the last element of the vector
|
||||
BOOST_UBLAS_INLINE
|
||||
const_iterator end () const {
|
||||
return find (data_.size ());
|
||||
}
|
||||
|
||||
#ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
|
||||
class iterator:
|
||||
public container_reference<fixed_vector>,
|
||||
public random_access_iterator_base<dense_random_access_iterator_tag,
|
||||
iterator, value_type, difference_type> {
|
||||
public:
|
||||
typedef typename fixed_vector::difference_type difference_type;
|
||||
typedef typename fixed_vector::value_type value_type;
|
||||
typedef typename fixed_vector::reference reference;
|
||||
typedef typename fixed_vector::pointer pointer;
|
||||
|
||||
|
||||
// Construction and destruction
|
||||
BOOST_UBLAS_INLINE
|
||||
iterator ():
|
||||
container_reference<self_type> (), it_ () {}
|
||||
BOOST_UBLAS_INLINE
|
||||
iterator (self_type &v, const subiterator_type &it):
|
||||
container_reference<self_type> (v), it_ (it) {}
|
||||
|
||||
// Arithmetic
|
||||
BOOST_UBLAS_INLINE
|
||||
iterator &operator ++ () {
|
||||
++ it_;
|
||||
return *this;
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
iterator &operator -- () {
|
||||
-- it_;
|
||||
return *this;
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
iterator &operator += (difference_type n) {
|
||||
it_ += n;
|
||||
return *this;
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
iterator &operator -= (difference_type n) {
|
||||
it_ -= n;
|
||||
return *this;
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
difference_type operator - (const iterator &it) const {
|
||||
BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
||||
return it_ - it.it_;
|
||||
}
|
||||
|
||||
// Dereference
|
||||
BOOST_UBLAS_INLINE
|
||||
reference operator * () const {
|
||||
BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
|
||||
return *it_;
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
reference operator [] (difference_type n) const {
|
||||
return *(it_ + n);
|
||||
}
|
||||
|
||||
// Index
|
||||
BOOST_UBLAS_INLINE
|
||||
size_type index () const {
|
||||
BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , bad_index ());
|
||||
return it_ - (*this) ().begin ().it_;
|
||||
}
|
||||
|
||||
// Assignment
|
||||
BOOST_UBLAS_INLINE
|
||||
iterator &operator = (const iterator &it) {
|
||||
container_reference<self_type>::assign (&it ());
|
||||
it_ = it.it_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Comparison
|
||||
BOOST_UBLAS_INLINE
|
||||
bool operator == (const iterator &it) const {
|
||||
BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
||||
return it_ == it.it_;
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
bool operator < (const iterator &it) const {
|
||||
BOOST_UBLAS_CHECK (&(*this) () == &it (), external_logic ());
|
||||
return it_ < it.it_;
|
||||
}
|
||||
|
||||
private:
|
||||
subiterator_type it_;
|
||||
|
||||
friend class const_iterator;
|
||||
};
|
||||
#endif
|
||||
|
||||
/// \brief Return an iterator on the first element of the vector
|
||||
BOOST_UBLAS_INLINE
|
||||
iterator begin () {
|
||||
return find (0);
|
||||
}
|
||||
|
||||
/// \brief Return an iterator at the end of the vector
|
||||
BOOST_UBLAS_INLINE
|
||||
iterator end () {
|
||||
return find (data_.size ());
|
||||
}
|
||||
|
||||
// Reverse iterator
|
||||
typedef reverse_iterator_base<const_iterator> const_reverse_iterator;
|
||||
typedef reverse_iterator_base<iterator> reverse_iterator;
|
||||
|
||||
/// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
|
||||
BOOST_UBLAS_INLINE
|
||||
const_reverse_iterator rbegin () const {
|
||||
return const_reverse_iterator (end ());
|
||||
}
|
||||
|
||||
/// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
|
||||
BOOST_UBLAS_INLINE
|
||||
const_reverse_iterator rend () const {
|
||||
return const_reverse_iterator (begin ());
|
||||
}
|
||||
|
||||
/// \brief Return a const reverse iterator before the first element of the reversed vector (i.e. end() of normal vector)
|
||||
BOOST_UBLAS_INLINE
|
||||
reverse_iterator rbegin () {
|
||||
return reverse_iterator (end ());
|
||||
}
|
||||
|
||||
/// \brief Return a const reverse iterator on the end of the reverse vector (i.e. first element of the normal vector)
|
||||
BOOST_UBLAS_INLINE
|
||||
reverse_iterator rend () {
|
||||
return reverse_iterator (begin ());
|
||||
}
|
||||
|
||||
// -------------
|
||||
// Serialization
|
||||
// -------------
|
||||
|
||||
/// Serialize a vector into and archive as defined in Boost
|
||||
/// \param ar Archive object. Can be a flat file, an XML file or any other stream
|
||||
/// \param file_version Optional file version (not yet used)
|
||||
template<class Archive>
|
||||
void serialize(Archive & ar, const unsigned int /* file_version */){
|
||||
ar & serialization::make_nvp("data",data_);
|
||||
}
|
||||
|
||||
private:
|
||||
array_type data_;
|
||||
};
|
||||
|
||||
#endif // BOOST_UBLAS_CPP11
|
||||
|
||||
// --------------------
|
||||
// Bounded vector class
|
||||
// --------------------
|
||||
@@ -867,6 +1619,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
};
|
||||
|
||||
|
||||
|
||||
// -----------------
|
||||
// Zero vector class
|
||||
// -----------------
|
||||
@@ -1597,13 +2350,13 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
c_vector (size_type size):
|
||||
size_ (size) /* , data_ () */ {
|
||||
if (size_ > N)
|
||||
bad_size ().raise ();
|
||||
bad_size ().raise ();
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
c_vector (const c_vector &v):
|
||||
size_ (v.size_) /* , data_ () */ {
|
||||
if (size_ > N)
|
||||
bad_size ().raise ();
|
||||
bad_size ().raise ();
|
||||
assign(v);
|
||||
}
|
||||
template<class AE>
|
||||
@@ -1611,7 +2364,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
c_vector (const vector_expression<AE> &ae):
|
||||
size_ (ae ().size ()) /* , data_ () */ {
|
||||
if (size_ > N)
|
||||
bad_size ().raise ();
|
||||
bad_size ().raise ();
|
||||
vector_assign<scalar_assign> (*this, ae);
|
||||
}
|
||||
|
||||
@@ -1633,7 +2386,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
BOOST_UBLAS_INLINE
|
||||
void resize (size_type size, bool preserve = true) {
|
||||
if (size > N)
|
||||
bad_size ().raise ();
|
||||
bad_size ().raise ();
|
||||
size_ = size;
|
||||
}
|
||||
|
||||
@@ -1782,7 +2535,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
BOOST_UBLAS_INLINE
|
||||
void swap (c_vector &v) {
|
||||
if (this != &v) {
|
||||
BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ());
|
||||
BOOST_UBLAS_CHECK (size_ == v.size_, bad_size ());
|
||||
std::swap (size_, v.size_);
|
||||
std::swap_ranges (data_, data_ + size_, v.data_);
|
||||
}
|
||||
|
||||
@@ -212,4 +212,9 @@ test-suite numeric/uBLAS
|
||||
:
|
||||
:
|
||||
]
|
||||
[ run test_fixed_containers.cpp
|
||||
:
|
||||
:
|
||||
: <toolset>gcc:<cxxflags>-std=c++11 <toolset>clang:<cxxflags>-std=c++11 <toolset>intel:<cxxflags>-std=c++11 <define>BOOST_UBLAS_CPP11
|
||||
]
|
||||
;
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#define _HPP_TESTHELPER_
|
||||
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <boost/numeric/ublas/vector_expression.hpp>
|
||||
#include <boost/numeric/ublas/matrix_expression.hpp>
|
||||
|
||||
static unsigned _success_counter = 0;
|
||||
static unsigned _fail_counter = 0;
|
||||
@@ -43,7 +46,7 @@ void assertEquals(const char* message, T expected, T actual) {
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
inline static
|
||||
std::pair<unsigned, unsigned> getResults() {
|
||||
return std::make_pair(_success_counter, _fail_counter);
|
||||
}
|
||||
|
||||
@@ -807,5 +807,5 @@ int main () {
|
||||
|
||||
BOOST_UBLAS_TEST_END();
|
||||
|
||||
return EXIT_SUCCESS;;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
304
test/test_fixed_containers.cpp
Normal file
304
test/test_fixed_containers.cpp
Normal file
@@ -0,0 +1,304 @@
|
||||
#undef BOOST_UBLAS_NO_EXCEPTIONS
|
||||
#include "common/testhelper.hpp"
|
||||
#include <boost/numeric/ublas/vector.hpp>
|
||||
#include <boost/numeric/ublas/matrix.hpp>
|
||||
#include <boost/numeric/ublas/assignment.hpp>
|
||||
#include <boost/numeric/ublas/io.hpp>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <complex>
|
||||
#include <iomanip>
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace boost::numeric::ublas;
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
template < class T >
|
||||
bool test_vector( std::string type_name)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << "Testing for: " << type_name;
|
||||
BOOST_UBLAS_DEBUG_TRACE( stream.str() );
|
||||
|
||||
bool pass = true;
|
||||
|
||||
{
|
||||
typedef fixed_vector<T, 1> vec1;
|
||||
|
||||
vec1 v1( 122.0 );
|
||||
|
||||
pass &= ( v1(0) == (T)122 );
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
typedef fixed_vector<T, 3> vec3;
|
||||
|
||||
vec3 v1((T)0.0, (T)0.0, (T)0.0);
|
||||
|
||||
pass &=(sizeof( vec3 ) == v1.size()*sizeof( T ) ) ;
|
||||
|
||||
vector<T> v( 3, 0 ) ;
|
||||
|
||||
pass &= compare( v1, v );
|
||||
|
||||
v1 <<= 10.0, 10, 33;
|
||||
v <<= 10.0, 10, 33;
|
||||
|
||||
//cout << std::setprecision(20) << v1 << '\n' << v;
|
||||
|
||||
pass &= compare( v1, v );
|
||||
|
||||
|
||||
vec3 v2;
|
||||
|
||||
v2( 0 ) = 10.0; v2( 1 ) = 10; v2( 2 ) = 33;
|
||||
pass &= compare( v, v2 );
|
||||
|
||||
v2 += v;
|
||||
|
||||
pass &= compare( v2, 2*v );
|
||||
|
||||
|
||||
v1 = 2*v1 + v - 6*v2;
|
||||
pass &= compare( v1, (3-2*6)*v );
|
||||
|
||||
|
||||
vec3 v3{ (T)-90.0, (T)-90.0, (T)-297.0 };
|
||||
pass &= compare( v3, v1 );
|
||||
|
||||
vec3 v4 = { (T)-90.0, (T)-90.0, (T)-297.0 };
|
||||
pass &= compare( v4, v1 );
|
||||
|
||||
vec3 v5( (T)-90.0, (T)-90.0, (T)-297.0 );
|
||||
pass &= compare( v5, v1 );
|
||||
|
||||
vec3 v6((T) 5.0, (T)8.0, (T)9.0);
|
||||
|
||||
matrix<T> M = outer_prod( v6, v6), L( 3, 3);
|
||||
|
||||
L <<= 25, 40, 45, 40, 64, 72, 45, 72, 81;
|
||||
|
||||
pass &= compare( M, L );
|
||||
|
||||
L <<= 1, 2, 3, 4, 5, 6, 7, 8, 9;
|
||||
v6 <<= 4, 5, 6;
|
||||
vec3 v7 ( (T)32.0, (T)77.0, (T)122.0 );
|
||||
|
||||
pass &= compare( v7, prod(L, v6) );
|
||||
|
||||
vec3 v8;
|
||||
noalias( v8 ) = prod(L, v6);
|
||||
|
||||
pass &= compare( v7, v8 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
const std::size_t N = 33;
|
||||
typedef fixed_vector<T, N> vec33;
|
||||
|
||||
vec33 v1;
|
||||
vector<T> v( N );
|
||||
|
||||
for ( std::size_t i = 0; i!= v1.size(); i++)
|
||||
{
|
||||
v1( i ) = 3.14159*i*i;
|
||||
v ( i ) = 3.14159*i*i;
|
||||
}
|
||||
|
||||
pass &= compare( v1, v );
|
||||
|
||||
|
||||
auto ip = inner_prod( v, v);
|
||||
auto ip1 = inner_prod( v1, v1);
|
||||
|
||||
pass &= ( ip == ip1 ) ;
|
||||
|
||||
T c = 0;
|
||||
for (auto i = v1.begin(); i != v1.end(); i++)
|
||||
{
|
||||
*i = c;
|
||||
c = c + 1;
|
||||
}
|
||||
|
||||
c = 0;
|
||||
for (auto i = v.begin(); i != v.end(); i++)
|
||||
{
|
||||
*i = c;
|
||||
c = c + 1;
|
||||
}
|
||||
|
||||
pass &= compare( v1, v );
|
||||
|
||||
// Check if bad index indeed works
|
||||
try {
|
||||
T a;
|
||||
a=v1( 100 );
|
||||
(void) a ;
|
||||
|
||||
} catch ( bad_index &e) {
|
||||
std::cout << " Caught: " << e.what() << endl;
|
||||
pass &= true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return pass;
|
||||
}
|
||||
|
||||
template < class T >
|
||||
bool test_matrix( std::string type_name)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << "Testing for: " << type_name;
|
||||
BOOST_UBLAS_DEBUG_TRACE( stream.str() );
|
||||
|
||||
bool pass = true;
|
||||
|
||||
typedef fixed_matrix<T, 3, 4> mat34;
|
||||
typedef fixed_matrix<T, 4, 3> mat43;
|
||||
typedef fixed_matrix<T, 3, 3> mat33;
|
||||
|
||||
|
||||
{
|
||||
typedef fixed_matrix<T, 1, 1> mat1;
|
||||
|
||||
mat1 m1( 122.0 );
|
||||
|
||||
pass &= ( m1(0, 0) == (T)122 );
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
mat34 m1( 3.0 );
|
||||
|
||||
pass &=(sizeof( mat34 ) == m1.size1()*m1.size2()*sizeof( T ) ) ;
|
||||
|
||||
matrix<T> m( 3.0, 4.0, 3.0 ) ;
|
||||
|
||||
pass &= compare( m1, m );
|
||||
|
||||
cout << m1 << endl;
|
||||
cout << m << endl;
|
||||
|
||||
|
||||
m1 <<= 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12;
|
||||
m <<= 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12;
|
||||
|
||||
pass &= compare( m1, m );
|
||||
|
||||
cout << m1 << endl;
|
||||
cout << m << endl;
|
||||
|
||||
mat34 m2( 0.0 );
|
||||
|
||||
T count = 1 ;
|
||||
for ( std::size_t i = 0; i != m2.size1(); i++)
|
||||
{
|
||||
for (std::size_t j = 0; j!= m2.size2(); j++)
|
||||
{
|
||||
m2( i, j ) = count;
|
||||
count = count + 1;
|
||||
}
|
||||
|
||||
}
|
||||
pass &= compare( m2, m );
|
||||
cout << m2 << endl;
|
||||
|
||||
}
|
||||
{
|
||||
mat34 m1 = { (T)1, (T)2, (T)3, (T)3, (T)3, (T)2, (T)5, (T)4, (T)2, (T)6, (T)5, (T)2 };
|
||||
mat43 m2 = { (T)4, (T)5, (T)6, (T)3, (T)2, (T)2, (T)1, (T)4, (T)2, (T)6, (T)5, (T)2 };
|
||||
|
||||
mat33 m3 = prod(m1, m2);
|
||||
|
||||
matrix<double> m(3, 3);
|
||||
m <<= 31,36,22,47,59,40,43,52,38;
|
||||
|
||||
pass &= compare(m ,m3);
|
||||
|
||||
mat33 m4;
|
||||
m4 <<= (T)1, (T)2, (T)1, (T)2, (T)1, (T)3, (T)1, (T)2, (T) 5;
|
||||
m3 = prod(m4, trans(m4));
|
||||
|
||||
m<<=6,7,10,7,14,19,10,19,30;
|
||||
|
||||
cout << m3 << endl;
|
||||
pass &= compare(m ,m3);
|
||||
|
||||
m3 = 2 * m4 - 1 * m3;
|
||||
|
||||
cout << m3;
|
||||
|
||||
m <<= -4,-3,-8,-3,-12,-13,-8,-15,-20;
|
||||
|
||||
pass &= compare(m, m3);
|
||||
|
||||
m = m3;
|
||||
|
||||
m3 = trans(m);
|
||||
|
||||
pass &= compare(m3, trans(m));
|
||||
|
||||
// Check if bad index indeed works
|
||||
try {
|
||||
T a;
|
||||
a=m1( 100, 100 );
|
||||
(void) a ;
|
||||
|
||||
} catch ( bad_index &e) {
|
||||
std::cout << " Caught: " << e.what() << endl;
|
||||
pass &= true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return pass;
|
||||
|
||||
}
|
||||
|
||||
BOOST_UBLAS_TEST_DEF (test_vector) {
|
||||
|
||||
BOOST_UBLAS_DEBUG_TRACE( "Starting fixed container tests" );
|
||||
|
||||
BOOST_UBLAS_TEST_CHECK( test_vector< double >( "double") );
|
||||
BOOST_UBLAS_TEST_CHECK( test_vector< float >( "float") );
|
||||
BOOST_UBLAS_TEST_CHECK( test_vector< int >( "int") );
|
||||
|
||||
BOOST_UBLAS_TEST_CHECK( test_vector< std::complex<double> >( "std::complex<double>") );
|
||||
BOOST_UBLAS_TEST_CHECK( test_vector< std::complex<float> >( "std::complex<float>") );
|
||||
BOOST_UBLAS_TEST_CHECK( test_vector< std::complex<int> >( "std::complex<int>") );
|
||||
|
||||
BOOST_UBLAS_TEST_CHECK( test_matrix< double >( "double") );
|
||||
BOOST_UBLAS_TEST_CHECK( test_vector< float >( "float") );
|
||||
BOOST_UBLAS_TEST_CHECK( test_vector< int >( "int") );
|
||||
|
||||
BOOST_UBLAS_TEST_CHECK( test_vector< std::complex<double> >( "std::complex<double>") );
|
||||
BOOST_UBLAS_TEST_CHECK( test_vector< std::complex<float> >( "std::complex<float>") );
|
||||
BOOST_UBLAS_TEST_CHECK( test_vector< std::complex<int> >( "std::complex<int>") );
|
||||
}
|
||||
|
||||
int main () {
|
||||
|
||||
#ifdef BOOST_UBLAS_NO_EXCEPTIONS
|
||||
std::cout << "DEFINED SDFSDF SDF SDF " << std::endl;
|
||||
#endif
|
||||
|
||||
BOOST_UBLAS_TEST_BEGIN();
|
||||
|
||||
BOOST_UBLAS_TEST_DO( test_vector );
|
||||
|
||||
BOOST_UBLAS_TEST_END();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user