Can we use implicit array expansion across = sign?

I recently started to port some of my MATLAB scripts to numpy/python and found a difference between MATLAB implicit array expansion and numpy/python broadcasting.
Here's my working python code:
# >>>>> calculate COORD (use broadcast)
coord = np.zeros((ny+1, nx+1, 6))
coord[:, :, [0, 3]] = x0 - dx/2 + dx*np.arange(nx+1).reshape([1, -1, 1])
coord[:, :, [1, 4]] = y0 - dy/2 + dy*np.arange(ny+1).reshape([-1, 1, 1])
coord[:, :, [2, 5]] = z0 - dz/2 + dz*np.array([0, nz+1]).reshape([1, 1, 2])
Here's my equivalent MATLAB code:
coord=zeros(6,nx+1,ny+1);
coord([1 4],:,:)=x0-dx/2+dx*repmat(reshape((0:nx),1,[],1),[2 1 ny+1]);
coord([2 5],:,:)=y0-dy/2+dy*repmat(reshape((0:ny),1,1,[]),[2 nx+1 1]);
coord([3 6],:,:)=z0-dz/2+dz*repmat(reshape([0,nz],[],1,1),[1 nx+1 ny+1]);
So, in the spirit of increasing my MATLAB skills, two questions:
1/ Is there a way to coax MATLAB to perform implicit array expansion across the "=" sign, to match the simplicity of the numpy/python broadcast calculation?
2/ Does it matter? Is the memory overhead in using repmat irrelevant?
My thanks in advance, for advice!
Mike

 Accepted Answer

Matt J
Matt J on 26 Dec 2023
Edited: Matt J on 27 Dec 2023
2/ Does it matter? Is the memory overhead in using repmat irrelevant?
It could matter. Most people would probably not bother to optimize it, but you could use a for-loop instead of repmat, e.g.,
tmp=x0-dx/2+dx*(0:nx);
for i=[1,4], coord(i,:)=tmp; end
This should have no memory allocation overhead.
1/ Is there a way to coax MATLAB to perform implicit array expansion across the "=" sign, to match the simplicity of the numpy/python broadcast calculation?
No, unfortunately. But as shown above, you can avoid reshape() in this case.

6 Comments

Mike
Mike on 27 Dec 2023
Edited: Mike on 27 Dec 2023
Can you clarify how this solution is intended to work?
for i=[1,4], coord(i,:)=tmp; end
Since coord is a 3d (not 2d) array, I get a mis-match in array dimensions.
Whoops. You're right. I guess it should be this instead,
[nx,ny,x0,dx]=deal(7,1,0,2);
coord=zeros(6,nx+1,ny+1);
tmp=x0-dx/2+dx*(0:nx);
for j=1:numel(tmp), coord([1,4],j,:)=tmp(j); end
coord
coord =
coord(:,:,1) = -1 1 3 5 7 9 11 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 3 5 7 9 11 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 coord(:,:,2) = -1 1 3 5 7 9 11 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 3 5 7 9 11 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Mike
Mike on 27 Dec 2023
Edited: Mike on 27 Dec 2023
Thanks for the quick answer & revision!
Yes, MATLAB lets us do Mx...xN to 1 implicit expansion across an "=" sign, which is what I was hoping could be generalized to compatible arrays.
I was really trying to avoid the use of repmat not of reshape. As I understand it, reshape only changes the internal header information for an array, not the data itself, so it should be a fast operation. Can you advise on that?
Reshape indeed has negligible, purely header-editiing overhead. I was just suggesting that omitting it could save typing. My original answer works if you were attempting to broadcast over only 1 dimension, e.g.
[nx,ny,x0,dx]=deal(7,1,0,2);
coord=zeros(6,nx+1,ny+1);
tmp=rand(1,8,2);
for i=[1,4], coord(i,:)=tmp(:); end
coord
coord =
coord(:,:,1) = 0.7961 0.7052 0.0838 0.2383 0.7550 0.6899 0.8388 0.9313 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.7961 0.7052 0.0838 0.2383 0.7550 0.6899 0.8388 0.9313 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 coord(:,:,2) = 0.3888 0.4559 0.0947 0.1061 0.5516 0.0825 0.3129 0.3639 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3888 0.4559 0.0947 0.1061 0.5516 0.0825 0.3129 0.3639 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Now that’s interesting (= unexpected). Thanks for the advice and quick assistance!
You're quite welcome, but if this resolves your question, please Accept-click the answer.

Sign in to comment.

More Answers (0)

Products

Release

R2016b

Asked:

on 26 Dec 2023

Commented:

on 27 Dec 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!