Skip to content

Commit 7201491

Browse files
committed
Add test for minpack_lmder1
1 parent 3ae813e commit 7201491

File tree

3 files changed

+78
-11
lines changed

3 files changed

+78
-11
lines changed

include/minpack.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,14 @@ minpack_lmder1(
194194
minpack_fcn_lmder /* fcn */,
195195
int /* m */,
196196
int /* n */,
197-
double /* *x */,
198-
double /* *fvec */,
199-
double /* *fjac */,
197+
double* /* x */,
198+
double* /* fvec */,
199+
double* /* fjac */,
200200
int /* ldfjac */,
201201
double /* tol */,
202-
int /* *info */,
203-
int /* *ipvt */,
204-
double /* *wa */,
202+
int* /* info */,
203+
int* /* ipvt */,
204+
double* /* wa */,
205205
int /* lwa */,
206206
void* /* udata */);
207207

src/minpack_capi.f90

+2-2
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ subroutine wrap_fcn(m, n, x, fvec, iflag)
284284
end subroutine wrap_fcn
285285
end subroutine minpack_lmdif
286286

287-
subroutine minpack_lmdif1(fcn, m, n, x, Fvec, Tol, Info, Iwa, Wa, Lwa, udata) &
287+
subroutine minpack_lmdif1(fcn, m, n, x, fvec, tol, info, iwa, wa, lwa, udata) &
288288
& bind(c)
289289
type(c_funptr) :: fcn
290290
integer(c_int), value :: m
@@ -294,7 +294,7 @@ subroutine minpack_lmdif1(fcn, m, n, x, Fvec, Tol, Info, Iwa, Wa, Lwa, udata) &
294294
integer(c_int), intent(inout) :: iwa(n)
295295
real(c_double), value :: tol
296296
real(c_double), intent(inout) :: x(n)
297-
real(c_double), intent(out) :: fvec(m)
297+
real(c_double), intent(inout) :: fvec(m)
298298
real(c_double), intent(inout) :: wa(lwa)
299299
type(c_ptr), value :: udata
300300

test/api/tester.c

+70-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
)(x, __VA_ARGS__)
1414

1515
static inline bool
16-
check_int(int expected, int actual, const char *msg)
16+
check_int(int actual, int expected, const char *msg)
1717
{
1818
if (expected == actual) {
1919
return true;
@@ -23,7 +23,7 @@ check_int(int expected, int actual, const char *msg)
2323
}
2424

2525
static inline bool
26-
check_double(double expected, double actual, double tol, const char *msg)
26+
check_double(double actual, double expected, double tol, const char *msg)
2727
{
2828
if (fabs(expected - actual) < tol) {
2929
return true;
@@ -88,14 +88,81 @@ test_hybrd1 (void)
8888
return 0;
8989
}
9090

91+
void
92+
trial_lmder_fcn(int m, int n, const double* x, double* fvec, double* fjac,
93+
int ldfjac, int* iflag, void* data) {
94+
assert(!!data);
95+
double* y = (double*)data;
96+
assert(m == 15);
97+
assert(n == 3);
98+
99+
if (*iflag == 1) {
100+
for (int i = 0; i < m; i++) {
101+
double tmp1 = i + 1;
102+
double tmp2 = 16 - i - 1;
103+
double tmp3 = i >= 8 ? tmp2 : tmp1;
104+
fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));
105+
}
106+
} else if (*iflag == 2) {
107+
assert(ldfjac == m);
108+
for (int i = 0; i < m; i++) {
109+
double tmp1 = i + 1;
110+
double tmp2 = 16 - i - 1;
111+
double tmp3 = i >= 8 ? tmp2 : tmp1;
112+
double tmp4 = pow(x[1]*tmp2 + x[2]*tmp3, 2);
113+
fjac[i] = -1.0;
114+
fjac[i + ldfjac] = tmp1*tmp2/tmp4;
115+
fjac[i + 2*ldfjac] = tmp1*tmp3/tmp4;
116+
}
117+
}
118+
}
119+
120+
static int
121+
test_lmder1 (void)
122+
{
123+
const double y[15] = {1.4e-1, 1.8e-1, 2.2e-1, 2.5e-1, 2.9e-1, 3.2e-1, 3.5e-1, 3.9e-1,
124+
3.7e-1, 5.8e-1, 7.3e-1, 9.6e-1, 1.34e0, 2.1e0, 4.39e0};
125+
const int m = 15, n = 3;
126+
int info = 0;
127+
double x[3] = {1.0, 1.0, 1.0}, xp[n];
128+
double fvec[m], fvecp[m], err[m];
129+
double fjac[m*n];
130+
int ipvt[n];
131+
double wa[5*n+m];
132+
double tol = sqrt(minpack_dpmpar(1));
133+
134+
minpack_chkder(m, n, x, fvec, fjac, m, xp, fvecp, 1, err);
135+
info = 1;
136+
trial_lmder_fcn(m, n, x, fvec, fjac, m, &info, y);
137+
info = 2;
138+
trial_lmder_fcn(m, n, x, fvec, fjac, m, &info, y);
139+
info = 1;
140+
trial_lmder_fcn(m, n, xp, fvecp, fjac, m, &info, y);
141+
minpack_chkder(m, n, x, fvec, fjac, m, xp, fvecp, 2, err);
142+
143+
for (int i = 0; i < 15; i++) {
144+
if (!check(err[i], 1.0, tol, "Unexpected derivatives")) return 1;
145+
}
146+
147+
minpack_lmder1(trial_lmder_fcn, m, n, x, fvec, fjac, m, tol, &info, ipvt, wa, 30, y);
148+
if (!check(info, 1, "Unexpected info value")) return 1;
149+
if (!check(x[0], 0.8241058e-1, 100*tol, "Unexpected x[0]")) return 1;
150+
if (!check(x[1], 0.1133037e+1, 100*tol, "Unexpected x[1]")) return 1;
151+
if (!check(x[2], 0.2343695e+1, 100*tol, "Unexpected x[2]")) return 1;
152+
if (!check(enorm(m, fvec), 0.9063596e-1, tol, "Unexpected residual")) return 1;
153+
154+
return 0;
155+
}
156+
91157
int
92158
main (void) {
93159
int stat = 0;
94160

95161
stat += test_hybrd1 ();
162+
stat += test_lmder1 ();
96163

97164
if (stat > 0) {
98-
fprintf(stderr, "[FAIL] %d tests failed\n", stat);
165+
fprintf(stderr, "[FAIL] %d test(s) failed\n", stat);
99166
} else {
100167
fprintf(stderr, "[PASS] all tests passed\n");
101168
}

0 commit comments

Comments
 (0)