bugGNU Octave - Bugs: bug #29445, cut() returning incorrect result

 
 

bug #29445: cut() returning incorrect result

Submitter:  None
Submitted:  Mon 05 Apr 2010 05:11:51 PM UTC
   
 
Category:  Libraries Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  None Assigned to:  None
Originator Name:  forkandwait Originator Email:  -email is unavailable-
Open/Closed:  * Closed Release:  * 3.3.50
Operating System:  * BSD Fixed Release:  None
Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Mon 05 Apr 2010 10:20:43 PM UTC, comment #7: 

We could decide to deprecate cut and refer people to histc if desired.  We should start a separate discussion over on the octave-maintainers mailing list for that issue.

For the time being, I will patch cut to work in the same manner as histc and close this bug.

Rik <rik5>
Group administrator
Mon 05 Apr 2010 10:00:22 PM UTC, comment #6: 

Another problem with cut() is using NaN to mark the exterior. This requires floating point storage and may limit optimizations in the future. I think that histc()'s use of 0 to mark the exterior makes more sense and could use index data types in the future. Unless anyone is heavily cut(), I favor getting rid of cut() or at the least moving it out of base. The migration path from cut() to histc() is mostly trivial.

Judd Storrs <judd>
Mon 05 Apr 2010 09:04:01 PM UTC, comment #5: 

I will actually start using histc(), since it seems more standard, and I would suggest putting a warning in cut() to that effect (though I would also include the patch below).

The grander scheme of things for me is to recode data that has number of years of school attended into primary only (1), hs no graduation (2) , etc.  [n idx] = histc() works just fine for that.

However, ... thanks for all the edification and prompt replies!

Anonymous
Mon 05 Apr 2010 07:53:20 PM UTC, comment #4: 

Matlab doesn't have a cut function according to the alphabetical list of functions (http://www.mathworks.com/access/helpdesk/help/techdoc/ref/funcalpha.html).

It seems like a reasonable suggestion to follow histc.  histc counts an item in an interval if [ lower_edge <= value < upper_edge ].  histc does one other thing which is to create an additional interval for the last edge and count the number of values which exactly match this maximum last edge.  This doesn't seem to make sense for cut.

Attached is a patch which modifies cut.m to follow the convention above.  In the sample data provided, the edges are [0 2 4].  Thus, 0 is now counted as part of interval one but 4 falls outside the interval range and is a NaN.

Please try patching your cut.m and report back.


(file #20121)

Rik <rik5>
Group administrator
Mon 05 Apr 2010 07:26:31 PM UTC, comment #3: 

It isn't clear to me from the help text how your example should be handled. When I grepped the scripts in scripts/statistics/... I was unable to find a script calling cut().

How are the values falling on the edges of the intervals to be handled?

A simple, single interval, example is ...

cut (1:2, 1:2)

Should the result be [1 1], [NaN 1], or [1 NaN]?

Currently cut() gives [0 1].

Ben Abbott <bpabbott>
Group Member
Mon 05 Apr 2010 07:26:05 PM UTC, comment #2: 

This is the result of using histc() instead of cut():

octave:1> data = -1:6 ;
octave:2> breaks = [0 2 4] ;
octave:3> [~,cdata] = histc(data,breaks) ;
octave:4> [data', cdata']
ans =

  -1   0
   0   1
   1   1
   2   2
   3   2
   4   3
   5   0
   6   0

The development version has the new "skipped output" parameter style, so perhaps it would be best to simply replace cut() with a call to histc(). Maybe cut() should be depreciated and scheduled for removal? I don't think any of the base octave uses cut().

judd@cuneus:/usr/local/stow/octave-devel/share/octave/3.3.51+$ find . -type f | xargs grep "\bcut\b"
./m/statistics/base/cut.m:## @deftypefn {Function File} {} cut (@var{x}, @var{breaks})
./m/statistics/base/cut.m:## If @var{breaks} is a scalar, the data is cut into that many
./m/statistics/base/cut.m:function group = cut (X, BREAKS)
./m/statistics/base/cut.m:    error ("cut: X must be a vector");
./m/statistics/base/cut.m:    error ("cut: BREAKS must be a scalar or vector");
./etc/doc-cache:cut
./etc/doc-cache: -- Function File:  cut (X, BREAKS)
./etc/doc-cache:     If BREAKS is a scalar, the data is cut into that many equal-width intervals.  If BREAKS is a vector of break points, the category has `length (BREAKS) - 1' groups.

Judd Storrs <judd>
Mon 05 Apr 2010 06:28:32 PM UTC, comment #1: 

Does Matlab have cut? I couldn't find it and the Matlab I have access to says cut is not a valid function.

My opinion is this: cut()'s behavior and treatment of cut points should be as consistent with histc() as possible.

Judd Storrs <judd>
Mon 05 Apr 2010 05:11:51 PM UTC, original submission:  

Hi all, I think there is a bug in cut() , or in its documentation.  Reading the docs (second and third paras specifically -- see below), I would think it would return only 1 & 2 and the rest NaNs in the example, but it also returns 0.  Why? Matlab?

If someone could clarify how the intervals to cut are supposed to be shaped, I would appreciate it. I would think like [ ) (closed on the minimum, open on the max), but I can't figure this out...

This behavior might be an attempt to deal with the interval situation, but if so it should be documented.  Likewise for ML compatibility.

If in fact this is a bug, I promise to send a patch with (1) new docs (2) a bunch of tests added to cut(), and (perhaps) a fix. 

I am running 3.2.4, but I get the same error the 3.3.50 on my freebsd box

Thoughts?

Supporting stuff -- first the cut help result, second some sample output, third
expected output:

## help cut

Function File:  cut (X, BREAKS)
     Create categorical data out of numerical or continuous data by cutting into intervals.

     If BREAKS is a scalar, the data is cut into that many equal-width  intervals.  **If BREAKS is a vector of break points, the category has `length (BREAKS) - 1' groups.**

     The returned value is a vector of the same size as X telling which group each point in X belongs to.  **Groups are labelled from 1 to the number of groups**; points outside the range of BREAKS are labelled by `NaN'.

## output 
data = -1:6
breaks = [0 2 4]
cdata = cut(data, breaks)

octave-3.2.4.exe:11> [data', cdata']
ans =

    -1   NaN
     0     0                # this shouldn't be here
     1     1
     2     1
     3     2
     4     2
     5   NaN
     6   NaN

## I would expect the following, assuming [,) behavior:

-1  NaN

  1.    1

 1    1
 2    2
 3    2
 4  NaN
 5  NaN
 6  NaN

Anonymous

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #20121:  patch.cut.m added by rik5 (717B - application/octet-stream)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by rik5 (Updated the item)
  • -email is unavailable- added by bpabbott (Posted a comment)
  • -email is unavailable- added by judd (Posted a comment)
  • -email is unavailable- added by None (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
    2010-04-05 rik5 Open/ClosedOpen Closed
    2010-04-05 rik5 Attached File- Added patch.cut.m, #20121

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code