Changes in version 1.0.1 Bug fixes - vsp() now selects presence/absence cells by cell index with uniform sampling (via sample.int()) instead of sample(cell_indices, prob = ...). This fixes the base-R sample() footgun when a pool has a single eligible cell, and removes suitability weighting from the spatial draw (suitability already enters the presence/absence outcome via rbinom()), which also avoids an error when an absence pool's weights are all zero. Changes in version 1.0.0 First public release. Highlights - End-to-end C++ likelihood chain. The optimization hot path (loglik_math, loglik_bio, log_prob_detect, math_to_bio, create_param_vector_masked, like_neg_ltsgr) is now driven entirely by C++ kernels via thin R wrappers. The pure-R reference implementations are preserved as non-exported *_r functions in R/internals.R and used by the test suite to assert numerical parity at tol = 1e-6. - optimize_likelihood() and profile_likelihood() drive ucminfcpp::ucminfcpp_xptr() with a pure-C++ XPtr factory (make_loglik_math_xptr_cpp), so there are no R callbacks in the inner loop. - Parameter masking is fully integrated: any subset of the canonical parameter vector can be fixed during optimization, and the remaining free parameters are optimized end-to-end on the math scale. - Profile-likelihood name propagation fix. profile_likelihood() now preserves free-parameter names across the ucminf boundary, so profile rows are reliably labelled with the parameter being held fixed. API changes - New canonical exported names (with thin C++ wrappers): | exported | non-exported reference | | --- | --- | | loglik_math | xsdm:::loglik_math_r | | loglik_bio | xsdm:::loglik_bio_r | | log_prob_detect | xsdm:::log_prob_detect_r | | math_to_bio | xsdm:::math_to_bio_r | | create_param_vector_masked | xsdm:::create_param_vector_masked_r | | like_neg_ltsgr | xsdm:::like_neg_ltsgr_r | | dist_between_params | xsdm:::dist_between_params_r | - like_neg_ltsgr_cpp is no longer exported; it remains as an unexported back-compat alias (xsdm:::like_neg_ltsgr_cpp) that forwards to like_neg_ltsgr. New code should call like_neg_ltsgr directly. - dist_between_params() is now backed by a pure-C++ implementation in src/dist_between_params.cpp that builds the pairing cost matrix and solves the linear sum assignment problem via a clean-room Hungarian / Kuhn--Munkres routine (O(n^3) potentials variant from Kuhn 1955, Munkres 1957, Jonker & Volgenant 1987). No code is taken from the clue package, avoiding the GPL-2 / AGPL-3 licence mismatch. The pure-R reference xsdm:::dist_between_params_r continues to call clue::solve_LSAP() and is used by the parity tests in tests/testthat/test-dist_between_params_r_vs_cpp.R. The legacy brute-force reference distance_between_params() is also preserved (non-exported) as xsdm:::distance_between_params_r. Validation & robustness - optimize_likelihood(), start_parms(), and get_start_parms_() now reject num_starts < 3 early with an informative checkmate error, rather than crashing inside sobol::sobol_design() (which segfaults at nseq = 0 and returns a malformed vector at nseq = 1). - start_parms() runtime: sobol::sobol_design output is defensively coerced to a data.frame, protecting against future behaviour changes. - dist_between_params() (and the xsdm:::dist_between_params_r reference) now accept a +/-Inf value in a sig* or pd coordinate of a free math-scale parameter vector, matching the rule already applied to the mask argument. This is the boundary-model case where a shape parameter saturates (e.g. sigrtil -> Inf): the distance is still well defined because sig* are compared on the inverse scale (1 / Inf = 0). Previously such a vector was rejected with "Must be finite", which forced callers to catch the error and record a missing (NA) distance. NA anywhere, and Inf in any non-sig*/non-pd coordinate, are still rejected. Build & packaging - terra and tibble moved from Suggests: to Imports:. Both are used unconditionally in mainline package code (env_data_array(), habitat_suitability(), start_parms(), vsp()). - src/*.hpp headers renamed to src/*.h to satisfy R CMD check's "Subdirectory 'src' contains" warning. - New R-CMD-check.yaml GitHub workflow runs R CMD check --as-cran on Ubuntu (release / devel / oldrel-1 / oldrel-2), Windows, and macOS. - Test suite: 1006 tests, full suite ~9s, all green; parity tests live under tests/testthat/test-*_r_vs_cpp.R. Internals - All non-exported helpers (check_env_array, logit, permutations, auto_plot_lims_, etc.) consolidated in R/internals.R. - profile_likelihood() cleanly stops when the requested parameter is outside the masked design.