What is the proper method to index a structure array

4 Ansichten (letzte 30 Tage)
Hugh Dolden
Hugh Dolden am 17 Feb. 2016
Bearbeitet: Stephen23 am 22 Feb. 2016
I initialized a 100x423 structure with the following code:
k = 0;
for i = 1:populationSize;
for j = 1:genomeLength;
k = k + 1;
Population(i,j).ShipmentID = k;
Population(i,j).OrderID = 0;
Population(i,j).CommodityID = 0;
Population(i,j).AssetID = randi(20);
Population(i,j).Zone = 0;
Population(i,j).Volume = 0.0;
Population(i,j).Prev = 0;
Population(i,j).Next = 0;
end;
end;
I want to link the elements with the same AssetID in random order with the following code:
[assetCount,assetID] = hist([Population(i,:).AssetID],unique([Population(i,:).AssetID]))
for j = 1:length(assetCount);
if assetID(j)>0;
[q,assetIndices]=ind2sub(1,find([Population(1,:).AssetID]==assetID(j)));
assetIndices = assetIndices(randperm(length(assetIndices)));
prevIndices = [0 assetIndices(1:end-1)];
nextIndices = [assetIndices(2:end) 0];
[Population(i,assetIndices).Prev] = prevIndices;
[Population(i,assetIndices).Next] = nextIndices;
end;
end;
PrevIndices, NextIndices and assetIndices all have the same length yet MATLAB returns the error: Insufficient number of outputs from right hand side of equal sign to satisfy assignment.
  1 Kommentar
Stephen23
Stephen23 am 17 Feb. 2016
Bearbeitet: Stephen23 am 22 Feb. 2016
Note that your method of creating the structure in nested loops is very memory-inefficient, as the structure has to grow on each iteration. There are several ways to write much more efficient code, such as array preallocation. This method applies just as much to structures as any other array types, as Loren Shure explains in her blog:
Check out the section title "Don't Grow Arrays" !
She gives easy ways to preallocate, for example you could simply put
Population(populationSize,genomeLength) = struct();
before your nest loops, and this will preallocate a structure of the appropriate size. The rest of your code stays the same.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Walter Roberson
Walter Roberson am 17 Feb. 2016
When you use
[structure(vector_index).field] = value
then the value needs to be structure or cell expansion of the number of results as are on the left hand side. For example,
c_pI = num2cell(prevIndices);
[Population(i,assetIndices).Prev] = c_pI{:};
Here prevIndices and assetIndices have the same length so the structure expansion has as many outputs on the left as you have in the list on the right, and each of the Prev will get exactly one value.
It is not possible to use structure expansion to copy the same vector to multiple fields, so if your Prev were intended to all get copies of the same vector, you would use
c_pI = repmat({prevIndices}, 1, length(assetIndices));
[Population(i,assetIndices).Prev] = c_pI{:};
In this way the expanded values on the right would all be identical and there would be enough copies to write to the locations on the left.
  1 Kommentar
Hugh Dolden
Hugh Dolden am 17 Feb. 2016
Thank you for your answer which solved my problem. I viewed the Array of Structures vs Structure of Arrays video. Would redefining the Population structure be appropriate?

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Creating and Concatenating Matrices finden Sie in Help Center und File Exchange

Tags

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by