%% Convert Quadratic Constraints to Second-Order Cone Constraints
% This example shows how to convert a quadratic constraint to the second-order cone constraint form. A quadratic constraint has the form
% \[{x^T}Qx + 2{q^T}x + c \le 0.\]
% Second-order cone programming has constraints of the form
% \[\left\| {{A_{{\rm{sc}}}}(i) \cdot x - {b_{{\rm{sc}}}}(i)} \right\| \le {d_{{\rm{sc}}}}(i) \cdot x - \gamma (i)\].
% The matrix Q must be symmetric and positive semidefinite for you to convert quadratic constraints. Let S be the square root of Q, meaning Q = S*S = S^T*S. You can compute S using sqrtm. Suppose that there is a solution b to the equation S^Tb = –q, which is always true when Q is positive definite. Compute b using b = -S\q.
% \[\begin{array}{l}
% {x^T}Qx + 2{q^T}x + c &= {x^T}{S^T}Sx - 2{\left( {{S^T}b} \right)^T}x + c\\
%  &= {\left( {Sx - b} \right)^T}\left( {Sx - b} \right) - {b^T}b + c\\
%  &= {\left\| {Sx - b} \right\|^2} + c - {b^T}b.
% \end{array}\]
% Therefore, if b^Tb > c, then the quadratic constraint is equivalent to the second-order cone constraint with
% A_{\rm sc} = S
% b_{\rm sc} = b
% d_{\rm sc} = 0
% \[\gamma  =  - \sqrt {{b^T}b - c} \]
%% Numeric Example
% Specify a five-element vector f representing the objective function f^Tx.

f = [1;-2;3;-4;5];

% Set the quadratic constraint matrix Q as a 5-by-5 random positive definite matrix. Set q as a random 5-element vector, and take the additive constant c=-1.

rng default % For reproducibility
Q = randn(5) + 3*eye(5);
Q = (Q + Q')/2; % Make Q symmetric
q = randn(5,1);
c = -1;

% To create the inputs for coneprog, create the matrix S as the square root of Q.

S = sqrtm(Q);

% Create the remaining inputs for the second-order cone constraint as specified in the first part of this example.

b = -S\q;
d = zeros(size(b));
gamma = -sqrt(b'*b-c);
sc = secondordercone(S,b,d,gamma);

% Call coneprog to solve the problem.

[x,fval] = coneprog(f,sc)

% Compare this result to the result returned by solving this same problem using fmincon. Write the quadratic constraint as described in Anonymous Nonlinear Constraint Function.

x0 = randn(5,1); % Initial point for fmincon
nlc = @(x)x'*Q*x + 2*q'*x + c;
nlcon = @(x)deal(nlc(x),[]);
[xfmc,fvalfmc] = fmincon(@(x)f'*x,x0,[],[],[],[],[],[],nlcon)

% The two solutions are nearly identical.
% Copyright 2020 The MathWorks, Inc.