Equalizing array of uknowns with a known array
조회 수: 7 (최근 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에서 Data Type Conversion에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!