octave-maintainers
[Top][All Lists]
Advanced

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

Re: Why NDArray is faster than int32NDArray?


From: John W. Eaton
Subject: Re: Why NDArray is faster than int32NDArray?
Date: Thu, 28 Jul 2011 15:03:35 -0400

On 28-Jul-2011, Hamid 2C wrote:

| > The data for an NDArray object is stored in an array of native double
| > values.
| >
| > Because of the semantics of integer operations that Octave must
| > implement for compatibility with Matlab, the data for an int32NDArray
| > object is stored as an array of octave_int32 objects.  The
| > multiplication and addition operators for octave_int32 objects must do
| > more than just multiply integer values.  They must also handle the
| > saturation semantics of Matlab's integer types.
| >
| > If you want to use native integer multiplication with wrapping
| > semantics, you'll have to do something different.
| >
| 
| Thanks for your reply. Could you please point me to some direction (to
| perform native integer multiplication). I would like to have a
| function that can be dynamically loaded to Octave and get its
| parameters (which are known to be matrices of integer) from the Octave
| interpreter.

The following works for me to bypass the octave_int multiplication and
addition operators.  I used int8 so that you can see the values
wrapping with smaller numbers than would show it with 32-bit integers.

  //mymult.cpp
  #include <octave/oct.h>
  #include <iostream>
  #include <cstdlib>
  DEFUN_DLD (mymult, args, nargout, "")
  {
    octave_value_list retval;

    int8NDArray x = args(0).int8_array_value ();
    int8NDArray y = args(1).int8_array_value ();

    octave_idx_type d1x = x.rows ();
    octave_idx_type d2x = x.columns ();
    octave_idx_type d1y = y.rows ();
    octave_idx_type d2y = y.columns ();

    if (d2x != d1y)
      {
        error ("incompatible dimensions");
        return retval;
     }

    int8NDArray z (dim_vector (d1x, d2y));

    for (octave_idx_type i = 0; i < d1x; i++)
      {
        for (octave_idx_type j = 0; j < d2y; j++)
          {
            z.xelem(i,j) = 0;
            for (octave_idx_type k = 0; k < d1y; k++)
              {
                int8_t tmp = z.xelem(i,j).value() + x.xelem(i,k).value() * 
y.xelem(k,j).value();
                z.xelem(i,j) = tmp;
              }
          }
      }

    return octave_value (z);
  }

Oddly, writing the body of the innermost loop as

  z.xelem(i,j) = z.xelem(i,j).value() + x.xelem(i,k).value() * 
y.xelem(k,j).value();

does not work as I expect.  There seems to be a subtle bug here, as I
would expect this to be equivalent to the version with the temporary
variable.

Also note my use of octave_idx_type in the code above.  You probably
want to use that instead of int if you ever want your code to work
properly for very large arrays on 64-bit systems.

Finally, the help list would be more appropriate for questions like
this.  The maintainers list is really supposed to be for discussions
about the development of Octave, not about how to use it.

jwe


reply via email to

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