You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2023/04/05 14:43:53 UTC
[commons-math] branch master updated: MATH-1657: Provide (protected) accessor to the objective function.
This is an automated email from the ASF dual-hosted git repository.
erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git
The following commit(s) were added to refs/heads/master by this push:
new 56844842a MATH-1657: Provide (protected) accessor to the objective function.
56844842a is described below
commit 56844842a86612c0fadd2e3ac6fc57f21e6747ae
Author: Gilles Sadowski <gi...@gmail.com>
AuthorDate: Wed Apr 5 16:41:24 2023 +0200
MATH-1657: Provide (protected) accessor to the objective function.
Deprecated method "computeObjectiveValue" (equivalent functionality).
Thanks to François Laferrière for the suggestion.
---
.../legacy/optim/nonlinear/scalar/LineSearch.java | 10 ++++++----
.../nonlinear/scalar/MultivariateOptimizer.java | 21 +++++++++++++++++++--
.../NonLinearConjugateGradientOptimizer.java | 4 +++-
.../nonlinear/scalar/noderiv/BOBYQAOptimizer.java | 5 +++--
.../nonlinear/scalar/noderiv/CMAESOptimizer.java | 10 ++++++----
.../nonlinear/scalar/noderiv/PowellOptimizer.java | 6 ++++--
.../nonlinear/scalar/noderiv/SimplexOptimizer.java | 4 +---
.../legacy/optim/univariate/BrentOptimizer.java | 6 ++++--
.../optim/univariate/UnivariateOptimizer.java | 21 +++++++++++++++++++--
src/changes/changes.xml | 4 ++++
10 files changed, 69 insertions(+), 22 deletions(-)
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/LineSearch.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/LineSearch.java
index 1dab36529..6e674c364 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/LineSearch.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/LineSearch.java
@@ -17,6 +17,7 @@
package org.apache.commons.math4.legacy.optim.nonlinear.scalar;
import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
+import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
import org.apache.commons.math4.legacy.optim.MaxEval;
import org.apache.commons.math4.legacy.optim.univariate.BracketFinder;
import org.apache.commons.math4.legacy.optim.univariate.BrentOptimizer;
@@ -73,9 +74,9 @@ public class LineSearch {
*
* @param optimizer Optimizer on behalf of which the line search
* be performed.
- * Its {@link MultivariateOptimizer#computeObjectiveValue(double[])
- * computeObjectiveValue} method will be called by the
- * {@link #search(double[],double[]) search} method.
+ * Its {@link MultivariateOptimizer#getObjectiveFunction() objective
+ * function} will be called by the {@link #search(double[],double[])
+ * search} method.
* @param relativeTolerance Search will stop when the function relative
* difference between successive iterations is below this value.
* @param absoluteTolerance Search will stop when the function absolute
@@ -111,6 +112,7 @@ public class LineSearch {
public UnivariatePointValuePair search(final double[] startPoint,
final double[] direction) {
final int n = startPoint.length;
+ final MultivariateFunction func = mainOptimizer.getObjectiveFunction();
final UnivariateFunction f = new UnivariateFunction() {
/** {@inheritDoc} */
@Override
@@ -119,7 +121,7 @@ public class LineSearch {
for (int i = 0; i < n; i++) {
x[i] = startPoint[i] + alpha * direction[i];
}
- return mainOptimizer.computeObjectiveValue(x);
+ return func.value(x);
}
};
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/MultivariateOptimizer.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/MultivariateOptimizer.java
index c36e95e16..2cd72d83b 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/MultivariateOptimizer.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/MultivariateOptimizer.java
@@ -85,7 +85,14 @@ public abstract class MultivariateOptimizer
continue;
}
if (data instanceof ObjectiveFunction) {
- function = ((ObjectiveFunction) data).getObjectiveFunction();
+ final MultivariateFunction delegate = ((ObjectiveFunction) data).getObjectiveFunction();
+ function = new MultivariateFunction() {
+ @Override
+ public double value(double[] point) {
+ incrementEvaluationCount();
+ return delegate.value(point);
+ }
+ };
continue;
}
}
@@ -98,6 +105,14 @@ public abstract class MultivariateOptimizer
return goal;
}
+ /**
+ * @return a wrapper that delegates to the user-supplied function,
+ * and counts the number of evaluations.
+ */
+ protected MultivariateFunction getObjectiveFunction() {
+ return function;
+ }
+
/**
* Computes the objective function value.
* This method <em>must</em> be called by subclasses to enforce the
@@ -107,9 +122,11 @@ public abstract class MultivariateOptimizer
* @return the objective function value at the specified point.
* @throws org.apache.commons.math4.legacy.exception.TooManyEvaluationsException
* if the maximal number of evaluations is exceeded.
+ *
+ * @deprecated Use {@link #getObjectiveFunction()} instead.
*/
+ @Deprecated
public double computeObjectiveValue(double[] params) {
- super.incrementEvaluationCount();
return function.value(params);
}
}
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/gradient/NonLinearConjugateGradientOptimizer.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/gradient/NonLinearConjugateGradientOptimizer.java
index 168fc72e6..f22eaf309 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/gradient/NonLinearConjugateGradientOptimizer.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/gradient/NonLinearConjugateGradientOptimizer.java
@@ -17,6 +17,7 @@
package org.apache.commons.math4.legacy.optim.nonlinear.scalar.gradient;
+import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
import org.apache.commons.math4.legacy.exception.MathInternalError;
import org.apache.commons.math4.legacy.exception.MathUnsupportedOperationException;
import org.apache.commons.math4.legacy.exception.TooManyEvaluationsException;
@@ -171,6 +172,7 @@ public class NonLinearConjugateGradientOptimizer
final ConvergenceChecker<PointValuePair> checker = getConvergenceChecker();
final double[] point = getStartPoint();
final GoalType goal = getGoalType();
+ final MultivariateFunction func = getObjectiveFunction();
final int n = point.length;
double[] r = computeObjectiveGradient(point);
if (goal == GoalType.MINIMIZE) {
@@ -192,7 +194,7 @@ public class NonLinearConjugateGradientOptimizer
while (true) {
incrementIterationCount();
- final double objective = computeObjectiveValue(point);
+ final double objective = func.value(point);
PointValuePair previous = current;
current = new PointValuePair(point, objective);
if (previous != null && checker.converged(getIterations(), previous, current)) {
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/BOBYQAOptimizer.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/BOBYQAOptimizer.java
index 87515e94c..593f0f663 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/BOBYQAOptimizer.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/BOBYQAOptimizer.java
@@ -17,6 +17,7 @@
// CHECKSTYLE: stop all
package org.apache.commons.math4.legacy.optim.nonlinear.scalar.noderiv;
+import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
import org.apache.commons.math4.legacy.exception.MathIllegalStateException;
import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
import org.apache.commons.math4.legacy.exception.OutOfRangeException;
@@ -826,7 +827,7 @@ public class BOBYQAOptimizer
}
}
- f = computeObjectiveValue(currentBest.toArray());
+ f = getObjectiveFunction().value(currentBest.toArray());
if (!isMinimize) {
f = -f;
@@ -1682,7 +1683,7 @@ public class BOBYQAOptimizer
}
}
- final double objectiveValue = computeObjectiveValue(currentBest.toArray());
+ final double objectiveValue = getObjectiveFunction().value(currentBest.toArray());
final double f = isMinimize ? objectiveValue : -objectiveValue;
final int numEval = getEvaluations(); // nfm + 1
fAtInterpolationPoints.setEntry(nfm, f);
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/CMAESOptimizer.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/CMAESOptimizer.java
index 1a6bf5c04..c50498a45 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/CMAESOptimizer.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/CMAESOptimizer.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
import org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.legacy.exception.OutOfRangeException;
@@ -885,14 +886,15 @@ public class CMAESOptimizer
* @return the objective value + penalty for violated bounds.
*/
public ValuePenaltyPair value(final double[] point) {
+ final MultivariateFunction func = CMAESOptimizer.this.getObjectiveFunction();
double value;
- double penalty=0.0;
+ double penalty = 0;
if (isRepairMode) {
double[] repaired = repair(point);
- value = CMAESOptimizer.this.computeObjectiveValue(repaired);
- penalty = penalty(point, repaired);
+ value = func.value(repaired);
+ penalty = penalty(point, repaired);
} else {
- value = CMAESOptimizer.this.computeObjectiveValue(point);
+ value = func.value(point);
}
value = isMinimize ? value : -value;
penalty = isMinimize ? penalty : -penalty;
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/PowellOptimizer.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/PowellOptimizer.java
index b09032f99..405c70349 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/PowellOptimizer.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/PowellOptimizer.java
@@ -17,6 +17,7 @@
package org.apache.commons.math4.legacy.optim.nonlinear.scalar.noderiv;
import java.util.Arrays;
+import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
import org.apache.commons.math4.legacy.exception.MathUnsupportedOperationException;
import org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
@@ -169,6 +170,7 @@ public class PowellOptimizer
final GoalType goal = getGoalType();
final double[] guess = getStartPoint();
+ final MultivariateFunction func = getObjectiveFunction();
final int n = guess.length;
final double[][] direc = new double[n][n];
@@ -180,7 +182,7 @@ public class PowellOptimizer
= getConvergenceChecker();
double[] x = guess;
- double fVal = computeObjectiveValue(x);
+ double fVal = func.value(x);
double[] x1 = x.clone();
while (true) {
incrementIterationCount();
@@ -234,7 +236,7 @@ public class PowellOptimizer
}
x1 = x.clone();
- fX2 = computeObjectiveValue(x2);
+ fX2 = func.value(x2);
if (fX > fX2) {
double t = 2 * (fX + fX2 - 2 * fVal);
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/SimplexOptimizer.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/SimplexOptimizer.java
index 20d5eee8a..1916ab625 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/SimplexOptimizer.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/SimplexOptimizer.java
@@ -174,9 +174,7 @@ public class SimplexOptimizer extends MultivariateOptimizer {
protected PointValuePair doOptimize() {
checkParameters();
- // Indirect call to "computeObjectiveValue" in order to update the
- // evaluations counter.
- final MultivariateFunction evalFunc = this::computeObjectiveValue;
+ final MultivariateFunction evalFunc = getObjectiveFunction();
final boolean isMinim = getGoalType() == GoalType.MINIMIZE;
final Comparator<PointValuePair> comparator = (o1, o2) -> {
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/univariate/BrentOptimizer.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/univariate/BrentOptimizer.java
index 7ed3e5e1e..602719393 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/univariate/BrentOptimizer.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/univariate/BrentOptimizer.java
@@ -16,6 +16,7 @@
*/
package org.apache.commons.math4.legacy.optim.univariate;
+import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
import org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
import org.apache.commons.math4.legacy.optim.ConvergenceChecker;
@@ -116,6 +117,7 @@ public class BrentOptimizer extends UnivariateOptimizer {
final double lo = getMin();
final double mid = getStartValue();
final double hi = getMax();
+ final UnivariateFunction func = getObjectiveFunction();
// Optional additional convergence criteria.
final ConvergenceChecker<UnivariatePointValuePair> checker
@@ -136,7 +138,7 @@ public class BrentOptimizer extends UnivariateOptimizer {
double w = x;
double d = 0;
double e = 0;
- double fx = computeObjectiveValue(x);
+ double fx = func.value(x);
if (!isMinim) {
fx = -fx;
}
@@ -222,7 +224,7 @@ public class BrentOptimizer extends UnivariateOptimizer {
u = x + d;
}
- double fu = computeObjectiveValue(u);
+ double fu = func.value(u);
if (!isMinim) {
fu = -fu;
}
diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/univariate/UnivariateOptimizer.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/univariate/UnivariateOptimizer.java
index ca6110f01..1b170adfa 100644
--- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/univariate/UnivariateOptimizer.java
+++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/optim/univariate/UnivariateOptimizer.java
@@ -105,7 +105,14 @@ public abstract class UnivariateOptimizer
continue;
}
if (data instanceof UnivariateObjectiveFunction) {
- function = ((UnivariateObjectiveFunction) data).getObjectiveFunction();
+ final UnivariateFunction delegate = ((UnivariateObjectiveFunction) data).getObjectiveFunction();
+ function = new UnivariateFunction() {
+ @Override
+ public double value(double point) {
+ incrementEvaluationCount();
+ return delegate.value(point);
+ }
+ };
continue;
}
if (data instanceof GoalType) {
@@ -134,6 +141,14 @@ public abstract class UnivariateOptimizer
return max;
}
+ /**
+ * @return a wrapper that delegates to the user-supplied function,
+ * and counts the number of evaluations.
+ */
+ protected UnivariateFunction getObjectiveFunction() {
+ return function;
+ }
+
/**
* Computes the objective function value.
* This method <em>must</em> be called by subclasses to enforce the
@@ -143,9 +158,11 @@ public abstract class UnivariateOptimizer
* @return the objective function value at the specified point.
* @throws TooManyEvaluationsException if the maximal number of
* evaluations is exceeded.
+ *
+ * @deprecated Use {@link #getObjectiveFunction()} instead.
*/
+ @Deprecated
protected double computeObjectiveValue(double x) {
- super.incrementEvaluationCount();
return function.value(x);
}
}
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 54a6a0d00..c93cfa424 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -96,6 +96,10 @@ Caveat:
to support the whole codebase (it was one of the main reasons for
creating more focused components).
">
+ <action dev="erans" type="update" issue="MATH-1657" due-to="François Laferrière">
+ Small refactoring of the "evaluation counter" in optimizers' base class:
+ Provide (protected) accessor (to replace method "computeObjectiveValue").
+ </action>
<action dev="erans" type="update" issue="MATH-1654" due-to="Cyril de Catheu">
"Array2DRowRealMatrix": Performance enhancement ("getEntry").
</action>