28 void casadi_forward_diff(
const T1** yk, T1* J, T1 h, casadi_int n_y) {
31 const double *yf, *yc;
39 for (i = 0; i < n_y; ++i) J[i] = hinv * (yf[i] - yc[i]);
44 void casadi_central_diff(
const T1** yk, T1* J, T1 h, casadi_int n_y) {
47 const T1 *yf, *yc, *yb;
56 for (i = 0; i < n_y; ++i) {
57 if (isfinite(yb[i])) {
58 if (isfinite(yf[i])) {
60 J[i] = 0.5 * hinv * (yf[i] - yb[i]);
63 J[i] = hinv * (yc[i] - yb[i]);
66 if (isfinite(yf[i])) {
68 J[i] = hinv * (yf[i] - yc[i]);
71 J[i] = std::numeric_limits<T1>::quiet_NaN();
79 T1 casadi_central_diff_err(
const T1** yk, T1 h, casadi_int n_y, casadi_int i,
80 T1 abstol, T1 reltol) {
82 const T1 *yf, *yc, *yb;
83 T1 err_trunc, err_round;
89 if (isfinite(yb[i]) && isfinite(yf[i])) {
91 err_trunc = yf[i] - 2*yc[i] + yb[i];
93 err_round = reltol / h * fmax(fabs(yf[i] - yc[i]), fabs(yc[i] - yb[i])) + abstol;
95 return err_trunc / err_round;
98 return std::numeric_limits<T1>::quiet_NaN();;
103 template<
typename T1>
104 T1 casadi_smoothing_diff_weights(casadi_int k, T1 yb, T1 yc, T1 yf, T1 *J) {
110 if (J) *J = 3 * yf - 4 * yc + yb;
124 if (J) *J = -3 * yb + 4 * yc - yf;
131 template<
typename T1>
132 void casadi_smoothing_diff(
const T1** yk, T1* J, T1 h, casadi_int n_y, T1 smoothing) {
136 T1 Jk, wk, sw, ui, sm;
140 for (i = 0; i < n_y; ++i) {
144 for (k = 0; k < 3; ++k) {
150 if (!isfinite(yb) || !isfinite(yc) || !isfinite(yf))
continue;
152 wk = casadi_smoothing_diff_weights(k, yb, yc, yf, &Jk);
157 wk /= sm*sm + smoothing;
165 J[i] = std::numeric_limits<T1>::quiet_NaN();
174 template<
typename T1>
175 T1 casadi_smoothing_diff_err(
const T1** yk, T1 h, casadi_int n_y, casadi_int i,
176 T1 abstol, T1 reltol, T1 smoothing) {
180 T1 wk, sw, ui, err_trunc, err_round, sm;
187 for (k = 0; k < 3; ++k) {
193 if (!isfinite(yb) || !isfinite(yc) || !isfinite(yf))
continue;
195 wk = casadi_smoothing_diff_weights(k, yb, yc, yf,
static_cast<T1*
>(0));
197 err_trunc = yf - 2*yc + yb;
199 err_round = reltol/h*fmax(fabs(yf - yc), fabs(yc - yb)) + abstol;
201 sm = err_trunc/(h*h);
203 wk /= sm*sm + smoothing;
206 ui += wk * fabs(err_trunc / err_round);
211 return std::numeric_limits<T1>::quiet_NaN();
219 template<
typename T1>
234 template<
typename T1>
235 T1 casadi_forward_diff_old(T1** yk, T1* y0, T1* J,
238 for (i=0; i<n_y; ++i) {
239 J[i] = (yk[0][i]-y0[i])/h;
245 template<
typename T1>
246 T1 casadi_central_diff_old(T1** yk, T1* y0, T1* J,
253 T1 err_trunc, err_round;
256 yf = yc = yb = u = 0;
257 for (i=0; i<n_y; ++i) {
259 if (!isfinite((yf=yk[1][i])) || !isfinite((yc=y0[i])) || !isfinite((yb=yk[0][i]))) {
260 J[i] = std::numeric_limits<T1>::quiet_NaN();
265 J[i] = (yf - yb)/(2*h);
267 err_trunc = yf - 2*yc + yb;
269 err_round = m->
reltol/h*fmax(fabs(yf-yc), fabs(yc-yb)) + m->
abstol;
271 if (u>=0) u = fmax(u, fabs(err_trunc/err_round));
277 template<
typename T1>
278 T1 casadi_smoothing_diff_old(T1** yk, T1* y0, T1* J,
285 T1 Jk, wk, sw, ui, err_trunc, err_round, sm;
288 yf = yc = yb = u = 0;
289 for (i=0; i<n_y; ++i) {
293 for (k=0; k<3; ++k) {
299 if (!isfinite((yc=yk[0][i])))
continue;
300 if (!isfinite((yb=yk[1][i])))
continue;
302 Jk = 3*yf - 4*yc + yb;
310 if (!isfinite((yf=yk[2][i])))
continue;
311 if (!isfinite((yb=yc)))
continue;
317 if (!isfinite((yc=yf)))
continue;
318 if (!isfinite((yf=yk[3][i])))
continue;
320 Jk = -3*yb + 4*yc - yf;
324 err_trunc = yf - 2*yc + yb;
326 err_round = m->
reltol/h*fmax(fabs(yf-yc), fabs(yc-yb)) + m->
abstol;
328 sm = err_trunc/(h*h);
334 ui += wk * fabs(err_trunc/err_round);
339 J[i] = std::numeric_limits<T1>::quiet_NaN();
344 if (u>=0) u = fmax(u, ui/sw);