commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Luc Maisonobe <...@spaceroots.org>
Subject [math] introducing DerivativeStructure into solvers hierarchy
Date Fri, 24 Aug 2012 09:34:07 GMT
Hi all,

As explained in various messages on this list, I am introducing an
enhanced differentiation framework into [math]. The low level part lies
in the analysis.differentiation package.

This low level part has already been integrated with the basic
functions, together with the older framework. The functions therefore
implement both the new UnivariateDifferentiable and the older
DifferentiableUnivariateFunction interface. The old one is deprecated
and will be removed in 4.0.

I am now integrating this framework into the solvers hierarchy. This is
not as easy. The current hierarchy is depicted here:
<http://people.apache.org/~luc/plantuml-apache-commons-math/solver.png>.

The top level interface is BaseUnivariateSolver, which is parameterized
using the type of function that are handled. So for example the second
level interface UnivariateSolver simply specifies the type to be
UnivariateFunction as follows:

public interface UnivariateSolver
    extends BaseUnivariateSolver<UnivariateFunction> {}

There are similar specialization for polynomials and differentiable
functions. I need to introduce a new specialization for the new
UnivariateDifferentiable interface. This part is trivial.

Between these interfaces and the lowest level solvers, there are some
intermediate classes that manage boilerplate for several kind of
solvers, the general purpose BaseAbstractUnivariateSolver class which is
also parameterized just as the top level interface, and the more
specialized AbstractUnivariateSolver,
AbstractDiffernetiableUnivariateSolver and AbstractPolynomialSolver.
Here again, adding a new abstract class is trivial.

At the lowest level, we have the solvers themselves (Brent, Muller,
Ridder, Illinois ...). The one I am interested in is the NewtonSolver,
which extends AbstractDifferentiableUnivariateSolver.
AbstractDifferentiableUnivariateSolver by itself extends
BaseAbstractUnivariateSolver<DifferentiableUnivariateFunction> and
implements DifferentiableUnivariateSolver.

It seems to me I cannot do the same thing I did for functions: I cannot
have the class (neither the concrete low level nor the abstract
intermediate level) support both the old and the new interfaces, and
mark the old methods as deprecated. The problem is that as the top level
interface is parameterized, this would imply something along these lines
in the classes hierarchy:

  SomeClass implements
            BaseUnivariateSolver<DifferentiableUnivariateFunction>,
            BaseUnivariateSolver<UnivariateDifferentiable>

However, Java forbids implementing an interface twice with different
parameters (I guess this as something to do with type erasure).

I see three different solutions for this.

1) don't try to merge at all, and duplicate the Newton solver with the
   new type.
2) change the Newton solver to implement only the new interface (i.e.
   remove the "implements" statements for the former interfaces but
   let the old methods in place (they would appear as independent
   methods, declared deprecated)
3) add solve methods with the new signature in the existing Newton
   solver, but do not declare them as implementation of the new
   interface (they would appear as independent methods)

Solution 1 is easy but would imply a new name is chosen for the solver,
and would stick when the former solver is removed. Using something as
Newton2 may seem good while Newton is still there, but would be awckward
when it will be removed, so we should either choose a different name or
rename Newton2 into Newton later on. I don't like this.

Solution 2 is not backward compatible. Some users may have written
something like the following, which would not compile anymore:
  DifferentiableUnivariateSolver solver = new Newton(...);

Solution 3 is my prefered choice, it is the opposite of solution 2. It
allows user to prepare using the new framework without breaking existing
code (at least I think). It's drawback will be that when 4.0 will be
released, the base class and interfaces for this Solver will be switched.

What do you think?

best regards,
Luc

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


Mime
View raw message