commit b8e1c8fcca2db7d211ff03acf46d5959d016c2c3
parent 8e156b814352b65e4fe5d99814dac05dcaa7a736
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 4 Nov 2020 10:44:17 +0100
Add the atrck_band_sample_quad_pt function
Diffstat:
3 files changed, 61 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -60,6 +60,10 @@ rcmake_prepend_path(ATRCK_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
add_library(atrck SHARED ${ATRCK_FILES_SRC} ${ATRCK_FILES_INC} ${ATRCK_FILES_INC_API})
target_link_libraries(atrck RSys)
+if(CMAKE_COMPILER_IS_GNUCC)
+ target_link_libraries(atrck m)
+endif()
+
set_target_properties(atrck PROPERTIES
DEFINE_SYMBOL ATRCK_SHARED_BUILD
VERSION ${VERSION}
diff --git a/src/atrck.c b/src/atrck.c
@@ -21,6 +21,8 @@
#include "atrck_c.h"
#include "atrck_log.h"
+#include <rsys/algorithm.h>
+
#include <unistd.h> /* sysconf support */
#include <errno.h>
@@ -39,6 +41,14 @@ reset_atrck(struct atrck* atrck)
darray_band_purge(&atrck->bands);
}
+static INLINE int
+cmp_dbl(const void* a, const void* b)
+{
+ const double d0 = *((const double*)a);
+ const double d1 = *((const double*)b);
+ return d0 < d1 ? -1 : (d0 > d1 ? 1 : 0);
+}
+
static res_T
read_quad_pt
(struct atrck* atrck,
@@ -480,6 +490,47 @@ error:
goto exit;
}
+res_T
+atrck_band_sample_quad_pt
+ (const struct atrck_band* atrck_band,
+ const double r, /* Canonical random number in [0, 1[ */
+ struct atrck_quad_pt* quad_pt)
+{
+ const struct band* band = NULL;
+ const double* cumul = NULL;
+ const double* find = NULL;
+ double r_next = nextafter(r, DBL_MAX);
+ size_t i;
+
+ if(!atrck_band || !quad_pt) return RES_BAD_ARG;
+
+ if(r < 0 || r >= 1) {
+ log_err(atrck_band->atrck__,
+ "%s: invalid canonical random number `%g'.\n", FUNC_NAME, r);
+ return RES_BAD_ARG;
+ }
+
+ band = atrck_band->band__;
+ cumul = darray_double_cdata_get(&band->quad_pts_cumul);
+
+ /* Use r_next rather than r in order to find the first entry that is not less
+ * than *or equal* to r */
+ find = search_lower_bound(&r_next, cumul, atrck_band->quad_pts_count,
+ sizeof(double), cmp_dbl);
+ ASSERT(find);
+
+ /* Compute the index of the found quadrature point */
+ i = (size_t)(find - cumul);
+ ASSERT(i < atrck_band->quad_pts_count);
+ ASSERT(cumul[i] > r);
+ ASSERT(!i || cumul[i-1] <= r);
+
+ /* Fetch the sampled quadrature point */
+ atrck_band_get_quad_pt(atrck_band, i, quad_pt);
+
+ return RES_OK;
+}
+
/*******************************************************************************
* Local functions
******************************************************************************/
diff --git a/src/atrck.h b/src/atrck.h
@@ -113,6 +113,12 @@ atrck_band_get_quad_pt
const size_t iquad_pt,
struct atrck_quad_pt* quad_pt);
+ATRCK_API res_T
+atrck_band_sample_quad_pt
+ (const struct atrck_band* band,
+ const double r, /* Canonical random number in [0, 1[ */
+ struct atrck_quad_pt* quad_pt);
+
END_DECLS
#endif /* ATRCK_H */