/[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 2300 - (hide annotations)
Wed Mar 11 08:17:57 2009 UTC (10 years, 7 months ago) by gross
File MIME type: text/x-python
File size: 224790 byte(s)
a power law model. tests still need to be added and needs to be linked with an incompressible solver.
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     def whereZero(arg,tol=0.):
1494     """
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     @param tol: tolerance. Values with absolute value less than tol are accepted
1500     as zero.
1501 gross 290 @type tol: C{float}
1502 caltinay 2169 @rtype: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray} depending
1503     on the type of C{arg}
1504     @raises TypeError: if the type of the argument is not expected
1505 gross 290 """
1506     if isinstance(arg,numarray.NumArray):
1507 gross 574 out=numarray.less_equal(abs(arg)-tol,numarray.zeros(arg.shape,numarray.Float64))*1.
1508     if isinstance(out,float): out=numarray.array(out,type=numarray.Float64)
1509 gross 396 return out
1510 gross 290 elif isinstance(arg,escript.Data):
1511 gross 698 return arg._whereZero(tol)
1512 gross 290 elif isinstance(arg,float):
1513     if abs(arg)<=tol:
1514     return 1.
1515     else:
1516     return 0.
1517     elif isinstance(arg,int):
1518     if abs(float(arg))<=tol:
1519     return 1.
1520     else:
1521     return 0.
1522     elif isinstance(arg,Symbol):
1523     return WhereZero_Symbol(arg,tol)
1524     else:
1525     raise TypeError,"whereZero: Unknown argument type."
1526    
1527     class WhereZero_Symbol(DependendSymbol):
1528     """
1529 caltinay 2169 L{Symbol} representing the result of the mask of zero entries function.
1530 gross 290 """
1531     def __init__(self,arg,tol=0.):
1532     """
1533 caltinay 2169 Initialization of whereZero L{Symbol} with argument C{arg}.
1534    
1535 gross 290 @param arg: argument of function
1536 caltinay 2169 @type arg: typically L{Symbol}
1537 gross 290 """
1538     DependendSymbol.__init__(self,args=[arg,tol],shape=arg.getShape(),dim=arg.getDim())
1539    
1540     def getMyCode(self,argstrs,format="escript"):
1541     """
1542 caltinay 2169 Returns program code that can be used to evaluate the symbol.
1543 gross 290
1544 caltinay 2169 @param argstrs: a string for each argument representing the argument
1545     for the evaluation
1546     @type argstrs: C{str} or a C{list} of length 1 of C{str}
1547     @param format: specifies the format to be used. At the moment only
1548     "escript", "str" and "text" are supported.
1549 gross 290 @type format: C{str}
1550 caltinay 2169 @return: a piece of program code which can be used to evaluate the
1551     expression assuming the values for the arguments are available
1552 gross 290 @rtype: C{str}
1553 caltinay 2169 @raise NotImplementedError: if no implementation for the given format
1554     is available
1555 gross 290 """
1556     if format=="escript" or format=="str" or format=="text":
1557     return "whereZero(%s,tol=%s)"%(argstrs[0],argstrs[1])
1558     else:
1559     raise NotImplementedError,"WhereZero_Symbol does not provide program code for format %s."%format
1560    
1561     def substitute(self,argvals):
1562     """
1563 caltinay 2169 Assigns new values to symbols in the definition of the symbol.
1564     The method replaces the L{Symbol} u by argvals[u] in the expression
1565     defining this object.
1566 gross 290
1567     @param argvals: new values assigned to symbols
1568 caltinay 2169 @type argvals: C{dict} with keywords of type L{Symbol}
1569     @return: result of the substitution process. Operations are executed as
1570     much as possible.
1571     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, C{numarray.NumArray}
1572     depending on the degree of substitution
1573     @raise TypeError: if a value for a L{Symbol} cannot be substituted
1574 gross 290 """
1575     if argvals.has_key(self):
1576     arg=argvals[self]
1577     if self.isAppropriateValue(arg):
1578     return arg
1579     else:
1580     raise TypeError,"%s: new value is not appropriate."%str(self)
1581     else:
1582     arg=self.getSubstitutedArguments(argvals)
1583     return whereZero(arg[0],arg[1])
1584    
1585     def whereNonZero(arg,tol=0.):
1586     """
1587 caltinay 2169 Returns mask of values different from zero of argument C{arg}.
1588 gross 290
1589     @param arg: argument
1590 caltinay 2169 @type arg: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray}.
1591     @rtype: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray} depending
1592     on the type of C{arg}
1593     @raise TypeError: if the type of the argument is not expected
1594 gross 290 """
1595     if isinstance(arg,numarray.NumArray):
1596 gross 574 out=numarray.greater(abs(arg)-tol,numarray.zeros(arg.shape,numarray.Float64))*1.
1597     if isinstance(out,float): out=numarray.array(out,type=numarray.Float64)
1598 gross 396 return out
1599 gross 290 elif isinstance(arg,escript.Data):
1600 gross 698 return arg._whereNonZero(tol)
1601 gross 290 elif isinstance(arg,float):
1602     if abs(arg)>tol:
1603     return 1.
1604     else:
1605     return 0.
1606     elif isinstance(arg,int):
1607     if abs(float(arg))>tol:
1608     return 1.
1609     else:
1610     return 0.
1611     elif isinstance(arg,Symbol):
1612     return 1.-whereZero(arg,tol)
1613     else:
1614     raise TypeError,"whereNonZero: Unknown argument type."
1615    
1616 ksteube 876 def erf(arg):
1617     """
1618 caltinay 2169 Returns the error function M{erf} of argument C{arg}.
1619 ksteube 876
1620     @param arg: argument
1621 caltinay 2169 @type arg: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray}.
1622     @rtype: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray} depending
1623     on the type of C{arg}
1624     @raise TypeError: if the type of the argument is not expected
1625 ksteube 876 """
1626     if isinstance(arg,escript.Data):
1627     return arg._erf()
1628     else:
1629     raise TypeError,"erf: Unknown argument type."
1630    
1631 gross 290 def sin(arg):
1632     """
1633 caltinay 2169 Returns sine of argument C{arg}.
1634 gross 290
1635     @param arg: argument
1636 caltinay 2169 @type arg: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray}.
1637     @rtype: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray} depending
1638     on the type of C{arg}
1639     @raise TypeError: if the type of the argument is not expected
1640 gross 290 """
1641     if isinstance(arg,numarray.NumArray):
1642     return numarray.sin(arg)
1643     elif isinstance(arg,escript.Data):
1644     return arg._sin()
1645     elif isinstance(arg,float):
1646     return math.sin(arg)
1647     elif isinstance(arg,int):
1648     return math.sin(arg)
1649     elif isinstance(arg,Symbol):
1650     return Sin_Symbol(arg)
1651     else:
1652     raise TypeError,"sin: Unknown argument type."
1653    
1654     class Sin_Symbol(DependendSymbol):
1655     """
1656 caltinay 2169 L{Symbol} representing the result of the sine function.
1657 gross 290 """
1658     def __init__(self,arg):
1659     """
1660 caltinay 2169 Initialization of sin L{Symbol} with argument C{arg}.
1661    
1662 gross 290 @param arg: argument of function
1663 caltinay 2169 @type arg: typically L{Symbol}
1664 gross 290 """
1665     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1666    
1667     def getMyCode(self,argstrs,format="escript"):
1668     """
1669 caltinay 2169 Returns program code that can be used to evaluate the symbol.
1670 gross 290
1671 caltinay 2169 @param argstrs: a string for each argument representing the argument
1672     for the evaluation
1673     @type argstrs: C{str} or a C{list} of length 1 of C{str}
1674     @param format: specifies the format to be used. At the moment only
1675     "escript", "str" and "text" are supported.
1676 gross 290 @type format: C{str}
1677 caltinay 2169 @return: a piece of program code which can be used to evaluate the
1678     expression assuming the values for the arguments are available
1679 gross 290 @rtype: C{str}
1680 caltinay 2169 @raise NotImplementedError: if no implementation for the given format
1681     is available
1682 gross 290 """
1683     if isinstance(argstrs,list):
1684     argstrs=argstrs[0]
1685     if format=="escript" or format=="str" or format=="text":
1686     return "sin(%s)"%argstrs
1687     else:
1688     raise NotImplementedError,"Sin_Symbol does not provide program code for format %s."%format
1689    
1690     def substitute(self,argvals):
1691     """
1692 caltinay 2169 Assigns new values to symbols in the definition of the symbol.
1693     The method replaces the L{Symbol} u by argvals[u] in the expression
1694     defining this object.
1695 gross 290
1696     @param argvals: new values assigned to symbols
1697 caltinay 2169 @type argvals: C{dict} with keywords of type L{Symbol}
1698     @return: result of the substitution process. Operations are executed as
1699     much as possible.
1700     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, C{numarray.NumArray}
1701     depending on the degree of substitution
1702     @raise TypeError: if a value for a L{Symbol} cannot be substituted
1703 gross 290 """
1704     if argvals.has_key(self):
1705     arg=argvals[self]
1706     if self.isAppropriateValue(arg):
1707     return arg
1708     else:
1709     raise TypeError,"%s: new value is not appropriate."%str(self)
1710     else:
1711     arg=self.getSubstitutedArguments(argvals)[0]
1712     return sin(arg)
1713    
1714     def diff(self,arg):
1715     """
1716 caltinay 2169 Differential of this object.
1717 gross 290
1718 caltinay 2169 @param arg: the derivative is calculated with respect to C{arg}
1719 gross 290 @type arg: L{escript.Symbol}
1720     @return: derivative with respect to C{arg}
1721 caltinay 2169 @rtype: typically L{Symbol} but other types such as C{float},
1722     L{escript.Data}, C{numarray.NumArray} are possible
1723 gross 290 """
1724     if arg==self:
1725     return identity(self.getShape())
1726     else:
1727     myarg=self.getArgument()[0]
1728     val=matchShape(cos(myarg),self.getDifferentiatedArguments(arg)[0])
1729     return val[0]*val[1]
1730    
1731     def cos(arg):
1732     """
1733 caltinay 2169 Returns cosine of argument C{arg}.
1734 gross 290
1735     @param arg: argument
1736 caltinay 2169 @type arg: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray}
1737     @rtype: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray} depending
1738     on the type of C{arg}
1739     @raises TypeError: if the type of the argument is not expected
1740 gross 290 """
1741     if isinstance(arg,numarray.NumArray):
1742     return numarray.cos(arg)
1743     elif isinstance(arg,escript.Data):
1744     return arg._cos()
1745     elif isinstance(arg,float):
1746     return math.cos(arg)
1747     elif isinstance(arg,int):
1748     return math.cos(arg)
1749     elif isinstance(arg,Symbol):
1750     return Cos_Symbol(arg)
1751     else:
1752     raise TypeError,"cos: Unknown argument type."
1753    
1754     class Cos_Symbol(DependendSymbol):
1755     """
1756 caltinay 2169 L{Symbol} representing the result of the cosine function.
1757 gross 290 """
1758     def __init__(self,arg):
1759     """
1760 caltinay 2169 Initialization of cos L{Symbol} with argument C{arg}.
1761    
1762 gross 290 @param arg: argument of function
1763 caltinay 2169 @type arg: typically L{Symbol}
1764 gross 290 """
1765     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1766    
1767     def getMyCode(self,argstrs,format="escript"):
1768     """
1769 caltinay 2169 Returns program code that can be used to evaluate the symbol.
1770 gross 290
1771 caltinay 2169 @param argstrs: a string for each argument representing the argument
1772     for the evaluation
1773     @type argstrs: C{str} or a C{list} of length 1 of C{str}
1774     @param format: specifies the format to be used. At the moment only
1775     "escript", "str" and "text" are supported.
1776 gross 290 @type format: C{str}
1777 caltinay 2169 @return: a piece of program code which can be used to evaluate the
1778     expression assuming the values for the arguments are available
1779 gross 290 @rtype: C{str}
1780 caltinay 2169 @raise NotImplementedError: if no implementation for the given format
1781     is available
1782 gross 290 """
1783     if isinstance(argstrs,list):
1784     argstrs=argstrs[0]
1785     if format=="escript" or format=="str" or format=="text":
1786     return "cos(%s)"%argstrs
1787     else:
1788     raise NotImplementedError,"Cos_Symbol does not provide program code for format %s."%format
1789    
1790     def substitute(self,argvals):
1791     """
1792 caltinay 2169 Assigns new values to symbols in the definition of the symbol.
1793     The method replaces the L{Symbol} u by argvals[u] in the expression
1794     defining this object.
1795 gross 290
1796     @param argvals: new values assigned to symbols
1797 caltinay 2169 @type argvals: C{dict} with keywords of type L{Symbol}
1798     @return: result of the substitution process. Operations are executed as
1799     much as possible.
1800     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, C{numarray.NumArray}
1801     depending on the degree of substitution
1802     @raise TypeError: if a value for a L{Symbol} cannot be substituted
1803 gross 290 """
1804     if argvals.has_key(self):
1805     arg=argvals[self]
1806     if self.isAppropriateValue(arg):
1807     return arg
1808     else:
1809     raise TypeError,"%s: new value is not appropriate."%str(self)
1810     else:
1811     arg=self.getSubstitutedArguments(argvals)[0]
1812     return cos(arg)
1813    
1814     def diff(self,arg):
1815     """
1816 caltinay 2169 Differential of this object.
1817 gross 290
1818 caltinay 2169 @param arg: the derivative is calculated with respect to C{arg}
1819 gross 290 @type arg: L{escript.Symbol}
1820     @return: derivative with respect to C{arg}
1821 caltinay 2169 @rtype: typically L{Symbol} but other types such as C{float},
1822     L{escript.Data}, C{numarray.NumArray} are possible
1823 gross 290 """
1824     if arg==self:
1825     return identity(self.getShape())
1826     else:
1827     myarg=self.getArgument()[0]
1828     val=matchShape(-sin(myarg),self.getDifferentiatedArguments(arg)[0])
1829     return val[0]*val[1]
1830    
1831     def tan(arg):
1832     """
1833 caltinay 2169 Returns tangent of argument C{arg}.
1834 gross 290
1835     @param arg: argument
1836 caltinay 2169 @type arg: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray}
1837     @rtype: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray} depending
1838     on the type of C{arg}
1839     @raises TypeError: if the type of the argument is not expected
1840 gross 290 """
1841     if isinstance(arg,numarray.NumArray):
1842     return numarray.tan(arg)
1843     elif isinstance(arg,escript.Data):
1844     return arg._tan()
1845     elif isinstance(arg,float):
1846     return math.tan(arg)
1847     elif isinstance(arg,int):
1848     return math.tan(arg)
1849     elif isinstance(arg,Symbol):
1850     return Tan_Symbol(arg)
1851     else:
1852     raise TypeError,"tan: Unknown argument type."
1853    
1854     class Tan_Symbol(DependendSymbol):
1855     """
1856 caltinay 2169 L{Symbol} representing the result of the tangent function.
1857 gross 290 """
1858     def __init__(self,arg):
1859     """
1860 caltinay 2169 Initialization of tan L{Symbol} with argument C{arg}.
1861    
1862 gross 290 @param arg: argument of function
1863 caltinay 2169 @type arg: typically L{Symbol}
1864 gross 290 """
1865     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1866    
1867     def getMyCode(self,argstrs,format="escript"):
1868     """
1869 caltinay 2169 Returns program code that can be used to evaluate the symbol.
1870 gross 290
1871 caltinay 2169 @param argstrs: a string for each argument representing the argument
1872     for the evaluation
1873     @type argstrs: C{str} or a C{list} of length 1 of C{str}
1874     @param format: specifies the format to be used. At the moment only
1875     "escript", "str" and "text" are supported.
1876 gross 290 @type format: C{str}
1877 caltinay 2169 @return: a piece of program code which can be used to evaluate the
1878     expression assuming the values for the arguments are available
1879 gross 290 @rtype: C{str}
1880 caltinay 2169 @raise NotImplementedError: if no implementation for the given format
1881     is available
1882 gross 290 """
1883     if isinstance(argstrs,list):
1884     argstrs=argstrs[0]
1885     if format=="escript" or format=="str" or format=="text":
1886     return "tan(%s)"%argstrs
1887     else:
1888     raise NotImplementedError,"Tan_Symbol does not provide program code for format %s."%format
1889    
1890     def substitute(self,argvals):
1891     """
1892 caltinay 2169 Assigns new values to symbols in the definition of the symbol.
1893     The method replaces the L{Symbol} u by argvals[u] in the expression
1894     defining this object.
1895 gross 290
1896     @param argvals: new values assigned to symbols
1897 caltinay 2169 @type argvals: C{dict} with keywords of type L{Symbol}
1898     @return: result of the substitution process. Operations are executed as
1899     much as possible.
1900     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, C{numarray.NumArray}
1901     depending on the degree of substitution
1902     @raise TypeError: if a value for a L{Symbol} cannot be substituted
1903 gross 290 """
1904     if argvals.has_key(self):
1905     arg=argvals[self]
1906     if self.isAppropriateValue(arg):
1907     return arg
1908     else:
1909     raise TypeError,"%s: new value is not appropriate."%str(self)
1910     else:
1911     arg=self.getSubstitutedArguments(argvals)[0]
1912     return tan(arg)
1913    
1914     def diff(self,arg):
1915     """
1916 caltinay 2169 Differential of this object.
1917 gross 290
1918 caltinay 2169 @param arg: the derivative is calculated with respect to C{arg}
1919 gross 290 @type arg: L{escript.Symbol}
1920     @return: derivative with respect to C{arg}
1921 caltinay 2169 @rtype: typically L{Symbol} but other types such as C{float},
1922     L{escript.Data}, C{numarray.NumArray} are possible
1923 gross 290 """
1924     if arg==self:
1925     return identity(self.getShape())
1926     else:
1927     myarg=self.getArgument()[0]
1928     val=matchShape(1./cos(myarg)**2,self.getDifferentiatedArguments(arg)[0])
1929     return val[0]*val[1]
1930    
1931     def asin(arg):
1932     """
1933 caltinay 2169 Returns the inverse sine of argument C{arg}.
1934 gross 290
1935     @param arg: argument
1936 caltinay 2169 @type arg: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray}
1937     @rtype: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray} depending
1938     on the type of C{arg}
1939     @raises TypeError: if the type of the argument is not expected
1940 gross 290 """
1941     if isinstance(arg,numarray.NumArray):
1942     return numarray.arcsin(arg)
1943     elif isinstance(arg,escript.Data):
1944     return arg._asin()
1945     elif isinstance(arg,float):
1946     return math.asin(arg)
1947     elif isinstance(arg,int):
1948     return math.asin(arg)
1949     elif isinstance(arg,Symbol):
1950     return Asin_Symbol(arg)
1951     else:
1952     raise TypeError,"asin: Unknown argument type."
1953    
1954     class Asin_Symbol(DependendSymbol):
1955     """
1956 caltinay 2169 L{Symbol} representing the result of the inverse sine function.
1957 gross 290 """
1958     def __init__(self,arg):
1959     """
1960 caltinay 2169 Initialization of asin L{Symbol} with argument C{arg}.
1961    
1962 gross 290 @param arg: argument of function
1963 caltinay 2169 @type arg: typically L{Symbol}
1964 gross 290 """
1965     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1966    
1967     def getMyCode(self,argstrs,format="escript"):
1968     """
1969 caltinay 2169 Returns program code that can be used to evaluate the symbol.
1970 gross 290
1971 caltinay 2169 @param argstrs: a string for each argument representing the argument
1972     for the evaluation
1973     @type argstrs: C{str} or a C{list} of length 1 of C{str}
1974     @param format: specifies the format to be used. At the moment only
1975     "escript", "str" and "text" are supported.
1976 gross 290 @type format: C{str}
1977 caltinay 2169 @return: a piece of program code which can be used to evaluate the
1978     expression assuming the values for the arguments are available
1979 gross 290 @rtype: C{str}
1980 caltinay 2169 @raise NotImplementedError: if no implementation for the given format
1981     is available
1982 gross 290 """
1983     if isinstance(argstrs,list):
1984     argstrs=argstrs[0]
1985     if format=="escript" or format=="str" or format=="text":
1986     return "asin(%s)"%argstrs
1987     else:
1988     raise NotImplementedError,"Asin_Symbol does not provide program code for format %s."%format
1989    
1990     def substitute(self,argvals):
1991     """
1992 caltinay 2169 Assigns new values to symbols in the definition of the symbol.
1993     The method replaces the L{Symbol} u by argvals[u] in the expression
1994     defining this object.
1995 gross 290
1996     @param argvals: new values assigned to symbols
1997 caltinay 2169 @type argvals: C{dict} with keywords of type L{Symbol}
1998     @return: result of the substitution process. Operations are executed as
1999     much as possible.
2000     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, C{numarray.NumArray}
2001     depending on the degree of substitution
2002     @raise TypeError: if a value for a L{Symbol} cannot be substituted
2003 gross 290 """
2004     if argvals.has_key(self):
2005     arg=argvals[self]
2006     if self.isAppropriateValue(arg):
2007     return arg
2008     else:
2009     raise TypeError,"%s: new value is not appropriate."%str(self)
2010     else:
2011     arg=self.getSubstitutedArguments(argvals)[0]
2012     return asin(arg)
2013    
2014     def diff(self,arg):
2015     """
2016 caltinay 2169 Differential of this object.
2017 gross 290
2018 caltinay 2169 @param arg: the derivative is calculated with respect to C{arg}
2019 gross 290 @type arg: L{escript.Symbol}
2020     @return: derivative with respect to C{arg}
2021 caltinay 2169 @rtype: typically L{Symbol} but other types such as C{float},
2022     L{escript.Data}, C{numarray.NumArray} are possible
2023 gross 290 """
2024     if arg==self:
2025     return identity(self.getShape())
2026     else:
2027     myarg=self.getArgument()[0]
2028     val=matchShape(1./sqrt(1.-myarg**2),self.getDifferentiatedArguments(arg)[0])
2029     return val[0]*val[1]
2030    
2031     def acos(arg):
2032     """
2033 caltinay 2169 Returns the inverse cosine of argument C{arg}.
2034 gross 290
2035     @param arg: argument
2036 caltinay 2169 @type arg: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray}
2037     @rtype: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray} depending
2038     on the type of C{arg}
2039     @raises TypeError: if the type of the argument is not expected
2040 gross 290 """
2041     if isinstance(arg,numarray.NumArray):
2042     return numarray.arccos(arg)
2043     elif isinstance(arg,escript.Data):
2044     return arg._acos()
2045     elif isinstance(arg,float):
2046     return math.acos(arg)
2047     elif isinstance(arg,int):
2048     return math.acos(arg)
2049     elif isinstance(arg,Symbol):
2050     return Acos_Symbol(arg)
2051     else:
2052     raise TypeError,"acos: Unknown argument type."
2053    
2054     class Acos_Symbol(DependendSymbol):
2055     """
2056 caltinay 2169 L{Symbol} representing the result of the inverse cosine function.
2057 gross 290 """
2058     def __init__(self,arg):
2059     """
2060 caltinay 2169 Initialization of acos L{Symbol} with argument C{arg}.
2061    
2062 gross 290 @param arg: argument of function
2063 caltinay 2169 @type arg: typically L{Symbol}
2064 gross 290 """
2065     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2066    
2067     def getMyCode(self,argstrs,format="escript"):
2068     """
2069 caltinay 2169 Returns program code that can be used to evaluate the symbol.
2070 gross 290
2071 caltinay 2169 @param argstrs: a string for each argument representing the argument
2072     for the evaluation
2073     @type argstrs: C{str} or a C{list} of length 1 of C{str}
2074     @param format: specifies the format to be used. At the moment only
2075     "escript", "str" and "text" are supported.
2076 gross 290 @type format: C{str}
2077 caltinay 2169 @return: a piece of program code which can be used to evaluate the
2078     expression assuming the values for the arguments are available
2079 gross 290 @rtype: C{str}
2080 caltinay 2169 @raise NotImplementedError: if no implementation for the given format
2081     is available
2082 gross 290 """
2083     if isinstance(argstrs,list):
2084     argstrs=argstrs[0]
2085     if format=="escript" or format=="str" or format=="text":
2086     return "acos(%s)"%argstrs
2087     else:
2088     raise NotImplementedError,"Acos_Symbol does not provide program code for format %s."%format
2089    
2090     def substitute(self,argvals):
2091     """
2092 caltinay 2169 Assigns new values to symbols in the definition of the symbol.
2093     The method replaces the L{Symbol} u by argvals[u] in the expression
2094     defining this object.
2095 gross 290
2096     @param argvals: new values assigned to symbols
2097 caltinay 2169 @type argvals: C{dict} with keywords of type L{Symbol}
2098     @return: result of the substitution process. Operations are executed as
2099     much as possible.
2100     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, C{numarray.NumArray}
2101     depending on the degree of substitution
2102     @raise TypeError: if a value for a L{Symbol} cannot be substituted
2103 gross 290 """
2104     if argvals.has_key(self):
2105     arg=argvals[self]
2106     if self.isAppropriateValue(arg):
2107     return arg
2108     else:
2109     raise TypeError,"%s: new value is not appropriate."%str(self)
2110     else:
2111     arg=self.getSubstitutedArguments(argvals)[0]
2112     return acos(arg)
2113    
2114     def diff(self,arg):
2115     """
2116 caltinay 2169 Differential of this object.
2117 gross 290
2118 caltinay 2169 @param arg: the derivative is calculated with respect to C{arg}
2119 gross 290 @type arg: L{escript.Symbol}
2120     @return: derivative with respect to C{arg}
2121 caltinay 2169 @rtype: typically L{Symbol} but other types such as C{float},
2122     L{escript.Data}, C{numarray.NumArray} are possible
2123 gross 290 """
2124     if arg==self:
2125     return identity(self.getShape())
2126     else:
2127     myarg=self.getArgument()[0]
2128     val=matchShape(-1./sqrt(1.-myarg**2),self.getDifferentiatedArguments(arg)[0])
2129     return val[0]*val[1]
2130    
2131     def atan(arg):
2132     """
2133 caltinay 2169 Returns inverse tangent of argument C{arg}.
2134 gross 290
2135     @param arg: argument
2136 caltinay 2169 @type arg: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray}
2137     @rtype: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray} depending
2138     on the type of C{arg}
2139     @raises TypeError: if the type of the argument is not expected
2140 gross 290 """
2141     if isinstance(arg,numarray.NumArray):
2142     return numarray.arctan(arg)
2143     elif isinstance(arg,escript.Data):
2144     return arg._atan()
2145     elif isinstance(arg,float):
2146     return math.atan(arg)
2147     elif isinstance(arg,int):
2148     return math.atan(arg)
2149     elif isinstance(arg,Symbol):
2150     return Atan_Symbol(arg)
2151     else:
2152     raise TypeError,"atan: Unknown argument type."
2153    
2154     class Atan_Symbol(DependendSymbol):
2155     """
2156 caltinay 2169 L{Symbol} representing the result of the inverse tangent function.
2157 gross 290 """
2158     def __init__(self,arg):
2159     """
2160 caltinay 2169 Initialization of atan L{Symbol} with argument C{arg}.
2161    
2162 gross 290 @param arg: argument of function
2163 caltinay 2169 @type arg: typically L{Symbol}
2164 gross 290 """
2165     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2166    
2167     def getMyCode(self,argstrs,format="escript"):
2168     """
2169 caltinay 2169 Returns program code that can be used to evaluate the symbol.
2170 gross 290
2171 caltinay 2169 @param argstrs: a string for each argument representing the argument
2172     for the evaluation
2173     @type argstrs: C{str} or a C{list} of length 1 of C{str}
2174     @param format: specifies the format to be used. At the moment only
2175     "escript", "str" and "text" are supported.
2176 gross 290 @type format: C{str}
2177 caltinay 2169 @return: a piece of program code which can be used to evaluate the
2178     expression assuming the values for the arguments are available
2179 gross 290 @rtype: C{str}
2180 caltinay 2169 @raise NotImplementedError: if no implementation for the given format
2181     is available
2182 gross 290 """
2183     if isinstance(argstrs,list):
2184     argstrs=argstrs[0]
2185     if format=="escript" or format=="str" or format=="text":
2186     return "atan(%s)"%argstrs
2187     else:
2188     raise NotImplementedError,"Atan_Symbol does not provide program code for format %s."%format
2189    
2190     def substitute(self,argvals):
2191     """
2192 caltinay 2169 Assigns new values to symbols in the definition of the symbol.
2193     The method replaces the L{Symbol} u by argvals[u] in the expression
2194     defining this object.
2195 gross 290
2196     @param argvals: new values assigned to symbols
2197 caltinay 2169 @type argvals: C{dict} with keywords of type L{Symbol}
2198     @return: result of the substitution process. Operations are executed as
2199     much as possible.
2200     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, C{numarray.NumArray}
2201     depending on the degree of substitution
2202     @raise TypeError: if a value for a L{Symbol} cannot be substituted
2203 gross 290 """
2204     if argvals.has_key(self):
2205     arg=argvals[self]
2206     if self.isAppropriateValue(arg):
2207     return arg
2208     else:
2209     raise TypeError,"%s: new value is not appropriate."%str(self)
2210     else:
2211     arg=self.getSubstitutedArguments(argvals)[0]
2212     return atan(arg)
2213    
2214     def diff(self,arg):
2215     """
2216 caltinay 2169 Differential of this object.
2217 gross 290
2218 caltinay 2169 @param arg: the derivative is calculated with respect to C{arg}
2219 gross 290 @type arg: L{escript.Symbol}
2220     @return: derivative with respect to C{arg}
2221 caltinay 2169 @rtype: typically L{Symbol} but other types such as C{float},
2222     L{escript.Data}, C{numarray.NumArray} are possible
2223 gross 290 """
2224     if arg==self:
2225     return identity(self.getShape())
2226     else:
2227     myarg=self.getArgument()[0]
2228     val=matchShape(1./(1+myarg**2),self.getDifferentiatedArguments(arg)[0])
2229     return val[0]*val[1]
2230    
2231 jgs 150 def sinh(arg):
2232 gross 290 """
2233 caltinay 2169 Returns the hyperbolic sine of argument C{arg}.
2234 jgs 150
2235 gross 290 @param arg: argument
2236 caltinay 2169 @type arg: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray}
2237     @rtype: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray} depending
2238     on the type of C{arg}
2239     @raises TypeError: if the type of the argument is not expected
2240 gross 290 """
2241     if isinstance(arg,numarray.NumArray):
2242     return numarray.sinh(arg)
2243     elif isinstance(arg,escript.Data):
2244     return arg._sinh()
2245     elif isinstance(arg,float):
2246     return math.sinh(arg)
2247     elif isinstance(arg,int):
2248     return math.sinh(arg)
2249     elif isinstance(arg,Symbol):
2250     return Sinh_Symbol(arg)
2251     else:
2252     raise TypeError,"sinh: Unknown argument type."
2253 jgs 150
2254 gross 290 class Sinh_Symbol(DependendSymbol):
2255     """
2256 caltinay 2169 L{Symbol} representing the result of the hyperbolic sine function.
2257 gross 290 """
2258     def __init__(self,arg):
2259     """
2260 caltinay 2169 Initialization of sinh L{Symbol} with argument C{arg}.
2261    
2262 gross 290 @param arg: argument of function
2263 caltinay 2169 @type arg: typically L{Symbol}
2264 gross 290 """
2265     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2266    
2267     def getMyCode(self,argstrs,format="escript"):
2268     """
2269 caltinay 2169 Returns program code that can be used to evaluate the symbol.
2270 gross 290
2271 caltinay 2169 @param argstrs: a string for each argument representing the argument
2272     for the evaluation
2273     @type argstrs: C{str} or a C{list} of length 1 of C{str}
2274     @param format: specifies the format to be used. At the moment only
2275     "escript", "str" and "text" are supported.
2276 gross 290 @type format: C{str}
2277 caltinay 2169 @return: a piece of program code which can be used to evaluate the
2278     expression assuming the values for the arguments are available
2279 gross 290 @rtype: C{str}
2280 caltinay 2169 @raise NotImplementedError: if no implementation for the given format
2281     is available
2282 gross 290 """
2283     if isinstance(argstrs,list):
2284     argstrs=argstrs[0]
2285     if format=="escript" or format=="str" or format=="text":
2286     return "sinh(%s)"%argstrs
2287     else:
2288     raise NotImplementedError,"Sinh_Symbol does not provide program code for format %s."%format
2289    
2290     def substitute(self,argvals):
2291     """
2292 caltinay 2169 Assigns new values to symbols in the definition of the symbol.
2293     The method replaces the L{Symbol} u by argvals[u] in the expression
2294     defining this object.
2295 gross 290
2296     @param argvals: new values assigned to symbols
2297 caltinay 2169 @type argvals: C{dict} with keywords of type L{Symbol}
2298     @return: result of the substitution process. Operations are executed as
2299     much as possible.
2300     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, C{numarray.NumArray}
2301     depending on the degree of substitution
2302     @raise TypeError: if a value for a L{Symbol} cannot be substituted
2303 gross 290 """
2304     if argvals.has_key(self):
2305     arg=argvals[self]
2306     if self.isAppropriateValue(arg):
2307     return arg
2308     else:
2309     raise TypeError,"%s: new value is not appropriate."%str(self)
2310     else:
2311     arg=self.getSubstitutedArguments(argvals)[0]
2312     return sinh(arg)
2313    
2314     def diff(self,arg):
2315     """
2316 caltinay 2169 Differential of this object.
2317 gross 290
2318 caltinay 2169 @param arg: the derivative is calculated with respect to C{arg}
2319 gross 290 @type arg: L{escript.Symbol}
2320     @return: derivative with respect to C{arg}
2321 caltinay 2169 @rtype: typically L{Symbol} but other types such as C{float},
2322     L{escript.Data}, C{numarray.NumArray} are possible
2323 gross 290 """
2324     if arg==self:
2325     return identity(self.getShape())
2326     else:
2327     myarg=self.getArgument()[0]
2328     val=matchShape(cosh(myarg),self.getDifferentiatedArguments(arg)[0])
2329     return val[0]*val[1]
2330    
2331 jgs 150 def cosh(arg):
2332 gross 290 """
2333 caltinay 2169 Returns the hyperbolic cosine of argument C{arg}.
2334 jgs 150
2335 gross 290 @param arg: argument
2336 caltinay 2169 @type arg: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray}
2337     @rtype: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray} depending
2338     on the type of C{arg}
2339     @raises TypeError: if the type of the argument is not expected
2340 gross 290 """
2341     if isinstance(arg,numarray.NumArray):
2342     return numarray.cosh(arg)
2343     elif isinstance(arg,escript.Data):
2344     return arg._cosh()
2345     elif isinstance(arg,float):
2346     return math.cosh(arg)
2347     elif isinstance(arg,int):
2348     return math.cosh(arg)
2349     elif isinstance(arg,Symbol):
2350     return Cosh_Symbol(arg)
2351     else:
2352     raise TypeError,"cosh: Unknown argument type."
2353 jgs 150
2354 gross 290 class Cosh_Symbol(DependendSymbol):
2355     """
2356 caltinay 2169 L{Symbol} representing the result of the hyperbolic cosine function.
2357 gross 290 """
2358     def __init__(self,arg):
2359     """
2360 caltinay 2169 Initialization of cosh L{Symbol} with argument C{arg}.
2361    
2362 gross 290 @param arg: argument of function
2363 caltinay 2169 @type arg: typically L{Symbol}
2364 gross 290 """
2365     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2366    
2367     def getMyCode(self,argstrs,format="escript"):
2368     """
2369 caltinay 2169 Returns program code that can be used to evaluate the symbol.
2370 gross 290
2371 caltinay 2169 @param argstrs: a string for each argument representing the argument
2372     for the evaluation
2373     @type argstrs: C{str} or a C{list} of length 1 of C{str}
2374     @param format: specifies the format to be used. At the moment only
2375     "escript", "str" and "text" are supported.
2376 gross 290 @type format: C{str}
2377 caltinay 2169 @return: a piece of program code which can be used to evaluate the
2378     expression assuming the values for the arguments are available
2379 gross 290 @rtype: C{str}
2380 caltinay 2169 @raise NotImplementedError: if no implementation for the given format
2381     is available
2382 gross 290 """
2383     if isinstance(argstrs,list):
2384     argstrs=argstrs[0]
2385     if format=="escript" or format=="str" or format=="text":
2386     return "cosh(%s)"%argstrs
2387     else:
2388     raise NotImplementedError,"Cosh_Symbol does not provide program code for format %s."%format
2389    
2390     def substitute(self,argvals):
2391     """
2392 caltinay 2169 Assigns new values to symbols in the definition of the symbol.
2393     The method replaces the L{Symbol} u by argvals[u] in the expression
2394     defining this object.
2395 gross 290
2396     @param argvals: new values assigned to symbols
2397 caltinay 2169 @type argvals: C{dict} with keywords of type L{Symbol}
2398     @return: result of the substitution process. Operations are executed as
2399     much as possible.
2400     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, C{numarray.NumArray}
2401     depending on the degree of substitution
2402     @raise TypeError: if a value for a L{Symbol} cannot be substituted
2403 gross 290 """
2404     if argvals.has_key(self):
2405     arg=argvals[self]
2406     if self.isAppropriateValue(arg):
2407     return arg
2408     else:
2409     raise TypeError,"%s: new value is not appropriate."%str(self)
2410     else:
2411     arg=self.getSubstitutedArguments(argvals)[0]
2412     return cosh(arg)
2413    
2414     def diff(self,arg):
2415     """
2416 caltinay 2169 Differential of this object.
2417 gross 290
2418 caltinay 2169 @param arg: the derivative is calculated with respect to C{arg}
2419 gross 290 @type arg: L{escript.Symbol}
2420     @return: derivative with respect to C{arg}
2421 caltinay 2169 @rtype: typically L{Symbol} but other types such as C{float},
2422     L{escript.Data}, C{numarray.NumArray} are possible
2423 gross 290 """
2424     if arg==self:
2425     return identity(self.getShape())
2426     else:
2427     myarg=self.getArgument()[0]
2428     val=matchShape(sinh(myarg),self.getDifferentiatedArguments(arg)[0])
2429     return val[0]*val[1]
2430    
2431 jgs 150 def tanh(arg):
2432 gross 290 """
2433 caltinay 2169 Returns the hyperbolic tangent of argument C{arg}.
2434 jgs 150
2435 gross 290 @param arg: argument
2436 caltinay 2169 @type arg: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray}
2437     @rtype: C{float}, L{escript.Data}, L{Symbol}, C{numarray.NumArray} depending
2438     on the type of C{arg}
2439     @raises TypeError: if the type of the argument is not expected
2440 gross 290 """
2441     if isinstance(arg,numarray.NumArray):
2442     return numarray.tanh(arg)
2443     elif isinstance(arg,escript.Data):
2444     return arg._tanh()
2445     elif isinstance(arg,float):
2446     return math.tanh(arg)
2447     elif isinstance(arg,int):
2448     return math.tanh(arg)
2449     elif isinstance(arg,Symbol):
2450     return Tanh_Symbol(arg)
2451     else:
2452     raise TypeError,"tanh: Unknown argument type."
2453 jgs 150
2454 gross 290 class Tanh_Symbol(DependendSymbol):
2455     """
2456 caltinay 2169 L{Symbol} representing the result of the hyperbolic tangent function.
2457 gross 290 """
2458     def __init__(self,arg):
2459     """
2460 caltinay 2169 Initialization of tanh L{Symbol} with argument C{arg}.
2461    
2462 gross 290 @param arg: argument of function
2463 caltinay 2169 @type arg: typically L{Symbol}
2464 gross 290 """
2465     DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2466    
2467     def getMyCode(self,argstrs,format="escript"):
2468     """
2469 caltinay 2169 Returns program code that can be used to evaluate the symbol.
2470 gross 290
2471 caltinay 2169 @param argstrs: a string for each argument representing the argument
2472     for the evaluation
2473     @type argstrs: C{str} or a C{list} of length 1 of C{str}
2474     @param format: specifies the format to be used. At the moment only
2475     "escript", "str" and "text" are supported.
2476 gross 290 @type format: C{str}
2477 caltinay 2169 @return: a piece of program code which can be used to evaluate the
2478     expression assuming the values for the arguments are available
2479 gross 290 @rtype: C{str}
2480 caltinay 2169 @raise NotImplementedError: if no implementation for the given format
2481     is available
2482 gross 290 """
2483     if isinstance(argstrs,list):
2484     argstrs=argstrs[0]
2485     if format=="escript" or format=="str" or format=="text":
2486     return "tanh(%s)"%argstrs
2487     else:
2488     raise NotImplementedError,"Tanh_Symbol does not provide program code for format %s."%format
2489    
2490     def substitute(self,argvals):
2491     """
2492 caltinay 2169 Assigns new values to symbols in the definition of the symbol.
2493     The method replaces the L{Symbol} u by argvals[u] in the expression
2494     defining this object.
2495 gross 290
2496     @param argvals: new values assigned to symbols
2497 caltinay 2169 @type argvals: C{dict} with keywords of type L{Symbol}
2498     @return: result of the substitution process. Operations are executed as
2499     much as possible.
2500     @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, C{numarray.NumArray}
2501     depending on the degree of substitution
2502     @raise TypeError: if a value for a L{Symbol} cannot be substituted
2503 gross 290 """
2504     if argvals.has_key(self):
2505     arg=argvals[self]
2506     if self.isAppropriateValue(arg):
2507     return arg
2508     else:
2509     raise TypeError,"%s: new value is not appropriate."%str(self)
2510     else:
2511     arg=self.getSubstitutedArguments(argvals)[0]
2512     return tanh(arg)
2513    
2514     def diff(self,arg):
2515     """
2516 caltinay