allocate array to structure, error "Scalar structure required for this assignment."
Afficher commentaires plus anciens
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 commentaires
@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
le 11 Nov 2024
Modifié(e) : Sven Larsen
le 11 Nov 2024
Réponses (1)
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 commentaires
Sven Larsen
le 11 Nov 2024
"Firstly, why C{:} and not just C"
My answer explains that both the LHS and RHS must be comma-separated lists.
"What {:} means?"
It is the MATLAB syntax for generating a comma-separated list from a cell array:
"Second, why [mpData(1).data.speed] and not just mpData(1).data.speed"
As my tutorial clearly explains, a comma-separated list is just a comma separated list. The MATLAB syntax for assigning multiple arrays on the LHS requires square brackets. Here is a comma-separated list on the LHS:
[A,B,C,D,..] = .. whatever ..
Writing the comma-separated list explicitly is interchangeable with generating it from a cell array, structure array, or string array (that is rather than whole point of them, and is the main reason why they are so useful). You still need to use square brackets because you are still allocating multiple arrays on the LHS.
"For example your link https://www.mathworks.com/matlabcentral/discussions/tips/847976-tutorial-comma-separated-lists-and-how-to-use-them is very shallow and examples are just a few; there should be myriad of examples, like excellent help of datetime."
DATETIME has many options, comma-separated lists do not. As my "very shallow" tutorial explains, they are essentially interchangeable with writing explicit lists of comma-separated variables (that is where the name comes from), which fundamentally do not have options like that.
If you are not sure when to use square brackets on the LHS then you should revise basic MATLAB syntax about square brackets on the LHS, e.g.:
Sven Larsen
le 12 Nov 2024
"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.
Sven Larsen
le 12 Nov 2024
Catégories
En savoir plus sur Structures dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
