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