Skip to content

Commit

Permalink
Added derivative output to piecewise_linear
Browse files Browse the repository at this point in the history
  • Loading branch information
mauro3 committed Dec 22, 2023
1 parent a946d87 commit 4244ee7
Showing 1 changed file with 21 additions and 13 deletions.
34 changes: 21 additions & 13 deletions src/misc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,13 @@ end


"""
piecewiselinear(xs::AbstractVector, ys::AbstractVector)
piecewiselinear(xs::AbstractVector, ys::AbstractVector; derivative=false)
Return a piecewise linear function `f(x) -> y`` through points (xs,ys).
Extrapolation with x<xs[1]->ys[1] and for x>xs[end] -> ys[end] .
If `derivative=true` it returns the derivative (slope) function instead.
Notes:
- xs needs monotonic, i.e. to be sorted in ascending or decending order
- when length(xs)==1, then it returns a constant function.
Expand All @@ -254,26 +256,32 @@ function piecewiselinear(xs::AbstractVector, ys::AbstractVector)
end
rats = diff(ys)./diff(xs)
if issorted(xs)
return function (xq)
return function (xq; derivative=false)
# xq<xs[1] && error("cannot extrapolate")
# xq>xs[end] && error("cannot extrapolate")
# xq==xs[end] && return ys[end]
xq<=xs[1] && return ys[1]
xq>=xs[end] && return ys[end]
xq<xs[1] && return derivative ? ys[1]*0 : ys[1]
xq>=xs[end] && return derivative ? ys[end]*0 : ys[end]
ii = searchsortedlast(xs, xq)
out = ys[ii] - (xs[ii]-xq)*rats[ii]
return out
if derivative
return rats[ii]
else
return ys[ii] - (xs[ii]-xq)*rats[ii]
end
end
elseif issorted(xs, Base.Order.Reverse)
return function (xq)
return function (xq; derivative=false)
# xq>xs[1] && error("cannot extrapolate")
# xq<xs[end] && error("cannot extrapolate")
# xq==xs[end] && return ys[end]
xq>=xs[1] && return ys[1]
xq<=xs[end] && return ys[end]
xq>xs[1] && return derivative ? ys[1]*0 : ys[1]
xq<=xs[end] && return derivative ? ys[end]*0 : ys[end]
ii = searchsortedlast(xs, xq, Base.Order.Reverse)
out = ys[ii] - (xs[ii]-xq)*rats[ii]
return out
if derivative
return rats[ii]
else
return ys[ii] - (xs[ii]-xq)*rats[ii]
end
end
else
error("xs must be sorted")
Expand All @@ -300,7 +308,7 @@ julia> pf, span = parameterized_curve(x,y);
julia> xy = hcat(pf.(r)...); plot(xy[1,:], xy[2,:])
````
"""
function parameterized_curve(x,y)
function parameterized_curve(x,y; derivative=false)
# TODO: make dimension agnostic sometime
pathlength = zeros(typeof(x[1]), length(x)-1) # assume all same datatype
for c in (x,y)
Expand All @@ -309,5 +317,5 @@ function parameterized_curve(x,y)
pathlength = [0, cumsum(sqrt.(pathlength))...]
fx = piecewiselinear(pathlength, x)
fy = piecewiselinear(pathlength, y)
return pl -> [fx(pl), fy(pl)], (0, pathlength[end])
return pl -> [fx(pl; derivative), fy(pl; derivative)], (0, pathlength[end])
end

0 comments on commit 4244ee7

Please sign in to comment.