comparison libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/fitting/CurveFitter.html @ 13:cbf34dd4d7e6

commons-math-2.1 added
author dwinter
date Tue, 04 Jan 2011 10:02:07 +0100
parents
children
comparison
equal deleted inserted replaced
12:970d26a94fb7 13:cbf34dd4d7e6
1 <HTML>
2 <BODY BGCOLOR="white">
3 <PRE>
4 <FONT color="green">001</FONT> /*<a name="line.1"></a>
5 <FONT color="green">002</FONT> * Licensed to the Apache Software Foundation (ASF) under one or more<a name="line.2"></a>
6 <FONT color="green">003</FONT> * contributor license agreements. See the NOTICE file distributed with<a name="line.3"></a>
7 <FONT color="green">004</FONT> * this work for additional information regarding copyright ownership.<a name="line.4"></a>
8 <FONT color="green">005</FONT> * The ASF licenses this file to You under the Apache License, Version 2.0<a name="line.5"></a>
9 <FONT color="green">006</FONT> * (the "License"); you may not use this file except in compliance with<a name="line.6"></a>
10 <FONT color="green">007</FONT> * the License. You may obtain a copy of the License at<a name="line.7"></a>
11 <FONT color="green">008</FONT> *<a name="line.8"></a>
12 <FONT color="green">009</FONT> * http://www.apache.org/licenses/LICENSE-2.0<a name="line.9"></a>
13 <FONT color="green">010</FONT> *<a name="line.10"></a>
14 <FONT color="green">011</FONT> * Unless required by applicable law or agreed to in writing, software<a name="line.11"></a>
15 <FONT color="green">012</FONT> * distributed under the License is distributed on an "AS IS" BASIS,<a name="line.12"></a>
16 <FONT color="green">013</FONT> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<a name="line.13"></a>
17 <FONT color="green">014</FONT> * See the License for the specific language governing permissions and<a name="line.14"></a>
18 <FONT color="green">015</FONT> * limitations under the License.<a name="line.15"></a>
19 <FONT color="green">016</FONT> */<a name="line.16"></a>
20 <FONT color="green">017</FONT> <a name="line.17"></a>
21 <FONT color="green">018</FONT> package org.apache.commons.math.optimization.fitting;<a name="line.18"></a>
22 <FONT color="green">019</FONT> <a name="line.19"></a>
23 <FONT color="green">020</FONT> import java.util.ArrayList;<a name="line.20"></a>
24 <FONT color="green">021</FONT> import java.util.List;<a name="line.21"></a>
25 <FONT color="green">022</FONT> <a name="line.22"></a>
26 <FONT color="green">023</FONT> import org.apache.commons.math.FunctionEvaluationException;<a name="line.23"></a>
27 <FONT color="green">024</FONT> import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction;<a name="line.24"></a>
28 <FONT color="green">025</FONT> import org.apache.commons.math.analysis.MultivariateMatrixFunction;<a name="line.25"></a>
29 <FONT color="green">026</FONT> import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;<a name="line.26"></a>
30 <FONT color="green">027</FONT> import org.apache.commons.math.optimization.OptimizationException;<a name="line.27"></a>
31 <FONT color="green">028</FONT> import org.apache.commons.math.optimization.VectorialPointValuePair;<a name="line.28"></a>
32 <FONT color="green">029</FONT> <a name="line.29"></a>
33 <FONT color="green">030</FONT> /** Fitter for parametric univariate real functions y = f(x).<a name="line.30"></a>
34 <FONT color="green">031</FONT> * &lt;p&gt;When a univariate real function y = f(x) does depend on some<a name="line.31"></a>
35 <FONT color="green">032</FONT> * unknown parameters p&lt;sub&gt;0&lt;/sub&gt;, p&lt;sub&gt;1&lt;/sub&gt; ... p&lt;sub&gt;n-1&lt;/sub&gt;,<a name="line.32"></a>
36 <FONT color="green">033</FONT> * this class can be used to find these parameters. It does this<a name="line.33"></a>
37 <FONT color="green">034</FONT> * by &lt;em&gt;fitting&lt;/em&gt; the curve so it remains very close to a set of<a name="line.34"></a>
38 <FONT color="green">035</FONT> * observed points (x&lt;sub&gt;0&lt;/sub&gt;, y&lt;sub&gt;0&lt;/sub&gt;), (x&lt;sub&gt;1&lt;/sub&gt;,<a name="line.35"></a>
39 <FONT color="green">036</FONT> * y&lt;sub&gt;1&lt;/sub&gt;) ... (x&lt;sub&gt;k-1&lt;/sub&gt;, y&lt;sub&gt;k-1&lt;/sub&gt;). This fitting<a name="line.36"></a>
40 <FONT color="green">037</FONT> * is done by finding the parameters values that minimizes the objective<a name="line.37"></a>
41 <FONT color="green">038</FONT> * function &amp;sum;(y&lt;sub&gt;i&lt;/sub&gt;-f(x&lt;sub&gt;i&lt;/sub&gt;))&lt;sup&gt;2&lt;/sup&gt;. This is<a name="line.38"></a>
42 <FONT color="green">039</FONT> * really a least squares problem.&lt;/p&gt;<a name="line.39"></a>
43 <FONT color="green">040</FONT> * @version $Revision: 927009 $ $Date: 2010-03-24 07:14:07 -0400 (Wed, 24 Mar 2010) $<a name="line.40"></a>
44 <FONT color="green">041</FONT> * @since 2.0<a name="line.41"></a>
45 <FONT color="green">042</FONT> */<a name="line.42"></a>
46 <FONT color="green">043</FONT> public class CurveFitter {<a name="line.43"></a>
47 <FONT color="green">044</FONT> <a name="line.44"></a>
48 <FONT color="green">045</FONT> /** Optimizer to use for the fitting. */<a name="line.45"></a>
49 <FONT color="green">046</FONT> private final DifferentiableMultivariateVectorialOptimizer optimizer;<a name="line.46"></a>
50 <FONT color="green">047</FONT> <a name="line.47"></a>
51 <FONT color="green">048</FONT> /** Observed points. */<a name="line.48"></a>
52 <FONT color="green">049</FONT> private final List&lt;WeightedObservedPoint&gt; observations;<a name="line.49"></a>
53 <FONT color="green">050</FONT> <a name="line.50"></a>
54 <FONT color="green">051</FONT> /** Simple constructor.<a name="line.51"></a>
55 <FONT color="green">052</FONT> * @param optimizer optimizer to use for the fitting<a name="line.52"></a>
56 <FONT color="green">053</FONT> */<a name="line.53"></a>
57 <FONT color="green">054</FONT> public CurveFitter(final DifferentiableMultivariateVectorialOptimizer optimizer) {<a name="line.54"></a>
58 <FONT color="green">055</FONT> this.optimizer = optimizer;<a name="line.55"></a>
59 <FONT color="green">056</FONT> observations = new ArrayList&lt;WeightedObservedPoint&gt;();<a name="line.56"></a>
60 <FONT color="green">057</FONT> }<a name="line.57"></a>
61 <FONT color="green">058</FONT> <a name="line.58"></a>
62 <FONT color="green">059</FONT> /** Add an observed (x,y) point to the sample with unit weight.<a name="line.59"></a>
63 <FONT color="green">060</FONT> * &lt;p&gt;Calling this method is equivalent to call<a name="line.60"></a>
64 <FONT color="green">061</FONT> * &lt;code&gt;addObservedPoint(1.0, x, y)&lt;/code&gt;.&lt;/p&gt;<a name="line.61"></a>
65 <FONT color="green">062</FONT> * @param x abscissa of the point<a name="line.62"></a>
66 <FONT color="green">063</FONT> * @param y observed value of the point at x, after fitting we should<a name="line.63"></a>
67 <FONT color="green">064</FONT> * have f(x) as close as possible to this value<a name="line.64"></a>
68 <FONT color="green">065</FONT> * @see #addObservedPoint(double, double, double)<a name="line.65"></a>
69 <FONT color="green">066</FONT> * @see #addObservedPoint(WeightedObservedPoint)<a name="line.66"></a>
70 <FONT color="green">067</FONT> * @see #getObservations()<a name="line.67"></a>
71 <FONT color="green">068</FONT> */<a name="line.68"></a>
72 <FONT color="green">069</FONT> public void addObservedPoint(double x, double y) {<a name="line.69"></a>
73 <FONT color="green">070</FONT> addObservedPoint(1.0, x, y);<a name="line.70"></a>
74 <FONT color="green">071</FONT> }<a name="line.71"></a>
75 <FONT color="green">072</FONT> <a name="line.72"></a>
76 <FONT color="green">073</FONT> /** Add an observed weighted (x,y) point to the sample.<a name="line.73"></a>
77 <FONT color="green">074</FONT> * @param weight weight of the observed point in the fit<a name="line.74"></a>
78 <FONT color="green">075</FONT> * @param x abscissa of the point<a name="line.75"></a>
79 <FONT color="green">076</FONT> * @param y observed value of the point at x, after fitting we should<a name="line.76"></a>
80 <FONT color="green">077</FONT> * have f(x) as close as possible to this value<a name="line.77"></a>
81 <FONT color="green">078</FONT> * @see #addObservedPoint(double, double)<a name="line.78"></a>
82 <FONT color="green">079</FONT> * @see #addObservedPoint(WeightedObservedPoint)<a name="line.79"></a>
83 <FONT color="green">080</FONT> * @see #getObservations()<a name="line.80"></a>
84 <FONT color="green">081</FONT> */<a name="line.81"></a>
85 <FONT color="green">082</FONT> public void addObservedPoint(double weight, double x, double y) {<a name="line.82"></a>
86 <FONT color="green">083</FONT> observations.add(new WeightedObservedPoint(weight, x, y));<a name="line.83"></a>
87 <FONT color="green">084</FONT> }<a name="line.84"></a>
88 <FONT color="green">085</FONT> <a name="line.85"></a>
89 <FONT color="green">086</FONT> /** Add an observed weighted (x,y) point to the sample.<a name="line.86"></a>
90 <FONT color="green">087</FONT> * @param observed observed point to add<a name="line.87"></a>
91 <FONT color="green">088</FONT> * @see #addObservedPoint(double, double)<a name="line.88"></a>
92 <FONT color="green">089</FONT> * @see #addObservedPoint(double, double, double)<a name="line.89"></a>
93 <FONT color="green">090</FONT> * @see #getObservations()<a name="line.90"></a>
94 <FONT color="green">091</FONT> */<a name="line.91"></a>
95 <FONT color="green">092</FONT> public void addObservedPoint(WeightedObservedPoint observed) {<a name="line.92"></a>
96 <FONT color="green">093</FONT> observations.add(observed);<a name="line.93"></a>
97 <FONT color="green">094</FONT> }<a name="line.94"></a>
98 <FONT color="green">095</FONT> <a name="line.95"></a>
99 <FONT color="green">096</FONT> /** Get the observed points.<a name="line.96"></a>
100 <FONT color="green">097</FONT> * @return observed points<a name="line.97"></a>
101 <FONT color="green">098</FONT> * @see #addObservedPoint(double, double)<a name="line.98"></a>
102 <FONT color="green">099</FONT> * @see #addObservedPoint(double, double, double)<a name="line.99"></a>
103 <FONT color="green">100</FONT> * @see #addObservedPoint(WeightedObservedPoint)<a name="line.100"></a>
104 <FONT color="green">101</FONT> */<a name="line.101"></a>
105 <FONT color="green">102</FONT> public WeightedObservedPoint[] getObservations() {<a name="line.102"></a>
106 <FONT color="green">103</FONT> return observations.toArray(new WeightedObservedPoint[observations.size()]);<a name="line.103"></a>
107 <FONT color="green">104</FONT> }<a name="line.104"></a>
108 <FONT color="green">105</FONT> <a name="line.105"></a>
109 <FONT color="green">106</FONT> /**<a name="line.106"></a>
110 <FONT color="green">107</FONT> * Remove all observations.<a name="line.107"></a>
111 <FONT color="green">108</FONT> */<a name="line.108"></a>
112 <FONT color="green">109</FONT> public void clearObservations() {<a name="line.109"></a>
113 <FONT color="green">110</FONT> observations.clear();<a name="line.110"></a>
114 <FONT color="green">111</FONT> }<a name="line.111"></a>
115 <FONT color="green">112</FONT> <a name="line.112"></a>
116 <FONT color="green">113</FONT> /** Fit a curve.<a name="line.113"></a>
117 <FONT color="green">114</FONT> * &lt;p&gt;This method compute the coefficients of the curve that best<a name="line.114"></a>
118 <FONT color="green">115</FONT> * fit the sample of observed points previously given through calls<a name="line.115"></a>
119 <FONT color="green">116</FONT> * to the {@link #addObservedPoint(WeightedObservedPoint)<a name="line.116"></a>
120 <FONT color="green">117</FONT> * addObservedPoint} method.&lt;/p&gt;<a name="line.117"></a>
121 <FONT color="green">118</FONT> * @param f parametric function to fit<a name="line.118"></a>
122 <FONT color="green">119</FONT> * @param initialGuess first guess of the function parameters<a name="line.119"></a>
123 <FONT color="green">120</FONT> * @return fitted parameters<a name="line.120"></a>
124 <FONT color="green">121</FONT> * @exception FunctionEvaluationException if the objective function throws one during<a name="line.121"></a>
125 <FONT color="green">122</FONT> * the search<a name="line.122"></a>
126 <FONT color="green">123</FONT> * @exception OptimizationException if the algorithm failed to converge<a name="line.123"></a>
127 <FONT color="green">124</FONT> * @exception IllegalArgumentException if the start point dimension is wrong<a name="line.124"></a>
128 <FONT color="green">125</FONT> */<a name="line.125"></a>
129 <FONT color="green">126</FONT> public double[] fit(final ParametricRealFunction f,<a name="line.126"></a>
130 <FONT color="green">127</FONT> final double[] initialGuess)<a name="line.127"></a>
131 <FONT color="green">128</FONT> throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {<a name="line.128"></a>
132 <FONT color="green">129</FONT> <a name="line.129"></a>
133 <FONT color="green">130</FONT> // prepare least squares problem<a name="line.130"></a>
134 <FONT color="green">131</FONT> double[] target = new double[observations.size()];<a name="line.131"></a>
135 <FONT color="green">132</FONT> double[] weights = new double[observations.size()];<a name="line.132"></a>
136 <FONT color="green">133</FONT> int i = 0;<a name="line.133"></a>
137 <FONT color="green">134</FONT> for (WeightedObservedPoint point : observations) {<a name="line.134"></a>
138 <FONT color="green">135</FONT> target[i] = point.getY();<a name="line.135"></a>
139 <FONT color="green">136</FONT> weights[i] = point.getWeight();<a name="line.136"></a>
140 <FONT color="green">137</FONT> ++i;<a name="line.137"></a>
141 <FONT color="green">138</FONT> }<a name="line.138"></a>
142 <FONT color="green">139</FONT> <a name="line.139"></a>
143 <FONT color="green">140</FONT> // perform the fit<a name="line.140"></a>
144 <FONT color="green">141</FONT> VectorialPointValuePair optimum =<a name="line.141"></a>
145 <FONT color="green">142</FONT> optimizer.optimize(new TheoreticalValuesFunction(f), target, weights, initialGuess);<a name="line.142"></a>
146 <FONT color="green">143</FONT> <a name="line.143"></a>
147 <FONT color="green">144</FONT> // extract the coefficients<a name="line.144"></a>
148 <FONT color="green">145</FONT> return optimum.getPointRef();<a name="line.145"></a>
149 <FONT color="green">146</FONT> <a name="line.146"></a>
150 <FONT color="green">147</FONT> }<a name="line.147"></a>
151 <FONT color="green">148</FONT> <a name="line.148"></a>
152 <FONT color="green">149</FONT> /** Vectorial function computing function theoretical values. */<a name="line.149"></a>
153 <FONT color="green">150</FONT> private class TheoreticalValuesFunction<a name="line.150"></a>
154 <FONT color="green">151</FONT> implements DifferentiableMultivariateVectorialFunction {<a name="line.151"></a>
155 <FONT color="green">152</FONT> <a name="line.152"></a>
156 <FONT color="green">153</FONT> /** Function to fit. */<a name="line.153"></a>
157 <FONT color="green">154</FONT> private final ParametricRealFunction f;<a name="line.154"></a>
158 <FONT color="green">155</FONT> <a name="line.155"></a>
159 <FONT color="green">156</FONT> /** Simple constructor.<a name="line.156"></a>
160 <FONT color="green">157</FONT> * @param f function to fit.<a name="line.157"></a>
161 <FONT color="green">158</FONT> */<a name="line.158"></a>
162 <FONT color="green">159</FONT> public TheoreticalValuesFunction(final ParametricRealFunction f) {<a name="line.159"></a>
163 <FONT color="green">160</FONT> this.f = f;<a name="line.160"></a>
164 <FONT color="green">161</FONT> }<a name="line.161"></a>
165 <FONT color="green">162</FONT> <a name="line.162"></a>
166 <FONT color="green">163</FONT> /** {@inheritDoc} */<a name="line.163"></a>
167 <FONT color="green">164</FONT> public MultivariateMatrixFunction jacobian() {<a name="line.164"></a>
168 <FONT color="green">165</FONT> return new MultivariateMatrixFunction() {<a name="line.165"></a>
169 <FONT color="green">166</FONT> public double[][] value(double[] point)<a name="line.166"></a>
170 <FONT color="green">167</FONT> throws FunctionEvaluationException, IllegalArgumentException {<a name="line.167"></a>
171 <FONT color="green">168</FONT> <a name="line.168"></a>
172 <FONT color="green">169</FONT> final double[][] jacobian = new double[observations.size()][];<a name="line.169"></a>
173 <FONT color="green">170</FONT> <a name="line.170"></a>
174 <FONT color="green">171</FONT> int i = 0;<a name="line.171"></a>
175 <FONT color="green">172</FONT> for (WeightedObservedPoint observed : observations) {<a name="line.172"></a>
176 <FONT color="green">173</FONT> jacobian[i++] = f.gradient(observed.getX(), point);<a name="line.173"></a>
177 <FONT color="green">174</FONT> }<a name="line.174"></a>
178 <FONT color="green">175</FONT> <a name="line.175"></a>
179 <FONT color="green">176</FONT> return jacobian;<a name="line.176"></a>
180 <FONT color="green">177</FONT> <a name="line.177"></a>
181 <FONT color="green">178</FONT> }<a name="line.178"></a>
182 <FONT color="green">179</FONT> };<a name="line.179"></a>
183 <FONT color="green">180</FONT> }<a name="line.180"></a>
184 <FONT color="green">181</FONT> <a name="line.181"></a>
185 <FONT color="green">182</FONT> /** {@inheritDoc} */<a name="line.182"></a>
186 <FONT color="green">183</FONT> public double[] value(double[] point)<a name="line.183"></a>
187 <FONT color="green">184</FONT> throws FunctionEvaluationException, IllegalArgumentException {<a name="line.184"></a>
188 <FONT color="green">185</FONT> <a name="line.185"></a>
189 <FONT color="green">186</FONT> // compute the residuals<a name="line.186"></a>
190 <FONT color="green">187</FONT> final double[] values = new double[observations.size()];<a name="line.187"></a>
191 <FONT color="green">188</FONT> int i = 0;<a name="line.188"></a>
192 <FONT color="green">189</FONT> for (WeightedObservedPoint observed : observations) {<a name="line.189"></a>
193 <FONT color="green">190</FONT> values[i++] = f.value(observed.getX(), point);<a name="line.190"></a>
194 <FONT color="green">191</FONT> }<a name="line.191"></a>
195 <FONT color="green">192</FONT> <a name="line.192"></a>
196 <FONT color="green">193</FONT> return values;<a name="line.193"></a>
197 <FONT color="green">194</FONT> <a name="line.194"></a>
198 <FONT color="green">195</FONT> }<a name="line.195"></a>
199 <FONT color="green">196</FONT> <a name="line.196"></a>
200 <FONT color="green">197</FONT> }<a name="line.197"></a>
201 <FONT color="green">198</FONT> <a name="line.198"></a>
202 <FONT color="green">199</FONT> }<a name="line.199"></a>
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263 </PRE>
264 </BODY>
265 </HTML>