fslaborg / FSharp.Stats

statistical testing, linear algebra, machine learning, fitting and signal processing in F#
https://fslab.org/FSharp.Stats/
Other
205 stars 54 forks source link

[BUG] In Akima interpolation, the slope at the last point is determined incorrectly. #290

Closed bvenn closed 10 months ago

bvenn commented 10 months ago

When using Akima subspline interpolation, the results within the last interval differ between three tested implementations:

image

I assume there may be an issue here, which comes from this commit 4e221a0. I'll have a look into that.

Code to reproduce ```fsharp #r "nuget: MathNet.Numerics.FSharp, 5.0.0" #r "nuget: Plotly.NET, 4.0.0" #r @"C:\Users\bvenn\source\repos\FSharp.Stats\src\FSharp.Stats\bin\Release\netstandard2.0\FSharp.Stats.dll" let xs = [|1.;2.;3.;4.;4.1;6.|] let ys = [|16.5;17.6;19.;18.1;18.1;16.|] open MathNet open Plotly.NET open FSharp.Stats open FSharp.Stats.Interpolation open Interpolation.CubicSpline [ [1.0 .. 0.01 .. 6.0] |> List.map (fun x -> x,Numerics.Interpolate.CubicSplineRobust(xs, ys).Interpolate(x)) |> Chart.Line |> Chart.withTraceInfo "Mathnet CubicSplineRobust" [1.0 .. 0.01 .. 6.0] |> List.map (fun x -> x,Interpolation.interpolate(xs, ys,InterpolationMethod.AkimaSubSpline).Predict x) |> Chart.Line |> Chart.withTraceInfo "FSharp.Stats Akima" [1.0 .. 0.01 .. 2.0] |> List.map (fun x -> x,(CubicSplineCoef.Create (vector [0..1]) (vector [-0.1154;0.2654;0.9500;16.5000])).Predict (x-1.0)) |> Chart.Line |> Chart.withLineStyle(Color=Color.fromHex "#2ca02c") |> Chart.withTraceInfo "valdivia.staff.jade-hs.de/akima.html" [2.0 .. 0.01 .. 3.0] |> List.map (fun x -> x,(CubicSplineCoef.Create (vector [0..1]) (vector [-0.8404;1.1058;1.1346;17.6000])).Predict (x-2.0)) |> Chart.Line |> Chart.withLineStyle(Color=Color.fromHex "#2ca02c") |> Chart.withTraceInfo "valdivia interval 2" [3.0 .. 0.01 .. 4.0] |> List.map (fun x -> x,(CubicSplineCoef.Create (vector [0..1]) (vector [2.3329;-4.0579;0.8250;19.0000])).Predict (x-3.0)) |> Chart.Line |> Chart.withLineStyle(Color=Color.fromHex "#2ca02c") |> Chart.withTraceInfo "valdivia interval 3" [4.0 .. 0.01 .. 4.1] |> List.map (fun x -> x,(CubicSplineCoef.Create (vector [0;0.1]) (vector [-78.8180;10.8030;-0.2921;18.1000])).Predict (x-4.0)) |> Chart.Line |> Chart.withLineStyle(Color=Color.fromHex "#2ca02c") |> Chart.withTraceInfo "valdivia interval 4" [4.1 .. 0.01 .. 6.0] |> List.map (fun x -> x,(CubicSplineCoef.Create (vector [0;1.9]) (vector [0.0157;-0.3504;-0.4961;18.1000])).Predict (x-4.1)) |> Chart.Line |> Chart.withLineStyle(Color=Color.fromHex "#2ca02c") |> Chart.withTraceInfo "valdivia interval 5" Chart.Point(xs,ys) ] |> Chart.combine |> Chart.withTemplate ChartTemplates.lightMirrored |> Chart.withSize(900.,800.) |> Chart.show ```
bvenn commented 10 months ago

Changing

tmp.[xValues.Length-1] <- Integration.Differentiation.differentiateThreePoint xValues yValues (xValues.Length-2) (xValues.Length-3) (xValues.Length-2) (xValues.Length-1)
//to                                                                                                          |
tmp.[xValues.Length-1] <- Integration.Differentiation.differentiateThreePoint xValues yValues (xValues.Length-1) (xValues.Length-3) (xValues.Length-2) (xValues.Length-1)

solved the issue as expected

bvenn commented 10 months ago

closed by 0ac2a52