LCOV - code coverage report
Current view: top level - modules - rand.sl (source / functions) Hit Total Coverage
Test: all.lcov Lines: 79 84 94.0 %
Date: 2022-08-02 14:41:00 Functions: 10 10 100.0 %

          Line data    Source code
       1             : % Copyright (C) 2012-2021,2022 John E. Davis
       2             : %
       3             : % This file is part of the S-Lang Library and may be distributed under the
       4             : % terms of the GNU General Public License.  See the file COPYING for
       5             : % more information.
       6             : %---------------------------------------------------------------------------
       7           4 : import ("rand");
       8             : 
       9             : private define get_generator_args (nargs, num_parms, parmsp, rtp, nump,
      10             :                                    usage_str)
      11             : {
      12         122 :    @rtp = NULL;
      13         122 :    @nump = NULL;
      14         122 :    if (nargs == num_parms)
      15             :      {
      16          39 :         @parmsp = __pop_list (num_parms);
      17             :         return;
      18             :      }
      19             : 
      20          83 :    if (nargs == num_parms + 1)
      21             :      {
      22          81 :         @nump = ();
      23          81 :         variable parms = __pop_list (num_parms);
      24          81 :         if (typeof (parms[0]) == Rand_Type)
      25             :           {
      26           1 :              @rtp = list_pop (parms);
      27           1 :              list_append (parms, @nump);
      28           1 :              @nump = NULL;
      29             :           }
      30          81 :         @parmsp = parms;
      31             :         return;
      32             :      }
      33             : 
      34           2 :    if (nargs == num_parms + 2)
      35             :      {
      36           1 :         @nump = ();
      37           1 :         @parmsp = __pop_list (num_parms);
      38           1 :         variable rt = ();
      39           1 :         if (typeof (rt) == Rand_Type)
      40             :           {
      41           1 :              @rtp = rt;
      42             :              return;
      43             :           }
      44             :      }
      45           1 :    else _pop_n (nargs);
      46             : 
      47           1 :    usage (usage_str);
      48             : }
      49             : 
      50             : private define call_rand_func ()
      51             : {
      52         184 :    variable num = ();
      53         184 :    variable args = __pop_list (_NARGS-3);
      54             :    variable rt, func;
      55         184 :    (func, rt) = ();
      56             : 
      57         184 :    if (rt == NULL)
      58             :      {
      59         182 :         if (num == NULL)
      60          60 :           return (@func) (__push_list(args));
      61             : 
      62         122 :         return (@func) (__push_list(args), num);
      63             :      }
      64             : 
      65           2 :    if (num == NULL)
      66           1 :      return (@func)(rt, __push_list(args));
      67             : 
      68           1 :    return (@func)(rt, __push_list(args), num);
      69             : }
      70             : 
      71             : define rand_flat ()
      72             : {
      73             :    variable parms, rt, num;
      74             : 
      75           3 :    get_generator_args (_NARGS, 2, &parms, &rt, &num,
      76             :                        "r = rand_flat ([Rand_Type,] xmin, xmax [,num])");
      77             : 
      78           3 :    variable r = call_rand_func (&rand_uniform, rt, num);
      79             : 
      80           3 :    return parms[0] + (parms[1] - parms[0])*__tmp(r);
      81             : }
      82             : 
      83             : define rand_chisq ()
      84             : {
      85             :    variable parms, rt, num;
      86             : 
      87          27 :    get_generator_args (_NARGS, 1, &parms, &rt, &num,
      88             :                        "r = rand_chisq ([Rand_Type,] nu [,num])");
      89          27 :    return 2.0 * call_rand_func (&rand_gamma, rt, 0.5*parms[0], 1.0, num);
      90             : }
      91             : 
      92             : define rand_fdist ()
      93             : {
      94             :    variable parms, rt, num;
      95             : 
      96          48 :    get_generator_args (_NARGS, 2, &parms, &rt, &num,
      97             :                        "r = rand_fdist ([Rand_Type,] nu1, nu2 [,num])");
      98          96 :    variable nu1 = parms[0], nu2 = parms[1];
      99             : 
     100          48 :    return (call_rand_func (&rand_gamma, rt, 0.5*nu1, 1.0, num)/nu1)
     101             :      / (call_rand_func(&rand_gamma, rt, 0.5*nu2, 1.0, num)/nu2);
     102             : }
     103             : 
     104             : define rand_tdist ()
     105             : {
     106             :    variable parms, rt, num;
     107             : 
     108          15 :    get_generator_args (_NARGS, 1, &parms, &rt, &num,
     109             :                        "r = rand_tdist ([Rand_Type,] nu, [,num])");
     110          15 :    variable nu = parms[0];
     111          15 :    return call_rand_func (&rand_gauss, rt, 1.0, num)
     112             :      / sqrt(call_rand_func(&rand_chisq, rt, nu, num)/nu);
     113             : }
     114             : 
     115             : define rand_int ()
     116             : {
     117             :    variable parms, rt, num;
     118             : 
     119          11 :    get_generator_args (_NARGS, 2, &parms, &rt, &num,
     120             :                        "r = rand_int ([Rand_Type,] imin, imax [,num])");
     121             : 
     122             :    variable
     123          10 :      imin = typecast (parms[0], Int32_Type),
     124          10 :      imax = typecast (parms[1], Int32_Type), di;
     125             : 
     126          10 :    if (imin > imax)
     127           0 :      throw InvalidParmError, "rand_int: imax < imin";
     128             : 
     129          10 :    di = typecast (imax - imin, UInt32_Type);
     130             : 
     131          10 :    variable r = call_rand_func (&rand, rt, num);
     132             : 
     133          10 :    if (di + 1 != 0)                    % UINT32_MAX does not exist
     134           9 :      r = __tmp(r) mod (di + 1);
     135             : 
     136          10 :    return typecast (imin + r, Int32_Type);
     137             : }
     138             : 
     139             : define rand_exp ()
     140             : {
     141             :    variable parms, rt, num;
     142             : 
     143          18 :    get_generator_args (_NARGS, 1, &parms, &rt, &num,
     144             :                        "r = rand_exp ([Rand_Type,] beta [,num])");
     145             : 
     146          18 :    return (-parms[0]) * log (call_rand_func (&rand_uniform_pos, rt, num));
     147             : }
     148             : 
     149             : private define make_indices (a, d, i)
     150             : {
     151          48 :    _for (0, length(array_shape(a))-1, 1)
     152             :      {
     153          96 :         variable j = ();
     154          96 :         if (j == d)
     155          48 :           i;
     156             :         else
     157          48 :           [:];
     158             :      }
     159             : }
     160             : 
     161             : define rand_sample ()
     162             : {
     163          32 :    if (_NARGS < 2)
     164             :      {
     165           0 :         _pop_n (_NARGS);
     166           0 :         usage ("(B1 [,B2,...]) = rand_sample ([Rand_Type,] A1 [A2,...], num)");
     167             :      }
     168             : 
     169          32 :    variable num = ();
     170          32 :    variable arrays = __pop_list (_NARGS-1);
     171          32 :    variable rt = NULL;
     172             : 
     173          32 :    if (typeof (arrays[0]) == Rand_Type)
     174          16 :      rt = list_pop (arrays);
     175             : 
     176          32 :    variable n0 = NULL, dim0;
     177             :    variable a, indices;
     178             : 
     179          32 :    foreach a (arrays)
     180             :      {
     181          48 :         dim0 = array_shape (a)[0];
     182          48 :         if (n0 == NULL)
     183             :           {
     184          32 :              n0 = dim0;
     185          32 :              continue;
     186             :           }
     187          16 :         if (n0 != dim0)
     188           0 :           throw TypeMismatchError, "The arrays passed to rand_sample must have the same leading dimension";
     189             :      }
     190             : 
     191          32 :    if (num > n0)
     192           0 :      num = n0;
     193             : 
     194          32 :    if (rt == NULL)
     195          16 :      indices = rand_permutation (n0);
     196             :    else
     197          16 :      indices = rand_permutation (rt, n0);
     198          32 :    if (num < n0)
     199          24 :      indices = indices[[0:num-1]];
     200             : 
     201          32 :    foreach a (arrays)
     202          48 :      a[make_indices(a, 0, indices)];
     203             : }
     204             : 

Generated by: LCOV version 1.13