Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modernize the tests #40

Merged
merged 51 commits into from
Mar 13, 2022
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
a8ab424
modernizing the tests
jacobwilliams Feb 18, 2022
9234042
refactor test_chkder
jacobwilliams Feb 19, 2022
05a2615
refactor test_hybrj
jacobwilliams Feb 19, 2022
f6b26ae
refactoring lmdif and lmstr
jacobwilliams Mar 2, 2022
dfb7076
Merge branch 'main' of https://github.com/fortran-lang/minpack into t…
jacobwilliams Mar 3, 2022
729a13a
fix interface mismatch
jacobwilliams Mar 4, 2022
7bb459a
fix interface mismatch
jacobwilliams Mar 4, 2022
58d4c43
make sure all output arrays are initialized to zero
jacobwilliams Mar 5, 2022
a08ce2e
converged some old fashioned logical operators
jacobwilliams Mar 5, 2022
a06311f
fixed a refactoring bug in test_lmstr
jacobwilliams Mar 5, 2022
2b6a640
added intent(inout) to func and jac function outputs for hybrj and lmstr
jacobwilliams Mar 5, 2022
0f62bbb
added missing cases from test_lmder
jacobwilliams Mar 5, 2022
0fd2a78
restored all the test cases that were being read from the files
jacobwilliams Mar 5, 2022
e24560e
removed test modules. just duplicate in each file as necessary
jacobwilliams Mar 5, 2022
cabe118
fix refactoring bug
jacobwilliams Mar 6, 2022
37f4cc1
fix refactor typo
jacobwilliams Mar 6, 2022
8114422
more cleanup in test_lmstr
jacobwilliams Mar 6, 2022
d6d5ca6
removed some unused variables
jacobwilliams Mar 6, 2022
12ca5d4
more cleanups
jacobwilliams Mar 6, 2022
a8ee074
more cleanup of tests
jacobwilliams Mar 7, 2022
074a2d8
added validation for test_chkder
jacobwilliams Mar 8, 2022
47bc4e9
added validation for test_hybrd
jacobwilliams Mar 8, 2022
139cd6f
added validation for test_hybrj
jacobwilliams Mar 8, 2022
12d1e5e
added validation for test_lmder
jacobwilliams Mar 12, 2022
9a0671e
added validation to test_lmdif
jacobwilliams Mar 12, 2022
6b01747
added validation to test_lmstr
jacobwilliams Mar 12, 2022
07961ce
split up fpm tests in ci
jacobwilliams Mar 12, 2022
79ec3d8
test: move lmder test last
jacobwilliams Mar 12, 2022
a279cc3
try an abs and rel tol check
jacobwilliams Mar 12, 2022
e7a0181
added the script used to generate the "truth" values
jacobwilliams Mar 12, 2022
fd9b3d2
fixed typos
jacobwilliams Mar 12, 2022
a2b36ec
TEST: change lmdif check tol to 1e-2
jacobwilliams Mar 12, 2022
688290a
increase tol for lmstr check
jacobwilliams Mar 12, 2022
737890e
fix tol check
jacobwilliams Mar 12, 2022
ecb91cd
test: in lmder test, only consider the ones where original minpack pa…
jacobwilliams Mar 12, 2022
0fdc387
same for lmdiff
jacobwilliams Mar 12, 2022
299f973
make these arrays the correct size
jacobwilliams Mar 12, 2022
7fcfe44
same for lmstr
jacobwilliams Mar 12, 2022
2f7df7b
now try tighter tol for lmdif
jacobwilliams Mar 12, 2022
d3bd2b6
try 1e-3 for lmder
jacobwilliams Mar 12, 2022
a7759da
tols
jacobwilliams Mar 12, 2022
34d05c6
Merge branch 'main' of https://github.com/fortran-lang/minpack into t…
jacobwilliams Mar 12, 2022
ca9fb55
recombined fpm tests in CI
jacobwilliams Mar 12, 2022
85fb603
add use, only for tests
jacobwilliams Mar 12, 2022
e145ec5
fixed typo in comments
jacobwilliams Mar 12, 2022
92a4c6a
added back examples
jacobwilliams Mar 12, 2022
fca10b5
see if this fixes the floating point warnings
jacobwilliams Mar 12, 2022
dbe588c
remove debug prints
jacobwilliams Mar 12, 2022
b0dcebc
fix CI yml
jacobwilliams Mar 12, 2022
9081a39
remove script that tests old minpack
jacobwilliams Mar 12, 2022
c4ddcc9
Merge branch 'main' of https://github.com/fortran-lang/minpack into t…
jacobwilliams Mar 12, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,34 @@ jobs:
if: ${{ matrix.build == 'fpm' }}
run: fpm build --profile release

- name: Run test (fpm)
- name: Run chkder test (fpm)
jacobwilliams marked this conversation as resolved.
Show resolved Hide resolved
if: ${{ matrix.build == 'fpm' }}
run: fpm test
run: fpm test test_chkder

- name: Run hybrd test (fpm)
if: ${{ matrix.build == 'fpm' }}
run: fpm test test_hybrd

- name: Run hybrj test (fpm)
if: ${{ matrix.build == 'fpm' }}
run: fpm test test_hybrj

- name: Run lmdif test (fpm)
if: ${{ matrix.build == 'fpm' }}
run: fpm test test_lmdif

- name: Run lmstr test (fpm)
if: ${{ matrix.build == 'fpm' }}
run: fpm test test_lmstr

- name: Run examples (fpm)
if: ${{ matrix.build == 'fpm' }}
run: fpm run --example --all

- name: Run lmder test (fpm)
if: ${{ matrix.build == 'fpm' }}
run: fpm test test_lmder

- name: Setup build (meson)
if: ${{ matrix.build == 'meson' }}
run: >-
Expand Down
4 changes: 2 additions & 2 deletions examples/example_lmder1.f90
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ subroutine fcn(m, n, x, fvec, fjac, ldfjac, iflag)
tmp1 = i
tmp2 = 16 - i
tmp3 = tmp1
if (i .gt. 8) tmp3 = tmp2
if (i > 8) tmp3 = tmp2
fvec(i) = y(i) - (x(1) + tmp1/(x(2)*tmp2 + x(3)*tmp3))
end do
else
do i = 1, 15
tmp1 = i
tmp2 = 16 - i
tmp3 = tmp1
if (i .gt. 8) tmp3 = tmp2
if (i > 8) tmp3 = tmp2
tmp4 = (x(2)*tmp2 + x(3)*tmp3)**2
fjac(i,1) = -1.D0
fjac(i,2) = tmp1*tmp2/tmp4
Expand Down
2 changes: 1 addition & 1 deletion examples/example_lmdif1.f90
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ subroutine fcn(m, n, x, fvec, iflag)
tmp1 = i
tmp2 = 16 - i
tmp3 = tmp1
if (i .gt. 8) tmp3 = tmp2
if (i > 8) tmp3 = tmp2
fvec(i) = y(i) - (x(1) + tmp1/(x(2)*tmp2 + x(3)*tmp3))
end do
end subroutine
Expand Down
111 changes: 111 additions & 0 deletions scripts/validate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/bin/bash

#
# Download the old minpack and test files from Netlib
# and compile and run all the tests.
#
# This was used to generate the comparisons for the unit tests.
#

COMPILER=gfortran

rm -rf lib
rm -rf test

mkdir lib
mkdir test

# minpack library files:
wget https://netlib.org/minpack/chkder.f
wget https://netlib.org/minpack/dogleg.f
wget https://netlib.org/minpack/dpmpar.f
wget https://netlib.org/minpack/enorm.f
wget https://netlib.org/minpack/fdjac1.f
wget https://netlib.org/minpack/fdjac2.f
wget https://netlib.org/minpack/hybrd.f
wget https://netlib.org/minpack/hybrd1.f
wget https://netlib.org/minpack/hybrj.f
wget https://netlib.org/minpack/hybrj1.f
wget https://netlib.org/minpack/lmder.f
wget https://netlib.org/minpack/lmder1.f
wget https://netlib.org/minpack/lmdif.f
wget https://netlib.org/minpack/lmdif1.f
wget https://netlib.org/minpack/lmpar.f
wget https://netlib.org/minpack/lmstr.f
wget https://netlib.org/minpack/lmstr1.f
wget https://netlib.org/minpack/qform.f
wget https://netlib.org/minpack/qrfac.f
wget https://netlib.org/minpack/qrsolv.f
wget https://netlib.org/minpack/r1mpyq.f
wget https://netlib.org/minpack/r1updt.f
wget https://netlib.org/minpack/rwupdt.f

mv *.f lib

# test programs:
wget https://netlib.org/minpack/ex/file15
wget https://netlib.org/minpack/ex/file16
wget https://netlib.org/minpack/ex/file17
wget https://netlib.org/minpack/ex/file18
wget https://netlib.org/minpack/ex/file19
wget https://netlib.org/minpack/ex/file20

mv file15 ./test/file15.f
mv file16 ./test/file16.f
mv file17 ./test/file17.f
mv file18 ./test/file18.f
mv file19 ./test/file19.f
mv file20 ./test/file20.f

# modify the tests to read the data from the files
# note: this is mac sed:
sed -i -e 's| READ (NREAD,50) NPROB,N,NTRIES| if (ic==0) open(unit=NREAD,file="file21",status="OLD");READ (NREAD,50) NPROB,N,NTRIES|g' ./test/file15.f
sed -i -e 's| READ (NREAD,50) NPROB,N,NTRIES| if (ic==0) open(unit=NREAD,file="file21",status="OLD");READ (NREAD,50) NPROB,N,NTRIES|g' ./test/file16.f
sed -i -e 's| READ (NREAD,50) NPROB,N,M,NTRIES| if (ic==0) open(unit=NREAD,file="file22",status="OLD");READ (NREAD,50) NPROB,N,M,NTRIES|g' ./test/file17.f
sed -i -e 's| READ (NREAD,50) NPROB,N,M,NTRIES| if (ic==0) open(unit=NREAD,file="file22",status="OLD");READ (NREAD,50) NPROB,N,M,NTRIES|g' ./test/file18.f
sed -i -e 's| READ (NREAD,50) NPROB,N,M,NTRIES| if (ic==0) open(unit=NREAD,file="file22",status="OLD");READ (NREAD,50) NPROB,N,M,NTRIES|g' ./test/file19.f
sed -i -e 's| LDFJAC = 10| LDFJAC = 10; open(unit=NREAD,file="file23",status="OLD")|g' ./test/file20.f

sed -i -e 's| DATA NREAD,NWRITE /5,6/| DATA NREAD,NWRITE /500,6/|g' ./test/file15.f
sed -i -e 's| DATA NREAD,NWRITE /5,6/| DATA NREAD,NWRITE /500,6/|g' ./test/file16.f
sed -i -e 's| DATA NREAD,NWRITE /5,6/| DATA NREAD,NWRITE /500,6/|g' ./test/file17.f
sed -i -e 's| DATA NREAD,NWRITE /5,6/| DATA NREAD,NWRITE /500,6/|g' ./test/file18.f
sed -i -e 's| DATA NREAD,NWRITE /5,6/| DATA NREAD,NWRITE /500,6/|g' ./test/file19.f
sed -i -e 's| DATA NREAD,NWRITE /5,6/| DATA NREAD,NWRITE /500,6/|g' ./test/file20.f

# input files:
wget https://netlib.org/minpack/ex/file21
wget https://netlib.org/minpack/ex/file22
wget https://netlib.org/minpack/ex/file23

# compile tests:
$COMPILER -O0 -ffixed-line-length-none ./lib/*.f ./test/file15.f -o test_hybrd_O0_$COMPILER
$COMPILER -O0 -ffixed-line-length-none ./lib/*.f ./test/file16.f -o test_hybrj_O0_$COMPILER
$COMPILER -O0 -ffixed-line-length-none ./lib/*.f ./test/file17.f -o test_lmder_O0_$COMPILER
$COMPILER -O0 -ffixed-line-length-none ./lib/*.f ./test/file18.f -o test_lmstr_O0_$COMPILER
$COMPILER -O0 -ffixed-line-length-none ./lib/*.f ./test/file19.f -o test_lmdif_O0_$COMPILER
$COMPILER -O0 -ffixed-line-length-none ./lib/*.f ./test/file20.f -o test_chkder_O0_$COMPILER

# run tests:
./test_hybrd_O0_$COMPILER > output_test_hybrd_O0_$COMPILER.txt
./test_hybrj_O0_$COMPILER > output_test_hybrj_O0_$COMPILER.txt
./test_lmder_O0_$COMPILER > output_test_lmder_O0_$COMPILER.txt
./test_lmstr_O0_$COMPILER > output_test_lmstr_O0_$COMPILER.txt
./test_lmdif_O0_$COMPILER > output_test_lmdif_O0_$COMPILER.txt
./test_chkder_O0_$COMPILER > output_test_chkder_O0_$COMPILER.txt

# compile tests:
$COMPILER -O2 -ffixed-line-length-none ./lib/*.f ./test/file15.f -o test_hybrd_O2_$COMPILER
$COMPILER -O2 -ffixed-line-length-none ./lib/*.f ./test/file16.f -o test_hybrj_O2_$COMPILER
$COMPILER -O2 -ffixed-line-length-none ./lib/*.f ./test/file17.f -o test_lmder_O2_$COMPILER
$COMPILER -O2 -ffixed-line-length-none ./lib/*.f ./test/file18.f -o test_lmstr_O2_$COMPILER
$COMPILER -O2 -ffixed-line-length-none ./lib/*.f ./test/file19.f -o test_lmdif_O2_$COMPILER
$COMPILER -O2 -ffixed-line-length-none ./lib/*.f ./test/file20.f -o test_chkder_O2_$COMPILER

# run tests:
./test_hybrd_O2_$COMPILER > output_test_hybrd_O2_$COMPILER.txt
./test_hybrj_O2_$COMPILER > output_test_hybrj_O2_$COMPILER.txt
./test_lmder_O2_$COMPILER > output_test_lmder_O2_$COMPILER.txt
./test_lmstr_O2_$COMPILER > output_test_lmstr_O2_$COMPILER.txt
./test_lmdif_O2_$COMPILER > output_test_lmdif_O2_$COMPILER.txt
./test_chkder_O2_$COMPILER > output_test_chkder_O2_$COMPILER.txt
jacobwilliams marked this conversation as resolved.
Show resolved Hide resolved
45 changes: 24 additions & 21 deletions src/minpack.f90
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,19 @@ subroutine fcn_hybrj(n, x, fvec, fjac, ldfjac, iflag)
!! user-supplied subroutine for [[hybrj]] and [[hybrj1]]
import :: wp
implicit none
integer, intent(in) :: n !! the number of variables.
real(wp), dimension(n), intent(in) :: x !! independant variable vector
integer, intent(in) :: ldfjac !! leading dimension of the array fjac.
real(wp), dimension(n), intent(out) :: fvec !! value of function at `x`
real(wp), dimension(ldfjac, n), intent(out) :: fjac !! jacobian matrix at `x`
integer, intent(inout) :: iflag !! if iflag = 1 calculate the functions at x and
!! return this vector in fvec. do not alter fjac.
!! if iflag = 2 calculate the jacobian at x and
!! return this matrix in fjac. do not alter fvec.
!!
!! the value of iflag should not be changed by fcn unless
!! the user wants to terminate execution of hybrj.
!! in this case set iflag to a negative integer.
integer, intent(in) :: n !! the number of variables.
real(wp), dimension(n), intent(in) :: x !! independant variable vector
integer, intent(in) :: ldfjac !! leading dimension of the array fjac.
real(wp), dimension(n), intent(inout) :: fvec !! value of function at `x`
real(wp), dimension(ldfjac, n), intent(inout) :: fjac !! jacobian matrix at `x`
integer, intent(inout) :: iflag !! if iflag = 1 calculate the functions at x and
!! return this vector in fvec. do not alter fjac.
!! if iflag = 2 calculate the jacobian at x and
!! return this matrix in fjac. do not alter fvec.
!!
!! the value of iflag should not be changed by fcn unless
!! the user wants to terminate execution of hybrj.
!! in this case set iflag to a negative integer.
end subroutine fcn_hybrj

subroutine fcn_lmder(m, n, x, fvec, fjac, ldfjac, iflag)
Expand Down Expand Up @@ -97,7 +97,7 @@ subroutine fcn_lmstr(m, n, x, fvec, fjrow, iflag)
!! the value of iflag should not be changed by fcn unless
!! the user wants to terminate execution of lmstr.
!! in this case set iflag to a negative integer.
real(wp), intent(in) :: x(n) !! independent variable vector
real(wp), intent(in) :: x(n) !! independant variable vector
jacobwilliams marked this conversation as resolved.
Show resolved Hide resolved
real(wp), intent(inout) :: fvec(m) !! value of function at `x`
real(wp), intent(inout) :: fjrow(n) !! jacobian row
end subroutine fcn_lmstr
Expand Down Expand Up @@ -703,7 +703,7 @@ subroutine hybrd(fcn, n, x, Fvec, Xtol, Maxfev, Ml, Mu, Epsfcn, Diag, Mode, &
! determine the number of calls to fcn needed to compute
! the jacobian matrix.

msum = min0(Ml + Mu + 1, n)
msum = min(Ml + Mu + 1, n)

! initialize iteration counter and monitors.

Expand Down Expand Up @@ -3125,7 +3125,7 @@ subroutine qform(m, n, q, Ldq, Wa)

! zero out upper triangle of q in the first min(m,n) columns.

minmn = min0(m, n)
minmn = min(m, n)
if (minmn >= 2) then
do j = 2, minmn
jm1 = j - 1
Expand Down Expand Up @@ -3240,7 +3240,7 @@ subroutine qrfac(m, n, a, Lda, Pivot, Ipvt, Lipvt, Rdiag, Acnorm, Wa)

! reduce a to r with householder transformations.

minmn = min0(m, n)
minmn = min(m, n)
do j = 1, minmn
if (Pivot) then

Expand Down Expand Up @@ -3515,10 +3515,13 @@ subroutine r1mpyq(m, n, a, Lda, v, w)
if (nm1 >= 1) then
do nmj = 1, nm1
j = n - nmj
if (abs(v(j)) > one) cos = one/v(j)
if (abs(v(j)) > one) sin = sqrt(one - cos**2)
if (abs(v(j)) <= one) sin = v(j)
if (abs(v(j)) <= one) cos = sqrt(one - sin**2)
if (abs(v(j)) > one) then
cos = one/v(j)
sin = sqrt(one - cos**2)
else
sin = v(j)
cos = sqrt(one - sin**2)
end if
do i = 1, m
temp = cos*a(i, j) - sin*a(i, n)
a(i, n) = sin*a(i, j) + cos*a(i, n)
Expand Down
8 changes: 4 additions & 4 deletions src/minpack_capi.f90
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ subroutine wrap_fcn(n, x, fvec, fjac, ldfjac, iflag)
integer, intent(in) :: n
real(wp), intent(in) :: x(n)
integer, intent(in) :: ldfjac
real(wp), intent(out) :: fvec(n)
real(wp), intent(out) :: fjac(ldfjac, n)
real(wp), intent(inout) :: fvec(n)
real(wp), intent(inout) :: fjac(ldfjac, n)
integer, intent(inout) :: iflag

call fcn(n, x, fvec, fjac, ldfjac, iflag, udata)
Expand Down Expand Up @@ -216,8 +216,8 @@ subroutine wrap_fcn(n, x, fvec, fjac, ldfjac, iflag)
integer, intent(in) :: n
real(wp), intent(in) :: x(n)
integer, intent(in) :: ldfjac
real(wp), intent(out) :: fvec(n)
real(wp), intent(out) :: fjac(ldfjac, n)
real(wp), intent(inout) :: fvec(n)
real(wp), intent(inout) :: fjac(ldfjac, n)
integer, intent(inout) :: iflag

call fcn(n, x, fvec, fjac, ldfjac, iflag, udata)
Expand Down
Loading