paradiseo/trunk/paradiseo-eo/doc/html/eig_8cpp-source.html
legrand c3aec878e5 Paradiseo-eo sources added
git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@40 331e1502-861f-0410-8da2-ba01fb791d7f
2006-12-12 14:49:08 +00:00

274 lines
16 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>EO: eig.cpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.3.9.1 -->
<div class="qindex"> <form class="search" action="search.php" method="get">
<a class="qindex" href="main.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class&nbsp;Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical&nbsp;List</a> | <a class="qindex" href="annotated.html">Class&nbsp;List</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="namespacemembers.html">Namespace&nbsp;Members</a> | <a class="qindex" href="functions.html">Class&nbsp;Members</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a> | <span class="search"><u>S</u>earch&nbsp;for&nbsp;<input class="search" type="text" name="query" value="" size="20" accesskey="s"/></span></form></div>
<div class="nav">
<a class="el" href="dir_000000.html">src</a>&nbsp;/&nbsp;<a class="el" href="dir_000010.html">es</a></div>
<h1>eig.cpp</h1><div class="fragment"><pre class="fragment">00001
00002 <span class="comment">/*</span>
00003 <span class="comment"> * C++ification of Nikolaus Hansen's original C-source code for the</span>
00004 <span class="comment"> * CMA-ES. These are the eigenvector calculations</span>
00005 <span class="comment"> *</span>
00006 <span class="comment"> * C++-ificiation performed by Maarten Keijzer (C) 2005. Licensed under</span>
00007 <span class="comment"> * the LGPL. Original copyright of Nikolaus Hansen can be found below</span>
00008 <span class="comment"> *</span>
00009 <span class="comment"> * This algorithm is held almost completely intact. Some other datatypes are used,</span>
00010 <span class="comment"> * but hardly any code has changed</span>
00011 <span class="comment"> * </span>
00012 <span class="comment"> */</span>
00013
00014 <span class="comment">/* --------------------------------------------------------- */</span>
00015 <span class="comment">/* --------------------------------------------------------- */</span>
00016 <span class="comment">/* --- File: cmaes.c -------- Author: Nikolaus Hansen --- */</span>
00017 <span class="comment">/* --------------------------------------------------------- */</span>
00018 <span class="comment">/*</span>
00019 <span class="comment"> * CMA-ES for non-linear function minimization.</span>
00020 <span class="comment"> *</span>
00021 <span class="comment"> * Copyright (C) 1996, 2003 Nikolaus Hansen.</span>
00022 <span class="comment"> * e-mail: hansen@bionik.tu-berlin.de</span>
00023 <span class="comment"> *</span>
00024 <span class="comment"> * This library is free software; you can redistribute it and/or</span>
00025 <span class="comment"> * modify it under the terms of the GNU Lesser General Public</span>
00026 <span class="comment"> * License as published by the Free Software Foundation; either</span>
00027 <span class="comment"> * version 2.1 of the License, or (at your option) any later</span>
00028 <span class="comment"> * version (see http://www.gnu.org/copyleft/lesser.html).</span>
00029 <span class="comment"> *</span>
00030 <span class="comment"> * This library is distributed in the hope that it will be useful,</span>
00031 <span class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
00032 <span class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</span>
00033 <span class="comment"> * Lesser General Public License for more details.</span>
00034 <span class="comment"> * </span>
00035 <span class="comment"> * */</span>
00036 <span class="comment">/* --- Changes : ---</span>
00037 <span class="comment"> * 03/03/21: argument const double *rgFunVal of</span>
00038 <span class="comment"> * cmaes_ReestimateDistribution() was treated incorrectly.</span>
00039 <span class="comment"> * 03/03/29: restart via cmaes_resume_distribution() implemented.</span>
00040 <span class="comment"> * 03/03/30: Always max std dev / largest axis is printed first.</span>
00041 <span class="comment"> * 03/08/30: Damping is adjusted for large mueff.</span>
00042 <span class="comment"> * 03/10/30: Damping is adjusted for large mueff always.</span>
00043 <span class="comment"> * 04/04/22: Cumulation time and damping for step size adjusted.</span>
00044 <span class="comment"> * No iniphase but conditional update of pc.</span>
00045 <span class="comment"> * Version 2.23.</span>
00046 <span class="comment"> * */</span>
00047 <span class="preprocessor">#include "eig.h"</span>
00048
00049 <span class="keyword">using</span> <span class="keyword">namespace </span>std;
00050
00051 <span class="comment">/* ========================================================= */</span>
00052 <span class="comment">/* </span>
00053 <span class="comment"> Householder Transformation einer symmetrischen Matrix</span>
00054 <span class="comment"> auf tridiagonale Form.</span>
00055 <span class="comment"> -&gt; n : Dimension</span>
00056 <span class="comment"> -&gt; ma : symmetrische nxn-Matrix</span>
00057 <span class="comment"> &lt;- ma : Transformationsmatrix (ist orthogonal): </span>
00058 <span class="comment"> Tridiag.-Matrix == &lt;-ma * -&gt;ma * (&lt;-ma)^t</span>
00059 <span class="comment"> &lt;- diag : Diagonale der resultierenden Tridiagonalmatrix</span>
00060 <span class="comment"> &lt;- neben[0..n-1] : Nebendiagonale (==1..n-1) der res. Tridiagonalmatrix</span>
00061 <span class="comment"></span>
00062 <span class="comment"> */</span>
00063 <span class="keyword">static</span> <span class="keywordtype">void</span>
00064 Householder( <span class="keywordtype">int</span> N, square_matrix&amp; ma, valarray&lt;double&gt;&amp; diag, <span class="keywordtype">double</span>* neben)
00065 {
00066 <span class="keywordtype">double</span> epsilon;
00067 <span class="keywordtype">int</span> i, j, k;
00068 <span class="keywordtype">double</span> h, sum, tmp, tmp2;
00069
00070 <span class="keywordflow">for</span> (i = N-1; i &gt; 0; --i)
00071 {
00072 h = 0.0;
00073 <span class="keywordflow">if</span> (i == 1)
00074 neben[i] = ma[i][i-1];
00075 <span class="keywordflow">else</span>
00076 {
00077 <span class="keywordflow">for</span> (k = i-1, epsilon = 0.0; k &gt;= 0; --k)
00078 epsilon += fabs(ma[i][k]);
00079
00080 <span class="keywordflow">if</span> (epsilon == 0.0)
00081 neben[i] = ma[i][i-1];
00082 <span class="keywordflow">else</span>
00083 {
00084 <span class="keywordflow">for</span>(k = i-1, sum = 0.0; k &gt;= 0; --k)
00085 { <span class="comment">/* i-te Zeile von i-1 bis links normieren */</span>
00086 ma[i][k] /= epsilon;
00087 sum += ma[i][k]*ma[i][k];
00088 }
00089 tmp = (ma[i][i-1] &gt; 0) ? -sqrt(sum) : sqrt(sum);
00090 neben[i] = epsilon*tmp;
00091 h = sum - ma[i][i-1]*tmp;
00092 ma[i][i-1] -= tmp;
00093 <span class="keywordflow">for</span> (j = 0, sum = 0.0; j &lt; i; ++j)
00094 {
00095 ma[j][i] = ma[i][j]/h;
00096 tmp = 0.0;
00097 <span class="keywordflow">for</span> (k = j; k &gt;= 0; --k)
00098 tmp += ma[j][k]*ma[i][k];
00099 <span class="keywordflow">for</span> (k = j+1; k &lt; i; ++k)
00100 tmp += ma[k][j]*ma[i][k];
00101 neben[j] = tmp/h;
00102 sum += neben[j] * ma[i][j];
00103 } <span class="comment">/* for j */</span>
00104 sum /= 2.*h;
00105 <span class="keywordflow">for</span> (j = 0; j &lt; i; ++j)
00106 {
00107 neben[j] -= ma[i][j]*sum;
00108 tmp = ma[i][j];
00109 tmp2 = neben[j];
00110 <span class="keywordflow">for</span> (k = j; k &gt;= 0; --k)
00111 ma[j][k] -= (tmp*neben[k] + tmp2*ma[i][k]);
00112 } <span class="comment">/* for j */</span>
00113 } <span class="comment">/* else epsilon */</span>
00114 } <span class="comment">/* else i == 1 */</span>
00115 diag[i] = h;
00116 } <span class="comment">/* for i */</span>
00117
00118 diag[0] = 0.0;
00119 neben[0] = 0.0;
00120
00121 <span class="keywordflow">for</span> (i = 0; i &lt; N; ++i)
00122 {
00123 <span class="keywordflow">if</span>(diag[i] != 0.0)
00124 <span class="keywordflow">for</span> (j = 0; j &lt; i; ++j)
00125 {
00126 <span class="keywordflow">for</span> (k = i-1, tmp = 0.0; k &gt;= 0; --k)
00127 tmp += ma[i][k] * ma[k][j];
00128 <span class="keywordflow">for</span> (k = i-1; k &gt;= 0; --k)
00129 ma[k][j] -= tmp*ma[k][i];
00130 } <span class="comment">/* for j */</span>
00131 diag[i] = ma[i][i];
00132 ma[i][i] = 1.0;
00133 <span class="keywordflow">for</span> (k = i-1; k &gt;= 0; --k)
00134 ma[k][i] = ma[i][k] = 0.0;
00135 } <span class="comment">/* for i */</span>
00136 }
00137
00138 <span class="comment">/*</span>
00139 <span class="comment"> QL-Algorithmus mit implizitem Shift, zur Berechnung von Eigenwerten</span>
00140 <span class="comment"> und -vektoren einer symmetrischen Tridiagonalmatrix. </span>
00141 <span class="comment"> -&gt; n : Dimension. </span>
00142 <span class="comment"> -&gt; diag : Diagonale der Tridiagonalmatrix. </span>
00143 <span class="comment"> -&gt; neben[0..n-1] : Nebendiagonale (==0..n-2), n-1. Eintrag beliebig</span>
00144 <span class="comment"> -&gt; mq : Matrix output von Householder() </span>
00145 <span class="comment"> -&gt; maxIt : maximale Zahl der Iterationen </span>
00146 <span class="comment"> &lt;- diag : Eigenwerte</span>
00147 <span class="comment"> &lt;- neben : Garbage</span>
00148 <span class="comment"> &lt;- mq : k-te Spalte ist normalisierter Eigenvektor zu diag[k]</span>
00149 <span class="comment"></span>
00150 <span class="comment"> */</span>
00151
00152 <span class="keyword">static</span> <span class="keywordtype">int</span>
00153 QLalgo( <span class="keywordtype">int</span> N, valarray&lt;double&gt;&amp; diag, square_matrix&amp; mq,
00154 <span class="keywordtype">int</span> maxIter, <span class="keywordtype">double</span>* neben)
00155 {
00156 <span class="keywordtype">int</span> i, j, k, kp1, l;
00157 <span class="keywordtype">double</span> tmp, diff, cneben, c1, c2, p;
00158 <span class="keywordtype">int</span> iter;
00159
00160 neben[N-1] = 0.0;
00161 <span class="keywordflow">for</span> (i = 0, iter = 0; i &lt; N &amp;&amp; iter &lt; maxIter; ++i)
00162 <span class="keywordflow">do</span> <span class="comment">/* while j != i */</span>
00163 {
00164 <span class="keywordflow">for</span> (j = i; j &lt; N-1; ++j)
00165 {
00166 tmp = fabs(diag[j]) + fabs(diag[j+1]);
00167 <span class="keywordflow">if</span> (fabs(neben[j]) + tmp == tmp)
00168 <span class="keywordflow">break</span>;
00169 }
00170 <span class="keywordflow">if</span> (j != i)
00171 {
00172 <span class="keywordflow">if</span> (++iter &gt; maxIter) <span class="keywordflow">return</span> maxIter-1;
00173 diff = (diag[i+1]-diag[i])/neben[i]/2.0;
00174 <span class="keywordflow">if</span> (diff &gt;= 0)
00175 diff = diag[j] - diag[i] +
00176 neben[i] / (diff + sqrt(diff * diff + 1.0));
00177 <span class="keywordflow">else</span>
00178 diff = diag[j] - diag[i] +
00179 neben[i] / (diff - sqrt(diff * diff + 1.0));
00180 c2 = c1 = 1.0;
00181 p = 0.0;
00182 <span class="keywordflow">for</span> (k = j-1; k &gt;= i; --k)
00183 {
00184 kp1 = k + 1;
00185 tmp = c2 * neben[k];
00186 cneben = c1 * neben[k];
00187 <span class="keywordflow">if</span> (fabs(tmp) &gt;= fabs(diff))
00188 {
00189 c1 = diff / tmp;
00190 c2 = 1. / sqrt(c1*c1 + 1.0);
00191 neben[kp1] = tmp / c2;
00192 c1 *= c2;
00193 }
00194 <span class="keywordflow">else</span>
00195 {
00196 c2 = tmp / diff;
00197 c1 = 1. / sqrt(c2*c2 + 1.0);
00198 neben[kp1] = diff / c1;
00199 c2 *= c1;
00200 } <span class="comment">/* else */</span>
00201 tmp = (diag[k] - diag[kp1] + p) * c2 + 2.0 * c1 * cneben;
00202 diag[kp1] += tmp * c2 - p;
00203 p = tmp * c2;
00204 diff = tmp * c1 - cneben;
00205 <span class="keywordflow">for</span> (l = N-1; l &gt;= 0; --l) <span class="comment">/* TF-Matrix Q */</span>
00206 {
00207 tmp = mq[l][kp1];
00208 mq[l][kp1] = c2 * mq[l][k] + c1 * tmp;
00209 mq[l][k] = c1 * mq[l][k] - c2 * tmp;
00210 } <span class="comment">/* for l */</span>
00211 } <span class="comment">/* for k */</span>
00212 diag[i] -= p;
00213 neben[i] = diff;
00214 neben[j] = 0.0;
00215 } <span class="comment">/* if */</span>
00216 } <span class="keywordflow">while</span> (j != i);
00217 <span class="keywordflow">return</span> iter;
00218 } <span class="comment">/* QLalgo() */</span>
00219
00220 <span class="comment">/* ========================================================= */</span>
00221 <span class="comment">/* </span>
00222 <span class="comment"> Calculating eigenvalues and vectors. </span>
00223 <span class="comment"> Input: </span>
00224 <span class="comment"> N: dimension.</span>
00225 <span class="comment"> C: lower_triangular NxN-matrix.</span>
00226 <span class="comment"> niter: number of maximal iterations for QL-Algorithm. </span>
00227 <span class="comment"> rgtmp: N+1-dimensional vector for temporal use. </span>
00228 <span class="comment"> Output: </span>
00229 <span class="comment"> diag: N eigenvalues.</span>
00230 <span class="comment"> Q: Columns are normalized eigenvectors.</span>
00231 <span class="comment"> return: number of iterations in QL-Algorithm.</span>
00232 <span class="comment"> */</span>
00233
00234 <span class="keyword">namespace </span>eo {
00235 <span class="keywordtype">int</span>
00236 eig( <span class="keywordtype">int</span> N, <span class="keyword">const</span> lower_triangular_matrix&amp; C, valarray&lt;double&gt;&amp; diag, square_matrix&amp; Q,
00237 <span class="keywordtype">int</span> niter)
00238 {
00239 <span class="keywordtype">int</span> ret;
00240 <span class="keywordtype">int</span> i, j;
00241
00242 <span class="keywordflow">if</span> (niter == 0) niter = 30*N;
00243
00244 <span class="keywordflow">for</span> (i=0; i &lt; N; ++i)
00245 {
00246 vector&lt;double&gt;::const_iterator row = C[i];
00247 <span class="keywordflow">for</span> (j = 0; j &lt;= i; ++j)
00248 Q[i][j] = Q[j][i] = row[j];
00249 }
00250
00251 <span class="keywordtype">double</span>* rgtmp = <span class="keyword">new</span> <span class="keywordtype">double</span>[N+1];
00252 Householder( N, Q, diag, rgtmp);
00253 ret = QLalgo( N, diag, Q, niter, rgtmp+1);
00254 <span class="keyword">delete</span> [] rgtmp;
00255
00256 <span class="keywordflow">return</span> ret;
00257 }
00258
00259 } <span class="comment">// namespace eo</span>
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Thu Oct 19 05:06:34 2006 for EO by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.3.9.1 </small></address>
</body>
</html>