annotate DEPENDENCIES/generic/include/boost/numeric/ublas/functional.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 //
Chris@16 2 // Copyright (c) 2000-2009
Chris@16 3 // Joerg Walter, Mathias Koch, Gunter Winkler
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 //
Chris@16 9 // The authors gratefully acknowledge the support of
Chris@16 10 // GeNeSys mbH & Co. KG in producing this work.
Chris@16 11 //
Chris@16 12
Chris@16 13 #ifndef _BOOST_UBLAS_FUNCTIONAL_
Chris@16 14 #define _BOOST_UBLAS_FUNCTIONAL_
Chris@16 15
Chris@16 16 #include <functional>
Chris@16 17
Chris@101 18 #include <boost/core/ignore_unused.hpp>
Chris@101 19
Chris@16 20 #include <boost/numeric/ublas/traits.hpp>
Chris@16 21 #ifdef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 22 #include <boost/numeric/ublas/detail/duff.hpp>
Chris@16 23 #endif
Chris@16 24 #ifdef BOOST_UBLAS_USE_SIMD
Chris@16 25 #include <boost/numeric/ublas/detail/raw.hpp>
Chris@16 26 #else
Chris@16 27 namespace boost { namespace numeric { namespace ublas { namespace raw {
Chris@16 28 }}}}
Chris@16 29 #endif
Chris@16 30 #ifdef BOOST_UBLAS_HAVE_BINDINGS
Chris@16 31 #include <boost/numeric/bindings/traits/std_vector.hpp>
Chris@16 32 #include <boost/numeric/bindings/traits/ublas_vector.hpp>
Chris@16 33 #include <boost/numeric/bindings/traits/ublas_matrix.hpp>
Chris@16 34 #include <boost/numeric/bindings/atlas/cblas.hpp>
Chris@16 35 #endif
Chris@16 36
Chris@16 37 #include <boost/numeric/ublas/detail/definitions.hpp>
Chris@16 38
Chris@16 39
Chris@16 40
Chris@16 41 namespace boost { namespace numeric { namespace ublas {
Chris@16 42
Chris@16 43 // Scalar functors
Chris@16 44
Chris@16 45 // Unary
Chris@16 46 template<class T>
Chris@16 47 struct scalar_unary_functor {
Chris@16 48 typedef T value_type;
Chris@16 49 typedef typename type_traits<T>::const_reference argument_type;
Chris@16 50 typedef typename type_traits<T>::value_type result_type;
Chris@16 51 };
Chris@16 52
Chris@16 53 template<class T>
Chris@16 54 struct scalar_identity:
Chris@16 55 public scalar_unary_functor<T> {
Chris@16 56 typedef typename scalar_unary_functor<T>::argument_type argument_type;
Chris@16 57 typedef typename scalar_unary_functor<T>::result_type result_type;
Chris@16 58
Chris@16 59 static BOOST_UBLAS_INLINE
Chris@16 60 result_type apply (argument_type t) {
Chris@16 61 return t;
Chris@16 62 }
Chris@16 63 };
Chris@16 64 template<class T>
Chris@16 65 struct scalar_negate:
Chris@16 66 public scalar_unary_functor<T> {
Chris@16 67 typedef typename scalar_unary_functor<T>::argument_type argument_type;
Chris@16 68 typedef typename scalar_unary_functor<T>::result_type result_type;
Chris@16 69
Chris@16 70 static BOOST_UBLAS_INLINE
Chris@16 71 result_type apply (argument_type t) {
Chris@16 72 return - t;
Chris@16 73 }
Chris@16 74 };
Chris@16 75 template<class T>
Chris@16 76 struct scalar_conj:
Chris@16 77 public scalar_unary_functor<T> {
Chris@16 78 typedef typename scalar_unary_functor<T>::value_type value_type;
Chris@16 79 typedef typename scalar_unary_functor<T>::argument_type argument_type;
Chris@16 80 typedef typename scalar_unary_functor<T>::result_type result_type;
Chris@16 81
Chris@16 82 static BOOST_UBLAS_INLINE
Chris@16 83 result_type apply (argument_type t) {
Chris@16 84 return type_traits<value_type>::conj (t);
Chris@16 85 }
Chris@16 86 };
Chris@16 87
Chris@16 88 // Unary returning real
Chris@16 89 template<class T>
Chris@16 90 struct scalar_real_unary_functor {
Chris@16 91 typedef T value_type;
Chris@16 92 typedef typename type_traits<T>::const_reference argument_type;
Chris@16 93 typedef typename type_traits<T>::real_type result_type;
Chris@16 94 };
Chris@16 95
Chris@16 96 template<class T>
Chris@16 97 struct scalar_real:
Chris@16 98 public scalar_real_unary_functor<T> {
Chris@16 99 typedef typename scalar_real_unary_functor<T>::value_type value_type;
Chris@16 100 typedef typename scalar_real_unary_functor<T>::argument_type argument_type;
Chris@16 101 typedef typename scalar_real_unary_functor<T>::result_type result_type;
Chris@16 102
Chris@16 103 static BOOST_UBLAS_INLINE
Chris@16 104 result_type apply (argument_type t) {
Chris@16 105 return type_traits<value_type>::real (t);
Chris@16 106 }
Chris@16 107 };
Chris@16 108 template<class T>
Chris@16 109 struct scalar_imag:
Chris@16 110 public scalar_real_unary_functor<T> {
Chris@16 111 typedef typename scalar_real_unary_functor<T>::value_type value_type;
Chris@16 112 typedef typename scalar_real_unary_functor<T>::argument_type argument_type;
Chris@16 113 typedef typename scalar_real_unary_functor<T>::result_type result_type;
Chris@16 114
Chris@16 115 static BOOST_UBLAS_INLINE
Chris@16 116 result_type apply (argument_type t) {
Chris@16 117 return type_traits<value_type>::imag (t);
Chris@16 118 }
Chris@16 119 };
Chris@16 120
Chris@16 121 // Binary
Chris@16 122 template<class T1, class T2>
Chris@16 123 struct scalar_binary_functor {
Chris@16 124 typedef typename type_traits<T1>::const_reference argument1_type;
Chris@16 125 typedef typename type_traits<T2>::const_reference argument2_type;
Chris@16 126 typedef typename promote_traits<T1, T2>::promote_type result_type;
Chris@16 127 };
Chris@16 128
Chris@16 129 template<class T1, class T2>
Chris@16 130 struct scalar_plus:
Chris@16 131 public scalar_binary_functor<T1, T2> {
Chris@16 132 typedef typename scalar_binary_functor<T1, T2>::argument1_type argument1_type;
Chris@16 133 typedef typename scalar_binary_functor<T1, T2>::argument2_type argument2_type;
Chris@16 134 typedef typename scalar_binary_functor<T1, T2>::result_type result_type;
Chris@16 135
Chris@16 136 static BOOST_UBLAS_INLINE
Chris@16 137 result_type apply (argument1_type t1, argument2_type t2) {
Chris@16 138 return t1 + t2;
Chris@16 139 }
Chris@16 140 };
Chris@16 141 template<class T1, class T2>
Chris@16 142 struct scalar_minus:
Chris@16 143 public scalar_binary_functor<T1, T2> {
Chris@16 144 typedef typename scalar_binary_functor<T1, T2>::argument1_type argument1_type;
Chris@16 145 typedef typename scalar_binary_functor<T1, T2>::argument2_type argument2_type;
Chris@16 146 typedef typename scalar_binary_functor<T1, T2>::result_type result_type;
Chris@16 147
Chris@16 148 static BOOST_UBLAS_INLINE
Chris@16 149 result_type apply (argument1_type t1, argument2_type t2) {
Chris@16 150 return t1 - t2;
Chris@16 151 }
Chris@16 152 };
Chris@16 153 template<class T1, class T2>
Chris@16 154 struct scalar_multiplies:
Chris@16 155 public scalar_binary_functor<T1, T2> {
Chris@16 156 typedef typename scalar_binary_functor<T1, T2>::argument1_type argument1_type;
Chris@16 157 typedef typename scalar_binary_functor<T1, T2>::argument2_type argument2_type;
Chris@16 158 typedef typename scalar_binary_functor<T1, T2>::result_type result_type;
Chris@16 159
Chris@16 160 static BOOST_UBLAS_INLINE
Chris@16 161 result_type apply (argument1_type t1, argument2_type t2) {
Chris@16 162 return t1 * t2;
Chris@16 163 }
Chris@16 164 };
Chris@16 165 template<class T1, class T2>
Chris@16 166 struct scalar_divides:
Chris@16 167 public scalar_binary_functor<T1, T2> {
Chris@16 168 typedef typename scalar_binary_functor<T1, T2>::argument1_type argument1_type;
Chris@16 169 typedef typename scalar_binary_functor<T1, T2>::argument2_type argument2_type;
Chris@16 170 typedef typename scalar_binary_functor<T1, T2>::result_type result_type;
Chris@16 171
Chris@16 172 static BOOST_UBLAS_INLINE
Chris@16 173 result_type apply (argument1_type t1, argument2_type t2) {
Chris@16 174 return t1 / t2;
Chris@16 175 }
Chris@16 176 };
Chris@16 177
Chris@16 178 template<class T1, class T2>
Chris@16 179 struct scalar_binary_assign_functor {
Chris@16 180 // ISSUE Remove reference to avoid reference to reference problems
Chris@16 181 typedef typename type_traits<typename boost::remove_reference<T1>::type>::reference argument1_type;
Chris@16 182 typedef typename type_traits<T2>::const_reference argument2_type;
Chris@16 183 };
Chris@16 184
Chris@16 185 struct assign_tag {};
Chris@16 186 struct computed_assign_tag {};
Chris@16 187
Chris@16 188 template<class T1, class T2>
Chris@16 189 struct scalar_assign:
Chris@16 190 public scalar_binary_assign_functor<T1, T2> {
Chris@16 191 typedef typename scalar_binary_assign_functor<T1, T2>::argument1_type argument1_type;
Chris@16 192 typedef typename scalar_binary_assign_functor<T1, T2>::argument2_type argument2_type;
Chris@16 193 #if BOOST_WORKAROUND( __IBMCPP__, <=600 )
Chris@16 194 static const bool computed ;
Chris@16 195 #else
Chris@16 196 static const bool computed = false ;
Chris@16 197 #endif
Chris@16 198
Chris@16 199 static BOOST_UBLAS_INLINE
Chris@16 200 void apply (argument1_type t1, argument2_type t2) {
Chris@16 201 t1 = t2;
Chris@16 202 }
Chris@16 203
Chris@16 204 template<class U1, class U2>
Chris@16 205 struct rebind {
Chris@16 206 typedef scalar_assign<U1, U2> other;
Chris@16 207 };
Chris@16 208 };
Chris@16 209
Chris@16 210 #if BOOST_WORKAROUND( __IBMCPP__, <=600 )
Chris@16 211 template<class T1, class T2>
Chris@16 212 const bool scalar_assign<T1,T2>::computed = false;
Chris@16 213 #endif
Chris@16 214
Chris@16 215 template<class T1, class T2>
Chris@16 216 struct scalar_plus_assign:
Chris@16 217 public scalar_binary_assign_functor<T1, T2> {
Chris@16 218 typedef typename scalar_binary_assign_functor<T1, T2>::argument1_type argument1_type;
Chris@16 219 typedef typename scalar_binary_assign_functor<T1, T2>::argument2_type argument2_type;
Chris@16 220 #if BOOST_WORKAROUND( __IBMCPP__, <=600 )
Chris@16 221 static const bool computed ;
Chris@16 222 #else
Chris@16 223 static const bool computed = true ;
Chris@16 224 #endif
Chris@16 225
Chris@16 226 static BOOST_UBLAS_INLINE
Chris@16 227 void apply (argument1_type t1, argument2_type t2) {
Chris@16 228 t1 += t2;
Chris@16 229 }
Chris@16 230
Chris@16 231 template<class U1, class U2>
Chris@16 232 struct rebind {
Chris@16 233 typedef scalar_plus_assign<U1, U2> other;
Chris@16 234 };
Chris@16 235 };
Chris@16 236
Chris@16 237 #if BOOST_WORKAROUND( __IBMCPP__, <=600 )
Chris@16 238 template<class T1, class T2>
Chris@16 239 const bool scalar_plus_assign<T1,T2>::computed = true;
Chris@16 240 #endif
Chris@16 241
Chris@16 242 template<class T1, class T2>
Chris@16 243 struct scalar_minus_assign:
Chris@16 244 public scalar_binary_assign_functor<T1, T2> {
Chris@16 245 typedef typename scalar_binary_assign_functor<T1, T2>::argument1_type argument1_type;
Chris@16 246 typedef typename scalar_binary_assign_functor<T1, T2>::argument2_type argument2_type;
Chris@16 247 #if BOOST_WORKAROUND( __IBMCPP__, <=600 )
Chris@16 248 static const bool computed ;
Chris@16 249 #else
Chris@16 250 static const bool computed = true ;
Chris@16 251 #endif
Chris@16 252
Chris@16 253 static BOOST_UBLAS_INLINE
Chris@16 254 void apply (argument1_type t1, argument2_type t2) {
Chris@16 255 t1 -= t2;
Chris@16 256 }
Chris@16 257
Chris@16 258 template<class U1, class U2>
Chris@16 259 struct rebind {
Chris@16 260 typedef scalar_minus_assign<U1, U2> other;
Chris@16 261 };
Chris@16 262 };
Chris@16 263
Chris@16 264 #if BOOST_WORKAROUND( __IBMCPP__, <=600 )
Chris@16 265 template<class T1, class T2>
Chris@16 266 const bool scalar_minus_assign<T1,T2>::computed = true;
Chris@16 267 #endif
Chris@16 268
Chris@16 269 template<class T1, class T2>
Chris@16 270 struct scalar_multiplies_assign:
Chris@16 271 public scalar_binary_assign_functor<T1, T2> {
Chris@16 272 typedef typename scalar_binary_assign_functor<T1, T2>::argument1_type argument1_type;
Chris@16 273 typedef typename scalar_binary_assign_functor<T1, T2>::argument2_type argument2_type;
Chris@16 274 static const bool computed = true;
Chris@16 275
Chris@16 276 static BOOST_UBLAS_INLINE
Chris@16 277 void apply (argument1_type t1, argument2_type t2) {
Chris@16 278 t1 *= t2;
Chris@16 279 }
Chris@16 280
Chris@16 281 template<class U1, class U2>
Chris@16 282 struct rebind {
Chris@16 283 typedef scalar_multiplies_assign<U1, U2> other;
Chris@16 284 };
Chris@16 285 };
Chris@16 286 template<class T1, class T2>
Chris@16 287 struct scalar_divides_assign:
Chris@16 288 public scalar_binary_assign_functor<T1, T2> {
Chris@16 289 typedef typename scalar_binary_assign_functor<T1, T2>::argument1_type argument1_type;
Chris@16 290 typedef typename scalar_binary_assign_functor<T1, T2>::argument2_type argument2_type;
Chris@16 291 static const bool computed ;
Chris@16 292
Chris@16 293 static BOOST_UBLAS_INLINE
Chris@16 294 void apply (argument1_type t1, argument2_type t2) {
Chris@16 295 t1 /= t2;
Chris@16 296 }
Chris@16 297
Chris@16 298 template<class U1, class U2>
Chris@16 299 struct rebind {
Chris@16 300 typedef scalar_divides_assign<U1, U2> other;
Chris@16 301 };
Chris@16 302 };
Chris@16 303 template<class T1, class T2>
Chris@16 304 const bool scalar_divides_assign<T1,T2>::computed = true;
Chris@16 305
Chris@16 306 template<class T1, class T2>
Chris@16 307 struct scalar_binary_swap_functor {
Chris@16 308 typedef typename type_traits<typename boost::remove_reference<T1>::type>::reference argument1_type;
Chris@16 309 typedef typename type_traits<typename boost::remove_reference<T2>::type>::reference argument2_type;
Chris@16 310 };
Chris@16 311
Chris@16 312 template<class T1, class T2>
Chris@16 313 struct scalar_swap:
Chris@16 314 public scalar_binary_swap_functor<T1, T2> {
Chris@16 315 typedef typename scalar_binary_swap_functor<T1, T2>::argument1_type argument1_type;
Chris@16 316 typedef typename scalar_binary_swap_functor<T1, T2>::argument2_type argument2_type;
Chris@16 317
Chris@16 318 static BOOST_UBLAS_INLINE
Chris@16 319 void apply (argument1_type t1, argument2_type t2) {
Chris@16 320 std::swap (t1, t2);
Chris@16 321 }
Chris@16 322
Chris@16 323 template<class U1, class U2>
Chris@16 324 struct rebind {
Chris@16 325 typedef scalar_swap<U1, U2> other;
Chris@16 326 };
Chris@16 327 };
Chris@16 328
Chris@16 329 // Vector functors
Chris@16 330
Chris@16 331 // Unary returning scalar
Chris@16 332 template<class V>
Chris@16 333 struct vector_scalar_unary_functor {
Chris@16 334 typedef typename V::value_type value_type;
Chris@16 335 typedef typename V::value_type result_type;
Chris@16 336 };
Chris@16 337
Chris@16 338 template<class V>
Chris@16 339 struct vector_sum:
Chris@16 340 public vector_scalar_unary_functor<V> {
Chris@16 341 typedef typename vector_scalar_unary_functor<V>::value_type value_type;
Chris@16 342 typedef typename vector_scalar_unary_functor<V>::result_type result_type;
Chris@16 343
Chris@16 344 template<class E>
Chris@16 345 static BOOST_UBLAS_INLINE
Chris@16 346 result_type apply (const vector_expression<E> &e) {
Chris@16 347 result_type t = result_type (0);
Chris@16 348 typedef typename E::size_type vector_size_type;
Chris@16 349 vector_size_type size (e ().size ());
Chris@16 350 for (vector_size_type i = 0; i < size; ++ i)
Chris@16 351 t += e () (i);
Chris@16 352 return t;
Chris@16 353 }
Chris@16 354 // Dense case
Chris@16 355 template<class D, class I>
Chris@16 356 static BOOST_UBLAS_INLINE
Chris@16 357 result_type apply (D size, I it) {
Chris@16 358 result_type t = result_type (0);
Chris@16 359 while (-- size >= 0)
Chris@16 360 t += *it, ++ it;
Chris@16 361 return t;
Chris@16 362 }
Chris@16 363 // Sparse case
Chris@16 364 template<class I>
Chris@16 365 static BOOST_UBLAS_INLINE
Chris@16 366 result_type apply (I it, const I &it_end) {
Chris@16 367 result_type t = result_type (0);
Chris@16 368 while (it != it_end)
Chris@16 369 t += *it, ++ it;
Chris@16 370 return t;
Chris@16 371 }
Chris@16 372 };
Chris@16 373
Chris@16 374 // Unary returning real scalar
Chris@16 375 template<class V>
Chris@16 376 struct vector_scalar_real_unary_functor {
Chris@16 377 typedef typename V::value_type value_type;
Chris@16 378 typedef typename type_traits<value_type>::real_type real_type;
Chris@16 379 typedef real_type result_type;
Chris@16 380 };
Chris@16 381
Chris@16 382 template<class V>
Chris@16 383 struct vector_norm_1:
Chris@16 384 public vector_scalar_real_unary_functor<V> {
Chris@16 385 typedef typename vector_scalar_real_unary_functor<V>::value_type value_type;
Chris@16 386 typedef typename vector_scalar_real_unary_functor<V>::real_type real_type;
Chris@16 387 typedef typename vector_scalar_real_unary_functor<V>::result_type result_type;
Chris@16 388
Chris@16 389 template<class E>
Chris@16 390 static BOOST_UBLAS_INLINE
Chris@16 391 result_type apply (const vector_expression<E> &e) {
Chris@16 392 real_type t = real_type ();
Chris@16 393 typedef typename E::size_type vector_size_type;
Chris@16 394 vector_size_type size (e ().size ());
Chris@16 395 for (vector_size_type i = 0; i < size; ++ i) {
Chris@16 396 real_type u (type_traits<value_type>::type_abs (e () (i)));
Chris@16 397 t += u;
Chris@16 398 }
Chris@16 399 return t;
Chris@16 400 }
Chris@16 401 // Dense case
Chris@16 402 template<class D, class I>
Chris@16 403 static BOOST_UBLAS_INLINE
Chris@16 404 result_type apply (D size, I it) {
Chris@16 405 real_type t = real_type ();
Chris@16 406 while (-- size >= 0) {
Chris@16 407 real_type u (type_traits<value_type>::norm_1 (*it));
Chris@16 408 t += u;
Chris@16 409 ++ it;
Chris@16 410 }
Chris@16 411 return t;
Chris@16 412 }
Chris@16 413 // Sparse case
Chris@16 414 template<class I>
Chris@16 415 static BOOST_UBLAS_INLINE
Chris@16 416 result_type apply (I it, const I &it_end) {
Chris@16 417 real_type t = real_type ();
Chris@16 418 while (it != it_end) {
Chris@16 419 real_type u (type_traits<value_type>::norm_1 (*it));
Chris@16 420 t += u;
Chris@16 421 ++ it;
Chris@16 422 }
Chris@16 423 return t;
Chris@16 424 }
Chris@16 425 };
Chris@16 426 template<class V>
Chris@16 427 struct vector_norm_2:
Chris@16 428 public vector_scalar_real_unary_functor<V> {
Chris@16 429 typedef typename vector_scalar_real_unary_functor<V>::value_type value_type;
Chris@16 430 typedef typename vector_scalar_real_unary_functor<V>::real_type real_type;
Chris@16 431 typedef typename vector_scalar_real_unary_functor<V>::result_type result_type;
Chris@16 432
Chris@16 433 template<class E>
Chris@16 434 static BOOST_UBLAS_INLINE
Chris@16 435 result_type apply (const vector_expression<E> &e) {
Chris@16 436 #ifndef BOOST_UBLAS_SCALED_NORM
Chris@16 437 real_type t = real_type ();
Chris@16 438 typedef typename E::size_type vector_size_type;
Chris@16 439 vector_size_type size (e ().size ());
Chris@16 440 for (vector_size_type i = 0; i < size; ++ i) {
Chris@16 441 real_type u (type_traits<value_type>::norm_2 (e () (i)));
Chris@16 442 t += u * u;
Chris@16 443 }
Chris@16 444 return type_traits<real_type>::type_sqrt (t);
Chris@16 445 #else
Chris@16 446 real_type scale = real_type ();
Chris@16 447 real_type sum_squares (1);
Chris@16 448 size_type size (e ().size ());
Chris@16 449 for (size_type i = 0; i < size; ++ i) {
Chris@16 450 real_type u (type_traits<value_type>::norm_2 (e () (i)));
Chris@16 451 if ( real_type () /* zero */ == u ) continue;
Chris@16 452 if (scale < u) {
Chris@16 453 real_type v (scale / u);
Chris@16 454 sum_squares = sum_squares * v * v + real_type (1);
Chris@16 455 scale = u;
Chris@16 456 } else {
Chris@16 457 real_type v (u / scale);
Chris@16 458 sum_squares += v * v;
Chris@16 459 }
Chris@16 460 }
Chris@16 461 return scale * type_traits<real_type>::type_sqrt (sum_squares);
Chris@16 462 #endif
Chris@16 463 }
Chris@16 464 // Dense case
Chris@16 465 template<class D, class I>
Chris@16 466 static BOOST_UBLAS_INLINE
Chris@16 467 result_type apply (D size, I it) {
Chris@16 468 #ifndef BOOST_UBLAS_SCALED_NORM
Chris@16 469 real_type t = real_type ();
Chris@16 470 while (-- size >= 0) {
Chris@16 471 real_type u (type_traits<value_type>::norm_2 (*it));
Chris@16 472 t += u * u;
Chris@16 473 ++ it;
Chris@16 474 }
Chris@16 475 return type_traits<real_type>::type_sqrt (t);
Chris@16 476 #else
Chris@16 477 real_type scale = real_type ();
Chris@16 478 real_type sum_squares (1);
Chris@16 479 while (-- size >= 0) {
Chris@16 480 real_type u (type_traits<value_type>::norm_2 (*it));
Chris@16 481 if (scale < u) {
Chris@16 482 real_type v (scale / u);
Chris@16 483 sum_squares = sum_squares * v * v + real_type (1);
Chris@16 484 scale = u;
Chris@16 485 } else {
Chris@16 486 real_type v (u / scale);
Chris@16 487 sum_squares += v * v;
Chris@16 488 }
Chris@16 489 ++ it;
Chris@16 490 }
Chris@16 491 return scale * type_traits<real_type>::type_sqrt (sum_squares);
Chris@16 492 #endif
Chris@16 493 }
Chris@16 494 // Sparse case
Chris@16 495 template<class I>
Chris@16 496 static BOOST_UBLAS_INLINE
Chris@16 497 result_type apply (I it, const I &it_end) {
Chris@16 498 #ifndef BOOST_UBLAS_SCALED_NORM
Chris@16 499 real_type t = real_type ();
Chris@16 500 while (it != it_end) {
Chris@16 501 real_type u (type_traits<value_type>::norm_2 (*it));
Chris@16 502 t += u * u;
Chris@16 503 ++ it;
Chris@16 504 }
Chris@16 505 return type_traits<real_type>::type_sqrt (t);
Chris@16 506 #else
Chris@16 507 real_type scale = real_type ();
Chris@16 508 real_type sum_squares (1);
Chris@16 509 while (it != it_end) {
Chris@16 510 real_type u (type_traits<value_type>::norm_2 (*it));
Chris@16 511 if (scale < u) {
Chris@16 512 real_type v (scale / u);
Chris@16 513 sum_squares = sum_squares * v * v + real_type (1);
Chris@16 514 scale = u;
Chris@16 515 } else {
Chris@16 516 real_type v (u / scale);
Chris@16 517 sum_squares += v * v;
Chris@16 518 }
Chris@16 519 ++ it;
Chris@16 520 }
Chris@16 521 return scale * type_traits<real_type>::type_sqrt (sum_squares);
Chris@16 522 #endif
Chris@16 523 }
Chris@16 524 };
Chris@16 525 template<class V>
Chris@16 526 struct vector_norm_inf:
Chris@16 527 public vector_scalar_real_unary_functor<V> {
Chris@16 528 typedef typename vector_scalar_real_unary_functor<V>::value_type value_type;
Chris@16 529 typedef typename vector_scalar_real_unary_functor<V>::real_type real_type;
Chris@16 530 typedef typename vector_scalar_real_unary_functor<V>::result_type result_type;
Chris@16 531
Chris@16 532 template<class E>
Chris@16 533 static BOOST_UBLAS_INLINE
Chris@16 534 result_type apply (const vector_expression<E> &e) {
Chris@16 535 real_type t = real_type ();
Chris@16 536 typedef typename E::size_type vector_size_type;
Chris@16 537 vector_size_type size (e ().size ());
Chris@16 538 for (vector_size_type i = 0; i < size; ++ i) {
Chris@16 539 real_type u (type_traits<value_type>::norm_inf (e () (i)));
Chris@16 540 if (u > t)
Chris@16 541 t = u;
Chris@16 542 }
Chris@16 543 return t;
Chris@16 544 }
Chris@16 545 // Dense case
Chris@16 546 template<class D, class I>
Chris@16 547 static BOOST_UBLAS_INLINE
Chris@16 548 result_type apply (D size, I it) {
Chris@16 549 real_type t = real_type ();
Chris@16 550 while (-- size >= 0) {
Chris@16 551 real_type u (type_traits<value_type>::norm_inf (*it));
Chris@16 552 if (u > t)
Chris@16 553 t = u;
Chris@16 554 ++ it;
Chris@16 555 }
Chris@16 556 return t;
Chris@16 557 }
Chris@16 558 // Sparse case
Chris@16 559 template<class I>
Chris@16 560 static BOOST_UBLAS_INLINE
Chris@16 561 result_type apply (I it, const I &it_end) {
Chris@16 562 real_type t = real_type ();
Chris@16 563 while (it != it_end) {
Chris@16 564 real_type u (type_traits<value_type>::norm_inf (*it));
Chris@16 565 if (u > t)
Chris@16 566 t = u;
Chris@16 567 ++ it;
Chris@16 568 }
Chris@16 569 return t;
Chris@16 570 }
Chris@16 571 };
Chris@16 572
Chris@16 573 // Unary returning index
Chris@16 574 template<class V>
Chris@16 575 struct vector_scalar_index_unary_functor {
Chris@16 576 typedef typename V::value_type value_type;
Chris@16 577 typedef typename type_traits<value_type>::real_type real_type;
Chris@16 578 typedef typename V::size_type result_type;
Chris@16 579 };
Chris@16 580
Chris@16 581 template<class V>
Chris@16 582 struct vector_index_norm_inf:
Chris@16 583 public vector_scalar_index_unary_functor<V> {
Chris@16 584 typedef typename vector_scalar_index_unary_functor<V>::value_type value_type;
Chris@16 585 typedef typename vector_scalar_index_unary_functor<V>::real_type real_type;
Chris@16 586 typedef typename vector_scalar_index_unary_functor<V>::result_type result_type;
Chris@16 587
Chris@16 588 template<class E>
Chris@16 589 static BOOST_UBLAS_INLINE
Chris@16 590 result_type apply (const vector_expression<E> &e) {
Chris@16 591 // ISSUE For CBLAS compatibility return 0 index in empty case
Chris@16 592 result_type i_norm_inf (0);
Chris@16 593 real_type t = real_type ();
Chris@16 594 typedef typename E::size_type vector_size_type;
Chris@16 595 vector_size_type size (e ().size ());
Chris@16 596 for (vector_size_type i = 0; i < size; ++ i) {
Chris@16 597 real_type u (type_traits<value_type>::norm_inf (e () (i)));
Chris@16 598 if (u > t) {
Chris@16 599 i_norm_inf = i;
Chris@16 600 t = u;
Chris@16 601 }
Chris@16 602 }
Chris@16 603 return i_norm_inf;
Chris@16 604 }
Chris@16 605 // Dense case
Chris@16 606 template<class D, class I>
Chris@16 607 static BOOST_UBLAS_INLINE
Chris@16 608 result_type apply (D size, I it) {
Chris@16 609 // ISSUE For CBLAS compatibility return 0 index in empty case
Chris@16 610 result_type i_norm_inf (0);
Chris@16 611 real_type t = real_type ();
Chris@16 612 while (-- size >= 0) {
Chris@16 613 real_type u (type_traits<value_type>::norm_inf (*it));
Chris@16 614 if (u > t) {
Chris@16 615 i_norm_inf = it.index ();
Chris@16 616 t = u;
Chris@16 617 }
Chris@16 618 ++ it;
Chris@16 619 }
Chris@16 620 return i_norm_inf;
Chris@16 621 }
Chris@16 622 // Sparse case
Chris@16 623 template<class I>
Chris@16 624 static BOOST_UBLAS_INLINE
Chris@16 625 result_type apply (I it, const I &it_end) {
Chris@16 626 // ISSUE For CBLAS compatibility return 0 index in empty case
Chris@16 627 result_type i_norm_inf (0);
Chris@16 628 real_type t = real_type ();
Chris@16 629 while (it != it_end) {
Chris@16 630 real_type u (type_traits<value_type>::norm_inf (*it));
Chris@16 631 if (u > t) {
Chris@16 632 i_norm_inf = it.index ();
Chris@16 633 t = u;
Chris@16 634 }
Chris@16 635 ++ it;
Chris@16 636 }
Chris@16 637 return i_norm_inf;
Chris@16 638 }
Chris@16 639 };
Chris@16 640
Chris@16 641 // Binary returning scalar
Chris@16 642 template<class V1, class V2, class TV>
Chris@16 643 struct vector_scalar_binary_functor {
Chris@16 644 typedef TV value_type;
Chris@16 645 typedef TV result_type;
Chris@16 646 };
Chris@16 647
Chris@16 648 template<class V1, class V2, class TV>
Chris@16 649 struct vector_inner_prod:
Chris@16 650 public vector_scalar_binary_functor<V1, V2, TV> {
Chris@16 651 typedef typename vector_scalar_binary_functor<V1, V2, TV>::value_type value_type;
Chris@16 652 typedef typename vector_scalar_binary_functor<V1, V2, TV>::result_type result_type;
Chris@16 653
Chris@16 654 template<class C1, class C2>
Chris@16 655 static BOOST_UBLAS_INLINE
Chris@16 656 result_type apply (const vector_container<C1> &c1,
Chris@16 657 const vector_container<C2> &c2) {
Chris@16 658 #ifdef BOOST_UBLAS_USE_SIMD
Chris@16 659 using namespace raw;
Chris@16 660 typedef typename C1::size_type vector_size_type;
Chris@16 661 vector_size_type size (BOOST_UBLAS_SAME (c1 ().size (), c2 ().size ()));
Chris@16 662 const typename V1::value_type *data1 = data_const (c1 ());
Chris@16 663 const typename V1::value_type *data2 = data_const (c2 ());
Chris@16 664 vector_size_type s1 = stride (c1 ());
Chris@16 665 vector_size_type s2 = stride (c2 ());
Chris@16 666 result_type t = result_type (0);
Chris@16 667 if (s1 == 1 && s2 == 1) {
Chris@16 668 for (vector_size_type i = 0; i < size; ++ i)
Chris@16 669 t += data1 [i] * data2 [i];
Chris@16 670 } else if (s2 == 1) {
Chris@16 671 for (vector_size_type i = 0, i1 = 0; i < size; ++ i, i1 += s1)
Chris@16 672 t += data1 [i1] * data2 [i];
Chris@16 673 } else if (s1 == 1) {
Chris@16 674 for (vector_size_type i = 0, i2 = 0; i < size; ++ i, i2 += s2)
Chris@16 675 t += data1 [i] * data2 [i2];
Chris@16 676 } else {
Chris@16 677 for (vector_size_type i = 0, i1 = 0, i2 = 0; i < size; ++ i, i1 += s1, i2 += s2)
Chris@16 678 t += data1 [i1] * data2 [i2];
Chris@16 679 }
Chris@16 680 return t;
Chris@16 681 #elif defined(BOOST_UBLAS_HAVE_BINDINGS)
Chris@16 682 return boost::numeric::bindings::atlas::dot (c1 (), c2 ());
Chris@16 683 #else
Chris@16 684 return apply (static_cast<const vector_expression<C1> > (c1), static_cast<const vector_expression<C2> > (c2));
Chris@16 685 #endif
Chris@16 686 }
Chris@16 687 template<class E1, class E2>
Chris@16 688 static BOOST_UBLAS_INLINE
Chris@16 689 result_type apply (const vector_expression<E1> &e1,
Chris@16 690 const vector_expression<E2> &e2) {
Chris@16 691 typedef typename E1::size_type vector_size_type;
Chris@16 692 vector_size_type size (BOOST_UBLAS_SAME (e1 ().size (), e2 ().size ()));
Chris@16 693 result_type t = result_type (0);
Chris@16 694 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 695 for (vector_size_type i = 0; i < size; ++ i)
Chris@16 696 t += e1 () (i) * e2 () (i);
Chris@16 697 #else
Chris@16 698 vector_size_type i (0);
Chris@16 699 DD (size, 4, r, (t += e1 () (i) * e2 () (i), ++ i));
Chris@16 700 #endif
Chris@16 701 return t;
Chris@16 702 }
Chris@16 703 // Dense case
Chris@16 704 template<class D, class I1, class I2>
Chris@16 705 static BOOST_UBLAS_INLINE
Chris@16 706 result_type apply (D size, I1 it1, I2 it2) {
Chris@16 707 result_type t = result_type (0);
Chris@16 708 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 709 while (-- size >= 0)
Chris@16 710 t += *it1 * *it2, ++ it1, ++ it2;
Chris@16 711 #else
Chris@16 712 DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2));
Chris@16 713 #endif
Chris@16 714 return t;
Chris@16 715 }
Chris@16 716 // Packed case
Chris@16 717 template<class I1, class I2>
Chris@16 718 static BOOST_UBLAS_INLINE
Chris@16 719 result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) {
Chris@16 720 result_type t = result_type (0);
Chris@16 721 typedef typename I1::difference_type vector_difference_type;
Chris@16 722 vector_difference_type it1_size (it1_end - it1);
Chris@16 723 vector_difference_type it2_size (it2_end - it2);
Chris@16 724 vector_difference_type diff (0);
Chris@16 725 if (it1_size > 0 && it2_size > 0)
Chris@16 726 diff = it2.index () - it1.index ();
Chris@16 727 if (diff != 0) {
Chris@16 728 vector_difference_type size = (std::min) (diff, it1_size);
Chris@16 729 if (size > 0) {
Chris@16 730 it1 += size;
Chris@16 731 it1_size -= size;
Chris@16 732 diff -= size;
Chris@16 733 }
Chris@16 734 size = (std::min) (- diff, it2_size);
Chris@16 735 if (size > 0) {
Chris@16 736 it2 += size;
Chris@16 737 it2_size -= size;
Chris@16 738 diff += size;
Chris@16 739 }
Chris@16 740 }
Chris@16 741 vector_difference_type size ((std::min) (it1_size, it2_size));
Chris@16 742 while (-- size >= 0)
Chris@16 743 t += *it1 * *it2, ++ it1, ++ it2;
Chris@16 744 return t;
Chris@16 745 }
Chris@16 746 // Sparse case
Chris@16 747 template<class I1, class I2>
Chris@16 748 static BOOST_UBLAS_INLINE
Chris@16 749 result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) {
Chris@16 750 result_type t = result_type (0);
Chris@16 751 if (it1 != it1_end && it2 != it2_end) {
Chris@16 752 while (true) {
Chris@16 753 if (it1.index () == it2.index ()) {
Chris@16 754 t += *it1 * *it2, ++ it1, ++ it2;
Chris@16 755 if (it1 == it1_end || it2 == it2_end)
Chris@16 756 break;
Chris@16 757 } else if (it1.index () < it2.index ()) {
Chris@16 758 increment (it1, it1_end, it2.index () - it1.index ());
Chris@16 759 if (it1 == it1_end)
Chris@16 760 break;
Chris@16 761 } else if (it1.index () > it2.index ()) {
Chris@16 762 increment (it2, it2_end, it1.index () - it2.index ());
Chris@16 763 if (it2 == it2_end)
Chris@16 764 break;
Chris@16 765 }
Chris@16 766 }
Chris@16 767 }
Chris@16 768 return t;
Chris@16 769 }
Chris@16 770 };
Chris@16 771
Chris@16 772 // Matrix functors
Chris@16 773
Chris@16 774 // Binary returning vector
Chris@16 775 template<class M1, class M2, class TV>
Chris@16 776 struct matrix_vector_binary_functor {
Chris@16 777 typedef typename M1::size_type size_type;
Chris@16 778 typedef typename M1::difference_type difference_type;
Chris@16 779 typedef TV value_type;
Chris@16 780 typedef TV result_type;
Chris@16 781 };
Chris@16 782
Chris@16 783 template<class M1, class M2, class TV>
Chris@16 784 struct matrix_vector_prod1:
Chris@16 785 public matrix_vector_binary_functor<M1, M2, TV> {
Chris@16 786 typedef typename matrix_vector_binary_functor<M1, M2, TV>::size_type size_type;
Chris@16 787 typedef typename matrix_vector_binary_functor<M1, M2, TV>::difference_type difference_type;
Chris@16 788 typedef typename matrix_vector_binary_functor<M1, M2, TV>::value_type value_type;
Chris@16 789 typedef typename matrix_vector_binary_functor<M1, M2, TV>::result_type result_type;
Chris@16 790
Chris@16 791 template<class C1, class C2>
Chris@16 792 static BOOST_UBLAS_INLINE
Chris@16 793 result_type apply (const matrix_container<C1> &c1,
Chris@16 794 const vector_container<C2> &c2,
Chris@16 795 size_type i) {
Chris@16 796 #ifdef BOOST_UBLAS_USE_SIMD
Chris@16 797 using namespace raw;
Chris@16 798 size_type size = BOOST_UBLAS_SAME (c1 ().size2 (), c2 ().size ());
Chris@16 799 const typename M1::value_type *data1 = data_const (c1 ()) + i * stride1 (c1 ());
Chris@16 800 const typename M2::value_type *data2 = data_const (c2 ());
Chris@16 801 size_type s1 = stride2 (c1 ());
Chris@16 802 size_type s2 = stride (c2 ());
Chris@16 803 result_type t = result_type (0);
Chris@16 804 if (s1 == 1 && s2 == 1) {
Chris@16 805 for (size_type j = 0; j < size; ++ j)
Chris@16 806 t += data1 [j] * data2 [j];
Chris@16 807 } else if (s2 == 1) {
Chris@16 808 for (size_type j = 0, j1 = 0; j < size; ++ j, j1 += s1)
Chris@16 809 t += data1 [j1] * data2 [j];
Chris@16 810 } else if (s1 == 1) {
Chris@16 811 for (size_type j = 0, j2 = 0; j < size; ++ j, j2 += s2)
Chris@16 812 t += data1 [j] * data2 [j2];
Chris@16 813 } else {
Chris@16 814 for (size_type j = 0, j1 = 0, j2 = 0; j < size; ++ j, j1 += s1, j2 += s2)
Chris@16 815 t += data1 [j1] * data2 [j2];
Chris@16 816 }
Chris@16 817 return t;
Chris@16 818 #elif defined(BOOST_UBLAS_HAVE_BINDINGS)
Chris@16 819 return boost::numeric::bindings::atlas::dot (c1 ().row (i), c2 ());
Chris@16 820 #else
Chris@16 821 return apply (static_cast<const matrix_expression<C1> > (c1), static_cast<const vector_expression<C2> > (c2, i));
Chris@16 822 #endif
Chris@16 823 }
Chris@16 824 template<class E1, class E2>
Chris@16 825 static BOOST_UBLAS_INLINE
Chris@16 826 result_type apply (const matrix_expression<E1> &e1,
Chris@16 827 const vector_expression<E2> &e2,
Chris@16 828 size_type i) {
Chris@16 829 size_type size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size ());
Chris@16 830 result_type t = result_type (0);
Chris@16 831 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 832 for (size_type j = 0; j < size; ++ j)
Chris@16 833 t += e1 () (i, j) * e2 () (j);
Chris@16 834 #else
Chris@16 835 size_type j (0);
Chris@16 836 DD (size, 4, r, (t += e1 () (i, j) * e2 () (j), ++ j));
Chris@16 837 #endif
Chris@16 838 return t;
Chris@16 839 }
Chris@16 840 // Dense case
Chris@16 841 template<class I1, class I2>
Chris@16 842 static BOOST_UBLAS_INLINE
Chris@16 843 result_type apply (difference_type size, I1 it1, I2 it2) {
Chris@16 844 result_type t = result_type (0);
Chris@16 845 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 846 while (-- size >= 0)
Chris@16 847 t += *it1 * *it2, ++ it1, ++ it2;
Chris@16 848 #else
Chris@16 849 DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2));
Chris@16 850 #endif
Chris@16 851 return t;
Chris@16 852 }
Chris@16 853 // Packed case
Chris@16 854 template<class I1, class I2>
Chris@16 855 static BOOST_UBLAS_INLINE
Chris@16 856 result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) {
Chris@16 857 result_type t = result_type (0);
Chris@16 858 difference_type it1_size (it1_end - it1);
Chris@16 859 difference_type it2_size (it2_end - it2);
Chris@16 860 difference_type diff (0);
Chris@16 861 if (it1_size > 0 && it2_size > 0)
Chris@16 862 diff = it2.index () - it1.index2 ();
Chris@16 863 if (diff != 0) {
Chris@16 864 difference_type size = (std::min) (diff, it1_size);
Chris@16 865 if (size > 0) {
Chris@16 866 it1 += size;
Chris@16 867 it1_size -= size;
Chris@16 868 diff -= size;
Chris@16 869 }
Chris@16 870 size = (std::min) (- diff, it2_size);
Chris@16 871 if (size > 0) {
Chris@16 872 it2 += size;
Chris@16 873 it2_size -= size;
Chris@16 874 diff += size;
Chris@16 875 }
Chris@16 876 }
Chris@16 877 difference_type size ((std::min) (it1_size, it2_size));
Chris@16 878 while (-- size >= 0)
Chris@16 879 t += *it1 * *it2, ++ it1, ++ it2;
Chris@16 880 return t;
Chris@16 881 }
Chris@16 882 // Sparse case
Chris@16 883 template<class I1, class I2>
Chris@16 884 static BOOST_UBLAS_INLINE
Chris@16 885 result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end,
Chris@16 886 sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag) {
Chris@16 887 result_type t = result_type (0);
Chris@16 888 if (it1 != it1_end && it2 != it2_end) {
Chris@16 889 size_type it1_index = it1.index2 (), it2_index = it2.index ();
Chris@16 890 while (true) {
Chris@16 891 difference_type compare = it1_index - it2_index;
Chris@16 892 if (compare == 0) {
Chris@16 893 t += *it1 * *it2, ++ it1, ++ it2;
Chris@16 894 if (it1 != it1_end && it2 != it2_end) {
Chris@16 895 it1_index = it1.index2 ();
Chris@16 896 it2_index = it2.index ();
Chris@16 897 } else
Chris@16 898 break;
Chris@16 899 } else if (compare < 0) {
Chris@16 900 increment (it1, it1_end, - compare);
Chris@16 901 if (it1 != it1_end)
Chris@16 902 it1_index = it1.index2 ();
Chris@16 903 else
Chris@16 904 break;
Chris@16 905 } else if (compare > 0) {
Chris@16 906 increment (it2, it2_end, compare);
Chris@16 907 if (it2 != it2_end)
Chris@16 908 it2_index = it2.index ();
Chris@16 909 else
Chris@16 910 break;
Chris@16 911 }
Chris@16 912 }
Chris@16 913 }
Chris@16 914 return t;
Chris@16 915 }
Chris@16 916 // Sparse packed case
Chris@16 917 template<class I1, class I2>
Chris@16 918 static BOOST_UBLAS_INLINE
Chris@16 919 result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &/* it2_end */,
Chris@16 920 sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag) {
Chris@16 921 result_type t = result_type (0);
Chris@16 922 while (it1 != it1_end) {
Chris@16 923 t += *it1 * it2 () (it1.index2 ());
Chris@16 924 ++ it1;
Chris@16 925 }
Chris@16 926 return t;
Chris@16 927 }
Chris@16 928 // Packed sparse case
Chris@16 929 template<class I1, class I2>
Chris@16 930 static BOOST_UBLAS_INLINE
Chris@16 931 result_type apply (I1 it1, const I1 &/* it1_end */, I2 it2, const I2 &it2_end,
Chris@16 932 packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag) {
Chris@16 933 result_type t = result_type (0);
Chris@16 934 while (it2 != it2_end) {
Chris@16 935 t += it1 () (it1.index1 (), it2.index ()) * *it2;
Chris@16 936 ++ it2;
Chris@16 937 }
Chris@16 938 return t;
Chris@16 939 }
Chris@16 940 // Another dispatcher
Chris@16 941 template<class I1, class I2>
Chris@16 942 static BOOST_UBLAS_INLINE
Chris@16 943 result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end,
Chris@16 944 sparse_bidirectional_iterator_tag) {
Chris@16 945 typedef typename I1::iterator_category iterator1_category;
Chris@16 946 typedef typename I2::iterator_category iterator2_category;
Chris@16 947 return apply (it1, it1_end, it2, it2_end, iterator1_category (), iterator2_category ());
Chris@16 948 }
Chris@16 949 };
Chris@16 950
Chris@16 951 template<class M1, class M2, class TV>
Chris@16 952 struct matrix_vector_prod2:
Chris@16 953 public matrix_vector_binary_functor<M1, M2, TV> {
Chris@16 954 typedef typename matrix_vector_binary_functor<M1, M2, TV>::size_type size_type;
Chris@16 955 typedef typename matrix_vector_binary_functor<M1, M2, TV>::difference_type difference_type;
Chris@16 956 typedef typename matrix_vector_binary_functor<M1, M2, TV>::value_type value_type;
Chris@16 957 typedef typename matrix_vector_binary_functor<M1, M2, TV>::result_type result_type;
Chris@16 958
Chris@16 959 template<class C1, class C2>
Chris@16 960 static BOOST_UBLAS_INLINE
Chris@16 961 result_type apply (const vector_container<C1> &c1,
Chris@16 962 const matrix_container<C2> &c2,
Chris@16 963 size_type i) {
Chris@16 964 #ifdef BOOST_UBLAS_USE_SIMD
Chris@16 965 using namespace raw;
Chris@16 966 size_type size = BOOST_UBLAS_SAME (c1 ().size (), c2 ().size1 ());
Chris@16 967 const typename M1::value_type *data1 = data_const (c1 ());
Chris@16 968 const typename M2::value_type *data2 = data_const (c2 ()) + i * stride2 (c2 ());
Chris@16 969 size_type s1 = stride (c1 ());
Chris@16 970 size_type s2 = stride1 (c2 ());
Chris@16 971 result_type t = result_type (0);
Chris@16 972 if (s1 == 1 && s2 == 1) {
Chris@16 973 for (size_type j = 0; j < size; ++ j)
Chris@16 974 t += data1 [j] * data2 [j];
Chris@16 975 } else if (s2 == 1) {
Chris@16 976 for (size_type j = 0, j1 = 0; j < size; ++ j, j1 += s1)
Chris@16 977 t += data1 [j1] * data2 [j];
Chris@16 978 } else if (s1 == 1) {
Chris@16 979 for (size_type j = 0, j2 = 0; j < size; ++ j, j2 += s2)
Chris@16 980 t += data1 [j] * data2 [j2];
Chris@16 981 } else {
Chris@16 982 for (size_type j = 0, j1 = 0, j2 = 0; j < size; ++ j, j1 += s1, j2 += s2)
Chris@16 983 t += data1 [j1] * data2 [j2];
Chris@16 984 }
Chris@16 985 return t;
Chris@16 986 #elif defined(BOOST_UBLAS_HAVE_BINDINGS)
Chris@16 987 return boost::numeric::bindings::atlas::dot (c1 (), c2 ().column (i));
Chris@16 988 #else
Chris@16 989 return apply (static_cast<const vector_expression<C1> > (c1), static_cast<const matrix_expression<C2> > (c2, i));
Chris@16 990 #endif
Chris@16 991 }
Chris@16 992 template<class E1, class E2>
Chris@16 993 static BOOST_UBLAS_INLINE
Chris@16 994 result_type apply (const vector_expression<E1> &e1,
Chris@16 995 const matrix_expression<E2> &e2,
Chris@16 996 size_type i) {
Chris@16 997 size_type size = BOOST_UBLAS_SAME (e1 ().size (), e2 ().size1 ());
Chris@16 998 result_type t = result_type (0);
Chris@16 999 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 1000 for (size_type j = 0; j < size; ++ j)
Chris@16 1001 t += e1 () (j) * e2 () (j, i);
Chris@16 1002 #else
Chris@16 1003 size_type j (0);
Chris@16 1004 DD (size, 4, r, (t += e1 () (j) * e2 () (j, i), ++ j));
Chris@16 1005 #endif
Chris@16 1006 return t;
Chris@16 1007 }
Chris@16 1008 // Dense case
Chris@16 1009 template<class I1, class I2>
Chris@16 1010 static BOOST_UBLAS_INLINE
Chris@16 1011 result_type apply (difference_type size, I1 it1, I2 it2) {
Chris@16 1012 result_type t = result_type (0);
Chris@16 1013 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 1014 while (-- size >= 0)
Chris@16 1015 t += *it1 * *it2, ++ it1, ++ it2;
Chris@16 1016 #else
Chris@16 1017 DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2));
Chris@16 1018 #endif
Chris@16 1019 return t;
Chris@16 1020 }
Chris@16 1021 // Packed case
Chris@16 1022 template<class I1, class I2>
Chris@16 1023 static BOOST_UBLAS_INLINE
Chris@16 1024 result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) {
Chris@16 1025 result_type t = result_type (0);
Chris@16 1026 difference_type it1_size (it1_end - it1);
Chris@16 1027 difference_type it2_size (it2_end - it2);
Chris@16 1028 difference_type diff (0);
Chris@16 1029 if (it1_size > 0 && it2_size > 0)
Chris@16 1030 diff = it2.index1 () - it1.index ();
Chris@16 1031 if (diff != 0) {
Chris@16 1032 difference_type size = (std::min) (diff, it1_size);
Chris@16 1033 if (size > 0) {
Chris@16 1034 it1 += size;
Chris@16 1035 it1_size -= size;
Chris@16 1036 diff -= size;
Chris@16 1037 }
Chris@16 1038 size = (std::min) (- diff, it2_size);
Chris@16 1039 if (size > 0) {
Chris@16 1040 it2 += size;
Chris@16 1041 it2_size -= size;
Chris@16 1042 diff += size;
Chris@16 1043 }
Chris@16 1044 }
Chris@16 1045 difference_type size ((std::min) (it1_size, it2_size));
Chris@16 1046 while (-- size >= 0)
Chris@16 1047 t += *it1 * *it2, ++ it1, ++ it2;
Chris@16 1048 return t;
Chris@16 1049 }
Chris@16 1050 // Sparse case
Chris@16 1051 template<class I1, class I2>
Chris@16 1052 static BOOST_UBLAS_INLINE
Chris@16 1053 result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end,
Chris@16 1054 sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag) {
Chris@16 1055 result_type t = result_type (0);
Chris@16 1056 if (it1 != it1_end && it2 != it2_end) {
Chris@16 1057 size_type it1_index = it1.index (), it2_index = it2.index1 ();
Chris@16 1058 while (true) {
Chris@16 1059 difference_type compare = it1_index - it2_index;
Chris@16 1060 if (compare == 0) {
Chris@16 1061 t += *it1 * *it2, ++ it1, ++ it2;
Chris@16 1062 if (it1 != it1_end && it2 != it2_end) {
Chris@16 1063 it1_index = it1.index ();
Chris@16 1064 it2_index = it2.index1 ();
Chris@16 1065 } else
Chris@16 1066 break;
Chris@16 1067 } else if (compare < 0) {
Chris@16 1068 increment (it1, it1_end, - compare);
Chris@16 1069 if (it1 != it1_end)
Chris@16 1070 it1_index = it1.index ();
Chris@16 1071 else
Chris@16 1072 break;
Chris@16 1073 } else if (compare > 0) {
Chris@16 1074 increment (it2, it2_end, compare);
Chris@16 1075 if (it2 != it2_end)
Chris@16 1076 it2_index = it2.index1 ();
Chris@16 1077 else
Chris@16 1078 break;
Chris@16 1079 }
Chris@16 1080 }
Chris@16 1081 }
Chris@16 1082 return t;
Chris@16 1083 }
Chris@16 1084 // Packed sparse case
Chris@16 1085 template<class I1, class I2>
Chris@16 1086 static BOOST_UBLAS_INLINE
Chris@16 1087 result_type apply (I1 it1, const I1 &/* it1_end */, I2 it2, const I2 &it2_end,
Chris@16 1088 packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag) {
Chris@16 1089 result_type t = result_type (0);
Chris@16 1090 while (it2 != it2_end) {
Chris@16 1091 t += it1 () (it2.index1 ()) * *it2;
Chris@16 1092 ++ it2;
Chris@16 1093 }
Chris@16 1094 return t;
Chris@16 1095 }
Chris@16 1096 // Sparse packed case
Chris@16 1097 template<class I1, class I2>
Chris@16 1098 static BOOST_UBLAS_INLINE
Chris@16 1099 result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &/* it2_end */,
Chris@16 1100 sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag) {
Chris@16 1101 result_type t = result_type (0);
Chris@16 1102 while (it1 != it1_end) {
Chris@16 1103 t += *it1 * it2 () (it1.index (), it2.index2 ());
Chris@16 1104 ++ it1;
Chris@16 1105 }
Chris@16 1106 return t;
Chris@16 1107 }
Chris@16 1108 // Another dispatcher
Chris@16 1109 template<class I1, class I2>
Chris@16 1110 static BOOST_UBLAS_INLINE
Chris@16 1111 result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end,
Chris@16 1112 sparse_bidirectional_iterator_tag) {
Chris@16 1113 typedef typename I1::iterator_category iterator1_category;
Chris@16 1114 typedef typename I2::iterator_category iterator2_category;
Chris@16 1115 return apply (it1, it1_end, it2, it2_end, iterator1_category (), iterator2_category ());
Chris@16 1116 }
Chris@16 1117 };
Chris@16 1118
Chris@16 1119 // Binary returning matrix
Chris@16 1120 template<class M1, class M2, class TV>
Chris@16 1121 struct matrix_matrix_binary_functor {
Chris@16 1122 typedef typename M1::size_type size_type;
Chris@16 1123 typedef typename M1::difference_type difference_type;
Chris@16 1124 typedef TV value_type;
Chris@16 1125 typedef TV result_type;
Chris@16 1126 };
Chris@16 1127
Chris@16 1128 template<class M1, class M2, class TV>
Chris@16 1129 struct matrix_matrix_prod:
Chris@16 1130 public matrix_matrix_binary_functor<M1, M2, TV> {
Chris@16 1131 typedef typename matrix_matrix_binary_functor<M1, M2, TV>::size_type size_type;
Chris@16 1132 typedef typename matrix_matrix_binary_functor<M1, M2, TV>::difference_type difference_type;
Chris@16 1133 typedef typename matrix_matrix_binary_functor<M1, M2, TV>::value_type value_type;
Chris@16 1134 typedef typename matrix_matrix_binary_functor<M1, M2, TV>::result_type result_type;
Chris@16 1135
Chris@16 1136 template<class C1, class C2>
Chris@16 1137 static BOOST_UBLAS_INLINE
Chris@16 1138 result_type apply (const matrix_container<C1> &c1,
Chris@16 1139 const matrix_container<C2> &c2,
Chris@16 1140 size_type i, size_type j) {
Chris@16 1141 #ifdef BOOST_UBLAS_USE_SIMD
Chris@16 1142 using namespace raw;
Chris@16 1143 size_type size = BOOST_UBLAS_SAME (c1 ().size2 (), c2 ().sizc1 ());
Chris@16 1144 const typename M1::value_type *data1 = data_const (c1 ()) + i * stride1 (c1 ());
Chris@16 1145 const typename M2::value_type *data2 = data_const (c2 ()) + j * stride2 (c2 ());
Chris@16 1146 size_type s1 = stride2 (c1 ());
Chris@16 1147 size_type s2 = stride1 (c2 ());
Chris@16 1148 result_type t = result_type (0);
Chris@16 1149 if (s1 == 1 && s2 == 1) {
Chris@16 1150 for (size_type k = 0; k < size; ++ k)
Chris@16 1151 t += data1 [k] * data2 [k];
Chris@16 1152 } else if (s2 == 1) {
Chris@16 1153 for (size_type k = 0, k1 = 0; k < size; ++ k, k1 += s1)
Chris@16 1154 t += data1 [k1] * data2 [k];
Chris@16 1155 } else if (s1 == 1) {
Chris@16 1156 for (size_type k = 0, k2 = 0; k < size; ++ k, k2 += s2)
Chris@16 1157 t += data1 [k] * data2 [k2];
Chris@16 1158 } else {
Chris@16 1159 for (size_type k = 0, k1 = 0, k2 = 0; k < size; ++ k, k1 += s1, k2 += s2)
Chris@16 1160 t += data1 [k1] * data2 [k2];
Chris@16 1161 }
Chris@16 1162 return t;
Chris@16 1163 #elif defined(BOOST_UBLAS_HAVE_BINDINGS)
Chris@16 1164 return boost::numeric::bindings::atlas::dot (c1 ().row (i), c2 ().column (j));
Chris@16 1165 #else
Chris@101 1166 boost::ignore_unused(j);
Chris@16 1167 return apply (static_cast<const matrix_expression<C1> > (c1), static_cast<const matrix_expression<C2> > (c2, i));
Chris@16 1168 #endif
Chris@16 1169 }
Chris@16 1170 template<class E1, class E2>
Chris@16 1171 static BOOST_UBLAS_INLINE
Chris@16 1172 result_type apply (const matrix_expression<E1> &e1,
Chris@16 1173 const matrix_expression<E2> &e2,
Chris@16 1174 size_type i, size_type j) {
Chris@16 1175 size_type size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size1 ());
Chris@16 1176 result_type t = result_type (0);
Chris@16 1177 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 1178 for (size_type k = 0; k < size; ++ k)
Chris@16 1179 t += e1 () (i, k) * e2 () (k, j);
Chris@16 1180 #else
Chris@16 1181 size_type k (0);
Chris@16 1182 DD (size, 4, r, (t += e1 () (i, k) * e2 () (k, j), ++ k));
Chris@16 1183 #endif
Chris@16 1184 return t;
Chris@16 1185 }
Chris@16 1186 // Dense case
Chris@16 1187 template<class I1, class I2>
Chris@16 1188 static BOOST_UBLAS_INLINE
Chris@16 1189 result_type apply (difference_type size, I1 it1, I2 it2) {
Chris@16 1190 result_type t = result_type (0);
Chris@16 1191 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
Chris@16 1192 while (-- size >= 0)
Chris@16 1193 t += *it1 * *it2, ++ it1, ++ it2;
Chris@16 1194 #else
Chris@16 1195 DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2));
Chris@16 1196 #endif
Chris@16 1197 return t;
Chris@16 1198 }
Chris@16 1199 // Packed case
Chris@16 1200 template<class I1, class I2>
Chris@16 1201 static BOOST_UBLAS_INLINE
Chris@16 1202 result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, packed_random_access_iterator_tag) {
Chris@16 1203 result_type t = result_type (0);
Chris@16 1204 difference_type it1_size (it1_end - it1);
Chris@16 1205 difference_type it2_size (it2_end - it2);
Chris@16 1206 difference_type diff (0);
Chris@16 1207 if (it1_size > 0 && it2_size > 0)
Chris@16 1208 diff = it2.index1 () - it1.index2 ();
Chris@16 1209 if (diff != 0) {
Chris@16 1210 difference_type size = (std::min) (diff, it1_size);
Chris@16 1211 if (size > 0) {
Chris@16 1212 it1 += size;
Chris@16 1213 it1_size -= size;
Chris@16 1214 diff -= size;
Chris@16 1215 }
Chris@16 1216 size = (std::min) (- diff, it2_size);
Chris@16 1217 if (size > 0) {
Chris@16 1218 it2 += size;
Chris@16 1219 it2_size -= size;
Chris@16 1220 diff += size;
Chris@16 1221 }
Chris@16 1222 }
Chris@16 1223 difference_type size ((std::min) (it1_size, it2_size));
Chris@16 1224 while (-- size >= 0)
Chris@16 1225 t += *it1 * *it2, ++ it1, ++ it2;
Chris@16 1226 return t;
Chris@16 1227 }
Chris@16 1228 // Sparse case
Chris@16 1229 template<class I1, class I2>
Chris@16 1230 static BOOST_UBLAS_INLINE
Chris@16 1231 result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) {
Chris@16 1232 result_type t = result_type (0);
Chris@16 1233 if (it1 != it1_end && it2 != it2_end) {
Chris@16 1234 size_type it1_index = it1.index2 (), it2_index = it2.index1 ();
Chris@16 1235 while (true) {
Chris@16 1236 difference_type compare = difference_type (it1_index - it2_index);
Chris@16 1237 if (compare == 0) {
Chris@16 1238 t += *it1 * *it2, ++ it1, ++ it2;
Chris@16 1239 if (it1 != it1_end && it2 != it2_end) {
Chris@16 1240 it1_index = it1.index2 ();
Chris@16 1241 it2_index = it2.index1 ();
Chris@16 1242 } else
Chris@16 1243 break;
Chris@16 1244 } else if (compare < 0) {
Chris@16 1245 increment (it1, it1_end, - compare);
Chris@16 1246 if (it1 != it1_end)
Chris@16 1247 it1_index = it1.index2 ();
Chris@16 1248 else
Chris@16 1249 break;
Chris@16 1250 } else if (compare > 0) {
Chris@16 1251 increment (it2, it2_end, compare);
Chris@16 1252 if (it2 != it2_end)
Chris@16 1253 it2_index = it2.index1 ();
Chris@16 1254 else
Chris@16 1255 break;
Chris@16 1256 }
Chris@16 1257 }
Chris@16 1258 }
Chris@16 1259 return t;
Chris@16 1260 }
Chris@16 1261 };
Chris@16 1262
Chris@16 1263 // Unary returning scalar norm
Chris@16 1264 template<class M>
Chris@16 1265 struct matrix_scalar_real_unary_functor {
Chris@16 1266 typedef typename M::value_type value_type;
Chris@16 1267 typedef typename type_traits<value_type>::real_type real_type;
Chris@16 1268 typedef real_type result_type;
Chris@16 1269 };
Chris@16 1270
Chris@16 1271 template<class M>
Chris@16 1272 struct matrix_norm_1:
Chris@16 1273 public matrix_scalar_real_unary_functor<M> {
Chris@16 1274 typedef typename matrix_scalar_real_unary_functor<M>::value_type value_type;
Chris@16 1275 typedef typename matrix_scalar_real_unary_functor<M>::real_type real_type;
Chris@16 1276 typedef typename matrix_scalar_real_unary_functor<M>::result_type result_type;
Chris@16 1277
Chris@16 1278 template<class E>
Chris@16 1279 static BOOST_UBLAS_INLINE
Chris@16 1280 result_type apply (const matrix_expression<E> &e) {
Chris@16 1281 real_type t = real_type ();
Chris@16 1282 typedef typename E::size_type matrix_size_type;
Chris@16 1283 matrix_size_type size2 (e ().size2 ());
Chris@16 1284 for (matrix_size_type j = 0; j < size2; ++ j) {
Chris@16 1285 real_type u = real_type ();
Chris@16 1286 matrix_size_type size1 (e ().size1 ());
Chris@16 1287 for (matrix_size_type i = 0; i < size1; ++ i) {
Chris@16 1288 real_type v (type_traits<value_type>::norm_1 (e () (i, j)));
Chris@16 1289 u += v;
Chris@16 1290 }
Chris@16 1291 if (u > t)
Chris@16 1292 t = u;
Chris@16 1293 }
Chris@16 1294 return t;
Chris@16 1295 }
Chris@16 1296 };
Chris@16 1297
Chris@16 1298 template<class M>
Chris@16 1299 struct matrix_norm_frobenius:
Chris@16 1300 public matrix_scalar_real_unary_functor<M> {
Chris@16 1301 typedef typename matrix_scalar_real_unary_functor<M>::value_type value_type;
Chris@16 1302 typedef typename matrix_scalar_real_unary_functor<M>::real_type real_type;
Chris@16 1303 typedef typename matrix_scalar_real_unary_functor<M>::result_type result_type;
Chris@16 1304
Chris@16 1305 template<class E>
Chris@16 1306 static BOOST_UBLAS_INLINE
Chris@16 1307 result_type apply (const matrix_expression<E> &e) {
Chris@16 1308 real_type t = real_type ();
Chris@16 1309 typedef typename E::size_type matrix_size_type;
Chris@16 1310 matrix_size_type size1 (e ().size1 ());
Chris@16 1311 for (matrix_size_type i = 0; i < size1; ++ i) {
Chris@16 1312 matrix_size_type size2 (e ().size2 ());
Chris@16 1313 for (matrix_size_type j = 0; j < size2; ++ j) {
Chris@16 1314 real_type u (type_traits<value_type>::norm_2 (e () (i, j)));
Chris@16 1315 t += u * u;
Chris@16 1316 }
Chris@16 1317 }
Chris@16 1318 return type_traits<real_type>::type_sqrt (t);
Chris@16 1319 }
Chris@16 1320 };
Chris@16 1321
Chris@16 1322 template<class M>
Chris@16 1323 struct matrix_norm_inf:
Chris@16 1324 public matrix_scalar_real_unary_functor<M> {
Chris@16 1325 typedef typename matrix_scalar_real_unary_functor<M>::value_type value_type;
Chris@16 1326 typedef typename matrix_scalar_real_unary_functor<M>::real_type real_type;
Chris@16 1327 typedef typename matrix_scalar_real_unary_functor<M>::result_type result_type;
Chris@16 1328
Chris@16 1329 template<class E>
Chris@16 1330 static BOOST_UBLAS_INLINE
Chris@16 1331 result_type apply (const matrix_expression<E> &e) {
Chris@16 1332 real_type t = real_type ();
Chris@16 1333 typedef typename E::size_type matrix_size_type;
Chris@16 1334 matrix_size_type size1 (e ().size1 ());
Chris@16 1335 for (matrix_size_type i = 0; i < size1; ++ i) {
Chris@16 1336 real_type u = real_type ();
Chris@16 1337 matrix_size_type size2 (e ().size2 ());
Chris@16 1338 for (matrix_size_type j = 0; j < size2; ++ j) {
Chris@16 1339 real_type v (type_traits<value_type>::norm_inf (e () (i, j)));
Chris@16 1340 u += v;
Chris@16 1341 }
Chris@16 1342 if (u > t)
Chris@16 1343 t = u;
Chris@16 1344 }
Chris@16 1345 return t;
Chris@16 1346 }
Chris@16 1347 };
Chris@16 1348
Chris@16 1349 // forward declaration
Chris@16 1350 template <class Z, class D> struct basic_column_major;
Chris@16 1351
Chris@16 1352 // This functor defines storage layout and it's properties
Chris@16 1353 // matrix (i,j) -> storage [i * size_i + j]
Chris@16 1354 template <class Z, class D>
Chris@16 1355 struct basic_row_major {
Chris@16 1356 typedef Z size_type;
Chris@16 1357 typedef D difference_type;
Chris@16 1358 typedef row_major_tag orientation_category;
Chris@16 1359 typedef basic_column_major<Z,D> transposed_layout;
Chris@16 1360
Chris@16 1361 static
Chris@16 1362 BOOST_UBLAS_INLINE
Chris@16 1363 size_type storage_size (size_type size_i, size_type size_j) {
Chris@16 1364 // Guard against size_type overflow
Chris@16 1365 BOOST_UBLAS_CHECK (size_j == 0 || size_i <= (std::numeric_limits<size_type>::max) () / size_j, bad_size ());
Chris@16 1366 return size_i * size_j;
Chris@16 1367 }
Chris@16 1368
Chris@16 1369 // Indexing conversion to storage element
Chris@16 1370 static
Chris@16 1371 BOOST_UBLAS_INLINE
Chris@16 1372 size_type element (size_type i, size_type size_i, size_type j, size_type size_j) {
Chris@16 1373 BOOST_UBLAS_CHECK (i < size_i, bad_index ());
Chris@16 1374 BOOST_UBLAS_CHECK (j < size_j, bad_index ());
Chris@16 1375 detail::ignore_unused_variable_warning(size_i);
Chris@16 1376 // Guard against size_type overflow
Chris@16 1377 BOOST_UBLAS_CHECK (i <= ((std::numeric_limits<size_type>::max) () - j) / size_j, bad_index ());
Chris@16 1378 return i * size_j + j;
Chris@16 1379 }
Chris@16 1380 static
Chris@16 1381 BOOST_UBLAS_INLINE
Chris@16 1382 size_type address (size_type i, size_type size_i, size_type j, size_type size_j) {
Chris@16 1383 BOOST_UBLAS_CHECK (i <= size_i, bad_index ());
Chris@16 1384 BOOST_UBLAS_CHECK (j <= size_j, bad_index ());
Chris@16 1385 // Guard against size_type overflow - address may be size_j past end of storage
Chris@16 1386 BOOST_UBLAS_CHECK (size_j == 0 || i <= ((std::numeric_limits<size_type>::max) () - j) / size_j, bad_index ());
Chris@16 1387 detail::ignore_unused_variable_warning(size_i);
Chris@16 1388 return i * size_j + j;
Chris@16 1389 }
Chris@16 1390
Chris@16 1391 // Storage element to index conversion
Chris@16 1392 static
Chris@16 1393 BOOST_UBLAS_INLINE
Chris@16 1394 difference_type distance_i (difference_type k, size_type /* size_i */, size_type size_j) {
Chris@16 1395 return size_j != 0 ? k / size_j : 0;
Chris@16 1396 }
Chris@16 1397 static
Chris@16 1398 BOOST_UBLAS_INLINE
Chris@16 1399 difference_type distance_j (difference_type k, size_type /* size_i */, size_type /* size_j */) {
Chris@16 1400 return k;
Chris@16 1401 }
Chris@16 1402 static
Chris@16 1403 BOOST_UBLAS_INLINE
Chris@16 1404 size_type index_i (difference_type k, size_type /* size_i */, size_type size_j) {
Chris@16 1405 return size_j != 0 ? k / size_j : 0;
Chris@16 1406 }
Chris@16 1407 static
Chris@16 1408 BOOST_UBLAS_INLINE
Chris@16 1409 size_type index_j (difference_type k, size_type /* size_i */, size_type size_j) {
Chris@16 1410 return size_j != 0 ? k % size_j : 0;
Chris@16 1411 }
Chris@16 1412 static
Chris@16 1413 BOOST_UBLAS_INLINE
Chris@16 1414 bool fast_i () {
Chris@16 1415 return false;
Chris@16 1416 }
Chris@16 1417 static
Chris@16 1418 BOOST_UBLAS_INLINE
Chris@16 1419 bool fast_j () {
Chris@16 1420 return true;
Chris@16 1421 }
Chris@16 1422
Chris@16 1423 // Iterating storage elements
Chris@16 1424 template<class I>
Chris@16 1425 static
Chris@16 1426 BOOST_UBLAS_INLINE
Chris@16 1427 void increment_i (I &it, size_type /* size_i */, size_type size_j) {
Chris@16 1428 it += size_j;
Chris@16 1429 }
Chris@16 1430 template<class I>
Chris@16 1431 static
Chris@16 1432 BOOST_UBLAS_INLINE
Chris@16 1433 void increment_i (I &it, difference_type n, size_type /* size_i */, size_type size_j) {
Chris@16 1434 it += n * size_j;
Chris@16 1435 }
Chris@16 1436 template<class I>
Chris@16 1437 static
Chris@16 1438 BOOST_UBLAS_INLINE
Chris@16 1439 void decrement_i (I &it, size_type /* size_i */, size_type size_j) {
Chris@16 1440 it -= size_j;
Chris@16 1441 }
Chris@16 1442 template<class I>
Chris@16 1443 static
Chris@16 1444 BOOST_UBLAS_INLINE
Chris@16 1445 void decrement_i (I &it, difference_type n, size_type /* size_i */, size_type size_j) {
Chris@16 1446 it -= n * size_j;
Chris@16 1447 }
Chris@16 1448 template<class I>
Chris@16 1449 static
Chris@16 1450 BOOST_UBLAS_INLINE
Chris@16 1451 void increment_j (I &it, size_type /* size_i */, size_type /* size_j */) {
Chris@16 1452 ++ it;
Chris@16 1453 }
Chris@16 1454 template<class I>
Chris@16 1455 static
Chris@16 1456 BOOST_UBLAS_INLINE
Chris@16 1457 void increment_j (I &it, difference_type n, size_type /* size_i */, size_type /* size_j */) {
Chris@16 1458 it += n;
Chris@16 1459 }
Chris@16 1460 template<class I>
Chris@16 1461 static
Chris@16 1462 BOOST_UBLAS_INLINE
Chris@16 1463 void decrement_j (I &it, size_type /* size_i */, size_type /* size_j */) {
Chris@16 1464 -- it;
Chris@16 1465 }
Chris@16 1466 template<class I>
Chris@16 1467 static
Chris@16 1468 BOOST_UBLAS_INLINE
Chris@16 1469 void decrement_j (I &it, difference_type n, size_type /* size_i */, size_type /* size_j */) {
Chris@16 1470 it -= n;
Chris@16 1471 }
Chris@16 1472
Chris@16 1473 // Triangular access
Chris@16 1474 static
Chris@16 1475 BOOST_UBLAS_INLINE
Chris@16 1476 size_type triangular_size (size_type size_i, size_type size_j) {
Chris@16 1477 size_type size = (std::max) (size_i, size_j);
Chris@16 1478 // Guard against size_type overflow - simplified
Chris@16 1479 BOOST_UBLAS_CHECK (size == 0 || size / 2 < (std::numeric_limits<size_type>::max) () / size /* +1/2 */, bad_size ());
Chris@16 1480 return ((size + 1) * size) / 2;
Chris@16 1481 }
Chris@16 1482 static
Chris@16 1483 BOOST_UBLAS_INLINE
Chris@16 1484 size_type lower_element (size_type i, size_type size_i, size_type j, size_type size_j) {
Chris@16 1485 BOOST_UBLAS_CHECK (i < size_i, bad_index ());
Chris@16 1486 BOOST_UBLAS_CHECK (j < size_j, bad_index ());
Chris@16 1487 BOOST_UBLAS_CHECK (i >= j, bad_index ());
Chris@16 1488 detail::ignore_unused_variable_warning(size_i);
Chris@16 1489 detail::ignore_unused_variable_warning(size_j);
Chris@16 1490 // FIXME size_type overflow
Chris@16 1491 // sigma_i (i + 1) = (i + 1) * i / 2
Chris@16 1492 // i = 0 1 2 3, sigma = 0 1 3 6
Chris@16 1493 return ((i + 1) * i) / 2 + j;
Chris@16 1494 }
Chris@16 1495 static
Chris@16 1496 BOOST_UBLAS_INLINE
Chris@16 1497 size_type upper_element (size_type i, size_type size_i, size_type j, size_type size_j) {
Chris@16 1498 BOOST_UBLAS_CHECK (i < size_i, bad_index ());
Chris@16 1499 BOOST_UBLAS_CHECK (j < size_j, bad_index ());
Chris@16 1500 BOOST_UBLAS_CHECK (i <= j, bad_index ());
Chris@16 1501 // FIXME size_type overflow
Chris@16 1502 // sigma_i (size - i) = size * i - i * (i - 1) / 2
Chris@16 1503 // i = 0 1 2 3, sigma = 0 4 7 9
Chris@16 1504 return (i * (2 * (std::max) (size_i, size_j) - i + 1)) / 2 + j - i;
Chris@16 1505 }
Chris@16 1506
Chris@16 1507 // Major and minor indices
Chris@16 1508 static
Chris@16 1509 BOOST_UBLAS_INLINE
Chris@16 1510 size_type index_M (size_type index1, size_type /* index2 */) {
Chris@16 1511 return index1;
Chris@16 1512 }
Chris@16 1513 static
Chris@16 1514 BOOST_UBLAS_INLINE
Chris@16 1515 size_type index_m (size_type /* index1 */, size_type index2) {
Chris@16 1516 return index2;
Chris@16 1517 }
Chris@16 1518 static
Chris@16 1519 BOOST_UBLAS_INLINE
Chris@16 1520 size_type size_M (size_type size_i, size_type /* size_j */) {
Chris@16 1521 return size_i;
Chris@16 1522 }
Chris@16 1523 static
Chris@16 1524 BOOST_UBLAS_INLINE
Chris@16 1525 size_type size_m (size_type /* size_i */, size_type size_j) {
Chris@16 1526 return size_j;
Chris@16 1527 }
Chris@16 1528 };
Chris@16 1529
Chris@16 1530 // This functor defines storage layout and it's properties
Chris@16 1531 // matrix (i,j) -> storage [i + j * size_i]
Chris@16 1532 template <class Z, class D>
Chris@16 1533 struct basic_column_major {
Chris@16 1534 typedef Z size_type;
Chris@16 1535 typedef D difference_type;
Chris@16 1536 typedef column_major_tag orientation_category;
Chris@16 1537 typedef basic_row_major<Z,D> transposed_layout;
Chris@16 1538
Chris@16 1539 static
Chris@16 1540 BOOST_UBLAS_INLINE
Chris@16 1541 size_type storage_size (size_type size_i, size_type size_j) {
Chris@16 1542 // Guard against size_type overflow
Chris@16 1543 BOOST_UBLAS_CHECK (size_i == 0 || size_j <= (std::numeric_limits<size_type>::max) () / size_i, bad_size ());
Chris@16 1544 return size_i * size_j;
Chris@16 1545 }
Chris@16 1546
Chris@16 1547 // Indexing conversion to storage element
Chris@16 1548 static
Chris@16 1549 BOOST_UBLAS_INLINE
Chris@16 1550 size_type element (size_type i, size_type size_i, size_type j, size_type size_j) {
Chris@16 1551 BOOST_UBLAS_CHECK (i < size_i, bad_index ());
Chris@16 1552 BOOST_UBLAS_CHECK (j < size_j, bad_index ());
Chris@16 1553 detail::ignore_unused_variable_warning(size_j);
Chris@16 1554 // Guard against size_type overflow
Chris@16 1555 BOOST_UBLAS_CHECK (j <= ((std::numeric_limits<size_type>::max) () - i) / size_i, bad_index ());
Chris@16 1556 return i + j * size_i;
Chris@16 1557 }
Chris@16 1558 static
Chris@16 1559 BOOST_UBLAS_INLINE
Chris@16 1560 size_type address (size_type i, size_type size_i, size_type j, size_type size_j) {
Chris@16 1561 BOOST_UBLAS_CHECK (i <= size_i, bad_index ());
Chris@16 1562 BOOST_UBLAS_CHECK (j <= size_j, bad_index ());
Chris@16 1563 detail::ignore_unused_variable_warning(size_j);
Chris@16 1564 // Guard against size_type overflow - address may be size_i past end of storage
Chris@16 1565 BOOST_UBLAS_CHECK (size_i == 0 || j <= ((std::numeric_limits<size_type>::max) () - i) / size_i, bad_index ());
Chris@16 1566 return i + j * size_i;
Chris@16 1567 }
Chris@16 1568
Chris@16 1569 // Storage element to index conversion
Chris@16 1570 static
Chris@16 1571 BOOST_UBLAS_INLINE
Chris@16 1572 difference_type distance_i (difference_type k, size_type /* size_i */, size_type /* size_j */) {
Chris@16 1573 return k;
Chris@16 1574 }
Chris@16 1575 static
Chris@16 1576 BOOST_UBLAS_INLINE
Chris@16 1577 difference_type distance_j (difference_type k, size_type size_i, size_type /* size_j */) {
Chris@16 1578 return size_i != 0 ? k / size_i : 0;
Chris@16 1579 }
Chris@16 1580 static
Chris@16 1581 BOOST_UBLAS_INLINE
Chris@16 1582 size_type index_i (difference_type k, size_type size_i, size_type /* size_j */) {
Chris@16 1583 return size_i != 0 ? k % size_i : 0;
Chris@16 1584 }
Chris@16 1585 static
Chris@16 1586 BOOST_UBLAS_INLINE
Chris@16 1587 size_type index_j (difference_type k, size_type size_i, size_type /* size_j */) {
Chris@16 1588 return size_i != 0 ? k / size_i : 0;
Chris@16 1589 }
Chris@16 1590 static
Chris@16 1591 BOOST_UBLAS_INLINE
Chris@16 1592 bool fast_i () {
Chris@16 1593 return true;
Chris@16 1594 }
Chris@16 1595 static
Chris@16 1596 BOOST_UBLAS_INLINE
Chris@16 1597 bool fast_j () {
Chris@16 1598 return false;
Chris@16 1599 }
Chris@16 1600
Chris@16 1601 // Iterating
Chris@16 1602 template<class I>
Chris@16 1603 static
Chris@16 1604 BOOST_UBLAS_INLINE
Chris@16 1605 void increment_i (I &it, size_type /* size_i */, size_type /* size_j */) {
Chris@16 1606 ++ it;
Chris@16 1607 }
Chris@16 1608 template<class I>
Chris@16 1609 static
Chris@16 1610 BOOST_UBLAS_INLINE
Chris@16 1611 void increment_i (I &it, difference_type n, size_type /* size_i */, size_type /* size_j */) {
Chris@16 1612 it += n;
Chris@16 1613 }
Chris@16 1614 template<class I>
Chris@16 1615 static
Chris@16 1616 BOOST_UBLAS_INLINE
Chris@16 1617 void decrement_i (I &it, size_type /* size_i */, size_type /* size_j */) {
Chris@16 1618 -- it;
Chris@16 1619 }
Chris@16 1620 template<class I>
Chris@16 1621 static
Chris@16 1622 BOOST_UBLAS_INLINE
Chris@16 1623 void decrement_i (I &it, difference_type n, size_type /* size_i */, size_type /* size_j */) {
Chris@16 1624 it -= n;
Chris@16 1625 }
Chris@16 1626 template<class I>
Chris@16 1627 static
Chris@16 1628 BOOST_UBLAS_INLINE
Chris@16 1629 void increment_j (I &it, size_type size_i, size_type /* size_j */) {
Chris@16 1630 it += size_i;
Chris@16 1631 }
Chris@16 1632 template<class I>
Chris@16 1633 static
Chris@16 1634 BOOST_UBLAS_INLINE
Chris@16 1635 void increment_j (I &it, difference_type n, size_type size_i, size_type /* size_j */) {
Chris@16 1636 it += n * size_i;
Chris@16 1637 }
Chris@16 1638 template<class I>
Chris@16 1639 static
Chris@16 1640 BOOST_UBLAS_INLINE
Chris@16 1641 void decrement_j (I &it, size_type size_i, size_type /* size_j */) {
Chris@16 1642 it -= size_i;
Chris@16 1643 }
Chris@16 1644 template<class I>
Chris@16 1645 static
Chris@16 1646 BOOST_UBLAS_INLINE
Chris@16 1647 void decrement_j (I &it, difference_type n, size_type size_i, size_type /* size_j */) {
Chris@16 1648 it -= n* size_i;
Chris@16 1649 }
Chris@16 1650
Chris@16 1651 // Triangular access
Chris@16 1652 static
Chris@16 1653 BOOST_UBLAS_INLINE
Chris@16 1654 size_type triangular_size (size_type size_i, size_type size_j) {
Chris@16 1655 size_type size = (std::max) (size_i, size_j);
Chris@16 1656 // Guard against size_type overflow - simplified
Chris@16 1657 BOOST_UBLAS_CHECK (size == 0 || size / 2 < (std::numeric_limits<size_type>::max) () / size /* +1/2 */, bad_size ());
Chris@16 1658 return ((size + 1) * size) / 2;
Chris@16 1659 }
Chris@16 1660 static
Chris@16 1661 BOOST_UBLAS_INLINE
Chris@16 1662 size_type lower_element (size_type i, size_type size_i, size_type j, size_type size_j) {
Chris@16 1663 BOOST_UBLAS_CHECK (i < size_i, bad_index ());
Chris@16 1664 BOOST_UBLAS_CHECK (j < size_j, bad_index ());
Chris@16 1665 BOOST_UBLAS_CHECK (i >= j, bad_index ());
Chris@16 1666 // FIXME size_type overflow
Chris@16 1667 // sigma_j (size - j) = size * j - j * (j - 1) / 2
Chris@16 1668 // j = 0 1 2 3, sigma = 0 4 7 9
Chris@16 1669 return i - j + (j * (2 * (std::max) (size_i, size_j) - j + 1)) / 2;
Chris@16 1670 }
Chris@16 1671 static
Chris@16 1672 BOOST_UBLAS_INLINE
Chris@16 1673 size_type upper_element (size_type i, size_type size_i, size_type j, size_type size_j) {
Chris@16 1674 BOOST_UBLAS_CHECK (i < size_i, bad_index ());
Chris@16 1675 BOOST_UBLAS_CHECK (j < size_j, bad_index ());
Chris@16 1676 BOOST_UBLAS_CHECK (i <= j, bad_index ());
Chris@16 1677 // FIXME size_type overflow
Chris@16 1678 // sigma_j (j + 1) = (j + 1) * j / 2
Chris@16 1679 // j = 0 1 2 3, sigma = 0 1 3 6
Chris@16 1680 return i + ((j + 1) * j) / 2;
Chris@16 1681 }
Chris@16 1682
Chris@16 1683 // Major and minor indices
Chris@16 1684 static
Chris@16 1685 BOOST_UBLAS_INLINE
Chris@16 1686 size_type index_M (size_type /* index1 */, size_type index2) {
Chris@16 1687 return index2;
Chris@16 1688 }
Chris@16 1689 static
Chris@16 1690 BOOST_UBLAS_INLINE
Chris@16 1691 size_type index_m (size_type index1, size_type /* index2 */) {
Chris@16 1692 return index1;
Chris@16 1693 }
Chris@16 1694 static
Chris@16 1695 BOOST_UBLAS_INLINE
Chris@16 1696 size_type size_M (size_type /* size_i */, size_type size_j) {
Chris@16 1697 return size_j;
Chris@16 1698 }
Chris@16 1699 static
Chris@16 1700 BOOST_UBLAS_INLINE
Chris@16 1701 size_type size_m (size_type size_i, size_type /* size_j */) {
Chris@16 1702 return size_i;
Chris@16 1703 }
Chris@16 1704 };
Chris@16 1705
Chris@16 1706
Chris@16 1707 template <class Z>
Chris@16 1708 struct basic_full {
Chris@16 1709 typedef Z size_type;
Chris@16 1710
Chris@16 1711 template<class L>
Chris@16 1712 static
Chris@16 1713 BOOST_UBLAS_INLINE
Chris@16 1714 size_type packed_size (L, size_type size_i, size_type size_j) {
Chris@16 1715 return L::storage_size (size_i, size_j);
Chris@16 1716 }
Chris@16 1717
Chris@16 1718 static
Chris@16 1719 BOOST_UBLAS_INLINE
Chris@16 1720 bool zero (size_type /* i */, size_type /* j */) {
Chris@16 1721 return false;
Chris@16 1722 }
Chris@16 1723 static
Chris@16 1724 BOOST_UBLAS_INLINE
Chris@16 1725 bool one (size_type /* i */, size_type /* j */) {
Chris@16 1726 return false;
Chris@16 1727 }
Chris@16 1728 static
Chris@16 1729 BOOST_UBLAS_INLINE
Chris@16 1730 bool other (size_type /* i */, size_type /* j */) {
Chris@16 1731 return true;
Chris@16 1732 }
Chris@16 1733 // FIXME: this should not be used at all
Chris@16 1734 static
Chris@16 1735 BOOST_UBLAS_INLINE
Chris@16 1736 size_type restrict1 (size_type i, size_type /* j */) {
Chris@16 1737 return i;
Chris@16 1738 }
Chris@16 1739 static
Chris@16 1740 BOOST_UBLAS_INLINE
Chris@16 1741 size_type restrict2 (size_type /* i */, size_type j) {
Chris@16 1742 return j;
Chris@16 1743 }
Chris@16 1744 static
Chris@16 1745 BOOST_UBLAS_INLINE
Chris@16 1746 size_type mutable_restrict1 (size_type i, size_type /* j */) {
Chris@16 1747 return i;
Chris@16 1748 }
Chris@16 1749 static
Chris@16 1750 BOOST_UBLAS_INLINE
Chris@16 1751 size_type mutable_restrict2 (size_type /* i */, size_type j) {
Chris@16 1752 return j;
Chris@16 1753 }
Chris@16 1754 };
Chris@16 1755
Chris@16 1756 namespace detail {
Chris@16 1757 template < class L >
Chris@16 1758 struct transposed_structure {
Chris@16 1759 typedef typename L::size_type size_type;
Chris@16 1760
Chris@16 1761 template<class LAYOUT>
Chris@16 1762 static
Chris@16 1763 BOOST_UBLAS_INLINE
Chris@16 1764 size_type packed_size (LAYOUT l, size_type size_i, size_type size_j) {
Chris@16 1765 return L::packed_size(l, size_j, size_i);
Chris@16 1766 }
Chris@16 1767
Chris@16 1768 static
Chris@16 1769 BOOST_UBLAS_INLINE
Chris@16 1770 bool zero (size_type i, size_type j) {
Chris@16 1771 return L::zero(j, i);
Chris@16 1772 }
Chris@16 1773 static
Chris@16 1774 BOOST_UBLAS_INLINE
Chris@16 1775 bool one (size_type i, size_type j) {
Chris@16 1776 return L::one(j, i);
Chris@16 1777 }
Chris@16 1778 static
Chris@16 1779 BOOST_UBLAS_INLINE
Chris@16 1780 bool other (size_type i, size_type j) {
Chris@16 1781 return L::other(j, i);
Chris@16 1782 }
Chris@16 1783 template<class LAYOUT>
Chris@16 1784 static
Chris@16 1785 BOOST_UBLAS_INLINE
Chris@16 1786 size_type element (LAYOUT /* l */, size_type i, size_type size_i, size_type j, size_type size_j) {
Chris@16 1787 return L::element(typename LAYOUT::transposed_layout(), j, size_j, i, size_i);
Chris@16 1788 }
Chris@16 1789
Chris@16 1790 static
Chris@16 1791 BOOST_UBLAS_INLINE
Chris@16 1792 size_type restrict1 (size_type i, size_type j, size_type size1, size_type size2) {
Chris@16 1793 return L::restrict2(j, i, size2, size1);
Chris@16 1794 }
Chris@16 1795 static
Chris@16 1796 BOOST_UBLAS_INLINE
Chris@16 1797 size_type restrict2 (size_type i, size_type j, size_type size1, size_type size2) {
Chris@16 1798 return L::restrict1(j, i, size2, size1);
Chris@16 1799 }
Chris@16 1800 static
Chris@16 1801 BOOST_UBLAS_INLINE
Chris@16 1802 size_type mutable_restrict1 (size_type i, size_type j, size_type size1, size_type size2) {
Chris@16 1803 return L::mutable_restrict2(j, i, size2, size1);
Chris@16 1804 }
Chris@16 1805 static
Chris@16 1806 BOOST_UBLAS_INLINE
Chris@16 1807 size_type mutable_restrict2 (size_type i, size_type j, size_type size1, size_type size2) {
Chris@16 1808 return L::mutable_restrict1(j, i, size2, size1);
Chris@16 1809 }
Chris@16 1810
Chris@16 1811 static
Chris@16 1812 BOOST_UBLAS_INLINE
Chris@16 1813 size_type global_restrict1 (size_type index1, size_type size1, size_type index2, size_type size2) {
Chris@16 1814 return L::global_restrict2(index2, size2, index1, size1);
Chris@16 1815 }
Chris@16 1816 static
Chris@16 1817 BOOST_UBLAS_INLINE
Chris@16 1818 size_type global_restrict2 (size_type index1, size_type size1, size_type index2, size_type size2) {
Chris@16 1819 return L::global_restrict1(index2, size2, index1, size1);
Chris@16 1820 }
Chris@16 1821 static
Chris@16 1822 BOOST_UBLAS_INLINE
Chris@16 1823 size_type global_mutable_restrict1 (size_type index1, size_type size1, size_type index2, size_type size2) {
Chris@16 1824 return L::global_mutable_restrict2(index2, size2, index1, size1);
Chris@16 1825 }
Chris@16 1826 static
Chris@16 1827 BOOST_UBLAS_INLINE
Chris@16 1828 size_type global_mutable_restrict2 (size_type index1, size_type size1, size_type index2, size_type size2) {
Chris@16 1829 return L::global_mutable_restrict1(index2, size2, index1, size1);
Chris@16 1830 }
Chris@16 1831 };
Chris@16 1832 }
Chris@16 1833
Chris@16 1834 template <class Z>
Chris@16 1835 struct basic_lower {
Chris@16 1836 typedef Z size_type;
Chris@16 1837 typedef lower_tag triangular_type;
Chris@16 1838
Chris@16 1839 template<class L>
Chris@16 1840 static
Chris@16 1841 BOOST_UBLAS_INLINE
Chris@16 1842 size_type packed_size (L, size_type size_i, size_type size_j) {
Chris@16 1843 return L::triangular_size (size_i, size_j);
Chris@16 1844 }
Chris@16 1845
Chris@16 1846 static
Chris@16 1847 BOOST_UBLAS_INLINE
Chris@16 1848 bool zero (size_type i, size_type j) {
Chris@16 1849 return j > i;
Chris@16 1850 }
Chris@16 1851 static
Chris@16 1852 BOOST_UBLAS_INLINE
Chris@16 1853 bool one (size_type /* i */, size_type /* j */) {
Chris@16 1854 return false;
Chris@16 1855 }
Chris@16 1856 static
Chris@16 1857 BOOST_UBLAS_INLINE
Chris@16 1858 bool other (size_type i, size_type j) {
Chris@16 1859 return j <= i;
Chris@16 1860 }
Chris@16 1861 template<class L>
Chris@16 1862 static
Chris@16 1863 BOOST_UBLAS_INLINE
Chris@16 1864 size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) {
Chris@16 1865 return L::lower_element (i, size_i, j, size_j);
Chris@16 1866 }
Chris@16 1867
Chris@16 1868 // return nearest valid index in column j
Chris@16 1869 static
Chris@16 1870 BOOST_UBLAS_INLINE
Chris@16 1871 size_type restrict1 (size_type i, size_type j, size_type size1, size_type /* size2 */) {
Chris@16 1872 return (std::max)(j, (std::min) (size1, i));
Chris@16 1873 }
Chris@16 1874 // return nearest valid index in row i
Chris@16 1875 static
Chris@16 1876 BOOST_UBLAS_INLINE
Chris@16 1877 size_type restrict2 (size_type i, size_type j, size_type /* size1 */, size_type /* size2 */) {
Chris@16 1878 return (std::max)(size_type(0), (std::min) (i+1, j));
Chris@16 1879 }
Chris@16 1880 // return nearest valid mutable index in column j
Chris@16 1881 static
Chris@16 1882 BOOST_UBLAS_INLINE
Chris@16 1883 size_type mutable_restrict1 (size_type i, size_type j, size_type size1, size_type /* size2 */) {
Chris@16 1884 return (std::max)(j, (std::min) (size1, i));
Chris@16 1885 }
Chris@16 1886 // return nearest valid mutable index in row i
Chris@16 1887 static
Chris@16 1888 BOOST_UBLAS_INLINE
Chris@16 1889 size_type mutable_restrict2 (size_type i, size_type j, size_type /* size1 */, size_type /* size2 */) {
Chris@16 1890 return (std::max)(size_type(0), (std::min) (i+1, j));
Chris@16 1891 }
Chris@16 1892
Chris@16 1893 // return an index between the first and (1+last) filled row
Chris@16 1894 static
Chris@16 1895 BOOST_UBLAS_INLINE
Chris@16 1896 size_type global_restrict1 (size_type index1, size_type size1, size_type /* index2 */, size_type /* size2 */) {
Chris@16 1897 return (std::max)(size_type(0), (std::min)(size1, index1) );
Chris@16 1898 }
Chris@16 1899 // return an index between the first and (1+last) filled column
Chris@16 1900 static
Chris@16 1901 BOOST_UBLAS_INLINE
Chris@16 1902 size_type global_restrict2 (size_type /* index1 */, size_type /* size1 */, size_type index2, size_type size2) {
Chris@16 1903 return (std::max)(size_type(0), (std::min)(size2, index2) );
Chris@16 1904 }
Chris@16 1905
Chris@16 1906 // return an index between the first and (1+last) filled mutable row
Chris@16 1907 static
Chris@16 1908 BOOST_UBLAS_INLINE
Chris@16 1909 size_type global_mutable_restrict1 (size_type index1, size_type size1, size_type /* index2 */, size_type /* size2 */) {
Chris@16 1910 return (std::max)(size_type(0), (std::min)(size1, index1) );
Chris@16 1911 }
Chris@16 1912 // return an index between the first and (1+last) filled mutable column
Chris@16 1913 static
Chris@16 1914 BOOST_UBLAS_INLINE
Chris@16 1915 size_type global_mutable_restrict2 (size_type /* index1 */, size_type /* size1 */, size_type index2, size_type size2) {
Chris@16 1916 return (std::max)(size_type(0), (std::min)(size2, index2) );
Chris@16 1917 }
Chris@16 1918 };
Chris@16 1919
Chris@16 1920 // the first row only contains a single 1. Thus it is not stored.
Chris@16 1921 template <class Z>
Chris@16 1922 struct basic_unit_lower : public basic_lower<Z> {
Chris@16 1923 typedef Z size_type;
Chris@16 1924 typedef unit_lower_tag triangular_type;
Chris@16 1925
Chris@16 1926 template<class L>
Chris@16 1927 static
Chris@16 1928 BOOST_UBLAS_INLINE
Chris@16 1929 size_type packed_size (L, size_type size_i, size_type size_j) {
Chris@16 1930 // Zero size strict triangles are bad at this point
Chris@16 1931 BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0, bad_index ());
Chris@16 1932 return L::triangular_size (size_i - 1, size_j - 1);
Chris@16 1933 }
Chris@16 1934
Chris@16 1935 static
Chris@16 1936 BOOST_UBLAS_INLINE
Chris@16 1937 bool one (size_type i, size_type j) {
Chris@16 1938 return j == i;
Chris@16 1939 }
Chris@16 1940 static
Chris@16 1941 BOOST_UBLAS_INLINE
Chris@16 1942 bool other (size_type i, size_type j) {
Chris@16 1943 return j < i;
Chris@16 1944 }
Chris@16 1945 template<class L>
Chris@16 1946 static
Chris@16 1947 BOOST_UBLAS_INLINE
Chris@16 1948 size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) {
Chris@16 1949 // Zero size strict triangles are bad at this point
Chris@16 1950 BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0 && i != 0, bad_index ());
Chris@16 1951 return L::lower_element (i-1, size_i - 1, j, size_j - 1);
Chris@16 1952 }
Chris@16 1953
Chris@16 1954 static
Chris@16 1955 BOOST_UBLAS_INLINE
Chris@16 1956 size_type mutable_restrict1 (size_type i, size_type j, size_type size1, size_type /* size2 */) {
Chris@16 1957 return (std::max)(j+1, (std::min) (size1, i));
Chris@16 1958 }
Chris@16 1959 static
Chris@16 1960 BOOST_UBLAS_INLINE
Chris@16 1961 size_type mutable_restrict2 (size_type i, size_type j, size_type /* size1 */, size_type /* size2 */) {
Chris@16 1962 return (std::max)(size_type(0), (std::min) (i, j));
Chris@16 1963 }
Chris@16 1964
Chris@16 1965 // return an index between the first and (1+last) filled mutable row
Chris@16 1966 static
Chris@16 1967 BOOST_UBLAS_INLINE
Chris@16 1968 size_type global_mutable_restrict1 (size_type index1, size_type size1, size_type /* index2 */, size_type /* size2 */) {
Chris@16 1969 return (std::max)(size_type(1), (std::min)(size1, index1) );
Chris@16 1970 }
Chris@16 1971 // return an index between the first and (1+last) filled mutable column
Chris@16 1972 static
Chris@16 1973 BOOST_UBLAS_INLINE
Chris@16 1974 size_type global_mutable_restrict2 (size_type /* index1 */, size_type /* size1 */, size_type index2, size_type size2) {
Chris@16 1975 BOOST_UBLAS_CHECK( size2 >= 1 , external_logic() );
Chris@16 1976 return (std::max)(size_type(0), (std::min)(size2-1, index2) );
Chris@16 1977 }
Chris@16 1978 };
Chris@16 1979
Chris@16 1980 // the first row only contains no element. Thus it is not stored.
Chris@16 1981 template <class Z>
Chris@16 1982 struct basic_strict_lower : public basic_unit_lower<Z> {
Chris@16 1983 typedef Z size_type;
Chris@16 1984 typedef strict_lower_tag triangular_type;
Chris@16 1985
Chris@16 1986 template<class L>
Chris@16 1987 static
Chris@16 1988 BOOST_UBLAS_INLINE
Chris@16 1989 size_type packed_size (L, size_type size_i, size_type size_j) {
Chris@16 1990 // Zero size strict triangles are bad at this point
Chris@16 1991 BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0, bad_index ());
Chris@16 1992 return L::triangular_size (size_i - 1, size_j - 1);
Chris@16 1993 }
Chris@16 1994
Chris@16 1995 static
Chris@16 1996 BOOST_UBLAS_INLINE
Chris@16 1997 bool zero (size_type i, size_type j) {
Chris@16 1998 return j >= i;
Chris@16 1999 }
Chris@16 2000 static
Chris@16 2001 BOOST_UBLAS_INLINE
Chris@16 2002 bool one (size_type /*i*/, size_type /*j*/) {
Chris@16 2003 return false;
Chris@16 2004 }
Chris@16 2005 static
Chris@16 2006 BOOST_UBLAS_INLINE
Chris@16 2007 bool other (size_type i, size_type j) {
Chris@16 2008 return j < i;
Chris@16 2009 }
Chris@16 2010 template<class L>
Chris@16 2011 static
Chris@16 2012 BOOST_UBLAS_INLINE
Chris@16 2013 size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) {
Chris@16 2014 // Zero size strict triangles are bad at this point
Chris@16 2015 BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0 && i != 0, bad_index ());
Chris@16 2016 return L::lower_element (i-1, size_i - 1, j, size_j - 1);
Chris@16 2017 }
Chris@16 2018
Chris@16 2019 static
Chris@16 2020 BOOST_UBLAS_INLINE
Chris@16 2021 size_type restrict1 (size_type i, size_type j, size_type size1, size_type size2) {
Chris@16 2022 return basic_unit_lower<Z>::mutable_restrict1(i, j, size1, size2);
Chris@16 2023 }
Chris@16 2024 static
Chris@16 2025 BOOST_UBLAS_INLINE
Chris@16 2026 size_type restrict2 (size_type i, size_type j, size_type size1, size_type size2) {
Chris@16 2027 return basic_unit_lower<Z>::mutable_restrict2(i, j, size1, size2);
Chris@16 2028 }
Chris@16 2029
Chris@16 2030 // return an index between the first and (1+last) filled row
Chris@16 2031 static
Chris@16 2032 BOOST_UBLAS_INLINE
Chris@16 2033 size_type global_restrict1 (size_type index1, size_type size1, size_type index2, size_type size2) {
Chris@16 2034 return basic_unit_lower<Z>::global_mutable_restrict1(index1, size1, index2, size2);
Chris@16 2035 }
Chris@16 2036 // return an index between the first and (1+last) filled column
Chris@16 2037 static
Chris@16 2038 BOOST_UBLAS_INLINE
Chris@16 2039 size_type global_restrict2 (size_type index1, size_type size1, size_type index2, size_type size2) {
Chris@16 2040 return basic_unit_lower<Z>::global_mutable_restrict2(index1, size1, index2, size2);
Chris@16 2041 }
Chris@16 2042 };
Chris@16 2043
Chris@16 2044
Chris@16 2045 template <class Z>
Chris@16 2046 struct basic_upper : public detail::transposed_structure<basic_lower<Z> >
Chris@16 2047 {
Chris@16 2048 typedef upper_tag triangular_type;
Chris@16 2049 };
Chris@16 2050
Chris@16 2051 template <class Z>
Chris@16 2052 struct basic_unit_upper : public detail::transposed_structure<basic_unit_lower<Z> >
Chris@16 2053 {
Chris@16 2054 typedef unit_upper_tag triangular_type;
Chris@16 2055 };
Chris@16 2056
Chris@16 2057 template <class Z>
Chris@16 2058 struct basic_strict_upper : public detail::transposed_structure<basic_strict_lower<Z> >
Chris@16 2059 {
Chris@16 2060 typedef strict_upper_tag triangular_type;
Chris@16 2061 };
Chris@16 2062
Chris@16 2063
Chris@16 2064 }}}
Chris@16 2065
Chris@16 2066 #endif