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