I attached a script below. My problem is a simple quadratic programming, but in the real world scenario I might add some linear constraints and linear objective terms. In the script I was merely isolating the quadratic component of it.
There are two ways of specifying quadratic function: x' Q x = (Hx)' where Q = H'H. The thing is, depending on how I specify it, the performance can vary greatly, even though mathematically they are supposed to be the same. The script below illustrates the difference. The "second way" is much faster than the "first way." The difference can be observed with n as low as 200, even though for my problem I usually need n around 2000 ish.
This is not a big deal as I've discovered the difference, and I can structure my code around it. But I was just wondering what the cause of the discrepancy may be, so that in the future when I use YALMIP, I can be more aware of these potential performance hot spots and not make the same mistake again.
clear;
profile clear;
yalmip('clear');
n = 500;
T = 10;
sigma = zeros(T, n, n);
for i = 1:T
H = 0.1 + 0.03*randn(n, n);
thisSigma = H * H';
sigma(i,:,:) = thisSigma;
end
%% First Way
x = sdpvar(n,1);
C = sdpvar(n,n,'full');
% objective: quadratic function
aux = C * x;
objective = aux' * aux;
% constraint
constraints = [];
fprintf('First way: starting to compile problem\n');
tic
options = sdpsettings('solver','cplex','verbose',0,'savesolveroutput',1);
P = optimizer(constraints,objective,options, C,x);
fprintf('First way: time taken to compile problem is : %s\n', hms(toc));
fprintf('First way: starting to solve problem\n');
for i = 1:T
thisC = reshape(sigma(i,:,:), [n,n]);
H = cholcov(thisC);
solution = P(H);
end
fprintf('First way: time taken to solve problem is : %s\n', hms(toc));
%% Second Way
yalmip('clear');
x = sdpvar(n,1);
C = sdpvar(n,n,'full');
% objective: quadratic function
aux = sdpvar(n,1);
objective = aux' * aux;
% constraint
constraints = [aux == C*x];
fprintf('Second way: starting to compile problem\n');
tic
options = sdpsettings('solver','cplex','verbose',0,'savesolveroutput',1);
P = optimizer(constraints,objective,options, C,x);
fprintf('Second way: time taken to compile problem is : %s\n', hms(toc));
fprintf('Second way: starting to solve problem\n');
for i = 1:T
thisC = reshape(sigma(i,:,:), [n,n]);
H = cholcov(thisC);
solution = P(H);
end
fprintf('Second way: time taken to solve problem is : %s\n', hms(toc));