NatLabRockies / NatLabRockies/ninterp

Split element type `T` into grid (`Tg`) and value (`Tv`) type parameters

Open
#57 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
17
Forks
13
Avg merge
44m
Merged PRs (30d)
2

Description

Motivation

Every generic type in ninterp today (Interp1D<T, S>, InterpData<T, N>,
Strategy1D<D>'s D::Elem, ...) uses one type parameter for both grid coordinates and
interpolated values, and that parameter is bounded Float nearly everywhere (see
src/strategy/cubic.rs, src/strategy/utils.rs, src/interpolator/mod.rs,
src/interpolator/enums.rs). That forces grid axes to be the same float type as the
function values, even when they conceptually aren't, e.g. an integer or otherwise
non-float grid axis paired with float-valued data.

Splitting into Tg (grid) and Tv (value) removes that coupling. This is a breaking
change; per this project's pre-1.0 convention it lands as a future 0.x -> 0.(x+1) bump,
not gated to any 1.0.

API changes

Every site that currently carries one T (or bounds D::Elem) needs to declare which
side of the split it's on:

  • InterpDataBase<D, N> (src/interpolator/data.rs): splits into two storage
    parameters, grid: [ArrayBase<Dg, Ix1>; N] and values: ArrayBase<Dv, Dim<[Ix; N]>>.
  • Interp1D/2D/3D/ND<D, S> and their *Base/*View/owned type aliases: follow
    InterpDataBase onto Dg/Dv.
  • Strategy1D/2D/3D/ND<D> (src/strategy/traits.rs): interpolate's point: &[Tg; N] (or &[Tg] for ND) is grid-side; its Result<Tv, InterpolateError> return is
    value-side. (This stays Tg-typed only as long as Tg: Float; see Tp below for
    when that stops holding.)
  • Extrapolate<T>::Fill(T) (src/interpolator/mod.rs): the held value is interpolation
    output, so Fill(Tv), even though Interp1D<T, S> around it today reads as
    grid-coordinate-typed.
  • InterpolateError/ValidateError: stay non-generic. (InterpolateError was already
    kept non-generic in the 0.10 error rework partly for this; ValidateError would only
    need to follow Extrapolate onto Tv if it ever went generic, which it isn't doing
    here.)

Open questions

  • Query-point type, Tp. A query point falls between grid points, so once Tg
    isn't Float, the point type can't just be Tg (an integer or date-like grid can't
    represent a fractional position). It can't just be Tv either: an unsigned-int grid
    image (Tg = pixel index, Tv = u8 grayscale) still wants high-precision
    fractional interpolation with the result rounded/cast down to u8, so Tv isn't
    float-shaped in general either. That points at Tp as a genuine third type
    parameter, bounded Float and defaulting to f64 so the common case needs no extra
    annotation, with numeric casts at each boundary: Tg -> Tp to compute fractional
    position, Tp -> Tv (round/clamp) to produce the final value. interpolate's point
    argument becomes Tp-typed once this lands, not Tg-typed. (Named Tp rather than
    Tq/"query" to match this codebase's existing point parameter naming, and because
    q reads as too visually similar to g next to Tg.)
  • Internal float-only math, resolved by the above: CubicC1/CubicC2's tridiagonal
    solves and Hermite evaluation (thomas, compute_m, hermite_eval_1d, etc. in
    src/strategy/cubic.rs) are T: Float today and stay float-like as Tp, rather than
    inventing a separate type for them.
  • Confirm no other cached strategy state (e.g. spline coefficient caches) is silently
    grid-typed when it should be value/float-typed.

Non-goals for this issue

Not implementing Tp here. This issue is scoped to the Tg/Tv split itself; Tp is
a follow-up once it's clear whether non-Float grids are something anyone actually
wants, or shipped speculatively. Its rough shape (a Float-bounded third parameter
defaulting to f64, with numeric casts at the Tg/Tv boundaries) is captured above
so the Tg/Tv split doesn't foreclose it.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/interpolator/data.rs, then trace the generic aliases and implementations in src/interpolator/mod.rs and src/interpolator/enums.rs. Read src/strategy/traits.rs, src/strategy/cubic.rs, and src/strategy/utils.rs to classify grid-, value-, and float-oriented state; the follow-up Tp design is explicitly out of scope. Done means the Tg/Tv split is applied consistently across the listed APIs without implementing Tp.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend-api-design
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.