Skip to content

Conversation

@rafaqz
Copy link
Collaborator

@rafaqz rafaqz commented Oct 16, 2025

This PR is an exploration of #31 and #32 to see whats possible.

Probably quite slow in current form but this largely works already for the current tests.

The idea is to break each dimension into a preparation step, a definition of the iteration space, and then scaling and index generation functions for the inner loop, then call all of these function from the same shared _interpolate! method.

Will need to add some tests for mixed dimension types.

Closes #31 and closes #32

@rafaqz rafaqz marked this pull request as draft October 16, 2025 06:18
@rafaqz rafaqz changed the title Gneralise _interpolate! to allow mixed dimensions Generalise _interpolate! to allow mixed dimensions Oct 16, 2025
@rafaqz rafaqz marked this pull request as ready for review October 19, 2025 23:53
Copy link
Member

@SouthEndMusic SouthEndMusic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully onderstand everything yet, but overall it looks good. I added some comments.

all(map(check_derivative_order, dims, derivative_orders))
check_derivative_order(::LinearInterpolationDimension, d_o) = d_o <= 1
check_derivative_order(::ConstantInterpolationDimension, d_o) = d_0 <= 0
check_derivative_order(::AbstractInterpolationDimension, d_o) = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this name can be more descriptive, something like is_nonzero_derivative. For BSplineInterpolationDimension it would be is_nonzero_derivative(interp_dim::BSplineInterpolationDimension, d_o) = d_0 < interp_dim.degree + 1. That is only the case when no weights are defined; if weights are defined the interpolation is a NURBS geometry defined by rational functions which generally have all nonzero derivatives

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally, my names are likely pretty bad this PR is coming in cold not knowing much about interpolation vernacular

You can see them more as placeholder tags for a structure that works rather than clear or correct descriptors

iteration_space(::LinearInterpolationDimension) = (false, true)
iteration_space(::ConstantInterpolationDimension) = 1
iteration_space(::NoInterpolationDimension) = 1
iteration_space(d::BSplineInterpolationDimension) = 1:d.degree + 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
iteration_space(d::BSplineInterpolationDimension) = 1:d.degree + 1
iteration_space(d::BSplineInterpolationDimension) = 1:(d.degree + 1)

iszero(derivative_order) ? t₂ - t : -one(t)
end * t_vol_inv
end
scale(::ConstantInterpolationDimension, prep::NamedTuple, i) = 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps just make a fallback method that returns true (I've seen that internally used in some places so it's probably a bit faster than multiplication with an integer).

# end

denom = zero(eltype(t))
function prepare(d::LinearInterpolationDimension, derivative_order, multi_point_index, t, i)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you motivate the need for these preparations? I'm generally not a fan of passing around NamedTuples.

Copy link
Collaborator Author

@rafaqz rafaqz Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a way to do out of loop precalulation of arbitrary things for each dimension, and different interpolatiom methods need different fields.

We can of course use structs specific to each interpolation type, NamedTuple is just easy for iterative development of a new idea.

@rafaqz
Copy link
Collaborator Author

rafaqz commented Oct 21, 2025

FYI there is a lot left to do, the tests that pass are because there are no missing dimensions but this will break if there are any.

sze = map(interp.interp_dims, size(interp.u)) do d, s
d isa NoInterpolationDimension ? s : length(d.t_eval)
end
# TODO: do we need to promote the type here, e.g. for eltype(u) <: Integer ?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I believe this is sometimes done by obtaining the type of a dummy calculation. Alternatively the output type can be passed as a kwarg

@rafaqz
Copy link
Collaborator Author

rafaqz commented Oct 23, 2025

This should be working now.

@rafaqz
Copy link
Collaborator Author

rafaqz commented Oct 24, 2025

There are a few outstanding questions not - like #38 on what dimensions the weights matrix should have now.

But more importantly, what should ts in itp(ts) be ? For NoInterpolationDimension should it require an Int, Colon or AbstractArray{Int} ? To me that would be the most powerful approach, but others may disagree. The alternative would be as now with the trailing dimensions, non interpolated dims are just not included.

Currently Colons are inserted into ts internall to represent the non-interpolating dimensions. But it would be much more flexible if the colon could be an Int or AbstractArray so that _interpolate could be the core function for e.g. a DimensionalData.jl wrapper that allowed arbitrary mixed indexing.

Please chime in here this should be finalised and tested in this PR.

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.

Intentions for mixed mode dimensions Add explicit NonInterpolatedDimension ?

2 participants