/[escript]/trunk/escript/py_src/util.py
ViewVC logotype

Annotation of /trunk/escript/py_src/util.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1042 - (hide annotations)
Mon Mar 19 03:50:34 2007 UTC (12 years, 6 months ago) by gross
File MIME type: text/x-python
File size: 211963 byte(s)
a small fix which deals with the case that a Model class
does not take the argument debug.



1 jgs 82 # $Id$
2    
3     """
4 jgs 149 Utility functions for escript
5 jgs 123
6 gross 290 @var __author__: name of author
7 gross 637 @var __copyright__: copyrights
8 elspeth 614 @var __license__: licence agreement
9 gross 290 @var __url__: url entry point on documentation
10     @var __version__: version
11     @var __date__: date of the version
12 jgs 82 """
13 gross 290
14     __author__="Lutz Gross, l.gross@uq.edu.au"
15 elspeth 608 __copyright__=""" Copyright (c) 2006 by ACcESS MNRF
16     http://www.access.edu.au
17     Primary Business: Queensland, Australia"""
18 elspeth 614 __license__="""Licensed under the Open Software License version 3.0
19     http://www.opensource.org/licenses/osl-3.0.php"""
20 gross 290 __url__="http://www.iservo.edu.au/esys/escript"
21 gross 353 __version__="$Revision$"
22 gross 290 __date__="$Date$"
23 jgs 82
24 gross 290
25     import math
26 jgs 82 import numarray
27 jgs 102 import escript
28 jgs 150 import os
29 ksteube 813 from esys.escript import C_GeneralTensorProduct
30 jgs 124
31 jgs 123 #=========================================================
32 gross 290 # some helpers:
33 jgs 123 #=========================================================
34 gross 1042 def getTagNames(domain):
35     """
36     returns a list of the tag names used by the domain
37    
38    
39     @param domain: a domain object
40     @type domain: C{escript.Domain}
41     @return: a list of the tag name used by the domain.
42     @rtype: C{list} of C{str}
43     """
44     return [n.strip() for n in domain.showTagNames().split(",") ]
45    
46 jgs 153 def saveVTK(filename,domain=None,**data):
47 jgs 150 """
48 jgs 153 writes a L{Data} objects into a files using the the VTK XML file format.
49 jgs 123
50 gross 720 Example::
51 jgs 123
52 jgs 153 tmp=Scalar(..)
53     v=Vector(..)
54     saveVTK("solution.xml",temperature=tmp,velovity=v)
55 jgs 150
56 gross 290 tmp and v are written into "solution.xml" where tmp is named "temperature" and v is named "velovity"
57 jgs 153
58     @param filename: file name of the output file
59 gross 290 @type filename: C{str}
60 jgs 153 @param domain: domain of the L{Data} object. If not specified, the domain of the given L{Data} objects is used.
61     @type domain: L{escript.Domain}
62     @keyword <name>: writes the assigned value to the VTK file using <name> as identifier.
63     @type <name>: L{Data} object.
64     @note: The data objects have to be defined on the same domain. They may not be in the same L{FunctionSpace} but one cannot expect that all L{FunctionSpace} can be mixed. Typically, data on the boundary and data on the interior cannot be mixed.
65 jgs 149 """
66 jgs 153 if domain==None:
67     for i in data.keys():
68     if not data[i].isEmpty(): domain=data[i].getFunctionSpace().getDomain()
69     if domain==None:
70     raise ValueError,"no domain detected."
71     else:
72     domain.saveVTK(filename,data)
73 jgs 154
74 jgs 153 def saveDX(filename,domain=None,**data):
75 jgs 149 """
76 jgs 153 writes a L{Data} objects into a files using the the DX file format.
77 jgs 149
78 gross 720 Example::
79 jgs 150
80 jgs 153 tmp=Scalar(..)
81     v=Vector(..)
82     saveDX("solution.dx",temperature=tmp,velovity=v)
83 jgs 150
84 gross 290 tmp and v are written into "solution.dx" where tmp is named "temperature" and v is named "velovity".
85 jgs 153
86     @param filename: file name of the output file
87 gross 290 @type filename: C{str}
88 jgs 153 @param domain: domain of the L{Data} object. If not specified, the domain of the given L{Data} objects is used.
89     @type domain: L{escript.Domain}
90     @keyword <name>: writes the assigned value to the DX file using <name> as identifier. The identifier can be used to select the data set when data are imported into DX.
91     @type <name>: L{Data} object.
92     @note: The data objects have to be defined on the same domain. They may not be in the same L{FunctionSpace} but one cannot expect that all L{FunctionSpace} can be mixed. Typically, data on the boundary and data on the interior cannot be mixed.
93 jgs 149 """
94 jgs 153 if domain==None:
95     for i in data.keys():
96     if not data[i].isEmpty(): domain=data[i].getFunctionSpace().getDomain()
97     if domain==None:
98     raise ValueError,"no domain detected."
99     else:
100     domain.saveDX(filename,data)
101 jgs 154
102 gross 290 def kronecker(d=3):
103     """
104     return the kronecker S{delta}-symbol
105 jgs 123
106 gross 290 @param d: dimension or an object that has the C{getDim} method defining the dimension
107 gross 442 @type d: C{int}, L{escript.Domain} or L{escript.FunctionSpace}
108 gross 290 @return: the object u of rank 2 with M{u[i,j]=1} for M{i=j} and M{u[i,j]=0} otherwise
109 gross 720 @rtype: L{numarray.NumArray} or L{escript.Data} of rank 2.
110 gross 290 """
111     return identityTensor(d)
112    
113     def identity(shape=()):
114     """
115     return the shape x shape identity tensor
116    
117     @param shape: input shape for the identity tensor
118     @type shape: C{tuple} of C{int}
119     @return: array of shape shape x shape with M{u[i,k]=1} for M{i=k} and M{u[i,k]=0} otherwise for len(shape)=1 and, for len(shape)=2: M{u[i,j,k,l]=1} for M{i=k and j=l} and M{u[i,j,k,l]=0} otherwise.
120     @rtype: L{numarray.NumArray} of rank 1, rankk 2 or rank 4.
121     @raise ValueError: if len(shape)>2.
122     """
123     if len(shape)>0:
124 gross 574 out=numarray.zeros(shape+shape,numarray.Float64)
125 gross 290 if len(shape)==1:
126     for i0 in range(shape[0]):
127     out[i0,i0]=1.
128     elif len(shape)==2:
129     for i0 in range(shape[0]):
130     for i1 in range(shape[1]):
131     out[i0,i1,i0,i1]=1.
132     else:
133     raise ValueError,"identity: length of shape is restricted to 2."
134     else:
135     out=1.
136     return out
137    
138     def identityTensor(d=3):
139     """
140     return the dxd identity matrix
141    
142     @param d: dimension or an object that has the C{getDim} method defining the dimension
143 gross 442 @type d: C{int}, L{escript.Domain} or L{escript.FunctionSpace}
144 gross 290 @return: the object u of rank 2 with M{u[i,j]=1} for M{i=j} and M{u[i,j]=0} otherwise
145 gross 720 @rtype: L{numarray.NumArray} or L{escript.Data} of rank 2
146 gross 290 """
147 gross 442 if isinstance(d,escript.FunctionSpace):
148     return escript.Data(identity((d.getDim(),)),d)
149     elif isinstance(d,escript.Domain):
150     return identity((d.getDim(),))
151     else:
152     return identity((d,))
153 gross 290
154     def identityTensor4(d=3):
155     """
156     return the dxdxdxd identity tensor
157    
158     @param d: dimension or an object that has the C{getDim} method defining the dimension
159     @type d: C{int} or any object with a C{getDim} method
160     @return: the object u of rank 4 with M{u[i,j,k,l]=1} for M{i=k and j=l} and M{u[i,j,k,l]=0} otherwise
161 gross 720 @rtype: L{numarray.NumArray} or L{escript.Data} of rank 4.
162 gross 290 """
163 gross 442 if isinstance(d,escript.FunctionSpace):
164     return escript.Data(identity((d.getDim(),d.getDim())),d)
165     elif isinstance(d,escript.Domain):
166     return identity((d.getDim(),d.getDim()))
167     else:
168     return identity((d,d))
169 gross 290
170     def unitVector(i=0,d=3):
171     """
172     return a unit vector u of dimension d with nonzero index i:
173    
174     @param i: index
175     @type i: C{int}
176     @param d: dimension or an object that has the C{getDim} method defining the dimension
177 gross 442 @type d: C{int}, L{escript.Domain} or L{escript.FunctionSpace}
178 gross 290 @return: the object u of rank 1 with M{u[j]=1} for M{j=i} and M{u[i]=0} otherwise
179 gross 720 @rtype: L{numarray.NumArray} or L{escript.Data} of rank 1
180 gross 290 """
181     return kronecker(d)[i]
182    
183     #=========================================================================
184     # global reduction operations (these functions have no symbolic version)
185     #=========================================================================
186     def Lsup(arg):
187 jgs 82 """
188 gross 290 returns the Lsup-norm of argument arg. This is the maximum absolute value over all data points.
189     This function is equivalent to sup(abs(arg)).
190 jgs 149
191 gross 290 @param arg: argument
192     @type arg: C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
193     @return: maximum value of the absolute value of arg over all components and all data points
194     @rtype: C{float}
195     @raise TypeError: if type of arg cannot be processed
196 jgs 123 """
197 gross 290 if isinstance(arg,numarray.NumArray):
198     return sup(abs(arg))
199     elif isinstance(arg,escript.Data):
200     return arg._Lsup()
201     elif isinstance(arg,float):
202     return abs(arg)
203     elif isinstance(arg,int):
204     return abs(float(arg))
205 jgs 108 else:
206 gross 290 raise TypeError,"Lsup: Unknown argument type."
207 jgs 82
208 gross 290 def sup(arg):
209 jgs 82 """
210 gross 290 returns the maximum value over all data points.
211 jgs 149
212 gross 290 @param arg: argument
213     @type arg: C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
214     @return: maximum value of arg over all components and all data points
215     @rtype: C{float}
216     @raise TypeError: if type of arg cannot be processed
217 jgs 123 """
218 gross 290 if isinstance(arg,numarray.NumArray):
219     return arg.max()
220     elif isinstance(arg,escript.Data):
221     return arg._sup()
222     elif isinstance(arg,float):
223     return arg
224     elif isinstance(arg,int):
225     return float(arg)
226 jgs 123 else:
227 gross 290 raise TypeError,"sup: Unknown argument type."
228 jgs 82
229 gross 290 def inf(arg):
230 jgs 82 """
231 gross 290 returns the maximum value over all data points.
232 jgs 149
233 gross 290 @param arg: argument
234     @type arg: C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
235 gross 720 @return: minimum value of arg over all components and all data points
236 gross 290 @rtype: C{float}
237     @raise TypeError: if type of arg cannot be processed
238 jgs 123 """
239 gross 290 if isinstance(arg,numarray.NumArray):
240     return arg.min()
241     elif isinstance(arg,escript.Data):
242     return arg._inf()
243     elif isinstance(arg,float):
244     return arg
245     elif isinstance(arg,int):
246     return float(arg)
247 jgs 108 else:
248 gross 290 raise TypeError,"inf: Unknown argument type."
249 jgs 82
250 gross 290
251     #=========================================================================
252     # some little helpers
253     #=========================================================================
254 gross 912 def getRank(arg):
255 jgs 124 """
256 gross 912 identifies the rank of its argument
257    
258     @param arg: a given object
259     @type arg: L{numarray.NumArray},L{escript.Data},C{float}, C{int}, C{Symbol}
260     @return: the rank of the argument
261     @rtype: C{int}
262     @raise TypeError: if type of arg cannot be processed
263     """
264    
265     if isinstance(arg,numarray.NumArray):
266     return arg.rank
267     elif isinstance(arg,escript.Data):
268     return arg.getRank()
269     elif isinstance(arg,float):
270     return 0
271     elif isinstance(arg,int):
272     return 0
273     elif isinstance(arg,Symbol):
274     return arg.getRank()
275     else:
276     raise TypeError,"getShape: cannot identify shape"
277     def getShape(arg):
278     """
279 gross 290 identifies the shape of its argument
280 jgs 149
281 gross 290 @param arg: a given object
282     @type arg: L{numarray.NumArray},L{escript.Data},C{float}, C{int}, C{Symbol}
283     @return: the shape of the argument
284     @rtype: C{tuple} of C{int}
285     @raise TypeError: if type of arg cannot be processed
286 jgs 124 """
287 gross 290
288     if isinstance(arg,numarray.NumArray):
289     return arg.shape
290     elif isinstance(arg,escript.Data):
291     return arg.getShape()
292     elif isinstance(arg,float):
293     return ()
294     elif isinstance(arg,int):
295     return ()
296     elif isinstance(arg,Symbol):
297     return arg.getShape()
298 jgs 124 else:
299 gross 912 raise TypeError,"getShape: cannot identify shape"
300 jgs 124
301 gross 290 def pokeDim(arg):
302 jgs 82 """
303 gross 290 identifies the spatial dimension of its argument
304 jgs 149
305 gross 290 @param arg: a given object
306     @type arg: any
307     @return: the spatial dimension of the argument, if available, or C{None}
308     @rtype: C{int} or C{None}
309 jgs 123 """
310 gross 290
311     if isinstance(arg,escript.Data):
312     return arg.getFunctionSpace().getDim()
313     elif isinstance(arg,Symbol):
314     return arg.getDim()
315 jgs 123 else:
316 gross 290 return None
317 jgs 82
318 gross 290 def commonShape(arg0,arg1):
319 jgs 82 """
320 gross 290 returns a shape to which arg0 can be extendent from the right and arg1 can be extended from the left.
321 jgs 149
322 gross 912 @param arg0: an object with a shape (see L{getShape})
323     @param arg1: an object with a shape (see L{getShape})
324 gross 290 @return: the shape of arg0 or arg1 such that the left port equals the shape of arg0 and the right end equals the shape of arg1.
325     @rtype: C{tuple} of C{int}
326     @raise ValueError: if no shape can be found.
327 jgs 123 """
328 gross 912 sh0=getShape(arg0)
329     sh1=getShape(arg1)
330 gross 290 if len(sh0)<len(sh1):
331     if not sh0==sh1[:len(sh0)]:
332     raise ValueError,"argument 0 cannot be extended to the shape of argument 1"
333     return sh1
334     elif len(sh0)>len(sh1):
335     if not sh1==sh0[:len(sh1)]:
336     raise ValueError,"argument 1 cannot be extended to the shape of argument 0"
337     return sh0
338 jgs 82 else:
339 gross 290 if not sh0==sh1:
340     raise ValueError,"argument 1 and argument 0 have not the same shape."
341     return sh0
342 jgs 82
343 gross 290 def commonDim(*args):
344 jgs 82 """
345 gross 290 identifies, if possible, the spatial dimension across a set of objects which may or my not have a spatial dimension.
346 jgs 149
347 gross 720 @param args: given objects
348 gross 290 @return: the spatial dimension of the objects with identifiable dimension (see L{pokeDim}). If none the objects has
349     a spatial dimension C{None} is returned.
350     @rtype: C{int} or C{None}
351     @raise ValueError: if the objects with identifiable dimension don't have the same spatial dimension.
352 jgs 123 """
353 gross 290 out=None
354     for a in args:
355     d=pokeDim(a)
356     if not out==None:
357     if not (d==None or out==d):
358     raise ValueError,"dimension of arguments don't match"
359     else:
360     out=d
361     return out
362 jgs 82
363 gross 290 def testForZero(arg):
364 jgs 150 """
365 gross 290 test the argument for being identical to Zero
366 jgs 123
367 gross 290 @param arg: a given object
368     @type arg: typically L{numarray.NumArray},L{escript.Data},C{float}, C{int}
369 gross 720 @return: True if the argument is identical to zero.
370     @rtype: C{bool}
371 jgs 150 """
372 gross 396 if isinstance(arg,numarray.NumArray):
373 gross 290 return not Lsup(arg)>0.
374 gross 396 elif isinstance(arg,escript.Data):
375 gross 290 return False
376 gross 396 elif isinstance(arg,float):
377     return not Lsup(arg)>0.
378     elif isinstance(arg,int):
379     return not Lsup(arg)>0.
380     elif isinstance(arg,Symbol):
381     return False
382     else:
383     return False
384 jgs 150
385 gross 290 def matchType(arg0=0.,arg1=0.):
386 jgs 150 """
387 gross 290 converting arg0 and arg1 both to the same type L{numarray.NumArray} or L{escript.Data} or, if one of arg0 or arg1 is of type L{Symbol}, the other one to be of type L{numarray.NumArray} or L{escript.Data}.
388 jgs 150
389 gross 290 @param arg0: first argument
390     @type arg0: L{numarray.NumArray},L{escript.Data},C{float}, C{int}, C{Symbol}
391     @param arg1: second argument
392     @type arg1: L{numarray.NumArray},L{escript.Data},C{float}, C{int}, C{Symbol}
393     @return: a tuple representing arg0 and arg1 with the same type or with one of them being a L{Symbol}
394     @rtype: C{tuple} of two L{numarray.NumArray}, two L{escript.Data}, a C{Symbol} and one of the types L{numarray.NumArray} or L{escript.Data}.
395     @raise TypeError: if type of arg0 or arg1 cannot be processed
396 jgs 150 """
397 gross 290 if isinstance(arg0,numarray.NumArray):
398     if isinstance(arg1,numarray.NumArray):
399     pass
400     elif isinstance(arg1,escript.Data):
401     arg0=escript.Data(arg0,arg1.getFunctionSpace())
402     elif isinstance(arg1,float):
403 gross 574 arg1=numarray.array(arg1,type=numarray.Float64)
404 gross 290 elif isinstance(arg1,int):
405 gross 574 arg1=numarray.array(float(arg1),type=numarray.Float64)
406 gross 290 elif isinstance(arg1,Symbol):
407     pass
408     else:
409     raise TypeError,"function: Unknown type of second argument."
410     elif isinstance(arg0,escript.Data):
411     if isinstance(arg1,numarray.NumArray):
412     arg1=escript.Data(arg1,arg0.getFunctionSpace())
413     elif isinstance(arg1,escript.Data):
414     pass
415     elif isinstance(arg1,float):
416     arg1=escript.Data(arg1,(),arg0.getFunctionSpace())
417     elif isinstance(arg1,int):
418     arg1=escript.Data(float(arg1),(),arg0.getFunctionSpace())
419     elif isinstance(arg1,Symbol):
420     pass
421     else:
422     raise TypeError,"function: Unknown type of second argument."
423     elif isinstance(arg0,Symbol):
424     if isinstance(arg1,numarray.NumArray):
425     pass
426     elif isinstance(arg1,escript.Data):
427     pass
428     elif isinstance(arg1,float):
429 gross 574 arg1=numarray.array(arg1,type=numarray.Float64)
430 gross 290 elif isinstance(arg1,int):
431 gross 574 arg1=numarray.array(float(arg1),type=numarray.Float64)
432 gross 290 elif isinstance(arg1,Symbol):
433     pass
434     else:
435     raise TypeError,"function: Unknown type of second argument."
436     elif isinstance(arg0,float):
437     if isinstance(arg1,numarray.NumArray):
438 gross 574 arg0=numarray.array(arg0,type=numarray.Float64)
439 gross 290 elif isinstance(arg1,escript.Data):
440     arg0=escript.Data(arg0,arg1.getFunctionSpace())
441     elif isinstance(arg1,float):
442 gross 574 arg0=numarray.array(arg0,type=numarray.Float64)
443     arg1=numarray.array(arg1,type=numarray.Float64)
444 gross 290 elif isinstance(arg1,int):
445 gross 574 arg0=numarray.array(arg0,type=numarray.Float64)
446     arg1=numarray.array(float(arg1),type=numarray.Float64)
447 gross 290 elif isinstance(arg1,Symbol):
448 gross 574 arg0=numarray.array(arg0,type=numarray.Float64)
449 gross 290 else:
450     raise TypeError,"function: Unknown type of second argument."
451     elif isinstance(arg0,int):
452     if isinstance(arg1,numarray.NumArray):
453 gross 574 arg0=numarray.array(float(arg0),type=numarray.Float64)
454 gross 290 elif isinstance(arg1,escript.Data):
455     arg0=escript.Data(float(arg0),arg1.getFunctionSpace())
456     elif isinstance(arg1,float):
457 gross 574 arg0=numarray.array(float(arg0),type=numarray.Float64)
458     arg1=numarray.array(arg1,type=numarray.Float64)
459 gross 290 elif isinstance(arg1,int):
460 gross 574 arg0=numarray.array(float(arg0),type=numarray.Float64)
461     arg1=numarray.array(float(arg1),type=numarray.Float64)
462 gross 290 elif isinstance(arg1,Symbol):
463 gross 574 arg0=numarray.array(float(arg0),type=numarray.Float64)
464 gross 290 else:
465     raise TypeError,"function: Unknown type of second argument."
466 jgs 150 else:
467 gross 290 raise TypeError,"function: Unknown type of first argument."
468 jgs 150
469 gross 290 return arg0,arg1
470    
471     def matchShape(arg0,arg1):
472 jgs 150 """
473 gross 720 return representations of arg0 amd arg1 which ahve the same shape
474 jgs 150
475 gross 720 @param arg0: a given object
476     @type arg0: L{numarray.NumArray},L{escript.Data},C{float}, C{int}, L{Symbol}
477     @param arg1: a given object
478     @type arg1: L{numarray.NumArray},L{escript.Data},C{float}, C{int}, L{Symbol}
479 gross 804 @return: C{arg0} and C{arg1} where copies are returned when the shape has to be changed.
480 gross 720 @rtype: C{tuple}
481 jgs 150 """
482 gross 290 sh=commonShape(arg0,arg1)
483 gross 912 sh0=getShape(arg0)
484     sh1=getShape(arg1)
485 gross 290 if len(sh0)<len(sh):
486 gross 574 return outer(arg0,numarray.ones(sh[len(sh0):],numarray.Float64)),arg1
487 gross 290 elif len(sh1)<len(sh):
488 gross 574 return arg0,outer(arg1,numarray.ones(sh[len(sh1):],numarray.Float64))
489 gross 290 else:
490     return arg0,arg1
491     #=========================================================
492     # symbolic tool box starts here:
493     #=========================================================
494     class Symbol(object):
495     """
496     Symbol class.
497 jgs 150
498 gross 290 Symbol class objects provide the same functionality as L{numarray.NumArray} and L{escript.Data} objects
499     but they do not have a value and therefore cannot be plotted or visualize. The main purpose is the possibilty
500     calculate derivatives with respect to other Symbols used to define a Symbol.
501    
502     """
503     def __init__(self,shape=(),args=[],dim=None):
504     """
505     Creates an instance of a symbol of a given shape. The symbol may depending on a list of arguments args which may be
506     symbols or any other object.
507    
508 gross 720 @param args: the arguments of the symbol.
509     @type args: C{list}
510 gross 290 @param shape: the shape
511     @type shape: C{tuple} of C{int}
512     @param dim: spatial dimension of the symbol. If dim=C{None} the spatial dimension is undefined.
513     @type dim: C{None} or C{int}
514    
515     """
516     if len(shape)>4:
517     raise ValueError,"Symbol supports only tensors up to order 4"
518     self.__args=args
519     self.__shape=shape
520     self.__dim=dim
521    
522     def getArgument(self,i=None):
523     """
524     returns the i-th argument of the symbol
525    
526     @param i: index of the argument requested.
527     @type i: C{int} or C{None}
528     @raise IndexError: if the requested index does not exist
529     @return: the vlaue of the i-th argument or i is not specified the list of all arguments.
530     @rtype: a single object or a list of objects
531     """
532     if i==None:
533     return self.__args
534     else:
535     if i<0 or i>=len(self.__args):
536     raise IndexError,"there are only %s arguments"%len(self.__args)
537     return self.__args[i]
538    
539     def getRank(self):
540     """
541     the rank of the symbol
542    
543     @return: the rank of the symbol. This is length of the shape
544     @rtype: C{int}
545     """
546     return len(self.getShape())
547    
548     def getShape(self):
549     """
550     the shape of the symbol.
551    
552 gross 720 @return: the shape of the symbol.
553 gross 290 @rtype: C{tuple} of C{int}
554     """
555     return self.__shape
556    
557     def getDim(self):
558     """
559     the spatial dimension
560    
561 gross 720 @return: the spatial dimension
562 gross 290 @rtype: C{int} if the dimension is defined. Otherwise C{None} is returned.
563     """
564     return self.__dim
565    
566     def __str__(self):
567     """
568     a string representation of the symbol.
569     @return: a string representation of the object
570     @rtype: C{str}
571     """
572     args=[]
573     for arg in self.getArgument():
574     args.append(str(arg))
575     try:
576     out=self.getMyCode(args,format="str")
577     except NotImplementedError:
578     out="<Symbol %s>"%id(self)
579     return out
580    
581     def getSubstitutedArguments(self,argvals):
582     """
583     substitutes symbols in the arguments of this object and returns the result as a list.
584    
585 gross 720 @param argvals: L{Symbol} and their substitutes. The L{Symbol} u in the expression defining this object is replaced by argvals[u].
586 gross 290 @type argvals: C{dict} with keywords of type L{Symbol}.
587     @rtype: C{list} of objects
588 gross 720 @return: list of the object assigned to the arguments through substitution or for the arguments which are not L{Symbol} the value assigned to the argument at instantiation.
589 gross 290 """
590     out=[]
591     for a in self.getArgument():
592     if isinstance(a,Symbol):
593     out.append(a.substitute(argvals))
594     else:
595     out.append(a)
596     return out
597    
598     def getDifferentiatedArguments(self,arg):
599     """
600     applifies differentials to the arguments of this object and returns the result as a list.
601    
602     @param arg: the derivative is calculated with respect to arg
603     @type arg: typically L{escript.Symbol} but can also be C{float}, L{escript.Data}, L{numarray.NumArray} depending the involved functions and data.
604     @rtype: C{list} of objects
605     @return: list of object obtained by calculating the derivatives of the argumenst with respct to arg
606     """
607     out=[]
608     for a in self.getArgument():
609     if isinstance(a,Symbol):
610     out.append(a.substitute(argvals))
611     else:
612 gross 912 s=getShape(s)+arg.getShape()
613 gross 290 if len(s)>0:
614 gross 574 out.append(numarray.zeros(s),numarray.Float64)
615 gross 290 else:
616     out.append(a)
617     return out
618    
619     def isAppropriateValue(self,arg):
620     """
621     checks if the given argument arg can be used as a substitution of this object. The method checks
622     the shape of arg and, if the spatial dimension is defined, the spatial dimension of arg.
623    
624     @param arg: a given object
625     @type arg: L{numarray.NumArray},L{escript.Data},C{float}, C{int}, C{Symbol}
626     @return: True if arg is a suitbale object to be used for substitution. Otherwise False is returned.
627     @rtype: C{bool}
628     """
629     if isinstance(arg,numarray.NumArray):
630     return arg.shape==self.getShape()
631     elif isinstance(arg,escript.Data):
632     if self.getDim()==None:
633     return arg.getShape()==self.getShape()
634     elif self.getDim()==arg.getFunctionSpace().getDim():
635     return arg.getShape()==self.getShape()
636     else:
637     return False
638     elif isinstance(arg,Symbol):
639     if self.getDim()==None:
640     return arg.getShape()==self.getShape()
641     elif self.getDim()==arg.getDim():
642     return arg.getShape()==self.getShape()
643     else:
644     return False
645     elif isinstance(arg,float):
646     return ()==self.getShape()
647     elif isinstance(arg,int):
648     return ()==self.getShape()
649     else:
650     return False
651    
652     def getMyCode(self,argstrs,format="escript"):
653     """
654     returns a program code that can be used to evaluate the symbol.
655    
656     @param argstrs: gives for each argument a string representing the argument for the evaluation.
657     @type argstrs: C{list} of C{str}.
658     @param format: specifies the format to be used. At the moment only "escript", "str" and "text" are supported.
659     @type format: C{str}
660     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
661     @rtype: C{str}
662     @raise NotImplementedError: if no implementation for the given format is available
663     @note: This method has to be overwritten by subclasses.
664     """
665     raise NotImplementedError,"no code for %s representation available"%format
666    
667     def substitute(self,argvals):
668     """
669     assigns new values to symbols in the definition of the symbol.
670     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
671    
672     @param argvals: new values assigned to symbols
673     @type argvals: C{dict} with keywords of type L{Symbol}.
674     @return: result of the substitution process. Operations are executed as much as possible.
675     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
676     @note: this method has to be overwritten by a particular L{Symbol}
677     @raise NotImplementedError: if no implementation for the given format is available
678     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
679     """
680     if argvals.has_key(self):
681     arg=argvals[self]
682     if self.isAppropriateValue(arg):
683     return arg
684     else:
685     raise TypeError,"Symbol: new value is not appropriate."
686     else:
687     raise NotImplementedError,"no substitution in %s avialable"%str(self)
688    
689     def diff(self,arg):
690     """
691     returns the derivative of the symbol with respect to L{Symbol} arg
692    
693     @param arg: the derivative is calculated with respect to arg
694     @type arg: typically L{escript.Symbol} but can also be C{float}, L{escript.Data}, L{numarray.NumArray} depending the involved functions and data.
695     @return: derivative with respect to C{arg}
696     @rtype: typically L{escript.Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
697     @note: this method is overwritten by a particular L{Symbol}
698     """
699     if arg==self:
700     return identity(self.getShape())
701     else:
702     s=self.getShape()+arg.getShape()
703     if len(s)>0:
704 gross 574 return numarray.zeros(s,numarray.Float64)
705 gross 290 else:
706     return 0.
707    
708     def __neg__(self):
709     """
710     returns -self.
711    
712 gross 720 @return: a L{Symbol} representing the negative of the object
713 gross 290 @rtype: L{DependendSymbol}
714     """
715     return self*(-1.)
716    
717     def __pos__(self):
718     """
719     returns +self.
720    
721 gross 720 @return: a L{Symbol} representing the positive of the object
722 gross 290 @rtype: L{DependendSymbol}
723     """
724     return self*(1.)
725    
726     def __abs__(self):
727     """
728 gross 720 returns a L{Symbol} representing the absolute value of the object.
729 gross 290 """
730     return Abs_Symbol(self)
731    
732     def __add__(self,other):
733     """
734     add another object to this object
735    
736     @param other: object to be added to this object
737     @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
738 gross 720 @return: a L{Symbol} representing the sum of this object and C{other}
739 gross 290 @rtype: L{DependendSymbol}
740     """
741     return add(self,other)
742    
743     def __radd__(self,other):
744     """
745     add this object to another object
746    
747     @param other: object this object is added to
748     @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
749 gross 720 @return: a L{Symbol} representing the sum of C{other} and this object object
750 gross 290 @rtype: L{DependendSymbol}
751     """
752     return add(other,self)
753    
754     def __sub__(self,other):
755     """
756     subtracts another object from this object
757    
758     @param other: object to be subtracted from this object
759     @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
760 gross 720 @return: a L{Symbol} representing the difference of C{other} and this object
761 gross 290 @rtype: L{DependendSymbol}
762     """
763     return add(self,-other)
764    
765     def __rsub__(self,other):
766     """
767     subtracts this object from another object
768    
769     @param other: object this object is been subtracted from
770     @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
771 gross 720 @return: a L{Symbol} representing the difference of this object and C{other}.
772 gross 290 @rtype: L{DependendSymbol}
773     """
774     return add(-self,other)
775    
776     def __mul__(self,other):
777     """
778     multiplies this object with other object
779    
780     @param other: object to be mutiplied by this object
781     @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
782 gross 720 @return: a L{Symbol} representing the product of the object and C{other}.
783 gross 290 @rtype: L{DependendSymbol} or 0 if other is identical to zero.
784     """
785     return mult(self,other)
786    
787     def __rmul__(self,other):
788     """
789     multiplies this object with other object
790    
791     @param other: object this object is multiplied with
792     @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
793 gross 720 @return: a L{Symbol} representing the product of C{other} and the object.
794 gross 290 @rtype: L{DependendSymbol} or 0 if other is identical to zero.
795     """
796     return mult(other,self)
797    
798     def __div__(self,other):
799     """
800     divides this object by other object
801    
802     @param other: object dividing this object
803     @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
804 gross 720 @return: a L{Symbol} representing the quotient of this object and C{other}
805 gross 290 @rtype: L{DependendSymbol}
806     """
807     return quotient(self,other)
808    
809     def __rdiv__(self,other):
810     """
811     divides this object by other object
812    
813     @param other: object dividing this object
814     @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
815 gross 720 @return: a L{Symbol} representing the quotient of C{other} and this object
816 gross 290 @rtype: L{DependendSymbol} or 0 if C{other} is identical to zero.
817     """
818     return quotient(other,self)
819    
820     def __pow__(self,other):
821     """
822     raises this object to the power of other
823    
824     @param other: exponent
825     @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
826 gross 720 @return: a L{Symbol} representing the power of this object to C{other}
827 gross 290 @rtype: L{DependendSymbol} or 1 if C{other} is identical to zero.
828     """
829     return power(self,other)
830    
831     def __rpow__(self,other):
832     """
833     raises an object to the power of this object
834    
835     @param other: basis
836     @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
837 gross 720 @return: a L{Symbol} representing the power of C{other} to this object
838 gross 290 @rtype: L{DependendSymbol} or 0 if C{other} is identical to zero.
839     """
840     return power(other,self)
841    
842 gross 517 def __getitem__(self,index):
843     """
844     returns the slice defined by index
845    
846     @param index: defines a
847     @type index: C{slice} or C{int} or a C{tuple} of them
848 gross 720 @return: a L{Symbol} representing the slice defined by index
849 gross 517 @rtype: L{DependendSymbol}
850     """
851     return GetSlice_Symbol(self,index)
852    
853 gross 290 class DependendSymbol(Symbol):
854     """
855     DependendSymbol extents L{Symbol} by modifying the == operator to allow two instances to be equal.
856     Two DependendSymbol are equal if they have the same shape, the same arguments and one of them has an unspecified spatial dimension or the spatial dimension is identical
857    
858 gross 720 Example::
859 gross 290
860 gross 720 u1=Symbol(shape=(3,4),dim=2,args=[4.])
861     u2=Symbol(shape=(3,4),dim=2,args=[4.])
862     print u1==u2
863     False
864 gross 290
865 gross 720 but::
866 gross 290
867 gross 720 u1=DependendSymbol(shape=(3,4),dim=2,args=[4.])
868     u2=DependendSymbol(shape=(3,4),dim=2,args=[4.])
869     u3=DependendSymbol(shape=(2,),dim=2,args=[4.])
870     print u1==u2, u1==u3
871     True False
872 gross 290
873     @note: DependendSymbol should be used as return value of functions with L{Symbol} arguments. This will allow the optimizer to remove redundant function calls.
874     """
875     def __eq__(self,other):
876     """
877     checks if other equals self
878    
879     @param other: any object
880     @return: True if other has the same class like self, and the shape, the spatial diemsnion and the arguments are equal.
881     @rtype: C{bool}
882     """
883     if isinstance(other,DependendSymbol):
884     if self.__class__==other.__class__:
885     if self.getShape()==other.getShape():
886     if self.getArgument()==other.getArgument():
887     if self.getDim()==None or other.getDim()==None or self.getDim()==other.getDim():
888     return True
889     return False
890    
891     def __ne__(self,other):
892     """
893     checks if other equals self
894    
895     @param other: any object
896     @return: Flase if other has the same class like self, and the shape, the spatial diemsnion and the arguments are equal.
897     @rtype: C{bool}
898     """
899     return not self==other
900     #=========================================================
901     # Unary operations prserving the shape
902     #========================================================
903 gross 517 class GetSlice_Symbol(DependendSymbol):
904     """
905     L{Symbol} representing getting a slice for a L{Symbol}
906     """
907     def __init__(self,arg,index):
908     """
909     initialization of wherePositive L{Symbol} with argument arg
910     @param arg: argument
911     @type arg: L{Symbol}.
912     @param index: defines index
913     @type index: C{slice} or C{int} or a C{tuple} of them
914     @raises IndexError: if length of index is larger than rank of arg or a index start or stop is out of range
915     @raises ValueError: if a step is given
916     """
917     if not isinstance(index,tuple): index=(index,)
918     if len(index)>arg.getRank():
919     raise IndexError,"GetSlice_Symbol: index out of range."
920     sh=()
921     index2=()
922     for i in range(len(index)):
923     ix=index[i]
924     if isinstance(ix,int):
925     if ix<0 or ix>=arg.getShape()[i]:
926     raise ValueError,"GetSlice_Symbol: index out of range."
927     index2=index2+(ix,)
928     else:
929     if not ix.step==None:
930     raise ValueError,"GetSlice_Symbol: steping is not supported."
931     if ix.start==None:
932     s=0
933     else:
934     s=ix.start
935     if ix.stop==None:
936     e=arg.getShape()[i]
937     else:
938     e=ix.stop
939     if e>arg.getShape()[i]:
940     raise IndexError,"GetSlice_Symbol: index out of range."
941     index2=index2+(slice(s,e),)
942     if e>s:
943     sh=sh+(e-s,)
944     elif s>e:
945     raise IndexError,"GetSlice_Symbol: slice start must be less or equal slice end"
946     for i in range(len(index),arg.getRank()):
947     index2=index2+(slice(0,arg.getShape()[i]),)
948     sh=sh+(arg.getShape()[i],)
949     super(GetSlice_Symbol, self).__init__(args=[arg,index2],shape=sh,dim=arg.getDim())
950    
951     def getMyCode(self,argstrs,format="escript"):
952     """
953     returns a program code that can be used to evaluate the symbol.
954    
955     @param argstrs: gives for each argument a string representing the argument for the evaluation.
956     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
957     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
958     @type format: C{str}
959     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
960     @rtype: C{str}
961 gross 720 @raise NotImplementedError: if the requested format is not available
962 gross 517 """
963     if format=="escript" or format=="str" or format=="text":
964     return "%s.__getitem__(%s)"%(argstrs[0],argstrs[1])
965     else:
966     raise NotImplementedError,"GetItem_Symbol does not provide program code for format %s."%format
967    
968     def substitute(self,argvals):
969     """
970     assigns new values to symbols in the definition of the symbol.
971     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
972    
973     @param argvals: new values assigned to symbols
974     @type argvals: C{dict} with keywords of type L{Symbol}.
975     @return: result of the substitution process. Operations are executed as much as possible.
976     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
977     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
978     """
979     if argvals.has_key(self):
980     arg=argvals[self]
981     if self.isAppropriateValue(arg):
982     return arg
983     else:
984     raise TypeError,"%s: new value is not appropriate."%str(self)
985     else:
986     args=self.getSubstitutedArguments(argvals)
987     arg=args[0]
988     index=args[1]
989     return arg.__getitem__(index)
990    
991 gross 290 def log10(arg):
992     """
993     returns base-10 logarithm of argument arg
994    
995     @param arg: argument
996     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
997 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
998 gross 290 @raises TypeError: if the type of the argument is not expected.
999     """
1000     if isinstance(arg,numarray.NumArray):
1001     return numarray.log10(arg)
1002     elif isinstance(arg,escript.Data):
1003     return arg._log10()
1004     elif isinstance(arg,float):
1005     return math.log10(arg)
1006     elif isinstance(arg,int):
1007     return math.log10(float(arg))
1008     elif isinstance(arg,Symbol):
1009     return log(arg)/log(10.)
1010     else:
1011     raise TypeError,"log10: Unknown argument type."
1012    
1013     def wherePositive(arg):
1014     """
1015     returns mask of positive values of argument arg
1016    
1017     @param arg: argument
1018     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1019 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1020 gross 290 @raises TypeError: if the type of the argument is not expected.
1021     """
1022     if isinstance(arg,numarray.NumArray):
1023 gross 574 out=numarray.greater(arg,numarray.zeros(arg.shape,numarray.Float64))*1.
1024     if isinstance(out,float): out=numarray.array(out,type=numarray.Float64)
1025 gross 396 return out
1026 gross 290 elif isinstance(arg,escript.Data):
1027     return arg._wherePositive()
1028     elif isinstance(arg,float):
1029     if arg>0:
1030     return 1.
1031     else:
1032     return 0.
1033     elif isinstance(arg,int):
1034     if arg>0:
1035     return 1.
1036     else:
1037     return 0.
1038     elif isinstance(arg,Symbol):
1039     return WherePositive_Symbol(arg)
1040     else:
1041     raise TypeError,"wherePositive: Unknown argument type."
1042    
1043     class WherePositive_Symbol(DependendSymbol):
1044     """
1045     L{Symbol} representing the result of the mask of positive values function
1046     """
1047     def __init__(self,arg):
1048     """
1049     initialization of wherePositive L{Symbol} with argument arg
1050     @param arg: argument of function
1051     @type arg: typically L{Symbol}.
1052     """
1053     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1054    
1055     def getMyCode(self,argstrs,format="escript"):
1056     """
1057     returns a program code that can be used to evaluate the symbol.
1058    
1059     @param argstrs: gives for each argument a string representing the argument for the evaluation.
1060     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1061     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1062     @type format: C{str}
1063     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1064     @rtype: C{str}
1065 gross 720 @raise NotImplementedError: if the requested format is not available
1066 gross 290 """
1067     if isinstance(argstrs,list):
1068     argstrs=argstrs[0]
1069     if format=="escript" or format=="str" or format=="text":
1070     return "wherePositive(%s)"%argstrs
1071     else:
1072     raise NotImplementedError,"WherePositive_Symbol does not provide program code for format %s."%format
1073    
1074     def substitute(self,argvals):
1075     """
1076     assigns new values to symbols in the definition of the symbol.
1077     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1078    
1079     @param argvals: new values assigned to symbols
1080     @type argvals: C{dict} with keywords of type L{Symbol}.
1081     @return: result of the substitution process. Operations are executed as much as possible.
1082     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1083     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1084     """
1085     if argvals.has_key(self):
1086     arg=argvals[self]
1087     if self.isAppropriateValue(arg):
1088     return arg
1089     else:
1090     raise TypeError,"%s: new value is not appropriate."%str(self)
1091     else:
1092     arg=self.getSubstitutedArguments(argvals)[0]
1093     return wherePositive(arg)
1094    
1095     def whereNegative(arg):
1096     """
1097     returns mask of positive values of argument arg
1098    
1099     @param arg: argument
1100     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1101 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1102 gross 290 @raises TypeError: if the type of the argument is not expected.
1103     """
1104     if isinstance(arg,numarray.NumArray):
1105 gross 574 out=numarray.less(arg,numarray.zeros(arg.shape,numarray.Float64))*1.
1106     if isinstance(out,float): out=numarray.array(out,type=numarray.Float64)
1107 gross 396 return out
1108 gross 290 elif isinstance(arg,escript.Data):
1109     return arg._whereNegative()
1110     elif isinstance(arg,float):
1111     if arg<0:
1112     return 1.
1113     else:
1114     return 0.
1115     elif isinstance(arg,int):
1116     if arg<0:
1117     return 1.
1118     else:
1119     return 0.
1120     elif isinstance(arg,Symbol):
1121     return WhereNegative_Symbol(arg)
1122     else:
1123     raise TypeError,"whereNegative: Unknown argument type."
1124    
1125     class WhereNegative_Symbol(DependendSymbol):
1126     """
1127     L{Symbol} representing the result of the mask of positive values function
1128     """
1129     def __init__(self,arg):
1130     """
1131     initialization of whereNegative L{Symbol} with argument arg
1132     @param arg: argument of function
1133     @type arg: typically L{Symbol}.
1134     """
1135     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1136    
1137     def getMyCode(self,argstrs,format="escript"):
1138     """
1139     returns a program code that can be used to evaluate the symbol.
1140    
1141     @param argstrs: gives for each argument a string representing the argument for the evaluation.
1142     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1143     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1144     @type format: C{str}
1145     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1146     @rtype: C{str}
1147 gross 720 @raise NotImplementedError: if the requested format is not available
1148 gross 290 """
1149     if isinstance(argstrs,list):
1150     argstrs=argstrs[0]
1151     if format=="escript" or format=="str" or format=="text":
1152     return "whereNegative(%s)"%argstrs
1153     else:
1154     raise NotImplementedError,"WhereNegative_Symbol does not provide program code for format %s."%format
1155    
1156     def substitute(self,argvals):
1157     """
1158     assigns new values to symbols in the definition of the symbol.
1159     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1160    
1161     @param argvals: new values assigned to symbols
1162     @type argvals: C{dict} with keywords of type L{Symbol}.
1163     @return: result of the substitution process. Operations are executed as much as possible.
1164     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1165     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1166     """
1167     if argvals.has_key(self):
1168     arg=argvals[self]
1169     if self.isAppropriateValue(arg):
1170     return arg
1171     else:
1172     raise TypeError,"%s: new value is not appropriate."%str(self)
1173     else:
1174     arg=self.getSubstitutedArguments(argvals)[0]
1175     return whereNegative(arg)
1176    
1177     def whereNonNegative(arg):
1178     """
1179     returns mask of non-negative values of argument arg
1180    
1181     @param arg: argument
1182     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1183 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1184 gross 290 @raises TypeError: if the type of the argument is not expected.
1185     """
1186     if isinstance(arg,numarray.NumArray):
1187 gross 574 out=numarray.greater_equal(arg,numarray.zeros(arg.shape,numarray.Float64))*1.
1188     if isinstance(out,float): out=numarray.array(out,type=numarray.Float64)
1189 gross 396 return out
1190 gross 290 elif isinstance(arg,escript.Data):
1191     return arg._whereNonNegative()
1192     elif isinstance(arg,float):
1193     if arg<0:
1194     return 0.
1195     else:
1196     return 1.
1197     elif isinstance(arg,int):
1198     if arg<0:
1199     return 0.
1200     else:
1201     return 1.
1202     elif isinstance(arg,Symbol):
1203     return 1.-whereNegative(arg)
1204     else:
1205     raise TypeError,"whereNonNegative: Unknown argument type."
1206    
1207     def whereNonPositive(arg):
1208     """
1209     returns mask of non-positive values of argument arg
1210    
1211     @param arg: argument
1212     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1213 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1214 gross 290 @raises TypeError: if the type of the argument is not expected.
1215     """
1216     if isinstance(arg,numarray.NumArray):
1217 gross 574 out=numarray.less_equal(arg,numarray.zeros(arg.shape,numarray.Float64))*1.
1218     if isinstance(out,float): out=numarray.array(out,type=numarray.Float64)
1219 gross 396 return out
1220 gross 290 elif isinstance(arg,escript.Data):
1221     return arg._whereNonPositive()
1222     elif isinstance(arg,float):
1223     if arg>0:
1224     return 0.
1225     else:
1226     return 1.
1227     elif isinstance(arg,int):
1228     if arg>0:
1229     return 0.
1230     else:
1231     return 1.
1232     elif isinstance(arg,Symbol):
1233     return 1.-wherePositive(arg)
1234     else:
1235     raise TypeError,"whereNonPositive: Unknown argument type."
1236    
1237     def whereZero(arg,tol=0.):
1238     """
1239     returns mask of zero entries of argument arg
1240    
1241     @param arg: argument
1242     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1243     @param tol: tolerance. values with absolute value less then tol are accepted as zero.
1244     @type tol: C{float}
1245 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1246 gross 290 @raises TypeError: if the type of the argument is not expected.
1247     """
1248     if isinstance(arg,numarray.NumArray):
1249 gross 574 out=numarray.less_equal(abs(arg)-tol,numarray.zeros(arg.shape,numarray.Float64))*1.
1250     if isinstance(out,float): out=numarray.array(out,type=numarray.Float64)
1251 gross 396 return out
1252 gross 290 elif isinstance(arg,escript.Data):
1253 gross 698 return arg._whereZero(tol)
1254 gross 290 elif isinstance(arg,float):
1255     if abs(arg)<=tol:
1256     return 1.
1257     else:
1258     return 0.
1259     elif isinstance(arg,int):
1260     if abs(float(arg))<=tol:
1261     return 1.
1262     else:
1263     return 0.
1264     elif isinstance(arg,Symbol):
1265     return WhereZero_Symbol(arg,tol)
1266     else:
1267     raise TypeError,"whereZero: Unknown argument type."
1268    
1269     class WhereZero_Symbol(DependendSymbol):
1270     """
1271     L{Symbol} representing the result of the mask of zero entries function
1272     """
1273     def __init__(self,arg,tol=0.):
1274     """
1275     initialization of whereZero L{Symbol} with argument arg
1276     @param arg: argument of function
1277     @type arg: typically L{Symbol}.
1278     """
1279     DependendSymbol.__init__(self,args=[arg,tol],shape=arg.getShape(),dim=arg.getDim())
1280    
1281     def getMyCode(self,argstrs,format="escript"):
1282     """
1283     returns a program code that can be used to evaluate the symbol.
1284    
1285     @param argstrs: gives for each argument a string representing the argument for the evaluation.
1286     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1287     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1288     @type format: C{str}
1289     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1290     @rtype: C{str}
1291 gross 720 @raise NotImplementedError: if the requested format is not available
1292 gross 290 """
1293     if format=="escript" or format=="str" or format=="text":
1294     return "whereZero(%s,tol=%s)"%(argstrs[0],argstrs[1])
1295     else:
1296     raise NotImplementedError,"WhereZero_Symbol does not provide program code for format %s."%format
1297    
1298     def substitute(self,argvals):
1299     """
1300     assigns new values to symbols in the definition of the symbol.
1301     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1302    
1303     @param argvals: new values assigned to symbols
1304     @type argvals: C{dict} with keywords of type L{Symbol}.
1305     @return: result of the substitution process. Operations are executed as much as possible.
1306     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1307     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1308     """
1309     if argvals.has_key(self):
1310     arg=argvals[self]
1311     if self.isAppropriateValue(arg):
1312     return arg
1313     else:
1314     raise TypeError,"%s: new value is not appropriate."%str(self)
1315     else:
1316     arg=self.getSubstitutedArguments(argvals)
1317     return whereZero(arg[0],arg[1])
1318    
1319     def whereNonZero(arg,tol=0.):
1320     """
1321     returns mask of values different from zero of argument arg
1322    
1323     @param arg: argument
1324     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1325 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1326 gross 290 @raises TypeError: if the type of the argument is not expected.
1327     """
1328     if isinstance(arg,numarray.NumArray):
1329 gross 574 out=numarray.greater(abs(arg)-tol,numarray.zeros(arg.shape,numarray.Float64))*1.
1330     if isinstance(out,float): out=numarray.array(out,type=numarray.Float64)
1331 gross 396 return out
1332 gross 290 elif isinstance(arg,escript.Data):
1333 gross 698 return arg._whereNonZero(tol)
1334 gross 290 elif isinstance(arg,float):
1335     if abs(arg)>tol:
1336     return 1.
1337     else:
1338     return 0.
1339     elif isinstance(arg,int):
1340     if abs(float(arg))>tol:
1341     return 1.
1342     else:
1343     return 0.
1344     elif isinstance(arg,Symbol):
1345     return 1.-whereZero(arg,tol)
1346     else:
1347     raise TypeError,"whereNonZero: Unknown argument type."
1348    
1349 ksteube 876 def erf(arg):
1350     """
1351     returns erf of argument arg
1352    
1353     @param arg: argument
1354     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1355     @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1356     @raises TypeError: if the type of the argument is not expected.
1357     """
1358     if isinstance(arg,escript.Data):
1359     return arg._erf()
1360     else:
1361     raise TypeError,"erf: Unknown argument type."
1362    
1363 gross 290 def sin(arg):
1364     """
1365     returns sine of argument arg
1366    
1367     @param arg: argument
1368     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1369 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1370 gross 290 @raises TypeError: if the type of the argument is not expected.
1371     """
1372     if isinstance(arg,numarray.NumArray):
1373     return numarray.sin(arg)
1374     elif isinstance(arg,escript.Data):
1375     return arg._sin()
1376     elif isinstance(arg,float):
1377     return math.sin(arg)
1378     elif isinstance(arg,int):
1379     return math.sin(arg)
1380     elif isinstance(arg,Symbol):
1381     return Sin_Symbol(arg)
1382     else:
1383     raise TypeError,"sin: Unknown argument type."
1384    
1385     class Sin_Symbol(DependendSymbol):
1386     """
1387     L{Symbol} representing the result of the sine function
1388     """
1389     def __init__(self,arg):
1390     """
1391     initialization of sin L{Symbol} with argument arg
1392     @param arg: argument of function
1393     @type arg: typically L{Symbol}.
1394     """
1395     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1396    
1397     def getMyCode(self,argstrs,format="escript"):
1398     """
1399     returns a program code that can be used to evaluate the symbol.
1400    
1401     @param argstrs: gives for each argument a string representing the argument for the evaluation.
1402     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1403     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1404     @type format: C{str}
1405     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1406     @rtype: C{str}
1407 gross 720 @raise NotImplementedError: if the requested format is not available
1408 gross 290 """
1409     if isinstance(argstrs,list):
1410     argstrs=argstrs[0]
1411     if format=="escript" or format=="str" or format=="text":
1412     return "sin(%s)"%argstrs
1413     else:
1414     raise NotImplementedError,"Sin_Symbol does not provide program code for format %s."%format
1415    
1416     def substitute(self,argvals):
1417     """
1418     assigns new values to symbols in the definition of the symbol.
1419     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1420    
1421     @param argvals: new values assigned to symbols
1422     @type argvals: C{dict} with keywords of type L{Symbol}.
1423     @return: result of the substitution process. Operations are executed as much as possible.
1424     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1425     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1426     """
1427     if argvals.has_key(self):
1428     arg=argvals[self]
1429     if self.isAppropriateValue(arg):
1430     return arg
1431     else:
1432     raise TypeError,"%s: new value is not appropriate."%str(self)
1433     else:
1434     arg=self.getSubstitutedArguments(argvals)[0]
1435     return sin(arg)
1436    
1437     def diff(self,arg):
1438     """
1439     differential of this object
1440    
1441     @param arg: the derivative is calculated with respect to arg
1442     @type arg: L{escript.Symbol}
1443     @return: derivative with respect to C{arg}
1444     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1445     """
1446     if arg==self:
1447     return identity(self.getShape())
1448     else:
1449     myarg=self.getArgument()[0]
1450     val=matchShape(cos(myarg),self.getDifferentiatedArguments(arg)[0])
1451     return val[0]*val[1]
1452    
1453     def cos(arg):
1454     """
1455     returns cosine of argument arg
1456    
1457     @param arg: argument
1458     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1459 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1460 gross 290 @raises TypeError: if the type of the argument is not expected.
1461     """
1462     if isinstance(arg,numarray.NumArray):
1463     return numarray.cos(arg)
1464     elif isinstance(arg,escript.Data):
1465     return arg._cos()
1466     elif isinstance(arg,float):
1467     return math.cos(arg)
1468     elif isinstance(arg,int):
1469     return math.cos(arg)
1470     elif isinstance(arg,Symbol):
1471     return Cos_Symbol(arg)
1472     else:
1473     raise TypeError,"cos: Unknown argument type."
1474    
1475     class Cos_Symbol(DependendSymbol):
1476     """
1477     L{Symbol} representing the result of the cosine function
1478     """
1479     def __init__(self,arg):
1480     """
1481     initialization of cos L{Symbol} with argument arg
1482     @param arg: argument of function
1483     @type arg: typically L{Symbol}.
1484     """
1485     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1486    
1487     def getMyCode(self,argstrs,format="escript"):
1488     """
1489     returns a program code that can be used to evaluate the symbol.
1490    
1491     @param argstrs: gives for each argument a string representing the argument for the evaluation.
1492     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1493     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1494     @type format: C{str}
1495     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1496     @rtype: C{str}
1497 gross 720 @raise NotImplementedError: if the requested format is not available
1498 gross 290 """
1499     if isinstance(argstrs,list):
1500     argstrs=argstrs[0]
1501     if format=="escript" or format=="str" or format=="text":
1502     return "cos(%s)"%argstrs
1503     else:
1504     raise NotImplementedError,"Cos_Symbol does not provide program code for format %s."%format
1505    
1506     def substitute(self,argvals):
1507     """
1508     assigns new values to symbols in the definition of the symbol.
1509     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1510    
1511     @param argvals: new values assigned to symbols
1512     @type argvals: C{dict} with keywords of type L{Symbol}.
1513     @return: result of the substitution process. Operations are executed as much as possible.
1514     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1515     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1516     """
1517     if argvals.has_key(self):
1518     arg=argvals[self]
1519     if self.isAppropriateValue(arg):
1520     return arg
1521     else:
1522     raise TypeError,"%s: new value is not appropriate."%str(self)
1523     else:
1524     arg=self.getSubstitutedArguments(argvals)[0]
1525     return cos(arg)
1526    
1527     def diff(self,arg):
1528     """
1529     differential of this object
1530    
1531     @param arg: the derivative is calculated with respect to arg
1532     @type arg: L{escript.Symbol}
1533     @return: derivative with respect to C{arg}
1534     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1535     """
1536     if arg==self:
1537     return identity(self.getShape())
1538     else:
1539     myarg=self.getArgument()[0]
1540     val=matchShape(-sin(myarg),self.getDifferentiatedArguments(arg)[0])
1541     return val[0]*val[1]
1542    
1543     def tan(arg):
1544     """
1545     returns tangent of argument arg
1546    
1547     @param arg: argument
1548     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1549 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1550 gross 290 @raises TypeError: if the type of the argument is not expected.
1551     """
1552     if isinstance(arg,numarray.NumArray):
1553     return numarray.tan(arg)
1554     elif isinstance(arg,escript.Data):
1555     return arg._tan()
1556     elif isinstance(arg,float):
1557     return math.tan(arg)
1558     elif isinstance(arg,int):
1559     return math.tan(arg)
1560     elif isinstance(arg,Symbol):
1561     return Tan_Symbol(arg)
1562     else:
1563     raise TypeError,"tan: Unknown argument type."
1564    
1565     class Tan_Symbol(DependendSymbol):
1566     """
1567     L{Symbol} representing the result of the tangent function
1568     """
1569     def __init__(self,arg):
1570     """
1571     initialization of tan L{Symbol} with argument arg
1572     @param arg: argument of function
1573     @type arg: typically L{Symbol}.
1574     """
1575     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1576    
1577     def getMyCode(self,argstrs,format="escript"):
1578     """
1579     returns a program code that can be used to evaluate the symbol.
1580    
1581     @param argstrs: gives for each argument a string representing the argument for the evaluation.
1582     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1583     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1584     @type format: C{str}
1585     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1586     @rtype: C{str}
1587 gross 720 @raise NotImplementedError: if the requested format is not available
1588 gross 290 """
1589     if isinstance(argstrs,list):
1590     argstrs=argstrs[0]
1591     if format=="escript" or format=="str" or format=="text":
1592     return "tan(%s)"%argstrs
1593     else:
1594     raise NotImplementedError,"Tan_Symbol does not provide program code for format %s."%format
1595    
1596     def substitute(self,argvals):
1597     """
1598     assigns new values to symbols in the definition of the symbol.
1599     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1600    
1601     @param argvals: new values assigned to symbols
1602     @type argvals: C{dict} with keywords of type L{Symbol}.
1603     @return: result of the substitution process. Operations are executed as much as possible.
1604     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1605     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1606     """
1607     if argvals.has_key(self):
1608     arg=argvals[self]
1609     if self.isAppropriateValue(arg):
1610     return arg
1611     else:
1612     raise TypeError,"%s: new value is not appropriate."%str(self)
1613     else:
1614     arg=self.getSubstitutedArguments(argvals)[0]
1615     return tan(arg)
1616    
1617     def diff(self,arg):
1618     """
1619     differential of this object
1620    
1621     @param arg: the derivative is calculated with respect to arg
1622     @type arg: L{escript.Symbol}
1623     @return: derivative with respect to C{arg}
1624     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1625     """
1626     if arg==self:
1627     return identity(self.getShape())
1628     else:
1629     myarg=self.getArgument()[0]
1630     val=matchShape(1./cos(myarg)**2,self.getDifferentiatedArguments(arg)[0])
1631     return val[0]*val[1]
1632    
1633     def asin(arg):
1634     """
1635     returns inverse sine of argument arg
1636    
1637     @param arg: argument
1638     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1639 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1640 gross 290 @raises TypeError: if the type of the argument is not expected.
1641     """
1642     if isinstance(arg,numarray.NumArray):
1643     return numarray.arcsin(arg)
1644     elif isinstance(arg,escript.Data):
1645     return arg._asin()
1646     elif isinstance(arg,float):
1647     return math.asin(arg)
1648     elif isinstance(arg,int):
1649     return math.asin(arg)
1650     elif isinstance(arg,Symbol):
1651     return Asin_Symbol(arg)
1652     else:
1653     raise TypeError,"asin: Unknown argument type."
1654    
1655     class Asin_Symbol(DependendSymbol):
1656     """
1657     L{Symbol} representing the result of the inverse sine function
1658     """
1659     def __init__(self,arg):
1660     """
1661     initialization of asin L{Symbol} with argument arg
1662     @param arg: argument of function
1663     @type arg: typically L{Symbol}.
1664     """
1665     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1666    
1667     def getMyCode(self,argstrs,format="escript"):
1668     """
1669     returns a program code that can be used to evaluate the symbol.
1670    
1671     @param argstrs: gives for each argument a string representing the argument for the evaluation.
1672     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1673     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1674     @type format: C{str}
1675     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1676     @rtype: C{str}
1677 gross 720 @raise NotImplementedError: if the requested format is not available
1678 gross 290 """
1679     if isinstance(argstrs,list):
1680     argstrs=argstrs[0]
1681     if format=="escript" or format=="str" or format=="text":
1682     return "asin(%s)"%argstrs
1683     else:
1684     raise NotImplementedError,"Asin_Symbol does not provide program code for format %s."%format
1685    
1686     def substitute(self,argvals):
1687     """
1688     assigns new values to symbols in the definition of the symbol.
1689     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1690    
1691     @param argvals: new values assigned to symbols
1692     @type argvals: C{dict} with keywords of type L{Symbol}.
1693     @return: result of the substitution process. Operations are executed as much as possible.
1694     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1695     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1696     """
1697     if argvals.has_key(self):
1698     arg=argvals[self]
1699     if self.isAppropriateValue(arg):
1700     return arg
1701     else:
1702     raise TypeError,"%s: new value is not appropriate."%str(self)
1703     else:
1704     arg=self.getSubstitutedArguments(argvals)[0]
1705     return asin(arg)
1706    
1707     def diff(self,arg):
1708     """
1709     differential of this object
1710    
1711     @param arg: the derivative is calculated with respect to arg
1712     @type arg: L{escript.Symbol}
1713     @return: derivative with respect to C{arg}
1714     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1715     """
1716     if arg==self:
1717     return identity(self.getShape())
1718     else:
1719     myarg=self.getArgument()[0]
1720     val=matchShape(1./sqrt(1.-myarg**2),self.getDifferentiatedArguments(arg)[0])
1721     return val[0]*val[1]
1722    
1723     def acos(arg):
1724     """
1725     returns inverse cosine of argument arg
1726    
1727     @param arg: argument
1728     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1729 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1730 gross 290 @raises TypeError: if the type of the argument is not expected.
1731     """
1732     if isinstance(arg,numarray.NumArray):
1733     return numarray.arccos(arg)
1734     elif isinstance(arg,escript.Data):
1735     return arg._acos()
1736     elif isinstance(arg,float):
1737     return math.acos(arg)
1738     elif isinstance(arg,int):
1739     return math.acos(arg)
1740     elif isinstance(arg,Symbol):
1741     return Acos_Symbol(arg)
1742     else:
1743     raise TypeError,"acos: Unknown argument type."
1744    
1745     class Acos_Symbol(DependendSymbol):
1746     """
1747     L{Symbol} representing the result of the inverse cosine function
1748     """
1749     def __init__(self,arg):
1750     """
1751     initialization of acos L{Symbol} with argument arg
1752     @param arg: argument of function
1753     @type arg: typically L{Symbol}.
1754     """
1755     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1756    
1757     def getMyCode(self,argstrs,format="escript"):
1758     """
1759     returns a program code that can be used to evaluate the symbol.
1760    
1761     @param argstrs: gives for each argument a string representing the argument for the evaluation.
1762     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1763     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1764     @type format: C{str}
1765     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1766     @rtype: C{str}
1767 gross 720 @raise NotImplementedError: if the requested format is not available
1768 gross 290 """
1769     if isinstance(argstrs,list):
1770     argstrs=argstrs[0]
1771     if format=="escript" or format=="str" or format=="text":
1772     return "acos(%s)"%argstrs
1773     else:
1774     raise NotImplementedError,"Acos_Symbol does not provide program code for format %s."%format
1775    
1776     def substitute(self,argvals):
1777     """
1778     assigns new values to symbols in the definition of the symbol.
1779     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1780    
1781     @param argvals: new values assigned to symbols
1782     @type argvals: C{dict} with keywords of type L{Symbol}.
1783     @return: result of the substitution process. Operations are executed as much as possible.
1784     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1785     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1786     """
1787     if argvals.has_key(self):
1788     arg=argvals[self]
1789     if self.isAppropriateValue(arg):
1790     return arg
1791     else:
1792     raise TypeError,"%s: new value is not appropriate."%str(self)
1793     else:
1794     arg=self.getSubstitutedArguments(argvals)[0]
1795     return acos(arg)
1796    
1797     def diff(self,arg):
1798     """
1799     differential of this object
1800    
1801     @param arg: the derivative is calculated with respect to arg
1802     @type arg: L{escript.Symbol}
1803     @return: derivative with respect to C{arg}
1804     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1805     """
1806     if arg==self:
1807     return identity(self.getShape())
1808     else:
1809     myarg=self.getArgument()[0]
1810     val=matchShape(-1./sqrt(1.-myarg**2),self.getDifferentiatedArguments(arg)[0])
1811     return val[0]*val[1]
1812    
1813     def atan(arg):
1814     """
1815     returns inverse tangent of argument arg
1816    
1817     @param arg: argument
1818     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1819 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1820 gross 290 @raises TypeError: if the type of the argument is not expected.
1821     """
1822     if isinstance(arg,numarray.NumArray):
1823     return numarray.arctan(arg)
1824     elif isinstance(arg,escript.Data):
1825     return arg._atan()
1826     elif isinstance(arg,float):
1827     return math.atan(arg)
1828     elif isinstance(arg,int):
1829     return math.atan(arg)
1830     elif isinstance(arg,Symbol):
1831     return Atan_Symbol(arg)
1832     else:
1833     raise TypeError,"atan: Unknown argument type."
1834    
1835     class Atan_Symbol(DependendSymbol):
1836     """
1837     L{Symbol} representing the result of the inverse tangent function
1838     """
1839     def __init__(self,arg):
1840     """
1841     initialization of atan L{Symbol} with argument arg
1842     @param arg: argument of function
1843     @type arg: typically L{Symbol}.
1844     """
1845     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1846    
1847     def getMyCode(self,argstrs,format="escript"):
1848     """
1849     returns a program code that can be used to evaluate the symbol.
1850    
1851     @param argstrs: gives for each argument a string representing the argument for the evaluation.
1852     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1853     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1854     @type format: C{str}
1855     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1856     @rtype: C{str}
1857 gross 720 @raise NotImplementedError: if the requested format is not available
1858 gross 290 """
1859     if isinstance(argstrs,list):
1860     argstrs=argstrs[0]
1861     if format=="escript" or format=="str" or format=="text":
1862     return "atan(%s)"%argstrs
1863     else:
1864     raise NotImplementedError,"Atan_Symbol does not provide program code for format %s."%format
1865    
1866     def substitute(self,argvals):
1867     """
1868     assigns new values to symbols in the definition of the symbol.
1869     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1870    
1871     @param argvals: new values assigned to symbols
1872     @type argvals: C{dict} with keywords of type L{Symbol}.
1873     @return: result of the substitution process. Operations are executed as much as possible.
1874     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1875     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1876     """
1877     if argvals.has_key(self):
1878     arg=argvals[self]
1879     if self.isAppropriateValue(arg):
1880     return arg
1881     else:
1882     raise TypeError,"%s: new value is not appropriate."%str(self)
1883     else:
1884     arg=self.getSubstitutedArguments(argvals)[0]
1885     return atan(arg)
1886    
1887     def diff(self,arg):
1888     """
1889     differential of this object
1890    
1891     @param arg: the derivative is calculated with respect to arg
1892     @type arg: L{escript.Symbol}
1893     @return: derivative with respect to C{arg}
1894     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1895     """
1896     if arg==self:
1897     return identity(self.getShape())
1898     else:
1899     myarg=self.getArgument()[0]
1900     val=matchShape(1./(1+myarg**2),self.getDifferentiatedArguments(arg)[0])
1901     return val[0]*val[1]
1902    
1903 jgs 150 def sinh(arg):
1904 gross 290 """
1905     returns hyperbolic sine of argument arg
1906 jgs 150
1907 gross 290 @param arg: argument
1908     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1909 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1910 gross 290 @raises TypeError: if the type of the argument is not expected.
1911     """
1912     if isinstance(arg,numarray.NumArray):
1913     return numarray.sinh(arg)
1914     elif isinstance(arg,escript.Data):
1915     return arg._sinh()
1916     elif isinstance(arg,float):
1917     return math.sinh(arg)
1918     elif isinstance(arg,int):
1919     return math.sinh(arg)
1920     elif isinstance(arg,Symbol):
1921     return Sinh_Symbol(arg)
1922     else:
1923     raise TypeError,"sinh: Unknown argument type."
1924 jgs 150
1925 gross 290 class Sinh_Symbol(DependendSymbol):
1926     """
1927     L{Symbol} representing the result of the hyperbolic sine function
1928     """
1929     def __init__(self,arg):
1930     """
1931     initialization of sinh L{Symbol} with argument arg
1932     @param arg: argument of function
1933     @type arg: typically L{Symbol}.
1934     """
1935     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1936    
1937     def getMyCode(self,argstrs,format="escript"):
1938     """
1939     returns a program code that can be used to evaluate the symbol.
1940    
1941     @param argstrs: gives for each argument a string representing the argument for the evaluation.
1942     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1943     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1944     @type format: C{str}
1945     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1946     @rtype: C{str}
1947 gross 720 @raise NotImplementedError: if the requested format is not available
1948 gross 290 """
1949     if isinstance(argstrs,list):
1950     argstrs=argstrs[0]
1951     if format=="escript" or format=="str" or format=="text":
1952     return "sinh(%s)"%argstrs
1953     else:
1954     raise NotImplementedError,"Sinh_Symbol does not provide program code for format %s."%format
1955    
1956     def substitute(self,argvals):
1957     """
1958     assigns new values to symbols in the definition of the symbol.
1959     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1960    
1961     @param argvals: new values assigned to symbols
1962     @type argvals: C{dict} with keywords of type L{Symbol}.
1963     @return: result of the substitution process. Operations are executed as much as possible.
1964     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1965     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1966     """
1967     if argvals.has_key(self):
1968     arg=argvals[self]
1969     if self.isAppropriateValue(arg):
1970     return arg
1971     else:
1972     raise TypeError,"%s: new value is not appropriate."%str(self)
1973     else:
1974     arg=self.getSubstitutedArguments(argvals)[0]
1975     return sinh(arg)
1976    
1977     def diff(self,arg):
1978     """
1979     differential of this object
1980    
1981     @param arg: the derivative is calculated with respect to arg
1982     @type arg: L{escript.Symbol}
1983     @return: derivative with respect to C{arg}
1984     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1985     """
1986     if arg==self:
1987     return identity(self.getShape())
1988     else:
1989     myarg=self.getArgument()[0]
1990     val=matchShape(cosh(myarg),self.getDifferentiatedArguments(arg)[0])
1991     return val[0]*val[1]
1992    
1993 jgs 150 def cosh(arg):
1994 gross 290 """
1995     returns hyperbolic cosine of argument arg
1996 jgs 150
1997 gross 290 @param arg: argument
1998     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1999 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2000 gross 290 @raises TypeError: if the type of the argument is not expected.
2001     """
2002     if isinstance(arg,numarray.NumArray):
2003     return numarray.cosh(arg)
2004     elif isinstance(arg,escript.Data):
2005     return arg._cosh()
2006     elif isinstance(arg,float):
2007     return math.cosh(arg)
2008     elif isinstance(arg,int):
2009     return math.cosh(arg)
2010     elif isinstance(arg,Symbol):
2011     return Cosh_Symbol(arg)
2012     else:
2013     raise TypeError,"cosh: Unknown argument type."
2014 jgs 150
2015 gross 290 class Cosh_Symbol(DependendSymbol):
2016     """
2017     L{Symbol} representing the result of the hyperbolic cosine function
2018     """
2019     def __init__(self,arg):
2020     """
2021     initialization of cosh L{Symbol} with argument arg
2022     @param arg: argument of function
2023     @type arg: typically L{Symbol}.
2024     """
2025     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2026    
2027     def getMyCode(self,argstrs,format="escript"):
2028     """
2029     returns a program code that can be used to evaluate the symbol.
2030    
2031     @param argstrs: gives for each argument a string representing the argument for the evaluation.
2032     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2033     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2034     @type format: C{str}
2035     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2036     @rtype: C{str}
2037 gross 720 @raise NotImplementedError: if the requested format is not available
2038 gross 290 """
2039     if isinstance(argstrs,list):
2040     argstrs=argstrs[0]
2041     if format=="escript" or format=="str" or format=="text":
2042     return "cosh(%s)"%argstrs
2043     else:
2044     raise NotImplementedError,"Cosh_Symbol does not provide program code for format %s."%format
2045    
2046     def substitute(self,argvals):
2047     """
2048     assigns new values to symbols in the definition of the symbol.
2049     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2050    
2051     @param argvals: new values assigned to symbols
2052     @type argvals: C{dict} with keywords of type L{Symbol}.
2053     @return: result of the substitution process. Operations are executed as much as possible.
2054     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2055     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2056     """
2057     if argvals.has_key(self):
2058     arg=argvals[self]
2059     if self.isAppropriateValue(arg):
2060     return arg
2061     else:
2062     raise TypeError,"%s: new value is not appropriate."%str(self)
2063     else:
2064     arg=self.getSubstitutedArguments(argvals)[0]
2065     return cosh(arg)
2066    
2067     def diff(self,arg):
2068     """
2069     differential of this object
2070    
2071     @param arg: the derivative is calculated with respect to arg
2072     @type arg: L{escript.Symbol}
2073     @return: derivative with respect to C{arg}
2074     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2075     """
2076     if arg==self:
2077     return identity(self.getShape())
2078     else:
2079     myarg=self.getArgument()[0]
2080     val=matchShape(sinh(myarg),self.getDifferentiatedArguments(arg)[0])
2081     return val[0]*val[1]
2082    
2083 jgs 150 def tanh(arg):
2084 gross 290 """
2085     returns hyperbolic tangent of argument arg
2086 jgs 150
2087 gross 290 @param arg: argument
2088     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2089 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2090 gross 290 @raises TypeError: if the type of the argument is not expected.
2091     """
2092     if isinstance(arg,numarray.NumArray):
2093     return numarray.tanh(arg)
2094     elif isinstance(arg,escript.Data):
2095     return arg._tanh()
2096     elif isinstance(arg,float):
2097     return math.tanh(arg)
2098     elif isinstance(arg,int):
2099     return math.tanh(arg)
2100     elif isinstance(arg,Symbol):
2101     return Tanh_Symbol(arg)
2102     else:
2103     raise TypeError,"tanh: Unknown argument type."
2104 jgs 150
2105 gross 290 class Tanh_Symbol(DependendSymbol):
2106     """
2107     L{Symbol} representing the result of the hyperbolic tangent function
2108     """
2109     def __init__(self,arg):
2110     """
2111     initialization of tanh L{Symbol} with argument arg
2112     @param arg: argument of function
2113     @type arg: typically L{Symbol}.
2114     """
2115     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2116    
2117     def getMyCode(self,argstrs,format="escript"):
2118     """
2119     returns a program code that can be used to evaluate the symbol.
2120    
2121     @param argstrs: gives for each argument a string representing the argument for the evaluation.
2122     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2123     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2124     @type format: C{str}
2125     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2126     @rtype: C{str}
2127 gross 720 @raise NotImplementedError: if the requested format is not available
2128 gross 290 """
2129     if isinstance(argstrs,list):
2130     argstrs=argstrs[0]
2131     if format=="escript" or format=="str" or format=="text":
2132     return "tanh(%s)"%argstrs
2133     else:
2134     raise NotImplementedError,"Tanh_Symbol does not provide program code for format %s."%format
2135    
2136     def substitute(self,argvals):
2137     """
2138     assigns new values to symbols in the definition of the symbol.
2139     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2140    
2141     @param argvals: new values assigned to symbols
2142     @type argvals: C{dict} with keywords of type L{Symbol}.
2143     @return: result of the substitution process. Operations are executed as much as possible.
2144     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2145     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2146     """
2147     if argvals.has_key(self):
2148     arg=argvals[self]
2149     if self.isAppropriateValue(arg):
2150     return arg
2151     else:
2152     raise TypeError,"%s: new value is not appropriate."%str(self)
2153     else:
2154     arg=self.getSubstitutedArguments(argvals)[0]
2155     return tanh(arg)
2156    
2157     def diff(self,arg):
2158     """
2159     differential of this object
2160    
2161     @param arg: the derivative is calculated with respect to arg
2162     @type arg: L{escript.Symbol}
2163     @return: derivative with respect to C{arg}
2164     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2165     """
2166     if arg==self:
2167     return identity(self.getShape())
2168     else:
2169     myarg=self.getArgument()[0]
2170     val=matchShape(1./cosh(myarg)**2,self.getDifferentiatedArguments(arg)[0])
2171     return val[0]*val[1]
2172    
2173 jgs 150 def asinh(arg):
2174 gross 290 """
2175     returns inverse hyperbolic sine of argument arg
2176 jgs 150
2177 gross 290 @param arg: argument
2178     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2179 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2180 gross 290 @raises TypeError: if the type of the argument is not expected.
2181     """
2182     if isinstance(arg,numarray.NumArray):
2183     return numarray.arcsinh(arg)
2184     elif isinstance(arg,escript.Data):
2185     return arg._asinh()
2186     elif isinstance(arg,float):
2187     return numarray.arcsinh(arg)
2188     elif isinstance(arg,int):
2189     return numarray.arcsinh(float(arg))
2190     elif isinstance(arg,Symbol):
2191     return Asinh_Symbol(arg)
2192     else:
2193     raise TypeError,"asinh: Unknown argument type."
2194 jgs 150
2195 gross 290 class Asinh_Symbol(DependendSymbol):
2196     """
2197     L{Symbol} representing the result of the inverse hyperbolic sine function
2198     """
2199     def __init__(self,arg):
2200     """
2201     initialization of asinh L{Symbol} with argument arg
2202     @param arg: argument of function
2203     @type arg: typically L{Symbol}.
2204     """
2205     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2206    
2207     def getMyCode(self,argstrs,format="escript"):
2208     """
2209     returns a program code that can be used to evaluate the symbol.
2210    
2211     @param argstrs: gives for each argument a string representing the argument for the evaluation.
2212     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2213     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2214     @type format: C{str}
2215     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2216     @rtype: C{str}
2217 gross 720 @raise NotImplementedError: if the requested format is not available
2218 gross 290 """
2219     if isinstance(argstrs,list):
2220     argstrs=argstrs[0]
2221     if format=="escript" or format=="str" or format=="text":
2222     return "asinh(%s)"%argstrs
2223     else:
2224     raise NotImplementedError,"Asinh_Symbol does not provide program code for format %s."%format
2225    
2226     def substitute(self,argvals):
2227     """
2228     assigns new values to symbols in the definition of the symbol.
2229     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2230    
2231     @param argvals: new values assigned to symbols
2232     @type argvals: C{dict} with keywords of type L{Symbol}.
2233     @return: result of the substitution process. Operations are executed as much as possible.
2234     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2235     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2236     """
2237     if argvals.has_key(self):
2238     arg=argvals[self]
2239     if self.isAppropriateValue(arg):
2240     return arg
2241     else:
2242     raise TypeError,"%s: new value is not appropriate."%str(self)
2243     else:
2244     arg=self.getSubstitutedArguments(argvals)[0]
2245     return asinh(arg)
2246    
2247     def diff(self,arg):
2248     """
2249     differential of this object
2250    
2251     @param arg: the derivative is calculated with respect to arg
2252     @type arg: L{escript.Symbol}
2253     @return: derivative with respect to C{arg}
2254     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2255     """
2256     if arg==self:
2257     return identity(self.getShape())
2258     else:
2259     myarg=self.getArgument()[0]
2260     val=matchShape(1./sqrt(myarg**2+1),self.getDifferentiatedArguments(arg)[0])
2261     return val[0]*val[1]
2262    
2263 jgs 150 def acosh(arg):
2264 gross 290 """
2265     returns inverse hyperolic cosine of argument arg
2266 jgs 150
2267 gross 290 @param arg: argument
2268     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2269 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2270 gross 290 @raises TypeError: if the type of the argument is not expected.
2271     """
2272     if isinstance(arg,numarray.NumArray):
2273     return numarray.arccosh(arg)
2274     elif isinstance(arg,escript.Data):
2275     return arg._acosh()
2276     elif isinstance(arg,float):
2277     return numarray.arccosh(arg)
2278     elif isinstance(arg,int):
2279     return numarray.arccosh(float(arg))
2280     elif isinstance(arg,Symbol):
2281     return Acosh_Symbol(arg)
2282     else:
2283     raise TypeError,"acosh: Unknown argument type."
2284 jgs 150
2285 gross 290 class Acosh_Symbol(DependendSymbol):
2286     """
2287     L{Symbol} representing the result of the inverse hyperolic cosine function
2288     """
2289     def __init__(self,arg):
2290     """
2291     initialization of acosh L{Symbol} with argument arg
2292     @param arg: argument of function
2293     @type arg: typically L{Symbol}.
2294     """
2295     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2296    
2297     def getMyCode(self,argstrs,format="escript"):
2298     """
2299     returns a program code that can be used to evaluate the symbol.
2300    
2301     @param argstrs: gives for each argument a string representing the argument for the evaluation.
2302     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2303     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2304     @type format: C{str}
2305     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2306     @rtype: C{str}
2307 gross 720 @raise NotImplementedError: if the requested format is not available
2308 gross 290 """
2309     if isinstance(argstrs,list):
2310     argstrs=argstrs[0]
2311     if format=="escript" or format=="str" or format=="text":
2312     return "acosh(%s)"%argstrs
2313     else:
2314     raise NotImplementedError,"Acosh_Symbol does not provide program code for format %s."%format
2315    
2316     def substitute(self,argvals):
2317     """
2318     assigns new values to symbols in the definition of the symbol.
2319     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2320    
2321     @param argvals: new values assigned to symbols
2322     @type argvals: C{dict} with keywords of type L{Symbol}.
2323     @return: result of the substitution process. Operations are executed as much as possible.
2324     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2325     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2326     """
2327     if argvals.has_key(self):
2328     arg=argvals[self]
2329     if self.isAppropriateValue(arg):
2330     return arg
2331     else:
2332     raise TypeError,"%s: new value is not appropriate."%str(self)
2333     else:
2334     arg=self.getSubstitutedArguments(argvals)[0]
2335     return acosh(arg)
2336    
2337     def diff(self,arg):
2338     """
2339     differential of this object
2340    
2341     @param arg: the derivative is calculated with respect to arg
2342     @type arg: L{escript.Symbol}
2343     @return: derivative with respect to C{arg}
2344     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2345     """
2346     if arg==self:
2347     return identity(self.getShape())
2348     else:
2349     myarg=self.getArgument()[0]
2350     val=matchShape(1./sqrt(myarg**2-1),self.getDifferentiatedArguments(arg)[0])
2351     return val[0]*val[1]
2352    
2353 jgs 150 def atanh(arg):
2354 gross 290 """
2355     returns inverse hyperbolic tangent of argument arg
2356 jgs 150
2357 gross 290 @param arg: argument
2358     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2359 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2360 gross 290 @raises TypeError: if the type of the argument is not expected.
2361     """
2362     if isinstance(arg,numarray.NumArray):
2363     return numarray.arctanh(arg)
2364     elif isinstance(arg,escript.Data):
2365     return arg._atanh()
2366     elif isinstance(arg,float):
2367     return numarray.arctanh(arg)
2368     elif isinstance(arg,int):
2369     return numarray.arctanh(float(arg))
2370     elif isinstance(arg,Symbol):
2371     return Atanh_Symbol(arg)
2372     else:
2373     raise TypeError,"atanh: Unknown argument type."
2374 jgs 150
2375 gross 290 class Atanh_Symbol(DependendSymbol):
2376     """
2377     L{Symbol} representing the result of the inverse hyperbolic tangent function
2378     """
2379     def __init__(self,arg):
2380     """
2381     initialization of atanh L{Symbol} with argument arg
2382     @param arg: argument of function
2383     @type arg: typically L{Symbol}.
2384     """
2385     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2386    
2387     def getMyCode(self,argstrs,format="escript"):
2388     """
2389     returns a program code that can be used to evaluate the symbol.
2390    
2391     @param argstrs: gives for each argument a string representing the argument for the evaluation.
2392     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2393     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2394     @type format: C{str}
2395     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2396     @rtype: C{str}
2397 gross 720 @raise NotImplementedError: if the requested format is not available
2398 gross 290 """
2399     if isinstance(argstrs,list):
2400     argstrs=argstrs[0]
2401     if format=="escript" or format=="str" or format=="text":
2402     return "atanh(%s)"%argstrs
2403     else:
2404     raise NotImplementedError,"Atanh_Symbol does not provide program code for format %s."%format
2405    
2406     def substitute(self,argvals):
2407     """
2408     assigns new values to symbols in the definition of the symbol.
2409     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2410    
2411     @param argvals: new values assigned to symbols
2412     @type argvals: C{dict} with keywords of type L{Symbol}.
2413     @return: result of the substitution process. Operations are executed as much as possible.
2414     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2415     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2416     """
2417     if argvals.has_key(self):
2418     arg=argvals[self]
2419     if self.isAppropriateValue(arg):
2420     return arg
2421     else:
2422     raise TypeError,"%s: new value is not appropriate."%str(self)
2423     else:
2424     arg=self.getSubstitutedArguments(argvals)[0]
2425     return atanh(arg)
2426    
2427     def diff(self,arg):
2428     """
2429     differential of this object
2430    
2431     @param arg: the derivative is calculated with respect to arg
2432     @type arg: L{escript.Symbol}
2433     @return: derivative with respect to C{arg}
2434     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2435     """
2436     if arg==self:
2437     return identity(self.getShape())
2438     else:
2439     myarg=self.getArgument()[0]
2440     val=matchShape(1./(1.-myarg**2),self.getDifferentiatedArguments(arg)[0])
2441     return val[0]*val[1]
2442    
2443     def exp(arg):
2444     """
2445     returns exponential of argument arg
2446    
2447     @param arg: argument
2448     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2449 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2450 gross 290 @raises TypeError: if the type of the argument is not expected.
2451     """
2452     if isinstance(arg,numarray.NumArray):
2453     return numarray.exp(arg)
2454     elif isinstance(arg,escript.Data):
2455     return arg._exp()
2456     elif isinstance(arg,float):
2457     return math.exp(arg)
2458     elif isinstance(arg,int):
2459     return math.exp(arg)
2460     elif isinstance(arg,Symbol):
2461     return Exp_Symbol(arg)
2462     else:
2463     raise TypeError,"exp: Unknown argument type."
2464    
2465     class Exp_Symbol(DependendSymbol):
2466     """
2467     L{Symbol} representing the result of the exponential function
2468     """
2469     def __init__(self,arg):
2470     """
2471     initialization of exp L{Symbol} with argument arg
2472     @param arg: argument of function
2473     @type arg: typically L{Symbol}.
2474     """
2475     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2476    
2477     def getMyCode(self,argstrs,format="escript"):
2478     """
2479     returns a program code that can be used to evaluate the symbol.
2480    
2481     @param argstrs: gives for each argument a string representing the argument for the evaluation.
2482     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2483     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2484     @type format: C{str}
2485     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2486     @rtype: C{str}
2487 gross 720 @raise NotImplementedError: if the requested format is not available
2488 gross 290 """
2489     if isinstance(argstrs,list):
2490     argstrs=argstrs[0]
2491     if format=="escript" or format=="str" or format=="text":
2492     return "exp(%s)"%argstrs
2493     else:
2494     raise NotImplementedError,"Exp_Symbol does not provide program code for format %s."%format
2495    
2496     def substitute(self,argvals):
2497     """
2498     assigns new values to symbols in the definition of the symbol.
2499     The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2500    
2501     @param argvals: new values assigned to symbols
2502     @type argvals: C{dict} with keywords of type L{Symbol}.
2503     @return: result of the substitution process. Operations are executed as much as possible.
2504     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2505     @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2506     """
2507     if argvals.has_key(self):
2508     arg=argvals[self]
2509     if self.isAppropriateValue(arg):
2510     return arg
2511     else:
2512     raise TypeError,"%s: new value is not appropriate."%str(self)
2513     else:
2514     arg=self.getSubstitutedArguments(argvals)[0]
2515     return exp(arg)
2516    
2517     def diff(self,arg):
2518     """
2519     differential of this object
2520    
2521     @param arg: the derivative is calculated with respect to arg
2522     @type arg: L{escript.Symbol}
2523     @return: derivative with respect to C{arg}
2524     @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2525     """
2526     if arg==self:
2527     return identity(self.getShape())
2528     else:
2529     myarg=self.getArgument()[0]
2530     val=matchShape(self,self.getDifferentiatedArguments(arg)[0])
2531     return val[0]*val[1]
2532    
2533     def sqrt(arg):
2534     """
2535     returns square root of argument arg
2536    
2537     @param arg: argument
2538     @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2539 gross 720 @rtype: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2540 gross 290 @raises TypeError: if the type of the argument is not expected.
2541     """
2542     if isinstance(arg,numarray.NumArray):
2543     return numarray.sqrt(arg)
2544     elif isinstance(arg,escript.Data):
2545     return arg._sqrt()
2546     elif isinstance(arg,float):
2547     return math.sqrt(arg)
2548     elif isinstance(arg,int):
2549     return math.sqrt(arg)
2550     elif isinstance(arg,Symbol):
2551     return Sqrt_Symbol(arg)
2552     else:
2553     raise TypeError,"sqrt: Unknown argument type."
2554    
2555     class Sqrt_Symbol(DependendSymbol):
2556     """
2557     L{Symbol} representing the result of the square root function
2558     """
2559     def __init__(self,arg):
2560     """
2561     initialization of sqrt L{Symbol} with argument arg
2562     @param arg: argument of function
2563     @type arg: typically L{Symbol}.
2564     """
2565     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2566    
2567     def getMyCode(self,argstrs,format="escript"):
2568     """
2569     returns a program code that can be used to evaluate the symbol.
2570    
2571     @param argstrs: gives for each argument a string representing the argument for the evaluation.
2572     @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2573     @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2574     @type format: C{str}
2575     @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2576     @rtype: C{str}
2577 gross 720 @raise NotImplementedError: if the requested format is not available
2578 gross 290 """
2579     if isinstance(argstrs,list):
2580     argstrs=argstrs[0]
2581     if format=="escript" or format=="str" or format=="text":
2582     return "sqrt(%s)"%argstrs
2583     else:
2584     raise NotImplementedError,"Sqrt_Symbol does not provide program code for format %s."%format
2585    
2586     def substitute(self,argvals):
2587     """
2588     assigns new values to symbols in the definition of the symbol.