DriveHQ Start Menu
Cloud Drive Mapping
Folder Sync
Cloud Backup
True Drop Box
FTP/SFTP Hosting
Group Account
DriveHQ Start Menu
Online File Server
My Storage
|
Manage Shares
|
Publishes
|
Drop Boxes
|
Group Account
WebDAV Drive Mapping
Cloud Drive Home
|
WebDAV Guide
|
Drive Mapping Tool
|
Drive Mapping URL
Complete Data Backup
Backup Guide
|
Online Backup Tool
|
Cloud-to-Cloud Backup
FTP, Email & Web Service
FTP Home
|
FTP Hosting FAQ
|
Email Hosting
|
EmailManager
|
Web Hosting
Help & Resources
About
|
Enterprise Service
|
Partnership
|
Comparisons
|
Support
Quick Links
Security and Privacy
Download Software
Service Manual
Use Cases
Group Account
Online Help
Blog
Contact
Cloud Surveillance
Sign Up
Login
Features
Business Features
Online File Server
FTP Hosting
Cloud Drive Mapping
Cloud File Backup
Email Backup & Hosting
Cloud File Sharing
Folder Synchronization
Group Management
True Drop Box
Full-text Search
AD Integration/SSO
Mobile Access
IP Camera & DVR Solution
More...
Personal Features
Personal Cloud Drive
Backup All Devices
Mobile APPs
Personal Web Hosting
Sub-Account (for Kids)
Home/PC/Kids Monitoring
More...
Software
DriveHQ Drive Mapping Tool
DriveHQ FileManager
DriveHQ Online Backup
DriveHQ Mobile Apps
Pricing
Business Plans & Pricing
Personal Plans & Pricing
Price Comparison with Others
Feature Comparison with Others
Install Mobile App
Sign up
Creating account...
Invalid character in username! Only 0-9, a-z, A-Z, _, -, . allowed.
Username is required!
Invalid email address!
E-mail is required!
Password is required!
Password is invalid!
Password and confirmation do not match.
Confirm password is required!
I accept
Membership Agreement
Please read the Membership Agreement and check "I accept"!
Free Quick Sign-up
Sign-up Page
Log in
Signing in...
Username or e-mail address is required!
Password is required!
Keep me logged in
Quick Login
Forgot Password
Up
Upload
Download
Share
Publish
New Folder
New File
Copy
Cut
Delete
Paste
Rate
Upgrade
Rotate
Effect
Edit
Slide
History
// // Copyright (c) 2000-2002 // Joerg Walter, Mathias Koch // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // The authors gratefully acknowledge the support of // GeNeSys mbH & Co. KG in producing this work. // #ifndef _BOOST_UBLAS_FUNCTIONAL_ #define _BOOST_UBLAS_FUNCTIONAL_ #include
#include
#ifdef BOOST_UBLAS_USE_DUFF_DEVICE #include
#endif #ifdef BOOST_UBLAS_USE_SIMD #include
#else namespace boost { namespace numeric { namespace ublas { namespace raw { }}}} #endif #ifdef BOOST_UBLAS_HAVE_BINDINGS #include
#include
#include
#include
#endif #include
namespace boost { namespace numeric { namespace ublas { // Scalar functors // Unary template
struct scalar_unary_functor { typedef T value_type; typedef typename type_traits
::const_reference argument_type; typedef typename type_traits
::value_type result_type; }; template
struct scalar_identity: public scalar_unary_functor
{ typedef typename scalar_unary_functor
::argument_type argument_type; typedef typename scalar_unary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument_type t) { return t; } }; template
struct scalar_negate: public scalar_unary_functor
{ typedef typename scalar_unary_functor
::argument_type argument_type; typedef typename scalar_unary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument_type t) { return - t; } }; template
struct scalar_conj: public scalar_unary_functor
{ typedef typename scalar_unary_functor
::value_type value_type; typedef typename scalar_unary_functor
::argument_type argument_type; typedef typename scalar_unary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument_type t) { return type_traits
::conj (t); } }; // Unary returning real template
struct scalar_real_unary_functor { typedef T value_type; typedef typename type_traits
::const_reference argument_type; typedef typename type_traits
::real_type result_type; }; template
struct scalar_real: public scalar_real_unary_functor
{ typedef typename scalar_real_unary_functor
::value_type value_type; typedef typename scalar_real_unary_functor
::argument_type argument_type; typedef typename scalar_real_unary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument_type t) { return type_traits
::real (t); } }; template
struct scalar_imag: public scalar_real_unary_functor
{ typedef typename scalar_real_unary_functor
::value_type value_type; typedef typename scalar_real_unary_functor
::argument_type argument_type; typedef typename scalar_real_unary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument_type t) { return type_traits
::imag (t); } }; // Binary template
struct scalar_binary_functor { typedef typename type_traits
::const_reference argument1_type; typedef typename type_traits
::const_reference argument2_type; typedef typename promote_traits
::promote_type result_type; }; template
struct scalar_plus: public scalar_binary_functor
{ typedef typename scalar_binary_functor
::argument1_type argument1_type; typedef typename scalar_binary_functor
::argument2_type argument2_type; typedef typename scalar_binary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument1_type t1, argument2_type t2) { return t1 + t2; } }; template
struct scalar_minus: public scalar_binary_functor
{ typedef typename scalar_binary_functor
::argument1_type argument1_type; typedef typename scalar_binary_functor
::argument2_type argument2_type; typedef typename scalar_binary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument1_type t1, argument2_type t2) { return t1 - t2; } }; template
struct scalar_multiplies: public scalar_binary_functor
{ typedef typename scalar_binary_functor
::argument1_type argument1_type; typedef typename scalar_binary_functor
::argument2_type argument2_type; typedef typename scalar_binary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument1_type t1, argument2_type t2) { return t1 * t2; } }; template
struct scalar_divides: public scalar_binary_functor
{ typedef typename scalar_binary_functor
::argument1_type argument1_type; typedef typename scalar_binary_functor
::argument2_type argument2_type; typedef typename scalar_binary_functor
::result_type result_type; static BOOST_UBLAS_INLINE result_type apply (argument1_type t1, argument2_type t2) { return t1 / t2; } }; template
struct scalar_binary_assign_functor { // ISSUE Remove reference to avoid reference to reference problems typedef typename type_traits
::type>::reference argument1_type; typedef typename type_traits
::const_reference argument2_type; }; struct assign_tag {}; struct computed_assign_tag {}; template
struct scalar_assign: public scalar_binary_assign_functor
{ typedef typename scalar_binary_assign_functor
::argument1_type argument1_type; typedef typename scalar_binary_assign_functor
::argument2_type argument2_type; #if BOOST_WORKAROUND( __IBMCPP__, <=600 ) static const bool computed ; #else static const bool computed = false ; #endif static BOOST_UBLAS_INLINE void apply (argument1_type t1, argument2_type t2) { t1 = t2; } template
struct rebind { typedef scalar_assign
other; }; }; #if BOOST_WORKAROUND( __IBMCPP__, <=600 ) template
const bool scalar_assign
::computed = false; #endif template
struct scalar_plus_assign: public scalar_binary_assign_functor
{ typedef typename scalar_binary_assign_functor
::argument1_type argument1_type; typedef typename scalar_binary_assign_functor
::argument2_type argument2_type; #if BOOST_WORKAROUND( __IBMCPP__, <=600 ) static const bool computed ; #else static const bool computed = true ; #endif static BOOST_UBLAS_INLINE void apply (argument1_type t1, argument2_type t2) { t1 += t2; } template
struct rebind { typedef scalar_plus_assign
other; }; }; #if BOOST_WORKAROUND( __IBMCPP__, <=600 ) template
const bool scalar_plus_assign
::computed = true; #endif template
struct scalar_minus_assign: public scalar_binary_assign_functor
{ typedef typename scalar_binary_assign_functor
::argument1_type argument1_type; typedef typename scalar_binary_assign_functor
::argument2_type argument2_type; #if BOOST_WORKAROUND( __IBMCPP__, <=600 ) static const bool computed ; #else static const bool computed = true ; #endif static BOOST_UBLAS_INLINE void apply (argument1_type t1, argument2_type t2) { t1 -= t2; } template
struct rebind { typedef scalar_minus_assign
other; }; }; #if BOOST_WORKAROUND( __IBMCPP__, <=600 ) template
const bool scalar_minus_assign
::computed = true; #endif template
struct scalar_multiplies_assign: public scalar_binary_assign_functor
{ typedef typename scalar_binary_assign_functor
::argument1_type argument1_type; typedef typename scalar_binary_assign_functor
::argument2_type argument2_type; static const bool computed = true; static BOOST_UBLAS_INLINE void apply (argument1_type t1, argument2_type t2) { t1 *= t2; } template
struct rebind { typedef scalar_multiplies_assign
other; }; }; template
struct scalar_divides_assign: public scalar_binary_assign_functor
{ typedef typename scalar_binary_assign_functor
::argument1_type argument1_type; typedef typename scalar_binary_assign_functor
::argument2_type argument2_type; static const bool computed ; static BOOST_UBLAS_INLINE void apply (argument1_type t1, argument2_type t2) { t1 /= t2; } template
struct rebind { typedef scalar_divides_assign
other; }; }; template
const bool scalar_divides_assign
::computed = true; template
struct scalar_binary_swap_functor { typedef typename type_traits
::type>::reference argument1_type; typedef typename type_traits
::type>::reference argument2_type; }; template
struct scalar_swap: public scalar_binary_swap_functor
{ typedef typename scalar_binary_swap_functor
::argument1_type argument1_type; typedef typename scalar_binary_swap_functor
::argument2_type argument2_type; static BOOST_UBLAS_INLINE void apply (argument1_type t1, argument2_type t2) { std::swap (t1, t2); } template
struct rebind { typedef scalar_swap
other; }; }; // Vector functors // Unary returning scalar template
struct vector_scalar_unary_functor { typedef typename V::value_type value_type; typedef typename V::value_type result_type; }; template
struct vector_sum: public vector_scalar_unary_functor
{ typedef typename vector_scalar_unary_functor
::value_type value_type; typedef typename vector_scalar_unary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e) { result_type t = result_type (0); typedef typename E::size_type vector_size_type; vector_size_type size (e ().size ()); for (vector_size_type i = 0; i < size; ++ i) t += e () (i); return t; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (D size, I it) { result_type t = result_type (0); while (-- size >= 0) t += *it, ++ it; return t; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I it, const I &it_end) { result_type t = result_type (0); while (it != it_end) t += *it, ++ it; return t; } }; // Unary returning real scalar template
struct vector_scalar_real_unary_functor { typedef typename V::value_type value_type; typedef typename type_traits
::real_type real_type; typedef real_type result_type; }; template
struct vector_norm_1: public vector_scalar_real_unary_functor
{ typedef typename vector_scalar_real_unary_functor
::value_type value_type; typedef typename vector_scalar_real_unary_functor
::real_type real_type; typedef typename vector_scalar_real_unary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e) { real_type t = real_type (); typedef typename E::size_type vector_size_type; vector_size_type size (e ().size ()); for (vector_size_type i = 0; i < size; ++ i) { real_type u (type_traits
::type_abs (e () (i))); t += u; } return t; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (D size, I it) { real_type t = real_type (); while (-- size >= 0) { real_type u (type_traits
::norm_1 (*it)); t += u; ++ it; } return t; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I it, const I &it_end) { real_type t = real_type (); while (it != it_end) { real_type u (type_traits
::norm_1 (*it)); t += u; ++ it; } return t; } }; template
struct vector_norm_2: public vector_scalar_real_unary_functor
{ typedef typename vector_scalar_real_unary_functor
::value_type value_type; typedef typename vector_scalar_real_unary_functor
::real_type real_type; typedef typename vector_scalar_real_unary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e) { #ifndef BOOST_UBLAS_SCALED_NORM real_type t = real_type (); typedef typename E::size_type vector_size_type; vector_size_type size (e ().size ()); for (vector_size_type i = 0; i < size; ++ i) { real_type u (type_traits
::norm_2 (e () (i))); t += u * u; } return type_traits
::type_sqrt (t); #else real_type scale = real_type (); real_type sum_squares (1); size_type size (e ().size ()); for (size_type i = 0; i < size; ++ i) { real_type u (type_traits
::norm_2 (e () (i))); if (scale < u) { real_type v (scale / u); sum_squares = sum_squares * v * v + real_type (1); scale = u; } else { real_type v (u / scale); sum_squares += v * v; } } return scale * type_traits
::type_sqrt (sum_squares); #endif } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (D size, I it) { #ifndef BOOST_UBLAS_SCALED_NORM real_type t = real_type (); while (-- size >= 0) { real_type u (type_traits
::norm_2 (*it)); t += u * u; ++ it; } return type_traits
::type_sqrt (t); #else real_type scale = real_type (); real_type sum_squares (1); while (-- size >= 0) { real_type u (type_traits
::norm_2 (*it)); if (scale < u) { real_type v (scale / u); sum_squares = sum_squares * v * v + real_type (1); scale = u; } else { real_type v (u / scale); sum_squares += v * v; } ++ it; } return scale * type_traits
::type_sqrt (sum_squares); #endif } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I it, const I &it_end) { #ifndef BOOST_UBLAS_SCALED_NORM real_type t = real_type (); while (it != it_end) { real_type u (type_traits
::norm_2 (*it)); t += u * u; ++ it; } return type_traits
::type_sqrt (t); #else real_type scale = real_type (); real_type sum_squares (1); while (it != it_end) { real_type u (type_traits
::norm_2 (*it)); if (scale < u) { real_type v (scale / u); sum_squares = sum_squares * v * v + real_type (1); scale = u; } else { real_type v (u / scale); sum_squares += v * v; } ++ it; } return scale * type_traits
::type_sqrt (sum_squares); #endif } }; template
struct vector_norm_inf: public vector_scalar_real_unary_functor
{ typedef typename vector_scalar_real_unary_functor
::value_type value_type; typedef typename vector_scalar_real_unary_functor
::real_type real_type; typedef typename vector_scalar_real_unary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e) { real_type t = real_type (); typedef typename E::size_type vector_size_type; vector_size_type size (e ().size ()); for (vector_size_type i = 0; i < size; ++ i) { real_type u (type_traits
::norm_inf (e () (i))); if (u > t) t = u; } return t; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (D size, I it) { real_type t = real_type (); while (-- size >= 0) { real_type u (type_traits
::norm_inf (*it)); if (u > t) t = u; ++ it; } return t; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I it, const I &it_end) { real_type t = real_type (); while (it != it_end) { real_type u (type_traits
::norm_inf (*it)); if (u > t) t = u; ++ it; } return t; } }; // Unary returning index template
struct vector_scalar_index_unary_functor { typedef typename V::value_type value_type; typedef typename type_traits
::real_type real_type; typedef typename V::size_type result_type; }; template
struct vector_index_norm_inf: public vector_scalar_index_unary_functor
{ typedef typename vector_scalar_index_unary_functor
::value_type value_type; typedef typename vector_scalar_index_unary_functor
::real_type real_type; typedef typename vector_scalar_index_unary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e) { // ISSUE For CBLAS compatibility return 0 index in empty case result_type i_norm_inf (0); real_type t = real_type (); typedef typename E::size_type vector_size_type; vector_size_type size (e ().size ()); for (vector_size_type i = 0; i < size; ++ i) { real_type u (type_traits
::norm_inf (e () (i))); if (u > t) { i_norm_inf = i; t = u; } } return i_norm_inf; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (D size, I it) { // ISSUE For CBLAS compatibility return 0 index in empty case result_type i_norm_inf (0); real_type t = real_type (); while (-- size >= 0) { real_type u (type_traits
::norm_inf (*it)); if (u > t) { i_norm_inf = it.index (); t = u; } ++ it; } return i_norm_inf; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I it, const I &it_end) { // ISSUE For CBLAS compatibility return 0 index in empty case result_type i_norm_inf (0); real_type t = real_type (); while (it != it_end) { real_type u (type_traits
::norm_inf (*it)); if (u > t) { i_norm_inf = it.index (); t = u; } ++ it; } return i_norm_inf; } }; // Binary returning scalar template
struct vector_scalar_binary_functor { typedef TV value_type; typedef TV result_type; }; template
struct vector_inner_prod: public vector_scalar_binary_functor
{ typedef typename vector_scalar_binary_functor
::value_type value_type; typedef typename vector_scalar_binary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_container
&c1, const vector_container
&c2) { #ifdef BOOST_UBLAS_USE_SIMD using namespace raw; typedef typename C1::size_type vector_size_type; vector_size_type size (BOOST_UBLAS_SAME (c1 ().size (), c2 ().size ())); const typename V1::value_type *data1 = data_const (c1 ()); const typename V1::value_type *data2 = data_const (c2 ()); vector_size_type s1 = stride (c1 ()); vector_size_type s2 = stride (c2 ()); result_type t = result_type (0); if (s1 == 1 && s2 == 1) { for (vector_size_type i = 0; i < size; ++ i) t += data1 [i] * data2 [i]; } else if (s2 == 1) { for (vector_size_type i = 0, i1 = 0; i < size; ++ i, i1 += s1) t += data1 [i1] * data2 [i]; } else if (s1 == 1) { for (vector_size_type i = 0, i2 = 0; i < size; ++ i, i2 += s2) t += data1 [i] * data2 [i2]; } else { for (vector_size_type i = 0, i1 = 0, i2 = 0; i < size; ++ i, i1 += s1, i2 += s2) t += data1 [i1] * data2 [i2]; } return t; #elif defined(BOOST_UBLAS_HAVE_BINDINGS) return boost::numeric::bindings::atlas::dot (c1 (), c2 ()); #else return apply (static_cast
> (c1), static_cast
> (c2)); #endif } template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e1, const vector_expression
&e2) { typedef typename E1::size_type vector_size_type; vector_size_type size (BOOST_UBLAS_SAME (e1 ().size (), e2 ().size ())); result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (vector_size_type i = 0; i < size; ++ i) t += e1 () (i) * e2 () (i); #else vector_size_type i (0); DD (size, 4, r, (t += e1 () (i) * e2 () (i), ++ i)); #endif return t; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (D size, I1 it1, I2 it2) { result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- size >= 0) t += *it1 * *it2, ++ it1, ++ it2; #else DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2)); #endif return t; } // Packed case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) { result_type t = result_type (0); typedef typename I1::difference_type vector_difference_type; vector_difference_type it1_size (it1_end - it1); vector_difference_type it2_size (it2_end - it2); vector_difference_type diff (0); if (it1_size > 0 && it2_size > 0) diff = it2.index () - it1.index (); if (diff != 0) { vector_difference_type size = (std::min) (diff, it1_size); if (size > 0) { it1 += size; it1_size -= size; diff -= size; } size = (std::min) (- diff, it2_size); if (size > 0) { it2 += size; it2_size -= size; diff += size; } } vector_difference_type size ((std::min) (it1_size, it2_size)); while (-- size >= 0) t += *it1 * *it2, ++ it1, ++ it2; return t; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); if (it1 != it1_end && it2 != it2_end) { while (true) { if (it1.index () == it2.index ()) { t += *it1 * *it2, ++ it1, ++ it2; if (it1 == it1_end || it2 == it2_end) break; } else if (it1.index () < it2.index ()) { increment (it1, it1_end, it2.index () - it1.index ()); if (it1 == it1_end) break; } else if (it1.index () > it2.index ()) { increment (it2, it2_end, it1.index () - it2.index ()); if (it2 == it2_end) break; } } } return t; } }; // Matrix functors // Binary returning vector template
struct matrix_vector_binary_functor { typedef typename M1::size_type size_type; typedef typename M1::difference_type difference_type; typedef TV value_type; typedef TV result_type; }; template
struct matrix_vector_prod1: public matrix_vector_binary_functor
{ typedef typename matrix_vector_binary_functor
::size_type size_type; typedef typename matrix_vector_binary_functor
::difference_type difference_type; typedef typename matrix_vector_binary_functor
::value_type value_type; typedef typename matrix_vector_binary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const matrix_container
&c1, const vector_container
&c2, size_type i) { #ifdef BOOST_UBLAS_USE_SIMD using namespace raw; size_type size = BOOST_UBLAS_SAME (c1 ().size2 (), c2 ().size ()); const typename M1::value_type *data1 = data_const (c1 ()) + i * stride1 (c1 ()); const typename M2::value_type *data2 = data_const (c2 ()); size_type s1 = stride2 (c1 ()); size_type s2 = stride (c2 ()); result_type t = result_type (0); if (s1 == 1 && s2 == 1) { for (size_type j = 0; j < size; ++ j) t += data1 [j] * data2 [j]; } else if (s2 == 1) { for (size_type j = 0, j1 = 0; j < size; ++ j, j1 += s1) t += data1 [j1] * data2 [j]; } else if (s1 == 1) { for (size_type j = 0, j2 = 0; j < size; ++ j, j2 += s2) t += data1 [j] * data2 [j2]; } else { for (size_type j = 0, j1 = 0, j2 = 0; j < size; ++ j, j1 += s1, j2 += s2) t += data1 [j1] * data2 [j2]; } return t; #elif defined(BOOST_UBLAS_HAVE_BINDINGS) return boost::numeric::bindings::atlas::dot (c1 ().row (i), c2 ()); #else return apply (static_cast
> (c1), static_cast
> (c2, i)); #endif } template
static BOOST_UBLAS_INLINE result_type apply (const matrix_expression
&e1, const vector_expression
&e2, size_type i) { size_type size = BOOST_UBLAS_SAME (e1 ().size2 (), e2 ().size ()); result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (size_type j = 0; j < size; ++ j) t += e1 () (i, j) * e2 () (j); #else size_type j (0); DD (size, 4, r, (t += e1 () (i, j) * e2 () (j), ++ j)); #endif return t; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (difference_type size, I1 it1, I2 it2) { result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- size >= 0) t += *it1 * *it2, ++ it1, ++ it2; #else DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2)); #endif return t; } // Packed case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) { result_type t = result_type (0); difference_type it1_size (it1_end - it1); difference_type it2_size (it2_end - it2); difference_type diff (0); if (it1_size > 0 && it2_size > 0) diff = it2.index () - it1.index2 (); if (diff != 0) { difference_type size = (std::min) (diff, it1_size); if (size > 0) { it1 += size; it1_size -= size; diff -= size; } size = (std::min) (- diff, it2_size); if (size > 0) { it2 += size; it2_size -= size; diff += size; } } difference_type size ((std::min) (it1_size, it2_size)); while (-- size >= 0) t += *it1 * *it2, ++ it1, ++ it2; return t; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); if (it1 != it1_end && it2 != it2_end) { size_type it1_index = it1.index2 (), it2_index = it2.index (); while (true) { difference_type compare = it1_index - it2_index; if (compare == 0) { t += *it1 * *it2, ++ it1, ++ it2; if (it1 != it1_end && it2 != it2_end) { it1_index = it1.index2 (); it2_index = it2.index (); } else break; } else if (compare < 0) { increment (it1, it1_end, - compare); if (it1 != it1_end) it1_index = it1.index2 (); else break; } else if (compare > 0) { increment (it2, it2_end, compare); if (it2 != it2_end) it2_index = it2.index (); else break; } } } return t; } // Sparse packed case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &/* it2_end */, sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag) { result_type t = result_type (0); while (it1 != it1_end) { t += *it1 * it2 () (it1.index2 ()); ++ it1; } return t; } // Packed sparse case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &/* it1_end */, I2 it2, const I2 &it2_end, packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); while (it2 != it2_end) { t += it1 () (it1.index1 (), it2.index ()) * *it2; ++ it2; } return t; } // Another dispatcher template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) { typedef typename I1::iterator_category iterator1_category; typedef typename I2::iterator_category iterator2_category; return apply (it1, it1_end, it2, it2_end, iterator1_category (), iterator2_category ()); } }; template
struct matrix_vector_prod2: public matrix_vector_binary_functor
{ typedef typename matrix_vector_binary_functor
::size_type size_type; typedef typename matrix_vector_binary_functor
::difference_type difference_type; typedef typename matrix_vector_binary_functor
::value_type value_type; typedef typename matrix_vector_binary_functor
::result_type result_type; template
static BOOST_UBLAS_INLINE result_type apply (const vector_container
&c1, const matrix_container
&c2, size_type i) { #ifdef BOOST_UBLAS_USE_SIMD using namespace raw; size_type size = BOOST_UBLAS_SAME (c1 ().size (), c2 ().size1 ()); const typename M1::value_type *data1 = data_const (c1 ()); const typename M2::value_type *data2 = data_const (c2 ()) + i * stride2 (c2 ()); size_type s1 = stride (c1 ()); size_type s2 = stride1 (c2 ()); result_type t = result_type (0); if (s1 == 1 && s2 == 1) { for (size_type j = 0; j < size; ++ j) t += data1 [j] * data2 [j]; } else if (s2 == 1) { for (size_type j = 0, j1 = 0; j < size; ++ j, j1 += s1) t += data1 [j1] * data2 [j]; } else if (s1 == 1) { for (size_type j = 0, j2 = 0; j < size; ++ j, j2 += s2) t += data1 [j] * data2 [j2]; } else { for (size_type j = 0, j1 = 0, j2 = 0; j < size; ++ j, j1 += s1, j2 += s2) t += data1 [j1] * data2 [j2]; } return t; #elif defined(BOOST_UBLAS_HAVE_BINDINGS) return boost::numeric::bindings::atlas::dot (c1 (), c2 ().column (i)); #else return apply (static_cast
> (c1), static_cast
> (c2, i)); #endif } template
static BOOST_UBLAS_INLINE result_type apply (const vector_expression
&e1, const matrix_expression
&e2, size_type i) { size_type size = BOOST_UBLAS_SAME (e1 ().size (), e2 ().size1 ()); result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE for (size_type j = 0; j < size; ++ j) t += e1 () (j) * e2 () (j, i); #else size_type j (0); DD (size, 4, r, (t += e1 () (j) * e2 () (j, i), ++ j)); #endif return t; } // Dense case template
static BOOST_UBLAS_INLINE result_type apply (difference_type size, I1 it1, I2 it2) { result_type t = result_type (0); #ifndef BOOST_UBLAS_USE_DUFF_DEVICE while (-- size >= 0) t += *it1 * *it2, ++ it1, ++ it2; #else DD (size, 4, r, (t += *it1 * *it2, ++ it1, ++ it2)); #endif return t; } // Packed case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end) { result_type t = result_type (0); difference_type it1_size (it1_end - it1); difference_type it2_size (it2_end - it2); difference_type diff (0); if (it1_size > 0 && it2_size > 0) diff = it2.index1 () - it1.index (); if (diff != 0) { difference_type size = (std::min) (diff, it1_size); if (size > 0) { it1 += size; it1_size -= size; diff -= size; } size = (std::min) (- diff, it2_size); if (size > 0) { it2 += size; it2_size -= size; diff += size; } } difference_type size ((std::min) (it1_size, it2_size)); while (-- size >= 0) t += *it1 * *it2, ++ it1, ++ it2; return t; } // Sparse case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); if (it1 != it1_end && it2 != it2_end) { size_type it1_index = it1.index (), it2_index = it2.index1 (); while (true) { difference_type compare = it1_index - it2_index; if (compare == 0) { t += *it1 * *it2, ++ it1, ++ it2; if (it1 != it1_end && it2 != it2_end) { it1_index = it1.index (); it2_index = it2.index1 (); } else break; } else if (compare < 0) { increment (it1, it1_end, - compare); if (it1 != it1_end) it1_index = it1.index (); else break; } else if (compare > 0) { increment (it2, it2_end, compare); if (it2 != it2_end) it2_index = it2.index1 (); else break; } } } return t; } // Packed sparse case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &/* it1_end */, I2 it2, const I2 &it2_end, packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag) { result_type t = result_type (0); while (it2 != it2_end) { t += it1 () (it2.index1 ()) * *it2; ++ it2; } return t; } // Sparse packed case template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &/* it2_end */, sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag) { result_type t = result_type (0); while (it1 != it1_end) { t += *it1 * it2 () (it1.index (), it2.index2 ()); ++ it1; } return t; } // Another dispatcher template
static BOOST_UBLAS_INLINE result_type apply (I1 it1, const I1 &it1_end, I2 it2, const I2 &it2_end, sparse_bidirectional_iterator_tag) { typedef typename I1::iterator_category iterator1_category; typedef typename I2::iterator_category iterator2_category; return apply (it1, it1_end, it2, it2_end, iterator1_category (), iterator2_category ()); } }; // Binary returning matrix template
struct matrix_matrix_binary_functor { typedef typename M1::size_type size_type; typedef typename M1::difference_type difference_type; typedef TV value_type; typedef TV result_type; }; template
struct matrix_matrix_prod: public matrix_matrix_binary_functor
{ typedef typename matrix_matrix_binary_functor