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