///////////////////////////////////////////////////////////////////////////// // // // Function that contains function f(x), f'(x) and flag if df/dx>0 // // // // Burkhard Militzer Berkeley 01-25-08 // // // ///////////////////////////////////////////////////////////////////////////// #ifndef _FUNCTION_ #define _FUNCTION_ class Function { public: double operator()(const double x) const { return f(x); } static double f(const double x) { return x; } static double Inverse(const double x) { return x; } static double Derivative(const double x) { return 1.0; } static double SecondDerivative(const double x) { return 0.0; } static bool Rising() { return true; } static string Name() { return "f(x) = x"; } }; class LogFunction : public Function { public: double operator()(const double x) const { return f(x); } static double f(const double x) { return log(x); } static double Inverse(const double x) { return exp(x); } static double Derivative(const double x) { return 1.0/x; } static double SecondDerivative(const double x) { return -1.0/(x*x); } static bool Rising() { return true; } static string Name() { return "f(x) = log(x)"; } }; class PowerFunction : public Function { public: const double alpha; PowerFunction(const double alpha_):alpha(alpha_) {} double operator()(const double x) const { // must be declared again, otherwise wrong f() called return f(x); } double f(const double x) const { return pow(x,alpha); } double Inverse(const double x) const { // ignore any negative roots return pow(x,1.0/alpha); } double Derivative(const double x) const { return alpha*pow(x,alpha-1.0); } double SecondDerivative(const double x) const { return alpha*(alpha-1)*pow(x,alpha-2.0); } bool Rising() const { return alpha>0.0; } string Name() const { return "f(x) = x^"+DoubleToString(alpha); } }; class Power3Function : public PowerFunction { public: Power3Function():PowerFunction(3.0){} }; class Power2Function : public PowerFunction { public: Power2Function():PowerFunction(2.0){} }; class Power1Function : public PowerFunction { public: Power1Function():PowerFunction(1.0){} }; class GeneralFunction : public Function { // slower but function type can be switched during execution public: enum FunctionType {lin, log, pow1, pow2, pow3}; FunctionType functionType; GeneralFunction():functionType(lin) {} GeneralFunction(FunctionType functionType_):functionType(functionType_) {} void SwitchToLogInterpolation() { functionType = log; } double operator()(const double x) const { // must be declared again, otherwise wrong f() called return f(x); } double f(const double x) const { switch (functionType) { case lin : { Function f_; return f_.f(x); } case log : { LogFunction f_; return f_.f(x); } case pow1 : { Power1Function f_; return f_.f(x); } case pow2 : { Power2Function f_; return f_.f(x); } case pow3 : { Power3Function f_; return f_.f(x); } } error("GeneralFunction",functionType); return 0.0; } double Inverse(const double x) const { switch (functionType) { case lin : { Function f; return f.Inverse(x); } case log : { LogFunction f; return f.Inverse(x); } case pow1 : { Power1Function f; return f.Inverse(x); } case pow2 : { Power2Function f; return f.Inverse(x); } case pow3 : { Power3Function f; return f.Inverse(x); } } error("GeneralFunction",functionType); return 0.0; } double Derivative(const double x) const { switch (functionType) { case lin : { Function f; return f.Derivative(x); } case log : { LogFunction f; return f.Derivative(x); } case pow1 : { Power1Function f; return f.Derivative(x); } case pow2 : { Power2Function f; return f.Derivative(x); } case pow3 : { Power3Function f; return f.Derivative(x); } } error("GeneralFunction",functionType); return 0.0; } double SecondDerivative(const double x) const { switch (functionType) { case lin : { Function f; return f.SecondDerivative(x); } case log : { LogFunction f; return f.SecondDerivative(x); } case pow1 : { Power1Function f; return f.SecondDerivative(x); } case pow2 : { Power2Function f; return f.SecondDerivative(x); } case pow3 : { Power3Function f; return f.SecondDerivative(x); } } error("GeneralFunction",functionType); return 0.0; } bool Rising() const { switch (functionType) { case lin : { Function f; return f.Rising(); } case log : { LogFunction f; return f.Rising(); } case pow1 : { Power1Function f; return f.Rising(); } case pow2 : { Power2Function f; return f.Rising(); } case pow3 : { Power3Function f; return f.Rising(); } } error("GeneralFunction",functionType); return true; } string Name() const { switch (functionType) { case lin : { Function f; return f.Name(); } case log : { LogFunction f; return f.Name(); } case pow1 : { Power1Function f; return f.Name(); } case pow2 : { Power2Function f; return f.Name(); } case pow3 : { Power3Function f; return f.Name(); } } error("GeneralFunction",functionType); return ""; } }; #endif // _FUNCTION_