#include "maxstar.h"

maxstar::maxstar()
{
    this->approx_maxstar_method = 1;
};

maxstar::maxstar(int approx_maxstar_method)
{
    initialize(approx_maxstar_method);
};

void maxstar::initialize(int approx_maxstar_method)
{
    this->approx_maxstar_method = approx_maxstar_method;
};

vec maxstar::approximation(mat input)
{
    vec out;
    vec difference;
    if (this->approx_maxstar_method==1)
        // Max-Log-MAP approximation
        out = itpp::max(input);
    else
    {
        if (input.rows()==1)
            input = input.transpose();
        out = input.get_row(0);
        for (int i=1; i<input.rows(); i++)
        {
            difference = out - input.get_row(i);

            for (int j=0; j<input.cols(); j++)
            {
                if (abs(difference(j))>=INFINITY)
                    difference(j) = 0;
                // Log-MAP approximation
                out(j) = std::max(out(j),input(i,j)) + std::log(1+exp(-abs(difference(j))));
            };

        }
    }

    return out;
};

double maxstar::approximation(vec input)
{
    double out;
    double difference;
    if (this->approx_maxstar_method==1)
    {
        // Max-Log-MAP approximation
        out = (double) itpp::max(input);
//cout << "running MAX-LOG-MAP....!" << endl;
    }
    else
    {
        out = input(0);
        for (int j=1; j<input.length();j++)
        {
            difference = out - input(j);
            if (abs(difference)>=INFINITY)
                difference = 0;
            // Log-MAP approximation
            out = std::max(out,input(j)) + std::log(1+exp(-abs(difference)));
        }
    }

    return out;
};
