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_vector_ )
const;
245 inline T squared_distance(
const vector& other_vector_ )
const;
247 template<
typename TT >
249 typename enable_if< M == 3, TT >::type* = 0 )
const;
253 void compute_normal(
const vector& v0,
const vector& v1,
const vector& v2 );
255 vector compute_normal(
const vector& v1,
const vector& v2 )
const;
270 template<
typename TT >
273 typename enable_if< M == 4, TT >::type* = 0 )
const;
276 template<
typename TT >
278 typename enable_if< M == 4, TT >::type* = 0 )
const;
281 template<
typename TT >
283 typename enable_if< M == 4, TT >::type* = 0 )
const;
285 template<
typename TT >
288 typename enable_if< M == 4, TT >::type* = 0 )
const;
291 size_t find_min_index()
const;
292 size_t find_max_index()
const;
295 size_t find_abs_min_index()
const;
296 size_t find_abs_max_index()
const;
301 const T& find_min()
const;
302 const T& find_max()
const;
304 void clamp(
const T& min = 0.0,
const T& max = 1.0 );
306 template<
typename TT >
308 T min_value = -1.0, T max_value = 1.0 )
const;
310 inline static size_t size();
312 bool is_unit_vector()
const;
315 void perturb( T perturbation = 0.0001 );
317 void sqrt_elementwise();
325 void reciprocal_safe();
327 template<
typename TT >
335 friend std::ostream& operator<< ( std::ostream& os,
const vector& vector_ )
337 #ifdef EQFABRIC_API_H
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 );
352 for( ; index < M - 1; ++index )
354 os << vector_.at( index ) <<
", ";
356 os << vector_.at( index ) <<
")";
364 VMMLIB_ALIGN( T array[ M ] );
368 static const vector FORWARD;
369 static const vector BACKWARD;
370 static const vector UP;
371 static const vector DOWN;
372 static const vector LEFT;
373 static const vector RIGHT;
375 static const vector ONE;
376 static const vector ZERO;
379 static const vector UNIT_X;
380 static const vector UNIT_Y;
381 static const vector UNIT_Z;
390 #ifndef VMMLIB_NO_TYPEDEFS
400 template<
size_t M,
typename T >
402 template<
size_t M,
typename T >
404 template<
size_t M,
typename T >
406 template<
size_t M,
typename T >
408 template<
size_t M,
typename T >
410 template<
size_t M,
typename T >
412 template<
size_t M,
typename T >
415 template<
size_t M,
typename T >
417 template<
size_t M,
typename T >
420 template<
size_t M,
typename T >
422 template<
size_t M,
typename T >
430 template<
size_t M,
typename T >
433 return a.equals( b );
438 template<
size_t M,
typename T >
439 static vector< M, T >
440 operator* ( T factor,
const vector< M, T >& vector_ )
442 return vector_ * factor;
446 template<
size_t M,
typename T >
447 inline T dot(
const vector< M, T >& first,
const vector< M, T >& second )
449 return first.dot( second );
453 template<
size_t M,
typename T >
460 template<
size_t M,
typename T >
461 inline vector< M, T > normalize(
const vector< M, T >& vector_ )
463 vector< M, T > v( vector_ );
468 template<
typename T >
478 plane.w() = -plane.x() * a.x() - plane.y() * a.y() - plane.z() * a.z();
482 template<
size_t M,
typename T >
483 vector< M, T >::vector(
const T& _a )
485 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
491 template<
size_t M,
typename T >
492 vector< M, T >::vector(
const T& _x,
const T& _y )
499 template<
size_t M,
typename T >
500 vector< M, T >::vector(
const T& _x,
const T& _y,
const T& _z )
509 template<
size_t M,
typename T >
510 vector< M, T >::vector(
const T& _x,
const T& _y,
const T& _z,
const T& _w )
519 template<
size_t M,
typename T >
520 vector< M, T >::vector(
const T* values )
522 memcpy( array, values, M *
sizeof( T ));
526 template<
size_t M,
typename T >
527 template<
typename OSGVEC3 >
528 vector< M, T >::vector(
const OSGVEC3& from,
529 typename enable_if< M == 3, OSGVEC3 >::type* )
531 array[ 0 ] = from.x();
532 array[ 1 ] = from.y();
533 array[ 2 ] = from.z();
538 template<
size_t M,
typename T >
540 vector< M, T >::vector(
const vector< M-1, T >& vector_, T last_ )
542 typename vector< M-1, T >::const_iterator
543 it = vector_.begin(), it_end = vector_.end();
545 iterator my_it = begin();
547 for( ; it != it_end; ++it, ++my_it )
558 template<
size_t M,
typename T >
560 vector< M, T >::vector(
const vector< N, T >& source_,
561 typename enable_if< N == M - 1 >::type* )
570 template<
size_t M,
typename T >
572 vector< M, T >::vector(
const vector< N, T >& source_,
573 typename enable_if< N == M + 1 >::type* )
579 template<
size_t M,
typename T >
580 template<
typename U >
581 vector< M, T >::vector(
const vector< M, U >& source_ )
588 template<
size_t M,
typename T >
void vector< M, T >::set( T _a )
590 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
598 template<
size_t M,
typename T >
599 void vector< M, T >::set(
const vector< M-1, T >& v, T _a )
601 memcpy( array, v.array,
sizeof( T ) * (M-1) );
606 template<
size_t M,
typename T >
template<
size_t N >
607 void vector< M, T >::set(
const vector< N, T >& v )
610 if (N < M) minimum = N;
611 memcpy( array, v.array,
sizeof( T ) * minimum );
614 template<
size_t M,
typename T >
615 void vector< M, T >::set( T _x, T _y )
622 template<
size_t M,
typename T >
623 void vector< M, T >::set( T _x, T _y, T _z )
632 template<
size_t M,
typename T >
633 void vector< M, T >::set( T _x, T _y, T _z, T _w )
642 template<
size_t M,
typename T >
644 vector< M, T >::operator()(
size_t index )
651 template<
size_t M,
typename T >
653 vector< M, T >::operator()(
size_t index )
const
660 template<
size_t M,
typename T >
662 vector< M, T >::at(
size_t index )
664 #ifdef VMMLIB_SAFE_ACCESSORS
667 VMMLIB_ERROR(
"at() - index out of bounds", VMMLIB_HERE );
670 return array[ index ];
675 template<
size_t M,
typename T >
677 vector< M, T >::at(
size_t index )
const
679 #ifdef VMMLIB_SAFE_ACCESSORS
682 VMMLIB_ERROR(
"at() - index out of bounds", VMMLIB_HERE );
685 return array[ index ];
689 #ifndef VMMLIB_NO_CONVERSION_OPERATORS
691 template<
size_t M,
typename T >
692 vector< M, T >::operator T*()
699 template<
size_t M,
typename T >
700 vector< M, T >::operator
const T*()
const
706 template<
size_t M,
typename T >
708 vector< M, T >::operator[](
size_t index )
713 template<
size_t M,
typename T >
715 vector< M, T >::operator[](
size_t index )
const
725 template<
size_t M,
typename T >
727 vector< M, T >::operator[](
size_t index )
734 template<
size_t M,
typename T >
736 vector< M, T >::operator[](
size_t index )
const
743 template<
size_t M,
typename T >
745 vector< M, T >::operator*(
const vector< M, T >& other )
const
747 vector< M, T > result;
748 for(
size_t index = 0; index < M; ++index )
750 result.at( index ) = at( index ) * other.at( index );
757 template<
size_t M,
typename T >
759 vector< M, T >::operator/(
const vector< M, T >& other )
const
761 vector< M, T > result;
762 for(
size_t index = 0; index < M; ++index )
764 result.at( index ) = at( index ) / other.at( index );
771 template<
size_t M,
typename T >
773 vector< M, T >::operator+(
const vector< M, T >& other )
const
775 vector< M, T > result;
776 for(
size_t index = 0; index < M; ++index )
778 result.at( index ) = at( index ) + other.at( index );
785 template<
size_t M,
typename T >
787 vector< M, T >::operator-(
const vector< M, T >& other )
const
789 vector< M, T > result;
790 for(
size_t index = 0; index < M; ++index )
792 result.at( index ) = at( index ) - other.at( index );
800 template<
size_t M,
typename T >
802 vector< M, T >::operator*=(
const vector< M, T >& other )
804 for(
size_t index = 0; index < M; ++index )
806 at( index ) *= other.at( index );
812 template<
size_t M,
typename T >
814 vector< M, T >::operator/=(
const vector< M, T >& other )
816 for(
size_t index = 0; index < M; ++index )
818 at( index ) /= other.at( index );
824 template<
size_t M,
typename T >
826 vector< M, T >::operator+=(
const vector< M, T >& other )
828 for(
size_t index = 0; index < M; ++index )
830 at( index ) += other.at( index );
836 template<
size_t M,
typename T >
838 vector< M, T >::operator-=(
const vector< M, T >& other )
840 for(
size_t index = 0; index < M; ++index )
842 at( index ) -= other.at( index );
848 template<
size_t M,
typename T >
850 vector< M, T >::operator*(
const T other )
const
852 vector< M, T > result;
853 for(
size_t index = 0; index < M; ++index )
855 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 )
869 result.at( index ) = at( index ) / other;
876 template<
size_t M,
typename T >
878 vector< M, T >::operator+(
const T other )
const
880 vector< M, T > result;
881 for(
size_t index = 0; index < M; ++index )
883 result.at( index ) = at( index ) + other;
890 template<
size_t M,
typename T >
892 vector< M, T >::operator-(
const T other )
const
894 vector< M, T > result;
895 for(
size_t index = 0; index < M; ++index )
897 result.at( index ) = 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 )
911 at( index ) *= other;
917 template<
size_t M,
typename T >
919 vector< M, T >::operator/=(
const T other )
921 for(
size_t index = 0; index < M; ++index )
923 at( index ) /= other;
929 template<
size_t M,
typename T >
931 vector< M, T >::operator+=(
const T other )
933 for(
size_t index = 0; index < M; ++index )
935 at( index ) += other;
941 template<
size_t M,
typename T >
943 vector< M, T >::operator-=(
const T other )
945 for(
size_t index = 0; index < M; ++index )
947 at( index ) -= other;
953 template<
size_t M,
typename T >
955 vector< M, T >::operator-()
const
957 vector< M, T > v( *
this );
963 template<
size_t M,
typename T >
964 const vector< M, T >&
965 vector< M, T >::negate()
967 for(
size_t index = 0; index < M; ++index )
969 array[ index ] = -array[ index ];
976 template<
size_t M,
typename T >
985 template<
size_t M,
typename T >
994 template<
size_t M,
typename T >
1003 template<
size_t M,
typename T >
1012 template<
size_t M,
typename T >
1014 vector< M, T >::x()
const
1021 template<
size_t M,
typename T >
1023 vector< M, T >::y()
const
1030 template<
size_t M,
typename T >
1032 vector< M, T >::z()
const
1039 template<
size_t M,
typename T >
1041 vector< M, T >::w()
const
1047 template<
size_t M,
typename T >
1056 template<
size_t M,
typename T >
1065 template<
size_t M,
typename T >
1074 template<
size_t M,
typename T >
1083 template<
size_t M,
typename T >
1085 vector< M, T >::r()
const
1092 template<
size_t M,
typename T >
1094 vector< M, T >::g()
const
1101 template<
size_t M,
typename T >
1103 vector< M, T >::b()
const
1110 template<
size_t M,
typename T >
1112 vector< M, T >::a()
const
1118 template<
size_t M,
typename T >
1119 template<
typename TT >
1120 inline vector< M, T > vector< M, T >::cross(
const vector< M, TT >& rhs,
1121 typename enable_if< M == 3, TT >::type* )
const
1123 vector< M, T > result;
1124 result.cross( *
this, rhs );
1131 template<
size_t M,
typename T >
1132 template<
typename TT >
1133 void vector< M, T >::cross(
const vector< M, TT >& aa,
1134 const vector< M, TT >& bb,
1135 typename enable_if< M == 3, TT >::type* )
1137 array[ 0 ] = aa.y() * bb.z() - aa.z() * bb.y();
1138 array[ 1 ] = aa.z() * bb.x() - aa.x() * bb.z();
1139 array[ 2 ] = aa.x() * bb.y() - aa.y() * bb.x();
1144 template<
size_t M,
typename T >
1145 inline T vector< M, T >::dot(
const vector< M, T >& other )
const
1148 for(
size_t index = 0; index < M; ++index )
1149 tmp += at( index ) * other.at( index );
1155 template<
size_t M,
typename T >
1156 inline T vector< M, T >::normalize()
1158 const T len = length();
1163 const T tmp = 1.0 / len;
1168 template<
size_t M,
typename T >
1169 inline T vector< M, T >::length()
const
1171 return std::sqrt( squared_length() );
1174 template<
size_t M,
typename T >
1175 inline T vector< M, T >::squared_length()
const
1177 T _squared_length = 0.0;
1178 for( const_iterator it = begin(), it_end = end(); it != it_end; ++it )
1179 _squared_length += (*it) * (*it);
1181 return _squared_length;
1186 template<
size_t M,
typename T >
1188 vector< M, T >::distance(
const vector< M, T >& other_vector_ )
const
1190 return std::sqrt( squared_distance( other_vector_ ) );
1195 template<
size_t M,
typename T >
1197 vector< M, T >::squared_distance(
const vector< M, T >& other_vector_ )
const
1199 vector< M, T > tmp( *
this );
1200 tmp -= other_vector_;
1201 return tmp.squared_length();
1206 template<
size_t M,
typename T >
1208 vector< M, T >::compute_normal(
1209 const vector< M, T >& aa,
1210 const vector< M, T >& bb,
1211 const vector< M, T >& cc
1224 template<
size_t M,
typename T >
1226 vector< M, T >::compute_normal(
const vector< M, T >& bb,
1227 const vector< M, T >& cc )
const
1230 tmp.compute_normal( *
this, bb, cc);
1234 template<
size_t M,
typename T >
1235 template<
typename TT >
1236 vector< 3, T > vector< M, T >::rotate(
const T theta, vector< M, TT > axis,
1237 typename enable_if< M == 3, TT >::type* )
const
1241 const T costheta = std::cos( theta );
1242 const T sintheta = std::sin( theta );
1245 (costheta + ( 1.0f - costheta ) * axis.x() * axis.x() ) * x() +
1246 (( 1 - costheta ) * axis.x() * axis.y() - axis.z() * sintheta ) * y() +
1247 (( 1 - costheta ) * axis.x() * axis.z() + axis.y() * sintheta ) * z(),
1249 (( 1 - costheta ) * axis.x() * axis.y() + axis.z() * sintheta ) * x() +
1250 ( costheta + ( 1 - costheta ) * axis.y() * axis.y() ) * y() +
1251 (( 1 - costheta ) * axis.y() * axis.z() - axis.x() * sintheta ) * z(),
1253 (( 1 - costheta ) * axis.x() * axis.z() - axis.y() * sintheta ) * x() +
1254 (( 1 - costheta ) * axis.y() * axis.z() + axis.x() * sintheta ) * y() +
1255 ( costheta + ( 1 - costheta ) * axis.z() * axis.z() ) * z() );
1260 template<
size_t M,
typename T >
1261 template<
typename TT >
1264 project_point_onto_sphere(
const vector< 3, TT >& point,
1265 typename enable_if< M == 4, TT >::type* )
const
1270 projected_point -= _center;
1271 projected_point.normalize();
1272 projected_point *= w();
1273 return _center + projected_point;
1279 template<
size_t M,
typename T >
1280 template<
typename TT >
1283 distance_to_sphere(
const vector< 3, TT >& point,
1284 typename enable_if< M == 4, TT >::type* )
const
1287 return ( point - center_ ).length() - w();
1290 template<
size_t M,
typename T >
1291 template<
size_t N >
1293 vector< M, T >::get_sub_vector( vector< N, T >& sub_v,
size_t offset,
1294 typename enable_if< M >= N >::type* )
1296 assert( offset <= M - N );
1297 sub_v =
reinterpret_cast< vector< N, T >&
>( *( begin() + offset ) );
1302 template<
size_t M,
typename T >
1303 template<
size_t N >
1304 inline vector< N, T >&
1305 vector< M, T >::get_sub_vector(
size_t offset,
1306 typename enable_if< M >= N >::type* )
1308 assert( offset <= M - N );
1309 return reinterpret_cast< vector< N, T >&
>( *( begin() + offset ) );
1314 template<
size_t M,
typename T >
1315 template<
size_t N >
1316 inline const vector< N, T >&
1317 vector< M, T >::get_sub_vector(
size_t offset,
1318 typename enable_if< M >= N >::type* )
const
1320 assert( offset <= M - N );
1321 return reinterpret_cast< const vector< N, T >&
>( *( begin() + offset ) );
1326 template<
size_t M,
typename T >
template<
typename TT >
1327 inline T vector< M, T >::distance_to_plane(
const vector< 3, TT >& point,
1328 typename enable_if< M == 4, TT >::type* )
const
1331 return normal.dot( point ) + w();
1337 template<
size_t M,
typename T >
1338 template<
typename TT >
1340 vector< M, T >::project_point_onto_plane(
const vector< 3, TT >& point,
1341 typename enable_if< M == 4, TT >::type* )
const
1344 return point - ( normal * distance_to_plane( point ) );
1349 template<
size_t M,
typename T >
1350 bool vector< M, T >::operator==(
const vector< M, T >& other )
const
1352 return memcmp( array, other.array,
sizeof( array )) == 0;
1356 template<
size_t M,
typename T >
1357 bool vector< M, T >::operator!=(
const vector< M, T >& other )
const
1359 return ! this->operator==( other );
1363 template<
size_t M,
typename T >
1366 equals(
const vector< M, T >& other, T tolerance )
const
1369 for(
size_t index = 0; is_ok && index < M; ++index )
1371 is_ok = fabs( at( index ) - other( index ) ) < tolerance;
1378 template<
size_t M,
typename T >
1380 vector< M, T >::operator<(
const vector< M, T >& other )
const
1382 for(
size_t index = 0; index < M; ++index )
1384 if (at( index ) < other.at( index ))
return true;
1385 if (other.at( index ) < at( index ))
return false;
1393 template<
size_t M,
typename T >
template<
size_t N >
1394 typename enable_if< N == M - 1 >::type*
1395 vector< M, T >::operator=(
const vector< N, T >& source_ )
1397 std::copy( source_.begin(), source_.end(), begin() );
1398 at( M - 1 ) =
static_cast< T
>( 1.0 );
1405 template<
size_t M,
typename T >
template<
size_t N >
1406 typename enable_if< N == M + 1 >::type*
1407 vector< M, T >::operator=(
const vector< N, T >& source_ )
1409 const T w_reci =
static_cast< T
>( 1.0 ) / source_( M );
1410 iterator it = begin(), it_end = end();
1411 for(
size_t index = 0; it != it_end; ++it, ++index )
1413 *it = source_( index ) * w_reci;
1419 template<
size_t M,
typename T >
1420 vector< M, T >& vector< M, T >::operator=(
const T* c_array )
1422 iter_set( c_array, c_array + M );
1428 template<
size_t M,
typename T >
1429 T vector< M, T >::operator=( T filler_value )
1431 for(
size_t index = 0; index < M; ++index )
1433 at( index ) = filler_value;
1435 return filler_value;
1441 template<
size_t M,
typename T >
1442 vector< M, T >& vector< M, T >::operator=(
const vector< M, T >& other )
1444 if(
this != &other )
1445 memcpy( array, other.array, M *
sizeof( T ) );
1452 template<
size_t M,
typename T >
template<
typename U >
1453 void vector< M, T >::operator=(
const vector< M, U >& source_ )
1455 typedef typename vector< M, U >::const_iterator u_c_iter;
1456 u_c_iter it = source_.begin(), it_end = source_.end();
1457 for( iterator my_it = begin(); it != it_end; ++it, ++my_it )
1459 *my_it =
static_cast< T
>( *it );
1465 template<
size_t M,
typename T >
1466 template<
typename input_iterator_t >
1468 vector< M, T >::iter_set( input_iterator_t begin_, input_iterator_t end_ )
1470 input_iterator_t in_it = begin_;
1471 iterator it = begin(), it_end = end();
1472 for( ; it != it_end && in_it != end_; ++it, ++in_it )
1474 (*it) =
static_cast< T
>( *in_it );
1479 template<
size_t M,
typename T >
1480 void vector< M, T >::clamp(
const T& min,
const T& max )
1482 for(
size_t i = 0; i < M; ++i )
1484 if( array[i] < min )
1486 if( array[i] > max )
1493 template<
size_t M,
typename T >
1494 template<
typename TT >
1496 vector< M, T >::scale_to( vector< M, TT >& result_,
1497 T min_value, T max_value )
const
1499 T range = max_value-min_value;
1500 T half_range = range * 0.5;
1501 T scale = ( 1.0 / range ) * static_cast< T >( std::numeric_limits< TT >::max() );
1503 for(
size_t index = 0; index < M; ++index )
1506 =
static_cast< TT
>( ( at( index ) + half_range ) * scale );
1513 template<
size_t M,
typename T >
1515 vector< M, T >::size()
1522 template<
size_t M,
typename T >
1524 vector< M, T >::find_min_index()
const
1526 return std::min_element( begin(), end() ) - begin();
1531 template<
size_t M,
typename T >
1533 vector< M, T >::find_max_index()
const
1535 return std::max_element( begin(), end() ) - begin();
1540 template<
size_t M,
typename T >
1542 vector< M, T >::find_abs_min_index()
const
1549 template<
size_t M,
typename T >
1551 vector< M, T >::find_abs_max_index()
const
1558 template<
size_t M,
typename T >
1560 vector< M, T >::find_min()
1562 return *std::min_element( begin(), end() );
1567 template<
size_t M,
typename T >
1569 vector< M, T >::find_min()
const
1571 return *std::min_element( begin(), end() );
1576 template<
size_t M,
typename T >
1578 vector< M, T >::find_max()
1580 return *std::max_element( begin(), end() );
1585 template<
size_t M,
typename T >
1587 vector< M, T >::find_max()
const
1589 return *std::max_element( begin(), end() );
1593 template<
size_t M,
typename T >
1594 inline typename vector< M, T >::iterator
1595 vector< M, T >::begin()
1601 template<
size_t M,
typename T >
1602 inline typename vector< M, T >::iterator
1603 vector< M, T >::end()
1609 template<
size_t M,
typename T >
1610 inline typename vector< M, T >::const_iterator
1611 vector< M, T >::begin()
const
1617 template<
size_t M,
typename T >
1618 inline typename vector< M, T >::const_iterator
1619 vector< M, T >::end()
const
1626 template<
size_t M,
typename T >
1627 inline typename vector< M, T >::reverse_iterator
1628 vector< M, T >::rbegin()
1630 return array + M - 1;
1634 template<
size_t M,
typename T >
1635 inline typename vector< M, T >::reverse_iterator
1636 vector< M, T >::rend()
1642 template<
size_t M,
typename T >
1643 inline typename vector< M, T >::const_reverse_iterator
1644 vector< M, T >::rbegin()
const
1646 return array + M - 1;
1650 template<
size_t M,
typename T >
1651 inline typename vector< M, T >::const_reverse_iterator
1652 vector< M, T >::rend()
const
1659 template<
size_t M,
typename T >
1661 vector< M, T >::is_unit_vector()
const
1663 const_iterator it = begin(), it_end = end();
1665 for( ; it != it_end; ++it )
1673 else if ( *it != 0.0 )
1684 template<
size_t M,
typename T >
1686 vector< M, T >::perturb( T perturbation )
1688 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
1690 (*it) += ( rand() & 1u ) ? perturbation : -perturbation;
1695 template<
size_t M,
typename T >
1697 vector< M, T >::sqrt_elementwise()
1699 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
1701 (*it) = std::sqrt(*it);
1707 template<
size_t M,
typename T >
1709 vector< M, T >::reciprocal()
1711 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
1713 (*it) =
static_cast< T
>( 1.0 ) / (*it);
1719 template<
size_t M,
typename T >
1721 vector< M, T >::reciprocal_safe()
1723 for( iterator it = begin(), it_end = end(); it != it_end; ++it )
1727 if ( v == static_cast< T >( 0 ) )
1728 v = std::numeric_limits< T >::max();
1730 v =
static_cast< T
>( 1.0 ) / v;
1736 template<
size_t M,
typename T >
1737 template<
typename TT >
1739 vector< M, T >::cast_from(
const vector< M, TT >& other )
1742 typedef typename vector_tt_type::const_iterator tt_const_iterator;
1744 iterator it = begin(), it_end = end();
1745 tt_const_iterator other_it = other.begin();
1746 for( ; it != it_end; ++it, ++other_it )
1748 *it =
static_cast< T
>( *other_it );
1752 template<
size_t M,
typename T >
1754 vector< M, T >::nnz()
const
1758 const_iterator it = begin(),
1760 for( ; it != it_end; ++it)
1771 template<
size_t M,
typename T >
1773 vector< M, T >::norm( )
const
1775 double norm_v = 0.0;
1777 const_iterator it = begin(), it_end = end();
1778 for( ; it != it_end; ++it )
1780 norm_v += *it * *it;
1783 return std::sqrt(norm_v);
1786 template<
size_t M,
typename T >
1788 vector< M, T >::set_random(
int seed )
1793 for(
size_t i = 0; i < M; ++i )
1795 const double fillValue = double( rand( )) / double( RAND_MAX );
1796 at( i ) = -1.0 + 2.0 * fillValue;