bugGNU Octave - Bugs: bug #46385, Can't Repmat Structure Arrays

 
 

bug #46385: Can't Repmat Structure Arrays

Submitter:  Max Görner <maxg>
Submitted:  Fri 06 Nov 2015 09:38:43 AM UTC
   
 
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Other
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sat 05 Aug 2017 04:18:42 AM UTC, comment #21: 

Reshape has been fixed in this cset (http://hg.savannah.gnu.org/hgweb/octave/rev/3544f88a2bb5).  The original motivating code now passes.  Marking as fixed and closing report.

Rik <rik5>
Group administrator
Sat 10 Sep 2016 03:57:34 PM UTC, comment #20: 

A quick search turns up this bug from 2014 where reshape produces the same error for some struct arrays:
https://savannah.gnu.org/bugs/?43650

my guess is if we fixed that than this bug would be resolved as well.

Nicholas Jankowski <nrjank>
Group Member
Sat 10 Sep 2016 02:31:38 PM UTC, comment #19: 

1 The key error appears to be in handling structs with reshape. Sincevtats a c function I can't step through it, but maybe a separate bug should be opened. The failing reshape command works fine in MATLAB.

2 The repelem workaround does appear to solve this bug. Should that patch be added as a dependency in this report, then when that gets pushed this could too?

3 Would someone be able to take a quick peek at the repelem patch and and comment if there's something glaring that needs to be done on it?

Nicholas Jankowski <nrjank>
Group Member
Sat 10 Sep 2016 11:42:49 AM UTC, comment #18: 

No, repelem hasn't been included yet, but it still could be.

John W. Eaton <jwe>
Group administrator
Sat 10 Sep 2016 11:37:14 AM UTC, comment #17: 

Repelem was a missing function. Patch submitted under bug #45497. Pushing that patch should make this patch work. Did the repelem patch make it into 4.2?

http://savannah.gnu.org/bugs/?45497

Nicholas Jankowski <nrjank>
Group Member
Fri 09 Sep 2016 08:45:26 PM UTC, comment #16: 

The first error was that 'repelem' does not exist.  I tried changing that to 'repelems', but still got a failure.

Rik <rik5>
Group administrator
Fri 09 Sep 2016 08:22:02 PM UTC, comment #15: 

Rik, curious what error you receive.  I applied Markus's patch (calling repelem if reshape is given a struct) and I get no errors and the output matches Matlab.

Nicholas Jankowski <nrjank>
Group Member
Tue 06 Sep 2016 10:36:33 PM UTC, comment #14: 

The patch from bug #48368 has been committed to the repository.  But that is still not enough to fix this problem.  I tried the patch attached to this report and still get an error.  I'm changing the status back to Confirmed from Patch Submitted since the patch doesn't appear to work.

Rik <rik5>
Group administrator
Fri 01 Jul 2016 11:38:02 PM UTC, comment #13: 

Nice thought, Nicholas, but even with the patch from bug #48368 the result is


octave:1> M = repmat(struct('a', ones(100), 'b', true), 1, 2);
octave:2> M = repmat(M, 1, 2);
error: internal error: dimension mismatch across fields in struct
error: called from
    repmat at line 120 column 9


Lachlan Andrew <lachlan>
Fri 01 Jul 2016 07:57:56 PM UTC, comment #12: 

yes, in Octave Rik's script produces:


>> size(s.a)
ans = 1


as it seems to be appending the first element (4) from s(2).a

It would be interesting to see if fixing size also fixes repmat without Markus's patch. My initial guess is calling repelem from within repmat would not be quite as efficient if it wasn't needed.

Nicholas Jankowski <nrjank>
Group Member
Fri 01 Jul 2016 07:43:14 PM UTC, comment #11: 

Since I'm not setup to recompile, this is using the 4.0.2 release.

Confirming Rik's test for Matlab:


>> s(1).a = [1 2 3];
>> s(2).a = [4;5;6];
>> s.a
ans =
     1     2     3
ans =
     4
     5
     6
>> size(s.a)
Error using size
Dimension argument must be a positive integer scalar within indexing range.
>> size(s(1).a)
ans =
     1     3
>> size(s(2).a)
ans =
     3     1


I switched to zeros to verify that it was picking up the 0 from the next 'a' and not from 'b' or elsewhere.

Nicholas Jankowski <nrjank>
Group Member
Fri 01 Jul 2016 07:07:31 PM UTC, comment #10: 

Oops.  Our posts crossed, Rik.

(Also, I notice that the answer to my question to Nicholas is that he was using  ones(100), not zeros (100), which is why he got size(M.a)=1; size just uses the first value in the second argument.)

I have a simple patch for size, but I'll file a separate bug report for it.

Lachlan Andrew <lachlan>
Fri 01 Jul 2016 06:47:24 PM UTC, comment #9: 

Nicholas, it looks like the size(M.a) is treating M.a as a cs-list.

Out of interest, this is what I get for a recent Octave tip:


>> M = struct('a',zeros(2),'b',true);
>> bigM = repmat (M, 1, 2);
>> bigM.a
ans =

   0   0
   0   0

ans =

   0   0
   0   0

>> size (bigM.a)
error: size: requested dimension DIM (= 0) out of range


When you got size(bigM.a) = 100, was that with Markus's patch?

Lachlan Andrew <lachlan>
Fri 01 Jul 2016 06:35:20 PM UTC, comment #8: 

Actually, it sounds like Matlab is returning a comma-separated list, which is what is supposed to happen when you ask for the same field from a structure array.

A simple example for testing in Matlab:


s(1).a = [1 2 3];
s(2).a = [4;5;6];
s.a           % Should have two lines beginning with "ans ="
size (s.a)    % Should error
size (s(1).a) % 1x3
size (s(2).a) % 3x1


Octave appears not to handle the 's.a' case correctly.


Rik <rik5>
Group administrator
Fri 01 Jul 2016 05:56:24 PM UTC, comment #7: 

apparently much of comments #4-6 can be disregarded. I had left M defined as the already repmat'd struct way back at the start for the Matlab case, making them look different. fixing that the outputs to almost all the code is identical.

BUT, a difference does exist between Octave and Matlab output with the error that Matlab produces for the one size call:

For both Octave and matlab:

>> M = struct('a',ones(100),'b',true);

>> bigM = repmat(M,1,2)

bigM =
1x2 struct array with fields:
    a
    b

>> size(bigM)
ans =
     1     2


In Octave:

>> size(bigM.a)
ans =  100


In Matlab:

>> size(bigM.a)
Error using size
Dimension argument must be a positive integer scalar within indexing range.


from this output it appears that size(bigM.a) is using something as a second size argument specifying one of the dimensions. Matlab yells that something improper is being passed to that size argument (likely the second 100x100 array). If we use zeros(100) instead of ones(100) to make M:


>> M = struct('a',zeros(100),'b',true);
>> bigM = repmat(M,1,2)
bigM =

  1x2 struct array containing the fields:

    a
    b
>> size(bigM.a)
error: size: requested dimension DIM (= 0) out of range


somewhat confirming that octave is taking the first element for size. 

maybe size needs a varargin check to catch this?

Nicholas Jankowski <nrjank>
Group Member
Fri 01 Jul 2016 03:00:01 PM UTC, comment #6: 

looking through repmat, there are places where it makes decisions based on the result of size(A) or numel(A).  For the example below octave gives numel(mtest) = 2, while Matlab gives numel(mtest) = 4.

if the patch using repelem works, I think it's just because it avoids those calls. When we rewrote repelem, I didn't do any tests on structs (or cells for that manner) so I don't at the moment know how it's handling them differently.  But while this would make repmat work, there still appears to be something broken in how octave determines the size of struct arrays.

Nicholas Jankowski <nrjank>
Group Member
Fri 01 Jul 2016 02:51:28 PM UTC, comment #5: 

sorry for the syntax typo's in the last comment, but to clarify:  it appears that the struct array created by repmat has the right pieces. a bit more, not using repmat:

Octave:

>> mtest = [M,M]
mtest =

  1x2 struct array containing the fields:

    a
    b


Matlab 2016a:

>> mtest = [M,M]
mtest =
1x4 struct array with fields:
    a
    b


So, this isn't just a repmat issue...

Nicholas Jankowski <nrjank>
Group Member
Fri 01 Jul 2016 02:41:16 PM UTC, comment #4: 

messing with this a little, there's a discrepancy with how Octave determines the size of a struct array:


>> M = struct('a',ones(100),'b',true);

M =

  scalar structure containing the fields:

    a = ***100x100 array of 1's***

    b = 1  ***stored as a logical***

>> size(M)
ans =

   1   1

>> size(M.a)
ans =

   100   100

>> size(M.b)
ans =

   1   1


now with repmat:


>> bigM=repmat(M,1,2)
bigM =

  1x2 struct array containing the fields:

    a
    b


Matlab 2016a reports it as:


>> bigM = repmat(M,1,2)
bigM =
1x4 struct array with fields:
    a
    b


looking at how the element sizes are reported

Octave:

>> size(bigM)
ans =
   1   2
>> size(bigM.a)
ans =  100
>> size(bigM.b)
ans =  1
>> size(bigM(1).a)
ans =
   100   100
>> size(bigM(2).a)
ans =
   100   100
>> size(bigM(1).b)
ans =
   1   1
>> size(bigM(2).b)
ans =
   1   1


Matlab 2016a:
+verbatim

>> size(bigM)

ans =
     1     4

>> size(bigM.a)

Error using size
Too many input arguments.

>> size(bigM.b)

Error using size
Too many input arguments.

>> size(bigM(1).a)

ans =
   100   100

>> size(bigM(2).a)

ans =
   100   100

>> size(bigM(1).b)

ans =
     1     1

>> size(bigM(2).b)

ans =
     1     1
-verbatim-

so, Octave returns 1x2 as the answer, Matlab 1x4. Maybe the size issue is some of the cause of the problem. or is this a separate bug?

Nicholas Jankowski <nrjank>
Group Member
Fri 27 Nov 2015 02:01:29 PM UTC, comment #3: 

the problem is in reshape, which is called by repmat.


>> M = repmat(struct('a', ones(100), 'b', true), 1, 2);
>> [m,n] = size(M);
>> reshape(M, m, 1, n, 1)

ans =

1x1x2 struct array with fields:

    a
    b


Octave failed here with a dimension mismatch across fields in struct.

Using repelem from #45497 makes it work without touching reshape.


octave:1> M = repmat(struct('a', ones(100), 'b', true), 1, 2);
octave:2> M = repmat(M, 1, 2)
M =

  1x4 struct array containing the fields:

    a
    b


(file #35577)

Markus Bergholz <markuman>
Fri 13 Nov 2015 08:05:31 PM UTC, comment #2: 

It's a 1x4 struct array.

Max Görner <maxg>
Fri 13 Nov 2015 05:45:37 PM UTC, comment #1: 

When you run the code in Matlab, what is the resulting output?  Is it a 1x4 struct array or does it make something else like a 1x2 cell array where element 1 is the 1x2 struct array M and element 2 is the 1x2 struct array M?

Rik <rik5>
Group administrator
Fri 06 Nov 2015 09:38:43 AM UTC, original submission:  

I wanted to repmat structure arrays, but this will fail.

An example is:

M = repmat(struct('a', ones(100), 'b', true), 1, 2);
M = repmat(M, 1, 2);
error: internal error: dimension mismatch across fields in struct
error: called from
    repmat at line 117 column 9


Under Matlab R2015b this works like a charm. But even ignoring Matlab I think that code should work.

Max Görner <maxg>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #35577:  repmat.patch added by markuman (615B - text/x-diff)

 

Depends on the following items: None found

Digest:
   bug dependencies.

 

Carbon-Copy List
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by nrjank (Posted a comment)
  • -email is unavailable- added by lachlan (Updated the item)
  • -email is unavailable- added by markuman (Updated the item)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by maxg (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 9 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2017-08-05 rik5 StatusConfirmed Fixed
        Open/ClosedOpen Closed
    2017-08-05 rik5 Dependencies- bugs #51634 is dependent
    2016-09-06 rik5 StatusPatch Submitted Confirmed
    2016-06-11 lachlan StatusConfirmed Patch Submitted
        Release4.0.0 dev
        Operating SystemGNU/Linux Any
    2015-11-27 markuman Attached File- Added repmat.patch, #35577
    2015-11-13 rik5 StatusNone Confirmed

    Back to the top

    Powered by Savane 3.13-3230.
    Corresponding source code