star-sp

Random number generators and distributions
git clone git://git.meso-star.fr/star-sp.git
Log | Files | Refs | README | LICENSE

test_ssp_ran_piecewise_linear.h (5758B)


      1 /* Copyright (C) 2015-2025 |Méso|Star> (contact@meso-star.com)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #ifndef TEST_SSP_RAN_PIECEWISE_LINEAR_H
     17 #define TEST_SSP_RAN_PIECEWISE_LINEAR_H
     18 
     19 #include "ssp.h"
     20 #include "test_ssp_utils.h"
     21 
     22 #define NBS 1000000
     23 
     24 #endif /* TEST_SSP_RAN_PIECEWISE_LINEAR_H */
     25 
     26 #if TYPE_FLOAT==0
     27   #define REAL double
     28   #define TEST test_double
     29   #define RANST_PIECEWISE_LINEAR ssp_ranst_piecewise_linear
     30   #define RANST_PIECEWISE_LINEAR_CREATE ssp_ranst_piecewise_linear_create
     31   #define RANST_PIECEWISE_LINEAR_SETUP ssp_ranst_piecewise_linear_setup
     32   #define RANST_PIECEWISE_LINEAR_GET ssp_ranst_piecewise_linear_get
     33   #define RANST_PIECEWISE_LINEAR_PDF ssp_ranst_piecewise_linear_pdf
     34   #define RANST_PIECEWISE_LINEAR_REF_GET ssp_ranst_piecewise_linear_ref_get
     35   #define RANST_PIECEWISE_LINEAR_REF_PUT ssp_ranst_piecewise_linear_ref_put
     36   #define EQ_EPS_R eq_eps
     37   #define EPS_R DBL_EPSILON
     38   #define SQRT sqrt
     39 
     40 #elif TYPE_FLOAT==1
     41   #define REAL float
     42   #define TEST test_float
     43   #define RANST_PIECEWISE_LINEAR ssp_ranst_piecewise_linear_float
     44   #define RANST_PIECEWISE_LINEAR_CREATE ssp_ranst_piecewise_linear_float_create
     45   #define RANST_PIECEWISE_LINEAR_SETUP ssp_ranst_piecewise_linear_float_setup
     46   #define RANST_PIECEWISE_LINEAR_GET ssp_ranst_piecewise_linear_float_get
     47   #define RANST_PIECEWISE_LINEAR_PDF ssp_ranst_piecewise_linear_float_pdf
     48   #define RANST_PIECEWISE_LINEAR_REF_GET ssp_ranst_piecewise_linear_float_ref_get
     49   #define RANST_PIECEWISE_LINEAR_REF_PUT ssp_ranst_piecewise_linear_float_ref_put
     50   #define EQ_EPS_R eq_epsf
     51   #define EPS_R FLT_EPSILON
     52   #define SQRT (float)sqrt
     53 #else
     54   #error "TYPE_FLOAT must be defined either 0 or 1"
     55 #endif
     56 
     57 static void
     58 TEST()
     59 {
     60   struct ssp_rng* rng;
     61   struct mem_allocator allocator;
     62   struct RANST_PIECEWISE_LINEAR *pwl;
     63   int i;
     64   REAL exp_mean = 5, mean;
     65   REAL exp_std = 10 / SQRT(12) /*sqrt((b - a)² / 12) */, std;
     66   REAL x = 0, x2 = 0;
     67   REAL intervals[] = { 0, 1, 3, 5, 7, 8, 10 };
     68   REAL weights[] = { 1, 1, 1, 1, 1, 1, 1 };
     69 
     70   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
     71 
     72   CHK(ssp_rng_create(&allocator, SSP_RNG_MT19937_64, &rng) == RES_OK);
     73 
     74   CHK(RANST_PIECEWISE_LINEAR_CREATE(NULL, NULL) == RES_BAD_ARG);
     75   CHK(RANST_PIECEWISE_LINEAR_CREATE(NULL, &pwl) == RES_OK);
     76   CHK(RANST_PIECEWISE_LINEAR_REF_PUT(pwl) == RES_OK);
     77 
     78   CHK(RANST_PIECEWISE_LINEAR_CREATE(&allocator, NULL) == RES_BAD_ARG);
     79   CHK(RANST_PIECEWISE_LINEAR_CREATE(&allocator, &pwl) == RES_OK);
     80 
     81   CHK(RANST_PIECEWISE_LINEAR_SETUP
     82     (NULL, intervals, weights, sizeof(intervals)/sizeof(REAL)) == RES_BAD_ARG);
     83   CHK(RANST_PIECEWISE_LINEAR_SETUP
     84     (pwl, NULL, weights, sizeof(intervals)/sizeof(REAL)) == RES_BAD_ARG);
     85   CHK(RANST_PIECEWISE_LINEAR_SETUP
     86     (pwl, intervals, NULL, sizeof(intervals)/sizeof(REAL)) == RES_BAD_ARG);
     87   CHK(RANST_PIECEWISE_LINEAR_SETUP
     88     (pwl, intervals, weights, 1) == RES_BAD_ARG);
     89   CHK(RANST_PIECEWISE_LINEAR_SETUP
     90     (pwl, intervals, weights, sizeof(intervals)/sizeof(REAL)) == RES_OK);
     91 
     92   CHK(RANST_PIECEWISE_LINEAR_REF_PUT(pwl) == RES_OK);
     93   CHK(RANST_PIECEWISE_LINEAR_CREATE(&allocator, &pwl) == RES_OK);
     94 
     95   weights[1] = -1;
     96   CHK(RANST_PIECEWISE_LINEAR_SETUP
     97     (pwl, intervals, weights, sizeof(intervals) / sizeof(REAL)) == RES_BAD_ARG);
     98   weights[1] = 1;
     99 
    100   intervals[1] = 4;
    101   CHK(RANST_PIECEWISE_LINEAR_SETUP
    102     (pwl, intervals, weights, sizeof(intervals) / sizeof(REAL)) == RES_BAD_ARG);
    103   intervals[1] = 1;
    104 
    105   intervals[1] = 3;
    106   CHK(RANST_PIECEWISE_LINEAR_SETUP
    107   (pwl, intervals, weights, sizeof(intervals) / sizeof(REAL)) == RES_BAD_ARG);
    108   intervals[1] = 1;
    109 
    110   CHK(RANST_PIECEWISE_LINEAR_SETUP
    111     (pwl, intervals, weights, sizeof(intervals) / sizeof(REAL)) == RES_OK);
    112 
    113   CHK(RANST_PIECEWISE_LINEAR_REF_GET(NULL) == RES_BAD_ARG);
    114   CHK(RANST_PIECEWISE_LINEAR_REF_GET(pwl) == RES_OK);
    115 
    116   CHK(RANST_PIECEWISE_LINEAR_REF_PUT(NULL) == RES_BAD_ARG);
    117   CHK(RANST_PIECEWISE_LINEAR_REF_PUT(pwl) == RES_OK);
    118 
    119   FOR_EACH(i, 0, NBS) {
    120     REAL pdf, r;
    121     r = RANST_PIECEWISE_LINEAR_GET(pwl, rng);
    122     CHK(0 <= r && r <= 10);
    123     pdf = RANST_PIECEWISE_LINEAR_PDF(pwl, r);
    124     CHK(EQ_EPS_R(pdf, (REAL)0.1, EPS_R) == 1);
    125     x += r;
    126     x2 += r * r;
    127   }
    128   CHK(EQ_EPS_R(RANST_PIECEWISE_LINEAR_PDF(pwl, 0), (REAL)0.1, EPS_R) == 1);
    129   CHK(EQ_EPS_R(RANST_PIECEWISE_LINEAR_PDF(pwl, 10), (REAL)0.1, EPS_R) == 1);
    130   CHK(RANST_PIECEWISE_LINEAR_PDF(pwl, -1) == 0);
    131   CHK(RANST_PIECEWISE_LINEAR_PDF(pwl, 11) == 0);
    132 
    133   mean = x/NBS;
    134   std = SQRT(x2/NBS - mean*mean);
    135   printf("%g %g\n", mean, std);
    136   CHK(EQ_EPS_R(mean, exp_mean, (REAL)1e-2) == 1);
    137   CHK(EQ_EPS_R(std, exp_std, (REAL)1.e-2) == 1);
    138 
    139   CHK(RANST_PIECEWISE_LINEAR_REF_PUT(pwl) == RES_OK);
    140 
    141   CHK(ssp_rng_ref_put(rng) == RES_OK);
    142 
    143   check_memory_allocator(&allocator);
    144   mem_shutdown_proxy_allocator(&allocator);
    145   CHK(mem_allocated_size() == 0);
    146 }
    147 
    148 #undef REAL
    149 #undef TEST
    150 #undef RANST_PIECEWISE_LINEAR
    151 #undef RANST_PIECEWISE_LINEAR_CREATE
    152 #undef RANST_PIECEWISE_LINEAR_SETUP
    153 #undef RANST_PIECEWISE_LINEAR_GET
    154 #undef RANST_PIECEWISE_LINEAR_PDF
    155 #undef RANST_PIECEWISE_LINEAR_REF_GET
    156 #undef RANST_PIECEWISE_LINEAR_REF_PUT
    157 #undef EQ_EPS_R
    158 #undef EPS_R
    159 #undef SQRT
    160 #undef TYPE_FLOAT