1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.fitting.leastsquares;
18
19 import org.apache.commons.math4.legacy.analysis.MultivariateVectorFunction;
20 import org.apache.commons.math4.legacy.analysis.UnivariateVectorFunction;
21 import org.apache.commons.math4.legacy.analysis.differentiation.DerivativeStructure;
22 import org.apache.commons.math4.legacy.analysis.differentiation.UnivariateVectorFunctionDifferentiator;
23 import org.apache.commons.math4.legacy.linear.Array2DRowRealMatrix;
24 import org.apache.commons.math4.legacy.linear.ArrayRealVector;
25 import org.apache.commons.math4.legacy.linear.RealMatrix;
26 import org.apache.commons.math4.legacy.linear.RealVector;
27 import org.apache.commons.math4.legacy.core.Pair;
28
29 import java.util.Arrays;
30
31
32
33
34
35
36
37 public class DifferentiatorVectorMultivariateJacobianFunction implements MultivariateJacobianFunction {
38
39
40
41 private final MultivariateVectorFunction function;
42
43
44
45 private final UnivariateVectorFunctionDifferentiator differentiator;
46
47
48
49
50
51
52
53 public DifferentiatorVectorMultivariateJacobianFunction(MultivariateVectorFunction function, UnivariateVectorFunctionDifferentiator differentiator) {
54 this.function = function;
55 this.differentiator = differentiator;
56 }
57
58
59 @Override
60 public Pair<RealVector, RealMatrix> value(RealVector point) {
61 double[] testArray = point.toArray();
62 RealVector value = new ArrayRealVector(function.value(testArray));
63 RealMatrix jacobian = new Array2DRowRealMatrix(value.getDimension(), point.getDimension());
64
65 for(int column = 0; column < point.getDimension(); column++) {
66 final int columnFinal = column;
67 double originalPoint = point.getEntry(column);
68 double[] partialDerivatives = getPartialDerivative(testPoint -> {
69
70 testArray[columnFinal] = testPoint;
71
72 return function.value(testArray);
73 }, originalPoint);
74
75 testArray[column] = originalPoint;
76
77 jacobian.setColumn(column, partialDerivatives);
78 }
79
80 return new Pair<>(value, jacobian);
81 }
82
83
84
85
86
87
88
89 private double[] getPartialDerivative(UnivariateVectorFunction univariateVectorFunction, double atParameterValue) {
90 DerivativeStructure[] derivatives = differentiator
91 .differentiate(univariateVectorFunction)
92 .value(new DerivativeStructure(1, 1, 0, atParameterValue));
93 return Arrays.stream(derivatives).mapToDouble(derivative -> derivative.getPartialDerivative(1)).toArray();
94 }
95 }