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