Skip to content

Commit 16f4335

Browse files
committed
fix a bug with derivative logic (bug from f77 conversion)
Fixes #9 added a unit test to check derivatives.
1 parent f44302f commit 16f4335

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed

src/splpak.F90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ subroutine bascmp(me,x,nderiv,xmin,nodes,icol,basm)
308308
fact = me%dxin(idim)
309309
end if
310310
z = fact* (x(idim)-xb) + 2.0_wp
311-
if (z<0.0_wp) then
311+
if (z>0.0_wp) then
312312
if (z<2.0_wp) then
313313
bas1 = 1.5_wp*z**2
314314
z = z - 1.0_wp

test/splpak_test_linear.f90

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
!*****************************************************************************************
2+
!>
3+
! Units test for splpak.
4+
! Test a linear function
5+
6+
program splpak_test_linesr
7+
8+
use splpak_module, wp => splpak_wp
9+
use iso_fortran_env
10+
use pyplot_module
11+
12+
implicit none
13+
14+
integer,parameter :: ndim = 1 !! 1d problem
15+
integer,parameter :: nxdata = 20 !! number of points in x
16+
integer,dimension(ndim),parameter :: nodes = [10]
17+
integer,parameter :: ncol = product(nodes)
18+
integer,parameter :: nwrk = ncol*(ncol+1) + 1 ! is doc wrong? do we need the + 1 (otherwise, it fails)...
19+
integer,parameter :: ncf = ncol
20+
integer,parameter :: nxdata_est = 100 !! number of points for estimate plot
21+
22+
real(wp),dimension(ndim,nxdata) :: xdata
23+
real(wp),dimension(nxdata) :: ydata
24+
real(wp),dimension(ndim) :: xmin
25+
real(wp),dimension(ndim) :: xmax
26+
real(wp),dimension(nwrk) :: work
27+
real(wp),dimension(ncf) :: coef
28+
real(wp),dimension(nxdata) :: wdata !! weights
29+
real(wp),dimension(nxdata_est) :: xdata_est, ydata_est
30+
real(wp),dimension(ndim) :: x
31+
32+
integer :: ierror, istat
33+
integer :: i !! counter
34+
real(wp) :: xtrap
35+
real(wp) :: tru, err, errmax, f, fleft, fright
36+
type(pyplot) :: plt
37+
character(len=10) :: nodes_str !! string version of `nodes`
38+
type(splpak_type) :: solver, solver2
39+
integer,dimension(2),parameter :: figsize = [20,10] !! figure size for plot
40+
41+
xtrap = 1.0_wp
42+
xmin(1) = 0.0_wp
43+
xmax(1) = 1.0_wp
44+
do i=1,nxdata
45+
wdata(i) = 1.0_wp ! weight
46+
xdata(1,i) = real(i-1,wp)/real(nxdata-1,wp)
47+
ydata(i) = f1(xdata(1,i))
48+
end do
49+
50+
! write(*,'(a,*(f8.3,","))') 'xdata = ', xdata
51+
! write(*,'(a,*(f8.3,","))') 'ydata = ', ydata
52+
53+
! initialize:
54+
call solver%initialize(1,xdata,1,ydata,wdata,nxdata,xmin,xmax, &
55+
nodes,xtrap,coef,ncf,work,nwrk,ierror)
56+
57+
write(*,*) 'splcw ierror = ', ierror
58+
if (ierror /= 0) error stop 'error calling splcw'
59+
60+
! compute max error at interpolation points
61+
errmax = 0.0_wp
62+
do i=1,nxdata_est
63+
xdata_est(i) = real(i-1,wp)/nxdata_est
64+
x(1) = xdata_est(i)
65+
f = solver%evaluate(ndim,x,coef,xmin,xmax,nodes,ierror)
66+
ydata_est(i) = f
67+
if (ierror /= 0) error stop 'error calling splfe'
68+
tru = f1(xdata_est(i))
69+
err = abs(tru-f)
70+
errmax = max(err,errmax)
71+
end do
72+
write(*,*) 'splfe errmax [linear] = ', errmax
73+
if (abs(errmax)>1.0e-1_wp) error stop 'errmax too large'
74+
75+
! write(*,'(a,*(f8.3,","))') 'xdata_est = ', xdata_est
76+
! write(*,'(a,*(f8.3,","))') 'ydata_est = ', ydata_est
77+
78+
! test the derivatives also:
79+
fleft = solver%evaluate(ndim,[0.0_wp],[1],coef,xmin,xmax,nodes,ierror)
80+
if (ierror /= 0) error stop 'error calling splde'
81+
errmax = fleft - 2.0_wp
82+
write(*,*) 'splde errmax left [linear] = ', errmax
83+
if (abs(errmax)>1.0e-12_wp) error stop 'errmax too large'
84+
85+
fright = solver%evaluate(ndim,[1.0_wp],[1],coef,xmin,xmax,nodes,ierror)
86+
if (ierror /= 0) error stop 'error calling splde'
87+
errmax = fleft - 2.0_wp
88+
write(*,*) 'splde errmax right [linear] = ', errmax
89+
if (abs(errmax)>1.0e-12_wp) error stop 'errmax too large'
90+
91+
write(nodes_str,'(I10)') nodes(1); nodes_str = adjustl(nodes_str)
92+
93+
call plt%initialize(grid=.true.,xlabel='x',ylabel='y',&
94+
figsize=figsize,font_size=20,axes_labelsize=20,&
95+
xtick_labelsize=20, ytick_labelsize=20,&
96+
legend_fontsize=20,&
97+
title='splpak_test',legend=.true.)
98+
call plt%add_plot(xdata(1,:),ydata,&
99+
label='Original points',&
100+
linestyle='ko',markersize=5,linewidth=2,istat=istat)
101+
call plt%add_plot(xdata_est,ydata_est,&
102+
label='Least squares bspline with '//trim(nodes_str)//' nodes',&
103+
linestyle='r-',markersize=2,linewidth=2,istat=istat)
104+
call plt%savefig(pyfile='splpak_test.py', figfile='splpak_test_linear.png',istat=istat)
105+
106+
contains
107+
108+
real(wp) function f1(x) !! 1d test function
109+
implicit none
110+
real(wp) :: x
111+
f1 = 2.0_wp * x
112+
end function f1
113+
114+
end program splpak_test_linesr

0 commit comments

Comments
 (0)