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