#include <func/func.hpp>
#include <iostream>
#include <armadillo>
#include <vector>
#include <boost/multiprecision/cpp_bin_float.hpp>

#include "../sample_functions/gamma.hpp"

#define MIN_STEP_EXP -5
#define NUM_SAMPLES 30

/* plot how TOUT affects the error in any LUT implementation */
int main() {
  using namespace func;
  using namespace boost::multiprecision;

  std::vector<std::string> implNames {
    "UniformExactInterpTable<3>",
  };

  std::cout << FUNCNAME << " over [" << MIN_ARG << ", " << MAX_ARG << "]\n";

  LookupTableGenerator<float,float,double> gen1({FUNC_SET_F(MyFunction,float)},MIN_ARG,MAX_ARG);
  LookupTableGenerator<double,double,cpp_bin_float_quad> gen2({FUNC_SET_F(MyFunction,double)},MIN_ARG,MAX_ARG);
  LookupTableGenerator<cpp_bin_float_quad,cpp_bin_float_quad,cpp_bin_float_oct> gen3({FUNC_SET_F(MyFunction,cpp_bin_float_quad)},MIN_ARG,MAX_ARG);

  // print each implementation name in one long row
  std::cout << "Step size |Error" << "\n";
  for(auto name : implNames){
    std::cout << name << "_float ";
    std::cout << name << "_double ";
    std::cout << name << "_quad ";
  }
  std::cout << "\n";

  // step sizes are some fraction of the max reasonable step size
  arma::vec stepsizes = arma::logspace(MIN_STEP_EXP, log10((MAX_ARG-MIN_ARG)/2), NUM_SAMPLES);
  std::cerr << "plotting " << NUM_SAMPLES << " logspaced points" << std::endl;
  for(double h : stepsizes){
    std::cout << h << " ";
    for(auto name : implNames){
      std::cout << gen1.error_at_step_size(name, h, 1) << " ";
      std::cout << gen2.error_at_step_size(name, h, 1) << " ";
      std::cout << gen3.error_at_step_size(name, h, 1) << " ";
    }
    std::cout << "\n";
    std::cerr << "computed h=" << h << "\n";
  }
}
