/[escript]/trunk/escript/py_src/symbolic/evaluator.py
ViewVC logotype

Contents of /trunk/escript/py_src/symbolic/evaluator.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3975 - (show annotations)
Thu Sep 20 01:54:06 2012 UTC (7 years, 1 month ago) by caltinay
File MIME type: text/x-python
File size: 4662 byte(s)
Merged symbolic branch into trunk. Curious what daniel and spartacus have to
say...

1
2 ########################################################
3 #
4 # Copyright (c) 2003-2012 by University of Queensland
5 # Earth Systems Science Computational Center (ESSCC)
6 # http://www.uq.edu.au/esscc
7 #
8 # Primary Business: Queensland, Australia
9 # Licensed under the Open Software License version 3.0
10 # http://www.opensource.org/licenses/osl-3.0.php
11 #
12 ########################################################
13
14 __copyright__="""Copyright (c) 2003-2012 by University of Queensland
15 Earth Systems Science Computational Center (ESSCC)
16 http://www.uq.edu.au/esscc
17 Primary Business: Queensland, Australia"""
18 __license__="""Licensed under the Open Software License version 3.0
19 http://www.opensource.org/licenses/osl-3.0.php"""
20 __url__="https://launchpad.net/escript-finley"
21 __author__="Cihan Altinay"
22
23 """
24 Symbolic expression evaluator for escript
25 """
26
27 class Evaluator:
28 def __init__(self, *expressions):
29 """
30 Returns a symbolic evaluator.
31
32 :param expressions: optional expressions to initialise with
33 """
34 self.expressions=[]
35 self.symbols=[]
36 self.lambdas=[]
37 self._subsdict={}
38 for ex in expressions:
39 self.addExpression(ex)
40
41 def __getstate__(self):
42 mydict=self.__dict__.copy()
43 # lambda functions cannot be pickled
44 mydict['lambdas']=[]
45 return mydict
46
47 def __setstate__(self, dict):
48 expressions=dict['expressions']
49 dict['expressions']=[]
50 self.__dict__.update(dict)
51 # regenerate lambdas
52 for ex in expressions:
53 self.addExpression(ex)
54
55 def addExpression(self, expression):
56 """
57 Adds an expression to this evaluator.
58
59 :return: the modified Evaluator object
60 """
61 import sympy
62 from esys import escript
63 if not hasattr(expression, "atoms"):
64 raise TypeError("Argument is not an expression")
65 self.expressions.append(expression)
66 if isinstance(expression, sympy.Function):
67 sym=set()
68 for arg in expression.args:
69 if arg is not None:
70 sym.update(arg.atoms(sympy.Symbol))
71 self.symbols.append(tuple(sym))
72 else:
73 sym=set(expression.atoms(sympy.Symbol))
74 self.symbols.append(sym)
75
76 if isinstance(expression, escript.Symbol):
77 subs=expression.getDataSubstitutions()
78 self.subs(**{s.name:subs[s] for s in subs.keys()})
79 self.lambdas.append(sympy.lambdify(sym, expression.lambdarepr(), ["escript","numpy"]))
80 else:
81 self.lambdas.append(sympy.lambdify(sym, expression, ["escript","numpy"]))
82 return self
83
84 def subs(self, **args):
85 """
86 Symbol substitution.
87
88 :return: the modified Evaluator object
89 """
90 self._subsdict.update(args)
91 return self
92
93 def evaluate(self, **args):
94 """
95 Evaluates all expressions in this evaluator and returns the result
96 as a tuple.
97
98 :return: the evaluated expressions in the order they were added to
99 this Evaluator.
100 """
101 self.subs(**args)
102 res=()
103 for i in range(len(self.lambdas)):
104 x=self.symbols[i]
105 subslist=[self._subsdict[a.name] for a in x if self._subsdict.has_key(a.name)]
106 if len(x)==len(subslist):
107 res+=self.lambdas[i](*subslist),
108 else:
109 raise RuntimeError("Not all symbols have a value")
110 if len(res)==1:
111 return res[0]
112 else:
113 return res
114
115 def __call__(self, **args):
116 """
117 Convenience method to substitute and evaluate at once.
118 """
119 return self.subs(**args).evaluate()
120
121 def __getitem__(self, index):
122 """
123 Expression accessor.
124 """
125 return self.expressions[index]
126
127 def __len__(self):
128 """
129 Returns the number of expressions in this evaluator.
130 """
131 return len(self.expressions)
132
133 def __iadd__(self, expression):
134 """
135 Same as addExpression(expression).
136 """
137 return self.addExpression(expression)
138
139 def __str__(self):
140 ret="\n".join([str(e) for e in self.expressions])+"\n"
141 for k in self._subsdict:
142 v=self._subsdict[k]
143 if v.__class__.__name__=="Data":
144 ret+="%s=<Data object>"%k
145 elif v.__class__.__name__=="FunctionSpace":
146 ret+="%s=<FunctionSpace object>"%k
147 else:
148 ret+="%s=%s"%(k,v)
149 ret+=", "
150 return ret
151
152 #
153 # vim: expandtab shiftwidth=4:

  ViewVC Help
Powered by ViewVC 1.1.26