See below results for the pure Julia packages:
(1) BSplineKit.jl’s nice solution given by @jipolanco
(2) SmoothingSplines.jl
(3) Loess.jl suggested by @marius311
They work relatively well for your dataset with following caveats:
(1) allows defining the number of knots but is a bit less smooth than (2)
(2) allows defining the smoothness (all input data abscissas become knots)
(3) struggles to follow the data at start and end locations
The best is to use InspectDR.jl Plots’ backend to interactively zoom and inspect the results.
x1 = midtime1[:] # imported from Matlab *.mat file using MAT.jl
y1 = rotationalspeed1[:] # imported from Matlab *.mat file using MAT.jl
using SmoothingSplines
# REINSCH, C. [1967] Smoothing by Spline Functions. Numerische Mathematik 10: 177-183
# http://eudml.org/doc/131782
spl = fit(SmoothingSpline, x1, y1, 1.0) # λ=1.0
ys1 = SmoothingSplines.predict(spl,x1) # fitted vector
using BSplineKit, LinearAlgebra, SparseArrays
# Create B-spline basis of order 4 (cubic splines) with chosen breakpoints
xbreaks = LinRange(extrema(x1)..., 200)
B = BSplineBasis(BSplineOrder(4), xbreaks)
# Construct spline from the given data by @jipolanco
C = collocation_matrix(B, x1, SparseMatrixCSC{Float64}) # evaluates basis functions at data points
coefs = qr(C) \ y1 # spline coefficients
fspline = Spline(B, coefs)
using Loess
model = loess(x1, y1, span=0.02)
yl1 = Loess.predict(model, x1)
using Plots; inspectdr()
inspectdr(size=(1000,800), lw=3, markerstrokewidth=0, ms=7, legend=:top)
Plots.scatter(x1, y1, mc=:blue,label="rotationalspeed1")
Plots.plot!(x1, ys1, lc=:red,label="(Cubic) SmoothingSpline.jl")
Plots.plot!(x1, fspline.(x1); lc=:cyan,ls=:dash, label = "Cubic BSplineKit.jl by@jipolanco")
Plots.plot!(x1, yl1, ls=:dot, lc=:black,label="Loess.jl")
Whole tachometer signal:
Zoom-in at start:
Zoom-in at peak:
Zoom-in at end: