/***************************************************************************
**
**  This file is part of QGpCoreMath.
**
**  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.
**
**  This file 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.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2002-10-14
**  Copyright: 2002-2019
**    Marc Wathelet
**    Marc Wathelet (ULg, Liège, Belgium)
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "ProcessStatistics.h"

namespace QGpCoreMath {

void ProcessStatistics::add(double newval)
{
  TRACE;
  // This way of computing the standard deviation is approximative
  // See chapter 14-1 from Numerical recipes for explanations
  // It does not correct the round-off errors
  _count++;
  _sumxi+=newval;
  _sumxi2+=newval*newval;
}

void ProcessStatistics::addLog(double newval)
{
  TRACE;
  double lv=log10(newval);
  _count++;
  _sumxi+=lv;
  _sumxi2+=lv*lv;
}

void ProcessStatistics::current(double& mean, double& stddev)
{
  TRACE;
  mean=_sumxi/_count;
  double var=(_sumxi2-mean*mean*_count)/(_count-1);
  if(var>0.0) stddev=::sqrt(var); else stddev=0.0;
}

void ProcessStatistics::currentLog(double& mean, double& stddev)
{
  TRACE;
  mean=_sumxi/_count;
  double var=(_sumxi2-mean*mean*_count)/(_count-1);
  if(var>0.0) {
    stddev=::sqrt(var);
    stddev =::pow(10.0, stddev);
  }
  else stddev=0.0;
  mean =::pow(10.0, mean);
}

double ProcessStatistics::stddev()
{
  TRACE;
  double mean=_sumxi/_count;
  double var=(_sumxi2-mean*mean*_count)/(_count-1);
  if(var>0.0) return ::sqrt(var); else return 0.0;
}

double ProcessStatistics::stddevLog()
{
  TRACE;
  double mean=_sumxi/_count;
  double var=(_sumxi2-mean*mean*_count)/(_count-1);
  if(var>0.0) return ::pow(10.0, ::sqrt(var)); else return 0.0;
}

RealStatisticalValue ProcessStatistics::value()
{
  TRACE;
  RealStatisticalValue v;
  double mean, stddev;
  current(mean, stddev);
  v.setMean(mean);
  v.setStddev(stddev);
  v.setWeight(_count);
  return v;
}

RealStatisticalValue ProcessStatistics::valueLog()
{
  TRACE;
  RealStatisticalValue v;
  double mean, stddev;
  currentLog(mean, stddev);
  v.setMean(mean);
  v.setStddev(stddev);
  v.setWeight(_count);
  return v;
}

} // namespace QGpCoreMath
