SeExpr
ExprMultiExpr.cpp
Go to the documentation of this file.
1/*
2 Copyright Disney Enterprises, Inc. All rights reserved.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License
6 and the following modification to it: Section 6 Trademarks.
7 deleted and replaced with:
8
9 6. Trademarks. This License does not grant permission to use the
10 trade names, trademarks, service marks, or product names of the
11 Licensor and its affiliates, except as required for reproducing
12 the content of the NOTICE file.
13
14 You may obtain a copy of the License at
15 http://www.apache.org/licenses/LICENSE-2.0
16*/
17#include "ExprMultiExpr.h"
18#include <algorithm>
19#include <set>
20
21namespace SeExpr2 {
22class GlobalVal : public ExprVarRef {
23 public:
24 GlobalVal(const std::string &varName, const SeExpr2::ExprType &et) : ExprVarRef(et), varName(varName) {}
25 std::set<DExpression *> users;
26 std::string varName;
27};
28
29struct GlobalFP : public GlobalVal {
30 GlobalFP(const std::string &varName, int dim) : GlobalVal(varName, ExprType().FP(dim).Varying()) {
31 val.assign(dim, 0);
32 }
33
34 std::vector<double> val;
35 void eval(double *result) {
36 for (int i = 0; i < type().dim(); i++) result[i] = val[i];
37 }
38 void eval(const char **result) { assert(false); }
39 bool isVec() { return type().dim() > 1; }
40};
41
42struct GlobalStr : public GlobalVal {
43 GlobalStr(const std::string &varName) : GlobalVal(varName, ExprType().String().Varying()), val(0) {}
44
45 const char *val;
46 void eval(double *result) { assert(false); }
47 void eval(const char **result) { *result = val; }
48 bool isVec() { return 0; }
49};
50}
51
52namespace {
53
54std::set<SeExpr2::DExpression *> getAffectedExpr(SeExpr2::GlobalVal *gv) {
55 std::set<SeExpr2::DExpression *> ret;
56
57 std::set<SeExpr2::DExpression *> workList = gv->users;
58 while (workList.size()) {
59 SeExpr2::DExpression *de = *workList.begin();
60 workList.erase(de);
61 ret.insert(de);
62 workList.insert(de->val->users.begin(), de->val->users.end());
63 }
64
65 return ret;
66}
67
68std::set<SeExpr2::DExpression *> getTransitiveOperandExpr(SeExpr2::DExpression *expr) {
69 std::set<SeExpr2::DExpression *> ret;
70
71 std::set<SeExpr2::DExpression *> workList;
72 workList.insert(expr);
73 while (workList.size()) {
74 SeExpr2::DExpression *de = *workList.begin();
75 workList.erase(de);
76 ret.insert(de);
77 workList.insert(de->operandExprs.begin(), de->operandExprs.end());
78 }
79
80 return ret;
81}
82
83std::set<SeExpr2::DExpression *> tmpOperandExprs;
84std::set<SeExpr2::GlobalVal *> tmpOperandVars;
85}
86
87namespace SeExpr2 {
88
89DExpression::DExpression(const std::string &varName,
91 const std::string &e,
92 const ExprType &type,
94 : Expression(e, type, be), context(context) {
95 if (type.isFP())
96 val = new GlobalFP(varName, type.dim());
97 else if (type.isString())
98 val = new GlobalStr(varName);
99 else
100 assert(false);
101
104 prepIfNeeded();
105 operandExprs = tmpOperandExprs;
106 operandVars = tmpOperandVars;
107}
108
109const std::string &DExpression::name() const { return val->varName; }
110
111ExprVarRef *DExpression::resolveVar(const std::string &name) const {
112 // first time resolve var from all exprs & vars
113 // then resolve var from used exprs & vars
114 for (std::set<DExpression *>::iterator I = operandExprs.begin(), E = operandExprs.end(); I != E; ++I)
115 if ((*I)->name() == name) {
116 tmpOperandExprs.insert(*I);
117 (*I)->val->users.insert(const_cast<DExpression *>(this));
118 return (*I)->val;
119 }
120
121 for (std::set<GlobalVal *>::iterator I = operandVars.begin(), E = operandVars.end(); I != E; ++I)
122 if ((*I)->varName == name) {
123 tmpOperandVars.insert(*I);
124 (*I)->users.insert(const_cast<DExpression *>(this));
125 return *I;
126 }
127
128 addError(name + " fail resolveVar", 0, 0);
129 return 0;
130}
131
133 if (_desiredReturnType.isFP()) {
134 const double *ret = evalFP();
135 GlobalFP *fpVal = dynamic_cast<GlobalFP *>(val);
136 fpVal->val.assign(ret, ret + fpVal->val.size());
137 return;
138 }
139
141 GlobalStr *strVal = dynamic_cast<GlobalStr *>(val);
142 strVal->val = evalStr();
143}
144
146 for (std::set<DExpression *>::iterator I = AllExprs.begin(), E = AllExprs.end(); I != E; ++I) delete *I;
147
148 for (std::set<GlobalVal *>::iterator I = AllExternalVars.begin(), E = AllExternalVars.end(); I != E; ++I) delete *I;
149}
150
151VariableHandle Expressions::addExternalVariable(const std::string &variableName, ExprType seTy) {
152 std::pair<std::set<GlobalVal *>::iterator, bool> ret;
153
154 if (seTy.isFP())
155 ret = AllExternalVars.insert(new GlobalFP(variableName, seTy.dim()));
156 else if (seTy.isString())
157 ret = AllExternalVars.insert(new GlobalStr(variableName));
158 else
159 assert(false);
160
161 return ret.first;
162}
163
164ExprHandle Expressions::addExpression(const std::string &varName, ExprType seTy, const std::string &expr) {
165 std::pair<std::set<DExpression *>::iterator, bool> ret;
166 ret = AllExprs.insert(new DExpression(varName, *this, expr, seTy));
167 return ret.first;
168}
169
171 GlobalVal *thisvar = *vh;
172 unsigned initSize = static_cast<unsigned>(thisvar->users.size());
173 if (!initSize) return AllExternalVars.end();
174
175 std::set<DExpression *> ret = getAffectedExpr(thisvar);
176 exprToEval.insert(ret.begin(), ret.end());
177 // std::cout << "exprToEval size is " << exprToEval.size() << std::endl;
178 return vh;
179}
180
181void Expressions::setLoopVariable(VariableSetHandle handle, double *values, unsigned dim) {
182 if (handle == AllExternalVars.end()) return;
183
184 GlobalFP *thisvar = dynamic_cast<GlobalFP *>(*handle);
185 assert(thisvar && "set value to variable with incompatible types.");
186
187 assert(dim == thisvar->val.size());
188 for (unsigned i = 0; i < dim; ++i) thisvar->val[i] = values[i];
189}
190
191void Expressions::setLoopVariable(VariableSetHandle handle, const char *values) {
192 if (handle == AllExternalVars.end()) return;
193
194 GlobalStr *thisvar = dynamic_cast<GlobalStr *>(*handle);
195 assert(thisvar && "set value to variable with incompatible types.");
196 thisvar->val = values;
197}
198
199void Expressions::setVariable(VariableHandle handle, double *values, unsigned dim) {
200 GlobalFP *thisvar = dynamic_cast<GlobalFP *>(*handle);
201 assert(thisvar && "set value to variable with incompatible types.");
202
203 assert(dim == thisvar->val.size());
204 for (unsigned i = 0; i < dim; ++i) thisvar->val[i] = values[i];
205
206 // eval loop invariant now.
207 std::set<DExpression *> ret = getAffectedExpr(thisvar);
208 for (std::set<DExpression *>::iterator I = ret.begin(), E = ret.end(); I != E; ++I) (*I)->eval();
209}
210
211void Expressions::setVariable(VariableHandle handle, const char *values) {
212 GlobalStr *thisvar = dynamic_cast<GlobalStr *>(*handle);
213 assert(thisvar && "set value to variable with incompatible types.");
214 thisvar->val = values;
215
216 // eval loop invariant now.
217 std::set<DExpression *> ret = getAffectedExpr(thisvar);
218 for (std::set<DExpression *>::iterator I = ret.begin(), E = ret.end(); I != E; ++I) (*I)->eval();
219}
220
222 bool ret = true;
223 for (std::set<DExpression *>::const_iterator I = AllExprs.begin(), E = AllExprs.end(); I != E; ++I)
224 ret &= (*I)->isValid();
225 return ret;
226}
227
229 // std::cout << "exprToEval size is " << exprToEval.size() << std::endl;
230
231 DExpression *de = *eh;
232 std::set<DExpression *> all = getTransitiveOperandExpr(de);
233 // std::cout << "all size is " << all.size() << std::endl;
234
235 std::vector<DExpression *>::iterator it;
236
237 std::vector<DExpression *> ret1(all.size());
238 it = std::set_intersection(all.begin(), all.end(), exprToEval.begin(), exprToEval.end(), ret1.begin());
239 ret1.resize(it - ret1.begin());
240
241 std::vector<DExpression *> ret2(ret1.size());
242 it = std::set_difference(ret1.begin(), ret1.end(), exprEvaled.begin(), exprEvaled.end(), ret2.begin());
243 ret2.resize(it - ret2.begin());
244
245 exprEvaled.insert(ret2.begin(), ret2.end());
246
247 // std::cout << "ret2 size is " << ret2.size() << std::endl;
248 return std::make_pair(eh, ret2);
249}
250
251const std::vector<double> &Expressions::evalFP(ExprEvalHandle eeh) {
252 // std::cout << "eeh.second.size() is " << eeh.second.size() << std::endl;
253 for (std::vector<DExpression *>::iterator I = eeh.second.begin(), E = eeh.second.end(); I != E; ++I) (*I)->eval();
254
255 GlobalFP *thisvar = dynamic_cast<GlobalFP *>((*eeh.first)->val);
256
257 // std::cout << thisvar->val[0] << ","
258 // << thisvar->val[1] << ","
259 // << thisvar->val[2] << std::endl;
260 return thisvar->val;
261}
262
264 for (std::vector<DExpression *>::iterator I = eeh.second.begin(), E = eeh.second.end(); I != E; ++I) (*I)->eval();
265
266 GlobalStr *thisvar = dynamic_cast<GlobalStr *>((*eeh.first)->val);
267 return thisvar->val;
268}
269}
std::set< DExpression * > operandExprs
ExprVarRef * resolveVar(const std::string &name) const
const std::string & name() const
DExpression(const std::string &varName, Expressions &context, const std::string &e, const ExprType &type=ExprType().FP(3), EvaluationStrategy be=defaultEvaluationStrategy)
Expressions & context
std::set< GlobalVal * > operandVars
bool isString() const
Definition ExprType.h:169
bool isFP() const
Direct is predicate checks.
Definition ExprType.h:164
int dim() const
Definition ExprType.h:160
abstract class for implementing variable references
Definition Expression.h:45
virtual ExprType type() const
returns (current) type
Definition Expression.h:59
main expression class
Definition Expression.h:76
EvaluationStrategy
Types of evaluation strategies that are available.
Definition Expression.h:79
const char * evalStr(VarBlock *varBlock=nullptr) const
void addError(const std::string &error, const int startPos, const int endPos) const
Definition Expression.h:205
const double * evalFP(VarBlock *varBlock=nullptr) const
ExprType _desiredReturnType
Definition Expression.h:266
void prepIfNeeded() const
Definition Expression.h:274
VariableSetHandle getLoopVarSetHandle(VariableHandle vh)
const std::vector< double > & evalFP(ExprEvalHandle eeh)
void setLoopVariable(VariableSetHandle handle, double *values, unsigned dim)
std::set< GlobalVal * > AllExternalVars
ExprEvalHandle getExprEvalHandle(ExprHandle eh)
ExprHandle addExpression(const std::string &varName, ExprType seTy, const std::string &expr)
std::set< DExpression * > exprEvaled
const char * evalStr(ExprEvalHandle eeh)
std::set< DExpression * > exprToEval
void setVariable(VariableHandle handle, double *values, unsigned dim)
std::set< DExpression * > AllExprs
VariableHandle addExternalVariable(const std::string &variableName, ExprType seTy)
GlobalVal(const std::string &varName, const SeExpr2::ExprType &et)
std::set< DExpression * > users
you may not use this file except in compliance with the License and the following modification to it
Definition license.txt:10
std::set< GlobalVal * >::iterator VariableSetHandle
std::set< GlobalVal * >::iterator VariableHandle
std::pair< ExprHandle, std::vector< DExpression * > > ExprEvalHandle
std::set< DExpression * >::iterator ExprHandle
void eval(const char **result)
std::vector< double > val
GlobalFP(const std::string &varName, int dim)
void eval(double *result)
returns this variable's value by setting result
void eval(const char **result)
void eval(double *result)
returns this variable's value by setting result
GlobalStr(const std::string &varName)
</pre >< h3 > Binding our variable reference</h3 > If we now tried to use the variable would still not be found by our expressions To make it bindable we need to override the resolveVar() function as follows</pre >< h3 > Variable setting</h3 > Next we need to make a way of setting the variable As the controlling code will use the expression it will repeatedly alternate between setting the independent variables that are used and calling evaluate(). What it has to do depends very much on the application. In this case we only need to set the independent variable x as</pre >< h2 > Evaluating expressions</h2 > Evaluating an expression is pretty easy But before we can do that we need to make an instance< pre > GrapherExpr expr("x+x^2")
If a scalar is used in a vector context
Definition userdoc.txt:436