Tôi biết của khá cũ và i80and đã làm một công việc tuyệt vời trả lời này, nhưng tôi chỉ nghĩ cho câu hỏi này thêm (đối với các SO-ers trong tương lai) có một cách khá dễ dàng để tính toán các dẫn xuất hoặc các dẫn xuất từng phần với Apache Math (vì vậy bạn không phải làm sự khác biệt của riêng bạn cho ma trận Jacobian). Đó là số DerivativeStructure.
Mở rộng câu trả lời i80and 's sử dụng lớp DerivativeStructure:
//Everything stays the same except for the Jacobian Matrix
import java.util.*;
import org.apache.commons.math3.analysis.ParametricUnivariateFunction;
import org.apache.commons.math3.fitting.AbstractCurveFitter;
import org.apache.commons.math3.fitting.leastsquares.LeastSquaresBuilder;
import org.apache.commons.math3.fitting.leastsquares.LeastSquaresProblem;
import org.apache.commons.math3.fitting.WeightedObservedPoint;
import org.apache.commons.math3.linear.DiagonalMatrix;
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
class MyFunc implements ParametricUnivariateFunction {
public double value(double t, double... parameters) {
return parameters[0] * Math.pow(t, parameters[1]) * Math.exp(-parameters[2] * t);
}
// Jacobian matrix of the above. In this case, this is just an array of
// partial derivatives of the above function, with one element for each parameter.
public double[] gradient(double t, double... parameters) {
final double a = parameters[0];
final double b = parameters[1];
final double c = parameters[2];
// Jacobian Matrix Edit
// Using Derivative Structures...
// constructor takes 4 arguments - the number of parameters in your
// equation to be differentiated (3 in this case), the order of
// differentiation for the DerivativeStructure, the index of the
// parameter represented by the DS, and the value of the parameter itself
DerivativeStructure aDev = new DerivativeStructure(3, 1, 0, a);
DerivativeStructure bDev = new DerivativeStructure(3, 1, 1, b);
DerivativeStructure cDev = new DerivativeStructure(3, 1, 2, c);
// define the equation to be differentiated using another DerivativeStructure
DerivativeStructure y = aDev.multiply(DerivativeStructure.pow(t, bDev))
.multiply(cDev.negate().multiply(t).exp());
// then return the partial derivatives required
// notice the format, 3 arguments for the method since 3 parameters were
// specified first order derivative of the first parameter, then the second,
// then the third
return new double[] {
y.getPartialDerivative(1, 0, 0),
y.getPartialDerivative(0, 1, 0),
y.getPartialDerivative(0, 0, 1)
};
}
}
public class MyFuncFitter extends AbstractCurveFitter {
protected LeastSquaresProblem getProblem(Collection<WeightedObservedPoint> points) {
final int len = points.size();
final double[] target = new double[len];
final double[] weights = new double[len];
final double[] initialGuess = { 1.0, 1.0, 1.0 };
int i = 0;
for(WeightedObservedPoint point : points) {
target[i] = point.getY();
weights[i] = point.getWeight();
i += 1;
}
final AbstractCurveFitter.TheoreticalValuesFunction model = new
AbstractCurveFitter.TheoreticalValuesFunction(new MyFunc(), points);
return new LeastSquaresBuilder().
maxEvaluations(Integer.MAX_VALUE).
maxIterations(Integer.MAX_VALUE).
start(initialGuess).
target(target).
weight(new DiagonalMatrix(weights)).
model(model.getModelFunction(), model.getModelFunctionJacobian()).
build();
}
public static void main(String[] args) {
MyFuncFitter fitter = new MyFuncFitter();
ArrayList<WeightedObservedPoint> points = new ArrayList<WeightedObservedPoint>();
// Add points here; for instance,
WeightedObservedPoint point = new WeightedObservedPoint(1.0,
1.0,
1.0);
points.add(point);
final double coeffs[] = fitter.fit(points);
System.out.println(Arrays.toString(coeffs));
}
}
Và đó là nó.Tôi biết đó là một lớp khá phức tạp/khó hiểu, nhưng nó chắc chắn có ích khi bạn đối phó với các phương trình rất phức tạp, có thể gây rắc rối để có được các dẫn xuất từng phần bằng tay (điều này xảy ra với tôi cách đây không lâu), hoặc khi bạn muốn lấy được các dẫn xuất một phần nói đến thứ tự thứ hai hoặc thứ ba.
Trong trường hợp,, vân vân dẫn xuất bậc ba thứ hai, tất cả các bạn sẽ phải làm là:
// specify the required order as the second argument, say second order so 2
DerivativeStructure aDev = new DerivativeStructure(3, 2, 0, a);
DerivativeStructure bDev = new DerivativeStructure(3, 2, 1, b);
DerivativeStructure cDev = new DerivativeStructure(3, 2, 2, c);
// and then specify the order again here
y.getPartialDerivative(2, 0, 0),
y.getPartialDerivative(0, 2, 0),
y.getPartialDerivative(0, 0, 2)
Hy vọng rằng, điều này sẽ giúp ai đó lúc nào đó.
Tôi đang bối rối về việc thu thập điểm. Không có X_value cho họ? Tại sao mục tiêu chỉ chứa giá trị Y? –
Ngoài ra làm thế nào tôi có thể thêm ràng buộc vào các tham số (ví dụ tham số a trong f (x) = c * ln (a * x) cần phải luôn luôn dương)? –