diff --git a/build/make.linux64.test.py b/build/make.linux64.test.py index 1d94d23..e2fa1b8 100644 --- a/build/make.linux64.test.py +++ b/build/make.linux64.test.py @@ -16,7 +16,7 @@ builddir = "./build_linux64" doinstall = True #copies the build_output to the install dir when finished cc = "g++" #compiler cflags = "-fPIC" -libraries = "-l{}".format(libname) +libraries = "-l{} -lamsmathutil2.linux64".format(libname) libdirs = "-L{} -L{}/lib".format(builddir,commondir) linkerflags = "-static -static-libgcc -Wl,-rpath=." srcexts = [".c",".cpp"] diff --git a/build/make.mingw64.test.py b/build/make.mingw64.test.py index b70fd1b..43fb90a 100644 --- a/build/make.mingw64.test.py +++ b/build/make.mingw64.test.py @@ -17,7 +17,7 @@ builddir = "./build_mingw64" doinstall = False #copies the build_output to the install dir when finished cc = "x86_64-w64-mingw32-g++" #compiler cflags = "-fPIC -O3" -libraries = "-l{}".format(libname) +libraries = "-l{} -lamsmathutil2.mingw64".format(libname) libdirs = "-L{} -L{}/lib -L{}/lib".format(builddir,commondir,depdir) linkerflags = "-static -static-libgcc -Wl,-rpath=." srcexts = [".c",".cpp"] diff --git a/build_linux64/libamscppnarray.linux64.a b/build_linux64/libamscppnarray.linux64.a index d6f2dd4..7ba017a 100644 Binary files a/build_linux64/libamscppnarray.linux64.a and b/build_linux64/libamscppnarray.linux64.a differ diff --git a/build_linux64/objstore/amscppnarray.o b/build_linux64/objstore/amscppnarray.o index 51ebb3e..dfcadd3 100644 Binary files a/build_linux64/objstore/amscppnarray.o and b/build_linux64/objstore/amscppnarray.o differ diff --git a/build_linux64/objstore/amscppnarray_inits.o b/build_linux64/objstore/amscppnarray_inits.o index ea9bf28..6b52b04 100644 Binary files a/build_linux64/objstore/amscppnarray_inits.o and b/build_linux64/objstore/amscppnarray_inits.o differ diff --git a/build_linux64/objstore/amscppnarray_math.o b/build_linux64/objstore/amscppnarray_math.o new file mode 100644 index 0000000..d28db26 Binary files /dev/null and b/build_linux64/objstore/amscppnarray_math.o differ diff --git a/build_linux64/objstore/amscppnarray_random.o b/build_linux64/objstore/amscppnarray_random.o index 68ab044..358977f 100644 Binary files a/build_linux64/objstore/amscppnarray_random.o and b/build_linux64/objstore/amscppnarray_random.o differ diff --git a/build_linux64/tests b/build_linux64/tests index b136d0f..05e1e02 100644 Binary files a/build_linux64/tests and b/build_linux64/tests differ diff --git a/build_mingw64/libamscppnarray.mingw64.a b/build_mingw64/libamscppnarray.mingw64.a new file mode 100644 index 0000000..245f6d9 Binary files /dev/null and b/build_mingw64/libamscppnarray.mingw64.a differ diff --git a/build_mingw64/objstore/amscppnarray.o b/build_mingw64/objstore/amscppnarray.o new file mode 100644 index 0000000..d8317ac Binary files /dev/null and b/build_mingw64/objstore/amscppnarray.o differ diff --git a/build_mingw64/objstore/amscppnarray_inits.o b/build_mingw64/objstore/amscppnarray_inits.o new file mode 100644 index 0000000..92c4b9f Binary files /dev/null and b/build_mingw64/objstore/amscppnarray_inits.o differ diff --git a/build_mingw64/objstore/amscppnarray_math.o b/build_mingw64/objstore/amscppnarray_math.o new file mode 100644 index 0000000..8571712 Binary files /dev/null and b/build_mingw64/objstore/amscppnarray_math.o differ diff --git a/build_mingw64/objstore/amscppnarray_random.o b/build_mingw64/objstore/amscppnarray_random.o new file mode 100644 index 0000000..1dad5f6 Binary files /dev/null and b/build_mingw64/objstore/amscppnarray_random.o differ diff --git a/build_mingw64/tests.exe b/build_mingw64/tests.exe new file mode 100644 index 0000000..522718d Binary files /dev/null and b/build_mingw64/tests.exe differ diff --git a/include/amscppnarray/amscppnarray.hpp b/include/amscppnarray/amscppnarray.hpp index 8619c6f..996d635 100644 --- a/include/amscppnarray/amscppnarray.hpp +++ b/include/amscppnarray/amscppnarray.hpp @@ -4,11 +4,16 @@ #include #include #include +#include + #include #include #include #include +#include +#include + namespace ams { namespace narray @@ -114,5 +119,6 @@ void test_narray3(); #include #include +#include #endif \ No newline at end of file diff --git a/include/amscppnarray/amscppnarray_math.hpp b/include/amscppnarray/amscppnarray_math.hpp new file mode 100644 index 0000000..a6aa683 --- /dev/null +++ b/include/amscppnarray/amscppnarray_math.hpp @@ -0,0 +1,28 @@ +#ifndef __AMSCPPNARRAY_MATH_HPP__ +#define __AMSCPPNARRAY_MATH_HPP__ + +namespace ams +{ +namespace narray +{ + +template T narray_max(const narray &q); +template T narray_min(const narray &q); +template double narray_mean(const narray &q); +template double narray_var(const narray &q); +template double narray_stdev(const narray &q); +template double narray_L2norm(const narray &q); + +template T narray_sum(const narray &q); + +template narray narray_abs(narray &q); + +void narray_testmath1(); +void narray_testmath2(); + +}; //end namespaces +}; + +#include + +#endif \ No newline at end of file diff --git a/include/amscppnarray/amscppnarray_mathimpl.hpp b/include/amscppnarray/amscppnarray_mathimpl.hpp new file mode 100644 index 0000000..943893b --- /dev/null +++ b/include/amscppnarray/amscppnarray_mathimpl.hpp @@ -0,0 +1,381 @@ +#ifndef __AMSCPPNARRAY_MATHIMPL_HPP__ +#define __AMSCPPNARRAY_MATHIMPL_HPP__ + +namespace ams +{ +namespace narray +{ + + template T narray_max(const narray &q) + { + return q.max(); + } + + template T narray_min(const narray &q) + { + return q.min(); + } + + template void narray_sum_tf( + const narray *in, + narray *sums, + int threadnum, + int nthreads + ) + { + int I0,I1,Is,I; + + Is = in->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? in->length: Is*(threadnum+1); + for(I=I0;Idata[threadnum] = sums->data[threadnum] + in->data[I]; + } + } + + template T narray_sum(const narray &q) + { + T ret = T(); + narray sums; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + if(q.length<=0) + { + return ret; + } + + if(q.lengthnarray_max_threads) ? narray_max_threads : nthreads; + threads.resize(nthreads); + sums.resize(nthreads); + sums.setall(T()); + for(J=0;J, + &q, + &sums, + J,nthreads + ); + if(threads[J]==NULL) + { + printf("narray_sum: warning: thread %d failed to initialize.\n",J); + //handle errors + } + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + ret = T(); + for(J=0;J double narray_mean(const narray &q) + { + double ret = 0.0; + T sum = narray_sum(q); + ret = (double)sum/((double)q.length); + return ret; + } + + template void narray_variance_tf( + const narray *in, + narray *sums, + double mean, + int threadnum, + int nthreads + ) + { + int I0,I1,Is,I; + double q2; + Is = in->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? in->length: Is*(threadnum+1); + for(I=I0;Idata[I]-mean; + sums->data[threadnum] = sums->data[threadnum] + q2*q2/((double)in->length); + } + } + + template double narray_var(const narray &q) + { + double ret = 0.0; + narray sums; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + double mn = ams::narray::narray_mean(q); + double q2; + + if(q.length<=0) + { + return ret; + } + + if(q.lengthnarray_max_threads) ? narray_max_threads : nthreads; + threads.resize(nthreads); + sums.resize(nthreads); + sums.setall(T()); + for(J=0;J, + &q, + &sums, + mn, + J,nthreads + ); + if(threads[J]==NULL) + { + printf("narray_var: warning: thread %d failed to initialize.\n",J); + //handle errors + } + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + ret = T(); + for(J=0;J double narray_stdev(const narray &q) + { + double ret = narray_var(q); + ret = ::sqrt(ret); + return ret; + } + + template void narray_L2norm_tf( + const narray *in, + narray *sums, + int threadnum, + int nthreads + ) + { + int I0,I1,Is,I; + double q2; + Is = in->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? in->length: Is*(threadnum+1); + for(I=I0;Idata[I]; + sums->data[threadnum] = sums->data[threadnum] + q2*q2; + } + } + + template double narray_L2norm(const narray &q) + { + double ret = 0.0; + narray sums; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + double q2; + + if(q.length<=0) + { + return ret; + } + + if(q.lengthnarray_max_threads) ? narray_max_threads : nthreads; + threads.resize(nthreads); + sums.resize(nthreads); + sums.setall(T()); + for(J=0;J, + &q, + &sums, + J,nthreads + ); + if(threads[J]==NULL) + { + printf("narray_L2norm: warning: thread %d failed to initialize.\n",J); + //handle errors + } + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + ret = T(); + for(J=0;J void narray_abs_tf( + const narray *in, + narray *out, + int threadnum, + int nthreads + ) + { + int I0,I1,Is,I; + double q2; + Is = in->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? in->length: Is*(threadnum+1); + for(I=I0;Idata[I] = (in->data[I]data[I] : in->data[I]; + } + } + + + template narray narray_abs(narray &q) + { + narray ret; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + if(q.length<=0) + { + ret.resize(0); + return ret; + } + + ret.resize(q.length); + if(ret.length!=q.length) + { + printf("narray_abs: error - could not allocate return array.\n"); + ret.resize(0); + return ret; + } + + if(q.lengthnarray_max_threads) ? narray_max_threads : nthreads; + threads.resize(nthreads); + for(J=0;J, + &q, + &ret, + J,nthreads + ); + if(threads[J]==NULL) + { + printf("narray_abs: warning: thread %d failed to initialize.\n",J); + //handle errors + } + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + } + + return ret; + } + + +}; //end namespaces +}; + +#endif \ No newline at end of file diff --git a/include/amscppnarray/amscppnarray_random.hpp b/include/amscppnarray/amscppnarray_random.hpp index 75d6e76..55248c4 100644 --- a/include/amscppnarray/amscppnarray_random.hpp +++ b/include/amscppnarray/amscppnarray_random.hpp @@ -5,7 +5,70 @@ namespace ams { namespace narray { +namespace rand +{ + + //Random functions for numeric array class + + //////////////////////////////////////////////////////////////////////// + //Simple Deterministic Psuedorandom Number Generator (32 bit version) // + //////////////////////////////////////////////////////////////////////// + + static const int32_t dpr32_mod = ( ((int32_t)1) << ((int32_t)30) ) - (int32_t)1; + static const int32_t dpr32_mult1 = ( (int32_t) 1201633 ); + static int32_t dpr32_rseed = 0; // global random number seed for numeric array class + + int32_t dpr32_nextseed(int32_t seed); + double dpr32_randd(int32_t *seed); + float dpr32_randf(int32_t *seed); + double dpr32_gaussian(int32_t *seed); + float dpr32_gaussianf(int32_t *seed); + int dpr32_randint(int32_t *seed, int low, int high); + + ams::vect2 dpr32_randuvect2(int32_t *seed); + ams::vect3 dpr32_randuvect3(int32_t *seed); + ams::vect4 dpr32_randuvect4(int32_t *seed); + + ams::vect2f dpr32_randuvect2f(int32_t *seed); + ams::vect3f dpr32_randuvect3f(int32_t *seed); + ams::vect4f dpr32_randuvect4f(int32_t *seed); + //////////////////////////////////////////// + //Numeric array threaded random generators// + //////////////////////////////////////////// + + int32_t get_rseed(); + void set_rseed(int32_t seed); + void set_rseed_withtimer(); + + narray narray_rand(narray_size_t N, + int32_t *rseed = &(ams::narray::rand::dpr32_rseed)); + narray narray_randf(narray_size_t N, + int32_t *rseed = &(ams::narray::rand::dpr32_rseed)); + narray narray_randgauss(narray_size_t N, + int32_t *rseed = &(ams::narray::rand::dpr32_rseed)); + narray narray_randgaussf(narray_size_t N, + int32_t *rseed = &(ams::narray::rand::dpr32_rseed)); + + narray narray_randint(narray_size_t N, int low, int highexcl, + int32_t *rseed = &(ams::narray::rand::dpr32_rseed)); + narray narray_randuvect2(narray_size_t N, + int32_t *rseed = &(ams::narray::rand::dpr32_rseed)); + narray narray_randuvect3(narray_size_t N, + int32_t *rseed = &(ams::narray::rand::dpr32_rseed)); + narray narray_randuvect4(narray_size_t N, + int32_t *rseed = &(ams::narray::rand::dpr32_rseed)); + narray narray_randuvect2f(narray_size_t N, + int32_t *rseed = &(ams::narray::rand::dpr32_rseed)); + narray narray_randuvect3f(narray_size_t N, + int32_t *rseed = &(ams::narray::rand::dpr32_rseed)); + narray narray_randuvect4f(narray_size_t N, + int32_t *rseed = &(ams::narray::rand::dpr32_rseed)); + + + void test_random1(); + +}; }; }; diff --git a/src/amscppnarray/amscppnarray_math.cpp b/src/amscppnarray/amscppnarray_math.cpp new file mode 100644 index 0000000..d7353ee --- /dev/null +++ b/src/amscppnarray/amscppnarray_math.cpp @@ -0,0 +1,85 @@ +#include + +namespace ams +{ +namespace narray +{ + + static void _intl_printarr(narray &q) + { + int I; + if(q.length>0) + { + printf("{"); + for(I=0;I &q) + { + int I; + if(q.length>0) + { + printf("{"); + for(I=0;I a = {-4,-3,-2,-1,0,1,2,3,4,5}; + narray b; + int asum = narray_sum(a); + double amean = narray_mean(a); + + printf("sum(a)=%d\n",asum); + printf("mean(a)=%1.3f\n",amean); + printf("stdev(a)=%1.3f\n",narray_stdev(a)); + printf("L2norm(a)=%1.3f\n",narray_L2norm(a)); + printf("min(a)=%d\n",narray_min(a)); + printf("max(a)=%d\n",narray_max(a)); + + b = narray_abs(a); + _intl_printarr(b); printf("\n"); + + return; + } + + void narray_testmath2() + { + rand::set_rseed_withtimer(); + + narray unif = ams::narray::rand::narray_rand(10000); + double mn1 = narray_mean(unif); + double std1 = narray_stdev(unif); + double mn2,std2; + + + + //_intl_printarr(unif); printf("\n"); + + unif = unif*2.0-1.0; + //_intl_printarr(unif); printf("\n"); + mn2 = narray_mean(unif); + std2 = narray_stdev(unif); + + + printf("mn1=%1.3f std1=%1.3f\n",mn1,std1); + printf("mn2=%1.3f std2=%1.3f\n",mn2,std2); + + + return; + } + +}; +}; \ No newline at end of file diff --git a/src/amscppnarray/amscppnarray_random.cpp b/src/amscppnarray/amscppnarray_random.cpp index a746ed0..87d5eeb 100644 --- a/src/amscppnarray/amscppnarray_random.cpp +++ b/src/amscppnarray/amscppnarray_random.cpp @@ -3,9 +3,584 @@ namespace ams { namespace narray +{ +namespace rand { - + int32_t dpr32_nextseed(int32_t seed) + { + int32_t sret = seed; + sret = ams::mod(sret*dpr32_mult1+1,dpr32_mod); + return sret; + } + + double dpr32_randd(int32_t *seed) + { + double ret; + *seed = ams::narray::rand::dpr32_nextseed(*seed); + ret = (double)*seed/(double)(dpr32_mod-1); + return ret; + } + + float dpr32_randf(int32_t *seed) + { + float ret; + *seed = ams::narray::rand::dpr32_nextseed(*seed); + ret = (float)*seed/(float)(dpr32_mod-1); + return ret; + } + + double dpr32_gaussian(int32_t *seed) + { + double ret = 0.0; + double u1,u2; + u1 = ams::narray::rand::dpr32_randd(seed); + u2 = ams::narray::rand::dpr32_randd(seed); + + if(u1>0.0) + { + ret = ::sqrt(-2.0*::log(u1))*::cos(2.0*pi*u2); + } + + return ret; + } + + + float dpr32_gaussianf(int32_t *seed) + { + float ret = 0.0f; + float u1,u2; + u1 = ams::narray::rand::dpr32_randf(seed); + u2 = ams::narray::rand::dpr32_randf(seed); + + if(u1>0.0) + { + ret = ::sqrt(-2.0f*::log(u1))*::cos(2.0f*pif*u2); + } + + return ret; + } + + vect2 dpr32_randuvect2(int32_t *seed) + { + vect2 ret = vect2(0,0); + double th = ams::narray::rand::dpr32_randd(seed)*2.0*pi; + ret = vect2(cos(th),sin(th)); + return ret; + } + + vect3 dpr32_randuvect3(int32_t *seed) + { + vect3 ret; + double az,el; + el = ::acos(2.0*dpr32_randd(seed)-1.0)-pi/2.0; + az = ams::narray::rand::dpr32_randd(seed)*2.0*pi; + + ret = vect3(cos(az)*cos(el),sin(az)*cos(el),sin(el)); + + return ret; + } + + vect4 dpr32_randuvect4(int32_t *seed) + { + vect4 ret; + double x,y,z,w; + + x = ams::narray::rand::dpr32_gaussian(seed); + y = ams::narray::rand::dpr32_gaussian(seed); + z = ams::narray::rand::dpr32_gaussian(seed); + w = ams::narray::rand::dpr32_gaussian(seed); + ret = vect4(x,y,z,w); + ret = vnormalize(ret); + + return ret; + } + + vect2f dpr32_randuvect2f(int32_t *seed) + { + vect2f ret = vect2f(0,0); + float th = ams::narray::rand::dpr32_randf(seed)*2.0*pi; + ret = vect2f(cos(th),sin(th)); + return ret; + } + + vect3f dpr32_randuvect3f(int32_t *seed) + { + vect3f ret; + float az,el; + el = ::acos(2.0f*dpr32_randf(seed)-1.0)-pif/2.0; + az = ams::narray::rand::dpr32_randf(seed)*2.0f*pif; + + ret = vect3f(cos(az)*cos(el),sin(az)*cos(el),sin(el)); + + return ret; + } + + vect4f dpr32_randuvect4f(int32_t *seed) + { + vect4f ret; + float x,y,z,w; + + x = ams::narray::rand::dpr32_gaussianf(seed); + y = ams::narray::rand::dpr32_gaussianf(seed); + z = ams::narray::rand::dpr32_gaussianf(seed); + w = ams::narray::rand::dpr32_gaussianf(seed); + ret = vect4f(x,y,z,w); + ret = vnormalize(ret); + return ret; + } + + int32_t get_rseed() + { + return ams::narray::rand::dpr32_rseed; + } + + void set_rseed(int32_t seed) + { + ams::narray::rand::dpr32_rseed = seed; + } + + void set_rseed_withtimer() + { + int32_t t1 = (int32_t)time(NULL); + int32_t t2 = (int32_t)(::fmod((double)clock()/((double)CLOCKS_PER_SEC)*1000.0f,36000.0f)); + ams::narray::rand::dpr32_rseed = (int32_t)t1 + (int32_t)t2; + } + + template void narray_rand_threadf1( + narray *out, + narray *rseeds, + T (*randfunc)(int32_t *), + int threadnum, + int nthreads + ) + { + int I0,I1,Is,I; + Is = out->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1)) ? out->length : Is*(threadnum+1); + for(I=I0;Idata[I] = randfunc(&(rseeds->data[threadnum])); + } + return; + } + + template void narray_random_threadexec1( + narray *out, + narray_size_t N, + T (*randfunc)(int32_t *), + int32_t *rseed + ) + { + narray_size_t I; + int J; + int nthreads; + std::vector threads; + narray rseeds; + int res; + + res = out->resize(N); + if(res!=narray_success) + { + out->resize(0); + return; + } + + if(Ndata[I] = randfunc(rseed); + } + } + else + { + //multi-threaded operation + nthreads = std::thread::hardware_concurrency(); + nthreads = (nthreads<1) ? 1 : nthreads; + nthreads = (nthreads>narray_max_threads) ? narray_max_threads : nthreads; + threads.resize(nthreads); + rseeds.resize(nthreads); + for(J=0;J, + out, + &rseeds, + randfunc, + J,nthreads + ); + if(threads[J]==NULL) + { + //handle thread allocation error + printf("warning: narray_random_threadexec1:: thread %d failed to allocate.\n",J); + } + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + } + + return; + } + + narray narray_rand(narray_size_t N, + int32_t *rseed) + { + narray ret; + + if(N<=0) + { + ret.resize(0); + return ret; + } + + narray_random_threadexec1( + &ret, + N, + &(ams::narray::rand::dpr32_randd), + rseed + ); + + return ret; + } + + narray narray_randf(narray_size_t N, + int32_t *rseed) + { + narray ret; + + if(N<=0) + { + ret.resize(0); + return ret; + } + + narray_random_threadexec1( + &ret, + N, + &(ams::narray::rand::dpr32_randf), + rseed + ); + + return ret; + } + + narray narray_randgauss(narray_size_t N, + int32_t *rseed) + { + narray ret; + + if(N<=0) + { + ret.resize(0); + return ret; + } + + narray_random_threadexec1( + &ret, + N, + &(ams::narray::rand::dpr32_gaussian), + rseed + ); + + return ret; + } + + narray narray_randgaussf(narray_size_t N, + int32_t *rseed) + { + narray ret; + + if(N<=0) + { + ret.resize(0); + return ret; + } + + narray_random_threadexec1( + &ret, + N, + &(ams::narray::rand::dpr32_gaussianf), + rseed + ); + + return ret; + } + + narray narray_randuvect2(narray_size_t N, + int32_t *rseed) + { + narray ret; + + if(N<=0) + { + ret.resize(0); + return ret; + } + + narray_random_threadexec1( + &ret, + N, + &(ams::narray::rand::dpr32_randuvect2), + rseed + ); + + return ret; + } + + narray narray_randuvect3(narray_size_t N, + int32_t *rseed) + { + narray ret; + + if(N<=0) + { + ret.resize(0); + return ret; + } + + narray_random_threadexec1( + &ret, + N, + &(ams::narray::rand::dpr32_randuvect3), + rseed + ); + + return ret; + } + + narray narray_randuvect4(narray_size_t N, + int32_t *rseed) + { + narray ret; + + if(N<=0) + { + ret.resize(0); + return ret; + } + + narray_random_threadexec1( + &ret, + N, + &(ams::narray::rand::dpr32_randuvect4), + rseed + ); + + return ret; + } + + narray narray_randuvect2f(narray_size_t N, + int32_t *rseed) + { + narray ret; + + if(N<=0) + { + ret.resize(0); + return ret; + } + + narray_random_threadexec1( + &ret, + N, + &(ams::narray::rand::dpr32_randuvect2f), + rseed + ); + + return ret; + } + + narray narray_randuvect3f(narray_size_t N, + int32_t *rseed) + { + narray ret; + + if(N<=0) + { + ret.resize(0); + return ret; + } + + narray_random_threadexec1( + &ret, + N, + &(ams::narray::rand::dpr32_randuvect3f), + rseed + ); + + return ret; + } + + narray narray_randuvect4f(narray_size_t N, + int32_t *rseed) + { + narray ret; + + if(N<=0) + { + ret.resize(0); + return ret; + } + + narray_random_threadexec1( + &ret, + N, + &(ams::narray::rand::dpr32_randuvect4f), + rseed + ); + + return ret; + } + + + int dpr32_randint(int32_t *seed, int low, int high) + { + int ret = 0; + int val; + + if(high-low>0) + { + *seed = dpr32_nextseed(*seed); + val = low + (int)(*seed)%(high-low); + } + + return ret; + } + + template void narray_rand_threadf2( + narray *out, + narray *rseeds, + T (*randfunc)(int32_t *, T, T), + T low, + T highexcl, + int threadnum, + int nthreads + ) + { + int I0,I1,Is,I; + Is = out->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1)) ? out->length : Is*(threadnum+1); + for(I=I0;Idata[I] = randfunc(&(rseeds->data[threadnum]),low,highexcl); + } + return; + } + + template void narray_random_threadexec2( + narray *out, + narray_size_t N, + T (*randfunc)(int32_t *, T, T), + T low, + T highexcl, + int32_t *rseed + ) + { + narray_size_t I; + int J; + int nthreads; + std::vector threads; + narray rseeds; + int res; + + res = out->resize(N); + if(res!=narray_success) + { + out->resize(0); + return; + } + + if(Ndata[I] = randfunc(rseed,low,highexcl); + } + } + else + { + //multi-threaded operation + nthreads = std::thread::hardware_concurrency(); + nthreads = (nthreads<1) ? 1 : nthreads; + nthreads = (nthreads>narray_max_threads) ? narray_max_threads : nthreads; + threads.resize(nthreads); + rseeds.resize(nthreads); + for(J=0;J, + out, + &rseeds, + randfunc, + low,highexcl, + J,nthreads + ); + if(threads[J]==NULL) + { + //handle thread allocation error + printf("warning: narray_random_threadexec1:: thread %d failed to allocate.\n",J); + } + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + } + + return; + } + + narray narray_randint(narray_size_t N, int low, int highexcl, + int32_t *rseed) + { + narray ret; + + if(N<=0) + { + ret.resize(0); + return ret; + } + + narray_random_threadexec2( + &ret, + N, + &(ams::narray::rand::dpr32_randint), + low,highexcl, + rseed + ); + + return ret; + } + + +}; //end namespace rand }; //end namespaces }; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 2e1ba97..90c4e6b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ int main(int argc, char* argv[]) //ams::narray::test_narray1(); //ams::narray::test_narray2(); //ams::narray::test_narray3(); + ams::narray::narray_testmath2(); return ret; } \ No newline at end of file