Hello,

I am a little puzzled by our use of generics in the analysis.solvers package.

Hoping the following ASCII art will survive mail, here is a rough overview (simplified) of what we have.

              BaseUnivariateRealSolver<FUNC>
                          |
        +-----------------+---------------------+
        |                                       |
        |                                       |
 UnivariateRealSolver,         BaseAbstractUnivariateRealSolver<FUNC>
   PolynomialSolver,                            |
DifferentiableUnivariateRealSolver              |
        |                                       |
        |                                       |
        +-----------------------+---------------+
                                |
                                |
           +--------------------+-----+----------------+
           |                          |                |
AbstractUnivariate...   AbstractPolynomial... AbstractDifferentiable...
           |                          |                |
     +-----+----------+               |                |
     |                |               |                |
 BrentSolver, BaseSecantSolver   LaguerreSolver    NewtonSolver
                     |
                     |
                     |
         BaseBracketedSecantSolver
                     |
                     |
                     |
      +--------------+---------------+
      |              |               |
      |              |               |
      |              |               |
  Illinois      Pegasus        RegulaFalsi

At top level (lets call it level 0), there is a generified interface: BaseUnivariateRealSolver<FUNC extends UnivariateRealFunction>

One level below (lets call it level 1a), there are three interfaces that merely pin the generic type: UnivariateRealSolver for UnivariateRealFunction, PolynomialSolver for PolynomialFunction, DifferentiableUnivariateRealSolver for DifferentiableUnivariateRealFunction.

At the same level (lets call it level 1b) there is an abstract class: public abstract class BaseAbstractUnivariateRealSolver<FUNC extends UnivariateRealFunction> implements BaseUnivariateRealSolver<FUNC>.

One level below (lets call it level 2), we have three abstract classes that both extends BaseAbstractUnivariateRealSolver from level 1b and implement one of the interface from level 1a: AbstractUnivariateRealSolver, AbstractPolynomialSolver and AbstractDifferentiableUnivariateRealSolver.

One level below (lets call it level 3), we have a few implementations like BrentSolver and a bunch of others for general function, LaguerreSolver for polynomials and NewtonSolver for differentiable functions.

There are also levels 4 and 5 for the new bracketing solvers, since BaseSecantSolver from level 3 is itself an abstract class that has several implementations.

In parallel, there is the new interface BracketedUnivariateRealSolver which extends UnivariateRealSolver (not shown in the picture above).

I am at loss trying to create a wrapper class that would allow taking a non-bracketing solver and add bracketing features to it (merely by adding a few steps after the raw non-bracketing solver has found a root, in case it is not on the chosen side).

The first point is we use "UnivariateReal" both as the name of the topmost level type when nothing is specified (just as in the name of the level 0 interface and level 1b abstract class), and as the name of generic functions, in parallel with polynomial and differentiable functions. Shouldn't we have a different name for both notions ? We could have for example UnivariateRealFunction at top level and GeneralRealFunction at low level. This would help separate the meanings from level 1b and level 2.

The second point is I don't understand the purpose of interfaces from level 1a.

If on the one hand someone implements a solver by taking advantage of the generified BaseAbstractUnivariateRealSolver we provide, these interface merely force to add a redundant implement clause with declarations like the ones found at level 2:

  AbstractXxxsolver extends BaseAbstractXxxSolver<XxxFunction>
                    implements  XxxSolver

instead of using only

  AbstractXxxsolver extends BaseAbstractXxxSolver<XxxFunction>

If on the other hand someone implements a solver without taking advantage of the generified BaseAbstractXxxSolver we provide, these interface simply allow to write:

  AbstractXxxsolver implements  XxxSolver

instead of using only

  AbstractXxxsolver implements BaseUnivariateRealSolver<XxxFunction>

I think removing the interfaces from level 1b would simplify the architecture and help users understand. We would avoid the losange-shape inheritance between levels 0, 1a/1b and 2.

The third point is I think I messed thing when I inserted BracketedUnivariateRealSolver interface back in the hierarchy a few days ago by extending UnivariateRealSolver. I should probably have generified it and have it extend BaseUnivariateRealSolver<FUNC extends UnivariateRealSolver>, thus allowing to have bracketing solvers also for polynomials and differentiable functions. Do you agree with this ?

The fourth point is the generified BaseAbstractUnivariateRealSolver we provide (level 1b, right of the losange). It forces to implement a doSolve but in this method we cannot access the function itself and we cannot reset the evaluations: the fields are private and have no accessors, even protected, we can only call the function and incrementing the evaluation at the same time, counting from a setting the derived class cannot change. I need access to the function and I need access to the counter. So i think I will add some accessors for them. Does this seems reasonable to other developers ?

Well, sorry for this long message and the ugly picture. You have a few hours to read it, as I will not be able to discuss in the few next hours.

thanks for your attention ;-)

Luc

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

Reply via email to