578 #ifndef TOOLS_MATRIX_INCLUDED
579 #define TOOLS_MATRIX_INCLUDED
583 #pragma warning(push, 4)
588 #define ASSERT(cond) (void)(sizeof(cond?0:0))
591 #define ASSERT(cond) assert(cond)
598 template<
typename type>
988 template<
size_t complexity>
1194 template<
typename value_t,
typename expr_t,
typename tag>
1217 template<
typename tag>
1218 struct tag_complexity
1219 {
enum { value = 0 }; };
1222 struct tag_complexity<tag::expression<c> >
1223 {
enum { value = c }; };
1225 struct unconstrained_first_non_zero
1227 typedef size_t first_type;
1228 template<
typename type>
1229 static first_type first(
const type&,
size_t) {
return 0; }
1232 struct unconstrained_last_non_zero_in_row
1234 typedef size_t last_type;
1235 template<
typename type>
1236 static last_type last(
const type &m,
size_t) {
return m.cols() - 1; }
1239 struct unconstrained_last_non_zero_in_column
1241 typedef size_t last_type;
1242 template<
typename type>
1243 static last_type last(
const type &m,
size_t) {
return m.rows() - 1; }
1246 struct constrained_first_non_zero
1248 typedef constrained_index first_type;
1249 template<
typename type>
1250 static first_type first(
const type&,
size_t i) {
return i; }
1253 struct constrained_last_non_zero
1255 typedef constrained_index last_type;
1256 template<
typename type>
1257 static last_type last(
const type &,
size_t i) {
return i; }
1260 template<
typename shape>
1261 struct non_zero_in_row : unconstrained_first_non_zero, unconstrained_last_non_zero_in_row
1271 template<
typename shape>
1272 struct non_zero_in_column : unconstrained_first_non_zero, unconstrained_last_non_zero_in_column
1283 struct non_zero_in_row<lower_triangular> : unconstrained_first_non_zero, constrained_last_non_zero
1294 struct non_zero_in_column<lower_triangular> : constrained_first_non_zero, unconstrained_last_non_zero_in_column
1305 struct non_zero_in_row<upper_triangular> : constrained_first_non_zero, unconstrained_last_non_zero_in_row
1316 struct non_zero_in_column<upper_triangular> : unconstrained_first_non_zero, constrained_last_non_zero
1403 template<
typename value_t,
typename expr_t,
typename tag_t,
typename shape>
1407 tag::expression<util::tag_complexity<tag_t>::value>
1412 typename util::non_zero_in_row<shape>::first_type
1414 {
return util::non_zero_in_row<shape>::first(m, row); }
1417 typename util::non_zero_in_row<shape>::last_type
1419 {
return util::non_zero_in_row<shape>::last(m, row); }
1422 typename util::non_zero_in_column<shape>::first_type
1424 {
return util::non_zero_in_column<shape>::first(m, column); }
1427 typename util::non_zero_in_column<shape>::last_type
1429 {
return util::non_zero_in_column<shape>::last(m, column); }
1435 template<
typename expr_t>
inline
1436 util::non_zero_in_row<rectangular>::first_type
1438 {
return util::non_zero_in_row<rectangular>::first(m, row); }
1440 template<
typename expr_t>
inline
1441 util::non_zero_in_row<rectangular>::last_type
1443 {
return util::non_zero_in_row<rectangular>::last(m, row); }
1445 template<
typename expr_t>
inline
1446 util::non_zero_in_column<rectangular>::first_type
1448 {
return util::non_zero_in_column<rectangular>::first(m, column); }
1450 template<
typename expr_t>
inline
1451 util::non_zero_in_column<rectangular>::last_type
1453 {
return util::non_zero_in_column<rectangular>::last(m, column); }
1461 template<
typename expression_type>
struct expr_traits;
1465 template<
typename value_t,
typename expr_t,
typename tag_t>
1473 complexity = util::tag_complexity<tag>::value
1479 template<
typename value_t,
typename expr_t,
typename tag_t,
typename shape_t>
1487 complexity = util::tag_complexity<tag>::value
1497 template<
typename value_t,
typename expr_t,
typename tag>
inline
1499 {
return *
static_cast<expr_t*
>(&a); }
1505 template<
typename value_t,
typename expr_t,
typename tag>
inline
1507 {
return *
static_cast<const expr_t*
>(&a); }
1511 namespace orientation {
1526 template<
typename expr_t>
1534 template<
size_t>
struct interpret_orientation;
1537 template<>
struct interpret_orientation<3> {
typedef orientation::row type; };
1538 template<
typename expr_t>
1539 struct vector_orientation
1541 typedef typename interpret_orientation<sizeof(id(orientation_type((expr_t*)42)))>::type type;
1546 template<
typename value_t,
typename expr_t,
typename tag,
1547 typename orientation =
typename util::vector_orientation<expr_t>::type
1549 struct vector_expression;
1665 template<
typename value_t,
typename expr_t,
typename tag,
typename orientation>
1670 template<
typename iterator_type>
1680 iterator_type &
operator++() { ++
col;
return *
static_cast<iterator_type*
>(
this); }
1687 template<
typename t>
1700 static type begin(t &v,
size_t r,
size_t c) {
return type(v, r, c); }
1704 template<
typename t>
1717 static type begin(
const t &v,
size_t r,
size_t c) {
return type(v, r, c); }
1721 template<
typename iterator_type>
1731 iterator_type &
operator++() { ++
row;
return *
static_cast<iterator_type*
>(
this); }
1738 template<
typename t>
1751 static type begin(
const t &v,
size_t c,
size_t r) {
return type(v, c, r); }
1755 template<
typename t>
1768 static type begin(
const t &v,
size_t c,
size_t r) {
return type(v, c, r); }
1772 template<
typename iterator_type>
1787 template<
typename t>
1800 static type begin(t &v,
size_t i) {
return type(v, i); }
1804 template<
typename t>
1817 static type begin(
const t &v,
size_t i) {
return type(v, i); }
1822 template<
typename value_t,
typename expr_t,
typename tag>
inline
1827 template<
typename value_t,
typename expr_t,
typename tag>
inline
1836 template<
typename value_t,
typename expr_t,
typename tag_t>
1839 column_wrapper<value_t, expr_t, tag_t>,
1840 tag::expression<util::tag_complexity<tag_t>::value>
1855 return (*static_cast<const expr_t*>(
this))(
row);
1859 size_t rows()
const {
return static_cast<const expr_t*
>(
this)->size(); }
1880 template<
typename value_t,
typename expr_t,
typename tag>
1898 template<
typename value_t,
typename expr_t,
typename tag_t>
1901 row_wrapper<value_t, expr_t, tag_t>,
1902 tag::expression<util::tag_complexity<tag_t>::value>
1917 return (*static_cast<const expr_t*>(
this))(col);
1924 size_t cols()
const {
return static_cast<const expr_t*
>(
this)->size(); }
1940 template<
typename value_t,
typename expr_t,
typename tag>
1955 template<
typename value_t,
typename expr_t,
typename tag_t,
typename orientation_t>
1963 complexity = util::tag_complexity<tag>::value
1973 template<
typename value_t,
typename expr_t,
typename tag>
inline
1975 {
return *
static_cast<expr_t*
>(&a); }
1981 template<
typename value_t,
typename expr_t,
typename tag>
inline
1983 {
return *
static_cast<const expr_t*
>(&a); }
1988 template<
typename type,
size_t static_size>
1993 sequence_base() : _p(0) {}
1995 ~sequence_base() {
if (_p && _p!=_data)
delete[] _p; }
1997 void realloc(
size_t size)
1999 type *p = size<=static_size ? _data :
new type[size];
2000 if (_p && _p!=_data)
delete[] _p;
2001 _p = size!=0 ? p : 0;
2006 type _data[static_size];
2009 template<
typename type>
2010 class sequence_base<type, 0>
2014 sequence_base() : _p(0) {}
2016 ~sequence_base() {
if (_p)
delete[] _p; }
2018 void realloc(
size_t size)
2020 type *p = size!=0 ?
new type[size] : 0;
2021 if (_p)
delete[] _p;
2028 template<
typename type,
size_t static_size = 0>
class sequence;
2029 template<
typename type,
size_t static_size>
void swap(sequence<type, static_size>&,
size_t, sequence<type, static_size>&,
size_t);
2030 template<
typename type>
void swap(sequence<type>&, sequence<type>&);
2032 template<
typename type,
size_t static_size>
2033 class sequence :
public sequence_base<type, static_size>
2036 typedef type value_type;
2037 typedef type &reference;
2038 typedef const type &const_reference;
2043 sequence(
size_t size) { this->realloc(size); }
2045 sequence(
size_t size,
const value_type &value) { this->realloc(size, value); }
2047 value_type &operator[](
size_t i) { ASSERT(!this->is_null());
return _p[i]; }
2049 const value_type &operator[](
size_t i)
const { ASSERT(!this->is_null());
return _p[i]; }
2052 sequence ©(
const sequence<type, s> &a,
size_t size)
2054 ASSERT(!this->is_null() && !a.is_null());
2055 for (
size_t i = 0; i<size; ++i)
2060 void fill(
const value_type &value,
size_t count)
2062 ASSERT(!this->is_null());
2063 for (
size_t i = 0; i<count; ++i)
2068 using sequence_base<type, static_size>::realloc;
2070 void realloc(
size_t size,
const value_type &value)
2072 this->realloc(size);
2077 bool is_null()
const {
return _p==0; }
2083 sequence(
const sequence&);
2084 sequence &operator=(
const sequence&);
2086 friend void swap<type, static_size>(sequence<type, static_size>&, size_t, sequence<type, static_size>&, size_t);
2087 friend void swap<type>(sequence<type>&, sequence<type>&);
2091 template<
typename type,
size_t static_size>
2092 void swap(sequence<type, static_size> &a,
size_t a_size, sequence<type, static_size> &b,
size_t b_size)
2096 a_is_static = a_size<=static_size,
2097 b_is_static = b_size<=static_size;
2104 for (
size_t i = 0; i<b_size; ++i)
2105 a._data[i] = b._p[i];
2111 else if (!b_is_static)
2113 for (
size_t i = 0; i<a_size; ++i)
2114 b._data[i] = a._p[i];
2123 for (
size_t i = min; i<b_size; ++i)
2129 for (
size_t i = min; i<a_size; ++i)
2132 for (
size_t i = 0; i<min; ++i)
2133 swap(a._p[i], b._p[i]);
2137 template<
typename type>
inline
2138 void swap(sequence<type> &a, sequence<type> &b)
2231 template<
typename type>
2242 swap(*static_cast<type*>(
this), *static_cast<type*>(&a));
2248 template<
typename other>
2255 swap(*static_cast<type*>(
this), *static_cast<type*>(&a));
2262 template<
typename other>
2269 template<
typename type>
2281 template<
typename type>
2287 template<
typename expression_type,
typename tag,
typename orientation>
class vector_ref;
2297 template<
typename expression_type>
2300 vector_ref<expression_type, tag::reference, orientation::row>,
2312 vector_ref(vector_ref &a) : _ref(a._ref), _row(a._row)
2318 vector_ref(expr_t &a,
size_t row) : _ref(a), _row(row)
2322 {
return _ref(_row, i); }
2325 {
return _ref(_row, i); }
2328 {
return _ref(_row, i); }
2331 {
return _ref(_row, i); }
2334 {
return _ref.cols(); }
2344 vector_ref &operator=(
const vector_ref&);
2356 template<
size_t a,
size_t b,
size_t c = 0>
2359 template<
bool cond,
size_t true_clause,
size_t false_clause>
2360 struct _if {
enum { value = true_clause }; };
2361 template<
size_t true_clause,
size_t false_clause>
2362 struct _if<false, true_clause, false_clause> {
enum { value = false_clause }; };
2364 max_of_2 = _if<(a>b), a, b>::value,
2365 max = _if<(max_of_2>c), max_of_2, c>::value
2379 template<
typename expression_type,
size_t complexity>
2382 vector_ref<expression_type, tag::expression<complexity>, orientation::row>,
2383 tag::expression<util::select<complexity, 1>::max - 1>,
2393 vector_ref(
const vector_ref &a) : _ref(a._ref), _row(a._row)
2396 vector_ref(
const expr_t &a,
size_t row) : _ref(a), _row(row)
2400 {
return _ref(_row, i); }
2403 {
return _ref(_row, i); }
2406 {
return _ref.cols(); }
2413 vector_ref &operator=(
const vector_ref&);
2426 template<
typename expression_type,
typename tag>
inline
2427 typename util::non_zero_in_row<typename expr_traits<expression_type>::shape>::first_type
2431 template<
typename expression_type,
typename tag>
inline
2432 typename util::non_zero_in_row<typename expr_traits<expression_type>::shape>::last_type
2439 template<
typename expression_type,
typename tag>
2443 static type begin(vector_ref<expression_type, tag, orientation::row> &v,
size_t i = 0)
2448 template<
typename expression_type,
typename tag>
2452 static type begin(
const vector_ref<expression_type, tag, orientation::row> &v,
size_t i = 0)
2463 access_error() : std::logic_error(
"access violation (inaccessible element)") {}
2472 static size_t alloc_size(
size_t size) {
return (size*(size + 1))/2; }
2475 template<
typename shape>
struct details;
2478 struct details<lower_triangular> :
public details_base
2481 static size_t index(
size_t row,
size_t column,
size_t = 0)
2482 {
return details_base::alloc_size(row) +
column; }
2484 template<
typename storage>
2485 static typename storage::reference element(storage &p,
size_t row,
size_t column,
size_t)
2488 throw access_error();
2489 return p[details::index(row, column)];
2492 template<
typename storage>
2493 static typename storage::const_reference element(
const storage &p,
size_t row,
size_t column,
size_t)
2494 {
return row>=column ? p[details::index(row, column)] : traits<typename storage::value_type>::zero; }
2496 template<
typename storage,
typename value_t,
typename expr_t,
typename tag>
2497 static void copy_values(storage &p,
const shaped_expression<value_t, expr_t, tag, lower_triangular> &rhs,
size_t size)
2500 for (
size_t i = 0, k = 0; i<size; ++i)
2501 for (
size_t j = 0; j<=i; ++j, ++k)
2508 struct details<symmetric> :
public details_base
2511 static size_t index(
size_t row,
size_t column,
size_t = 0)
2513 typedef details<lower_triangular> det_lower_tr;
2514 return row>=column ? det_lower_tr::index(row, column) : det_lower_tr::index(column, row);
2517 template<
typename storage>
2518 static typename storage::reference element(storage &p,
size_t row,
size_t column,
size_t)
2519 {
return p[details::index(row, column)]; }
2521 template<
typename storage>
2522 static typename storage::const_reference element(
const storage &p,
size_t row,
size_t column,
size_t)
2523 {
return p[details::index(row, column)]; }
2525 template<
typename storage,
typename value_t,
typename expr_t,
typename tag>
2526 static void copy_values(storage &p,
const shaped_expression<value_t, expr_t, tag, symmetric> &rhs,
size_t size)
2529 for (
size_t i = 0, k = 0; i<size; ++i)
2530 for (
size_t j = 0; j<=i; ++j, ++k)
2537 struct details<upper_triangular> :
public details_base
2540 static size_t index(
size_t row,
size_t column,
size_t size)
2541 {
return (row*(2*size - row - 1))/2 +
column; }
2543 template<
typename storage>
2544 static typename storage::reference element(storage &p,
size_t row,
size_t column,
size_t size)
2547 throw access_error();
2548 return p[details::index(row, column, size)];
2551 template<
typename storage>
2552 static typename storage::const_reference element(
const storage &p,
size_t row,
size_t column,
size_t size)
2553 {
return row<=column ? p[details::index(row, column, size)] : traits<typename storage::value_type>::zero; }
2555 template<
typename storage,
typename value_t,
typename expr_t,
typename tag>
2556 static void copy_values(storage &p,
const shaped_expression<value_t, expr_t, tag, upper_triangular> &rhs,
size_t size)
2559 for (
size_t i = 0, k = 0; i<size; ++i)
2560 for (
size_t j = i; j<size; ++j, ++k)
2568 template<
typename value_t,
typename shape = rectangular>
class matrix;
2623 template<
typename value_t,
typename shape>
2629 typedef typename util::sequence<value_type>::reference
reference;
2632 typedef vector_ref<expression_type, tag::expression<0>,
orientation::row> const_row_ref;
2644 template<
typename expr_t,
typename tag>
2648 explicit matrix(
size_t size) : _p(), _size(0)
2652 { this->
resize(size, value); }
2660 _p.copy(a._p, util::details<shape>::alloc_size(_size));
2664 template<
typename expr_t,
typename tag>
2672 { this->
swap(a);
return *
this; }
2687 ASSERT(row<this->
rows() && column<this->
cols());
2688 return util::details<shape>::element(_p, row, column, _size);
2693 ASSERT(row<this->
rows() && column<this->
cols());
2694 return util::details<shape>::element(_p, row, column, _size);
2698 { ASSERT(row<this->
rows());
return row_ref(*
this, row); }
2701 { ASSERT(row<this->
rows());
return const_row_ref(*
this, row); }
2704 { ASSERT(row<this->
rows());
return row_ref(*
this, row); }
2707 { ASSERT(row<this->
rows());
return const row_ref(*
this, row); }
2710 template<
typename expr_t,
typename tag>
2714 ASSERT(a.rows()==a.cols());
2716 util::details<shape>::copy_values(_p, rhs, _size);
2726 _p.realloc(util::details<shape>::alloc_size(size));
2737 _p.fill(value, util::details<shape>::alloc_size(_size));
2746 swap(_size, a._size);
2757 util::sequence<value_type> _p;
2763 struct base_symmetric_matrix_iterator
2770 base_symmetric_matrix_iterator(
size_t r,
size_t c) : row(r), col(c) {}
2772 template<
typename ptr_t>
2773 void advance(ptr_t &ptr)
2775 ptr += size_t(row<=col)*col + 1; ++col;
2780 base_symmetric_matrix_iterator &operator=(
const base_symmetric_matrix_iterator&);
2783 template<
typename value_t,
typename iterator_type>
2784 struct symmetric_matrix_iterator :
public base_symmetric_matrix_iterator
2789 symmetric_matrix_iterator(matrix<value_t, symmetric> &m,
size_t r,
size_t c) :
2790 base_symmetric_matrix_iterator(r, c), ptr(&m(r, c))
2795 iterator_type &operator++() { this->advance(ptr);
return *
static_cast<iterator_type*
>(
this); }
2798 template<
typename value_t,
typename iterator_type>
2799 struct symmetric_matrix_const_iterator :
public base_symmetric_matrix_iterator
2804 symmetric_matrix_const_iterator(
const matrix<value_t, symmetric> &m,
size_t r,
size_t c) :
2805 base_symmetric_matrix_iterator(r, c), ptr(&m(r, c))
2810 iterator_type &operator++() { this->advance(ptr);
return *
static_cast<iterator_type*
>(
this); }
2815 template<
typename value_t>
2816 struct row_iterator<matrix<value_t, symmetric> >
2819 struct type :
public util::symmetric_matrix_iterator<value_t, type>
2827 template<
typename value_t>
2828 struct row_const_iterator<matrix<value_t, symmetric> >
2831 struct type :
public util::symmetric_matrix_const_iterator<value_t, type>
2840 template<
typename value_t>
2841 struct column_iterator<matrix<value_t, symmetric> >
2844 struct type :
public util::symmetric_matrix_iterator<value_t, type>
2852 template<
typename value_t>
2853 struct column_const_iterator<matrix<value_t, symmetric> >
2856 struct type :
public util::symmetric_matrix_const_iterator<value_t, type>
2865 template<
typename expression1,
typename expression2>
class product;
2879 template<
typename value_t>
2886 typedef typename util::sequence<value_type>::reference
reference;
2889 typedef vector_ref<expression_type, tag::expression<0>,
orientation::row> const_row_ref;
2902 template<
typename expr_t,
typename tag>
2906 matrix(
size_t nrows,
size_t ncols) : _p(), _rows(0), _cols(0)
2907 { this->
resize(nrows, ncols); }
2910 { this->
resize(nrows, ncols, value); }
2917 this->
resize(a._rows, a._cols);
2918 _p.copy(a._p, _rows*_cols);
2922 template<
typename expr_t,
typename tag>
2930 { this->
swap(a);
return *
this; }
2933 { ASSERT(row<this->
rows() && column<this->
cols());
return _p[row*_cols +
column]; }
2936 { ASSERT(row<this->
rows() && column<this->
cols());
return _p[row*_cols +
column]; }
2939 { ASSERT(row<this->
rows());
return row_ref(*
this, row); }
2942 { ASSERT(row<this->
rows());
return const_row_ref(*
this, row); }
2945 { ASSERT(row<this->
rows());
return row_ref(*
this, row); }
2948 { ASSERT(row<this->
rows());
return const_row_ref(*
this, row); }
2966 template<
typename expr_t,
typename tag>
2970 this->
resize(a.rows(), a.cols());
2971 for (
size_t i = 0, k = 0; i<_rows; ++i)
2972 for (
size_t j = 0; j<_cols; ++j, ++k)
2977 template<
typename expression1,
typename expression2,
typename tag>
2984 const size_t size = nrows*ncols;
2987 if (size!=_rows*_cols)
3000 this->
resize(nrows, ncols);
3001 _p.fill(value, _rows*_cols);
3010 swap(_rows, a._rows);
3011 swap(_cols, a._cols);
3022 util::sequence<value_type> _p;
3023 size_t _rows, _cols;
3027 template<
typename value_t>
3028 struct row_iterator<matrix<value_t> >
3045 static type begin(
matrix<value_t> &m,
size_t r,
size_t c) {
return type(m, r, c); }
3048 template<
typename value_t>
3049 struct row_const_iterator<matrix<value_t> >
3066 static type begin(
const matrix<value_t> &m,
size_t r,
size_t c) {
return type(m, r, c); }
3069 template<
typename value_t>
3070 struct column_iterator<matrix<value_t> >
3089 static type begin(
matrix<value_t> &m,
size_t c,
size_t r) {
return type(m, c, r); }
3092 template<
typename value_t>
3093 struct column_const_iterator<matrix<value_t> >
3112 static type begin(
const matrix<value_t> &m,
size_t c,
size_t r) {
return type(m, c, r); }
3127 template<
typename value_t>
3132 typedef typename util::sequence<value_type>::reference
reference;
3146 template<
typename expr_t,
typename tag>
3150 explicit vector(
size_t size) : _p(), _size(0)
3154 { this->
resize(size, value); }
3162 _p.copy(a._p, _size);
3166 template<
typename expr_t,
typename tag>
3174 { this->
swap(a);
return *
this; }
3177 { ASSERT(i<this->
size());
return _p[i]; }
3180 { ASSERT(i<this->
size());
return _p[i]; }
3183 { ASSERT(i<this->
size());
return _p[i]; }
3186 { ASSERT(i<this->
size());
return _p[i]; }
3204 template<
typename expr_t,
typename tag>
3209 for (
size_t i = 0; i<_size; ++i)
3229 _p.fill(value, _size);
3238 swap(_size, a._size);
3246 util::sequence<value_type> _p;
3262 template<
typename value_t,
typename expr_t>
inline
3277 template<
typename value_t,
typename expr_t,
typename shape>
inline
3290 reshape_error() : std::logic_error(
"matrix must be square (of size strictly n by n)") {}
3301 explicit size_error(
const std::string &msg) : std::invalid_argument(msg) {}
3323 template<
typename value_t,
typename expr_t,
typename tag,
typename shape>
3330 template<
typename value_t,
typename expr_t,
typename tag>
3336 template<
typename s
ide>
struct choose;
3342 template<
typename expr_t>
3343 static typename expr_t::reference element(expr_t &a,
size_t row,
size_t col)
3344 {
return a(row, col); }
3346 template<
typename expr_t>
3347 static typename expr_t::const_reference element(
const expr_t &a,
size_t row,
size_t col)
3348 {
return a(row, col); }
3352 struct choose<lower_triangular>
3355 template<
typename expr_t>
3356 static typename expr_t::reference element(expr_t &a,
size_t row,
size_t col)
3357 {
return a(col, row); }
3359 template<
typename expr_t>
3360 static typename expr_t::const_reference element(
const expr_t &a,
size_t row,
size_t col)
3361 {
return a(col, row); }
3364 template<
typename shape,
typename s
ide = upper_triangular>
3365 struct translate_access
3368 template<
typename expr_t>
3369 static typename expr_t::reference
get(expr_t &a,
size_t row,
size_t col)
3370 {
return choose<side>::element(a, row, col); }
3372 template<
typename expr_t>
3373 static typename expr_t::const_reference
get(
const expr_t &a,
size_t row,
size_t col)
3374 {
return choose<side>::element(a, row, col); }
3388 minmax(
size_t a,
size_t b)
3400 ASSERT(std::min(a, b)==min() && std::max(a, b)==max());
3402 size_t min()
const {
return sup; }
3403 size_t max()
const {
return inf; }
3406 template<
typename s
ide>
3407 struct translate_access<symmetric, side>
3410 template<
typename expr_t>
3411 static typename expr_t::reference
get(expr_t &a,
size_t row,
size_t col)
3417 const minmax i(row, col);
3418 return choose<side>::element(a, i.min(), i.max());
3421 template<
typename expr_t>
3422 static typename expr_t::const_reference
get(
const expr_t &a,
size_t row,
size_t col)
3428 const minmax i(row, col);
3429 return choose<side>::element(a, i.min(), i.max());
3433 template<
typename s
ide>
3434 struct translate_access<upper_triangular, side>
3438 template<
typename expr_t>
3439 static typename expr_t::reference
get(expr_t &a,
size_t row,
size_t col)
3442 return choose<side>::element(a, row, col);
3443 throw access_error();
3446 template<
typename expr_t>
3447 static typename expr_t::const_reference
get(
const expr_t &a,
size_t row,
size_t col)
3448 {
return row<=col ? choose<side>::element(a, row, col) : traits<typename expr_t::value_type>::zero; }
3451 template<
typename s
ide>
3452 struct translate_access<lower_triangular, side>
3456 template<
typename expr_t>
3457 static typename expr_t::reference
get(expr_t &a,
size_t row,
size_t col)
3460 return choose<side>::element(a, col, row);
3461 throw access_error();
3464 template<
typename expr_t>
3465 static typename expr_t::const_reference
get(
const expr_t &a,
size_t row,
size_t col)
3466 {
return row>=col ? choose<side>::element(a, col, row) : traits<typename expr_t::value_type>::zero; }
3469 template<
typename expr_t>
3475 explicit const_ref(
const expr_t &a) : ref(a)
3478 operator const expr_t&() {
return ref; }
3482 const_ref &operator=(
const const_ref&);
3485 template<
typename expr_t>
inline
3486 const_ref<expr_t> make_const_ref(
const expr_t &a)
3487 {
return const_ref<expr_t>(a); }
3496 template<
typename target_shape>
3503 template<
typename value_t,
typename expr_t,
typename tag>
3507 if (m.rows()!=m.cols())
3522 template<
typename value_t,
typename expr_t,
typename tag>
3581 template<
typename expression_type,
typename target_shape,
typename s
ide = upper_triangular>
class reshaped;
3585 template<
typename value_t,
typename expr_t,
typename tag_t,
typename target_shape>
3588 typename expr_t::value_type,
3589 reshaped<matrix_expression<value_t, expr_t, tag_t>, target_shape, upper_triangular>,
3590 tag::expression<util::tag_complexity<tag_t>::value>,
3600 reshaped(
const util::const_ref<expr_t> &a) : _ref(a.ref)
3606 {
return util::translate_access<target_shape, upper_triangular>::get(_ref, row, col); }
3609 {
return _ref.rows(); }
3612 {
return _ref.cols(); }
3624 template<
typename value_t,
typename expr_t,
typename tag_t,
typename target_shape>
3627 typename expr_t::value_type,
3628 reshaped<matrix_expression<value_t, expr_t, tag_t>, target_shape, lower_triangular>,
3629 tag::expression<util::tag_complexity<tag_t>::value>,
3639 reshaped(
const util::const_ref<expr_t> &a) : _ref(a.ref)
3645 {
return util::translate_access<target_shape, lower_triangular>::get(_ref, row, col); }
3648 {
return _ref.rows(); }
3651 {
return _ref.cols(); }
3662 template<
typename expr_t,
typename target_shape,
typename s
ide = upper_triangular>
struct reshape_return;
3664 template<
typename value_t,
typename expr_t,
typename tag,
typename target_shape,
typename s
ide>
3670 template<
typename value_t,
typename expr_t,
typename tag,
typename s
ide>
3716 template<
typename target_shape,
typename value_t,
typename expr_t,
typename tag>
inline
3717 typename util::reshape_return<matrix_expression<value_t, expr_t, tag>, target_shape>::type
3725 template<
typename target_shape,
typename s
ide,
typename value_t,
typename expr_t,
typename tag>
inline
3726 typename util::reshape_return<matrix_expression<value_t, expr_t, tag>, target_shape, side>::type
3735 template<
typename type1,
typename type2>
struct same_types;
3737 template<
typename t>
3738 struct same_types<t, t>
3747 template<
typename value_t>
inline
3748 const value_t &
conj(
const value_t &a) {
return a; }
3750 template<
typename type>
3763 template<
typename type>
3772 template<
typename type>
3781 template<
typename type>
3790 template<
typename type1,
typename type2>
3799 template<
typename type1,
typename type2>
3808 template<
typename type1,
typename type2>
3817 template<
typename type1,
typename type2>
3830 template<
typename expression_type,
template<
typename>
class op>
3833 typename expr_traits<expression_type>::type::value_type,
3834 unary<expression_type, op>,
3835 tag::expression<expr_traits<expression_type>::complexity>,
3836 typename expr_traits<expression_type>::shape
3849 {
return op<value_type>::op(_ref(row, col)); }
3852 {
return _ref.rows(); }
3855 {
return _ref.cols(); }
3874 template<
typename value_t,
typename expr_t,
typename tag>
inline
3875 const unary<matrix_expression<value_t, expr_t, tag>, op::plus>
3882 template<
typename value_t,
typename expr_t,
typename tag,
typename shape>
inline
3883 const unary<shaped_expression<value_t, expr_t, tag, shape>, op::plus>
3893 template<
typename value_t,
typename expr_t,
typename tag>
inline
3894 const unary<matrix_expression<value_t, expr_t, tag>, op::minus>
3901 template<
typename value_t,
typename expr_t,
typename tag,
typename shape>
inline
3902 const unary<shaped_expression<value_t, expr_t, tag, shape>, op::minus>
3919 template<
typename value_t,
typename expr_t,
typename tag>
inline
3920 const unary<matrix_expression<value_t, expr_t, tag>,
op::conj>
3927 template<
typename value_t,
typename expr_t,
typename tag,
typename shape>
inline
3928 const unary<shaped_expression<value_t, expr_t, tag, shape>,
op::conj>
3936 template<
typename expression_type,
template<
typename>
class op = dummy::operation>
3939 typename expr_traits<expression_type>::type::value_type,
3940 transposed<expression_type, op>,
3941 tag::expression<expr_traits<expression_type>::complexity>,
3942 typename expr_traits<expression_type>::shape
3955 {
return op<value_type>::op(_ref(col, row)); }
3958 {
return _ref.cols(); }
3961 {
return _ref.rows(); }
3980 template<
typename value_t,
typename expr_t,
typename tag>
inline
3981 const transposed<matrix_expression<value_t, expr_t, tag> >
3988 template<
typename value_t,
typename expr_t,
typename tag,
typename shape>
inline
3989 const transposed<shaped_expression<value_t, expr_t, tag, shape> >
4001 template<
typename value_t,
typename expr_t,
typename tag>
inline
4013 template<
typename value_t,
typename expr_t,
typename tag>
inline
4014 const reshaped<shaped_expression<value_t, expr_t, tag, lower_triangular>, upper_triangular, lower_triangular>
4026 template<
typename value_t,
typename expr_t,
typename tag>
inline
4027 const reshaped<shaped_expression<value_t, expr_t, tag, upper_triangular>, lower_triangular, upper_triangular>
4035 template<
typename expression_type>
4038 typename expr_traits<expression_type>::type::value_type,
4039 scaled<expression_type>,
4040 tag::expression<util::select<expr_traits<expression_type>::complexity, 2>::max>,
4041 typename expr_traits<expression_type>::shape
4057 {
return _ref(row, col)*_scale; }
4060 {
return _ref.rows(); }
4063 {
return _ref.cols(); }
4079 template<
typename value_t,
typename expr_t,
typename tag>
inline
4080 const scaled<matrix_expression<value_t, expr_t, tag> >
4087 template<
typename value_t,
typename expr_t,
typename tag,
typename shape>
inline
4088 const scaled<shaped_expression<value_t, expr_t, tag, shape> >
4096 template<
typename value_t,
typename expr_t,
typename tag>
inline
4097 const scaled<matrix_expression<value_t, expr_t, tag> >
4104 template<
typename value_t,
typename expr_t,
typename tag,
typename shape>
inline
4105 const scaled<shaped_expression<value_t, expr_t, tag, shape> >
4112 template<
typename shape1,
typename shape2>
4113 struct binary_shapes
4115 typedef rectangular resulting_shape;
4118 template<
typename shape>
4119 struct binary_shapes<shape, shape>
4121 typedef shape resulting_shape;
4124 template<
typename expr1,
typename expr2>
4139 template<
typename expr1,
typename expr2>
4140 pair_const_ref<expr1, expr2> make_pair_const_ref(
const expr1 &a,
const expr2 &b)
4141 {
return pair_const_ref<expr1, expr2>(a, b); }
4147 template<
typename expression1,
typename expression2,
template<
typename,
typename>
class op>
4150 typename util::same_types<typename expr_traits<expression1>::value_type,
4151 typename expr_traits<expression2>::value_type>::type,
4152 binary<expression1, expression2, op>,
4153 tag::expression<util::select<expr_traits<expression1>::complexity,
4154 expr_traits<expression2>::complexity,
4156 typename util::binary_shapes<typename expr_traits<expression1>::shape,
4157 typename expr_traits<expression2>::shape>::resulting_shape
4163 typedef typename op<typename expr1::value_type, typename expr2::value_type>::result_type
value_type;
4168 _left(p.first), _right(p.second)
4170 if (_left.rows()!=_right.rows() || _left.cols()!=_right.cols())
4171 throw size_error(
"sizes of matrices must be equal");
4175 {
return op<typename expr1::value_type, typename expr2::value_type>::op(_left(row, col), _right(row, col)); }
4179 ASSERT(_left.rows()==_right.rows());
4180 return _left.rows();
4185 ASSERT(_left.cols()==_right.cols());
4186 return _left.cols();
4191 const expr2 &_right;
4207 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
4208 const binary<matrix_expression<value_t, expr1, tag1>, matrix_expression<value_t, expr2, tag2>, op::add>
4220 template<
typename value_t,
typename expr1,
typename tag1,
typename shape1,
typename expr2,
typename tag2,
typename shape2>
inline
4221 const binary<shaped_expression<value_t, expr1, tag1, shape1>, shaped_expression<value_t, expr2, tag2, shape1>, op::add>
4233 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
4234 const binary<matrix_expression<value_t, expr1, tag1>, matrix_expression<value_t, expr2, tag2>, op::sub>
4246 template<
typename value_t,
typename expr1,
typename tag1,
typename shape1,
typename expr2,
typename tag2,
typename shape2>
inline
4247 const binary<shaped_expression<value_t, expr1, tag1, shape1>, shaped_expression<value_t, expr2, tag2, shape2>, op::sub>
4263 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
4264 const binary<matrix_expression<value_t, expr1, tag1>, matrix_expression<value_t, expr2, tag2>,
op::mul>
4276 template<
typename value_t,
typename expr1,
typename tag1,
typename shape1,
typename expr2,
typename tag2,
typename shape2>
inline
4277 const binary<shaped_expression<value_t, expr1, tag1, shape1>, shaped_expression<value_t, expr2, tag2, shape2>,
op::mul>
4293 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
4294 const binary<matrix_expression<value_t, expr1, tag1>, matrix_expression<value_t, expr2, tag2>,
op::div>
4306 template<
typename value_t,
typename expr1,
typename tag1,
typename shape1,
typename expr2,
typename tag2,
typename shape2>
inline
4307 const binary<shaped_expression<value_t, expr1, tag1, shape1>, shaped_expression<value_t, expr2, tag2, shape2>,
op::div>
4322 template<
typename expression_type>
4325 vector_ref<expression_type, tag::reference, orientation::column>,
4337 vector_ref(vector_ref &a) : _ref(a._ref), _col(a._col)
4343 vector_ref(expr_t &a,
size_t column) : _ref(a), _col(column)
4347 {
return _ref(i, _col); }
4350 {
return _ref(i, _col); }
4353 {
return _ref(i, _col); }
4356 {
return _ref(i, _col); }
4359 {
return _ref.rows(); }
4369 vector_ref &operator=(
const vector_ref&);
4380 template<
typename expression_type,
size_t complexity>
4390 vector_ref<expression_type, tag::expression<complexity>, orientation::column>,
4391 tag::expression<util::select<complexity, 1>::max - 1>,
4401 vector_ref(
const vector_ref &a) : _ref(a._ref), _col(a._col)
4404 vector_ref(
const expr_t &a,
size_t col) : _ref(a), _col(col)
4408 {
return _ref(i, _col); }
4411 {
return _ref(i, _col); }
4414 {
return _ref.rows(); }
4421 vector_ref &operator=(
const vector_ref&);
4434 template<
typename expression_type,
typename tag>
inline
4435 typename util::non_zero_in_column<typename expr_traits<expression_type>::shape>::first_type
4439 template<
typename expression_type,
typename tag>
inline
4440 typename util::non_zero_in_column<typename expr_traits<expression_type>::shape>::last_type
4447 template<
typename expression_type,
typename tag>
4448 struct iterator<vector_ref<expression_type, tag, orientation::column> >
4451 static type begin(vector_ref<expression_type, tag, orientation::column> &v,
size_t i = 0)
4456 template<
typename expression_type,
typename tag>
4460 static type begin(
const vector_ref<expression_type, tag, orientation::column> &v,
size_t i = 0)
4466 template<
typename expression_type>
4469 template<
typename expression_type>
4470 struct const_row_ref {
typedef const vector_ref<expression_type, tag::expression<expr_traits<expression_type>::complexity>,
orientation::row> type; };
4472 template<
typename expression_type>
4473 struct column_ref {
typedef vector_ref<expression_type, tag::reference, orientation::column> type; };
4475 template<
typename expression_type>
4476 struct const_column_ref {
typedef const vector_ref<expression_type, tag::expression<expr_traits<expression_type>::complexity>,
orientation::column> type; };
4483 template<
typename value_t,
typename expr_t,
typename tag>
inline
4484 typename util::row_ref<matrix_expression<value_t, expr_t, tag> >::type
4488 return util::row_ref<matrix_expression<value_t, expr_t, tag> >::type(
get_matrix(a), r);
4493 template<
typename value_t,
typename expr_t,
typename tag_t>
inline
4494 typename util::const_row_ref<matrix_expression<value_t, expr_t, tag_t> >::type
4498 return util::const_row_ref<matrix_expression<value_t, expr_t, tag_t> >::type(
get_matrix(a), r);
4503 template<
typename value_t,
typename expr_t,
typename tag,
typename shape>
inline
4504 typename util::row_ref<shaped_expression<value_t, expr_t, tag, shape> >::type
4508 return util::row_ref<shaped_expression<value_t, expr_t, tag, shape> >::type(
get_matrix(a), r);
4513 template<
typename value_t,
typename expr_t,
typename tag_t,
typename shape>
inline
4514 typename util::const_row_ref<shaped_expression<value_t, expr_t, tag_t, shape> >::type
4518 return util::const_row_ref<shaped_expression<value_t, expr_t, tag_t, shape> >::type(
get_matrix(a), r);
4523 template<
typename value_t,
typename expr_t,
typename tag>
inline
4524 typename util::column_ref<matrix_expression<value_t, expr_t, tag> >::type
4528 return util::column_ref<matrix_expression<value_t, expr_t, tag> >::type(
get_matrix(a), c);
4533 template<
typename value_t,
typename expr_t,
typename tag_t>
inline
4534 typename util::const_column_ref<matrix_expression<value_t, expr_t, tag_t> >::type
4538 return util::const_column_ref<matrix_expression<value_t, expr_t, tag_t> >::type(
get_matrix(a), c);
4543 template<
typename value_t,
typename expr_t,
typename tag,
typename shape>
inline
4544 typename util::column_ref<shaped_expression<value_t, expr_t, tag, shape> >::type
4548 return util::column_ref<shaped_expression<value_t, expr_t, tag, shape> >::type(
get_matrix(a), c);
4553 template<
typename value_t,
typename expr_t,
typename tag_t,
typename shape>
inline
4554 typename util::const_column_ref<shaped_expression<value_t, expr_t, tag_t, shape> >::type
4558 return util::const_column_ref<shaped_expression<value_t, expr_t, tag_t, shape> >::type(
get_matrix(a), c);
4565 template<
typename expr_t>
inline
4569 template<
typename expr_t>
inline
4571 {
return v.size() - 1; }
4575 struct min {
static size_t op(
size_t a,
size_t b) {
return std::min(a, b); } };
4576 struct max {
static size_t op(
size_t a,
size_t b) {
return std::max(a, b); } };
4577 template<
typename op>
inline
4578 size_t combine_indices(
size_t a,
size_t b)
4579 { ASSERT(a==b);
return a; }
4580 template<
typename op>
inline
4581 size_t combine_indices(constrained_index a,
size_t b)
4582 { ASSERT(op::op(a, b)==a);
return a; }
4583 template<
typename op>
inline
4584 size_t combine_indices(
size_t a, constrained_index b)
4585 { ASSERT(op::op(a, b)==b);
return b; }
4586 template<
typename op>
inline
4587 size_t combine_indices(constrained_index a, constrained_index b)
4588 {
return op::op(a, b); }
4594 template<
typename expr1,
typename expr2>
4598 template<
typename expr1,
typename expr2>
4616 template<
template<
typename,
typename>
class op,
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
4617 typename op<value_t, value_t>::result_type
4620 typedef typename op<value_t, value_t>::result_type result_type;
4623 ASSERT(v1.size()==v2.size());
4625 const size_t size = v1.size();
4631 for (
size_t i = 0; i<size; ++i, ++i1, ++i2)
4632 sum = sum + op<value_t, value_t>::op(*i1, *i2);
4636 template<
template<
typename,
typename>
class op_t,
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
4637 typename op_t<value_t, value_t>::result_type
4640 typedef op_t<value_t, value_t> op;
4641 typedef typename op::result_type result_type;
4644 ASSERT(v1.size()==v2.size());
4648 ASSERT(last<v1.size());
4654 for (; i<=last; ++i, ++i1, ++i2)
4655 sum = sum + op::op(*i1, *i2);
4678 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
4679 typename op::mul<value_t, value_t>::result_type
4682 {
return accumulate_skip_zeros<op::mul>(a, b); }
4687 template<
typename shape1,
typename shape2>
4688 struct product_shapes
4690 typedef rectangular resulting_shape;
4694 struct product_shapes<lower_triangular, lower_triangular>
4696 typedef lower_triangular resulting_shape;
4700 struct product_shapes<upper_triangular, upper_triangular>
4702 typedef upper_triangular resulting_shape;
4705 template<typename expression_type, size_t complexity = expr_traits<expression_type>::complexity>
4706 struct const_complexity
4708 typedef const matrix<typename expr_traits<expression_type>::value_type,
4709 typename expr_traits<expression_type>::shape> type;
4710 typedef type &const_reference;
4713 template<
typename expression_type>
4714 struct const_complexity<expression_type, 0>
4716 typedef const typename expr_traits<expression_type>::type &type;
4717 typedef type const_reference;
4724 template<
typename expression1,
typename expression2>
4727 typename util::same_types<typename expr_traits<expression1>::value_type,
4728 typename expr_traits<expression2>::value_type>::type,
4729 product<expression1, expression2>,
4731 typename util::product_shapes<typename expr_traits<expression1>::shape,
4732 typename expr_traits<expression2>::shape>::resulting_shape
4737 typedef typename util::same_types<typename expr1::value_type, typename expr2::value_type>::type deduced_value_type;
4744 _left(p.first), _right(p.second)
4746 if (_left.cols()!=_right.rows())
4747 throw size_error(
"number of columns of the first matrix and number of rows of the second matrix must be equal");
4755 {
return _left.rows(); }
4758 {
return _right.cols(); }
4769 friend typename util::const_complexity<expression2>::const_reference right(
const product &p) {
return p._right; }
4772 template<
typename value_t>
4773 template<
typename expression1,
typename expression2,
typename tag>
4774 void matrix<value_t>::assign(
const matrix_expression<value_type, product<expression1, expression2>, tag> &rhs)
4776 const product<expression1, expression2> &p =
get_matrix(rhs);
4780 if (rows*cols<64*64 &&
false)
4782 this->resize(rows, cols);
4783 for (
size_t i = 0, k = 0; i<_rows; ++i)
4784 for (
size_t j = 0; j<_cols; ++j, ++k)
4788 typename util::const_complexity<expression1>::const_reference a = left(p);
4789 typename util::const_complexity<expression2>::const_reference b = right(p);
4790 typedef typename expr_traits<expression1>::type left_t;
4791 typedef typename expr_traits<expression2>::type right_t;
4792 this->resize(a.rows(), b.cols(), traits<value_type>::zero);
4793 const size_t n = a.cols();
4794 ASSERT(n==b.rows());
4795 for (
size_t i = 0; i<_rows; ++i)
4801 typename row_const_iterator<left_t>::type i1(a, i, k0);
4802 value_type *
const p_i = &_p[i*_cols];
4803 for (
size_t k = k0; k<=k1; ++k, ++i1)
4805 value_type *p = p_i;
4807 const value_type a1 = *i1;
4812 typename row_const_iterator<right_t>::type i2(b, k, first);
4814 for (
size_t j = first; j<=last; ++j, ++p, ++i2)
4831 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
4832 product<matrix_expression<value_t, expr1, tag1>, matrix_expression<value_t, expr2, tag2> >
4848 template<
typename value_t,
typename expr1,
typename tag1,
typename shape1,
typename expr2,
typename tag2,
typename shape2>
inline
4849 product<shaped_expression<value_t, expr1, tag1, shape1>, shaped_expression<value_t, expr2, tag2, shape2> >
4858 template<
typename value_t,
typename expr_t,
typename tag_t,
size_t complexity>
4859 struct const_complexity<vector_expression<value_t, expr_t, tag_t>, complexity>
4861 typedef const vector<value_t> type;
4864 template<
typename value_t,
typename expr_t,
typename tag_t>
4865 struct const_complexity<vector_expression<value_t, expr_t, tag_t>, 0>
4867 typedef const expr_t &type;
4874 template<
typename expression1,
typename value_t,
typename expr2,
typename tag2>
4877 typename util::same_types<typename expr_traits<expression1>::value_type, value_t>::type,
4878 product<expression1, vector_expression<value_t, expr2, tag2> >,
4880 typename util::vector_orientation<expr2>::type
4884 typedef typename util::same_types<typename expr1::value_type, typename expr2::value_type>::type deduced_value_type;
4891 _left(p.first), _right(p.second)
4893 if (_left.cols()!=_right.size())
4894 throw size_error(
"number of columns of matrix and size of vector must be equal");
4902 {
return _left.rows(); }
4905 typename util::const_complexity<vector_expression<value_t, expr2, tag2> >::type _right;
4923 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
4924 product<matrix_expression<value_t, expr1, tag1>, vector_expression<value_t, expr2, tag2> >
4936 template<
typename value_t,
typename expr1,
typename tag1,
typename shape,
typename expr2,
typename tag2>
inline
4937 product<shaped_expression<value_t, expr1, tag1, shape>, vector_expression<value_t, expr2, tag2> >
4963 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
4964 product<matrix_expression<value_t, expr1, tag1>, vector_expression<value_t, expr2, tag2> >
4976 template<
typename value_t,
typename expr1,
typename tag1,
typename shape,
typename expr2,
typename tag2>
inline
4977 product<shaped_expression<value_t, expr1, tag1, shape>, vector_expression<value_t, expr2, tag2> >
4988 template<
typename value_t,
typename expr1,
typename expr2,
typename tag2>
inline
4994 expr1(a + right).swap(a);
5003 template<
typename value_t,
typename expr1,
typename shape,
typename expr2,
typename tag2>
inline
5009 expr1(a + right).swap(a);
5018 template<
typename value_t,
typename expr1,
typename expr2,
typename tag2>
inline
5024 expr1(a - right).swap(a);
5033 template<
typename value_t,
typename expr1,
typename shape,
typename expr2,
typename tag2>
inline
5039 expr1(a - right).swap(a);
5047 template<
typename value_t,
typename expr_t>
inline
5049 const value_t &right
5056 for (
size_t i = 0; i<rows; ++i)
5057 for (
size_t j = 0; j<cols; ++j)
5065 template<
typename value_t,
typename expr_t,
typename shape>
inline
5067 const value_t &right
5071 expr_t(a*right).swap(a);
5081 template<
typename value_t,
typename expr1,
typename expr2,
typename tag2>
inline
5087 expr1(a*right).swap(a);
5096 template<
typename value_t,
typename expr1,
typename expr2,
typename tag2>
inline
5102 expr1(a*right).swap(a);
5111 template<
typename value_t,
typename expr1,
typename expr2,
typename tag2>
inline
5117 expr1(a*right).swap(a);
5134 template<
typename value_t,
typename expr_t>
inline
5157 template<
typename value_t,
typename expr1,
typename expr2>
inline
5172 template<
typename expr1,
typename expr2>
inline
5173 void swap_vectors(expr1& a, expr2 &b)
5176 const size_t count = std::min(a.size(), b.size());
5177 for (
size_t i = 0; i<count; ++i)
5204 template<
typename value_t,
typename expr1,
typename expr2,
typename orientation>
inline
5206 vector_ref<expr2, tag::reference, orientation> b)
5208 typedef typename util::same_types<value_t, expr_traits<expr2>::value_type>::type value_type;
5215 template<
typename expr1,
typename orientation,
typename value_t,
typename expr2>
inline
5216 void swap(vector_ref<expr1, tag::reference, orientation> a,
5219 typedef typename util::same_types<value_t, expr_traits<expr1>::value_type>::type value_type;
5226 template<
typename expr1,
typename orientation1,
typename expr2,
typename orientation2>
inline
5227 void swap(vector_ref<expr1, tag::reference, orientation1> a,
5228 vector_ref<expr2, tag::reference, orientation2> b)
5231 util::swap_vectors(a, b);
5238 template<
typename type1,
typename type2>
5242 typedef typename util::same_types<type1, type2>::type result_type;
5244 static result_type op(
const type1 &a,
const type2 &b) {
using dummy::conj;
return a*
conj(b); }
5270 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
5271 typename util::mul_conj<value_t, value_t>::result_type
5274 {
return accumulate_skip_zeros<util::mul_conj>(v1, v2); }
5288 template<
template<
typename>
class op,
typename value_t,
typename expr_t,
typename tag>
inline
5289 typename op<value_t>::result_type
5292 typedef typename op<value_t>::result_type result_type;
5295 const size_t size = v.size();
5296 for (
size_t i = 0; i<size; ++i)
5297 sum = sum + op<value_t>::op(v(i));
5300 template<
template<
typename>
class op_t,
typename value_t,
typename expr_t,
typename tag>
inline
5301 typename op_t<value_t>::result_type
5312 typedef op_t<value_t> op;
5313 typedef typename op::result_type result_type;
5318 ASSERT(last<v.size());
5321 for (; i<=last; ++i, ++it)
5322 sum = sum + op::op(*it);
5331 template<
typename type>
5335 typedef type result_type;
5337 static result_type op(
const type &a) {
using dummy::conj;
return a*
conj(a); }
5363 template<
typename value_t,
typename expr_t,
typename tag>
5365 {
return accumulate_skip_zeros<util::sqr>(v); }
5388 template<
typename value_t,
typename expr_t,
typename tag>
5396 template<
typename value_t,
typename expr_t,
typename tag_t,
template<
typename>
class op>
5399 unary<vector_expression<value_t, expr_t, tag_t>, op>,
5400 tag::expression< util::select<util::tag_complexity<tag_t>::value, 0>::max>,
5401 typename util::vector_orientation<expr_t>::type
5413 {
return op<value_type>::op(_ref(i)); }
5416 {
return _ref.size(); }
5435 template<
typename value_t,
typename expr_t,
typename tag>
inline
5436 const unary<vector_expression<value_t, expr_t, tag>, op::plus>
5446 template<
typename value_t,
typename expr_t,
typename tag>
inline
5447 const unary<vector_expression<value_t, expr_t, tag>, op::minus>
5464 template<
typename value_t,
typename expr_t,
typename tag>
inline
5465 const unary<vector_expression<value_t, expr_t, tag>,
op::conj>
5473 template<
typename value_t,
typename expr_t,
typename tag_t>
5476 scaled<vector_expression<value_t, expr_t, tag_t> >,
5477 tag::expression<util::select<util::tag_complexity<tag_t>::value, 2>::max>,
5478 typename util::vector_orientation<expr_t>::type
5493 {
return _ref(i)*_scale; }
5496 {
return _ref.size(); }
5500 const value_type _scale;
5512 template<
typename value_t,
typename expr_t,
typename tag>
inline
5513 const scaled<vector_expression<value_t, expr_t, tag> >
5521 template<
typename value_t,
typename expr_t,
typename tag>
inline
5522 const scaled<vector_expression<value_t, expr_t, tag> >
5529 template<
typename orienation1,
typename orienation2>
5532 typedef orientation::undefined resulting_orientation;
5534 template<
typename orienation_t>
5535 struct orientations<orienation_t, orienation_t>
5537 typedef orienation_t resulting_orientation;
5539 template<
typename orienation_t>
5540 struct orientations<orientation::undefined, orienation_t>
5542 typedef orienation_t resulting_orientation;
5544 template<
typename orienation_t>
5545 struct orientations<orienation_t, orientation::undefined>
5547 typedef orienation_t resulting_orientation;
5554 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2,
template<
typename,
typename>
class op>
5558 binary<vector_expression<value_t, expr1, tag1>, vector_expression<value_t, expr2, tag2>, op>,
5559 tag::expression<util::select<util::tag_complexity<tag1>::value,
5560 util::tag_complexity<tag2>::value,
5562 typename util::orientations<typename util::vector_orientation<expr1>::type,
5563 typename util::vector_orientation<expr2>::type>::resulting_orientation
5567 typedef typename op<typename expr1::value_type, typename expr2::value_type>::result_type
value_type;
5572 _left(p.first), _right(p.second)
5574 if (_left.size()!=_right.size())
5575 throw size_error(
"sizes of vectors must be equal");
5579 {
return op<typename expr1::value_type, typename expr2::value_type>::op(_left(i), _right(i)); }
5583 ASSERT(_left.size()==_right.size());
5584 return _left.size();
5589 const expr2 &_right;
5605 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
5606 const binary<vector_expression<value_t, expr1, tag1>, vector_expression<value_t, expr2, tag2>, op::add>
5618 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
5619 const binary<vector_expression<value_t, expr1, tag1>, vector_expression<value_t, expr2, tag2>, op::sub>
5631 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
5632 const binary<vector_expression<value_t, expr1, tag1>, vector_expression<value_t, expr2, tag2>,
op::mul>
5644 template<
typename value_t,
typename expr1,
typename tag1,
typename expr2,
typename tag2>
inline
5645 const binary<vector_expression<value_t, expr1, tag1>, vector_expression<value_t, expr2, tag2>,
op::div>
5656 template<
typename value_t,
typename expr1,
typename expr2,
typename tag2>
inline
5677 template<
typename value_t,
typename expr1,
typename expr2,
typename tag2>
inline
5684 const size_t size = a.size();
5685 ASSERT(size==b.size());
5686 for (
size_t i = 0; i<size; ++i)
5696 template<
typename value_t,
typename expr1,
typename expr2,
typename tag2>
inline
5717 template<
typename value_t,
typename expr1,
typename expr2,
typename tag2>
inline
5724 const size_t size = a.size();
5725 ASSERT(size==b.size());
5726 for (
size_t i = 0; i<size; ++i)
5734 template<
typename type>
inline
5735 type &scale_vector(type &a,
typename const type::value_type &b)
5737 const size_t size = a.size();
5738 for (
size_t i = 0; i<size; ++i)
5750 template<
typename value_t,
typename expr_t>
inline
5752 const value_t &right
5754 {
return util::scale_vector(
get_vector(left), right); }
5763 template<
typename value_t,
typename expr_t>
inline
5765 const value_t &right
5767 {
return util::scale_vector(
get_vector(left), right); }
5771 #pragma warning(pop)
5772 #endif//TOOLS_MATRIX_INCLUDED