#pragma once

#include <functional>
#include <cmath>
#include <iostream>
#include "../generic/Algorithm.h"
#include "Function1d.h"

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Wrapper for calculating inverse of a monotonic function 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class MonotonicFunctionInverter : public Function1d
{
private:
	std::function<double(double)> m_y_to_x;

	// lower bound of function inverse
	double m_lb;

	// upper bound of function inverse
	double m_ub;

	// function evaluated at point to invert
	double m_fx;

public:

	MonotonicFunctionInverter(double lb, double ub);
	MonotonicFunctionInverter(const std::function<double(double)>& y_to_x, double lb, double ub);
	double calculate_inverse(double y, const std::string& error);

	// inverse is the root of this function
	double evaluate(double y) override;
};