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