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