How do I find the minimum between a matrix and a varying matrix function? I get "Error in fmincon (line 563) initVals.f = feval(funfcn{3},X,varargin{:});"
2 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Goncalo Costa
el 1 de Dic. de 2023
Comentada: Star Strider
el 1 de Dic. de 2023
I am trying to analyse how close, percentually, my samples are to pure water (0%) and to "no water"/dried (100%). In theory my results should give me a value between 0% and 100% (or 0 and 1, labelled below as fitvar)
I have a 2D data array for water, a 2D data array for "dried" and a 2D data for each data set that I am trying to analyse. All data arrays are composed of complex numbers, hence why I can't solve this analytically.
% the size of the data arrays are 75 x 75 matrices.
num_x = 75;
num_y = 75;
perc_water = zeros(num_latex_measurements, num_x, num_y);
% loading a 75 x 75 matrix of the current sample to analyse, of pure water
% and of dried sample.
eps_current_sample = load('eps_1.mat');
eps_water = load('eps_water.mat');
eps_dried = load('eps_32.mat');
%relabelling the data (as it had been saved with the variable name of
%I3.epsilon)
eps_water = eps_water.I3_epsilon;
eps_dried = eps_dried.I3.epsilon;
for x=1:num_x
for y=1:num_y
% calculating the theoretical values for eps over a range of
% fit_var, from 0 to 1
eps_theory = @(fit_var) FORMULA( eps_water(x, y), eps_dried(x,y), fit_var );
% calculate the absolute value between the difference of the
% current sample data and of the theoretical values.
loss_fx = @(fit_var) abs(eps_current_sample(x, y) - eps_theory(fit_var) );
%finding the smallest difference for each 2D matrix, for each
%fit_var value
perc_water(x, y) = fmincon(loss_fx, 0.5, [], [] , [], [], 0, 1);
end
end
The FORMULA function is shown below (this is simple multiplication and divisions resulting in a 75 x 75 matrix with complex numbers.
function eps_eff = FORMULA(eps_water, eps_dried, perc_water)
eps_eff = eps_dried./2.0-eps_water./4.0-eps_dried.*perc_water.*(3.0./4.0)+eps_water.*perc_water.*(3.0./4.0)+sqrt(eps_dried.*eps_water.*4.0-eps_dried.^2.*perc_water.*1.2e+1-eps_water.^2.*perc_water.*6.0+eps_dried.^2.*4.0+eps_water.^2+eps_dried.^2.*perc_water.^2.*9.0+eps_water.^2.*perc_water.^2.*9.0+eps_dried.*eps_water.*perc_water.*1.8e+1-eps_dried.*eps_water.*perc_water.^2.*1.8e+1)./4.0;
end
Whenever I try to run it I get the following error message.
Operator '-' is not supported for operands of type 'struct'.
Error in @(fit_var)abs(eps_current_latex(x,y)-perc_water_fx(fit_var))
Error in fmincon (line 563)
initVals.f = feval(funfcn{3},X,varargin{:});
I have never used fmincon before, is there anything incorrect with my approach? I know the operator is not really the problem, but I don't see what is.
Thanks for your help.
0 comentarios
Respuesta aceptada
Star Strider
el 1 de Dic. de 2023
Editada: Star Strider
el 1 de Dic. de 2023
There is one typo (. where _ should be) in:
eps_dried = eps_dried.I3.epsilon;
so change that to:
eps_dried = eps_dried.I3_epsilon;
and the displayed error is corrected by changing the current ‘loss_fx’ line to:
loss_fx = @(fit_var) abs(eps_current_sample.I3_epsilon(x, y) - eps_theory(fit_var) );
Consider suppressing the fmincon outputs as well, in an options structure:
opts = optimoptions('fmincon', 'Display','off');
perc_water(x, y) = fmincon(loss_fx, 0.5, [], [] , [], [], 0, 1, [], opts);
Then run it —
% the size of the data arrays are 75 x 75 matrices.
num_x = 75;
num_y = 75;
% perc_water = zeros(num_latex_measurements, num_x, num_y); % Missing Variable
% loading a 75 x 75 matrix of the current sample to analyse, of pure water
% and of dried sample.
eps_current_sample = load('eps_1.mat');
eps_water = load('water.mat');
eps_dried = load('eps_32.mat');
%relabelling the data (as it had been saved with the variable name of
%I3.epsilon)
eps_water = eps_water.I3_epsilon;
eps_dried = eps_dried.I3_epsilon;
opts = optimoptions('fmincon', 'Display','off');
for x=1:num_x
for y=1:num_y
% calculating the theoretical values for eps over a range of
% fit_var, from 0 to 1
eps_theory = @(fit_var) FORMULA( eps_water(x, y), eps_dried(x,y), fit_var );
% calculate the absolute value between the difference of the
% current sample data and of the theoretical values.
loss_fx = @(fit_var) abs(eps_current_sample.I3_epsilon(x, y) - eps_theory(fit_var) );
%finding the smallest difference for each 2D matrix, for each
%fit_var value
perc_water(x, y) = fmincon(loss_fx, 0.5, [], [] , [], [], 0, 1, [], opts);
end
end
Output = perc_water
figure
surfc(Output)
xlabel('X')
ylabel('Y')
zlabel('perc\_water')
title('Output')
colormap(turbo)
function eps_eff = FORMULA(eps_water, eps_dried, perc_water)
eps_eff = eps_dried./2.0-eps_water./4.0-eps_dried.*perc_water.*(3.0./4.0)+eps_water.*perc_water.*(3.0./4.0)+sqrt(eps_dried.*eps_water.*4.0-eps_dried.^2.*perc_water.*1.2e+1-eps_water.^2.*perc_water.*6.0+eps_dried.^2.*4.0+eps_water.^2+eps_dried.^2.*perc_water.^2.*9.0+eps_water.^2.*perc_water.^2.*9.0+eps_dried.*eps_water.*perc_water.*1.8e+1-eps_dried.*eps_water.*perc_water.^2.*1.8e+1)./4.0;
end
EDIT — (1 Dec 2023 at 13:28)
Added surfc call, expanded explanation.
.
4 comentarios
Star Strider
el 1 de Dic. de 2023
@Goncalo Costa — I removed the preallocation:
% perc_water = zeros(num_latex_measurements, num_x, num_y); % Missing Variable
because ‘num_latex_measurements’ was missing. The preallocation defines a 3D matrix, however since I didn’t know what the missing variable was, I just removed (commented-out) the entire preallocation. If you want to do a loop over a number of data sets, a 3D matrix is one option. A cell array with each 2D matrix being in a different cell is another option. It all depends on how you choose to index them.
Más respuestas (0)
Ver también
Categorías
Más información sobre Matrix Indexing 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!