octave-bug-tracker
[Top][All Lists]
Advanced

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

[Octave-bug-tracker] [bug #55682] round(X,N) and round(X,N,type)


From: Rik
Subject: [Octave-bug-tracker] [bug #55682] round(X,N) and round(X,N,type)
Date: Fri, 24 May 2019 13:00:00 -0400 (EDT)
User-agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko

Follow-up Comment #6, bug #55682 (project octave):

Adding jwe to the CC list for some guidance on coding strategy.

This bug would be easy to resolve by writing a new m-file round.m and renaming
the C++ function to something internal like __round__.  In Octave's languagage
the operation to accomplish is just


Y=round(X*10^N)/10^N;


However, round is used so frequently by coders coming from Matlab that I think
it is important that it be written in C++ for speed.  The input validation,
written in an m-file, would be significant.

So I started down that route, but it has gotten ugly.

The function round is in mappers.cc.  I rewrote the first bit to


  if (nargin == 1)
    return ovl (args(0).round ());


which exactly preserves the functionality we have today where the round()
function is a method on an octave_value object.

I then tried the following which works, but seems kind of slow because I am
not doing an in-place map operation on the object x.


octave_value_list retval (1);
 
if (args(0).is_double_type ())
  {
    if (args(0).isreal ())
      {
        Matrix x = args(0).matrix_value ();
        x *= pow (10.0, N);
        x = x.map<double> (octave::math::round);
        x /= pow (10.0, N);
        retval(0) = octave_value (x);
verbatim-

I can work around this by writing my own static function in mappers.cc.


template <typename T>
void
do_map_round (Array<T>& x)
{
  for (octave_idx_type i = 0; i < x.numel (); i++)
    x.xelem (i) = octave::math::round (x.xelem (i));
}


followed by 


octave_value_list retval (1);
 
if (args(0).is_double_type ())
  {
    if (args(0).isreal ())
      {
        NDArray x = args(0).array_value ();
        x *= pow (10.0, N);
        do_map_round (retval);
        x /= pow (10.0, N);
        retval(0) = octave_value (x);


Of course, I will have to write at least 4 if branches (double+real,
double+complex, single+real, single+complex) and maybe another two branches
for (sparse+real, sparse+complex).  Is there some other, more natural way, to
tackle this?

A diff for the changes so far is attached.



(file #46967)
    _______________________________________________________

Additional Item Attachment:

File name: roundn.diff                    Size:3 KB
    <https://savannah.gnu.org/file/roundn.diff?file_id=46967>



    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?55682>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/




reply via email to

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