ext/numo/narray/gen/tmpl/rand_norm.c in numo-narray-0.9.0.3 vs ext/numo/narray/gen/tmpl/rand_norm.c in numo-narray-0.9.0.4
- old
+ new
@@ -1,46 +1,119 @@
+typedef struct {
+ dtype mu;
+ rtype sigma;
+} randn_opt_t;
+
static void
<%=c_iter%>(na_loop_t *const lp)
{
size_t i;
char *p1;
ssize_t s1;
size_t *idx1;
- dtype y;
- dtype a[2];
+ <% if is_complex %>
+ dtype *a0;
+ <% else %>
+ dtype *a0, *a1;
+ <% end %>
+ dtype mu;
+ rtype sigma;
+ randn_opt_t *g;
INIT_COUNTER(lp, i);
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
+ g = (randn_opt_t*)(lp->opt_ptr);
+ mu = g->mu;
+ sigma = g->sigma;
+
if (idx1) {
+ <% if is_complex %>
+ for (; i--;) {
+ a0 = (dtype*)(p1+*idx1);
+ m_rand_norm(mu,sigma,a0);
+ idx1 += 1;
+ }
+ <% else %>
for (; i>1; i-=2) {
- m_rand_norm(a);
- *(dtype*)(p1+*idx1) = a[0];
- *(dtype*)(p1+*(idx1+1)) = a[1];
+ a0 = (dtype*)(p1+*idx1);
+ a1 = (dtype*)(p1+*(idx1+1));
+ m_rand_norm(mu,sigma,a0,a1);
idx1 += 2;
}
if (i>0) {
- m_rand_norm(a);
- *(dtype*)(p1+*idx1) = a[0];
+ a0 = (dtype*)(p1+*idx1);
+ m_rand_norm(mu,sigma,a0,0);
}
+ <% end %>
} else {
+ <% if is_complex %>
+ for (; i--;) {
+ a0 = (dtype*)(p1);
+ m_rand_norm(mu,sigma,a0);
+ p1 += s1;
+ }
+ <% else %>
for (; i>1; i-=2) {
- m_rand_norm(a);
- *(dtype*)(p1) = a[0];
- *(dtype*)(p1+s1) = a[1];
+ a0 = (dtype*)(p1);
+ a1 = (dtype*)(p1+s1);
+ m_rand_norm(mu,sigma,a0,a1);
p1 += s1*2;
}
if (i>0) {
- m_rand_norm(a);
- *(dtype*)(p1) = a[0];
+ a0 = (dtype*)(p1);
+ m_rand_norm(mu,sigma,a0,0);
}
+ <% end %>
}
}
+/*
+ Generates random numbers from the normal distribution on self narray
+ using Box-Muller Transformation.
+ @overload rand_norm([mu,[sigma]])
+ @param [Numeric] mu mean of normal distribution. (default=0)
+ @param [Numeric] sigma standard deviation of normal distribution. (default=1)
+ @return [Numo::<%=class_name%>] self.
+ @example
+ Numo::DFloat.new(5,5).rand_norm
+ => Numo::DFloat#shape=[5,5]
+ [[-0.581255, -0.168354, 0.586895, -0.595142, -0.802802],
+ [-0.326106, 0.282922, 1.68427, 0.918499, -0.0485384],
+ [-0.464453, -0.992194, 0.413794, -0.60717, -0.699695],
+ [-1.64168, 0.48676, -0.875871, -1.43275, 0.812172],
+ [-0.209975, -0.103612, -0.878617, -1.42495, 1.0968]]
+ Numo::DFloat.new(5,5).rand_norm(10,0.1)
+ => Numo::DFloat#shape=[5,5]
+ [[9.9019, 9.90339, 10.0826, 9.98384, 9.72861],
+ [9.81507, 10.0272, 9.91445, 10.0568, 9.88923],
+ [10.0234, 9.97874, 9.96011, 9.9006, 9.99964],
+ [10.0186, 9.94598, 9.92236, 9.99811, 9.97003],
+ [9.79266, 9.95044, 9.95212, 9.93692, 10.2027]]
+ Numo::DComplex.new(3,3).rand_norm(5+5i)
+ => Numo::DComplex#shape=[3,3]
+ [[5.84303+4.40052i, 4.00984+6.08982i, 5.10979+5.13215i],
+ [4.26477+3.99655i, 4.90052+5.00763i, 4.46607+2.3444i],
+ [4.5528+7.11003i, 5.62117+6.69094i, 5.05443+5.35133i]]
+*/
static VALUE
-<%=c_func%>(VALUE self)
+<%=c_func%>(int argc, VALUE *args, VALUE self)
{
+ int n;
+ randn_opt_t g;
+ VALUE v1=Qnil, v2=Qnil;
ndfunc_arg_in_t ain[1] = {{OVERWRITE,0}};
- ndfunc_t ndf = { <%=c_iter%>, FULL_LOOP, 1, 0, ain, 0 };
+ ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP, 1,0, ain,0};
- na_ndloop(&ndf, 1, self);
- return self
+ n = rb_scan_args(argc, args, "02", &v1, &v2);
+ if (n == 0) {
+ g.mu = m_zero;
+ } else {
+ g.mu = m_num_to_data(v1);
+ }
+ if (n == 2) {
+ g.sigma = NUM2DBL(v2);
+ } else {
+ g.sigma = 1;
+ }
+ na_ndloop3(&ndf, &g, 1, self);
+ return self;
}