|
| 1 | +!***************************************************************************************** |
| 2 | +!> |
| 3 | +! Linear interpolation test |
| 4 | + |
| 5 | + program bspline_linear_test |
| 6 | + |
| 7 | + use bspline_module |
| 8 | + use bspline_kinds_module, only: wp, ip |
| 9 | + use pyplot_module |
| 10 | + use linear_interpolation_module |
| 11 | + |
| 12 | + implicit none |
| 13 | + |
| 14 | + integer(ip),parameter :: nx = 10 !! number of points in x |
| 15 | + integer(ip),parameter :: nxv = 111 !100 !! number of points to evaluate interpolant |
| 16 | + |
| 17 | + integer(ip),parameter :: kx = 2 !! order in x [linear] |
| 18 | + !integer(ip),parameter :: kx = bspline_order_cubic !! order in x [cubic] |
| 19 | + !integer(ip),parameter :: kx = bspline_order_quartic |
| 20 | + integer(ip),parameter :: iknot = 0 !! automatically select the knots |
| 21 | + |
| 22 | + real(wp) :: x(nx) |
| 23 | + real(wp) :: xval(nxv),fval(nxv),fval_linear(nxv) |
| 24 | + real(wp) :: tx(nx+kx) |
| 25 | + real(wp) :: fcn_1d(nx) |
| 26 | + real(wp) :: val,tru,err,errmax |
| 27 | + integer(ip) :: i,idx,iflag,inbvx,iloy |
| 28 | + type(pyplot) :: plt |
| 29 | + integer :: istat !! pyplot-fortran status flag |
| 30 | + real(wp),dimension(3*kx) :: w1_1d !! work array |
| 31 | + type(linear_interp_1d) :: s1 |
| 32 | + |
| 33 | + idx = 0 |
| 34 | + |
| 35 | + x = huge(1.0_wp) |
| 36 | + xval = huge(1.0_wp) |
| 37 | + |
| 38 | + do i=1,nx |
| 39 | + x(i) = real(i-1,wp) * 10.0_wp |
| 40 | + fcn_1d(i) = f1(x(i)) |
| 41 | + end do |
| 42 | + do i=1,nxv |
| 43 | + xval(i) = real(i-1,wp) - 10 |
| 44 | + end do |
| 45 | + |
| 46 | + !have to set these before the first evaluate call: |
| 47 | + inbvx = 1 |
| 48 | + iloy = 1 |
| 49 | + |
| 50 | + ! initialize |
| 51 | + call db1ink(x,nx,fcn_1d,kx,iknot,tx,fcn_1d,iflag) |
| 52 | + if (iflag/=0) then |
| 53 | + write(*,*) 'Error initializing 1D spline: '//get_status_message(iflag) |
| 54 | + end if |
| 55 | + call s1%initialize(x,fcn_1d,iflag) |
| 56 | + if (iflag/=0) then |
| 57 | + write(*,*) 'Error initializing 1D linear interpolator: ', iflag |
| 58 | + end if |
| 59 | + |
| 60 | + !initialize the plot: |
| 61 | + call plt%initialize(grid=.true.,xlabel='x (deg)',ylabel='f(x)',& |
| 62 | + title='Linear Test',legend=.true.) |
| 63 | + call plt%add_plot(x,fcn_1d,& |
| 64 | + label='Function $f(x) = \sin(x)$',& |
| 65 | + linestyle='ko',markersize=5,linewidth=2,istat=istat) |
| 66 | + |
| 67 | + errmax = 0.0_wp |
| 68 | + do i=1,nxv |
| 69 | + call db1val(xval(i),idx,tx,nx,kx,fcn_1d,val,iflag,inbvx,w1_1d,extrap=.true.) |
| 70 | + fval(i) = val ! save it for plot |
| 71 | + if (iflag/=0) error stop 'error calling db1val: '//get_status_message(iflag) |
| 72 | + |
| 73 | + tru = f1(xval(i)) |
| 74 | + err = abs(tru-val) |
| 75 | + errmax = max(err,errmax) |
| 76 | + !write(*,*) xval(i), val, tru, err, iflag |
| 77 | + |
| 78 | + ! also compute linear interpolation: |
| 79 | + call s1%evaluate(xval(i),val) |
| 80 | + fval_linear(i) = val ! linear vector for plot |
| 81 | + write(*,*) "error : ", xval(i), fval(i) - fval_linear(i) |
| 82 | + |
| 83 | + end do |
| 84 | + |
| 85 | + ! check max error against tolerance |
| 86 | + write(*,*) '' |
| 87 | + write(*,*) '1D: max error:', errmax |
| 88 | + write(*,*) '' |
| 89 | + |
| 90 | + call plt%add_plot(xval,fval,& |
| 91 | + label='k=2 Spline Interpolated',& |
| 92 | + linestyle='g.-',linewidth=1,istat=istat) |
| 93 | + call plt%add_plot(xval,fval_linear,& |
| 94 | + label='Linear Interpolated',& |
| 95 | + linestyle='r.-',linewidth=1,istat=istat) |
| 96 | + call plt%savefig('bspline_linear_test.png',istat=istat) |
| 97 | + |
| 98 | + contains |
| 99 | + |
| 100 | + real(wp) function f1(x) !! 1d test function |
| 101 | + implicit none |
| 102 | + real(wp) :: x |
| 103 | + real(wp),parameter :: a = acos(-1.0_wp)/18.0_wp |
| 104 | + f1 = sin(a*x) |
| 105 | + end function f1 |
| 106 | + |
| 107 | + end program bspline_linear_test |
0 commit comments