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