-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Interpolating vector quantities #17
Comments
I guess this is kind of like barycentric interpolation? The way I did it in GeometryOps was to have two APIs, one that returns weights on each coordinate and one that returns a value. It causes a bit of code duplication, though. You could potentially also return a namedtuple of |
All the interpolants take the form (edit 13/05/2024: not true, the smooth interpolants are where |
Gotcha. I guess this could be built off of |
I haven't really intended to make much public API outside of the interpolants themselves. The natural coordinates stuff isn't really public, but it could be. Everything that is public is on the first page of the docs, but if there are functions in the package you find useful feel free to make a PR putting them in there so that they are a part of the API. There'd be a couple steps to implement this issue:
@inline function _eval_natural_coordinates(coordinates, indices, z::Vector)
val = zero(eltype(z))
for (λ, k) in zip(coordinates, indices)
zₖ = z[k]
val += λ * zₖ
end
return val
end
@inline function _eval_natural_coordinates(coordinates, indices, z::Matrix)
val = zeros(eltype(z), size(z, 1))
for (λ, k) in zip(coordinates, indices)
zₖ = @views z[:, k]
@. val += λ * zₖ
end
return val
end
function _val_cache(itp::NaturalNeighboursInterpolant, n)
tri = get_triangulation(itp)
F = number_type(tri)
if is_scalar(itp)
return zeros(F, n)
else
z = get_z(itp)
m = size(z, 1)
return zeros(F, m, n)
end
end so that
NaturalNeighbours.jl/src/interpolation/interpolate.jl Lines 138 to 156 in 95a1f50
vals[i] = itp(x[i], y[i], chunk_id; method, kwargs...) (and similarly for Line 143) with something like
_set_vals!(vals, itp::NaturalNeighboursInterpolant, idx, val) = is_scalar(itp) ? (vals[idx] = val) : (vals[:, idx] .= val)
val = itp(x[i], y[i], chunk_id; method, kwargs...)
_set_vals!(vals, itp, i, val) or if is_scalar(itp)
vals[i] = itp(x[i], y[i], chunk_id; method, kwargs...)
else
vals[:, i] .= itp(x[i], y[i], chunk_id; method, kwargs...)
end The vector case still wouldn't be so optimised at this point since NaturalNeighbours.jl/src/data_structures/neighbour_cache.jl Lines 1 to 9 in 95a1f50
data_cache::C which is nothing if is_scalar(itp) and a vector of length size(z, 1) otherwise. Then, an in-place version of _eval_natural_coordinates(coordinates, indices, z::Vector) (above) would need to be defined to make use of this cache appropriately to avoid these extra allocations.
I think that would be enough. I haven't run any of the above code so I've not seen if I've overlooked anything, but that'd be a good start. If we wanted to go a step further and allow for differentiating such data, I think a similar amount of work might have to be done - I think the linear system is just of the form |
Differentiating might be one of the first things needed actually, at least the generation of the derivatives, so that methods like NaturalNeighbours.jl/src/differentiation/generate.jl Lines 76 to 77 in 0d79b4d
∇ = Matrix{NTuple{2,F}}(undef, size(z)...)
ℋ = Matrix{NTuple{3,F}}(undef, size(z)...) |
Started an implementation in #32, but just need to get around to finishing it off testing and documenting it. Not sure when I'll do that. |
I wonder if it would be nice to have a way to interpolate data of the form$\mathbf z = f(x, y)$ . One application would be solutions from a PDE, in which case we might want to interpolate at the same point but at many times. Being able to do this just a single time would save a lot of time.
The text was updated successfully, but these errors were encountered: