!>
!> @file l2err.f90
!>
!> @brief
!>
!> @copyright
!> Copyright (©) 2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
!> SPC (Swiss Plasma Center)
!>
!> SPClibs is free software: you can redistribute it and/or modify it under
!> the terms of the GNU Lesser General Public License as published by the Free
!> Software Foundation, either version 3 of the License, or (at your option)
!> any later version.
!>
!> SPClibs is distributed in the hope that it will be useful, but WITHOUT ANY
!> WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
!> FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
!>
!> You should have received a copy of the GNU Lesser General Public License
!> along with this program. If not, see .
!>
!> @author
!> (in alphabetical order)
!> @author Trach-Minh Tran
!>
subroutine l2err ( iprfun, ftau, error )
!*************************************************************************
!
!! L2ERR computes the errors of an L2 approximation.
!
! Discussion:
!
! This routine computes various errors of the current L2-approximation,
! whose piecewise polynomial representation is contained in common
! block APPROX, to the given data contained in common block data.
!
! It prints out the average error errl1, the l2-error errl2, and the
! maximum error errmax.
!
! Reference:
!
! Carl DeBoor,
! A Practical Guide to Splines,
! Springer Verlag.
!
! Parameters:
!
! Input, integer IPRFUN. If iprfun= 1, the routine prints out
! the value of the approximation as well as its error at
! every data point.
!
! Output, real ( kind = 8 ) FTAU(NTAU), contains the value of the computed
! approximation at each value TAU(1:NTAU).
!
! Output, error(1), ..., error(ntau), with error(i)=scale*(g-f)
! at tau(i), all i. here, SCALE equals 1. in case
! iprfun /= 1 , or the absolute error is greater than 100 some-
! where. otherwise, SCALE is such that the maximum of
! abs(error)) over all I lies between 10 and 100. This
! makes the printed output more illustrative.
!
implicit none
integer, parameter :: lpkmax = 100
integer, parameter :: ntmax = 200
integer, parameter :: ltkmax = 2000
integer ntau
real ( kind = 8 ) break
real ( kind = 8 ) coef
real ( kind = 8 ) err
real ( kind = 8 ) errl1
real ( kind = 8 ) errl2
real ( kind = 8 ) errmax
real ( kind = 8 ) error(ntau)
real ( kind = 8 ) ftau(ntau)
real ( kind = 8 ) gtau
integer ie
integer iprfun
integer k
integer l
integer ll
real ( kind = 8 ) scale
real ( kind = 8 ) tau
real ( kind = 8 ) totalw
real ( kind = 8 ) weight
COMMON /DATA/ tau(ntmax),gtau(ntmax),weight(ntmax),totalw,ntau
common /approx/ break(lpkmax),coef(ltkmax),l,k
errl1 = 0.0D+00
errl2 = 0.0D+00
errmax = 0.0D+00
do ll = 1, ntau
call ppvalu(break,coef,l,k,tau(ll),0,ftau(ll))
error(ll) = gtau(ll)-ftau(ll)
err = abs(error(ll))
if ( errmax < err ) then
errmax = err
end if
errl1 = errl1 + err * weight(ll)
errl2 = errl2 + err**2 * weight(ll)
end do
errl1 = errl1 / totalw
errl2 = sqrt ( errl2 / totalw )
write ( *, * ) ' '
write ( *, * ) ' Least square error =',errl2
write ( *, * ) ' Average error =',errl1
write ( *, * ) ' Maximum error =',errmax
write ( *, * ) ' '
if ( iprfun /= 1 ) then
return
end if
!
! Scale error curve and print
!
ie = 0
scale = 1.0D+00
if ( errmax < 10.0D+00 ) then
do ie = 1, 9
scale = scale * 10.0D+00
if ( 10.0D+00 <= errmax * scale ) then
exit
end if
end do
end if
error(1:ntau) = error(1:ntau) * scale
write(*,60) ie, (ll,tau(ll),ftau(ll),error(ll),ll=1,ntau)
60 format (///14x,'approximation and scaled error curve'/ &
7x,'data point',7x,'approximation',3x,'deviation x 10**',i1/ &
(i4, f16.8,f16.8,f17.6))
return
end