/***************************************************************************
**
**  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: 2006-09-07
**  Copyright: 2006-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "Curve.h"

namespace QGpCoreMath {

  /*!
    \class Curve Curve.h
    \brief Template class for a curve
    It is a vector of "points" that may eventually contain extra data. The "point" type must at least have the
    following functions:

    \li double x() const;
    \li void setX(double);
    \li double y() const;
    \li void setY(double);
    \li void interpole(double valX, const pointType& p1, const pointType& p2);
    \li void average(const pointType& p) const;
    \li void setValid(bool v);
    \li bool isValid() const;
  */

  /*!
    \fn void Curve::sort()
    Sort points by increasing x and remove duplicates if any, so that only one Y corresponds to each X.
  */

  /*!
    \fn void Curve::checkSort()
    Check if X are properly sorted and unique. Internal sort flag is set accordingly.
  */

  /*!
    \fn void Curve::isSorted()
    Return true is X values are sorted.
  */

  /*!
    \fn int Curve<pointType>::indexAfter (double valX)
    Returns the index for which x() is just greater or equal to valX.
    Returns indexes from 0 to count(). Uses dichotomy, best for functions with
    more than 10 values. Assumes that points are
    sorted (setFunction() called before).
  */

  /*!
    \fn void Curve::resample(int n, double min, double max, ::SamplingOptions options, double valX, double valY)
    Resamples the curve with a constant adimensional distance between samples.
    \a valX and \a valY are representative values used to adimensionalize.
    Select identical values if X and Y have the same dimensions.
    If options has Function flag, \a n samples are taken starting from \a min (x) to \a max (x).
    Extrapolation is performed but resulting new samples are set as invalid.

    Accepted \a options are Function, InversedScale and LogScale.
  */

  /*!
    \fn void Curve::resample(int n, double min, double max, ::SamplingOptions options)
    Resamples the curve with \a n samples from \a min to \a max

    Accepted \a options are InversedScale and LogScale, option Function is mandatory and you must call setFunction() before.
  */

  /*!
    \fn void Curve::resample(const Curve<pointType>& xModel, ::SamplingOptions options)
    Resample the function at x defined by xModel (x() of xModel)

    Accepted \a options are Interpole, option Function is mandatory and you must call setFunction() before.
  */

  /*!
    \fn void Curve::resample(const QVector<double>& xModel, ::SamplingOptions options)
    Resample the function at x defined by xModel (e.g. from another curve)

    Accepted \a options are Interpole, option Function is mandatory and you must call setFunction() before.
  */

  /*!
    \fn void Curve::cut(double min, double max, ::SamplingOptions options)
    Cut function between \a min and \a max considering these limits expressed in a linear or
    inversed scale.

    Accepted \a options are LinearScale or InversedScale, option Function is mandatory and you must call setFunction() before.
  */

  /*!
    \fn void Curve::validate(double min, double max, ::SamplingOptions options, bool value)
    Validate or invalidate function between \a min and \a max considering these limits expressed in a linear or
    inversed scale.

    Accepted \a options are LinearScale or InversedScale, option Function is mandatory and you must call setFunction() before.
  */

  /*!
    \fn void Curve::smooth(const SamplingParameters& sampling, const SmoothingParameters& param)
    Smooth function between two x values
  */

  /*!
    \fn void Curve::average(const Curve<pointType>& curve)
    Average this function with \a curve and put the result in this curve.
  */

  /*!
    \fn void Curve::setValid(bool v)
    Set all point as valid or not valid according to \a v.
  */

  /*!
    \fn void Curve::removeInvalid()
    Remove invalid points
  */

  /*!
    \fn void Curve::swapXY()
    Swap x() and y(), if the curve is a function, mandatory to call setFunction() again, except if monotoneous.
  */

  /*!
    \fn void Curve::log10()
    Order not modified, just take _x=log10(_x)
  */

  /*!
    \fn void Curve::exp10()
    Order not modified, just take _x=10^_x
  */

  /*!
    \fn Curve::inverse( ::SamplingOptions options)
    Order of _x values must be changed, inverse x values
  */

  /*!
    \fn const pointType& Curve::minimumY()
    Return the point at minimum Y value
  */

  /*!
    \fn const pointType& Curve::maximumY()
    Return the point at maximum Y value
  */

  /*! \fn void Curve::line(double x1, double y1, double x2, double y2)
    Construct a basic line curve between (\a x1 , \a y1) and ( \a x2 , \a y2)

    The resulting curve is not necessarely a function.
  */

  /*! \fn void Curve::closestMax(int index)
    Return the local maxima close to index either on the left or right side
  */

  /*!
    \fn int Curve::max()
    Return the index of the maximum value. Return -1 if the curve is empty.
  */

  /*!
    \fn void Curve::indexRange(double xMin, double xMax, int& indexMin, int& indexMax)
    Return the \a indexMin \a and indexMax that just enclose \a xMin and \aMax.
    Initial values of \a indexMin \a and indexMax are taken into account. The interval
    is never enlarged.
  */

  /*!
    \fn int Curve<pointType>::indexAfter(double valX) const

    Return the index of the point after or at \a valX.
    Returned value in between 0 and count().
    count() is returned if \a valX is after the last point.
  */

} // namespace QGpCoreMath
