1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.ode;
18
19 import java.util.Arrays;
20 import java.util.Collection;
21 import java.util.HashMap;
22 import java.util.Map;
23
24 import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
25 import org.apache.commons.math4.legacy.exception.MaxCountExceededException;
26
27
28
29
30
31
32 class ParameterJacobianWrapper implements ParameterJacobianProvider {
33
34
35 private final FirstOrderDifferentialEquations fode;
36
37
38 private final ParameterizedODE pode;
39
40
41 private final Map<String, Double> hParam;
42
43
44
45
46
47
48
49 ParameterJacobianWrapper(final FirstOrderDifferentialEquations fode,
50 final ParameterizedODE pode,
51 final ParameterConfiguration[] paramsAndSteps) {
52 this.fode = fode;
53 this.pode = pode;
54 this.hParam = new HashMap<>();
55
56
57 for (final ParameterConfiguration param : paramsAndSteps) {
58 final String name = param.getParameterName();
59 if (pode.isSupported(name)) {
60 hParam.put(name, param.getHP());
61 }
62 }
63 }
64
65
66 @Override
67 public Collection<String> getParametersNames() {
68 return pode.getParametersNames();
69 }
70
71
72 @Override
73 public boolean isSupported(String name) {
74 return pode.isSupported(name);
75 }
76
77
78 @Override
79 public void computeParameterJacobian(double t, double[] y, double[] yDot,
80 String paramName, double[] dFdP)
81 throws DimensionMismatchException, MaxCountExceededException {
82
83 final int n = fode.getDimension();
84 if (pode.isSupported(paramName)) {
85 final double[] tmpDot = new double[n];
86
87
88 final double p = pode.getParameter(paramName);
89 final double hP = hParam.get(paramName);
90 pode.setParameter(paramName, p + hP);
91 fode.computeDerivatives(t, y, tmpDot);
92 for (int i = 0; i < n; ++i) {
93 dFdP[i] = (tmpDot[i] - yDot[i]) / hP;
94 }
95 pode.setParameter(paramName, p);
96 } else {
97 Arrays.fill(dFdP, 0, n, 0.0);
98 }
99 }
100 }