Salome HOME
pour MT
[tools/eficas.git] / Extensions / param2.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013   EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
8 #
9 # This library 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 GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20 from __future__ import division
21 from __future__ import absolute_import
22 try :
23   from builtins import str
24   from builtins import object
25 except : pass
26 import math
27 import types
28 import six
29
30 try:
31   import Numeric
32 except:
33   try:
34     import numpy
35     Numeric = numpy
36   except ImportError:
37     Numeric = None
38
39
40 def mkf(value):
41     if type(value) in (type(1), type(1), type(1.5), type(1j),type("hh")) :
42         return Constant(value)
43     elif isinstance(value, Formula):
44         return value
45     elif type(value) == type([]):
46         return Constant(value)
47     else:
48 #        return Constant(value)
49         raise TypeError("Can't make formula from", value)
50
51 #class Formula(object):
52 class Formula(object):
53     def __len__(self):
54         val=self.eval()
55         if val is None:return 0
56         try:
57            return len(val)
58         except:
59            return 1
60     def __complex__(self): return complex(self.eval())
61     def __int__(self): return int(self.eval())
62     def __long__(self): return int(self.eval())
63     def __float__(self): return float(self.eval())
64     def __pos__(self): return self  # positive
65     def __neg__(self): return Unop('-', self)
66     def __abs__(self): return Unop('abs', self)
67     def __add__(self, other): return Binop('+', self, other)
68     def __radd__(self, other): return Binop('+', other, self)
69     def __sub__(self, other): return Binop('-', self, other)
70     def __rsub__(self, other): return Binop('-', other, self)
71     def __mul__(self, other): return Binop('*', self, other)
72     def __rmul__(self, other): return Binop('*', other, self)
73     def __div__(self, other): return Binop('/', self, other)
74     def __rdiv__(self, other): return Binop('/', other, self)
75     def __truediv__(self, other): return Binop('/', self, other)
76     def __rtruediv__(self, other): return Binop('/', other, self)
77     def __floordiv__(self, other): return Binop('//', self, other)
78     def __rfloordiv__(self, other): return Binop('//', other, self)
79     def __pow__(self, other): return Binop('**', self, other)
80     def __rpow__(self, other): return Binop('**', other, self)
81     def __getitem__(self,i): 
82         if i > len(self) : raise StopIteration
83         return Binop('[]',self,i)
84     def __cmp__( self, other ): return self.eval().__cmp__(other)
85     def __eq__(  self, other ): return self.eval() == other
86     def __ne__(  self, other ): return self.eval() != other
87     def __lt__(  self, other ): return self.eval() < other
88     def __le__(  self, other ): return self.eval() <= other
89     def __gt__(  self, other ): return self.eval() > other
90     def __ge__(  self, other ): return self.eval() >= other
91     def __hash__(self):return id(self)
92
93 def _div(a,b):
94   if isinstance(a,six.integer_types) and isinstance(b,six.integer_types):
95     if a%b:
96       return a/b
97     else:
98       return a//b
99   else:
100     return a/b
101
102
103 class Binop(Formula):
104     opmap = { '+': lambda a, b: a + b,
105               '*': lambda a, b: a * b,
106               '-': lambda a, b: a - b,
107               '/': _div,
108               '//': lambda a, b: a // b,
109               '**': lambda a, b: a ** b,
110               '[]': lambda a, b: a[b] ,
111             }
112     def __init__(self, op, value1, value2):
113         self.op = op
114         self.values = mkf(value1), mkf(value2)
115
116     def __str__(self):
117         if self.op == '[]':
118            return "%s[%s]" % (self.values[0], self.values[1])
119         else:
120            return "(%s %s %s)" % (self.values[0], self.op, self.values[1])
121     def __repr__(self):
122         if self.op == '[]':
123            return "%s[%s]" % (self.values[0], self.values[1])
124         else:
125            return "(%s %s %s)" % (self.values[0], self.op, self.values[1])
126     def eval(self):
127         result= self.opmap[self.op](self.values[0].eval(),
128                                    self.values[1].eval())
129         while isinstance(result,Formula):
130               result=result.eval()
131         return result
132     def __adapt__(self,validator):
133         return validator.adapt(self.eval())
134
135
136 class Unop(Formula):
137     opmap = { '-': lambda x: -x,
138               'abs': lambda x: abs(x),
139              }
140     def __init__(self, op, arg):
141         self._op = op
142         self._arg = mkf(arg)
143     def __str__(self):
144         return "%s(%s)" % (self._op, self._arg)
145     def __repr__(self):
146         return "%s(%s)" % (self._op, self._arg)
147     def eval(self):
148         return self.opmap[self._op](self._arg.eval())
149     def __adapt__(self,validator):
150         return validator.adapt(self.eval())
151
152 class Unop2(Unop):
153     def __init__(self, nom, op, arg):
154         self._nom = nom
155         self._op = op
156         self._arg=[]
157         for a in arg:
158            self._arg.append(mkf(a))
159     def __str__(self):
160         s="%s(" % self._nom
161         for a in self._arg:
162            s=s+str(a)+','
163         s=s+")"
164         return s
165     def __repr__(self):
166         s="%s(" % self._nom
167         for a in self._arg:
168            s=s+str(a)+','
169         s=s+")"
170         return s
171     def eval(self):
172         l=[]
173         for a in self._arg:
174           l.append(a.eval())
175         return self._op(*l)
176
177 class Constant(Formula):
178     def __init__(self, value): self._value = value
179     def eval(self): return self._value
180     def __str__(self): return str(self._value)
181     def __adapt__(self,validator):
182         return validator.adapt(self._value)
183
184 class Variable(Formula):
185     def __init__(self,name,value):
186         self._name=name
187         self._value=value
188     def eval(self): return self._value
189     def __repr__(self): return "Variable('%s',%s)" % (self._name, self._value)
190     def __str__(self): return self._name
191     def __adapt__(self,validator):
192         return validator.adapt(self._value)
193 def Eval(f):
194     if isinstance(f,Formula):
195         f=f.eval()
196     elif type(f) in (list, ):
197         f=[Eval(i) for i in f]
198     elif type(f) in (tuple,):
199         f=tuple([Eval(i) for i in f])
200     return f
201
202
203 def cos(f): return Unop('ncos', f)
204 def sin(f): return Unop('nsin', f)
205 def array(f,*tup,**args): 
206     """array de Numeric met en defaut la mecanique des parametres
207        on la supprime dans ce cas. Il faut que la valeur du parametre soit bien definie
208     """
209     originalMath=OriginalMath()
210     original_narray=originalMath.original_narray
211     return original_narray(Eval(f),*tup,**args)
212 def sin(f): return Unop('sin', f)
213 def cos(f): return Unop('cos', f)
214 def ceil(f): return Unop('ceil', f)
215 def sqrt(f): return Unop('sqrt', f)
216
217 def pi2():return Unop('pi')
218
219 class  OriginalMath(object):
220     _instance = None
221     def __new__(cls, *args, **kwargs):
222         if not cls._instance:
223             cls._instance = super(OriginalMath, cls).__new__(
224                                 cls, *args, **kwargs)
225
226         return cls._instance
227
228     def __init__(self):
229         if hasattr(self,'pi') :return
230         import math
231         try : 
232           self.toSurcharge()
233         except : pass
234
235     def toSurcharge(self):
236         self.numeric_ncos=Numeric.cos
237         self.numeric_nsin=Numeric.sin
238         self.numeric_narray=Numeric.array
239         self.sin=math.sin
240         self.cos=math.cos
241         self.sqrt=math.sqrt
242         self.ceil=math.ceil
243         self.pi=math.pi
244
245         #surcharge de la fonction cos de Numeric pour les parametres
246         original_ncos=Numeric.cos
247         Unop.opmap['ncos']=lambda x: original_ncos(x)
248         Numeric.cos=cos
249
250         #surcharge de la fonction sin de Numeric pour les parametres
251         original_nsin=Numeric.sin
252         Unop.opmap['nsin']=lambda x: original_nsin(x)
253         Numeric.sin=sin
254
255         #surcharge de la fonction array de Numeric pour les parametres
256         original_narray=Numeric.array
257         self.original_narray=Numeric.array
258         Numeric.array=array
259
260         #surcharge de la fonction sin de math pour les parametres
261         original_sin=math.sin
262         Unop.opmap['sin']=lambda x: original_sin(x)
263         math.sin=sin
264
265         #surcharge de la fonction cos de math pour les parametres
266         original_cos=math.cos
267         Unop.opmap['cos']=lambda x: original_cos(x)
268         math.cos=cos
269
270         #surcharge de la fonction sqrt de math pour les parametres
271         original_sqrt=math.sqrt
272         Unop.opmap['sqrt']=lambda x: original_sqrt(x)
273         math.sqrt=sqrt
274
275         #surcharge de la fonction ceil de math pour les parametres
276         original_ceil=math.ceil
277         Unop.opmap['ceil']=lambda x: original_ceil(x)
278         math.ceil=ceil
279
280         original_pi=math.pi
281         Unop.opmap['pi']=lambda x: original_pi
282         pi=Variable('pi',pi2)
283         math.pi=pi
284
285     def toOriginal(self):
286         import math
287         try:
288           import Numeric
289         except:
290           import numpy
291           Numeric = numpy
292
293         try : 
294           Numeric.cos=originalMath.numeric_ncos
295           Numeric.sin=originalMath.numeric_nsin
296           Numeric.array=originalMath.numeric_narray
297         except : pass
298         math.sin=originalMath.sin
299         math.cos=originalMath.cos
300         math.sqrt=originalMath.sqrt
301         math.ceil=originalMath.ceil
302         math.pi=originalMath.pi
303
304
305 originalMath=OriginalMath()