13
13
)(x, __VA_ARGS__)
14
14
15
15
static inline bool
16
- check_int (int expected , int actual , const char * msg )
16
+ check_int (int actual , int expected , const char * msg )
17
17
{
18
18
if (expected == actual ) {
19
19
return true;
@@ -23,7 +23,7 @@ check_int(int expected, int actual, const char *msg)
23
23
}
24
24
25
25
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 )
27
27
{
28
28
if (fabs (expected - actual ) < tol ) {
29
29
return true;
@@ -88,14 +88,81 @@ test_hybrd1 (void)
88
88
return 0 ;
89
89
}
90
90
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
+
91
157
int
92
158
main (void ) {
93
159
int stat = 0 ;
94
160
95
161
stat += test_hybrd1 ();
162
+ stat += test_lmder1 ();
96
163
97
164
if (stat > 0 ) {
98
- fprintf (stderr , "[FAIL] %d tests failed\n" , stat );
165
+ fprintf (stderr , "[FAIL] %d test(s) failed\n" , stat );
99
166
} else {
100
167
fprintf (stderr , "[PASS] all tests passed\n" );
101
168
}
0 commit comments