00001 #ifndef __MULTI_ARRAY_OP_H 00002 #define __MULTI_ARRAY_OP_H 00003 00004 #include <boost/array.hpp> 00005 #include <boost/multi_array.hpp> 00006 #include <functional> 00007 #include "functions.h" 00008 00009 namespace mimas { 00036 00037 template< 00038 typename T1, typename T2, size_t NumDims, 00039 template< typename, size_t > class MultiArray 00040 > 00041 boost::multi_array< T1, NumDims > empty_clone 00042 ( const MultiArray< T2, NumDims > &x ) 00043 { 00044 boost::array< size_t, NumDims > shape; 00045 std::copy( x.shape(), x.shape() + NumDims, shape.begin() ); 00046 boost::multi_array< T1, NumDims > retVal( shape ); 00047 return retVal; 00048 } 00049 00051 template< 00052 typename T, class F 00053 > 00054 boost::detail::multi_array::sub_array< T, 1 > multi_apply 00055 ( boost::detail::multi_array::sub_array< T, 1 > a, F f ) { 00056 for ( typename boost::detail::multi_array::sub_array< T, 1 >::iterator i = a.begin(); 00057 i != a.end(); i++ ) 00058 f( *i ); 00059 return a; 00060 } 00061 00063 template< 00064 typename T, class F, 00065 template< typename, size_t > class MultiArray 00066 > 00067 MultiArray< T, 1 > &multi_apply 00068 ( MultiArray< T, 1 > &a, F f ) { 00069 for ( typename MultiArray< T, 1 >::iterator i = a.begin(); 00070 i != a.end(); i++ ) 00071 f( *i ); 00072 return a; 00073 } 00074 00076 template< 00077 typename T, size_t NumDims, class F 00078 > 00079 boost::detail::multi_array::sub_array< T, NumDims > multi_apply 00080 ( boost::detail::multi_array::sub_array< T, NumDims > a, F f ) { 00081 for ( typename boost::detail::multi_array::sub_array< T, NumDims >::iterator i = a.begin(); 00082 i != a.end(); i++ ) 00083 multi_apply( *i, f ); 00084 return a; 00085 } 00086 00088 template< 00089 typename T, size_t NumDims, class F, 00090 template< typename, size_t > class MultiArray 00091 > 00092 MultiArray< T, NumDims > &multi_apply 00093 ( MultiArray< T, NumDims > &a, F f ) { 00094 for ( typename MultiArray< T, NumDims >::iterator i = a.begin(); 00095 i != a.end(); i++ ) 00096 multi_apply( *i, f ); 00097 return a; 00098 } 00099 00101 template< 00102 typename T1, typename T2, class F, 00103 template< typename, size_t > class MultiArray2 00104 > 00105 boost::detail::multi_array::sub_array< T1, 1 > multi_apply 00106 ( boost::detail::multi_array::sub_array< T1, 1 > a, 00107 const MultiArray2< T2, 1 > &b, 00108 F f ) { 00109 typename MultiArray2< T2, 1 >::const_iterator j = b.begin(); 00110 for ( typename boost::detail::multi_array::sub_array< T1, 1 >::iterator i = a.begin(); 00111 i != a.end(); i++, j++ ) 00112 f( *i, *j ); 00113 return a; 00114 } 00115 00117 template< 00118 typename T1, typename T2, class F, 00119 template< typename, size_t > class MultiArray1, 00120 template< typename, size_t > class MultiArray2 00121 > 00122 MultiArray1< T1, 1 > &multi_apply 00123 ( MultiArray1< T1, 1 > &a, 00124 const MultiArray2< T2, 1 > &b, F f ) { 00125 typename MultiArray2< T2, 1 >::const_iterator j = b.begin(); 00126 for ( typename MultiArray1< T1, 1 >::iterator i = a.begin(); 00127 i != a.end(); i++, j++ ) 00128 f( *i, *j ); 00129 return a; 00130 } 00131 00133 template< 00134 typename T1, typename T2, size_t NumDims, class F, 00135 template< typename, size_t > class MultiArray2 00136 > 00137 boost::detail::multi_array::sub_array< T1, NumDims > multi_apply 00138 ( boost::detail::multi_array::sub_array< T1, NumDims > a, 00139 const MultiArray2< T2, NumDims > &b, 00140 F f ) { 00141 typename MultiArray2< T2, NumDims >::const_iterator j = b.begin(); 00142 for ( typename boost::detail::multi_array::sub_array< T1, NumDims >::iterator i = a.begin(); 00143 i != a.end(); i++, j++ ) 00144 multi_apply( *i, *j, f ); 00145 return a; 00146 } 00147 00149 template< 00150 typename T1, typename T2, size_t NumDims, class F, 00151 template< typename, size_t > class MultiArray1, 00152 template< typename, size_t > class MultiArray2 00153 > 00154 MultiArray1< T1, NumDims > &multi_apply 00155 ( MultiArray1< T1, NumDims > &a, 00156 const MultiArray2< T2, NumDims > &b, F f ) { 00157 typename MultiArray2< T2, NumDims >::const_iterator j = b.begin(); 00158 for ( typename MultiArray1< T1, NumDims >::iterator i = a.begin(); 00159 i != a.end(); i++, j++ ) 00160 multi_apply( *i, *j, f ); 00161 return a; 00162 } 00163 00165 template< 00166 typename T1, typename T2, typename T3, class F, 00167 template< typename, size_t > class MultiArray2, 00168 template< typename, size_t > class MultiArray3 00169 > 00170 boost::detail::multi_array::sub_array< T1, 1 > multi_apply 00171 ( boost::detail::multi_array::sub_array< T1, 1 > a, 00172 const MultiArray2< T2, 1 > &b, 00173 const MultiArray3< T3, 1 > &c, 00174 F f ) { 00175 typename MultiArray2< T2, 1 >::const_iterator j = b.begin(); 00176 typename MultiArray3< T3, 1 >::const_iterator k = c.begin(); 00177 for ( typename boost::detail::multi_array::sub_array< T1, 1 >::iterator i = a.begin(); 00178 i != a.end(); i++, j++, k++ ) 00179 f( *i, *j, *k ); 00180 return a; 00181 } 00182 00184 template< 00185 typename T1, typename T2, typename T3, class F, 00186 template< typename, size_t > class MultiArray1, 00187 template< typename, size_t > class MultiArray2, 00188 template< typename, size_t > class MultiArray3 00189 > 00190 MultiArray1< T1, 1 > &multi_apply 00191 ( MultiArray1< T1, 1 > &a, 00192 const MultiArray2< T2, 1 > &b, 00193 const MultiArray3< T3, 1 > &c, F f ) { 00194 typename MultiArray2< T2, 1 >::const_iterator j = b.begin(); 00195 typename MultiArray3< T3, 1 >::const_iterator k = c.begin(); 00196 for ( typename MultiArray1< T1, 1 >::iterator i = a.begin(); 00197 i != a.end(); i++, j++, k++ ) 00198 f( *i, *j, *k ); 00199 return a; 00200 } 00201 00203 template< 00204 typename T1, typename T2, typename T3, size_t NumDims, class F, 00205 template< typename, size_t > class MultiArray2, 00206 template< typename, size_t > class MultiArray3 00207 > 00208 boost::detail::multi_array::sub_array< T1, NumDims > multi_apply 00209 ( boost::detail::multi_array::sub_array< T1, NumDims > a, 00210 const MultiArray2< T2, NumDims > &b, 00211 const MultiArray3< T3, NumDims > &c, 00212 F f ) { 00213 typename MultiArray2< T2, NumDims >::const_iterator j = b.begin(); 00214 typename MultiArray3< T3, NumDims >::const_iterator k = c.begin(); 00215 for ( typename boost::detail::multi_array::sub_array< T1, NumDims >::iterator i = a.begin(); 00216 i != a.end(); i++, j++, k++ ) multi_apply( *i, *j, *k, f ); 00217 return a; 00218 } 00219 00221 template< 00222 typename T1, typename T2, typename T3, size_t NumDims, class F, 00223 template< typename, size_t > class MultiArray1, 00224 template< typename, size_t > class MultiArray2, 00225 template< typename, size_t > class MultiArray3 00226 > 00227 MultiArray1< T1, NumDims > &multi_apply 00228 ( MultiArray1< T1, NumDims > &a, 00229 const MultiArray2< T2, NumDims > &b, 00230 const MultiArray3< T3, NumDims > &c, F f ) { 00231 typename MultiArray2< T2, NumDims >::const_iterator j = b.begin(); 00232 typename MultiArray3< T3, NumDims >::const_iterator k = c.begin(); 00233 for ( typename MultiArray1< T1, NumDims >::iterator i = a.begin(); 00234 i != a.end(); i++, j++, k++ ) 00235 multi_apply( *i, *j, *k, f ); 00236 return a; 00237 } 00238 00240 template< typename T1, typename T2, class F > 00241 struct _multi_help1 00242 { 00243 _multi_help1( F _f ): f(_f) {} 00244 T1 &operator()( T1 &x, const T2 &y ) const 00245 { x = f( y ); return x; } 00246 F f; 00247 }; 00248 00250 template< typename T1, typename T2, typename T3, class F > 00251 struct _multi_help2 00252 { 00253 _multi_help2( F _f ): f(_f) {} 00254 T1 &operator()( T1 &x, const T2 &y, const T3 &z ) const 00255 { x = f( y, z ); return x; } 00256 F f; 00257 }; 00258 00260 template< 00261 typename T1, typename T2, size_t NumDims, class F, 00262 template< typename, size_t > class MultiArray 00263 > 00264 boost::multi_array< T1, NumDims > multi_func 00265 ( const MultiArray< T2, NumDims > &a, F f ) { 00266 boost::multi_array< T1, NumDims > retVal( empty_clone< T1 >( a ) ); 00267 return multi_apply( retVal, a, _multi_help1< T1, T2, F >( f ) ); 00268 } 00269 00271 template< 00272 typename T1, typename T2, typename T3, size_t NumDims, class F, 00273 template< typename, size_t > class MultiArray1, 00274 template< typename, size_t > class MultiArray2 00275 > 00276 boost::multi_array< T1, NumDims > multi_func 00277 ( const MultiArray1< T2, NumDims > &a, 00278 const MultiArray2< T3, NumDims > &b, F f ) { 00279 boost::multi_array< T1, NumDims > retVal( empty_clone< T1 >( a ) ); 00280 return multi_apply( retVal, a, b, _multi_help2< T1, T2, T3, F >( f ) ); 00281 } 00282 00284 template< 00285 typename T1, typename T2, size_t NumDims, 00286 template< typename, size_t > class MultiArray 00287 > 00288 boost::multi_array< T1, NumDims > multi_cast 00289 ( const MultiArray< T2, NumDims > &a ) { 00290 return multi_func< T1 >( a, std::_Identity< T2 >() ); 00291 } 00292 00294 00295 } 00296 00297 #define __MIMASINTERNALARRAYFUNC operator*= 00298 #define __MIMASEXTERNALARRAYFUNC operator* 00299 #define __MIMASFUNCTIONOBJECT std::multiplies 00300 #include "multi_array_op_help.h" 00301 00302 #define __MIMASINTERNALARRAYFUNC operator/= 00303 #define __MIMASEXTERNALARRAYFUNC operator/ 00304 #define __MIMASFUNCTIONOBJECT std::divides 00305 #include "multi_array_op_help.h" 00306 00307 #define __MIMASINTERNALARRAYFUNC operator+= 00308 #define __MIMASEXTERNALARRAYFUNC operator+ 00309 #define __MIMASFUNCTIONOBJECT std::plus 00310 #include "multi_array_op_help.h" 00311 00312 #define __MIMASINTERNALARRAYFUNC operator-= 00313 #define __MIMASEXTERNALARRAYFUNC operator- 00314 #define __MIMASFUNCTIONOBJECT std::minus 00315 #include "multi_array_op_help.h" 00316 00317 #define __MIMASEXTERNALARRAYFUNC absolute 00318 #define __MIMASINTERNALARRAYFUNC absoluteIt 00319 #define __MIMASFUNCTIONOBJECT _abs 00320 #include "multi_array_op_help2.h" 00321 00322 #define __MIMASEXTERNALARRAYFUNC conj 00323 #define __MIMASINTERNALARRAYFUNC conjIt 00324 #define __MIMASFUNCTIONOBJECT _conj 00325 #include "multi_array_op_help2.h" 00326 00327 #define __MIMASEXTERNALARRAYFUNC sqr 00328 #define __MIMASINTERNALARRAYFUNC sqrIt 00329 #define __MIMASFUNCTIONOBJECT _sqr 00330 #include "multi_array_op_help2.h" 00331 00332 #define __MIMASEXTERNALARRAYFUNC logarithm 00333 #define __MIMASINTERNALARRAYFUNC logarithmIt 00334 #define __MIMASFUNCTIONOBJECT _log 00335 #include "multi_array_op_help2.h" 00336 00337 #define __MIMASEXTERNALARRAYFUNC squareRoot 00338 #define __MIMASINTERNALARRAYFUNC squareRootIt 00339 #define __MIMASFUNCTIONOBJECT _sqrt 00340 #include "multi_array_op_help2.h" 00341 00342 #define __MIMASEXTERNALARRAYFUNC sumSquares 00343 #define __MIMASFUNCTIONOBJECT _sumsquares 00344 #include "multi_array_op_help3.h" 00345 00346 #define __MIMASEXTERNALARRAYFUNC orientation 00347 #define __MIMASFUNCTIONOBJECT _orientation 00348 #include "multi_array_op_help3.h" 00349 00350 namespace mimas { 00353 00354 template < 00355 typename T1, typename T2, size_t NumDims, 00356 template< typename, size_t > class MultiArray 00357 > 00358 boost::multi_array< T1, NumDims > norm( const MultiArray< T2, NumDims > &a ) 00359 { 00360 return multi_func< T1 >( a, _norm< T1, T2 >() ); 00361 } 00362 00364 template < 00365 typename T1, typename T2, size_t NumDims, 00366 template< typename, size_t > class MultiArray 00367 > 00368 boost::multi_array< T1, NumDims > arg( const MultiArray< T2, NumDims > &a ) 00369 { 00370 return multi_func< T1 >( a, _arg< T1, T2 >() ); 00371 } 00372 00374 template < 00375 typename T, size_t NumDims, 00376 template< typename, size_t > class MultiArray 00377 > 00378 boost::multi_array< int, NumDims > fastSqr( const MultiArray< T, NumDims > &a ) 00379 { 00380 return multi_func< int >( a, _fastsqr< T >() ); 00381 } 00382 00384 } 00385 00386 #endif