% Boyd & Vandenberghe, "Convex Optimization"
% Joëlle Skaf - 08/29/05
%
% Solves an extension of the classical Markovitz portfolio optimization
% problem:      minimize    x'Sx
%                   s.t.    p_'*x >= r_min
%                           1'*x = 1,   x >= 0
%                           sum_{i=1}^{0.1*n}x[i] <= alpha
% where p_ and S are the mean and covariance matrix of the price range
% vector p, x[i] is the ith greatest component in x.
% The last constraint can be replaced by this equivalent set of constraints
%                           r*t + sum(u) <= alpha
%                           t*1 + u >= x
%                           u >= 0

% Input data
randn('state',0);
n = 25;
p_mean = randn(n,1);
temp = randn(n);
sig = temp'*temp;
r = floor(0.1*n);
alpha = 0.8;
r_min = 1;

% original formulation
fprintf(1,'Computing the optimal Markovitz portfolio: \n');
fprintf(1,'# using the original formulation ... ');

cvx_begin
    variable x1(n)
    minimize ( quad_form(x1,sig) )
    p_mean'*x1 >= r_min;
    ones(1,n)*x1 == 1;
    x1 >= 0;
    sum_largest(x1,r) <= alpha;
cvx_end

fprintf(1,'Done! \n');
opt1 = cvx_optval;

% equivalent formulation
fprintf(1,'# using an equivalent formulation by replacing the diversification\n');
fprintf(1,'  constraint by an equivalent set of linear constraints...');

cvx_begin
    variables x2(n) u(n) t(1)
    minimize ( quad_form(x2,sig) )
    p_mean'*x2 >= r_min;
    sum(x2) == 1;
    x2 >= 0;
    r*t + sum(u) <= alpha;
    t*ones(n,1) + u >= x2;
    u >= 0;
cvx_end

fprintf(1,'Done! \n');
opt2 = cvx_optval;

% Displaying results
disp('------------------------------------------------------------------------');
disp('The optimal portfolios obtained from the original problem formulation and');
disp('from the equivalent formulation are respectively: ');
disp([x1 x2])
disp('They are equal as expected!');
Computing the optimal Markovitz portfolio: 
# using the original formulation ...  
Calling Mosek 9.1.9: 105 variables, 52 equality constraints
   For improved efficiency, Mosek is solving the dual problem.
------------------------------------------------------------

MOSEK Version 9.1.9 (Build date: 2019-11-21 11:32:15)
Copyright (c) MOSEK ApS, Denmark. WWW: mosek.com
Platform: MACOSX/64-X86

Problem
  Name                   :                 
  Objective sense        : min             
  Type                   : CONIC (conic optimization problem)
  Constraints            : 52              
  Cones                  : 1               
  Scalar variables       : 105             
  Matrix variables       : 0               
  Integer variables      : 0               

Optimizer started.
Presolve started.
Linear dependency checker started.
Linear dependency checker terminated.
Eliminator started.
Freed constraints in eliminator : 1
Eliminator terminated.
Eliminator - tries                  : 1                 time                   : 0.00            
Lin. dep.  - tries                  : 1                 time                   : 0.00            
Lin. dep.  - number                 : 0               
Presolve terminated. Time: 0.00    
Problem
  Name                   :                 
  Objective sense        : min             
  Type                   : CONIC (conic optimization problem)
  Constraints            : 52              
  Cones                  : 1               
  Scalar variables       : 105             
  Matrix variables       : 0               
  Integer variables      : 0               

Optimizer  - threads                : 8               
Optimizer  - solved problem         : the primal      
Optimizer  - Constraints            : 51
Optimizer  - Cones                  : 2
Optimizer  - Scalar variables       : 105               conic                  : 29              
Optimizer  - Semi-definite variables: 0                 scalarized             : 0               
Factor     - setup time             : 0.00              dense det. time        : 0.00            
Factor     - ML order time          : 0.00              GP order time          : 0.00            
Factor     - nonzeros before factor : 749               after factor           : 1109            
Factor     - dense dim.             : 0                 flops                  : 3.96e+04        
ITE PFEAS    DFEAS    GFEAS    PRSTATUS   POBJ              DOBJ              MU       TIME  
0   4.4e+01  1.0e+00  1.0e+00  0.00e+00   0.000000000e+00   0.000000000e+00   1.0e+00  0.00  
1   9.9e+00  2.3e-01  4.4e-01  -9.49e-01  4.991596544e+00   7.839295295e+00   2.3e-01  0.01  
2   4.6e+00  1.0e-01  8.7e-02  -1.87e-01  -8.043575265e+00  -7.681980818e+00  1.0e-01  0.01  
3   3.0e+00  6.8e-02  2.8e-02  3.75e+00   -1.946947865e+01  -1.939062664e+01  6.8e-02  0.01  
4   9.0e-01  2.1e-02  3.4e-03  2.08e+00   -2.237115464e+01  -2.236081483e+01  2.1e-02  0.01  
5   1.2e-01  2.7e-03  1.5e-04  1.31e+00   -2.311404058e+01  -2.311313702e+01  2.7e-03  0.01  
6   3.5e-03  8.0e-05  5.9e-07  1.06e+00   -2.322037638e+01  -2.322037590e+01  8.0e-05  0.01  
7   5.9e-05  1.3e-06  1.2e-09  1.01e+00   -2.322323127e+01  -2.322323136e+01  1.3e-06  0.01  
8   2.5e-08  5.6e-10  1.4e-14  1.00e+00   -2.322327950e+01  -2.322327950e+01  5.6e-10  0.01  
Optimizer terminated. Time: 0.02    


Interior-point solution summary
  Problem status  : PRIMAL_AND_DUAL_FEASIBLE
  Solution status : OPTIMAL
  Primal.  obj: -2.3223279498e+01   nrm: 4e+01    Viol.  con: 2e-08    var: 2e-10    cones: 0e+00  
  Dual.    obj: -2.3223279498e+01   nrm: 5e-01    Viol.  con: 0e+00    var: 4e-10    cones: 0e+00  
Optimizer summary
  Optimizer                 -                        time: 0.02    
    Interior-point          - iterations : 8         time: 0.01    
      Basis identification  -                        time: 0.00    
        Primal              - iterations : 0         time: 0.00    
        Dual                - iterations : 0         time: 0.00    
        Clean primal        - iterations : 0         time: 0.00    
        Clean dual          - iterations : 0         time: 0.00    
    Simplex                 -                        time: 0.00    
      Primal simplex        - iterations : 0         time: 0.00    
      Dual simplex          - iterations : 0         time: 0.00    
    Mixed integer           - relaxations: 0         time: 0.00    

------------------------------------------------------------
Status: Solved
Optimal value (cvx_optval): +0.75017
 
Done! 
# using an equivalent formulation by replacing the diversification
  constraint by an equivalent set of linear constraints... 
Calling Mosek 9.1.9: 105 variables, 52 equality constraints
   For improved efficiency, Mosek is solving the dual problem.
------------------------------------------------------------

MOSEK Version 9.1.9 (Build date: 2019-11-21 11:32:15)
Copyright (c) MOSEK ApS, Denmark. WWW: mosek.com
Platform: MACOSX/64-X86

Problem
  Name                   :                 
  Objective sense        : min             
  Type                   : CONIC (conic optimization problem)
  Constraints            : 52              
  Cones                  : 1               
  Scalar variables       : 105             
  Matrix variables       : 0               
  Integer variables      : 0               

Optimizer started.
Presolve started.
Linear dependency checker started.
Linear dependency checker terminated.
Eliminator started.
Freed constraints in eliminator : 1
Eliminator terminated.
Eliminator - tries                  : 1                 time                   : 0.00            
Lin. dep.  - tries                  : 1                 time                   : 0.00            
Lin. dep.  - number                 : 0               
Presolve terminated. Time: 0.00    
Problem
  Name                   :                 
  Objective sense        : min             
  Type                   : CONIC (conic optimization problem)
  Constraints            : 52              
  Cones                  : 1               
  Scalar variables       : 105             
  Matrix variables       : 0               
  Integer variables      : 0               

Optimizer  - threads                : 8               
Optimizer  - solved problem         : the primal      
Optimizer  - Constraints            : 51
Optimizer  - Cones                  : 2
Optimizer  - Scalar variables       : 105               conic                  : 29              
Optimizer  - Semi-definite variables: 0                 scalarized             : 0               
Factor     - setup time             : 0.00              dense det. time        : 0.00            
Factor     - ML order time          : 0.00              GP order time          : 0.00            
Factor     - nonzeros before factor : 749               after factor           : 1109            
Factor     - dense dim.             : 0                 flops                  : 3.96e+04        
ITE PFEAS    DFEAS    GFEAS    PRSTATUS   POBJ              DOBJ              MU       TIME  
0   4.4e+01  1.0e+00  1.0e+00  0.00e+00   0.000000000e+00   0.000000000e+00   1.0e+00  0.00  
1   9.9e+00  2.3e-01  4.4e-01  -9.49e-01  4.991596544e+00   7.839295295e+00   2.3e-01  0.01  
2   4.6e+00  1.0e-01  8.7e-02  -1.87e-01  -8.043575265e+00  -7.681980818e+00  1.0e-01  0.01  
3   3.0e+00  6.8e-02  2.8e-02  3.75e+00   -1.946947865e+01  -1.939062664e+01  6.8e-02  0.01  
4   9.0e-01  2.1e-02  3.4e-03  2.08e+00   -2.237115464e+01  -2.236081483e+01  2.1e-02  0.01  
5   1.2e-01  2.7e-03  1.5e-04  1.31e+00   -2.311404058e+01  -2.311313702e+01  2.7e-03  0.01  
6   3.5e-03  8.0e-05  5.9e-07  1.06e+00   -2.322037638e+01  -2.322037590e+01  8.0e-05  0.01  
7   5.9e-05  1.3e-06  1.2e-09  1.01e+00   -2.322323127e+01  -2.322323136e+01  1.3e-06  0.01  
8   2.5e-08  5.6e-10  1.4e-14  1.00e+00   -2.322327950e+01  -2.322327950e+01  5.5e-10  0.01  
Optimizer terminated. Time: 0.02    


Interior-point solution summary
  Problem status  : PRIMAL_AND_DUAL_FEASIBLE
  Solution status : OPTIMAL
  Primal.  obj: -2.3223279498e+01   nrm: 4e+01    Viol.  con: 2e-08    var: 3e-10    cones: 0e+00  
  Dual.    obj: -2.3223279498e+01   nrm: 5e-01    Viol.  con: 0e+00    var: 4e-10    cones: 0e+00  
Optimizer summary
  Optimizer                 -                        time: 0.02    
    Interior-point          - iterations : 8         time: 0.01    
      Basis identification  -                        time: 0.00    
        Primal              - iterations : 0         time: 0.00    
        Dual                - iterations : 0         time: 0.00    
        Clean primal        - iterations : 0         time: 0.00    
        Clean dual          - iterations : 0         time: 0.00    
    Simplex                 -                        time: 0.00    
      Primal simplex        - iterations : 0         time: 0.00    
      Dual simplex          - iterations : 0         time: 0.00    
    Mixed integer           - relaxations: 0         time: 0.00    

------------------------------------------------------------
Status: Solved
Optimal value (cvx_optval): +0.75017
 
Done! 
------------------------------------------------------------------------
The optimal portfolios obtained from the original problem formulation and
from the equivalent formulation are respectively: 
   -0.0000   -0.0000
   -0.0000   -0.0000
    0.1342    0.1342
    0.0000    0.0000
    0.0000    0.0000
    0.1177    0.1177
    0.1134    0.1134
    0.0123    0.0123
    0.0904    0.0904
    0.0256    0.0256
    0.0451    0.0451
    0.0437    0.0437
   -0.0000   -0.0000
    0.1435    0.1435
   -0.0000   -0.0000
    0.0086    0.0086
    0.1177    0.1177
    0.0000    0.0000
    0.0000    0.0000
   -0.0000   -0.0000
   -0.0000   -0.0000
   -0.0000   -0.0000
    0.0313    0.0313
    0.1164    0.1164
   -0.0000   -0.0000

They are equal as expected!