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