commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Luc Maisonobe <>
Subject Re: [Math] Optimizers: API for simple bound constraints
Date Fri, 28 Oct 2011 07:14:31 GMT
Le 28/10/2011 08:27, Sébastien Brisard a écrit :

Hi Sébastien,

> 2011/10/27 Gilles Sadowski <>:
>>>>> The BOBYQA optimizer takes simple bound contraints into account:
>>>>>   lowerBound(i) <= p(i) <= upperBound(i)    0 <= i < n
>>>>> where "n" is the problem dimension.
>>>>> The parent class ("BaseMultivariateRealOptimizer") currently mandates
>>>>> following "optimize" method:
>>>>> ---CUT---
>>>>>     RealPointValuePair optimize(int maxEval,
>>>>>                                 FUNC f,
>>>>>                                 GoalType goalType,
>>>>>                                 double[] startPoint);
>>>>> ---CUT---
>>>>> I think that the bounds are arguments that should be passed through that
>>>>> method. The current method definition is a special case: no bound
>>>>> constraints (or, equivalently, all lower bounds = -infinity, all upper
>>>>> bounds = +infinity).
>>>>> Thus, it seems that adding the following to the API
>>>>> ---CUT---
>>>>>     RealPointValuePair optimize(int maxEval,
>>>>>                                 FUNC f,
>>>>>                                 GoalType goalType,
>>>>>                                 double[] startPoint,
>>>>>                                 double[] lowerBounds,
>>>>>                                 double[] upperBounds);
>>>>> ---CUT---
>>>>> is all there is to do in order to accomodate algorithms like BOBYQA.
>>>> [...]
>>> It sounds like a useful addition, which raises one question I'd like
>>> to ask all of you. I guess all three double[] arrays should have the
>>> same size, which must be checked, and also documented in the javadoc.
>>> In order to avoid this, what I tend to do at the moment is to define a
>>> new class --say, BoundedPoint-- which would hold three double:s an
>>> initial value, a lower bound and an upper bound. Then I would just
>>> provide the method with the corresponding array of BoundedPoint,
>>> instead of three arrays of doubles. Then no dimension mismatch can
>>> occur, and no additional information needs be provided in the javadoc.
>>> Of course, the price to pay is that you have to construct a few
>>> BoundedPoint. As I said, this is what I tend to do at the moment, but
>>> I have mixed feelings about this solution vs. passing 3 double[]. Any
>>> thoughts about this side question?
>> On the principle, you are right of course.
>> But I'm not sure that we gain much by adding this layer of data
>> encapsulation, because having a single array (instead of three) is not
>> enough to prevent a dimensionality error: indeed, the arrays dimension must
>> match the expected argument of the function, and this possible mismatch can
>> only be detected later, when the function is called (within the "doOptimize"
>> method).
> OK, that's a fair point.
>> To be completely safe, we would have to introduce an additional method
>> ("getDimension") in the "MultivariateFunction" interface. [But this has
>> the drawback that it reduces the generality of this interface.]
> I'm certainly not claiming that such a method *should* be added, but
> may I ask why you think it reduces generality? I guess you are
> thinking of generic multivariate functions, with unspecified number of
> arguments (like sum(), product(), ...), but this could be handled by
> returning eg a negative value. Again, I'm not claiming anything, I'm
> just wondering (actually, wondering if what I did was wrong --or not
> so good--, in a project I'm working on at work...).

Both ways can be used and both are either good or bad depending on
context. We probably all have this kind of problems all the time. As
Apache Commons Math is a rather low level component in a complete
software stack, as many users are still used to non-object languages
(Fortran and C mostly), and as it is a library with many different users
and use cases, using very generic primitive arrays seems fair at this
level. For a dedicated application, using specific objects is better.

One reason I prefer primitive objects for low level components is that
most of the time you already need to do some mapping from your
domain-specific objects. With primitive arrays, you may simply rely on
passing references to existing internal data structures and avoid
copying them back and forth all the time, which is cumbersome, adds
management code, and may impact performance in iterative algorithms.

However, there is nothing against using several separate arguments in
high level applications even if they should be kept consistent with each
other, and there is nothing against using objects in low level
libraries. We may well change our mind in a few releases, this would not
be the end of the world.

>> Also, keeping it simple (although not totally safe) by using (arrays of)
>> primitive type makes the interface closer to what people are accustomed to
>> coming from e.g. the C language. This approach is also used in the
>> "...VectorialOptimizer" classes (see "BaseAbstractVectorialOptimizer" where
>> a check is done to verify that the "target" and "weight" arrays have the
>> same length).
>> That said, I agree that it would be nicer to have a completely uniform and
>> integrated set of interfaces. The current design is already quite a rework
>> of the previous state of affairs (see versions 2.1 and 2.2) with much of the
>> inconsistency and code duplication corrected. However, similarly to other
>> design issues raised during the last months, it is not clear that the
>> obvious solution at this point will lead to a clear improvement in the
>> overall design. I mean that the code might in fact need a more thorough
>> refactoring, not some patch here and there. But that work would be for the
>> next++ major release. :-)
>> Best,
>> Gilles
> I'm too new to this project to make any statement... We'll talk about
> that in a few years...

No, nobody is too new. Everybody can express their concerns and propose
something different.

best regards,

> Best regards,
> Sébastien
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message