/[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 2100 - (hide annotations)
Wed Nov 26 08:13:00 2008 UTC (10 years, 10 months ago) by gross
File MIME type: text/x-python
File size: 210560 byte(s)
This commit cleans up the incompressible solver and adds a DarcyFlux solver in model module. 
Some documentation for both classes has been added.
The convection code is only linear at the moment.



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