Home > matpower7.0 > lib > have_fcn.m

have_fcn

PURPOSE ^

HAVE_FCN Test for optional functionality / version info.

SYNOPSIS ^

function rv = have_fcn(tag, rtype)

DESCRIPTION ^

HAVE_FCN  Test for optional functionality / version info.
   TORF = HAVE_FCN(TAG)
   TORF = HAVE_FCN(TAG, TOGGLE)
   VER_STR = HAVE_FCN(TAG, 'vstr')
   VER_NUM = HAVE_FCN(TAG, 'vnum')
   DATE    = HAVE_FCN(TAG, 'date')
   INFO    = HAVE_FCN(TAG, 'all')
   HAVE_FCN(TAG, 'clear_cache')
   HAVE_FCN('all', 'clear_cache')

   Returns availability, version and release information for optional
   MATPOWER functionality. All information is cached, and the cached values
   returned on subsequent calls. If the functionality exists, an attempt is
   made to determine the release date and version number. The second
   argument defines which value is returned, as follows:
       <none>      1 = optional functionality is available, 0 = not available
       'vstr'      version number as a string (e.g. '3.11.4')
       'vnum'      version number as numeric value (e.g. 3.011004)
       'date'      release date as a string (e.g. '20-Jan-2015')
       'all'       struct with fields named 'av' (for 'availability'), 'vstr',
                   'vnum' and 'date', and values corresponding to the above,
                   respectively.

   For functionality that is not available, all calls with a string-valued
   second argument will return an empty value.

   Alternatively, the optional functionality specified by TAG can be toggled
   OFF or ON by calling HAVE_FCN with a numeric second argument TOGGLE with
   one of the following values:
       0 - turn OFF the optional functionality
       1 - turn ON the optional functionality (if available)
      -1 - toggle the ON/OFF state of the optional functionality

   Finally, passing 'clear_cache' as the second argument will cause the
   cached information to be cleared for the specified TAG or, if the first
   argument is 'all', for all optional functionality. When calling with
   'clear_cache' no return value is defined.

   Possible values for input TAG and their meanings:
       bpmpd       - BP, BPMPD interior point solver
       clp         - CLP, LP/QP solver(https://github.com/coin-or/Clp)
        opti_clp   -   version of CLP distributed with OPTI Toolbox
                       (https://www.inverseproblem.co.nz/OPTI/)
       cplex       - CPLEX, IBM ILOG CPLEX Optimizer
       e4st        - E4ST (https://e4st.com/)
       fmincon     - FMINCON, solver from Optimization Toolbox 2.x +
       fmincon_ipm - FMINCON with Interior Point solver, from Opt Tbx 4.x +
       glpk        - GLPK, GNU Linear Programming Kit
       gurobi      - GUROBI, Gurobi solver (https://www.gurobi.com/), 5.x +
       intlinprog  - INTLINPROG, MILP solver from Optimization
                     Toolbox 7.0 (R2014a)+
       ipopt       - IPOPT, NLP solver
                       (https://github.com/coin-or/Ipopt)
       linprog     - LINPROG, LP solver from Optimization Toolbox 2.x +
       linprog_ds  - LINPROG with dual-simplex solver
                       from Optimization Toolbox 7.1 (R2014b) +
       knitro      - Artelys Knitro, NLP solver
                     (https://www.artelys.com/solvers/knitro/)
         knitromatlab - Artelys Knitro, version 9.0.0+
         ktrlink      - KNITRO, version < 9.0.0 (requires Opt Tbx)
       matlab      - code is running under MATLAB, as opposed to Octave
       minopf      - MINOPF, MINOPF, MINOS-based OPF solver
       most        - MOST, MATPOWER Optimal Scheduling Tool
       mosek       - MOSEK, LP/QP solver (https://www.mosek.com/)
       optimoptions - OPTIMOPTIONS, option setting funciton for Optim Tbx 6.3+
       pardiso     - PARDISO, Parallel Sparse Direct & Iterative Linear Solver
                       (https://pardiso-project.org)
       quadprog    - QUADPROG, QP solver from Optimization Toolbox 2.x +
       quadprog_ls - QUADPROG with large-scale interior point convex solver
                       from Optimization Toolbox 6.x +
       pdipmopf    - PDIPMOPF, primal-dual interior point method OPF solver
       scpdipmopf  - SCPDIPMOPF, step-controlled PDIPM OPF solver
       smartmarket - RUNMARKET and friends, for running an auction
       syngrid     - SynGrid, Synthetic Grid Creation for MATPOWER
       tralmopf    - TRALMOPF, trust region based augmented Langrangian
                     OPF solver
       octave      - code is running under Octave, as opposed to MATLAB
       sdp_pf      - SDP_PF applications of semi-definite programming
                     relaxation of power flow equations
       yalmip      - YALMIP SDP modeling platform
       sedumi      - SeDuMi SDP solver
       sdpt3       - SDPT3 SDP solver

   Examples:
       if have_fcn('minopf')
           results = runopf(mpc, mpoption('opf.ac.solver', 'MINOPF'));
       end

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function rv = have_fcn(tag, rtype)
0002 %HAVE_FCN  Test for optional functionality / version info.
0003 %   TORF = HAVE_FCN(TAG)
0004 %   TORF = HAVE_FCN(TAG, TOGGLE)
0005 %   VER_STR = HAVE_FCN(TAG, 'vstr')
0006 %   VER_NUM = HAVE_FCN(TAG, 'vnum')
0007 %   DATE    = HAVE_FCN(TAG, 'date')
0008 %   INFO    = HAVE_FCN(TAG, 'all')
0009 %   HAVE_FCN(TAG, 'clear_cache')
0010 %   HAVE_FCN('all', 'clear_cache')
0011 %
0012 %   Returns availability, version and release information for optional
0013 %   MATPOWER functionality. All information is cached, and the cached values
0014 %   returned on subsequent calls. If the functionality exists, an attempt is
0015 %   made to determine the release date and version number. The second
0016 %   argument defines which value is returned, as follows:
0017 %       <none>      1 = optional functionality is available, 0 = not available
0018 %       'vstr'      version number as a string (e.g. '3.11.4')
0019 %       'vnum'      version number as numeric value (e.g. 3.011004)
0020 %       'date'      release date as a string (e.g. '20-Jan-2015')
0021 %       'all'       struct with fields named 'av' (for 'availability'), 'vstr',
0022 %                   'vnum' and 'date', and values corresponding to the above,
0023 %                   respectively.
0024 %
0025 %   For functionality that is not available, all calls with a string-valued
0026 %   second argument will return an empty value.
0027 %
0028 %   Alternatively, the optional functionality specified by TAG can be toggled
0029 %   OFF or ON by calling HAVE_FCN with a numeric second argument TOGGLE with
0030 %   one of the following values:
0031 %       0 - turn OFF the optional functionality
0032 %       1 - turn ON the optional functionality (if available)
0033 %      -1 - toggle the ON/OFF state of the optional functionality
0034 %
0035 %   Finally, passing 'clear_cache' as the second argument will cause the
0036 %   cached information to be cleared for the specified TAG or, if the first
0037 %   argument is 'all', for all optional functionality. When calling with
0038 %   'clear_cache' no return value is defined.
0039 %
0040 %   Possible values for input TAG and their meanings:
0041 %       bpmpd       - BP, BPMPD interior point solver
0042 %       clp         - CLP, LP/QP solver(https://github.com/coin-or/Clp)
0043 %        opti_clp   -   version of CLP distributed with OPTI Toolbox
0044 %                       (https://www.inverseproblem.co.nz/OPTI/)
0045 %       cplex       - CPLEX, IBM ILOG CPLEX Optimizer
0046 %       e4st        - E4ST (https://e4st.com/)
0047 %       fmincon     - FMINCON, solver from Optimization Toolbox 2.x +
0048 %       fmincon_ipm - FMINCON with Interior Point solver, from Opt Tbx 4.x +
0049 %       glpk        - GLPK, GNU Linear Programming Kit
0050 %       gurobi      - GUROBI, Gurobi solver (https://www.gurobi.com/), 5.x +
0051 %       intlinprog  - INTLINPROG, MILP solver from Optimization
0052 %                     Toolbox 7.0 (R2014a)+
0053 %       ipopt       - IPOPT, NLP solver
0054 %                       (https://github.com/coin-or/Ipopt)
0055 %       linprog     - LINPROG, LP solver from Optimization Toolbox 2.x +
0056 %       linprog_ds  - LINPROG with dual-simplex solver
0057 %                       from Optimization Toolbox 7.1 (R2014b) +
0058 %       knitro      - Artelys Knitro, NLP solver
0059 %                     (https://www.artelys.com/solvers/knitro/)
0060 %         knitromatlab - Artelys Knitro, version 9.0.0+
0061 %         ktrlink      - KNITRO, version < 9.0.0 (requires Opt Tbx)
0062 %       matlab      - code is running under MATLAB, as opposed to Octave
0063 %       minopf      - MINOPF, MINOPF, MINOS-based OPF solver
0064 %       most        - MOST, MATPOWER Optimal Scheduling Tool
0065 %       mosek       - MOSEK, LP/QP solver (https://www.mosek.com/)
0066 %       optimoptions - OPTIMOPTIONS, option setting funciton for Optim Tbx 6.3+
0067 %       pardiso     - PARDISO, Parallel Sparse Direct & Iterative Linear Solver
0068 %                       (https://pardiso-project.org)
0069 %       quadprog    - QUADPROG, QP solver from Optimization Toolbox 2.x +
0070 %       quadprog_ls - QUADPROG with large-scale interior point convex solver
0071 %                       from Optimization Toolbox 6.x +
0072 %       pdipmopf    - PDIPMOPF, primal-dual interior point method OPF solver
0073 %       scpdipmopf  - SCPDIPMOPF, step-controlled PDIPM OPF solver
0074 %       smartmarket - RUNMARKET and friends, for running an auction
0075 %       syngrid     - SynGrid, Synthetic Grid Creation for MATPOWER
0076 %       tralmopf    - TRALMOPF, trust region based augmented Langrangian
0077 %                     OPF solver
0078 %       octave      - code is running under Octave, as opposed to MATLAB
0079 %       sdp_pf      - SDP_PF applications of semi-definite programming
0080 %                     relaxation of power flow equations
0081 %       yalmip      - YALMIP SDP modeling platform
0082 %       sedumi      - SeDuMi SDP solver
0083 %       sdpt3       - SDPT3 SDP solver
0084 %
0085 %   Examples:
0086 %       if have_fcn('minopf')
0087 %           results = runopf(mpc, mpoption('opf.ac.solver', 'MINOPF'));
0088 %       end
0089 
0090 %   Private tags for internal use only:
0091 %       catchme         - support for 'catch me' syntax in try/catch constructs
0092 %       evalc           - support for evalc() function
0093 %       ipopt_auxdata   - support for ipopt_auxdata(), required by 3.11 and later
0094 %       lu_vec          - support for lu(..., 'vector') syntax
0095 %       pardiso_legacy  - PARDISO v5, individual MEX files for factor, solve, etc
0096 %       pardiso_object  - PARDISO v6 and later, object interface
0097 %       regexp_split    - support for 'split' argument to regexp()
0098 %       rithmaticker    - used for testing HAVE_FCN
0099 %
0100 %   The following calling syntaxes are also implemented to set and get the
0101 %   entire cache struct and are used during testing only.
0102 %       CACHE = HAVE_FCN('all', 'get_cache')
0103 %       HAVE_FCN(CACHE, 'set_cache')
0104 
0105 %   MATPOWER
0106 %   Copyright (c) 2004-2019, Power Systems Engineering Research Center (PSERC)
0107 %   by Ray Zimmerman, PSERC Cornell
0108 %
0109 %   This file is part of MATPOWER.
0110 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0111 %   See https://matpower.org for more info.
0112 
0113 persistent fcns;
0114 
0115 action = 'D';                   %% detecting functionality (default)
0116 if nargin > 1
0117     if isnumeric(rtype)
0118         action = 'T';           %% toggling functionality
0119         on_off = rtype;
0120         if on_off < 0                   %% flip the toggle
0121             TorF = have_fcn(tag);
0122             on_off = ~TorF;
0123         end
0124     else
0125         switch lower(rtype)
0126             case 'get_cache'
0127                 action = 'C';   %% getting cache
0128                 rv = fcns;
0129             case 'set_cache'
0130                 action = 'C';   %% setting cache
0131                 fcns = tag;
0132             case 'clear_cache'
0133                 action = 'C';   %% clearing cache
0134                 if strcmpi(tag, 'all')
0135                     fcns = struct();            %% delete all fields
0136                 else
0137                     fcns = rmfield(fcns, tag);  %% delete field to force re-check
0138                 end
0139         end
0140     end
0141 end
0142 
0143 if action == 'T'            %% change availability
0144     if on_off                   %% turn on if available
0145         fcns = rmfield(fcns, tag);  %% delete field to force re-check
0146     else                        %% turn off
0147         if ~isfield(fcns, tag)      %% not yet been checked
0148             TorF = have_fcn(tag);   %% cache result first
0149         end
0150         fcns.(tag).av = 0;          %% then turn off
0151     end
0152     TorF = have_fcn(tag);           %% return availability
0153                                     %% (recheck if ON, cached 0 if OFF)
0154 elseif action == 'D'        %% detect availability
0155     %% info not yet cached?
0156     if ~isfield(fcns, tag)
0157         %%-----  determine installation status, version number, etc.  -----
0158         %% initialize default values
0159         TorF = 0;
0160         vstr = '';
0161         rdate = '';
0162 
0163         switch tag
0164             %%-----  public tags  -----
0165             case 'bpmpd'
0166                 TorF = exist('bp', 'file') == 3;
0167                 if TorF
0168                     v = bpver('all');
0169                     vstr = v.Version;
0170                     rdate = v.Date;
0171                 end
0172             case 'clp'
0173                 tmp = have_fcn('opti_clp', 'all');
0174                 if tmp.av   %% have opti_clp
0175                     TorF = tmp.av;
0176                     vstr = tmp.vstr;
0177                     rdate = tmp.date;
0178                 elseif exist('clp','file') == 2 && exist('mexclp','file') == 3
0179                     TorF = 1;
0180                     vstr = '';
0181                 end
0182             case 'opti_clp'
0183                 TorF = exist('opti_clp', 'file') == 2 && exist('clp', 'file') == 3;
0184                 if TorF
0185                     str = evalc('clp');
0186                     pat = 'CLP: COIN-OR Linear Programming \[v([^\s,]+), Built ([^\],])+(,[^\]]*)*\]';  %% OPTI, Giorgetti/Currie
0187                     [s,e,tE,m,t] = regexp(str, pat);
0188                     if ~isempty(t)
0189                         vstr = t{1}{1};
0190                         rdate = datestr(t{1}{2}, 'dd-mmm-yyyy');
0191                     end
0192                 end
0193             case 'cplex'
0194                 if exist('cplexqp', 'file')
0195                     %% it's installed, but we need to check for MEX for this arch
0196                     p = which('cplexqp');   %% get the path
0197                     len = length(p) - length('cplexqp.p');
0198                     w = what(p(1:len));             %% look for mex files on the path
0199                     for k = 1:length(w.mex)
0200                         if regexp(w.mex{k}, 'cplexlink[^\.]*');
0201                             TorF = 1;
0202                             break;
0203                         end
0204                     end
0205                 end
0206                 if TorF
0207                     try
0208                         cplex = Cplex('null');
0209                         vstr = cplex.getVersion;
0210                     catch
0211                         TorF = 0;
0212                     end
0213                 end
0214             case 'e4st'
0215                 TorF = exist('e4st_ver', 'file') == 2;
0216                 if TorF
0217                     v = e4st_ver('all');
0218                     vstr = v.Version;
0219                     rdate = v.Date;
0220                 end
0221             case {'fmincon', 'fmincon_ipm', 'intlinprog', 'linprog', ...
0222                         'linprog_ds', 'optimoptions', 'quadprog', 'quadprog_ls'}
0223                 matlab = have_fcn('matlab');
0224                 if ~matlab || (matlab && license('test', 'optimization_toolbox'))
0225                     v = ver('optim');
0226                     if length(v) > 1
0227                         warning('The built-in VER command is behaving strangely, probably as a result of installing a 3rd party toolbox in a directory named ''optim'' on your path. Check each element of the output of ver(''optim'') to find the offending toolbox, then move the toolbox to a more appropriately named directory.');
0228                         v = v(1);
0229                     end
0230                     if isempty(v) || isempty(v.Version)
0231                         vstr = '';      %% make sure it's a string
0232                         rdate = [];
0233                     else
0234                         vstr = v.Version;
0235                         rdate = v.Date;
0236                     end
0237                     otver = vstr2num(vstr);
0238                     switch tag
0239                         case 'fmincon'
0240                             TorF = (exist('fmincon', 'file') == 2 || ...
0241                                 exist('fmincon', 'file') == 6) & matlab;
0242                         case 'intlinprog'
0243                             TorF = exist('intlinprog', 'file') == 2 & matlab;
0244                         case 'linprog'
0245                             TorF = exist('linprog', 'file') == 2 & matlab;  %% don't try to use Octave linprog
0246                         case 'quadprog'
0247                             TorF = exist('quadprog', 'file') == 2;
0248                             %% Octave optim 1.5.0 and earlier, had problems with
0249                             %% incorrect lambdas, including opposite sign
0250                             %% convention for equality multipliers
0251                             if ~matlab && otver <= 1.005
0252                                 TorF = 0;
0253                             end
0254                         otherwise
0255                             if matlab
0256                                 switch tag
0257                                     case 'fmincon_ipm'
0258                                         if otver >= 4       %% Opt Tbx 4.0+ (R208a+, MATLAB 7.6+)
0259                                             TorF = 1;
0260                                         end
0261                                     case 'linprog_ds'
0262                                         if otver >= 7.001   %% Opt Tbx 7.1+ (R2014b+, MATLAB 8.4+)
0263                                             TorF = 1;
0264                                         end
0265                                     case 'optimoptions'
0266                                         if otver >= 6.003   %% Opt Tbx 6.3+ (R2013a+, MATLAB 8.1+)
0267                                             TorF = 1;
0268                                         end
0269                                     case 'quadprog_ls'
0270                                         if otver >= 6       %% Opt Tbx 6.0+ (R2011a+, MATLAB 7.12+)
0271                                             TorF = 1;
0272                                         end
0273                                 end
0274                             else    %% octave
0275                                 TorF = 0;
0276                             end
0277                     end
0278                 end
0279             case 'glpk'
0280                 if exist('glpk','file') == 3    %% Windows OPTI install (no glpk.m)
0281                     TorF = 1;
0282                     str = evalc('glpk');
0283                     pat = 'GLPK: GNU Linear Programming Kit \[v([^\s,\]]+).*\]';  %% OPTI, Giorgetti/Currie
0284                     [s,e,tE,m,t] = regexp(str, pat);
0285                     if ~isempty(t)
0286                         vstr = t{1}{1};
0287                     end
0288                     pat = 'Built ([^\],])+';  %% OPTI, Giorgetti/Currie
0289                     [s,e,tE,m,t] = regexp(str, pat);
0290                     if ~isempty(t)
0291                         rdate = datestr(t{1}{1}, 'dd-mmm-yyyy');
0292                     end
0293                 elseif exist('glpk','file') == 2    %% others have glpk.m and ...
0294                     if exist('__glpk__','file') == 3    %% octave __glpk__ MEX
0295                         TorF = 1;
0296                         if have_fcn('evalc')
0297                             str = evalc('glpk(1, 1, 1, 1, 1, ''U'', ''C'', -1, struct(''msglev'', 3))');
0298                             pat = 'GLPK Simplex Optimizer, v([^\s,]+)';
0299                             [s,e,tE,m,t] = regexp(str, pat);
0300                             if ~isempty(t)
0301                                 vstr = t{1}{1};
0302                             end
0303                         end
0304                     elseif exist('glpkcc','file') == 3  %% MATLAB glpkcc MEX
0305                         TorF = 1;
0306                         str = evalc('glpk');
0307                         pat = 'GLPK Matlab interface\. Version: ([^\s,]+)';     %% glpkccm, Giorgetti/Klitgord
0308                         [s,e,tE,m,t] = regexp(str, pat);
0309                         if ~isempty(t)
0310                             vstr = t{1}{1};
0311                         end
0312                     end
0313                 end
0314             case 'gurobi'
0315                 TorF = exist('gurobi', 'file') == 3;
0316                 if TorF
0317                     try
0318                         model = struct( ...
0319                             'A', sparse(1), ...
0320                             'rhs', 1, ...
0321                             'sense', '=', ...
0322                             'vtype', 'C', ...
0323                             'obj', 1, ...
0324                             'modelsense', 'min' ...
0325                         );
0326                         params = struct( ...
0327                             'outputflag', 0 ...
0328                         );
0329                         result = gurobi(model, params);
0330                         vstr = sprintf('%d.%d.%d', result.versioninfo.major, result.versioninfo.minor, result.versioninfo.technical);
0331                     catch % gurobiError
0332                         TorF = 0;
0333                         fprintf('Gurobi Error!\n');
0334 %                         disp(gurobiError.message);
0335                     end
0336                 end
0337             case 'ipopt'
0338                 TorF = exist('ipopt', 'file') == 3;
0339                 if TorF
0340                     if have_fcn('evalc')
0341                         str = evalc('qps_ipopt([],[1; 1],[1 1],[2],[2],[1; 1],[1; 1],[1; 1],struct(''verbose'', 2))');
0342                         pat = 'Ipopt version ([^\s,]+)';
0343                         [s,e,tE,m,t] = regexp(str, pat);
0344                         if ~isempty(t)
0345                             vstr = t{1}{1};
0346                             if vstr2num(vstr) >= 3.011 && ...
0347                                     ~exist('ipopt_auxdata', 'file')
0348                                 TorF = 0;
0349                                 warning('Improper installation of IPOPT. Version %s detected, but IPOPT_AUXDATA.M is missing.', vstr);
0350                             end
0351                         end
0352                     else
0353                         try
0354 %                             x = feval('qps_ipopt', [],[1; 1],[1 1],[2],[2],[1; 1],[1; 1],[1; 1],struct('verbose', 2));
0355                             x = feval('qps_ipopt', [],[1; 1],[1 1],[2],[2],[1; 1],[1; 1],[1; 1],struct('verbose', 0));
0356                             if ~isequal(x, [1;1])
0357                                 TorF = 0;
0358                             end
0359                         catch
0360                             TorF = 0;
0361                         end
0362                     end
0363                 end
0364             case 'knitro'       %% any Knitro
0365                 tmp = have_fcn('knitromatlab', 'all');
0366                 if tmp.av
0367                     TorF = tmp.av;
0368                     vstr = tmp.vstr;
0369                     rdate = tmp.date;
0370                 else
0371                     tmp = have_fcn('ktrlink', 'all');
0372                     if tmp.av
0373                         TorF = tmp.av;
0374                         vstr = tmp.vstr;
0375                         rdate = tmp.date;
0376                     end
0377                 end
0378             case {'knitromatlab', 'ktrlink'}
0379                 %% knitromatlab for Knitro 9.0 or greater
0380                 %% ktrlink for pre-Knitro 9.0, requires Optim Toolbox
0381                 TorF = exist(tag, 'file') == 2;
0382                 if TorF
0383                     try
0384                         str = evalc(['[x fval] = ' tag '(@(x)1,1);']);
0385                     end
0386                     TorF = exist('fval', 'var') && fval == 1;
0387                     if TorF
0388                         pat = 'KNITRO ([^\s]+)\n|Knitro ([^\s]+)\n';
0389                         [s,e,tE,m,t] = regexp(str, pat);
0390                         if ~isempty(t)
0391                             vstr = t{1}{1};
0392                         end
0393                     end
0394                 end
0395             case 'matlab'
0396                 v = ver('matlab');
0397                 if length(v) > 1
0398                     warning('The built-in VER command is behaving strangely, probably as a result of installing a 3rd party toolbox in a directory named ''matlab'' on your path. Check each element of the output of ver(''matlab'') to find the offending toolbox, then move the toolbox to a more appropriately named directory.');
0399                     v = v(1);
0400                 end
0401                 if ~isempty(v) && isfield(v, 'Version') && ~isempty(v.Version)
0402                     TorF = 1;
0403                     vstr = v.Version;
0404                     rdate = v.Date;
0405                 end
0406             case 'minopf'
0407                 TorF = exist('minopf', 'file') == 3;
0408                 if TorF
0409                     v = minopfver('all');
0410                     vstr = v.Version;
0411                     rdate = v.Date;
0412                 end
0413             case 'most'
0414                 TorF = exist('most', 'file') == 2;
0415                 if TorF
0416                     v = mostver('all');
0417                     vstr = v.Version;
0418                     rdate = v.Date;
0419                 end
0420             case 'mosek'
0421                 TorF = exist('mosekopt', 'file') == 3;
0422                 if TorF
0423                     % MOSEK Version 6.0.0.93 (Build date: 2010-10-26 13:03:27)
0424                     % MOSEK Version 6.0.0.106 (Build date: 2011-3-17 10:46:54)
0425                     % MOSEK Version 7.0.0.134 (Build date: 2014-10-2 11:10:02)
0426                     pat = 'Version (\.*\d)+.*Build date: (\d+-\d+-\d+)';
0427                     [s,e,tE,m,t] = regexp(evalc('mosekopt'), pat);
0428                     if isempty(t)
0429                         [r, res] = mosekopt('version');
0430                         v = res.version;
0431                         vstr = sprintf('%d.%d.%d.%d', ...
0432                             v.major, v.minor, v.build, v.revision);
0433                     else
0434                         vstr = t{1}{1};
0435                         rdate = datestr(t{1}{2}, 'dd-mmm-yyyy');
0436                     end
0437                 end
0438             case 'smartmarket'
0439                 TorF = exist('runmarket', 'file') == 2;
0440                 if TorF
0441                     v = mpver('all');
0442                     vstr = v.Version;
0443                     rdate = v.Date;
0444                 end
0445             case 'syngrid'
0446                 TorF = exist('syngrid', 'file') == 2;
0447                 if TorF
0448                     v = sgver('all');
0449                     vstr = v.Version;
0450                     rdate = v.Date;
0451                 end
0452             case 'octave'
0453                 TorF = exist('OCTAVE_VERSION', 'builtin') == 5;
0454                 if TorF
0455                     v = ver('octave');
0456                     vstr = v.Version;
0457                     rdate = v.Date;
0458                 end
0459             case 'pardiso'
0460                 TorF = have_fcn('pardiso_object') || have_fcn('pardiso_legacy');
0461             case {'pdipmopf', 'scpdipmopf', 'tralmopf'}
0462                 if have_fcn('matlab')
0463                     vn = have_fcn('matlab', 'vnum');
0464                     %% requires >= MATLAB 6.5 (R13) (released 20-Jun-2002)
0465                     %% older versions do not have mxCreateDoubleScalar() function
0466                     %% (they have mxCreateScalarDouble() instead)
0467                     if vn >= 6.005
0468                         switch tag
0469                             case 'pdipmopf'
0470                                 TorF = exist('pdipmopf', 'file') == 3;
0471                             case 'scpdipmopf'
0472                                 TorF = exist('scpdipmopf', 'file') == 3;
0473                             case 'tralmopf'
0474                                 %% requires >= MATLAB 7.3 (R2006b) (released 03-Aug-2006)
0475                                 %% older versions do not include the needed form of chol()
0476                                 if vn >= 7.003
0477                                     TorF = exist('tralmopf', 'file') == 3;
0478                                 end
0479                         end
0480                     end
0481                     if TorF
0482                         v = feval([tag 'ver'], 'all');
0483                         vstr = v.Version;
0484                         rdate = v.Date;
0485                     end
0486                 end
0487             case 'sdp_pf'
0488                 TorF = have_fcn('yalmip') && exist('mpoption_info_sdp_pf', 'file') == 2;
0489                 if TorF
0490                     v = sdp_pf_ver('all');
0491                     vstr = v.Version;
0492                     rdate = v.Date;
0493                 end
0494             case 'yalmip'
0495                 TorF = exist('yalmip','file') == 2;
0496                 if TorF
0497                     vstr = yalmip('version');
0498                     if length(vstr) == 8
0499                         yr = str2num(vstr(1:4));
0500                         mo = str2num(vstr(5:6));
0501                         dy = str2num(vstr(7:8));
0502                         rdate = datestr([yr mo dy 0 0 0], 'dd-mmm-yyyy');
0503                     end
0504                 end
0505             case 'sdpt3'
0506                 TorF = exist('sdpt3','file') == 2;
0507                 if TorF && have_fcn('evalc')
0508                     str = evalc('help sdpt3');
0509                     pat = 'version\s+([^\s]+).*Last Modified: ([^\n]+)\n';
0510                     [s,e,tE,m,t] = regexp(str, pat);
0511                     if ~isempty(t)
0512                         vstr = t{1}{1};
0513                         rdate = datestr(t{1}{2}, 'dd-mmm-yyyy');
0514                     end
0515                 end
0516             case 'sedumi'
0517                 TorF = exist('sedumi','file') == 2;
0518                 if TorF && have_fcn('evalc')
0519                     warn_state = warning;  %% sedumi turns (and leaves!) off all warnings
0520                     str = evalc('x = sedumi([1 1], 1, [1;2])');
0521                     warning(warn_state);
0522                     pat = 'SeDuMi\s+([^\s]+)';
0523                     [s,e,tE,m,t] = regexp(str, pat);
0524                     if ~isempty(t)
0525                         vstr = t{1}{1};
0526                     end
0527                 end
0528 
0529             %%-----  private tags  -----
0530             case 'catchme'  %% not supported by MATLAB <= 7.4 (R2007a), Octave <= 3.6
0531                 if have_fcn('octave')
0532                     if have_fcn('octave', 'vnum') > 3.006
0533                         TorF = 1;
0534                     end
0535                 else
0536                     if have_fcn('matlab', 'vnum') > 7.004
0537                         TorF = 1;
0538                     end
0539                 end
0540             case 'evalc'
0541                 if have_fcn('matlab')
0542                     TorF = 1;
0543                 end
0544             case 'ipopt_auxdata'
0545                 if have_fcn('ipopt')
0546                     vn = have_fcn('ipopt', 'vnum');
0547                     if ~isempty(vn)
0548                         if vn >= 3.011  %% have_fcn('ipopt') already checked
0549                             TorF = 1;   %% for existence of 'ipopt_auxdata'
0550                         else
0551                             TorF = 0;   %% don't use it, even if it exists
0552                         end
0553                     %% no version info, decide based on presence
0554                     %% or absence of 'ipopt_auxdata'
0555                     elseif exist('ipopt_auxdata', 'file')
0556                         TorF = 1;
0557                     else
0558                         TorF = 0;
0559                     end
0560                 else
0561                     TorF = 0;
0562                 end
0563             case 'lu_vec'       %% lu(..., 'vector') syntax supported?
0564                 if have_fcn('matlab') && have_fcn('matlab', 'vnum') < 7.003
0565                     TorF = 0;     %% lu(..., 'vector') syntax not supported
0566                 else
0567                     TorF = 1;
0568                 end
0569             case 'pardiso_object'
0570                 TorF = exist('pardiso', 'file') == 2;
0571                 if TorF
0572                     try
0573                         id = 1;
0574                         A = sparse([1 2; 3 4]);
0575                         b = [1;1];
0576                         p = pardiso(id, 11, 0);
0577                         p.factorize(id, A);
0578                         x = p.solve(id, A, b);
0579                         p.free(id);
0580                         p.clear();
0581                         if any(x ~= [-1; 1])
0582                             TorF = 0;
0583                         end
0584                     catch
0585                         TorF = 0;
0586                     end
0587                 end
0588             case 'pardiso_legacy'
0589                 TorF = exist('pardisoinit', 'file') == 3 && ...
0590                         exist('pardisoreorder', 'file') == 3 && ...
0591                         exist('pardisofactor', 'file') == 3 && ...
0592                         exist('pardisosolve', 'file') == 3 && ...
0593                         exist('pardisofree', 'file') == 3;
0594                 if TorF
0595                     try
0596                         A = sparse([1 2; 3 4]);
0597                         b = [1;1];
0598                         info = pardisoinit(11, 0);
0599                         info = pardisoreorder(A, info, false);
0600 %                         % Summary PARDISO 5.1.0: ( reorder to reorder )
0601 %                         pat = 'Summary PARDISO (\.*\d)+:';
0602 %                         [s,e,tE,m,t] = regexp(evalc('info = pardisoreorder(A, info, true);'), pat);
0603 %                         if ~isempty(t)
0604 %                             vstr = t{1}{1};
0605 %                         end
0606                         info = pardisofactor(A, info, false);
0607                         [x, info] = pardisosolve(A, b, info, false);
0608                         pardisofree(info);
0609                         if any(x ~= [-1; 1])
0610                             TorF = 0;
0611                         end
0612                     catch
0613                         TorF = 0;
0614                     end
0615                 end
0616             case 'regexp_split'     %% missing for MATLAB < 7.3 & Octave < 3.8
0617                 if have_fcn('matlab') && have_fcn('matlab', 'vnum') >= 7.003
0618                     TorF = 1;
0619                 elseif have_fcn('octave', 'vnum') >= 3.008
0620                     TorF = 1;
0621                 end
0622             case 'rithmaticker'     %% used for testing HAVE_FCN
0623                 TorF = exist('rithmaticker', 'file') == 2;
0624                 if TorF
0625                     vstr = '3.1.4';
0626                     rdate = datestr([2019 5 30 0 0 0], 'dd-mmm-yyyy');
0627                 end
0628 
0629         %%-----  unknown tag  -----
0630             otherwise
0631                 warning('have_fcn: unknown functionality ''%s''', tag);
0632                 vstr = 'unknown';
0633         end
0634 
0635         %% assign values to cache
0636         fcns.(tag).av   = TorF;
0637         fcns.(tag).vstr = vstr;
0638         if isempty(vstr)
0639             fcns.(tag).vnum = [];
0640         else
0641             fcns.(tag).vnum = vstr2num(vstr);
0642         end
0643         fcns.(tag).date = rdate;
0644     end
0645 end
0646 
0647 %% extract desired values from cache
0648 if action ~= 'C' || nargout
0649     if nargin < 2 || action == 'T'
0650         rv = fcns.(tag).av;
0651     else
0652         switch lower(rtype)
0653             case 'vstr'
0654                 rv = fcns.(tag).vstr;
0655             case 'vnum'
0656                 rv = fcns.(tag).vnum;
0657             case 'date'
0658                 rv = fcns.(tag).date;
0659             case 'all'
0660                 rv = fcns.(tag);
0661         end
0662     end
0663 end
0664 
0665 function num = vstr2num(vstr)
0666 % Converts version string to numerical value suitable for < or > comparisons
0667 % E.g. '3.11.4' -->  3.011004
0668 pat = '\.?(\d+)';
0669 [s,e,tE,m,t] = regexp(vstr, pat);
0670 b = 1;
0671 num = 0;
0672 for k = 1:length(t)
0673     num = num + b * str2num(t{k}{1});
0674     b = b / 1000;
0675 end

Generated on Mon 24-Jun-2019 15:58:45 by m2html © 2005