I need to do some basic interpolation and think Grid.jl should provide all the functionality I need, but I can’t quite get it to work for me.
I am essentially looking to do something like what is described for this form of the interp1 matlab function (copied and pasted excerpt from documentation):
Vq = interp1(X,V,Xq) interpolates to find Vq, the values of the underlying function V=F(X) at the query points Xq. X must be a vector of length N.
A minimal example from the Matlab docs (slightly adapted) of what I would like to do is
X = 3:15;
V = sin(X);
Xq = 4:.25:12;
Vq = interp1(X,V,Xq);
Here is what I have so far in Julia:
X = [3:15]
V = sin(X);
Xq = [4:.25:12]
ig = InterpGrid(V, BCnil, InterpLinear)
As far as I understand, I can now “index” the ig object to do interpolation. The problem I am having is that the portion of the grid I would like to interpolate over, Xq, is not represented in terms of indexes, but rather points on the interval [minimum(X), maximum(X)].
What do I need to do to evaluate the function underlying ig at the grid points Xq?
X = [3:15]V = sin(X);
Hey Stefan, thanks for the reply. That was the type of functionality I was hoping for, but it doesn’t quite work like we are expecting.
While the “interpolated” data does look like a sin wave, it is not even close to in the right place.
See what happens if we plot the actual grid points used to çreate the ig object (X, and V) with the interpolated values as well as the actual values of sin(Xq).
X = [3:15];
V = sin(X);
Xq = [4:.25:12];
ig = InterpGrid(V, BCnil, InterpLinear);
y=[ig[x] for x in Xq];
plot(X,V,"o",Xq,y, "orange", Xq, sin(Xq), "red");
legend(["Data", "Interp", "Actual"])
Also,
The getindex method for the InterpGrid object can accept more than one point. There is no need to evaluate the points using a comprehension:
julia> y2 = ig[Xq - 2.0];
julia> y=[ig[x - 2.0] for x in Xq];
julia> maximum(y - y2)
0.0
julia> minimum(y - y2)
0.0
Also Tim,
I am not sure I understand what you mean by
You could also scale the values if they aren’t usually spaced by 1.
Thanks for the response. I think I have settled on how to get this to work. This is what I have right now
immutable ShiftedInterpGrid{T,N,BC,IT}
IG::InterpGrid{T,N,BC,IT}
m::Number
b::Number
end
function ShiftedInterpGrid{T,BC,IT}(V::Vector{T}, X::Vector{T}, ::Type{BC}, ::Type{IT})
n = size(X, 1)
(b, m) = [1 X[1]; 1 X[n]] \ [1; n]
IG = InterpGrid(V, BC, IT)
ShiftedInterpGrid(IG, m, b)
end
function getindex{T,R<:Real}(G::ShiftedInterpGrid{T,1}, x::AbstractVector{R})
s_x::AbstractVector{R} = G.b .+ G.m.*x
return getindex(G.IG, s_x)
end
function getindex{T,R<:Real}(G::ShiftedInterpGrid{T,1}, x::R)
s_x::R = G.b + G.m * x
return getindex(G.IG, s_x)
end
It seems to me that this would be fairly standard functionality. I am sure there is a benefit to having the default getindex methods deal in “index units” instead of physical ones, but I can’t tell what that benefit is? Is there a reason you chose to have it set up the way it is?
Thanks again,
Spencer
AltInterp = CoordInterpGrid(Znw,squeeze(Altura_segun_corte[xx,yy,:],(1,2)),BCnil,InterpLinear);
ERROR: LoadError: MethodError: `convert` has no method matching convert(::Type{Grid.CoordInterpGrid{T<:AbstractFloat,N,BC<:Grid.BoundaryCondition,IT<:Grid.InterpType,R}}, ::Array{Float64,1}, ::Array{Float64,1}, ::Type{Grid.BCnil}, ::Type{Grid.InterpLinear})
This may have arisen from a call to the constructor Grid.CoordInterpGrid{T<:AbstractFloat,N,BC<:Grid.BoundaryCondition,IT<:Grid.InterpType,R}(...),
since type constructors fall back to convert methods.
Closest candidates are:
Grid.CoordInterpGrid{N,T<:AbstractFloat}(::NTuple{N,Range{T}}, ::Array{T<:AbstractFloat,N}, ::Any...)
Grid.CoordInterpGrid{R<:Range{T},T<:AbstractFloat}(::R<:Range{T}, ::Array{T<:AbstractFloat,1}, ::Any...)
call{T}(::Type{T}, ::Any)
...
in call at essentials.jl:57
[inlined code] from Cortes_horizontales_U_V_mod2.jl:46
in anonymous at no file:0
in include at ./boot.jl:261
in include_from_node1 at ./loading.jl:304
while loading Cortes_horizontales_U_V_mod2.jl, in expression starting on line 42
julia> typeof(Znw)
Array{Float64,1}
julia> typeof(squeeze(Altura_segun_corte[1,1,:],(1,2)))
Array{Float64,1}
julia> sizeof(Znw)
224
julia> sizeof(squeeze(Altura_segun_corte[1,1,:],(1,2)))
224