commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Luc Maisonobe (JIRA)" <>
Subject [jira] Commented: (MATH-313) Functions could be more object-oriented without losing any power.
Date Fri, 30 Oct 2009 14:36:59 GMT


Luc Maisonobe commented on MATH-313:

I guess you didn't get my point so I'll try to be more explicit.
I don't speak about solvers classes, which users almost never extend. I speak about the functions
that are solved, which are what the user must implement.
Of course, if a solver accepts an UnivariateRealFunction as parameter it will accept an AbstractUnivariateRealFunction
without any change, but it's not the point.

Consider a user with an existing AbstractSensor and a complete classes hierarchy extending
this abstract class: OpticalSensor, ContactSensor, HeatSensor, SmellSensor, TelepathicSensor,
QuanticSensor, MagicSensor ... One of these derived class, say HeatSensor also implements
UnivariateRealFunction because it is used somewhere to find when the heat crosses a desired
public class HeatSensor extends AbstractSensor implements UnivariateRealFunction {

  public double getHeat(double controlValue) {
     // some computation

   public double f(double controlValue) {
      return getHeat(controlValue) - desiredHeat;


The previous code is sufficient to find the controlValue that should be used to get the desired
heat by providing an instance of this user class to one of the existing commons-math solvers.
This user really doesn't want to implement seven methods when he really needs only one. The
contract for the solvers is that the must be able to call f, that's all. HeatSensor cannot
extend AbstractUnivariateRealFunction because it already extends AbstractSensor.

There is a big conceptual difference between interfaces that users are almost forced to implement
because they will provide instances to commons-math algorithms and interfaces that are rather
extension points for which we provide one or a few implementations but want to let users add
their own. In the first set, you will find UnivariateRealfunction (analytical), MutationPolicy
(genetics), RealMatrixChangingVisitor (linear), FirstOrderDifferentialEquation (ode) ... In
the second set you will find RealVector, RealMatrix, ODEIntegrator ...

The interfaces from the first step should remain as simple as possible.

Could you on your side present real use cases for functions composition that could not be
handled by a simple:
UnivariateRealFunction gaussian = new UnivariateRealFunction {
  public double f(double t) {
      return Exp.f((Negate.f(Pow2.f(t))));

> Functions could be more object-oriented without losing any power.
> -----------------------------------------------------------------
>                 Key: MATH-313
>                 URL:
>             Project: Commons Math
>          Issue Type: New Feature
>    Affects Versions: 2.0
>         Environment: all
>            Reporter: Jake Mannix
>             Fix For: 2.1
> UnivariateRealFunction, for example, is a map from R to R.  The set of such functions
has tons and tons of structure: in addition to being an algebra, equipped with +,-,*, and
scaling by constants, it maps the same space into itself, so it is composable, both pre and
> I'd propose we add:
> {code}
>   UnivariateRealFunction plus(UnivariateRealFunction other);
>   UnivariateRealFunction minus(UnivariateRealFunction other);
>   UnivariateRealFunction times(UnivariateRealFunction other);
>   UnivariateRealFunction times(double scale);
>   UnivariateRealFunction preCompose(UnivariateRealFunction other);
>   UnivariateRealFunction postCompose(UnivariateRealFunction other);
> {code}
> to the interface, and then implement them in an AbstractUnivariateRealFunction base class.
 No implementer would need to notice, other than switching to extend this class rather than
implement UnivariateRealFunction.
> Many people don't need or use this, but... it makes for some powerfully easy code:
> {code}UnivariateRealFunction gaussian = Exp.preCompose(Negate.preCompose(Pow2));{code}
> which is even nicer when done anonymously passing into a map/collect method (a la MATH-312).

This message is automatically generated by JIRA.
You can reply to this email to add a comment to the issue online.

View raw message