/[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 1247 - (hide annotations)
Tue Aug 14 01:29:20 2007 UTC (12 years, 2 months ago) by ksteube
File MIME type: text/x-python
File size: 212759 byte(s)
New python method getVersion() which returns the Subversion revision
from which escript was compiled

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