commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gilles Sadowski <gil...@harfang.homelinux.org>
Subject [Math] About the API of the optimizers
Date Thu, 04 Oct 2012 01:36:19 GMT
Hello.

This issue
  https://issues.apache.org/jira/browse/MATH-872
is about a workaround similar to one already existing for
"SimplexOptimizer", i.e. having a specific method (setter) to set
data that cannot be passed through the common API ("optimize" method) and
should not be specified at construction (because it is of the same "nature"
as the parameters passed through "optimize").

I was thinking of improving the situation by modifying the "optimize" method
(in interface "BaseMultivariateOptimizer") to become:
  PointValuePair optimize(int maxEval,
                          FUNC f,
                          GoalType goalType,
                          double[] startPoint,
                          OptimizationData... optData);

There is a new array argument, "optData", the elements of which are
instances of classes implementing a new marker interface:
  interface OptimizationData {}

Concrete optimizer implementations would define which kind of data they need
(and in which order they must be supplied in the call to "optimize").
["BaseAbstractMultivariateOptimizer" would store those data and provide
(protected) access to it (similar to "getStartPoint()").]

For "SimplexOptimizer", the "data" is the "AbstractSimplex" class which will
just have to implement the "OptimizationData" interface:
-----
  public class AbstractSimplex implements OptimizationData {
    // No changes here.
  }
-----
And, in "SimplexOptimizer", the "doOptimize" method will retrieve the data,
check that it has the appropriate type and then use it as before:
-----
  private PointValuePair doOptimize() {
    // ...

    final OptimizationData[] optData = getOptimizationData();
    if (optData == null ||
        optData.length == 0) {
      throw new NoDataException();
      // Or: use default values (?).
    }
    if (!(optData[0] instanceof AbstractSimplex)) {
      throw new IllegalOptimizationDataTypeException(optData[0].getClass().getName());
    }
    final AbstractSimplex simplex = (AbstractSimplex) optData[0];

    // etc.
  }
-----
We could then get rid of the "setSimplex" method that is not part of the
optimizers common API, and the necessary input data would be passed with the
call to "optimize", e.g. (in user code):
-----
  final SimplexOptimizer optim = new SimplexOptimizer(absTol, relTol);
  final MultivariateFunction func = ...
  final double[] init = new double[] { 1, 2, 3, 4 };
  final PointValuePair sol
    = optim.optimize(2500, func, GoalType.MINIMIZE, init,
                     new NelderMeadSimplex(init.length, 0.1));
-----
[Of course, one drawback is that an illegal type argument is detected only
at runtime (but it's also an obvious programming bug that would probably
only occur during development, and not in production use).]

One benefit is that bounds could also be considered as a kind of
"OptimizationData":
-----
  public class SimpleBounds implements OptimizationData {
    private final double[] lo;
    private final double[] hi;

    public SimpleBounds(double[] lowerBounds,
                        double[] upperBounds) {
      lo = lowerBounds.clone();
      hi = upperBounds.clone();
    }

    public double[] getLo {
      return lo.clone();
    }
    public double[] getHi {
      return hi.clone();
    }
  }
-----
We could thus get rid of the "BaseMultivariateSimpleBoundsOptimizer"
interface.


What do you think?

Gilles

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message