bugGNU Octave - Bugs: bug #45758, for 'range' type input some...

 
 

bug #45758: for 'range' type input some functions fail to return type range

Submitter:  Michael Godfrey <godfrey>
Submitted:  Fri 14 Aug 2015 11:14:02 AM UTC
   
 
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Feature Request
Status:  Confirmed Assigned to:  None
Originator Name:  Godfrey Open/Closed:  * Open
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Fri 21 Aug 2015 05:46:33 PM UTC, comment #8: 

Would the range class a template be cleaner?
Would not require test in do_colon_op.
Seems a good idea to me. No obvious side-effects.

Michael Godfrey <godfrey>
Group Member
Fri 21 Aug 2015 05:11:29 PM UTC, comment #7: 

For better compatibility with Matlab, the class of an expression like


int8(1):int8(10)


should be int8.  That might be fairly straightforward to handle by fixing the do_colon_op function in ov.cc, at least when special storage for ranges is disabled.  Or we could make the Range class a template so that it can handle types other than double.

John W. Eaton <jwe>
Group administrator
Thu 20 Aug 2015 03:35:51 PM UTC, comment #6: 

The possible source of confusion I see is not that range types are not preserved in some functions, but that the class of the range is always double.  I think the base assumption might be that a range constructed from type X variables would itself be of type X.  See an example below with uint8.


octave:1> lo = uint8 (1)
lo = 1
octave:2> hi = uint8 (5)
hi = 5
octave:3> x = lo:hi
x =

   1   2   3   4   5

octave:4> class (x)
ans = double
octave:5> y = uint8 (lo:hi)
y =

  1  2  3  4  5

octave:6> class (y)
ans = uint8


I'm not arguing to change this, as I think it would involve a lot of code for very few actual usage cases; just pointing out that this probably violates people's internal expectations.

If there was a change to make to the Range class I would like to see the extension to column vectors.  I understand why Ranges were implemented first for row vectors to compact the argument to a for loop.  But it has always seemed a little strange that x = 1:50 is fine but taking the transpose with y = x' undoes all of the magic.

Rik <rik5>
Group administrator
Wed 19 Aug 2015 06:44:50 PM UTC, comment #5: 

I created the range type as a space optimization for the colon operator in the scripting language because I didn't think it made sense to run out of memory for an expression like


for i = 1:huge_number
  ...
end


I could have restricted this optimization just to FOR loops, but then things like the above would be allowed but


x = 1:huge_number;
for i = x
  ...
end


would still fail.  It didn't occur to me to also allow the range type to allow integer types or to be N-dimensional (with all but one dimension == 1).  I suppose we could make those changes now if we really wanted to, but it seems like a lot of work for little gain.

John W. Eaton <jwe>
Group administrator
Wed 19 Aug 2015 06:40:36 PM UTC, comment #4: 

I think it would be possible to use a template to avoid duplicating a lot of code if you want to provide integer and float versions of the mixed range/scalar operators.  But is it really necessary?  For


typeinfo (1:5 + int8 (3))


I get "range", so it seems like Octave is already doing the right thing.

John W. Eaton <jwe>
Group administrator
Fri 14 Aug 2015 07:02:26 PM UTC, comment #3: 

Rik:  OK. Just wanted to point this out. What you
say makes sense.

John may have a bit of time to comment on all this
in a well-informed way.

Michael Godfrey <godfrey>
Group Member
Fri 14 Aug 2015 05:38:25 PM UTC, comment #2: 

ranges only exist as "row" vectors.  If you do anything that reshapes the row vector into something else then Octave converts to a matrix and manipulates that instead.

For example,


octave:8> x = 1:50;
octave:9> whos x
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  =====
        x           1x50                        24  double

Total is 50 elements using 24 bytes

octave:10> x = x';
octave:11> whos x
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  =====
        x          50x1                        400  double

Total is 50 elements using 400 bytes


I suppose one could arrange for flip.m to have a special case that checks the typeinfo() of the input and if it is a range then it reverses it.  But that might be overkill for how often it gets used.  Most ranges seem to be used for indexing or for loops and so there is not much reason to call flip on them.

For changing a range by multiplication or addition/subtraction see the following function prototypes in Range.h


extern OCTAVE_API Range operator - (const Range& r);
extern OCTAVE_API Range operator + (double x, const Range& r);
extern OCTAVE_API Range operator + (const Range& r, double x);
extern OCTAVE_API Range operator - (double x, const Range& r);
extern OCTAVE_API Range operator - (const Range& r, double x);
extern OCTAVE_API Range operator * (double x, const Range& r);
extern OCTAVE_API Range operator * (const Range& r, double x);


As you can see, only arguments of type double are supported.  One could expand this to include single and all the integer classes, but it would certainly lead to a lot of similar looking code (7 functions * 9 types = 63 new declarations).  I'm not sure it's worth it since this seems like a low probability way of using ranges.

In all of these cases Octave falls back to a full matrix which is exactly what Matlab does so it is no worse than the competition.  I think we would want to go to the trouble of coding this only if these are reasonably frequent usage cases.

Rik <rik5>
Group administrator
Fri 14 Aug 2015 03:48:00 PM UTC, comment #1: 

An additional comment on type range:
Only type double variables multiplied by or used
for add/subtract of the righthand side of
the construction:
r = x1:x2:x3;
produce an r of type range.

Would it lead to problems if int[8,16,32,64] and single types
were allowed as multipliers or add/subtract values
preserving the type range?

Michael Godfrey <godfrey>
Group Member
Fri 14 Aug 2015 11:14:02 AM UTC, original submission:  

Bug #45739 has brought to light the fact that some
functions which are expected to return a result of
the same type as the input that is to be processed
fail to do this in the case that the input is type
'range'.

At the base of this is: flip. For example:

>> r = 1:2:7

r =

   1   3   5   7

>> a= flip(r,2)

a =

   7   5   3   1

>> typeinfo(a)

ans = matrix

>>


This affects at least: fliplr, flipud, rot90, rotdim.
permute is also invoked in these functions.

Michael Godfrey <godfrey>
Group Member

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by godfrey (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 2 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2015-08-14 rik5 Item GroupIncorrect Result Feature Request
        StatusNone Confirmed

    Back to the top

    Powered by Savane 3.13-cf05.
    Corresponding source code