0001 function rv = have_fcn(tag, rtype)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 if nargin > 1 && isnumeric(rtype)
0101 toggle = 1;
0102 on_off = rtype;
0103 if on_off < 0
0104 TorF = have_fcn(tag);
0105 on_off = ~TorF;
0106 end
0107 else
0108 toggle = 0;
0109 end
0110
0111 persistent fcns;
0112
0113 if toggle
0114 if on_off
0115 fcns = rmfield(fcns, tag);
0116 else
0117 if ~isfield(fcns, tag)
0118 TorF = have_fcn(tag);
0119 end
0120 fcns.(tag).av = 0;
0121 end
0122 TorF = have_fcn(tag);
0123 else
0124
0125 if ~isfield(fcns, tag)
0126
0127
0128 TorF = 0;
0129 vstr = '';
0130 rdate = '';
0131
0132 switch tag
0133
0134 case 'bpmpd'
0135 TorF = exist('bp', 'file') == 3;
0136 if TorF
0137 v = bpver('all');
0138 vstr = v.Version;
0139 rdate = v.Date;
0140 end
0141 case 'clp'
0142 tmp = have_fcn('opti_clp', 'all');
0143 if tmp.av
0144 TorF = tmp.av;
0145 vstr = tmp.vstr;
0146 rdate = tmp.date;
0147 elseif exist('clp','file') == 2 && exist('mexclp','file') == 3
0148 TorF = 1;
0149 vstr = '';
0150 end
0151 case 'opti_clp'
0152 TorF = exist('opti_clp', 'file') == 2 && exist('clp', 'file') == 3;
0153 if TorF
0154 str = evalc('clp');
0155 pat = 'CLP: COIN-OR Linear Programming \[v([^\s,]+), Built ([^\]])+\]';
0156 [s,e,tE,m,t] = regexp(str, pat);
0157 if ~isempty(t)
0158 vstr = t{1}{1};
0159 rdate = datestr(t{1}{2}, 'dd-mmm-yyyy');
0160 end
0161 end
0162 case 'cplex'
0163 if exist('cplexqp', 'file')
0164
0165 p = which('cplexqp');
0166 len = length(p) - length('cplexqp.p');
0167 w = what(p(1:len));
0168 for k = 1:length(w.mex)
0169 if regexp(w.mex{k}, 'cplexlink[^\.]*');
0170 TorF = 1;
0171 break;
0172 end
0173 end
0174 end
0175 if TorF
0176 try
0177 cplex = Cplex('null');
0178 vstr = cplex.getVersion;
0179 catch
0180 TorF = 0;
0181 end
0182 end
0183 case {'fmincon', 'fmincon_ipm', 'intlinprog', 'linprog', ...
0184 'linprog_ds', 'optimoptions', 'quadprog', 'quadprog_ls'}
0185 if license('test', 'optimization_toolbox')
0186 v = ver('optim');
0187 vstr = v.Version;
0188 rdate = v.Date;
0189 switch tag
0190 case 'fmincon'
0191 TorF = exist('fmincon', 'file') == 2 || ...
0192 exist('fmincon', 'file') == 6;
0193 case 'intlinprog'
0194 TorF = exist('intlinprog', 'file') == 2;
0195 case 'linprog'
0196 TorF = exist('linprog', 'file') == 2;
0197 case 'quadprog'
0198 TorF = exist('quadprog', 'file') == 2;
0199 otherwise
0200 otver = vstr2num(vstr);
0201 switch tag
0202 case 'fmincon_ipm'
0203 if otver >= 4
0204 TorF = 1;
0205 else
0206 TorF = 0;
0207 end
0208 case 'linprog_ds'
0209 if otver >= 7.001
0210 TorF = 1;
0211 else
0212 TorF = 0;
0213 end
0214 case 'optimoptions'
0215 if otver >= 6.003
0216 TorF = 1;
0217 else
0218 TorF = 0;
0219 end
0220 case 'quadprog_ls'
0221 if otver >= 6
0222 TorF = 1;
0223 else
0224 TorF = 0;
0225 end
0226 end
0227 end
0228 else
0229 TorF = 0;
0230 end
0231 case 'glpk'
0232 if exist('glpk','file') == 3
0233 TorF = 1;
0234 str = evalc('glpk');
0235 pat = 'GLPK: GNU Linear Programming Kit \[v([^\s,]+), Built ([^\]])+\]';
0236 [s,e,tE,m,t] = regexp(str, pat);
0237 if ~isempty(t)
0238 vstr = t{1}{1};
0239 rdate = datestr(t{1}{2}, 'dd-mmm-yyyy');
0240 end
0241 elseif exist('glpk','file') == 2
0242 if exist('__glpk__','file') == 3
0243 TorF = 1;
0244 if have_fcn('evalc')
0245 str = evalc('glpk(1, 1, 1, 1, 1, ''U'', ''C'', -1, struct(''msglev'', 3))');
0246 pat = 'GLPK Simplex Optimizer, v([^\s,]+)';
0247 [s,e,tE,m,t] = regexp(str, pat);
0248 if ~isempty(t)
0249 vstr = t{1}{1};
0250 end
0251 end
0252 elseif exist('glpkcc','file') == 3
0253 TorF = 1;
0254 str = evalc('glpk');
0255 pat = 'GLPK Matlab interface\. Version: ([^\s,]+)';
0256 [s,e,tE,m,t] = regexp(str, pat);
0257 if ~isempty(t)
0258 vstr = t{1}{1};
0259 end
0260 end
0261 end
0262 case 'gurobi'
0263 TorF = exist('gurobi', 'file') == 3;
0264 if TorF
0265 try
0266 model = struct( ...
0267 'A', sparse(1), ...
0268 'rhs', 1, ...
0269 'sense', '=', ...
0270 'vtype', 'C', ...
0271 'obj', 1, ...
0272 'modelsense', 'min' ...
0273 );
0274 params = struct( ...
0275 'outputflag', 0 ...
0276 );
0277 result = gurobi(model, params);
0278 vstr = sprintf('%d.%d.%d', result.versioninfo.major, result.versioninfo.minor, result.versioninfo.technical);
0279 catch
0280 fprintf('Gurobi Error!\n');
0281
0282 end
0283 end
0284 case 'ipopt'
0285 TorF = exist('ipopt', 'file') == 3;
0286 if TorF
0287 str = evalc('qps_ipopt([],1,1,1,1,1,1,1,struct(''verbose'', 2))');
0288 pat = 'Ipopt version ([^\s,]+)';
0289 [s,e,tE,m,t] = regexp(str, pat);
0290 if ~isempty(t)
0291 vstr = t{1}{1};
0292 if vstr2num(vstr) >= 3.011 && ...
0293 ~exist('ipopt_auxdata', 'file')
0294 TorF = 0;
0295 warning('Improper installation of IPOPT. Version %s detected, but IPOPT_AUXDATA.M is missing.', vstr);
0296 end
0297 end
0298 end
0299 case 'knitro'
0300 tmp = have_fcn('knitromatlab', 'all');
0301 if tmp.av
0302 TorF = tmp.av;
0303 vstr = tmp.vstr;
0304 rdate = tmp.date;
0305 else
0306 tmp = have_fcn('ktrlink', 'all');
0307 if tmp.av
0308 TorF = tmp.av;
0309 vstr = tmp.vstr;
0310 rdate = tmp.date;
0311 end
0312 end
0313 case {'knitromatlab', 'ktrlink'}
0314
0315
0316 TorF = exist(tag, 'file') == 2;
0317 if TorF
0318 try
0319 str = evalc(['[x fval] = ' tag '(@(x)1,1);']);
0320 end
0321 TorF = exist('fval', 'var') && fval == 1;
0322 if TorF
0323 pat = 'KNITRO ([^\s]+)\n';
0324 [s,e,tE,m,t] = regexp(str, pat);
0325 if ~isempty(t)
0326 vstr = t{1}{1};
0327 end
0328 end
0329 end
0330 case 'matlab'
0331 v = ver('matlab');
0332 if ~isempty(v) && isfield(v, 'Version') && ~isempty(v.Version)
0333 TorF = 1;
0334 vstr = v.Version;
0335 rdate = v.Date;
0336 end
0337 case 'minopf'
0338 TorF = exist('minopf', 'file') == 3;
0339 if TorF
0340 v = minopfver('all');
0341 vstr = v.Version;
0342 rdate = v.Date;
0343 end
0344 case 'mosek'
0345 TorF = exist('mosekopt', 'file') == 3;
0346 if TorF
0347
0348
0349
0350 pat = 'Version (\.*\d)+.*Build date: (\d+-\d+-\d+)';
0351 [s,e,tE,m,t] = regexp(evalc('mosekopt'), pat);
0352 if ~isempty(t)
0353 vstr = t{1}{1};
0354 rdate = datestr(t{1}{2}, 'dd-mmm-yyyy');
0355 end
0356 end
0357 case 'smartmarket'
0358 TorF = exist('runmarket', 'file') == 2;
0359 if TorF
0360 v = mpver('all');
0361 vstr = v.Version;
0362 rdate = v.Date;
0363 end
0364 case 'octave'
0365 TorF = exist('OCTAVE_VERSION', 'builtin') == 5;
0366 if TorF
0367 v = ver('octave');
0368 vstr = v.Version;
0369 rdate = v.Date;
0370 end
0371 case 'pardiso'
0372 TorF = exist('pardisoinit', 'file') == 3 && ...
0373 exist('pardisoreorder', 'file') == 3 && ...
0374 exist('pardisofactor', 'file') == 3 && ...
0375 exist('pardisosolve', 'file') == 3 && ...
0376 exist('pardisofree', 'file') == 3;
0377 if TorF
0378 try
0379 A = sparse([1 2; 3 4]);
0380 b = [1;1];
0381
0382 pat = 'Summary PARDISO (\.*\d)+:';
0383 info = pardisoinit(11, 0);
0384 info = pardisoreorder(A, info, false);
0385
0386
0387
0388
0389 info = pardisofactor(A, info, false);
0390 [x, info] = pardisosolve(A, b, info, false);
0391 pardisofree(info);
0392 if any(x ~= [-1; 1])
0393 TorF = 0;
0394 end
0395 catch
0396 TorF = 0;
0397 end
0398 end
0399 case {'pdipmopf', 'scpdipmopf', 'tralmopf'}
0400 if have_fcn('matlab')
0401 v = ver('Matlab');
0402 vn = vstr2num(v.Version);
0403
0404
0405
0406 if vn >= 6.005
0407 switch tag
0408 case 'pdipmopf'
0409 TorF = exist('pdipmopf', 'file') == 3;
0410 case 'scpdipmopf'
0411 TorF = exist('scpdipmopf', 'file') == 3;
0412 case 'tralmopf'
0413
0414
0415 if vn >= 7.003
0416 TorF = exist('tralmopf', 'file') == 3;
0417 else
0418 TorF = 0;
0419 end
0420 end
0421 else
0422 TorF = 0;
0423 end
0424 if TorF
0425 v = feval([tag 'ver'], 'all');
0426 vstr = v.Version;
0427 rdate = v.Date;
0428 end
0429 end
0430 case 'sdp_pf'
0431 TorF = have_fcn('yalmip') && exist('mpoption_info_sdp_pf', 'file') == 2;
0432 if TorF
0433 v = sdp_pf_ver('all');
0434 vstr = v.Version;
0435 rdate = v.Date;
0436 end
0437 case 'yalmip'
0438 TorF = ~have_fcn('octave') && exist('yalmip','file') == 2;
0439
0440 if TorF
0441 str = evalc('yalmip;');
0442 pat = 'Version\s+([^\s]+)\n';
0443 [s,e,tE,m,t] = regexp(str, pat);
0444 if ~isempty(t)
0445 rdate = t{1}{1};
0446 vstr = datestr(rdate, 'yy.mm.dd');
0447 end
0448 end
0449 case 'sdpt3'
0450 TorF = exist('sdpt3','file') == 2;
0451 if TorF
0452 str = evalc('help sdpt3');
0453 pat = 'version\s+([^\s]+).*Last Modified: ([^\n]+)\n';
0454 [s,e,tE,m,t] = regexp(str, pat);
0455 if ~isempty(t)
0456 vstr = t{1}{1};
0457 rdate = datestr(t{1}{2}, 'dd-mmm-yyyy');
0458 end
0459 end
0460 case 'sedumi'
0461 TorF = exist('sedumi','file') == 2;
0462 if TorF
0463 str = evalc('x = sedumi([1 1], 1, [1;2])');
0464 pat = 'SeDuMi\s+([^\s]+)';
0465 [s,e,tE,m,t] = regexp(str, pat);
0466 if ~isempty(t)
0467 vstr = t{1}{1};
0468 end
0469 end
0470
0471
0472 case 'catchme'
0473 if have_fcn('octave')
0474 if have_fcn('octave', 'vnum') <= 3.006
0475 TorF = 0;
0476 else
0477 TorF = 1;
0478 end
0479 else
0480 if have_fcn('matlab', 'vnum') <= 7.004
0481 TorF = 0;
0482 else
0483 TorF = 1;
0484 end
0485 end
0486 case 'evalc'
0487 if have_fcn('octave')
0488 TorF = 0;
0489 else
0490 TorF = 1;
0491 end
0492 case 'ipopt_auxdata'
0493 if have_fcn('ipopt')
0494 vn = have_fcn('ipopt', 'vnum');
0495 if ~isempty(vn) && vn >= 3.011
0496 TorF = 1;
0497 end
0498 end
0499 case 'regexp_split'
0500 if have_fcn('matlab') && have_fcn('matlab', 'vnum') >= 7.003
0501 TorF = 1;
0502 elseif have_fcn('octave', 'vnum') >= 3.008
0503 TorF = 1;
0504 end
0505
0506
0507 otherwise
0508 error('have_fcn: unknown functionality %s', tag);
0509 end
0510
0511
0512 fcns.(tag).av = TorF;
0513 fcns.(tag).vstr = vstr;
0514 if isempty(vstr)
0515 fcns.(tag).vnum = [];
0516 else
0517 fcns.(tag).vnum = vstr2num(vstr);
0518 end
0519 fcns.(tag).date = rdate;
0520 end
0521 end
0522
0523
0524 if nargin < 2 || toggle
0525 rv = fcns.(tag).av;
0526 else
0527 switch lower(rtype)
0528 case 'vstr'
0529 rv = fcns.(tag).vstr;
0530 case 'vnum'
0531 rv = fcns.(tag).vnum;
0532 case 'date'
0533 rv = fcns.(tag).date;
0534 case 'all'
0535 rv = fcns.(tag);
0536 end
0537 end
0538
0539 function num = vstr2num(vstr)
0540
0541
0542 pat = '\.?(\d+)';
0543 [s,e,tE,m,t] = regexp(vstr, pat);
0544 b = 1;
0545 num = 0;
0546 for k = 1:length(t)
0547 num = num + b * str2num(t{k}{1});
0548 b = b / 1000;
0549 end