#ifndef included_FunctionTable_hpp #define included_FunctionTable_hpp #include "common/FunctionTable.h" #include "common/Utilities.h" #include #include #include #include /******************************************************** * Random number initialization * ********************************************************/ template void FunctionTable::rand( Array &x ) { FunctionTable::rand( x.length(), x.data() ); } template<> inline void FunctionTable::rand( size_t N, double *x ) { std::random_device rd; std::mt19937 gen( rd() ); std::uniform_real_distribution<> dis( 0, 1 ); for ( size_t i = 0; i < N; i++ ) x[i] = dis( gen ); } template<> inline void FunctionTable::rand( size_t N, float *x ) { std::random_device rd; std::mt19937 gen( rd() ); std::uniform_real_distribution<> dis( 0, 1 ); for ( size_t i = 0; i < N; i++ ) x[i] = dis( gen ); } template<> inline void FunctionTable::rand( size_t N, int *x ) { std::random_device rd; std::mt19937 gen( rd() ); std::uniform_int_distribution<> dis; for ( size_t i = 0; i < N; i++ ) x[i] = dis( gen ); } /******************************************************** * Reduction * ********************************************************/ template inline TYPE FunctionTable::reduce( LAMBDA &op, const Array &A ) { if ( A.length() == 0 ) return TYPE(); const TYPE *x = A.data(); TYPE y = x[0]; const size_t N = A.length(); for ( size_t i = 1; i < N; i++ ) y = op( x[i], y ); return y; } /******************************************************** * Unary transformation * ********************************************************/ template inline void FunctionTable::transform( LAMBDA &fun, const Array &x, Array &y ) { y.resize( x.size() ); const size_t N = x.length(); for ( size_t i = 0; i < N; i++ ) y( i ) = fun( x( i ) ); } template inline void FunctionTable::transform( LAMBDA &fun, const Array &x, const Array &y, Array &z ) { if ( !x.sizeMatch( y ) ) throw std::logic_error( "Sizes of x and y do not match" ); z.resize( x.size() ); const size_t N = x.length(); for ( size_t i = 0; i < N; i++ ) z( i ) = fun( x( i ), y( i ) ); } /******************************************************** * Multiply two arrays * ********************************************************/ template void FunctionTable::multiply( const Array &a, const Array &b, Array &c ) { if ( a.ndim() <= 2 && b.ndim() <= 2 ) { if ( a.size( 1 ) != b.size( 0 ) ) throw std::logic_error( "Inner dimensions must match" ); c.resize( a.size( 0 ), b.size( 1 ) ); c.fill( 0 ); for ( size_t k = 0; k < b.size( 1 ); k++ ) { for ( size_t j = 0; j < a.size( 1 ); j++ ) { for ( size_t i = 0; i < a.size( 0 ); i++ ) { c( i, k ) += a( i, j ) * b( j, k ); } } } } else { throw std::logic_error( "Not finished yet" ); } } #endif