Skip to content

Commit 222b1e4

Browse files
pcaspersjenkins
authored andcommitted
QPR-11984 avoid memcpy, fixes
1 parent 916c981 commit 222b1e4

1 file changed

Lines changed: 58 additions & 33 deletions

File tree

QuantExt/qle/math/randomvariable.cpp

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Filter::Filter(const Filter& r) {
3737
constantData_ = r.constantData_;
3838
if (r.data_) {
3939
data_ = new bool[n_];
40-
std::memcpy(r.data_, data_, n_ * sizeof(bool));
40+
std::copy(r.data_, r.data_ + n_, data_);
4141
} else {
4242
data_ = nullptr;
4343
}
@@ -67,7 +67,7 @@ Filter& Filter::operator=(const Filter& r) {
6767
delete[] data_;
6868
data_ = new bool[r.n_];
6969
}
70-
std::memcpy(r.data_, data_, r.n_ * sizeof(bool));
70+
std::copy(r.data_, r.data_ + n_, data_);
7171
} else {
7272
if (data_) {
7373
delete[] data_;
@@ -96,6 +96,7 @@ Filter::Filter(const Size n, const bool value) : n_(n), constantData_(value), da
9696

9797
void Filter::clear() {
9898
n_ = 0;
99+
constantData_ = false;
99100
if (data_) {
100101
delete[] data_;
101102
data_ = nullptr;
@@ -106,7 +107,7 @@ void Filter::clear() {
106107
void Filter::updateDeterministic() {
107108
if (deterministic_ || !initialised())
108109
return;
109-
for (Size i = 1; i < n_; ++i) {
110+
for (Size i = 0; i < n_; ++i) {
110111
if (data_[i] != constantData_)
111112
return;
112113
}
@@ -136,15 +137,15 @@ void Filter::setAll(const bool v) {
136137

137138
bool Filter::operator[](const Size i) const {
138139
if (deterministic_)
139-
return constantData_ != 0;
140+
return constantData_;
140141
else
141142
return data_[i];
142143
}
143144

144145
bool Filter::at(const Size i) const {
145146
QL_REQUIRE(n_ > 0, "Filter::at(" << i << "): dimension is zero");
146147
if (deterministic_)
147-
return constantData_ != 0;
148+
return constantData_;
148149
QL_REQUIRE(i < n_, "Filter::at(" << i << "): out of bounds, size is " << n_);
149150
return operator[](i);
150151
}
@@ -175,9 +176,9 @@ bool operator!=(const Filter& a, const Filter& b) { return !(a == b); }
175176
Filter operator&&(Filter x, const Filter& y) {
176177
QL_REQUIRE(!x.initialised() || !y.initialised() || x.size() == y.size(),
177178
"RandomVariable: x && y: x size (" << x.size() << ") must be equal to y size (" << y.size() << ")");
178-
if (x.deterministic() && x.constantData_ == 0)
179+
if (x.deterministic() && !x.constantData_)
179180
return Filter(x.size(), false);
180-
if (y.deterministic() && y.constantData_ == 0)
181+
if (y.deterministic() && !y.constantData_)
181182
return Filter(y.size(), false);
182183
if (!x.initialised() || !y.initialised())
183184
return Filter();
@@ -252,7 +253,7 @@ RandomVariable::RandomVariable(const RandomVariable& r) {
252253
constantData_ = r.constantData_;
253254
if (r.data_) {
254255
data_ = new double[n_];
255-
std::memcpy(r.data_, data_, n_ * sizeof(double));
256+
std::copy(r.data_, r.data_ + n_, data_);
256257
} else {
257258
data_ = nullptr;
258259
}
@@ -284,7 +285,7 @@ RandomVariable& RandomVariable::operator=(const RandomVariable& r) {
284285
delete[] data_;
285286
data_ = new double[r.n_];
286287
}
287-
std::memcpy(r.data_, data_, r.n_ * sizeof(double));
288+
std::copy(r.data_, r.data_ + n_, data_);
288289
} else {
289290
if (data_) {
290291
delete[] data_;
@@ -323,6 +324,7 @@ RandomVariable::RandomVariable(const Filter& f, const Real valueTrue, const Real
323324
if (f.deterministic())
324325
setAll(f.at(0) ? valueTrue : valueFalse);
325326
else {
327+
constantData_ = 0.0;
326328
deterministic_ = false;
327329
data_ = new double[n_];
328330
for (Size i = 0; i < n_; ++i)
@@ -337,8 +339,9 @@ RandomVariable::RandomVariable(const QuantLib::Array& array, const Real time) {
337339
time_ = time;
338340
if (n_ != 0) {
339341
data_ = new double[n_];
340-
std::memcpy((void*)array.begin(), data_, n_ * sizeof(double));
342+
std::copy(array.begin(), array.end(), data_);
341343
}
344+
constantData_ = 0.0;
342345
}
343346

344347
void RandomVariable::copyToMatrixCol(QuantLib::Matrix& m, const Size j) const {
@@ -353,12 +356,13 @@ void RandomVariable::copyToArray(QuantLib::Array& array) const {
353356
if (deterministic_)
354357
std::fill(array.begin(), array.end(), constantData_);
355358
else if (n_ != 0) {
356-
std::memcpy(data_, array.begin(), n_ * sizeof(double));
359+
std::copy(data_, data_ + n_, array.begin());
357360
}
358361
}
359362

360363
void RandomVariable::clear() {
361364
n_ = 0;
365+
constantData_ = 0.0;
362366
if (data_) {
363367
delete[] data_;
364368
data_ = nullptr;
@@ -370,7 +374,7 @@ void RandomVariable::clear() {
370374
void RandomVariable::updateDeterministic() {
371375
if (deterministic_ || !initialised())
372376
return;
373-
for (Size i = 1; i < n_; ++i) {
377+
for (Size i = 0; i < n_; ++i) {
374378
if (!QuantLib::close_enough(data_[i], constantData_))
375379
return;
376380
}
@@ -463,10 +467,11 @@ RandomVariable& RandomVariable::operator+=(const RandomVariable& y) {
463467
return *this;
464468
if (deterministic_)
465469
constantData_ += y.constantData_;
466-
else
470+
else {
467471
for (Size i = 0; i < n_; ++i) {
468472
data_[i] += y[i];
469473
}
474+
}
470475
return *this;
471476
}
472477

@@ -484,10 +489,11 @@ RandomVariable& RandomVariable::operator-=(const RandomVariable& y) {
484489
return *this;
485490
if (deterministic_)
486491
constantData_ -= y.constantData_;
487-
else
492+
else {
488493
for (Size i = 0; i < n_; ++i) {
489494
data_[i] -= y[i];
490495
}
496+
}
491497
return *this;
492498
}
493499

@@ -505,10 +511,11 @@ RandomVariable& RandomVariable::operator*=(const RandomVariable& y) {
505511
return *this;
506512
if (deterministic_)
507513
constantData_ *= y.constantData_;
508-
else
514+
else {
509515
for (Size i = 0; i < n_; ++i) {
510516
data_[i] *= y[i];
511517
}
518+
}
512519
return *this;
513520
}
514521

@@ -526,10 +533,11 @@ RandomVariable& RandomVariable::operator/=(const RandomVariable& y) {
526533
return *this;
527534
if (deterministic_)
528535
constantData_ /= y.constantData_;
529-
else
536+
else {
530537
for (Size i = 0; i < n_; ++i) {
531538
data_[i] /= y[i];
532539
}
540+
}
533541
return *this;
534542
}
535543

@@ -571,10 +579,11 @@ RandomVariable max(RandomVariable x, const RandomVariable& y) {
571579
x.expand();
572580
if (x.deterministic())
573581
x.constantData_ = std::max(x.constantData_, y.constantData_);
574-
else
582+
else {
575583
for (Size i = 0; i < x.size(); ++i) {
576584
x.data_[i] = std::max(x.data_[i], y[i]);
577585
}
586+
}
578587
return x;
579588
}
580589

@@ -588,10 +597,11 @@ RandomVariable min(RandomVariable x, const RandomVariable& y) {
588597
x.expand();
589598
if (x.deterministic())
590599
x.constantData_ = std::min(x.constantData_, y.constantData_);
591-
else
600+
else {
592601
for (Size i = 0; i < x.size(); ++i) {
593602
x.data_[i] = std::min(x.data_[i], y[i]);
594603
}
604+
}
595605
return x;
596606
}
597607

@@ -607,40 +617,44 @@ RandomVariable pow(RandomVariable x, const RandomVariable& y) {
607617
return x;
608618
if (x.deterministic())
609619
x.constantData_ = std::pow(x.constantData_, y.constantData_);
610-
else
620+
else {
611621
for (Size i = 0; i < x.size(); ++i) {
612622
x.data_[i] = std::pow(x.data_[i], y[i]);
613623
}
624+
}
614625
return x;
615626
}
616627

617628
RandomVariable operator-(RandomVariable x) {
618629
if (x.deterministic_)
619630
x.constantData_ = -x.constantData_;
620-
else
631+
else {
621632
for (Size i = 0; i < x.n_; ++i) {
622633
x.data_[i] = -x.data_[i];
623634
}
635+
}
624636
return x;
625637
}
626638

627639
RandomVariable abs(RandomVariable x) {
628640
if (x.deterministic_)
629641
x.constantData_ = std::abs(x.constantData_);
630-
else
642+
else {
631643
for (Size i = 0; i < x.n_; ++i) {
632644
x.data_[i] = std::abs(x.data_[i]);
633645
}
646+
}
634647
return x;
635648
}
636649

637650
RandomVariable exp(RandomVariable x) {
638651
if (x.deterministic_)
639652
x.constantData_ = std::exp(x.constantData_);
640-
else
653+
else {
641654
for (Size i = 0; i < x.n_; ++i) {
642655
x.data_[i] = std::exp(x.data_[i]);
643656
}
657+
}
644658
return x;
645659
}
646660

@@ -657,52 +671,57 @@ RandomVariable log(RandomVariable x) {
657671
RandomVariable sqrt(RandomVariable x) {
658672
if (x.deterministic_)
659673
x.constantData_ = std::sqrt(x.constantData_);
660-
else
674+
else {
661675
for (Size i = 0; i < x.n_; ++i) {
662676
x.data_[i] = std::sqrt(x.data_[i]);
663677
}
678+
}
664679
return x;
665680
}
666681

667682
RandomVariable sin(RandomVariable x) {
668683
if (x.deterministic_)
669684
x.constantData_ = std::sin(x.constantData_);
670-
else
685+
else {
671686
for (Size i = 0; i < x.n_; ++i) {
672687
x.data_[i] = std::sin(x.data_[i]);
673688
}
689+
}
674690
return x;
675691
}
676692

677693
RandomVariable cos(RandomVariable x) {
678694
if (x.deterministic_)
679695
x.constantData_ = std::cos(x.constantData_);
680-
else
696+
else {
681697
for (Size i = 0; i < x.n_; ++i) {
682698
x.data_[i] = std::cos(x.data_[i]);
683699
}
700+
}
684701
return x;
685702
}
686703

687704
RandomVariable normalCdf(RandomVariable x) {
688705
static const boost::math::normal_distribution<double> n;
689706
if (x.deterministic_)
690707
x.constantData_ = boost::math::cdf(n, x.constantData_);
691-
else
708+
else {
692709
for (Size i = 0; i < x.n_; ++i) {
693710
x.data_[i] = boost::math::cdf(n, x.data_[i]);
694711
}
712+
}
695713
return x;
696714
}
697715

698716
RandomVariable normalPdf(RandomVariable x) {
699717
static const boost::math::normal_distribution<double> n;
700718
if (x.deterministic_)
701719
x.constantData_ = boost::math::pdf(n, x.constantData_);
702-
else
720+
else {
703721
for (Size i = 0; i < x.n_; ++i) {
704722
x.data_[i] = boost::math::pdf(n, x.data_[i]);
705723
}
724+
}
706725
return x;
707726
}
708727

@@ -762,8 +781,12 @@ RandomVariable indicatorEq(RandomVariable x, const RandomVariable& y, const Real
762781
x.checkTimeConsistencyAndUpdate(y.time());
763782
if (!y.deterministic_)
764783
x.expand();
765-
for (Size i = 0; i < x.n_; ++i) {
766-
x.data_[i] = QuantLib::close_enough(x.data_[i], y[i]) ? trueVal : falseVal;
784+
if (x.deterministic()) {
785+
x.constantData_ = QuantLib::close_enough(x.constantData_, y.constantData_) ? trueVal : falseVal;
786+
} else {
787+
for (Size i = 0; i < x.n_; ++i) {
788+
x.data_[i] = QuantLib::close_enough(x.data_[i], y[i]) ? trueVal : falseVal;
789+
}
767790
}
768791
return x;
769792
}
@@ -776,14 +799,15 @@ RandomVariable indicatorGt(RandomVariable x, const RandomVariable& y, const Real
776799
x.checkTimeConsistencyAndUpdate(y.time());
777800
if (!y.deterministic_)
778801
x.expand();
779-
if (x.deterministic())
802+
if (x.deterministic()) {
780803
x.constantData_ =
781804
(x.constantData_ > y.constantData_ && !QuantLib::close_enough(x.constantData_, y.constantData_)) ? trueVal
782805
: falseVal;
783-
else
806+
} else {
784807
for (Size i = 0; i < x.n_; ++i) {
785808
x.data_[i] = (x.data_[i] > y[i] && !QuantLib::close_enough(x.data_[i], y[i])) ? trueVal : falseVal;
786809
}
810+
}
787811
return x;
788812
}
789813

@@ -795,14 +819,15 @@ RandomVariable indicatorGeq(RandomVariable x, const RandomVariable& y, const Rea
795819
x.checkTimeConsistencyAndUpdate(y.time());
796820
if (!y.deterministic_)
797821
x.expand();
798-
if (x.deterministic())
822+
if (x.deterministic()) {
799823
x.constantData_ =
800824
(x.constantData_ > y.constantData_ || QuantLib::close_enough(x.constantData_, y.constantData_)) ? trueVal
801825
: falseVal;
802-
else
826+
} else {
803827
for (Size i = 0; i < x.n_; ++i) {
804828
x.data_[i] = (x.data_[i] > y[i] || QuantLib::close_enough(x.data_[i], y[i])) ? trueVal : falseVal;
805829
}
830+
}
806831
return x;
807832
}
808833

0 commit comments

Comments
 (0)