commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ole Ersoy <>
Subject Re: [math] Should this throw a NO_DATA exception?
Date Sat, 09 Jan 2016 06:27:37 GMT
Hi Gilles,

On 01/08/2016 07:37 PM, Gilles wrote:
> Hi Ole.
> Maybe I don't understand the point of the question but I'm
> not sure that collecting here answers to implementation-level
> questions is going to lead us anywhere.
Well it could lead to an improved implementation :).

> There is a issue on the bug-tracking system that started to
> collect many of the various problems (specific and general)
> of data containers ("RealVector", "RealMatrix", etc.) of the
> "o.a.c.m.linear" package.
> Perhaps it should more useful, for future reference, to list
> everything in one place.
Sure - I think in this case though we can knock it out fast. Sometimes when we list everything
in one place people look at it, get a headache, and start drinking :).  To me it seems like
a vector that is empty (no elements) is different from having a vector with 1 or more 0d entries.
 In the latter case, according to the formula, the norm is zero, but in the first case, is

> On Fri, 8 Jan 2016 18:41:27 -0600, Ole Ersoy wrote:
>> public double getLInfNorm() {
>>         double norm = 0;
>>         Iterator<Entry> it = iterator();
>>         while (it.hasNext()) {
>>             final Entry e =;
>>             norm = FastMath.max(norm, FastMath.abs(e.getValue()));
>>         }
>>         return norm;
>>     }
> The main problem with the above is that it assumes that the elements
> of a "RealVector" are Cartesian coordinates.
> There is no provision that it must be the case, and assuming it is
> then in contradiction with other methods like "append".

While experimenting with the design of the current implementation I ended up throwing the
exception.  I think it's the right thing to do.  The net effect is that if someone creates
a new ArrayVector(new double[]{}), then the exception is thrown, so if they don't want it
thrown then they should new ArrayVector(new double[]{0}).   More explanations of this design
below ...

> At first (and second and third) sight, I think that these container
> classes should be abandoned and replaced by specific ones.
> For example:
> * Single "matrix" abstract type or interface for computations in
>   the "linear" package (rather than "vector" and "matrix" types)
> * Perhaps a "DoubleArray" (for such things as "append", etc.).
>   And by the way, there already exists "ResizableDoubleArray" which
>   could be a start.
> * Geometrical vectors (that can perhaps support various coordinate
>   systems)
> * ...

I think we are thinking along the same lines here.  So far I have the following:
A Vector interface with only these methods:
- getDimension()
- getEntry()
- setEntry()

An ArrayVector implements Vector implementation where the one and only constructor takes a
double[] array argument.  The vector length cannot be mutated.  If someone wants to do that
they have to create a new one.

A VectorFunctionFactory class containing methods that return Function and BiFunction instances
that can be used to perform vector mapping and reduction.  For example:

      * Returns a {@link Function} that produces the lInfNorm of the vector
      * {@code v} .
      * Example {@code lInfNorm().apply(v);}
      * @throws MathException
      *             Of type {@code NO_DATA} if {@code v1.getDimension()} == 0.
     public static Function<Vector, Double> lInfNorm() {
         return lInfNorm(false);

      * Returns a {@link Function} that produces the lInfNormNorm of the vector
      * {@code v} .
      * Example {@code lInfNorm(true).apply(v);}
      * @param parallel
      *            Whether to perform the operation in parallel.
      * @throws MathException
      *             Of type {@code NO_DATA} if {@code v.getDimension()}  == 0.
     public static Function<Vector, Double> lInfNorm(boolean parallel) {
         return (v) -> {
             IntStream stream = range(0, v.getDimension());
             stream = parallel ? stream.parallel() : stream;
             return stream.mapToDouble(i -> Math.abs(v.getEntry(i))).max().getAsDouble();

So the design leaves more specialized structures like Sparce matrices to a different module.
 I'm not sure if this is the best design, but so far I'm feeling pretty good about it.  WDYT?


To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message