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:  1 - Wish
Priority:  3 - Low Item Group:  Feature Request
Status:  Wont Fix Assigned to:  None
Originator Name:  Jochen Weber Originator Email:  -email is unavailable-
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

Sun 11 Dec 2022 02:12:22 AM UTC, comment #6: 

no comments in a few months. It's no longer a matlab compatibility concern since they no longer have this feature. It's not clearly a speed advantage from the examples here.  Closing as won't fix unless someone comes back wanting to make the change if they can see an optimization improvement.

Nicholas Jankowski <nrjank>
Group Member
Fri 22 Jul 2022 07:47:41 PM UTC, comment #5: 

regarding the primary focus of this report, the comment #0 code no longer runs in Matlab:

matlab 2022a:

>> r = randn(4,4);
>> subsasgn(r, struct('type', '()', 'subs', {{2, 2}}), 0)
Error using indexing
SUBSASGN must be called with an output.

Not interested in digging through a decade worth or release notes to see if it's mentioned, but it appears that sometime over the past decade this undocumented behavior changed.

Now Octave still allows a subsasgn without an output, and simply puts the result in ans, leaving r unchanged:

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

   1.8659   0.2015  -1.9407   0.1915
   0.3151        0  -0.1796  -0.8894
  -1.1896  -0.5194   1.1625   1.0586
   0.2087  -1.3228  -0.3853  -0.2635

>> who
Variables visible from the current scope:

ans  r

>> ans
ans =

   1.8659   0.2015  -1.9407   0.1915
   0.3151        0  -0.1796  -0.8894
  -1.1896  -0.5194   1.1625   1.0586
   0.2087  -1.3228  -0.3853  -0.2635

>> r
r =

   1.8659   0.2015  -1.9407   0.1915
   0.3151   0.1767  -0.1796  -0.8894
  -1.1896  -0.5194   1.1625   1.0586
   0.2087  -1.3228  -0.3853  -0.2635

of the two speed examples given in comment #0, Matlab no longer allows the comparison, but both 'slow' versions run almost instantaneously in both Matlab and Octave. Don't know if this is because both programs have made these optimizations already, or if things are just faster 11 years later. 

In any case, I'm going to change the category to Wish/Feature request.  It should probably be closed as Wont Fix unless someone  can verify the code optimization still needs to be addressed.

Nicholas Jankowski <nrjank>
Group Member
Fri 22 Jul 2022 07:33:35 PM UTC, comment #4: 

Several issues here, but the simplest first: the comment #3 docstring note is correct.  the command as written returns the substituted result in 'ans', and is not the same as the command in the last line. if the 4th line in the example read:

val = subsasgn (val, idx, 0)

the rest of the docstring would be correct. I've made this simple docstring change and pushed it to stable as:

Nicholas Jankowski <nrjank>
Group Member
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>
Group 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>
Group Member
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 nrjank (Posted a comment)
  • -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 group members can vote.


    Follow 14 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2022-12-11 nrjank StatusNeed Info Wont Fix
        Open/ClosedOpen Closed
    2022-07-22 nrjank StatusConfirmed Need Info
    2022-07-22 nrjank Severity2 - Minor 1 - Wish
        Priority5 - Normal 3 - Low
        Item GroupMatlab Compatibility Feature Request
    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.13-ee12.
    Corresponding source code