# dlib C++ Library - isotonic_regression.cpp

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

    #include <dlib/optimization.h>
    #include <dlib/global_optimization.h>
    #include <sstream>
    #include <string>
    #include <cstdlib>
    #include <ctime>
    #include <vector>

    #include "tester.h"

    namespace
    {

        using namespace test;
        using namespace dlib;
        using namespace std;

        logger dlog("test.isotonic_regression");

    // ----------------------------------------------------------------------------------------

        class optimization_tester : public tester
        {
        public:
            optimization_tester (
            ) :
                tester ("test_isotonic_regression",
                        "Runs tests on the isotonic_regression object.")
            {}

            void perform_test (
            )
            {
                dlib::rand rnd;

                for (int round = 0; round < 100; ++round)
                {
                    print_spinner();
                    std::vector<double> vect;
                    for (int i = 0; i < 5; ++i)
                        vect.push_back(put_in_range(-1,1,rnd.get_random_gaussian()));

                    auto f = [&](const matrix<double,0,1>& x)
                    {
                        double dist = 0;
                        double sum = 0;
                        for (long i = 0; i < x.size(); ++i)
                        {
                            sum += x(i);
                            dist += (sum-vect[i])*(sum-vect[i]);
                        }
                        return dist;
                    };

                    auto objval = [vect](const matrix<double,0,1>& x)
                    {
                        return sum(squared(mat(vect)-x));
                    };

                    auto is_monotonic = [](const matrix<double,0,1>& x)
                    {
                        for (long i = 1; i < x.size(); ++i)
                        {
                            if (x(i-1) > x(i))
                                return false;
                        }
                        return true;
                    };

                    matrix<double,0,1> lower(5), upper(5);
                    lower = 0;
                    lower(0) = -4;
                    upper = 4;
                    // find the solution with find_min_global() and then check that it matches
                    auto result = find_min_global(f, lower, upper, max_function_calls(40));

                    for (long i = 1; i < result.x.size(); ++i)
                        result.x(i) += result.x(i-1);

                    isotonic_regression mr;
                    mr(vect);

                    dlog << LINFO << "err: "<<  objval(mat(vect)) - objval(result.x);

                    DLIB_CASSERT(is_monotonic(mat(vect)));
                    DLIB_CASSERT(is_monotonic(result.x));
                    // isotonic_regression should be at least as good as find_min_global().
                    DLIB_CASSERT(objval(mat(vect)) - objval(result.x) < 1e-13);
                }

            }
        } a;

    }