bugGNU Octave - Bugs: bug #50854, zeros, ones, NaN, Inf, NA:...

 
 

bug #50854: zeros, ones, NaN, Inf, NA: "like" keyword

Submitter:  Ceral Paquet <octavebugs>
Submitted:  Sat 22 Apr 2017 04:34:37 PM UTC
   
 
Category:  Octave Function Severity:  1 - Wish
Priority:  3 - Low Item Group:  Feature Request
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

Wed 23 Dec 2020 10:34:08 AM UTC, comment #30: 

I pushed this change to document the new syntax:
https://hg.savannah.gnu.org/hgweb/octave/rev/8469b3aad7ac

Closing as fixed.

Markus Mützel <mmuetzel>
Group administrator
Mon 23 Nov 2020 04:12:23 PM UTC, comment #29: 

The English phrasing is a little odd when using "like" where "as" would be preferred.  This reads a little more naturally


If a variable @var{var} is specified after @qcode{"like"}, the output @var{val} will have the same data type, complexity, and sparsity as @var{var}.



Rik <rik5>
Group administrator
Mon 23 Nov 2020 03:09:46 PM UTC, comment #28: 

Looks good to me.
While you're at it, maybe you could also add the return argument to the @deftypfn macros (also the existing ones) and change the sentence slightly like this (but use correct line wrap):

+@deftypefnx {} {@var{val} = } ones (@dots{}, "@var{like}", @var{var}))

+If a variable @var{var} is specified after @qcode{"like"}, the returned array @var{val}
+has the same data type, complexity and sparsity attribute like @var{var}.


Markus Mützel <mmuetzel>
Group administrator
Mon 23 Nov 2020 02:01:32 PM UTC, comment #27: 

Thanks Markus for the extra work. I notice I forgot to update the help text for zeros, ones, NaN, Inf and NA. Would you agree with the following?


+@deftypefnx {} {} ones (@dots{}, "@var{like}", @var{var}))

+If a variable @var{var} is specified after @qcode{"like"}, the return array
+has the same data type, complexity and sparsity attribute than @var{var}.


If so, I can create a changeset.

Guillaume <gyom>
Sun 22 Nov 2020 02:43:32 PM UTC, comment #26: 

I also rebased the patch from comment #22 to the current tip and pushed it here:
https://hg.savannah.gnu.org/hgweb/octave/rev/944fd6fca864

Marking as ready for test.

Markus Mützel <mmuetzel>
Group administrator
Sun 22 Nov 2020 01:54:47 PM UTC, comment #25: 

The patch in comment #17 no longer applied cleanly. It took me longer to rebase it and clean it up than I'd like to admit.
Pushed here:
https://hg.savannah.gnu.org/hgweb/octave/rev/d0fe364977c1

Markus Mützel <mmuetzel>
Group administrator
Thu 19 Nov 2020 05:23:50 PM UTC, comment #24: 

Looking back into this: it seems patches from comment #17 and comment #22 are ready to be applied. Do you agree, Markus?

Guillaume <gyom>
Tue 09 Jun 2020 04:49:51 PM UTC, comment #23: 

Thanks for this, Markus; I had missed your comment #21. The code is cleaner now and there was indeed no need for the extra conversion to double when sparsity is required as it would have already happened anyway.

Concerning whether to allow user-defined objects as inputs, this indeed goes beyond what Matlab does. The fact that "like" deals specifically with sparsity and complex attributes, I wonder if it is well suited for non numeric classes.

Guillaume <gyom>
Sun 07 Jun 2020 06:54:11 PM UTC, comment #22: 

I made the changes mentioned in comment #21 and transformed your diff into a mercurial patch.

In the Matlab documentation for "cast", they mention that only input of one of the built-in numeric classes is allowed.
From our documentation it looks like we want to allow input of any user-defined class, too.
In the light of that, I wonder if it is ok to impose the following condition on the input "val":

  if (! isnumeric (val) && ! islogical (val) && ! ischar (val))
    error("cast: type conversion from '%s' is not supported ", class (val));
  endif


Maybe we should drop that input check completely. Instead we could let the target class constructor allow to error out if the conversion is not implemented (like e.g. from struct to double).

(file #49223)

Markus Mützel <mmuetzel>
Group administrator
Thu 04 Jun 2020 11:03:25 AM UTC, comment #21: 

A classdef could overload the "is*" methods which might lead to unexpected results again.

What about overriding the "type" input variable with class(var) in case of the "like" syntax and keep the input validation for "type" as it was. (Store is_like beforehand.)
That might also allow to slightly reduce the complexity of the conversion block.

I haven't tested the changes yet. But they look good otherwise.
Could you prepare a mercurial patch including a commit message?

Markus Mützel <mmuetzel>
Group administrator
Fri 29 May 2020 09:09:42 AM UTC, comment #20: 

Thanks, I added some validations for the first and last inputs and some extra BISTs.
I still have to look at your patch about all the other functions.

(file #49186)

Guillaume <gyom>
Thu 28 May 2020 05:41:27 PM UTC, comment #19: 

@Guillaume: Thanks for your patch for the "cast" function.
I think there should be more input validation. E.g. this is probably not the expected result:

>> cast(3, 'like', cell(1))
ans =
{
  [1,1] = [](0x0)
  [2,1] = [](0x0)
  [3,1] = [](0x0)
  [1,2] = [](0x0)
  [2,2] = [](0x0)
  [3,2] = [](0x0)
  [1,3] = [](0x0)
  [2,3] = [](0x0)
  [3,3] = [](0x0)
}


Markus Mützel <mmuetzel>
Group administrator
Wed 20 May 2020 02:46:22 PM UTC, comment #18: 

Adding a patch to have "like" type for "cast".

@Markus: will look at your latest patch.

(file #49132)

Guillaume <gyom>
Fri 24 Apr 2020 06:40:18 PM UTC, comment #17: 

I forgot to update a few BISTs in the last patch. Also the "like" type for "Inf", "NaN" and "NA" can only be single or double.

Here a new patch that uses the fixed check and passes all tests here.

(file #48928)

Markus Mützel <mmuetzel>
Group administrator
Fri 24 Apr 2020 06:12:03 PM UTC, comment #16: 

The patch from comment #15 still applies on the current default branch and compiles successfully.
However, it doesn't seem to work for complex single "like" input:

>> a = ones (1, 1, "like", single (1i))
a = 1
>> whos ("a")
Variables visible from the current scope:

variables in scope: top scope

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  =====
        a           1x1                          8  double

Total is 1 element using 8 bytes


The returned value is double when it should be single.

I hope the attached patch fixes that.

I'm not sure if it is worth leaving the "iscomplex" logic in since Octave seems to happily eat the imaginary part of complex numbers whenever it can anyway.

Documentation changes are still missing. I would be happy if you could take that on, Guillaume.

(file #48927)

Markus Mützel <mmuetzel>
Group administrator
Wed 25 Sep 2019 05:20:43 PM UTC, comment #15: 

I have updated the patch from comment #9 by @co60ca so that it can be applied on current dev. It passes all the test but requires more work on documentation. I would be happy to do it once it is agreed that the way this is implemented is the most appropriate one.

(file #47572)

Guillaume <gyom>
Sun 17 Mar 2019 01:19:39 AM UTC, comment #14: 

Bumpity bump. Another version another request for the like keyword ;)

Ceral Paquet <octavebugs>
Tue 23 Oct 2018 01:18:59 PM UTC, comment #13: 

Hi there as per comment #12 I worked on this a long time ago. I was discouraged by the speed for which I got feedback on my patch so I did not continue.

I don't currently have a Octave dev environment so if anyone wants to take my patch and replay it thats fine or they could start from scratch.

co60ca
Tue 23 Oct 2018 10:43:45 AM UTC, comment #12: 

I tried to test the patch from comment #9 but it would need to be adjusted for current dev. Brad, do you think you would have time to update your patch? I can try to have a look otherwise.
It would be great to have it for Octave 5.0.

Guillaume <gyom>
Sun 12 Aug 2018 07:00:26 PM UTC, comment #11: 

Just a little bump for the 'like' keyword which is still unsupported (release 4.4.1).

Ceral Paquet <octavebugs>
Sun 18 Feb 2018 07:59:53 PM UTC, comment #10: 

Another function that should support 'like' functionality

-cast

Ceral Paquet <octavebugs>
Wed 12 Jul 2017 04:52:40 AM UTC, comment #9: 

I added the functionality 'like' functionality to the following functions:
- NaN
- Inf
- ones
- zeros
- false
- true

Which were all listed in Matlab 2017a documentation as accepting the 'like' argument. (and existed in the data.cc file)

I also added tests to this effect.

Patch should be attached. I think we should separate this from rand, randi, randn which localize this patch.


(file #41183)

co60ca
Tue 11 Jul 2017 04:01:54 AM UTC, comment #8: 

Inf and NaN both use this call model too.

I have some of this done and will submit patches for this.

co60ca
Wed 26 Apr 2017 07:20:52 PM UTC, comment #7: 


Matlab also uses 'like' for rand, randi, randn,
to get a result which has the same object type as the given parameter.

Avinoam Kalma <avinoam>
Group Member
Wed 26 Apr 2017 05:55:57 AM UTC, comment #6: 

It looks like "like" only copies the following properties:

  • data type (class)
  • complexity
  • sparsity



X = zeros(___,'like',p) returns an array of zeros like p; that is, of the same data type (class), sparsity, and complexity (real or complex) as p. You can specify typename or 'like', but not both.


Sorry I have no ability to implement this properly. It's not that it's a must-have thing, it just not having it breaks Matlab code.  This is a horrible hackaround.

function x = zeros(varargin)

for k = 1:nargin
    if isequal(varargin{k},'like')
        if k+1 > nargin
            error('''like'' must be followed by a variable.');
        end
        varargin{k} = class(varargin{k+1});
        varargin(k+1) = [];
        break;
    end
end

x = builtin('zeros',varargin{:});

Ceral Paquet <octavebugs>
Mon 24 Apr 2017 03:38:20 AM UTC, comment #5: 

Okay, so they are inconsistent.  If you're very interested in this feature you could work out the exact logic they are using and submit a changeset.

Rik <rik5>
Group administrator
Sun 23 Apr 2017 08:23:30 PM UTC, comment #4: 

Looks like not.


>> whos ('gvar')
  Name      Size            Bytes  Class     Attributes

  gvar      1x1                 8  single    global, complex

>> whos ('z')
  Name      Size            Bytes  Class     Attributes

  z         1x1                 8  single    complex


Ceral Paquet <octavebugs>
Sun 23 Apr 2017 07:14:12 PM UTC, comment #3: 

I see.  Yes, I suppose it would be interesting to have a function that copies all attributes.  Does Matlab, for example, also copy the global attribute?


global gvar;
gvar = complex (single (1), single (0))
whos ('gvar')
z = zeros (1, 'like', gvar)



Rik <rik5>
Group administrator
Sun 23 Apr 2017 06:45:19 PM UTC, comment #2: 

You're right Rik, class is a nice workaround.

Unfortunately I've got myself addicted to using the gpuArray class in Matlab and 'like' is useful for copying that attribute over. It's still a hack in Matlab if you just want to copy the GPU part but not the complexity... they haven't really ironed out bugs in pcg, lsqr, etc. which use 'like' to declare arrays like resvec. My data is complex so these come back as complex arrays. Matlabs support could not care less, just cut&paste replies describing memory management on the gpu side.

So you still end up with if/else statements all over the place. Annoying.

Ceral Paquet <octavebugs>
Sun 23 Apr 2017 02:19:43 PM UTC, comment #1: 

Yeah.  Matlab has been this way for a while.  I happen to think it clutters the interface to the matrix-producing functions like zeros, ones, etc., but maybe it will get implemented.

A pretty easy hack, if one really needs this functionality, is to use class().


A = single (1+i);
B = zeros (1, class (A));
whos ('B')
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  =====
        B           1x1                          4  single

Total is 1 element using 4 bytes


The complex attribute isn't really necessary to copy because Octave adjusts matrices automatically as necessary to save memory.  If a matrix has all zero imaginary parts t is automatically reduced to real to save memory.  Conversely, if you assign a complex variable to a real matrix Octave will conver the matrix to complex.  Using the example above.



octave:4> B(1) = 1+i
B =  1 + 1i
whos ('B')
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  =====
   c    B           1x1                          8  single

Total is 1 element using 8 bytes


Now B is taking up 8 bytes just as the Matlab variable does.


B(1) = 1
B =  1
octave:7> whos ('B')
Variables in the current scope:

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  =====
        B           1x1                          4  single

Total is 1 element using 4 bytes


And now it is back to requiring only 4 bytes.

Rik <rik5>
Group administrator
Sat 22 Apr 2017 04:34:37 PM UTC, original submission:  

MATLAB introduced the 'like' keyword for zeros, ones, cast.


>> A = single(1+i);
>> B = zeros(1,'like',A);
>> whos('B')
  Name      Size            Bytes  Class     Attributes

  B         1x1                 8  single    complex



Ceral Paquet <octavebugs>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #49223:  bug50854_cast_like_v3.patch added by mmuetzel (5KiB - application/octet-stream)
file #49186:  patch_cast_like_2.diff added by gyom (4KiB - text/x-patch)
file #49132:  patch_cast_like.diff added by gyom (3KiB - text/x-patch)
file #48928:  bug50854_patch_like_v3.patch added by mmuetzel (11KiB - application/octet-stream)
file #48927:  bug50854_patch_like_v2.patch added by mmuetzel (10KiB - application/octet-stream)
file #47572:  patch_like.txt added by gyom (6KiB - text/plain)
file #41183:  patch.txt added by co60ca (6KiB - text/plain)

 

Carbon-Copy List
  • -email is unavailable- added by jwe (Updated the item)
  • -email is unavailable- added by mmuetzel (Updated the item)
  • -email is unavailable- added by gyom (Posted a comment)
  • -email is unavailable- added by co60ca (Posted a comment)
  • -email is unavailable- added by avinoam (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by octavebugs (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 25 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2020-12-23 mmuetzel StatusReady For Test Fixed
        Open/ClosedOpen Closed
    2020-12-22 mmuetzel Dependencies- bugs #59751 is dependent
    2020-12-22 jwe Item GroupMatlab Compatibility Feature Request
    2020-11-22 mmuetzel StatusPatch Submitted Ready For Test
    2020-11-22 mmuetzel Priority2 3 - Low
        StatusIn Progress Patch Submitted
    2020-06-07 mmuetzel Attached File- Added bug50854_cast_like_v3.patch, #49223
    2020-05-29 gyom Attached File- Added patch_cast_like_2.diff, #49186
    2020-05-28 mmuetzel StatusConfirmed In Progress
    2020-05-20 gyom Attached File- Added patch_cast_like.diff, #49132
    2020-04-24 mmuetzel Attached File- Added bug50854_patch_like_v3.patch, #48928
    2020-04-24 mmuetzel Attached File- Added bug50854_patch_like_v2.patch, #48927
        Item GroupWTF, Matlab?!? Matlab Compatibility
        Release4.2.1 dev
        Operating SystemGNU/Linux Any
        Summaryzeros: like keyword zeros, ones, NaN, Inf, NA: "like" keyword
    2020-01-05 rik5 Dependencies- bugs #57543 is dependent
    2019-09-25 gyom Attached File- Added patch_like.txt, #47572
    2019-09-23 mtmiller Dependencies- bugs #56934 is dependent
    2017-07-12 co60ca Attached File- Added patch.txt, #41183
    2017-04-23 rik5 CategoryNone Octave Function
        Severity3 - Normal 1 - Wish
        Priority5 - Normal 2
        StatusNone Confirmed

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code