/[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 2169 - (show annotations)
Wed Dec 17 03:08:58 2008 UTC (10 years, 10 months ago) by caltinay
File MIME type: text/x-python
File size: 220269 byte(s)
Assorted spelling, grammar, whitespace and copy/paste error fixes (Part 2).
All epydoc warnings for these files have been fixed.
This commit should be a no-op.

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