Store structure output into an array that you can index

I used a [X,fval,exitflag,output] = fmincon(fun,...) for global optimization that is in a parfor loop.
In each loop, I get an "output" that show something like:
output =
struct with fields:
iterations: 24
funcCount: 84
constrviolation: 0
stepsize: 6.9162e-06
algorithm: 'interior-point'
firstorderopt: 2.4373e-08
cgiterations: 4
message: 'Local minimum found that satisfies the constraints....'
bestfeasible: [1x1 struct]
The information here is important so I want to store them in each loop. After the loop is done, I am going to use indexing to call for the output of a particular calculation that finished with an exitflag = 1.
X, fval, exitflag are easy to store for recalling them later since they are scalar numbers (using normal array). However, the output is a structure. I saw that the structure array could be used, but it seems to me that creating empty TotalNumberOfIteration-by-1 structure array is impossible without directly naming each of the elements.
I want to know of a way to store in a similar way to normal array to recall them later. Is there such way?

 Réponse acceptée

Luca Ferro
Luca Ferro le 2 Fév 2023
i would either store it in a 1xn struct (n is the number of outputs you want to store):
for (your current loop condition, i'll call the index it idx)
[..,output(idx)] = fmincon(fun,..) %this stores your your outout in a 1xn struct
end
%to access the struct (let's say the first one)
output(1)
..
output(idx)
%to access the values
output(1).iterations
..
output(idx).iterations
%to access the struct within the values
output(1).bestfeasible.fieldnameinsidethestruct
or i would go for a cell array
for (your current loop condition, i'll call the index it idx)
[..,output{1}] = fmincon(fun,..) %this stores your your outout in a 1xn cell array
end
%to access the cell array (let's say the first one)
output{1}
..
output{idx}
%to access the values
output{1}.iterations
..
output{idx}.iterations
%to access the struct within the values
output{1}.bestfeasible.fieldnameinsidethestruct
The main difference is that the first method allows only structs with the same dimensions, the latter one is a bit more flexible.

5 commentaires

Thanks. I think structures can't be stored into cell array. I actually tried the cell array method, and it gave me an error.
I'll try the first one, though, and get back. Huge thanks.
It definitely should be possible to store the structures in a cell array, like this:
fun = @(x)100*(x(2)-x(1)^2)^2 + (1-x(1))^2;
parfor i = 1:3
x0 = [-1,2];
A = [1,2];
b = i;
[x{i}, ~, ~, out{i}] = fmincon(fun,x0,A,b);
end
Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. <stopping criteria details> Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. <stopping criteria details> Local minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. <stopping criteria details>
celldisp(out)
out{1} = iterations: 30 funcCount: 103 constrviolation: 0 stepsize: 1.1259e-05 algorithm: 'interior-point' firstorderopt: 8.0208e-08 cgiterations: 2 message: 'Local minimum found that satisfies the constraints.↵↵Optimization completed because the objective function is non-decreasing in ↵feasible directions, to within the value of the optimality tolerance,↵and constraints are satisfied to within the value of the constraint tolerance.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 8.020757e-08,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.' bestfeasible: [1×1 struct] out{2} = iterations: 48 funcCount: 161 constrviolation: 0 stepsize: 4.1680e-09 algorithm: 'interior-point' firstorderopt: 8.0000e-08 cgiterations: 3 message: 'Local minimum found that satisfies the constraints.↵↵Optimization completed because the objective function is non-decreasing in ↵feasible directions, to within the value of the optimality tolerance,↵and constraints are satisfied to within the value of the constraint tolerance.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 8.000000e-08,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.' bestfeasible: [1×1 struct] out{3} = iterations: 62 funcCount: 201 constrviolation: 0 stepsize: 7.2713e-07 algorithm: 'interior-point' firstorderopt: 2.5600e-07 cgiterations: 2 message: 'Local minimum found that satisfies the constraints.↵↵Optimization completed because the objective function is non-decreasing in ↵feasible directions, to within the value of the optimality tolerance,↵and constraints are satisfied to within the value of the constraint tolerance.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 2.560002e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.' bestfeasible: [1×1 struct]
"I think structures can't be stored into cell array."
Here is a structure stored in a cell array:
C = {struct('X',pi')}
C = 1×1 cell array
{1×1 struct}
C{1}
ans = struct with fields:
X: 3.1416
"The main difference is that the first method allows only structs with the same dimensions, the latter one is a bit more flexible."
The main difference is that with a structure array you can use comma-separated lists to process the field content. With a cell array of scalar structures you cannot.
This means that although within the loop it can be convenient to use a cell array, but after the loop you should concatenate those scalar structure into one structure array (which you can access using indexing, as per your original question):
nmi = 3;
out = cell(1,nmi); % better to preallocate.
parfor k = 1:nmi
..
[..,out{k}] = fmincon(..);
end
out = [out{:}] % one structure array
Luca Ferro
Luca Ferro le 2 Fév 2023
Modifié(e) : Luca Ferro le 2 Fév 2023
thank you for expanding on the differences, i missed that for sure
I see, I didn't know that was how I was supposed to do it. I did it wrong, which is why cell array didn't work for me.
Huge thanks guys. Now it worked!!!

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Loops and Conditional Statements dans Centre d'aide et File Exchange

Produits

Version

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by