Operands to the logical AND (&&) and OR (||) operators must be convertible to logical scalar values. Use the ANY or ALL functions to reduce operands to logical scalar values.
2 views (last 30 days)
Show older comments
Hi, I get the following error with the given code,
"Operands to the logical AND (&&) and OR (||) operators must be convertible to logical scalar values. Use the ANY or ALL functions to reduce operands to logical scalar values."
This performs a minimization using the active set method. But seemingly, it stops over this operator problem.
Any ideas welcome!
% Define symbolic variables
syms x1 x2 x3 lambda1 lambda3
% Objective function
f = x1^2 + x2^2 + x3^2 - x1 + 2*x2 - 4*x3;
% Constraints
g1 = -x1 + x2 + 1; % -x1 + x2 >= -1 is equivalent to g1 <= 0
g2 = x1 + x2 + x3 + 3; % x1 + x2 + x3 >= -3 is equivalent to g2 <= 0
g3 = x3; % x3 >= 0 is equivalent to g3 <= 0
% Initial point
x0 = [0; 0; 0];
% Iterative process
x = x0;
activeSet = []; % Initially empty active set
maxIter = 10; % Maximum number of iterations
tol = 1e-6; % Tolerance for convergence
for iter = 1:maxIter
% Compute gradients of the objective function and constraints
grad_f = gradient(f, [x1, x2, x3]);
grad_g1 = gradient(g1, [x1, x2, x3]);
grad_g2 = gradient(g2, [x1, x2, x3]);
grad_g3 = gradient(g3, [x1, x2, x3]);
% Evaluate gradients at the current point
grad_f_val = double(subs(grad_f, {x1, x2, x3}, x'));
grad_g1_val = double(subs(grad_g1, {x1, x2, x3}, x'));
grad_g2_val = double(subs(grad_g2, {x1, x2, x3}, x'));
grad_g3_val = double(subs(grad_g3, {x1, x2, x3}, x'));
% Check KKT conditions to determine active set
if abs(grad_g1_val) < tol && subs(g1, {x1, x2, x3}, x') <= 0
activeSet = [activeSet, 1]; % Constraint 1 is active
end
if abs(grad_g2_val) < tol && subs(g2, {x1, x2, x3}, x') <= 0
activeSet = [activeSet, 2]; % Constraint 2 is active
end
if abs(grad_g3_val) < tol && subs(g3, {x1, x2, x3}, x') <= 0
activeSet = [activeSet, 3]; % Constraint 3 is active
end
% Solve the subproblem using the active set
A_eq = [];
b_eq = [];
A_ineq = [];
b_ineq = [];
lb = [];
ub = [];
options = optimoptions('quadprog', 'Display', 'off');
if any(activeSet == 1)
A_ineq = [A_ineq; -1, 1, 0];
b_ineq = [b_ineq; -1];
end
if any(activeSet == 2)
A_ineq = [A_ineq; 1, 1, 1];
b_ineq = [b_ineq; -3];
end
if any(activeSet == 3)
A_ineq = [A_ineq; 0, 0, 1];
b_ineq = [b_ineq; 0];
end
[x_new, ~, exitflag] = quadprog(eye(3), -grad_f_val', A_ineq, b_ineq, A_eq, b_eq, lb, ub, [], options);
% Check convergence
if norm(x_new - x) < tol
break;
end
% Update x and active set
x = x_new;
activeSet = unique(activeSet);
end
% Display results
disp(['Optimal point: x = [', num2str(x'), ']']);
disp(['Objective function value: ', num2str(double(subs(f, {x1, x2, x3}, x')))]);
0 Comments
Accepted Answer
Torsten
on 4 Jul 2024
Edited: Torsten
on 4 Jul 2024
if all(abs(grad_g1_val) < tol) && subs(g1, {x1, x2, x3}, x') <= 0
activeSet = [activeSet, 1]; % Constraint 1 is active
end
if all(abs(grad_g2_val) < tol) && subs(g2, {x1, x2, x3}, x') <= 0
activeSet = [activeSet, 2]; % Constraint 2 is active
end
if all(abs(grad_g3_val) < tol) && subs(g3, {x1, x2, x3}, x') <= 0
activeSet = [activeSet, 3]; % Constraint 3 is active
end
instead of
if abs(grad_g1_val) < tol && subs(g1, {x1, x2, x3}, x') <= 0
activeSet = [activeSet, 1]; % Constraint 1 is active
end
if abs(grad_g2_val) < tol && subs(g2, {x1, x2, x3}, x') <= 0
activeSet = [activeSet, 2]; % Constraint 2 is active
end
if abs(grad_g3_val) < tol && subs(g3, {x1, x2, x3}, x') <= 0
activeSet = [activeSet, 3]; % Constraint 3 is active
end
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!