NaiveIRGenerator.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include "NaiveIRGenerator.h"
  2. #include "IterationIR.h"
  3. using mnd::NaiveIRGenerator;
  4. template<typename T>
  5. NaiveIRGenerator<T>::NaiveIRGenerator(const mnd::ir::Formula& irf,
  6. mnd::Precision prec) :
  7. mnd::MandelGenerator{ prec },
  8. form{ irf }
  9. {
  10. }
  11. template<typename U>
  12. void NaiveIRGenerator<U>::generate(const mnd::MandelInfo& info, float* data)
  13. {
  14. const MandelViewport& view = info.view;
  15. const bool parallel = true;
  16. using T = double;
  17. T viewx = mnd::convert<T>(view.x);
  18. T viewy = mnd::convert<T>(view.y);
  19. T wpp = mnd::convert<T>(view.width / info.bWidth);
  20. T hpp = mnd::convert<T>(view.height / info.bHeight);
  21. if constexpr (parallel)
  22. omp_set_num_threads(omp_get_num_procs());
  23. //#pragma omp parallel for schedule(static, 1) if (parallel)
  24. for (long j = 0; j < info.bHeight; j++) {
  25. T y = viewy + T(double(j)) * hpp;
  26. long i = 0;
  27. for (i; i < info.bWidth; i++) {
  28. T x = viewx + T(double(i)) * wpp;
  29. T a = calc(form.startA, x, y, 0, 0);
  30. T b = calc(form.startB, x, y, 0, 0);
  31. int k = 0;
  32. for (k = 0; k < info.maxIter; k++) {
  33. double newA = calc(form.newA, a, b, x, y);
  34. double newB = calc(form.newB, a, b, x, y);
  35. a = newA;
  36. b = newB;
  37. if (a * a + b * b >= 16.0)
  38. break;
  39. }
  40. data[i + j * info.bWidth] = float(k);
  41. }
  42. }
  43. }
  44. template<typename T>
  45. struct EvalNode
  46. {
  47. };
  48. template<typename T>
  49. double NaiveIRGenerator<T>::calc(mnd::ir::Node* expr, double a, double b, double x, double y)
  50. {
  51. struct DoubleVisitor
  52. {
  53. double a, b, x, y;
  54. double visitNode(ir::Node* n) {
  55. auto& nodeData = getNodeData(n);
  56. //if (std::get_a)
  57. return std::visit(*this, *n);
  58. }
  59. const std::any& getNodeData(ir::Node* n) {
  60. return std::visit([](auto& n) {
  61. return n.nodeData;
  62. }, *n);
  63. }
  64. double operator()(const ir::Constant& c) {
  65. return mnd::convert<double>(c.value);
  66. }
  67. double operator()(const ir::Variable& v) {
  68. if (v.name == "z_re")
  69. return a;
  70. else if (v.name == "z_im")
  71. return b;
  72. else if (v.name == "c_re")
  73. return x;
  74. else if (v.name == "c_im")
  75. return y;
  76. else
  77. return 0.0;
  78. }
  79. double operator()(const ir::Negation& n) {
  80. return -visitNode(n.value);
  81. }
  82. double operator()(const ir::Addition& n) {
  83. return visitNode(n.left) + visitNode(n.right);
  84. }
  85. double operator()(const ir::Subtraction& n) {
  86. return visitNode(n.left) - visitNode(n.right);
  87. }
  88. double operator()(const ir::Multiplication& n) {
  89. return visitNode(n.left) * visitNode(n.right);
  90. }
  91. double operator()(const ir::Division& n) {
  92. return visitNode(n.left) / visitNode(n.right);
  93. }
  94. double operator()(const ir::Atan2& n) {
  95. return ::atan2(visitNode(n.left), visitNode(n.right));
  96. }
  97. double operator()(const ir::Pow& n) {
  98. return ::pow(visitNode(n.left), visitNode(n.right));
  99. }
  100. double operator()(const ir::Cos& n) {
  101. return ::cos(visitNode(n.value));
  102. }
  103. double operator()(const ir::Sin& n) {
  104. return ::sin(visitNode(n.value));
  105. }
  106. double operator()(const ir::Exp& n) {
  107. return ::exp(visitNode(n.value));
  108. }
  109. double operator()(const ir::Ln& n) {
  110. return ::log(visitNode(n.value));
  111. }
  112. };
  113. DoubleVisitor dv{ a, b, x, y };
  114. return dv.visitNode(expr);
  115. }