33 #ifndef __VMML__VECTOR__HPP__
34 #define __VMML__VECTOR__HPP__
36 #include <vmmlib/vmmlib_config.hpp>
37 #include <vmmlib/math.hpp>
38 #include <vmmlib/enable_if.hpp>
39 #include <vmmlib/exception.hpp>
52 template<
size_t M,
typename T =
float >
58 typedef const T* const_iterator;
59 typedef std::reverse_iterator< iterator > reverse_iterator;
60 typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
62 static const size_t DIMENSION = M;
66 explicit vector(
const T& a );
67 vector(
const T& x,
const T& y );
68 vector(
const T& x,
const T& y,
const T& z );
69 vector(
const T& x,
const T& y,
const T& z,
const T& w );
79 template<
typename OSGVEC3 >
80 explicit vector(
const OSGVEC3& from,
81 typename enable_if< M == 3, OSGVEC3 >::type* = 0 );
88 typename enable_if< N == M - 1 >::type* = 0 );
93 typename enable_if< N == M + 1 >::type* = 0 );
98 inline iterator begin();
99 inline iterator end();
100 inline const_iterator begin()
const;
101 inline const_iterator end()
const;
102 inline reverse_iterator rbegin();
103 inline reverse_iterator rend();
104 inline const_reverse_iterator rbegin()
const;
105 inline const_reverse_iterator rend()
const;
107 # ifndef VMMLIB_NO_CONVERSION_OPERATORS
109 inline operator T*();
110 inline operator const T*()
const;
112 inline T& operator[](
size_t index );
113 inline const T& operator[](
size_t index )
const;
117 inline T& operator()(
size_t index );
118 inline const T& operator()(
size_t index )
const;
120 inline T& at(
size_t index );
121 inline const T& at(
size_t index )
const;
128 inline const T& x()
const;
129 inline const T& y()
const;
130 inline const T& z()
const;
131 inline const T& w()
const;
138 inline const T& r()
const;
139 inline const T& g()
const;
140 inline const T& b()
const;
141 inline const T& a()
const;
143 bool operator==(
const vector& other )
const;
144 bool operator!=(
const vector& other )
const;
145 bool equals(
const vector& other,
146 T tolerance = std::numeric_limits< T >::epsilon() )
const;
147 bool operator<(
const vector& other )
const;
150 vector& operator=(
const T* c_array );
151 T operator=( T filler );
153 vector& operator=(
const vector& other );
156 template<
typename U >
void operator=(
const vector< M, U >& other );
167 typename enable_if< N == M + 1 >::type*
170 vector operator*(
const vector& other )
const;
171 vector operator/(
const vector& other )
const;
172 vector operator+(
const vector& other )
const;
173 vector operator-(
const vector& other )
const;
175 void operator*=(
const vector& other );
176 void operator/=(
const vector& other );
177 void operator+=(
const vector& other );
178 void operator-=(
const vector& other );
180 vector operator*(
const T other )
const;
181 vector operator/(
const T other )
const;
182 vector operator+(
const T other )
const;
183 vector operator-(
const T other )
const;
185 void operator*=(
const T other );
186 void operator/=(
const T other );
187 void operator+=(
const T other );
188 void operator-=(
const T other );
190 vector operator-()
const;
192 const vector& negate();
202 void set( T x, T y );
203 void set( T x, T y, T z );
204 void set( T x, T y, T z, T w );
206 template<
typename input_iterator_t >
207 void iter_set( input_iterator_t begin_, input_iterator_t end_ );
214 template<
typename TT >
216 typename enable_if< M == 3, TT >::type* = 0 )
const;
219 template<
typename TT >
221 typename enable_if< M == 3, TT >::type* = 0 );
227 inline T dot(
const vector& other )
const;
233 inline T normalize();
239 void set_random(
int seed = -1 );
241 inline T length()
const;
242 inline T squared_length()
const;
244 inline T distance(
const vector& other )
const;
245 inline T squared_distance(
const vector& other )
const;
250 template<
typename TT >
252 typename enable_if< M == 3, TT >::type* = 0 )
const;
256 void compute_normal(
const vector& v0,
const vector& v1,
const vector& v2 );
258 vector compute_normal(
const vector& v1,
const vector& v2 )
const;
271 template<
typename TT >
274 typename enable_if< M == 4, TT >::type* = 0 )
const;
277 template<
typename TT >
279 typename enable_if< M == 4, TT >::type* = 0 )
const;
282 template<
typename TT >
284 typename enable_if< M == 4, TT >::type* = 0 )
const;
286 template<
typename TT >
289 typename enable_if< M == 4, TT >::type* = 0 )
const;
292 size_t find_min_index()
const;
293 size_t find_max_index()
const;
296 size_t find_abs_min_index()
const;
297 size_t find_abs_max_index()
const;
302 const T& find_min()
const;
303 const T& find_max()
const;
305 void clamp(
const T& min = 0.0,
const T& max = 1.0 );
307 template<
typename TT >
309 T min_value = -1.0, T max_value = 1.0 )
const;
311 inline static size_t size();
313 bool is_unit_vector()
const;
316 void perturb( T perturbation = 0.0001 );
318 void sqrt_elementwise();
326 void reciprocal_safe();
328 template<
typename TT >
336 friend std::ostream& operator<< ( std::ostream& os,
const vector& vector_ )
338 const std::ios::fmtflags flags = os.flags();
339 const int prec = os.precision();
341 os.setf( std::ios::right, std::ios::adjustfield );
344 for(
size_t index = 0; index < M; ++index )
345 os << std::setw(10) << vector_.at( index ) <<
" ";
347 os.precision( prec );
356 static const vector FORWARD;
357 static const vector BACKWARD;
358 static const vector UP;
359 static const vector DOWN;
360 static const vector LEFT;
361 static const vector RIGHT;
363 static const vector ONE;
364 static const vector ZERO;
367 static const vector UNIT_X;
368 static const vector UNIT_Y;
369 static const vector UNIT_Z;
378 template<
size_t M,
typename T >
380 template<
size_t M,
typename T >
382 template<
size_t M,
typename T >
384 template<
size_t M,
typename T >
386 template<
size_t M,
typename T >
388 template<
size_t M,
typename T >
390 template<
size_t M,
typename T >
393 template<
size_t M,
typename T >
395 template<
size_t M,
typename T >
398 template<
size_t M,
typename T >
400 template<
size_t M,
typename T >
404 #ifndef VMMLIB_NO_TYPEDEFS
406 typedef UINT8 uint8_t;
427 template<
size_t M,
typename T >
430 return a.equals( b );
435 template<
size_t M,
typename T >
436 static vector< M, T > operator* ( T factor,
const vector< M, T >& vector_ )
438 return vector_ * factor;
442 template<
size_t M,
typename T >
443 inline T dot(
const vector< M, T >& first,
const vector< M, T >& second )
445 return first.dot( second );
449 template<
size_t M,
typename T >
456 template<
size_t M,
typename T >
457 inline vector< M, T > normalize(
const vector< M, T >& vector_ )
459 vector< M, T > v( vector_ );
464 template<
typename T >
474 plane.w() = -plane.x() * a.x() - plane.y() * a.y() - plane.z() * a.z();
478 template<
size_t M,
typename T >
479 vector< M, T >::vector(
const T& _a )
481 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
487 template<
size_t M,
typename T >
488 vector< M, T >::vector(
const T& _x,
const T& _y )
495 template<
size_t M,
typename T >
496 vector< M, T >::vector(
const T& _x,
const T& _y,
const T& _z )
505 template<
size_t M,
typename T >
506 vector< M, T >::vector(
const T& _x,
const T& _y,
const T& _z,
const T& _w )
515 template<
size_t M,
typename T >
516 vector< M, T >::vector(
const T* values )
518 memcpy( array, values, M *
sizeof( T ));
522 template<
size_t M,
typename T >
523 template<
typename OSGVEC3 >
524 vector< M, T >::vector(
const OSGVEC3& from,
525 typename enable_if< M == 3, OSGVEC3 >::type* )
527 array[ 0 ] = from.x();
528 array[ 1 ] = from.y();
529 array[ 2 ] = from.z();
534 template<
size_t M,
typename T >
536 vector< M, T >::vector(
const vector< M-1, T >& vector_, T last_ )
538 typename vector< M-1, T >::const_iterator
539 it = vector_.begin(), it_end = vector_.end();
541 iterator my_it = begin();
543 for( ; it != it_end; ++it, ++my_it )
554 template<
size_t M,
typename T >
556 vector< M, T >::vector(
const vector< N, T >& source_,
557 typename enable_if< N == M - 1 >::type* )
566 template<
size_t M,
typename T >
568 vector< M, T >::vector(
const vector< N, T >& source_,
569 typename enable_if< N == M + 1 >::type* )
575 template<
size_t M,
typename T >
576 template<
typename U >
577 vector< M, T >::vector(
const vector< M, U >& source_ )
584 template<
size_t M,
typename T >
void vector< M, T >::set( T _a )
586 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
592 template<
size_t M,
typename T >
593 void vector< M, T >::set(
const vector< M-1, T >& v, T _a )
595 memcpy( array, v.array,
sizeof( T ) * (M-1) );
600 template<
size_t M,
typename T >
template<
size_t N >
601 void vector< M, T >::set(
const vector< N, T >& v )
604 if (N < M) minimum = N;
605 memcpy( array, v.array,
sizeof( T ) * minimum );
608 template<
size_t M,
typename T >
609 void vector< M, T >::set( T _x, T _y )
616 template<
size_t M,
typename T >
617 void vector< M, T >::set( T _x, T _y, T _z )
626 template<
size_t M,
typename T >
627 void vector< M, T >::set( T _x, T _y, T _z, T _w )
636 template<
size_t M,
typename T >
638 vector< M, T >::operator()(
size_t index )
645 template<
size_t M,
typename T >
647 vector< M, T >::operator()(
size_t index )
const
654 template<
size_t M,
typename T >
656 vector< M, T >::at(
size_t index )
658 #ifdef VMMLIB_SAFE_ACCESSORS
661 VMMLIB_ERROR(
"at() - index out of bounds", VMMLIB_HERE );
664 return array[ index ];
669 template<
size_t M,
typename T >
671 vector< M, T >::at(
size_t index )
const
673 #ifdef VMMLIB_SAFE_ACCESSORS
676 VMMLIB_ERROR(
"at() - index out of bounds", VMMLIB_HERE );
679 return array[ index ];
683 #ifndef VMMLIB_NO_CONVERSION_OPERATORS
685 template<
size_t M,
typename T >
686 vector< M, T >::operator T*()
693 template<
size_t M,
typename T >
694 vector< M, T >::operator
const T*()
const
700 template<
size_t M,
typename T >
702 vector< M, T >::operator[](
size_t index )
707 template<
size_t M,
typename T >
709 vector< M, T >::operator[](
size_t index )
const
719 template<
size_t M,
typename T >
721 vector< M, T >::operator[](
size_t index )
728 template<
size_t M,
typename T >
730 vector< M, T >::operator[](
size_t index )
const
737 template<
size_t M,
typename T >
739 vector< M, T >::operator*(
const vector< M, T >& other )
const
741 vector< M, T > result;
742 for(
size_t index = 0; index < M; ++index )
743 result.at( index ) = at( index ) * other.at( index );
749 template<
size_t M,
typename T >
751 vector< M, T >::operator/(
const vector< M, T >& other )
const
753 vector< M, T > result;
754 for(
size_t index = 0; index < M; ++index )
755 result.at( index ) = at( index ) / other.at( index );
761 template<
size_t M,
typename T >
763 vector< M, T >::operator+(
const vector< M, T >& other )
const
765 vector< M, T > result;
766 for(
size_t index = 0; index < M; ++index )
767 result.at( index ) = at( index ) + other.at( index );
773 template<
size_t M,
typename T >
775 vector< M, T >::operator-(
const vector< M, T >& other )
const
777 vector< M, T > result;
778 for(
size_t index = 0; index < M; ++index )
779 result.at( index ) = at( index ) - other.at( index );
786 template<
size_t M,
typename T >
788 vector< M, T >::operator*=(
const vector< M, T >& other )
790 for(
size_t index = 0; index < M; ++index )
791 at( index ) *= other.at( index );
796 template<
size_t M,
typename T >
798 vector< M, T >::operator/=(
const vector< M, T >& other )
800 for(
size_t index = 0; index < M; ++index )
801 at( index ) /= other.at( index );
806 template<
size_t M,
typename T >
808 vector< M, T >::operator+=(
const vector< M, T >& other )
810 for(
size_t index = 0; index < M; ++index )
811 at( index ) += other.at( index );
816 template<
size_t M,
typename T >
818 vector< M, T >::operator-=(
const vector< M, T >& other )
820 for(
size_t index = 0; index < M; ++index )
821 at( index ) -= other.at( index );
826 template<
size_t M,
typename T >
828 vector< M, T >::operator*(
const T other )
const
830 vector< M, T > result;
831 for(
size_t index = 0; index < M; ++index )
832 result.at( index ) = at( index ) * other;
838 template<
size_t M,
typename T >
840 vector< M, T >::operator/(
const T other )
const
842 vector< M, T > result;
843 for(
size_t index = 0; index < M; ++index )
844 result.at( index ) = at( index ) / other;
850 template<
size_t M,
typename T >
852 vector< M, T >::operator+(
const T other )
const
854 vector< M, T > result;
855 for(
size_t index = 0; index < M; ++index )
856 result.at( index ) = at( index ) + other;
862 template<
size_t M,
typename T >
864 vector< M, T >::operator-(
const T other )
const
866 vector< M, T > result;
867 for(
size_t index = 0; index < M; ++index )
868 result.at( index ) = at( index ) - other;
875 template<
size_t M,
typename T >
877 vector< M, T >::operator*=(
const T other )
879 for(
size_t index = 0; index < M; ++index )
880 at( index ) *= other;
885 template<
size_t M,
typename T >
887 vector< M, T >::operator/=(
const T other )
889 for(
size_t index = 0; index < M; ++index )
890 at( index ) /= other;
895 template<
size_t M,
typename T >
897 vector< M, T >::operator+=(
const T other )
899 for(
size_t index = 0; index < M; ++index )
900 at( index ) += other;
905 template<
size_t M,
typename T >
907 vector< M, T >::operator-=(
const T other )
909 for(
size_t index = 0; index < M; ++index )
910 at( index ) -= other;
915 template<
size_t M,
typename T >
917 vector< M, T >::operator-()
const
919 vector< M, T > v( *
this );
925 template<
size_t M,
typename T >
926 const vector< M, T >&
927 vector< M, T >::negate()
929 for(
size_t index = 0; index < M; ++index )
930 array[ index ] = -array[ index ];
936 template<
size_t M,
typename T >
945 template<
size_t M,
typename T >
954 template<
size_t M,
typename T >
963 template<
size_t M,
typename T >
972 template<
size_t M,
typename T >
974 vector< M, T >::x()
const
981 template<
size_t M,
typename T >
983 vector< M, T >::y()
const
990 template<
size_t M,
typename T >
992 vector< M, T >::z()
const
999 template<
size_t M,
typename T >
1001 vector< M, T >::w()
const
1007 template<
size_t M,
typename T >
1016 template<
size_t M,
typename T >
1025 template<
size_t M,
typename T >
1034 template<
size_t M,
typename T >
1043 template<
size_t M,
typename T >
1045 vector< M, T >::r()
const
1052 template<
size_t M,
typename T >
1054 vector< M, T >::g()
const
1061 template<
size_t M,
typename T >
1063 vector< M, T >::b()
const
1070 template<
size_t M,
typename T >
1072 vector< M, T >::a()
const
1078 template<
size_t M,
typename T >
1079 template<
typename TT >
1080 inline vector< M, T > vector< M, T >::cross(
const vector< M, TT >& rhs,
1081 typename enable_if< M == 3, TT >::type* )
const
1083 vector< M, T > result;
1084 result.cross( *
this, rhs );
1091 template<
size_t M,
typename T >
1092 template<
typename TT >
1093 void vector< M, T >::cross(
const vector< M, TT >& aa,
1094 const vector< M, TT >& bb,
1095 typename enable_if< M == 3, TT >::type* )
1097 array[ 0 ] = aa.y() * bb.z() - aa.z() * bb.y();
1098 array[ 1 ] = aa.z() * bb.x() - aa.x() * bb.z();
1099 array[ 2 ] = aa.x() * bb.y() - aa.y() * bb.x();
1104 template<
size_t M,
typename T >
1105 inline T vector< M, T >::dot(
const vector< M, T >& other )
const
1108 for(
size_t index = 0; index < M; ++index )
1109 tmp += at( index ) * other.at( index );
1115 template<
size_t M,
typename T >
1116 inline T vector< M, T >::normalize()
1118 const T len = length();
1123 const T tmp = 1.0 / len;
1128 template<
size_t M,
typename T >
1129 inline T vector< M, T >::length()
const
1131 return std::sqrt( squared_length() );
1134 template<
size_t M,
typename T >
1135 inline T vector< M, T >::squared_length()
const
1137 T _squared_length = 0.0;
1138 for( const_iterator it = begin(), it_end = end(); it != it_end; ++it )
1139 _squared_length += (*it) * (*it);
1141 return _squared_length;
1146 template<
size_t M,
typename T >
1148 vector< M, T >::distance(
const vector< M, T >& other )
const
1150 return std::sqrt( squared_distance( other ) );
1155 template<
size_t M,
typename T >
1156 inline T vector< M, T >::squared_distance(
const vector< M, T >& other )
const
1158 vector< M, T > tmp( *
this );
1160 return tmp.squared_length();
1166 for(
size_t i = 1; i < M; ++i )
1171 template<
size_t M,
typename T >
1186 template<
size_t M,
typename T >
1188 vector< M, T >::compute_normal(
const vector< M, T >& bb,
1189 const vector< M, T >& cc )
const
1192 tmp.compute_normal( *
this, bb, cc);
1196 template<
size_t M,
typename T >
1197 template<
typename TT >
1198 vector< 3, T > vector< M, T >::rotate(
const T theta, vector< M, TT > axis,
1199 typename enable_if< M == 3, TT >::type* )
const
1203 const T costheta = std::cos( theta );
1204 const T sintheta = std::sin( theta );
1207 (costheta + ( 1.0f - costheta ) * axis.x() * axis.x() ) * x() +
1208 (( 1 - costheta ) * axis.x() * axis.y() - axis.z() * sintheta ) * y() +
1209 (( 1 - costheta ) * axis.x() * axis.z() + axis.y() * sintheta ) * z(),
1211 (( 1 - costheta ) * axis.x() * axis.y() + axis.z() * sintheta ) * x() +
1212 ( costheta + ( 1 - costheta ) * axis.y() * axis.y() ) * y() +
1213 (( 1 - costheta ) * axis.y() * axis.z() - axis.x() * sintheta ) * z(),
1215 (( 1 - costheta ) * axis.x() * axis.z() - axis.y() * sintheta ) * x() +
1216 (( 1 - costheta ) * axis.y() * axis.z() + axis.x() * sintheta ) * y() +
1217 ( costheta + ( 1 - costheta ) * axis.z() * axis.z() ) * z() );
1222 template<
size_t M,
typename T >
1223 template<
typename TT >
1226 project_point_onto_sphere(
const vector< 3, TT >& point,
1227 typename enable_if< M == 4, TT >::type* )
const
1232 projected_point -= _center;
1233 projected_point.normalize();
1234 projected_point *= w();
1235 return _center + projected_point;
1241 template<
size_t M,
typename T >
1242 template<
typename TT >
1245 distance_to_sphere(
const vector< 3, TT >& point,
1246 typename enable_if< M == 4, TT >::type* )
const
1249 return ( point - center_ ).length() - w();
1252 template<
size_t M,
typename T >
template<
size_t N >
inline
1256 assert( offset <= M - N );
1257 return reinterpret_cast< vector< N, T >&
>( *( begin() + offset ) );
1260 template<
size_t M,
typename T >
template<
size_t N >
inline
1264 assert( offset <= M - N );
1265 return reinterpret_cast< const vector< N, T >&
>( *( begin() + offset ) );
1270 template<
size_t M,
typename T >
template<
typename TT >
1272 typename enable_if< M == 4, TT >::type* )
const
1275 return normal.dot( point ) + w();
1281 template<
size_t M,
typename T >
1282 template<
typename TT >
1284 vector< M, T >::project_point_onto_plane(
const vector< 3, TT >& point,
1285 typename enable_if< M == 4, TT >::type* )
const
1288 return point - ( normal * distance_to_plane( point ) );
1293 template<
size_t M,
typename T >
1294 bool vector< M, T >::operator==(
const vector< M, T >& other )
const
1296 return memcmp( array, other.array,
sizeof( array )) == 0;
1300 template<
size_t M,
typename T >
1301 bool vector< M, T >::operator!=(
const vector< M, T >& other )
const
1303 return ! this->operator==( other );
1307 template<
size_t M,
typename T >
1309 vector< M, T >::equals(
const vector< M, T >& other, T tolerance )
const
1311 for(
size_t index = 0; index < M; ++index )
1312 if( fabs( at( index ) - other( index ) ) >= tolerance )
1319 template<
size_t M,
typename T >
1321 vector< M, T >::operator<(
const vector< M, T >& other )
const
1323 for(
size_t index = 0; index < M; ++index )
1325 if (at( index ) < other.at( index ))
return true;
1326 if (other.at( index ) < at( index ))
return false;
1334 template<
size_t M,
typename T >
template<
size_t N >
1335 typename enable_if< N == M - 1 >::type*
1336 vector< M, T >::operator=(
const vector< N, T >& source_ )
1338 std::copy( source_.begin(), source_.end(), begin() );
1339 at( M - 1 ) =
static_cast< T
>( 1.0 );
1346 template<
size_t M,
typename T >
template<
size_t N >
1347 typename enable_if< N == M + 1 >::type*
1348 vector< M, T >::operator=(
const vector< N, T >& source_ )
1350 const T w_reci =
static_cast< T
>( 1.0 ) / source_( M );
1351 iterator it = begin(), it_end = end();
1352 for(
size_t index = 0; it != it_end; ++it, ++index )
1353 *it = source_( index ) * w_reci;
1358 template<
size_t M,
typename T >
1359 vector< M, T >& vector< M, T >::operator=(
const T* c_array )
1361 iter_set( c_array, c_array + M );
1367 template<
size_t M,
typename T >
1368 T vector< M, T >::operator=( T filler_value )
1370 for(
size_t index = 0; index < M; ++index )
1371 at( index ) = filler_value;
1372 return filler_value;
1378 template<
size_t M,
typename T >
1379 vector< M, T >& vector< M, T >::operator=(
const vector< M, T >& other )
1381 if(
this != &other )
1382 memcpy( array, other.array, M *
sizeof( T ) );
1389 template<
size_t M,
typename T >
template<
typename U >
1390 void vector< M, T >::operator=(
const vector< M, U >& source_ )
1392 typedef typename vector< M, U >::const_iterator u_c_iter;
1393 u_c_iter it = source_.begin(), it_end = source_.end();
1394 for( iterator my_it = begin(); it != it_end; ++it, ++my_it )
1395 *my_it = static_cast< T >( *it );
1400 template<
size_t M,
typename T >
1401 template<
typename input_iterator_t >
1403 vector< M, T >::iter_set( input_iterator_t begin_, input_iterator_t end_ )
1405 input_iterator_t in_it = begin_;
1406 iterator it = begin(), it_end = end();
1407 for( ; it != it_end && in_it != end_; ++it, ++in_it )
1408 (*it) =
static_cast< T
>( *in_it );
1411 template<
size_t M,
typename T >
1412 void vector< M, T >::clamp(
const T& min,
const T& max )
1414 for(
size_t i = 0; i < M; ++i )
1416 if( array[i] < min )
1418 if( array[i] > max )
1425 template<
size_t M,
typename T >
1426 template<
typename TT >
1428 vector< M, T >::scale_to( vector< M, TT >& result_,
1429 T min_value, T max_value )
const
1431 T range = max_value-min_value;
1432 T half_range = range * 0.5;
1433 T scale = ( 1.0 / range ) * static_cast< T >( std::numeric_limits< TT >::max() );
1435 for(
size_t index = 0; index < M; ++index )
1438 =
static_cast< TT
>( ( at( index ) + half_range ) * scale );
1445 template<
size_t M,
typename T >
1447 vector< M, T >::size()
1454 template<
size_t M,
typename T >
1456 vector< M, T >::find_min_index()
const
1458 return std::min_element( begin(), end() ) - begin();
1463 template<
size_t M,
typename T >
1465 vector< M, T >::find_max_index()
const
1467 return std::max_element( begin(), end() ) - begin();
1472 template<
size_t M,
typename T >
1474 vector< M, T >::find_abs_min_index()
const
1481 template<
size_t M,
typename T >
1483 vector< M, T >::find_abs_max_index()
const
1490 template<
size_t M,
typename T >
1492 vector< M, T >::find_min()
1494 return *std::min_element( begin(), end() );
1499 template<
size_t M,
typename T >
1501 vector< M, T >::find_min()
const
1503 return *std::min_element( begin(), end() );
1508 template<
size_t M,
typename T >
1510 vector< M, T >::find_max()
1512 return *std::max_element( begin(), end() );
1517 template<
size_t M,
typename T >
1519 vector< M, T >::find_max()
const
1521 return *std::max_element( begin(), end() );
1525 template<
size_t M,
typename T >
1526 inline typename vector< M, T >::iterator
1527 vector< M, T >::begin()
1533 template<
size_t M,
typename T >
1534 inline typename vector< M, T >::iterator
1535 vector< M, T >::end()
1541 template<
size_t M,
typename T >
1542 inline typename vector< M, T >::const_iterator
1543 vector< M, T >::begin()
const
1549 template<
size_t M,
typename T >
1550 inline typename vector< M, T >::const_iterator
1551 vector< M, T >::end()
const
1558 template<
size_t M,
typename T >
1559 inline typename vector< M, T >::reverse_iterator
1560 vector< M, T >::rbegin()
1562 return array + M - 1;
1566 template<
size_t M,
typename T >
1567 inline typename vector< M, T >::reverse_iterator
1568 vector< M, T >::rend()
1574 template<
size_t M,
typename T >
1575 inline typename vector< M, T >::const_reverse_iterator
1576 vector< M, T >::rbegin()
const
1578 return array + M - 1;
1582 template<
size_t M,
typename T >
1583 inline typename vector< M, T >::const_reverse_iterator
1584 vector< M, T >::rend()
const
1591 template<
size_t M,
typename T >
1593 vector< M, T >::is_unit_vector()
const
1595 const_iterator it = begin(), it_end = end();
1597 for( ; it != it_end; ++it )
1605 else if ( *it != 0.0 )
1616 template<
size_t M,
typename T >
1618 vector< M, T >::perturb( T perturbation )
1620 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
1622 (*it) += ( rand() & 1u ) ? perturbation : -perturbation;
1627 template<
size_t M,
typename T >
1629 vector< M, T >::sqrt_elementwise()
1631 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
1633 (*it) = std::sqrt(*it);
1639 template<
size_t M,
typename T >
1641 vector< M, T >::reciprocal()
1643 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
1645 (*it) =
static_cast< T
>( 1.0 ) / (*it);
1651 template<
size_t M,
typename T >
1653 vector< M, T >::reciprocal_safe()
1655 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
1659 if ( v == static_cast< T >( 0 ) )
1660 v = std::numeric_limits< T >::max();
1662 v =
static_cast< T
>( 1.0 ) / v;
1668 template<
size_t M,
typename T >
1669 template<
typename TT >
1671 vector< M, T >::cast_from(
const vector< M, TT >& other )
1674 typedef typename vector_tt_type::const_iterator tt_const_iterator;
1676 iterator it = begin(), it_end = end();
1677 tt_const_iterator other_it = other.begin();
1678 for( ; it != it_end; ++it, ++other_it )
1680 *it =
static_cast< T
>( *other_it );
1684 template<
size_t M,
typename T >
1686 vector< M, T >::nnz()
const
1690 const_iterator it = begin(),
1692 for( ; it != it_end; ++it)
1703 template<
size_t M,
typename T >
1705 vector< M, T >::norm( )
const
1707 double norm_v = 0.0;
1709 const_iterator it = begin(), it_end = end();
1710 for( ; it != it_end; ++it )
1712 norm_v += *it * *it;
1715 return std::sqrt(norm_v);
1718 template<
size_t M,
typename T >
1720 vector< M, T >::set_random(
int seed )
1725 for(
size_t i = 0; i < M; ++i )
1727 const double fillValue = double( rand( )) / double( RAND_MAX );
1728 at( i ) = -1.0 + 2.0 * fillValue;
heavily inspired by boost::enable_if http://www.boost.org, file: boost/utility/enable_if.hpp, Copyright 2003 Jaakko Järvi, Jeremiah Willcock, Andrew Lumsdaine
vector< N, T > & get_sub_vector(size_t offset=0, typename enable_if< M >=N >::type *=0)