source: src/main/java/agents/anac/y2019/harddealer/math3/fitting/AbstractCurveFitter.java

Last change on this file was 204, checked in by Katsuhide Fujita, 5 years ago

Fixed errors of ANAC2019 agents

  • Property svn:executable set to *
File size: 5.6 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17package agents.anac.y2019.harddealer.math3.fitting;
18
19import java.util.Collection;
20
21import agents.anac.y2019.harddealer.math3.analysis.MultivariateVectorFunction;
22import agents.anac.y2019.harddealer.math3.analysis.MultivariateMatrixFunction;
23import agents.anac.y2019.harddealer.math3.analysis.ParametricUnivariateFunction;
24import agents.anac.y2019.harddealer.math3.fitting.leastsquares.LeastSquaresOptimizer;
25import agents.anac.y2019.harddealer.math3.fitting.leastsquares.LeastSquaresProblem;
26import agents.anac.y2019.harddealer.math3.fitting.leastsquares.LevenbergMarquardtOptimizer;
27
28/**
29 * Base class that contains common code for fitting parametric univariate
30 * real functions <code>y = f(p<sub>i</sub>;x)</code>, where {@code x} is
31 * the independent variable and the <code>p<sub>i</sub></code> are the
32 * <em>parameters</em>.
33 * <br/>
34 * A fitter will find the optimal values of the parameters by
35 * <em>fitting</em> the curve so it remains very close to a set of
36 * {@code N} observed points <code>(x<sub>k</sub>, y<sub>k</sub>)</code>,
37 * {@code 0 <= k < N}.
38 * <br/>
39 * An algorithm usually performs the fit by finding the parameter
40 * values that minimizes the objective function
41 * <pre><code>
42 * &sum;y<sub>k</sub> - f(x<sub>k</sub>)<sup>2</sup>,
43 * </code></pre>
44 * which is actually a least-squares problem.
45 * This class contains boilerplate code for calling the
46 * {@link #fit(Collection)} method for obtaining the parameters.
47 * The problem setup, such as the choice of optimization algorithm
48 * for fitting a specific function is delegated to subclasses.
49 *
50 * @since 3.3
51 */
52public abstract class AbstractCurveFitter {
53 /**
54 * Fits a curve.
55 * This method computes the coefficients of the curve that best
56 * fit the sample of observed points.
57 *
58 * @param points Observations.
59 * @return the fitted parameters.
60 */
61 public double[] fit(Collection<WeightedObservedPoint> points) {
62 // Perform the fit.
63 return getOptimizer().optimize(getProblem(points)).getPoint().toArray();
64 }
65
66 /**
67 * Creates an optimizer set up to fit the appropriate curve.
68 * <p>
69 * The default implementation uses a {@link LevenbergMarquardtOptimizer
70 * Levenberg-Marquardt} optimizer.
71 * </p>
72 * @return the optimizer to use for fitting the curve to the
73 * given {@code points}.
74 */
75 protected LeastSquaresOptimizer getOptimizer() {
76 return new LevenbergMarquardtOptimizer();
77 }
78
79 /**
80 * Creates a least squares problem corresponding to the appropriate curve.
81 *
82 * @param points Sample points.
83 * @return the least squares problem to use for fitting the curve to the
84 * given {@code points}.
85 */
86 protected abstract LeastSquaresProblem getProblem(Collection<WeightedObservedPoint> points);
87
88 /**
89 * Vector function for computing function theoretical values.
90 */
91 protected static class TheoreticalValuesFunction {
92 /** Function to fit. */
93 private final ParametricUnivariateFunction f;
94 /** Observations. */
95 private final double[] points;
96
97 /**
98 * @param f function to fit.
99 * @param observations Observations.
100 */
101 public TheoreticalValuesFunction(final ParametricUnivariateFunction f,
102 final Collection<WeightedObservedPoint> observations) {
103 this.f = f;
104
105 final int len = observations.size();
106 this.points = new double[len];
107 int i = 0;
108 for (WeightedObservedPoint obs : observations) {
109 this.points[i++] = obs.getX();
110 }
111 }
112
113 /**
114 * @return the model function values.
115 */
116 public MultivariateVectorFunction getModelFunction() {
117 return new MultivariateVectorFunction() {
118 /** {@inheritDoc} */
119 public double[] value(double[] p) {
120 final int len = points.length;
121 final double[] values = new double[len];
122 for (int i = 0; i < len; i++) {
123 values[i] = f.value(points[i], p);
124 }
125
126 return values;
127 }
128 };
129 }
130
131 /**
132 * @return the model function Jacobian.
133 */
134 public MultivariateMatrixFunction getModelFunctionJacobian() {
135 return new MultivariateMatrixFunction() {
136 /** {@inheritDoc} */
137 public double[][] value(double[] p) {
138 final int len = points.length;
139 final double[][] jacobian = new double[len][];
140 for (int i = 0; i < len; i++) {
141 jacobian[i] = f.gradient(points[i], p);
142 }
143 return jacobian;
144 }
145 };
146 }
147 }
148}
Note: See TracBrowser for help on using the repository browser.