1
$\begingroup$

I am working with MATLAB, and I would have the following problem. I have the following matrix of random numbers rand(200,200) and I need to create a 3D matrix with the following structure 3D_mat(r,s,p) with 15 layers (p=15), where each layer will contain the given data rand(200,200). Perhaps, it is easy task, but I am MATLAB beginner.

$\endgroup$
  • $\begingroup$ It is very unlikely that you can call a variable 3D_mat (cannot start with a number) $\endgroup$ – Laurent Duval Aug 18 '16 at 22:03
  • 1
    $\begingroup$ This is actually a duplicate of stackoverflow.com/questions/16746999/… (modulo replacing 1d arrays by 2d arrays), which also includes some timings. $\endgroup$ – Christian Clason Aug 18 '16 at 22:17
  • $\begingroup$ @Christian Clason Yes, and link you point at is "so 2013" $\endgroup$ – Laurent Duval Aug 23 '16 at 6:27
  • $\begingroup$ Same data for 15 layers? Or each layer with different random numbers? $\endgroup$ – Memming Sep 20 '16 at 19:28
1
$\begingroup$

This is probably not the most efficient way to do this in MATLAB, but the following works for me in Octave:

A=rand(200,200);
for i=1:15
  B(:,:,i)=A;
end

And, I think it should work fine in MATLAB as well. If your dimensions get a lot bigger or you have to create the 3D matrix frequently, there are probably much more efficient was to accomplish this.

$\endgroup$
  • 3
    $\begingroup$ You can also use repmat: B=repmat(A,1,1,15). If the dimensions are a lot bigger, it would make sense to not construct B at all and instead use broadcasting (look for bsxfun in the online help) whenever you need to do something with B. $\endgroup$ – Christian Clason Aug 18 '16 at 13:46
  • 1
    $\begingroup$ @ Christian Clason To maintain compatibility with older versions of MATLAB, it is better to use repmat(A,[1,1,15]) which will work in new and old versions of MATLAB. $\endgroup$ – Mark L. Stone Aug 18 '16 at 15:18
0
$\begingroup$

Here are three options: with repmat or bsxfun, two functions evoked by @Christian Clason. On some versions of Matlab (notably older than 2013, as can be seen from https://stackoverflow.com/questions/16746999/most-efficient-way-for-repeating-a-vector-in-matlab), bsxfun was faster, and if not the case, is believed to use less memory (useful if you get much bigger than $200\times 200\times15$). The last one plays with indexing.

nRow = 200;
nCol = 200;
nDep = 15;

r = rand(nRow,nCol);
o = zeros(nRow,nCol,nDep); % Not bad to initialize

% Choose one
o = repmat(r,1,1,nDep); % repmat version
o = bsxfun(@times,ones(1, 1 , nDep),r); % bsxfun version
o = r(:,:,ones(1, 1 , nDep)); % multiple-indexing version

In my case (Matlab2013b), repmat is $2/3$ faster than the two others, for several matrix sizes and repetition depth (including yours). According to some testimonies, since a novel coding of repmat exist in Matlab2013b and above, bsxfun indeed can be slower.

$\endgroup$
  • 2
    $\begingroup$ Actually, I wasn't recommending to use bsxfun for creating o -- that would completely defeat the purpose. Instead, when you want to do (e.g.) D=o.*C, you do D=bsxfun(@times,C,r) (and similarly for other operations). But as I said, I doubt you'll see much difference for the sizes in this example. $\endgroup$ – Christian Clason Aug 18 '16 at 22:11
  • $\begingroup$ @Christian Clason Actually, I never used bsxfun before, that was an opportunity for me to try it. I'll be aware of its convenience in the future $\endgroup$ – Laurent Duval Aug 18 '16 at 22:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.