1%%%%%%%%%%%%%%%%%%%
2% XLiFE++ is an extended library of finite elements written in C++
3%     Copyright (C) 2014  Lunéville, Eric; Kielbasiewicz, Nicolas; Lafranche, Yvon; Nguyen, Manh-Ha; Chambeyron, Colin
4%
5%     This program is free software: you can redistribute it and/or modify
6%     it under the terms of the GNU General Public License as published by
7%     the Free Software Foundation, either version 3 of the License, or
8%     (at your option) any later version.
9%     This program is distributed in the hope that it will be useful,
10%     but WITHOUT ANY WARRANTY; without even the implied warranty of
11%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12%     GNU General Public License for more details.
13%     You should have received a copy of the GNU General Public License
14%     along with this program.  If not, see <http://www.gnu.org/licenses/>.
15%%%%%%%%%%%%%%%%%%%
16
17\section{The {\classtitle SymbolicFunction} class}\label{s.symbfunction}
18
19The {\class SymbolicFunction} class handles a function described in a symbolic way, that is an expression involving variables, constant and operators. In fact, a {\class SymbolicFunction} object is a node of a tree :
20\vspace{.1cm}
21\begin{lstlisting}[]{}
22class SymbolicFunction
23{
24   public :
25   const SymbolicFunction* fn1, *fn2;  //nodes involved 0, 1 or 2 (0 by default)
26   VariableName var;                   //variable involved (undef by default)
27   SymbolicOperation op;               //operation involved (id by default)
28   complex_t coef;                     //coefficient to apply to
29   complex_t par;                      //additional parameter
30   ...
31}
32\end{lstlisting}
33\vspace{.2cm}
34A node may be
35\begin{itemize}
36	\item a constant value stored in {\var coef} with {\var fn1=fn2=0} and {\var var=\_varundef}
37	\item a variable ({\var \_x1}, or {\var\_x2} or {\var\_x3}) stored in {\var var}, with  {\var fn1=fn2=0}
38	\item a unary operation stored in {\var op} and acting either on the variable or the {\class SymbolicFunction} object {\var fn1}
39	\item a binary operation stored in {\var op} and acting on the {\class SymbolicFunction} objects {\var fn1} and {\var fn2}
40\end{itemize}
41The unary and binary operators are given by the enumeration:
42\vspace{.1cm}
43\begin{lstlisting}[]{}
44enum SymbolicOperation
45{_idop=0, _plus, _minus, _multiply, _divide, _power,
46 _equal, _different, _less, _lessequal, _greater, _greaterequal, _and, _or,
47 _abs, _realPart, _imagPart, _sqrt, _squared, _sin, _cos, _tan,        //unary
48 _asin, _acos, _atan, _sinh, _cosh, _tanh, _asinh, _acosh, _atanh,     //unary
49 _exp, _log, _log10, _pow, _not                                        //unary
50};
51\end{lstlisting}
52\vspace{.2cm}
53As an example, the function {\var f(x\_1,x\_2)=  (x\_1+x\_2)<1 \&\& exp(x\_1)>2} has the following tree representation:
54\begin{figure}[H]
55\centering
56\includePict[width=14cm]{SymbolicFunction_tree.png}
57\caption{exemple of SymbolicFunction tree}
58\end{figure}
59\begin{remark}
60The function asinh, acosh, atanh are only available when compiling with a C++ version greater than 2011.
61\end{remark}
62
63
64\vspace{.2cm}
65The {\class SymbolicFunction} class provides some basic constructors for each kind of node:
66\vspace{.1cm}
67\begin{lstlisting}[]{}
68explicit SymbolicFunction(VariableName v=_varUndef);
69explicit SymbolicFunction(const real_t&);
70explicit SymbolicFunction(const complex_t&);
71SymbolicFunction(const SymbolicFunction&, SymbolicOperation,
72                 complex_t c=1.,complex_t p=0.);
73SymbolicFunction(const SymbolicFunction&, const SymbolicFunction&,
74                 SymbolicOperation, complex_t c=1., complex_t p=0.);
75SymbolicFunction(const SymbolicFunction&);
76~SymbolicFunction();
77SymbolicFunction& operator=(const SymbolicFunction&);
78\end{lstlisting}
79\vspace{.2cm}
80The copy constructor and the assign operator do full copy of object referenced by pointers {\var fn1} and {\var fn2}. So, the destructor deletes them if they are assigned. Note that the variable {\var coef} and {\var par} are complex. Obviously, they may store some real scalars and the code interprets the imaginary part to know if they are real.\\
81
82In order to make easier the construction of {\class SymbolicFunction} object, a lot of function or operator are provided, for instance :
83\vspace{.1cm}
84\begin{lstlisting}[]{}
85//binary operation on SymbolicFunction's
86SymbolicFunction& operator+ (const SymbolicFunction&, const SymbolicFunction&);
87SymbolicFunction& operator- (const SymbolicFunction&, const SymbolicFunction&);
88SymbolicFunction& operator* (const SymbolicFunction&, const SymbolicFunction&);
89SymbolicFunction& operator/ (const SymbolicFunction&, const SymbolicFunction&);
90SymbolicFunction& operator^ (const SymbolicFunction&, const SymbolicFunction&);
91SymbolicFunction& operator==(const SymbolicFunction&, const SymbolicFunction&);
92SymbolicFunction& operator!=(const SymbolicFunction&, const SymbolicFunction&);
93SymbolicFunction& operator> (const SymbolicFunction&, const SymbolicFunction&);
94SymbolicFunction& operator>=(const SymbolicFunction&, const SymbolicFunction&);
95SymbolicFunction& operator< (const SymbolicFunction&, const SymbolicFunction&);
96SymbolicFunction& operator<=(const SymbolicFunction&, const SymbolicFunction&);
97SymbolicFunction& operator&&(const SymbolicFunction&, const SymbolicFunction&);
98SymbolicFunction& operator||(const SymbolicFunction&, const SymbolicFunction&);
99\end{lstlisting}
100\vspace{.1cm}
101\begin{lstlisting}[]{}
102//unary operation on SymbolicFunction
103SymbolicFunction& operator-(const SymbolicFunction&);
104SymbolicFunction& operator+(const SymbolicFunction&);
105SymbolicFunction& operator!(const SymbolicFunction&);
106SymbolicFunction& abs(const SymbolicFunction&);
107SymbolicFunction& real(const SymbolicFunction&);
108SymbolicFunction& imag(const SymbolicFunction&);
109SymbolicFunction& sqrt(const SymbolicFunction&);
110SymbolicFunction& squared(const SymbolicFunction&);
111SymbolicFunction& sin(const SymbolicFunction&);
112SymbolicFunction& cos(const SymbolicFunction&);
113SymbolicFunction& tan(const SymbolicFunction&);
114SymbolicFunction& asin(const SymbolicFunction&);
115SymbolicFunction& acos(const SymbolicFunction&);
116SymbolicFunction& atan(const SymbolicFunction&);
117SymbolicFunction& sinh(const SymbolicFunction&);
118SymbolicFunction& cosh(const SymbolicFunction&);
119SymbolicFunction& tanh(const SymbolicFunction&);
120SymbolicFunction& exp(const SymbolicFunction&);
121SymbolicFunction& log(const SymbolicFunction&);
122SymbolicFunction& log10(const SymbolicFunction&);
123SymbolicFunction& pow(const SymbolicFunction&, const double&);
124#if __cplusplus > 199711L
125SymbolicFunction& asinh(const SymbolicFunction&);
126SymbolicFunction& acosh(const SymbolicFunction&);
127SymbolicFunction& atanh(const SymbolicFunction&);
128#endif
129\end{lstlisting}
130The binary operators are also provided for {\class SymbolicFunction} object and constant (real or complex).\\
131
132Besides, some basic tools are proposed by the class:
133\vspace{.1cm}
134\begin{lstlisting}[]{}
135bool isSingle() const;  //true if a constant or variable
136bool isConst() const;   //true if a constant expression
137set<VariableName> listOfVar() const; //list of involved variables
138number_t numberOfVar()const; //number of involved variables
139void print(ostream& = cout) const;
140void printTree(ostream& =cout, int lev=0) const;
141\end{lstlisting}
142\vspace{.2cm}
143Finally, by overloading the operator (), the symbolic function can be evaluated for any set of real values or complex values:
144\vspace{.1cm}
145\begin{lstlisting}[]{}
146complex_t operator()(const vector<complex_t>& xs) const;
147complex_t operator()(const complex_t& x1) const;
148complex_t operator()(const complex_t& x1, const complex_t& x2) const;
149complex_t operator()(const complex_t& x1, const complex_t& x2,
150                     const complex_t& x3) const;
151real_t operator()(const vector<real_t>& xs) const;
152real_t operator()(const real_t& x1) const;
153real_t operator()(const real_t& x1, const real_t& x2) const;
154real_t operator()(const real_t& x1, const real_t& x2, const real_t& x3) const;
155\end{lstlisting}
156\vspace{.1cm}
157These member functions use the fundamental functions that performs computations:
158\vspace{.1cm}
159\begin{lstlisting}[]{}
160inline real_t evalOp(SymbolicOperation op,const real_t& x,const real_t& y);
161inline real_t evalFun(SymbolicOperation op,const real_t& x,const real_t& p=0.);
162inline complex_t evalOp(SymbolicOperation op,const complex_t& x,
163                        const complex_t& y);
164inline complex_t evalFun(SymbolicOperation op,const complex_t& z,
165                         const complex_t& p=0.);
166\end{lstlisting}
167\vspace{.2cm}
168Hereafter, some examples of construction of {\class SymbolicFunction} objects:
169\vspace{.1cm}
170\begin{lstlisting}[]{}
171SymbolicFunction fs;
172fs = x_1+x_2-1;
173fs = 2*x_1-3*x_2;
174fs = 5*(2*x_1-3*x_2);
175fs = 4*sqrt(2*x_1-3*x_2)/x_2;
176fs = sin(cos(sqrt(abs(log(x_1*x_1+x_2*x_2+x_3*x_3)))));
177fs = (1.-sin(x_1))*(cos(1.+x_1)/5 + 2*sin(3*x_1));
178fs = pow(squared(x_1), 0.5);
179fs = SymbolicFunction(3);
180fs = -sin(x_1);
181fs = +sin(-x_1);
182fs = cos(x_2)-2*sqrt(x_1*x_2);
183fs = x_1 < 1;
184fs = (x_1+x_2)<=1 && exp(x_1)>2;
185fs = (x_1+x_2)^3;
186\end{lstlisting}
187
188\displayInfos{library=utils, header=SymbolicFunction.hpp, implementation=SymbolicFunction.cpp, test=unit\_SymbolicFunction.cpp,
189header dep={config.h, Messages.hpp}}
190