[
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)