#include <iostream>
#include "alglib/cpp/src/optimization.h"

void radius(const alglib::real_1d_array& x, double& value, 
                 alglib::real_1d_array& grad, void*) {
	value = 0.;
    for (auto i = 0; i < x.length(); ++i) {
        value += x[i] * x[i];
        grad[i] = 2. * x[i];
    }
}

int main()
{   
	alglib::minbleicstate state;
    // Initials
    alglib::real_1d_array initials;
    initials.setlength(14);
    for (auto i = 0; i < 8; ++i) {
        initials[i] = 1.;
    }
    for (auto i = 8; i < 14; ++i) {
        initials[i] = 0.;
    }
    alglib::minbleiccreate(14, initials, state);

    // Box constraints
    alglib::real_1d_array lowers;
    alglib::real_1d_array uppers;
    lowers.setlength(14);
    uppers.setlength(14);
    for (auto i = 0; i < 14; ++i) {
        lowers[i] = 0;
        uppers[i] = std::numeric_limits<double>::infinity();
    }
    alglib::minbleicsetbc(state, lowers, uppers);

    // Linear constraint

    alglib::real_2d_array constraints;
    alglib::integer_1d_array constraint_types;
    constraints.setlength(1, 15);
    constraint_types.setlength(1);
    for (auto i = 0; i < 10; ++i) {
        constraints[0][i] = 1.;
    }
    constraints[0][10] = -1.;
    constraints[0][11] = -1.;
    constraints[0][12] = 0.5;
    constraints[0][13] = 0.5;
    constraints[0][14] = 8.; // Total.
    constraint_types[0] = 0;

    alglib::minbleicsetlc(state, constraints, constraint_types, 1);

    alglib::minbleicsetcond(state, 0, 0, 0, 0); // Automatic stopping conditions.

    alglib::minbleicoptimize(state, radius);

    alglib::minbleicreport report;
    alglib::real_1d_array bestSolution;
    bestSolution.setlength(18);
    alglib::minbleicresults(state, bestSolution, report);
    std::cout << "Termination code is " << report.terminationtype << "\n";
    return 0;
}