Ruiqi Dong created MATH-1680:
--------------------------------
Summary: BOBYQAOptimizer constructor fails to validate trust
region radius parameters
Key: MATH-1680
URL: https://issues.apache.org/jira/browse/MATH-1680
Project: Commons Math
Issue Type: Bug
Reporter: Ruiqi Dong
The {{BOBYQAOptimizer}} constructor does not validate the
{{initialTrustRegionRadius}} and {{stoppingTrustRegionRadius}} parameters,
despite explicit documentation requirements stating these constraints must be
enforced.
According to the JavaDoc in the {{bobyqa}} method:
{{* RHOBEG and RHOEND must be set to the initial and final values of a trust
* region radius, so both must be positive with RHOEND no greater than
* RHOBEG.}}
However, the three-parameter constructor accepts invalid values without
throwing any exceptions, violating the documented API contract. This issue may
cause line 1178 to have the problem of dividing by 0.
Test Case:
@Test
public void testConstructorParameterValidation() {
// Should throw for negative initial radius
assertThrows(IllegalArgumentException.class,
() -> new BOBYQAOptimizer(5, -1.0, 0.001));
// Should throw for negative stopping radius
assertThrows(IllegalArgumentException.class,
() -> new BOBYQAOptimizer(5, 1.0, -0.001));
// Should throw when stopping radius > initial radius
assertThrows(IllegalArgumentException.class,
() -> new BOBYQAOptimizer(5, 0.5, 1.0));
// Should throw for zero radii
assertThrows(IllegalArgumentException.class,
() -> new BOBYQAOptimizer(5, 0.0, 0.0));
}
Steps to Reproduce:
// All of these should throw IllegalArgumentException but don't:
// 1. Negative initial radius
BOBYQAOptimizer opt1 = new BOBYQAOptimizer(5, -1.0, 0.001);
// 2. Negative stopping radius
BOBYQAOptimizer opt2 = new BOBYQAOptimizer(5, 1.0, -0.001);
// 3. Stopping radius greater than initial radius
BOBYQAOptimizer opt3 = new BOBYQAOptimizer(5, 0.5, 1.0);
// 4. Zero radii
BOBYQAOptimizer opt4 = new BOBYQAOptimizer(5, 0.0, 0.0);
Proposed Fix: Add parameter validation to the constructor
public BOBYQAOptimizer(int numberOfInterpolationPoints,
double initialTrustRegionRadius,
double stoppingTrustRegionRadius) {
super(null);
if (initialTrustRegionRadius <= 0) {
throw new IllegalArgumentException(
"Initial trust region radius must be positive: " +
initialTrustRegionRadius);
}
if (stoppingTrustRegionRadius <= 0) {
throw new IllegalArgumentException(
"Stopping trust region radius must be positive: " +
stoppingTrustRegionRadius);
}
if (stoppingTrustRegionRadius > initialTrustRegionRadius) {
throw new IllegalArgumentException(
"Stopping trust region radius (" + stoppingTrustRegionRadius +
") must not exceed initial trust region radius (" +
initialTrustRegionRadius + ")");
}
this.numberOfInterpolationPoints = numberOfInterpolationPoints;
this.initialTrustRegionRadius = initialTrustRegionRadius;
this.stoppingTrustRegionRadius = stoppingTrustRegionRadius;
}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)