21#include <ql/errors.hpp>
23#include <boost/make_shared.hpp>
30struct RandomASTGenerator {
31 RandomASTGenerator(
const Size maxSequenceLength,
const Size maxDepth,
const Size seed)
32 : maxSequenceLength_(maxSequenceLength), maxDepth_(maxDepth), gen_(seed) {}
34 void createInstructionSequence() {
35 std::uniform_int_distribution<> seq(1, maxSequenceLength_);
36 std::uniform_int_distribution<> instr(0, depth >= maxDepth_ ? 4 : 6);
38 std::vector<ASTNodePtr> args;
39 for (
int i = 0; i < seq(gen_); ++i) {
40 switch (instr(gen_)) {
63 QL_FAIL(
"internal error:");
65 args.push_back(current);
67 current = QuantLib::ext::make_shared<SequenceNode>(args);
71 void createRequire() {
74 current = QuantLib::ext::make_shared<RequireNode>(std::vector<ASTNodePtr>(1, current));
79 std::uniform_int_distribution<> seq(1, 3);
80 std::vector<ASTNodePtr> vars;
81 for (
int i = 0; i < seq(gen_); ++i) {
82 vars.push_back(QuantLib::ext::make_shared<VariableNode>(createVariableName()));
84 current = QuantLib::ext::make_shared<SortNode>(vars);
87 void createPermute() {
88 std::uniform_int_distribution<> seq(2, 3);
89 std::vector<ASTNodePtr> vars;
90 for (
int i = 0; i < seq(gen_); ++i) {
91 vars.push_back(QuantLib::ext::make_shared<VariableNode>(createVariableName()));
93 current = QuantLib::ext::make_shared<PermuteNode>(vars);
96 void createDeclaration() {
97 std::uniform_int_distribution<> seq(1, maxSequenceLength_);
99 std::vector<ASTNodePtr> args;
100 for (
int i = 0; i < seq(gen_); ++i) {
102 args.push_back(current);
104 current = QuantLib::ext::make_shared<DeclarationNumberNode>(args);
108 void createIfThenElse() {
110 std::uniform_int_distribution<> yn(0, 1);
111 std::vector<ASTNodePtr> args;
113 args.push_back(current);
114 createInstructionSequence();
115 args.push_back(current);
117 createInstructionSequence();
118 args.push_back(current);
120 current = QuantLib::ext::make_shared<IfThenElseNode>(args);
126 std::vector<ASTNodePtr> args;
128 args.push_back(current);
130 args.push_back(current);
132 args.push_back(current);
133 createInstructionSequence();
134 args.push_back(current);
135 current = QuantLib::ext::make_shared<LoopNode>(createVariableName(), args);
139 void createAssignment() {
141 std::vector<ASTNodePtr> args;
143 args.push_back(current);
145 args.push_back(current);
146 current = QuantLib::ext::make_shared<AssignmentNode>(args);
150 void createCondition() {
151 std::uniform_int_distribution<> dep(0, maxDepth_);
152 std::uniform_int_distribution<> cond(0, 5);
153 std::uniform_int_distribution<> andor(0, 1);
155 if (depth + dep(gen_) >= maxDepth_) {
156 std::vector<ASTNodePtr> args;
158 args.push_back(current);
160 args.push_back(current);
161 switch (cond(gen_)) {
163 current = QuantLib::ext::make_shared<ConditionEqNode>(args);
166 current = QuantLib::ext::make_shared<ConditionNeqNode>(args);
169 current = QuantLib::ext::make_shared<ConditionGeqNode>(args);
172 current = QuantLib::ext::make_shared<ConditionGtNode>(args);
175 current = QuantLib::ext::make_shared<ConditionLeqNode>(args);
178 current = QuantLib::ext::make_shared<ConditionLtNode>(args);
181 QL_FAIL(
"internal error");
184 std::vector<ASTNodePtr> args;
186 args.push_back(current);
188 args.push_back(current);
189 switch (andor(gen_)) {
191 current = QuantLib::ext::make_shared<ConditionAndNode>(args);
194 current = QuantLib::ext::make_shared<ConditionOrNode>(args);
197 QL_FAIL(
"internal error");
204 std::uniform_int_distribution<> dep(0, maxDepth_);
205 std::uniform_int_distribution<> pm(0, 3);
207 if (depth + dep(gen_) >= maxDepth_) {
210 std::vector<ASTNodePtr> args;
212 args.push_back(current);
214 args.push_back(current);
217 current = QuantLib::ext::make_shared<OperatorPlusNode>(args);
220 current = QuantLib::ext::make_shared<OperatorMinusNode>(args);
223 current = QuantLib::ext::make_shared<OperatorMultiplyNode>(args);
226 current = QuantLib::ext::make_shared<OperatorDivideNode>(args);
229 QL_FAIL(
"internal error");
235 void createFactor() {
236 std::uniform_int_distribution<> dep(0, maxDepth_);
237 std::uniform_int_distribution<> sing(0, 2);
238 std::uniform_int_distribution<> fac(0, 25);
239 std::uniform_int_distribution<> yn(0, 1);
240 std::uniform_int_distribution<> zero123(0, 3);
241 std::uniform_int_distribution<> slot(0, 5);
242 std::uniform_int_distribution<> legNo(0, 5);
244 if (depth + dep(gen_) >= maxDepth_) {
245 switch (sing(gen_)) {
247 current = QuantLib::ext::make_shared<VariableNode>(createVariableName(), std::vector<ASTNodePtr>());
250 current = QuantLib::ext::make_shared<ConstantNumberNode>(createConstantNumber());
253 current = QuantLib::ext::make_shared<SizeOpNode>(createVariableName());
256 QL_FAIL(
"internal error");
259 std::vector<ASTNodePtr> args;
263 args.push_back(current);
264 current = QuantLib::ext::make_shared<NegateNode>(args);
268 args.push_back(current);
269 current = QuantLib::ext::make_shared<FunctionAbsNode>(args);
273 args.push_back(current);
274 current = QuantLib::ext::make_shared<FunctionExpNode>(args);
278 args.push_back(current);
279 current = QuantLib::ext::make_shared<FunctionLogNode>(args);
283 args.push_back(current);
284 current = QuantLib::ext::make_shared<FunctionSqrtNode>(args);
288 args.push_back(current);
289 current = QuantLib::ext::make_shared<FunctionNormalCdfNode>(args);
293 args.push_back(current);
294 current = QuantLib::ext::make_shared<FunctionNormalPdfNode>(args);
298 args.push_back(current);
300 args.push_back(current);
301 current = QuantLib::ext::make_shared<FunctionMaxNode>(args);
305 args.push_back(current);
307 args.push_back(current);
308 current = QuantLib::ext::make_shared<FunctionMinNode>(args);
312 args.push_back(current);
314 args.push_back(current);
315 current = QuantLib::ext::make_shared<FunctionPowNode>(args);
319 args.push_back(current);
321 args.push_back(current);
323 args.push_back(current);
325 args.push_back(current);
327 args.push_back(current);
329 args.push_back(current);
330 current = QuantLib::ext::make_shared<FunctionBlackNode>(args);
334 args.push_back(current);
336 args.push_back(current);
338 args.push_back(current);
339 current = QuantLib::ext::make_shared<FunctionDcfNode>(args);
343 args.push_back(current);
345 args.push_back(current);
347 args.push_back(current);
348 current = QuantLib::ext::make_shared<FunctionDaysNode>(args);
352 args.push_back(current);
354 args.push_back(current);
356 args.push_back(current);
358 args.push_back(current);
359 current = QuantLib::ext::make_shared<FunctionPayNode>(args);
363 args.push_back(current);
365 args.push_back(current);
367 args.push_back(current);
369 args.push_back(current);
373 args.push_back(current);
374 args.push_back(QuantLib::ext::make_shared<VariableNode>(createVariableName()));
378 args.push_back(current);
381 current = QuantLib::ext::make_shared<FunctionLogPayNode>(args);
386 args.push_back(current);
388 args.push_back(current);
391 args.push_back(current);
394 args.push_back(current);
397 args.push_back(current);
401 current = QuantLib::ext::make_shared<FunctionNpvNode>(args);
405 args.push_back(current);
407 args.push_back(current);
409 args.push_back(current);
412 args.push_back(current);
415 args.push_back(current);
418 args.push_back(current);
422 current = QuantLib::ext::make_shared<FunctionNpvMemNode>(args);
426 args.push_back(current);
428 args.push_back(current);
429 current = QuantLib::ext::make_shared<HistFixingNode>(args);
433 args.push_back(current);
435 args.push_back(current);
437 args.push_back(current);
438 current = QuantLib::ext::make_shared<FunctionDiscountNode>(args);
442 args.push_back(current);
444 args.push_back(current);
446 args.push_back(current);
448 args.push_back(current);
449 switch (zero123(gen_)) {
453 args.push_back(current);
455 args.push_back(current);
457 args.push_back(current);
459 args.push_back(current);
463 args.push_back(current);
465 args.push_back(current);
467 args.push_back(current);
469 args.push_back(current);
473 args.push_back(current);
475 args.push_back(current);
480 QL_FAIL(
"internal error");
482 current = QuantLib::ext::make_shared<FunctionFwdCompNode>(args);
486 args.push_back(current);
488 args.push_back(current);
490 args.push_back(current);
492 args.push_back(current);
493 switch (zero123(gen_)) {
497 args.push_back(current);
499 args.push_back(current);
501 args.push_back(current);
503 args.push_back(current);
507 args.push_back(current);
509 args.push_back(current);
511 args.push_back(current);
513 args.push_back(current);
517 args.push_back(current);
519 args.push_back(current);
524 QL_FAIL(
"internal error");
526 current = QuantLib::ext::make_shared<FunctionFwdAvgNode>(args);
530 args.push_back(current);
532 args.push_back(current);
534 args.push_back(current);
536 args.push_back(current);
537 current = QuantLib::ext::make_shared<FunctionAboveProbNode>(args);
541 args.push_back(current);
543 args.push_back(current);
545 args.push_back(current);
547 args.push_back(current);
548 current = QuantLib::ext::make_shared<FunctionBelowProbNode>(args);
552 args.push_back(current);
553 boost::fusion::vector<std::string, std::string> p(createVariableName(), createVariableName());
554 current = QuantLib::ext::make_shared<FunctionDateIndexNode>(p, args);
559 args.push_back(current);
560 current = QuantLib::ext::make_shared<VariableNode>(createVariableName(), args);
564 args.push_back(current);
566 args.push_back(current);
569 args.push_back(current);
571 current = QuantLib::ext::make_shared<VarEvaluationNode>(args);
574 QL_FAIL(
"internal error");
580 void createVarExpr() {
581 std::uniform_int_distribution<> dep(0, maxDepth_);
583 if (depth + dep(gen_) > maxDepth_) {
584 current = QuantLib::ext::make_shared<VariableNode>(createVariableName());
587 current = QuantLib::ext::make_shared<VariableNode>(createVariableName(), std::vector<ASTNodePtr>{current});
592 std::string createVariableName() {
593 std::uniform_int_distribution<> id(1, 999);
594 return "Var" + std::to_string(
id(gen_));
597 double createConstantNumber() {
598 std::uniform_int_distribution<> yn(0, 1);
599 std::uniform_int_distribution<> whole(-999, 999);
600 std::uniform_real_distribution<> real(-999, 999);
602 return static_cast<double>(whole(gen_));
604 return std::stod(std::to_string(real(gen_)));
611 const Size maxSequenceLength_, maxDepth_;
617 RandomASTGenerator gen(maxSequenceLength, maxDepth, seed);
618 gen.createInstructionSequence();
ASTNodePtr generateRandomAST(const Size maxSequenceLength, const Size maxDepth, const Size seed)
QuantLib::ext::shared_ptr< ASTNode > ASTNodePtr
Serializable Credit Default Swap.
random ast generator for testing purposes