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:
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 */