Setting multiple variables to empty vectors

I want to create multiple vectors as columns of zeros so that I can then fill them in later. What I've done so far is, for example:
flowm=zeros(12,1);
flowmax=zeros(12,1);
flowmin=zeros(12,1);
But this seems a bit tedious. I attempted the following to see if it would work
[flowm,flowmax,flowmin]=zeros(12,3)
but to no avail.
Can anyone suggest what might work?

2 comentarios

Luna
Luna el 20 de Nov. de 2018
What do you want to create? A matrix 12x3 or after filling the columns you want to merge them?
Samuel Newall
Samuel Newall el 20 de Nov. de 2018
I just want to set the vectors flowm, flowmax etc to columns of zeros in a compact way. What i am trying to do is similar to below:
imagine I had the matrix (1 2 3; 4 5 6; 7 8 9)
I want to be able to equate the vector matrix [a, b, c] (this is the matrix where the vector a is the first column, the vector b is the second, and vector c is the third) to the above matrix, such that the value of a is now (1;4;7), b is (2;5;8) and c is (3;6;9) or in matlab terms, a=[1 4 7]', b=[2 5 8]', c=[3 6 9]'
I hope that makes sense.

Iniciar sesión para comentar.

 Respuesta aceptada

Stephen23
Stephen23 el 20 de Nov. de 2018
Editada: Stephen23 el 20 de Nov. de 2018

0 votos

[flowm,flowmax,flowmin]= deal(zeros(12,1))

9 comentarios

Samuel Newall
Samuel Newall el 20 de Nov. de 2018
Editada: Samuel Newall el 20 de Nov. de 2018
Actually, it turns out that this sets flowm, flowmax and flowmin all to 12x3 matrices of zeros. So what I actually want is
[flowm,flowmax,flowmin]=deal(zeros(12,1))
This sets them all to column vectors of 12 zeros.
So thanks!
Stephen23
Stephen23 el 20 de Nov. de 2018
@Samuel Newall: good point. I fixed my answer, thanks!
Note that behind the scenes, there is difference between
flowm = zeros(12, 1);
flowmax = zeros(12, 1);
flowmin = zeros(12, 1);
and
[flowm, flowmax, flowmin] = deal(zeros(12,1));
which may or may not matter at all to you. The former creates 3 separate 12x1 arrays of 0s in memory. The latter creates a single array in memory and all three variables share that single array. As soon as you assign a single value to one of these arrays matlab will have to spend time copying the 0s so that it is no longer shared. I.e. the flows goes like this:
flowm = zeros(12, 1); %allocate memory for a 12x1 array
flowmax = zeros(12, 1); %allocate another block of memory for a 12x1 array
flowmin = zeros(12, 1); %allocate third block of memory for a 12x1 array
flowm(3) = 1; %fast operation, assign 1 to 3rd element of 1st memory block
flowmax(8) = 5; %fast operation, assign 5 to 8th element of 2nd memory block
flowmin(1) = 4; %fast operation, assign 4 to 1st element of 3rd memory block
in the first case, and
[flowm, flowmax, flowmin] = deal(zeros(12,1)); %allocate memory for a single 12x1 array shared by all 3 variables
flowm(3) = 1; %allocate memory for a 12x1 array. Copy the array of zeros in that new block. then assign 1 to 3rd element in this new block
%initial array is still shared by flowmax and flowmin
flowmax(8) = 5; %allocate memory for a 12x1 array. Copy the array of zeros in that new block. then assign 5 to 8th element in this new block
%original array is now used by flowmin only
flowmin(1) = 4; %fast operation, assign 4 to 1st element of original memory block
in the 2nd case. So you have additional array copy in the 2nd case and the memory allocation occurs at different times. For 12x1 arrays however, you'll never notice the difference.
Samuel Newall
Samuel Newall el 20 de Nov. de 2018
Thanks, I dont really know enough about MatLab to understand the difference, but good to know that they have different processes. The reason i wanted a different way of doing this was so that if i hypothetically had a large number of variables, like 100 instead of 3, it feels silly to allocate 100 lines of almost identical code to setting these to zero vectors. With a large amount of vectors would it be faster to run the code the first way (with 100 lines of code) or the second way, with 1 line of code?
The gist is that with deal the actual cost of creating the arrays may be delayed. For small arrays you'll never notice it anyway, for larger ones, if that delayed cost occurs inside a loop that needs to execute fast you may care.
"if i hypothetically had a large number of variables, like 100 instead of 3, it feels silly to allocate 100 lines of almost identical code to setting these to zero vectors."
I wouldn't recommend having 100 of variables anyway. Particularly, if they're all the same size, I would greatly recommend you have one single table instead (where the 100 variables are variables of the table). Your allocation then becomes:
varnames = {'flow', 'flowmax', 'flowmin'};
height = 12;
t = array2table(zeros(height, numel(varnames)), 'VariableNames', varnames);
%or
t = table('Size', [height, numel(varnames)], 'VariableTypes', repelem({'double'}, numel(varnames)), 'VariableNames', varnames)
"With a large amount of vectors would it be faster to run the code the first way (with 100 lines of code) or the second way, with 1 line of code?"
The 100 lines of code would be marginally faster as deal will cause 99 extra copy operations to occur at some point. In general, you will never notice it unless the arrays are large. Don't worry about speed until you've proven it's a problem. Clear code should be your priority until then.
Stephen23
Stephen23 el 20 de Nov. de 2018
Editada: Stephen23 el 20 de Nov. de 2018
"The 100 lines of code would be marginally faster as deal will cause 99 extra copy operations to occur at some point."
I don't really follow why this should be true. If 100 matrices are created either way, why does it matter when they are created?
With the 100 separate lines of zeros, the memory allocation for the 100 arrays occurs at the beginning of the code. With deal, at first there's only one shared array allocated. The actual allocation occurs when copy-on-write is triggered when one of the shared variable is modified. When c-o-w is triggered, you get a memory allocation of the non-longer shared copy, + copy of the content of the shared copy.
It's easy to demonstrate:
[a, b, c] = deal(zeros(1e4, 1e4));
numiter = 310;
timing = zeros(numiter, 1);
for counter = 1:numiter
tic;
if counter > 100
a(randi(numel(a))) = 5;
b(randi(numel(a))) = 10;
end
timing(counter) = toc;
end
plot(timing);
In the above, c-o-w is triggered at step 100 of the loop. You can clearly see the slowdown (at least on my machine) when that happens.
testalloc.png
Stephen23
Stephen23 el 21 de Nov. de 2018
Editada: Stephen23 el 21 de Nov. de 2018
@Guialluame: sure, it is clear why this allocation has to occur at some point. But you have not explained why this will be slower overall than allocating one hundred matrices at the start of the code.
As far as I can see, the time would be more or less the the same:
tic
create 100 matrices
do stuff with them
toc
vs.
tic
create one matrix
do stuff that creates 99 matrices
toc
As long as only 100 matrices are created, I don't see why "The 100 lines of code would be marginally faster as deal will cause 99 extra copy operations to occur at some point." It is clear that they have to be created at some point, but why would this matrix creation be "marginally faster" at the start of the code? Surely the matrix creation mechanism is not slower at the end of my script than at the start, or at some random point while it is running... Or are you simply excluding the matrix creation at the start of the code from your comparison?:
create 100 matrices
tic
do stuff
toc
vs.
create 1 matrix
tic
do stuff that creates 99 matrices
toc
My point was more that due to c-o-w mechanism the actual matrix creation is delayed to a time where it may not be expected. If the actual creating occurs in a loop which is expected to run at a fixed frequency, c-o-w may break that expectation.
In addition, in the second case, there are 99 copy operations that do not occur in the first case. However, I must admit that I forgot about the 99 setting the memory to 0 that occur in the first case. So the comparison is in effect (C equivalent):
%100 x zeros is
100 x malloc %allocate memory
100 x memset %set blocks to 0
vs
%1 x zeros
1 x malloc
1 x memset
%99 x copy-on-write:
99 x malloc
99 x memcpy
I would suspect that memset is generally faster than memcpy, the former is just writing to memory, the latter is both reading and writing. So I would expect the first version to be faster overall.
This discussion probably doesn't matter for the OP though, and a much more important point that I made has been lost:
I wouldn't recommend having 100 of variables anyway. Particularly, if they're all the same size, I would greatly recommend you have one single table instead (where the 100 variables are variables of the table).

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Entering Commands en Centro de ayuda y File Exchange.

Preguntada:

el 20 de Nov. de 2018

Comentada:

el 21 de Nov. de 2018

Community Treasure Hunt

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

Start Hunting!

Translated by