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