git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@40 331e1502-861f-0410-8da2-ba01fb791d7f
274 lines
16 KiB
HTML
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 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 Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical List</a> | <a class="qindex" href="annotated.html">Class List</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="namespacemembers.html">Namespace Members</a> | <a class="qindex" href="functions.html">Class Members</a> | <a class="qindex" href="pages.html">Related Pages</a> | <span class="search"><u>S</u>earch for <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> / <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"> -> n : Dimension</span>
|
|
00056 <span class="comment"> -> ma : symmetrische nxn-Matrix</span>
|
|
00057 <span class="comment"> <- ma : Transformationsmatrix (ist orthogonal): </span>
|
|
00058 <span class="comment"> Tridiag.-Matrix == <-ma * ->ma * (<-ma)^t</span>
|
|
00059 <span class="comment"> <- diag : Diagonale der resultierenden Tridiagonalmatrix</span>
|
|
00060 <span class="comment"> <- 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& ma, valarray<double>& 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 > 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 >= 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 >= 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] > 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 < i; ++j)
|
|
00094 {
|
|
00095 ma[j][i] = ma[i][j]/h;
|
|
00096 tmp = 0.0;
|
|
00097 <span class="keywordflow">for</span> (k = j; k >= 0; --k)
|
|
00098 tmp += ma[j][k]*ma[i][k];
|
|
00099 <span class="keywordflow">for</span> (k = j+1; k < 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 < 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 >= 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 < N; ++i)
|
|
00122 {
|
|
00123 <span class="keywordflow">if</span>(diag[i] != 0.0)
|
|
00124 <span class="keywordflow">for</span> (j = 0; j < i; ++j)
|
|
00125 {
|
|
00126 <span class="keywordflow">for</span> (k = i-1, tmp = 0.0; k >= 0; --k)
|
|
00127 tmp += ma[i][k] * ma[k][j];
|
|
00128 <span class="keywordflow">for</span> (k = i-1; k >= 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 >= 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"> -> n : Dimension. </span>
|
|
00142 <span class="comment"> -> diag : Diagonale der Tridiagonalmatrix. </span>
|
|
00143 <span class="comment"> -> neben[0..n-1] : Nebendiagonale (==0..n-2), n-1. Eintrag beliebig</span>
|
|
00144 <span class="comment"> -> mq : Matrix output von Householder() </span>
|
|
00145 <span class="comment"> -> maxIt : maximale Zahl der Iterationen </span>
|
|
00146 <span class="comment"> <- diag : Eigenwerte</span>
|
|
00147 <span class="comment"> <- neben : Garbage</span>
|
|
00148 <span class="comment"> <- 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<double>& diag, square_matrix& 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 < N && iter < 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 < 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 > 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 >= 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 >= 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) >= 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 >= 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& C, valarray<double>& diag, square_matrix& 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 < N; ++i)
|
|
00245 {
|
|
00246 vector<double>::const_iterator row = C[i];
|
|
00247 <span class="keywordflow">for</span> (j = 0; j <= 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
|
|
<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>
|