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