star-mc

Parallel estimation of Monte Carlo integrators
git clone git://git.meso-star.fr/star-mc.git
Log | Files | Refs | README | LICENSE

smc_doubleN.c (5574B)


      1 /* Copyright (C) 2015-2018, 2021-2023 |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 "smc.h"
     17 #include <rsys/dynamic_array_double.h>
     18 #include <math.h>
     19 
     20 /*******************************************************************************
     21  * smc_doubleN functions
     22  ******************************************************************************/
     23 static void
     24 smc_doubleN_destroy(struct mem_allocator* allocator, void* data)
     25 {
     26   struct darray_double* dblN = data;
     27   ASSERT(data);
     28   darray_double_release(dblN);
     29   MEM_RM(allocator, dblN);
     30 }
     31 
     32 static void*
     33 smc_doubleN_create(struct mem_allocator* allocator, void* context)
     34 {
     35   struct smc_doubleN_context* ctx = context;
     36   struct darray_double* dblN = NULL;
     37   res_T res = RES_OK;
     38   ASSERT(allocator);
     39 
     40   if(!ctx || !ctx->count) goto error;
     41 
     42   dblN = MEM_ALLOC(allocator, sizeof(struct darray_double));
     43   if(!dblN) goto error;
     44 
     45   darray_double_init(allocator, dblN);
     46   res = darray_double_resize(dblN, ctx->count);
     47   if(res != RES_OK) goto error;
     48 
     49 exit:
     50   return dblN;
     51 error:
     52   if(dblN) {
     53     smc_doubleN_destroy(allocator, dblN);
     54     dblN = NULL;
     55   }
     56   goto exit;
     57 }
     58 
     59 static void
     60 smc_doubleN_set(void* result, const void* value)
     61 {
     62   struct darray_double* dst = result;
     63   const struct darray_double* src = value;
     64   size_t i, n;
     65   ASSERT(dst && src);
     66 
     67   n = darray_double_size_get(dst);
     68   if(n !=  darray_double_size_get(src)) {
     69     FATAL("The vectors must have the same dimension.\n");
     70   }
     71   FOR_EACH(i, 0, n) {
     72     darray_double_data_get(dst)[i] = darray_double_cdata_get(src)[i];
     73   }
     74 }
     75 
     76 static void
     77 smc_doubleN_zero(void* result)
     78 {
     79   struct darray_double* dblN = result;
     80   ASSERT(result);
     81   memset(darray_double_data_get(dblN), 0,
     82     darray_double_size_get(dblN)*sizeof(double));
     83 }
     84 
     85 static void
     86 smc_doubleN_add(void* result, const void* op0, const void* op1)
     87 {
     88   struct darray_double* dst = result;
     89   const struct darray_double* a = op0;
     90   const struct darray_double* b = op1;
     91   size_t i, n;
     92   ASSERT(result && op0 && op1);
     93 
     94   n = darray_double_size_get(dst);
     95   if(n != darray_double_size_get(a) || n != darray_double_size_get(b)) {
     96     FATAL("The vectors must have the same dimension.\n");
     97   }
     98   FOR_EACH(i, 0, n) {
     99     darray_double_data_get(dst)[i] =
    100       darray_double_cdata_get(a)[i] + darray_double_cdata_get(b)[i];
    101   }
    102 }
    103 
    104 static void
    105 smc_doubleN_sub(void* result, const void* op0, const void* op1)
    106 {
    107   struct darray_double* dst = result;
    108   const struct darray_double* a = op0;
    109   const struct darray_double* b = op1;
    110   size_t i, n;
    111   ASSERT(result && op0 && op1);
    112 
    113   n = darray_double_size_get(dst);
    114   if(n != darray_double_size_get(a) || n != darray_double_size_get(b)) {
    115     FATAL("The vectors must have the same dimension.\n");
    116   }
    117   FOR_EACH(i, 0, n) {
    118     darray_double_data_get(dst)[i] =
    119       darray_double_cdata_get(a)[i] - darray_double_cdata_get(b)[i];
    120   }
    121 }
    122 
    123 static void
    124 smc_doubleN_mul(void* result, const void* op0, const void* op1)
    125 {
    126   struct darray_double* dst = result;
    127   const struct darray_double* a = op0;
    128   const struct darray_double* b = op1;
    129   size_t i, n;
    130   ASSERT(result && op0 && op1);
    131 
    132   n = darray_double_size_get(dst);
    133   if(n != darray_double_size_get(a) || n != darray_double_size_get(b)) {
    134     FATAL("The vectors must have the same dimension.\n");
    135   }
    136   FOR_EACH(i, 0, n) {
    137     darray_double_data_get(dst)[i] =
    138       darray_double_cdata_get(a)[i] * darray_double_cdata_get(b)[i];
    139   }
    140 }
    141 
    142 static void
    143 smc_doubleN_divi(void* result, const void* op0, const size_t op1)
    144 {
    145   struct darray_double* dst = result;
    146   const struct darray_double* a = op0;
    147   size_t i, n;
    148   ASSERT(result && op0 && op1);
    149 
    150   n = darray_double_size_get(dst);
    151   if(n != darray_double_size_get(a)) {
    152     FATAL("The vectors must have the same dimension.\n");
    153   }
    154   FOR_EACH(i, 0, n) {
    155     darray_double_data_get(dst)[i] = darray_double_cdata_get(a)[i]/(double)op1;
    156   }
    157 }
    158 
    159 static void
    160 smc_doubleN_sqrt(void* result, const void* value)
    161 {
    162   struct darray_double* dst = result;
    163   const struct darray_double* src = value;
    164   size_t i, n;
    165   ASSERT(result && value);
    166 
    167   n = darray_double_size_get(dst);
    168   if(n !=  darray_double_size_get(src)) {
    169     FATAL("The vectors must have the same dimension.\n");
    170   }
    171   FOR_EACH(i, 0, n) {
    172     darray_double_data_get(dst)[i] = sqrt(darray_double_cdata_get(src)[i]);
    173   }
    174 }
    175 
    176 /*******************************************************************************
    177  * Exported helper function
    178  ******************************************************************************/
    179 double*
    180 SMC_DOUBLEN(void* val)
    181 {
    182   ASSERT(val);
    183   return darray_double_data_get(val);
    184 }
    185 
    186 /*******************************************************************************
    187  * Exported type
    188  ******************************************************************************/
    189 const struct smc_type smc_doubleN = {
    190   smc_doubleN_create,
    191   smc_doubleN_destroy,
    192   smc_doubleN_set,
    193   smc_doubleN_zero,
    194   smc_doubleN_add,
    195   smc_doubleN_sub,
    196   smc_doubleN_mul,
    197   smc_doubleN_divi,
    198   smc_doubleN_sqrt
    199 };
    200