/[escript]/trunk/escript/py_src/util.py
ViewVC logotype

Contents of /trunk/escript/py_src/util.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 429 - (show annotations)
Wed Jan 11 05:53:40 2006 UTC (13 years, 9 months ago) by gross
File MIME type: text/x-python
File size: 167666 byte(s)
new implementation and testing for trace function
1 # $Id$
2 #
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
12 """
13 Utility functions for escript
14
15 @remark: This module is under construction and is still tested!!!
16
17 @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 """
23
24 __author__="Lutz Gross, l.gross@uq.edu.au"
25 __licence__="contact: esys@access.uq.edu.au"
26 __url__="http://www.iservo.edu.au/esys/escript"
27 __version__="$Revision$"
28 __date__="$Date$"
29
30
31 import math
32 import numarray
33 import escript
34 import os
35
36 # 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 transpose(arg,axis=None):
47 # def trace(arg,axis0=0,axis1=1):
48 # def reorderComponents(arg,index):
49
50 # def integrate(arg,where=None):
51 # def interpolate(arg,where):
52 # def div(arg,where=None):
53 # def grad(arg,where=None):
54
55 #
56 # slicing: get
57 # set
58 #
59 # and derivatives
60
61 #=========================================================
62 # some helpers:
63 #=========================================================
64 def saveVTK(filename,domain=None,**data):
65 """
66 writes a L{Data} objects into a files using the the VTK XML file format.
67
68 Example:
69
70 tmp=Scalar(..)
71 v=Vector(..)
72 saveVTK("solution.xml",temperature=tmp,velovity=v)
73
74 tmp and v are written into "solution.xml" where tmp is named "temperature" and v is named "velovity"
75
76 @param filename: file name of the output file
77 @type filename: C{str}
78 @param domain: domain of the L{Data} object. If not specified, the domain of the given L{Data} objects is used.
79 @type domain: L{escript.Domain}
80 @keyword <name>: writes the assigned value to the VTK file using <name> as identifier.
81 @type <name>: L{Data} object.
82 @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.
83 """
84 if domain==None:
85 for i in data.keys():
86 if not data[i].isEmpty(): domain=data[i].getFunctionSpace().getDomain()
87 if domain==None:
88 raise ValueError,"no domain detected."
89 else:
90 domain.saveVTK(filename,data)
91
92 def saveDX(filename,domain=None,**data):
93 """
94 writes a L{Data} objects into a files using the the DX file format.
95
96 Example:
97
98 tmp=Scalar(..)
99 v=Vector(..)
100 saveDX("solution.dx",temperature=tmp,velovity=v)
101
102 tmp and v are written into "solution.dx" where tmp is named "temperature" and v is named "velovity".
103
104 @param filename: file name of the output file
105 @type filename: C{str}
106 @param domain: domain of the L{Data} object. If not specified, the domain of the given L{Data} objects is used.
107 @type domain: L{escript.Domain}
108 @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.
109 @type <name>: L{Data} object.
110 @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.
111 """
112 if domain==None:
113 for i in data.keys():
114 if not data[i].isEmpty(): domain=data[i].getFunctionSpace().getDomain()
115 if domain==None:
116 raise ValueError,"no domain detected."
117 else:
118 domain.saveDX(filename,data)
119
120 def kronecker(d=3):
121 """
122 return the kronecker S{delta}-symbol
123
124 @param d: dimension or an object that has the C{getDim} method defining the dimension
125 @type d: C{int} or any object with a C{getDim} method
126 @return: the object u of rank 2 with M{u[i,j]=1} for M{i=j} and M{u[i,j]=0} otherwise
127 @rtype d: L{numarray.NumArray} of rank 2.
128 @remark: the function is identical L{identity}
129 """
130 return identityTensor(d)
131
132 def identity(shape=()):
133 """
134 return the shape x shape identity tensor
135
136 @param shape: input shape for the identity tensor
137 @type shape: C{tuple} of C{int}
138 @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.
139 @rtype: L{numarray.NumArray} of rank 1, rankk 2 or rank 4.
140 @raise ValueError: if len(shape)>2.
141 """
142 if len(shape)>0:
143 out=numarray.zeros(shape+shape,numarray.Float)
144 if len(shape)==1:
145 for i0 in range(shape[0]):
146 out[i0,i0]=1.
147
148 elif len(shape)==2:
149 for i0 in range(shape[0]):
150 for i1 in range(shape[1]):
151 out[i0,i1,i0,i1]=1.
152 else:
153 raise ValueError,"identity: length of shape is restricted to 2."
154 else:
155 out=1.
156 return out
157
158 def identityTensor(d=3):
159 """
160 return the dxd identity matrix
161
162 @param d: dimension or an object that has the C{getDim} method defining the dimension
163 @type d: C{int} or any object with a C{getDim} method
164 @return: the object u of rank 2 with M{u[i,j]=1} for M{i=j} and M{u[i,j]=0} otherwise
165 @rtype: L{numarray.NumArray} of rank 2.
166 """
167 if hasattr(d,"getDim"):
168 d=d.getDim()
169 return identity(shape=(d,))
170
171 def identityTensor4(d=3):
172 """
173 return the dxdxdxd identity tensor
174
175 @param d: dimension or an object that has the C{getDim} method defining the dimension
176 @type d: C{int} or any object with a C{getDim} method
177 @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
178 @rtype: L{numarray.NumArray} of rank 4.
179 """
180 if hasattr(d,"getDim"):
181 d=d.getDim()
182 return identity((d,d))
183
184 def unitVector(i=0,d=3):
185 """
186 return a unit vector u of dimension d with nonzero index i:
187
188 @param i: index
189 @type i: C{int}
190 @param d: dimension or an object that has the C{getDim} method defining the dimension
191 @type d: C{int} or any object with a C{getDim} method
192 @return: the object u of rank 1 with M{u[j]=1} for M{j=i} and M{u[i]=0} otherwise
193 @rtype: L{numarray.NumArray} of rank 1.
194 """
195 return kronecker(d)[i]
196
197 #=========================================================================
198 # global reduction operations (these functions have no symbolic version)
199 #=========================================================================
200 def Lsup(arg):
201 """
202 returns the Lsup-norm of argument arg. This is the maximum absolute value over all data points.
203 This function is equivalent to sup(abs(arg)).
204
205 @param arg: argument
206 @type arg: C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
207 @return: maximum value of the absolute value of arg over all components and all data points
208 @rtype: C{float}
209 @raise TypeError: if type of arg cannot be processed
210 """
211 if isinstance(arg,numarray.NumArray):
212 return sup(abs(arg))
213 elif isinstance(arg,escript.Data):
214 return arg._Lsup()
215 elif isinstance(arg,float):
216 return abs(arg)
217 elif isinstance(arg,int):
218 return abs(float(arg))
219 else:
220 raise TypeError,"Lsup: Unknown argument type."
221
222 def sup(arg):
223 """
224 returns the maximum value over all data points.
225
226 @param arg: argument
227 @type arg: C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
228 @return: maximum value of arg over all components and all data points
229 @rtype: C{float}
230 @raise TypeError: if type of arg cannot be processed
231 """
232 if isinstance(arg,numarray.NumArray):
233 return arg.max()
234 elif isinstance(arg,escript.Data):
235 return arg._sup()
236 elif isinstance(arg,float):
237 return arg
238 elif isinstance(arg,int):
239 return float(arg)
240 else:
241 raise TypeError,"sup: Unknown argument type."
242
243 def inf(arg):
244 """
245 returns the maximum value over all data points.
246
247 @param arg: argument
248 @type arg: C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
249 @return : minimum value of arg over all components and all data points
250 @rtype: C{float}
251 @raise TypeError: if type of arg cannot be processed
252 """
253 if isinstance(arg,numarray.NumArray):
254 return arg.min()
255 elif isinstance(arg,escript.Data):
256 return arg._inf()
257 elif isinstance(arg,float):
258 return arg
259 elif isinstance(arg,int):
260 return float(arg)
261 else:
262 raise TypeError,"inf: Unknown argument type."
263
264
265 #=========================================================================
266 # some little helpers
267 #=========================================================================
268 def pokeShape(arg):
269 """
270 identifies the shape of its argument
271
272 @param arg: a given object
273 @type arg: L{numarray.NumArray},L{escript.Data},C{float}, C{int}, C{Symbol}
274 @return: the shape of the argument
275 @rtype: C{tuple} of C{int}
276 @raise TypeError: if type of arg cannot be processed
277 """
278
279 if isinstance(arg,numarray.NumArray):
280 return arg.shape
281 elif isinstance(arg,escript.Data):
282 return arg.getShape()
283 elif isinstance(arg,float):
284 return ()
285 elif isinstance(arg,int):
286 return ()
287 elif isinstance(arg,Symbol):
288 return arg.getShape()
289 else:
290 raise TypeError,"pokeShape: cannot identify shape"
291
292 def pokeDim(arg):
293 """
294 identifies the spatial dimension of its argument
295
296 @param arg: a given object
297 @type arg: any
298 @return: the spatial dimension of the argument, if available, or C{None}
299 @rtype: C{int} or C{None}
300 """
301
302 if isinstance(arg,escript.Data):
303 return arg.getFunctionSpace().getDim()
304 elif isinstance(arg,Symbol):
305 return arg.getDim()
306 else:
307 return None
308
309 def commonShape(arg0,arg1):
310 """
311 returns a shape to which arg0 can be extendent from the right and arg1 can be extended from the left.
312
313 @param arg0: an object with a shape (see L{pokeShape})
314 @param arg1: an object with a shape (see L{pokeShape})
315 @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.
316 @rtype: C{tuple} of C{int}
317 @raise ValueError: if no shape can be found.
318 """
319 sh0=pokeShape(arg0)
320 sh1=pokeShape(arg1)
321 if len(sh0)<len(sh1):
322 if not sh0==sh1[:len(sh0)]:
323 raise ValueError,"argument 0 cannot be extended to the shape of argument 1"
324 return sh1
325 elif len(sh0)>len(sh1):
326 if not sh1==sh0[:len(sh1)]:
327 raise ValueError,"argument 1 cannot be extended to the shape of argument 0"
328 return sh0
329 else:
330 if not sh0==sh1:
331 raise ValueError,"argument 1 and argument 0 have not the same shape."
332 return sh0
333
334 def commonDim(*args):
335 """
336 identifies, if possible, the spatial dimension across a set of objects which may or my not have a spatial dimension.
337
338 @param *args: given objects
339 @return: the spatial dimension of the objects with identifiable dimension (see L{pokeDim}). If none the objects has
340 a spatial dimension C{None} is returned.
341 @rtype: C{int} or C{None}
342 @raise ValueError: if the objects with identifiable dimension don't have the same spatial dimension.
343 """
344 out=None
345 for a in args:
346 d=pokeDim(a)
347 if not out==None:
348 if not (d==None or out==d):
349 raise ValueError,"dimension of arguments don't match"
350 else:
351 out=d
352 return out
353
354 def testForZero(arg):
355 """
356 test the argument for being identical to Zero
357
358 @param arg: a given object
359 @type arg: typically L{numarray.NumArray},L{escript.Data},C{float}, C{int}
360 @return : True if the argument is identical to zero.
361 @rtype : C{bool}
362 """
363 if isinstance(arg,numarray.NumArray):
364 return not Lsup(arg)>0.
365 elif isinstance(arg,escript.Data):
366 return False
367 elif isinstance(arg,float):
368 return not Lsup(arg)>0.
369 elif isinstance(arg,int):
370 return not Lsup(arg)>0.
371 elif isinstance(arg,Symbol):
372 return False
373 else:
374 return False
375
376 def matchType(arg0=0.,arg1=0.):
377 """
378 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}.
379
380 @param arg0: first argument
381 @type arg0: L{numarray.NumArray},L{escript.Data},C{float}, C{int}, C{Symbol}
382 @param arg1: second argument
383 @type arg1: L{numarray.NumArray},L{escript.Data},C{float}, C{int}, C{Symbol}
384 @return: a tuple representing arg0 and arg1 with the same type or with one of them being a L{Symbol}
385 @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}.
386 @raise TypeError: if type of arg0 or arg1 cannot be processed
387 """
388 if isinstance(arg0,numarray.NumArray):
389 if isinstance(arg1,numarray.NumArray):
390 pass
391 elif isinstance(arg1,escript.Data):
392 arg0=escript.Data(arg0,arg1.getFunctionSpace())
393 elif isinstance(arg1,float):
394 arg1=numarray.array(arg1)
395 elif isinstance(arg1,int):
396 arg1=numarray.array(float(arg1))
397 elif isinstance(arg1,Symbol):
398 pass
399 else:
400 raise TypeError,"function: Unknown type of second argument."
401 elif isinstance(arg0,escript.Data):
402 if isinstance(arg1,numarray.NumArray):
403 arg1=escript.Data(arg1,arg0.getFunctionSpace())
404 elif isinstance(arg1,escript.Data):
405 pass
406 elif isinstance(arg1,float):
407 arg1=escript.Data(arg1,(),arg0.getFunctionSpace())
408 elif isinstance(arg1,int):
409 arg1=escript.Data(float(arg1),(),arg0.getFunctionSpace())
410 elif isinstance(arg1,Symbol):
411 pass
412 else:
413 raise TypeError,"function: Unknown type of second argument."
414 elif isinstance(arg0,Symbol):
415 if isinstance(arg1,numarray.NumArray):
416 pass
417 elif isinstance(arg1,escript.Data):
418 pass
419 elif isinstance(arg1,float):
420 arg1=numarray.array(arg1)
421 elif isinstance(arg1,int):
422 arg1=numarray.array(float(arg1))
423 elif isinstance(arg1,Symbol):
424 pass
425 else:
426 raise TypeError,"function: Unknown type of second argument."
427 elif isinstance(arg0,float):
428 if isinstance(arg1,numarray.NumArray):
429 arg0=numarray.array(arg0)
430 elif isinstance(arg1,escript.Data):
431 arg0=escript.Data(arg0,arg1.getFunctionSpace())
432 elif isinstance(arg1,float):
433 arg0=numarray.array(arg0)
434 arg1=numarray.array(arg1)
435 elif isinstance(arg1,int):
436 arg0=numarray.array(arg0)
437 arg1=numarray.array(float(arg1))
438 elif isinstance(arg1,Symbol):
439 arg0=numarray.array(arg0)
440 else:
441 raise TypeError,"function: Unknown type of second argument."
442 elif isinstance(arg0,int):
443 if isinstance(arg1,numarray.NumArray):
444 arg0=numarray.array(float(arg0))
445 elif isinstance(arg1,escript.Data):
446 arg0=escript.Data(float(arg0),arg1.getFunctionSpace())
447 elif isinstance(arg1,float):
448 arg0=numarray.array(float(arg0))
449 arg1=numarray.array(arg1)
450 elif isinstance(arg1,int):
451 arg0=numarray.array(float(arg0))
452 arg1=numarray.array(float(arg1))
453 elif isinstance(arg1,Symbol):
454 arg0=numarray.array(float(arg0))
455 else:
456 raise TypeError,"function: Unknown type of second argument."
457 else:
458 raise TypeError,"function: Unknown type of first argument."
459
460 return arg0,arg1
461
462 def matchShape(arg0,arg1):
463 """
464
465
466 If shape is not given the shape "largest" shape of args is used.
467
468 @param args: a given ob
469 @type arg: typically L{numarray.NumArray},L{escript.Data},C{float}, C{int}
470 @return: True if the argument is identical to zero.
471 @rtype: C{list} of C{int}
472 """
473 sh=commonShape(arg0,arg1)
474 sh0=pokeShape(arg0)
475 sh1=pokeShape(arg1)
476 if len(sh0)<len(sh):
477 return outer(arg0,numarray.ones(sh[len(sh0):],numarray.Float)),arg1
478 elif len(sh1)<len(sh):
479 return arg0,outer(arg1,numarray.ones(sh[len(sh1):],numarray.Float))
480 else:
481 return arg0,arg1
482 #=========================================================
483 # symbolic tool box starts here:
484 #=========================================================
485 class Symbol(object):
486 """
487 Symbol class.
488
489 Symbol class objects provide the same functionality as L{numarray.NumArray} and L{escript.Data} objects
490 but they do not have a value and therefore cannot be plotted or visualize. The main purpose is the possibilty
491 calculate derivatives with respect to other Symbols used to define a Symbol.
492
493 """
494 def __init__(self,shape=(),args=[],dim=None):
495 """
496 Creates an instance of a symbol of a given shape. The symbol may depending on a list of arguments args which may be
497 symbols or any other object.
498
499 @param arg: the arguments of the symbol.
500 @type arg: C{list}
501 @param shape: the shape
502 @type shape: C{tuple} of C{int}
503 @param dim: spatial dimension of the symbol. If dim=C{None} the spatial dimension is undefined.
504 @type dim: C{None} or C{int}
505
506 """
507 if len(shape)>4:
508 raise ValueError,"Symbol supports only tensors up to order 4"
509 self.__args=args
510 self.__shape=shape
511 self.__dim=dim
512
513 def getArgument(self,i=None):
514 """
515 returns the i-th argument of the symbol
516
517 @param i: index of the argument requested.
518 @type i: C{int} or C{None}
519 @raise IndexError: if the requested index does not exist
520 @return: the vlaue of the i-th argument or i is not specified the list of all arguments.
521 @rtype: a single object or a list of objects
522 """
523 if i==None:
524 return self.__args
525 else:
526 if i<0 or i>=len(self.__args):
527 raise IndexError,"there are only %s arguments"%len(self.__args)
528 return self.__args[i]
529
530 def getRank(self):
531 """
532 the rank of the symbol
533
534 @return: the rank of the symbol. This is length of the shape
535 @rtype: C{int}
536 """
537 return len(self.getShape())
538
539 def getShape(self):
540 """
541 the shape of the symbol.
542
543 @return : the shape of the symbol.
544 @rtype: C{tuple} of C{int}
545 """
546 return self.__shape
547
548 def getDim(self):
549 """
550 the spatial dimension
551
552 @return : the spatial dimension
553 @rtype: C{int} if the dimension is defined. Otherwise C{None} is returned.
554 """
555 return self.__dim
556
557 def __str__(self):
558 """
559 a string representation of the symbol.
560 @return: a string representation of the object
561 @rtype: C{str}
562 """
563 args=[]
564 for arg in self.getArgument():
565 args.append(str(arg))
566 try:
567 out=self.getMyCode(args,format="str")
568 except NotImplementedError:
569 out="<Symbol %s>"%id(self)
570 return out
571
572 def getSubstitutedArguments(self,argvals):
573 """
574 substitutes symbols in the arguments of this object and returns the result as a list.
575
576 @param argvals: L{Symbols} and their substitutes. The L{Symbol} u in the expression defining this object is replaced by argvals[u].
577 @type argvals: C{dict} with keywords of type L{Symbol}.
578 @rtype: C{list} of objects
579 @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.
580 """
581 out=[]
582 for a in self.getArgument():
583 if isinstance(a,Symbol):
584 out.append(a.substitute(argvals))
585 else:
586 out.append(a)
587 return out
588
589 def getDifferentiatedArguments(self,arg):
590 """
591 applifies differentials to the arguments of this object and returns the result as a list.
592
593 @param arg: the derivative is calculated with respect to arg
594 @type arg: typically L{escript.Symbol} but can also be C{float}, L{escript.Data}, L{numarray.NumArray} depending the involved functions and data.
595 @rtype: C{list} of objects
596 @return: list of object obtained by calculating the derivatives of the argumenst with respct to arg
597 """
598 out=[]
599 for a in self.getArgument():
600 if isinstance(a,Symbol):
601 out.append(a.substitute(argvals))
602 else:
603 s=pokeShape(s)+arg.getShape()
604 if len(s)>0:
605 out.append(numarray.zeros(s),numarray.Float)
606 else:
607 out.append(a)
608 return out
609
610 def isAppropriateValue(self,arg):
611 """
612 checks if the given argument arg can be used as a substitution of this object. The method checks
613 the shape of arg and, if the spatial dimension is defined, the spatial dimension of arg.
614
615 @param arg: a given object
616 @type arg: L{numarray.NumArray},L{escript.Data},C{float}, C{int}, C{Symbol}
617 @return: True if arg is a suitbale object to be used for substitution. Otherwise False is returned.
618 @rtype: C{bool}
619 """
620 if isinstance(arg,numarray.NumArray):
621 return arg.shape==self.getShape()
622 elif isinstance(arg,escript.Data):
623 if self.getDim()==None:
624 return arg.getShape()==self.getShape()
625 elif self.getDim()==arg.getFunctionSpace().getDim():
626 return arg.getShape()==self.getShape()
627 else:
628 return False
629 elif isinstance(arg,Symbol):
630 if self.getDim()==None:
631 return arg.getShape()==self.getShape()
632 elif self.getDim()==arg.getDim():
633 return arg.getShape()==self.getShape()
634 else:
635 return False
636 elif isinstance(arg,float):
637 return ()==self.getShape()
638 elif isinstance(arg,int):
639 return ()==self.getShape()
640 else:
641 return False
642
643 def getMyCode(self,argstrs,format="escript"):
644 """
645 returns a program code that can be used to evaluate the symbol.
646
647 @param argstrs: gives for each argument a string representing the argument for the evaluation.
648 @type argstrs: C{list} of C{str}.
649 @param format: specifies the format to be used. At the moment only "escript", "str" and "text" are supported.
650 @type format: C{str}
651 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
652 @rtype: C{str}
653 @raise NotImplementedError: if no implementation for the given format is available
654 @note: This method has to be overwritten by subclasses.
655 """
656 raise NotImplementedError,"no code for %s representation available"%format
657
658 def substitute(self,argvals):
659 """
660 assigns new values to symbols in the definition of the symbol.
661 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
662
663 @param argvals: new values assigned to symbols
664 @type argvals: C{dict} with keywords of type L{Symbol}.
665 @return: result of the substitution process. Operations are executed as much as possible.
666 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
667 @note: this method has to be overwritten by a particular L{Symbol}
668 @raise NotImplementedError: if no implementation for the given format is available
669 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
670 """
671 if argvals.has_key(self):
672 arg=argvals[self]
673 if self.isAppropriateValue(arg):
674 return arg
675 else:
676 raise TypeError,"Symbol: new value is not appropriate."
677 else:
678 raise NotImplementedError,"no substitution in %s avialable"%str(self)
679
680 def diff(self,arg):
681 """
682 returns the derivative of the symbol with respect to L{Symbol} arg
683
684 @param arg: the derivative is calculated with respect to arg
685 @type arg: typically L{escript.Symbol} but can also be C{float}, L{escript.Data}, L{numarray.NumArray} depending the involved functions and data.
686 @return: derivative with respect to C{arg}
687 @rtype: typically L{escript.Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
688 @note: this method is overwritten by a particular L{Symbol}
689 """
690 if arg==self:
691 return identity(self.getShape())
692 else:
693 s=self.getShape()+arg.getShape()
694 if len(s)>0:
695 return numarray.zeros(s,numarray.Float)
696 else:
697 return 0.
698
699 def __neg__(self):
700 """
701 returns -self.
702
703 @return: a S{Symbol} representing the negative of the object
704 @rtype: L{DependendSymbol}
705 """
706 return self*(-1.)
707
708 def __pos__(self):
709 """
710 returns +self.
711
712 @return: a S{Symbol} representing the positive of the object
713 @rtype: L{DependendSymbol}
714 """
715 return self*(1.)
716
717 def __abs__(self):
718 """
719 returns a S{Symbol} representing the absolute value of the object.
720 """
721 return Abs_Symbol(self)
722
723 def __add__(self,other):
724 """
725 add another object to this object
726
727 @param other: object to be added to this object
728 @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
729 @return: a S{Symbol} representing the sum of this object and C{other}
730 @rtype: L{DependendSymbol}
731 """
732 return add(self,other)
733
734 def __radd__(self,other):
735 """
736 add this object to another object
737
738 @param other: object this object is added to
739 @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
740 @return: a S{Symbol} representing the sum of C{other} and this object object
741 @rtype: L{DependendSymbol}
742 """
743 return add(other,self)
744
745 def __sub__(self,other):
746 """
747 subtracts another object from this object
748
749 @param other: object to be subtracted from this object
750 @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
751 @return: a S{Symbol} representing the difference of C{other} and this object
752 @rtype: L{DependendSymbol}
753 """
754 return add(self,-other)
755
756 def __rsub__(self,other):
757 """
758 subtracts this object from another object
759
760 @param other: object this object is been subtracted from
761 @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
762 @return: a S{Symbol} representing the difference of this object and C{other}.
763 @rtype: L{DependendSymbol}
764 """
765 return add(-self,other)
766
767 def __mul__(self,other):
768 """
769 multiplies this object with other object
770
771 @param other: object to be mutiplied by this object
772 @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
773 @return: a S{Symbol} representing the product of the object and C{other}.
774 @rtype: L{DependendSymbol} or 0 if other is identical to zero.
775 """
776 return mult(self,other)
777
778 def __rmul__(self,other):
779 """
780 multiplies this object with other object
781
782 @param other: object this object is multiplied with
783 @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
784 @return: a S{Symbol} representing the product of C{other} and the object.
785 @rtype: L{DependendSymbol} or 0 if other is identical to zero.
786 """
787 return mult(other,self)
788
789 def __div__(self,other):
790 """
791 divides this object by other object
792
793 @param other: object dividing this object
794 @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
795 @return: a S{Symbol} representing the quotient of this object and C{other}
796 @rtype: L{DependendSymbol}
797 """
798 return quotient(self,other)
799
800 def __rdiv__(self,other):
801 """
802 divides this object by other object
803
804 @param other: object dividing this object
805 @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
806 @return: a S{Symbol} representing the quotient of C{other} and this object
807 @rtype: L{DependendSymbol} or 0 if C{other} is identical to zero.
808 """
809 return quotient(other,self)
810
811 def __pow__(self,other):
812 """
813 raises this object to the power of other
814
815 @param other: exponent
816 @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
817 @return: a S{Symbol} representing the power of this object to C{other}
818 @rtype: L{DependendSymbol} or 1 if C{other} is identical to zero.
819 """
820 return power(self,other)
821
822 def __rpow__(self,other):
823 """
824 raises an object to the power of this object
825
826 @param other: basis
827 @type other: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
828 @return: a S{Symbol} representing the power of C{other} to this object
829 @rtype: L{DependendSymbol} or 0 if C{other} is identical to zero.
830 """
831 return power(other,self)
832
833 class DependendSymbol(Symbol):
834 """
835 DependendSymbol extents L{Symbol} by modifying the == operator to allow two instances to be equal.
836 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
837
838 Example:
839
840 u1=Symbol(shape=(3,4),dim=2,args=[4.])
841 u2=Symbol(shape=(3,4),dim=2,args=[4.])
842 print u1==u2
843 False
844
845 but
846
847 u1=DependendSymbol(shape=(3,4),dim=2,args=[4.])
848 u2=DependendSymbol(shape=(3,4),dim=2,args=[4.])
849 u3=DependendSymbol(shape=(2,),dim=2,args=[4.])
850 print u1==u2, u1==u3
851 True False
852
853 @note: DependendSymbol should be used as return value of functions with L{Symbol} arguments. This will allow the optimizer to remove redundant function calls.
854 """
855 def __eq__(self,other):
856 """
857 checks if other equals self
858
859 @param other: any object
860 @return: True if other has the same class like self, and the shape, the spatial diemsnion and the arguments are equal.
861 @rtype: C{bool}
862 """
863 if isinstance(other,DependendSymbol):
864 if self.__class__==other.__class__:
865 if self.getShape()==other.getShape():
866 if self.getArgument()==other.getArgument():
867 if self.getDim()==None or other.getDim()==None or self.getDim()==other.getDim():
868 return True
869 return False
870
871 def __ne__(self,other):
872 """
873 checks if other equals self
874
875 @param other: any object
876 @return: Flase if other has the same class like self, and the shape, the spatial diemsnion and the arguments are equal.
877 @rtype: C{bool}
878 """
879 return not self==other
880 #=========================================================
881 # Unary operations prserving the shape
882 #========================================================
883 def log10(arg):
884 """
885 returns base-10 logarithm of argument arg
886
887 @param arg: argument
888 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
889 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
890 @raises TypeError: if the type of the argument is not expected.
891 """
892 if isinstance(arg,numarray.NumArray):
893 return numarray.log10(arg)
894 elif isinstance(arg,escript.Data):
895 return arg._log10()
896 elif isinstance(arg,float):
897 return math.log10(arg)
898 elif isinstance(arg,int):
899 return math.log10(float(arg))
900 elif isinstance(arg,Symbol):
901 return log(arg)/log(10.)
902 else:
903 raise TypeError,"log10: Unknown argument type."
904
905 def wherePositive(arg):
906 """
907 returns mask of positive values of argument arg
908
909 @param arg: argument
910 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
911 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
912 @raises TypeError: if the type of the argument is not expected.
913 """
914 if isinstance(arg,numarray.NumArray):
915 out=numarray.greater(arg,numarray.zeros(arg.shape,numarray.Float))*1.
916 if isinstance(out,float): out=numarray.array(out)
917 return out
918 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 out=numarray.less(arg,numarray.zeros(arg.shape,numarray.Float))*1.
998 if isinstance(out,float): out=numarray.array(out)
999 return out
1000 elif isinstance(arg,escript.Data):
1001 return arg._whereNegative()
1002 elif isinstance(arg,float):
1003 if arg<0:
1004 return 1.
1005 else:
1006 return 0.
1007 elif isinstance(arg,int):
1008 if arg<0:
1009 return 1.
1010 else:
1011 return 0.
1012 elif isinstance(arg,Symbol):
1013 return WhereNegative_Symbol(arg)
1014 else:
1015 raise TypeError,"whereNegative: Unknown argument type."
1016
1017 class WhereNegative_Symbol(DependendSymbol):
1018 """
1019 L{Symbol} representing the result of the mask of positive values function
1020 """
1021 def __init__(self,arg):
1022 """
1023 initialization of whereNegative L{Symbol} with argument arg
1024 @param arg: argument of function
1025 @type arg: typically L{Symbol}.
1026 """
1027 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1028
1029 def getMyCode(self,argstrs,format="escript"):
1030 """
1031 returns a program code that can be used to evaluate the symbol.
1032
1033 @param argstrs: gives for each argument a string representing the argument for the evaluation.
1034 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1035 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1036 @type format: C{str}
1037 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1038 @rtype: C{str}
1039 @raise: NotImplementedError: if the requested format is not available
1040 """
1041 if isinstance(argstrs,list):
1042 argstrs=argstrs[0]
1043 if format=="escript" or format=="str" or format=="text":
1044 return "whereNegative(%s)"%argstrs
1045 else:
1046 raise NotImplementedError,"WhereNegative_Symbol does not provide program code for format %s."%format
1047
1048 def substitute(self,argvals):
1049 """
1050 assigns new values to symbols in the definition of the symbol.
1051 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1052
1053 @param argvals: new values assigned to symbols
1054 @type argvals: C{dict} with keywords of type L{Symbol}.
1055 @return: result of the substitution process. Operations are executed as much as possible.
1056 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1057 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1058 """
1059 if argvals.has_key(self):
1060 arg=argvals[self]
1061 if self.isAppropriateValue(arg):
1062 return arg
1063 else:
1064 raise TypeError,"%s: new value is not appropriate."%str(self)
1065 else:
1066 arg=self.getSubstitutedArguments(argvals)[0]
1067 return whereNegative(arg)
1068
1069 def whereNonNegative(arg):
1070 """
1071 returns mask of non-negative values of argument arg
1072
1073 @param arg: argument
1074 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1075 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1076 @raises TypeError: if the type of the argument is not expected.
1077 """
1078 if isinstance(arg,numarray.NumArray):
1079 out=numarray.greater_equal(arg,numarray.zeros(arg.shape,numarray.Float))*1.
1080 if isinstance(out,float): out=numarray.array(out)
1081 return out
1082 elif isinstance(arg,escript.Data):
1083 return arg._whereNonNegative()
1084 elif isinstance(arg,float):
1085 if arg<0:
1086 return 0.
1087 else:
1088 return 1.
1089 elif isinstance(arg,int):
1090 if arg<0:
1091 return 0.
1092 else:
1093 return 1.
1094 elif isinstance(arg,Symbol):
1095 return 1.-whereNegative(arg)
1096 else:
1097 raise TypeError,"whereNonNegative: Unknown argument type."
1098
1099 def whereNonPositive(arg):
1100 """
1101 returns mask of non-positive values of argument arg
1102
1103 @param arg: argument
1104 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1105 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1106 @raises TypeError: if the type of the argument is not expected.
1107 """
1108 if isinstance(arg,numarray.NumArray):
1109 out=numarray.less_equal(arg,numarray.zeros(arg.shape,numarray.Float))*1.
1110 if isinstance(out,float): out=numarray.array(out)
1111 return out
1112 elif isinstance(arg,escript.Data):
1113 return arg._whereNonPositive()
1114 elif isinstance(arg,float):
1115 if arg>0:
1116 return 0.
1117 else:
1118 return 1.
1119 elif isinstance(arg,int):
1120 if arg>0:
1121 return 0.
1122 else:
1123 return 1.
1124 elif isinstance(arg,Symbol):
1125 return 1.-wherePositive(arg)
1126 else:
1127 raise TypeError,"whereNonPositive: Unknown argument type."
1128
1129 def whereZero(arg,tol=0.):
1130 """
1131 returns mask of zero entries of argument arg
1132
1133 @param arg: argument
1134 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1135 @param tol: tolerance. values with absolute value less then tol are accepted as zero.
1136 @type tol: C{float}
1137 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1138 @raises TypeError: if the type of the argument is not expected.
1139 """
1140 if isinstance(arg,numarray.NumArray):
1141 out=numarray.less_equal(abs(arg)-tol,numarray.zeros(arg.shape,numarray.Float))*1.
1142 if isinstance(out,float): out=numarray.array(out)
1143 return out
1144 elif isinstance(arg,escript.Data):
1145 if tol>0.:
1146 return whereNegative(abs(arg)-tol)
1147 else:
1148 return arg._whereZero()
1149 elif isinstance(arg,float):
1150 if abs(arg)<=tol:
1151 return 1.
1152 else:
1153 return 0.
1154 elif isinstance(arg,int):
1155 if abs(float(arg))<=tol:
1156 return 1.
1157 else:
1158 return 0.
1159 elif isinstance(arg,Symbol):
1160 return WhereZero_Symbol(arg,tol)
1161 else:
1162 raise TypeError,"whereZero: Unknown argument type."
1163
1164 class WhereZero_Symbol(DependendSymbol):
1165 """
1166 L{Symbol} representing the result of the mask of zero entries function
1167 """
1168 def __init__(self,arg,tol=0.):
1169 """
1170 initialization of whereZero L{Symbol} with argument arg
1171 @param arg: argument of function
1172 @type arg: typically L{Symbol}.
1173 """
1174 DependendSymbol.__init__(self,args=[arg,tol],shape=arg.getShape(),dim=arg.getDim())
1175
1176 def getMyCode(self,argstrs,format="escript"):
1177 """
1178 returns a program code that can be used to evaluate the symbol.
1179
1180 @param argstrs: gives for each argument a string representing the argument for the evaluation.
1181 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1182 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1183 @type format: C{str}
1184 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1185 @rtype: C{str}
1186 @raise: NotImplementedError: if the requested format is not available
1187 """
1188 if format=="escript" or format=="str" or format=="text":
1189 return "whereZero(%s,tol=%s)"%(argstrs[0],argstrs[1])
1190 else:
1191 raise NotImplementedError,"WhereZero_Symbol does not provide program code for format %s."%format
1192
1193 def substitute(self,argvals):
1194 """
1195 assigns new values to symbols in the definition of the symbol.
1196 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1197
1198 @param argvals: new values assigned to symbols
1199 @type argvals: C{dict} with keywords of type L{Symbol}.
1200 @return: result of the substitution process. Operations are executed as much as possible.
1201 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1202 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1203 """
1204 if argvals.has_key(self):
1205 arg=argvals[self]
1206 if self.isAppropriateValue(arg):
1207 return arg
1208 else:
1209 raise TypeError,"%s: new value is not appropriate."%str(self)
1210 else:
1211 arg=self.getSubstitutedArguments(argvals)
1212 return whereZero(arg[0],arg[1])
1213
1214 def whereNonZero(arg,tol=0.):
1215 """
1216 returns mask of values different from zero of argument arg
1217
1218 @param arg: argument
1219 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1220 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1221 @raises TypeError: if the type of the argument is not expected.
1222 """
1223 if isinstance(arg,numarray.NumArray):
1224 out=numarray.greater(abs(arg)-tol,numarray.zeros(arg.shape,numarray.Float))*1.
1225 if isinstance(out,float): out=numarray.array(out)
1226 return out
1227 elif isinstance(arg,escript.Data):
1228 if tol>0.:
1229 return 1.-whereZero(arg,tol)
1230 else:
1231 return arg._whereNonZero()
1232 elif isinstance(arg,float):
1233 if abs(arg)>tol:
1234 return 1.
1235 else:
1236 return 0.
1237 elif isinstance(arg,int):
1238 if abs(float(arg))>tol:
1239 return 1.
1240 else:
1241 return 0.
1242 elif isinstance(arg,Symbol):
1243 return 1.-whereZero(arg,tol)
1244 else:
1245 raise TypeError,"whereNonZero: Unknown argument type."
1246
1247 def sin(arg):
1248 """
1249 returns sine of argument arg
1250
1251 @param arg: argument
1252 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1253 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1254 @raises TypeError: if the type of the argument is not expected.
1255 """
1256 if isinstance(arg,numarray.NumArray):
1257 return numarray.sin(arg)
1258 elif isinstance(arg,escript.Data):
1259 return arg._sin()
1260 elif isinstance(arg,float):
1261 return math.sin(arg)
1262 elif isinstance(arg,int):
1263 return math.sin(arg)
1264 elif isinstance(arg,Symbol):
1265 return Sin_Symbol(arg)
1266 else:
1267 raise TypeError,"sin: Unknown argument type."
1268
1269 class Sin_Symbol(DependendSymbol):
1270 """
1271 L{Symbol} representing the result of the sine function
1272 """
1273 def __init__(self,arg):
1274 """
1275 initialization of sin L{Symbol} with argument arg
1276 @param arg: argument of function
1277 @type arg: typically L{Symbol}.
1278 """
1279 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1280
1281 def getMyCode(self,argstrs,format="escript"):
1282 """
1283 returns a program code that can be used to evaluate the symbol.
1284
1285 @param argstrs: gives for each argument a string representing the argument for the evaluation.
1286 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1287 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1288 @type format: C{str}
1289 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1290 @rtype: C{str}
1291 @raise: NotImplementedError: if the requested format is not available
1292 """
1293 if isinstance(argstrs,list):
1294 argstrs=argstrs[0]
1295 if format=="escript" or format=="str" or format=="text":
1296 return "sin(%s)"%argstrs
1297 else:
1298 raise NotImplementedError,"Sin_Symbol does not provide program code for format %s."%format
1299
1300 def substitute(self,argvals):
1301 """
1302 assigns new values to symbols in the definition of the symbol.
1303 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1304
1305 @param argvals: new values assigned to symbols
1306 @type argvals: C{dict} with keywords of type L{Symbol}.
1307 @return: result of the substitution process. Operations are executed as much as possible.
1308 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1309 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1310 """
1311 if argvals.has_key(self):
1312 arg=argvals[self]
1313 if self.isAppropriateValue(arg):
1314 return arg
1315 else:
1316 raise TypeError,"%s: new value is not appropriate."%str(self)
1317 else:
1318 arg=self.getSubstitutedArguments(argvals)[0]
1319 return sin(arg)
1320
1321 def diff(self,arg):
1322 """
1323 differential of this object
1324
1325 @param arg: the derivative is calculated with respect to arg
1326 @type arg: L{escript.Symbol}
1327 @return: derivative with respect to C{arg}
1328 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1329 """
1330 if arg==self:
1331 return identity(self.getShape())
1332 else:
1333 myarg=self.getArgument()[0]
1334 val=matchShape(cos(myarg),self.getDifferentiatedArguments(arg)[0])
1335 return val[0]*val[1]
1336
1337 def cos(arg):
1338 """
1339 returns cosine of argument arg
1340
1341 @param arg: argument
1342 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1343 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1344 @raises TypeError: if the type of the argument is not expected.
1345 """
1346 if isinstance(arg,numarray.NumArray):
1347 return numarray.cos(arg)
1348 elif isinstance(arg,escript.Data):
1349 return arg._cos()
1350 elif isinstance(arg,float):
1351 return math.cos(arg)
1352 elif isinstance(arg,int):
1353 return math.cos(arg)
1354 elif isinstance(arg,Symbol):
1355 return Cos_Symbol(arg)
1356 else:
1357 raise TypeError,"cos: Unknown argument type."
1358
1359 class Cos_Symbol(DependendSymbol):
1360 """
1361 L{Symbol} representing the result of the cosine function
1362 """
1363 def __init__(self,arg):
1364 """
1365 initialization of cos L{Symbol} with argument arg
1366 @param arg: argument of function
1367 @type arg: typically L{Symbol}.
1368 """
1369 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1370
1371 def getMyCode(self,argstrs,format="escript"):
1372 """
1373 returns a program code that can be used to evaluate the symbol.
1374
1375 @param argstrs: gives for each argument a string representing the argument for the evaluation.
1376 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1377 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1378 @type format: C{str}
1379 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1380 @rtype: C{str}
1381 @raise: NotImplementedError: if the requested format is not available
1382 """
1383 if isinstance(argstrs,list):
1384 argstrs=argstrs[0]
1385 if format=="escript" or format=="str" or format=="text":
1386 return "cos(%s)"%argstrs
1387 else:
1388 raise NotImplementedError,"Cos_Symbol does not provide program code for format %s."%format
1389
1390 def substitute(self,argvals):
1391 """
1392 assigns new values to symbols in the definition of the symbol.
1393 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1394
1395 @param argvals: new values assigned to symbols
1396 @type argvals: C{dict} with keywords of type L{Symbol}.
1397 @return: result of the substitution process. Operations are executed as much as possible.
1398 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1399 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1400 """
1401 if argvals.has_key(self):
1402 arg=argvals[self]
1403 if self.isAppropriateValue(arg):
1404 return arg
1405 else:
1406 raise TypeError,"%s: new value is not appropriate."%str(self)
1407 else:
1408 arg=self.getSubstitutedArguments(argvals)[0]
1409 return cos(arg)
1410
1411 def diff(self,arg):
1412 """
1413 differential of this object
1414
1415 @param arg: the derivative is calculated with respect to arg
1416 @type arg: L{escript.Symbol}
1417 @return: derivative with respect to C{arg}
1418 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1419 """
1420 if arg==self:
1421 return identity(self.getShape())
1422 else:
1423 myarg=self.getArgument()[0]
1424 val=matchShape(-sin(myarg),self.getDifferentiatedArguments(arg)[0])
1425 return val[0]*val[1]
1426
1427 def tan(arg):
1428 """
1429 returns tangent of argument arg
1430
1431 @param arg: argument
1432 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1433 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1434 @raises TypeError: if the type of the argument is not expected.
1435 """
1436 if isinstance(arg,numarray.NumArray):
1437 return numarray.tan(arg)
1438 elif isinstance(arg,escript.Data):
1439 return arg._tan()
1440 elif isinstance(arg,float):
1441 return math.tan(arg)
1442 elif isinstance(arg,int):
1443 return math.tan(arg)
1444 elif isinstance(arg,Symbol):
1445 return Tan_Symbol(arg)
1446 else:
1447 raise TypeError,"tan: Unknown argument type."
1448
1449 class Tan_Symbol(DependendSymbol):
1450 """
1451 L{Symbol} representing the result of the tangent function
1452 """
1453 def __init__(self,arg):
1454 """
1455 initialization of tan L{Symbol} with argument arg
1456 @param arg: argument of function
1457 @type arg: typically L{Symbol}.
1458 """
1459 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1460
1461 def getMyCode(self,argstrs,format="escript"):
1462 """
1463 returns a program code that can be used to evaluate the symbol.
1464
1465 @param argstrs: gives for each argument a string representing the argument for the evaluation.
1466 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1467 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1468 @type format: C{str}
1469 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1470 @rtype: C{str}
1471 @raise: NotImplementedError: if the requested format is not available
1472 """
1473 if isinstance(argstrs,list):
1474 argstrs=argstrs[0]
1475 if format=="escript" or format=="str" or format=="text":
1476 return "tan(%s)"%argstrs
1477 else:
1478 raise NotImplementedError,"Tan_Symbol does not provide program code for format %s."%format
1479
1480 def substitute(self,argvals):
1481 """
1482 assigns new values to symbols in the definition of the symbol.
1483 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1484
1485 @param argvals: new values assigned to symbols
1486 @type argvals: C{dict} with keywords of type L{Symbol}.
1487 @return: result of the substitution process. Operations are executed as much as possible.
1488 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1489 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1490 """
1491 if argvals.has_key(self):
1492 arg=argvals[self]
1493 if self.isAppropriateValue(arg):
1494 return arg
1495 else:
1496 raise TypeError,"%s: new value is not appropriate."%str(self)
1497 else:
1498 arg=self.getSubstitutedArguments(argvals)[0]
1499 return tan(arg)
1500
1501 def diff(self,arg):
1502 """
1503 differential of this object
1504
1505 @param arg: the derivative is calculated with respect to arg
1506 @type arg: L{escript.Symbol}
1507 @return: derivative with respect to C{arg}
1508 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1509 """
1510 if arg==self:
1511 return identity(self.getShape())
1512 else:
1513 myarg=self.getArgument()[0]
1514 val=matchShape(1./cos(myarg)**2,self.getDifferentiatedArguments(arg)[0])
1515 return val[0]*val[1]
1516
1517 def asin(arg):
1518 """
1519 returns inverse sine of argument arg
1520
1521 @param arg: argument
1522 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1523 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1524 @raises TypeError: if the type of the argument is not expected.
1525 """
1526 if isinstance(arg,numarray.NumArray):
1527 return numarray.arcsin(arg)
1528 elif isinstance(arg,escript.Data):
1529 return arg._asin()
1530 elif isinstance(arg,float):
1531 return math.asin(arg)
1532 elif isinstance(arg,int):
1533 return math.asin(arg)
1534 elif isinstance(arg,Symbol):
1535 return Asin_Symbol(arg)
1536 else:
1537 raise TypeError,"asin: Unknown argument type."
1538
1539 class Asin_Symbol(DependendSymbol):
1540 """
1541 L{Symbol} representing the result of the inverse sine function
1542 """
1543 def __init__(self,arg):
1544 """
1545 initialization of asin L{Symbol} with argument arg
1546 @param arg: argument of function
1547 @type arg: typically L{Symbol}.
1548 """
1549 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1550
1551 def getMyCode(self,argstrs,format="escript"):
1552 """
1553 returns a program code that can be used to evaluate the symbol.
1554
1555 @param argstrs: gives for each argument a string representing the argument for the evaluation.
1556 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1557 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1558 @type format: C{str}
1559 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1560 @rtype: C{str}
1561 @raise: NotImplementedError: if the requested format is not available
1562 """
1563 if isinstance(argstrs,list):
1564 argstrs=argstrs[0]
1565 if format=="escript" or format=="str" or format=="text":
1566 return "asin(%s)"%argstrs
1567 else:
1568 raise NotImplementedError,"Asin_Symbol does not provide program code for format %s."%format
1569
1570 def substitute(self,argvals):
1571 """
1572 assigns new values to symbols in the definition of the symbol.
1573 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1574
1575 @param argvals: new values assigned to symbols
1576 @type argvals: C{dict} with keywords of type L{Symbol}.
1577 @return: result of the substitution process. Operations are executed as much as possible.
1578 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1579 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1580 """
1581 if argvals.has_key(self):
1582 arg=argvals[self]
1583 if self.isAppropriateValue(arg):
1584 return arg
1585 else:
1586 raise TypeError,"%s: new value is not appropriate."%str(self)
1587 else:
1588 arg=self.getSubstitutedArguments(argvals)[0]
1589 return asin(arg)
1590
1591 def diff(self,arg):
1592 """
1593 differential of this object
1594
1595 @param arg: the derivative is calculated with respect to arg
1596 @type arg: L{escript.Symbol}
1597 @return: derivative with respect to C{arg}
1598 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1599 """
1600 if arg==self:
1601 return identity(self.getShape())
1602 else:
1603 myarg=self.getArgument()[0]
1604 val=matchShape(1./sqrt(1.-myarg**2),self.getDifferentiatedArguments(arg)[0])
1605 return val[0]*val[1]
1606
1607 def acos(arg):
1608 """
1609 returns inverse cosine of argument arg
1610
1611 @param arg: argument
1612 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1613 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1614 @raises TypeError: if the type of the argument is not expected.
1615 """
1616 if isinstance(arg,numarray.NumArray):
1617 return numarray.arccos(arg)
1618 elif isinstance(arg,escript.Data):
1619 return arg._acos()
1620 elif isinstance(arg,float):
1621 return math.acos(arg)
1622 elif isinstance(arg,int):
1623 return math.acos(arg)
1624 elif isinstance(arg,Symbol):
1625 return Acos_Symbol(arg)
1626 else:
1627 raise TypeError,"acos: Unknown argument type."
1628
1629 class Acos_Symbol(DependendSymbol):
1630 """
1631 L{Symbol} representing the result of the inverse cosine function
1632 """
1633 def __init__(self,arg):
1634 """
1635 initialization of acos L{Symbol} with argument arg
1636 @param arg: argument of function
1637 @type arg: typically L{Symbol}.
1638 """
1639 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1640
1641 def getMyCode(self,argstrs,format="escript"):
1642 """
1643 returns a program code that can be used to evaluate the symbol.
1644
1645 @param argstrs: gives for each argument a string representing the argument for the evaluation.
1646 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1647 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1648 @type format: C{str}
1649 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1650 @rtype: C{str}
1651 @raise: NotImplementedError: if the requested format is not available
1652 """
1653 if isinstance(argstrs,list):
1654 argstrs=argstrs[0]
1655 if format=="escript" or format=="str" or format=="text":
1656 return "acos(%s)"%argstrs
1657 else:
1658 raise NotImplementedError,"Acos_Symbol does not provide program code for format %s."%format
1659
1660 def substitute(self,argvals):
1661 """
1662 assigns new values to symbols in the definition of the symbol.
1663 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1664
1665 @param argvals: new values assigned to symbols
1666 @type argvals: C{dict} with keywords of type L{Symbol}.
1667 @return: result of the substitution process. Operations are executed as much as possible.
1668 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1669 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1670 """
1671 if argvals.has_key(self):
1672 arg=argvals[self]
1673 if self.isAppropriateValue(arg):
1674 return arg
1675 else:
1676 raise TypeError,"%s: new value is not appropriate."%str(self)
1677 else:
1678 arg=self.getSubstitutedArguments(argvals)[0]
1679 return acos(arg)
1680
1681 def diff(self,arg):
1682 """
1683 differential of this object
1684
1685 @param arg: the derivative is calculated with respect to arg
1686 @type arg: L{escript.Symbol}
1687 @return: derivative with respect to C{arg}
1688 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1689 """
1690 if arg==self:
1691 return identity(self.getShape())
1692 else:
1693 myarg=self.getArgument()[0]
1694 val=matchShape(-1./sqrt(1.-myarg**2),self.getDifferentiatedArguments(arg)[0])
1695 return val[0]*val[1]
1696
1697 def atan(arg):
1698 """
1699 returns inverse tangent of argument arg
1700
1701 @param arg: argument
1702 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1703 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1704 @raises TypeError: if the type of the argument is not expected.
1705 """
1706 if isinstance(arg,numarray.NumArray):
1707 return numarray.arctan(arg)
1708 elif isinstance(arg,escript.Data):
1709 return arg._atan()
1710 elif isinstance(arg,float):
1711 return math.atan(arg)
1712 elif isinstance(arg,int):
1713 return math.atan(arg)
1714 elif isinstance(arg,Symbol):
1715 return Atan_Symbol(arg)
1716 else:
1717 raise TypeError,"atan: Unknown argument type."
1718
1719 class Atan_Symbol(DependendSymbol):
1720 """
1721 L{Symbol} representing the result of the inverse tangent function
1722 """
1723 def __init__(self,arg):
1724 """
1725 initialization of atan L{Symbol} with argument arg
1726 @param arg: argument of function
1727 @type arg: typically L{Symbol}.
1728 """
1729 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1730
1731 def getMyCode(self,argstrs,format="escript"):
1732 """
1733 returns a program code that can be used to evaluate the symbol.
1734
1735 @param argstrs: gives for each argument a string representing the argument for the evaluation.
1736 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1737 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1738 @type format: C{str}
1739 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1740 @rtype: C{str}
1741 @raise: NotImplementedError: if the requested format is not available
1742 """
1743 if isinstance(argstrs,list):
1744 argstrs=argstrs[0]
1745 if format=="escript" or format=="str" or format=="text":
1746 return "atan(%s)"%argstrs
1747 else:
1748 raise NotImplementedError,"Atan_Symbol does not provide program code for format %s."%format
1749
1750 def substitute(self,argvals):
1751 """
1752 assigns new values to symbols in the definition of the symbol.
1753 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1754
1755 @param argvals: new values assigned to symbols
1756 @type argvals: C{dict} with keywords of type L{Symbol}.
1757 @return: result of the substitution process. Operations are executed as much as possible.
1758 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1759 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1760 """
1761 if argvals.has_key(self):
1762 arg=argvals[self]
1763 if self.isAppropriateValue(arg):
1764 return arg
1765 else:
1766 raise TypeError,"%s: new value is not appropriate."%str(self)
1767 else:
1768 arg=self.getSubstitutedArguments(argvals)[0]
1769 return atan(arg)
1770
1771 def diff(self,arg):
1772 """
1773 differential of this object
1774
1775 @param arg: the derivative is calculated with respect to arg
1776 @type arg: L{escript.Symbol}
1777 @return: derivative with respect to C{arg}
1778 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1779 """
1780 if arg==self:
1781 return identity(self.getShape())
1782 else:
1783 myarg=self.getArgument()[0]
1784 val=matchShape(1./(1+myarg**2),self.getDifferentiatedArguments(arg)[0])
1785 return val[0]*val[1]
1786
1787 def sinh(arg):
1788 """
1789 returns hyperbolic sine of argument arg
1790
1791 @param arg: argument
1792 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1793 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1794 @raises TypeError: if the type of the argument is not expected.
1795 """
1796 if isinstance(arg,numarray.NumArray):
1797 return numarray.sinh(arg)
1798 elif isinstance(arg,escript.Data):
1799 return arg._sinh()
1800 elif isinstance(arg,float):
1801 return math.sinh(arg)
1802 elif isinstance(arg,int):
1803 return math.sinh(arg)
1804 elif isinstance(arg,Symbol):
1805 return Sinh_Symbol(arg)
1806 else:
1807 raise TypeError,"sinh: Unknown argument type."
1808
1809 class Sinh_Symbol(DependendSymbol):
1810 """
1811 L{Symbol} representing the result of the hyperbolic sine function
1812 """
1813 def __init__(self,arg):
1814 """
1815 initialization of sinh L{Symbol} with argument arg
1816 @param arg: argument of function
1817 @type arg: typically L{Symbol}.
1818 """
1819 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1820
1821 def getMyCode(self,argstrs,format="escript"):
1822 """
1823 returns a program code that can be used to evaluate the symbol.
1824
1825 @param argstrs: gives for each argument a string representing the argument for the evaluation.
1826 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1827 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1828 @type format: C{str}
1829 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1830 @rtype: C{str}
1831 @raise: NotImplementedError: if the requested format is not available
1832 """
1833 if isinstance(argstrs,list):
1834 argstrs=argstrs[0]
1835 if format=="escript" or format=="str" or format=="text":
1836 return "sinh(%s)"%argstrs
1837 else:
1838 raise NotImplementedError,"Sinh_Symbol does not provide program code for format %s."%format
1839
1840 def substitute(self,argvals):
1841 """
1842 assigns new values to symbols in the definition of the symbol.
1843 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1844
1845 @param argvals: new values assigned to symbols
1846 @type argvals: C{dict} with keywords of type L{Symbol}.
1847 @return: result of the substitution process. Operations are executed as much as possible.
1848 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1849 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1850 """
1851 if argvals.has_key(self):
1852 arg=argvals[self]
1853 if self.isAppropriateValue(arg):
1854 return arg
1855 else:
1856 raise TypeError,"%s: new value is not appropriate."%str(self)
1857 else:
1858 arg=self.getSubstitutedArguments(argvals)[0]
1859 return sinh(arg)
1860
1861 def diff(self,arg):
1862 """
1863 differential of this object
1864
1865 @param arg: the derivative is calculated with respect to arg
1866 @type arg: L{escript.Symbol}
1867 @return: derivative with respect to C{arg}
1868 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1869 """
1870 if arg==self:
1871 return identity(self.getShape())
1872 else:
1873 myarg=self.getArgument()[0]
1874 val=matchShape(cosh(myarg),self.getDifferentiatedArguments(arg)[0])
1875 return val[0]*val[1]
1876
1877 def cosh(arg):
1878 """
1879 returns hyperbolic cosine of argument arg
1880
1881 @param arg: argument
1882 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1883 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1884 @raises TypeError: if the type of the argument is not expected.
1885 """
1886 if isinstance(arg,numarray.NumArray):
1887 return numarray.cosh(arg)
1888 elif isinstance(arg,escript.Data):
1889 return arg._cosh()
1890 elif isinstance(arg,float):
1891 return math.cosh(arg)
1892 elif isinstance(arg,int):
1893 return math.cosh(arg)
1894 elif isinstance(arg,Symbol):
1895 return Cosh_Symbol(arg)
1896 else:
1897 raise TypeError,"cosh: Unknown argument type."
1898
1899 class Cosh_Symbol(DependendSymbol):
1900 """
1901 L{Symbol} representing the result of the hyperbolic cosine function
1902 """
1903 def __init__(self,arg):
1904 """
1905 initialization of cosh L{Symbol} with argument arg
1906 @param arg: argument of function
1907 @type arg: typically L{Symbol}.
1908 """
1909 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
1910
1911 def getMyCode(self,argstrs,format="escript"):
1912 """
1913 returns a program code that can be used to evaluate the symbol.
1914
1915 @param argstrs: gives for each argument a string representing the argument for the evaluation.
1916 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
1917 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
1918 @type format: C{str}
1919 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
1920 @rtype: C{str}
1921 @raise: NotImplementedError: if the requested format is not available
1922 """
1923 if isinstance(argstrs,list):
1924 argstrs=argstrs[0]
1925 if format=="escript" or format=="str" or format=="text":
1926 return "cosh(%s)"%argstrs
1927 else:
1928 raise NotImplementedError,"Cosh_Symbol does not provide program code for format %s."%format
1929
1930 def substitute(self,argvals):
1931 """
1932 assigns new values to symbols in the definition of the symbol.
1933 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
1934
1935 @param argvals: new values assigned to symbols
1936 @type argvals: C{dict} with keywords of type L{Symbol}.
1937 @return: result of the substitution process. Operations are executed as much as possible.
1938 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
1939 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
1940 """
1941 if argvals.has_key(self):
1942 arg=argvals[self]
1943 if self.isAppropriateValue(arg):
1944 return arg
1945 else:
1946 raise TypeError,"%s: new value is not appropriate."%str(self)
1947 else:
1948 arg=self.getSubstitutedArguments(argvals)[0]
1949 return cosh(arg)
1950
1951 def diff(self,arg):
1952 """
1953 differential of this object
1954
1955 @param arg: the derivative is calculated with respect to arg
1956 @type arg: L{escript.Symbol}
1957 @return: derivative with respect to C{arg}
1958 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
1959 """
1960 if arg==self:
1961 return identity(self.getShape())
1962 else:
1963 myarg=self.getArgument()[0]
1964 val=matchShape(sinh(myarg),self.getDifferentiatedArguments(arg)[0])
1965 return val[0]*val[1]
1966
1967 def tanh(arg):
1968 """
1969 returns hyperbolic tangent of argument arg
1970
1971 @param arg: argument
1972 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
1973 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
1974 @raises TypeError: if the type of the argument is not expected.
1975 """
1976 if isinstance(arg,numarray.NumArray):
1977 return numarray.tanh(arg)
1978 elif isinstance(arg,escript.Data):
1979 return arg._tanh()
1980 elif isinstance(arg,float):
1981 return math.tanh(arg)
1982 elif isinstance(arg,int):
1983 return math.tanh(arg)
1984 elif isinstance(arg,Symbol):
1985 return Tanh_Symbol(arg)
1986 else:
1987 raise TypeError,"tanh: Unknown argument type."
1988
1989 class Tanh_Symbol(DependendSymbol):
1990 """
1991 L{Symbol} representing the result of the hyperbolic tangent function
1992 """
1993 def __init__(self,arg):
1994 """
1995 initialization of tanh L{Symbol} with argument arg
1996 @param arg: argument of function
1997 @type arg: typically L{Symbol}.
1998 """
1999 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2000
2001 def getMyCode(self,argstrs,format="escript"):
2002 """
2003 returns a program code that can be used to evaluate the symbol.
2004
2005 @param argstrs: gives for each argument a string representing the argument for the evaluation.
2006 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2007 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2008 @type format: C{str}
2009 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2010 @rtype: C{str}
2011 @raise: NotImplementedError: if the requested format is not available
2012 """
2013 if isinstance(argstrs,list):
2014 argstrs=argstrs[0]
2015 if format=="escript" or format=="str" or format=="text":
2016 return "tanh(%s)"%argstrs
2017 else:
2018 raise NotImplementedError,"Tanh_Symbol does not provide program code for format %s."%format
2019
2020 def substitute(self,argvals):
2021 """
2022 assigns new values to symbols in the definition of the symbol.
2023 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2024
2025 @param argvals: new values assigned to symbols
2026 @type argvals: C{dict} with keywords of type L{Symbol}.
2027 @return: result of the substitution process. Operations are executed as much as possible.
2028 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2029 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2030 """
2031 if argvals.has_key(self):
2032 arg=argvals[self]
2033 if self.isAppropriateValue(arg):
2034 return arg
2035 else:
2036 raise TypeError,"%s: new value is not appropriate."%str(self)
2037 else:
2038 arg=self.getSubstitutedArguments(argvals)[0]
2039 return tanh(arg)
2040
2041 def diff(self,arg):
2042 """
2043 differential of this object
2044
2045 @param arg: the derivative is calculated with respect to arg
2046 @type arg: L{escript.Symbol}
2047 @return: derivative with respect to C{arg}
2048 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2049 """
2050 if arg==self:
2051 return identity(self.getShape())
2052 else:
2053 myarg=self.getArgument()[0]
2054 val=matchShape(1./cosh(myarg)**2,self.getDifferentiatedArguments(arg)[0])
2055 return val[0]*val[1]
2056
2057 def asinh(arg):
2058 """
2059 returns inverse hyperbolic sine of argument arg
2060
2061 @param arg: argument
2062 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2063 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2064 @raises TypeError: if the type of the argument is not expected.
2065 """
2066 if isinstance(arg,numarray.NumArray):
2067 return numarray.arcsinh(arg)
2068 elif isinstance(arg,escript.Data):
2069 return arg._asinh()
2070 elif isinstance(arg,float):
2071 return numarray.arcsinh(arg)
2072 elif isinstance(arg,int):
2073 return numarray.arcsinh(float(arg))
2074 elif isinstance(arg,Symbol):
2075 return Asinh_Symbol(arg)
2076 else:
2077 raise TypeError,"asinh: Unknown argument type."
2078
2079 class Asinh_Symbol(DependendSymbol):
2080 """
2081 L{Symbol} representing the result of the inverse hyperbolic sine function
2082 """
2083 def __init__(self,arg):
2084 """
2085 initialization of asinh L{Symbol} with argument arg
2086 @param arg: argument of function
2087 @type arg: typically L{Symbol}.
2088 """
2089 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2090
2091 def getMyCode(self,argstrs,format="escript"):
2092 """
2093 returns a program code that can be used to evaluate the symbol.
2094
2095 @param argstrs: gives for each argument a string representing the argument for the evaluation.
2096 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2097 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2098 @type format: C{str}
2099 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2100 @rtype: C{str}
2101 @raise: NotImplementedError: if the requested format is not available
2102 """
2103 if isinstance(argstrs,list):
2104 argstrs=argstrs[0]
2105 if format=="escript" or format=="str" or format=="text":
2106 return "asinh(%s)"%argstrs
2107 else:
2108 raise NotImplementedError,"Asinh_Symbol does not provide program code for format %s."%format
2109
2110 def substitute(self,argvals):
2111 """
2112 assigns new values to symbols in the definition of the symbol.
2113 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2114
2115 @param argvals: new values assigned to symbols
2116 @type argvals: C{dict} with keywords of type L{Symbol}.
2117 @return: result of the substitution process. Operations are executed as much as possible.
2118 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2119 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2120 """
2121 if argvals.has_key(self):
2122 arg=argvals[self]
2123 if self.isAppropriateValue(arg):
2124 return arg
2125 else:
2126 raise TypeError,"%s: new value is not appropriate."%str(self)
2127 else:
2128 arg=self.getSubstitutedArguments(argvals)[0]
2129 return asinh(arg)
2130
2131 def diff(self,arg):
2132 """
2133 differential of this object
2134
2135 @param arg: the derivative is calculated with respect to arg
2136 @type arg: L{escript.Symbol}
2137 @return: derivative with respect to C{arg}
2138 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2139 """
2140 if arg==self:
2141 return identity(self.getShape())
2142 else:
2143 myarg=self.getArgument()[0]
2144 val=matchShape(1./sqrt(myarg**2+1),self.getDifferentiatedArguments(arg)[0])
2145 return val[0]*val[1]
2146
2147 def acosh(arg):
2148 """
2149 returns inverse hyperolic cosine of argument arg
2150
2151 @param arg: argument
2152 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2153 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2154 @raises TypeError: if the type of the argument is not expected.
2155 """
2156 if isinstance(arg,numarray.NumArray):
2157 return numarray.arccosh(arg)
2158 elif isinstance(arg,escript.Data):
2159 return arg._acosh()
2160 elif isinstance(arg,float):
2161 return numarray.arccosh(arg)
2162 elif isinstance(arg,int):
2163 return numarray.arccosh(float(arg))
2164 elif isinstance(arg,Symbol):
2165 return Acosh_Symbol(arg)
2166 else:
2167 raise TypeError,"acosh: Unknown argument type."
2168
2169 class Acosh_Symbol(DependendSymbol):
2170 """
2171 L{Symbol} representing the result of the inverse hyperolic cosine function
2172 """
2173 def __init__(self,arg):
2174 """
2175 initialization of acosh L{Symbol} with argument arg
2176 @param arg: argument of function
2177 @type arg: typically L{Symbol}.
2178 """
2179 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2180
2181 def getMyCode(self,argstrs,format="escript"):
2182 """
2183 returns a program code that can be used to evaluate the symbol.
2184
2185 @param argstrs: gives for each argument a string representing the argument for the evaluation.
2186 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2187 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2188 @type format: C{str}
2189 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2190 @rtype: C{str}
2191 @raise: NotImplementedError: if the requested format is not available
2192 """
2193 if isinstance(argstrs,list):
2194 argstrs=argstrs[0]
2195 if format=="escript" or format=="str" or format=="text":
2196 return "acosh(%s)"%argstrs
2197 else:
2198 raise NotImplementedError,"Acosh_Symbol does not provide program code for format %s."%format
2199
2200 def substitute(self,argvals):
2201 """
2202 assigns new values to symbols in the definition of the symbol.
2203 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2204
2205 @param argvals: new values assigned to symbols
2206 @type argvals: C{dict} with keywords of type L{Symbol}.
2207 @return: result of the substitution process. Operations are executed as much as possible.
2208 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2209 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2210 """
2211 if argvals.has_key(self):
2212 arg=argvals[self]
2213 if self.isAppropriateValue(arg):
2214 return arg
2215 else:
2216 raise TypeError,"%s: new value is not appropriate."%str(self)
2217 else:
2218 arg=self.getSubstitutedArguments(argvals)[0]
2219 return acosh(arg)
2220
2221 def diff(self,arg):
2222 """
2223 differential of this object
2224
2225 @param arg: the derivative is calculated with respect to arg
2226 @type arg: L{escript.Symbol}
2227 @return: derivative with respect to C{arg}
2228 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2229 """
2230 if arg==self:
2231 return identity(self.getShape())
2232 else:
2233 myarg=self.getArgument()[0]
2234 val=matchShape(1./sqrt(myarg**2-1),self.getDifferentiatedArguments(arg)[0])
2235 return val[0]*val[1]
2236
2237 def atanh(arg):
2238 """
2239 returns inverse hyperbolic tangent of argument arg
2240
2241 @param arg: argument
2242 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2243 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2244 @raises TypeError: if the type of the argument is not expected.
2245 """
2246 if isinstance(arg,numarray.NumArray):
2247 return numarray.arctanh(arg)
2248 elif isinstance(arg,escript.Data):
2249 return arg._atanh()
2250 elif isinstance(arg,float):
2251 return numarray.arctanh(arg)
2252 elif isinstance(arg,int):
2253 return numarray.arctanh(float(arg))
2254 elif isinstance(arg,Symbol):
2255 return Atanh_Symbol(arg)
2256 else:
2257 raise TypeError,"atanh: Unknown argument type."
2258
2259 class Atanh_Symbol(DependendSymbol):
2260 """
2261 L{Symbol} representing the result of the inverse hyperbolic tangent function
2262 """
2263 def __init__(self,arg):
2264 """
2265 initialization of atanh L{Symbol} with argument arg
2266 @param arg: argument of function
2267 @type arg: typically L{Symbol}.
2268 """
2269 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2270
2271 def getMyCode(self,argstrs,format="escript"):
2272 """
2273 returns a program code that can be used to evaluate the symbol.
2274
2275 @param argstrs: gives for each argument a string representing the argument for the evaluation.
2276 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2277 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2278 @type format: C{str}
2279 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2280 @rtype: C{str}
2281 @raise: NotImplementedError: if the requested format is not available
2282 """
2283 if isinstance(argstrs,list):
2284 argstrs=argstrs[0]
2285 if format=="escript" or format=="str" or format=="text":
2286 return "atanh(%s)"%argstrs
2287 else:
2288 raise NotImplementedError,"Atanh_Symbol does not provide program code for format %s."%format
2289
2290 def substitute(self,argvals):
2291 """
2292 assigns new values to symbols in the definition of the symbol.
2293 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2294
2295 @param argvals: new values assigned to symbols
2296 @type argvals: C{dict} with keywords of type L{Symbol}.
2297 @return: result of the substitution process. Operations are executed as much as possible.
2298 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2299 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2300 """
2301 if argvals.has_key(self):
2302 arg=argvals[self]
2303 if self.isAppropriateValue(arg):
2304 return arg
2305 else:
2306 raise TypeError,"%s: new value is not appropriate."%str(self)
2307 else:
2308 arg=self.getSubstitutedArguments(argvals)[0]
2309 return atanh(arg)
2310
2311 def diff(self,arg):
2312 """
2313 differential of this object
2314
2315 @param arg: the derivative is calculated with respect to arg
2316 @type arg: L{escript.Symbol}
2317 @return: derivative with respect to C{arg}
2318 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2319 """
2320 if arg==self:
2321 return identity(self.getShape())
2322 else:
2323 myarg=self.getArgument()[0]
2324 val=matchShape(1./(1.-myarg**2),self.getDifferentiatedArguments(arg)[0])
2325 return val[0]*val[1]
2326
2327 def exp(arg):
2328 """
2329 returns exponential of argument arg
2330
2331 @param arg: argument
2332 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2333 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2334 @raises TypeError: if the type of the argument is not expected.
2335 """
2336 if isinstance(arg,numarray.NumArray):
2337 return numarray.exp(arg)
2338 elif isinstance(arg,escript.Data):
2339 return arg._exp()
2340 elif isinstance(arg,float):
2341 return math.exp(arg)
2342 elif isinstance(arg,int):
2343 return math.exp(arg)
2344 elif isinstance(arg,Symbol):
2345 return Exp_Symbol(arg)
2346 else:
2347 raise TypeError,"exp: Unknown argument type."
2348
2349 class Exp_Symbol(DependendSymbol):
2350 """
2351 L{Symbol} representing the result of the exponential function
2352 """
2353 def __init__(self,arg):
2354 """
2355 initialization of exp L{Symbol} with argument arg
2356 @param arg: argument of function
2357 @type arg: typically L{Symbol}.
2358 """
2359 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2360
2361 def getMyCode(self,argstrs,format="escript"):
2362 """
2363 returns a program code that can be used to evaluate the symbol.
2364
2365 @param argstrs: gives for each argument a string representing the argument for the evaluation.
2366 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2367 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2368 @type format: C{str}
2369 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2370 @rtype: C{str}
2371 @raise: NotImplementedError: if the requested format is not available
2372 """
2373 if isinstance(argstrs,list):
2374 argstrs=argstrs[0]
2375 if format=="escript" or format=="str" or format=="text":
2376 return "exp(%s)"%argstrs
2377 else:
2378 raise NotImplementedError,"Exp_Symbol does not provide program code for format %s."%format
2379
2380 def substitute(self,argvals):
2381 """
2382 assigns new values to symbols in the definition of the symbol.
2383 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2384
2385 @param argvals: new values assigned to symbols
2386 @type argvals: C{dict} with keywords of type L{Symbol}.
2387 @return: result of the substitution process. Operations are executed as much as possible.
2388 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2389 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2390 """
2391 if argvals.has_key(self):
2392 arg=argvals[self]
2393 if self.isAppropriateValue(arg):
2394 return arg
2395 else:
2396 raise TypeError,"%s: new value is not appropriate."%str(self)
2397 else:
2398 arg=self.getSubstitutedArguments(argvals)[0]
2399 return exp(arg)
2400
2401 def diff(self,arg):
2402 """
2403 differential of this object
2404
2405 @param arg: the derivative is calculated with respect to arg
2406 @type arg: L{escript.Symbol}
2407 @return: derivative with respect to C{arg}
2408 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2409 """
2410 if arg==self:
2411 return identity(self.getShape())
2412 else:
2413 myarg=self.getArgument()[0]
2414 val=matchShape(self,self.getDifferentiatedArguments(arg)[0])
2415 return val[0]*val[1]
2416
2417 def sqrt(arg):
2418 """
2419 returns square root of argument arg
2420
2421 @param arg: argument
2422 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2423 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2424 @raises TypeError: if the type of the argument is not expected.
2425 """
2426 if isinstance(arg,numarray.NumArray):
2427 return numarray.sqrt(arg)
2428 elif isinstance(arg,escript.Data):
2429 return arg._sqrt()
2430 elif isinstance(arg,float):
2431 return math.sqrt(arg)
2432 elif isinstance(arg,int):
2433 return math.sqrt(arg)
2434 elif isinstance(arg,Symbol):
2435 return Sqrt_Symbol(arg)
2436 else:
2437 raise TypeError,"sqrt: Unknown argument type."
2438
2439 class Sqrt_Symbol(DependendSymbol):
2440 """
2441 L{Symbol} representing the result of the square root function
2442 """
2443 def __init__(self,arg):
2444 """
2445 initialization of sqrt L{Symbol} with argument arg
2446 @param arg: argument of function
2447 @type arg: typically L{Symbol}.
2448 """
2449 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2450
2451 def getMyCode(self,argstrs,format="escript"):
2452 """
2453 returns a program code that can be used to evaluate the symbol.
2454
2455 @param argstrs: gives for each argument a string representing the argument for the evaluation.
2456 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2457 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2458 @type format: C{str}
2459 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2460 @rtype: C{str}
2461 @raise: NotImplementedError: if the requested format is not available
2462 """
2463 if isinstance(argstrs,list):
2464 argstrs=argstrs[0]
2465 if format=="escript" or format=="str" or format=="text":
2466 return "sqrt(%s)"%argstrs
2467 else:
2468 raise NotImplementedError,"Sqrt_Symbol does not provide program code for format %s."%format
2469
2470 def substitute(self,argvals):
2471 """
2472 assigns new values to symbols in the definition of the symbol.
2473 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2474
2475 @param argvals: new values assigned to symbols
2476 @type argvals: C{dict} with keywords of type L{Symbol}.
2477 @return: result of the substitution process. Operations are executed as much as possible.
2478 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2479 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2480 """
2481 if argvals.has_key(self):
2482 arg=argvals[self]
2483 if self.isAppropriateValue(arg):
2484 return arg
2485 else:
2486 raise TypeError,"%s: new value is not appropriate."%str(self)
2487 else:
2488 arg=self.getSubstitutedArguments(argvals)[0]
2489 return sqrt(arg)
2490
2491 def diff(self,arg):
2492 """
2493 differential of this object
2494
2495 @param arg: the derivative is calculated with respect to arg
2496 @type arg: L{escript.Symbol}
2497 @return: derivative with respect to C{arg}
2498 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2499 """
2500 if arg==self:
2501 return identity(self.getShape())
2502 else:
2503 myarg=self.getArgument()[0]
2504 val=matchShape(0.5/self,self.getDifferentiatedArguments(arg)[0])
2505 return val[0]*val[1]
2506
2507 def log(arg):
2508 """
2509 returns natural logarithm of argument arg
2510
2511 @param arg: argument
2512 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2513 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2514 @raises TypeError: if the type of the argument is not expected.
2515 """
2516 if isinstance(arg,numarray.NumArray):
2517 return numarray.log(arg)
2518 elif isinstance(arg,escript.Data):
2519 return arg._log()
2520 elif isinstance(arg,float):
2521 return math.log(arg)
2522 elif isinstance(arg,int):
2523 return math.log(arg)
2524 elif isinstance(arg,Symbol):
2525 return Log_Symbol(arg)
2526 else:
2527 raise TypeError,"log: Unknown argument type."
2528
2529 class Log_Symbol(DependendSymbol):
2530 """
2531 L{Symbol} representing the result of the natural logarithm function
2532 """
2533 def __init__(self,arg):
2534 """
2535 initialization of log L{Symbol} with argument arg
2536 @param arg: argument of function
2537 @type arg: typically L{Symbol}.
2538 """
2539 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2540
2541 def getMyCode(self,argstrs,format="escript"):
2542 """
2543 returns a program code that can be used to evaluate the symbol.
2544
2545 @param argstrs: gives for each argument a string representing the argument for the evaluation.
2546 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2547 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2548 @type format: C{str}
2549 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2550 @rtype: C{str}
2551 @raise: NotImplementedError: if the requested format is not available
2552 """
2553 if isinstance(argstrs,list):
2554 argstrs=argstrs[0]
2555 if format=="escript" or format=="str" or format=="text":
2556 return "log(%s)"%argstrs
2557 else:
2558 raise NotImplementedError,"Log_Symbol does not provide program code for format %s."%format
2559
2560 def substitute(self,argvals):
2561 """
2562 assigns new values to symbols in the definition of the symbol.
2563 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2564
2565 @param argvals: new values assigned to symbols
2566 @type argvals: C{dict} with keywords of type L{Symbol}.
2567 @return: result of the substitution process. Operations are executed as much as possible.
2568 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2569 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2570 """
2571 if argvals.has_key(self):
2572 arg=argvals[self]
2573 if self.isAppropriateValue(arg):
2574 return arg
2575 else:
2576 raise TypeError,"%s: new value is not appropriate."%str(self)
2577 else:
2578 arg=self.getSubstitutedArguments(argvals)[0]
2579 return log(arg)
2580
2581 def diff(self,arg):
2582 """
2583 differential of this object
2584
2585 @param arg: the derivative is calculated with respect to arg
2586 @type arg: L{escript.Symbol}
2587 @return: derivative with respect to C{arg}
2588 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2589 """
2590 if arg==self:
2591 return identity(self.getShape())
2592 else:
2593 myarg=self.getArgument()[0]
2594 val=matchShape(1./arg,self.getDifferentiatedArguments(arg)[0])
2595 return val[0]*val[1]
2596
2597 def sign(arg):
2598 """
2599 returns sign of argument arg
2600
2601 @param arg: argument
2602 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2603 @rtype:C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2604 @raises TypeError: if the type of the argument is not expected.
2605 """
2606 if isinstance(arg,numarray.NumArray):
2607 return wherePositive(arg)-whereNegative(arg)
2608 elif isinstance(arg,escript.Data):
2609 return arg._sign()
2610 elif isinstance(arg,float):
2611 if arg>0:
2612 return 1.
2613 elif arg<0:
2614 return -1.
2615 else:
2616 return 0.
2617 elif isinstance(arg,int):
2618 if float(arg)>0:
2619 return 1.
2620 elif float(arg)<0:
2621 return -1.
2622 else:
2623 return 0.
2624 elif isinstance(arg,Symbol):
2625 return wherePositive(arg)-whereNegative(arg)
2626 else:
2627 raise TypeError,"sign: Unknown argument type."
2628
2629 class Abs_Symbol(DependendSymbol):
2630 """
2631 L{Symbol} representing the result of the absolute value function
2632 """
2633 def __init__(self,arg):
2634 """
2635 initialization of abs L{Symbol} with argument arg
2636 @param arg: argument of function
2637 @type arg: typically L{Symbol}.
2638 """
2639 DependendSymbol.__init__(self,args=[arg],shape=arg.getShape(),dim=arg.getDim())
2640
2641 def getMyCode(self,argstrs,format="escript"):
2642 """
2643 returns a program code that can be used to evaluate the symbol.
2644
2645 @param argstrs: gives for each argument a string representing the argument for the evaluation.
2646 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2647 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2648 @type format: C{str}
2649 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2650 @rtype: C{str}
2651 @raise: NotImplementedError: if the requested format is not available
2652 """
2653 if isinstance(argstrs,list):
2654 argstrs=argstrs[0]
2655 if format=="escript" or format=="str" or format=="text":
2656 return "abs(%s)"%argstrs
2657 else:
2658 raise NotImplementedError,"Abs_Symbol does not provide program code for format %s."%format
2659
2660 def substitute(self,argvals):
2661 """
2662 assigns new values to symbols in the definition of the symbol.
2663 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2664
2665 @param argvals: new values assigned to symbols
2666 @type argvals: C{dict} with keywords of type L{Symbol}.
2667 @return: result of the substitution process. Operations are executed as much as possible.
2668 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2669 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2670 """
2671 if argvals.has_key(self):
2672 arg=argvals[self]
2673 if self.isAppropriateValue(arg):
2674 return arg
2675 else:
2676 raise TypeError,"%s: new value is not appropriate."%str(self)
2677 else:
2678 arg=self.getSubstitutedArguments(argvals)[0]
2679 return abs(arg)
2680
2681 def diff(self,arg):
2682 """
2683 differential of this object
2684
2685 @param arg: the derivative is calculated with respect to arg
2686 @type arg: L{escript.Symbol}
2687 @return: derivative with respect to C{arg}
2688 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
2689 """
2690 if arg==self:
2691 return identity(self.getShape())
2692 else:
2693 myarg=self.getArgument()[0]
2694 val=matchShape(sign(myarg),self.getDifferentiatedArguments(arg)[0])
2695 return val[0]*val[1]
2696
2697 def minval(arg):
2698 """
2699 returns minimum value over all components of arg at each data point
2700
2701 @param arg: argument
2702 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2703 @rtype:C{float}, L{escript.Data}, L{Symbol} depending on the type of arg.
2704 @raises TypeError: if the type of the argument is not expected.
2705 """
2706 if isinstance(arg,numarray.NumArray):
2707 if arg.rank==0:
2708 return float(arg)
2709 else:
2710 return arg.min()
2711 elif isinstance(arg,escript.Data):
2712 return arg._minval()
2713 elif isinstance(arg,float):
2714 return arg
2715 elif isinstance(arg,int):
2716 return float(arg)
2717 elif isinstance(arg,Symbol):
2718 return Minval_Symbol(arg)
2719 else:
2720 raise TypeError,"minval: Unknown argument type."
2721
2722 class Minval_Symbol(DependendSymbol):
2723 """
2724 L{Symbol} representing the result of the minimum value function
2725 """
2726 def __init__(self,arg):
2727 """
2728 initialization of minimum value L{Symbol} with argument arg
2729 @param arg: argument of function
2730 @type arg: typically L{Symbol}.
2731 """
2732 DependendSymbol.__init__(self,args=[arg],shape=(),dim=arg.getDim())
2733
2734 def getMyCode(self,argstrs,format="escript"):
2735 """
2736 returns a program code that can be used to evaluate the symbol.
2737
2738 @param argstrs: gives for each argument a string representing the argument for the evaluation.
2739 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2740 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2741 @type format: C{str}
2742 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2743 @rtype: C{str}
2744 @raise: NotImplementedError: if the requested format is not available
2745 """
2746 if isinstance(argstrs,list):
2747 argstrs=argstrs[0]
2748 if format=="escript" or format=="str" or format=="text":
2749 return "minval(%s)"%argstrs
2750 else:
2751 raise NotImplementedError,"Minval_Symbol does not provide program code for format %s."%format
2752
2753 def substitute(self,argvals):
2754 """
2755 assigns new values to symbols in the definition of the symbol.
2756 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2757
2758 @param argvals: new values assigned to symbols
2759 @type argvals: C{dict} with keywords of type L{Symbol}.
2760 @return: result of the substitution process. Operations are executed as much as possible.
2761 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2762 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2763 """
2764 if argvals.has_key(self):
2765 arg=argvals[self]
2766 if self.isAppropriateValue(arg):
2767 return arg
2768 else:
2769 raise TypeError,"%s: new value is not appropriate."%str(self)
2770 else:
2771 arg=self.getSubstitutedArguments(argvals)[0]
2772 return minval(arg)
2773
2774 def maxval(arg):
2775 """
2776 returns maximum value over all components of arg at each data point
2777
2778 @param arg: argument
2779 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2780 @rtype:C{float}, L{escript.Data}, L{Symbol} depending on the type of arg.
2781 @raises TypeError: if the type of the argument is not expected.
2782 """
2783 if isinstance(arg,numarray.NumArray):
2784 if arg.rank==0:
2785 return float(arg)
2786 else:
2787 return arg.max()
2788 elif isinstance(arg,escript.Data):
2789 return arg._maxval()
2790 elif isinstance(arg,float):
2791 return arg
2792 elif isinstance(arg,int):
2793 return float(arg)
2794 elif isinstance(arg,Symbol):
2795 return Maxval_Symbol(arg)
2796 else:
2797 raise TypeError,"maxval: Unknown argument type."
2798
2799 class Maxval_Symbol(DependendSymbol):
2800 """
2801 L{Symbol} representing the result of the maximum value function
2802 """
2803 def __init__(self,arg):
2804 """
2805 initialization of maximum value L{Symbol} with argument arg
2806 @param arg: argument of function
2807 @type arg: typically L{Symbol}.
2808 """
2809 DependendSymbol.__init__(self,args=[arg],shape=(),dim=arg.getDim())
2810
2811 def getMyCode(self,argstrs,format="escript"):
2812 """
2813 returns a program code that can be used to evaluate the symbol.
2814
2815 @param argstrs: gives for each argument a string representing the argument for the evaluation.
2816 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2817 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2818 @type format: C{str}
2819 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2820 @rtype: C{str}
2821 @raise: NotImplementedError: if the requested format is not available
2822 """
2823 if isinstance(argstrs,list):
2824 argstrs=argstrs[0]
2825 if format=="escript" or format=="str" or format=="text":
2826 return "maxval(%s)"%argstrs
2827 else:
2828 raise NotImplementedError,"Maxval_Symbol does not provide program code for format %s."%format
2829
2830 def substitute(self,argvals):
2831 """
2832 assigns new values to symbols in the definition of the symbol.
2833 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2834
2835 @param argvals: new values assigned to symbols
2836 @type argvals: C{dict} with keywords of type L{Symbol}.
2837 @return: result of the substitution process. Operations are executed as much as possible.
2838 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2839 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2840 """
2841 if argvals.has_key(self):
2842 arg=argvals[self]
2843 if self.isAppropriateValue(arg):
2844 return arg
2845 else:
2846 raise TypeError,"%s: new value is not appropriate."%str(self)
2847 else:
2848 arg=self.getSubstitutedArguments(argvals)[0]
2849 return maxval(arg)
2850
2851 def length(arg):
2852 """
2853 returns length/Euclidean norm of argument arg at each data point
2854
2855 @param arg: argument
2856 @type arg: C{float}, L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2857 @rtype:C{float}, L{escript.Data}, L{Symbol} depending on the type of arg.
2858 """
2859 return sqrt(inner(arg,arg))
2860
2861 def trace(arg,axis_offset=0):
2862 """
2863 returns the trace of arg which the sum of arg[k,k] over k.
2864
2865 @param arg: argument
2866 @type arg: L{escript.Data}, L{Symbol}, L{numarray.NumArray}.
2867 @param axis_offset: axis_offset to components to sum over. C{axis_offset} must be non-negative and less than the rank of arg +1. The dimensions on component
2868 axis_offset and axis_offset+1 must be equal.
2869 @type axis_offset: C{int}
2870 @return: trace of arg. The rank of the returned object is minus 2 of the rank of arg.
2871 @rtype: L{escript.Data}, L{Symbol}, L{numarray.NumArray} depending on the type of arg.
2872 """
2873 if isinstance(arg,numarray.NumArray):
2874 sh=arg.shape
2875 if len(sh)<2:
2876 raise ValueError,"trace: rank of argument must be greater than 1"
2877 if axis_offset<0 or axis_offset>len(sh)-2:
2878 raise ValueError,"trace: axis_offset must be between 0 and %s"%len(sh)-2
2879 s1=1
2880 for i in range(axis_offset): s1*=sh[i]
2881 s2=1
2882 for i in range(axis_offset+2,len(sh)): s2*=sh[i]
2883 if not sh[axis_offset] == sh[axis_offset+1]:
2884 raise ValueError,"trace: dimensions of component %s and %s must match."%(axis_offset.axis_offset+1)
2885 arg_reshaped=numarray.reshape(arg,(s1,sh[axis_offset],sh[axis_offset],s2))
2886 out=numarray.zeros([s1,s2],numarray.Float)
2887 for i1 in range(s1):
2888 for i2 in range(s2):
2889 for j in range(sh[axis_offset]): out[i1,i2]+=arg_reshaped[i1,j,j,i2]
2890 out.resize(sh[:axis_offset]+sh[axis_offset+2:])
2891 return out
2892 elif isinstance(arg,escript.Data):
2893 return escript_trace(arg,axis_offset)
2894 elif isinstance(arg,float):
2895 raise TypeError,"trace: illegal argument type float."
2896 elif isinstance(arg,int):
2897 raise TypeError,"trace: illegal argument type int."
2898 elif isinstance(arg,Symbol):
2899 return Trace_Symbol(arg,axis_offset)
2900 else:
2901 raise TypeError,"trace: Unknown argument type."
2902
2903 def escript_trace(arg,axis_offset): # this should be escript._trace
2904 "arg si a Data objects!!!"
2905 if arg.getRank()<2:
2906 raise ValueError,"escript_trace: rank of argument must be greater than 1"
2907 if axis_offset<0 or axis_offset>arg.getRank()-2:
2908 raise ValueError,"escript_trace: axis_offset must be between 0 and %s"%arg.getRank()-2
2909 s=list(arg.getShape())
2910 if not s[axis_offset] == s[axis_offset+1]:
2911 raise ValueError,"escript_trace: dimensions of component %s and %s must match."%(axis_offset.axis_offset+1)
2912 out=escript.Data(0.,tuple(s[0:axis_offset]+s[axis_offset+2:]),arg.getFunctionSpace())
2913 if arg.getRank()==2:
2914 for i0 in range(s[0]):
2915 out+=arg[i0,i0]
2916 elif arg.getRank()==3:
2917 if axis_offset==0:
2918 for i0 in range(s[0]):
2919 for i2 in range(s[2]):
2920 out[i2]+=arg[i0,i0,i2]
2921 elif axis_offset==1:
2922 for i0 in range(s[0]):
2923 for i1 in range(s[1]):
2924 out[i0]+=arg[i0,i1,i1]
2925 elif arg.getRank()==4:
2926 if axis_offset==0:
2927 for i0 in range(s[0]):
2928 for i2 in range(s[2]):
2929 for i3 in range(s[3]):
2930 out[i2,i3]+=arg[i0,i0,i2,i3]
2931 elif axis_offset==1:
2932 for i0 in range(s[0]):
2933 for i1 in range(s[1]):
2934 for i3 in range(s[3]):
2935 out[i0,i3]+=arg[i0,i1,i1,i3]
2936 elif axis_offset==2:
2937 for i0 in range(s[0]):
2938 for i1 in range(s[1]):
2939 for i2 in range(s[2]):
2940 out[i0,i1]+=arg[i0,i1,i2,i2]
2941 return out
2942 class Trace_Symbol(DependendSymbol):
2943 """
2944 L{Symbol} representing the result of the trace function
2945 """
2946 def __init__(self,arg,axis_offset=0):
2947 """
2948 initialization of trace L{Symbol} with argument arg
2949 @param arg: argument of function
2950 @type arg: L{Symbol}.
2951 @param axis_offset: axis_offset to components to sum over. C{axis_offset} must be non-negative and less than the rank of arg +1. The dimensions on component
2952 axis_offset and axis_offset+1 must be equal.
2953 @type axis_offset: C{int}
2954 """
2955 if arg.getRank()<2:
2956 raise ValueError,"Trace_Symbol: rank of argument must be greater than 1"
2957 if axis_offset<0 or axis_offset>arg.getRank()-2:
2958 raise ValueError,"Trace_Symbol: axis_offset must be between 0 and %s"%arg.getRank()-2
2959 s=list(arg.getShape())
2960 if not s[axis_offset] == s[axis_offset+1]:
2961 raise ValueError,"Trace_Symbol: dimensions of component %s and %s must match."%(axis_offset.axis_offset+1)
2962 super(Trace_Symbol,self).__init__(args=[arg,axis_offset],shape=tuple(s[0:axis_offset]+s[axis_offset+2:]),dim=arg.getDim())
2963
2964 def getMyCode(self,argstrs,format="escript"):
2965 """
2966 returns a program code that can be used to evaluate the symbol.
2967
2968 @param argstrs: gives for each argument a string representing the argument for the evaluation.
2969 @type argstrs: C{str} or a C{list} of length 1 of C{str}.
2970 @param format: specifies the format to be used. At the moment only "escript" ,"text" and "str" are supported.
2971 @type format: C{str}
2972 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
2973 @rtype: C{str}
2974 @raise: NotImplementedError: if the requested format is not available
2975 """
2976 if format=="escript" or format=="str" or format=="text":
2977 return "trace(%s,axis_offset=%s)"%(argstrs[0],argstrs[1])
2978 else:
2979 raise NotImplementedError,"Trace_Symbol does not provide program code for format %s."%format
2980
2981 def substitute(self,argvals):
2982 """
2983 assigns new values to symbols in the definition of the symbol.
2984 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
2985
2986 @param argvals: new values assigned to symbols
2987 @type argvals: C{dict} with keywords of type L{Symbol}.
2988 @return: result of the substitution process. Operations are executed as much as possible.
2989 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
2990 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
2991 """
2992 if argvals.has_key(self):
2993 arg=argvals[self]
2994 if self.isAppropriateValue(arg):
2995 return arg
2996 else:
2997 raise TypeError,"%s: new value is not appropriate."%str(self)
2998 else:
2999 arg=self.getSubstitutedArguments(argvals)
3000 return trace(arg[0],axis_offset=arg[1])
3001
3002 def diff(self,arg):
3003 """
3004 differential of this object
3005
3006 @param arg: the derivative is calculated with respect to arg
3007 @type arg: L{escript.Symbol}
3008 @return: derivative with respect to C{arg}
3009 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
3010 """
3011 if arg==self:
3012 return identity(self.getShape())
3013 else:
3014 return trace(self.getDifferentiatedArguments(arg)[0],axis_offset=self.getArgument()[1])
3015
3016 #=======================================================
3017 # Binary operations:
3018 #=======================================================
3019 def add(arg0,arg1):
3020 """
3021 adds arg0 and arg1 together.
3022
3023 @param arg0: first term
3024 @type arg0: L{escript.Symbol}, C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
3025 @param arg1: second term
3026 @type arg1: L{escript.Symbol}, C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
3027 @return: the some of arg0 and arg1
3028 @rtype: L{escript.Symbol}, C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
3029 @note: The shape of both arguments is matched according to the rules in used in L{matchShape}
3030 """
3031 args=matchShape(arg0,arg1)
3032 if testForZero(args[0]):
3033 return args[1]
3034 elif testForZero(args[1]):
3035 return args[0]
3036 else:
3037 if isinstance(args[0],Symbol) or isinstance(args[1],Symbol) :
3038 return Add_Symbol(args[0],args[1])
3039 elif isinstance(args[0],numarray.NumArray):
3040 return args[1]+args[0]
3041 else:
3042 return args[0]+args[1]
3043
3044 class Add_Symbol(DependendSymbol):
3045 """
3046 Symbol representing the sum of two arguments.
3047 """
3048 def __init__(self,arg0,arg1):
3049 """
3050 initialization of the L{Symbol} representing the sum of two arguments
3051
3052 @param arg0: first term in the sum
3053 @type arg0: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
3054 @param arg1: second term in the sum
3055 @type arg1: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
3056 @raise ValueError: if both arguments do not have the same shape.
3057 @note: if both arguments have a spatial dimension, they must equal.
3058 """
3059 sh0=pokeShape(arg0)
3060 sh1=pokeShape(arg1)
3061 if not sh0==sh1:
3062 raise ValueError,"Add_Symbol: shape of arguments must match"
3063 DependendSymbol.__init__(self,dim=commonDim(arg0,arg1),shape=sh0,args=[arg0,arg1])
3064
3065 def getMyCode(self,argstrs,format="escript"):
3066 """
3067 returns a program code that can be used to evaluate the symbol.
3068
3069 @param argstrs: gives for each argument a string representing the argument for the evaluation.
3070 @type argstrs: C{list} of length 2 of C{str}.
3071 @param format: specifies the format to be used. At the moment only "escript", "str" and "text" are supported.
3072 @type format: C{str}
3073 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
3074 @rtype: C{str}
3075 @raise: NotImplementedError: if the requested format is not available
3076 """
3077 if format=="str" or format=="text":
3078 return "(%s)+(%s)"%(argstrs[0],argstrs[1])
3079 elif format=="escript":
3080 return "add(%s,%s)"%(argstrs[0],argstrs[1])
3081 else:
3082 raise NotImplementedError,"%s does not provide program code for format %s."%(str(self),format)
3083
3084 def substitute(self,argvals):
3085 """
3086 assigns new values to symbols in the definition of the symbol.
3087 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
3088
3089 @param argvals: new values assigned to symbols
3090 @type argvals: C{dict} with keywords of type L{Symbol}.
3091 @return: result of the substitution process. Operations are executed as much as possible.
3092 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
3093 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
3094 """
3095 if argvals.has_key(self):
3096 arg=argvals[self]
3097 if self.isAppropriateValue(arg):
3098 return arg
3099 else:
3100 raise TypeError,"%s: new value is not appropriate."%str(self)
3101 else:
3102 args=self.getSubstitutedArguments(argvals)
3103 return add(args[0],args[1])
3104
3105 def diff(self,arg):
3106 """
3107 differential of this object
3108
3109 @param arg: the derivative is calculated with respect to arg
3110 @type arg: L{escript.Symbol}
3111 @return: derivative with respect to C{arg}
3112 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
3113 """
3114 if arg==self:
3115 return identity(self.getShape())
3116 else:
3117 dargs=self.getDifferentiatedArguments(arg)
3118 return add(dargs[0],dargs[1])
3119
3120 def mult(arg0,arg1):
3121 """
3122 product of arg0 and arg1
3123
3124 @param arg0: first term
3125 @type arg0: L{escript.Symbol}, C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
3126 @param arg1: second term
3127 @type arg1: L{escript.Symbol}, C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
3128 @return: the some of arg0 and arg1
3129 @rtype: L{escript.Symbol}, C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
3130 @note: The shape of both arguments is matched according to the rules in used in L{matchShape}
3131 """
3132 args=matchShape(arg0,arg1)
3133 if testForZero(args[0]) or testForZero(args[1]):
3134 return numarray.zeros(pokeShape(args[0]),numarray.Float)
3135 else:
3136 if isinstance(args[0],Symbol) or isinstance(args[1],Symbol) :
3137 return Mult_Symbol(args[0],args[1])
3138 elif isinstance(args[0],numarray.NumArray):
3139 return args[1]*args[0]
3140 else:
3141 return args[0]*args[1]
3142
3143 class Mult_Symbol(DependendSymbol):
3144 """
3145 Symbol representing the product of two arguments.
3146 """
3147 def __init__(self,arg0,arg1):
3148 """
3149 initialization of the L{Symbol} representing the product of two arguments
3150
3151 @param arg0: first factor
3152 @type arg0: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
3153 @param arg1: second factor
3154 @type arg1: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
3155 @raise ValueError: if both arguments do not have the same shape.
3156 @note: if both arguments have a spatial dimension, they must equal.
3157 """
3158 sh0=pokeShape(arg0)
3159 sh1=pokeShape(arg1)
3160 if not sh0==sh1:
3161 raise ValueError,"Mult_Symbol: shape of arguments must match"
3162 DependendSymbol.__init__(self,dim=commonDim(arg0,arg1),shape=sh0,args=[arg0,arg1])
3163
3164 def getMyCode(self,argstrs,format="escript"):
3165 """
3166 returns a program code that can be used to evaluate the symbol.
3167
3168 @param argstrs: gives for each argument a string representing the argument for the evaluation.
3169 @type argstrs: C{list} of length 2 of C{str}.
3170 @param format: specifies the format to be used. At the moment only "escript", "str" and "text" are supported.
3171 @type format: C{str}
3172 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
3173 @rtype: C{str}
3174 @raise: NotImplementedError: if the requested format is not available
3175 """
3176 if format=="str" or format=="text":
3177 return "(%s)*(%s)"%(argstrs[0],argstrs[1])
3178 elif format=="escript":
3179 return "mult(%s,%s)"%(argstrs[0],argstrs[1])
3180 else:
3181 raise NotImplementedError,"%s does not provide program code for format %s."%(str(self),format)
3182
3183 def substitute(self,argvals):
3184 """
3185 assigns new values to symbols in the definition of the symbol.
3186 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
3187
3188 @param argvals: new values assigned to symbols
3189 @type argvals: C{dict} with keywords of type L{Symbol}.
3190 @return: result of the substitution process. Operations are executed as much as possible.
3191 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
3192 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
3193 """
3194 if argvals.has_key(self):
3195 arg=argvals[self]
3196 if self.isAppropriateValue(arg):
3197 return arg
3198 else:
3199 raise TypeError,"%s: new value is not appropriate."%str(self)
3200 else:
3201 args=self.getSubstitutedArguments(argvals)
3202 return mult(args[0],args[1])
3203
3204 def diff(self,arg):
3205 """
3206 differential of this object
3207
3208 @param arg: the derivative is calculated with respect to arg
3209 @type arg: L{escript.Symbol}
3210 @return: derivative with respect to C{arg}
3211 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
3212 """
3213 if arg==self:
3214 return identity(self.getShape())
3215 else:
3216 myargs=self.getArgument()
3217 dargs=self.getDifferentiatedArguments(arg)
3218 return add(mult(myargs[0],dargs[1]),mult(myargs[1],dargs[0]))
3219
3220 def quotient(arg0,arg1):
3221 """
3222 quotient of arg0 and arg1
3223
3224 @param arg0: numerator
3225 @type arg0: L{escript.Symbol}, C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
3226 @param arg1: denominator
3227 @type arg1: L{escript.Symbol}, C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
3228 @return: the some of arg0 and arg1
3229 @rtype: L{escript.Symbol}, C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
3230 @note: The shape of both arguments is matched according to the rules in used in L{matchShape}
3231 """
3232 args=matchShape(arg0,arg1)
3233 if testForZero(args[0]):
3234 return numarray.zeros(pokeShape(args[0]),numarray.Float)
3235 elif isinstance(args[0],Symbol):
3236 if isinstance(args[1],Symbol):
3237 return Quotient_Symbol(args[0],args[1])
3238 else:
3239 return mult(args[0],1./args[1])
3240 else:
3241 if isinstance(args[1],Symbol):
3242 return Quotient_Symbol(args[0],args[1])
3243 elif isinstance(args[0],numarray.NumArray) and not isinstance(args[1],numarray.NumArray):
3244 return 1./args[1]*args[0]
3245 else:
3246 return args[0]/args[1]
3247
3248 class Quotient_Symbol(DependendSymbol):
3249 """
3250 Symbol representing the quotient of two arguments.
3251 """
3252 def __init__(self,arg0,arg1):
3253 """
3254 initialization of L{Symbol} representing the quotient of two arguments
3255
3256 @param arg0: numerator
3257 @type arg0: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
3258 @param arg1: denominator
3259 @type arg1: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
3260 @raise ValueError: if both arguments do not have the same shape.
3261 @note: if both arguments have a spatial dimension, they must equal.
3262 """
3263 sh0=pokeShape(arg0)
3264 sh1=pokeShape(arg1)
3265 if not sh0==sh1:
3266 raise ValueError,"Quotient_Symbol: shape of arguments must match"
3267 DependendSymbol.__init__(self,dim=commonDim(arg0,arg1),shape=sh0,args=[arg0,arg1])
3268
3269 def getMyCode(self,argstrs,format="escript"):
3270 """
3271 returns a program code that can be used to evaluate the symbol.
3272
3273 @param argstrs: gives for each argument a string representing the argument for the evaluation.
3274 @type argstrs: C{list} of length 2 of C{str}.
3275 @param format: specifies the format to be used. At the moment only "escript", "str" and "text" are supported.
3276 @type format: C{str}
3277 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
3278 @rtype: C{str}
3279 @raise: NotImplementedError: if the requested format is not available
3280 """
3281 if format=="str" or format=="text":
3282 return "(%s)/(%s)"%(argstrs[0],argstrs[1])
3283 if format=="escript":
3284 return "quotient(%s,%s)"%(argstrs[0],argstrs[1])
3285 else:
3286 raise NotImplementedError,"%s does not provide program code for format %s."%(str(self),format)
3287
3288 def substitute(self,argvals):
3289 """
3290 assigns new values to symbols in the definition of the symbol.
3291 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
3292
3293 @param argvals: new values assigned to symbols
3294 @type argvals: C{dict} with keywords of type L{Symbol}.
3295 @return: result of the substitution process. Operations are executed as much as possible.
3296 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
3297 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
3298 """
3299 if argvals.has_key(self):
3300 arg=argvals[self]
3301 if self.isAppropriateValue(arg):
3302 return arg
3303 else:
3304 raise TypeError,"%s: new value is not appropriate."%str(self)
3305 else:
3306 args=self.getSubstitutedArguments(argvals)
3307 return quotient(args[0],args[1])
3308
3309 def diff(self,arg):
3310 """
3311 differential of this object
3312
3313 @param arg: the derivative is calculated with respect to arg
3314 @type arg: L{escript.Symbol}
3315 @return: derivative with respect to C{arg}
3316 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
3317 """
3318 if arg==self:
3319 return identity(self.getShape())
3320 else:
3321 myargs=self.getArgument()
3322 dargs=self.getDifferentiatedArguments(arg)
3323 return quotient(add(mult(myargs[1],dargs[0]),mult(-myargs[0],dargs[1])),myargs[1]*myargs[1])
3324
3325
3326 def power(arg0,arg1):
3327 """
3328 raises arg0 to the power of arg1
3329
3330 @param arg0: basis
3331 @type arg0: L{escript.Symbol}, C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
3332 @param arg1: exponent
3333 @type arg1: L{escript.Symbol}, C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
3334 @return: of arg0 and arg1
3335 @rtype: L{escript.Symbol}, C{float}, C{int}, L{escript.Data}, L{numarray.NumArray}.
3336 @note: The shape of both arguments is matched according to the rules in used in L{matchShape}
3337 """
3338 args=matchShape(arg0,arg1)
3339 if testForZero(args[0]):
3340 return numarray.zeros(args[0],numarray.Float)
3341 elif testForZero(args[1]):
3342 return numarray.ones(args[0],numarray.Float)
3343 elif isinstance(args[0],Symbol) or isinstance(args[1],Symbol):
3344 return Power_Symbol(args[0],args[1])
3345 elif isinstance(args[0],numarray.NumArray) and not isinstance(args[1],numarray.NumArray):
3346 return exp(args[1]*log(args[0]))
3347 else:
3348 return args[0]**args[1]
3349
3350 class Power_Symbol(DependendSymbol):
3351 """
3352 Symbol representing the first argument to the power of the second argument.
3353 """
3354 def __init__(self,arg0,arg1):
3355 """
3356 initialization of the L{Symbol} representing rasing the first argument to the power of the second.
3357
3358 @param arg0: basis
3359 @type arg0: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
3360 @param arg1: exponent
3361 @type arg1: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray}.
3362 @raise ValueError: if both arguments do not have the same shape.
3363 @note: if both arguments have a spatial dimension, they must equal.
3364 """
3365 sh0=pokeShape(arg0)
3366 sh1=pokeShape(arg1)
3367 if not sh0==sh1:
3368 raise ValueError,"Power_Symbol: shape of arguments must match"
3369 d0=pokeDim(arg0)
3370 d1=pokeDim(arg1)
3371 DependendSymbol.__init__(self,dim=commonDim(arg0,arg1),shape=sh0,args=[arg0,arg1])
3372
3373 def getMyCode(self,argstrs,format="escript"):
3374 """
3375 returns a program code that can be used to evaluate the symbol.
3376
3377 @param argstrs: gives for each argument a string representing the argument for the evaluation.
3378 @type argstrs: C{list} of length 2 of C{str}.
3379 @param format: specifies the format to be used. At the moment only "escript", "str" and "text" are supported.
3380 @type format: C{str}
3381 @return: a piece of program code which can be used to evaluate the expression assuming the values for the arguments are available.
3382 @rtype: C{str}
3383 @raise: NotImplementedError: if the requested format is not available
3384 """
3385 if format=="escript" or format=="str" or format=="text":
3386 return "(%s)**(%s)"%(argstrs[0],argstrs[1])
3387 elif format=="escript":
3388 return "power(%s,%s)"%(argstrs[0],argstrs[1])
3389 else:
3390 raise NotImplementedError,"%s does not provide program code for format %s."%(str(self),format)
3391
3392 def substitute(self,argvals):
3393 """
3394 assigns new values to symbols in the definition of the symbol.
3395 The method replaces the L{Symbol} u by argvals[u] in the expression defining this object.
3396
3397 @param argvals: new values assigned to symbols
3398 @type argvals: C{dict} with keywords of type L{Symbol}.
3399 @return: result of the substitution process. Operations are executed as much as possible.
3400 @rtype: L{escript.Symbol}, C{float}, L{escript.Data}, L{numarray.NumArray} depending on the degree of substitution
3401 @raise TypeError: if a value for a L{Symbol} cannot be substituted.
3402 """
3403 if argvals.has_key(self):
3404 arg=argvals[self]
3405 if self.isAppropriateValue(arg):
3406 return arg
3407 else:
3408 raise TypeError,"%s: new value is not appropriate."%str(self)
3409 else:
3410 args=self.getSubstitutedArguments(argvals)
3411 return power(args[0],args[1])
3412
3413 def diff(self,arg):
3414 """
3415 differential of this object
3416
3417 @param arg: the derivative is calculated with respect to arg
3418 @type arg: L{escript.Symbol}
3419 @return: derivative with respect to C{arg}
3420 @rtype: typically L{Symbol} but other types such as C{float}, L{escript.Data}, L{numarray.NumArray} are possible.
3421 """
3422 if arg==self:
3423 return identity(self.getShape())
3424 else:
3425 myargs=self.getArgument()
3426 dargs=self.getDifferentiatedArguments(arg)
3427 return mult(self,add(mult(log(myargs[0]),dargs[1]),mult(quotient(myargs[1],myargs[0]),dargs[0])))
3428
3429 def maximum(*args):
3430<