Skip to content

Commit c625635

Browse files
committed
feat: add InterpolationBlock
1 parent 2d19a9d commit c625635

File tree

2 files changed

+42
-35
lines changed

2 files changed

+42
-35
lines changed

src/Blocks/Blocks.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export Log, Log10
1616
include("math.jl")
1717

1818
export Constant, TimeVaryingFunction, Sine, Cosine, ContinuousClock, Ramp, Step, ExpSine,
19-
Square, Triangular, Parameter, SampledData, ParametrizedInterpolation
19+
Square, Triangular, Parameter, SampledData,
20+
InterpolationBlock, ParametrizedInterpolationBlock
2021
include("sources.jl")
2122

2223
export Limiter, DeadZone, SlewRateLimiter

src/Blocks/sources.jl

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -732,40 +732,46 @@ function SampledData(; name, buffer, sample_time, circular_buffer)
732732
SampledData(SampledDataType.vector_based; name, buffer, sample_time, circular_buffer)
733733
end
734734

735-
# This needs to be extend for interpolation types
736-
# apply_interpolation(interp, t) = interp(t)
737-
738-
# function Symbolics.derivative(::typeof(apply_interpolation), args::NTuple{2, Any}, ::Val{2})
739-
# Symbolics.derivative(args[1], (args[2],), Val(1))
740-
# end
741-
742-
# function cached_interpolation(interpolation_type, u, x, args)
743-
# prev_u = DiffCache(u)
744-
# # Interpolation points can be a range, but we want to be able
745-
# # to update the cache if needed (and setindex! is not defined on ranges)
746-
# # with a view from MTKParameters, so we collect to get a vector
747-
# prev_x = DiffCache(collect(x))
748-
# interp = GeneralLazyBufferCache() do (u, x)
749-
# interpolation_type(get_tmp(prev_u, u), get_tmp(prev_x, x), args...)
750-
# end
751-
752-
# let prev_u = prev_u,
753-
# prev_x = prev_x,
754-
# interp = interp,
755-
# interpolation_type = interpolation_type
756-
757-
# function build_interpolation(u, x, args)
758-
# if (u, x) ≠ (get_tmp(prev_u, u), get_tmp(prev_x, x))
759-
# get_tmp(prev_u, u) .= u
760-
# get_tmp(prev_x, x) .= x
761-
# interp.bufs[(u, x)] = interpolation_type(
762-
# get_tmp(prev_u, u), get_tmp(prev_x, x), args...)
763-
# else
764-
# interp[(u, x)]
765-
# end
766-
# end
767-
# end
768-
# end
735+
"""
736+
InterpolationBlock(interp_type, u, x, args...; name, t = ModelingToolkit.t_nounits)
737+
738+
Represent function interpolation symbolically as a block component.
739+
By default interpolation types from [`DataInterpolations.jl`](https://github.com/SciML/DataInterpolations.jl) are supported,
740+
but in general any callable type that builds the interpolation object via `itp = interpolation_type(u, x, args...)` and calls
741+
the interpolation with `itp(t)` should work. This does not need to represent an interpolation, it can be any type that satisfies
742+
the interface, such as lookup tables.
743+
# Arguments:
744+
- `interp_type`: the type of the interpolation. For `DataInterpolations`,
745+
these would be any of [the available interpolations](https://github.com/SciML/DataInterpolations.jl?tab=readme-ov-file#available-interpolations),
746+
such as `LinearInterpolation`, `ConstantInterpolation` or `CubicSpline`.
747+
- `u`: the data used for interpolation. For `DataInterpolations` this will be an `AbstractVector`
748+
- `x`: the values that each data points correspond to, usually the times corresponding to each value in `u`.
749+
- `args`: any other arguments beeded to build the interpolation
750+
# Keyword arguments:
751+
- `name`: the name of the component
752+
- `t`: the interpolation parameter, this is the time (`ModelingToolkit.t_nounits`) by default
753+
754+
# Parameters:
755+
- `interpolator`: the symbolic
756+
- `t`: the parameter used for interpolation
757+
758+
# Connectors:
759+
- `output`: a [`RealOutput`](@ref) connector corresponding to the interpolated value
760+
"""
761+
function InterpolationBlock(interp_type, u, x, args...; name, t = ModelingToolkit.t_nounits)
762+
itp = interp_type(u, x, args...)
763+
InterpolationBlock(itp; name, t)
764+
end
765+
766+
function InterpolationBlock(itp; name, t = ModelingToolkit.t_nounits)
767+
@parameters (interpolator::typeof(itp))(..) = itp
768+
769+
@named output = RealOutput()
770+
771+
eqs = [output.u ~ interpolator(t)]
772+
773+
ODESystem(eqs, ModelingToolkit.t_nounits, [], [interpolator, t]; name, systems = [output])
774+
end
769775

770776
struct CachedInterpolation{T,I,U,X,C}
771777
interpolation_type::I

0 commit comments

Comments
 (0)