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