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_sphere_cap.h (4318B)


      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_SPHERE_CAP_H
     17 #define TEST_SSP_RAN_SPHERE_CAP_H
     18 
     19 #include "ssp.h"
     20 #include "test_ssp_utils.h"
     21 
     22 #define NSAMPS 1024
     23 
     24 #endif /* TEST_SSP_RAN_SPHERE_H */
     25 
     26 #if TYPE_FLOAT==0
     27   #define REAL double
     28   #define TEST test_double
     29   #define RAN_SPHERE_CAP_UNIFORM_LOCAL ssp_ran_sphere_cap_uniform_local
     30   #define RAN_SPHERE_CAP_UNIFORM_PDF ssp_ran_sphere_cap_uniform_pdf
     31   #define RAN_SPHERE_CAP_UNIFORM ssp_ran_sphere_cap_uniform
     32   #define RAN_SPHERE_UNIFORM ssp_ran_sphere_uniform
     33   #define EQ_EPS eq_eps
     34   #define R3_EQ_EPS d3_eq_eps
     35   #define R3_IS_NORMALIZED d3_is_normalized
     36   #define R3_NORMALIZE d3_normalize
     37   #define R3_DOT d3_dot
     38 #elif TYPE_FLOAT==1
     39   #define REAL float
     40   #define TEST test_float
     41   #define RAN_SPHERE_CAP_UNIFORM_LOCAL ssp_ran_sphere_cap_uniform_float_local
     42   #define RAN_SPHERE_CAP_UNIFORM_PDF ssp_ran_sphere_cap_uniform_float_pdf
     43   #define RAN_SPHERE_CAP_UNIFORM ssp_ran_sphere_cap_uniform_float
     44   #define RAN_SPHERE_UNIFORM ssp_ran_sphere_uniform_float
     45   #define EQ_EPS eq_epsf
     46   #define R3_EQ_EPS f3_eq_eps
     47   #define R3_IS_NORMALIZED f3_is_normalized
     48   #define R3_NORMALIZE f3_normalize
     49   #define R3_DOT f3_dot
     50 #else
     51   #error "TYPE_FLOAT must be defined either 0 or 1"
     52 #endif
     53 
     54 static void
     55 TEST(void)
     56 {
     57   struct ssp_rng* rng;
     58   struct mem_allocator allocator;
     59   REAL pdf;
     60   REAL samps[NSAMPS][3];
     61   REAL up[3];
     62   int i, j;
     63 
     64   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
     65   CHK(ssp_rng_create(&allocator, SSP_RNG_MT19937_64, &rng) == RES_OK);
     66 
     67   CHK(RAN_SPHERE_CAP_UNIFORM_LOCAL(rng, 1, samps[0], &pdf) == samps[0]);
     68   CHK(samps[0][0] == 0);
     69   CHK(samps[0][1] == 0);
     70   CHK(samps[0][2] == 1);
     71   CHK(IS_INF(pdf));
     72 
     73   CHK(RAN_SPHERE_CAP_UNIFORM_LOCAL(rng,-1, samps[0], &pdf) == samps[0]);
     74   CHK(EQ_EPS(pdf, 1/(4*(REAL)PI), (REAL)1.e-6));
     75 
     76   /* Check NULL pdf */
     77   CHK(RAN_SPHERE_CAP_UNIFORM_LOCAL(rng, (REAL)0.2, samps[0], NULL) == samps[0]);
     78 
     79   FOR_EACH(i, 0, NSAMPS) {
     80     const REAL height = (REAL)-0.7;
     81     CHK(RAN_SPHERE_CAP_UNIFORM_LOCAL(rng, height, samps[i], &pdf) == samps[i]);
     82     CHK(R3_IS_NORMALIZED(samps[i]));
     83     CHK(EQ_EPS(pdf, 1/(2*(REAL)PI*(1-height)), (REAL)1.e-6));
     84     CHK(EQ_EPS(pdf, RAN_SPHERE_CAP_UNIFORM_PDF(height), (REAL)1.e-6));
     85     CHK(samps[i][2] >= height);
     86     FOR_EACH(j, 0, i) {
     87       CHK(!R3_EQ_EPS(samps[j], samps[i], (REAL)1.e-6));
     88     }
     89   }
     90 
     91   /* Sample an up vector */
     92   RAN_SPHERE_UNIFORM(rng, up, NULL);
     93 
     94   CHK(RAN_SPHERE_CAP_UNIFORM(rng, up, 1, samps[0], &pdf) == samps[0]);
     95   CHK(R3_EQ_EPS(samps[0], up, (REAL)1.e-6));
     96   CHK(IS_INF(pdf));
     97 
     98   CHK(RAN_SPHERE_CAP_UNIFORM(rng, up, -1, samps[0], &pdf) == samps[0]);
     99   CHK(EQ_EPS(pdf, 1/(4*(REAL)PI), (REAL)1.e-6));
    100 
    101   /* Check NULL pdf */
    102   CHK(RAN_SPHERE_CAP_UNIFORM(rng, up, (REAL)0.2, samps[0], NULL) == samps[0]);
    103 
    104   FOR_EACH(i, 0, NSAMPS) {
    105     const REAL height = (REAL)0.3;
    106     CHK(RAN_SPHERE_CAP_UNIFORM(rng, up, height, samps[i], &pdf) == samps[i]);
    107     CHK(R3_IS_NORMALIZED(samps[i]));
    108     CHK(EQ_EPS(pdf, 1/(2*(REAL)PI*(1-height)), (REAL)1.e-6));
    109     CHK(EQ_EPS(pdf, RAN_SPHERE_CAP_UNIFORM_PDF(height), (REAL)1.e-6));
    110     CHK(R3_DOT(up, samps[i]) >= height);
    111     FOR_EACH(j, 0, i) {
    112       CHK(!R3_EQ_EPS(samps[j], samps[i], (REAL)1.e-6));
    113     }
    114   }
    115 
    116   ssp_rng_ref_put(rng);
    117   check_memory_allocator(&allocator);
    118   mem_shutdown_proxy_allocator(&allocator);
    119 
    120   CHK(mem_allocated_size() == 0);
    121 }
    122 
    123 #undef REAL
    124 #undef TEST
    125 #undef RAN_SPHERE_CAP_UNIFORM_LOCAL
    126 #undef RAN_SPHERE_CAP_UNIFORM_PDF
    127 #undef RAN_SPHERE_CAP_UNIFORM
    128 #undef RAN_SPHERE_UNIFORM
    129 #undef EQ_EPS
    130 #undef R3_EQ_EPS
    131 #undef R3_IS_NORMALIZED
    132 #undef R3_NORMALIZE
    133 #undef R3_DOT
    134 #undef TYPE_FLOAT