Giter VIP home page Giter VIP logo

cubicsplines.jl's Introduction

codecov

Cubic Splines

A simple package for interpolating 1D data with Akima cubic splines, based on "A New Method of Interpolation and Smooth Curve Fitting Based on Local Parameters", Akima, 1970.

Works for both uniformly and non-uniformly spaced data points.

Example usage

Interpolation

using PyPlot
using CubicSplines

# spline some sinusoidal data with randomness in the x coordinates
xdata = range(0,stop=4pi,length=20) .+ 0.5rand(20)
ydata = sin.(xdata)
plot(xdata, ydata, "o")

spline = CubicSpline(xdata, ydata)

xs = range(xdata[1], stop=xdata[end], length=1000)
ys = spline[xs]
plot(xs, ys)
xlabel("x")
ylabel("y")

Example sinusoid

Extrapolation

By default, you will receive an error if you attempt to sample outside of the xdata range.

spline = CubicSpline(xdata, ydata)
# will throw errors:
spline[minimum(xdata) - 0.001]
spline[maximum(xdata) + 0.001]

If you want to extrapolate outside of the data range, you can specify the polynomials to use for this extrapolation (one for each end of the spline). The left-hand side polynomial coefficients are given as keyword argument extrapl, the right-hand side coefficients as extrapr (assuming a x-axis where -Inf is on the left and +Inf on the right). For example, if extrapl is given, then the left of the spline will be extrapolated as

extrapl = [p1, p2, p3, ..., pn]
y = p0 + p1*(x-xdata[1]) + p2*(x-xdata[1])^2 + p3*(x-xdata[1])^3 + ... + pn*(x-xdata[1])^n

For example, we can extrapolate from a spline with straight lines of a specified slope as follows:

using PyPlot
using CubicSplines

# spline some sinusoidal data
xdata = range(0,stop=2π,length=20)
ydata = sin.(xdata)
plot(xdata, ydata, "ko")

# x values outside of the xdata range
xs = range(-1, stop=2π+1, length=1000)

# extrapolate with linear polynomials of slope=1 or slope=2
for slope in [1,2]
	spline = CubicSpline(xdata, ydata, extrapl=[slope,], extrapr=[slope,])
	plot(xs, spline[xs], label="Slope = $(slope)")
end

xlabel("x")
ylabel("y")
legend()

Example extrapolation

Note that the first and second derivatives of the spline will be matched to the extrapolating polynomials. Changing the extrapolating polynomials can therefore result in small changes at the edges of the interpolated region, as we see in the image above.

It is also possible to allow extrapolate on one side of the spline without allowing extrapolation on the other side of the spline. For example, if we provided a value of extrapl and left extrapr as the default value nothing then we could extrapolate to the left of the spline and throw an out of bounds error to the right of the spline.

Gradient calculation

The gradient of grade n at value x can be requested by gradient(spline, x, n). This also works for the extrapolation regions.

cubicsplines.jl's People

Contributors

sp94 avatar stefanmathis avatar yutakasi634 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

cubicsplines.jl's Issues

New release

Hello Samuel,

I just found that there is no new release of the package yet, which leads to Pkg still downloading the old version w/o extrapolation. Would you mind releasing a new version (v0.1.2)?

Documentation of extrapolation

@StefanMathis thanks very much for your pull request #5. I have a couple questions about some of the documentation

In CubicSplines.jl

The extrapolation behaviour is defined by the coefficients of a 3rd degree
polynomial which can be given as additional keyword arguments extrapl and extrapr
to the constructor. extrapl and/or extrapr should be either "nothing" or a
set of coefficients.

Case 1: Extrapolation is set to "nothing"
In this case, the default quadratic extrapolation according to section 2.3 of [1]
is used to construct the spline and the spline throws an error when evaluated
outside its boundaries.

Case 2: Extrapolation is set to a vector
The container is given as a n-element collection of values:
extrapl = [p1, p2, p3, ..., pn]
which are used to evaluate the following function:
y = p0 + p1*(x-x3) + p2*(x-x3)^2 + p3*(x-x3)^3 + ... + pn*(x-x3)^n
The constant p0 is equal to y3 by definition (continuous spline). x3 and y3
are the first/last datapoint values respectively.

Does the first paragraph contradict the third paragraph? Should we remove "3rd degree" from the first line?


In README.md

The example doesn't run (it doesn't include the xdata and ydata). Do you know what xdata and ydata were used?

Suggestion: remove restriction on real numbers

Hello,

I'm currently using CubicSplines.jl together with the Unitful.jl package. Since the CubicSpline struct is currently restricted to vectors with real elements, this forces me to convert units to real numbers and back. Could we possibly remove the restriction to real elements (instead restricting it to numbers)?

CI/CD

We should add CI/CD for automatic testing and code coverage

There is the start of a travis.yaml file from #6, but fails on systems without matplotlib installed

  • Remove PyPlot as a dependency?
  • Migrate to GitHub actions? (Travis has placed limits on free usage)

Bug in CubicSplines.jl line 38, with fix

I discovered that the interpolated values given from CubicSplines.jl do not match those given by the R function aspline for input values in the interval xs[end-1] to xs[end]

It's not too hard to use a symmetry argument to see that the Julia splined value must be wrong, as set out in the script below. I believe the fix is at line 38 of CubicSplines.jl which should read:
for i in 1:length(ms)
rather than
for i in 1:length(ms)-1

using CubicSplines
using RCall
using Plots

#=CubicSplines2.jl is a copy of CubicSplines.jl with line 38 changed from:
for i in 1:length(ms)-1
to read instead:
for i in 1:length(ms)
=#
include("CubicSplines2.jl")

xs = collect(-2.0:2.0)
ys = mod.(xs, 2)
xin = collect(-2.0:0.5:2.0)

#=By symmetry about zero we should have result(+x) = result(-x)
But that's not true when x is in the interval xs[end-1] to xs[end]

CubicSplines.CubicSpline(xs, ys)[ 1.5] == 0.725
CubicSplines.CubicSpline(xs, ys)[-1.5] == 0.75

As a further check, compare against R's aspline https://www.rdocumentation.org/packages/akima/versions/0.6-2/topics/aspline
=#

j_res = CubicSplines.CubicSpline(xs, ys)[xin]
J_res = CubicSplines2.CubicSpline(xs, ys)[xin]
R_res = rcopy(rcall(:aspline, xs, ys, xin))[:y]

@show xin
@show j_res
@show J_res
@show R_res

@show all(j_res .== R_res)
@show all(J_res .== R_res)

plot(xin,j_res)
plot!(xin,R_res)

running that script:

xin = [-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0]
j_res = [0.0, 0.75, 1.0, 0.5, 0.0, 0.5, 1.0, 0.725, 0.0]
J_res = [0.0, 0.75, 1.0, 0.5, 0.0, 0.5, 1.0, 0.75, 0.0]
R_res = [0.0, 0.75, 1.0, 0.5, 0.0, 0.5, 1.0, 0.75, 0.0]
all(j_res .== R_res) = false
all(J_res .== R_res) = true

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.