octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: min and max functions


From: Jaroslav Hajek
Subject: Re: min and max functions
Date: Fri, 14 Nov 2008 10:04:55 +0100

On Thu, Nov 13, 2008 at 11:04 PM, John W. Eaton <address@hidden> wrote:
> I see that we have many versions of these functions
>
>  min (scalar, array)
>  min (array, scalar)
>  min (array, array)
>
> (and the same for max).  I think they appear in all of the following
> classes:
>
>   Matrix   FloatMatrix   ComplexMatrix   FloatComplexMatrix
>   NDArray  FloatNDArray  ComplexNDArray  FloatComplexNDArray
>
>   int8NDArray   int16NDArray   int32NDArray   int64NDArray
>   uint8NDArray  uint16NDArray  uint32NDArray  uint64NDArray
>
> I don't see an obvious place to put these templates because the class
> hierarchies are
>
>  Matrix  <- MArray2 <- Array2 <- Array
>  NDArray <- MArrayN <- ArrayN <- Array
>

IMHO, it would be best if we simply drop Array2 and ArrayN (they
really add no functionality), and have a single MArray class. Given
that Array itself can be multidimensional, these specializations are
actually weird.
I also think it's actually possible to move most or all code from the
*Matrix classes to MArray or add another inheritance layer
(base_matrix).
Btw. is using multiple inheritance acceptable for Octave?

> (for example) and Jaroslav has already suggested (and I agree) that it
> would be best to avoid requiring that the elements of an Array object
> have an operator < method.
>
> I think it would still be good to avoid the explicit code
> duplication, which I think we could do using templates like this
>
>  template <typename ARRAY_T>
>  ARRAY_T
>  min (typename ARRAY_T::element_type scalar, const ARRAY_T& array)
>  {
>    dim_vector dv = array.dims ();
>    octave_idx_type nel = dv.numel ();
>
>    ARRAY_T result (dv);
>
>    if (nel != 0)
>      {
>        for (octave_idx_type i = 0; i < nel; i++)
>          {
>            OCTAVE_QUIT;
>            result(i) = xmin (d, array(i));
>          }
>      }
>
>    return result;
>  }
>
> etc., along with suitable definition of xmin (or xmax).  I hesitate to
> use < here since this should work for complex types and we have to do
> the right thing for NaN and I think it would be best to hide all of
> that inside a function.  Otherwise, it is not as easy to take
> advantage of the template for integer types, or we need to define a
> bunch of specializations, which goes against my reason for trying to
> eliminate the duplication...
>

Personally, I think the best solution is a set of general "reduction"
template algorithms. See the norm accumulators in oct-norm.cc - they
demonstrate precisely this idea. You just supply a class that can 1.
initialize an object 2. accept a next number 3. yield the final value.
These objects can be easily defined for max, min, sum, product, any,
all, the p-norms, and maybe more.


> So, if we make a change like this, where should we put these
> templates?  Do we need an octave-algorithms.h header file?
>
> OTOH, there is no difference between the template for the Matrix and
> NDArray objects, so they could easily go in the base class if we had
> an acceptable one that was common to both classes.
>
> Thinking about this a little more, is the Matrix class in the wrong
> spot in the hierarchy?  Is it necessary to have the Array2 and MArray2
> classes now (they really only exist for historical reasons as Octave
> did not originally have N-d arrays)?  Should the Matrix class just be
> an NDArray object with the added constraint that there are only two
> dimensions?  If so, what would be the right way to enforce that?
>

See above. The only reason for Matrix vs. NDArray is that 2D arrays
are capable of some things N-d arrays are not. Some of these can be
reasonably extended to NDArrays (like matrix multiplication), some
cannot (factorizations). I think we can have something like
Array<T> -> MArray<T> -> MArray2<T>
typedef MArray<double> NDArray; // etc
typedef MArray2<double> Matrix; // etc
No need for Array2, IMHO (when you have no operations, there's no need
to require two dimensions).

That way, you can easily write a template function that is supposed to
work with N-d arrays (and will also work with matrices), or a function
that should work with matrices only.



> jwe
>



-- 
RNDr. Jaroslav Hajek
computing expert
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz


reply via email to

[Prev in Thread] Current Thread [Next in Thread]