octave-maintainers
[Top][All Lists]
Advanced

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

Re: mapper functions for 3.1


From: John W. Eaton
Subject: Re: mapper functions for 3.1
Date: Sat, 16 Feb 2008 04:37:09 -0500

On 16-Feb-2008, David Bateman wrote:

| Here is an update to the mapper patch implementing your idea..

Thanks.

Since all the map functions for the Array<T> classes look the same, I
think we should be able to push them down to the Array<T> level, but
it will require some template tricks because it seems you can't do
something like

  template <class T>
  class Array
    ...
    template <class U>
    Array<U> map (U (*fcn) (T)) { ... }

but instead you need to wrap the function pointer in a class.  For
example, we need something like

  template <typename RT, typename PT>
  class fcn_ptr
  {
  public:
    typedef RT (*TYPE) (PT);
  };

  template <typename RT, typename PT>
  class functor
  {
  private:
    typedef typename fcn_ptr<RT, PT>::TYPE fcn_ptr_type;
    fcn_ptr_type fptr;

  public:

    functor (fcn_ptr_type p) : fptr (p) { }

    RT operator () (PT arg) { return fptr (arg); }
  };

  template <typename RT, typename PT>
  functor<RT, PT>
  func_ptr (RT (*f) (PT))
  {
    return functor<RT, PT> (f);
  }

then we can write

  template <class U, class F>
  Array<U>
  map (F fcn) const
  {
    octave_idx_type len = length ();

    const T *m = data ();

    Array<U> result (dims ());
    U *p = result.fortran_vec ();

    for (octave_idx_type i = 0; i < len; i++)
      {
        OCTAVE_QUIT;

        p[i] = fcn (m[i]);
      }

    return result;
  }

and then in ArrayN.h:

  template <class U, class F>
  ArrayN<U> map (F fcn) const
  {
    return Array<T>::template map<U> (fcn);
  }

and MArrayN.h:

  template <class U, class F>
  MArrayN<U> map (F fcn) const
  {
    return ArrayN<T>::template map<U> (fcn);
  }

and (for example) dNDArray.h:

  NDArray map (double (*fcn) (double)) const;
  ComplexNDArray map (Complex (*fcn) (const Complex&)) const;
  boolNDArray map (bool (*fcn) (double)) const;

and finally in dNDArray.cc:

  NDArray
  NDArray::map (double (*fcn) (double)) const
  {
    return MArrayN<double>::map<double> (func_ptr (fcn));
  }

  ComplexNDArray
  NDArray::map (Complex (*fcn) (const Complex&)) const
  {
    return MArrayN<double>::map<Complex> (func_ptr (fcn));
  }

  boolNDArray
  NDArray::map (bool (*fcn) (double)) const
  {
    return MArrayN<double>::map<bool> (func_ptr (fcn));
  }

Do you see any potential problem in doing this?  I'm assuming that the
different map functions you defined are all functionally identical and
only differ in the types of the arguments and return values.  Is that
correct?  If so, I can make this change for the Array class but it may
take me a few days to get to it.  I suspect something similar can be
done for the Sparse class, but I haven't looked at it.

jwe


reply via email to

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