Maestro 0.1.0
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
Expr.h
Go to the documentation of this file.
1
11#pragma once
12
13#ifndef _EXPR_H_
14#define _EXPR_H_
15
16#ifdef DEBUG
17#define BOOST_SPIRIT_QI_DEBUG
18#endif // DEBUG
19
20#define _USE_MATH_DEFINES
21#include <math.h>
22
23#include <boost/fusion/include/adapt_struct.hpp>
24#include <boost/fusion/include/io.hpp>
25#include <boost/phoenix.hpp>
26#include <boost/phoenix/object.hpp>
27#include <boost/spirit/include/qi.hpp>
28
29#include <algorithm>
30#include <optional>
31#include <string>
32#include <variant>
33#include <vector>
34
35namespace qasm {
36namespace qi = boost::spirit::qi;
37namespace ascii = boost::spirit::ascii;
38namespace phx = boost::phoenix;
39
41public:
42 virtual ~AbstractSyntaxTree() = default;
43 virtual double Eval() const { return 0; }
44 virtual double
45 Eval(const std::unordered_map<std::string, double> &variables) const {
46 return 0;
47 }
48
49protected:
50 AbstractSyntaxTree() = default;
55};
56
57typedef std::shared_ptr<AbstractSyntaxTree> AbstractSyntaxTreePtr;
58
59template <typename Expr> static AbstractSyntaxTreePtr Clone(Expr const &t) {
60 return std::make_shared<Expr>(t);
61}
62
63// for expressions (to be evaluated, typically those are values for parameters
64// for gates)
65
67public:
68 Constant(double value = 0) : value(value) {}
69 Constant(int value) : value(value) {}
70
71 Constant &operator=(int value) {
72 this->value = value;
73 return *this;
74 }
75 Constant &operator=(double value) {
76 this->value = value;
77 return *this;
78 }
79
80 double Eval() const override { return value; }
81 double Eval(
82 const std::unordered_map<std::string, double> &variables) const override {
83 return value;
84 }
85
86private:
87 double value;
88};
89
91 template <typename> struct result {
92 typedef Constant type;
93 };
94
95 template <typename C> Constant operator()(C op) const { return Constant(op); }
96};
97
98phx::function<MakeConstantExpression> MakeConstant;
99
101public:
102 Variable(const std::string &value = "") : value(value) {}
103
104 Variable &operator=(int value) {
105 this->value = value;
106 return *this;
107 }
108
109 double Eval() const override { return 0; }
110 double Eval(
111 const std::unordered_map<std::string, double> &variables) const override {
112 auto it = variables.find(value);
113 if (it != variables.end())
114 return it->second;
115 else
116 throw std::invalid_argument("Variable not found: " + value);
117
118 return 0;
119 }
120
121private:
122 std::string value;
123};
124
126 template <typename> struct result {
127 typedef Variable type;
128 };
129
130 template <typename V> Variable operator()(V v) const { return Variable(v); }
131};
132
133phx::function<MakeVariableExpression> MakeVariable;
134
136public:
137 template <typename L, typename R>
138 BinaryOperator(char op, const L &left, const R &right)
139 : op(op), left(Clone(left)), right(Clone(right)) {}
140
141 double Eval() const override {
142 switch (op) {
143 case '+':
144 return left->Eval() + right->Eval();
145 case '-':
146 return left->Eval() - right->Eval();
147 case '*':
148 return left->Eval() * right->Eval();
149 case '/':
150 return left->Eval() / right->Eval();
151 case '^':
152 return pow(left->Eval(), right->Eval());
153 default:
154 throw std::invalid_argument("Unknown binary operator");
155 }
156
157 return 0;
158 }
159
160 double Eval(
161 const std::unordered_map<std::string, double> &variables) const override {
162 switch (op) {
163 case '+':
164 return left->Eval(variables) + right->Eval(variables);
165 case '-':
166 return left->Eval(variables) - right->Eval(variables);
167 case '*':
168 return left->Eval(variables) * right->Eval(variables);
169 case '/':
170 return left->Eval(variables) / right->Eval(variables);
171 case '^':
172 return pow(left->Eval(variables), right->Eval(variables));
173 default:
174 throw std::invalid_argument("Unknown binary operator");
175 }
176
177 return 0;
178 }
179
180private:
181 char op;
182 AbstractSyntaxTreePtr left, right;
183};
184
186 template <typename, typename, typename> struct result {
188 };
189
190 template <typename C, typename L, typename R>
191 BinaryOperator operator()(C op, const L &lhs, const R &rhs) const {
192 return BinaryOperator(op, lhs, rhs);
193 }
194};
195
196phx::function<MakeBinaryExpression> MakeBinary;
197
199public:
200 UnaryOperator() : op('+') {}
201
202 template <typename R>
203 UnaryOperator(char op, const R &right) : op(op), right(Clone(right)) {}
204
205 double Eval() const override {
206 switch (op) {
207 case '+':
208 return right->Eval();
209 case '-':
210 return -right->Eval();
211 default:
212 throw std::invalid_argument("Unknown unary operator");
213 }
214
215 return 0;
216 }
217
218 double Eval(
219 const std::unordered_map<std::string, double> &variables) const override {
220 switch (op) {
221 case '+':
222 return right->Eval(variables);
223 case '-':
224 return -right->Eval(variables);
225 default:
226 throw std::invalid_argument("Unknown unary operator");
227 }
228 return 0;
229 }
230
231private:
232 char op;
234};
235
237 template <typename, typename> struct result {
239 };
240
241 template <typename C, typename R>
242 UnaryOperator operator()(C op, const R &rhs) const {
243 return UnaryOperator(op, rhs);
244 }
245};
246
247phx::function<MakeUnaryExpression> MakeUnary;
248
250public:
251 template <typename F>
252 Function(const std::string &func, const F &param)
253 : func(func), param(Clone(param)) {}
254
255 double Eval() const override {
256 if (func == "sin")
257 return sin(param->Eval());
258 else if (func == "cos")
259 return cos(param->Eval());
260 else if (func == "tan")
261 return tan(param->Eval());
262 else if (func == "exp")
263 return exp(param->Eval());
264 else if (func == "ln")
265 return log(param->Eval());
266 else if (func == "sqrt")
267 return sqrt(param->Eval());
268
269 throw std::invalid_argument("Unknown function");
270
271 return 0;
272 }
273
274 double Eval(
275 const std::unordered_map<std::string, double> &variables) const override {
276 if (func == "sin")
277 return sin(param->Eval(variables));
278 else if (func == "cos")
279 return cos(param->Eval(variables));
280 else if (func == "tan")
281 return tan(param->Eval(variables));
282 else if (func == "exp")
283 return exp(param->Eval(variables));
284 else if (func == "ln")
285 return log(param->Eval(variables));
286 else if (func == "sqrt")
287 return sqrt(param->Eval(variables));
288
289 throw std::invalid_argument("Unknown function");
290
291 return 0;
292 }
293
294private:
295 std::string func;
297};
298
300 template <typename, typename, typename> struct result {
301 typedef Function type;
302 };
303
304 template <typename Params>
305 Function operator()(const std::string &funcName, const Params &params) const {
306 return Function(funcName, params);
307 }
308};
309
310phx::function<MakeFunctionExpression> MakeFunction;
311
313public:
315 ~Expression() override {}
316
317 template <typename E> Expression(E const &e) : expr(Clone(e)) {}
318
319 double Eval() const override { return expr->Eval(); }
320
321 double Eval(
322 const std::unordered_map<std::string, double> &variables) const override {
323 return expr->Eval(variables);
324 }
325
326 friend AbstractSyntaxTreePtr Clone(Expression const &e) { return e.expr; }
327
328private:
330};
331} // namespace qasm
332
333#endif
AbstractSyntaxTree(AbstractSyntaxTree &&)=default
AbstractSyntaxTree(const AbstractSyntaxTree &)=default
virtual ~AbstractSyntaxTree()=default
virtual double Eval(const std::unordered_map< std::string, double > &variables) const
Definition Expr.h:45
virtual double Eval() const
Definition Expr.h:43
AbstractSyntaxTree & operator=(const AbstractSyntaxTree &)=default
AbstractSyntaxTree & operator=(AbstractSyntaxTree &&)=default
double Eval() const override
Definition Expr.h:141
double Eval(const std::unordered_map< std::string, double > &variables) const override
Definition Expr.h:160
BinaryOperator(char op, const L &left, const R &right)
Definition Expr.h:138
Constant(int value)
Definition Expr.h:69
double Eval() const override
Definition Expr.h:80
Constant(double value=0)
Definition Expr.h:68
Constant & operator=(int value)
Definition Expr.h:71
Constant & operator=(double value)
Definition Expr.h:75
double Eval(const std::unordered_map< std::string, double > &variables) const override
Definition Expr.h:81
~Expression() override
Definition Expr.h:315
friend AbstractSyntaxTreePtr Clone(Expression const &e)
Definition Expr.h:326
double Eval() const override
Definition Expr.h:319
Expression(E const &e)
Definition Expr.h:317
double Eval(const std::unordered_map< std::string, double > &variables) const override
Definition Expr.h:321
Function(const std::string &func, const F &param)
Definition Expr.h:252
double Eval() const override
Definition Expr.h:255
double Eval(const std::unordered_map< std::string, double > &variables) const override
Definition Expr.h:274
UnaryOperator(char op, const R &right)
Definition Expr.h:203
double Eval() const override
Definition Expr.h:205
double Eval(const std::unordered_map< std::string, double > &variables) const override
Definition Expr.h:218
Variable & operator=(int value)
Definition Expr.h:104
double Eval() const override
Definition Expr.h:109
Variable(const std::string &value="")
Definition Expr.h:102
double Eval(const std::unordered_map< std::string, double > &variables) const override
Definition Expr.h:110
phx::function< MakeFunctionExpression > MakeFunction
Definition Expr.h:310
phx::function< MakeUnaryExpression > MakeUnary
Definition Expr.h:247
phx::function< MakeBinaryExpression > MakeBinary
Definition Expr.h:196
static AbstractSyntaxTreePtr Clone(Expr const &t)
Definition Expr.h:59
std::shared_ptr< AbstractSyntaxTree > AbstractSyntaxTreePtr
Definition Expr.h:57
phx::function< MakeVariableExpression > MakeVariable
Definition Expr.h:133
phx::function< MakeConstantExpression > MakeConstant
Definition Expr.h:98
BinaryOperator operator()(C op, const L &lhs, const R &rhs) const
Definition Expr.h:191
Constant operator()(C op) const
Definition Expr.h:95
Function operator()(const std::string &funcName, const Params &params) const
Definition Expr.h:305
UnaryOperator operator()(C op, const R &rhs) const
Definition Expr.h:242
Variable operator()(V v) const
Definition Expr.h:130