Home > matpower7.1 > mp-opt-model > lib > @opt_model > parse_soln.m

parse_soln

PURPOSE ^

PARSE_SOLN Parse solution vector and shadow prices by all named sets.

SYNOPSIS ^

function ps = parse_soln(om)

DESCRIPTION ^

PARSE_SOLN  Parse solution vector and shadow prices by all named sets.
   PS = OM.PARSE_SOLN()

   For a solved model, OM.PARSE_SOLN() returns a struct of parsed
   solution vector and shadow price values for each named set of
   variables and constraints. The returned PS (parsed solution) struct
   has the following format, where each of the terminal elements is a
   struct with fields corresponding to the respective named sets:

   Output:
       PS
           .var
               .val
               .mu_l
               .mu_u
           .lin
               .mu_l
               .mu_u
           .nle
               .lam
           .nli
               .mu

   The value of each element in the returned struct can be obtained
   via the GET_SOLN method as well, but using PARSE_SOLN is generally
   more efficient if a complete set of values is needed.

   See also GET_SOLN

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function ps = parse_soln(om)
0002 %PARSE_SOLN  Parse solution vector and shadow prices by all named sets.
0003 %   PS = OM.PARSE_SOLN()
0004 %
0005 %   For a solved model, OM.PARSE_SOLN() returns a struct of parsed
0006 %   solution vector and shadow price values for each named set of
0007 %   variables and constraints. The returned PS (parsed solution) struct
0008 %   has the following format, where each of the terminal elements is a
0009 %   struct with fields corresponding to the respective named sets:
0010 %
0011 %   Output:
0012 %       PS
0013 %           .var
0014 %               .val
0015 %               .mu_l
0016 %               .mu_u
0017 %           .lin
0018 %               .mu_l
0019 %               .mu_u
0020 %           .nle
0021 %               .lam
0022 %           .nli
0023 %               .mu
0024 %
0025 %   The value of each element in the returned struct can be obtained
0026 %   via the GET_SOLN method as well, but using PARSE_SOLN is generally
0027 %   more efficient if a complete set of values is needed.
0028 %
0029 %   See also GET_SOLN
0030 
0031 %   MP-Opt-Model
0032 %   Copyright (c) 2020, Power Systems Engineering Research Center (PSERC)
0033 %   by Ray Zimmerman, PSERC Cornell
0034 %
0035 %   This file is part of MP-Opt-Model.
0036 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0037 %   See https://github.com/MATPOWER/mp-opt-model for more info.
0038 
0039 %% calls to substruct() are relatively expensive, so we pre-build the
0040 %% structs for addressing cell and numeric array fields, updating only
0041 %% the subscripts before use
0042 sc = struct('type', {'.', '{}'}, 'subs', {'', 1});  %% cell array field
0043 sn = sc; sn(2).type = '()';                         %% num array field
0044 
0045 ps = struct('var', []);     %% parsed solution
0046 s = om.soln;                %% aggregate solution
0047 
0048 %% var
0049 params = struct('src', s.x, 'dst', 'val');
0050 if isfield(s.lambda, 'lower')
0051     params(end+1).src = s.lambda.lower;
0052     params(end  ).dst = 'mu_l';
0053 end
0054 if isfield(s.lambda, 'upper')
0055     params(end+1).src = s.lambda.upper;
0056     params(end  ).dst = 'mu_u';
0057 end
0058 ps.var = parse_soln_fields(om, 'var', params, sn, sc);
0059 
0060 %% lin
0061 if om.getN('lin')
0062     if isfield(s.lambda, 'mu_l')
0063         if isfield(s.lambda, 'mu_u')
0064             params = struct('src', {s.lambda.mu_l, s.lambda.mu_u}, ...
0065                             'dst', {'mu_l', 'mu_u'});
0066         else
0067             params = struct('src', s.lambda.mu_l, 'dst', 'mu_l');
0068         end
0069     else
0070         if isfield(s.lambda, 'mu_u')
0071             params = struct('src', s.lambda.mu_u, 'dst', 'mu_u');
0072         else
0073             params = [];
0074         end
0075     end
0076     if ~isempty(params)
0077         ps.lin = parse_soln_fields(om, 'lin', params, sn, sc);
0078     end
0079 end
0080 
0081 %% nle
0082 if om.getN('nle') && isfield(s.lambda, 'eqnonlin')
0083     params = struct('src', s.lambda.eqnonlin, ...
0084                     'dst',     'lam'  );
0085     ps.nle = parse_soln_fields(om, 'nle', params, sn, sc);
0086 end
0087 
0088 %% nli
0089 if om.getN('nli') && isfield(s.lambda, 'ineqnonlin')
0090     params = struct('src', s.lambda.ineqnonlin, ...
0091                     'dst',      'mu' );
0092     ps.nli = parse_soln_fields(om, 'nli', params, sn, sc);
0093 end
0094 
0095 
0096 
0097 
0098 function psf = parse_soln_fields(om, ff, params, sn, sc)
0099 om_ff = om.(ff);
0100 psf = struct();     %% parsed solution field
0101 
0102 np = length(params);
0103 have_param = zeros(np, 1);
0104 for j = 1:np
0105     have_param(j) = ~isempty(params(j).src);
0106 end
0107 for k = 1:om_ff.NS
0108     name = om_ff.order(k).name;
0109     idx = om_ff.order(k).idx;
0110     if isempty(idx)
0111         N = om_ff.idx.N.(name);
0112     else
0113         sn(1).subs = name;
0114         sn(2).subs = idx;
0115         N = subsref(om_ff.idx.N, sn);
0116         need_init = all([idx{:}] == 1);
0117     end
0118     if N
0119         for j = 1:np
0120             if have_param(j)    %% parameter is available
0121                 dname = params(j).dst;  %% destination field name
0122                 if isempty(idx)
0123                     i1 = om_ff.idx.i1.(name);
0124                     iN = om_ff.idx.iN.(name);
0125                     psf.(dname).(name)  = params(j).src(i1:iN);
0126                 else
0127                     if need_init
0128                         switch ff
0129                             case 'var'
0130                                 psf.(dname).(name) = cell(size(om_ff.data.v0.(name)));
0131                             case 'lin'
0132                                 psf.(dname).(name) = cell(size(om_ff.data.A.(name)));
0133                             case 'qdc'
0134                                 psf.(dname).(name) = cell(size(om_ff.data.c.(name)));
0135                             otherwise
0136                                 psf.(dname).(name) = cell(size(om_ff.data.fcn.(name)));
0137                         end
0138                     end
0139                     i1 = subsref(om_ff.idx.i1, sn);    %% starting row index
0140                     iN = subsref(om_ff.idx.iN, sn);    %% ending row index
0141                     sc(1).subs = name;
0142                     sc(2).subs = idx;
0143                     psf.(dname) = ...
0144                         subsasgn(psf.(dname), sc, params(j).src(i1:iN));
0145                 end
0146             end
0147         end     %% for j
0148     end
0149 end     %% for k

Generated on Fri 09-Oct-2020 11:21:31 by m2html © 2005