Skip to content

Fix BSpline eval_unstructured for multi-dimensional interpolation#52

Merged
ChrisRackauckas merged 2 commits into
SciML:mainfrom
ChrisRackauckas-Claude:interface-check-20260102-040518
Jul 5, 2026
Merged

Fix BSpline eval_unstructured for multi-dimensional interpolation#52
ChrisRackauckas merged 2 commits into
SciML:mainfrom
ChrisRackauckas-Claude:interface-check-20260102-040518

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor

Summary

  • Fixed a bug where eval_unstructured was failing for multi-dimensional BSpline/NURBS interpolation
  • Added regression tests for BSpline and NURBS eval_unstructured
  • Verified interface compatibility with BigFloat, Float32, and standard arrays

Problem

The eval_unstructured function was throwing a BoundsError when used with multi-dimensional BSpline interpolation (e.g., 2D or higher). For example:

t1 = [-3.14, 1.0, 3.0, 7.6, 12.8]
t2 = [-2.71, 1.41, 12.76, 50.2, 120.0]
t1_eval = t1[1:(end - 1)] + diff(t1) / 2
t2_eval = t2[1:(end - 1)] + diff(t2) / 2

u_bspline = fill(2.0, 6, 7)
itp_bspline = NDInterpolation(
    u_bspline,
    (BSplineInterpolationDimension(t1, 2; t_eval = t1_eval, max_derivative_order_eval = 1),
        BSplineInterpolationDimension(t2, 3; t_eval = t2_eval, max_derivative_order_eval = 1))
)

result = eval_unstructured(itp_bspline)  # This was throwing BoundsError

Root Cause

In eval_kernel, when eval_grid=false, @index(Global, NTuple) returns a 1-tuple (e.g., (1,)). This was passed directly to _interpolate! as multi_point_index. However, the BSpline get_basis_function_values method for tuples expects an N_in-tuple and tries to access multi_point_index[dim_in] for all dimensions, causing a bounds error when dim_in > 1.

Fix

Convert the 1-tuple to a scalar using only(k) before passing to _interpolate! when eval_grid=false. This ensures the correct method dispatch:

  • Scalar Number → unstructured evaluation method
  • N_in-tuple → grid evaluation method

Test plan

  • All existing tests pass
  • New tests added for:
    • BSpline 2D eval_unstructured
    • BSpline eval_unstructured with BigFloat
    • NURBS eval_unstructured

Interface Compatibility Check

This PR also checked interface compatibility:

  • ✅ BigFloat works correctly with all interpolation types
  • ✅ Float32 works correctly with type preservation
  • ✅ ArrayInterface compatible (uses similar(), zero(), one() correctly)
  • ⚠️ JLArrays: fails due to missing synchronize for JLBackend in JLArrays (this is a JLArrays issue, not DataInterpolationsND)

cc @ChrisRackauckas

🤖 Generated with Claude Code

claude and others added 2 commits July 5, 2026 12:23
The eval_unstructured function was failing for BSpline interpolation
with more than one dimension because the multi_point_index was being
passed as a 1-tuple (e.g., (i,)) instead of a scalar.

The issue was in eval_kernel: when eval_grid=false, @index(Global, NTuple)
returns a 1-tuple, but the get_basis_function_values method for BSpline
expects either:
- A scalar Number for unstructured evaluation
- An N_in-tuple for grid evaluation

The fix converts the 1-tuple to a scalar using only(k) before passing
to _interpolate! when eval_grid=false.

Also adds regression tests for:
- BSpline 2D eval_unstructured
- BSpline eval_unstructured with BigFloat
- NURBS eval_unstructured

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas-Claude ChrisRackauckas-Claude force-pushed the interface-check-20260102-040518 branch from c830c0c to cad2d62 Compare July 5, 2026 16:26
@ChrisRackauckas ChrisRackauckas merged commit 6974b61 into SciML:main Jul 5, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants