25 void casadi_forward_diff(
const T1** yk, T1* J, T1 h, casadi_int n_y) {
28 const double *yf, *yc;
36 for (i = 0; i < n_y; ++i) J[i] = hinv * (yf[i] - yc[i]);
41 void casadi_central_diff(
const T1** yk, T1* J, T1 h, casadi_int n_y) {
44 const T1 *yf, *yc, *yb;
53 for (i = 0; i < n_y; ++i) {
54 if (isfinite(yb[i])) {
55 if (isfinite(yf[i])) {
57 J[i] = 0.5 * hinv * (yf[i] - yb[i]);
60 J[i] = hinv * (yc[i] - yb[i]);
63 if (isfinite(yf[i])) {
65 J[i] = hinv * (yf[i] - yc[i]);
68 J[i] = std::numeric_limits<T1>::quiet_NaN();
76 T1 casadi_central_diff_err(
const T1** yk, T1 h, casadi_int n_y, casadi_int i,
77 T1 abstol, T1 reltol) {
79 const T1 *yf, *yc, *yb;
80 T1 err_trunc, err_round;
86 if (isfinite(yb[i]) && isfinite(yf[i])) {
88 err_trunc = yf[i] - 2*yc[i] + yb[i];
90 err_round = reltol / h * fmax(fabs(yf[i] - yc[i]), fabs(yc[i] - yb[i])) + abstol;
92 return err_trunc / err_round;
95 return std::numeric_limits<T1>::quiet_NaN();;
100 template<
typename T1>
101 T1 casadi_smoothing_diff_weights(casadi_int k, T1 yb, T1 yc, T1 yf, T1 *J) {
107 if (J) *J = 3 * yf - 4 * yc + yb;
121 if (J) *J = -3 * yb + 4 * yc - yf;
128 template<
typename T1>
129 void casadi_smoothing_diff(
const T1** yk, T1* J, T1 h, casadi_int n_y, T1 smoothing) {
133 T1 Jk, wk, sw, ui, sm;
137 for (i = 0; i < n_y; ++i) {
141 for (k = 0; k < 3; ++k) {
147 if (!isfinite(yb) || !isfinite(yc) || !isfinite(yf))
continue;
149 wk = casadi_smoothing_diff_weights(k, yb, yc, yf, &Jk);
154 wk /= sm*sm + smoothing;
162 J[i] = std::numeric_limits<T1>::quiet_NaN();
171 template<
typename T1>
172 T1 casadi_smoothing_diff_err(
const T1** yk, T1 h, casadi_int n_y, casadi_int i,
173 T1 abstol, T1 reltol, T1 smoothing) {
177 T1 wk, sw, ui, err_trunc, err_round, sm;
184 for (k = 0; k < 3; ++k) {
190 if (!isfinite(yb) || !isfinite(yc) || !isfinite(yf))
continue;
192 wk = casadi_smoothing_diff_weights(k, yb, yc, yf,
static_cast<T1*
>(0));
194 err_trunc = yf - 2*yc + yb;
196 err_round = reltol/h*fmax(fabs(yf - yc), fabs(yc - yb)) + abstol;
198 sm = err_trunc/(h*h);
200 wk /= sm*sm + smoothing;
203 ui += wk * fabs(err_trunc / err_round);
208 return std::numeric_limits<T1>::quiet_NaN();;
216 template<
typename T1>
231 template<
typename T1>
232 T1 casadi_forward_diff_old(T1** yk, T1* y0, T1* J,
235 for (i=0; i<n_y; ++i) {
236 J[i] = (yk[0][i]-y0[i])/h;
242 template<
typename T1>
243 T1 casadi_central_diff_old(T1** yk, T1* y0, T1* J,
250 T1 err_trunc, err_round;
253 yf = yc = yb = u = 0;
254 for (i=0; i<n_y; ++i) {
256 if (!isfinite((yf=yk[1][i])) || !isfinite((yc=y0[i])) || !isfinite((yb=yk[0][i]))) {
257 J[i] = std::numeric_limits<T1>::quiet_NaN();
262 J[i] = (yf - yb)/(2*h);
264 err_trunc = yf - 2*yc + yb;
266 err_round = m->
reltol/h*fmax(fabs(yf-yc), fabs(yc-yb)) + m->
abstol;
268 if (u>=0) u = fmax(u, fabs(err_trunc/err_round));
274 template<
typename T1>
275 T1 casadi_smoothing_diff_old(T1** yk, T1* y0, T1* J,
282 T1 Jk, wk, sw, ui, err_trunc, err_round, sm;
285 yf = yc = yb = u = 0;
286 for (i=0; i<n_y; ++i) {
290 for (k=0; k<3; ++k) {
296 if (!isfinite((yc=yk[0][i])))
continue;
297 if (!isfinite((yb=yk[1][i])))
continue;
299 Jk = 3*yf - 4*yc + yb;
307 if (!isfinite((yf=yk[2][i])))
continue;
308 if (!isfinite((yb=yc)))
continue;
314 if (!isfinite((yc=yf)))
continue;
315 if (!isfinite((yf=yk[3][i])))
continue;
317 Jk = -3*yb + 4*yc - yf;
321 err_trunc = yf - 2*yc + yb;
323 err_round = m->
reltol/h*fmax(fabs(yf-yc), fabs(yc-yb)) + m->
abstol;
325 sm = err_trunc/(h*h);
331 ui += wk * fabs(err_trunc/err_round);
336 J[i] = std::numeric_limits<T1>::quiet_NaN();
341 if (u>=0) u = fmax(u, ui/sw);