star-wf

First-passage time of brownian motion
git clone git://git.meso-star.fr/star-wf.git
Log | Files | Refs | README | LICENSE

commit ee5831cc6b1e53556cb2185446f53280c62b44c1
parent 19b8a3bb68406884c8f62bce036adf0b1d7d8bcd
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  6 Mar 2024 14:40:18 +0100

Implement swf_H3d_tabulate function

Implement tabulation reference counting functions; reference release is
required for error handling in the event of tabulation failure.

Diffstat:
MMakefile | 2+-
Msrc/swf.h | 8+++++++-
Msrc/swf_H.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/swf_tabulation.c | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/swf_tabulation.h | 45+++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 208 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile @@ -25,7 +25,7 @@ LIBNAME = $(LIBNAME_$(LIB_TYPE)) ################################################################################ # Library building ################################################################################ -SRC = src/swf_H.c +SRC = src/swf_H.c src/swf_tabulation.c OBJ = $(SRC:.c=.o) DEP = $(SRC:.c=.d) diff --git a/src/swf.h b/src/swf.h @@ -25,13 +25,19 @@ #define SWF_API extern #endif +#ifndef NDEBUG + #define SWF(Func) ASSERT(swf_ ## Func == RES_OK) +#else + #define SWF(Func) swf_ ## Func +#endif + /* Forward declarations of external data types */ struct mem_allocator; struct swf_H_tabulate_args { double x_min; double x_max; - double x_delta; + double delta_x; struct mem_allocator* allocator; /* NULL <=> use default allocator */ }; #define SWF_H_TABULATE_ARGS_DEFAULT__ {1e-5, 3.88, 4e-5, NULL} diff --git a/src/swf_H.c b/src/swf_H.c @@ -14,6 +14,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "swf.h" +#include "swf_tabulation.h" #include <rsys/math.h> /* PI */ @@ -21,6 +22,33 @@ #include <math.h> /******************************************************************************* + * Helper functions + ******************************************************************************/ +static INLINE res_T +check_swf_H_tabulate_args(const struct swf_H_tabulate_args* args) +{ + if(!args) return RES_BAD_ARG; + + /* X cannot be negative */ + if(args->x_min < 0) + return RES_BAD_ARG; + + /* X range cannot be degenerated */ + if(args->x_min >= args->x_max) + return RES_BAD_ARG; + + /* Delta X cannot be null */ + if(args->delta_x <= 0) + return RES_BAD_ARG; + + /* Delta X cannot be greater than the X range */ + if(args->delta_x > args->x_max - args->x_min) + return RES_BAD_ARG; + + return RES_OK; +} + +/******************************************************************************* * Exported symbols ******************************************************************************/ /* H(x) = 1 + 2 Sum(k=1..INF)((-1)^k * exp(-(PI*k)^2 * x)) */ @@ -47,3 +75,51 @@ swf_H3d_eval(const double x) return 1.0 + 2.0 * sum; } + +res_T +swf_H3d_tabulate + (const struct swf_H_tabulate_args* args, + struct swf_tabulation** out_tab) +{ + struct swf_tabulation* tab = NULL; + struct item* items = NULL; + size_t nitems = 0; + size_t i = 0; + double x_range = 0; + double norm = 0; + res_T res = RES_OK; + + if(!out_tab) { res = RES_BAD_ARG; goto error; } + + if((res = check_swf_H_tabulate_args(args)) != RES_OK) goto error; + if((res = tabulation_create(args->allocator, &tab)) != RES_OK) goto error; + + /* Calculate the number of x arguments to be tabulated */ + x_range = args->x_max - args->x_min; + nitems = (size_t)((x_range + args->delta_x/*round up*/) / args->delta_x); + + /* Tabulation memory space allocation */ + if((res = darray_item_resize(&tab->items, nitems)) != RES_OK) goto error; + items = darray_item_data_get(&tab->items); + + /* Setup the tabulation */ + FOR_EACH(i, 0, nitems) { + items[i].x = MMIN(args->x_min + (double)i*args->delta_x, args->x_max); + items[i].f_x = swf_H3d_eval(items[i].x); + } + ASSERT(items[i].x == args->x_max); + + /* Normalize the tabulation */ + norm = items[nitems - 1].f_x; + FOR_EACH(i, 0, nitems) items[i].f_x /= norm; + +exit: + if(out_tab) *out_tab = tab; + return res; +error: + if(tab) { + SWF(tabulation_ref_put(tab)); + tab = NULL; + } + goto exit; +} diff --git a/src/swf_tabulation.c b/src/swf_tabulation.c @@ -0,0 +1,79 @@ +/* Copyright (C) 2024 |Méso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "swf.h" +#include "swf_tabulation.h" + +#include <rsys/mem_allocator.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static void +release_tabulation(ref_T* ref) +{ + struct swf_tabulation* tab = CONTAINER_OF(ref, struct swf_tabulation, ref); + ASSERT(ref); + darray_item_release(&tab->items); + MEM_RM(tab->allocator, tab); +} + +/******************************************************************************* + * Exported symbols + ******************************************************************************/ +res_T +swf_tabulation_ref_get(struct swf_tabulation* tab) +{ + if(!tab) return RES_BAD_ARG; + ref_get(&tab->ref); + return RES_OK; +} + +res_T +swf_tabulation_ref_put(struct swf_tabulation* tab) +{ + if(!tab) return RES_BAD_ARG; + ref_put(&tab->ref, release_tabulation); + return RES_OK; +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +tabulation_create + (struct mem_allocator* mem_allocator, + struct swf_tabulation** out_tab) +{ + struct swf_tabulation* tab = NULL; + struct mem_allocator* allocator = NULL; + res_T res = RES_OK; + ASSERT(out_tab); + + allocator = mem_allocator ? mem_allocator : &mem_default_allocator; + tab = MEM_CALLOC(allocator, 1, sizeof(*tab)); + if(!tab) { res = RES_MEM_ERR; goto error; } + darray_item_init(allocator, &tab->items); + +exit: + *out_tab = tab; + return res; +error: + if(tab) { + SWF(tabulation_ref_put(tab)); + tab = NULL; + } + goto exit; +} diff --git a/src/swf_tabulation.h b/src/swf_tabulation.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2024 |Méso|Star> (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef SWF_TABULATION_H +#define SWF_TABULATION_H + +#include <rsys/dynamic_array.h> +#include <rsys/ref_count.h> + +struct item { + double x; /* Function argument */ + double f_x; /* Value of the function */ +}; +#define ITEM_NULL__ {0, 0} +static const struct item ITEM_NULL = ITEM_NULL__; + +/* Declare the dynamic array of items */ +#define DARRAY_NAME item +#define DARRAY_DATA struct item +#include <rsys/dynamic_array.h> + +struct swf_tabulation { + struct darray_item items; + struct mem_allocator* allocator; + ref_T ref; +}; + +extern LOCAL_SYM res_T +tabulation_create + (struct mem_allocator* allocator, + struct swf_tabulation** out_tab); + +#endif /* SWF_TABULATION_H */