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