Hi Gilles,

Le 08/11/2011 16:29, Gilles Sadowski a écrit :
>>> Hi all,
> 
> Hi Luc.
> 
>>>
>>> Gilles has started adding an API for simple bounds constraints in
>>> optimization, which will soo be available for both Bobyqa and CMA-ES, as
>>> both method naturally support such constraints.
>>>
>>> I wondered if we could take the opportunity to set up a poor man
>>> implementation in the abstract base class for optimizers that do not
>>> support constraints, such as Nelder-Mead and Virginia Torczon's
>>> multi-directional algorithm. Gilles work on the proper API plus this
>>> poor man implementation would allow solving the old issue MATH-196 I
>>> created 3 years and an half ago ...
>>>
>>> A basic implementation can be based on an array of mappers inserted
>>> between the user variables and the variables the optimizer manages. For
>>> each component of the current point x[i] considered in user space, we
>>> would map it to an optimizer variable y[i] using:
>>>
>>>   for (int i = 0; i < n; ++i) {
>>>     y[i] = mapper[i].encode(x[i]);
>>>   }
>>>
>>> and a similar setting for retrieving x[i] from y[i] using a decode
>>> function. The x[i] variables would be subject to bounds (some may be
>>> bounded and others not bouded), whereas y[i] would all be unbounded.
>>>
>>> Mapper would be an interface with four implementations, depending on bounds.
>>>
>>> NoBoundsMapper would be used for components x[i] which are nturally
>>> unbounded, encode and decode would be the identity function.
>>>
>>> LowerBoundMapper would be used for components x[i] that must be larger
>>> than a lower bound a:
>>>   encode(x) = ln(x - a)
>>>   decode(y) = a + exp(y).
>>>
>>> UpperBoundMapper would be used for components x[i] that must be lesser
>>> than an upper bound b:
>>>   encode(x) = -ln(b -x)
>>>   decode(y) = b - exp(-y).
>>>
>>> LowerUpperBoundMapper would be used for components x[i] that must be
>>> betwee lower bound a and upper bound b:
>>>   encode(x) = ln((x - a) / (b - x))
>>>   decode(y) = (a + b exp(y)) / (1 + exp(y))
>>
>> I forgot to say all these classes would be internal ones, the user would
>> never see them, he will simply see Gilles API with the bounds arrays,
>> where some elements of the array could be set to infinity, or some
>> arrays could be null which would be equivalent to set all their
>> components to infinity with the proper sign.
>>
>> Luc
>>
>>>
>>> Due to numerical considerations and the fact infinity can be
>>> represented, I'm not sure if the bounds can be reached or not, it
>>> probably depends on how we implement the encode/decode functions.
>>>
>>> For sure, it does not replace proper handling of bounds, but it would be
>>> quite useful. It is what we suggested as a fallback solution to several
>>> users who needed constrained optimization.
>>>
>>> If you agree with this, I could implement it in the next few days, so
>>> Gilles could set up the proper handling for CMA-ES and fine-tune the API.
>>>
>>> What do you think about this ?
> 
> I wonder whether this feature should be "prominent" rather than "internal".
> By having it an implementation detail we run the risk of giving a false
> impression of an algorithm's ability to correctly/efficiently deal with the
> constraints. It seems dangerous to hide a feature that is in fact not part
> of the "standard" implementation (cf. another discussion where this point
> was also raised).

In this case, the new API with boundaries setting should not be set at
the level of the abstract class that is share by CMA-ES, Bobyqa,
Nelder-Mead and MultiDirectional.

I proposed this implementation, as a way to provide this even for the
last two methods. Of course, we should document this. In this case, it
is not a modification of the algorithm, and in fact we do rely on the
original ones. We simply add another method, which uses an internal adapter.

> An alternative would be to create an adapter class (which users would have
> to explicitly instantiate) that would take care of the conversion from
> bounded to unbounded.
> Concerning the mapping itself, it migh be useful to be able to select the
> "encode" and "decode" functions.[1]

Fine, I missed this.

> 
> Another argument for not hiding the mapping is that another poor man's
> approach is to use a penalty (when the optimizer's "guess" falls out of
> bounds) and I wonder whether some algorithm could behave better with one or
> the other approach.

As far as I understand, direct methods that do not rely on derivatives
support well penalty functions. Gradients based methods do not.

> 
> It would be nice to have an optimization specialist's opinion on this whole
> issue.

Sure.

best regards,
Luc

> 
> 
> Regards,
> Gilles
> 
> [1] The classes "Logit" and "Sigmoid" (in "o.a.c.m.analysis.function") were
>     introduced for exactly this purpose.
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
> For additional commands, e-mail: dev-h...@commons.apache.org
> 


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

Reply via email to