Skip to content

Commit 3133672

Browse files
committed
Fix C++ implementation loading and function availability
- Add useDynLib directive to NAMESPACE for proper C++ library linking - Export C++ functions (process_district_all_vars, simple_smoothing_single_var, gaussian_smoothing_single_var) - Improve .onLoad function with better error handling and C++ availability checking - Fix critical bug in C++ weighted calculation (weighted_sum_all division) - Update smooth_variables function to properly check for C++ availability - Add informative messages about which implementation is being used - Ensure robust fallback to R implementation when C++ fails The package now successfully loads C++ functions and automatically uses them for spatial smoothing, with automatic fallback to R implementation for maximum reliability.
1 parent e32e659 commit 3133672

4 files changed

Lines changed: 54 additions & 14 deletions

File tree

NAMESPACE

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Generated by roxygen2: do not edit by hand
22

3+
useDynLib(hexsmoothR, .registration = TRUE)
4+
35
export(compute_topology)
46
export(create_grid)
57
export(extract_raster_data)
@@ -10,6 +12,9 @@ export(hex_edge_to_flat)
1012
export(hex_flat_to_circumradius)
1113
export(hex_flat_to_edge)
1214
export(smooth_variables)
15+
export(process_district_all_vars)
16+
export(simple_smoothing_single_var)
17+
export(gaussian_smoothing_single_var)
1318
importFrom(exactextractr,exact_extract)
1419
importFrom(sf,st_bbox)
1520
importFrom(sf,st_centroid)

R/cpp_wrapper.R

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,27 @@ smooth_variables <- function(variable_values, first_neighbors, second_neighbors,
119119
hex_indices <- 1:length(first_neighbors)
120120
}
121121

122-
# Try to use C++ implementation if available
123-
tryCatch({
124-
return(process_district_all_vars(variable_values, first_neighbors, second_neighbors, weights, hex_indices, var_names))
125-
}, error = function(e) {
126-
# Use R fallback if C++ fails
122+
# Check if C++ implementation is available
123+
cpp_available <- getOption("hexsmoothR.cpp_available", FALSE)
124+
125+
if (cpp_available && exists("process_district_all_vars", mode = "function")) {
126+
# Use C++ implementation
127+
if (getOption("hexsmoothR.verbose", TRUE)) {
128+
message("hexsmoothR: Using C++ implementation for spatial smoothing")
129+
}
130+
tryCatch({
131+
return(process_district_all_vars(variable_values, first_neighbors, second_neighbors, weights, hex_indices, var_names))
132+
}, error = function(e) {
133+
if (getOption("hexsmoothR.verbose", TRUE)) {
134+
warning("hexsmoothR: C++ implementation failed, falling back to R: ", e$message)
135+
}
136+
return(smooth_variables_r_fallback(variable_values, first_neighbors, second_neighbors, weights, hex_indices, var_names))
137+
})
138+
} else {
139+
# Use R fallback
140+
if (getOption("hexsmoothR.verbose", TRUE)) {
141+
message("hexsmoothR: Using R fallback implementation for spatial smoothing")
142+
}
127143
return(smooth_variables_r_fallback(variable_values, first_neighbors, second_neighbors, weights, hex_indices, var_names))
128-
})
144+
}
129145
}

R/zzz.R

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,27 @@
88
missing_packages <- required_packages[!sapply(required_packages, requireNamespace, quietly = TRUE)]
99
if (length(missing_packages) > 0) warning("hexsmoothR: Missing required packages: ", paste(missing_packages, collapse = ", "))
1010

11-
# Load the C++ library
12-
library.dynam("hexsmoothR", pkgname, libname)
11+
# Load the C++ library with better error handling
12+
tryCatch({
13+
library.dynam("hexsmoothR", pkgname, libname)
14+
# Check if C++ functions are available
15+
if (exists("process_district_all_vars", mode = "function")) {
16+
options(hexsmoothR.cpp_available = TRUE)
17+
if (getOption("hexsmoothR.verbose", TRUE)) {
18+
message("hexsmoothR: C++ implementation loaded successfully")
19+
}
20+
} else {
21+
options(hexsmoothR.cpp_available = FALSE)
22+
if (getOption("hexsmoothR.verbose", TRUE)) {
23+
message("hexsmoothR: C++ implementation not available, using R fallback")
24+
}
25+
}
26+
}, error = function(e) {
27+
options(hexsmoothR.cpp_available = FALSE)
28+
if (getOption("hexsmoothR.verbose", TRUE)) {
29+
warning("hexsmoothR: Failed to load C++ library: ", e$message, "\nUsing R fallback implementation")
30+
}
31+
})
1332
}
1433

1534
#' Package startup message (internal)

src/hex_smoothing.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ List process_district_all_vars(
197197
double weighted_sum_first = 0.0;
198198
double weight_sum_first = 0.0;
199199
double weighted_sum_all = 0.0;
200-
double weight_sum_all = 0.0;
200+
double total_weight_sum = 0.0;
201201

202202
// Add self value
203203
if (valid[hex_idx]) {
@@ -207,7 +207,7 @@ List process_district_all_vars(
207207
weighted_sum_first += val * center_weight;
208208
weight_sum_first += center_weight;
209209
weighted_sum_all += val * center_weight;
210-
weight_sum_all += center_weight;
210+
total_weight_sum += center_weight;
211211
}
212212

213213
// Add first-order neighbors (single pass for all calculations)
@@ -219,7 +219,7 @@ List process_district_all_vars(
219219
weighted_sum_first += val * first_order_weight;
220220
weight_sum_first += first_order_weight;
221221
weighted_sum_all += val * first_order_weight;
222-
weight_sum_all += first_order_weight;
222+
total_weight_sum += first_order_weight;
223223
}
224224
}
225225

@@ -235,7 +235,7 @@ List process_district_all_vars(
235235
combined_sum += val;
236236
combined_count++;
237237
weighted_sum_all += val * second_order_weight;
238-
weight_sum_all += second_order_weight;
238+
total_weight_sum += second_order_weight;
239239
}
240240
}
241241

@@ -244,8 +244,8 @@ List process_district_all_vars(
244244
combined_means[v][i] = combined_sum / combined_count;
245245
}
246246

247-
if (weight_sum_all > 0) {
248-
weighted_combined[v][i] = weighted_sum_all / weight_sum_all;
247+
if (total_weight_sum > 0) {
248+
weighted_combined[v][i] = weighted_sum_all / total_weight_sum;
249249
}
250250
}
251251
}

0 commit comments

Comments
 (0)