bugGNU Octave - Bugs: bug #33221, subsasgn without LHS should do...


bug #33221: subsasgn without LHS should do in-place assignment for performance

Submitter:  None
Submitted:  Tue 03 May 2011 02:41:31 PM UTC
Category:  Octave Function Severity:  2 - Minor
Priority:  5 - Normal Item Group:  Matlab Compatibility
Status:  Confirmed Assigned to:  None
Originator Name:  Jochen Weber Originator Email:  -email is unavailable-
Open/Closed:  * Open Release:  * dev
Operating System:  * Any
* Mandatory Fields

Add a New Comment (Rich Markup)

Comment Type & Canned Response:


Tue 26 May 2020 11:55:58 AM UTC, comment #3: 

It is not only a Matlab compatibility issue, but apparently an inconsistency with Octave documentation.

octave:1> help subsasgn
          val = magic (3);
          idx.type = "()";
          idx.subs = {":", 1:2};
          subsasgn (val, idx, 0)
               =>  [ 0   0   6
                     0   0   7
                     0   0   2 ]

     Note that this is the same as writing 'val(:, 1:2) = 0'.

However, last sentence is not correct (val is not assigned after subsasgn call). Example that shows it:

octave:1> val = magic (3);
octave:2> idx.type = "()";
octave:3> idx.subs = {":", 1:2};
octave:4> subsasgn (val, idx, 0)
ans =

   0   0   6
   0   0   7
   0   0   2

octave:5> val
val =

   8   1   6
   3   5   7
   4   9   2

octave:6> val(:, 1:2) = 0
val =

   0   0   6
   0   0   7
   0   0   2

octave:7> val
val =

   0   0   6
   0   0   7
   0   0   2

If I understand it correctly, documentation should be modified/clarified or subsasgn implementation modified.

Daniel Molina GarcĂ­a <dmolina>
Thu 17 Nov 2016 07:09:13 PM UTC, comment #2: 

The optimization may be possible.  The operators such as '+=' or '-=' use in-place optimization and are significantly faster.

octave:6> x = rand (1000,1000);
octave:7> tic; x = x + 1; toc
Elapsed time is 0.0022521 seconds.
octave:8> tic; x += 1; toc
Elapsed time is 0.00102091 seconds.

It already appears that indexing in the normal case is in-place.

octave:9> x = rand (1000,1000);
octave:10> tic; x(2,2) = 1; toc
Elapsed time is 2.69413e-05 seconds.
octave:11> idx = struct ("type", "()", "subs", {{2,2}});
octave:12> tic; subsasgn (x, idx, -1); toc
Elapsed time is 0.0146961 seconds.

Thus, it is a question of whether there is a way to hook in to the operator based function or not.

Rik <rik5>
Project Administrator
Sun 19 Jan 2014 11:16:03 PM UTC, comment #1: 

I can't confirm whether this is the behavior in Matlab or not, but confirmed that subsasgn does not modify the value argument in place. I don't think any Octave function modifies the value of its argument.

Can someone confirm whether this is the behavior in a current version of Matlab?

Mike Miller <mtmiller>
Project Administrator
Tue 03 May 2011 02:41:31 PM UTC, original submission:  

**This seems to be rather a Matlab-internal, undocumented features**

In some of my code I've been making use of the undocumented feature that if a call to subsasgn (only on a built-in type!) does not have a LHS assignment, the assignment is done "in place" (speed gain):

r = randn(4, 4);
subsasgn(r, struct('type', '()', 'subs', {{2, 2}}), 0);

The previous code actually alters 'r', which is, to my knowledge, NOT documented by Mathworks.

The reason to use this syntax is that there is no cost to keep another copy of the variable in memory (to allow error handling, etc.).

So the following two subsasgn calls in Matlab work (and produce the same result), but the first is instantaneous, whereas the second one takes quite a while and might even end with an out-of-memory error:

r = zeros(256, 256, 256, 4); % 0.5GByte of double 0's
subsasgn(r, struct('type', '()', 'subs', {{2, 2}}), 1); % instantaneous
r = subsasgn(r, struct('type', '()', 'subs', {{2, 2}}), 2); % creating a copy of r, assign in copy, then replace r with copy

While this is not a big deal, it would be nice to also have this "speedup" available in Octave (particularly when working on large, full matrices, such as 4D datasets that require a large amount of memory).

In Octave, a "manual" call of subsasgn on a large array always requires a copy, whereas using

r = zeros(256, 256, 256, 4);
r(2, 2) = 1;

is instantaneous, which is a little "inconsistent", I guess...



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

Attach Files:

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 dmolina (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by mtmiller (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 project members can vote.





    Follow 8 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2016-11-17 rik5 StatusNeed Info Confirmed
        Summarysubsasgn without LHS assignment Matlab incompatibility subsasgn without LHS should do in-place assignment for performance
    2014-01-19 mtmiller CategoryNone Octave Function
        Severity3 - Normal 2 - Minor
        Item GroupOther Matlab Compatibility
        StatusNone Need Info
        Release3.4.0 dev
        Operating SystemMac OS Any

    Back to the top

    Powered by Savane 3.9