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