allocate array to structure, error "Scalar structure required for this assignment."
61 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Sven Larsen
el 11 de Nov. de 2024 a las 12:09
Comentada: Sven Larsen
el 12 de Nov. de 2024 a las 9:26
im trying to allocate numeric array to all cells in certain field of structure.
mpData(i).data.speed = interp1(x,v,xq);
and get error "Scalar structure required for this assignment."
both interp1(x,v,xq) and mpData(i).data.speed are 168x1 double but still, I get this error.
[mpData(i).data.speed] = deal(interp1(x,v,xq));
wont work since it just allocated all 168 arrays to each cell of mpData(i).data.speed struct. Also num2cell wont work
2 comentarios
Stephen23
el 11 de Nov. de 2024 a las 12:40
Editada: Stephen23
el 11 de Nov. de 2024 a las 13:27
@Sven Larsen: please save your structure in a MAT file and upload it here by clicking the paperclip button.
Descriptions of non-scalar structures are usually incorrect, which makes answering the question hard/impossible. With your actual structure answering is easier.
Sven Larsen
el 11 de Nov. de 2024 a las 12:51
Editada: Sven Larsen
el 11 de Nov. de 2024 a las 12:51
Respuestas (1)
Stephen23
el 11 de Nov. de 2024 a las 12:47
Editada: Stephen23
el 11 de Nov. de 2024 a las 13:43
The error is easy to replicate given a scalar structure** on the LHS, which contains a non-scalar structure DATA (in your case with 168 elements). The RHS is basically irrelevant, as long as it is one array. Assuming that i is scalar:
mpData(1).data = struct('speed',cell(1,168));
mpData(2).data = struct('speed',{}) % optional, serves no purpose here.
try % what you are doing -> error
mpData(1).data.speed = 1:168
catch ME
ME.message
end
The error occurs because you are trying to assign one array on the RHS to 168 structure elements on the LHS. That will not work (except with DEAL, which is unlikely to be what you want to achieve).
Using NUM2CELL works without error, by creating 168 separate (scalar) arrays that can be allocated to 168 elements of the DATA structure:
C = num2cell(1:168);
[mpData(1).data.speed] = C{:}
Checking the 2nd element of the DATA structure:
mpData(1).data(2).speed
Learn more about comma-separated lists:
For the Future
Based on your previous question:
here is a little guide to thinking about this operation:
- just like solving any other mathematical/engineering problem, reduce the problem to something simpler by getting rid of everything superfluous and causes clutter,
- this means forget about MPDATA: as long as all parent structures are scalar then they are irrelevant, you only really need consider the first (nested) non-scalar structure. And in your case that is DATA, which (apparently) has 168 elements. Luckily you do not have any structures nested within that (which would require a loop or other tricks),
- Your goal is to allocate 168 separate arrays to 168 separate locations in a structure, i.e. your operation is requires two comma-separated lists, one on the LHS and one on the RHS. So you need to ensure that the RHS can generate 168 separate arrays in a comma-separated list and the LHS is also a valid comma-separated list. My tutorial covers the main ways you specify comma-separated lists, so I will not repeat it here.
This means that your operation reduces down to this:
S = struct('X',cell(1,168))
try % error
S.X = 1:168
catch ME
ME.message
end
C = num2cell(1:168);
[S.X] = C{:} % no error
You can nest that in as many scalar structures as you wish, they make no difference.
** which you refer to using the (presumably) scalar i-index, thus the LHS refers to a scalar structure containing a nested non-scalar structure. The fact that MPDATA itself might be a non-scalar structure is completely irrelevant.
5 comentarios
Stephen23
el 12 de Nov. de 2024 a las 9:07
Editada: Stephen23
el 12 de Nov. de 2024 a las 9:23
"Why is that [] necessary in first place in LHS?"
By definition, because that is the syntax MATLAB uses to specify multiple arrays on the LHS. For example, this is used to return multiple outputs from a function call (note that many languages only support one output argument). Returning multiple output arguments from a function call is explained in the introductory tutorials:
"I have never used this before"
While I guess it would be possible to write code without them, doing so would be extremely restrictive: you would miss out on many many many useful output arguments, e.g. the indices from MIN, MAX, ISMEMBER, etc.
"because im assuming that there is no need for that, if that variable already is comma separated list."
Sure, it is a comma-separated list. But a comma-separated list by itself does nothing much. Why do this?:
A,B,C,D
%^^^^^^^ comma-separated list
If your goal is e.g. to display some variables then that is all you need. For fun perhaps, but otherwise not very useful. But the point of any comma-separated list is where you can use it. For example, when calling a function by providing it with multiple inputs:
fun(A,B,C,D)
% ^^^^^^^ comma-separated list
"i.e if a = [1,2,3,4]..."
Note that your example used a comma-separated list with the concatenation operator:
a = [1,2,3,4]
% ^^^^^^^ comma-separated list
"then a == [a]"
That is only one array. In general comma-separated lists refer to zero, one, or multiple arrays:
A,B,C,D
The goal of your original question was to allocate 168 arrays (to the elements of a non-scalar structure), not one array.
Ver también
Categorías
Más información sobre Spreadsheets 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!