2 // ********************************************************************
 
    3 // * License and Disclaimer                                           *
 
    5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
 
    6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
 
    7 // * conditions of the Geant4 Software License,  included in the file *
 
    8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
 
    9 // * include a list of copyright holders.                             *
 
   11 // * Neither the authors of this software system, nor their employing *
 
   12 // * institutes,nor the agencies providing financial support for this *
 
   13 // * work  make  any representation or  warranty, express or implied, *
 
   14 // * regarding  this  software system or assume any liability for its *
 
   15 // * use.  Please see the license in the file  LICENSE  and URL above *
 
   16 // * for the full disclaimer and the limitation of liability.         *
 
   18 // * This  code  implementation is the result of  the  scientific and *
 
   19 // * technical work of the GEANT4 collaboration.                      *
 
   20 // * By using,  copying,  modifying or  distributing the software (or *
 
   21 // * any work based  on the software)  you  agree  to acknowledge its *
 
   22 // * use  in  resulting  scientific  publications,  and indicate your *
 
   23 // * acceptance of all terms of the Geant4 Software license.          *
 
   24 // ********************************************************************
 
   27 // $Id: G4SimplexDownhill.icc 67970 2013-03-13 10:10:06Z gcosmo $
 
   29 // Author: Tatsumi Koi (SLAC/SCCS), 2007
 
   30 // --------------------------------------------------------------------------
 
   36 template<class T> void G4SimplexDownhill<T>::init()
 
   38    alpha = 2.0;  // refrection coefficient:  0 < alpha
 
   39    beta = 0.5;   // contraction coefficient:   0 < beta < 1 
 
   40    gamma = 2.0;  // expantion coefficient:  1 < gamma
 
   42    maximum_no_trial = 10000;
 
   44    //max_ratio = FLT_EPSILON/1;
 
   45    max_ratio = DBL_EPSILON/1;
 
   52 void G4SimplexDownhill<class T>::
 
   53 SetFunction( G4int n , G4double( *afunc )( std::vector < G4double > ) ) 
 
   64 G4double G4SimplexDownhill<T>::GetMinimum()
 
   71    //G4cout << "Begin First Trials" << G4endl;
 
   73    //G4cout << "End First Trials" << G4endl;
 
   75    std::vector< G4double >::iterator it_minh =
 
   76       std::min_element( currentHeights.begin() , currentHeights.end() );
 
   79    for ( std::vector< G4double >::iterator it = currentHeights.begin();
 
   80          it != currentHeights.end(); it++ )
 
   88    minimumPoint = currentSimplex[ imin ];
 
   92    //std::vector< G4double > minimumPoint = currentSimplex[ 0 ];
 
   95    currentSimplex[ numberOfVariable ] = minimumPoint;
 
   97    //G4cout << "Begin Second Trials" << G4endl;
 
   99    //G4cout << "End Second Trials" << G4endl;
 
  101    G4double sum = std::accumulate( currentHeights.begin() ,
 
  102                                    currentHeights.end() , 0.0 );
 
  103    G4double average = sum/(numberOfVariable+1); 
 
  104    G4double minimum = average;
 
  115 void G4SimplexDownhill<T>::initialize()
 
  118    currentSimplex.resize( numberOfVariable+1 );
 
  119    currentHeights.resize( numberOfVariable+1 );
 
  121    for ( G4int i = 0 ; i < numberOfVariable ; i++ ) 
 
  123       std::vector< G4double > avec ( numberOfVariable , 0.0 ); 
 
  125       currentSimplex[ i ] = avec;
 
  128    //std::vector< G4double > avec ( numberOfVariable , 0.0 ); 
 
  129    std::vector< G4double > avec ( numberOfVariable , 1 ); 
 
  130    currentSimplex[ numberOfVariable ] = avec;
 
  137 void G4SimplexDownhill<T>::calHeights()
 
  140    for ( G4int i = 0 ; i <= numberOfVariable ; i++ ) 
 
  142       currentHeights[i] = getValue ( currentSimplex[i] );
 
  150 std::vector< G4double > G4SimplexDownhill<T>::calCentroid( G4int ih )
 
  153     std::vector< G4double > centroid ( numberOfVariable , 0.0 );
 
  156     for ( std::vector< std::vector< G4double > >::iterator
 
  157           it = currentSimplex.begin(); it != currentSimplex.end() ; it++ )
 
  161           for ( G4int j = 0 ; j < numberOfVariable ; j++ ) 
 
  163              centroid[j] += (*it)[j]/numberOfVariable;
 
  175 std::vector< G4double > G4SimplexDownhill<T>::
 
  176 getReflectionPoint( std::vector< G4double > p ,
 
  177                     std::vector< G4double > centroid )
 
  179    //G4cout << "Reflection" << G4endl;
 
  181    std::vector< G4double > reflectionP ( numberOfVariable , 0.0 );
 
  183    for ( G4int i = 0 ; i < numberOfVariable ; i++ )
 
  185       reflectionP[ i ] = ( 1 + alpha ) * centroid[ i ] - alpha * p[ i ];
 
  194 std::vector< G4double > G4SimplexDownhill<T>::
 
  195 getExpansionPoint( std::vector< G4double > p ,
 
  196                    std::vector< G4double > centroid )
 
  198    //G4cout << "Expantion" << G4endl;
 
  200    std::vector< G4double > expansionP ( numberOfVariable , 0.0 );
 
  202    for ( G4int i = 0 ; i < numberOfVariable ; i++ )
 
  204       expansionP[i] = ( 1 - gamma ) * centroid[i] + gamma * p[i];
 
  211 std::vector< G4double > G4SimplexDownhill<T>::
 
  212 getContractionPoint( std::vector< G4double > p ,
 
  213                      std::vector< G4double > centroid )
 
  215    //G4cout << "Contraction" << G4endl;
 
  217    std::vector< G4double > contractionP ( numberOfVariable , 0.0 );
 
  219    for ( G4int i = 0 ; i < numberOfVariable ; i++ )
 
  221       contractionP[i] = ( 1 - beta ) * centroid[i] + beta * p[i];
 
  230 G4bool G4SimplexDownhill<T>::isItGoodEnough()
 
  232    G4bool result = false;
 
  234    G4double sum = std::accumulate( currentHeights.begin() ,
 
  235                                    currentHeights.end() , 0.0 );
 
  236    G4double average = sum/(numberOfVariable+1); 
 
  237    //G4cout << "average " << average << G4endl;
 
  239    G4double delta = 0.0; 
 
  240    for ( G4int i = 0 ; i <= numberOfVariable ; i++ )
 
  242       delta += std::abs ( currentHeights[ i ] - average );  
 
  244    //G4cout << "ratio of delta to average is "
 
  245    //       << delta / (numberOfVariable+1) / average << G4endl;
 
  247    if ( delta/(numberOfVariable+1)/average < max_ratio )
 
  253    G4double sigma = 0.0; 
 
  254    G4cout << "average " << average << G4endl;
 
  255    for ( G4int i = 0 ; i <= numberOfVariable ; i++ )
 
  257       sigma += ( currentHeights[ i ] - average )
 
  258               *( currentHeights[ i ] - average );  
 
  261    G4cout << "standard error of hs "
 
  262           << std::sqrt ( sigma ) / (numberOfVariable+1) << G4endl;
 
  263    if ( std::sqrt ( sigma ) / (numberOfVariable+1) < max_se )
 
  275 void G4SimplexDownhill<T>::doDownhill()
 
  280    while ( nth_trial < maximum_no_trial )
 
  284       G4cout << "Begining " << nth_trial << "th trial " << G4endl;
 
  285       for ( G4int j = 0 ; j <= numberOfVariable ; j++ )
 
  287          G4cout << "SimplexPoint " << j << ": "; 
 
  288          for ( G4int i = 0 ; i < numberOfVariable ; i++ )
 
  290              G4cout << currentSimplex[j][i] 
 
  299       if ( isItGoodEnough() ) 
 
  304       std::vector< G4double >::iterator it_maxh =
 
  305         std::max_element( currentHeights.begin() , currentHeights.end() );
 
  306       std::vector< G4double >::iterator it_minh =
 
  307         std::min_element( currentHeights.begin() , currentHeights.end() );;
 
  309       G4double h_H = *it_maxh;
 
  310       G4double h_L = *it_minh;
 
  316       for ( std::vector< G4double >::iterator 
 
  317             it = currentHeights.begin(); it != currentHeights.end(); it++ )
 
  325             h_H2 = std::max( h_H2 , *it );
 
  335       //G4cout << "max " << h_H << " " << ih << G4endl;
 
  336       //G4cout << "max-dash " << h_H2 << G4endl;
 
  337       //G4cout << "min " << h_L << " " << il << G4endl;
 
  339       std::vector< G4double > centroidPoint = calCentroid ( ih );
 
  342       std::vector< G4double > reflectionPoint =
 
  343         getReflectionPoint( currentSimplex[ ih ] , centroidPoint );
 
  345       G4double h = getValue( reflectionPoint );
 
  350          std::vector< G4double > expansionPoint =
 
  351            getExpansionPoint( reflectionPoint , centroidPoint );
 
  352          G4double hh = getValue( expansionPoint );
 
  357             currentSimplex[ ih ] = expansionPoint;
 
  358             //G4cout << "A" << G4endl;
 
  363             currentSimplex[ ih ] = reflectionPoint;
 
  364             //G4cout << "B1" << G4endl;
 
  372             currentSimplex[ ih ] = reflectionPoint;
 
  373             //G4cout << "B2" << G4endl;
 
  380               currentSimplex[ ih ] = reflectionPoint;
 
  381               //G4cout << "BC" << G4endl;
 
  384             std::vector< G4double > contractionPoint =
 
  385               getContractionPoint( currentSimplex[ ih ] , centroidPoint );
 
  386             G4double hh = getValue( contractionPoint );
 
  390                currentSimplex[ ih ] = contractionPoint;
 
  391                //G4cout << "C" << G4endl;
 
  396                for ( G4int j = 0 ; j <= numberOfVariable ; j++ ) 
 
  398                   std::vector< G4double > vec ( numberOfVariable , 0.0 );
 
  399                   for ( G4int k = 0 ; k < numberOfVariable ; k++ ) 
 
  401                      vec[ k ] = ( currentSimplex[ j ][ k ]
 
  402                                 + currentSimplex[ il ][ k ] ) / 2.0;
 
  404                   currentSimplex[ j ] = vec;
 
  406                //G4cout << "D" << G4endl;
 
  419 std::vector< G4double > G4SimplexDownhill<T>::GetMinimumPoint()
 
  421    if ( minimized != true )
 
  426    std::vector< G4double >::iterator it_minh =
 
  427      std::min_element( currentHeights.begin() , currentHeights.end() );;
 
  430    for ( std::vector< G4double >::iterator 
 
  431          it = currentHeights.begin(); it != currentHeights.end(); it++ )
 
  439    minimumPoint = currentSimplex[ imin ];