= #JxnPortable\docs\programmer_examples\commons_math_examples\CommonsMath_SplineInterpolation~Demo.jxn

#import org.apache.commons.math.analysis.interpolation.SplineInterpolator
#import org.apache.commons.math3.analysis.interpolation.SplineInterpolator
!
slider = @JxnSliderPanel( $this, true )
!
x0 = slider.add( "x0", -8., -10., 10. )
x1 = slider.add( "x1", -6., -10., 10. )
x2 = slider.add( "x2", -4., -10., 10. )
x3 = slider.add( "x3", -2., -10., 10. )
x4 = slider.add( "x4",  0., -10., 10. )
x5 = slider.add( "x5",  2., -10., 10. )
x6 = slider.add( "x6",  4., -10., 10. )
x7 = slider.add( "x7",  6., -10., 10. )
x8 = slider.add( "x8",  8., -10., 10., true )
!
! example 
! Runge function: yi = 1 / ( 1 + xi^2 )  
y0 = slider.add( "y0", 0.015, -10., 10. )
y1 = slider.add( "y1", 0.027, -10., 10. )
y2 = slider.add( "y2", 0.059, -10., 10. )
y3 = slider.add( "y3", 0.2,   -10., 10. )
y4 = slider.add( "y4", 1.0,   -10., 10. )
y5 = slider.add( "y5", 0.2,   -10., 10. )
y6 = slider.add( "y6", 0.059, -10., 10. )
y7 = slider.add( "y7", 0.027, -10., 10. )
y8 = slider.add( "y8", 0.015, -10., 10. )
!
xx = { x0, x1, x2, x3, x4, x5, x6, x7, x8  }
yy = { y0, y1, y2, y3, y4, y5, y6, y7, y8  }
!
si = @SplineInterpolator();
! requires strictly monotonic increasing x0 < x1 < x2 < ...
psf = si.interpolate( xx, yy );
psd = psf.derivative();
psdd = psd.derivative();
!
! parametric spline x(t), y(t)
! requires strictly monotonic increasing t0 < t1 < t2 < ... (monotone x is not required)
tt = 1. { 0 : 8 }
psfx = si.interpolate( tt, xx );
psfy = si.interpolate( tt, yy );
psdx = psfx.derivative();
psdy = psfy.derivative();
!
xi = 0.8 x.toArray()
! Runge-Function (see https://en.wikipedia.org/wiki/Runge%27s_phenomenon):
yi = 1 / ( 1 + xi^2 )
! Spline interpolation avoids the Runge phenomenon
!
ti = ( 8 t ).toArray()
pf2 = plot( xi, psdd.value(xi) )
pf2.setPlotFrameTitle( "2nd derivative" ).setAutoScale(2)
pf1 = plot( xi, psd.value(xi) ).add( curve( psfx.value(ti), psdy.value(ti) / psdx.value(ti), B ) )
pf1.setPlotFrameTitle( "1st derivative" ).setAutoScale(2)
pf0 = plot( xi, psf.value(xi) ).add( curve( psfx.value(ti), psfy.value(ti), B ) ).add( curve( xi, yi, G ) ).add( curve( xx, yy, G, 21 ) )
pf0.setPlotFrameTitle( "red: spline, blue: parametric spline, green: Runge function" ).setAutoScale(2)