% M-file (i.e. Matlab script) for gdxmrw_qp1 from GAMS datalib

% first define the data in Matlab, and make sure it has the expected
% form for this example of sending to GDX

slist = { 'hardware', 'software', 'show-biz', 't-bills' };
mean = [ 8.0 9.0 12.0 7.0 ]';
cov =  [    4         3         -1        0  ;
            3         6          1        0  ;
           -1         1         10        0  ;
            0         0          0        0  ];

[MM,N] = size(slist);
if MM ~= 1
   error('Securities list slist is bogus: MM ~= 1');
end
[MM,NN] = size(mean);
if NN ~= 1
   error('mean data is bogus: NN ~= 1');
end
if MM ~= N
   error('mean data is bogus: MM ~= N');
end
[MM,NN] = size(cov);
if MM ~= N
   error('cov data is bogus: NN ~= N');
end
if NN ~= N
   error('cov data is bogus: MM ~= N');
end

% The data looks good.  Write it to GDX now

fnameData = 'qp1data.gdx';
fnameResult = 'qp1frontier.gdx';

if exist(fnameData,'file')
  delete (fnameData);
end
if exist(fnameResult,'file')
  delete (fnameResult);
end
if exist(fnameData,'file')
  error([ 'File ', fnameData, ' still exists' ]);
end
if exist(fnameResult,'file')
  error([ 'File ', fnameResult, ' still exists' ]);
end

is = struct();
is.name = 'i';
is.type = 'set';
is.ts = 'securities for GDXMRW QP1 example';
is.uels{1} = slist;

ms = struct();
ms.name = 'mean';
ms.type = 'parameter';
ms.ts = 'mean annual return on QP1 securities (%)';
ms.form = 'full';  % the default, but we include it anyway
ms.uels = is.uels;
ms.val = mean;

cs = struct();
cs.name = 'cov';
cs.type = 'parameter';
cs.ts = 'variance-covariance array (%-squared annual return) for QP1 securities';
cs.form = 'full';  % the default, but we include it anyway
cs.uels{1} = slist;
cs.uels{2} = slist;
cs.val = cov;

wgdx(fnameData,is,ms,cs);

if ~ exist(fnameData,'file')
   error([ 'File ', fnameData, ' does not exist' ]);
end

% run GAMS to do the analysis
flag = system (['gams gdxmrw_qp1 lo=2 --INFILE=', fnameData, ...
                ' --OUTFILE=', fnameResult ]);
if flag ~= 0
  error('gams run failed: rc = %d', flag);
end
if ~ exist(fnameResult,'file')
   error([ 'Results file ', fnameResult, ' does not exist after gams run' ]);
end

% visualize the results

% we want to read the domain t (target mean) and minimum variance v
% using a filtered read, so they have the same size, regardless of the
% universe in the GDX or zeros in the data

rs.name = 's';
rs.compress = 'true';
s = rgdx(fnameResult,rs);

rt.name = 't';
rt.form = 'full';
rt.uels{1} = s.uels{1};
t = rgdx(fnameResult,rt);

rv = rt;
rv.name = 'v';
v = rgdx(fnameResult,rv);

figure(1);
plot (t.val,v.val);
title('efficient frontier for QP1 example');
xlabel('mean return');
ylabel('variance');
