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