#include "logistic.h"
       
using namespace scl;
using namespace std; 

int main(int argc, char** argp, char** envp)
{
  logistic_neg_log_likelihood lnll;
  INTEGER p = lnll.get_p();
  INTEGER n = lnll.get_n();
  nlopt minimizer(lnll);
  ofstream fout("mle.out");
  minimizer.set_output(true, &fout);
  minimizer.set_check_derivatives(true);
  minimizer.set_warning_messages(true);
  realmat b_start(p,1); realmat b_stop;
  b_start[1] = 1.0; b_start[2] = 1.5; b_start[3] = 2.1; b_start[4] = 0.75;
  bool rv = minimizer.minimize(b_start, b_stop);
  if (rv) {
    fout << starbox("/The Answer!//Estimate & Standard Error//");
    realmat V = invpsd(lnll.get_information_matrix(b_stop))/n;
    realmat stderr(p,1); for (INTEGER i=1; i<=p; ++i) stderr[i] = sqrt(V(i,i));
    fout << cbind(b_stop,stderr) << '\n';
    fout << starbox("/Status//") << '\n';
    fout << "\t termination_code = " << minimizer.get_termination_code()<<'\n';
    fout << "\t iter_count = " << minimizer.get_iter_count() << '\n';
    fout << "\t Variance estimate = " << V << '\n';
    fout << "\t H = " << minimizer.get_H_matrix() << '\n';
    return 0;
  }
  else {
    fout << starbox("/Failure/Check your derivatives!//") << '\n';
    realmat f, F;
    rv = lnll.get_F(b_start,f,F);
    fout << "get_F returns " << boolalpha << rv << F << '\n';
    rv = lnll.get_numerical_F(b_start,f,F);
    fout << "get_numerical_F returns " << rv << F << '\n';
    return 1;
  }
}
