On Thu, Jul 07, 2011 at 03:40:19PM +0200, Luc Maisonobe wrote:
> Le 07/07/2011 14:41, Gilles Sadowski a écrit :
> >Hi.
> >
> >>>We also do not have a clear separation between algorithms that take a
> >>>bracket (e.g. "BrentSolver") and those that don't (e.g. "NewtonSolver").
> >>>If the "solve" methods called by the user contains more parameters than
> >>>needed by the algorithm implemented in the instance, they will be
> >>>ignored. [In some sense, this is even worst than the bracketing "enum"
> >>>case. However, in both cases we could maybe assume that the user has a
> >>>minimal knowledge of the concept implemented in the class which he is
> >>>using.
> >>
> >>Although this could be solved by adding very clear documentation, I
> >>think it would be about the worst thing we could do. Ignoring what
> >>the user asks for will confuse many users. While I don't like it
> >>that much, in this case it would be better to use a fallback
> >>bracketing solver to guarantee the solution that the user asked for.
> >
> >I think that there is a misunderstanding here:
> >For the "bracketed solutions" use case, it will always be what the user
> >requested: Either the call to "solve" specify a "solutionType" parameter
> >and the bracketing will be used to provide the corresponding answer, or the
> >call to "solve" does not specify a "solutionType" and the solution of the
> >original algorithm will be returned.
> >
> >In "NewtonSolver", the interval bounds passed to "solve" are used to compute
> >the mid-point that is then used as the "startValue" of the solver. So it's
> >not to be interpreted as a bracket.
> >Maybe a safer alternative would be to throw an exception instead, as you
> >suggest below. However this implies that the user must compute the starting
> >point himself (i.e. we deprive him from syntactic sugar in this case...).
> >
> >>
> >>>And, again, not specifying a parameter (in the call to "solve")
> >>>won't do any harm ;-).]
> >>
> >>Sure. That is always a good idea, as it keeps backward compatibility.
> >>
> >>>Yes, this is probably a good point.
> >>>It could be solved by adding a "setBracketingSolver" method to the base
> >>>class. If not explicitely specified, which one should be the default?
> >>
> >>Of the secant-based methods Pegasus claims the fastest convergence
> >>rates, so I would suggest that one. If the Brent solver is
> >>bracketing, as you suggest, then it should probably be adapted to
> >>implement the allowed solutions as well, and then maybe that one
> >>could be used.
> >
> >This reminds me of a discussion we had some time ago about naming classes
> >according to well-known algorithms but slightly "improving" the
> >implementation. [It was about "LevenbergMarquardt".]
> >Is the choice of "..._SIDE" part of the algorithm's standard implementation?
> >In "Brent" it is not, and I think that it would be misleading to merge this
> >functionality within the core algorithm. IMHO, this would also point towards
> >the "refine" route.
> 
> At least it points towards have a separation from raw solvers.
> 
> >
> >>>However, if we do want to provide the utility, maybe that it should be
> >>>considered as such and _not_ as a solver by itself. E.g. some method
> >>>"refine" in some utility class:
> >>
> >>This has the downside of having to handle the different cases in
> >>very place we use them. For instance, the ODE solver's state event
> >>detection would have to check whether it is a bracketing solver, and
> >>if not, use the refine method. Other uses would get a duplication of
> >>that block of code.
> >
> >[I haven't looked at the ODE part of CM yet, so my comment here might be
> >completely off base.]
> >It seems that the ODE routines need a bracketing solver where you can
> >specify the location of the root. If this is so, it looks like it is
> >_inside_ the ODE code that it must be made sure that solution is the
> >correct one, and if not, "refine" it ("LEFT" or "RIGHT" according to the
> >needs of the procedure.
> >Even safer would be to only allow a "BracketingSolver" to be passed to the
> >ODE code. Why bother allowing an algorithm that do not guarantee the needs
> >of the ODE routines?
> 
> This is what was intended at first. Up to 2.2, users could not
> choose the solver, it was always Brent that was used and dirty
> tricks had to be done in the events detection to circumvent problems
> when the wrong side was returned. Now users can choose the solver,
> so we considered a few days ago that only bracketing solvers should
> be allowed. However, this is only due to an internal implementation.
> In fact, at user level there should not be any requirements for a
> bracketing solver, and in fact even if the user provides a
> bracketing solver we *will* reconfigure it to make sure the proper
> side is selected according to integration direction (forward or
> backward integration). So I considered adding the wrapper and let
> the user choose any solver he wants.
> 
> This is however internal code, so for this specific case, we can use
> any solution, be it a wrapper added before solving or a refinement
> after solving.

So, in the ODE code, there are "under hood", "magical", things going on!
Reconfiguration of a user-passed argument??? Shouldn't we instead throw an
exception if the user did not call "setAllowedSolution" with the correct
parameter? ;-)

Seriously, here the "user" code is the ODE code, and it is free to do
whatever necessary to get at its goal (i.e. as you say, refine the root so
that it is on the correct side). But then, the top-level user of the ODE
code will not really totally control the solver.
So I'd go for the simplest solution of the single use-case we have right
now: A "refine" method in "UnivariateRealSolverUtils".


Regards,
Gilles

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

Reply via email to