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