Equalizing array of uknowns with a known array
2 次查看(过去 30 天)
显示 更早的评论
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?
0 个评论
采纳的回答
Jan
2017-10-25
编辑:Jan
2017-10-25
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 个评论
Jan
2017-10-25
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.
更多回答(2 个)
KL
2017-10-25
编辑:KL
2017-10-25
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 个评论
John D'Errico
2017-10-25
编辑:Jan
2017-10-25
+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.)
John D'Errico
2017-10-25
编辑:John D'Errico
2017-10-25
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 个评论
Jan
2017-10-25
编辑:Jan
2017-10-25
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{:})
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Structures 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!