Skip to content

Commit e8c9363

Browse files
pcaspersjenkins
authored andcommitted
QPR-11984 move filter implementation
1 parent 61db72e commit e8c9363

2 files changed

Lines changed: 131 additions & 44 deletions

File tree

QuantExt/qle/math/randomvariable.cpp

Lines changed: 124 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -28,33 +28,95 @@
2828

2929
namespace QuantExt {
3030

31-
Filter::~Filter() {}
31+
Filter::~Filter() { clear(); }
3232

33-
Filter::Filter() : n_(0), deterministic_(false) {}
33+
Filter::Filter() : n_(0), data_(nullptr), deterministic_(false) {}
3434

35-
Filter::Filter(const Size n, const bool value) : n_(n), data_(1, value), deterministic_(true) {}
35+
Filter::Filter(const Filter& r) {
36+
n_ = r.n_;
37+
constantData_ = r.constantData_;
38+
if (r.data_) {
39+
data_ = new bool[n_];
40+
std::memcpy(r.data_, data_, n_ * sizeof(bool));
41+
} else {
42+
data_ = nullptr;
43+
}
44+
deterministic_ = r.deterministic_;
45+
}
46+
47+
Filter::Filter(Filter&& r) {
48+
n_ = r.n_;
49+
constantData_ = r.constantData_;
50+
data_ = r.data_;
51+
r.data_ = nullptr;
52+
deterministic_ = r.deterministic_;
53+
}
54+
55+
Filter& Filter::operator=(const Filter& r) {
56+
if (r.deterministic_) {
57+
deterministic_ = true;
58+
if (data_) {
59+
delete[] data_;
60+
data_ = nullptr;
61+
}
62+
} else {
63+
deterministic_ = false;
64+
if (r.n_ != 0) {
65+
if (n_ != r.n_) {
66+
if (data_)
67+
delete[] data_;
68+
data_ = new bool[r.n_];
69+
}
70+
std::memcpy(r.data_, data_, r.n_ * sizeof(bool));
71+
} else {
72+
if (data_) {
73+
delete[] data_;
74+
data_ = nullptr;
75+
}
76+
}
77+
}
78+
n_ = r.n_;
79+
constantData_ = r.constantData_;
80+
return *this;
81+
}
82+
83+
Filter& Filter::operator=(Filter&& r) {
84+
n_ = r.n_;
85+
constantData_ = r.constantData_;
86+
if (data_) {
87+
delete[] data_;
88+
}
89+
data_ = r.data_;
90+
r.data_ = nullptr;
91+
deterministic_ = r.deterministic_;
92+
return *this;
93+
}
94+
95+
Filter::Filter(const Size n, const bool value) : n_(n), constantData_(value), deterministic_(true) {}
3696

3797
void Filter::clear() {
3898
n_ = 0;
39-
data_.clear();
40-
data_.shrink_to_fit();
99+
if (data_) {
100+
delete[] data_;
101+
data_ = nullptr;
102+
}
41103
deterministic_ = false;
42104
}
43105

44106
void Filter::updateDeterministic() {
45107
if (deterministic_ || !initialised())
46108
return;
47109
for (Size i = 1; i < n_; ++i) {
48-
if (data_[i] != data_.front())
110+
if (data_[i] != constantData_)
49111
return;
50112
}
51-
setAll(data_.front());
113+
setAll(constantData_);
52114
}
53115

54116
void Filter::set(const Size i, const bool v) {
55117
QL_REQUIRE(i < n_, "Filter::set(" << i << "): out of bounds, size is " << n_);
56118
if (deterministic_) {
57-
if (v != data_.front())
119+
if (v != constantData_)
58120
expand();
59121
else
60122
return;
@@ -63,21 +125,26 @@ void Filter::set(const Size i, const bool v) {
63125
}
64126

65127
void Filter::setAll(const bool v) {
66-
data_ = std::vector<bool>(1, v);
128+
QL_REQUIRE(n_ > 0, "Filter::setAll(): dimension is zero");
129+
if (data_) {
130+
delete[] data_;
131+
data_ = nullptr;
132+
}
133+
constantData_ = v;
67134
deterministic_ = true;
68135
}
69136

70137
bool Filter::operator[](const Size i) const {
71138
if (deterministic_)
72-
return data_.front();
139+
return constantData_ != 0;
73140
else
74141
return data_[i];
75142
}
76143

77144
bool Filter::at(const Size i) const {
78145
QL_REQUIRE(n_ > 0, "Filter::at(" << i << "): dimension is zero");
79146
if (deterministic_)
80-
return data_.front();
147+
return constantData_ != 0;
81148
QL_REQUIRE(i < n_, "Filter::at(" << i << "): out of bounds, size is " << n_);
82149
return operator[](i);
83150
}
@@ -86,15 +153,20 @@ void Filter::expand() {
86153
if (!deterministic_)
87154
return;
88155
deterministic_ = false;
89-
data_.resize(size(), data_.front());
156+
data_ = new bool[n_];
157+
std::fill(data_, data_ + n_, constantData_);
90158
}
91159

92160
bool operator==(const Filter& a, const Filter& b) {
93161
if (a.size() != b.size())
94162
return false;
95-
for (Size j = 0; j < a.size(); ++j)
96-
if (a[j] != b[j])
97-
return false;
163+
if (a.deterministic_ && b.deterministic_) {
164+
return a.constantData_ == b.constantData_;
165+
} else {
166+
for (Size j = 0; j < a.size(); ++j)
167+
if (a[j] != b[j])
168+
return false;
169+
}
98170
return true;
99171
}
100172

@@ -103,41 +175,41 @@ bool operator!=(const Filter& a, const Filter& b) { return !(a == b); }
103175
Filter operator&&(Filter x, const Filter& y) {
104176
QL_REQUIRE(!x.initialised() || !y.initialised() || x.size() == y.size(),
105177
"RandomVariable: x && y: x size (" << x.size() << ") must be equal to y size (" << y.size() << ")");
106-
if (x.deterministic() && !x.data_.front())
178+
if (x.deterministic() && x.constantData_ == 0)
107179
return Filter(x.size(), false);
108-
if (y.deterministic() && !y.data_.front())
180+
if (y.deterministic() && y.constantData_ == 0)
109181
return Filter(y.size(), false);
110182
if (!x.initialised() || !y.initialised())
111183
return Filter();
112184
if (!y.deterministic_)
113185
x.expand();
114-
else if (y.data_.front())
115-
return x;
116-
else
117-
return Filter(x.size(), false);
118-
for (Size i = 0; i < x.data_.size(); ++i) {
119-
x.data_[i] = x.data_[i] && y[i];
186+
if (x.deterministic_) {
187+
x.constantData_ = x.constantData_ && y.constantData_;
188+
} else {
189+
for (Size i = 0; i < x.size(); ++i) {
190+
x.data_[i] = x.data_[i] && y[i];
191+
}
120192
}
121193
return x;
122194
}
123195

124196
Filter operator||(Filter x, const Filter& y) {
125197
QL_REQUIRE(!x.initialised() || !y.initialised() || x.size() == y.size(),
126198
"RandomVariable: x || y: x size (" << x.size() << ") must be equal to y size (" << y.size() << ")");
127-
if (x.deterministic() && x.data_.front())
199+
if (x.deterministic() && x.constantData_)
128200
return Filter(x.size(), true);
129-
if (y.deterministic() && y.data_.front())
201+
if (y.deterministic() && y.constantData_)
130202
return Filter(y.size(), true);
131203
if (!x.initialised() || !y.initialised())
132204
return Filter();
133205
if (!y.deterministic_)
134206
x.expand();
135-
else if (!y.data_.front())
136-
return x;
137-
else
138-
return Filter(x.size(), true);
139-
for (Size i = 0; i < x.data_.size(); ++i) {
140-
x.data_[i] = x.data_[i] || y[i];
207+
if (x.deterministic_) {
208+
x.constantData_ = x.constantData_ || y.constantData_;
209+
} else {
210+
for (Size i = 0; i < x.size(); ++i) {
211+
x.data_[i] = x.data_[i] || y[i];
212+
}
141213
}
142214
return x;
143215
}
@@ -149,24 +221,29 @@ Filter equal(Filter x, const Filter& y) {
149221
"RandomVariable: equal(x,y): x size (" << x.size() << ") must be equal to y size (" << y.size() << ")");
150222
if (!y.deterministic_)
151223
x.expand();
152-
for (Size i = 0; i < x.data_.size(); ++i) {
153-
x.data_[i] = x.data_[i] == y[i];
224+
if (x.deterministic_) {
225+
x.constantData_ = x.constantData_ == y.constantData_;
226+
} else {
227+
for (Size i = 0; i < x.size(); ++i) {
228+
x.data_[i] = x.data_[i] == y[i];
229+
}
154230
}
155231
return x;
156232
}
157233

158234
Filter operator!(Filter x) {
159-
for (Size i = 0; i < x.data_.size(); ++i) {
160-
x.data_[i] = !x.data_[i];
235+
if (x.deterministic_)
236+
x.constantData_ = !x.constantData_;
237+
else {
238+
for (Size i = 0; i < x.size(); ++i) {
239+
x.data_[i] = !x.data_[i];
240+
}
161241
}
162242
return x;
163243
}
164244

165245
RandomVariable::~RandomVariable() { clear(); }
166246

167-
RandomVariable::RandomVariable(const Size n, const Real value, const Real time)
168-
: n_(n), constantData_(value), data_(nullptr), deterministic_(true), time_(time) {}
169-
170247
RandomVariable::RandomVariable() : n_(0), data_(nullptr), deterministic_(false), time_(Null<Real>()) {}
171248

172249
RandomVariable::RandomVariable(const RandomVariable& r) {
@@ -194,9 +271,10 @@ RandomVariable::RandomVariable(RandomVariable&& r) {
194271
RandomVariable& RandomVariable::operator=(const RandomVariable& r) {
195272
if (r.deterministic_) {
196273
deterministic_ = true;
197-
if (data_)
274+
if (data_) {
198275
delete[] data_;
199-
data_ = nullptr;
276+
data_ = nullptr;
277+
}
200278
} else {
201279
deterministic_ = false;
202280
if (r.n_ != 0) {
@@ -207,9 +285,10 @@ RandomVariable& RandomVariable::operator=(const RandomVariable& r) {
207285
}
208286
std::memcpy(r.data_, data_, r.n_ * sizeof(double));
209287
} else {
210-
if (data_)
288+
if (data_) {
211289
delete[] data_;
212-
data_ = nullptr;
290+
data_ = nullptr;
291+
}
213292
}
214293
}
215294
n_ = r.n_;
@@ -223,7 +302,6 @@ RandomVariable& RandomVariable::operator=(RandomVariable&& r) {
223302
constantData_ = r.constantData_;
224303
if (data_) {
225304
delete[] data_;
226-
data_ = nullptr;
227305
}
228306
data_ = r.data_;
229307
r.data_ = nullptr;
@@ -232,6 +310,9 @@ RandomVariable& RandomVariable::operator=(RandomVariable&& r) {
232310
return *this;
233311
}
234312

313+
RandomVariable::RandomVariable(const Size n, const Real value, const Real time)
314+
: n_(n), constantData_(value), data_(nullptr), deterministic_(true), time_(time) {}
315+
235316
RandomVariable::RandomVariable(const Filter& f, const Real valueTrue, const Real valueFalse, const Real time) {
236317
if (!f.initialised()) {
237318
clear();

QuantExt/qle/math/randomvariable.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ struct Filter {
3838
// ctors
3939
~Filter();
4040
Filter();
41+
Filter(const Filter& r);
42+
Filter(Filter&& r);
43+
Filter& operator=(const Filter& r);
44+
Filter& operator=(Filter&& r);
45+
4146
explicit Filter(const Size n, const bool value = false);
4247
// modifiers
4348
void clear();
@@ -64,7 +69,8 @@ struct Filter {
6469

6570
private:
6671
Size n_;
67-
std::vector<bool> data_;
72+
bool constantData_;
73+
bool* data_;
6874
bool deterministic_;
6975
};
7076

0 commit comments

Comments
 (0)