comparison libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/optimization/LeastSquaresConverter.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;<a name="line.18"></a>
22 <FONT color="green">019</FONT> <a name="line.19"></a>
23 <FONT color="green">020</FONT> import org.apache.commons.math.FunctionEvaluationException;<a name="line.20"></a>
24 <FONT color="green">021</FONT> import org.apache.commons.math.MathRuntimeException;<a name="line.21"></a>
25 <FONT color="green">022</FONT> import org.apache.commons.math.analysis.MultivariateRealFunction;<a name="line.22"></a>
26 <FONT color="green">023</FONT> import org.apache.commons.math.analysis.MultivariateVectorialFunction;<a name="line.23"></a>
27 <FONT color="green">024</FONT> import org.apache.commons.math.linear.RealMatrix;<a name="line.24"></a>
28 <FONT color="green">025</FONT> <a name="line.25"></a>
29 <FONT color="green">026</FONT> /** This class converts {@link MultivariateVectorialFunction vectorial<a name="line.26"></a>
30 <FONT color="green">027</FONT> * objective functions} to {@link MultivariateRealFunction scalar objective functions}<a name="line.27"></a>
31 <FONT color="green">028</FONT> * when the goal is to minimize them.<a name="line.28"></a>
32 <FONT color="green">029</FONT> * &lt;p&gt;<a name="line.29"></a>
33 <FONT color="green">030</FONT> * This class is mostly used when the vectorial objective function represents<a name="line.30"></a>
34 <FONT color="green">031</FONT> * a theoretical result computed from a point set applied to a model and<a name="line.31"></a>
35 <FONT color="green">032</FONT> * the models point must be adjusted to fit the theoretical result to some<a name="line.32"></a>
36 <FONT color="green">033</FONT> * reference observations. The observations may be obtained for example from<a name="line.33"></a>
37 <FONT color="green">034</FONT> * physical measurements whether the model is built from theoretical<a name="line.34"></a>
38 <FONT color="green">035</FONT> * considerations.<a name="line.35"></a>
39 <FONT color="green">036</FONT> * &lt;/p&gt;<a name="line.36"></a>
40 <FONT color="green">037</FONT> * &lt;p&gt;<a name="line.37"></a>
41 <FONT color="green">038</FONT> * This class computes a possibly weighted squared sum of the residuals, which is<a name="line.38"></a>
42 <FONT color="green">039</FONT> * a scalar value. The residuals are the difference between the theoretical model<a name="line.39"></a>
43 <FONT color="green">040</FONT> * (i.e. the output of the vectorial objective function) and the observations. The<a name="line.40"></a>
44 <FONT color="green">041</FONT> * class implements the {@link MultivariateRealFunction} interface and can therefore be<a name="line.41"></a>
45 <FONT color="green">042</FONT> * minimized by any optimizer supporting scalar objectives functions.This is one way<a name="line.42"></a>
46 <FONT color="green">043</FONT> * to perform a least square estimation. There are other ways to do this without using<a name="line.43"></a>
47 <FONT color="green">044</FONT> * this converter, as some optimization algorithms directly support vectorial objective<a name="line.44"></a>
48 <FONT color="green">045</FONT> * functions.<a name="line.45"></a>
49 <FONT color="green">046</FONT> * &lt;/p&gt;<a name="line.46"></a>
50 <FONT color="green">047</FONT> * &lt;p&gt;<a name="line.47"></a>
51 <FONT color="green">048</FONT> * This class support combination of residuals with or without weights and correlations.<a name="line.48"></a>
52 <FONT color="green">049</FONT> * &lt;/p&gt;<a name="line.49"></a>
53 <FONT color="green">050</FONT> *<a name="line.50"></a>
54 <FONT color="green">051</FONT> * @see MultivariateRealFunction<a name="line.51"></a>
55 <FONT color="green">052</FONT> * @see MultivariateVectorialFunction<a name="line.52"></a>
56 <FONT color="green">053</FONT> * @version $Revision: 811685 $ $Date: 2009-09-05 13:36:48 -0400 (Sat, 05 Sep 2009) $<a name="line.53"></a>
57 <FONT color="green">054</FONT> * @since 2.0<a name="line.54"></a>
58 <FONT color="green">055</FONT> */<a name="line.55"></a>
59 <FONT color="green">056</FONT> <a name="line.56"></a>
60 <FONT color="green">057</FONT> public class LeastSquaresConverter implements MultivariateRealFunction {<a name="line.57"></a>
61 <FONT color="green">058</FONT> <a name="line.58"></a>
62 <FONT color="green">059</FONT> /** Underlying vectorial function. */<a name="line.59"></a>
63 <FONT color="green">060</FONT> private final MultivariateVectorialFunction function;<a name="line.60"></a>
64 <FONT color="green">061</FONT> <a name="line.61"></a>
65 <FONT color="green">062</FONT> /** Observations to be compared to objective function to compute residuals. */<a name="line.62"></a>
66 <FONT color="green">063</FONT> private final double[] observations;<a name="line.63"></a>
67 <FONT color="green">064</FONT> <a name="line.64"></a>
68 <FONT color="green">065</FONT> /** Optional weights for the residuals. */<a name="line.65"></a>
69 <FONT color="green">066</FONT> private final double[] weights;<a name="line.66"></a>
70 <FONT color="green">067</FONT> <a name="line.67"></a>
71 <FONT color="green">068</FONT> /** Optional scaling matrix (weight and correlations) for the residuals. */<a name="line.68"></a>
72 <FONT color="green">069</FONT> private final RealMatrix scale;<a name="line.69"></a>
73 <FONT color="green">070</FONT> <a name="line.70"></a>
74 <FONT color="green">071</FONT> /** Build a simple converter for uncorrelated residuals with the same weight.<a name="line.71"></a>
75 <FONT color="green">072</FONT> * @param function vectorial residuals function to wrap<a name="line.72"></a>
76 <FONT color="green">073</FONT> * @param observations observations to be compared to objective function to compute residuals<a name="line.73"></a>
77 <FONT color="green">074</FONT> */<a name="line.74"></a>
78 <FONT color="green">075</FONT> public LeastSquaresConverter(final MultivariateVectorialFunction function,<a name="line.75"></a>
79 <FONT color="green">076</FONT> final double[] observations) {<a name="line.76"></a>
80 <FONT color="green">077</FONT> this.function = function;<a name="line.77"></a>
81 <FONT color="green">078</FONT> this.observations = observations.clone();<a name="line.78"></a>
82 <FONT color="green">079</FONT> this.weights = null;<a name="line.79"></a>
83 <FONT color="green">080</FONT> this.scale = null;<a name="line.80"></a>
84 <FONT color="green">081</FONT> }<a name="line.81"></a>
85 <FONT color="green">082</FONT> <a name="line.82"></a>
86 <FONT color="green">083</FONT> /** Build a simple converter for uncorrelated residuals with the specific weights.<a name="line.83"></a>
87 <FONT color="green">084</FONT> * &lt;p&gt;<a name="line.84"></a>
88 <FONT color="green">085</FONT> * The scalar objective function value is computed as:<a name="line.85"></a>
89 <FONT color="green">086</FONT> * &lt;pre&gt;<a name="line.86"></a>
90 <FONT color="green">087</FONT> * objective = &amp;sum;weight&lt;sub&gt;i&lt;/sub&gt;(observation&lt;sub&gt;i&lt;/sub&gt;-objective&lt;sub&gt;i&lt;/sub&gt;)&lt;sup&gt;2&lt;/sup&gt;<a name="line.87"></a>
91 <FONT color="green">088</FONT> * &lt;/pre&gt;<a name="line.88"></a>
92 <FONT color="green">089</FONT> * &lt;/p&gt;<a name="line.89"></a>
93 <FONT color="green">090</FONT> * &lt;p&gt;<a name="line.90"></a>
94 <FONT color="green">091</FONT> * Weights can be used for example to combine residuals with different standard<a name="line.91"></a>
95 <FONT color="green">092</FONT> * deviations. As an example, consider a residuals array in which even elements<a name="line.92"></a>
96 <FONT color="green">093</FONT> * are angular measurements in degrees with a 0.01&amp;deg; standard deviation and<a name="line.93"></a>
97 <FONT color="green">094</FONT> * odd elements are distance measurements in meters with a 15m standard deviation.<a name="line.94"></a>
98 <FONT color="green">095</FONT> * In this case, the weights array should be initialized with value<a name="line.95"></a>
99 <FONT color="green">096</FONT> * 1.0/(0.01&lt;sup&gt;2&lt;/sup&gt;) in the even elements and 1.0/(15.0&lt;sup&gt;2&lt;/sup&gt;) in the<a name="line.96"></a>
100 <FONT color="green">097</FONT> * odd elements (i.e. reciprocals of variances).<a name="line.97"></a>
101 <FONT color="green">098</FONT> * &lt;/p&gt;<a name="line.98"></a>
102 <FONT color="green">099</FONT> * &lt;p&gt;<a name="line.99"></a>
103 <FONT color="green">100</FONT> * The array computed by the objective function, the observations array and the<a name="line.100"></a>
104 <FONT color="green">101</FONT> * weights array must have consistent sizes or a {@link FunctionEvaluationException} will be<a name="line.101"></a>
105 <FONT color="green">102</FONT> * triggered while computing the scalar objective.<a name="line.102"></a>
106 <FONT color="green">103</FONT> * &lt;/p&gt;<a name="line.103"></a>
107 <FONT color="green">104</FONT> * @param function vectorial residuals function to wrap<a name="line.104"></a>
108 <FONT color="green">105</FONT> * @param observations observations to be compared to objective function to compute residuals<a name="line.105"></a>
109 <FONT color="green">106</FONT> * @param weights weights to apply to the residuals<a name="line.106"></a>
110 <FONT color="green">107</FONT> * @exception IllegalArgumentException if the observations vector and the weights<a name="line.107"></a>
111 <FONT color="green">108</FONT> * vector dimensions don't match (objective function dimension is checked only when<a name="line.108"></a>
112 <FONT color="green">109</FONT> * the {@link #value(double[])} method is called)<a name="line.109"></a>
113 <FONT color="green">110</FONT> */<a name="line.110"></a>
114 <FONT color="green">111</FONT> public LeastSquaresConverter(final MultivariateVectorialFunction function,<a name="line.111"></a>
115 <FONT color="green">112</FONT> final double[] observations, final double[] weights)<a name="line.112"></a>
116 <FONT color="green">113</FONT> throws IllegalArgumentException {<a name="line.113"></a>
117 <FONT color="green">114</FONT> if (observations.length != weights.length) {<a name="line.114"></a>
118 <FONT color="green">115</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.115"></a>
119 <FONT color="green">116</FONT> "dimension mismatch {0} != {1}",<a name="line.116"></a>
120 <FONT color="green">117</FONT> observations.length, weights.length);<a name="line.117"></a>
121 <FONT color="green">118</FONT> }<a name="line.118"></a>
122 <FONT color="green">119</FONT> this.function = function;<a name="line.119"></a>
123 <FONT color="green">120</FONT> this.observations = observations.clone();<a name="line.120"></a>
124 <FONT color="green">121</FONT> this.weights = weights.clone();<a name="line.121"></a>
125 <FONT color="green">122</FONT> this.scale = null;<a name="line.122"></a>
126 <FONT color="green">123</FONT> }<a name="line.123"></a>
127 <FONT color="green">124</FONT> <a name="line.124"></a>
128 <FONT color="green">125</FONT> /** Build a simple converter for correlated residuals with the specific weights.<a name="line.125"></a>
129 <FONT color="green">126</FONT> * &lt;p&gt;<a name="line.126"></a>
130 <FONT color="green">127</FONT> * The scalar objective function value is computed as:<a name="line.127"></a>
131 <FONT color="green">128</FONT> * &lt;pre&gt;<a name="line.128"></a>
132 <FONT color="green">129</FONT> * objective = y&lt;sup&gt;T&lt;/sup&gt;y with y = scale&amp;times;(observation-objective)<a name="line.129"></a>
133 <FONT color="green">130</FONT> * &lt;/pre&gt;<a name="line.130"></a>
134 <FONT color="green">131</FONT> * &lt;/p&gt;<a name="line.131"></a>
135 <FONT color="green">132</FONT> * &lt;p&gt;<a name="line.132"></a>
136 <FONT color="green">133</FONT> * The array computed by the objective function, the observations array and the<a name="line.133"></a>
137 <FONT color="green">134</FONT> * the scaling matrix must have consistent sizes or a {@link FunctionEvaluationException}<a name="line.134"></a>
138 <FONT color="green">135</FONT> * will be triggered while computing the scalar objective.<a name="line.135"></a>
139 <FONT color="green">136</FONT> * &lt;/p&gt;<a name="line.136"></a>
140 <FONT color="green">137</FONT> * @param function vectorial residuals function to wrap<a name="line.137"></a>
141 <FONT color="green">138</FONT> * @param observations observations to be compared to objective function to compute residuals<a name="line.138"></a>
142 <FONT color="green">139</FONT> * @param scale scaling matrix<a name="line.139"></a>
143 <FONT color="green">140</FONT> * @exception IllegalArgumentException if the observations vector and the scale<a name="line.140"></a>
144 <FONT color="green">141</FONT> * matrix dimensions don't match (objective function dimension is checked only when<a name="line.141"></a>
145 <FONT color="green">142</FONT> * the {@link #value(double[])} method is called)<a name="line.142"></a>
146 <FONT color="green">143</FONT> */<a name="line.143"></a>
147 <FONT color="green">144</FONT> public LeastSquaresConverter(final MultivariateVectorialFunction function,<a name="line.144"></a>
148 <FONT color="green">145</FONT> final double[] observations, final RealMatrix scale)<a name="line.145"></a>
149 <FONT color="green">146</FONT> throws IllegalArgumentException {<a name="line.146"></a>
150 <FONT color="green">147</FONT> if (observations.length != scale.getColumnDimension()) {<a name="line.147"></a>
151 <FONT color="green">148</FONT> throw MathRuntimeException.createIllegalArgumentException(<a name="line.148"></a>
152 <FONT color="green">149</FONT> "dimension mismatch {0} != {1}",<a name="line.149"></a>
153 <FONT color="green">150</FONT> observations.length, scale.getColumnDimension());<a name="line.150"></a>
154 <FONT color="green">151</FONT> }<a name="line.151"></a>
155 <FONT color="green">152</FONT> this.function = function;<a name="line.152"></a>
156 <FONT color="green">153</FONT> this.observations = observations.clone();<a name="line.153"></a>
157 <FONT color="green">154</FONT> this.weights = null;<a name="line.154"></a>
158 <FONT color="green">155</FONT> this.scale = scale.copy();<a name="line.155"></a>
159 <FONT color="green">156</FONT> }<a name="line.156"></a>
160 <FONT color="green">157</FONT> <a name="line.157"></a>
161 <FONT color="green">158</FONT> /** {@inheritDoc} */<a name="line.158"></a>
162 <FONT color="green">159</FONT> public double value(final double[] point) throws FunctionEvaluationException {<a name="line.159"></a>
163 <FONT color="green">160</FONT> <a name="line.160"></a>
164 <FONT color="green">161</FONT> // compute residuals<a name="line.161"></a>
165 <FONT color="green">162</FONT> final double[] residuals = function.value(point);<a name="line.162"></a>
166 <FONT color="green">163</FONT> if (residuals.length != observations.length) {<a name="line.163"></a>
167 <FONT color="green">164</FONT> throw new FunctionEvaluationException(point, "dimension mismatch {0} != {1}",<a name="line.164"></a>
168 <FONT color="green">165</FONT> residuals.length, observations.length);<a name="line.165"></a>
169 <FONT color="green">166</FONT> }<a name="line.166"></a>
170 <FONT color="green">167</FONT> for (int i = 0; i &lt; residuals.length; ++i) {<a name="line.167"></a>
171 <FONT color="green">168</FONT> residuals[i] -= observations[i];<a name="line.168"></a>
172 <FONT color="green">169</FONT> }<a name="line.169"></a>
173 <FONT color="green">170</FONT> <a name="line.170"></a>
174 <FONT color="green">171</FONT> // compute sum of squares<a name="line.171"></a>
175 <FONT color="green">172</FONT> double sumSquares = 0;<a name="line.172"></a>
176 <FONT color="green">173</FONT> if (weights != null) {<a name="line.173"></a>
177 <FONT color="green">174</FONT> for (int i = 0; i &lt; residuals.length; ++i) {<a name="line.174"></a>
178 <FONT color="green">175</FONT> final double ri = residuals[i];<a name="line.175"></a>
179 <FONT color="green">176</FONT> sumSquares += weights[i] * ri * ri;<a name="line.176"></a>
180 <FONT color="green">177</FONT> }<a name="line.177"></a>
181 <FONT color="green">178</FONT> } else if (scale != null) {<a name="line.178"></a>
182 <FONT color="green">179</FONT> for (final double yi : scale.operate(residuals)) {<a name="line.179"></a>
183 <FONT color="green">180</FONT> sumSquares += yi * yi;<a name="line.180"></a>
184 <FONT color="green">181</FONT> }<a name="line.181"></a>
185 <FONT color="green">182</FONT> } else {<a name="line.182"></a>
186 <FONT color="green">183</FONT> for (final double ri : residuals) {<a name="line.183"></a>
187 <FONT color="green">184</FONT> sumSquares += ri * ri;<a name="line.184"></a>
188 <FONT color="green">185</FONT> }<a name="line.185"></a>
189 <FONT color="green">186</FONT> }<a name="line.186"></a>
190 <FONT color="green">187</FONT> <a name="line.187"></a>
191 <FONT color="green">188</FONT> return sumSquares;<a name="line.188"></a>
192 <FONT color="green">189</FONT> <a name="line.189"></a>
193 <FONT color="green">190</FONT> }<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
197
198
199
200
201
202
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 </PRE>
257 </BODY>
258 </HTML>