⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eig.cpp

📁 这是linux下的进化计算的源代码。 === === === === === === === === === === === ===== check latest news at http:
💻 CPP
字号:
/* * C++ification of Nikolaus Hansen's original C-source code for the * CMA-ES. These are the eigenvector calculations * * C++-ificiation performed by Maarten Keijzer (C) 2005. Licensed under * the LGPL. Original copyright of Nikolaus Hansen can be found below * * This algorithm is held almost completely intact. Some other datatypes are used, * but hardly any code has changed *  *//* --------------------------------------------------------- *//* --------------------------------------------------------- *//* --- File: cmaes.c  -------- Author: Nikolaus Hansen   --- *//* --------------------------------------------------------- *//* *      CMA-ES for non-linear function minimization. * *           Copyright (C) 1996, 2003  Nikolaus Hansen. *           e-mail: hansen@bionik.tu-berlin.de * *           This library is free software; you can redistribute it and/or *           modify it under the terms of the GNU Lesser General Public *           License as published by the Free Software Foundation; either *           version 2.1 of the License, or (at your option) any later *           version (see http://www.gnu.org/copyleft/lesser.html). * *           This library is distributed in the hope that it will be useful, *           but WITHOUT ANY WARRANTY; without even the implied warranty of *           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *           Lesser General Public License for more details. *  *                                                             *//* --- Changes : --- *   03/03/21: argument const double *rgFunVal of *   cmaes_ReestimateDistribution() was treated incorrectly. *   03/03/29: restart via cmaes_resume_distribution() implemented. *   03/03/30: Always max std dev / largest axis is printed first. *   03/08/30: Damping is adjusted for large mueff. *   03/10/30: Damping is adjusted for large mueff always. *   04/04/22: Cumulation time and damping for step size adjusted. *   No iniphase but conditional update of pc. *   Version 2.23. *                               */#include "eig.h"using namespace std;/* ========================================================= *//*    Householder Transformation einer symmetrischen Matrix   auf tridiagonale Form.   -> n             : Dimension   -> ma            : symmetrische nxn-Matrix   <- ma            : Transformationsmatrix (ist orthogonal):                       Tridiag.-Matrix == <-ma * ->ma * (<-ma)^t   <- diag          : Diagonale der resultierenden Tridiagonalmatrix   <- neben[0..n-1] : Nebendiagonale (==1..n-1) der res. Tridiagonalmatrix   */static void Householder( int N, square_matrix& ma, valarray<double>& diag, double* neben){  double epsilon;   int i, j, k;  double h, sum, tmp, tmp2;  for (i = N-1; i > 0; --i)  {    h = 0.0;    if (i == 1)      neben[i] = ma[i][i-1];    else    {      for (k = i-1, epsilon = 0.0; k >= 0; --k)        epsilon += fabs(ma[i][k]);      if (epsilon == 0.0)        neben[i] = ma[i][i-1];      else      {        for(k = i-1, sum = 0.0; k >= 0; --k)	{ /* i-te Zeile von i-1 bis links normieren */          ma[i][k] /= epsilon;	  sum += ma[i][k]*ma[i][k];	} 	tmp = (ma[i][i-1] > 0) ? -sqrt(sum) : sqrt(sum);	neben[i] = epsilon*tmp;	h = sum - ma[i][i-1]*tmp;	ma[i][i-1] -= tmp;	for (j = 0, sum = 0.0; j < i; ++j)	{	  ma[j][i] = ma[i][j]/h;	  tmp = 0.0;	  for (k = j; k >= 0; --k)	    tmp += ma[j][k]*ma[i][k];	  for (k = j+1; k < i; ++k)	    tmp += ma[k][j]*ma[i][k];	  neben[j] = tmp/h;	  sum += neben[j] * ma[i][j];	} /* for j */	sum /= 2.*h;	for (j = 0; j < i; ++j)	{	  neben[j] -= ma[i][j]*sum;	  tmp = ma[i][j];	  tmp2 = neben[j];	  for (k = j; k >= 0; --k)	    ma[j][k] -= (tmp*neben[k] + tmp2*ma[i][k]);	} /* for j */      } /* else epsilon */    } /* else i == 1 */    diag[i] = h;  } /* for i */  diag[0] = 0.0;  neben[0] = 0.0;    for (i = 0; i < N; ++i)  {    if(diag[i] != 0.0)      for (j = 0; j < i; ++j)      {	for (k = i-1, tmp = 0.0; k >= 0; --k)	  tmp += ma[i][k] * ma[k][j];        for (k = i-1; k >= 0; --k)	  ma[k][j] -= tmp*ma[k][i];      } /* for j   */    diag[i] = ma[i][i];    ma[i][i] = 1.0;    for (k = i-1; k >= 0; --k)      ma[k][i] = ma[i][k] = 0.0;  } /* for i */}/*  QL-Algorithmus mit implizitem Shift, zur Berechnung von Eigenwerten  und -vektoren einer symmetrischen Tridiagonalmatrix.   -> n     : Dimension.   -> diag        : Diagonale der Tridiagonalmatrix.   -> neben[0..n-1] : Nebendiagonale (==0..n-2), n-1. Eintrag beliebig  -> mq    : Matrix output von Householder()   -> maxIt : maximale Zahl der Iterationen   <- diag  : Eigenwerte  <- neben : Garbage  <- mq    : k-te Spalte ist normalisierter Eigenvektor zu diag[k]  */static int QLalgo( int N, valarray<double>& diag, square_matrix& mq, 	int maxIter, double* neben){  int i, j, k, kp1, l;  double tmp, diff, cneben, c1, c2, p;  int iter;  neben[N-1] = 0.0;  for (i = 0, iter = 0; i < N && iter < maxIter; ++i)    do /* while j != i */    {      for (j = i; j < N-1; ++j)      {	tmp = fabs(diag[j]) + fabs(diag[j+1]);	if (fabs(neben[j]) + tmp == tmp)	  break;      }      if (j != i)      {	if (++iter > maxIter) return maxIter-1;	diff = (diag[i+1]-diag[i])/neben[i]/2.0;	if (diff >= 0)	  diff = diag[j] - diag[i] + 	    neben[i] / (diff + sqrt(diff * diff + 1.0));	else	  diff = diag[j] - diag[i] + 	    neben[i] / (diff - sqrt(diff * diff + 1.0));	c2 = c1 = 1.0;	p = 0.0;	for (k = j-1; k >= i; --k)	{	  kp1 = k + 1;	  tmp = c2 * neben[k];	  cneben = c1 * neben[k];	  if (fabs(tmp) >= fabs(diff))	  {	    c1 = diff / tmp;	    c2 = 1. / sqrt(c1*c1 + 1.0);	    neben[kp1] = tmp / c2;	    c1 *= c2;	  }	  else	  {	    c2 = tmp / diff;	    c1 = 1. / sqrt(c2*c2 + 1.0);	    neben[kp1] = diff / c1;	    c2 *= c1;	  } /* else */	  tmp = (diag[k] - diag[kp1] + p) * c2 + 2.0 * c1 * cneben;	  diag[kp1] += tmp * c2 - p;	  p = tmp * c2;	  diff = tmp * c1 - cneben;	  for (l = N-1; l >= 0; --l) /* TF-Matrix Q */	  { 	    tmp = mq[l][kp1];	    mq[l][kp1] = c2 * mq[l][k] + c1 * tmp;	    mq[l][k] = c1 * mq[l][k] - c2 * tmp;	  } /* for l */	} /* for k */	diag[i] -= p;	neben[i] = diff;	neben[j] = 0.0;      } /* if */    } while (j != i);  return iter;} /* QLalgo() *//* ========================================================= *//*    Calculating eigenvalues and vectors.    Input:      N: dimension.     C: lower_triangular NxN-matrix.     niter: number of maximal iterations for QL-Algorithm.      rgtmp: N+1-dimensional vector for temporal use.    Output:      diag: N eigenvalues.     Q: Columns are normalized eigenvectors.     return: number of iterations in QL-Algorithm. */namespace eo {int eig( int N,  const lower_triangular_matrix& C, valarray<double>& diag, square_matrix& Q,        int niter){  int ret;  int i, j;  if (niter == 0) niter = 30*N;  for (i=0; i < N; ++i)  {      vector<double>::const_iterator row = C[i];      for (j = 0; j <= i; ++j)	  Q[i][j] = Q[j][i] = row[j];  }    double* rgtmp = new double[N+1];  Householder( N, Q, diag, rgtmp);  ret = QLalgo( N, diag, Q, niter, rgtmp+1);  delete [] rgtmp;    return ret;}  } // namespace eo

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -