[ 
https://issues.apache.org/jira/browse/MATH-1658?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17737234#comment-17737234
 ] 

François Laferrière commented on MATH-1658:
-------------------------------------------

I gave a try to a "final" (in java sense) of BaseOptimizer.parseOptimizationData
{code:java}
    protected final void parseOptimizationData(OptimizationData... optData) {
        // The existing values (as set by the previous call) are reused if
        // not provided in the argument list.
        for (OptimizationData data : optData) {
            Class optDataClass = data.getClass() ;
            // String setterMethodName = "set" + optDataClass.getSimpleName();
            Method optDataSetter = null;

            // build a list of possible setter set<name> with name that can be
            // - current classname and all parent classname
            // - all interfaces implemented by the current class
            ArrayList<Class> classAndInterfaceList = new ArrayList<Class>();

            while (optDataClass != null) {
                classAndInterfaceList.add(optDataClass) ;
                optDataClass = optDataClass.getSuperclass();
            }

            Class[] interfaceTable = data.getClass().getInterfaces();
            for (Class interf : interfaceTable ) {
                classAndInterfaceList.add(interf) ;
            }

            boolean success = false;
            for (Class classOrInterface : classAndInterfaceList ) {
                try {
                    optDataSetter = this.getClass().getMethod("set" + 
classOrInterface.getSimpleName(), classOrInterface);
                    optDataSetter.invoke(this, data);
                    success = true ;
                    break;
                } catch (Exception e) {
                    continue ;
                }
            }
            if (!success) {
                // We should do nothing here to be fully compatible with 
previous
                // implementation that let pass silently unrecognized parameter
            }
        }
    }
{code}
Given that everywhere we give public write accessors 
of the form set<optDataClassName>(<optDataClass> data)
{code:java}
public void setMaxEval(MaxEval optData) {
        maxEvaluations = optData.getMaxEval();
    }
    
    public void setMaxIter(MaxIter optData) {
        maxEvaluations = optData.getMaxIter();
    }
    
    public void setConvergenceChecker(ConvergenceChecker<PAIR> optData) {
        checker = optData;
    }

{code}
Note that in my previous comment accessors were protected. This was a mistake: 
reflexion works only with public methods (or you have to fiddle with the 
SecurityManager; not a good idea)

Note also that if the accessor returns the current instance (instead of void) 
we may have a new fluent interface for the same price. for instance

 
{code:java}
public BaseOptimizer<PAIR> setMaxEval(MaxEval optData) {
    maxEvaluations = optData.getMaxEval();
    return this;
}{code}
On the long run, we may deprecate the parseOptimizationData and encourage  the 
use of fluent API which is simpler, and less prone to runtime error.

By the way, I gave a try to a full rewrite of the accessors and all junit tests 
pass.

 

> ConvergenceChecker should implement OptimizationData
> ----------------------------------------------------
>
>                 Key: MATH-1658
>                 URL: https://issues.apache.org/jira/browse/MATH-1658
>             Project: Commons Math
>          Issue Type: Improvement
>          Components: legacy
>    Affects Versions: 4.0-beta1
>            Reporter: François Laferrière
>            Priority: Minor
>         Attachments: 
> MATH-1658-ConvergenceChecker-implements-OptimizationData.patch
>
>
> It is a bit peculiar that with BaseOptimizer, ConvergenceChecker can be 
> passed only in constructor.
> It should be possible to change ConvergenceChecker at any other time.
> Further it is a bit strange that the constructor do not accept other 
> OptimizationData.
> In my use cases, I need to create an optimizer once with complex 
> OptimizationData and reuse it many time with very few changes (including 
> changing the ConvergenceChecker).
> So, I suggest that
>  * ConvergenceChecker implements OptimizationData.
>  * protected BaseOptimizer(ConvergenceChecker<PAIR> checker) is replaced by 
> protected BaseOptimizer(OptimizationData... optData) 
> Doing so is compatible with existing code and provide much more flexibility.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to