Import upstream mathexpr

This commit is contained in:
Xavier Del Campo Romero 2024-04-14 21:53:02 +02:00
commit 520274a73d
Signed by: xavi
GPG Key ID: 84FF3612A9BF43F2
7 changed files with 3116 additions and 0 deletions

23
mathexpr/LICENSE Normal file
View File

@ -0,0 +1,23 @@
Copied from http://www.yann-ollivier.org/mathlib/mathexpr:
This software is available under the MIT Licence:
Copyright (c) 1997-2000 Yann OLLIVIER
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,84 @@
/*
example.cpp , example file for mathexpr.cpp 2.0
Copyright (c) 1997-2000 Yann OLLIVIER
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdio.h>
#include "mathexpr.h"
// Compilation :
// g++ mathexpr.cpp example.cpp -lm
int main()
{
// The number that the variable "x" will point to
double x;
// Creates a variable named "x" and which value will be x
RVar xvar ( "x" , &x );
// Asks for a fomula depending on the variable x, e.g. "sin 2x"
char s[500]="";
printf("Enter a formula depending on the variable x:\n");
gets(s);
// Creates an operation with this formula. The operation depends on one
// variable, which is xvar; the third argument is an array of pointers
// to variables; the previous argument is its size
RVar* vararray[1]; vararray[0]=&xvar;
ROperation op ( s, 1, vararray );
// Affects (indirectly) a value to xvar
x=3;
// Printfs the value of the formula for x=3;
printf("%s = %G for x=3\n\n", op.Expr(), op.Val() );
// Creates a function name which can be used in later functions to refer to the operation op(x)
RFunction f (op, &xvar); f.SetName("f");
// Creates a second variable named y, and a formula depending on both x and y
double y;
RVar yvar ( "y" , &y );
RVar* vararray2[2]; // table of variables containing the adresses of xvar and yvar
vararray2[0]=&xvar; vararray2[1]=&yvar;
// Asks for a formula using x, y and the already-defined function f, e.g. x+f(3y)
printf("Enter a formula using x, y and the function f(x): x -> %s that you just entered, e.g. x+f(3y) :\n", op.Expr() );
gets(s);
RFunction* funcarray[1]; funcarray[0]=&f;
ROperation op2 ( (char*)s , 2 , vararray2 , 1, funcarray );
// vararray2 is a RVar* array with two elements
// funcarray is a RFunction* array with one element
y=5;
printf("Value for x=3, y=5 : %G\n", op2.Val() );
// Turns the last expression into a function of x and y
RFunction g(op2, 2, vararray2); g.SetName("g");
// Here is another way to do it
double z,t;
RVar zvar("z", &z), tvar("t", &t);
ROperation op3,zop,top;
zop=zvar; top=tvar; // constructs, from a variable, the operation returning its value
op3=g( (zop+top, top^2) ); // Ready-to-use ; needs two pairs of ( )
// Now op3 contains the operation op2 with x replaced with z+t, and y replaced with t^2
z=5;t=7;
printf("\nLet g be the function g : x,y -> %s\n", op2.Expr() );
printf("Value of %s for z=5,t=7:\n %G\n", op3.Expr(), op3.Val() );
ROperation dopdt = op3.Diff(tvar); // Computes the derivative of op3 w.r.t t
printf("Value of d/dt (g(z+t,t^2)) = %s for z=5,t=7:\n %G\n", dopdt.Expr(), dopdt.Val() );
return 0;
}

View File

@ -0,0 +1,86 @@
/*
example.cpp , example file for mathexpr.cpp 2.0
Copyright (c) 1997-2000 Yann OLLIVIER
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdio.h>
#include "mathexpr_c.h"
// Compilation :
// g++ mathexpr_c.cpp example_c.cpp
int main()
{
// The number that the variable "x" will point to
double_complex x;
// Creates a variable named "x" and which value will be x
CVar xvar ( "x" , &x );
// Asks for a fomula depending on the variable x, e.g. "sin 2x"
char s[500]="";
printf("Enter a formula depending on the variable x:\n");
gets(s);
// Creates an operation with this formula. The operation depends on one
// variable, which is xvar ; the third argument is an array of pointers
// to variables; the previous argument is its size
CVar* vararray[1]; vararray[0]=&xvar;
COperation op ( s, 1, vararray );
// Affects (indirectly) a value to xvar
x=3;
// Printfs the value of the formula for x=3;
printf("%s = %s for x=3\n\n", op.Expr(), PrettyPrint(op.Val()) );
// Creates a function name which can be used in later functions to refer to the operation op(x)
CFunction f (op, &xvar); f.SetName("f");
// Creates a second variable named y, and a formula depending on both x and y
double_complex y;
CVar yvar ( "y" , &y );
CVar* vararray2[2]; // table of variables containing the adresses of xvar and yvar
vararray2[0]=&xvar; vararray2[1]=&yvar;
// Asks for a formula using x, y and the already-defined function f, e.g. x+f(3y)
printf("Enter a formula using x, y and the function f(x): x -> %s that you just entered, e.g. x+f(3y) :\n", op.Expr());
gets(s);
CFunction* funcarray[1]; funcarray[0]=&f;
COperation op2 ( (char*)s , 2 , vararray2 , 1, funcarray );
// vararray2 is a CVar* array with two elements
// funcarray is a CFunction* array with one element
y=5;
printf("Value for x=3, y=5 : %s\n", PrettyPrint(op2.Val()) );
// Turns the last expression into a function of x and y
CFunction g(op2, 2, vararray2); g.SetName("g");
// Here is another way to do it
double_complex z,t;
CVar zvar("z", &z), tvar("t", &t);
COperation op3,zop,top;
zop=zvar; top=tvar; // constructs, from a variable, the operation returning its value
op3=g( (zop+top, top^2) ); // Ready-to-use ; needs two pairs of ( )
// Now op3 contains the operation op2 with x replaced with z+t, and y replaced with t^2
z=5;t=7;
printf("\nLet g be the function g : x,y -> %s\n", op2.Expr());
printf("Value of %s for z=5,t=7:\n %s\n", op3.Expr(), PrettyPrint(op3.Val()) );
COperation dopdt=op3.Diff(tvar); // Computes the derivative of op3 w.r.t t
printf("Value of d/dt (g(z+t,t^2)) = %s for z=5,t=7:\n %s\n", dopdt.Expr(), PrettyPrint(dopdt.Val()) );
COperation dopdtbar=op3.DiffConj(tvar); // Computes the derivative of op3 w.r.t the conjugate of t
printf("Value of d/dtbar (g(z+t,t^2)) = %s for z=5,t=7:\n %s\n", dopdtbar.Expr(), PrettyPrint(dopdtbar.Val()) );
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,146 @@
/*
mathexpr.h version 2.0
Copyright (c) 1997-2000 Yann OLLIVIER
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _MATHEXPR_H
#define _MATHEXPR_H
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<float.h>
// Compatibility with long double-typed functions
#define atanl atan
#define asinl asin
#define acosl acos
#define expl exp
#define logl log
#define powl pow
#define pow10l(x) pow(10,x)
#define fabsl fabs
#define cosl cos
#define sinl sin
#define tanl tan
#define fmodl fmod
#define sqrtl sqrt
// Warning : if ints are short, everything will fail with strings longer than 32767 chars
const double ErrVal=DBL_MAX;
//Class definitions for operations
class RVar{
public:
char*name;double*pval;
RVar(){name=NULL;pval=NULL;};
RVar(const RVar&);
RVar(const char*,double*);
~RVar();
friend int operator==(const RVar&,const RVar&);
};
typedef RVar* PRVar;
enum ROperator{ErrOp,Juxt,Num,Var,Add,Sub,Opp,Mult,Div,Pow,Sqrt,
NthRoot,Abs,Sin,Cos,Tg,Ln,Exp,Acos,Asin,Atan,E10,Fun};
typedef void ((*pfoncld)(double*&));
class ROperation;
typedef ROperation* PROperation;
class RFunction;
typedef RFunction* PRFunction;
class ROperation{
pfoncld*pinstr;double**pvals;double*ppile;RFunction**pfuncpile;
mutable signed char containfuncflag;
void BuildCode();
void Destroy();
public:
ROperator op;
PROperation mmb1,mmb2;
double ValC;const RVar* pvar;double*pvarval;
RFunction* pfunc;
ROperation();
ROperation(const ROperation&);
ROperation(double);
ROperation(const RVar&);
ROperation(char*sp,int nvarp=0,PRVar*ppvarp=NULL,int nfuncp=0,PRFunction*ppfuncp=NULL);
~ROperation();
double Val() const;
signed char ContainVar(const RVar&) const;
signed char ContainFunc(const RFunction&) const;
signed char ContainFuncNoRec(const RFunction&) const; // No recursive test on subfunctions
ROperation NthMember(int) const;int NMembers() const;
signed char HasError(const ROperation* =NULL) const;
ROperation& operator=(const ROperation&);
friend int operator==(const ROperation& ,const double);
friend int operator==(const ROperation& ,const ROperation&);
friend int operator!=(const ROperation& ,const ROperation&);
ROperation operator+() const;ROperation operator-() const;
friend ROperation operator,(const ROperation&,const ROperation&);
friend ROperation operator+(const ROperation&,const ROperation&);
friend ROperation operator-(const ROperation&,const ROperation&);
friend ROperation operator*(const ROperation&,const ROperation&);
friend ROperation operator/(const ROperation&,const ROperation&);
friend ROperation operator^(const ROperation&,const ROperation&); // Caution: wrong associativity and precedence
friend ROperation sqrt(const ROperation&);
friend ROperation abs(const ROperation&);
friend ROperation sin(const ROperation&);
friend ROperation cos(const ROperation&);
friend ROperation tan(const ROperation&);
friend ROperation log(const ROperation&);
friend ROperation exp(const ROperation&);
friend ROperation acos(const ROperation&);
friend ROperation asin(const ROperation&);
friend ROperation atan(const ROperation&);
friend ROperation ApplyOperator(int,ROperation**,ROperation (*)(const ROperation&,const ROperation&));
ROperation Diff(const RVar&) const; // Differentiate w.r.t a variable
char* Expr() const;
ROperation Substitute(const RVar&,const ROperation&) const;
};
class RFunction{
double*buf;
public:
signed char type;
double ((*pfuncval)(double));
ROperation op;int nvars;RVar** ppvar;
char*name;
RFunction();
RFunction(double ((*)(double)));
RFunction(const ROperation& opp,RVar* pvarp);
RFunction(const ROperation& opp,int nvarsp,RVar**ppvarp);
RFunction(const RFunction&);
~RFunction();
RFunction& operator=(const RFunction&);
void SetName(const char*s);
double Val(double) const;
double Val(double*) const;
friend int operator==(const RFunction&,const RFunction&);
ROperation operator()(const ROperation&);
};
char* MidStr(const char*s,int i1,int i2);
char* CopyStr(const char*s);
char* InsStr(const char*s,int n,char c);
signed char EqStr(const char*s,const char*s2);
signed char CompStr(const char*s,int n,const char*s2);
char* DelStr(const char*s,int n);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,160 @@
/*
mathexpr_c.h version 2.0
Copyright (c) 1997-2000 Yann OLLIVIER
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __MATHEXPR_C_H
#define __MATHEXPR_C_H
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<complex>
#include<float.h>
#ifndef __STD_COMPLEX_
#define double_complex std::complex<double>
double_complex tan(double_complex);
double_complex acos(double_complex);
double_complex asin(double_complex);
double_complex atan(double_complex);
#endif
// Compatibility with long double-typed functions
#define atanl atan
#define asinl asin
#define acosl acos
#define expl exp
#define logl log
#define powl pow
#define pow10l(x) pow(10,x)
#define fabsl fabs
#define cosl cos
#define sinl sin
#define tanl tan
#define fmodl fmod
#define sqrtl sqrt
// Warning : everything will fail with strings longer than 32767 chars
const double_complex ErrVal=double_complex(DBL_MAX,0);
//Class definitions for operations
class CVar{
public:
char*name;double_complex*pval;
CVar(const CVar&);
CVar(const char*,double_complex*);
~CVar();
friend int operator==(const CVar&,const CVar&);
};
typedef CVar* PCVar;
enum COperator{ErrOp,Juxt,Num,Var,Add,Sub,Opp,Mult,Div,Pow,Sqrt,
NthRoot,Real,Imag,Conj,Abs,Arg,Sin,Cos,Tg,Ln,Exp,Acos,Asin,Atan,E10,Fun};
typedef void ((*pfoncld)(double_complex*&));
class COperation;
typedef COperation* PCOperation;
class CFunction;
typedef CFunction* PCFunction;
class COperation{
pfoncld*pinstr;double_complex**pvals;double_complex*ppile;CFunction**pfuncpile;
mutable signed char containfuncflag;
void BuildCode();
void Destroy();
public:
COperator op;
PCOperation mmb1,mmb2;
double_complex ValC;const CVar* pvar;double_complex*pvarval;
CFunction* pfunc;
COperation();
COperation(const COperation&);
COperation(double);COperation(double_complex);
COperation(const CVar&);
COperation(char*sp,int nvarp=0,PCVar*ppvarp=NULL,int nfuncp=0,PCFunction*ppfuncp=NULL);
~COperation();
double_complex Val() const;
signed char ContainVar(const CVar&) const;
signed char ContainFunc(const CFunction&) const;
signed char ContainFuncNoRec(const CFunction&) const; // No recursive test on subfunctions
COperation NthMember(int) const;int NMembers() const;
signed char HasError(const COperation* =NULL) const;
COperation& operator=(const COperation&);
friend int operator==(const COperation&,const double);
friend int operator==(const COperation&,const double_complex);
friend int operator==(const COperation&,const COperation&);
friend int operator!=(const COperation&,const COperation&);
COperation operator+() const;COperation operator-() const;
friend COperation operator,(const COperation&,const COperation&);
friend COperation operator+(const COperation&,const COperation&);
friend COperation operator-(const COperation&,const COperation&);
friend COperation operator*(const COperation&,const COperation&);
friend COperation operator/(const COperation&,const COperation&);
friend COperation operator^(const COperation&,const COperation&); // Caution: wrong associativity and precedence
friend COperation real(const COperation&);
friend COperation imag(const COperation&);
friend COperation conj(const COperation&);
friend COperation arg(const COperation&);
friend COperation sqrt(const COperation&);
friend COperation abs(const COperation&);
friend COperation sin(const COperation&);
friend COperation cos(const COperation&);
friend COperation tan(const COperation&);
friend COperation log(const COperation&);
friend COperation exp(const COperation&);
friend COperation acos(const COperation&);
friend COperation asin(const COperation&);
friend COperation atan(const COperation&);
friend COperation ApplyOperator(int,COperation**,COperation (*)(const COperation&,const COperation&));
COperation Diff(const CVar&) const; // Differentiate w.r.t a variable
COperation DiffConj(const CVar&) const; // This one is d / d conj(z)
char* Expr() const;
COperation Substitute(const CVar&,const COperation&) const;
};
class CFunction{
double_complex*buf;
public:
signed char type;
double_complex ((*pfuncval)(double_complex));
COperation op;int nvars;CVar** ppvar;
char*name;
CFunction();
CFunction(double_complex ((*pfuncvalp)(double_complex)));
CFunction(const COperation& opp, CVar* pvarp);
CFunction(const COperation& opp, int nvarsp, CVar**ppvarp);
CFunction(const CFunction&);
~CFunction();
CFunction& operator=(const CFunction&);
void SetName(const char*s);
double_complex Val(double_complex) const;
double_complex Val(double_complex*) const;
friend int operator==(const CFunction&,const CFunction&);
COperation operator()(const COperation&);
};
char* PrettyPrint(double_complex);
char* MidStr(const char*s,int i1,int i2);
char* CopyStr(const char*s);
char* InsStr(const char*s,int n,const char c);
signed char EqStr(const char*s,const char*s2);
signed char CompStr(const char*s,int n,const char*s2);
char* DelStr(const char*s,int n);
#endif