// Copyright (C) 2018  Davis E. King (davis@dlib.net)
// License: Boost Software License   See LICENSE.txt for the full license.
#undef DLIB_ISOTONIC_ReGRESSION_ABSTRACT_H_
#ifdef DLIB_ISOTONIC_ReGRESSION_ABSTRACT_H_

#include <vector>

namespace dlib
{
    class isotonic_regression
    {
        /*!
            WHAT THIS OBJECT REPRESENTS
                This object is a tool for performing 1-D isotonic regression. That is, it
                finds the least squares fit of a non-parametric curve to some user supplied
                data, subject to the constraint that the fitted curve is non-decreasing.

                This is done using the fast O(n) pool adjacent violators algorithm.
        !*/

    public:

        template <
            typename const_iterator, 
            typename iterator
            >
        void operator() (
            const_iterator begin,
            const_iterator end,
            iterator obegin
        );
        /*!
            requires
                - [begin,end) is an iterator range of float or doubles.
                - obegin points to an iterator range at least std::distance(begin,end) in
                  size which is capable of storing double or float values.
            ensures
                - Given the range of real values stored in [begin,end), this method performs isotonic regression
                  on this data and writes the results to obegin.  To be specific:
                    - let IN refer to the input values stored in the iterator range [begin,end).
                    - let OUT refer to the output values stored in the iterator range [obegin, obegin+std::distance(begin,end)).
                    - This function populates OUT with values such that the sum_i of
                      (IN[i]-OUT[i])^2 is minimized, subject to the constraint that 
                      OUT[i] <= OUT[i+1], i.e. that OUT is monotonic.
                - It is OK for [begin,end) to overlap with the range pointed to by obegin.
                  That is, this function can run in-place.
        !*/

        void operator() (
            std::vector<double>& vect
        ) { (*this)(vect.begin(), vect.end(), vect.begin()); }
        /*!
            ensures
                - performs in-place isotonic regression.  Therefore, #vect will contain the
                  isotonic regression of vect.
                - #vect.size() == vect.size()
        !*/

    };
}

#endif // DLIB_ISOTONIC_ReGRESSION_ABSTRACT_H_



