View difference between Paste ID: dZEZvpUj and FjKyRuyX
SHOW: | | - or go back to the newest paste.
1
/**
2
 * Author: F. Philipp
3
 *
4
 * Translation of
5
 * https://benchmarksgame.alioth.debian.org/u64q/program.php?test=mandelbrot&lang=rust&id=4
6
 * with minor changes
7
 *
8
 * Contains a bug resulting in slightly different results
9
 */
10
11-
#include <array>
11+
#include <Eigen/Dense>
12-
// using std::array
12+
13
14
#include <vector>
15-
#include <tuple>
15+
16-
// using std::tuple
16+
17
// using std::stoi
18
#include <iostream>
19
// using std::cout
20
#include <algorithm>
21
// using std::transform
22-
// using std::transform, std::all_of
22+
23-
#include <functional>
23+
24-
// using std::bind, std::placeholders, std::multiplies, std::plus, std::minus
24+
25
26
namespace {
27
28
  constexpr int MAX_ITER = 50;
29
  constexpr int VLEN = CHAR_BIT;
30
  using double_t = double;
31
32
  using Vecf64 = Eigen::Array<double_t, VLEN, 1>;
33-
  typedef double double_t;
33+
34
  template<class T>
35-
  struct Vecf64
35+
  using vector = std::vector<T, Eigen::aligned_allocator<T> >;
36
37-
    using array_type = std::array<double_t, VLEN>;
37+
38-
    array_type array;
38+
39
    Vecf64 cr, cr2;
40-
    Vecf64() = default;
40+
41
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
42-
    explicit Vecf64(double_t s) noexcept
42+
43-
    { array.fill(s); }
43+
44
  class Mandelbrot8
45-
    Vecf64& operator=(const Vecf64&) = default;
45+
46
    Vecf64 zr, zi, tr, ti, cr;
47-
    Vecf64& operator=(double_t s) noexcept
47+
48
49-
      array.fill(s);
49+
50-
      return *this;
50+
51
      for(int i = 0; i < iterations; ++i) {
52-
    double_t& operator[](int idx) noexcept
52+
53-
    { return array[idx]; }
53+
54
        tr = zr.square();
55-
    double_t operator[](int idx) const noexcept
55+
56-
    { return array[idx]; }
56+
57
    }
58-
    template<class BinaryFunctor>
58+
59-
    Vecf64& inplace_transform(const Vecf64& o, BinaryFunctor f)
59+
60
      return ((tr + ti) > 4).all();
61-
      array_type::iterator first = array.begin();
61+
62-
      std::transform(first, array.end(), o.array.begin(), first, f);
62+
63-
      return *this;
63+
64
      const Vecf64 trti = tr + ti;
65-
    template<class BinaryFunctor>
65+
66-
    Vecf64 transform(const Vecf64& o, BinaryFunctor f) const
66+
67
        if(trti[i] <= 4.)
68-
      Vecf64 rtrn;
68+
69-
      std::transform(array.begin(), array.end(), o.array.begin(),
69+
70-
                     rtrn.array.begin(), f);
70+
71-
      return rtrn;
71+
72
  public:
73-
    template<class UnaryFunctor>
73+
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
74-
    Vecf64& inplace_transform(UnaryFunctor f)
74+
75
    explicit Mandelbrot8(double_t ci) noexcept
76-
      array_type::iterator first = array.begin();
76+
77-
      std::transform(first, array.end(), first, f);
77+
78-
      return *this;
78+
79
    unsigned char operator()(const CrCr2Chunk& col_invariant) noexcept
80-
    template<class UnaryFunctor>
80+
81-
    Vecf64 transform(UnaryFunctor f) const
81+
82
      zi = ci;
83-
      Vecf64 rtrn;
83+
84-
      std::transform(array.begin(), array.end(), rtrn.array.begin(), f);
84+
85-
      return rtrn;
85+
86
      advance(4);
87
      constexpr int n = MAX_ITER / 5 - 1;
88-
    Vecf64& operator*=(const Vecf64& o) noexcept
88+
89-
    { return inplace_transform(o, std::multiplies<double_t>{}); }
89+
90
          return 0;
91-
    Vecf64 operator*(const Vecf64& o) const noexcept
91+
92-
    { return transform(o, std::multiplies<double_t>{}); }
92+
93
      return to_byte();
94-
    Vecf64& operator*=(double_t s) noexcept
94+
95
  };
96-
      return inplace_transform(std::bind(std::multiplies<double_t>{},
96+
97-
                                         std::placeholders::_1, s));
97+
  vector<CrCr2Chunk> make_column_invariant(int bytes_per_line)
98
  {
99-
    Vecf64 operator*(double_t s) const noexcept
99+
100
    const double_t inv = 2. / pixels_per_line;
101-
      return transform(std::bind(std::multiplies<double_t>{},
101+
    vector<CrCr2Chunk> rtrn(bytes_per_line);
102-
                                 std::placeholders::_1, s));
102+
103
    for(int col_byte = 0; col_byte < bytes_per_line; ++col_byte) {
104-
    friend Vecf64 operator*(double_t left, const Vecf64& right) noexcept
104+
105-
    { return right * left; }
105+
106
        const int col = col_byte * VLEN + bit;
107-
    Vecf64& operator+=(const Vecf64& o) noexcept
107+
108-
    { return inplace_transform(o, std::plus<double_t>{}); }
108+
109
      chunk.cr2 = chunk.cr.square();
110-
    Vecf64 operator+(const Vecf64& o) const noexcept
110+
111-
    { return transform(o, std::plus<double_t>{}); }
111+
112
  }
113-
    Vecf64& operator+=(double_t s) noexcept
113+
114
  std::vector<unsigned char>
115-
      return inplace_transform(std::bind(std::plus<double_t>{},
115+
  make_bitmap(const vector<CrCr2Chunk>& column_invariants)
116-
                                         std::placeholders::_1, s));
116+
117
    const int bytes_per_line = static_cast<int>(column_invariants.size());
118-
    Vecf64 operator+(double_t s) const noexcept
118+
119
    const double_t inv = 2. / pixels_per_line;
120-
      return transform(std::bind(std::plus<double_t>{},
120+
121-
                                 std::placeholders::_1, s));
121+
122
    for(int row = 0; row < pixels_per_line; ++row) {
123-
    friend Vecf64 operator+(double_t left, const Vecf64& right) noexcept
123+
124-
    { return right + left; }
124+
125
      std::transform(column_invariants.begin(), column_invariants.end(),
126-
    Vecf64& operator-=(const Vecf64& o) noexcept
126+
127-
    { return inplace_transform(o, std::minus<double_t>{}); }
127+
128
    }
129-
    Vecf64 operator-(const Vecf64& o) const noexcept
129+
130-
    { return transform(o, std::minus<double_t>{}); }
130+
131
  void print_pbm(const std::vector<unsigned char>& bitmap,
132-
    Vecf64& operator-=(double_t s) noexcept
132+
133
                 std::ostream& binary_output)
134-
      return inplace_transform(std::bind(std::minus<double_t>{},
134+
135-
                                         std::placeholders::_1, s));
135+
136
                  << ' ' << pixels_per_line
137-
    Vecf64 operator-(double_t s) const noexcept
137+
138
    binary_output.write(reinterpret_cast<const char*>(bitmap.data()),
139-
      return transform(std::bind(std::minus<double_t>{},
139+
140-
                                 std::placeholders::_1, s));
140+
141
  }
142-
    friend Vecf64 operator-(double_t left, const Vecf64& right) noexcept
142+
143
144-
      return right.transform(std::bind(std::minus<double_t>{},
144+
145-
                                       left, std::placeholders::_1));
145+
146
  /* number of pixels in each dimension */
147-
    Vecf64& inplace_square() noexcept
147+
148
  if(argc > 1)
149-
      return inplace_transform(std::bind(std::multiplies<double_t>{},
149+
150-
                                         std::placeholders::_1,
150+
151-
                                         std::placeholders::_1));
151+
152
  const vector<CrCr2Chunk> column_invariants =
153-
    Vecf64 square() const noexcept
153+
154
  const std::vector<unsigned char> bitmap = make_bitmap(column_invariants);
155-
      return transform(std::bind(std::multiplies<double_t>{},
155+
156-
                                 std::placeholders::_1,
156+