Borrar filtros
Borrar filtros

Equalizing array of uknowns with a known array

2 visualizaciones (últimos 30 días)
Saeid
Saeid el 25 de Oct. de 2017
Editada: Jan el 25 de Oct. de 2017
I have a vector of known values such as V=[0.012 2 0.47 100] and I wnat to assign these values to parameters from a different matrix of strings such as: S={'Mass' 'Volume' 'Width' 'Height'} so that I can use the numerical values of Mass and Volume in my calculations from now on (e.g. to calculate Density=Mass(Volume). How can I assign the numerical values to the strings?

Respuesta aceptada

Jan
Jan el 25 de Oct. de 2017
Editada: Jan el 25 de Oct. de 2017
Do not create variables dynamically. This is the most frequently ask question and the answer is always the same: This is a very bad idea. See http://www.mathworks.com/matlabcentral/answers/304528-tutorial-why-variables-should-not-be-named-dynamically-eval .
Use a struct instead:
Data = cell2struct(num2cell(V(:)), S(:))
% [EDITED], typo fixed, "struct" --> "cell2struct"
This creates:
Data =
Mass: 0.0120
Volume: 2
Width: 0.4700
Height: 100
[EDITED 2] After measuring some timings, I suggest this to support a large number of fields also:
P = struct();
for i = 1:numel(S)
P.(S{i}) = V(i);
end
Or use the modern and powerful table object suggested by K L.
  1 comentario
Jan
Jan el 25 de Oct. de 2017
Thanks. Somebody has voted for my answer, although it was not even working due to a typo. It is fixed now. cell2struct is equivalent to the loop method with setfield, but without the loop and setfield.

Iniciar sesión para comentar.

Más respuestas (2)

KL
KL el 25 de Oct. de 2017
Editada: KL el 25 de Oct. de 2017
You can create a table,
V=[0.012 2 0.47 100]
S={'Mass' 'Volume' 'Width' 'Height'}
T = array2table(V,'v',S)
and now T is,
T =
1×4 table
Mass Volume Width Height
_____ ______ _____ ______
0.012 2 0.47 100
So, to calculate density now,
T.density = T.Mass/T.Volume
  1 comentario
John D'Errico
John D'Errico el 25 de Oct. de 2017
Editada: Jan el 25 de Oct. de 2017
+1. I'll argue that this may be the best answer, in the sense that it is simplest to perform. As such, it is simpler to implement than my own answer, which suggests a struct. The only negative is that some users will not have tables available to them, because of an older MATLAB release. Those users who find themselves stuck in the bronze age of MATLAB computing will best use a struct. (And if you have a stone age MATLAB release that is too old to have even structs available, then somehow find a way to upgrade.)

Iniciar sesión para comentar.


John D'Errico
John D'Errico el 25 de Oct. de 2017
Editada: John D'Errico el 25 de Oct. de 2017
You can't assign a numerical value to a string.
I would suggest creating a struct. This is a good way of storing such parameters anyway.
S={'Mass' 'Volume' 'Width' 'Height'}
V=[0.012 2 0.47 100]
P = struct(S{1},V(1),S{2},V(2),S{3},V(3),S{4},V(4));
So now...
P
P =
struct with fields:
Mass: 0.012
Volume: 2
Width: 0.47
Height: 100
and,
P.Mass
ans =
0.012
Or you can use setfield.
If you don't know how long the set of properties is, or if there are just a huge number of them, then use setfield, with a loop.
clear P
P = struct(S{1},V(1));
for i = 2:numel(S)
P = setfield(P,S{i},V(i));
end
Again,
P =
struct with fields:
Mass: 0.012
Volume: 2
Width: 0.47
Height: 100
  4 comentarios
Stephen23
Stephen23 el 25 de Oct. de 2017
Editada: Stephen23 el 25 de Oct. de 2017
It is not required to use a loop, because a comma-separated list does the job perfectly:
>> S = {'Mass','Volume','Width','Height'};
>> V = [0.012,2,0.47,100];
>> C = [S;num2cell(V)];
>> P = struct(C{:})
Jan
Jan el 25 de Oct. de 2017
Editada: Jan el 25 de Oct. de 2017
I assume it is more efficient to access the struct directly:
P = struct(); % Overwrite P if it exists before
for i = 1:numel(S)
P.(S{i}) = V(i);
end
With P=setfield(P,S,V) the struct P is copied in each iteration after adding the new field. See:
S = sprintfc('f%d', (1:10000).');
V = rand(10000, 1);
tic;
P = struct();
for i = 1:numel(S);
P = setfield(P,S{i},V(i));
end
toc
tic;
P = struct();
for i = 1:numel(S)
P.(S{i}) = V(i);
end
toc
tic;
P = cell2struct(num2cell(V), S);
toc
tic;
C = [S.'; num2cell(V.')];
P = struct(C{:});
toc
R2009a/64 Win7 (NOTE: Measured with an ancient Matlab version!):
Elapsed time is 6.642184 seconds. SETFIELD
Elapsed time is 0.077548 seconds. P.(S{i})
Elapsed time is 0.366581 seconds. CELL2STRUCT
Elapsed time is 0.374473 seconds. STRUCT(C{:})

Iniciar sesión para comentar.

Categorías

Más información sobre Structures en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by