Skip to content

Commit

Permalink
Make fewer copies of arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
eltoder committed Nov 14, 2024
1 parent 1aae346 commit ffaa622
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 28 deletions.
28 changes: 13 additions & 15 deletions ql/math/optimization/levenbergmarquardt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,16 @@ namespace QuantLib {
EndCriteria::Type LevenbergMarquardt::minimize(Problem& P,
const EndCriteria& endCriteria) {
P.reset();
Array x_ = P.currentValue();
const Array& initX = P.currentValue();
currentProblem_ = &P;
initCostValues_ = P.costFunction().values(x_);
initCostValues_ = P.costFunction().values(initX);
int m = initCostValues_.size();
int n = x_.size();
if(useCostFunctionsJacobian_) {
int n = initX.size();
if (useCostFunctionsJacobian_) {
initJacobian_ = Matrix(m,n);
P.costFunction().jacobian(initJacobian_, x_);
P.costFunction().jacobian(initJacobian_, initX);
}
std::unique_ptr<Real[]> xx(new Real[n]);
std::copy(x_.begin(), x_.end(), xx.get());
Array xx = initX;
std::unique_ptr<Real[]> fvec(new Real[m]);
std::unique_ptr<Real[]> diag(new Real[n]);
int mode = 1;
Expand Down Expand Up @@ -81,15 +80,15 @@ namespace QuantLib {
// in n variables by the Levenberg-Marquardt algorithm.
MINPACK::LmdifCostFunction lmdifCostFunction =
[this](const auto m, const auto n, const auto x, const auto fvec, const auto iflag) {
this->fcn(m, n, x, fvec, iflag);
this->fcn(m, n, x, fvec);
};
MINPACK::LmdifCostFunction lmdifJacFunction =
useCostFunctionsJacobian_
? [this](const auto m, const auto n, const auto x, const auto fjac, const auto iflag) {
this->jacFcn(m, n, x, fjac, iflag);
this->jacFcn(m, n, x, fjac);
}
: MINPACK::LmdifCostFunction();
MINPACK::lmdif(m, n, xx.get(), fvec.get(),
MINPACK::lmdif(m, n, xx.begin(), fvec.get(),
endCriteria.functionEpsilon(),
xtol_,
gtol_,
Expand Down Expand Up @@ -132,14 +131,13 @@ namespace QuantLib {
QL_FAIL("unknown MINPACK result: " << info);
}
// set problem
std::copy(xx.get(), xx.get()+n, x_.begin());
P.setCurrentValue(x_);
P.setFunctionValue(P.costFunction().value(x_));
P.setCurrentValue(std::move(xx));
P.setFunctionValue(P.costFunction().value(P.currentValue()));

return ecType;
}

void LevenbergMarquardt::fcn(int, int n, Real* x, Real* fvec, int*) {
void LevenbergMarquardt::fcn(int, int n, Real* x, Real* fvec) {
Array xt(n);
std::copy(x, x+n, xt.begin());
// constraint handling needs some improvement in the future:
Expand All @@ -152,7 +150,7 @@ namespace QuantLib {
}
}

void LevenbergMarquardt::jacFcn(int m, int n, Real* x, Real* fjac, int*) {
void LevenbergMarquardt::jacFcn(int m, int n, Real* x, Real* fjac) {
Array xt(n);
std::copy(x, x+n, xt.begin());
// constraint handling needs some improvement in the future:
Expand Down
6 changes: 2 additions & 4 deletions ql/math/optimization/levenbergmarquardt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,11 @@ namespace QuantLib {
void fcn(int m,
int n,
Real* x,
Real* fvec,
int* iflag);
Real* fvec);
void jacFcn(int m,
int n,
Real* x,
Real* fjac,
int* iflag);
Real* fjac);

/*! \deprecated Don't use this method; inspect the result of minimize instead.
Deprecated in version 1.36.
Expand Down
4 changes: 2 additions & 2 deletions ql/math/optimization/problem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ namespace QuantLib {
//! Cost function
CostFunction& costFunction() const { return costFunction_; }

void setCurrentValue(const Array& currentValue) {
currentValue_=currentValue;
void setCurrentValue(Array currentValue) {
currentValue_ = std::move(currentValue);
}

//! current value of the local minimum
Expand Down
9 changes: 2 additions & 7 deletions ql/termstructures/globalbootstrap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,6 @@ template <class Curve> void GlobalBootstrap<Curve>::calculate() const {
return std::tan((y - lowerBounds_[i]) * M_PI / (upperBounds_[i] - lowerBounds_[i]) - M_PI_2);
}

Real value(const Array& x) const override {
Array v = values(x);
std::transform(v.begin(), v.end(), v.begin(), [](Real x) -> Real { return x*x; });
return std::sqrt(std::accumulate(v.begin(), v.end(), Real(0.0)) / static_cast<Real>(v.size()));
}

Array values(const Array& x) const override {
for (Size i = 0; i < x.size(); ++i) {
Traits::updateGuess(ts_->data_, transformDirect(x[i], i), i + 1);
Expand All @@ -304,7 +298,8 @@ template <class Curve> void GlobalBootstrap<Curve>::calculate() const {
Curve *ts_;
const std::vector<Real> lowerBounds_, upperBounds_;
};
TargetFunction cost(firstHelper_, numberHelpers_, additionalErrors_, ts_, lowerBounds, upperBounds);
TargetFunction cost(firstHelper_, numberHelpers_, additionalErrors_, ts_,
std::move(lowerBounds), std::move(upperBounds));

// setup guess
Array guess(numberBounds);
Expand Down

0 comments on commit ffaa622

Please sign in to comment.