/[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 2169 - (hide annotations)
Wed Dec 17 03:08:58 2008 UTC (10 years, 9 months ago) by caltinay
File MIME type: text/x-python
File size: 220269 byte(s)
Assorted spelling, grammar, whitespace and copy/paste error fixes (Part 2).
All epydoc warnings for these files have been fixed.
This commit should be a no-op.

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