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