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)

Reply via email to