updates
This commit is contained in:
85
src/amscppnarray/amscppnarray_math.cpp
Normal file
85
src/amscppnarray/amscppnarray_math.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include <amscppnarray/amscppnarray.hpp>
|
||||
|
||||
namespace ams
|
||||
{
|
||||
namespace narray
|
||||
{
|
||||
|
||||
static void _intl_printarr(narray<int> &q)
|
||||
{
|
||||
int I;
|
||||
if(q.length>0)
|
||||
{
|
||||
printf("{");
|
||||
for(I=0;I<q.length-1;I++) printf("%d,",q[I]);
|
||||
printf("%d}",q[q.length-1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("{}");
|
||||
}
|
||||
}
|
||||
|
||||
static void _intl_printarr(narray<double> &q)
|
||||
{
|
||||
int I;
|
||||
if(q.length>0)
|
||||
{
|
||||
printf("{");
|
||||
for(I=0;I<q.length-1;I++) printf("%1.3f,",q[I]);
|
||||
printf("%1.3f}",q[q.length-1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("{}");
|
||||
}
|
||||
}
|
||||
|
||||
void narray_testmath1()
|
||||
{
|
||||
narray<int> a = {-4,-3,-2,-1,0,1,2,3,4,5};
|
||||
narray<int> 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<double> 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;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
@ -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<typename T> void narray_rand_threadf1(
|
||||
narray<T> *out,
|
||||
narray<int32_t> *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;I<I1;I++)
|
||||
{
|
||||
out->data[I] = randfunc(&(rseeds->data[threadnum]));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
template<typename T> void narray_random_threadexec1(
|
||||
narray<T> *out,
|
||||
narray_size_t N,
|
||||
T (*randfunc)(int32_t *),
|
||||
int32_t *rseed
|
||||
)
|
||||
{
|
||||
narray_size_t I;
|
||||
int J;
|
||||
int nthreads;
|
||||
std::vector<std::thread*> threads;
|
||||
narray<int32_t> rseeds;
|
||||
int res;
|
||||
|
||||
res = out->resize(N);
|
||||
if(res!=narray_success)
|
||||
{
|
||||
out->resize(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(N<narray_thread_sz)
|
||||
{
|
||||
//single threaded
|
||||
for(I=0;I<N;I++)
|
||||
{
|
||||
out->data[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<nthreads;J++)
|
||||
{
|
||||
*rseed = dpr32_nextseed(*rseed);
|
||||
rseeds.data[J] = *rseed + 13*J;
|
||||
}
|
||||
for(J=0;J<nthreads;J++)
|
||||
{
|
||||
threads[J] = new(std::nothrow) std::thread(
|
||||
&narray_rand_threadf1<T>,
|
||||
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;J<nthreads;J++)
|
||||
{
|
||||
if(threads[J]!=NULL)
|
||||
{
|
||||
threads[J]->join();
|
||||
delete threads[J];
|
||||
threads[J]= NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
narray<double> narray_rand(narray_size_t N,
|
||||
int32_t *rseed)
|
||||
{
|
||||
narray<double> ret;
|
||||
|
||||
if(N<=0)
|
||||
{
|
||||
ret.resize(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray_random_threadexec1(
|
||||
&ret,
|
||||
N,
|
||||
&(ams::narray::rand::dpr32_randd),
|
||||
rseed
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray<float> narray_randf(narray_size_t N,
|
||||
int32_t *rseed)
|
||||
{
|
||||
narray<float> ret;
|
||||
|
||||
if(N<=0)
|
||||
{
|
||||
ret.resize(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray_random_threadexec1(
|
||||
&ret,
|
||||
N,
|
||||
&(ams::narray::rand::dpr32_randf),
|
||||
rseed
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray<double> narray_randgauss(narray_size_t N,
|
||||
int32_t *rseed)
|
||||
{
|
||||
narray<double> ret;
|
||||
|
||||
if(N<=0)
|
||||
{
|
||||
ret.resize(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray_random_threadexec1(
|
||||
&ret,
|
||||
N,
|
||||
&(ams::narray::rand::dpr32_gaussian),
|
||||
rseed
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray<float> narray_randgaussf(narray_size_t N,
|
||||
int32_t *rseed)
|
||||
{
|
||||
narray<float> ret;
|
||||
|
||||
if(N<=0)
|
||||
{
|
||||
ret.resize(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray_random_threadexec1(
|
||||
&ret,
|
||||
N,
|
||||
&(ams::narray::rand::dpr32_gaussianf),
|
||||
rseed
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray<vect2> narray_randuvect2(narray_size_t N,
|
||||
int32_t *rseed)
|
||||
{
|
||||
narray<vect2> ret;
|
||||
|
||||
if(N<=0)
|
||||
{
|
||||
ret.resize(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray_random_threadexec1(
|
||||
&ret,
|
||||
N,
|
||||
&(ams::narray::rand::dpr32_randuvect2),
|
||||
rseed
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray<vect3> narray_randuvect3(narray_size_t N,
|
||||
int32_t *rseed)
|
||||
{
|
||||
narray<vect3> ret;
|
||||
|
||||
if(N<=0)
|
||||
{
|
||||
ret.resize(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray_random_threadexec1(
|
||||
&ret,
|
||||
N,
|
||||
&(ams::narray::rand::dpr32_randuvect3),
|
||||
rseed
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray<vect4> narray_randuvect4(narray_size_t N,
|
||||
int32_t *rseed)
|
||||
{
|
||||
narray<vect4> ret;
|
||||
|
||||
if(N<=0)
|
||||
{
|
||||
ret.resize(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray_random_threadexec1(
|
||||
&ret,
|
||||
N,
|
||||
&(ams::narray::rand::dpr32_randuvect4),
|
||||
rseed
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray<vect2f> narray_randuvect2f(narray_size_t N,
|
||||
int32_t *rseed)
|
||||
{
|
||||
narray<vect2f> ret;
|
||||
|
||||
if(N<=0)
|
||||
{
|
||||
ret.resize(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray_random_threadexec1(
|
||||
&ret,
|
||||
N,
|
||||
&(ams::narray::rand::dpr32_randuvect2f),
|
||||
rseed
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray<vect3f> narray_randuvect3f(narray_size_t N,
|
||||
int32_t *rseed)
|
||||
{
|
||||
narray<vect3f> ret;
|
||||
|
||||
if(N<=0)
|
||||
{
|
||||
ret.resize(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray_random_threadexec1(
|
||||
&ret,
|
||||
N,
|
||||
&(ams::narray::rand::dpr32_randuvect3f),
|
||||
rseed
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
narray<vect4f> narray_randuvect4f(narray_size_t N,
|
||||
int32_t *rseed)
|
||||
{
|
||||
narray<vect4f> 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<typename T> void narray_rand_threadf2(
|
||||
narray<T> *out,
|
||||
narray<int32_t> *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;I<I1;I++)
|
||||
{
|
||||
out->data[I] = randfunc(&(rseeds->data[threadnum]),low,highexcl);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
template<typename T> void narray_random_threadexec2(
|
||||
narray<T> *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<std::thread*> threads;
|
||||
narray<int32_t> rseeds;
|
||||
int res;
|
||||
|
||||
res = out->resize(N);
|
||||
if(res!=narray_success)
|
||||
{
|
||||
out->resize(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(N<narray_thread_sz)
|
||||
{
|
||||
//single threaded
|
||||
for(I=0;I<N;I++)
|
||||
{
|
||||
out->data[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<nthreads;J++)
|
||||
{
|
||||
*rseed = dpr32_nextseed(*rseed);
|
||||
rseeds.data[J] = *rseed + 13*J;
|
||||
}
|
||||
for(J=0;J<nthreads;J++)
|
||||
{
|
||||
threads[J] = new(std::nothrow) std::thread(
|
||||
&narray_rand_threadf2<T>,
|
||||
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;J<nthreads;J++)
|
||||
{
|
||||
if(threads[J]!=NULL)
|
||||
{
|
||||
threads[J]->join();
|
||||
delete threads[J];
|
||||
threads[J]= NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
narray<int> narray_randint(narray_size_t N, int low, int highexcl,
|
||||
int32_t *rseed)
|
||||
{
|
||||
narray<int> 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
|
||||
};
|
@ -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;
|
||||
}
|
Reference in New Issue
Block a user