#ifndef __FUNCTIONPARSER_H
#define __FUNCTIONPARSER_H
#include "stdafx.h"
// Klassen in diesem Header-File (Forward-Deklarationen)
/*
template <class T> class CFunction;
template <class T> class CNullFunction;
template <class T> class CIdentityFunction;
template <class T> class CPolynom1Function;
template <class T> class CPolynom2Function;
template <class T> class CPolynom3Function;
template <class T> class CPolynom4Function;
template <class T> class CExp1Function;
template <class T> class CSin1Function;
template <class T> class CCos1Function;
template <class T> class CTan1Function;
template <class T> class CCot1Function;
template <class T> class CAsin1Function;
template <class T> class CAcos1Function;
template <class T> class CAtan1Function;
template <class T> class CSinh1Function;
template <class T> class CCosh1Function;
template <class T> class CTanh1Function;
template <class T> class CCoth1Function;
template <class T> class CSign1Function;
template <class T> class CAbs1Function;
template <class T> class CCeil1Function;
template <class T> class CFloor1Function;
template <class T> class CLog101Function;
template <class T> class CLog1Function;
template <class T> class CLogarithmus1Function;
template <class T> class CSqrt1Function;
template <class T> class CSqr1Function;
template <class T> class CGamma1Function;
template <class T> class CConstFunction;
template <class T> class CFunction1;
template <class T> class CExpFunction;
template <class T> class CSinFunction;
template <class T> class CCosFunction;
template <class T> class CTanFunction;
template <class T> class CCotFunction;
template <class T> class CAsinFunction;
template <class T> class CAcosFunction;
template <class T> class CAtanFunction;
template <class T> class CSinhFunction;
template <class T> class CCoshFunction;
template <class T> class CTanhFunction;
template <class T> class CCothFunction;
template <class T> class CSignFunction;
template <class T> class CAbsFunction;
template <class T> class CCeilFunction;
template <class T> class CFloorFunction;
template <class T> class CLog10Function;
template <class T> class CLogFunction;
template <class T> class CLogarithmusFunction;
template <class T> class CSqrFunction;
template <class T> class CSqrtFunction;
template <class T> class CGammaFunction;
template <class T> class CNegFunction;
template <class T> class CAdd0Function;
template <class T> class CSubR0Function;
template <class T> class CSubL0Function;
template <class T> class CMul0Function;
template <class T> class CDivL0Function;
template <class T> class CDivR0Function;
template <class T> class CPowerL0Function;
template <class T> class CPowerR0Function;
template <class T> class CFunction2;
template <class T> class CAddFunction;
template <class T> class CSubFunction;
template <class T> class CMulFunction;
template <class T> class CDivFunction;
template <class T> class CPowerFunction;
template <class T> class CComponenteFunction;
*/
// Um symbolisches Ableiten zu beschleunigen:
// Kann besser gemacht werden, indem erst die Bausteine der Ableitung berechnet werden und dann nochmal geguckt wird
#define DERIVATE_TEST if (IsConstantFunction()) return new CNullFunction<T>();
// Basisklasse, abstrakt
template <class T>
class CFunction : public CObject
{
public:
// Konstruktor, Destruktor
CFunction() {};
virtual ~CFunction() {};
// Abstrakte Prototypen
virtual CString GetName() const = 0; // abstrakte Funktion, mu� �berschrieben werden
virtual CString GetTeX() const = 0; // abstrakte Funktion, mu� �berschrieben werden
virtual CFunction<T>* GetDerivate() const = 0; // abstrakte Funktion, mu� �berschrieben werden
virtual CFunction<T>* GetDuplicate(bool simplify = true) const = 0; // abstrakte Funktion, mu� �berschrieben werden
virtual T Execute(T x) const = 0; // abstrakte Funktion, mu� �berschrieben werden
virtual bool IsConstantFunction() const {return false;} // Sollte �berschrieben werden, um symbolische Operationen zu beschleunigen und Ausdr�cke zu vereinfachen
virtual bool IsNullFunction() const {return false;} // Sollte �berschrieben werden, um symbolische Operationen zu beschleunigen und Ausdr�cke zu vereinfachen
// Ableitung, Nullstellenbestimmung, Integrale (numerisch)
virtual T Derivate(T x, int grad = 1, double h = 1E-6) const;
virtual T Nullstelle_Newton(T StartWert, double tol = 1E-6) const;
virtual T Integral_Trapezregel(T x1, T x2, long nIntervals, double tol = 1E-6) const;
virtual T Integral_Mittelpunktregel(T x1, T x2, long nIntervals, double tol = 1E-6) const;
virtual T Integral_Simpsonregel(T x1, T x2, long nIntervals, double tol = 1E-6) const;
// Funktions-Parser und Hilfsfunktionen
static CFunction<T>* Parse(CString& str, const char* Var = _T("X"));
static CFunction<T>* Parse1(const char* str, const char* Var = _T("X"));
static bool IsFunction(CString& str, const char* Token); // Pr�ft, ob Ausdruck Funktion ist
static bool IsConstFunction(CString& str, const char* Token); // Pr�ft, ob Ausdruck Funktion ist und ob das Argument die Identit�t ist
static bool IsPureFunction(CString& str, const char* Token, const char* Var = _T("X")); // Pr�ft, ob Ausdruck Funktion ist und ob das Argument die Identit�t ist
static bool IsConst(const char* str); // strtod anwendbar?
static T Value(const char* str); // liefert Ergebnis der Funktion strtod
static bool IsIdentity(const char* str, const char* Var = _T("X"));
};
// Funktion mit einer eingebetteten Funktion, immer noch abstrakt!
template <class T>
class CFunction1 : public CFunction<T>
{
public:
CFunction1(CFunction<T>* _f1) : f1(_f1) {};
virtual ~CFunction1() {delete f1;};
virtual CString GetConcName(const char* basisfkt) const;
protected:
CFunction<T>* f1;
};
// Funktion mit zwei eingebetteten Funktionen, immer noch abstrakt!
template <class T>
class CFunction2 : public CFunction<T>
{
public:
CFunction2(CFunction<T>* _f1, CFunction<T>* _f2) : f1(_f1), f2(_f2) {};
virtual ~CFunction2() {delete f1; delete f2;};
virtual CString GetConcName(const char* basisfkt) const;
protected:
CFunction<T>* f1;
CFunction<T>* f2;
};
// Nullfunktion
template <class T>
class CNullFunction : public CFunction<T>
{
public:
CNullFunction() {};
virtual T Execute(T /*x*/) const {return 0;};
virtual bool IsConstantFunction() const {return true;}
virtual bool IsNullFunction() const {return true;}
virtual CString GetName() const {return _T("0");};
virtual CString GetTeX() const {return _T("0");};
virtual CFunction<T>* GetDerivate() const {return new CNullFunction<T>;};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
// Identit�t
template <class T>
class CIdentityFunction : public CFunction<T>
{
public:
CIdentityFunction() {};
virtual T Execute(T x) const {return x;};
virtual CString GetName() const {return _T("x");};
virtual CString GetTeX() const {return _T("x");};
virtual CFunction<T>* GetDerivate() const {return new CConstFunction<T>(1);};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CIdentityFunction<T>;};
};
// Polynome
template <class T>
class CPolynom1Function : public CFunction<T>
{
public:
CPolynom1Function(T _a0, T _a1) : a0(_a0), a1(_a1) {};
virtual T Execute(T x) const {return a0+x*a1;};
virtual bool IsConstantFunction() const {return a1==0.0;}
virtual bool IsNullFunction() const {return a1==0.0 && a0==0.0;}
virtual CString GetName() const;
virtual CString GetTeX() const;
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CConstFunction<T>(a1);};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T a0;
T a1;
};
template <class T>
class CPolynom2Function : public CFunction<T>
{
public:
CPolynom2Function(T _a0, T _a1, T _a2) : a0(_a0), a1(_a1), a2(_a2) {};
virtual T Execute(T x) const {return a0+x*(a1+x*a2);};
virtual bool IsConstantFunction() const {return a2==0.0 && a1==0.0;}
virtual bool IsNullFunction() const {return a2==0.0 && a1==0.0 && a0==0.0;}
virtual CString GetName() const;
virtual CString GetTeX() const;
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CPolynom1Function<T>(a1,2*a2);};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T a0;
T a1;
T a2;
};
template <class T>
class CPolynom3Function : public CFunction<T>
{
public:
CPolynom3Function(T _a0, T _a1, T _a2, T _a3) : a0(_a0), a1(_a1), a2(_a2), a3(_a3) {};
virtual T Execute(T x) const {return a0+x*(a1+x*(a2+x*a3));};
virtual bool IsConstantFunction() const {return a3==0.0 && a2==0.0 && a1==0.0;}
virtual bool IsNullFunction() const {return a3==0.0 && a2==0.0 && a1==0.0 && a0==0.0;}
virtual CString GetName() const;
virtual CString GetTeX() const;
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CPolynom2Function<T>(a1,2*a2,3*a3);};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T a0;
T a1;
T a2;
T a3;
};
template <class T>
class CPolynom4Function : public CFunction<T>
{
public:
CPolynom4Function(T _a0, T _a1, T _a2, T _a3, T _a4) : a0(_a0), a1(_a1), a2(_a2), a3(_a3), a4(_a4) {};
virtual T Execute(T x) const {return a0+x*(a1+x*(a2+x*(a3+x*a4)));};
virtual bool IsConstantFunction() const {return a4==0.0 && a3==0.0 && a2==0.0 && a1==0.0;}
virtual bool IsNullFunction() const {return a4==0.0 && a3==0.0 && a2==0.0 && a1==0.0 && a0==0.0;}
virtual CString GetName() const;
virtual CString GetTeX() const;
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CPolynom3Function<T>(a1,2*a2,3*a3,4*a4);};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T a0;
T a1;
T a2;
T a3;
T a4;
};
// Exponentialfunktion
template <class T>
class CExpFunction : public CFunction1<T>
{
public:
CExpFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return expl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("exp"));};
virtual CString GetTeX() const {CString str = _T("e^{"); str += f1->GetTeX(); str += _T("}"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMulFunction<T>(new CExpFunction<T>(f1->GetDuplicate()), f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CExp1Function : public CFunction<T>
{
public:
CExp1Function() {};
virtual T Execute(T x) const {return expl(x);};
virtual CString GetName() const {return _T("exp(x)");};
virtual CString GetTeX() const {return _T("e^x");};
virtual CFunction<T>* GetDerivate() const {return new CExp1Function<T>;};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CExp1Function<T>;};
};
// Trigonometrische Funktionen
template <class T>
class CSinFunction : public CFunction1<T>
{
public:
CSinFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return sinl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("sin"));};
virtual CString GetTeX() const {CString str = _T("\\sin\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMulFunction<T>(new CCosFunction<T>(f1->GetDuplicate()), f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CCosFunction : public CFunction1<T>
{
public:
CCosFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return cosl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual CString GetName() const {return GetConcName(_T("cos"));};
virtual CString GetTeX() const {CString str = _T("\\cos\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CNegFunction<T>(new CMulFunction<T>(new CSinFunction<T>(f1->GetDuplicate()), f1->GetDerivate()));};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CTanFunction : public CFunction1<T>
{
public:
CTanFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return tanl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("tan"));};
virtual CString GetTeX() const {CString str = _T("\\tan\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMulFunction<T>(new CAdd0Function<T>(new CMulFunction<T>(new CTanFunction<T>(f1->GetDuplicate()), new CTanFunction<T>(f1->GetDuplicate())), 1), f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CCotFunction : public CFunction1<T>
{
public:
CCotFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return cosl(f1->Execute(x))/sinl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual CString GetName() const {return GetConcName(_T("cot"));};
virtual CString GetTeX() const {CString str = _T("\\cot\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CNegFunction<T>(new CMulFunction<T>(new CAdd0Function<T>(new CMulFunction<T>(new CCotFunction<T>(f1->GetDuplicate()), new CCotFunction<T>(f1->GetDuplicate())), 1), f1->GetDerivate()));};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CAsinFunction : public CFunction1<T>
{
public:
CAsinFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return asinl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("Asin"));};
virtual CString GetTeX() const {CString str = _T("\\arcsin\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMulFunction<T>(new CDivL0Function<T>(1, new CSqrtFunction<T>(new CPolynom2Function<T>(1, 0, -1))), f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CAcosFunction : public CFunction1<T>
{
public:
CAcosFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return acosl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual CString GetName() const {return GetConcName(_T("Acos"));};
virtual CString GetTeX() const {CString str = _T("\\arccos\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMulFunction<T>(new CDivL0Function<T>(-1, new CSqrtFunction<T>(new CPolynom2Function<T>(1, 0, -1))), f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CAtanFunction : public CFunction1<T>
{
public:
CAtanFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return atanl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("Atan"));};
virtual CString GetTeX() const {CString str = _T("\\arctan\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMulFunction<T>(new CDivL0Function<T>(1, new CPolynom2Function<T>(1, 0, 1)), f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CAcotFunction : public CFunction1<T>
{
public:
CAcotFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return acotl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual CString GetName() const {return GetConcName(_T("Acot"));};
virtual CString GetTeX() const {CString str = _T("\\mathop{\\rm arccot}\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMulFunction<T>(new CDivL0Function<T>(-1, new CPolynom2Function<T>(1, 0, 1))), f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CSin1Function : public CFunction<T>
{
public:
CSin1Function() {};
virtual T Execute(T x) const {return sinl(x);};
virtual CString GetName() const {return _T("sin(x)");};
virtual CString GetTeX() const {return _T("\\sin(x)");};
virtual CFunction<T>* GetDerivate() const {return new CCos1Function<T>;};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CSin1Function<T>;};
};
template <class T>
class CCos1Function : public CFunction<T>
{
public:
CCos1Function() {};
virtual T Execute(T x) const {return cosl(x);};
virtual CString GetName() const {return _T("cos(x)");};
virtual CString GetTeX() const {return _T("\\cos(x)");};
virtual CFunction<T>* GetDerivate() const {return new CNegFunction<T>(new CSin1Function<T>);};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CCos1Function<T>;};
};
template <class T>
class CTan1Function : public CFunction<T>
{
public:
CTan1Function() {};
virtual T Execute(T x) const {return tanl(x);};
virtual CString GetName() const {return _T("tan(x)");};
virtual CString GetTeX() const {return _T("\\tan(x)");};
virtual CFunction<T>* GetDerivate() const {return new CAdd0Function<T>(new CMulFunction<T>(new CTan1Function<T>, new CTan1Function<T>), 1);};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CTan1Function<T>;};
};
template <class T>
class CCot1Function : public CFunction<T>
{
public:
CCot1Function() {};
virtual T Execute(T x) const {return cosl(x)/sinl(x);};
virtual CString GetName() const {return _T("cot(x)");};
virtual CString GetTeX() const {return _T("\\cot(x)");};
virtual CFunction<T>* GetDerivate() const {return new CNegFunction<T>(new CAdd0Function<T>(new CMulFunction<T>(new CCot1Function<T>, new CCot1Function<T>), 1));};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CCot1Function<T>;};
};
template <class T>
class CAsin1Function : public CFunction<T>
{
public:
CAsin1Function() {};
virtual T Execute(T x) const {return asinl(x);};
virtual CString GetName() const {return _T("Asin(x)");};
virtual CString GetTeX() const {return _T("\\arcsin(x)");};
virtual CFunction<T>* GetDerivate() const {return new CDivL0Function<T>(1, new CSqrtFunction<T>(new CPolynom2Function<T>(1,0,-1)));};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CAsin1Function<T>;};
};
template <class T>
class CAcos1Function : public CFunction<T>
{
public:
CAcos1Function() {};
virtual T Execute(T x) const {return acosl(x);};
virtual CString GetName() const {return _T("Acos(x)");};
virtual CString GetTeX() const {return _T("\\arccos(x)");};
virtual CFunction<T>* GetDerivate() const {return new CDivL0Function<T>(-1, new CSqrtFunction<T>(new CPolynom2Function<T>(1,0,-1)));};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CAcos1Function<T>;};
};
template <class T>
class CAtan1Function : public CFunction<T>
{
public:
CAtan1Function() {};
virtual T Execute(T x) const {return atanl(x);};
virtual CString GetName() const {return _T("Atan(x)");};
virtual CString GetTeX() const {return _T("\\arctan(x)");};
virtual CFunction<T>* GetDerivate() const {return new CDivL0Function<T>(1, new CPolynom2Function<T>(1, 0, 1));};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CAtan1Function<T>;};
};
template <class T>
class CAcot1Function : public CFunction<T>
{
public:
CAcot1Function() {};
virtual T Execute(T x) const {return acotl(x);};
virtual CString GetName() const {return _T("Acot(x)");};
virtual CString GetTeX() const {return _T("\\mathop{\\rm arccot}(x)");};
virtual CFunction<T>* GetDerivate() const {return new CDivL0Function<T>(-1, new CPolynom2Function<T>(1, 0, 1));};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const {return new CAcot1Function<T>;};
};
// Hyperbolische Funktionen
template <class T>
class CSinhFunction : public CFunction1<T>
{
public:
CSinhFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return sinhl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("sinh"));};
virtual CString GetTeX() const {CString str = _T("\\sinh\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMulFunction<T>(new CCoshFunction<T>(f1->GetDuplicate()), f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CCoshFunction : public CFunction1<T>
{
public:
CCoshFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return coshl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual CString GetName() const {return GetConcName(_T("cosh"));};
virtual CString GetTeX() const {CString str = _T("\\cosh\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMulFunction<T>(new CSinhFunction<T>(f1->GetDuplicate()), f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CTanhFunction : public CFunction1<T>
{
public:
CTanhFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return tanhl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("tanh"));};
virtual CString GetTeX() const {CString str = _T("\\tanh\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMulFunction<T>(new CDivL0Function<T>(1, new CMulFunction<T>(new CCoshFunction<T>(f1->GetDuplicate()), new CCoshFunction<T>(f1->GetDuplicate()))), f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CCothFunction : public CFunction1<T>
{
public:
CCothFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return coshl(f1->Execute(x)) / sinhl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual CString GetName() const {return GetConcName(_T("coth"));};
virtual CString GetTeX() const {CString str = _T("\\coth\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMulFunction<T>(new CDivL0Function<T>(-1, new CMulFunction<T>(new CSinhFunction<T>(f1->GetDuplicate()), new CSinhFunction<T>(f1->GetDuplicate()))), f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CSinh1Function : public CFunction<T>
{
public:
CSinh1Function() {};
virtual T Execute(T x) const {return sinhl(x);};
virtual CString GetName() const {return _T("sinh(x)");};
virtual CString GetTeX() const {return _T("\\sinh(x)");};
virtual CFunction<T>* GetDerivate() const {return new CCosh1Function<T>;};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CSinh1Function<T>;};
};
template <class T>
class CCosh1Function : public CFunction<T>
{
public:
CCosh1Function() {};
virtual T Execute(T x) const {return coshl(x);};
virtual CString GetName() const {return _T("cosh(x)");};
virtual CString GetTeX() const {return _T("\\cosh(x)");};
virtual CFunction<T>* GetDerivate() const {return new CSinh1Function<T>;};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CCosh1Function<T>;};
};
template <class T>
class CTanh1Function : public CFunction<T>
{
public:
CTanh1Function() {};
virtual T Execute(T x) const {return tanhl(x);};
virtual CString GetName() const {return _T("tanh(x)");};
virtual CString GetTeX() const {return _T("\\tanh(x)");};
virtual CFunction<T>* GetDerivate() const {return new CDivL0Function<T>(1, new CMulFunction<T>(new CCosh1Function<T>, new CCosh1Function<T>));};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CTanh1Function<T>;};
};
template <class T>
class CCoth1Function : public CFunction<T>
{
public:
CCoth1Function() {};
virtual T Execute(T x) const {return coshl(x)/sinhl(x);};
virtual CString GetName() const {return _T("coth(x)");};
virtual CString GetTeX() const {return _T("\\coth(x)");};
virtual CFunction<T>* GetDerivate() const {return new CDivL0Function<T>(-1, new CMulFunction<T>(new CSinh1Function<T>, new CSinh1Function<T>));};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CCoth1Function<T>;};
};
// Vorzeichen-Funktion
template <class T>
class CSignFunction : public CFunction1<T>
{
public:
CSignFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return signl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("sign"));};
virtual CString GetTeX() const {CString str = _T("\\mathop{\\rm sign}\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CNullFunction<T>;}; // !! eigentlich nicht korrekt, aber das �berhaupt etwas definiert ist!
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CSign1Function : public CFunction<T>
{
public:
CSign1Function() {};
virtual T Execute(T x) const {return signl(x);};
virtual CString GetName() const {return _T("sing(x)");};
virtual CString GetTeX() const {return _T("\\mathop{\\rm sign}(x)");};
virtual CFunction<T>* GetDerivate() const {return new CNullFunction<T>;}; // !! eigentlich nicht korrekt, aber das �berhaupt etwas definiert ist!
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CSign1Function<T>;};
};
// Absoluter Betrag
template <class T>
class CAbsFunction : public CFunction1<T>
{
public:
CAbsFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return fabsl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("abs"));};
virtual CString GetTeX() const {CString str = _T("\\left\\|"); str += f1->GetTeX(); str += _T("\\right\\|"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMulFunction<T>(new CSignFunction<T>(f1->GetDuplicate()), f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CAbs1Function : public CFunction<T>
{
public:
CAbs1Function() {};
virtual T Execute(T x) const {return fabsl(x);};
virtual CString GetName() const {return _T("abs(x)");};
virtual CString GetTeX() const {return _T("\\left\\|x\\right\\|");};
virtual CFunction<T>* GetDerivate() const {return new CSign1Function<T>;};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CAbs1Function<T>;};
};
// ceil
template <class T>
class CCeilFunction : public CFunction1<T>
{
public:
CCeilFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return ceill(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("ceil"));};
virtual CString GetTeX() const {CString str = _T("\\mathop{\\rm ceil}\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CNullFunction<T>;}; // eigentlich nicht korrekt
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CCeil1Function : public CFunction<T>
{
public:
CCeil1Function() {};
virtual T Execute(T x) const {return ceill(x);};
virtual CString GetName() const {return _T("ceil(x)");};
virtual CString GetTeX() const {return _T("\\mathop{\\rm ceil}(x)");};
virtual CFunction<T>* GetDerivate() const {return new CNullFunction<T>;}; // eigentlich nicht korrekt
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CCeil1Function<T>;};
};
// floor
template <class T>
class CFloorFunction : public CFunction1<T>
{
public:
CFloorFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return floorl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("floor"));};
virtual CString GetTeX() const {CString str = _T("\\mathop{\\rm floor}\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CNullFunction<T>;}; // eigentlich nicht korrekt
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CFloor1Function : public CFunction<T>
{
public:
CFloor1Function() {};
virtual T Execute(T x) const {return floorl(x);};
virtual CString GetName() const {return _T("floor(x)");};
virtual CString GetTeX() const {return _T("\\mathop{\\rm floor}(x)");};
virtual CFunction<T>* GetDerivate() const {return new CNullFunction<T>;}; // eigentlich nicht korrekt
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CFloor1Function<T>;};
};
// Logarithmus
template <class T>
class CLog10Function : public CFunction1<T>
{
public:
CLog10Function(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return log10l(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsConstantFunction() && f1->Execute(0.0)==1.0;}
virtual CString GetName() const {return GetConcName(_T("lg"));};
virtual CString GetTeX() const {CString str = _T("\\lg\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CDivFunction<T>(f1->GetDerivate(), new CMul0Function<T>(f1->GetDuplicate(), logl(10)));};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CLogFunction : public CFunction1<T>
{
public:
CLogFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return logl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsConstantFunction() && f1->Execute(0.0)==1.0;}
virtual CString GetName() const {return GetConcName(_T("log"));};
virtual CString GetTeX() const {CString str = _T("\\ln\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CDivFunction<T>(f1->GetDerivate(), f1->GetDuplicate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CLogarithmusFunction : public CFunction1<T>
{
public:
CLogarithmusFunction(T _b, CFunction<T>* _f1) : CFunction1<T>(_f1), b(_b) {};
virtual T Execute(T x) const {return log(f1->Execute(x))/log(b);};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsConstantFunction() && f1->Execute(0.0)==1.0;}
virtual CString GetName() const {CString str = _T("log_"); str += CMathString(b); return GetConcName(str);};
virtual CString GetTeX() const {CString str = _T("\\log_"); str += CMathString(b); str += _T("\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CDivFunction<T>(f1->GetDerivate(), new CMulFunction<T>(logl(b), f1->GetDuplicate()));};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T b;
};
template <class T>
class CLog101Function : public CFunction<T>
{
public:
CLog101Function() {};
virtual T Execute(T x) const {return log10l(x);};
virtual CString GetName() const {return _T("lg(x)");};
virtual CString GetTeX() const {return _T("\\lg\\left(x\\right)");};
virtual CFunction<T>* GetDerivate() const {return new CDivL0Function<T>(1/logl(10), new CIdentityFunction<T>);};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CLog101Function<T>;};
};
template <class T>
class CLog1Function : public CFunction<T>
{
public:
CLog1Function() {};
virtual T Execute(T x) const {return logl(x);};
virtual CString GetName() const {return _T("log(x)");};
virtual CString GetTeX() const {return _T("\\ln\\left(x\\right)");};
virtual CFunction<T>* GetDerivate() const {return new CDivL0Function<T>(1, new CIdentityFunction<T>);};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CLog1Function<T>;};
};
template <class T>
class CLogarithmus1Function : public CFunction<T>
{
public:
CLogarithmus1Function(T _b) : b(_b) {};
virtual T Execute(T x) const {return log(x)/log(b);};
virtual CString GetName() const {CString str = _T("log_"); str += CMathString(b); str += _T("(x)"); return str;};
virtual CString GetTeX() const {CString str = _T("\\log_"); str += CMathString(b); str += _T("\\left(x\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {return new CDivL0Function<T>(1/logl(b), new CIdentityFunction<T>);};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const {return new CLogarithmusFunction<T>(b);};
private:
T b;
};
// Wurzel
template <class T>
class CSqrtFunction : public CFunction1<T>
{
public:
CSqrtFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return sqrtl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("sqrt"));};
virtual CString GetTeX() const {CString str = _T("\\sqrt\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CDivFunction<T>(f1->GetDerivate(), new CMul0Function<T>(new CSqrtFunction<T>(f1->GetDuplicate()), 2));};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CSqrt1Function : public CFunction<T>
{
public:
CSqrt1Function() {};
virtual T Execute(T x) const {return sqrtl(x);};
virtual CString GetName() const {return _T("sqrt(x)");};
virtual CString GetTeX() const {return _T("\\sqrt\\left(x\\right)");};
virtual CFunction<T>* GetDerivate() const {return new CDivL0Function<T>(1/2, new CSqrt1Function<T>);};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CSqrt1Function<T>;};
};
// Wurzel
template <class T>
class CSqrFunction : public CFunction1<T>
{
public:
CSqrFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return sqrl(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("sqr"));};
virtual CString GetTeX() const {CString str = _T("\\sqr\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMul0Function<T>(f1->GetDuplicate(), 2);};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CSqr1Function : public CFunction<T>
{
public:
CSqr1Function() {};
virtual T Execute(T x) const {return sqrl(x);};
virtual CString GetName() const {return _T("x^2");};
virtual CString GetTeX() const {return _T("x^2");};
virtual CFunction<T>* GetDerivate() const {return new CPolynom1Function<T>(0, 2.0);};
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CSqr1Function<T>;};
};
// Gamma-Funktion
template <class T>
class CGammaFunction : public CFunction1<T>
{
public:
CGammaFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return FGammal(f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual CString GetName() const {return GetConcName(_T("Gamma"));};
virtual CString GetTeX() const {CString str = _T("\\Gamma\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CNullFunction<T>;}; // not implemented
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
template <class T>
class CGamma1Function : public CFunction<T>
{
public:
CGamma1Function() {};
virtual T Execute(T x) const {return FGammal(x);};
virtual CString GetName() const {return _T("Gamma(x)");};
virtual CString GetTeX() const {return _T("\\Gamma\\left(x\\right)");};
virtual CFunction<T>* GetDerivate() const {return new CNullFunction<T>;}; // not implemented
virtual CFunction<T>* GetDuplicate(bool /*simplify*/ = true) const {return new CGamma1Function<T>;};
};
// Konstante Funtion
template <class T>
class CConstFunction : public CFunction<T>
{
public:
CConstFunction(T _c) : c(_c) {};
virtual T Execute(T /*x*/) const {return c;};
virtual bool IsConstantFunction() const {return true;}
virtual bool IsNullFunction() const {return c==0.0;}
virtual CString GetName() const {return CMathString(c);};
virtual CString GetTeX() const {return CMathString(c);};
virtual CFunction<T>* GetDerivate() const {return new CNullFunction<T>;};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T c;
};
// Negation
template <class T>
class CNegFunction : public CFunction1<T>
{
public:
CNegFunction(CFunction<T>* _f1) : CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return -f1->Execute(x);};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {CString str = _T("-"); str += f1->GetName(); return str;};
virtual CString GetTeX() const {CString str = _T("-"); str += f1->GetTeX(); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CNegFunction<T>(f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
// Addition
template <class T>
class CAdd0Function : public CFunction1<T>
{
public:
CAdd0Function(CFunction<T>* _f1, T _c) : CFunction1<T>(_f1), c(_c) {};
virtual T Execute(T x) const {return f1->Execute(x) + c;};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsConstantFunction() && f1->Execute(0.0)==-c;}
virtual CString GetName() const {CString str = f1->GetName(); str += _T("+"); str += CMathString(c); return str;};
virtual CString GetTeX() const {CString str = f1->GetTeX(); str += _T("+"); str += CMathString(c); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return f1->GetDerivate();};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T c;
};
// Subtraktion
template <class T>
class CSubR0Function : public CFunction1<T>
{
public:
CSubR0Function(CFunction<T>* _f1, T _c) : CFunction1<T>(_f1), c(_c) {};
virtual T Execute(T x) const {return f1->Execute(x) - c;};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsConstantFunction() && f1->Execute(0.0)==c;}
virtual CString GetName() const {CString str = f1->GetName(); str += _T("-"); str += CMathString(c); return str;};
virtual CString GetTeX() const {CString str = f1->GetTeX(); str += _T("-"); str += CMathString(c); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return f1->GetDerivate();};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T c;
};
template <class T>
class CSubL0Function : public CFunction1<T>
{
public:
CSubL0Function(T _c, CFunction<T>* _f1) : CFunction1<T>(_f1), c(_c) {};
virtual T Execute(T x) const {return c - f1->Execute(x);};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsConstantFunction() && f1->Execute(0.0)==c;}
virtual CString GetName() const {CString str = CMathString(c); str += _T("-"); str += f1->GetName(); return str;};
virtual CString GetTeX() const {CString str = CMathString(c); str += _T("-"); str += f1->GetTeX(); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CNegFunction<T>(f1->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T c;
};
// Multiplikation
template <class T>
class CMul0Function : public CFunction1<T>
{
public:
CMul0Function(CFunction<T>* _f1, T _c) : CFunction1<T>(_f1), c(_c) {};
virtual T Execute(T x) const {return f1->Execute(x) * c;};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction() || c==0.0;}
virtual bool IsNullFunction() const {return f1->IsNullFunction() || c==0.0;}
virtual CString GetName() const {CString str = CMathString(c); str += _T("*("); str += f1->GetName(); str += _T(")"); return str;};
virtual CString GetTeX() const {CString str = CMathString(c); str += _T("\\left("); str += f1->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CMul0Function<T>(f1->GetDerivate(), c);};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T c;
};
// Division
template <class T>
class CDivL0Function : public CFunction1<T>
{
public:
CDivL0Function(T _c, CFunction<T>* _f1) : CFunction1<T>(_f1), c(_c) {};
virtual T Execute(T x) const {return c / f1->Execute(x);};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction() || c==0.0;}
virtual bool IsNullFunction() const {return c==0.0;}
virtual CString GetName() const {CString str = CMathString(c); str += _T("/("); str += f1->GetName(); str += _T(")"); return str;};
virtual CString GetTeX() const {CString str = _T("\\frac{"); str += CMathString(c); str += _T("}{"); str += f1->GetTeX(); str += _T("}"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CNegFunction<T>(new CDivFunction<T>(f1->GetDerivate(), new CMulFunction<T>(f1->GetDuplicate(), f1->GetDuplicate())));};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T c;
};
template <class T>
class CDivR0Function : public CFunction1<T>
{
public:
CDivR0Function(CFunction<T>* _f1, T _c) : CFunction1<T>(_f1), c(_c) {};
virtual T Execute(T x) const {return f1->Execute(x) / c;};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {CString str = _T("("); str += f1->GetName(); str += _T(")/"); str += CMathString(c); return str;};
virtual CString GetTeX() const {CString str = _T("\\frac{"); str += f1->GetTeX(); str += _T("}{"); str += CMathString(c); str += _T("}"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CDivR0Function<T>(f1->GetDerivate(), c);};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T c;
};
// Addition
template <class T>
class CAddFunction : public CFunction2<T>
{
public:
CAddFunction(CFunction<T>* _f1, CFunction<T>* _f2) : CFunction2<T>(_f1, _f2) {};
virtual T Execute(T x) const {return f1->Execute(x) + f2->Execute(x);};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction() && f2->IsConstantFunction();}
virtual bool IsNullFunction() const {return (f1->IsNullFunction() && f2->IsNullFunction()) || (f1->IsConstantFunction() && f2->IsConstantFunction() && f1->Execute(0.0)==-f2->Execute(0.0));}
virtual CString GetName() const {CString str = f1->GetName(); str += _T("+"); str += f2->GetName(); return str;};
virtual CString GetTeX() const {CString str = f1->GetTeX(); str += _T("+"); str += f2->GetTeX(); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CAddFunction<T>(f1->GetDerivate(), f2->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
// Subtraktion
template <class T>
class CSubFunction : public CFunction2<T>
{
public:
CSubFunction(CFunction<T>* _f1, CFunction<T>* _f2) : CFunction2<T>(_f1, _f2) {};
virtual T Execute(T x) const {return f1->Execute(x) - f2->Execute(x);};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction() && f2->IsConstantFunction();}
virtual bool IsNullFunction() const {return (f1->IsNullFunction() && f2->IsNullFunction()) || (f1->IsConstantFunction() && f2->IsConstantFunction() && f1->Execute(0.0)==f2->Execute(0.0));}
//virtual CString GetName() const {CString str = _T("("); str += f1->GetName(); str += _T(")-("); str += f2->GetName(); str += _T(")"); return str;};
virtual CString GetName() const {return GetConcName(_T("-"));};
virtual CString GetTeX() const {CString str = f1->GetTeX(); str += _T("-"); str += f2->GetTeX(); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CSubFunction<T>(f1->GetDerivate(), f2->GetDerivate());};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
// Multiplikation
template <class T>
class CMulFunction : public CFunction2<T>
{
public:
CMulFunction(CFunction<T>* _f1, CFunction<T>* _f2) : CFunction2<T>(_f1, _f2) {};
virtual T Execute(T x) const {return f1->Execute(x) * f2->Execute(x);};
virtual bool IsConstantFunction() const {return (f1->IsConstantFunction() && f2->IsConstantFunction()) || f1->IsNullFunction() || f2->IsNullFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction() || f2->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("*"));};
virtual CString GetTeX() const {CString str = _T("\\left("); str += f1->GetTeX(); str += _T("\\right)\\left("); str += f2->GetTeX(); str += _T("\\right)"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CAddFunction<T>(new CMulFunction<T>(f1->GetDuplicate(), f2->GetDerivate()), new CMulFunction<T>(f1->GetDerivate(), f2->GetDuplicate()));};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
// Division
template <class T>
class CDivFunction : public CFunction2<T>
{
public:
CDivFunction(CFunction<T>* _f1, CFunction<T>* _f2) : CFunction2<T>(_f1, _f2) {};
virtual T Execute(T x) const {return f1->Execute(x) / f2->Execute(x);};
virtual bool IsConstantFunction() const {return (f1->IsConstantFunction() && f2->IsConstantFunction()) || f1->IsNullFunction();}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {return GetConcName(_T("/"));};
virtual CString GetTeX() const {CString str = _T("\\frac{"); str += f1->GetTeX(); str += _T("}{"); str += f2->GetTeX(); str += _T("}"); return str;};
virtual CFunction<T>* GetDerivate() const {DERIVATE_TEST; return new CDivFunction<T>(new CSubFunction<T>(new CMulFunction<T>(f1->GetDerivate(), f2->GetDuplicate()), new CMulFunction<T>(f1->GetDuplicate(), f2->GetDerivate())), new CMulFunction<T>(f2->GetDuplicate(), f2->GetDuplicate()));};
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
// Potenzieren
template <class T>
class CPowerFunction : public CFunction2<T>
{
public:
CPowerFunction(CFunction<T>* _f1, CFunction<T>* _f2) : CFunction2<T>(_f1, _f2) {};
virtual T Execute(T x) const {return powl(f1->Execute(x), f2->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsNullFunction() || f2->IsNullFunction() || (f1->IsConstantFunction() && f2->IsConstantFunction());}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
//virtual CString GetName() const {CString str = _T("("); str += f1->GetName(); str += _T(")^("); str += f2->GetName(); str += _T(")"); return str;};
virtual CString GetName() const {return GetConcName(_T("^"));};
virtual CString GetTeX() const {CString str = _T("{"); str += f1->GetTeX(); str += _T("}^{"); str += f2->GetTeX(); str += _T("}"); return str;};
virtual CFunction<T>* GetDerivate() const;
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
};
// c ^ f1(x)
template <class T>
class CPowerL0Function : public CFunction1<T>
{
public:
CPowerL0Function(T _c, CFunction<T>* _f1) : c(_c), CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return powl(c, f1->Execute(x));};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction() && c==0.0;}
virtual bool IsNullFunction() const {return c==0.0;}
virtual CString GetName() const {CMathString str(c); str += _T("^("); str += f1->GetName(); str += _T(")"); return str;};
virtual CString GetTeX() const {CMathString str(c); str += _T("^{"); str += f1->GetName(); str += _T("}"); return str;};
virtual CFunction<T>* GetDerivate() const;
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T c;
};
// f1(x) ^ c
template <class T>
class CPowerR0Function : public CFunction1<T>
{
public:
CPowerR0Function(CFunction<T>* _f1, T _c) : c(_c), CFunction1<T>(_f1) {};
virtual T Execute(T x) const {return powl(f1->Execute(x), c);};
virtual bool IsConstantFunction() const {return f1->IsConstantFunction() || c==0.0;}
virtual bool IsNullFunction() const {return f1->IsNullFunction();}
virtual CString GetName() const {CString str = f1->GetName(); str += _T("^"); str += CMathString(c); return str;};
virtual CString GetTeX() const {CString str = f1->GetName(); str += _T("^"); str += CMathString(c); return str;};
virtual CFunction<T>* GetDerivate() const;
virtual CFunction<T>* GetDuplicate(bool simplify = true) const;
private:
T c;
};
// noch nicht verwendet
template <class T>
class CComponenteFunction : public CFunction<T>
{
public:
CComponenteFunction(int _index) : index(_index) {};
virtual T Execute(T x) const {return x[index];};
virtual CString GetName() const {CString str; str.Format(_T("x[%d]"), index); return str;};
virtual CString GetTeX() const {CString str; str.Format(_T("x_{%d}"), index); return str;};
virtual CFunction<T>* GetDerivate() const {return new CNullFunction<T>;}; // not implemented
virtual CFunction<T>* GetDuplicate(bool simplify = true) const {return new CComponenteFunction<T>(index);};
private:
int index;
};
template <class T>
T CFunction<T>::Derivate(T x, int grad, double h) const
{
switch (grad)
{
case 0:
{
return Execute(x);
}
case 1:
{
T y1 = Execute(x);
T y2 = Execute(x+h);
return (y2-y1)/h;
}
case 2:
{
T y1 = Execute(x-h);
T y2 = Execute(x);
T y3 = Execute(x+h);
return (2*y2-y1-y3)/(2*h*h);
}
default:
{
T y1 = Derivate(x+h, grad-1, h);
T y2 = Derivate(x, grad-1, h);
return (y2-y1)/h;
}
}
};
template <class T>
T CFunction<T>::Nullstelle_Newton(T x/*StartWert*/, double tol) const
{
T y = Execute(x);
while (fabsl(y)>tol)
{
T z = Derivate(x);
x -= y/z;
y = Execute(x);
}
return x;
};
template <class T>
T CFunction<T>::Integral_Trapezregel(T x1, T x2, long nIntervals, double /*tol*/) const
{
T summe = 0;
T delta = (x2-x1) / nIntervals;
T u = x1;
summe += delta/2 * Execute(u);
u += delta;
for (int i=1; i<nIntervals; i++)
{
summe += delta * Execute(u);
u += delta;
}
summe += delta/2 * Execute(u);
return summe;
};
template <class T>
T CFunction<T>::Integral_Mittelpunktregel(T x1, T x2, long nIntervals, double /*tol*/) const
{
T summe = 0;
T delta = (x2-x1) / nIntervals;
T u = x1;
for (int i=0; i<nIntervals; i++)
{
summe += delta * Execute(u+delta/2);
u += delta;
}
return summe;
};
template <class T>
T CFunction<T>::Integral_Simpsonregel(T x1, T x2, long nIntervals, double /*tol*/) const
{
T summe = 0;
// nIntervals mu� gerade sein, Intervall-Punkte: 0 bis 2m
if (nIntervals%2)
nIntervals++;
T delta = (x2-x1) / nIntervals;
T u = x1;
summe += delta/3 * Execute(u); // 0
u += delta;
summe += 4*delta/3 * Execute(u); // 1
u += delta;
for (long i=1; i<nIntervals/2; i++)
{
summe += 4*delta/3 * Execute(u); // 2j, von 2 bis 2m-2
u += delta;
summe += 2*delta/3 * Execute(u); // 2j+1, von 3 bis 2m-1
u += delta;
}
summe += delta/3 * Execute(u); // 2m
return summe;
};
template <class T>
bool CFunction<T>::IsConstFunction(CString& str, const char* Token)
{
// Token OK ?
if (strnicmp(str, Token, strlen(Token)) != 0) return false;
// Nach Token Klammer auf oder leer ?
if (str.GetAt(strlen(Token))!='(' && str.GetAt(strlen(Token))!=' ') return false;
// Verbliebener Ausdruck Identit�t ?
CString str1 = str.Mid(strlen(Token)+1);
str1 = str1.Left(str1.GetLength()-1);
if (!CFunction<T>::IsConst(str.Mid(strlen(Token)))) return false;
str = str1;
// Alle Tests �berstanden -> true zur�ckgeben
return true;
};
template <class T>
bool CFunction<T>::IsPureFunction(CString& str, const char* Token, const char* Var)
{
// Token OK ?
if (strnicmp(str, Token, strlen(Token)) != 0) return false;
// Nach Token Klammer auf oder leer ?
if (str.GetAt(strlen(Token))!='(' && str.GetAt(strlen(Token))!=' ') return false;
// Verbliebener Ausdruck Identit�t ?
if (!CFunction<T>::IsIdentity(str.Mid(strlen(Token)), Var)) return false;
// Alle Tests �berstanden -> true zur�ckgeben
return true;
};
template <class T>
bool CFunction<T>::IsFunction(CString& str, const char* Token)
{
if (strnicmp(str, Token, strlen(Token)) != 0) return false;
if (str.GetAt(strlen(Token))!='(' && str.GetAt(strlen(Token))!=' ') return false;
int Level = 0;
for (int i=strlen(Token); i<str.GetLength(); i++)
{
switch (str[i])
{
case '(': Level++; break;
case ')': Level--; break;
}
if (Level==0 && i<str.GetLength()-1) return false;
}
if (Level!=0) return false;
str = str.Mid(strlen(Token));
return true;
};
template <class T>
bool CFunction<T>::IsConst(const char* str)
{
// Konstanten abfragen
CString str1(str);
str1.TrimLeft();
str1.TrimRight();
if (stricmp(str1, _T("M_E"))==0) return true;
if (stricmp(str1, _T("M_LOG2E"))==0) return true;
if (stricmp(str1, _T("M_LOG10E"))==0) return true;
if (stricmp(str1, _T("M_LN2"))==0) return true;
if (stricmp(str1, _T("M_LN10"))==0) return true;
if (stricmp(str1, _T("M_PI_2"))==0) return true;
if (stricmp(str1, _T("M_PI_4"))==0) return true;
if (stricmp(str1, _T("M_PI"))==0) return true;
if (stricmp(str1, _T("M_1_PI"))==0) return true;
if (stricmp(str1, _T("M_2_PI"))==0) return true;
if (stricmp(str1, _T("M_1_SQRTPI"))==0) return true;
if (stricmp(str1, _T("M_2_SQRTPI"))==0) return true;
if (stricmp(str1, _T("M_SQRT2"))==0) return true;
if (stricmp(str1, _T("M_SQRT_2"))==0) return true;
if (stricmp(str1, _T("PI"))==0) return true;
char* stopstring;
T x;
x = strtod(str, &stopstring);
return (stopstring==NULL || strlen(stopstring)==0) ? true : false;
};
template <class T>
T CFunction<T>::Value(const char* str)
{
CString str1(str);
str1.TrimLeft();
str1.TrimRight();
if (stricmp(str1, _T("M_E"))==0) return 2.71828182845904523536;
if (stricmp(str1, _T("M_LOG2E"))==0) return 1.44269504088896340736;
if (stricmp(str1, _T("M_LOG10E"))==0) return 0.434294481903251827651;
if (stricmp(str1, _T("M_LN2"))==0) return 0.693147180559945309417;
if (stricmp(str1, _T("M_LN10"))==0) return 2.30258509299404568402;
if (stricmp(str1, _T("M_PI_2"))==0) return 1.57079632679489661923;
if (stricmp(str1, _T("M_PI_4"))==0) return 0.785398163397448309616;
if (stricmp(str1, _T("M_PI"))==0) return 3.14159265358979323846;
if (stricmp(str1, _T("M_1_PI"))==0) return 0.318309886183790671538;
if (stricmp(str1, _T("M_2_PI"))==0) return 0.636619772367581343076;
if (stricmp(str1, _T("M_1_SQRTPI"))==0) return 0.564189583547756286948;
if (stricmp(str1, _T("M_2_SQRTPI"))==0) return 1.12837916709551257390;
if (stricmp(str1, _T("M_SQRT2"))==0) return 1.41421356237309504880;
if (stricmp(str1, _T("M_SQRT_2"))==0) return 0.707106781186547524401;
if (stricmp(str1, _T("PI"))==0) return 3.14159265358979323846;
char* stopstring;
T x;
x = strtod(str, &stopstring);
return x;
};
template <class T>
bool CFunction<T>::IsIdentity(const char* str, const char* Var)
{
int i;
int Level = 0;
CString str1 = str;
// Einschlie�ende Klammern beseitigen
for (i=0; i<str1.GetLength(); i++)
{
switch (str1[i])
{
case '(': Level++; continue;
case ')': Level--; continue;
}
if (Level==0 && i<str1.GetLength()-1)
{
Level = -1; // Markierung
break;
}
}
if (Level!=-1)
{
while (str1[0]=='(' && str1[str1.GetLength()-1]==')')
{
str1 = str1.Mid(1, str1.GetLength()-2);
}
}
// F�hrende Leerzeichen und positive Vorzeichen entfernen
while (str1[0]=='+' || str1[0]==' ')
{
str1 = str1.Mid(1);
}
return (stricmp(str1, Var)==0) ? true : false;
};
template <class T>
CFunction<T>* CFunction<T>::Parse1(const char* str, const char* Var)
{
CString str1 = str;
return CFunction<T>::Parse(str1, Var);
};
template <class T>
CFunction<T>* CFunction<T>::Parse(CString& str, const char* Var)
{
int i;
int Level = 0;
CMathString str1;
CMathString str2;
// Punkte durch Kommas ersetzen, alles runde Klammern
CMathString::Replace_All(str, _T("."), _T(","));
CMathString::Replace_All(str, _T("["), _T("("));
CMathString::Replace_All(str, _T("]"), _T(")"));
CMathString::Replace_All(str, _T("{"), _T("("));
CMathString::Replace_All(str, _T("}"), _T(")"));
// Einschlie�ende Klammern beseitigen
for (i=0; i<str.GetLength(); i++)
{
switch (str[i])
{
case '(': Level++; continue;
case ')': Level--; continue;
}
if (Level==0 && i<str.GetLength()-1)
{
Level = -1; // Markierung
break;
}
}
if (Level!=-1)
{
while (str[0]=='(' && str[str.GetLength()-1]==')')
{
str = str.Mid(1, str.GetLength()-2);
}
}
// F�hrende und abschlie�ende Leerzeichen und positive Vorzeichen entfernen
while (str[0]=='+' || str[0]==' ')
{
str = str.Mid(1);
}
str.TrimRight();
/* if (str[0]=='-')
{
CFunction<T>* f2 = CFunction<T>::Parse1(str.Mid(1), Var);
return new CNegFunction<T>(f2);
}*/
// Zerlegen des Ausdrucks, Suche nach Operatoren
Level=0;
//for (i=0; i<str.GetLength(); i++)
for (i=str.GetLength()-1; i>=0; i--)
{
// Verarbeitung von Klammern
switch (str[i])
{
case '(': Level--; continue;
case ')': Level++; continue;
}
// Weiterarbeiten nur, wenn in �u�erer Ebene
if (Level>0) continue;
// Operatoren des niedrigsten Ranges
if (str[i]=='+' && Level==0 && i>0 && IsConst(str.Left(i)) && IsConst(str.Mid(i+1)))
{
return new CConstFunction<T>(CFunction<T>::Value(str.Left(i)) + CFunction<T>::Value(str.Mid(i+1)));
}
if (str[i]=='+' && Level==0 && i>0 && IsConst(str.Left(i)))
{
CFunction<T>* f2 = CFunction<T>::Parse1(str.Mid(i+1), Var);
CFunction<T>* f3 = new CAdd0Function<T>(f2, CFunction<T>::Value(str.Left(i)));
if (f3->IsNullFunction())
{
delete f3;
return new CNullFunction<T>();
}
if (f3->IsConstantFunction())
{
T value1 = f3->Execute(0.0);
delete f3;
return new CConstFunction<T>(value1);
}
return f3;
}
if (str[i]=='+' && Level==0 && i>0 && IsConst(str.Mid(i+1)))
{
CFunction<T>* f1 = CFunction<T>::Parse1(str.Left(i), Var);
CFunction<T>* f3 = new CAdd0Function<T>(f1, CFunction<T>::Value(str.Mid(i+1)));
if (f3->IsNullFunction())
{
delete f3;
return new CNullFunction<T>();
}
if (f3->IsConstantFunction())
{
T value1 = f3->Execute(0.0);
delete f3;
return new CConstFunction<T>(value1);
}
return f3;
}
if (str[i]=='+' && Level==0 && i>0)
{
CFunction<T>* f1 = CFunction<T>::Parse1(str.Left(i), Var);
if (str.Left(i) == str.Mid(i+1))
{
return new CMul0Function<T>(f1, 2);
}
CFunction<T>* f2 = CFunction<T>::Parse1(str.Mid(i+1), Var);
CFunction<T>* f3 = new CAddFunction<T>(f1, f2);
if (f3->IsNullFunction())
{
delete f3;
return new CNullFunction<T>();
}
if (f3->IsConstantFunction())
{
T value1 = f3->Execute(0.0);
delete f3;
return new CConstFunction<T>(value1);
}
return f3;
}
if (str[i]=='-' && Level==0 && i==0 && IsConst(str.Mid(i+1)))
{
return new CConstFunction<T>(CFunction<T>::Value(str));
}
if (str[i]=='-' && Level==0 && i==0)
{
CFunction<T>* f1 = CFunction<T>::Parse1(str.Mid(i+1), Var);
if (f1->IsNullFunction())
{
delete f1;
return new CNullFunction<T>();
}
if (f1->IsConstantFunction())
{
T value1 = f1->Execute(0.0);
delete f1;
return new CConstFunction<T>(-value1);
}
return new CNegFunction<T>(f1);
}
if (str[i]=='-' && Level==0 && i>0 && IsConst(str.Left(i)) && IsConst(str.Mid(i+1)))
{
return new CConstFunction<T>(CFunction<T>::Value(str.Left(i)) - CFunction<T>::Value(str.Mid(i+1)));
}
if (str[i]=='-' && Level==0 && i>0 && IsConst(str.Left(i)))
{
CFunction<T>* f2 = CFunction<T>::Parse1(str.Mid(i+1), Var);
CFunction<T>* f3 = new CSubL0Function<T>(CFunction<T>::Value(str.Left(i)), f2);
if (f3->IsNullFunction())
{
delete f3;
return new CNullFunction<T>();
}
if (f3->IsConstantFunction())
{
T value1 = f3->Execute(0.0);
delete f3;
return new CConstFunction<T>(value1);
}
return f3;
}
if (str[i]=='-' && Level==0 && i>0 && IsConst(str.Mid(i+1)))
{
CFunction<T>* f1 = CFunction<T>::Parse1(str.Left(i), Var);
CFunction<T>* f3 = new CSubR0Function<T>(f1, CFunction<T>::Value(str.Mid(i+1)));
if (f3->IsNullFunction())
{
delete f3;
return new CNullFunction<T>();
}
if (f3->IsConstantFunction())
{
T value1 = f3->Execute(0.0);
delete f3;
return new CConstFunction<T>(value1);
}
return f3;
}
if (str[i]=='-' && Level==0 && i>0)
{
if (str.Left(i) == str.Mid(i+1))
{
return new CNullFunction<T>;
}
CFunction<T>* f1 = CFunction<T>::Parse1(str.Left(i), Var);
CFunction<T>* f2 = CFunction<T>::Parse1(str.Mid(i+1), Var);
CFunction<T>* f3 = new CSubFunction<T>(f1, f2);
if (f3->IsNullFunction())
{
delete f3;
return new CNullFunction<T>();
}
if (f3->IsConstantFunction())
{
T value1 = f3->Execute(0.0);
delete f3;
return new CConstFunction<T>(value1);
}
return f3;
}
}
Level=0;
//for (i=0; i<str.GetLength(); i++)
for (i=str.GetLength()-1; i>=0; i--)
{
// Verarbeitung von Klammern
switch (str[i])
{
case '(': Level--; continue;
case ')': Level++; continue;
}
if (str[i]=='*' && Level==0 && i>0)
{
str1 = str.Left(i);
str2 = str.Mid(i+1);
if (IsConst(str1) && IsConst(str2))
{
T value = CFunction<T>::Value(str1) * CFunction<T>::Value(str2);
if (value == 0.0)
return new CNullFunction<T>();
return new CConstFunction<T>(value);
}
if (IsConst(str1) && !IsConst(str2))
{
T value = CFunction<T>::Value(str1);
if (value == 0.0)
return new CNullFunction<T>();
CFunction<T>* f1 = CFunction<T>::Parse1(str2, Var);
CFunction<T>* f3 = new CMul0Function<T>(f1, value);
if (f3->IsNullFunction())
{
delete f3;
return new CNullFunction<T>();
}
if (f3->IsConstantFunction())
{
T value1 = f3->Execute(0.0);
delete f3;
return new CConstFunction<T>(value1);
}
return f3;
}
if (!IsConst(str1) && IsConst(str2))
{
T value = CFunction<T>::Value(str2);
if (value == 0.0)
return new CNullFunction<T>();
CFunction<T>* f1 = CFunction<T>::Parse1(str1, Var);
CFunction<T>* f3 = new CMul0Function<T>(f1, value);
if (f3->IsNullFunction())
{
delete f3;
return new CNullFunction<T>();
}
if (f3->IsConstantFunction())
{
T value1 = f3->Execute(0.0);
delete f3;
return new CConstFunction<T>(value1);
}
return f3;
}
if (!IsConst(str1) && !IsConst(str2))
{
CFunction<T>* f1 = CFunction<T>::Parse1(str.Left(i), Var);
if (str1 == str2 && str1 == Var)
{
return new CSqr1Function<T>;
}
if (str1 == str2 && str1 != Var)
{
return new CSqrFunction<T>(f1);
}
CFunction<T>* f2 = CFunction<T>::Parse1(str.Mid(i+1), Var);
CFunction<T>* f3 = new CMulFunction<T>(f1, f2);
if (f3->IsNullFunction())
{
delete f3;
return new CNullFunction<T>();
}
if (f3->IsConstantFunction())
{
T value1 = f3->Execute(0.0);
delete f3;
return new CConstFunction<T>(value1);
}
return f3;
}
}
if (str[i]=='/' && Level==0 && i>0)
{
str1 = str.Left(i);
str2 = str.Mid(i+1);
if (IsConst(str1) && IsConst(str2))
{
return new CConstFunction<T>(CFunction<T>::Value(str1) / CFunction<T>::Value(str2));
}
if (IsConst(str1) && !IsConst(str2))
{
T value = CFunction<T>::Value(str1);
if (value == 0.0)
return new CNullFunction<T>();
CFunction<T>* f1 = CFunction<T>::Parse1(str2, Var);
CFunction<T>* f3 = new CDivL0Function<T>(value, f1);
if (f3->IsNullFunction())
{
delete f3;
return new CNullFunction<T>();
}
if (f3->IsConstantFunction())
{
T value1 = f3->Execute(0.0);
delete f3;
return new CConstFunction<T>(value1);
}
return f3;
}
if (!IsConst(str1) && IsConst(str2))
{
T value = CFunction<T>::Value(str2);
if (value == 0.0)
return new CNullFunction<T>();
CFunction<T>* f1 = CFunction<T>::Parse1(str1, Var);
CFunction<T>* f3 = new CDivR0Function<T>(f1, value);
if (f3->IsNullFunction())
{
delete f3;
return new CNullFunction<T>();
}
if (f3->IsConstantFunction())
{
T value1 = f3->Execute(0.0);
delete f3;
return new CConstFunction<T>(value1);
}
return f3;
}
if (!IsConst(str1) && !IsConst(str2))
{
if (str1 == str2)
{
return new CConstFunction<T>(1.0);
}
CFunction<T>* f1 = CFunction<T>::Parse1(str.Left(i), Var);
CFunction<T>* f2 = CFunction<T>::Parse1(str.Mid(i+1), Var);
CFunction<T>* f3 = new CDivFunction<T>(f1, f2);
if (f3->IsNullFunction())
{
delete f3;
return new CNullFunction<T>();
}
if (f3->IsConstantFunction())
{
T value = f3->Execute(0.0);
delete f3;
return new CConstFunction<T>(value);
}
return f3;
}
}
}
Level=0;
//for (i=0; i<str.GetLength(); i++)
for (i=str.GetLength()-1; i>=0; i--)
{
// Verarbeitung von Klammern
switch (str[i])
{
case '(': Level--; continue;
case ')': Level++; continue;
}
if (str[i]=='^' && Level==0 && i>0)
{
str1 = str.Left(i);
str2 = str.Mid(i+1);
if (IsConst(str1) && IsConst(str2))
{
return new CConstFunction<T>(powl(CFunction<T>::Value(str1), CFunction<T>::Value(str2)));
}
if (IsConst(str1) && !IsConst(str2))
{
CFunction<T>* f1 = CFunction<T>::Parse1(str2, Var);
return new CPowerL0Function<T>(CFunction<T>::Value(str1), f1);
}
if (!IsConst(str1) && IsConst(str2))
{
CFunction<T>* f1 = CFunction<T>::Parse1(str1, Var);
return new CPowerR0Function<T>(f1, CFunction<T>::Value(str2));
}
if (!IsConst(str1) && !IsConst(str2))
{
CFunction<T>* f1 = CFunction<T>::Parse1(str.Left(i), Var);
CFunction<T>* f2 = CFunction<T>::Parse1(str.Mid(i+1), Var);
return new CPowerFunction<T>(f1, f2);
}
}
}
// Suche nach Funktionen
if (IsConstFunction(str, _T("EXP")))
{
T value = CFunction<T>::Value(str);
return new CConstFunction<T>(expl(value));
}
if (IsConstFunction(str, _T("SIN")))
{
T value = CFunction<T>::Value(str);
if (value == 0.0)
return new CNullFunction<T>();
return new CConstFunction<T>(sinl(value));
}
if (IsConstFunction(str, _T("COS")))
{
T value = CFunction<T>::Value(str);
return new CConstFunction<T>(cosl(value));
}
if (IsConstFunction(str, _T("TAN")))
{
T value = CFunction<T>::Value(str);
if (value == 0.0)
return new CNullFunction<T>();
return new CConstFunction<T>(tanl(value));
}
if (IsConstFunction(str, _T("COT")))
{
T value = CFunction<T>::Value(str);
return new CConstFunction<T>(cosl(value)/sinl(value));
}
if (IsConstFunction(str, _T("SINH")))
{
T value = CFunction<T>::Value(str);
if (value == 0.0)
return new CNullFunction<T>();
return new CConstFunction<T>(sinhl(value));
}
if (IsConstFunction(str, _T("COSH")))
{
T value = CFunction<T>::Value(str);
return new CConstFunction<T>(coshl(value));
}
if (IsConstFunction(str, _T("TANH")))
{
T value = CFunction<T>::Value(str);
if (value == 0.0)
return new CNullFunction<T>();
return new CConstFunction<T>(tanhl(value));
}
if (IsConstFunction(str, _T("ABS")))
{
T value = CFunction<T>::Value(str);
if (value == 0.0)
return new CNullFunction<T>();
return new CConstFunction<T>(fabsl(value));
}
if (IsConstFunction(str, _T("CEIL")))
{
T value = CFunction<T>::Value(str);
if (value == 0.0)
return new CNullFunction<T>();
return new CConstFunction<T>(ceill(value));
}
if (IsConstFunction(str, _T("FLOOR")))
{
T value = CFunction<T>::Value(str);
if (value == 0.0)
return new CNullFunction<T>();
return new CConstFunction<T>(floorl(value));
}
if (IsConstFunction(str, _T("LG")))
{
T value = CFunction<T>::Value(str);
if (value == 1.0)
return new CNullFunction<T>();
return new CConstFunction<T>(log10l(value));
}
if (IsConstFunction(str, _T("LN")))
{
T value = CFunction<T>::Value(str);
if (value == 1.0)
return new CNullFunction<T>();
return new CConstFunction<T>(logl(value));
}
if (IsConstFunction(str, _T("SQRT")))
{
T value = CFunction<T>::Value(str);
if (value == 0.0)
return new CNullFunction<T>();
return new CConstFunction<T>(sqrtl(value));
}
if (IsConstFunction(str, _T("ASIN")))
{
T value = CFunction<T>::Value(str);
if (value == 0.0)
return new CNullFunction<T>();
return new CConstFunction<T>(asinl(value));
}
if (IsConstFunction(str, _T("ACOS")))
{
T value = CFunction<T>::Value(str);
return new CConstFunction<T>(acosl(value));
}
if (IsConstFunction(str, _T("ATAN")))
{
T value = CFunction<T>::Value(str);
if (value == 0.0)
return new CNullFunction<T>();
return new CConstFunction<T>(atanl(value));
}
if (IsConstFunction(str, _T("GAMMA")))
{
T value = CFunction<T>::Value(str);
return new CConstFunction<T>(FGammal(value));
}
if (IsPureFunction(str, _T("EXP"), Var))
return new CExp1Function<T>;
if (IsPureFunction(str, _T("SIN"), Var))
return new CSin1Function<T>;
if (IsPureFunction(str, _T("COS"), Var))
return new CCos1Function<T>;
if (IsPureFunction(str, _T("TAN"), Var))
return new CTan1Function<T>;
if (IsPureFunction(str, _T("COT"), Var))
return new CCot1Function<T>;
if (IsPureFunction(str, _T("SINH"), Var))
return new CSinh1Function<T>;
if (IsPureFunction(str, _T("COSH"), Var))
return new CCosh1Function<T>;
if (IsPureFunction(str, _T("TANH"), Var))
return new CTanh1Function<T>;
if (IsPureFunction(str, _T("COTH"), Var))
return new CCoth1Function<T>;
if (IsPureFunction(str, _T("ABS"), Var))
return new CAbs1Function<T>;
if (IsPureFunction(str, _T("CEIL"), Var))
return new CCeil1Function<T>;
if (IsPureFunction(str, _T("FLOOR"), Var))
return new CFloor1Function<T>;
if (IsPureFunction(str, _T("LG"), Var))
return new CLog101Function<T>;
if (IsPureFunction(str, _T("LN"), Var))
return new CLog1Function<T>;
if (IsPureFunction(str, _T("SQRT"), Var))
return new CSqrt1Function<T>;
if (IsPureFunction(str, _T("ASIN"), Var))
return new CAsin1Function<T>;
if (IsPureFunction(str, _T("ACOS"), Var))
return new CAcos1Function<T>;
if (IsPureFunction(str, _T("ATAN"), Var))
return new CAtan1Function<T>;
if (IsPureFunction(str, _T("GAMMA"), Var))
return new CGamma1Function<T>;
if (IsFunction(str, _T("EXP")))
return new CExpFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("SIN")))
return new CSinFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("COS")))
return new CCosFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("TAN")))
return new CTanFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("COT")))
return new CCotFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("SINH")))
return new CSinhFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("COSH")))
return new CCoshFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("TANH")))
return new CTanhFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("COTH")))
return new CCothFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("ABS")))
return new CAbsFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("CEIL")))
return new CCeilFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("FLOOR")))
return new CFloorFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("LG")))
return new CLog10Function<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("LN")))
return new CLogFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("SQRT")))
return new CSqrtFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("ASIN")))
return new CAsinFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("ACOS")))
return new CAcosFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("ATAN")))
return new CAtanFunction<T>(CFunction<T>::Parse(str, Var));
if (IsFunction(str, _T("GAMMA")))
return new CGammaFunction<T>(CFunction<T>::Parse(str, Var));
// x ?
if (stricmp(str, Var)==0)
return new CIdentityFunction<T>;
if (str[0]=='-') // Ist diese Position besser?
{
CFunction<T>* f2 = CFunction<T>::Parse1(str.Mid(1), Var);
if (f2->IsNullFunction())
{
delete f2;
return new CNullFunction<T>();
}
if (f2->IsConstantFunction())
{
T value = f2->Execute(0.0);
delete f2;
return new CConstFunction<T>(-value);
}
return new CNegFunction<T>(f2);
}
#pragma warning ( disable : 4244 )
return new CConstFunction<T>(CFunction<T>::Value(str));
#pragma warning ( default : 4244 )
};
template <class T>
CString CFunction1<T>::GetConcName(const char* basisfkt) const
{
CString str = basisfkt;
str += _T("(");
str += f1->GetName();
str += _T(")");
return str;
};
template <class T>
CString CFunction2<T>::GetConcName(const char* basisfkt) const
{
CString str = _T("(");
str += f1->GetName();
str += _T(")");
str += basisfkt;
str += _T("(");
str += f2->GetName();
str += _T(")");
return str;
};
template <class T>
CString CPolynom1Function<T>::GetName() const
{
CString str;
str += CMathString(a1);
str += _T("*x+");
str += CMathString(a0);
return str;
};
template <class T>
CString CPolynom1Function<T>::GetTeX() const
{
CString str;
str += CMathString(a1);
str += _T("x+");
str += CMathString(a0);
return str;
};
template <class T>
CString CPolynom2Function<T>::GetName() const
{
CString str;
str += CMathString(a2);
str += _T("*x^2+");
str += CMathString(a1);
str += _T("*x+");
str += CMathString(a0);
return str;
};
template <class T>
CString CPolynom2Function<T>::GetTeX() const
{
CString str;
str += CMathString(a2);
str += _T("x^2+");
str += CMathString(a1);
str += _T("x+");
str += CMathString(a0);
return str;
};
template <class T>
CString CPolynom3Function<T>::GetName() const
{
CString str;
str += CMathString(a3);
str += _T("*x^3+");
str += CMathString(a2);
str += _T("*x^2+");
str += CMathString(a1);
str += _T("*x+");
str += CMathString(a0);
return str;
};
template <class T>
CString CPolynom3Function<T>::GetTeX() const
{
CString str;
str += CMathString(a3);
str += _T("x^3+");
str += CMathString(a2);
str += _T("x^2+");
str += CMathString(a1);
str += _T("x+");
str += CMathString(a0);
return str;
};
template <class T>
CString CPolynom4Function<T>::GetName() const
{
CString str;
str += CMathString(a4);
str += _T("*x^4+");
str += CMathString(a3);
str += _T("*x^3+");
str += CMathString(a2);
str += _T("*x^2+");
str += CMathString(a1);
str += _T("*x+");
str += CMathString(a0);
return str;
};
template <class T>
CString CPolynom4Function<T>::GetTeX() const
{
CString str;
str += CMathString(a4);
str += _T("x^4+");
str += CMathString(a3);
str += _T("x^3+");
str += CMathString(a2);
str += _T("x^2+");
str += CMathString(a1);
str += _T("x+");
str += CMathString(a0);
return str;
};
// f1(x) ^ f2(x)
template <class T>
CFunction<T>* CPowerFunction<T>::GetDerivate() const
{
DERIVATE_TEST;
return new CMulFunction<T>(GetDuplicate(), new CAddFunction<T>(new CMulFunction<T>(f2->GetDerivate(), new CLogFunction<T>(f1->GetDuplicate())),
new CDivFunction<T>(new CMulFunction<T>(f1->GetDerivate(), f2->GetDuplicate()), f1->GetDuplicate())));
};
// c ^ f1(x)
template <class T>
CFunction<T>* CPowerL0Function<T>::GetDerivate() const
{
DERIVATE_TEST;
return new CMulFunction<T>(GetDuplicate(), new CMul0Function<T>(f1->GetDerivate(), logl(c)));
};
// f1(x) ^ c
template <class T>
CFunction<T>* CPowerR0Function<T>::GetDerivate() const
{
DERIVATE_TEST;
if (c==0)
return new CNullFunction<T>;
if (c==1)
return f1->GetDerivate();
return new CMul0Function<T>(new CMulFunction<T>(new CPowerR0Function<T>(f1->GetDuplicate(), c-1), f1->GetDerivate()), c);
};
template <class T>
CFunction<T>* CNullFunction<T>::GetDuplicate(bool /*simplify*/ /*= true*/) const
{
return new CNullFunction<T>;
};
template <class T>
CFunction<T>* CPolynom1Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
if (simplify)
{
if (a1==0.0 && a0==0.0)
return new CNullFunction<T>();
if (a1==0.0)
return new CConstFunction<T>(a0);
}
return new CPolynom1Function<T>(a0,a1);
};
template <class T>
CFunction<T>* CPolynom2Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
if (simplify)
{
if (a2==0.0 && a1==0.0 && a0==0.0)
return new CNullFunction<T>();
if (a2==0.0 && a1==0.0)
return new CConstFunction<T>(a0);
if (a2==0.0)
return new CPolynom1Function<T>(a0, a1);
}
return new CPolynom2Function<T>(a0,a1,a2);
};
template <class T>
CFunction<T>* CPolynom3Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
if (simplify)
{
if (a3==0.0 && a2==0.0 && a1==0.0 && a0==0.0)
return new CNullFunction<T>();
if (a3==0.0 && a2==0.0 && a1==0.0)
return new CConstFunction<T>(a0);
if (a3==0.0 && a2==0.0)
return new CPolynom1Function<T>(a0, a1);
if (a3==0.0)
return new CPolynom2Function<T>(a0, a1, a2);
}
return new CPolynom3Function<T>(a0,a1,a2,a3);
};
template <class T>
CFunction<T>* CPolynom4Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
if (simplify)
{
if (a4==0.0 && a3==0.0 && a2==0.0 && a1==0.0 && a0==0.0)
return new CNullFunction<T>();
if (a4==0.0 && a3==0.0 && a2==0.0 && a1==0.0)
return new CConstFunction<T>(a0);
if (a4==0.0 && a3==0.0 && a2==0.0)
return new CPolynom1Function<T>(a0, a1);
if (a4==0.0 && a3==0.0)
return new CPolynom2Function<T>(a0, a1, a2);
if (a4==0.0)
return new CPolynom3Function<T>(a0, a1, a2, a3);
}
return new CPolynom4Function<T>(a0,a1,a2,a3,a4);
};
template <class T>
CFunction<T>* CExpFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CExpFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CSinFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CSinFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CCosFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CCosFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CTanFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CTanFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CCotFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CCotFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CAsinFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CAsinFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CAcosFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CAcosFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CAtanFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CAtanFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CAcotFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CAcotFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CSinhFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CSinhFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CCoshFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CCoshFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CTanhFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CTanhFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CCothFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CCothFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CSignFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CSignFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CAbsFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CAbsFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CCeilFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CCeilFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CFloorFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CFloorFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CLog10Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CLog10Function<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CLogFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CLogFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CLogarithmusFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CLogarithmusFunction<T>(f1->GetDuplicate(simplify), b);
};
template <class T>
CFunction<T>* CSqrFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CSqrFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CSqrtFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CSqrtFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CGammaFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CGammaFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CConstFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
if (simplify && c==0.0)
return new CNullFunction<T>();
return new CConstFunction<T>(c);
};
template <class T>
CFunction<T>* CNegFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CNegFunction<T>(f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CAdd0Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
CFunction<T>* df1 = f1->GetDuplicate(simplify);
if (simplify)
{
if (df1->IsNullFunction())
{
delete df1;
return new CConstFunction<T>(c);
}
if (df1->IsConstantFunction())
{
T value = df1->Execute(0.0);
delete df1;
return new CConstFunction<T>(c+value);
}
}
return new CAdd0Function<T>(df1, c);
};
template <class T>
CFunction<T>* CSubR0Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
CFunction<T>* df1 = f1->GetDuplicate(simplify);
if (simplify)
{
if (df1->IsNullFunction())
{
delete df1;
return new CConstFunction<T>(-c);
}
if (df1->IsConstantFunction())
{
T value = df1->Execute(0.0);
delete df1;
return new CConstFunction<T>(value-c);
}
}
return new CSubR0Function<T>(df1, c);
};
template <class T>
CFunction<T>* CSubL0Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
CFunction<T>* df1 = f1->GetDuplicate(simplify);
if (simplify)
{
if (df1->IsNullFunction())
{
delete df1;
return new CConstFunction<T>(c);
}
if (df1->IsConstantFunction())
{
T value = df1->Execute(0.0);
delete df1;
return new CConstFunction<T>(c-value);
}
}
return new CSubL0Function<T>(c, df1);
};
template <class T>
CFunction<T>* CMul0Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
CFunction<T>* df1 = f1->GetDuplicate(simplify);
if (simplify)
{
if (df1->IsNullFunction())
{
delete df1;
return new CNullFunction<T>();
}
if (df1->IsConstantFunction())
{
T value = df1->Execute(0.0);
delete df1;
return new CConstFunction<T>(c*value);
}
}
return new CMul0Function<T>(df1, c);
};
template <class T>
CFunction<T>* CDivL0Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
CFunction<T>* df1 = f1->GetDuplicate(simplify);
if (simplify)
{
if (df1->IsConstantFunction())
{
T value = df1->Execute(0.0);
delete df1;
return new CConstFunction<T>(c/value);
}
}
return new CDivL0Function<T>(c, df1);
};
template <class T>
CFunction<T>* CDivR0Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
CFunction<T>* df1 = f1->GetDuplicate(simplify);
if (simplify)
{
if (df1->IsNullFunction())
{
delete df1;
return new CNullFunction<T>();
}
if (df1->IsConstantFunction())
{
T value = df1->Execute(0.0);
delete df1;
return new CConstFunction<T>(value/c);
}
}
return new CDivR0Function<T>(df1, c);
};
template <class T>
CFunction<T>* CAddFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
CFunction<T>* df1 = f1->GetDuplicate(simplify);
CFunction<T>* df2 = f2->GetDuplicate(simplify);
if (simplify)
{
if (df1->IsNullFunction() && df2->IsNullFunction())
{
delete df1;
delete df2;
return new CNullFunction<T>();
}
if (df1->IsConstantFunction() && df2->IsConstantFunction())
{
T value1 = df1->Execute(0.0);
T value2 = df2->Execute(0.0);
delete df1;
delete df2;
return new CConstFunction<T>(value1 + value2);
}
if (df1->IsConstantFunction())
{
T value1 = df1->Execute(0.0);
delete df1;
return new CAdd0Function<T>(df2, value1);
}
if (df2->IsConstantFunction())
{
T value2 = df2->Execute(0.0);
delete df2;
return new CAdd0Function<T>(df1, value2);
}
}
return new CAddFunction<T>(df1, df2);
};
template <class T>
CFunction<T>* CSubFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
CFunction<T>* df1 = f1->GetDuplicate(simplify);
CFunction<T>* df2 = f2->GetDuplicate(simplify);
if (simplify)
{
if (df1->IsNullFunction() && df2->IsNullFunction())
{
delete df1;
delete df2;
return new CNullFunction<T>();
}
if (df1->IsConstantFunction() && df2->IsConstantFunction())
{
T value1 = df1->Execute(0.0);
T value2 = df2->Execute(0.0);
delete df1;
delete df2;
return new CConstFunction<T>(value1 - value2);
}
if (df1->IsConstantFunction())
{
T value1 = df1->Execute(0.0);
delete df1;
return new CSubL0Function<T>(value1, df2);
}
if (df2->IsConstantFunction())
{
T value2 = df2->Execute(0.0);
delete df2;
return new CSubR0Function<T>(df1, value2);
}
}
return new CSubFunction<T>(df1, df2);
};
template <class T>
CFunction<T>* CMulFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
CFunction<T>* df1 = f1->GetDuplicate(simplify);
CFunction<T>* df2 = f2->GetDuplicate(simplify);
if (simplify)
{
if (df1->IsNullFunction() || df2->IsNullFunction())
{
delete df1;
delete df2;
return new CNullFunction<T>();
}
if (df1->IsConstantFunction() && df2->IsConstantFunction())
{
T value1 = df1->Execute(0.0);
T value2 = df2->Execute(0.0);
delete df1;
delete df2;
return new CConstFunction<T>(value1 * value2);
}
if (df1->IsConstantFunction())
{
T value1 = df1->Execute(0.0);
delete df1;
return new CMul0Function<T>(df2, value1);
}
if (df2->IsConstantFunction())
{
T value2 = df2->Execute(0.0);
delete df2;
return new CMul0Function<T>(df1, value2);
}
}
return new CMulFunction<T>(df1, df2);
};
template <class T>
CFunction<T>* CDivFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
CFunction<T>* df1 = f1->GetDuplicate(simplify);
CFunction<T>* df2 = f2->GetDuplicate(simplify);
if (simplify)
{
if (df1->IsNullFunction())
{
delete df1;
delete df2;
return new CNullFunction<T>();
}
if (df1->IsConstantFunction() && df2->IsConstantFunction())
{
T value1 = df1->Execute(0.0);
T value2 = df2->Execute(0.0);
delete df1;
delete df2;
return new CConstFunction<T>(value1 / value2);
}
if (df1->IsConstantFunction())
{
T value1 = df1->Execute(0.0);
delete df1;
return new CDivL0Function<T>(value1, df2);
}
if (df2->IsConstantFunction())
{
T value2 = df2->Execute(0.0);
delete df2;
return new CDivR0Function<T>(df1, value2);
}
}
return new CDivFunction<T>(df1, df2);
};
template <class T>
CFunction<T>* CPowerFunction<T>::GetDuplicate(bool simplify /*= true*/) const
{
CFunction<T>* df1 = f1->GetDuplicate(simplify);
CFunction<T>* df2 = f2->GetDuplicate(simplify);
if (simplify)
{
if (df1->IsConstantFunction() && df2->IsConstantFunction())
{
T value1 = df1->Execute(0.0);
T value2 = df2->Execute(0.0);
delete df1;
delete df2;
return new CConstFunction<T>(powl(value1, value2));
}
if (df1->IsConstantFunction())
{
T value1 = df1->Execute(0.0);
delete df1;
return new CPowerL0Function<T>(value1, df2);
}
if (df2->IsConstantFunction())
{
T value2 = df2->Execute(0.0);
delete df2;
return new CPowerR0Function<T>(df1, value2);
}
}
return new CPowerFunction<T>(df1, df2);
};
template <class T>
CFunction<T>* CPowerL0Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CPowerL0Function<T>(c, f1->GetDuplicate(simplify));
};
template <class T>
CFunction<T>* CPowerR0Function<T>::GetDuplicate(bool simplify /*= true*/) const
{
return new CPowerR0Function<T>(f1->GetDuplicate(simplify), c);
};
#else
#error already included
#endif