/*-------------------------------------------------------------------------------------*/
/*  NOMAD - Nonsmooth Optimization by Mesh Adaptive Direct search - version 3.0.0      */
/*                                                                                     */
/*  Copyright (C) 2001-2008  Mark Abramson        - the Boeing Company, Seattle        */
/*                           Charles Audet        - Ecole Polytechnique, Montreal      */
/*                           Gilles Couture       - Ecole Polytechnique, Montreal      */
/*                           John Dennis          - Rice University, Houston           */
/*                           Sebastien Le Digabel - Ecole Polytechnique, Montreal      */
/*                                                                                     */
/*  funded in part by AFOSR and Exxon Mobil                                            */
/*                                                                                     */
/*  Author: Sebastien Le Digabel                                                       */
/*                                                                                     */
/*  Contact information:                                                               */
/*    Ecole Polytechnique de Montreal - GERAD                                          */
/*    C.P. 6079, Succ. Centre-ville, Montreal (Quebec) H3C 3A7 Canada                  */
/*    e-mail: Sebastien.Le.Digabel@gerad.ca                                            */
/*    phone : 1-514-340-6053 #6673                                                     */
/*    fax   : 1-514-340-5665                                                           */
/*                                                                                     */
/*  This program is free software: you can redistribute it and/or modify it under the  */
/*  terms of the GNU General Public License as published by the Free Software          */
/*  Foundation, either version 3 of the License, or (at your option) any later         */
/*  version.                                                                           */
/*                                                                                     */
/*  This program 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 General Public License for more details.          */
/*                                                                                     */
/*  You should have received a copy of the GNU General Public License along with this  */
/*  program. If not, see <http://www.gnu.org/licenses/>.                               */
/*                                                                                     */
/*  You can find information on the NOMAD software at www.gerad.ca/nomad               */
/*-------------------------------------------------------------------------------------*/
#include "Stats.hpp"
using namespace std;

/*---------------------------------------------------------*/
/*                        constructor                      */
/*---------------------------------------------------------*/
Stats::Stats ( int sgte_cost ) : _sgte_cost(sgte_cost) { reset(); }

/*---------------------------------------------------------*/
/*                      reset the stats                    */
/*---------------------------------------------------------*/
void Stats::reset ( void ) {
  _eval             = 0;
  _sim_bb_eval      = 0;
  _sgte_eval        = 0;
  _bb_eval          = 0;
  _failed_eval      = 0;
  _cache_hits       = 0;
  _interrupted_eval = 0;
  _iterations       = 0;
  _poll_pts         = 0;
  _poll_success     = 0;
  _spec_pts         = 0;
  _spec_success     = 0;
  _LH_pts           = 0;
  _LH_success       = 0;
  _p1_iterations    = 0;
  _p1_bbe           = 0;
  _clock.reset();

  _stat_sum.clear();
  _stat_avg.clear();
  _cnt_avg = 0;
}

/*---------------------------------------------------------*/
/*                      update _stat_sum                   */
/*---------------------------------------------------------*/
void Stats::update_stat_sum ( const NOMAD::Double & d ) {
  if ( !d.is_defined() )
    return;

  if ( _stat_sum.is_defined() )
    _stat_sum += d;
  else
    _stat_sum  = d;
}

/*---------------------------------------------------------*/
/*                      update _stat_avg                   */
/*---------------------------------------------------------*/
void Stats::update_stat_avg ( const NOMAD::Double & d ) {
  if ( !d.is_defined() )
    return;

  if ( _stat_avg.is_defined() )
    _stat_avg += d;
  else
    _stat_avg  = d;
  ++_cnt_avg;
}

/*---------------------------------------------------------*/
/*                          display                        */
/*---------------------------------------------------------*/
void Stats::display ( ostream & out , int display_degree ) const {
  out << "\titerations                      : " << _iterations;
  if ( _p1_iterations > 0 )
    out << " (phase one: " << _p1_iterations << ")";
  out << endl;
  if ( _sgte_cost > 0 )
    out << "\tbb evaluations (with sgte cost) : " << get_bb_eval();
  else
    out << "\tblack-box evaluations           : " << _bb_eval;
  if ( _p1_bbe > 0 )
    out << " (phase one: " << _p1_bbe << ")";
  out << "\n\tsimulated black-box evaluations : " << _sim_bb_eval         << endl;
  out << "\tevaluations                     : "   << _eval                << endl;
  if ( _sgte_cost > 0 || _sgte_eval > 0 )
    out << "\tsurrogate evaluations           : " << _sgte_eval           << endl;
  out << "\tfailed evaluations              : " << _failed_eval;
  if (_failed_eval > 0 && _failed_eval==_bb_eval+_sgte_eval)
    out << " (all evaluations failed)";
  out << endl;
  if ( display_degree > 3 )
    out << "\tinterrupted sequences of eval.  : " << _interrupted_eval    << endl;
  out << "\tcache hits                      : " << _cache_hits            << endl
      << "\tpoll points                     : " << _poll_pts              << endl
      << "\tpoll successes                  : " << _poll_success          << endl
      << "\tspeculative search points       : " << _spec_pts              << endl
      << "\tspeculative search successes    : " << _spec_success          << endl
      << "\tLatin-Hypercube search points   : " << _LH_pts                << endl
      << "\tLatin-Hypercube search successes: " << _LH_success            << endl
      // << "\tcpu time                        : " << _clock.get_cpu_time()  << "s\n"
      << "\twall-clock time                 : " << _clock.get_real_time() << "s\n";
  if ( _stat_sum.is_defined() )
    out << "\tstat sum                        : " << _stat_sum            << endl;
  if ( _stat_avg.is_defined() )
    out << "\tstat avg                        : " << get_stat_avg()       << endl;
}
