31 size_t * tgt_points,
size_t count,
33 int * interpolation_complete);
72 "internal error (default search distance type is assumed to be cell area)");
77 .search_distance.scale =
96 for (
size_t i = 0; i < count; ++i) {
97 memcpy(bnd_circles[i].base_vector, tgt_coords[i], 3 *
sizeof(
double));
98 bnd_circles[i].
inc_angle = search_distance_angle;
99 bnd_circles[i].
sq_crd = DBL_MAX;
119 for (
size_t i = 0; i < count; ++i) {
123 tgt_basic_grid_data, tgt_points[i], &grid_cell);
130 double sin_arg = sqrt(cell_area / (4.0 * M_PI));
132 if (sin_arg > 1.0) sin_arg = 1.0;
133 double theta = 2.0 * asin(sin_arg);
136 double search_distance = theta * search_distance_scale;
137 if (search_distance > M_PI) search_distance = M_PI;
140 memcpy(bnd_circles[i].base_vector, tgt_coords[i], 3 *
sizeof(
double));
143 bnd_circles[i].
sq_crd = DBL_MAX;
154 size_t * tgt_points,
size_t count,
156 int * interpolation_complete) {
158 if (*interpolation_complete)
return 0;
170 "search_distance_type == cell_area requires target_field_location == CELL")
175 interp_grid, tgt_points, count, tgt_coords);
179 xmalloc(count *
sizeof(*bnd_circles));
183 method_dnn, interp_grid, tgt_points, tgt_coords, bnd_circles, count);
186 size_t * src_points = NULL;
187 size_t * num_src_per_tgt =
xmalloc(count *
sizeof(*num_src_per_tgt));
188 int const src_field_idx = 0;
190 interp_grid, bnd_circles, count, src_field_idx, &src_points,
200 size_t result_count = 0;
201 size_t * reorder_idx =
xmalloc(count *
sizeof(*reorder_idx));
202 int * fail_flag =
xmalloc(count *
sizeof(*fail_flag));
203 size_t max_src_per_tgt = 0;
204 size_t * src_offsets =
xmalloc(count *
sizeof(*src_offsets));
205 size_t src_offset = 0;
206 size_t total_weights = 0;
207 size_t n_min = method_dnn->
n_min;
208 for (
size_t i = 0; i < count; ++i) {
209 src_offsets[i] = src_offset;
210 size_t curr_num_src_per_tgt = num_src_per_tgt[i];
211 src_offset += curr_num_src_per_tgt;
212 if (curr_num_src_per_tgt < n_min) {
217 if (curr_num_src_per_tgt > max_src_per_tgt) {
218 max_src_per_tgt = curr_num_src_per_tgt;
220 total_weights += curr_num_src_per_tgt;
228 fail_flag, count, reorder_idx, tgt_points);
234 double scale = method_dnn->
scale;
236 double * w =
xmalloc(total_weights *
sizeof(*w));
237 size_t * num_weights_per_tgt =
238 xmalloc(result_count *
sizeof(*num_weights_per_tgt));
239 size_t * reordered_src_points =
240 xmalloc(total_weights *
sizeof(*reordered_src_points));
244 xmalloc(max_src_per_tgt *
sizeof(*src_coord_buffer));
250 for (
size_t i = 0, weight_offset = 0; i < result_count; ++i) {
251 size_t curr_reorder_idx = reorder_idx[i];
252 size_t curr_num_src_per_tgt = num_src_per_tgt[curr_reorder_idx];
253 size_t curr_src_offset = src_offsets[curr_reorder_idx];
256 for (
size_t j = 0; j < curr_num_src_per_tgt; ++j) {
259 src_field_coordinates[src_points[curr_src_offset + j]],
263 reordered_src_points + weight_offset, src_points + curr_src_offset,
264 curr_num_src_per_tgt *
sizeof(*reordered_src_points));
265 num_weights_per_tgt[i] = curr_num_src_per_tgt;
268 compute_weights_func(
269 tgt_coords[curr_reorder_idx],
271 w + weight_offset, scale);
273 weight_offset += curr_num_src_per_tgt;
277 free(src_coord_buffer);
279 free(num_src_per_tgt);
285 interp_grid, src_field_idx, reordered_src_points, total_weights);
290 interp_grid, tgt_points, result_count),
291 .count = result_count};
295 weights, &tgts, num_weights_per_tgt, srcs, w);
298 free(reordered_src_points);
302 free(num_weights_per_tgt);
315 config.search_distance != NULL,
"search_distance config is NULL")
319 "unsupported value for n_min (%d), has to be >= 1",
config.n_min)
325 switch (
config.search_distance->type) {
330 (
config.search_distance->search_distance.fixed > 0.0) &&
331 (
config.search_distance->search_distance.fixed <= M_PI),
332 "unsupported value for search_distance (%lf), has to be in (0.0,PI]",
333 config.search_distance->search_distance.fixed)
335 config.search_distance->search_distance.fixed;
341 config.search_distance->search_distance.scale > 0.0,
342 "search_distance_scale must be positive (%lf)",
343 config.search_distance->search_distance.scale)
345 config.search_distance->search_distance.scale;
364 "gauss_scale must be positive (%lf)",
config.gauss_scale)
372 "rbf_scale must be positive (%lf)",
config.rbf_scale)
418 copy->
config = config_dnn->config;
425 void const *a_,
void const *b_) {
449 switch (a->config.search_distance->type) {
451 "invalid distance-nearest-neighbour search distance type");
460 switch (a->config.type) {
462 "invalid distance-nearest-neighbour search distance type");
501 if (search_distance == NULL) {
506 FIXED_HAS_DEFAULT = 1,
507 FIXED_IS_DEFINED = 1,
508 CELL_AREA_HAS_DEFAULT = 1,
509 CELL_AREA_IS_DEFINED = 1,
514 YAC_ASSERT(search_distance != NULL,
"search_distance is NULL")
518 switch (search_distance->
type) {
526 0.0, M_PI - 0.000001,
527 FIXED_HAS_DEFAULT, FIXED_IS_DEFINED);
536 SCALE_ALLOW_NAN, SCALE_ALLOW_INF,
537 CELL_AREA_HAS_DEFAULT, CELL_AREA_IS_DEFINED);
545 char const *
name,
void ** obj,
546 struct yac_param ** param,
int * is_default) {
559 *search_distance_ptr == NULL,
"search_distance pointer is not NULL");
562 search_distance_type_table,
570 search_distance_type_table, search_distance_type_table_size,
name);
618 WEIGHTED_HAS_DEFAULT = 1,
619 WEIGHTED_IS_DEFINED = 1,
620 N_MIN_HAS_DEFAULT = 1,
621 N_MIN_IS_DEFINED = 1,
622 GAUSS_SCALE_HAS_DEFAULT = 1,
623 GAUSS_SCALE_IS_DEFINED = 1,
624 RBF_SCALE_HAS_DEFAULT = 1,
625 RBF_SCALE_IS_DEFINED = 1,
631 dnn_weighted_enum_table,
642 dnn_weighted_enum_table, dnn_weighted_enum_table_size,
643 WEIGHTED_HAS_DEFAULT, WEIGHTED_IS_DEFINED);
645 int const n_min_min = 1;
646 int const n_min_max = INT_MAX;
653 n_min_min, n_min_max,
654 N_MIN_HAS_DEFAULT, N_MIN_IS_DEFINED);
656 double const gauss_scale_min = -DBL_MAX;
657 double const gauss_scale_max = DBL_MAX;
664 gauss_scale_min, gauss_scale_max,
665 SCALE_ALLOW_NAN, SCALE_ALLOW_INF,
666 GAUSS_SCALE_HAS_DEFAULT, GAUSS_SCALE_IS_DEFINED);
668 double const rbf_scale_min = -DBL_MAX;
669 double const rbf_scale_max = DBL_MAX;
676 rbf_scale_min, rbf_scale_max,
677 SCALE_ALLOW_NAN, SCALE_ALLOW_INF,
678 RBF_SCALE_HAS_DEFAULT, RBF_SCALE_IS_DEFINED);
680 struct yac_param * search_distance_subparam =
684 struct yac_param *search_distance_param =
689 search_distance_subparam,
699 search_distance_param,
702 "dnn", root_param_array,
703 sizeof(root_param_array) /
sizeof(root_param_array[0]));
721 .search_distance = NULL,
#define YAC_ASSERT(exp, msg)
double yac_grid_cell_area(struct yac_grid_cell cell)
Area calculation of a spherical cell.
Structs and interfaces for area calculations.
void yac_const_basic_grid_data_get_grid_cell(struct yac_const_basic_grid_data *grid_data, size_t cell_idx, struct yac_grid_cell *buffer_cell)
static struct sin_cos_angle sin_cos_angle_new(double sin, double cos)
void yac_init_grid_cell(struct yac_grid_cell *cell)
void yac_free_grid_cell(struct yac_grid_cell *cell)
int yac_name_type_pair_get_type(struct yac_name_type_pair const *pairs, size_t count, char const *name)
#define DEF_NAME_TYPE_PAIR(NAME, TYPE)
#define DEF_NAME_TYPE_PAIRS(NAME,...)
#define YAC_INSTRUMENT_START(ID)
Enter an instrumented region.
#define YAC_INSTRUMENT_STOP(ID)
Exit an instrumented region entered with YAC_INSTRUMENT_START(ID).
enum yac_location yac_interp_grid_get_tgt_field_location(struct yac_interp_grid *interp_grid)
void yac_interp_grid_do_dnn_search_src(struct yac_interp_grid *interp_grid, const_bounding_circle_pointer bnd_circles, size_t count, size_t src_field_idx, size_t **src_points, size_t *num_src_per_bnd_circle)
struct remote_point * yac_interp_grid_get_tgt_remote_points(struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count)
struct remote_point * yac_interp_grid_get_src_remote_points(struct yac_interp_grid *interp_grid, size_t src_field_idx, size_t *src_points, size_t count)
yac_const_coordinate_pointer yac_interp_grid_get_src_field_coords(struct yac_interp_grid *interp_grid, size_t src_field_idx)
void yac_interp_grid_get_tgt_coordinates(struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count, yac_coordinate_pointer tgt_coordinates)
struct yac_const_basic_grid_data * yac_interp_grid_get_basic_grid_data_tgt(struct yac_interp_grid *interp_grid)
@ YAC_DISTANCE_NEAREST_NEIGHBOR
Distance-nearest-neighbor interpolation.
#define DEF_INTERP_METHOD_CONFIG_COMPARE_TYPE(TYPE)
#define DEF_INTERP_METHOD_CONFIG_TYPE(TYPE)
#define CHECK_ANGLE(FIELD)
struct interp_method * yac_interp_method_dnn_new(struct yac_interp_method_dnn_config config)
static struct yac_param * config_dnn_get_param(struct yac_interp_method_config const *config)
static void config_dnn_delete(struct yac_interp_method_config *config)
static void delete_dnn(struct interp_method *method)
static struct yac_param * yac_interp_method_dnn_config_search_distance_build_param(struct yac_interp_method_dnn_config_search_distance *search_distance)
static int config_dnn_search_distance_factory(char const *name, void **obj, struct yac_param **param, int *is_default)
static int config_dnn_compare(void const *a_, void const *b_)
struct yac_interp_method_config * yac_interp_method_config_default_dnn_new(void)
Creates a distance-nearest-neighbour (DNN) interpolation method configuration with default parameters...
static struct yac_interp_method_dnn_config_search_distance get_default_search_distance(void)
static struct interp_method_vtable interp_method_dnn_vtable
static struct yac_interp_method_dnn_config_search_distance * copy_search_distance_config(struct yac_interp_method_dnn_config_search_distance const *search_distance)
static struct yac_interp_method_config_vtable yac_interp_method_config_vtable_dnn
static void set_dnn_bounding_circles(struct interp_method_dnn *method_dnn, struct yac_interp_grid *interp_grid, size_t *tgt_points, yac_coordinate_pointer tgt_coords, struct bounding_circle *bnd_circles, size_t count)
static size_t do_search_dnn(struct interp_method *method, struct yac_interp_grid *interp_grid, size_t *tgt_points, size_t count, struct yac_interp_weights *weights, int *interpolation_complete)
static struct yac_interp_method_config * config_dnn_copy(const struct yac_interp_method_config *config)
static struct interp_method * config_dnn_generate(struct yac_interp_method_config const *config)
static enum yac_interpolation_list config_dnn_get_type()
@ YAC_INTERP_DNN_WEIGHT_AVG
average of source points within search distance
@ YAC_INTERP_DNN_WEIGHT_DIST
distance weighted average of source points
@ YAC_INTERP_DNN_WEIGHT_GAUSS
Gauss weighted average of source points.
@ YAC_INTERP_DNN_WEIGHT_RBF
radial basis function weighted average
#define YAC_INTERP_DNN_SEARCH_DISTANCE_FIXED_DEFAULT
#define YAC_INTERP_DNN_RBF_SCALE_DEFAULT
#define YAC_INTERP_DNN_SEARCH_DISTANCE_TYPE_DEFAULT
#define YAC_INTERP_DNN_GAUSS_SCALE_DEFAULT
#define YAC_INTERP_DNN_DUMMY_SCALE
#define YAC_INTERP_DNN_N_MIN_DEFAULT
#define YAC_INTERP_DNN_WEIGHT_DEFAULT
#define YAC_INTERP_DNN_SEARCH_DISTANCE_CELL_AREA_DEFAULT
yac_interp_dnn_search_distance_type
@ YAC_INTERP_DNN_SEARCH_DISTANCE_FIXED
use a fixed search distance (in radians)
@ YAC_INTERP_DNN_SEARCH_DISTANCE_CELL_AREA
void yac_interp_compute_weights_gauss(double tgt_coord[3], yac_const_coordinate_pointer src_coords, size_t const n, double *weights, double const gauss_scale)
void yac_interp_compute_weights_avg(double tgt_coord[3], yac_const_coordinate_pointer src_coords, size_t const n, double *weights, double const dummy)
void yac_interp_compute_weights_dist(double tgt_coord[3], yac_const_coordinate_pointer src_coords, size_t const n, double *weights, double const dummy)
void yac_interp_compute_weights_rbf(double tgt_coord[3], yac_const_coordinate_pointer src_coords, size_t const n, double *weights, double const rbf_scale)
#define CHECK_SRC_FIELD_COUNT_SINGLE(INTERP_GRID)
void(* yac_interp_compute_weights_func)(double tgt_coord[3], yac_const_coordinate_pointer src_coords, size_t const n, double *weights, double const scale)
void yac_interp_weights_add_wsum(struct yac_interp_weights *weights, struct remote_points *tgts, size_t *num_src_per_tgt, struct remote_point *srcs, double *w)
#define YAC_INTERP_GRID_FIELD_ASSERT(INTERP_GRID, EXP, MSG)
struct yac_param * yac_param_dble_new(const char *name, double *value_ptr, double default_value, double value_min, double value_max, int allow_nan, int allow_inf, int has_default, int is_defined)
Create a double parameter.
struct yac_param * yac_param_distance_new(const char *name, double *value_ptr, double default_value, double value_min, double value_max, int has_default, int is_defined)
Create a distance parameter (stored in radians)
struct yac_param * yac_param_enum_new(const char *name, int *value_ptr, int default_value, struct yac_name_type_pair const *enum_table, size_t enum_table_size, int has_default, int is_defined)
Create a new enum parameter for configuration.
struct yac_param * yac_param_int_new(const char *name, int *value_ptr, int default_value, int value_min, int value_max, int has_default, int is_defined)
Create an int parameter.
#define YAC_PARAM_ASSERT(COND,...)
struct yac_param * yac_param_oneof_new(const char *name, yac_param_oneof_factory_ptr default_factory, void **value_ptr, struct yac_param *subparam, int subparam_is_default)
Create a new one-of struct parameter with a given name and a default_factory.
struct yac_param * yac_param_struct_new(const char *name, struct yac_param **subparams, size_t subparam_count)
Create a new struct parameter with a given name and subparameters.
struct sin_cos_angle inc_angle
angle between the middle point and the boundary of the spherical cap
yac_interp_compute_weights_func compute_weights
union interp_method_dnn::@27 search_distance
struct interp_method_vtable * vtable
enum yac_interp_dnn_search_distance_type search_distance_type
size_t(* do_search)(struct interp_method *method, struct yac_interp_grid *grid, size_t *tgt_points, size_t count, struct yac_interp_weights *weights, int *interpolation_complete)
information (global id and location) about a point that
structure containing the information (global id and location)
struct remote_point * data
Concrete implementation of yac_interp_method_config for the DNN method.
struct yac_interp_method_config base
base config object, must be first entry
struct yac_interp_method_dnn_config config
method-specific configuration
void(* delete)(struct yac_interp_method_config *config)
struct yac_param * root_param_cache
struct yac_interp_method_config_vtable const * vtable
union yac_interp_method_dnn_config_search_distance::@28 search_distance
enum yac_interp_dnn_search_distance_type type
method for determining the search distance
enum yac_interp_dnn_weight_type type
weighting type
struct yac_interp_method_dnn_config_search_distance * search_distance
double gauss_scale
scale factor for Gauss weighting
double rbf_scale
scale factor for RBF weighting
static struct yac_interp_method_config * config
void yac_quicksort_index_int_size_t_size_t(int *a, size_t n, size_t *b, size_t *c)
#define YAC_ASSERT_F(exp, format,...)
#define YAC_UNREACHABLE_DEFAULT(msg)
double const (* yac_const_coordinate_pointer)[3]
double(* yac_coordinate_pointer)[3]