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