[bug #68300] blkdiag with arguments of type single returns result of type double

Rik <[email protected]> Mon, 4 May 2026 08:27:23 -0400 (EDT)
Newsgroups gmane.comp.gnu.octave.bugs
Message-ID <[email protected]>
Please use the bug tracker to post updates to a bug report.  The mailing list is intended as a read-only notification stream.  Info posted to this mailing list address won't appear in the tracker database where it is most useful.

Update of bug #68300 (group octave):

                  Status:          Patch Reviewed => Fixed
             Open/Closed:                    Open => Closed
           Fixed Release:                    None => 12.1.0 (current default)

    _______________________________________________________

Follow-up Comment #10:

I did some benchmarking on the proposed changeset using the following script:
bm_double.m

N = 3e4;

## Initialize variables
varargin_orig = { ones(2, 'double'), 2*ones(2, 'single'), 3*ones(2, 'uint8'),
4*ones(2, 'int32'), 5*ones(2, 'uint64') };
nargin = numel (varargin_orig);

################################################################################

bm = 0;

for i = 1:N

  varargin = varargin_orig;

  tic;
  for p = 1:nargin
    if (! isa (varargin{p}, "double"))
      varargin{p} = double (varargin{p});
    endif
  endfor
  bm += toc;

endfor

bm

############################################################

bm = 0;

for i = 1:N

  varargin = varargin_orig;

  tic;
  for p = 1:nargin
    varargin{p} = double (varargin{p});
  endfor
  bm += toc;

endfor

bm

############################################################

bm = 0;

for i = 1:N

  varargin = varargin_orig;

  tic;
  varargin = cellfun (@double, varargin, "UniformOutput", false);
  bm += toc;

endfor

bm


BM #1 is your original code.

Octave functional calls are often slow so instead of checking something, it is
often faster to just go ahead and do it and see if that results in an error.

BM #2 Remove call to *isa()* and just cast all arguments with *double*.

And lastly, for loops are often slow compared to any sort of built-in
function.

BM #3 Use *cellfun* instead of *for* loop to cast all inputs to double.

Results:

bm = 0.9783
bm = 0.6303
bm = 0.3196

The last formulation, with *cellfun*, wins so I replaced the original code
with that construction.

I did the same benchmarking for the determination of class using *cat*
semantics: bm_cat.m

N = 3e4;

## Initialize variables
varargin = { ones(2, 'double'), 2*ones(2, 'single'), 3*ones(2, 'uint8'),
4*ones(2, 'int32'), 5*ones(2, 'uint64') };
nargin = numel (varargin);

################################################################################

bm = 0;

for i = 1:N

  tic;
  cls = class (varargin{1});
  for p = 2:nargin
    if (! isa (varargin{p}, cls))
      cls = class (cat (1, zeros (0, 0, cls), ...
                           zeros (0, 0, class (varargin{p}))));
    endif
  endfor
  bm += toc;

endfor

bm

############################################################

bm = 0;

for i = 1:N

  tic;
  cls = class (varargin{1});
  for p = 2:nargin
    cls = class (cat (1, zeros (0, 0, cls), ...
                         zeros (0, 0, class (varargin{p}))));
  endfor
  bm += toc;

endfor

bm

############################################################

bm = 0;

for i = 1:N

  tic;
  clsnames = cellfun (@class, varargin, 'UniformOutput', false);
  z = cellfun (@(cls) zeros (0,0, cls), clsnames, 'UniformOutput', false);
  cls = class (horzcat (z{:}));
  bm += toc;

endfor

bm

############################################################

bm = 0;

for i = 1:N

  tic;
  z = zeros (0,0, class (varargin{1}));
  for p = 2:nargin
    z = horzcat (z, zeros (0, 0, class (varargin{p})));
  endfor
  cls = class (z);
  bm += toc;

endfor

bm


BM #1 is the original code.

BM #2 strips out the call to *isa*

BM #3 uses two *cellfun* calls to replace one *for* loop

BM #4 uses progressive calls to *horzcat* and "remembers" current type in
variable *z* rather than in string variable *cls*.

Results:

bm = 1.8184
bm = 1.4105
bm = 1.3320
bm = 1.0988

The last formulation, with *cellfun*, wins so I replaced the original code
with that construction.

I also added the bug #68300 to some of the BIST tests.  Because the original
file had no input validation tests, I also added some of those.

I checked everything in at
https://hg.savannah.gnu.org/hgweb/octave/rev/e4cbb143b974. 

Marking as Fixed and closing report.


(file #58547, file #58548)

    _______________________________________________________

Additional Item Attachment:

Name: bm_double.m                    Size: 898B
    <https://file.savannah.gnu.org/file/bm_double.m?file_id=58547>

Name: bm_cat.m                       Size: 1.3KiB
    <https://file.savannah.gnu.org/file/bm_cat.m?file_id=58548>


    AGPL NOTICE

These attachments are served by Savane. You can download the corresponding
source code of Savane at
https://savannah.gnu.org/source/savane-c36938be85ff6c1b727bc7dd7fd30e48f9142870.tar.gz


    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?68300>

_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/
signature.asc (application/pgp-signature, 228 B)
-----BEGIN PGP SIGNATURE-----

iHUEABYIAB0WIQQk97aszIMMAvLLwm6qLAuaBUf3TgUCafiQqwAKCRCqLAuaBUf3
TmmhAQCCGKBfaBHABBAErvdvBdk37ccQ7ywVWGuH5j3kfLFywwEA/uzxmkZMv83M
uipS4vc4Ow1IhhCTAX0MJdvvbnLECQ0=
=g2hu
-----END PGP SIGNATURE-----