comparison libs/commons-math-2.1/docs/apidocs/src-html/org/apache/commons/math/estimation/LevenbergMarquardtEstimator.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> package org.apache.commons.math.estimation;<a name="line.17"></a>
21 <FONT color="green">018</FONT> <a name="line.18"></a>
22 <FONT color="green">019</FONT> import java.io.Serializable;<a name="line.19"></a>
23 <FONT color="green">020</FONT> import java.util.Arrays;<a name="line.20"></a>
24 <FONT color="green">021</FONT> <a name="line.21"></a>
25 <FONT color="green">022</FONT> <a name="line.22"></a>
26 <FONT color="green">023</FONT> /**<a name="line.23"></a>
27 <FONT color="green">024</FONT> * This class solves a least squares problem.<a name="line.24"></a>
28 <FONT color="green">025</FONT> *<a name="line.25"></a>
29 <FONT color="green">026</FONT> * &lt;p&gt;This implementation &lt;em&gt;should&lt;/em&gt; work even for over-determined systems<a name="line.26"></a>
30 <FONT color="green">027</FONT> * (i.e. systems having more variables than equations). Over-determined systems<a name="line.27"></a>
31 <FONT color="green">028</FONT> * are solved by ignoring the variables which have the smallest impact according<a name="line.28"></a>
32 <FONT color="green">029</FONT> * to their jacobian column norm. Only the rank of the matrix and some loop bounds<a name="line.29"></a>
33 <FONT color="green">030</FONT> * are changed to implement this.&lt;/p&gt;<a name="line.30"></a>
34 <FONT color="green">031</FONT> *<a name="line.31"></a>
35 <FONT color="green">032</FONT> * &lt;p&gt;The resolution engine is a simple translation of the MINPACK &lt;a<a name="line.32"></a>
36 <FONT color="green">033</FONT> * href="http://www.netlib.org/minpack/lmder.f"&gt;lmder&lt;/a&gt; routine with minor<a name="line.33"></a>
37 <FONT color="green">034</FONT> * changes. The changes include the over-determined resolution and the Q.R.<a name="line.34"></a>
38 <FONT color="green">035</FONT> * decomposition which has been rewritten following the algorithm described in the<a name="line.35"></a>
39 <FONT color="green">036</FONT> * P. Lascaux and R. Theodor book &lt;i&gt;Analyse num&amp;eacute;rique matricielle<a name="line.36"></a>
40 <FONT color="green">037</FONT> * appliqu&amp;eacute;e &amp;agrave; l'art de l'ing&amp;eacute;nieur&lt;/i&gt;, Masson 1986.&lt;/p&gt;<a name="line.37"></a>
41 <FONT color="green">038</FONT> * &lt;p&gt;The authors of the original fortran version are:<a name="line.38"></a>
42 <FONT color="green">039</FONT> * &lt;ul&gt;<a name="line.39"></a>
43 <FONT color="green">040</FONT> * &lt;li&gt;Argonne National Laboratory. MINPACK project. March 1980&lt;/li&gt;<a name="line.40"></a>
44 <FONT color="green">041</FONT> * &lt;li&gt;Burton S. Garbow&lt;/li&gt;<a name="line.41"></a>
45 <FONT color="green">042</FONT> * &lt;li&gt;Kenneth E. Hillstrom&lt;/li&gt;<a name="line.42"></a>
46 <FONT color="green">043</FONT> * &lt;li&gt;Jorge J. More&lt;/li&gt;<a name="line.43"></a>
47 <FONT color="green">044</FONT> * &lt;/ul&gt;<a name="line.44"></a>
48 <FONT color="green">045</FONT> * The redistribution policy for MINPACK is available &lt;a<a name="line.45"></a>
49 <FONT color="green">046</FONT> * href="http://www.netlib.org/minpack/disclaimer"&gt;here&lt;/a&gt;, for convenience, it<a name="line.46"></a>
50 <FONT color="green">047</FONT> * is reproduced below.&lt;/p&gt;<a name="line.47"></a>
51 <FONT color="green">048</FONT> *<a name="line.48"></a>
52 <FONT color="green">049</FONT> * &lt;table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0"&gt;<a name="line.49"></a>
53 <FONT color="green">050</FONT> * &lt;tr&gt;&lt;td&gt;<a name="line.50"></a>
54 <FONT color="green">051</FONT> * Minpack Copyright Notice (1999) University of Chicago.<a name="line.51"></a>
55 <FONT color="green">052</FONT> * All rights reserved<a name="line.52"></a>
56 <FONT color="green">053</FONT> * &lt;/td&gt;&lt;/tr&gt;<a name="line.53"></a>
57 <FONT color="green">054</FONT> * &lt;tr&gt;&lt;td&gt;<a name="line.54"></a>
58 <FONT color="green">055</FONT> * Redistribution and use in source and binary forms, with or without<a name="line.55"></a>
59 <FONT color="green">056</FONT> * modification, are permitted provided that the following conditions<a name="line.56"></a>
60 <FONT color="green">057</FONT> * are met:<a name="line.57"></a>
61 <FONT color="green">058</FONT> * &lt;ol&gt;<a name="line.58"></a>
62 <FONT color="green">059</FONT> * &lt;li&gt;Redistributions of source code must retain the above copyright<a name="line.59"></a>
63 <FONT color="green">060</FONT> * notice, this list of conditions and the following disclaimer.&lt;/li&gt;<a name="line.60"></a>
64 <FONT color="green">061</FONT> * &lt;li&gt;Redistributions in binary form must reproduce the above<a name="line.61"></a>
65 <FONT color="green">062</FONT> * copyright notice, this list of conditions and the following<a name="line.62"></a>
66 <FONT color="green">063</FONT> * disclaimer in the documentation and/or other materials provided<a name="line.63"></a>
67 <FONT color="green">064</FONT> * with the distribution.&lt;/li&gt;<a name="line.64"></a>
68 <FONT color="green">065</FONT> * &lt;li&gt;The end-user documentation included with the redistribution, if any,<a name="line.65"></a>
69 <FONT color="green">066</FONT> * must include the following acknowledgment:<a name="line.66"></a>
70 <FONT color="green">067</FONT> * &lt;code&gt;This product includes software developed by the University of<a name="line.67"></a>
71 <FONT color="green">068</FONT> * Chicago, as Operator of Argonne National Laboratory.&lt;/code&gt;<a name="line.68"></a>
72 <FONT color="green">069</FONT> * Alternately, this acknowledgment may appear in the software itself,<a name="line.69"></a>
73 <FONT color="green">070</FONT> * if and wherever such third-party acknowledgments normally appear.&lt;/li&gt;<a name="line.70"></a>
74 <FONT color="green">071</FONT> * &lt;li&gt;&lt;strong&gt;WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS"<a name="line.71"></a>
75 <FONT color="green">072</FONT> * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE<a name="line.72"></a>
76 <FONT color="green">073</FONT> * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND<a name="line.73"></a>
77 <FONT color="green">074</FONT> * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR<a name="line.74"></a>
78 <FONT color="green">075</FONT> * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES<a name="line.75"></a>
79 <FONT color="green">076</FONT> * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE<a name="line.76"></a>
80 <FONT color="green">077</FONT> * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY<a name="line.77"></a>
81 <FONT color="green">078</FONT> * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR<a name="line.78"></a>
82 <FONT color="green">079</FONT> * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF<a name="line.79"></a>
83 <FONT color="green">080</FONT> * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4)<a name="line.80"></a>
84 <FONT color="green">081</FONT> * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION<a name="line.81"></a>
85 <FONT color="green">082</FONT> * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL<a name="line.82"></a>
86 <FONT color="green">083</FONT> * BE CORRECTED.&lt;/strong&gt;&lt;/li&gt;<a name="line.83"></a>
87 <FONT color="green">084</FONT> * &lt;li&gt;&lt;strong&gt;LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT<a name="line.84"></a>
88 <FONT color="green">085</FONT> * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF<a name="line.85"></a>
89 <FONT color="green">086</FONT> * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT,<a name="line.86"></a>
90 <FONT color="green">087</FONT> * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF<a name="line.87"></a>
91 <FONT color="green">088</FONT> * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF<a name="line.88"></a>
92 <FONT color="green">089</FONT> * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER<a name="line.89"></a>
93 <FONT color="green">090</FONT> * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT<a name="line.90"></a>
94 <FONT color="green">091</FONT> * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,<a name="line.91"></a>
95 <FONT color="green">092</FONT> * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE<a name="line.92"></a>
96 <FONT color="green">093</FONT> * POSSIBILITY OF SUCH LOSS OR DAMAGES.&lt;/strong&gt;&lt;/li&gt;<a name="line.93"></a>
97 <FONT color="green">094</FONT> * &lt;ol&gt;&lt;/td&gt;&lt;/tr&gt;<a name="line.94"></a>
98 <FONT color="green">095</FONT> * &lt;/table&gt;<a name="line.95"></a>
99 <FONT color="green">096</FONT> <a name="line.96"></a>
100 <FONT color="green">097</FONT> * @version $Revision: 825919 $ $Date: 2009-10-16 10:51:55 -0400 (Fri, 16 Oct 2009) $<a name="line.97"></a>
101 <FONT color="green">098</FONT> * @since 1.2<a name="line.98"></a>
102 <FONT color="green">099</FONT> * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has<a name="line.99"></a>
103 <FONT color="green">100</FONT> * been deprecated and replaced by package org.apache.commons.math.optimization.general<a name="line.100"></a>
104 <FONT color="green">101</FONT> *<a name="line.101"></a>
105 <FONT color="green">102</FONT> */<a name="line.102"></a>
106 <FONT color="green">103</FONT> @Deprecated<a name="line.103"></a>
107 <FONT color="green">104</FONT> public class LevenbergMarquardtEstimator extends AbstractEstimator implements Serializable {<a name="line.104"></a>
108 <FONT color="green">105</FONT> <a name="line.105"></a>
109 <FONT color="green">106</FONT> /** Serializable version identifier */<a name="line.106"></a>
110 <FONT color="green">107</FONT> private static final long serialVersionUID = -5705952631533171019L;<a name="line.107"></a>
111 <FONT color="green">108</FONT> <a name="line.108"></a>
112 <FONT color="green">109</FONT> /** Number of solved variables. */<a name="line.109"></a>
113 <FONT color="green">110</FONT> private int solvedCols;<a name="line.110"></a>
114 <FONT color="green">111</FONT> <a name="line.111"></a>
115 <FONT color="green">112</FONT> /** Diagonal elements of the R matrix in the Q.R. decomposition. */<a name="line.112"></a>
116 <FONT color="green">113</FONT> private double[] diagR;<a name="line.113"></a>
117 <FONT color="green">114</FONT> <a name="line.114"></a>
118 <FONT color="green">115</FONT> /** Norms of the columns of the jacobian matrix. */<a name="line.115"></a>
119 <FONT color="green">116</FONT> private double[] jacNorm;<a name="line.116"></a>
120 <FONT color="green">117</FONT> <a name="line.117"></a>
121 <FONT color="green">118</FONT> /** Coefficients of the Householder transforms vectors. */<a name="line.118"></a>
122 <FONT color="green">119</FONT> private double[] beta;<a name="line.119"></a>
123 <FONT color="green">120</FONT> <a name="line.120"></a>
124 <FONT color="green">121</FONT> /** Columns permutation array. */<a name="line.121"></a>
125 <FONT color="green">122</FONT> private int[] permutation;<a name="line.122"></a>
126 <FONT color="green">123</FONT> <a name="line.123"></a>
127 <FONT color="green">124</FONT> /** Rank of the jacobian matrix. */<a name="line.124"></a>
128 <FONT color="green">125</FONT> private int rank;<a name="line.125"></a>
129 <FONT color="green">126</FONT> <a name="line.126"></a>
130 <FONT color="green">127</FONT> /** Levenberg-Marquardt parameter. */<a name="line.127"></a>
131 <FONT color="green">128</FONT> private double lmPar;<a name="line.128"></a>
132 <FONT color="green">129</FONT> <a name="line.129"></a>
133 <FONT color="green">130</FONT> /** Parameters evolution direction associated with lmPar. */<a name="line.130"></a>
134 <FONT color="green">131</FONT> private double[] lmDir;<a name="line.131"></a>
135 <FONT color="green">132</FONT> <a name="line.132"></a>
136 <FONT color="green">133</FONT> /** Positive input variable used in determining the initial step bound. */<a name="line.133"></a>
137 <FONT color="green">134</FONT> private double initialStepBoundFactor;<a name="line.134"></a>
138 <FONT color="green">135</FONT> <a name="line.135"></a>
139 <FONT color="green">136</FONT> /** Desired relative error in the sum of squares. */<a name="line.136"></a>
140 <FONT color="green">137</FONT> private double costRelativeTolerance;<a name="line.137"></a>
141 <FONT color="green">138</FONT> <a name="line.138"></a>
142 <FONT color="green">139</FONT> /** Desired relative error in the approximate solution parameters. */<a name="line.139"></a>
143 <FONT color="green">140</FONT> private double parRelativeTolerance;<a name="line.140"></a>
144 <FONT color="green">141</FONT> <a name="line.141"></a>
145 <FONT color="green">142</FONT> /** Desired max cosine on the orthogonality between the function vector<a name="line.142"></a>
146 <FONT color="green">143</FONT> * and the columns of the jacobian. */<a name="line.143"></a>
147 <FONT color="green">144</FONT> private double orthoTolerance;<a name="line.144"></a>
148 <FONT color="green">145</FONT> <a name="line.145"></a>
149 <FONT color="green">146</FONT> /**<a name="line.146"></a>
150 <FONT color="green">147</FONT> * Build an estimator for least squares problems.<a name="line.147"></a>
151 <FONT color="green">148</FONT> * &lt;p&gt;The default values for the algorithm settings are:<a name="line.148"></a>
152 <FONT color="green">149</FONT> * &lt;ul&gt;<a name="line.149"></a>
153 <FONT color="green">150</FONT> * &lt;li&gt;{@link #setInitialStepBoundFactor initial step bound factor}: 100.0&lt;/li&gt;<a name="line.150"></a>
154 <FONT color="green">151</FONT> * &lt;li&gt;{@link #setMaxCostEval maximal cost evaluations}: 1000&lt;/li&gt;<a name="line.151"></a>
155 <FONT color="green">152</FONT> * &lt;li&gt;{@link #setCostRelativeTolerance cost relative tolerance}: 1.0e-10&lt;/li&gt;<a name="line.152"></a>
156 <FONT color="green">153</FONT> * &lt;li&gt;{@link #setParRelativeTolerance parameters relative tolerance}: 1.0e-10&lt;/li&gt;<a name="line.153"></a>
157 <FONT color="green">154</FONT> * &lt;li&gt;{@link #setOrthoTolerance orthogonality tolerance}: 1.0e-10&lt;/li&gt;<a name="line.154"></a>
158 <FONT color="green">155</FONT> * &lt;/ul&gt;<a name="line.155"></a>
159 <FONT color="green">156</FONT> * &lt;/p&gt;<a name="line.156"></a>
160 <FONT color="green">157</FONT> */<a name="line.157"></a>
161 <FONT color="green">158</FONT> public LevenbergMarquardtEstimator() {<a name="line.158"></a>
162 <FONT color="green">159</FONT> <a name="line.159"></a>
163 <FONT color="green">160</FONT> // set up the superclass with a default max cost evaluations setting<a name="line.160"></a>
164 <FONT color="green">161</FONT> setMaxCostEval(1000);<a name="line.161"></a>
165 <FONT color="green">162</FONT> <a name="line.162"></a>
166 <FONT color="green">163</FONT> // default values for the tuning parameters<a name="line.163"></a>
167 <FONT color="green">164</FONT> setInitialStepBoundFactor(100.0);<a name="line.164"></a>
168 <FONT color="green">165</FONT> setCostRelativeTolerance(1.0e-10);<a name="line.165"></a>
169 <FONT color="green">166</FONT> setParRelativeTolerance(1.0e-10);<a name="line.166"></a>
170 <FONT color="green">167</FONT> setOrthoTolerance(1.0e-10);<a name="line.167"></a>
171 <FONT color="green">168</FONT> <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> /**<a name="line.171"></a>
175 <FONT color="green">172</FONT> * Set the positive input variable used in determining the initial step bound.<a name="line.172"></a>
176 <FONT color="green">173</FONT> * This bound is set to the product of initialStepBoundFactor and the euclidean norm of diag*x if nonzero,<a name="line.173"></a>
177 <FONT color="green">174</FONT> * or else to initialStepBoundFactor itself. In most cases factor should lie<a name="line.174"></a>
178 <FONT color="green">175</FONT> * in the interval (0.1, 100.0). 100.0 is a generally recommended value<a name="line.175"></a>
179 <FONT color="green">176</FONT> *<a name="line.176"></a>
180 <FONT color="green">177</FONT> * @param initialStepBoundFactor initial step bound factor<a name="line.177"></a>
181 <FONT color="green">178</FONT> * @see #estimate<a name="line.178"></a>
182 <FONT color="green">179</FONT> */<a name="line.179"></a>
183 <FONT color="green">180</FONT> public void setInitialStepBoundFactor(double initialStepBoundFactor) {<a name="line.180"></a>
184 <FONT color="green">181</FONT> this.initialStepBoundFactor = initialStepBoundFactor;<a name="line.181"></a>
185 <FONT color="green">182</FONT> }<a name="line.182"></a>
186 <FONT color="green">183</FONT> <a name="line.183"></a>
187 <FONT color="green">184</FONT> /**<a name="line.184"></a>
188 <FONT color="green">185</FONT> * Set the desired relative error in the sum of squares.<a name="line.185"></a>
189 <FONT color="green">186</FONT> *<a name="line.186"></a>
190 <FONT color="green">187</FONT> * @param costRelativeTolerance desired relative error in the sum of squares<a name="line.187"></a>
191 <FONT color="green">188</FONT> * @see #estimate<a name="line.188"></a>
192 <FONT color="green">189</FONT> */<a name="line.189"></a>
193 <FONT color="green">190</FONT> public void setCostRelativeTolerance(double costRelativeTolerance) {<a name="line.190"></a>
194 <FONT color="green">191</FONT> this.costRelativeTolerance = costRelativeTolerance;<a name="line.191"></a>
195 <FONT color="green">192</FONT> }<a name="line.192"></a>
196 <FONT color="green">193</FONT> <a name="line.193"></a>
197 <FONT color="green">194</FONT> /**<a name="line.194"></a>
198 <FONT color="green">195</FONT> * Set the desired relative error in the approximate solution parameters.<a name="line.195"></a>
199 <FONT color="green">196</FONT> *<a name="line.196"></a>
200 <FONT color="green">197</FONT> * @param parRelativeTolerance desired relative error<a name="line.197"></a>
201 <FONT color="green">198</FONT> * in the approximate solution parameters<a name="line.198"></a>
202 <FONT color="green">199</FONT> * @see #estimate<a name="line.199"></a>
203 <FONT color="green">200</FONT> */<a name="line.200"></a>
204 <FONT color="green">201</FONT> public void setParRelativeTolerance(double parRelativeTolerance) {<a name="line.201"></a>
205 <FONT color="green">202</FONT> this.parRelativeTolerance = parRelativeTolerance;<a name="line.202"></a>
206 <FONT color="green">203</FONT> }<a name="line.203"></a>
207 <FONT color="green">204</FONT> <a name="line.204"></a>
208 <FONT color="green">205</FONT> /**<a name="line.205"></a>
209 <FONT color="green">206</FONT> * Set the desired max cosine on the orthogonality.<a name="line.206"></a>
210 <FONT color="green">207</FONT> *<a name="line.207"></a>
211 <FONT color="green">208</FONT> * @param orthoTolerance desired max cosine on the orthogonality<a name="line.208"></a>
212 <FONT color="green">209</FONT> * between the function vector and the columns of the jacobian<a name="line.209"></a>
213 <FONT color="green">210</FONT> * @see #estimate<a name="line.210"></a>
214 <FONT color="green">211</FONT> */<a name="line.211"></a>
215 <FONT color="green">212</FONT> public void setOrthoTolerance(double orthoTolerance) {<a name="line.212"></a>
216 <FONT color="green">213</FONT> this.orthoTolerance = orthoTolerance;<a name="line.213"></a>
217 <FONT color="green">214</FONT> }<a name="line.214"></a>
218 <FONT color="green">215</FONT> <a name="line.215"></a>
219 <FONT color="green">216</FONT> /**<a name="line.216"></a>
220 <FONT color="green">217</FONT> * Solve an estimation problem using the Levenberg-Marquardt algorithm.<a name="line.217"></a>
221 <FONT color="green">218</FONT> * &lt;p&gt;The algorithm used is a modified Levenberg-Marquardt one, based<a name="line.218"></a>
222 <FONT color="green">219</FONT> * on the MINPACK &lt;a href="http://www.netlib.org/minpack/lmder.f"&gt;lmder&lt;/a&gt;<a name="line.219"></a>
223 <FONT color="green">220</FONT> * routine. The algorithm settings must have been set up before this method<a name="line.220"></a>
224 <FONT color="green">221</FONT> * is called with the {@link #setInitialStepBoundFactor},<a name="line.221"></a>
225 <FONT color="green">222</FONT> * {@link #setMaxCostEval}, {@link #setCostRelativeTolerance},<a name="line.222"></a>
226 <FONT color="green">223</FONT> * {@link #setParRelativeTolerance} and {@link #setOrthoTolerance} methods.<a name="line.223"></a>
227 <FONT color="green">224</FONT> * If these methods have not been called, the default values set up by the<a name="line.224"></a>
228 <FONT color="green">225</FONT> * {@link #LevenbergMarquardtEstimator() constructor} will be used.&lt;/p&gt;<a name="line.225"></a>
229 <FONT color="green">226</FONT> * &lt;p&gt;The authors of the original fortran function are:&lt;/p&gt;<a name="line.226"></a>
230 <FONT color="green">227</FONT> * &lt;ul&gt;<a name="line.227"></a>
231 <FONT color="green">228</FONT> * &lt;li&gt;Argonne National Laboratory. MINPACK project. March 1980&lt;/li&gt;<a name="line.228"></a>
232 <FONT color="green">229</FONT> * &lt;li&gt;Burton S. Garbow&lt;/li&gt;<a name="line.229"></a>
233 <FONT color="green">230</FONT> * &lt;li&gt;Kenneth E. Hillstrom&lt;/li&gt;<a name="line.230"></a>
234 <FONT color="green">231</FONT> * &lt;li&gt;Jorge J. More&lt;/li&gt;<a name="line.231"></a>
235 <FONT color="green">232</FONT> * &lt;/ul&gt;<a name="line.232"></a>
236 <FONT color="green">233</FONT> * &lt;p&gt;Luc Maisonobe did the Java translation.&lt;/p&gt;<a name="line.233"></a>
237 <FONT color="green">234</FONT> *<a name="line.234"></a>
238 <FONT color="green">235</FONT> * @param problem estimation problem to solve<a name="line.235"></a>
239 <FONT color="green">236</FONT> * @exception EstimationException if convergence cannot be<a name="line.236"></a>
240 <FONT color="green">237</FONT> * reached with the specified algorithm settings or if there are more variables<a name="line.237"></a>
241 <FONT color="green">238</FONT> * than equations<a name="line.238"></a>
242 <FONT color="green">239</FONT> * @see #setInitialStepBoundFactor<a name="line.239"></a>
243 <FONT color="green">240</FONT> * @see #setCostRelativeTolerance<a name="line.240"></a>
244 <FONT color="green">241</FONT> * @see #setParRelativeTolerance<a name="line.241"></a>
245 <FONT color="green">242</FONT> * @see #setOrthoTolerance<a name="line.242"></a>
246 <FONT color="green">243</FONT> */<a name="line.243"></a>
247 <FONT color="green">244</FONT> @Override<a name="line.244"></a>
248 <FONT color="green">245</FONT> public void estimate(EstimationProblem problem)<a name="line.245"></a>
249 <FONT color="green">246</FONT> throws EstimationException {<a name="line.246"></a>
250 <FONT color="green">247</FONT> <a name="line.247"></a>
251 <FONT color="green">248</FONT> initializeEstimate(problem);<a name="line.248"></a>
252 <FONT color="green">249</FONT> <a name="line.249"></a>
253 <FONT color="green">250</FONT> // arrays shared with the other private methods<a name="line.250"></a>
254 <FONT color="green">251</FONT> solvedCols = Math.min(rows, cols);<a name="line.251"></a>
255 <FONT color="green">252</FONT> diagR = new double[cols];<a name="line.252"></a>
256 <FONT color="green">253</FONT> jacNorm = new double[cols];<a name="line.253"></a>
257 <FONT color="green">254</FONT> beta = new double[cols];<a name="line.254"></a>
258 <FONT color="green">255</FONT> permutation = new int[cols];<a name="line.255"></a>
259 <FONT color="green">256</FONT> lmDir = new double[cols];<a name="line.256"></a>
260 <FONT color="green">257</FONT> <a name="line.257"></a>
261 <FONT color="green">258</FONT> // local variables<a name="line.258"></a>
262 <FONT color="green">259</FONT> double delta = 0;<a name="line.259"></a>
263 <FONT color="green">260</FONT> double xNorm = 0;<a name="line.260"></a>
264 <FONT color="green">261</FONT> double[] diag = new double[cols];<a name="line.261"></a>
265 <FONT color="green">262</FONT> double[] oldX = new double[cols];<a name="line.262"></a>
266 <FONT color="green">263</FONT> double[] oldRes = new double[rows];<a name="line.263"></a>
267 <FONT color="green">264</FONT> double[] work1 = new double[cols];<a name="line.264"></a>
268 <FONT color="green">265</FONT> double[] work2 = new double[cols];<a name="line.265"></a>
269 <FONT color="green">266</FONT> double[] work3 = new double[cols];<a name="line.266"></a>
270 <FONT color="green">267</FONT> <a name="line.267"></a>
271 <FONT color="green">268</FONT> // evaluate the function at the starting point and calculate its norm<a name="line.268"></a>
272 <FONT color="green">269</FONT> updateResidualsAndCost();<a name="line.269"></a>
273 <FONT color="green">270</FONT> <a name="line.270"></a>
274 <FONT color="green">271</FONT> // outer loop<a name="line.271"></a>
275 <FONT color="green">272</FONT> lmPar = 0;<a name="line.272"></a>
276 <FONT color="green">273</FONT> boolean firstIteration = true;<a name="line.273"></a>
277 <FONT color="green">274</FONT> while (true) {<a name="line.274"></a>
278 <FONT color="green">275</FONT> <a name="line.275"></a>
279 <FONT color="green">276</FONT> // compute the Q.R. decomposition of the jacobian matrix<a name="line.276"></a>
280 <FONT color="green">277</FONT> updateJacobian();<a name="line.277"></a>
281 <FONT color="green">278</FONT> qrDecomposition();<a name="line.278"></a>
282 <FONT color="green">279</FONT> <a name="line.279"></a>
283 <FONT color="green">280</FONT> // compute Qt.res<a name="line.280"></a>
284 <FONT color="green">281</FONT> qTy(residuals);<a name="line.281"></a>
285 <FONT color="green">282</FONT> <a name="line.282"></a>
286 <FONT color="green">283</FONT> // now we don't need Q anymore,<a name="line.283"></a>
287 <FONT color="green">284</FONT> // so let jacobian contain the R matrix with its diagonal elements<a name="line.284"></a>
288 <FONT color="green">285</FONT> for (int k = 0; k &lt; solvedCols; ++k) {<a name="line.285"></a>
289 <FONT color="green">286</FONT> int pk = permutation[k];<a name="line.286"></a>
290 <FONT color="green">287</FONT> jacobian[k * cols + pk] = diagR[pk];<a name="line.287"></a>
291 <FONT color="green">288</FONT> }<a name="line.288"></a>
292 <FONT color="green">289</FONT> <a name="line.289"></a>
293 <FONT color="green">290</FONT> if (firstIteration) {<a name="line.290"></a>
294 <FONT color="green">291</FONT> <a name="line.291"></a>
295 <FONT color="green">292</FONT> // scale the variables according to the norms of the columns<a name="line.292"></a>
296 <FONT color="green">293</FONT> // of the initial jacobian<a name="line.293"></a>
297 <FONT color="green">294</FONT> xNorm = 0;<a name="line.294"></a>
298 <FONT color="green">295</FONT> for (int k = 0; k &lt; cols; ++k) {<a name="line.295"></a>
299 <FONT color="green">296</FONT> double dk = jacNorm[k];<a name="line.296"></a>
300 <FONT color="green">297</FONT> if (dk == 0) {<a name="line.297"></a>
301 <FONT color="green">298</FONT> dk = 1.0;<a name="line.298"></a>
302 <FONT color="green">299</FONT> }<a name="line.299"></a>
303 <FONT color="green">300</FONT> double xk = dk * parameters[k].getEstimate();<a name="line.300"></a>
304 <FONT color="green">301</FONT> xNorm += xk * xk;<a name="line.301"></a>
305 <FONT color="green">302</FONT> diag[k] = dk;<a name="line.302"></a>
306 <FONT color="green">303</FONT> }<a name="line.303"></a>
307 <FONT color="green">304</FONT> xNorm = Math.sqrt(xNorm);<a name="line.304"></a>
308 <FONT color="green">305</FONT> <a name="line.305"></a>
309 <FONT color="green">306</FONT> // initialize the step bound delta<a name="line.306"></a>
310 <FONT color="green">307</FONT> delta = (xNorm == 0) ? initialStepBoundFactor : (initialStepBoundFactor * xNorm);<a name="line.307"></a>
311 <FONT color="green">308</FONT> <a name="line.308"></a>
312 <FONT color="green">309</FONT> }<a name="line.309"></a>
313 <FONT color="green">310</FONT> <a name="line.310"></a>
314 <FONT color="green">311</FONT> // check orthogonality between function vector and jacobian columns<a name="line.311"></a>
315 <FONT color="green">312</FONT> double maxCosine = 0;<a name="line.312"></a>
316 <FONT color="green">313</FONT> if (cost != 0) {<a name="line.313"></a>
317 <FONT color="green">314</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.314"></a>
318 <FONT color="green">315</FONT> int pj = permutation[j];<a name="line.315"></a>
319 <FONT color="green">316</FONT> double s = jacNorm[pj];<a name="line.316"></a>
320 <FONT color="green">317</FONT> if (s != 0) {<a name="line.317"></a>
321 <FONT color="green">318</FONT> double sum = 0;<a name="line.318"></a>
322 <FONT color="green">319</FONT> int index = pj;<a name="line.319"></a>
323 <FONT color="green">320</FONT> for (int i = 0; i &lt;= j; ++i) {<a name="line.320"></a>
324 <FONT color="green">321</FONT> sum += jacobian[index] * residuals[i];<a name="line.321"></a>
325 <FONT color="green">322</FONT> index += cols;<a name="line.322"></a>
326 <FONT color="green">323</FONT> }<a name="line.323"></a>
327 <FONT color="green">324</FONT> maxCosine = Math.max(maxCosine, Math.abs(sum) / (s * cost));<a name="line.324"></a>
328 <FONT color="green">325</FONT> }<a name="line.325"></a>
329 <FONT color="green">326</FONT> }<a name="line.326"></a>
330 <FONT color="green">327</FONT> }<a name="line.327"></a>
331 <FONT color="green">328</FONT> if (maxCosine &lt;= orthoTolerance) {<a name="line.328"></a>
332 <FONT color="green">329</FONT> return;<a name="line.329"></a>
333 <FONT color="green">330</FONT> }<a name="line.330"></a>
334 <FONT color="green">331</FONT> <a name="line.331"></a>
335 <FONT color="green">332</FONT> // rescale if necessary<a name="line.332"></a>
336 <FONT color="green">333</FONT> for (int j = 0; j &lt; cols; ++j) {<a name="line.333"></a>
337 <FONT color="green">334</FONT> diag[j] = Math.max(diag[j], jacNorm[j]);<a name="line.334"></a>
338 <FONT color="green">335</FONT> }<a name="line.335"></a>
339 <FONT color="green">336</FONT> <a name="line.336"></a>
340 <FONT color="green">337</FONT> // inner loop<a name="line.337"></a>
341 <FONT color="green">338</FONT> for (double ratio = 0; ratio &lt; 1.0e-4;) {<a name="line.338"></a>
342 <FONT color="green">339</FONT> <a name="line.339"></a>
343 <FONT color="green">340</FONT> // save the state<a name="line.340"></a>
344 <FONT color="green">341</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.341"></a>
345 <FONT color="green">342</FONT> int pj = permutation[j];<a name="line.342"></a>
346 <FONT color="green">343</FONT> oldX[pj] = parameters[pj].getEstimate();<a name="line.343"></a>
347 <FONT color="green">344</FONT> }<a name="line.344"></a>
348 <FONT color="green">345</FONT> double previousCost = cost;<a name="line.345"></a>
349 <FONT color="green">346</FONT> double[] tmpVec = residuals;<a name="line.346"></a>
350 <FONT color="green">347</FONT> residuals = oldRes;<a name="line.347"></a>
351 <FONT color="green">348</FONT> oldRes = tmpVec;<a name="line.348"></a>
352 <FONT color="green">349</FONT> <a name="line.349"></a>
353 <FONT color="green">350</FONT> // determine the Levenberg-Marquardt parameter<a name="line.350"></a>
354 <FONT color="green">351</FONT> determineLMParameter(oldRes, delta, diag, work1, work2, work3);<a name="line.351"></a>
355 <FONT color="green">352</FONT> <a name="line.352"></a>
356 <FONT color="green">353</FONT> // compute the new point and the norm of the evolution direction<a name="line.353"></a>
357 <FONT color="green">354</FONT> double lmNorm = 0;<a name="line.354"></a>
358 <FONT color="green">355</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.355"></a>
359 <FONT color="green">356</FONT> int pj = permutation[j];<a name="line.356"></a>
360 <FONT color="green">357</FONT> lmDir[pj] = -lmDir[pj];<a name="line.357"></a>
361 <FONT color="green">358</FONT> parameters[pj].setEstimate(oldX[pj] + lmDir[pj]);<a name="line.358"></a>
362 <FONT color="green">359</FONT> double s = diag[pj] * lmDir[pj];<a name="line.359"></a>
363 <FONT color="green">360</FONT> lmNorm += s * s;<a name="line.360"></a>
364 <FONT color="green">361</FONT> }<a name="line.361"></a>
365 <FONT color="green">362</FONT> lmNorm = Math.sqrt(lmNorm);<a name="line.362"></a>
366 <FONT color="green">363</FONT> <a name="line.363"></a>
367 <FONT color="green">364</FONT> // on the first iteration, adjust the initial step bound.<a name="line.364"></a>
368 <FONT color="green">365</FONT> if (firstIteration) {<a name="line.365"></a>
369 <FONT color="green">366</FONT> delta = Math.min(delta, lmNorm);<a name="line.366"></a>
370 <FONT color="green">367</FONT> }<a name="line.367"></a>
371 <FONT color="green">368</FONT> <a name="line.368"></a>
372 <FONT color="green">369</FONT> // evaluate the function at x + p and calculate its norm<a name="line.369"></a>
373 <FONT color="green">370</FONT> updateResidualsAndCost();<a name="line.370"></a>
374 <FONT color="green">371</FONT> <a name="line.371"></a>
375 <FONT color="green">372</FONT> // compute the scaled actual reduction<a name="line.372"></a>
376 <FONT color="green">373</FONT> double actRed = -1.0;<a name="line.373"></a>
377 <FONT color="green">374</FONT> if (0.1 * cost &lt; previousCost) {<a name="line.374"></a>
378 <FONT color="green">375</FONT> double r = cost / previousCost;<a name="line.375"></a>
379 <FONT color="green">376</FONT> actRed = 1.0 - r * r;<a name="line.376"></a>
380 <FONT color="green">377</FONT> }<a name="line.377"></a>
381 <FONT color="green">378</FONT> <a name="line.378"></a>
382 <FONT color="green">379</FONT> // compute the scaled predicted reduction<a name="line.379"></a>
383 <FONT color="green">380</FONT> // and the scaled directional derivative<a name="line.380"></a>
384 <FONT color="green">381</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.381"></a>
385 <FONT color="green">382</FONT> int pj = permutation[j];<a name="line.382"></a>
386 <FONT color="green">383</FONT> double dirJ = lmDir[pj];<a name="line.383"></a>
387 <FONT color="green">384</FONT> work1[j] = 0;<a name="line.384"></a>
388 <FONT color="green">385</FONT> int index = pj;<a name="line.385"></a>
389 <FONT color="green">386</FONT> for (int i = 0; i &lt;= j; ++i) {<a name="line.386"></a>
390 <FONT color="green">387</FONT> work1[i] += jacobian[index] * dirJ;<a name="line.387"></a>
391 <FONT color="green">388</FONT> index += cols;<a name="line.388"></a>
392 <FONT color="green">389</FONT> }<a name="line.389"></a>
393 <FONT color="green">390</FONT> }<a name="line.390"></a>
394 <FONT color="green">391</FONT> double coeff1 = 0;<a name="line.391"></a>
395 <FONT color="green">392</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.392"></a>
396 <FONT color="green">393</FONT> coeff1 += work1[j] * work1[j];<a name="line.393"></a>
397 <FONT color="green">394</FONT> }<a name="line.394"></a>
398 <FONT color="green">395</FONT> double pc2 = previousCost * previousCost;<a name="line.395"></a>
399 <FONT color="green">396</FONT> coeff1 = coeff1 / pc2;<a name="line.396"></a>
400 <FONT color="green">397</FONT> double coeff2 = lmPar * lmNorm * lmNorm / pc2;<a name="line.397"></a>
401 <FONT color="green">398</FONT> double preRed = coeff1 + 2 * coeff2;<a name="line.398"></a>
402 <FONT color="green">399</FONT> double dirDer = -(coeff1 + coeff2);<a name="line.399"></a>
403 <FONT color="green">400</FONT> <a name="line.400"></a>
404 <FONT color="green">401</FONT> // ratio of the actual to the predicted reduction<a name="line.401"></a>
405 <FONT color="green">402</FONT> ratio = (preRed == 0) ? 0 : (actRed / preRed);<a name="line.402"></a>
406 <FONT color="green">403</FONT> <a name="line.403"></a>
407 <FONT color="green">404</FONT> // update the step bound<a name="line.404"></a>
408 <FONT color="green">405</FONT> if (ratio &lt;= 0.25) {<a name="line.405"></a>
409 <FONT color="green">406</FONT> double tmp =<a name="line.406"></a>
410 <FONT color="green">407</FONT> (actRed &lt; 0) ? (0.5 * dirDer / (dirDer + 0.5 * actRed)) : 0.5;<a name="line.407"></a>
411 <FONT color="green">408</FONT> if ((0.1 * cost &gt;= previousCost) || (tmp &lt; 0.1)) {<a name="line.408"></a>
412 <FONT color="green">409</FONT> tmp = 0.1;<a name="line.409"></a>
413 <FONT color="green">410</FONT> }<a name="line.410"></a>
414 <FONT color="green">411</FONT> delta = tmp * Math.min(delta, 10.0 * lmNorm);<a name="line.411"></a>
415 <FONT color="green">412</FONT> lmPar /= tmp;<a name="line.412"></a>
416 <FONT color="green">413</FONT> } else if ((lmPar == 0) || (ratio &gt;= 0.75)) {<a name="line.413"></a>
417 <FONT color="green">414</FONT> delta = 2 * lmNorm;<a name="line.414"></a>
418 <FONT color="green">415</FONT> lmPar *= 0.5;<a name="line.415"></a>
419 <FONT color="green">416</FONT> }<a name="line.416"></a>
420 <FONT color="green">417</FONT> <a name="line.417"></a>
421 <FONT color="green">418</FONT> // test for successful iteration.<a name="line.418"></a>
422 <FONT color="green">419</FONT> if (ratio &gt;= 1.0e-4) {<a name="line.419"></a>
423 <FONT color="green">420</FONT> // successful iteration, update the norm<a name="line.420"></a>
424 <FONT color="green">421</FONT> firstIteration = false;<a name="line.421"></a>
425 <FONT color="green">422</FONT> xNorm = 0;<a name="line.422"></a>
426 <FONT color="green">423</FONT> for (int k = 0; k &lt; cols; ++k) {<a name="line.423"></a>
427 <FONT color="green">424</FONT> double xK = diag[k] * parameters[k].getEstimate();<a name="line.424"></a>
428 <FONT color="green">425</FONT> xNorm += xK * xK;<a name="line.425"></a>
429 <FONT color="green">426</FONT> }<a name="line.426"></a>
430 <FONT color="green">427</FONT> xNorm = Math.sqrt(xNorm);<a name="line.427"></a>
431 <FONT color="green">428</FONT> } else {<a name="line.428"></a>
432 <FONT color="green">429</FONT> // failed iteration, reset the previous values<a name="line.429"></a>
433 <FONT color="green">430</FONT> cost = previousCost;<a name="line.430"></a>
434 <FONT color="green">431</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.431"></a>
435 <FONT color="green">432</FONT> int pj = permutation[j];<a name="line.432"></a>
436 <FONT color="green">433</FONT> parameters[pj].setEstimate(oldX[pj]);<a name="line.433"></a>
437 <FONT color="green">434</FONT> }<a name="line.434"></a>
438 <FONT color="green">435</FONT> tmpVec = residuals;<a name="line.435"></a>
439 <FONT color="green">436</FONT> residuals = oldRes;<a name="line.436"></a>
440 <FONT color="green">437</FONT> oldRes = tmpVec;<a name="line.437"></a>
441 <FONT color="green">438</FONT> }<a name="line.438"></a>
442 <FONT color="green">439</FONT> <a name="line.439"></a>
443 <FONT color="green">440</FONT> // tests for convergence.<a name="line.440"></a>
444 <FONT color="green">441</FONT> if (((Math.abs(actRed) &lt;= costRelativeTolerance) &amp;&amp;<a name="line.441"></a>
445 <FONT color="green">442</FONT> (preRed &lt;= costRelativeTolerance) &amp;&amp;<a name="line.442"></a>
446 <FONT color="green">443</FONT> (ratio &lt;= 2.0)) ||<a name="line.443"></a>
447 <FONT color="green">444</FONT> (delta &lt;= parRelativeTolerance * xNorm)) {<a name="line.444"></a>
448 <FONT color="green">445</FONT> return;<a name="line.445"></a>
449 <FONT color="green">446</FONT> }<a name="line.446"></a>
450 <FONT color="green">447</FONT> <a name="line.447"></a>
451 <FONT color="green">448</FONT> // tests for termination and stringent tolerances<a name="line.448"></a>
452 <FONT color="green">449</FONT> // (2.2204e-16 is the machine epsilon for IEEE754)<a name="line.449"></a>
453 <FONT color="green">450</FONT> if ((Math.abs(actRed) &lt;= 2.2204e-16) &amp;&amp; (preRed &lt;= 2.2204e-16) &amp;&amp; (ratio &lt;= 2.0)) {<a name="line.450"></a>
454 <FONT color="green">451</FONT> throw new EstimationException("cost relative tolerance is too small ({0})," +<a name="line.451"></a>
455 <FONT color="green">452</FONT> " no further reduction in the" +<a name="line.452"></a>
456 <FONT color="green">453</FONT> " sum of squares is possible",<a name="line.453"></a>
457 <FONT color="green">454</FONT> costRelativeTolerance);<a name="line.454"></a>
458 <FONT color="green">455</FONT> } else if (delta &lt;= 2.2204e-16 * xNorm) {<a name="line.455"></a>
459 <FONT color="green">456</FONT> throw new EstimationException("parameters relative tolerance is too small" +<a name="line.456"></a>
460 <FONT color="green">457</FONT> " ({0}), no further improvement in" +<a name="line.457"></a>
461 <FONT color="green">458</FONT> " the approximate solution is possible",<a name="line.458"></a>
462 <FONT color="green">459</FONT> parRelativeTolerance);<a name="line.459"></a>
463 <FONT color="green">460</FONT> } else if (maxCosine &lt;= 2.2204e-16) {<a name="line.460"></a>
464 <FONT color="green">461</FONT> throw new EstimationException("orthogonality tolerance is too small ({0})," +<a name="line.461"></a>
465 <FONT color="green">462</FONT> " solution is orthogonal to the jacobian",<a name="line.462"></a>
466 <FONT color="green">463</FONT> orthoTolerance);<a name="line.463"></a>
467 <FONT color="green">464</FONT> }<a name="line.464"></a>
468 <FONT color="green">465</FONT> <a name="line.465"></a>
469 <FONT color="green">466</FONT> }<a name="line.466"></a>
470 <FONT color="green">467</FONT> <a name="line.467"></a>
471 <FONT color="green">468</FONT> }<a name="line.468"></a>
472 <FONT color="green">469</FONT> <a name="line.469"></a>
473 <FONT color="green">470</FONT> }<a name="line.470"></a>
474 <FONT color="green">471</FONT> <a name="line.471"></a>
475 <FONT color="green">472</FONT> /**<a name="line.472"></a>
476 <FONT color="green">473</FONT> * Determine the Levenberg-Marquardt parameter.<a name="line.473"></a>
477 <FONT color="green">474</FONT> * &lt;p&gt;This implementation is a translation in Java of the MINPACK<a name="line.474"></a>
478 <FONT color="green">475</FONT> * &lt;a href="http://www.netlib.org/minpack/lmpar.f"&gt;lmpar&lt;/a&gt;<a name="line.475"></a>
479 <FONT color="green">476</FONT> * routine.&lt;/p&gt;<a name="line.476"></a>
480 <FONT color="green">477</FONT> * &lt;p&gt;This method sets the lmPar and lmDir attributes.&lt;/p&gt;<a name="line.477"></a>
481 <FONT color="green">478</FONT> * &lt;p&gt;The authors of the original fortran function are:&lt;/p&gt;<a name="line.478"></a>
482 <FONT color="green">479</FONT> * &lt;ul&gt;<a name="line.479"></a>
483 <FONT color="green">480</FONT> * &lt;li&gt;Argonne National Laboratory. MINPACK project. March 1980&lt;/li&gt;<a name="line.480"></a>
484 <FONT color="green">481</FONT> * &lt;li&gt;Burton S. Garbow&lt;/li&gt;<a name="line.481"></a>
485 <FONT color="green">482</FONT> * &lt;li&gt;Kenneth E. Hillstrom&lt;/li&gt;<a name="line.482"></a>
486 <FONT color="green">483</FONT> * &lt;li&gt;Jorge J. More&lt;/li&gt;<a name="line.483"></a>
487 <FONT color="green">484</FONT> * &lt;/ul&gt;<a name="line.484"></a>
488 <FONT color="green">485</FONT> * &lt;p&gt;Luc Maisonobe did the Java translation.&lt;/p&gt;<a name="line.485"></a>
489 <FONT color="green">486</FONT> *<a name="line.486"></a>
490 <FONT color="green">487</FONT> * @param qy array containing qTy<a name="line.487"></a>
491 <FONT color="green">488</FONT> * @param delta upper bound on the euclidean norm of diagR * lmDir<a name="line.488"></a>
492 <FONT color="green">489</FONT> * @param diag diagonal matrix<a name="line.489"></a>
493 <FONT color="green">490</FONT> * @param work1 work array<a name="line.490"></a>
494 <FONT color="green">491</FONT> * @param work2 work array<a name="line.491"></a>
495 <FONT color="green">492</FONT> * @param work3 work array<a name="line.492"></a>
496 <FONT color="green">493</FONT> */<a name="line.493"></a>
497 <FONT color="green">494</FONT> private void determineLMParameter(double[] qy, double delta, double[] diag,<a name="line.494"></a>
498 <FONT color="green">495</FONT> double[] work1, double[] work2, double[] work3) {<a name="line.495"></a>
499 <FONT color="green">496</FONT> <a name="line.496"></a>
500 <FONT color="green">497</FONT> // compute and store in x the gauss-newton direction, if the<a name="line.497"></a>
501 <FONT color="green">498</FONT> // jacobian is rank-deficient, obtain a least squares solution<a name="line.498"></a>
502 <FONT color="green">499</FONT> for (int j = 0; j &lt; rank; ++j) {<a name="line.499"></a>
503 <FONT color="green">500</FONT> lmDir[permutation[j]] = qy[j];<a name="line.500"></a>
504 <FONT color="green">501</FONT> }<a name="line.501"></a>
505 <FONT color="green">502</FONT> for (int j = rank; j &lt; cols; ++j) {<a name="line.502"></a>
506 <FONT color="green">503</FONT> lmDir[permutation[j]] = 0;<a name="line.503"></a>
507 <FONT color="green">504</FONT> }<a name="line.504"></a>
508 <FONT color="green">505</FONT> for (int k = rank - 1; k &gt;= 0; --k) {<a name="line.505"></a>
509 <FONT color="green">506</FONT> int pk = permutation[k];<a name="line.506"></a>
510 <FONT color="green">507</FONT> double ypk = lmDir[pk] / diagR[pk];<a name="line.507"></a>
511 <FONT color="green">508</FONT> int index = pk;<a name="line.508"></a>
512 <FONT color="green">509</FONT> for (int i = 0; i &lt; k; ++i) {<a name="line.509"></a>
513 <FONT color="green">510</FONT> lmDir[permutation[i]] -= ypk * jacobian[index];<a name="line.510"></a>
514 <FONT color="green">511</FONT> index += cols;<a name="line.511"></a>
515 <FONT color="green">512</FONT> }<a name="line.512"></a>
516 <FONT color="green">513</FONT> lmDir[pk] = ypk;<a name="line.513"></a>
517 <FONT color="green">514</FONT> }<a name="line.514"></a>
518 <FONT color="green">515</FONT> <a name="line.515"></a>
519 <FONT color="green">516</FONT> // evaluate the function at the origin, and test<a name="line.516"></a>
520 <FONT color="green">517</FONT> // for acceptance of the Gauss-Newton direction<a name="line.517"></a>
521 <FONT color="green">518</FONT> double dxNorm = 0;<a name="line.518"></a>
522 <FONT color="green">519</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.519"></a>
523 <FONT color="green">520</FONT> int pj = permutation[j];<a name="line.520"></a>
524 <FONT color="green">521</FONT> double s = diag[pj] * lmDir[pj];<a name="line.521"></a>
525 <FONT color="green">522</FONT> work1[pj] = s;<a name="line.522"></a>
526 <FONT color="green">523</FONT> dxNorm += s * s;<a name="line.523"></a>
527 <FONT color="green">524</FONT> }<a name="line.524"></a>
528 <FONT color="green">525</FONT> dxNorm = Math.sqrt(dxNorm);<a name="line.525"></a>
529 <FONT color="green">526</FONT> double fp = dxNorm - delta;<a name="line.526"></a>
530 <FONT color="green">527</FONT> if (fp &lt;= 0.1 * delta) {<a name="line.527"></a>
531 <FONT color="green">528</FONT> lmPar = 0;<a name="line.528"></a>
532 <FONT color="green">529</FONT> return;<a name="line.529"></a>
533 <FONT color="green">530</FONT> }<a name="line.530"></a>
534 <FONT color="green">531</FONT> <a name="line.531"></a>
535 <FONT color="green">532</FONT> // if the jacobian is not rank deficient, the Newton step provides<a name="line.532"></a>
536 <FONT color="green">533</FONT> // a lower bound, parl, for the zero of the function,<a name="line.533"></a>
537 <FONT color="green">534</FONT> // otherwise set this bound to zero<a name="line.534"></a>
538 <FONT color="green">535</FONT> double sum2;<a name="line.535"></a>
539 <FONT color="green">536</FONT> double parl = 0;<a name="line.536"></a>
540 <FONT color="green">537</FONT> if (rank == solvedCols) {<a name="line.537"></a>
541 <FONT color="green">538</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.538"></a>
542 <FONT color="green">539</FONT> int pj = permutation[j];<a name="line.539"></a>
543 <FONT color="green">540</FONT> work1[pj] *= diag[pj] / dxNorm;<a name="line.540"></a>
544 <FONT color="green">541</FONT> }<a name="line.541"></a>
545 <FONT color="green">542</FONT> sum2 = 0;<a name="line.542"></a>
546 <FONT color="green">543</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.543"></a>
547 <FONT color="green">544</FONT> int pj = permutation[j];<a name="line.544"></a>
548 <FONT color="green">545</FONT> double sum = 0;<a name="line.545"></a>
549 <FONT color="green">546</FONT> int index = pj;<a name="line.546"></a>
550 <FONT color="green">547</FONT> for (int i = 0; i &lt; j; ++i) {<a name="line.547"></a>
551 <FONT color="green">548</FONT> sum += jacobian[index] * work1[permutation[i]];<a name="line.548"></a>
552 <FONT color="green">549</FONT> index += cols;<a name="line.549"></a>
553 <FONT color="green">550</FONT> }<a name="line.550"></a>
554 <FONT color="green">551</FONT> double s = (work1[pj] - sum) / diagR[pj];<a name="line.551"></a>
555 <FONT color="green">552</FONT> work1[pj] = s;<a name="line.552"></a>
556 <FONT color="green">553</FONT> sum2 += s * s;<a name="line.553"></a>
557 <FONT color="green">554</FONT> }<a name="line.554"></a>
558 <FONT color="green">555</FONT> parl = fp / (delta * sum2);<a name="line.555"></a>
559 <FONT color="green">556</FONT> }<a name="line.556"></a>
560 <FONT color="green">557</FONT> <a name="line.557"></a>
561 <FONT color="green">558</FONT> // calculate an upper bound, paru, for the zero of the function<a name="line.558"></a>
562 <FONT color="green">559</FONT> sum2 = 0;<a name="line.559"></a>
563 <FONT color="green">560</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.560"></a>
564 <FONT color="green">561</FONT> int pj = permutation[j];<a name="line.561"></a>
565 <FONT color="green">562</FONT> double sum = 0;<a name="line.562"></a>
566 <FONT color="green">563</FONT> int index = pj;<a name="line.563"></a>
567 <FONT color="green">564</FONT> for (int i = 0; i &lt;= j; ++i) {<a name="line.564"></a>
568 <FONT color="green">565</FONT> sum += jacobian[index] * qy[i];<a name="line.565"></a>
569 <FONT color="green">566</FONT> index += cols;<a name="line.566"></a>
570 <FONT color="green">567</FONT> }<a name="line.567"></a>
571 <FONT color="green">568</FONT> sum /= diag[pj];<a name="line.568"></a>
572 <FONT color="green">569</FONT> sum2 += sum * sum;<a name="line.569"></a>
573 <FONT color="green">570</FONT> }<a name="line.570"></a>
574 <FONT color="green">571</FONT> double gNorm = Math.sqrt(sum2);<a name="line.571"></a>
575 <FONT color="green">572</FONT> double paru = gNorm / delta;<a name="line.572"></a>
576 <FONT color="green">573</FONT> if (paru == 0) {<a name="line.573"></a>
577 <FONT color="green">574</FONT> // 2.2251e-308 is the smallest positive real for IEE754<a name="line.574"></a>
578 <FONT color="green">575</FONT> paru = 2.2251e-308 / Math.min(delta, 0.1);<a name="line.575"></a>
579 <FONT color="green">576</FONT> }<a name="line.576"></a>
580 <FONT color="green">577</FONT> <a name="line.577"></a>
581 <FONT color="green">578</FONT> // if the input par lies outside of the interval (parl,paru),<a name="line.578"></a>
582 <FONT color="green">579</FONT> // set par to the closer endpoint<a name="line.579"></a>
583 <FONT color="green">580</FONT> lmPar = Math.min(paru, Math.max(lmPar, parl));<a name="line.580"></a>
584 <FONT color="green">581</FONT> if (lmPar == 0) {<a name="line.581"></a>
585 <FONT color="green">582</FONT> lmPar = gNorm / dxNorm;<a name="line.582"></a>
586 <FONT color="green">583</FONT> }<a name="line.583"></a>
587 <FONT color="green">584</FONT> <a name="line.584"></a>
588 <FONT color="green">585</FONT> for (int countdown = 10; countdown &gt;= 0; --countdown) {<a name="line.585"></a>
589 <FONT color="green">586</FONT> <a name="line.586"></a>
590 <FONT color="green">587</FONT> // evaluate the function at the current value of lmPar<a name="line.587"></a>
591 <FONT color="green">588</FONT> if (lmPar == 0) {<a name="line.588"></a>
592 <FONT color="green">589</FONT> lmPar = Math.max(2.2251e-308, 0.001 * paru);<a name="line.589"></a>
593 <FONT color="green">590</FONT> }<a name="line.590"></a>
594 <FONT color="green">591</FONT> double sPar = Math.sqrt(lmPar);<a name="line.591"></a>
595 <FONT color="green">592</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.592"></a>
596 <FONT color="green">593</FONT> int pj = permutation[j];<a name="line.593"></a>
597 <FONT color="green">594</FONT> work1[pj] = sPar * diag[pj];<a name="line.594"></a>
598 <FONT color="green">595</FONT> }<a name="line.595"></a>
599 <FONT color="green">596</FONT> determineLMDirection(qy, work1, work2, work3);<a name="line.596"></a>
600 <FONT color="green">597</FONT> <a name="line.597"></a>
601 <FONT color="green">598</FONT> dxNorm = 0;<a name="line.598"></a>
602 <FONT color="green">599</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.599"></a>
603 <FONT color="green">600</FONT> int pj = permutation[j];<a name="line.600"></a>
604 <FONT color="green">601</FONT> double s = diag[pj] * lmDir[pj];<a name="line.601"></a>
605 <FONT color="green">602</FONT> work3[pj] = s;<a name="line.602"></a>
606 <FONT color="green">603</FONT> dxNorm += s * s;<a name="line.603"></a>
607 <FONT color="green">604</FONT> }<a name="line.604"></a>
608 <FONT color="green">605</FONT> dxNorm = Math.sqrt(dxNorm);<a name="line.605"></a>
609 <FONT color="green">606</FONT> double previousFP = fp;<a name="line.606"></a>
610 <FONT color="green">607</FONT> fp = dxNorm - delta;<a name="line.607"></a>
611 <FONT color="green">608</FONT> <a name="line.608"></a>
612 <FONT color="green">609</FONT> // if the function is small enough, accept the current value<a name="line.609"></a>
613 <FONT color="green">610</FONT> // of lmPar, also test for the exceptional cases where parl is zero<a name="line.610"></a>
614 <FONT color="green">611</FONT> if ((Math.abs(fp) &lt;= 0.1 * delta) ||<a name="line.611"></a>
615 <FONT color="green">612</FONT> ((parl == 0) &amp;&amp; (fp &lt;= previousFP) &amp;&amp; (previousFP &lt; 0))) {<a name="line.612"></a>
616 <FONT color="green">613</FONT> return;<a name="line.613"></a>
617 <FONT color="green">614</FONT> }<a name="line.614"></a>
618 <FONT color="green">615</FONT> <a name="line.615"></a>
619 <FONT color="green">616</FONT> // compute the Newton correction<a name="line.616"></a>
620 <FONT color="green">617</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.617"></a>
621 <FONT color="green">618</FONT> int pj = permutation[j];<a name="line.618"></a>
622 <FONT color="green">619</FONT> work1[pj] = work3[pj] * diag[pj] / dxNorm;<a name="line.619"></a>
623 <FONT color="green">620</FONT> }<a name="line.620"></a>
624 <FONT color="green">621</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.621"></a>
625 <FONT color="green">622</FONT> int pj = permutation[j];<a name="line.622"></a>
626 <FONT color="green">623</FONT> work1[pj] /= work2[j];<a name="line.623"></a>
627 <FONT color="green">624</FONT> double tmp = work1[pj];<a name="line.624"></a>
628 <FONT color="green">625</FONT> for (int i = j + 1; i &lt; solvedCols; ++i) {<a name="line.625"></a>
629 <FONT color="green">626</FONT> work1[permutation[i]] -= jacobian[i * cols + pj] * tmp;<a name="line.626"></a>
630 <FONT color="green">627</FONT> }<a name="line.627"></a>
631 <FONT color="green">628</FONT> }<a name="line.628"></a>
632 <FONT color="green">629</FONT> sum2 = 0;<a name="line.629"></a>
633 <FONT color="green">630</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.630"></a>
634 <FONT color="green">631</FONT> double s = work1[permutation[j]];<a name="line.631"></a>
635 <FONT color="green">632</FONT> sum2 += s * s;<a name="line.632"></a>
636 <FONT color="green">633</FONT> }<a name="line.633"></a>
637 <FONT color="green">634</FONT> double correction = fp / (delta * sum2);<a name="line.634"></a>
638 <FONT color="green">635</FONT> <a name="line.635"></a>
639 <FONT color="green">636</FONT> // depending on the sign of the function, update parl or paru.<a name="line.636"></a>
640 <FONT color="green">637</FONT> if (fp &gt; 0) {<a name="line.637"></a>
641 <FONT color="green">638</FONT> parl = Math.max(parl, lmPar);<a name="line.638"></a>
642 <FONT color="green">639</FONT> } else if (fp &lt; 0) {<a name="line.639"></a>
643 <FONT color="green">640</FONT> paru = Math.min(paru, lmPar);<a name="line.640"></a>
644 <FONT color="green">641</FONT> }<a name="line.641"></a>
645 <FONT color="green">642</FONT> <a name="line.642"></a>
646 <FONT color="green">643</FONT> // compute an improved estimate for lmPar<a name="line.643"></a>
647 <FONT color="green">644</FONT> lmPar = Math.max(parl, lmPar + correction);<a name="line.644"></a>
648 <FONT color="green">645</FONT> <a name="line.645"></a>
649 <FONT color="green">646</FONT> }<a name="line.646"></a>
650 <FONT color="green">647</FONT> }<a name="line.647"></a>
651 <FONT color="green">648</FONT> <a name="line.648"></a>
652 <FONT color="green">649</FONT> /**<a name="line.649"></a>
653 <FONT color="green">650</FONT> * Solve a*x = b and d*x = 0 in the least squares sense.<a name="line.650"></a>
654 <FONT color="green">651</FONT> * &lt;p&gt;This implementation is a translation in Java of the MINPACK<a name="line.651"></a>
655 <FONT color="green">652</FONT> * &lt;a href="http://www.netlib.org/minpack/qrsolv.f"&gt;qrsolv&lt;/a&gt;<a name="line.652"></a>
656 <FONT color="green">653</FONT> * routine.&lt;/p&gt;<a name="line.653"></a>
657 <FONT color="green">654</FONT> * &lt;p&gt;This method sets the lmDir and lmDiag attributes.&lt;/p&gt;<a name="line.654"></a>
658 <FONT color="green">655</FONT> * &lt;p&gt;The authors of the original fortran function are:&lt;/p&gt;<a name="line.655"></a>
659 <FONT color="green">656</FONT> * &lt;ul&gt;<a name="line.656"></a>
660 <FONT color="green">657</FONT> * &lt;li&gt;Argonne National Laboratory. MINPACK project. March 1980&lt;/li&gt;<a name="line.657"></a>
661 <FONT color="green">658</FONT> * &lt;li&gt;Burton S. Garbow&lt;/li&gt;<a name="line.658"></a>
662 <FONT color="green">659</FONT> * &lt;li&gt;Kenneth E. Hillstrom&lt;/li&gt;<a name="line.659"></a>
663 <FONT color="green">660</FONT> * &lt;li&gt;Jorge J. More&lt;/li&gt;<a name="line.660"></a>
664 <FONT color="green">661</FONT> * &lt;/ul&gt;<a name="line.661"></a>
665 <FONT color="green">662</FONT> * &lt;p&gt;Luc Maisonobe did the Java translation.&lt;/p&gt;<a name="line.662"></a>
666 <FONT color="green">663</FONT> *<a name="line.663"></a>
667 <FONT color="green">664</FONT> * @param qy array containing qTy<a name="line.664"></a>
668 <FONT color="green">665</FONT> * @param diag diagonal matrix<a name="line.665"></a>
669 <FONT color="green">666</FONT> * @param lmDiag diagonal elements associated with lmDir<a name="line.666"></a>
670 <FONT color="green">667</FONT> * @param work work array<a name="line.667"></a>
671 <FONT color="green">668</FONT> */<a name="line.668"></a>
672 <FONT color="green">669</FONT> private void determineLMDirection(double[] qy, double[] diag,<a name="line.669"></a>
673 <FONT color="green">670</FONT> double[] lmDiag, double[] work) {<a name="line.670"></a>
674 <FONT color="green">671</FONT> <a name="line.671"></a>
675 <FONT color="green">672</FONT> // copy R and Qty to preserve input and initialize s<a name="line.672"></a>
676 <FONT color="green">673</FONT> // in particular, save the diagonal elements of R in lmDir<a name="line.673"></a>
677 <FONT color="green">674</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.674"></a>
678 <FONT color="green">675</FONT> int pj = permutation[j];<a name="line.675"></a>
679 <FONT color="green">676</FONT> for (int i = j + 1; i &lt; solvedCols; ++i) {<a name="line.676"></a>
680 <FONT color="green">677</FONT> jacobian[i * cols + pj] = jacobian[j * cols + permutation[i]];<a name="line.677"></a>
681 <FONT color="green">678</FONT> }<a name="line.678"></a>
682 <FONT color="green">679</FONT> lmDir[j] = diagR[pj];<a name="line.679"></a>
683 <FONT color="green">680</FONT> work[j] = qy[j];<a name="line.680"></a>
684 <FONT color="green">681</FONT> }<a name="line.681"></a>
685 <FONT color="green">682</FONT> <a name="line.682"></a>
686 <FONT color="green">683</FONT> // eliminate the diagonal matrix d using a Givens rotation<a name="line.683"></a>
687 <FONT color="green">684</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.684"></a>
688 <FONT color="green">685</FONT> <a name="line.685"></a>
689 <FONT color="green">686</FONT> // prepare the row of d to be eliminated, locating the<a name="line.686"></a>
690 <FONT color="green">687</FONT> // diagonal element using p from the Q.R. factorization<a name="line.687"></a>
691 <FONT color="green">688</FONT> int pj = permutation[j];<a name="line.688"></a>
692 <FONT color="green">689</FONT> double dpj = diag[pj];<a name="line.689"></a>
693 <FONT color="green">690</FONT> if (dpj != 0) {<a name="line.690"></a>
694 <FONT color="green">691</FONT> Arrays.fill(lmDiag, j + 1, lmDiag.length, 0);<a name="line.691"></a>
695 <FONT color="green">692</FONT> }<a name="line.692"></a>
696 <FONT color="green">693</FONT> lmDiag[j] = dpj;<a name="line.693"></a>
697 <FONT color="green">694</FONT> <a name="line.694"></a>
698 <FONT color="green">695</FONT> // the transformations to eliminate the row of d<a name="line.695"></a>
699 <FONT color="green">696</FONT> // modify only a single element of Qty<a name="line.696"></a>
700 <FONT color="green">697</FONT> // beyond the first n, which is initially zero.<a name="line.697"></a>
701 <FONT color="green">698</FONT> double qtbpj = 0;<a name="line.698"></a>
702 <FONT color="green">699</FONT> for (int k = j; k &lt; solvedCols; ++k) {<a name="line.699"></a>
703 <FONT color="green">700</FONT> int pk = permutation[k];<a name="line.700"></a>
704 <FONT color="green">701</FONT> <a name="line.701"></a>
705 <FONT color="green">702</FONT> // determine a Givens rotation which eliminates the<a name="line.702"></a>
706 <FONT color="green">703</FONT> // appropriate element in the current row of d<a name="line.703"></a>
707 <FONT color="green">704</FONT> if (lmDiag[k] != 0) {<a name="line.704"></a>
708 <FONT color="green">705</FONT> <a name="line.705"></a>
709 <FONT color="green">706</FONT> final double sin;<a name="line.706"></a>
710 <FONT color="green">707</FONT> final double cos;<a name="line.707"></a>
711 <FONT color="green">708</FONT> double rkk = jacobian[k * cols + pk];<a name="line.708"></a>
712 <FONT color="green">709</FONT> if (Math.abs(rkk) &lt; Math.abs(lmDiag[k])) {<a name="line.709"></a>
713 <FONT color="green">710</FONT> final double cotan = rkk / lmDiag[k];<a name="line.710"></a>
714 <FONT color="green">711</FONT> sin = 1.0 / Math.sqrt(1.0 + cotan * cotan);<a name="line.711"></a>
715 <FONT color="green">712</FONT> cos = sin * cotan;<a name="line.712"></a>
716 <FONT color="green">713</FONT> } else {<a name="line.713"></a>
717 <FONT color="green">714</FONT> final double tan = lmDiag[k] / rkk;<a name="line.714"></a>
718 <FONT color="green">715</FONT> cos = 1.0 / Math.sqrt(1.0 + tan * tan);<a name="line.715"></a>
719 <FONT color="green">716</FONT> sin = cos * tan;<a name="line.716"></a>
720 <FONT color="green">717</FONT> }<a name="line.717"></a>
721 <FONT color="green">718</FONT> <a name="line.718"></a>
722 <FONT color="green">719</FONT> // compute the modified diagonal element of R and<a name="line.719"></a>
723 <FONT color="green">720</FONT> // the modified element of (Qty,0)<a name="line.720"></a>
724 <FONT color="green">721</FONT> jacobian[k * cols + pk] = cos * rkk + sin * lmDiag[k];<a name="line.721"></a>
725 <FONT color="green">722</FONT> final double temp = cos * work[k] + sin * qtbpj;<a name="line.722"></a>
726 <FONT color="green">723</FONT> qtbpj = -sin * work[k] + cos * qtbpj;<a name="line.723"></a>
727 <FONT color="green">724</FONT> work[k] = temp;<a name="line.724"></a>
728 <FONT color="green">725</FONT> <a name="line.725"></a>
729 <FONT color="green">726</FONT> // accumulate the tranformation in the row of s<a name="line.726"></a>
730 <FONT color="green">727</FONT> for (int i = k + 1; i &lt; solvedCols; ++i) {<a name="line.727"></a>
731 <FONT color="green">728</FONT> double rik = jacobian[i * cols + pk];<a name="line.728"></a>
732 <FONT color="green">729</FONT> final double temp2 = cos * rik + sin * lmDiag[i];<a name="line.729"></a>
733 <FONT color="green">730</FONT> lmDiag[i] = -sin * rik + cos * lmDiag[i];<a name="line.730"></a>
734 <FONT color="green">731</FONT> jacobian[i * cols + pk] = temp2;<a name="line.731"></a>
735 <FONT color="green">732</FONT> }<a name="line.732"></a>
736 <FONT color="green">733</FONT> <a name="line.733"></a>
737 <FONT color="green">734</FONT> }<a name="line.734"></a>
738 <FONT color="green">735</FONT> }<a name="line.735"></a>
739 <FONT color="green">736</FONT> <a name="line.736"></a>
740 <FONT color="green">737</FONT> // store the diagonal element of s and restore<a name="line.737"></a>
741 <FONT color="green">738</FONT> // the corresponding diagonal element of R<a name="line.738"></a>
742 <FONT color="green">739</FONT> int index = j * cols + permutation[j];<a name="line.739"></a>
743 <FONT color="green">740</FONT> lmDiag[j] = jacobian[index];<a name="line.740"></a>
744 <FONT color="green">741</FONT> jacobian[index] = lmDir[j];<a name="line.741"></a>
745 <FONT color="green">742</FONT> <a name="line.742"></a>
746 <FONT color="green">743</FONT> }<a name="line.743"></a>
747 <FONT color="green">744</FONT> <a name="line.744"></a>
748 <FONT color="green">745</FONT> // solve the triangular system for z, if the system is<a name="line.745"></a>
749 <FONT color="green">746</FONT> // singular, then obtain a least squares solution<a name="line.746"></a>
750 <FONT color="green">747</FONT> int nSing = solvedCols;<a name="line.747"></a>
751 <FONT color="green">748</FONT> for (int j = 0; j &lt; solvedCols; ++j) {<a name="line.748"></a>
752 <FONT color="green">749</FONT> if ((lmDiag[j] == 0) &amp;&amp; (nSing == solvedCols)) {<a name="line.749"></a>
753 <FONT color="green">750</FONT> nSing = j;<a name="line.750"></a>
754 <FONT color="green">751</FONT> }<a name="line.751"></a>
755 <FONT color="green">752</FONT> if (nSing &lt; solvedCols) {<a name="line.752"></a>
756 <FONT color="green">753</FONT> work[j] = 0;<a name="line.753"></a>
757 <FONT color="green">754</FONT> }<a name="line.754"></a>
758 <FONT color="green">755</FONT> }<a name="line.755"></a>
759 <FONT color="green">756</FONT> if (nSing &gt; 0) {<a name="line.756"></a>
760 <FONT color="green">757</FONT> for (int j = nSing - 1; j &gt;= 0; --j) {<a name="line.757"></a>
761 <FONT color="green">758</FONT> int pj = permutation[j];<a name="line.758"></a>
762 <FONT color="green">759</FONT> double sum = 0;<a name="line.759"></a>
763 <FONT color="green">760</FONT> for (int i = j + 1; i &lt; nSing; ++i) {<a name="line.760"></a>
764 <FONT color="green">761</FONT> sum += jacobian[i * cols + pj] * work[i];<a name="line.761"></a>
765 <FONT color="green">762</FONT> }<a name="line.762"></a>
766 <FONT color="green">763</FONT> work[j] = (work[j] - sum) / lmDiag[j];<a name="line.763"></a>
767 <FONT color="green">764</FONT> }<a name="line.764"></a>
768 <FONT color="green">765</FONT> }<a name="line.765"></a>
769 <FONT color="green">766</FONT> <a name="line.766"></a>
770 <FONT color="green">767</FONT> // permute the components of z back to components of lmDir<a name="line.767"></a>
771 <FONT color="green">768</FONT> for (int j = 0; j &lt; lmDir.length; ++j) {<a name="line.768"></a>
772 <FONT color="green">769</FONT> lmDir[permutation[j]] = work[j];<a name="line.769"></a>
773 <FONT color="green">770</FONT> }<a name="line.770"></a>
774 <FONT color="green">771</FONT> <a name="line.771"></a>
775 <FONT color="green">772</FONT> }<a name="line.772"></a>
776 <FONT color="green">773</FONT> <a name="line.773"></a>
777 <FONT color="green">774</FONT> /**<a name="line.774"></a>
778 <FONT color="green">775</FONT> * Decompose a matrix A as A.P = Q.R using Householder transforms.<a name="line.775"></a>
779 <FONT color="green">776</FONT> * &lt;p&gt;As suggested in the P. Lascaux and R. Theodor book<a name="line.776"></a>
780 <FONT color="green">777</FONT> * &lt;i&gt;Analyse num&amp;eacute;rique matricielle appliqu&amp;eacute;e &amp;agrave;<a name="line.777"></a>
781 <FONT color="green">778</FONT> * l'art de l'ing&amp;eacute;nieur&lt;/i&gt; (Masson, 1986), instead of representing<a name="line.778"></a>
782 <FONT color="green">779</FONT> * the Householder transforms with u&lt;sub&gt;k&lt;/sub&gt; unit vectors such that:<a name="line.779"></a>
783 <FONT color="green">780</FONT> * &lt;pre&gt;<a name="line.780"></a>
784 <FONT color="green">781</FONT> * H&lt;sub&gt;k&lt;/sub&gt; = I - 2u&lt;sub&gt;k&lt;/sub&gt;.u&lt;sub&gt;k&lt;/sub&gt;&lt;sup&gt;t&lt;/sup&gt;<a name="line.781"></a>
785 <FONT color="green">782</FONT> * &lt;/pre&gt;<a name="line.782"></a>
786 <FONT color="green">783</FONT> * we use &lt;sub&gt;k&lt;/sub&gt; non-unit vectors such that:<a name="line.783"></a>
787 <FONT color="green">784</FONT> * &lt;pre&gt;<a name="line.784"></a>
788 <FONT color="green">785</FONT> * H&lt;sub&gt;k&lt;/sub&gt; = I - beta&lt;sub&gt;k&lt;/sub&gt;v&lt;sub&gt;k&lt;/sub&gt;.v&lt;sub&gt;k&lt;/sub&gt;&lt;sup&gt;t&lt;/sup&gt;<a name="line.785"></a>
789 <FONT color="green">786</FONT> * &lt;/pre&gt;<a name="line.786"></a>
790 <FONT color="green">787</FONT> * where v&lt;sub&gt;k&lt;/sub&gt; = a&lt;sub&gt;k&lt;/sub&gt; - alpha&lt;sub&gt;k&lt;/sub&gt; e&lt;sub&gt;k&lt;/sub&gt;.<a name="line.787"></a>
791 <FONT color="green">788</FONT> * The beta&lt;sub&gt;k&lt;/sub&gt; coefficients are provided upon exit as recomputing<a name="line.788"></a>
792 <FONT color="green">789</FONT> * them from the v&lt;sub&gt;k&lt;/sub&gt; vectors would be costly.&lt;/p&gt;<a name="line.789"></a>
793 <FONT color="green">790</FONT> * &lt;p&gt;This decomposition handles rank deficient cases since the tranformations<a name="line.790"></a>
794 <FONT color="green">791</FONT> * are performed in non-increasing columns norms order thanks to columns<a name="line.791"></a>
795 <FONT color="green">792</FONT> * pivoting. The diagonal elements of the R matrix are therefore also in<a name="line.792"></a>
796 <FONT color="green">793</FONT> * non-increasing absolute values order.&lt;/p&gt;<a name="line.793"></a>
797 <FONT color="green">794</FONT> * @exception EstimationException if the decomposition cannot be performed<a name="line.794"></a>
798 <FONT color="green">795</FONT> */<a name="line.795"></a>
799 <FONT color="green">796</FONT> private void qrDecomposition() throws EstimationException {<a name="line.796"></a>
800 <FONT color="green">797</FONT> <a name="line.797"></a>
801 <FONT color="green">798</FONT> // initializations<a name="line.798"></a>
802 <FONT color="green">799</FONT> for (int k = 0; k &lt; cols; ++k) {<a name="line.799"></a>
803 <FONT color="green">800</FONT> permutation[k] = k;<a name="line.800"></a>
804 <FONT color="green">801</FONT> double norm2 = 0;<a name="line.801"></a>
805 <FONT color="green">802</FONT> for (int index = k; index &lt; jacobian.length; index += cols) {<a name="line.802"></a>
806 <FONT color="green">803</FONT> double akk = jacobian[index];<a name="line.803"></a>
807 <FONT color="green">804</FONT> norm2 += akk * akk;<a name="line.804"></a>
808 <FONT color="green">805</FONT> }<a name="line.805"></a>
809 <FONT color="green">806</FONT> jacNorm[k] = Math.sqrt(norm2);<a name="line.806"></a>
810 <FONT color="green">807</FONT> }<a name="line.807"></a>
811 <FONT color="green">808</FONT> <a name="line.808"></a>
812 <FONT color="green">809</FONT> // transform the matrix column after column<a name="line.809"></a>
813 <FONT color="green">810</FONT> for (int k = 0; k &lt; cols; ++k) {<a name="line.810"></a>
814 <FONT color="green">811</FONT> <a name="line.811"></a>
815 <FONT color="green">812</FONT> // select the column with the greatest norm on active components<a name="line.812"></a>
816 <FONT color="green">813</FONT> int nextColumn = -1;<a name="line.813"></a>
817 <FONT color="green">814</FONT> double ak2 = Double.NEGATIVE_INFINITY;<a name="line.814"></a>
818 <FONT color="green">815</FONT> for (int i = k; i &lt; cols; ++i) {<a name="line.815"></a>
819 <FONT color="green">816</FONT> double norm2 = 0;<a name="line.816"></a>
820 <FONT color="green">817</FONT> int iDiag = k * cols + permutation[i];<a name="line.817"></a>
821 <FONT color="green">818</FONT> for (int index = iDiag; index &lt; jacobian.length; index += cols) {<a name="line.818"></a>
822 <FONT color="green">819</FONT> double aki = jacobian[index];<a name="line.819"></a>
823 <FONT color="green">820</FONT> norm2 += aki * aki;<a name="line.820"></a>
824 <FONT color="green">821</FONT> }<a name="line.821"></a>
825 <FONT color="green">822</FONT> if (Double.isInfinite(norm2) || Double.isNaN(norm2)) {<a name="line.822"></a>
826 <FONT color="green">823</FONT> throw new EstimationException(<a name="line.823"></a>
827 <FONT color="green">824</FONT> "unable to perform Q.R decomposition on the {0}x{1} jacobian matrix",<a name="line.824"></a>
828 <FONT color="green">825</FONT> rows, cols);<a name="line.825"></a>
829 <FONT color="green">826</FONT> }<a name="line.826"></a>
830 <FONT color="green">827</FONT> if (norm2 &gt; ak2) {<a name="line.827"></a>
831 <FONT color="green">828</FONT> nextColumn = i;<a name="line.828"></a>
832 <FONT color="green">829</FONT> ak2 = norm2;<a name="line.829"></a>
833 <FONT color="green">830</FONT> }<a name="line.830"></a>
834 <FONT color="green">831</FONT> }<a name="line.831"></a>
835 <FONT color="green">832</FONT> if (ak2 == 0) {<a name="line.832"></a>
836 <FONT color="green">833</FONT> rank = k;<a name="line.833"></a>
837 <FONT color="green">834</FONT> return;<a name="line.834"></a>
838 <FONT color="green">835</FONT> }<a name="line.835"></a>
839 <FONT color="green">836</FONT> int pk = permutation[nextColumn];<a name="line.836"></a>
840 <FONT color="green">837</FONT> permutation[nextColumn] = permutation[k];<a name="line.837"></a>
841 <FONT color="green">838</FONT> permutation[k] = pk;<a name="line.838"></a>
842 <FONT color="green">839</FONT> <a name="line.839"></a>
843 <FONT color="green">840</FONT> // choose alpha such that Hk.u = alpha ek<a name="line.840"></a>
844 <FONT color="green">841</FONT> int kDiag = k * cols + pk;<a name="line.841"></a>
845 <FONT color="green">842</FONT> double akk = jacobian[kDiag];<a name="line.842"></a>
846 <FONT color="green">843</FONT> double alpha = (akk &gt; 0) ? -Math.sqrt(ak2) : Math.sqrt(ak2);<a name="line.843"></a>
847 <FONT color="green">844</FONT> double betak = 1.0 / (ak2 - akk * alpha);<a name="line.844"></a>
848 <FONT color="green">845</FONT> beta[pk] = betak;<a name="line.845"></a>
849 <FONT color="green">846</FONT> <a name="line.846"></a>
850 <FONT color="green">847</FONT> // transform the current column<a name="line.847"></a>
851 <FONT color="green">848</FONT> diagR[pk] = alpha;<a name="line.848"></a>
852 <FONT color="green">849</FONT> jacobian[kDiag] -= alpha;<a name="line.849"></a>
853 <FONT color="green">850</FONT> <a name="line.850"></a>
854 <FONT color="green">851</FONT> // transform the remaining columns<a name="line.851"></a>
855 <FONT color="green">852</FONT> for (int dk = cols - 1 - k; dk &gt; 0; --dk) {<a name="line.852"></a>
856 <FONT color="green">853</FONT> int dkp = permutation[k + dk] - pk;<a name="line.853"></a>
857 <FONT color="green">854</FONT> double gamma = 0;<a name="line.854"></a>
858 <FONT color="green">855</FONT> for (int index = kDiag; index &lt; jacobian.length; index += cols) {<a name="line.855"></a>
859 <FONT color="green">856</FONT> gamma += jacobian[index] * jacobian[index + dkp];<a name="line.856"></a>
860 <FONT color="green">857</FONT> }<a name="line.857"></a>
861 <FONT color="green">858</FONT> gamma *= betak;<a name="line.858"></a>
862 <FONT color="green">859</FONT> for (int index = kDiag; index &lt; jacobian.length; index += cols) {<a name="line.859"></a>
863 <FONT color="green">860</FONT> jacobian[index + dkp] -= gamma * jacobian[index];<a name="line.860"></a>
864 <FONT color="green">861</FONT> }<a name="line.861"></a>
865 <FONT color="green">862</FONT> }<a name="line.862"></a>
866 <FONT color="green">863</FONT> <a name="line.863"></a>
867 <FONT color="green">864</FONT> }<a name="line.864"></a>
868 <FONT color="green">865</FONT> <a name="line.865"></a>
869 <FONT color="green">866</FONT> rank = solvedCols;<a name="line.866"></a>
870 <FONT color="green">867</FONT> <a name="line.867"></a>
871 <FONT color="green">868</FONT> }<a name="line.868"></a>
872 <FONT color="green">869</FONT> <a name="line.869"></a>
873 <FONT color="green">870</FONT> /**<a name="line.870"></a>
874 <FONT color="green">871</FONT> * Compute the product Qt.y for some Q.R. decomposition.<a name="line.871"></a>
875 <FONT color="green">872</FONT> *<a name="line.872"></a>
876 <FONT color="green">873</FONT> * @param y vector to multiply (will be overwritten with the result)<a name="line.873"></a>
877 <FONT color="green">874</FONT> */<a name="line.874"></a>
878 <FONT color="green">875</FONT> private void qTy(double[] y) {<a name="line.875"></a>
879 <FONT color="green">876</FONT> for (int k = 0; k &lt; cols; ++k) {<a name="line.876"></a>
880 <FONT color="green">877</FONT> int pk = permutation[k];<a name="line.877"></a>
881 <FONT color="green">878</FONT> int kDiag = k * cols + pk;<a name="line.878"></a>
882 <FONT color="green">879</FONT> double gamma = 0;<a name="line.879"></a>
883 <FONT color="green">880</FONT> int index = kDiag;<a name="line.880"></a>
884 <FONT color="green">881</FONT> for (int i = k; i &lt; rows; ++i) {<a name="line.881"></a>
885 <FONT color="green">882</FONT> gamma += jacobian[index] * y[i];<a name="line.882"></a>
886 <FONT color="green">883</FONT> index += cols;<a name="line.883"></a>
887 <FONT color="green">884</FONT> }<a name="line.884"></a>
888 <FONT color="green">885</FONT> gamma *= beta[pk];<a name="line.885"></a>
889 <FONT color="green">886</FONT> index = kDiag;<a name="line.886"></a>
890 <FONT color="green">887</FONT> for (int i = k; i &lt; rows; ++i) {<a name="line.887"></a>
891 <FONT color="green">888</FONT> y[i] -= gamma * jacobian[index];<a name="line.888"></a>
892 <FONT color="green">889</FONT> index += cols;<a name="line.889"></a>
893 <FONT color="green">890</FONT> }<a name="line.890"></a>
894 <FONT color="green">891</FONT> }<a name="line.891"></a>
895 <FONT color="green">892</FONT> }<a name="line.892"></a>
896 <FONT color="green">893</FONT> <a name="line.893"></a>
897 <FONT color="green">894</FONT> }<a name="line.894"></a>
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958 </PRE>
959 </BODY>
960 </HTML>