source: Sophya/trunk/SophyaLib/SysTools/rpneval.cc@ 2510

Last change on this file since 2510 was 2510, checked in by ansari, 22 years ago

Ajout fichiers des classes RPNExpressionEvaluator et CExpressionEvaluator (expression arithmetiques) et MAJ du fichier Makefile et objlist.list - Reza 15 Mars 2003

File size: 7.1 KB
Line 
1#include "rpneval.h"
2#include <stdlib.h>
3#include "strutilxx.h"
4#include "srandgen.h"
5#include <iostream>
6#include <math.h>
7
8namespace SOPHYA {
9
10/*!
11 \class SOPHYA::RPNExpressionEvaluator
12 \ingroup SysTools
13 Arithmetic expression (double precision float) evaluator
14 in Reverse Polish Notation (RPN). This is an HP calculator
15 like syntax. Space are used for separating the string
16 expression into tokens.
17*/
18
19RPNExpressionEvaluator::RPNExpressionEvaluator(string const & sex)
20{
21 vector<string> exe;
22 FillVStringFrString(sex, exe, ' ');
23 int rc = EvalRPNExpr(exe, 0);
24 if (rc != 0) throw RPNExprException("RPNExpressionEvaluator() - syntax error");
25}
26
27RPNExpressionEvaluator::RPNExpressionEvaluator(vector<string> & exe, int off)
28{
29 int rc = EvalRPNExpr(exe, off);
30 if (rc != 0) throw RPNExprException("RPNExpressionEvaluator() - syntax error");
31}
32
33RPNExpressionEvaluator::~RPNExpressionEvaluator()
34{
35}
36
37/* Operations sur le stack RPN */
38/* --Methode-- */
39double RPNExpressionEvaluator::Evaluate() const
40{
41 double x;
42 if ( CheckStack( x) )
43 throw RPNExprException("RPNExpressionEvaluator::Evaluate() EmptyStack");
44 else return x;
45}
46
47/* --Methode-- */
48int RPNExpressionEvaluator::EvalRPNExpr(vector<string> & args, int off)
49{
50
51 if (args.size() <= off) return 0;
52 double x,y;
53 x = y = 0.;
54 stack<double> rpnstack_; // Stack des operations en RPN
55 for(int k=off; k<args.size(); k++) {
56 // Les 4 operations de base + - * /
57 if (args[k] == "+") {
58 if ( CheckStack( x, y) ) return(1);
59 rpnstack_.top() = y+x;
60 }
61 else if (args[k] == "-") {
62 if ( CheckStack( x, y) ) return(1);
63 rpnstack_.top() = y-x;
64 }
65 else if (args[k] == "*") {
66 if ( CheckStack( x, y) ) return(1);
67 rpnstack_.top() = y*x;
68 }
69 else if (args[k] == "/") {
70 if ( CheckStack( x, y) ) return(1);
71 rpnstack_.top() = y/x;
72 }
73 else if (args[k] == "%") {
74 if ( CheckStack( x, y) ) return(1);
75 rpnstack_.top() = (int)y % (int)x;
76 }
77 // Les constantes : e , pi
78 else if (args[k] == "e") {
79 rpnstack_.push(M_E);
80 }
81 else if (args[k] == "pi") {
82 rpnstack_.push(M_PI);
83 }
84 // Les fonctions usuelles a 1 argument f(x)
85 else if (args[k] == "cos") {
86 if ( CheckStack( x) ) return(1);
87 rpnstack_.top() = cos(x);
88 }
89 else if (args[k] == "sin") {
90 if ( CheckStack( x) ) return(1);
91 rpnstack_.top() = sin(x);
92 }
93 else if (args[k] == "tan") {
94 if ( CheckStack( x) ) return(1);
95 rpnstack_.top() = tan(x);
96 }
97 else if (args[k] == "acos") {
98 if ( CheckStack( x) ) return(1);
99 rpnstack_.top() = acos(x);
100 }
101 else if (args[k] == "asin") {
102 if ( CheckStack( x) ) return(1);
103 rpnstack_.top() = asin(x);
104 }
105 else if (args[k] == "atan") {
106 if ( CheckStack( x) ) return(1);
107 rpnstack_.top() = atan(x);
108 }
109 else if (args[k] == "chs") {
110 if ( CheckStack( x) ) return(1);
111 rpnstack_.top() = -x;
112 }
113 else if (args[k] == "sqrt") {
114 if ( CheckStack( x) ) return(1);
115 rpnstack_.top() = sqrt(x);
116 }
117 else if (args[k] == "sq") { // x^2
118 if ( CheckStack( x) ) return(1);
119 rpnstack_.top() = x*x;
120 }
121 else if (args[k] == "log") {
122 if ( CheckStack( x) ) return(1);
123 rpnstack_.top() = log(x);
124 }
125 else if (args[k] == "log10") {
126 if ( CheckStack( x) ) return(1);
127 rpnstack_.top() = log10(x);
128 }
129 else if (args[k] == "exp") {
130 if ( CheckStack( x) ) return(1);
131 rpnstack_.top() = exp(x);
132 }
133 else if (args[k] == "fabs") {
134 if ( CheckStack( x) ) return(1);
135 rpnstack_.top() = fabs(x);
136 }
137 else if (args[k] == "floor") {
138 if ( CheckStack( x) ) return(1);
139 rpnstack_.top() = floor(x);
140 }
141 else if (args[k] == "ceil") {
142 if ( CheckStack( x) ) return(1);
143 rpnstack_.top() = ceil(x);
144 }
145 // trunc et nint vire - ca ne compile pas sous linux - Reza 01/2003
146 else if (args[k] == "deg2rad") {
147 if ( CheckStack( x) ) return(1);
148 rpnstack_.top() = x*M_PI/180.;
149 }
150 else if (args[k] == "rad2deg") {
151 if ( CheckStack( x) ) return(1);
152 rpnstack_.top() = x*180./M_PI;
153 }
154 // Les fonctions usuelles a 2 argument f(x,y)
155 else if (args[k] == "pow") {
156 if ( CheckStack( x, y) ) return(1);
157 rpnstack_.top() = pow(y,x);
158 }
159 else if (args[k] == "atan2") {
160 if ( CheckStack( x, y) ) return(1);
161 rpnstack_.top() = atan2(x,y);
162 }
163 // generateur aleatoire
164 else if (args[k] == "rand") {
165 double rnd = drand01();
166 rpnstack_.push(rnd);
167 }
168 else if (args[k] == "norand") {
169 double rnd = GauRnd(0., 1.);
170 rpnstack_.push(rnd);
171 }
172 // Fonction a N arguments - Somme, produit, etc ...
173 else if ((args[k] == "sum") || (args[k] == "mean") || (args[k] == "sigmean") ||
174 (args[k] == "sigma") || (args[k] == "sigma2") ) {
175 double sx, sx2;
176 int nn = SumStack( sx, sx2);
177 if (args[k] == "sum") rpnstack_.push(sx);
178 else {
179 if (nn == 0) return 1;
180 double fnn = nn;
181 if ((args[k] == "sigma") || (args[k] == "sigmean"))
182 rpnstack_.push(sqrt(sx2/fnn-(x*x/(fnn*fnn))));
183 else if ((args[k] == "mean") || (args[k] == "sigmean")) rpnstack_.push(sx/fnn);
184 else rpnstack_.push(sx2/fnn-(x*x/(fnn*fnn)));
185 }
186 }
187 else if (args[k] == "product") {
188 double px;
189 int nn = ProductStack( px);
190 if (nn == 0) return(1);
191 rpnstack_.push(px);
192 }
193 // Fonctions de manipulation de stack
194 else if (args[k] == "print") {
195 PrintStack();
196 }
197 else if (args[k] == "x<>y") {
198 if ( CheckStack( x, y) ) return(1);
199 rpnstack_.top() = x; rpnstack_.push(y);
200 }
201 else if (args[k] == "pop") {
202 rpnstack_.pop();
203 }
204 else if (args[k] == "push") {
205 if (rpnstack_.empty()) rpnstack_.push(0.);
206 else rpnstack_.push(rpnstack_.top());
207 }
208 // On met un nombre sur le stack
209 else {
210 char * esptr;
211 x = strtod(args[k].c_str(), &esptr);
212 // if (ctof(args[k].c_str(),&x) < 0) {
213 if (esptr == args[k].c_str()) return 2;
214 rpnstack_.push(x);
215 }
216
217 }
218 return(0);
219}
220
221inline void RPNExpressionEvaluator::PrintStack()
222{
223 if (rpnstack_.empty())
224 cout << "RPNExpressionEvaluator::PrintStack() Empty stack " << endl;
225 else {
226 stack<double> s;
227 s = rpnstack_;
228 int k = 0;
229 cout << "RPNExpressionEvaluator::PrintStack() Size()= " << s.size() << endl;
230 while( !s.empty() ) {
231 cout << " " << k << ": " << s.top() << " ";
232 if (k == 0) cout << " (x) " << endl;
233 else if (k == 1) cout << " (y) " << endl;
234 else if (k == 2) cout << " (z) " << endl;
235 else cout << endl;
236 s.pop(); k++;
237 }
238 }
239
240}
241
242int RPNExpressionEvaluator::SumStack(double& sx, double& sx2)
243{
244 sx = sx2 = 0.;
245 int nn = 0;
246 double x = 0.;
247 while( !rpnstack_.empty() ) {
248 x = rpnstack_.top(); rpnstack_.pop();
249 sx += x; sx2 += x*x;
250 nn++;
251 }
252 return(nn);
253}
254
255int RPNExpressionEvaluator::ProductStack(double& px)
256{
257 px = 1.;
258 int nn = 0;
259 double x = 0.;
260 while( !rpnstack_.empty() ) {
261 x = rpnstack_.top(); rpnstack_.pop();
262 px *= x; nn++;
263 }
264 return(nn);
265}
266
267
268} // End of namespace SOPHYA
Note: See TracBrowser for help on using the repository browser.