test_ssf_phase_rdgfa.c (4506B)
1 /* Copyright (C) 2016-2018, 2021-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 #include "ssf.h" 17 #include "test_ssf_utils.h" 18 19 #include <string.h> 20 21 int 22 main(int argc, char** argv) 23 { 24 static const size_t NSAMPS = 10000; 25 26 struct mem_allocator allocator; 27 struct ssf_info info = SSF_INFO_NULL; 28 struct ssf_phase_rdgfa_setup_args args = SSF_PHASE_RDGFA_SETUP_ARGS_DEFAULT; 29 struct ssf_phase_rdgfa_desc desc = SSF_PHASE_RDGFA_DESC_NULL; 30 struct ssf_phase_rdgfa_interval interval = SSF_PHASE_RDGFA_INTERVAL_NULL; 31 struct ssf_phase* phase; 32 struct ssf_phase* dummy; 33 struct ssp_rng* rng; 34 double cumulative_prev; 35 double wo[3]; 36 int err = 0; 37 size_t i; 38 (void)argc, (void)argv; 39 40 if(argc <= 1) { 41 fprintf(stderr, "Usage: %s <simd_none|simd_128|simd_256>\n", argv[0]); 42 goto error; 43 } 44 45 if(!strcmp(argv[1], "simd_none")) { 46 args.simd = SSF_SIMD_NONE; 47 } else if(!strcmp(argv[1], "simd_128")) { 48 args.simd = SSF_SIMD_128; 49 } else if(!strcmp(argv[1], "simd_256")) { 50 args.simd = SSF_SIMD_256; 51 } else { 52 fprintf(stderr, "Invalid argument '%s'.\n", argv[1]); 53 goto error; 54 } 55 56 CHK(ssf_get_info(NULL) == RES_BAD_ARG); 57 CHK(ssf_get_info(&info) == RES_OK); 58 if(args.simd == SSF_SIMD_128) { 59 CHK(info.simd_128 != 0); 60 } 61 if(args.simd == SSF_SIMD_256) { 62 CHK(info.simd_256 != 0); 63 } 64 65 mem_init_proxy_allocator(&allocator, &mem_default_allocator); 66 CHK(ssp_rng_create(&allocator, SSP_RNG_MT19937_64, &rng) == RES_OK); 67 68 CHK(ssf_phase_create(&allocator, &ssf_phase_rdgfa, &phase) == RES_OK); 69 CHK(ssf_phase_create(&allocator, &phase_dummy, &dummy) == RES_OK); 70 71 args.wavelength = 532; 72 args.fractal_dimension = 1.80; 73 args.gyration_radius = 111.6372805638; 74 args.nintervals = 1000; 75 CHK(ssf_phase_rdgfa_setup(NULL, &args) == RES_BAD_ARG); 76 CHK(ssf_phase_rdgfa_setup(phase, NULL) == RES_BAD_ARG); 77 CHK(ssf_phase_rdgfa_setup(dummy, &args) == RES_BAD_ARG); 78 CHK(ssf_phase_rdgfa_setup(phase, &args) == RES_OK); 79 80 CHK(ssf_phase_rdgfa_get_desc(NULL, &desc) == RES_BAD_ARG); 81 CHK(ssf_phase_rdgfa_get_desc(phase, NULL) == RES_BAD_ARG); 82 CHK(ssf_phase_rdgfa_get_desc(dummy, &desc) == RES_BAD_ARG); 83 CHK(ssf_phase_rdgfa_get_desc(phase, &desc) == RES_OK); 84 85 CHK(desc.wavelength == args.wavelength); 86 CHK(desc.fractal_dimension == args.fractal_dimension); 87 CHK(desc.gyration_radius == args.gyration_radius); 88 CHK(desc.nintervals = args.nintervals); 89 90 CHK(ssf_phase_rdgfa_get_interval(NULL, 0, &interval) == RES_BAD_ARG); 91 CHK(ssf_phase_rdgfa_get_interval(phase, desc.nintervals+1, &interval) 92 == RES_BAD_ARG); 93 CHK(ssf_phase_rdgfa_get_interval(phase, 0, NULL) == RES_BAD_ARG); 94 95 cumulative_prev = 0; 96 FOR_EACH(i, 0, desc.nintervals) { 97 double range[2]; 98 99 range[0] = PI/(double)desc.nintervals * (double)(i+0); 100 range[1] = PI/(double)desc.nintervals * (double)(i+1); 101 102 CHK(ssf_phase_rdgfa_get_interval(phase, i, &interval) == RES_OK); 103 CHK(eq_eps(interval.range[0], range[0], fabs(range[0]*1.e-6))); 104 CHK(eq_eps(interval.range[1], range[1], fabs(range[1]*1.e-6))); 105 CHK(interval.cumulative > cumulative_prev); 106 CHK(interval.cumulative <= 1.0); 107 108 cumulative_prev = interval.cumulative; 109 } 110 111 ssp_ran_sphere_uniform(rng, wo, NULL); 112 FOR_EACH(i, 0, NSAMPS) { 113 double wi[3]; 114 double pdf; 115 ssf_phase_sample(phase, rng, wo, wi, &pdf); 116 CHK(eq_eps(pdf, ssf_phase_eval(phase, wo, wi), fabs(pdf*1.e-6))); 117 CHK(d3_is_normalized(wi)); 118 119 #if 0 120 fprintf(stderr, "v %g %g %g\n", wi[0]*pdf, wi[1]*pdf, wi[2]*pdf); 121 fprintf(stderr, "p %lu\n", (unsigned long)(i+1)); 122 #endif 123 } 124 125 CHK(ssf_phase_ref_put(phase) == RES_OK); 126 CHK(ssf_phase_ref_put(dummy) == RES_OK); 127 CHK(ssp_rng_ref_put(rng) == RES_OK); 128 129 check_memory_allocator(&allocator); 130 mem_shutdown_proxy_allocator(&allocator); 131 CHK(mem_allocated_size() == 0); 132 exit: 133 return err; 134 error: 135 err = -1; 136 goto exit; 137 } 138