├── matlab ├── util │ ├── end_snopt.m │ ├── end_sqopt.m │ ├── snprint.m │ ├── sqprint.m │ ├── snscreen.m │ ├── sqscreen.m │ ├── snsetwork.m │ ├── sqsetwork.m │ ├── snJac.m │ ├── snset.m │ ├── snspec.m │ ├── sqspec.m │ ├── sqset.m │ ├── snget.m │ ├── snsetr.m │ ├── snseti.m │ ├── checkFun.m │ ├── snsummary.m │ ├── sqsummary.m │ ├── snfindG.m │ ├── colvec.m │ ├── crd2spr.m │ ├── solve_sqopt.m │ ├── solve_snopt.m │ └── solve_snfmincon.m ├── examples │ ├── hs76 │ │ ├── hs76.spc │ │ └── hs76.m │ ├── t1diet │ │ ├── t1dietuserfun.m │ │ ├── t1diet.spc │ │ ├── t1diet_lp.m │ │ └── t1diet.m │ ├── hsmain │ │ ├── hs13.spc │ │ ├── hs13userfun.m │ │ ├── hsmain.spc │ │ ├── hsmainusrfun.m │ │ ├── hs13.m │ │ └── hsmain.m │ ├── sntoy │ │ ├── sntoy.spc │ │ ├── sntoy2.spc │ │ ├── toyusrfun2.m │ │ ├── toyusrfun.m │ │ ├── sntoy2.m │ │ └── sntoy.m │ ├── fmincon │ │ ├── sntoy.spc │ │ ├── toyCon.m │ │ ├── toyObj.m │ │ └── toymin.m │ ├── snmain │ │ ├── snoptmain.spc │ │ ├── snoptmain3.spc │ │ ├── snoptmain2.spc │ │ ├── snoptuserfun.m │ │ ├── snoptuserfun3.m │ │ ├── snoptmain.m │ │ ├── snoptuserfun2.m │ │ ├── snoptmain2.m │ │ └── snoptmain3.m │ ├── spring │ │ ├── spring.spc │ │ ├── springFun.m │ │ └── springa.m │ └── hs116 │ │ ├── hs116G.spc │ │ ├── hs116.spc │ │ ├── hs116M.spc │ │ ├── hs116userfun.m │ │ ├── hs116userfunM.m │ │ ├── hs116Guserfun.m │ │ ├── hs116G.m │ │ ├── hs116.m │ │ └── hs116M.m ├── runQPexamples.m ├── setpath.m ├── README ├── runNPexamples.m ├── lpopt.m ├── sqsolve.m ├── sqopt.m ├── snsolve.m └── snopt.m ├── README.md ├── LICENSE └── mex ├── iomex.f90 ├── snmex.F90 └── sqoptmex.F90 /matlab/util/end_snopt.m: -------------------------------------------------------------------------------- 1 | function end_snopt 2 | 3 | snoptmex(999); -------------------------------------------------------------------------------- /matlab/util/end_sqopt.m: -------------------------------------------------------------------------------- 1 | function end_sqopt() 2 | 3 | sqoptmex(999); 4 | -------------------------------------------------------------------------------- /matlab/util/snprint.m: -------------------------------------------------------------------------------- 1 | function snprint(printfile) 2 | % function snprint(printfile) 3 | 4 | if ~strcmp(printfile,''), 5 | mexopt = 10; 6 | snoptmex(mexopt,printfile); 7 | end 8 | -------------------------------------------------------------------------------- /matlab/util/sqprint.m: -------------------------------------------------------------------------------- 1 | function sqprint(printfile) 2 | % function sqprint(printfile) 3 | 4 | if ~strcmp(printfile,''), 5 | mexopt = 10; 6 | sqoptmex(mexopt,printfile); 7 | end 8 | -------------------------------------------------------------------------------- /matlab/examples/hs76/hs76.spc: -------------------------------------------------------------------------------- 1 | Begin HS76 2 | Major Print level 000001 3 | Minor print level 1 4 | Print frequency 1 5 | Summary frequency 1 6 | End HS76 7 | -------------------------------------------------------------------------------- /matlab/examples/t1diet/t1dietuserfun.m: -------------------------------------------------------------------------------- 1 | function [F,G] = t1dietuserfun(x) 2 | %function [F,G] = t1dietuserfun(x) 3 | % Defines the dummy function for the (vacuous) nonlinear function 4 | % for the problem t1diet. 5 | 6 | F = []; G = []; 7 | -------------------------------------------------------------------------------- /matlab/examples/hsmain/hs13.spc: -------------------------------------------------------------------------------- 1 | Begin Toy NLP problem 2 | Major Print level 000001 3 | * (JFLXBT) 4 | Minor print level 1 5 | Solution yes 6 | End Toy NLP problem 7 | -------------------------------------------------------------------------------- /matlab/examples/sntoy/sntoy.spc: -------------------------------------------------------------------------------- 1 | Begin Toy NLP problem 2 | Major Print level 000001 3 | * (JFLXBT) 4 | Minor print level 1 5 | Solution yes 6 | End Toy NLP problem 7 | -------------------------------------------------------------------------------- /matlab/util/snscreen.m: -------------------------------------------------------------------------------- 1 | function snscreen(screen) 2 | %function snscreen(screen) 3 | 4 | if strcmp(screen,'on'), 5 | mexopt = 15; 6 | snoptmex(mexopt); 7 | elseif strcmp(screen,'off') 8 | mexopt = 16; 9 | snoptmex(mexopt); 10 | end 11 | -------------------------------------------------------------------------------- /matlab/util/sqscreen.m: -------------------------------------------------------------------------------- 1 | function sqscreen(screen) 2 | %function sqscreen(screen) 3 | 4 | if strcmp(screen,'on'), 5 | mexopt = 15; 6 | sqoptmex(mexopt); 7 | elseif strcmp(screen,'off') 8 | mexopt = 16; 9 | sqoptmex(mexopt); 10 | end 11 | -------------------------------------------------------------------------------- /matlab/examples/fmincon/sntoy.spc: -------------------------------------------------------------------------------- 1 | Begin Toy NLP problem 2 | Major Print level 000001 3 | * (JFLXBT) 4 | Minor print level 1 5 | Solution yes 6 | End Toy NLP problem 7 | -------------------------------------------------------------------------------- /matlab/examples/sntoy/sntoy2.spc: -------------------------------------------------------------------------------- 1 | Begin Toy NLP problem 2 | Major Print level 000001 3 | * (JFLXBT) 4 | Minor print level 1 5 | Solution yes 6 | End Toy NLP problem 7 | -------------------------------------------------------------------------------- /matlab/examples/snmain/snoptmain.spc: -------------------------------------------------------------------------------- 1 | Begin snmain 2 | Major iterations 750 3 | Major Print level 000001 4 | * (JFLXBT) 5 | Minor print level 1 6 | Solution No 7 | End snmain 8 | -------------------------------------------------------------------------------- /matlab/examples/snmain/snoptmain3.spc: -------------------------------------------------------------------------------- 1 | Begin snmain3 2 | Major iterations 200 3 | Major Print level 000001 4 | * (JFLXBT) 5 | Minor print level 1 6 | Solution No 7 | End snmain3 8 | -------------------------------------------------------------------------------- /matlab/util/snsetwork.m: -------------------------------------------------------------------------------- 1 | function snsetwork(iwork,rwork) 2 | % function snsetwork(leniw, lenrw) 3 | % Modify the initial amount of workspace for SNOPT. 4 | % Values must be at least 500. 5 | % 6 | 7 | if iwork > 0 && rwork > 0, 8 | mexopt = 14; 9 | snoptmex(mexopt,iwork,rwork); 10 | end 11 | -------------------------------------------------------------------------------- /matlab/util/sqsetwork.m: -------------------------------------------------------------------------------- 1 | function sqsetwork(iwork,rwork) 2 | % function sqsetwork(leniw, lenrw) 3 | % Modify the initial amount of workspace for SQOPT. 4 | % Values must be at least 500. 5 | % 6 | 7 | if iwork > 0 && rwork > 0, 8 | mexopt = 14; 9 | sqoptmex(mexopt,iwork,rwork); 10 | end 11 | -------------------------------------------------------------------------------- /matlab/examples/fmincon/toyCon.m: -------------------------------------------------------------------------------- 1 | function [c,ceq,dc,dceq] = toyCon(x) 2 | % function [F,G] = toyusrfun(x) 3 | 4 | c = []; 5 | dc = []; 6 | 7 | 8 | ceq = [ x(1) + x(2)^2 + x(3)^2 - 2; 9 | x(2)^4 + x(3)^4 + x(4) - 4 ]; 10 | dceq = [ 1 2*x(2) 2*x(3) 0; 11 | 0 4*x(2)^3 4*x(3)^3 1 ]; 12 | -------------------------------------------------------------------------------- /matlab/examples/fmincon/toyObj.m: -------------------------------------------------------------------------------- 1 | function [F,G] = toyObj(x) 2 | % function [F,G] = toyObj(x) 3 | % Return objective value and gradient 4 | 5 | F = [ 3*x(1) + (x(1) + x(2) + x(3))^2 + 5*x(4) ]; 6 | 7 | G = [ 2*(x(1)+x(2)+x(3)) + 3; 8 | 2*(x(1)+x(2)+x(3)); 9 | 2*(x(1)+x(2)+x(3)) 10 | 5 ]; 11 | -------------------------------------------------------------------------------- /matlab/examples/snmain/snoptmain2.spc: -------------------------------------------------------------------------------- 1 | Begin snmain2 2 | Derivative option 1 3 | Major iterations 200 4 | Major Print level 000001 5 | * (JFLXBT) 6 | Minor print level 1 7 | Solution No 8 | End snmain2 9 | -------------------------------------------------------------------------------- /matlab/util/snJac.m: -------------------------------------------------------------------------------- 1 | function [A,iAfun,jAvar,iGfun,jGvar] = snJac(userfun,x0,xlow,xupp,nF) 2 | %function [A,iAfun,jAvar,iGfun,jGvar] = snJac(usrfun,x0,xlow,xupp,nF) 3 | % Finds the coordinate structure for the Jacobian. 4 | 5 | 6 | userFG = checkFun(userfun,'SNOPT','userfun'); 7 | [A,iAfun,jAvar,iGfun,jGvar] = snoptmex(17,userFG,x0,xlow,xupp,nF); 8 | -------------------------------------------------------------------------------- /matlab/examples/spring/spring.spc: -------------------------------------------------------------------------------- 1 | Begin SpringA -- optimal control problem 2 | 3 | Derivative option 0 4 | 5 | Major iterations 1000 6 | Major Print level 000001 7 | * (JFLXBT) 8 | Minor print level 1 9 | Solution No 10 | End SpringA 11 | -------------------------------------------------------------------------------- /matlab/util/snset.m: -------------------------------------------------------------------------------- 1 | function snset( option ) 2 | % function snset( option ) 3 | % Sets a optional parameter of sqopt. The string "option" will be read 4 | % by sqopt. If the string contains a setting that sqopt understands, 5 | % sqopt will set internal parameters accordingly. For a description of 6 | % available parameters, please see the SNOPT documentation. 7 | % 8 | snoptmex(2, option); -------------------------------------------------------------------------------- /matlab/util/snspec.m: -------------------------------------------------------------------------------- 1 | function info = snspec(specsfile) 2 | % function info = snspec(specsfile) 3 | % Causes snopt to read its optional parameters from the named file. 4 | % The format of this file is described in the snopt documentation. 5 | % 6 | % Returns 101 or 107 if successful. 7 | 8 | if ~strcmp(specsfile,''), 9 | mexopt = 9; 10 | info = snoptmex(mexopt,specsfile); 11 | end -------------------------------------------------------------------------------- /matlab/util/sqspec.m: -------------------------------------------------------------------------------- 1 | function info = sqspec(specsfile) 2 | % function info = sqspec(specsfile) 3 | % Causes sqopt to read its optional parameters from the named file. 4 | % The format of this file is described in the snopt documentation. 5 | % 6 | % Returns 101 or 107 if successful. 7 | 8 | if ~strcmp(specsfile,''), 9 | mexopt = 9; 10 | info = sqoptmex(mexopt,specsfile); 11 | end -------------------------------------------------------------------------------- /matlab/util/sqset.m: -------------------------------------------------------------------------------- 1 | function sqset( option ) 2 | % function sqset( option ) 3 | % Sets a optional parameter of sqopt. The string "option" will be read 4 | % by sqopt. If the string contains a setting that sqopt understands, 5 | % sqopt will set internal parameters accordingly. For a description of 6 | % available parameters, please see the SQOPT documentation. 7 | % 8 | 9 | sqoptmex(2, option); -------------------------------------------------------------------------------- /matlab/examples/t1diet/t1diet.spc: -------------------------------------------------------------------------------- 1 | Begin t1diet problem 2 | 3 | Major iterations 100 4 | 5 | Major Print level 000001 6 | * (JFLXBT) 7 | Minor print level 1 8 | 9 | Print frequency 1 10 | Summary frequency 1 11 | 12 | Solution no 13 | 14 | End t1diet problem 15 | -------------------------------------------------------------------------------- /matlab/util/snget.m: -------------------------------------------------------------------------------- 1 | function [value] = snget( option ) 2 | % function snget( option ) 3 | % Gets value of an option in snopt. The string "option" will be read 4 | % by snopt. If the string contains a setting that snopt understands, 5 | % snopt will retrive the parameter accordingly. For a description of 6 | % available parameters, please see the SNOPT documentation. 7 | % 8 | [value] = snoptmex(5, option); -------------------------------------------------------------------------------- /matlab/util/snsetr.m: -------------------------------------------------------------------------------- 1 | function snsetr( option, rvalue ) 2 | % function snset( option ) 3 | % Sets a optional real parameter of snopt. The string "option" will be read 4 | % by snopt. If the string contains a setting that snopt understands, 5 | % snopt will set internal parameters accordingly. For a description of 6 | % available parameters, please see the SNOPT documentation. 7 | % 8 | snoptmex(4, option, rvalue); -------------------------------------------------------------------------------- /matlab/util/snseti.m: -------------------------------------------------------------------------------- 1 | function snseti( option, ivalue ) 2 | % function snset( option ) 3 | % Sets a optional integer parameter of snopt. The string "option" will be read 4 | % by snopt. If the string contains a setting that snopt understands, 5 | % snopt will set internal parameters accordingly. For a description of 6 | % available parameters, please see the SNOPT documentation. 7 | % 8 | snoptmex(3, option, ivalue); -------------------------------------------------------------------------------- /matlab/runQPexamples.m: -------------------------------------------------------------------------------- 1 | %Test Script. 2 | 3 | format compact; 4 | setpath; % defines the path 5 | 6 | fprintf('\n============================================================= '); 7 | fprintf('\nhs76: sqopt solves quadratic problem hs76 ... '); 8 | hs76; 9 | 10 | fprintf('\n============================================================= '); 11 | fprintf('\nt1diet_lp: sqopt solves linear problem t1diet_lp ... '); 12 | t1diet_lp; 13 | -------------------------------------------------------------------------------- /matlab/examples/hsmain/hs13userfun.m: -------------------------------------------------------------------------------- 1 | function [F,G] = hs13userfun(x) 2 | %function [F,G] = hs13userfun(x) 3 | % Defines the nonlinear part of the function and derivatives 4 | % for HS 13. 5 | 6 | F = [ x(1)+x(2); 7 | x(1)^3-x(2) ]; 8 | 9 | % Define the derivatives. 10 | % The coordinates aren't used but are included as a safety check. 11 | 12 | G = [ 1, 1, 1; 13 | 1, 2, 1; 14 | 2, 1, 3*x(1)^2 15 | 2, 2, -1 ]; 16 | 17 | G = G(:,3); 18 | -------------------------------------------------------------------------------- /matlab/setpath.m: -------------------------------------------------------------------------------- 1 | function setpath(varargin) 2 | 3 | addpath([pwd,'/util' ], '-end'); 4 | addpath([pwd,'/examples' ], '-end'); 5 | addpath([pwd,'/examples/t1diet'], '-end'); 6 | addpath([pwd,'/examples/sntoy' ], '-end'); 7 | addpath([pwd,'/examples/snmain'], '-end'); 8 | addpath([pwd,'/examples/hsmain'], '-end'); 9 | addpath([pwd,'/examples/hs76' ], '-end'); 10 | addpath([pwd,'/examples/fmincon'], '-end'); 11 | addpath([pwd,'/examples/hs116' ], '-end'); 12 | addpath([pwd,'/examples/spring' ], '-end'); 13 | 14 | -------------------------------------------------------------------------------- /matlab/util/checkFun.m: -------------------------------------------------------------------------------- 1 | function [myfun] = checkFun(fun,solver,name) 2 | % Check function is a string or function handle. 3 | % Optionally, check function has correct number of output arguments. 4 | % Return the function handle. 5 | % 6 | % myfun = checkFun(fun,solver,name) 7 | % myfun = checkFun(fun,solver,name,nouts) 8 | % 9 | errID = [solver ':InputArgs']; 10 | 11 | if ischar(fun), 12 | myfun = str2func(fun); 13 | elseif isa(fun,'function_handle'), 14 | myfun = fun; 15 | else 16 | error(errID,'%s should be a function handle or string',name); 17 | end 18 | -------------------------------------------------------------------------------- /matlab/examples/hsmain/hsmain.spc: -------------------------------------------------------------------------------- 1 | Begin HS problem 2 | Major iterations 100 3 | Minor iterations 100 4 | 5 | Derivative option 1 * First derivatives 6 | Derivative line search * The default 7 | 8 | Major Print level 000001 9 | * (JFLXBT) 10 | Minor print level 1 11 | 12 | * Print frequency 1 13 | * Summary frequency 1 14 | 15 | * Objective row 0 * Would find a feasible point 16 | Solution no 17 | End HS problem 18 | -------------------------------------------------------------------------------- /matlab/examples/hs116/hs116G.spc: -------------------------------------------------------------------------------- 1 | Begin HS problem 2 | Major iterations 100 3 | Minor iterations 100 4 | 5 | Derivative option 1 * First derivatives 6 | Derivative line search * The default 7 | 8 | Major Print level 000001 9 | * (JFLXBT) 10 | Minor print level 1 11 | 12 | * Print frequency 1 13 | * Summary frequency 1 14 | 15 | * Objective row 0 * Would find a feasible point 16 | Solution no 17 | End HS problem 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | snopt-matlab (version 3.0) 2 | ========================= 3 | 4 | This is version 3.0 of the Matlab interface for sparse nonlinear optimization software SNOPT. 5 | 6 | Requires the SNOPT software package. 7 | 8 | Changes from version 2.5: 9 | * all-in-one calls to SNOPT (for NLPs) and SQOPT (for LPs and QPs) 10 | * new options handling 11 | * specifiy print, summary output via options structure 12 | * linear and nonlinear Jacobian structure in SNOPT can be defined in structs or as matrices 13 | 14 | 15 | Documentation for the Matlab interface available here. 16 | 17 | -------------------------------------------------------------------------------- /matlab/examples/hs116/hs116.spc: -------------------------------------------------------------------------------- 1 | Begin HS problem 2 | Major iterations 100 3 | Minor iterations 100 4 | 5 | Derivative option 1 * First derivatives 6 | Derivative line search * The default 7 | 8 | Major Print level 000001 9 | * (JFLXBT) 10 | Minor print level 1 11 | 12 | * Print frequency 1 13 | * Summary frequency 1 14 | 15 | Verify level 3 16 | 17 | * Objective row 0 * Would find a feasible point 18 | Solution Yes 19 | End HS problem 20 | 21 | -------------------------------------------------------------------------------- /matlab/examples/hs116/hs116M.spc: -------------------------------------------------------------------------------- 1 | Begin HS problem 2 | Major iterations 100 3 | Minor iterations 100 4 | 5 | Derivative option 1 * First derivatives 6 | Derivative line search * The default 7 | 8 | Major Print level 000001 9 | * (JFLXBT) 10 | Minor print level 1 11 | 12 | * Print frequency 1 13 | * Summary frequency 1 14 | 15 | Verify level 3 16 | 17 | * Objective row 0 * Would find a feasible point 18 | Solution Yes 19 | End HS problem 20 | 21 | -------------------------------------------------------------------------------- /matlab/examples/spring/springFun.m: -------------------------------------------------------------------------------- 1 | function [F] = springFun(x) 2 | 3 | [n,~] = size(x); 4 | T = (n - 2) / 3; 5 | ObjRow = 2*T + 1; 6 | 7 | lin = 1; nln = lin + T; 8 | jy0 = 1; jx0 = jy0 + T + 1; ju0 = jx0 + T + 1; 9 | 10 | F = zeros(2*T+1,1); 11 | fObj = 0; 12 | for jt = 0:T-1 13 | jy = jy0 + jt; jx = jx0 + jt; ju = ju0 + jt; 14 | 15 | yt = x(jy); ytp1 = x(jy+1); 16 | 17 | xt = x(jx); xtp1 = x(jx+1); 18 | 19 | ut = x(ju); 20 | 21 | F(nln) = 1e-2 * yt*yt - yt + ytp1 + 4e-3*xt - .2*ut; 22 | F(lin) = -.2*yt - xt + xtp1; 23 | fObj = fObj + xt*xt; 24 | 25 | nln = nln + 1; lin = lin + 1; 26 | end 27 | 28 | F(ObjRow) = (fObj + xtp1*xtp1)/2; -------------------------------------------------------------------------------- /matlab/util/snsummary.m: -------------------------------------------------------------------------------- 1 | %function snsummary( filename ) 2 | % Causes SNOPT to write summarized information about its progress 3 | % to the file named in "filename". 4 | % 5 | % "snsummary off" causes SNOPT to stop writing to filename, 6 | % and close the file. 7 | % 8 | % Note that until the file has been closed, it may not contain 9 | % all of the output. 10 | % 11 | % WARNING: Do not use snset() or snseti() to set the summary file. 12 | function snsummary( filename ) 13 | 14 | opensummary = 11; 15 | closesummary = 13; 16 | 17 | if strcmp( filename, 'off' ) 18 | snoptmex( closesummary ); 19 | else 20 | snoptmex( opensummary, filename ); 21 | end 22 | -------------------------------------------------------------------------------- /matlab/util/sqsummary.m: -------------------------------------------------------------------------------- 1 | %function sqsummary( filename ) 2 | % Causes SQOPT to write summarized information about its progress 3 | % to the file named in "filename". 4 | % 5 | % "sqsummary off" causes SQOPT to stop writing to filename, 6 | % and close the file. 7 | % 8 | % Note that until the file has been closed, it may not contain 9 | % all of the output. 10 | % 11 | % WARNING: Do not use sqset() or sqseti() to set the summary file. 12 | function sqsummary( filename ) 13 | 14 | opensummary = 11; 15 | closesummary = 13; 16 | 17 | if strcmp( filename, 'off' ) 18 | sqoptmex( closesummary ); 19 | else 20 | sqoptmex( opensummary, filename ); 21 | end 22 | -------------------------------------------------------------------------------- /matlab/util/snfindG.m: -------------------------------------------------------------------------------- 1 | function [Gvec] = snfindG(iGfun, jGvar, Gfull) 2 | %function [Gvec] = snfindG(iGfun, jGvar, Gfull) 3 | % Grabs elements in Gfull corresponding to 4 | % row and column indices (iGfun, jGvar). 5 | % 6 | % Note: We cannot simply use the Matlab 7 | % function find(), since it is crucial that 8 | % the order of Gvec correspond to iGfun, 9 | % and jGvar. Furthermore, zero 10 | % elements in Gfull must not be deleted 11 | % from Gvec. 12 | 13 | Gind = sub2ind(size(Gfull), iGfun, jGvar); 14 | Gvec = Gfull(Gind); 15 | 16 | % Avoid Gvec being stored in sparse format: 17 | Gvec = full(Gvec); 18 | m = size(Gvec,1); 19 | if m == 1, 20 | Gvec = Gvec'; 21 | end 22 | -------------------------------------------------------------------------------- /matlab/examples/sntoy/toyusrfun2.m: -------------------------------------------------------------------------------- 1 | function [F,G] = toyusrfun2(x) 2 | % [F,G] = toyusrfun2(x) 3 | % returns dense G. 4 | 5 | F = [ 3*x(1) + (x(1) + x(2) + x(3))^2 + 5*x(4); 6 | 4*x(2) + 2*x(3); 7 | x(1) + x(2)^2 + x(3)^2; 8 | x(2)^4 + x(3)^4 + x(4) ]; 9 | 10 | J = [ 1, 1, 2*(x(1)+x(2)+x(3)) + 3; 11 | 1, 2, 2*(x(1)+x(2)+x(3)); 12 | 1, 3, 2*(x(1)+x(2)+x(3)); 13 | 1, 4, 5; 14 | 2, 2, 4; 15 | 2, 3, 2; 16 | 3, 1, 1; 17 | 3, 2, 2*x(2); 18 | 3, 3, 2*x(3); 19 | 4, 2, 4*x(2)^3; 20 | 4, 3, 4*x(3)^3; 21 | 4, 4, 1 ]; 22 | 23 | iGfun = J(:,1); jGvar = J(:,2); G = J(:,3); 24 | G = sparse(iGfun,jGvar,G); 25 | G = full(G); 26 | -------------------------------------------------------------------------------- /matlab/util/colvec.m: -------------------------------------------------------------------------------- 1 | function x = colvec(y,name,emptyOK,n) 2 | % Return the column vector y. 3 | % If it's a row vector, return the transpose. 4 | % If it's netiher row or column, throw an error. 5 | % If it's empty and it's not allowed, throw an error. 6 | % If n > 0, check y has length n. 7 | % 8 | 9 | x = []; 10 | if isempty(y), 11 | if ~emptyOK, 12 | s = ['Error: ', name, ' must be a non-empty row or column vector']; 13 | error(s); 14 | end 15 | return; 16 | end 17 | 18 | if iscolumn(y), 19 | x = y; 20 | elseif isrow(y), 21 | x = y'; 22 | else 23 | s = ['Error: ', name, ' must be a row or column vector']; 24 | error(s); 25 | end 26 | 27 | if n > 0 && length(x) ~= n, 28 | s = ['Error: ', name, ' has to be of length ', num2str(n)]; 29 | error(s); 30 | end 31 | -------------------------------------------------------------------------------- /matlab/util/crd2spr.m: -------------------------------------------------------------------------------- 1 | function [neA,indA,locA,valA] = crd2spr(A) 2 | % Given matrix A, return A in sparse-by-column format 3 | % 4 | 5 | [m,n] = size(A); 6 | neA = 0; indA = []; locA = []; valA = []; 7 | 8 | if ( m == 0 ), 9 | return; 10 | end 11 | 12 | [iA,jA,vA] = find(A); 13 | neA = numel(vA); 14 | 15 | indA = zeros(neA,1); 16 | valA = zeros(neA,1); 17 | locA = zeros(n+1,1); 18 | 19 | for k = 1:neA, 20 | j = jA(k); 21 | locA(j) = locA(j) + 1; 22 | end 23 | locA(n+1) = neA+1; 24 | 25 | for k = n:-1:1, 26 | locA(k) = locA(k+1) - locA(k); 27 | end 28 | 29 | for k = 1:neA, 30 | j = jA(k); 31 | i = iA(k); 32 | ii = locA(j); 33 | 34 | valA(ii) = vA(k); 35 | indA(ii) = i; 36 | locA(j) = ii+1; 37 | end 38 | 39 | locA(2:n) = locA(1:n-1); 40 | locA(1) = 1; 41 | -------------------------------------------------------------------------------- /matlab/examples/t1diet/t1diet_lp.m: -------------------------------------------------------------------------------- 1 | function t1diet_lp() 2 | 3 | options.screen = 'on'; 4 | options.printfile = 't1dietLP.out'; 5 | options.specsfile = which('t1diet.spc'); 6 | 7 | 8 | % Linear objective term 9 | c = [3 24 13 9 20 19]; 10 | 11 | % Initial x and bounds on x 12 | x0 = ones (6,1); 13 | xlow = zeros(6,1); 14 | xupp = [ 4 15 | 3 16 | 2 17 | 8 18 | 2 19 | 2 ]; 20 | 21 | 22 | % Linear constraint matrix and bounds 23 | A = [ 110 205 160 160 420 260; 24 | 4 32 13 8 4 14; 25 | 2 12 54 285 22 80]; 26 | 27 | alow = [ 2000; 28 | 55; 29 | 800]; 30 | aupp = Inf*ones(3,1); 31 | 32 | options.name = 't1dietlp'; 33 | 34 | [x,obj,INFO,output,lambda,states] = lpopt(c, x0, xlow, xupp, ... 35 | A, alow, aupp, options); 36 | states 37 | lambda 38 | -------------------------------------------------------------------------------- /matlab/examples/sntoy/toyusrfun.m: -------------------------------------------------------------------------------- 1 | function [F,G] = toyusrfun(x) 2 | %function [F,G] = toyusrfun(x) 3 | % Defines the nonlinear part of the function and derivatives 4 | % for the toy problem. 5 | 6 | F = [ 3*x(1) + (x(1) + x(2) + x(3))^2 + 5*x(4); 7 | 4*x(2) + 2*x(3); 8 | x(1) + x(2)^2 + x(3)^2; 9 | x(2)^4 + x(3)^4 + x(4) ]; 10 | 11 | % Define the derivatives. 12 | % The coordinates aren't used but are included as a safety check. 13 | 14 | G = [ 1, 1, 2*(x(1)+x(2)+x(3)) + 3; 15 | 1, 2, 2*(x(1)+x(2)+x(3)); 16 | 1, 3, 2*(x(1)+x(2)+x(3)); 17 | 1, 4, 5; 18 | 2, 2, 4; 19 | 2, 3, 2; 20 | 3, 1, 1; 21 | 3, 2, 2*x(2); 22 | 3, 3, 2*x(3); 23 | 4, 2, 4*x(2)^3; 24 | 4, 3, 4*x(3)^3; 25 | 4, 4, 1 ]; 26 | 27 | G = G(:,3); 28 | -------------------------------------------------------------------------------- /matlab/util/solve_sqopt.m: -------------------------------------------------------------------------------- 1 | function [x,obj,info,output,lambda,states] = solve_sqopt(start,name,m,n,userHx, ... 2 | c, x0, xl, xu, xstate, xmul, ... 3 | neA, indA, locA, valA, ... 4 | al, au, astate, amul) 5 | %function [x,obj,info,output,lambda,states] = solve_sqopt(start,name,m,n,userHx, ... 6 | % c, x0, xl, xu, xstate, ... 7 | % xmul, ... 8 | % neA, indA, locA, valA, ... 9 | % al, au, astate, amul) 10 | % Wrapper for solving QPs 11 | 12 | mexopt = 1; 13 | [x,obj,info,itn,y,state] = sqoptmex(mexopt, start, name, ... 14 | m, n, userHx, c, ... 15 | x0, xl, xu, xstate, xmul, ... 16 | neA, indA, locA, valA, al, au, astate, amul); 17 | % Set output 18 | output.iterations = itn; 19 | output.info = info; 20 | 21 | states.x = state(1:n); 22 | lambda.x = y(1:n); 23 | 24 | if m > 0, 25 | states.linear = state(n+1:n+m); 26 | lambda.linear = y(n+1:n+m); 27 | end 28 | -------------------------------------------------------------------------------- /matlab/examples/snmain/snoptuserfun.m: -------------------------------------------------------------------------------- 1 | function [F] = snoptuserfun(x) 2 | %function [F] = snoptuserfun(x) 3 | % Computes F for the hexagon problem. 4 | 5 | F = [ x(2)*x(6) - x(1)*x(7) + x(3)*x(7) + x(5)*x(8) - x(4)*x(9) - x(3)*x(8); 6 | x(1)^2 + x(6)^2; 7 | (x(2) - x(1))^2 + (x(7) - x(6))^2; 8 | (x(3) - x(1))^2 + x(6)^2; 9 | (x(1) - x(4))^2 + (x(6) - x(8))^2; 10 | (x(1) - x(5))^2 + (x(6) - x(9))^2; 11 | x(2)^2 + x(7)^2; 12 | (x(3) - x(2))^2 + x(7)^2;; 13 | (x(4) - x(2))^2 + (x(8) - x(7))^2; 14 | (x(2) - x(5))^2 + (x(7) - x(9))^2; 15 | (x(4) - x(3))^2 + x(8)^2; 16 | (x(5) - x(3))^2 + x(9)^2; 17 | x(4)^2 + x(8)^2; 18 | (x(4) - x(5))^2 + (x(9) - x(8))^2; 19 | x(5)^2 + x(9)^2; 20 | -x(1) + x(2); 21 | -x(2) + x(3); 22 | x(3) - x(4); 23 | x(4) - x(5) ]; 24 | 25 | -------------------------------------------------------------------------------- /matlab/examples/hsmain/hsmainusrfun.m: -------------------------------------------------------------------------------- 1 | function [F,G] = hsmainusrfun(x) 2 | %function [F,G] = hsmainusrfun(x) 3 | % Defines the nonlinear part of the function and derivatives 4 | % for the problem HS47. 5 | 6 | % Nonlinear part of F. 7 | % The values of the linear rows are set to 0 (they are not used) 8 | 9 | F = [ 0; 10 | x(2)*x(2) + x(3)*x(3)*x(3); 11 | 0; 12 | -x(3)*x(3); 13 | x(1)*x(5); 14 | (x(1)-x(2))^2 + (x(2)-x(3))^3 + (x(3)-x(4))^4 + (x(4)-x(5))^4 ]; 15 | 16 | % Define the derivatives. 17 | % The coordinates aren't needed but we include them as a safety check. 18 | 19 | Obj = 6; 20 | 21 | G = [ Obj, 1, 2*(x(1)-x(2)); 22 | Obj, 2, 3*(x(2)-x(3))^2 - 2*(x(1)-x(2)); 23 | Obj, 3, 4*(x(3)-x(4))^3 - 3*(x(2)-x(3))^2; 24 | Obj, 4, 4*(x(4)-x(5))^3 - 4*(x(3)-x(4))^3; 25 | Obj, 5, -4*(x(4)-x(5))^3; 26 | 2, 2, 2* x(2); 27 | 2, 3, 3* x(3)^2; 28 | 4, 3, -2* x(3); 29 | 5, 1, x(5); 30 | 5, 5, x(1) ]; 31 | G = G(:,3); 32 | -------------------------------------------------------------------------------- /matlab/util/solve_snopt.m: -------------------------------------------------------------------------------- 1 | function [x,F,inform,xmul,Fmul,xstate,Fstate,output] = solve_snopt(start,stopFun,name,userfun,x, ... 2 | xlow, xupp, xmul, xstate,... 3 | Flow, Fupp, Fmul, Fstate,... 4 | ObjAdd, ObjRow, ... 5 | A, iAfun, jAvar, iGfun, ... 6 | jGvar) 7 | %function [x,F,inform,xmul,Fmul,xstate,Fstate,output] = solve_snopt(start,stopFun,name,userfun,x, ... 8 | % xlow, xupp, xmul, xstate,... 9 | % Flow, Fupp, Fmul, Fstate,... 10 | % ObjAdd, ObjRow, ... 11 | % A, iAfun, jAvar, iGfun, ... 12 | % jGvar) 13 | % Wrapper for solving NLPs 14 | 15 | mexopt = 1; 16 | [x,F,inform,xmul,Fmul, ... 17 | xstate,Fstate,itn,mjritn] = snoptmex(mexopt, ... 18 | start, stopFun, name, ... 19 | userfun, x, ... 20 | xlow, xupp, xmul, xstate, ... 21 | Flow, Fupp, Fmul, Fstate, ... 22 | ObjAdd, ObjRow, ... 23 | A, iAfun, jAvar, ... 24 | iGfun, jGvar); 25 | 26 | output.info = inform; 27 | output.iterations = itn; 28 | output.majors = mjritn; 29 | 30 | -------------------------------------------------------------------------------- /matlab/examples/sntoy/sntoy2.m: -------------------------------------------------------------------------------- 1 | function [x,F,inform] = sntoy2() 2 | %function [x,F,inform] = sntoy2() 3 | %Mimics sntoyA.f in $SNOPT/examples 4 | % Minimize 3*x(1) + (x(1) + x(2) + x(3))^2 + 5*x(4) 5 | % 6 | % subject to 4*x(2) + 2*x(3) >= 0 7 | % x(1) + x(2)^2 + x(3)^2 = 2 8 | % x(2)^4 + x(3)^4 + x(4) = 4 9 | % 10 | % x(1) >= 0, x(4) >= 0. 11 | % 12 | 13 | options.name = 'sntoy2'; 14 | options.screen = 'on'; 15 | 16 | options.printfile = 'sntoy2.out'; % By default, screen output is on; 17 | options.specsfile = which('sntoy2.spc'); 18 | 19 | x = ones(4,1); 20 | xstate = zeros(4,1); 21 | xmul = zeros(4,1); 22 | xlow = [ 0,-Inf,-Inf, 0]'; 23 | xupp = [ Inf, Inf, Inf, Inf]'; 24 | 25 | Fmul = zeros(4,1); 26 | Fstate = zeros(4,1); 27 | Flow = [-Inf, 0, 2, 4]'; 28 | Fupp = [ Inf, Inf, 2, 4]'; 29 | 30 | [x,F,inform] = snopt(x,xlow,xupp,xmul,xstate, ... 31 | Flow,Fupp,Fmul,Fstate,@toyusrfun2,options); 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 snopt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /matlab/README: -------------------------------------------------------------------------------- 1 | 2 | Using the SNOPT mex Files in $SNOPT/matlab 3 | ========================================== 4 | 5 | Run Matlab in the directory $SNOPT/matlab. 6 | 7 | At the Matlab prompt, type 8 | 9 | >> runQPExamples % for qpopt 10 | >> runNPExamples % for snopt 11 | 12 | This script sets the matlab path appropriately. 13 | 14 | The subdirectory ./examples contains various sample problems 15 | that demonstrate how to use the snOpt Matlab interfaces. Read 16 | the in-line help information for each m-file for more 17 | information. To run the individual m-files type 18 | 19 | >> setpath % if you haven't already called run**Examples script 20 | >> snoptmain 21 | 22 | SNOPT can be called via the Matlab m-file functions "snopt" and "snsolve". 23 | snopt is similar to the Fortran version of SNOPTA. snsolve is based off 24 | Matlab's "fmincon". 25 | 26 | 27 | If you provide the derivatives of your problem functions be sure to check them 28 | first by setting the option:using the command: 29 | >> option.verify_level = 3; 30 | 31 | 32 | BOTTOM LINE: The more information you give, the FASTER and MORE RELIABLE the solve. 33 | (the LONGER THE ARGUMENT LIST, the FASTER and MORE RELIABLE the solve) 34 | -------------------------------------------------------------------------------- /matlab/examples/hs76/hs76.m: -------------------------------------------------------------------------------- 1 | function [x,Obj,INFO] = hs76 2 | % Matlab example quadratic problem 3 | % This example calls SQOPT. 4 | % 5 | % HS 76 6 | % 7 | % min f'x + 1/2 * x'Hx 8 | % 9 | % subject to x(1) + 2*x(2) + x(3) + x(4) <= 5 10 | % 3*x(1) + x(2) + 2*x(3) - x(4) <= 4 11 | % - x(2) - 4*x(3) <= -1.5 12 | % x >= 0 13 | % 14 | 15 | % Add path to SQOPT matlab files 16 | addpath([pwd,'/../../'], '-end'); 17 | 18 | options.name = 'hs76'; 19 | options.screen = 'on'; 20 | options.printfile = 'hs76.out'; 21 | options.specsfile = which('hs76.spc'); 22 | 23 | 24 | % Set up the problem 25 | m = 3; 26 | n = 4; 27 | x0 = zeros(n,1); 28 | x0 = [ .5; .5; .5; .5 ]; 29 | 30 | % Linear objective term 31 | f = [ -1 -3 1 -1 ]'; 32 | 33 | % Linear constraint matrix 34 | A = [ 1 2 1 1 ; 35 | 3 1 2 -1 ; 36 | 0 -1 -4 0 ]; 37 | 38 | al = []; % No lower bounds A*x 39 | au = [ 5; 4; -1.5 ]; 40 | 41 | % Lower and upper bounds on x >= 0 42 | xl = zeros(n,1); 43 | xu = []; % No upper bounds on x 44 | 45 | % Hessian 46 | H = [ 2 0 -1 0 ; 47 | 0 1 0 0 ; 48 | -1 0 2 1 ; 49 | 0 0 1 1 ]; 50 | 51 | % Solve the problem. 52 | [x,Obj,INFO,lambda,states,output] = sqopt(H, f, x0, xl, xu, A, al, au); 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /matlab/examples/fmincon/toymin.m: -------------------------------------------------------------------------------- 1 | function [x,fval,INFO]=toymin 2 | % Mimics sntoyA.f in $SNOPT/examples 3 | % Example of the 'fmincon'-style call to SNOPT. 4 | % 5 | % Minimize 3*x(1) + (x(1) + x(2) + x(3))^2 + 5*x(4) 6 | % 7 | % subject to 4*x(2) + 2*x(3) >= 0 8 | % x(1) + x(2)^2 + x(3)^2 = 2 9 | % x(2)^4 + x(3)^4 + x(4) = 4 10 | % 11 | % x(1) >= 0, x(4) >= 0. 12 | % 13 | % 14 | 15 | 16 | options.screen = 'on'; 17 | options.printfile = 'toymin.out'; 18 | options.specsfile = which('sntoy.spc'); 19 | 20 | x0 = ones(4,1); 21 | A = [ 0 -4 -2 0]; 22 | b = [ 0 ]; 23 | Aeq = []; 24 | beq = []; 25 | 26 | lb = [ 0,-Inf,-Inf, 0]'; 27 | ub = Inf*ones(4,1); 28 | 29 | options.name = 'toyprob'; 30 | options.stop = @toySTOP; 31 | 32 | [x,fval,INFO,output,lambda,states] = snsolve(@toyObj, x0, A, b, Aeq, beq, lb, ub, ... 33 | @toyCon, options); 34 | 35 | 36 | 37 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 38 | function [iAbort] = toySTOP(itn, nMajor, nMinor, condZHZ, obj, merit, step, ... 39 | primalInf, dualInf, maxViol, maxViolRel, ... 40 | x, xlow, xupp, xmul, xstate, ... 41 | F, Flow, Fupp, Fmul, Fstate) 42 | 43 | % Called every major iteration 44 | % Use iAbort to stop SNOPT (if iAbort == 0, continue; else stop) 45 | 46 | iAbort = 0 47 | 48 | 49 | -------------------------------------------------------------------------------- /matlab/runNPexamples.m: -------------------------------------------------------------------------------- 1 | %Test Script. 2 | 3 | format compact; 4 | setpath; % defines the path 5 | 6 | fprintf('\n============================================================= '); 7 | fprintf('\nt1diet: Solving diet LP problem using SNOPT ... '); 8 | t1diet; 9 | 10 | fprintf('\n============================================================= '); 11 | fprintf('\nsntoy: Solving toy problem using SNOPT ... '); 12 | sntoy; 13 | 14 | fprintf('\n============================================================= '); 15 | fprintf('\ntoymin: Solving toy problem using fmincon-style SNOPT ... '); 16 | toymin; 17 | 18 | fprintf('\n============================================================= '); 19 | fprintf('\nhsmain: snopt solves hs47 ... '); 20 | hsmain; 21 | 22 | fprintf('\n============================================================= '); 23 | fprintf('\nsntoy2: snopt solves toy problem ... '); 24 | sntoy2; 25 | 26 | fprintf('\n============================================================= '); 27 | fprintf('\nsnoptmain: snopt solves hexagon with no derivatives ... '); 28 | snoptmain; 29 | 30 | fprintf('\n============================================================= '); 31 | fprintf('\nsnoptmain2: snopt solves hexagon with dense Jacobian ... '); 32 | snoptmain2; 33 | 34 | fprintf('\n============================================================= '); 35 | fprintf('\nsnoptmain3: snopt solves hexagon with some derivatives ... '); 36 | snoptmain3; 37 | 38 | fprintf('\n============================================================= '); 39 | fprintf('\nhs116: snopt solves hs116 ... '); 40 | hs116; 41 | 42 | fprintf('\n============================================================= '); 43 | fprintf('\nspring: snopt solves spring ... '); 44 | springa; 45 | -------------------------------------------------------------------------------- /matlab/examples/hsmain/hs13.m: -------------------------------------------------------------------------------- 1 | function [x,F,xmul,Fmul,INFO] = hs13() 2 | % HS 13 (modified so CQ holds) 3 | % 4 | % Minimize x(1) + x(2) 5 | % 6 | % subject to x(1)^3 - x(2) >= 0 7 | % 8 | % x(2) >= 1. 9 | % 10 | % 11 | 12 | options.name = 'hs13'; 13 | options.screen = 'on'; 14 | 15 | options.printfile = 'hs13.out'; % By default, screen output is off; 16 | options.specsfile = which('hs13.spc'); 17 | 18 | [x,xlow,xupp,xmul,xstate, ... 19 | Flow,Fupp,Fmul,Fstate, ... 20 | ObjAdd,ObjRow, ... 21 | A.val,A.row,A.col,G.row,G.col] = hs13data; 22 | 23 | [x,F,INFO]= snopt(x, xlow, xupp, xmul, xstate, ... 24 | Flow, Fupp, Fmul, Fstate, ... 25 | 'hs13userfun', ObjAdd, ObjRow, ... 26 | A, G, options); 27 | 28 | 29 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 30 | function [x,xlow,xupp,xmul,xstate, ... 31 | Flow,Fupp,Fmul,Fstate, ... 32 | ObjAdd,ObjRow,A,iAfun,jAvar,iGfun,jGvar] = hs13data() 33 | 34 | ObjRow = 1; 35 | ObjAdd = 0; 36 | 37 | x = [ 3 1]'; 38 | xlow = [-Inf, 1 ]'; 39 | xupp = [ Inf, Inf]'; 40 | xmul = zeros(2,1); 41 | xstate = zeros(2,1); 42 | 43 | Flow = [ -Inf, 0]'; 44 | Fupp = [ Inf, Inf]'; 45 | Fmul = zeros(2,1); 46 | Fstate = zeros(2,1); 47 | 48 | % ------------------------------------------------------------------ 49 | % The nonzero pattern of the Jacobian is as follows: 50 | % 51 | % Column 52 | % | 1 2 53 | % +-------- 54 | % row 1 | G G Objective row 55 | % 2 | G G 56 | % 57 | % 58 | 59 | A = []; 60 | iAfun = []; 61 | jAvar = []; 62 | 63 | G = [ 1, 1; 64 | 1, 2; 65 | 2, 1; 66 | 2, 2 ]; 67 | 68 | iGfun = G(:,1); jGvar = G(:,2); 69 | -------------------------------------------------------------------------------- /matlab/examples/hs116/hs116userfun.m: -------------------------------------------------------------------------------- 1 | function [F,G] = hs116userfun(x) 2 | % Defines nonlinear terms of F and derivatives for HS 116. 3 | % Linear constraints are explicit. 4 | 5 | % Parameters 6 | a = 2e-3; 7 | b = 1.262626; 8 | c = 1.231059; 9 | d = 3.475e-2; 10 | e = 9.75e-1; 11 | f = 9.75e-3; 12 | Obj = 5; 13 | 14 | F = [ 1, 0; 15 | 2, 0; 16 | 3, 0; 17 | 4, 0; 18 | 5, 0; 19 | 6, -b*x(10) + c*x(3)*x(10); % 20 | 7, x(5) - d*x(2) - e*x(2)*x(5) + f*x(2)^2; % 21 | 8, x(6) - d*x(3) - e*x(3)*x(6) + f*x(3)^2; % 22 | 9, x(4) - d*x(1) - e*x(1)*x(4) + f*x(1)^2; % 23 | 10, -b*x(9) + c*x(2)*x(9); % 24 | 11, -b*x(8) + c*x(1)*x(8); % 25 | 12, x(5)*x(7) - x(1)*x(8) - x(4)*x(7) + x(4)*x(8); % 26 | 13, x(6) + x(5) + a*(x(2)*x(9) + x(5)*x(8) - x(1)*x(8) - x(6)*x(9)); % 27 | 14, -500*(x(2) - x(6)) + x(2)*x(9) - x(3)*x(10) - x(6)*x(9) + x(2)*x(10); % 28 | 15, x(2) - a*(x(2)*x(10) - x(3)*x(10)) ]; % 29 | F = F(:,2); 30 | 31 | if nargout > 1, 32 | % Define the derivatives. 33 | G = [ 6, 3, c*x(10); 34 | 6, 10, -b + c*x(3); 35 | 7, 2, -d - e*x(5) + 2*f*x(2); 36 | 7, 5, 1 - e*x(2); 37 | 8, 3, -d - e*x(6) + 2*f*x(3); 38 | 8, 6, 1 - e*x(3); 39 | 9, 1, -d - e*x(4) + 2*f*x(1); 40 | 9, 4, 1 - e*x(1); 41 | 10, 2, c*x(9); 42 | 10, 9, -b + c*x(2); 43 | 11, 1, c*x(8); 44 | 11, 8, -b + c*x(1); 45 | 12, 1, -x(8); 46 | 12, 4, -x(7) + x(8); 47 | 12, 5, x(7); 48 | 12, 7, x(5) - x(4); 49 | 12, 8, -x(1) + x(4); 50 | 13, 1, -a*x(8); 51 | 13, 2, a*x(9); 52 | 13, 5, 1 + a*x(8); 53 | 13, 6, 1 - a*x(9); 54 | 13, 8, a*(x(5) - x(1)); 55 | 13, 9, a*(x(2) - x(6)); 56 | 14, 2, -500 + x(9) + x(10); 57 | 14, 3, -x(10); 58 | 14, 6, 500 - x(9); 59 | 14, 9, x(2) - x(6); 60 | 14, 10, -x(3) + x(2); 61 | 15, 2, 1 - a*x(10); 62 | 15, 3, a*x(10); 63 | 15, 10, -a*(x(2) - x(3)) ]; 64 | G = G(:,3); 65 | end 66 | -------------------------------------------------------------------------------- /matlab/examples/sntoy/sntoy.m: -------------------------------------------------------------------------------- 1 | function [x,F,xmul,Fmul,INFO] = sntoy() 2 | %Mimics sntoyA.f in $SNOPT/examples 3 | % 4 | % Minimize 3*x(1) + (x(1) + x(2) + x(3))^2 + 5*x(4) 5 | % 6 | % subject to 4*x(2) + 2*x(3) >= 0 7 | % x(1) + x(2)^2 + x(3)^2 = 2 8 | % x(2)^4 + x(3)^4 + x(4) = 4 9 | % 10 | % x(1) >= 0, x(4) >= 0. 11 | % 12 | % 13 | 14 | options.name = 'sntoy'; 15 | options.screen = 'on'; 16 | options.printfile = 'sntoy.out'; 17 | options.specsfile = which('sntoy.spc'); 18 | 19 | [x,xlow,xupp,xmul,xstate, ... 20 | Flow,Fupp,Fmul,Fstate, ... 21 | ObjAdd,ObjRow,A.val,A.row,A.col,G.row,G.col] = toydata; 22 | 23 | [x,F,INFO]= snopt(x, xlow, xupp, xmul, xstate, ... 24 | Flow, Fupp, Fmul, Fstate, ... 25 | @toyusrfun, ObjAdd, ObjRow, ... 26 | A, G, options); 27 | 28 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 29 | function [x,xlow,xupp,xmul,xstate, ... 30 | Flow,Fupp,Fmul,Fstate, ... 31 | ObjAdd,ObjRow,A,iAfun,jAvar,iGfun,jGvar] = toydata() 32 | 33 | ObjRow = 1; 34 | ObjAdd = 0; 35 | 36 | x = ones(4,1); 37 | xlow = [ 0,-Inf,-Inf, 0]'; 38 | xupp = [Inf, Inf, Inf, Inf]'; 39 | xmul = []; xstate = []; 40 | 41 | Flow = [ -Inf, 0, 2, 4]'; 42 | Fupp = [ Inf, Inf, 2, 4]'; 43 | Fmul = []; Fstate = []; 44 | 45 | % ------------------------------------------------------------------ 46 | % The nonzero pattern of the Jacobian is as follows: 47 | % 48 | % Column 49 | % | 1 2 3 4 50 | % +------------------ 51 | % row 1 | G G G G Objective row 52 | % 2 | G G 53 | % 3 | G G G 54 | % 4 | G G G 55 | % 56 | % 57 | 58 | A = []; 59 | iAfun = []; 60 | jAvar = []; 61 | 62 | G = [ 1, 1; 63 | 1, 2; 64 | 1, 3; 65 | 1, 4; 66 | 2, 2; 67 | 2, 3; 68 | 3, 1; 69 | 3, 2; 70 | 3, 3; 71 | 4, 2; 72 | 4, 3; 73 | 4, 4 ]; 74 | 75 | iGfun = G(:,1); jGvar = G(:,2); 76 | -------------------------------------------------------------------------------- /matlab/examples/spring/springa.m: -------------------------------------------------------------------------------- 1 | function [x,F,xmul,Fmul,INFO] = springa() 2 | 3 | 4 | options.screen = 'on'; 5 | options.printfile = 'spring.out'; 6 | options.specsfile = which('spring.spc'); 7 | options.name = 'spring'; 8 | 9 | [x,xlow,xupp,xmul,xstate, ... 10 | Flow,Fupp,Fmul,Fstate, ... 11 | ObjAdd,ObjRow] = springData; 12 | 13 | [x,F,INFO,xmul,Fmul]= snopt(x, xlow, xupp, xmul, xstate, ... 14 | Flow, Fupp, Fmul, Fstate, ... 15 | @springFun, ObjAdd, ObjRow, options); 16 | 17 | 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | function [x,xlow,xupp,xmul,xstate, ... 20 | Flow,Fupp,Fmul,Fstate, ... 21 | ObjAdd,ObjRow] = springData() 22 | 23 | T = 100; 24 | 25 | n = 3*T + 2; 26 | nCon = 2*T; 27 | nF = nCon + 1; 28 | 29 | Obj = nF; 30 | ObjRow = Obj; 31 | 32 | ObjAdd = 0; 33 | 34 | x = zeros(n,1); 35 | xstate = zeros(n,1); 36 | xmul = zeros(n,1); 37 | xlow = -inf*ones(n,1); 38 | xupp = inf*ones(n,1); 39 | 40 | F = zeros(nF,1); 41 | Fstate = zeros(nF,1); 42 | Fmul = zeros(nF,1); 43 | Flow = -inf*ones(nF,1); 44 | Fupp = inf*ones(nF,1); 45 | 46 | jy0 = 1; jx0 = jy0 + T + 1; ju0 = jx0 + T + 1; 47 | 48 | for jt = 0:T 49 | jy = jy0 + jt; jx = jx0 + jt; 50 | 51 | xlow(jx) = -inf; xupp(jx) = inf; 52 | x(jx) = 0; xstate(jx) = 3; 53 | 54 | xlow(jy) = -1; xupp(jy) = inf; 55 | x(jy) = -1; xstate(jy) = 0; 56 | 57 | if jt < T, 58 | ju = ju0 + jt; 59 | 60 | xlow(ju) = -.2; xupp(ju) = .2; 61 | x(ju) = 0; xstate(ju) = 3; 62 | end 63 | end 64 | 65 | 66 | % Boundary conditions 67 | xlow(jy0) = 0; xupp(jy0) = 0; 68 | xlow(jy0+T) = 0; xupp(jy0+T) = 0; x(jy0+T) = 0; 69 | xlow(jx0) = 10; xupp(jx0+T) = 10; x(jx0+T) = 10; 70 | 71 | % Bounds on F 72 | Flow(1:nCon) = 0; Fupp(1:nCon) = 0; Fmul(1:nCon) = 0; 73 | Flow(ObjRow) = -inf; Fupp(ObjRow) = inf; Fmul(ObjRow) = 0; 74 | 75 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 76 | -------------------------------------------------------------------------------- /matlab/util/solve_snfmincon.m: -------------------------------------------------------------------------------- 1 | function [x,fval,exitflag,output,lambda,states] = solve_snfmincon(start, stopFun, ... 2 | name, userfun, x0, xlow, ... 3 | xupp, xmul, xstate, ... 4 | Flow, Fupp, Fmul, Fstate, ... 5 | ObjAdd, ObjRow, ... 6 | Aij, iAfun, jAvar, iGfun,jGvar, ... 7 | n, nonlin_ineq, nonlin_eq, ... 8 | linear_ineq, linear_eq) 9 | % function [x,fval,exitflag,output,lambda,states] = solve_snfmincon(start, stopFun, ... 10 | % name, userfun, x0, xlow, ... 11 | % xupp, xmul, xstate, ... 12 | % Flow, Fupp, Fmul, Fstate, ... 13 | % ObjAdd, ObjRow, ... 14 | % Aij, iAfun, jAvar, iGfun, ... 15 | % jGvar) 16 | 17 | 18 | mexopt = 1; 19 | [x,F,exitflag,xmul,Fmul,xstate,Fstate,itn,mjritn] = ... 20 | snoptmex(mexopt, ... 21 | start, stopFun, name, ... 22 | userfun, x0, ... 23 | xlow, xupp, xmul, xstate, ... 24 | Flow, Fupp, Fmul, Fstate, ... 25 | ObjAdd, ObjRow, ... 26 | Aij, iAfun, jAvar, iGfun, jGvar); 27 | 28 | 29 | fval = F(1); 30 | zero = zeros(n,1); 31 | states.x = xstate(1:n); 32 | lambda.x = xmul(1:n); 33 | 34 | if nonlin_ineq > 0, 35 | i1 = 1+1; i2 = i1-1 + nonlin_ineq; 36 | lambda.ineqnonlin = Fmul(i1:i2); 37 | states.ineqnonlin = Fstate(i1:i2); 38 | else 39 | lambda.ineqnonlin = []; 40 | states.ineqnonlin = []; 41 | end 42 | 43 | if nonlin_eq > 0, 44 | i1 = 1+nonlin_ineq; i2 = i1-1 + nonlin_eq; 45 | lambda.eqnonlin = Fmul(i1:i2); 46 | states.eqnonlin = Fmul(i1:i2); 47 | else 48 | lambda.eqnonlin = []; 49 | states.eqnonlin = []; 50 | end 51 | 52 | if linear_ineq > 0, 53 | i1 = 1+nonlin_ineq+nonlin_eq; i2 = i1-1 + linear_ineq; 54 | lambda.ineqlin = Fmul(i1:i2); 55 | states.ineqlin = Fmul(i1:i2); 56 | else 57 | lambda.ineqlin = []; 58 | states.ineqlin = []; 59 | end 60 | 61 | if linear_eq > 0, 62 | i1 = 1+nonlin_ineq+nonlin_eq+linear_ineq; i2 = i1-1 + linear_eq; 63 | lambda.eqlin = Fmul(i1:i2); 64 | states.eqlin = Fmul(i1:i2); 65 | else 66 | lambda.eqlin = []; 67 | states.eqlin = []; 68 | end 69 | 70 | output.info = exitflag; 71 | output.iterations = itn; 72 | output.majors = mjritn; 73 | -------------------------------------------------------------------------------- /matlab/examples/hs116/hs116userfunM.m: -------------------------------------------------------------------------------- 1 | function [F,G] = hs116userfunM(x) 2 | % Defines nonlinear terms of F and derivatives for HS 116. 3 | % Linear constraints are explicit. 4 | 5 | % Parameters 6 | a = 2e-3; 7 | b = 1.262626; 8 | c = 1.231059; 9 | d = 3.475e-2; 10 | e = 9.75e-1; 11 | f = 9.75e-3; 12 | Obj = 5; 13 | 14 | F = [ 1, 0; 15 | 2, 0; 16 | 3, 0; 17 | 4, 0; 18 | 5, 0; 19 | 6, x(13) - b*x(10) + c*x(3)*x(10); % 20 | 7, x(5) - d*x(2) - e*x(2)*x(5) + f*x(2)^2; % 21 | 8, x(6) - d*x(3) - e*x(3)*x(6) + f*x(3)^2; % 22 | 9, x(4) - d*x(1) - e*x(1)*x(4) + f*x(1)^2; % 23 | 10, x(12) - b*x(9) + c*x(2)*x(9); % 24 | 11, x(11) - b*x(8) + c*x(1)*x(8); % 25 | 12, x(5)*x(7) - x(1)*x(8) - x(4)*x(7) + x(4)*x(8); % 26 | 13, x(6) + x(5) + a*(x(2)*x(9) + x(5)*x(8) - x(1)*x(8) - x(6)*x(9)); % 27 | 14, -500*(x(2) - x(6)) + x(2)*x(9) - x(3)*x(10) - x(6)*x(9) + x(2)*x(10); % 28 | 15, x(2) - a*(x(2)*x(10) - x(3)*x(10)) ]; % 29 | F = F(:,2); 30 | 31 | % Define the derivatives. 32 | Obj = 5; 33 | G = [ 6, 3, c*x(10); 34 | 6, 10, -b + c*x(3); 35 | 6, 13, 1; 36 | 7, 2, -d - e*x(5) + 2*f*x(2); 37 | 7, 5, 1 - e*x(2); 38 | 8, 3, -d - e*x(6) + 2*f*x(3); 39 | 8, 6, 1 - e*x(3); 40 | 9, 1, -d - e*x(4) + 2*f*x(1); 41 | 9, 4, 1 - e*x(1); 42 | 10, 2, c*x(9); 43 | 10, 9, -b + c*x(2); 44 | 10, 12, 1; 45 | 11, 1, c*x(8); 46 | 11, 8, -b + c*x(1); 47 | 11, 11, 1; 48 | 12, 1, -x(8); 49 | 12, 4, -x(7) + x(8); 50 | 12, 5, x(7); 51 | 12, 7, x(5) - x(4); 52 | 12, 8, -x(1) + x(4); 53 | 13, 1, -a*x(8); 54 | 13, 2, a*x(9); 55 | 13, 5, 1 + a*x(8); 56 | 13, 6, 1 - a*x(9); 57 | 13, 8, a*(x(5) - x(1)); 58 | 13, 9, a*(x(2) - x(6)); 59 | 14, 2, -500 + x(9) + x(10); 60 | 14, 3, -x(10); 61 | 14, 6, 500 - x(9); 62 | 14, 9, x(2) - x(6); 63 | 14, 10, -x(3) + x(2); 64 | 15, 2, 1 - a*x(10); 65 | 15, 3, a*x(10); 66 | 15, 10, -a*(x(2) - x(3)) ]; 67 | G = G(:,3); 68 | -------------------------------------------------------------------------------- /matlab/examples/t1diet/t1diet.m: -------------------------------------------------------------------------------- 1 | function [x,F,xmul,Fmul,INFO] = t1diet() 2 | 3 | options.printfile = 't1diet.out'; 4 | options.specsfile = which('t1diet.spc'); 5 | 6 | [x,xlow,xupp,xmul,xstate, ... 7 | Flow,Fupp,Fmul,Fstate, ... 8 | ObjAdd,ObjRow,A.val,A.row,A.col,G.row,G.col] = dietdata; 9 | 10 | [x,F,INFO,xmul,Fmul,xstate,Fstate,output]= snopt( x, xlow, xupp, xmul, xstate, ... 11 | Flow, Fupp, Fmul, Fstate, ... 12 | @t1dietuserfun, ObjAdd, ObjRow, ... 13 | A, G, options); 14 | 15 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 | function [x,xlow,xupp,xmul,xstate, ... 17 | Flow,Fupp,Fmul,Fstate, ... 18 | ObjAdd,ObjRow,A,iAfun,jAvar,iGfun,jGvar] = dietdata() 19 | % dietdata defines input data for the Diet LP problem of Chvatal, 1983. 20 | % 21 | % 22 | % ( 110 205 160 160 420 260 ) 23 | % A = ( 4 32 13 8 4 14 ) 24 | % ( 2 12 54 285 22 80 ) 25 | % ( 3 24 13 9 20 19 ) ( = objective row c') 26 | % 27 | 28 | neF = 4; 29 | n = 6; 30 | Obj = 4; 31 | ObjRow = 4; 32 | 33 | G = []; iGfun = []; jGvar = []; 34 | 35 | % Assign the constant part of the Jacobian 36 | % (i,j,Aij) = (rowNumber, colNumber, Element) 37 | 38 | A = [ 1, 1, 110 39 | 1, 2, 205 40 | 1, 3, 160 41 | 1, 4, 160 42 | 1, 5, 420 43 | 1, 6, 260 44 | 2, 1, 4 45 | 2, 2, 32 46 | 2, 3, 13 47 | 2, 4, 8 48 | 2, 5, 4 49 | 2, 6, 14 50 | 3, 1, 2 51 | 3, 2, 12 52 | 3, 3, 54 53 | 3, 4, 285 54 | 3, 5, 22 55 | 3, 6, 80 56 | Obj, 1, 3 57 | Obj, 2, 24 58 | Obj, 3, 13 59 | Obj, 4, 9 60 | Obj, 5, 20 61 | Obj, 6, 19 ]; 62 | 63 | iAfun = A(:,1); jAvar = A(:,2); A = A(:,3); 64 | 65 | ObjAdd = 0; 66 | 67 | % Initial x. 68 | 69 | x = ones (n,1); 70 | 71 | xlow = zeros(n,1); 72 | xupp = [ 4 73 | 3 74 | 2 75 | 8 76 | 2 77 | 2 ]; 78 | 79 | Flow = [ 2000; 80 | 55; 81 | 800; 82 | -Inf ]; 83 | Fupp = Inf*ones(neF,1); 84 | 85 | xstate = zeros(n,1); 86 | xmul = zeros(n,1); 87 | 88 | Fstate = zeros(neF,1); 89 | Fmul = zeros(neF,1); 90 | -------------------------------------------------------------------------------- /matlab/examples/hs116/hs116Guserfun.m: -------------------------------------------------------------------------------- 1 | function [F,G] = hs116userfun(x) 2 | % Defines nonlinear terms of F and derivatives for HS 116. 3 | 4 | % Parameters 5 | a = 2e-3; 6 | b = 1.262626; 7 | c = 1.231059; 8 | d = 3.475e-2; 9 | e = 9.75e-1; 10 | f = 9.75e-3; 11 | Obj = 5; 12 | 13 | F = [ 1, x(3) - x(2); 14 | 2, x(2) - x(1); 15 | 3, a*x(7) - a*x(8); 16 | 4, x(11) + x(12) + x(13); 17 | 5, x(11) + x(12) + x(13); 18 | 6, x(13) - b*x(10) + c*x(3)*x(10); % 19 | 7, x(5) - d*x(2) - e*x(2)*x(5) + f*x(2)^2; % 20 | 8, x(6) - d*x(3) - e*x(3)*x(6) + f*x(3)^2; % 21 | 9, x(4) - d*x(1) - e*x(1)*x(4) + f*x(1)^2; % 22 | 10, x(12) - b*x(9) + c*x(2)*x(9); % 23 | 11, x(11) - b*x(8) + c*x(1)*x(8); % 24 | 12, x(5)*x(7) - x(1)*x(8) - x(4)*x(7) + x(4)*x(8); % 25 | 13, x(6) + x(5) + a*(x(2)*x(9) + x(5)*x(8) - x(1)*x(8) - x(6)*x(9)); % 26 | 14, -500*(x(2) - x(6)) + x(2)*x(9) - x(3)*x(10) - x(6)*x(9) + x(2)*x(10); % 27 | 15, x(2) - a*(x(2)*x(10) - x(3)*x(10)) ]; % 28 | F = F(:,2); 29 | 30 | % Define the derivatives. 31 | Obj = 5; 32 | G = [ 1, 2, -1; 33 | 1, 3, 1; 34 | 2, 1, -1; 35 | 2, 2, 1; 36 | 3, 7, a; 37 | 3, 8, -a; 38 | 4, 11, 1; 39 | 4, 12, 1; 40 | 4, 13, 1; 41 | Obj, 11, 1; 42 | Obj, 12, 1; 43 | Obj, 13, 1; 44 | 6, 3, c*x(10); 45 | 6, 10, -b + c*x(3); 46 | 6, 13, 1; 47 | 7, 2, -d - e*x(5) + 2*f*x(2); 48 | 7, 5, 1 - e*x(2); 49 | 8, 3, -d - e*x(6) + 2*f*x(3); 50 | 8, 6, 1 - e*x(3); 51 | 9, 1, -d - e*x(4) + 2*f*x(1); 52 | 9, 4, 1 - e*x(1); 53 | 10, 2, c*x(9); 54 | 10, 9, -b + c*x(2); 55 | 10, 12, 1; 56 | 11, 1, c*x(8); 57 | 11, 8, -b + c*x(1); 58 | 11, 11, 1; 59 | 12, 1, -x(8); 60 | 12, 4, -x(7) + x(8); 61 | 12, 5, x(7); 62 | 12, 7, x(5) - x(4); 63 | 12, 8, -x(1) + x(4); 64 | 13, 1, -a*x(8); 65 | 13, 2, a*x(9); 66 | 13, 5, 1 + a*x(8); 67 | 13, 6, 1 - a*x(9); 68 | 13, 8, a*(x(5) - x(1)); 69 | 13, 9, a*(x(2) - x(6)); 70 | 14, 2, -500 + x(9) + x(10); 71 | 14, 3, -x(10); 72 | 14, 6, 500 - x(9); 73 | 14, 9, x(2) - x(6); 74 | 14, 10, -x(3) + x(2); 75 | 15, 2, 1 - a*x(10); 76 | 15, 3, a*x(10); 77 | 15, 10, -a*(x(2) - x(3)) ]; 78 | G = G(:,3); 79 | -------------------------------------------------------------------------------- /matlab/examples/snmain/snoptuserfun3.m: -------------------------------------------------------------------------------- 1 | function [F,G] = snoptuserfun3(x) 2 | %function [F,G] = snoptuserfun3(x) 3 | % Computes F and a subset of the derivatives for the hexagon problem. 4 | 5 | F = [ x(2)*x(6) - x(1)*x(7) + x(3)*x(7) + x(5)*x(8) - x(4)*x(9) - x(3)*x(8); 6 | x(1)^2 + x(6)^2; 7 | (x(2) - x(1))^2 + (x(7) - x(6))^2; 8 | (x(3) - x(1))^2 + x(6)^2; 9 | (x(1) - x(4))^2 + (x(6) - x(8))^2; 10 | (x(1) - x(5))^2 + (x(6) - x(9))^2; 11 | x(2)^2 + x(7)^2; 12 | (x(3) - x(2))^2 + x(7)^2;; 13 | (x(4) - x(2))^2 + (x(8) - x(7))^2; 14 | (x(2) - x(5))^2 + (x(7) - x(9))^2; 15 | (x(4) - x(3))^2 + x(8)^2; 16 | (x(5) - x(3))^2 + x(9)^2; 17 | x(4)^2 + x(8)^2; 18 | (x(4) - x(5))^2 + (x(9) - x(8))^2; 19 | x(5)^2 + x(9)^2; 20 | 0; % snopt computes the linear rows 21 | 0; 22 | 0; 23 | 0 ]; 24 | 25 | % Define the derivatives (i,j,Gij). 26 | % Unknown derivatives are marked by a NaN. 27 | % The coordinates (i,j) are included for clarity, they aren't used here. 28 | if nargout > 1, 29 | G = [ 1, 1, -x(7); 30 | 1, 2, x(6); 31 | 1, 3, x(7) - x(8); 32 | 1, 4, -x(9); 33 | 1, 5, x(8); 34 | 1, 6, x(2); 35 | 1, 7, x(3) - x(1); 36 | 1, 8, x(5) - x(3); 37 | 1, 9, - x(4); 38 | 2, 1, 2*x(1); 39 | 2, 6, 2*x(6); 40 | 3, 1, -2*(x(2) - x(1)); 41 | 3, 2, 2*(x(2) - x(1)); 42 | 3, 6, -2*(x(7) - x(6)); 43 | 3, 7, 2*(x(7) - x(6)); 44 | 4, 1, -2*(x(3) - x(1)); 45 | 4, 3, 2*(x(3) - x(1)); 46 | 4, 6, 2*x(6); 47 | 5, 1, 2*(x(1) - x(4)); 48 | 5, 4, -2*(x(1) - x(4)); 49 | 5, 6, 2*(x(6) - x(8)); 50 | 5, 8, -2*(x(6) - x(8)); 51 | 6, 1, 2*(x(1) - x(5)); 52 | 6, 5, -2*(x(1) - x(5)); 53 | 6, 6, 2*(x(6) - x(9)); 54 | 6, 9, -2*(x(6) - x(9)); 55 | 7, 2, 2*x(2); 56 | 7, 7, 2*x(7); 57 | 8, 2, -2*(x(3) - x(2)); 58 | 8, 3, 2*(x(3) - x(2)); 59 | 8, 7, 2*x(7); 60 | 9, 2, NaN 61 | 9, 4, NaN 62 | 9, 7, NaN 63 | 9, 8, NaN 64 | 10, 2, 2*(x(2) - x(5)); 65 | 10, 5, -2*(x(2) - x(5)); 66 | 10, 7, 2*(x(7) - x(9)); 67 | 10, 9, -2*(x(7) - x(9)); 68 | 11, 3, -2*(x(4) - x(3)); 69 | 11, 4, 2*(x(4) - x(3)); 70 | 11, 8, 2*x(8); 71 | 12, 3, -2*(x(5) - x(3)); 72 | 12, 5, 2*(x(5) - x(3)); 73 | 12, 9, 2*x(9); 74 | 13, 4, 2*x(4); 75 | 13, 8, 2*x(8); 76 | 14, 4, 2*(x(4) - x(5)); 77 | 14, 5, -2*(x(4) - x(5)); 78 | 14, 8, -2*(x(9) - x(8)); 79 | 14, 9, 2*(x(9) - x(8)); 80 | 15, 5, 2*x(5); 81 | 15, 9, 2*x(9) ]; 82 | 83 | % Set the nonlinear Jacobian elements. 84 | G = G(:,3); 85 | end -------------------------------------------------------------------------------- /matlab/examples/snmain/snoptmain.m: -------------------------------------------------------------------------------- 1 | function [x,F,INFO] = snoptmain() 2 | %function [x,F,INFO] = snoptmain() 3 | % Defines the NLP problem and calls the simplest 4 | % version of the mex interface for snopt. 5 | 6 | options.name = 'snmain'; 7 | options.screen = 'on'; 8 | 9 | options.printfile = 'snoptmain.out'; 10 | options.specesfile = which('snoptmain.spc'); 11 | 12 | %Get condensed data for the Hexagon problem. 13 | [x,xlow,xupp,xmul,xstate,Flow,Fupp,Fmul,Fstate] = hexagon; 14 | 15 | options.maximize = ''; 16 | 17 | [x,F,INFO,~,~,~,~,output] = snopt(x,xlow,xupp,xmul,xstate,... 18 | Flow,Fupp,Fmul,Fstate,@snoptuserfun); 19 | 20 | itns = output.iterations; 21 | majors = output.majors; 22 | 23 | 24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | function [x,xlow,xupp,xmul,xstate,Flow,Fupp,Fmul,Fstate] = hexagon() 26 | %function [x,xlow,xupp,Flow,Fupp] = hexagon() 27 | % 28 | % Defines the problem hexagon: 29 | % maximize F(1) (the objective row) 30 | % subject to 31 | % xlow <= x <= xupp 32 | % Flow <= F(x) <= Fupp 33 | % where 34 | % F( 1) = x_2 x_6 - x_1 x_7 + x_3 x_7 + x_5 x_8 - x_4 x_9 - x_3 x_8 35 | % F( 2) = x_1^2 + x_6^2 36 | % F( 3) = (x_2 - x_1)^2 + (x_7 - x_6)^2 37 | % F( 4) = (x_3 - x_1)^2 + x_6^2 38 | % F( 5) = (x_1 - x_4)^2 + (x_6 - x_8)^2 39 | % F( 6) = (x_1 - x_5)^2 + (x_6 - x_9)^2 40 | % F( 7) = x_2^2 + x_7^2 41 | % F( 8) = (x_3 - x_2)^2 + x_7^2 42 | % F( 9) = (x_4 - x_2)^2 + (x_8 - x_7)^2 43 | % F(10) = (x_2 - x_5)^2 + (x_7 - x_9)^2 44 | % F(11) = (x_4 - x_3)^2 + x_8^2 45 | % F(12) = (x_5 - x_3)^2 + x_9^2 46 | % F(13) = x_4^2 + x_8^2 47 | % F(14) = (x_4 - x_5)^2 +(x_9 - x_8)^2 48 | % F(15) = x_5^2 + x_9^2 49 | % F(16) = -x_1 + x_2 50 | % F(17) = -x_2 + x_3 51 | % F(18) = x_3 - x_4 52 | % F(19) = x_4 - x_5 53 | 54 | neF = 19; 55 | n = 9; 56 | Obj = 1; % The default objective row 57 | 58 | % Ranges for F. 59 | 60 | Flow = zeros(neF,1); 61 | Fupp = ones(neF,1); 62 | 63 | Flow( 1:15) = -Inf; 64 | Fupp(16:neF) = Inf; 65 | 66 | % The Objective row is always free. 67 | 68 | Flow(Obj) = -Inf; 69 | Fupp(Obj) = Inf; 70 | 71 | % Multipliers and states 72 | Fmul = zeros(neF,1); 73 | Fstate = zeros(neF,1); 74 | 75 | % Ranges for x. 76 | 77 | xlow = -Inf*ones(n,1); 78 | xupp = Inf*ones(n,1); 79 | 80 | xlow(1) = 0; 81 | xlow(3) = -1; 82 | xlow(5) = 0; 83 | xlow(6) = 0; 84 | xlow(7) = 0; 85 | 86 | xupp(3) = 1; 87 | xupp(8) = 0; 88 | xupp(9) = 0; 89 | 90 | % Multipliers and states 91 | xmul = zeros(n,1); 92 | xstate = zeros(n,1); 93 | 94 | x = [ .1; 95 | .125; 96 | .666666; 97 | .142857; 98 | .111111; 99 | .2; 100 | .25; 101 | -.2; 102 | -.25 ]; 103 | 104 | -------------------------------------------------------------------------------- /matlab/examples/snmain/snoptuserfun2.m: -------------------------------------------------------------------------------- 1 | function [F,G] = snoptuserfun2(x) 2 | %function [F,G] = snoptuserfun(x) 3 | % Computes F and dense Jacobian G for the hexagon problem. 4 | 5 | F = [ x(2)*x(6) - x(1)*x(7) + x(3)*x(7) + x(5)*x(8) - x(4)*x(9) - x(3)*x(8); 6 | x(1)^2 + x(6)^2; 7 | (x(2) - x(1))^2 + (x(7) - x(6))^2; 8 | (x(3) - x(1))^2 + x(6)^2; 9 | (x(1) - x(4))^2 + (x(6) - x(8))^2; 10 | (x(1) - x(5))^2 + (x(6) - x(9))^2; 11 | x(2)^2 + x(7)^2; 12 | (x(3) - x(2))^2 + x(7)^2;; 13 | (x(4) - x(2))^2 + (x(8) - x(7))^2; 14 | (x(2) - x(5))^2 + (x(7) - x(9))^2; 15 | (x(4) - x(3))^2 + x(8)^2; 16 | (x(5) - x(3))^2 + x(9)^2; 17 | x(4)^2 + x(8)^2; 18 | (x(4) - x(5))^2 + (x(9) - x(8))^2; 19 | x(5)^2 + x(9)^2; 20 | -x(1) + x(2); 21 | -x(2) + x(3); 22 | x(3) - x(4); 23 | x(4) - x(5) ]; 24 | 25 | % The coordinates aren't needed but we include them as a safety check. 26 | if nargout > 1, 27 | J = [ 1, 1, -x(7); 28 | 1, 2, x(6); 29 | 1, 3, x(7) - x(8); 30 | 1, 4, -x(9); 31 | 1, 5, x(8); 32 | 1, 6, x(2); 33 | 1, 7, x(3) - x(1); 34 | 1, 8, x(5) - x(3); 35 | 1, 9, - x(4); 36 | 2, 1, 2*x(1); 37 | 2, 6, 2*x(6); 38 | 3, 1, -2*(x(2) - x(1)); 39 | 3, 2, 2*(x(2) - x(1)); 40 | 3, 6, -2*(x(7) - x(6)); 41 | 3, 7, 2*(x(7) - x(6)); 42 | 4, 1, -2*(x(3) - x(1)); 43 | 4, 3, 2*(x(3) - x(1)); 44 | 4, 6, 2*x(6); 45 | 5, 1, 2*(x(1) - x(4)); 46 | 5, 4, -2*(x(1) - x(4)); 47 | 5, 6, 2*(x(6) - x(8)); 48 | 5, 8, -2*(x(6) - x(8)); 49 | 6, 1, 2*(x(1) - x(5)); 50 | 6, 5, -2*(x(1) - x(5)); 51 | 6, 6, 2*(x(6) - x(9)); 52 | 6, 9, -2*(x(6) - x(9)); 53 | 7, 2, 2*x(2); 54 | 7, 7, 2*x(7); 55 | 8, 2, -2*(x(3) - x(2)); 56 | 8, 3, 2*(x(3) - x(2)); 57 | 8, 7, 2*x(7); 58 | 9, 2, -2*(x(4) - x(2)); 59 | 9, 4, 2*(x(4) - x(2)); 60 | 9, 7, -2*(x(8) - x(7)); 61 | 9, 8, 2*(x(8) - x(7)); 62 | 10, 2, 2*(x(2) - x(5)); 63 | 10, 5, -2*(x(2) - x(5)); 64 | 10, 7, 2*(x(7) - x(9)); 65 | 10, 9, -2*(x(7) - x(9)); 66 | 11, 3, -2*(x(4) - x(3)); 67 | 11, 4, 2*(x(4) - x(3)); 68 | 11, 8, 2*x(8); 69 | 12, 3, -2*(x(5) - x(3)); 70 | 12, 5, 2*(x(5) - x(3)); 71 | 12, 9, 2*x(9); 72 | 13, 4, 2*x(4); 73 | 13, 8, 2*x(8); 74 | 14, 4, 2*(x(4) - x(5)); 75 | 14, 5, -2*(x(4) - x(5)); 76 | 14, 8, -2*(x(9) - x(8)); 77 | 14, 9, 2*(x(9) - x(8)); 78 | 15, 5, 2*x(5); 79 | 15, 9, 2*x(9) 80 | 16, 1, -1 81 | 16, 2, 1 82 | 17, 2, -1 83 | 17, 3, 1 84 | 18, 3, 1 85 | 18, 4, -1 86 | 19, 4, 1 87 | 19, 5, -1 ]; 88 | 89 | iGfun = J(:,1); jGvar = J(:,2); G = J(:,3); 90 | G = sparse(iGfun,jGvar,G); 91 | G = full(G); 92 | end 93 | -------------------------------------------------------------------------------- /matlab/examples/snmain/snoptmain2.m: -------------------------------------------------------------------------------- 1 | function [x,F,INFO] = snoptmain2() 2 | %function [x,F,INFO] = snoptmain2() 3 | % Defines the NLP problem and calls the mex interface for snopt. 4 | % First derivatives are provided. 5 | 6 | options.name = 'snmain2'; 7 | options.screen = 'on'; 8 | 9 | options.specsfile = which('snoptmain2.spc'); 10 | options.printfile = 'snoptmain2.out'; 11 | 12 | %Get condensed data for the Hexagon problem. 13 | [x,xlow,xupp,xmul,xstate, ... 14 | Flow,Fupp,Fmul,Fstate, ... 15 | A.val, A.row, A.col, G.row, G.col, ... 16 | ObjRow, ObjAdd] = hexagon; 17 | 18 | options.maximize = ''; 19 | 20 | [x,F,INFO] = snopt(x,xlow,xupp,xmul,xstate, ... 21 | Flow,Fupp,Fmul,Fstate, ... 22 | @snoptuserfun2, ... 23 | ObjAdd, ObjRow, ... 24 | A,G,options); 25 | 26 | 27 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | function [x,xlow,xupp,xmul,xstate, ... 29 | Flow,Fupp,Fmul,Fstate, ... 30 | A,iAfun,jAvar,iGfun,jGvar ... 31 | Obj, ObjAdd] = hexagon() 32 | %function [x,xlow,xupp,Flow,Fupp,A,iAfun,jAvar,iGfun,jGvar] = hexagon() 33 | % 34 | % Defines the problem hexagon: 35 | % maximize F(1) (the objective row) 36 | % subject to 37 | % xlow <= x <= xupp 38 | % Flow <= F(x) <= Fupp 39 | % where 40 | % F( 1) = x_2 x_6 - x_1 x_7 + x_3 x_7 + x_5 x_8 - x_4 x_9 - x_3 x_8 41 | % F( 2) = x_1^2 + x_6^2 42 | % F( 3) = (x_2 - x_1)^2 + (x_7 - x_6)^2 43 | % F( 4) = (x_3 - x_1)^2 + x_6^2 44 | % F( 5) = (x_1 - x_4)^2 + (x_6 - x_8)^2 45 | % F( 6) = (x_1 - x_5)^2 + (x_6 - x_9)^2 46 | % F( 7) = x_2^2 + x_7^2 47 | % F( 8) = (x_3 - x_2)^2 + x_7^2 48 | % F( 9) = (x_4 - x_2)^2 + (x_8 - x_7)^2 49 | % F(10) = (x_2 - x_5)^2 + (x_7 - x_9)^2 50 | % F(11) = (x_4 - x_3)^2 + x_8^2 51 | % F(12) = (x_5 - x_3)^2 + x_9^2 52 | % F(13) = x_4^2 + x_8^2 53 | % F(14) = (x_4 - x_5)^2 + (x_9 - x_8)^2 54 | % F(15) = x_5^2 + x_9^2 55 | % F(16) = -x_1 + x_2 56 | % F(17) = -x_2 + x_3 57 | % F(18) = x_3 - x_4 58 | % F(19) = x_4 - x_5 59 | 60 | neF = 19; 61 | n = 9; 62 | Obj = 1; % The default objective row 63 | ObjAdd = 0.; 64 | 65 | % A dense Jacobian of F is provided in snoptuserfun2 66 | 67 | [iGfun,jGvar] = find(ones(neF,n)); 68 | 69 | % Constant Jacobian elements are not treated specially. 70 | 71 | iAfun = []; jAvar = []; A = []; 72 | 73 | % Multipliers and states 74 | 75 | Fstate = zeros(neF,1); 76 | Fmul = zeros(neF,1); 77 | 78 | % Ranges for F. 79 | 80 | Flow = zeros(neF,1); Fupp = ones (neF,1); 81 | 82 | Flow( 1:15) = -Inf; Fupp(16:neF) = Inf; 83 | 84 | % The Objective row (row 1 by default) is free. 85 | 86 | Flow(Obj) = -Inf; Fupp(Obj) = Inf; 87 | 88 | % Ranges for x. 89 | 90 | xlow = -Inf*ones(n,1); xupp = Inf*ones(n,1); 91 | 92 | xlow(1) = 0; 93 | xlow(3) = -1; 94 | xlow(5) = 0; 95 | xlow(6) = 0; 96 | xlow(7) = 0; 97 | 98 | xupp(3) = 1; 99 | xupp(8) = 0; 100 | xupp(9) = 0; 101 | 102 | 103 | x = [ .1; 104 | .125; 105 | .666666; 106 | .142857; 107 | .111111; 108 | .2; 109 | .25; 110 | -.2; 111 | -.25 ]; 112 | 113 | % Multipliers and states 114 | 115 | xstate = zeros(n,1); 116 | xmul = zeros(n,1); 117 | -------------------------------------------------------------------------------- /matlab/examples/hsmain/hsmain.m: -------------------------------------------------------------------------------- 1 | function [x,F,xmul,Fmul,INFO] = hsmain() 2 | 3 | options.name = 'hsmain'; 4 | options.screen = 'on'; 5 | 6 | options.printfile = 'hsmain.out'; 7 | options.specsfile = which('hsmain.spc'); 8 | 9 | [x,xlow,xupp,xmul,xstate, ... 10 | Flow,Fupp,Fmul,Fstate, ... 11 | ObjAdd,ObjRow,A.val,A.row,A.col,G.row,G.col] = hs47data; 12 | 13 | [x,F,INFO,xmul,Fmul,xstate,Fstate,output]= snopt(x, xlow, xupp, xmul, xstate, ... 14 | Flow, Fupp, Fmul, Fstate, ... 15 | @hsmainusrfun, ObjAdd, ObjRow, ... 16 | A, G, options); 17 | 18 | options.start = 'warm'; 19 | [x,F,INFO,xmul,Fmul,xstate,Fstate,output]= snopt(x, xlow, xupp, xmul, xstate, ... 20 | Flow, Fupp, Fmul, Fstate, ... 21 | @hsmainusrfun, ObjAdd, ObjRow, ... 22 | A, G, options ); 23 | 24 | 25 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 26 | function [x,xlow,xupp,xmul,xstate, ... 27 | Flow,Fupp,Fmul,Fstate, ... 28 | ObjAdd,ObjRow,A,iAfun,jAvar,iGfun,jGvar] = hs47data() 29 | % 30 | % hs47data defines a modified form of the problem HS47. 31 | % 32 | % Minimize (x(1)-x(2))^2 + (x(2)-x(3))^3 + (x(3)-x(4))^4 33 | % + (x(4)-x(5))^4 34 | % 35 | % subject to x(3) + x(4) + x(5) >= 3 36 | % x(1) + x(2)^2 + x(3)^3 = 3 37 | % x(1) + x(2) >= 1 38 | % x(2) - x(3)^2 + x(4) = 1 39 | % x(1)*x(5) = 1 40 | % 41 | % The pattern of nonzeros in the Jacobian is as follows, where 42 | % A = constant element, G = nonlinear element. 43 | % 44 | % Column 45 | % | 1 2 3 4 5 46 | % +---------------------- 47 | % 1 | A A A 48 | % 2 | A G G 49 | % 3 | A A 50 | % 4 | A G A 51 | % 5 | G G 52 | % row 6 | G G G G G Objective row 53 | % 54 | % 55 | 56 | neF = 6; 57 | n = 5; 58 | Obj = 6; 59 | ObjRow = 6; 60 | 61 | % First we assign the list of nonlinear derivative entries. 62 | % The pattern of nonlinear elements is as follows: 63 | % 64 | % Column 65 | % | 1 2 3 4 5 66 | % +---------------------- 67 | % 1 | 68 | % 2 | 6 7 69 | % 3 | 70 | % 4 | 8 71 | % 5 | 9 10 72 | % row 6 | 1 2 3 4 5 Objective row 73 | % 74 | % 75 | % ------------------------------------------------------------------ 76 | 77 | G = [ Obj, 1; 78 | Obj, 2; 79 | Obj, 3; 80 | Obj, 4; 81 | Obj, 5; 82 | 2, 2; 83 | 2, 3; 84 | 4, 3; 85 | 5, 1; 86 | 5, 5 ]; 87 | 88 | iGfun = G(:,1); jGvar = G(:,2); 89 | 90 | % Assign the list of constant derivative entries. 91 | % The order of the constant elements is as follows: 92 | % 93 | % Column 94 | % | 1 2 3 4 5 95 | % +---------------------- 96 | % 1 | 4 5 6 97 | % 2 | 1 98 | % 3 | 7 8 99 | % 4 | 2 3 100 | % 5 | 101 | % row 6 | Objective row 102 | % 103 | 104 | % Assign the constant part of the Jacobian (i,j,Aij) 105 | 106 | A = [ 2, 1, 1; 107 | 4, 2, 1; 108 | 4, 4, 1; 109 | 1, 3, 1; 110 | 1, 4, 1; 111 | 1, 5, 1; 112 | 3, 1, 1; 113 | 3, 2, 1 ]; 114 | 115 | iAfun = A(:,1); jAvar = A(:,2); A = A(:,3); 116 | 117 | ObjAdd = 0; 118 | 119 | % Initial x. 120 | 121 | x = [ 2; 122 | sqrt(2) - 1 ; 123 | sqrt(2) - 1 ; 124 | 2; 125 | 0.5 ]; 126 | 127 | xlow = []; 128 | xupp = []; 129 | xstate = []; 130 | xmul = []; 131 | 132 | Flow = -Inf*ones(neF,1); 133 | Fupp = Inf*ones(neF,1); 134 | 135 | Flow(1) = 3; 136 | Flow(2) = 3; 137 | Fupp(2) = 3; 138 | Flow(3) = 1; 139 | Flow(4) = 1; 140 | Fupp(4) = 1; 141 | Flow(5) = 1; 142 | Fupp(5) = 1; 143 | 144 | Fmul = []; 145 | Fstate = []; 146 | -------------------------------------------------------------------------------- /matlab/examples/hs116/hs116G.m: -------------------------------------------------------------------------------- 1 | function [x,F,xmul,Fmul,INFO] = hs116G() 2 | 3 | options.printfile = 'hs116.out'; 4 | options.specsfile = which('hs116.spc'); 5 | options.screen = 'on'; 6 | options.name = 'hs116G; 7 | 8 | [x,xlow,xupp,xmul,xstate, ... 9 | Flow,Fupp,Fmul,Fstate, ... 10 | ObjAdd,ObjRow,A.val,A.row,A.col,G.row,G.col] = hs116data; 11 | 12 | [x,F,INFO,xmul,Fmul]= snopt(x, xlow, xupp, xmul, xstate, ... 13 | Flow, Fupp, Fmul, Fstate, ... 14 | @hs116userfun, ObjAdd, ObjRow, ... 15 | A, G, options); 16 | 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18 | function [x,xlow,xupp,xmul,xstate, ... 19 | Flow,Fupp,Fmul,Fstate, ... 20 | ObjAdd,ObjRow,A,iAfun,jAvar,iGfun,jGvar] = hs116data() 21 | % hs116data defines problem HS116. 22 | % 23 | % Minimize x(11) + x(12) + x(13) 24 | % subject to many constraints 25 | n = 13; 26 | neF = 15; 27 | Obj = 5; 28 | ObjRow = Obj; 29 | 30 | %% parameters 31 | a = 0.002; 32 | b = 1.262626; 33 | c = 1.231059; 34 | d = 0.03475; 35 | e = 0.975; 36 | f = 0.00975; 37 | % HS Solution 38 | x = [ 0.80377 39 | 0.89999 40 | 0.97095 41 | 0.10000 42 | 0.19081 43 | 0.46057 44 | 574.07758 45 | 74.07758 46 | 500.01615 47 | 0.10000 48 | 20.23309 49 | 77.34768 50 | 0.00673]; 51 | %% initial x 52 | x = [ 0.5; 53 | 0.8; 54 | 0.9; 55 | 0.1; 56 | 0.14; 57 | 0.5; 58 | 489; 59 | 80; 60 | 650; 61 | 450; 62 | 150; 63 | 150; 64 | 150 ]; 65 | %% lower bounds on x 66 | xlow = [ 0.1; 67 | 0.1; 68 | 0.1; 69 | 1e-4; 70 | 0.1; 71 | 0.1; 72 | 0.1; 73 | 0.1; 74 | 500; 75 | 0.1; 76 | 1; 77 | 1e-4; 78 | 1e-4 ]; 79 | %% upper bounds on x 80 | xupp = [ 1 ; 81 | 1 ; 82 | 1 ; 83 | 0.1; 84 | 0.9; 85 | 0.9; 86 | 1000; 87 | 1000; 88 | 1000; 89 | 500; 90 | 150; 91 | 150; 92 | 150 ]; 93 | 94 | xstate = zeros(n,1); 95 | xmul = zeros(n,1); 96 | 97 | iAfun = []; jAvar = []; A = []; 98 | ObjAdd = 0; 99 | 100 | %% Bounds on F 101 | 102 | Flow = zeros(neF,1); Fupp = Inf*ones(neF,1); 103 | Flow(Obj) = -Inf; Fupp(Obj) = Inf; 104 | Flow(3) = -Inf; Fupp(3) = 1; 105 | Flow(4) = 50; Fupp(4) = 250; 106 | Flow(13) = -Inf; Fupp(13) = 1; 107 | Flow(15) = 0.9; Fupp(15) = Inf; 108 | 109 | Fmul = zeros(neF,1); 110 | Fstate = zeros(neF,1); 111 | 112 | G = [ 1, 2, -1; 113 | 1, 3, 1; 114 | 2, 1, -1; 115 | 2, 2, 1; 116 | 3, 7, a; 117 | 3, 8, -a; 118 | 4, 11, 1; 119 | 4, 12, 1; 120 | 4, 13, 1; 121 | Obj, 11, 1; 122 | Obj, 12, 1; 123 | Obj, 13, 1; 124 | 6, 3, c*x(10); 125 | 6, 10, -b + c*x(3); 126 | 6, 13, 1; 127 | 7, 2, -d - e*x(5) + 2*f*x(2); 128 | 7, 5, 1 - e*x(2); 129 | 8, 3, -d - e*x(6) + 2*f*x(3); 130 | 8, 6, 1 - e*x(3); 131 | 9, 1, -d - e*x(4) + 2*f*x(1); 132 | 9, 4, 1 - e*x(1); 133 | 10, 2, c*x(9); 134 | 10, 9, -b + c*x(2); 135 | 10, 12, 1; 136 | 11, 1, c*x(8); 137 | 11, 8, -b + c*x(1); 138 | 11, 11, 1; 139 | 12, 1, -x(8); 140 | 12, 4, -x(7) + x(8); 141 | 12, 5, x(7); 142 | 12, 7, x(5) - x(4); 143 | 12, 8, -x(1) + x(4); 144 | 13, 1, -a*x(8); 145 | 13, 2, a*x(9); 146 | 13, 5, -1 + a*x(8); 147 | 13, 6, 1 - a*x(9); 148 | 13, 8, a*(x(5) - x(1)); 149 | 13, 9, a*(x(2) - x(6)); 150 | 14, 2, -500 + x(9) + x(10); 151 | 14, 3, -x(10); 152 | 14, 6, 500 - x(9); 153 | 14, 9, x(2) - x(6); 154 | 14, 10, -x(3) + x(2); 155 | 15, 2, 1 - a*x(10); 156 | 15, 3, a*x(10); 157 | 15, 10, -a*(x(2) - x(3)) ]; 158 | iGfun = G(:,1); jGvar = G(:,2); 159 | -------------------------------------------------------------------------------- /matlab/examples/snmain/snoptmain3.m: -------------------------------------------------------------------------------- 1 | function [x,F,INFO] = snoptmain3() 2 | %function [x,F,INFO] = snoptmain3() 3 | % Defines the NLP problem and calls the mex interface for snopt. 4 | % Some, but not all first derivatives are provided. 5 | 6 | options.name = 'snmain3'; 7 | 8 | options.screen = 'on'; 9 | options.specsfile = which('snoptmain3.spc'); 10 | options.printfile = 'snoptmain3.out'; 11 | 12 | options.verify_level = 3; 13 | options.maximize = 1; 14 | options.derivative_option = 0; 15 | 16 | 17 | % Get the data defining the Hexagon problem. 18 | [x,xlow,xupp,xmul,xstate, ... 19 | Flow,Fupp,Fmul,Fstate, ... 20 | A.val,A.row,A.col,G.row,G.col, ... 21 | ObjRow, ObjAdd] = hexagon; 22 | 23 | [x,F,INFO] = snopt(x,xlow,xupp,xmul,xstate, ... 24 | Flow,Fupp,Fmul,Fstate, ... 25 | @snoptuserfun3, ... 26 | ObjAdd, ObjRow, ... 27 | A, G, options); 28 | 29 | 30 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 31 | function [x,xlow,xupp,xmul,xstate, ... 32 | Flow,Fupp,Fmul,Fstate, ... 33 | A,iAfun,jAvar,iGfun,jGvar, ... 34 | Obj, ObjAdd] = hexagon() 35 | %function [x,xlow,xupp,Flow,Fupp,A,iAfun,jAvar,iGfun,jGvar] = hexagon() 36 | % 37 | % Defines the problem hexagon: 38 | % maximize F(1) (the objective row) 39 | % subject to 40 | % xlow <= x <= xupp 41 | % Flow <= F(x) <= Fupp 42 | % where 43 | % F( 1) = x_2 x_6 - x_1 x_7 + x_3 x_7 + x_5 x_8 - x_4 x_9 - x_3 x_8 44 | % F( 2) = x_1^2 + x_6^2 45 | % F( 3) = (x_2 - x_1)^2 + (x_7 - x_6)^2 46 | % F( 4) = (x_3 - x_1)^2 + x_6^2 47 | % F( 5) = (x_1 - x_4)^2 + (x_6 - x_8)^2 48 | % F( 6) = (x_1 - x_5)^2 + (x_6 - x_9)^2 49 | % F( 7) = x_2^2 + x_7^2 50 | % F( 8) = (x_3 - x_2)^2 + x_7^2 51 | % F( 9) = (x_4 - x_2)^2 + (x_8 - x_7)^2 52 | % F(10) = (x_2 - x_5)^2 + (x_7 - x_9)^2 53 | % F(11) = (x_4 - x_3)^2 + x_8^2 54 | % F(12) = (x_5 - x_3)^2 + x_9^2 55 | % F(13) = x_4^2 + x_8^2 56 | % F(14) = (x_4 - x_5)^2 + (x_9 - x_8)^2 57 | % F(15) = x_5^2 + x_9^2 58 | % F(16) = -x_1 + x_2 59 | % F(17) = -x_2 + x_3 60 | % F(18) = x_3 - x_4 61 | % F(19) = x_4 - x_5 62 | 63 | neF = 19; 64 | n = 9; 65 | Obj = 1; % The default objective row 66 | ObjAdd = 0.; 67 | 68 | % The nonzeros of the Jacobian of F are provided in snoptuserfun3 69 | 70 | G = [Obj, 1 71 | Obj, 2 72 | Obj, 3 73 | Obj, 4 74 | Obj, 5 75 | Obj, 6 76 | Obj, 7 77 | Obj, 8 78 | 1, 9 79 | 2, 1 80 | 2, 6 81 | 3, 1 82 | 3, 2 83 | 3, 6 84 | 3, 7 85 | 4, 1 86 | 4, 3 87 | 4, 6 88 | 5, 1 89 | 5, 4 90 | 5, 6 91 | 5, 8 92 | 6, 1 93 | 6, 5 94 | 6, 6 95 | 6, 9 96 | 7, 2 97 | 7, 7 98 | 8, 2 99 | 8, 3 100 | 8, 7 101 | 9, 2 102 | 9, 4 103 | 9, 7 104 | 9, 8 105 | 10, 2 106 | 10, 5 107 | 10, 7 108 | 10, 9 109 | 11, 3 110 | 11, 4 111 | 11, 8 112 | 12, 3 113 | 12, 5 114 | 12, 9 115 | 13, 4 116 | 13, 8 117 | 14, 4 118 | 14, 5 119 | 14, 8 120 | 14, 9 121 | 15, 5 122 | 15, 9 ]; 123 | 124 | iGfun = G(:,1); jGvar = G(:,2); 125 | 126 | % Constant Jacobian elements are defined once here. 127 | 128 | A = [ 16, 1, -1 129 | 16, 2, 1 130 | 17, 2, -1 131 | 17, 3, 1 132 | 18, 3, 1 133 | 18, 4, -1 134 | 19, 4, 1 135 | 19, 5, -1 ]; 136 | 137 | iAfun = A(:,1); jAvar = A(:,2); A = A(:,3); 138 | 139 | 140 | % Ranges for F. 141 | % The Objective row (row 1 by default) is free. 142 | 143 | Fmul = zeros(neF,1); Fstate = zeros(neF,1); 144 | Flow = zeros(neF,1); Fupp = ones (neF,1); 145 | 146 | Flow( 1:15) = -Inf; Fupp(16:neF) = Inf; 147 | 148 | Flow(Obj) = -Inf; Fupp(Obj) = Inf; 149 | 150 | % Ranges for x. 151 | 152 | xmul = zeros(n,1); xstate = zeros(n,1); 153 | xlow = -Inf*ones(n,1); xupp = Inf*ones(n,1); 154 | 155 | xlow(1) = 0; 156 | xlow(3) = -1; 157 | xlow(5) = 0; 158 | xlow(6) = 0; 159 | xlow(7) = 0; 160 | 161 | xupp(3) = 1; 162 | xupp(8) = 0; 163 | xupp(9) = 0; 164 | 165 | x = [ .1; 166 | .125; 167 | .666666; 168 | .142857; 169 | .111111; 170 | .2; 171 | .25; 172 | -.2; 173 | -.25 ]; -------------------------------------------------------------------------------- /matlab/examples/hs116/hs116.m: -------------------------------------------------------------------------------- 1 | function [x,F,info]=hs116() 2 | % HS Problem 116 with explicit linear constraints. 3 | 4 | options.printfile = 'hs116.out'; 5 | options.specsfile = which('hs116.spc'); 6 | 7 | [x, xlow, xupp, xmul, xstate, ... 8 | Flow, Fupp, Fmul, Fstate, ... 9 | ObjAdd, ObjRow, ... 10 | A.val A.row, A.col, ... 11 | G.row, G.col] = hs116data; 12 | 13 | options.name = 'hs116'; 14 | 15 | [x,F,info]= snopt(x, xlow, xupp, xmul, xstate, ... 16 | Flow, Fupp, Fmul, Fstate, ... 17 | @(x)hs116userfun(x), ObjAdd, ObjRow, ... 18 | A, G, options); 19 | 20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 | function [x,xlow,xupp,xmul,xstate, ... 22 | Flow,Fupp,Fmul,Fstate, ... 23 | ObjAdd,ObjRow,A,iAfun,jAvar,iGfun,jGvar] = hs116data() 24 | % hs116data defines problem HS116. 25 | % 26 | % Minimize x(11) + x(12) + x(13) 27 | % subject to linear and nonlinear constraints 28 | n = 13; 29 | neF = 15; 30 | Obj = 5; 31 | ObjRow = Obj; 32 | 33 | %% parameters 34 | a = 0.002; 35 | b = 1.262626; 36 | c = 1.231059; 37 | d = 0.03475; 38 | e = 0.975; 39 | f = 0.00975; 40 | 41 | % HS Solution 42 | x = [ 0.80377 43 | 0.89999 44 | 0.97095 45 | 0.10000 46 | 0.19081 47 | 0.46057 48 | 574.07758 49 | 74.07758 50 | 500.01615 51 | 0.10000 52 | 20.23309 53 | 77.34768 54 | 0.00673]; 55 | 56 | %% initial x 57 | x = [ 0.5; 58 | 0.8; 59 | 0.9; 60 | 0.1; 61 | 0.14; 62 | 0.5; 63 | 489; 64 | 80; 65 | 650; 66 | 450; 67 | 150; 68 | 150; 69 | 150 ]; 70 | 71 | %% lower bounds on x 72 | xlow = [ 0.1; 73 | 0.1; 74 | 0.1; 75 | 1e-4; 76 | 0.1; 77 | 0.1; 78 | 0.1; 79 | 0.1; 80 | 500; 81 | 0.1; 82 | 1; 83 | 1e-4; 84 | 1e-4 ]; 85 | 86 | %% upper bounds on x 87 | xupp = [ 1 ; 88 | 1 ; 89 | 1 ; 90 | 0.1; 91 | 0.9; 92 | 0.9; 93 | 1000; 94 | 1000; 95 | 1000; 96 | 500; 97 | 150; 98 | 150; 99 | 150 ]; 100 | 101 | xstate = zeros(n,1); 102 | xmul = zeros(n,1); 103 | 104 | ObjAdd = 0; 105 | 106 | %% Bounds on F 107 | 108 | Flow = zeros(neF,1); Fupp = Inf*ones(neF,1); 109 | Flow(Obj) = -Inf; Fupp(Obj) = Inf; 110 | Flow(3) = -Inf; Fupp(3) = 1; 111 | Flow(4) = 50; Fupp(4) = 250; 112 | Flow(13) = -Inf; Fupp(13) = 1; 113 | Flow(15) = 0.9; Fupp(15) = Inf; 114 | 115 | Fmul = zeros(neF,1); 116 | Fstate = zeros(neF,1); 117 | 118 | A = [ 1, 2, -1; 119 | 1, 3, 1; 120 | 2, 1, -1; 121 | 2, 2, 1; 122 | 3, 7, a; 123 | 3, 8, -a; 124 | 4, 11, 1; 125 | 4, 12, 1; 126 | 4, 13, 1; 127 | Obj, 11, 1; 128 | Obj, 12, 1; 129 | Obj, 13, 1; 130 | 6, 13, 1; 131 | 10, 12, 1; 132 | 11, 11, 1 ]; 133 | iAfun = A(:,1); jAvar = A(:,2); A = A(:,3); 134 | 135 | G = [ 6, 3, c*x(10); 136 | 6, 10, -b + c*x(3); 137 | 7, 2, -d - e*x(5) + 2*f*x(2); 138 | 7, 5, 1 - e*x(2); 139 | 8, 3, -d - e*x(6) + 2*f*x(3); 140 | 8, 6, 1 - e*x(3); 141 | 9, 1, -d - e*x(4) + 2*f*x(1); 142 | 9, 4, 1 - e*x(1); 143 | 10, 2, c*x(9); 144 | 10, 9, -b + c*x(2); 145 | 11, 1, c*x(8); 146 | 11, 8, -b + c*x(1); 147 | 12, 1, -x(8); 148 | 12, 4, -x(7) + x(8); 149 | 12, 5, x(7); 150 | 12, 7, x(5) - x(4); 151 | 12, 8, -x(1) + x(4); 152 | 13, 1, -a*x(8); 153 | 13, 2, a*x(9); 154 | 13, 5, 1 + a*x(8); 155 | 13, 6, 1 - a*x(9); 156 | 13, 8, a*(x(5) - x(1)); 157 | 13, 9, a*(x(2) - x(6)); 158 | 14, 2, -500 + x(9) + x(10); 159 | 14, 3, -x(10); 160 | 14, 6, 500 - x(9); 161 | 14, 9, x(2) - x(6); 162 | 14, 10, -x(3) + x(2); 163 | 15, 2, 1 - a*x(10); 164 | 15, 3, a*x(10); 165 | 15, 10, -a*(x(2) - x(3)) ]; 166 | iGfun = G(:,1); jGvar = G(:,2); 167 | -------------------------------------------------------------------------------- /matlab/examples/hs116/hs116M.m: -------------------------------------------------------------------------------- 1 | function [x,F,xmul,Fmul,INFO] = hs116M() 2 | % HS Problem 116 with explicit linear constraints. 3 | 4 | options.printfile = 'hs116M.out'; 5 | options.specsfile = which('hs116M.spc'); 6 | options.screen = 'on'; 7 | options.name = 'hs116M'; 8 | 9 | [x,xlow,xupp,xmul,xstate, ... 10 | Flow,Fupp,Fmul,Fstate, ... 11 | ObjAdd,ObjRow,A.val,A.row,A.col,G.row,G.col] = hs116data; 12 | 13 | [x,F,INFO,xmul,Fmul]= snopt(x, xlow, xupp, xmul, xstate, ... 14 | Flow, Fupp, Fmul, Fstate, ... 15 | @hs116userfunM, ObjAdd, ObjRow, ... 16 | A, G); 17 | 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | function [x,xlow,xupp,xmul,xstate, ... 20 | Flow,Fupp,Fmul,Fstate, ... 21 | ObjAdd,ObjRow,A,iAfun,jAvar,iGfun,jGvar] = hs116data() 22 | % hs116data defines problem HS116. 23 | % 24 | % Minimize x(11) + x(12) + x(13) 25 | % subject to linear and nonlinear constraints 26 | n = 13; 27 | neF = 15; 28 | Obj = 5; 29 | ObjRow = Obj; 30 | 31 | %% parameters 32 | a = 0.002; 33 | b = 1.262626; 34 | c = 1.231059; 35 | d = 0.03475; 36 | e = 0.975; 37 | f = 0.00975; 38 | % HS Solution 39 | x = [ 0.80377 40 | 0.89999 41 | 0.97095 42 | 0.10000 43 | 0.19081 44 | 0.46057 45 | 574.07758 46 | 74.07758 47 | 500.01615 48 | 0.10000 49 | 20.23309 50 | 77.34768 51 | 0.00673]; 52 | %% initial x 53 | x = [ 0.5; 54 | 0.8; 55 | 0.9; 56 | 0.1; 57 | 0.14; 58 | 0.5; 59 | 489; 60 | 80; 61 | 650; 62 | 450; 63 | 150; 64 | 150; 65 | 150 ]; 66 | % HS Solution 67 | x = [ 0.80377 68 | 0.89999 69 | 0.97095 70 | 0.10000 71 | 0.19081 72 | 0.46057 73 | 574.07758 74 | 74.07758 75 | 500.01615 76 | 0.10000 77 | 20.23309 78 | 77.34768 79 | 0.00673]; 80 | %% lower bounds on x 81 | xlow = [ 0.1; 82 | 0.1; 83 | 0.1; 84 | 1e-4; 85 | 0.1; 86 | 0.1; 87 | 0.1; 88 | 0.1; 89 | 500; 90 | 0.1; 91 | 1; 92 | 1e-4; 93 | 1e-4 ]; 94 | %% upper bounds on x 95 | xupp = [ 1 ; 96 | 1 ; 97 | 1 ; 98 | 0.1; 99 | 0.9; 100 | 0.9; 101 | 1000; 102 | 1000; 103 | 1000; 104 | 500; 105 | 150; 106 | 150; 107 | 150 ]; 108 | 109 | xstate = zeros(n,1); 110 | xmul = zeros(n,1); 111 | 112 | ObjAdd = 0; 113 | 114 | %% Bounds on F 115 | 116 | Flow = zeros(neF,1); Fupp = Inf*ones(neF,1); 117 | Flow(Obj) = -Inf; Fupp(Obj) = Inf; 118 | Flow(3) = -Inf; Fupp(3) = 1; 119 | Flow(4) = 50; Fupp(4) = 250; 120 | Flow(13) = -Inf; Fupp(13) = 1; 121 | Flow(15) = 0.9; Fupp(15) = Inf; 122 | 123 | Fmul = zeros(neF,1); 124 | Fstate = zeros(neF,1); 125 | 126 | A = [ 1, 2, -1; 127 | 1, 3, 1; 128 | 2, 1, -1; 129 | 2, 2, 1; 130 | 3, 7, a; 131 | 3, 8, -a; 132 | 4, 11, 1; 133 | 4, 12, 1; 134 | 4, 13, 1; 135 | Obj, 11, 1; 136 | Obj, 12, 1; 137 | Obj, 13, 1 ]; 138 | iAfun = A(:,1); jAvar = A(:,2); A = A(:,3); 139 | 140 | G = [ 6, 3, c*x(10); 141 | 6, 10, -b + c*x(3); 142 | 6, 13, 1; 143 | 7, 2, -d - e*x(5) + 2*f*x(2); 144 | 7, 5, 1 - e*x(2); 145 | 8, 3, -d - e*x(6) + 2*f*x(3); 146 | 8, 6, 1 - e*x(3); 147 | 9, 1, -d - e*x(4) + 2*f*x(1); 148 | 9, 4, 1 - e*x(1); 149 | 10, 2, c*x(9); 150 | 10, 9, -b + c*x(2); 151 | 10, 12, 1; 152 | 11, 1, c*x(8); 153 | 11, 8, -b + c*x(1); 154 | 11, 11, 1; 155 | 12, 1, -x(8); 156 | 12, 4, -x(7) + x(8); 157 | 12, 5, x(7); 158 | 12, 7, x(5) - x(4); 159 | 12, 8, -x(1) + x(4); 160 | 13, 1, -a*x(8); 161 | 13, 2, a*x(9); 162 | 13, 5, -1 + a*x(8); 163 | 13, 6, 1 - a*x(9); 164 | 13, 8, a*(x(5) - x(1)); 165 | 13, 9, a*(x(2) - x(6)); 166 | 14, 2, -500 + x(9) + x(10); 167 | 14, 3, -x(10); 168 | 14, 6, 500 - x(9); 169 | 14, 9, x(2) - x(6); 170 | 14, 10, -x(3) + x(2); 171 | 15, 2, 1 - a*x(10); 172 | 15, 3, a*x(10); 173 | 15, 10, -a*(x(2) - x(3)) ]; 174 | iGfun = G(:,1); jGvar = G(:,2); 175 | -------------------------------------------------------------------------------- /mex/iomex.f90: -------------------------------------------------------------------------------- 1 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 | ! 3 | ! File iomex.f90 4 | ! 5 | ! snPRNT ioTRIM snREAD 6 | ! 7 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 | 9 | subroutine snPRNT ( mode, string, iw, leniw ) 10 | implicit none 11 | character*(*) string 12 | integer mode, leniw, iw(leniw) 13 | 14 | !===================================================================== 15 | ! snPRNT prints a trimmed form of "string" on various files. 16 | ! If mode = 0, nothing is output. 17 | ! If mode = 1, string is output to iPrint. 18 | ! If mode = 2, string is output to iSumm. 19 | ! If mode = 3 or 4, string is output to iPrint and iSumm. 20 | ! If mode = 4, string is output to the screen. 21 | ! This mode is intended for error messages. 22 | ! If mode = 5, string is output to iStdo (standard output) 23 | ! This mode is to be used when the elements of 24 | ! the integer work array iw cannot be trusted. 25 | ! 26 | ! mode 11-15 are the same as mode 1-5 with blank line before output. 27 | ! 28 | ! If mode > 15 then nothing is printed unless lvlSys > 0. 29 | ! mode 21-25 are the same as mode 1-5 30 | ! mode 31-35 are the same as mode 11-15 31 | ! 32 | ! 25 Sep 2002: First version of snPRNT. 33 | ! 31 Jul 2003: mode 11-14 added. form introduced. 34 | ! 27 Dec 2003: mode 5 added to allow printing before iw is set. 35 | ! 12 Mar 2004: s1trim called to trim the string. 36 | ! 22 Jun 2004: System printing option added. 37 | ! 14 Oct 2004: Matlab version of snPRNT. 38 | ! 30 Apr 2006: Files opened and closed in C. 39 | !===================================================================== 40 | integer iPrint, iSumm, length, lvlSys, m, newline, & 41 | screenOK, summaryOK, printOK 42 | character Buff*140 43 | 44 | lvlSys = iw( 91) ! > 0 => print system info 45 | 46 | newline = 0 47 | m = 0 48 | if (mode .le. 0) then 49 | ! Relax 50 | else if (mode .lt. 10) then 51 | m = mode 52 | else if (mode .lt. 20) then ! Blank line first 53 | m = mode - 10 54 | newline = 1 55 | else if (lvlSys .gt. 0) then ! Print system Info 56 | if (mode .lt. 30) then 57 | m = mode - 20 58 | else 59 | m = mode - 30 60 | newline = 1 61 | end if 62 | end if 63 | 64 | 65 | if (m .gt. 0) then 66 | 67 | call iomexfilestatus( screenOK, summaryOK, printOK ) 68 | 69 | ! length = len_trim(string) ! An F90 intrinsic 70 | call ioTRIM( string, length ) ! The F77 equivalent 71 | Buff = string 72 | 73 | if (m .eq. 5) then 74 | call iomexwritescreen( newline, Buff, length) 75 | else 76 | iPrint = iw( 12) ! Print file 77 | iSumm = iw( 13) ! Summary file 78 | 79 | if (m .eq. 1 .or. m .ge. 3) then 80 | if (printOK .gt. 0) then 81 | call iomexwritefile( newline, iPrint, Buff, length ) 82 | end if 83 | end if 84 | 85 | if (m .eq. 2 .or. m .ge. 3) then 86 | if (screenOK .gt. 0) then 87 | call iomexwritescreen( newline, Buff, length) 88 | end if 89 | if (summaryOK .gt. 0) then 90 | call iomexwritefile( newline, iSumm , Buff, length ) 91 | end if 92 | end if 93 | 94 | if (m .eq. 4) then 95 | call iomexwritescreen( newline, Buff, length) 96 | end if 97 | end if 98 | end if 99 | 100 | end subroutine snPRNT 101 | 102 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 103 | 104 | subroutine ioTrim( buffer, lenbuf ) 105 | implicit none 106 | character*(*) buffer 107 | integer lenbuf 108 | 109 | !=================================================================== 110 | ! ioTrim returns the length of buffer with trailing blanks omitted. 111 | ! 112 | ! 02 Dec 2000: First version written for snLog and snLog2. 113 | !=================================================================== 114 | integer k 115 | 116 | lenbuf = len( buffer ) 117 | do k = lenbuf, 2, -1 118 | if (buffer(k:k) .ne. ' ') go to 100 119 | lenbuf = lenbuf - 1 120 | end do 121 | 122 | 100 return 123 | 124 | end subroutine ioTrim 125 | 126 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 127 | 128 | subroutine snREAD ( unitno, string, nchar, endfile ) 129 | implicit none 130 | character*(*) string 131 | integer endfile, nchar, unitno 132 | !=================================================================== 133 | ! snREAD reads a string of length nchar from file unitno. 134 | ! 135 | ! 30 Apr 2006: First version of snREAD. 136 | ! 30 Apr 2006: Matlab version. 137 | !=================================================================== 138 | call iomexRead ( unitno, string, nchar, endfile ) 139 | 140 | end subroutine snREAD 141 | 142 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 143 | 144 | subroutine iomexFileStatus ( scrnOK, summOK, prntOK ) 145 | use mxsnWork 146 | 147 | implicit none 148 | integer scrnOK, summOK, prntOK 149 | 150 | 151 | if ( screenOn .and. callType == 1 ) then 152 | scrnOK = 1 153 | else 154 | scrnOK = 0 155 | end if 156 | 157 | if ( summOpen .and. callType == 1 ) then 158 | summOK = 1 159 | else 160 | summOK = 0 161 | end if 162 | 163 | if ( printOpen .and. callType == 1 ) then 164 | prntOK = 1 165 | else 166 | prntOK = 0 167 | end if 168 | 169 | end subroutine iomexFileStatus 170 | 171 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 172 | 173 | subroutine iomexwriteScreen ( newline, buffer, length ) 174 | 175 | implicit none 176 | character*(*) buffer 177 | integer newline, length 178 | 179 | if ( length > 140 ) & 180 | call mexErrMsgTxt ( 'Print buffer too long for snPRNT' ) 181 | 182 | if ( newline > 0 ) call mexPrintf ( achar(10) ) 183 | call mexPrintf ( buffer(1:length)//achar(10) ) 184 | 185 | end subroutine iomexwriteScreen 186 | 187 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 188 | 189 | subroutine iomexwriteFile ( newline, unitno, buffer, length ) 190 | use mxsnWork 191 | 192 | implicit none 193 | character*(*) buffer 194 | integer newline, unitno, length 195 | 196 | 197 | if ( length > 140 ) & 198 | call mexErrMsgTxt ( 'Print buffer too long for snPRNT' ) 199 | 200 | if ( unitno == iPrint ) then 201 | if ( newline > 0 ) then 202 | write(iPrint,'(/,a)') buffer(1:length) 203 | else 204 | write(iPrint,'(a)') buffer(1:length) 205 | end if 206 | 207 | else if ( unitno == iSumm ) then 208 | if ( newline > 0 ) then 209 | write(iSumm,'(/,a)') buffer(1:length) 210 | else 211 | write(iSumm,'(a)') buffer(1:length) 212 | end if 213 | 214 | end if 215 | 216 | end subroutine iomexwriteFile 217 | 218 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 219 | 220 | subroutine iomexRead ( unitno, string, nchar, endfile ) 221 | implicit none 222 | character*(*) string 223 | integer endfile, nchar, unitno 224 | 225 | character frmt*6 226 | 227 | frmt = ' ' 228 | 229 | if (nchar .ge. 1 .and. nchar .le. 999) then 230 | if (nchar .lt. 10) then 231 | write(frmt, '(a2,i1,a1)') '(a', nchar, ')' 232 | else if (nchar .lt. 100) then 233 | write(frmt, '(a2,i2,a1)') '(a', nchar, ')' 234 | else 235 | write(frmt, '(a2,i3,a1)') '(a', nchar, ')' 236 | end if 237 | 238 | endfile = 0 239 | read (unitno, frmt, end = 100) string 240 | 241 | return 242 | end if 243 | 244 | 100 endfile = 1 245 | 246 | end subroutine iomexRead 247 | -------------------------------------------------------------------------------- /matlab/lpopt.m: -------------------------------------------------------------------------------- 1 | function [x,obj,info,output,lambda,states] = lpopt(c, x0, xl, xu, A, al, au, varargin) 2 | % function [x,obj,info,output,lambda,states] = lpopt(c, x0, xl, xu, A, al, au, varargin) 3 | % 4 | % This function solves the linear optimization problem: 5 | % minimize: 6 | % c'x 7 | % subject to: 8 | % xl <= x <= xu 9 | % al <= Ax <= au 10 | % where: 11 | % x is the column vector of initial values of the unknowns 12 | % xl, xu are the lower and upper bounds of the variables 13 | % c is the linear term of the objective 14 | % A is the linear constraint matrix 15 | % al, au are the lower and upper bounds of the linear constraints 16 | % 17 | % Calling sequences: 18 | % [] = lpopt(c, x0, xl, xu, A, al, au) 19 | % [] = lpopt(c, x0, xl, xu, A, al, au, options) 20 | % 21 | % [] = lpopt(c, x0, xl, xu, A, al, au, states, lambda) 22 | % [] = lpopt(c, x0, xl, xu, A, al, au, states, lambda, options) 23 | % 24 | % [x,obj,info,output,lambda,states] = lpopt(...) 25 | % 26 | % 27 | % INPUT: 28 | % x0 is the initial guess for x 29 | % 30 | % c is the linear term of the quadratic objective 31 | % 32 | % xl, xu are the upper and lower bounds on x 33 | % 34 | % A is the linear constraint matrix. A can be a structure, or a 35 | % dense or sparse matrix. 36 | % If A is a structure, then A is represented as a 37 | % sparse-by-column matrix and should have fields: 38 | % A.loc -- column pointers 39 | % A.ind -- row indices 40 | % A.val -- matrix values 41 | % 42 | % al, au are the upper and lower bounds on the linear constraints A*x 43 | % 44 | % options is an (optional) input argument of type struct. SNOPT 45 | % options can be set using this structure by creating an entry with a 46 | % field name equal to the SNOPT keyword with spaces replaced by 47 | % underscores '_'. For example, 48 | % options.iterations_limit = 250; 49 | % 50 | % Additional keywords include: 51 | % 52 | % options.name is the problem name 53 | % 54 | % options.start 'Cold', 'Warm' 55 | % 56 | % options.screen is a string set to 'on' or 'off'. 57 | % Summary to the screen is controlled 58 | % by this option. (default 'on') 59 | % 60 | % options.printfile is a string denoting the print file. 61 | % By default, no print file is created. 62 | % Not setting this option or setting it to 63 | % '' turns off print output. 64 | % 65 | % options.specsfile is a string denoting the options 66 | % filename. 67 | % 68 | % options.iwork is an integer defining the integer 69 | % SNOPT workspace length. 70 | % 71 | % options.rwork is an integer defining the real 72 | % SNOPT workspace length. 73 | % 74 | % OUTPUT: 75 | % x is the final point 76 | % 77 | % obj is the final objective value 78 | % 79 | % info is the exit flag returned by the solver 80 | % 81 | % output is a structure containing run information -- 82 | % output.iterations is the total number of iterations 83 | % output.funcCount is the total number of function evaluations 84 | % 85 | % lambda is a structure containing the multipliers 86 | % lambda.x are for the variables 87 | % lambda.linear are for the linear constraints 88 | % 89 | % states is a structure 90 | % states.x are for the variables 91 | % states.linear are for the linear constraints 92 | % 93 | 94 | name = ''; 95 | start = 'Cold'; 96 | 97 | printfile = ''; 98 | screen = 'on'; 99 | specsfile = ''; 100 | 101 | iwork = 0; 102 | rwork = 0; 103 | 104 | % Deal with options. 105 | optionsLoc = 0; 106 | if nargin == 8 || nargin == 10, 107 | optionsLoc = nargin - 7; 108 | if isstruct(varargin{optionsLoc}), 109 | options = varargin{optionsLoc}; 110 | % Name 111 | if isfield(options,'name'), 112 | name = options.name; 113 | end 114 | 115 | % Start 116 | if isfield(options,'start'), 117 | start = options.start; 118 | end 119 | 120 | % Print output 121 | if isfield(options,'printfile'), 122 | if ischar(options.printfile), 123 | printfile = options.printfile; 124 | end 125 | end 126 | 127 | % Specs file 128 | if isfield(options,'specsfile'), 129 | if ischar(options.specsfile), 130 | specsfile = options.specsfile; 131 | end 132 | end 133 | 134 | % Screen 135 | if isfield(options,'screen'), 136 | if ischar(options.screen), 137 | screen = options.screen; 138 | end 139 | end 140 | 141 | % iwork 142 | if isfield(options,'iwork'), 143 | if ischar(options.iwork), 144 | iwork = options.iwork; 145 | end 146 | end 147 | 148 | % rwork 149 | if isfield(options,'rwork'), 150 | if ischar(options.rwork), 151 | rwork = options.rwork; 152 | end 153 | end 154 | 155 | else 156 | optionsLoc = 0; 157 | end 158 | end 159 | 160 | 161 | % Set print, screen, workspace FIRST. 162 | sqprint(printfile); 163 | sqscreen(screen); 164 | sqsetwork(iwork,rwork); 165 | 166 | 167 | % Read specsfile 168 | if ~strcmp(specsfile,''), 169 | info = sqspec(specsfile); 170 | 171 | if info ~= 101 && info ~= 107, 172 | x = []; obj = 0; output = []; lambda = []; states = []; 173 | end_sqopt(); 174 | return; 175 | end 176 | end 177 | 178 | % Handle other options 179 | if (optionsLoc ~= 0), 180 | fields = fieldnames(options); 181 | for i = 1:numel(fields), 182 | if (ischar(fields{i})), 183 | keyword = strrep(fields{i}, '_', ' '); 184 | 185 | if ~strcmp(keyword,'screen') && ... 186 | ~strcmp(keyword,'printfile') && ... 187 | ~strcmp(keyword,'specsfile') && ... 188 | ~strcmp(keyword,'name') && ... 189 | ~strcmp(keyword,'iwork') && ... 190 | ~strcmp(keyword,'rwork') && ... 191 | ~strcmp(keyword,'start'), 192 | 193 | option = options.(fields{i}); 194 | 195 | if (isnumeric(option)), 196 | option = num2str(option); 197 | end 198 | string = strjoin({keyword, option}); 199 | 200 | sqset(string); 201 | end 202 | end 203 | end 204 | end 205 | 206 | if nargin == 7 || nargin == 8, 207 | % lpopt(c, x0, xl, xu, A, al, au) 208 | % lpopt(c, x0, xl, xu, A, al, au, options) 209 | 210 | xstate = []; xmul = []; 211 | astate = []; amul = []; 212 | 213 | elseif nargin == 9 || nargin == 10, 214 | % lpopt(c, x0, xl, xu, A, al, au, states, lambda) 215 | % lpopt(c, x0, xl, xu, A, al, au, states, lambda, options) 216 | 217 | states = varargin{1}; 218 | lambda = varargin{2}; 219 | 220 | xstate = []; xmul = []; 221 | astate = []; amul = []; 222 | 223 | if isfield(states,'x'), 224 | xstate = states.x; 225 | end 226 | 227 | if isfield(lambda,'x'), 228 | xmul = lambda.x; 229 | end 230 | 231 | if isfield(states,'linear'), 232 | astate = states.linear; 233 | end 234 | 235 | if isfield(lambda,'linear'), 236 | amul = lambda.linear; 237 | end 238 | 239 | else 240 | error('LPOPT:InputArgs','Wrong number of arguments in LPOPT'); 241 | end 242 | 243 | if isempty(A), 244 | % Setup fake constraint matrix and bounds 245 | warning('LPOPT:InputArgs','No linear constraints detected; dummy constraint created'); 246 | 247 | m = 1; 248 | n = numel(x0); 249 | 250 | neA = 1; 251 | indA(1) = 1; 252 | valA(1) = 1.0; 253 | 254 | locA = zeros(n+1,1); 255 | locA(1) = 1; 256 | locA(2:n+1) = 2; 257 | al = [-inf]; au = [inf]; 258 | 259 | else 260 | if isstruct(A), 261 | if isfield(A,'ind') && isfield(A,'loc') && isfield(A,'val'), 262 | % In sparse-by-col form 263 | n = numel(x0); 264 | locA = colvec(A.loc,'A.loc',1,n+1); 265 | indA = colvec(A.ind,'A.ind',1,0); 266 | valA = colvec(A.val,'A.val',1,0); 267 | m = max(indA); 268 | neA = numel(valA); 269 | else 270 | error('LPOPT:InputArgs','Matrix must have ind, loc, and val fields') 271 | end 272 | 273 | else 274 | [m,n] = size(A); 275 | [neA,indA,locA,valA] = crd2spr(A); 276 | end 277 | end 278 | 279 | x0 = colvec(x0,'x0',1,n); 280 | xl = colvec(xl,'xl',1,n); 281 | xu = colvec(xu,'xu',1,n); 282 | al = colvec(al,'al',1,m); 283 | au = colvec(au,'au',1,m); 284 | c = colvec(c,'c',1,0); 285 | 286 | 287 | [x,obj,info,output,lambda,states] = solve_sqopt(start, name, ... 288 | m, n, 0, c, ... 289 | x0, xl, xu, xstate, xmul, ... 290 | neA, indA, locA, valA, al, au, astate, amul); 291 | 292 | 293 | end_sqopt(); 294 | -------------------------------------------------------------------------------- /matlab/sqsolve.m: -------------------------------------------------------------------------------- 1 | function [x,fval,exitFlag,output,lambda] = sqsolve(H, f, varargin) 2 | % function [x,fval,exitFlag,output,lambda] = sqsolve(H, f, varargin) 3 | % 4 | % This function interface is similar to the MATLAB function quadprog. 5 | % 6 | % Solve the given quadratic problem: 7 | % minimize q(x) = half*x'*H*x + f'*x 8 | % subject to lb <= x <= ub 9 | % A*x <= b 10 | % Aeq*x = beq 11 | % 12 | % Calling sequences: 13 | % x = sqsolve(H, f) 14 | % x = sqsolve(H, f, A, b) 15 | % x = sqsolve(H, f, A, b, Aeq, beq) 16 | % x = sqsolve(H, f, A, b, Aeq, beq, lb, ub) 17 | % x = sqsolve(H, f, A, b, Aeq, beq, lb, ub, x0) 18 | % x = sqsolve(H, f, A, b, Aeq, beq, lb, ub, x0, options) 19 | % x = sqsolve(H, f, A, b, Aeq, beq, lb, ub, x0, lambda, states, options) 20 | % 21 | % [x,fval] = sqsolve(H, f, ...) 22 | % [x,fval,exitflag] = sqsolve(H, f, ...) 23 | % [x,fval,exitflag,output] = sqsolve(H, f, ...) 24 | % [x,fval,exitflag,output,lambda] = sqsolve(H, f, ...) 25 | % 26 | % 27 | % INPUT: 28 | % H is a Matlab function (either a function handle or string) 29 | % that computes H*x for a given x or a matrix (dense or sparse). 30 | % If the problem is an LP (H = 0), then set H = 0 or H = [] 31 | % (or call lpopt). 32 | % 33 | % f is the linear term of the objective 34 | % 35 | % A, b contain the linear inequality constraints A*x <= b 36 | % 37 | % Aeq, beq(optional) contain the lineaer equality constraints Aeq*x <= beq 38 | % 39 | % lb, ub (optional) are the lower and upper bounds of x 40 | % 41 | % x0 is the initial point x 42 | % 43 | % options is an (optional) input argument of type struct. SNOPT 44 | % options can be set using this structure by creating an entry with a 45 | % field name equal to the SNOPT keyword with spaces replaced by 46 | % underscores '_'. For example, 47 | % options.iterations_limit = 250; 48 | % 49 | % Additional keywords include: 50 | % 51 | % options.name is the problem name 52 | % 53 | % options.start 'Cold', 'Warm' 54 | % 55 | % options.screen is a string set to 'on' or 'off'. 56 | % Summary to the screen is controlled 57 | % by this option. (default 'on') 58 | % 59 | % options.printfile is a string denoting the print file. 60 | % By default, no print file is created. 61 | % Not setting this option or setting it to 62 | % '' turns off print output. 63 | % 64 | % options.specsfile is a string denoting the options 65 | % filename. 66 | % 67 | % options.iwork is an integer defining the integer 68 | % SNOPT workspace length. 69 | % 70 | % options.rwork is an integer defining the real 71 | % SNOPT workspace length. 72 | % 73 | % OUTPUT: 74 | % x is the final point 75 | % 76 | % fval is the final objective value 77 | % 78 | % exitFlag is the exit flag returned by SQOPT 79 | % 80 | % output is a structure containing run information -- 81 | % output.iterations is the total number of iterations 82 | % output.funcCount is the total number of function evaluations 83 | % 84 | % lambda is a structure containing the multipliers 85 | % lambda.x are for the variables 86 | % lambda.linear are for the linear constraints 87 | % 88 | % states is a structure containing the states 89 | % states.x are for the variables 90 | % states.linear are for the linear constraints 91 | % 92 | 93 | name = ''; 94 | start = 'Cold'; 95 | 96 | printfile = ''; 97 | screen = 'on'; 98 | specsfile = ''; 99 | 100 | iwork = 0; 101 | rwork = 0; 102 | 103 | % Deal with options. 104 | optionsLoc = 0; 105 | if nargin == 10 || nargin == 12, 106 | optionsLoc = nargin - 9; 107 | if isstruct(varargin{optionsLoc}), 108 | options = varargin{optionsLoc}; 109 | % Name 110 | if isfield(options,'name'), 111 | probName = options.name; 112 | end 113 | 114 | % Start 115 | if isfield(options,'start'), 116 | start = options.start; 117 | end 118 | 119 | % Print output 120 | if isfield(options,'printfile'), 121 | if ischar(options.printfile), 122 | printfile = options.printfile; 123 | end 124 | end 125 | 126 | % Specs file 127 | if isfield(options,'specsfile'), 128 | if ischar(options.specsfile), 129 | specsfile = options.specsfile; 130 | end 131 | end 132 | 133 | % Screen 134 | if isfield(options,'screen'), 135 | if ischar(options.screen), 136 | screen = options.screen; 137 | end 138 | end 139 | 140 | % iwork 141 | if isfield(options,'iwork'), 142 | if ischar(options.iwork), 143 | iwork = options.iwork; 144 | end 145 | end 146 | 147 | % rwork 148 | if isfield(options,'rwork'), 149 | if ischar(options.rwork), 150 | rwork = options.rwork; 151 | end 152 | end 153 | 154 | else 155 | optionsLoc = 0; 156 | end 157 | end 158 | 159 | 160 | % Set print, screen, workspace FIRST. 161 | sqprint(printfile); 162 | sqscreen(screen); 163 | sqsetwork(iwork,rwork); 164 | 165 | 166 | % Read specsfile 167 | if ~strcmp(specsfile,''), 168 | mexopt = 9; 169 | info = sqspecs(specsfile); 170 | 171 | if info ~= 101 && info ~= 107, 172 | x = []; obj = 0; output = []; lambda = []; states = []; 173 | 174 | end_sqopt(); 175 | return; 176 | end 177 | end 178 | 179 | % Handle other options 180 | if (optionsLoc ~= 0), 181 | fields = fieldnames(options); 182 | for i = 1:numel(fields), 183 | if (ischar(fields{i})), 184 | keyword = strrep(fields{i}, '_', ' '); 185 | 186 | if ~strcmp(keyword,'screen') && ... 187 | ~strcmp(keyword,'printfile') && ... 188 | ~strcmp(keyword,'specsfile') && ... 189 | ~strcmp(keyword,'name') && ... 190 | ~strcmp(keyword,'iwork') && ... 191 | ~strcmp(keyword,'rwork') && ... 192 | ~strcmp(keyword,'start'), 193 | 194 | option = options.(fields{i}); 195 | 196 | if (isnumeric(option)), 197 | option = num2str(option); 198 | end 199 | string = strjoin({keyword, option}); 200 | 201 | sqset(string); 202 | end 203 | end 204 | end 205 | end 206 | 207 | if isempty(H), 208 | warning('No Hessian detected: the problem is an LP'); 209 | userHx = 0; 210 | else 211 | if isnumeric(H), 212 | if H == 0, 213 | warning('No Hessian detected: the problem is an LP'); 214 | userHx = 0; 215 | else 216 | userHx = @(x)myHx(H,x); 217 | end 218 | else 219 | userHx = checkFun(H,'SQOPT','H'); 220 | end 221 | end 222 | 223 | 224 | if nargin == 2, 225 | % sqsolve(H, f) 226 | A = []; b = []; 227 | Aeq = []; beq = []; 228 | lb = []; ub = []; 229 | x0 = []; 230 | 231 | xstate = []; xmul = []; 232 | astate = []; amul = []; 233 | 234 | elseif nargin == 4, 235 | % sqsolve(H, f, A, b) 236 | A = varargin{1}; 237 | b = varargin{2}; 238 | Aeq = []; beq = []; 239 | lb = []; ub = []; 240 | x0 = []; 241 | 242 | xstate = []; xmul = []; 243 | astate = []; amul = []; 244 | 245 | 246 | elseif nargin == 6, 247 | % sqsolve(H, f, A, b, Aeq, beq) 248 | A = varargin{1}; 249 | b = varargin{2}; 250 | Aeq = varargin{3}; 251 | beq = varargin{4}; 252 | lb = []; ub = []; 253 | x0 = []; 254 | 255 | xstate = []; xmul = []; 256 | astate = []; amul = []; 257 | 258 | elseif nargin == 8, 259 | % sqsolve(H, f, A, b, Aeq, beq, lb, ub) 260 | A = varargin{1}; 261 | b = varargin{2}; 262 | Aeq = varargin{3}; 263 | beq = varargin{4}; 264 | lb = varargin{5}; 265 | ub = varargin{6}; 266 | x0 = []; 267 | 268 | xstate = []; xmul = []; 269 | astate = []; amul = []; 270 | 271 | elseif nargin == 9, 272 | % sqsolve(H, f, A, b, Aeq, beq, lb, ub, x0) 273 | A = varargin{1}; 274 | b = varargin{2}; 275 | Aeq = varargin{3}; 276 | beq = varargin{4}; 277 | lb = varargin{5}; 278 | ub = varargin{6}; 279 | x0 = varargin{7}; 280 | 281 | xstate = []; xmul = []; 282 | astate = []; amul = []; 283 | 284 | elseif nargin == 10 || nargin == 12, 285 | % sqsolve(H, f, A, b, Aeq, beq, lb, ub, x0, options) 286 | % sqsolve(H, f, A, b, Aeq, beq, lb, ub, x0, lambda, states, options) 287 | A = varargin{1}; 288 | b = varargin{2}; 289 | Aeq = varargin{3}; 290 | beq = varargin{4}; 291 | lb = varargin{5}; 292 | ub = varargin{6}; 293 | x0 = varargin{7}; 294 | 295 | xstate = []; xmul = []; 296 | astate = []; amul = []; 297 | 298 | if nargin == 12, 299 | lambda = varargin{8}; 300 | states = varargin{9}; 301 | 302 | xstate = states.x; 303 | xmul = lambda.x; 304 | astate = states.linear; 305 | amul = lambda.linear; 306 | end 307 | 308 | else 309 | error('SQOPT:InputArgs','Wrong number of input arguments for sqsolve'); 310 | end 311 | 312 | ineq = size(A,1); 313 | AA = [ A; Aeq ]; 314 | al = [ -inf*ones(ineq,1); beq ]; 315 | au = [ b; beq ]; 316 | 317 | m = size(AA,1); 318 | n = size(x0,1); 319 | 320 | [x,fval,exitFlag,output,lambda] = solve_sqopt(start,name, m, n, ... 321 | userHx, f, x0, lb, ub, xstate, xmul, ... 322 | AA, al, au, astate, amul); 323 | 324 | end_sqopt(); 325 | 326 | 327 | function [Hx] = myHx(H,x) 328 | Hx = H*x; -------------------------------------------------------------------------------- /matlab/sqopt.m: -------------------------------------------------------------------------------- 1 | function [x,obj,info,output,lambda,states] = sqopt(H, c, x0, xl, xu, A, al, au, varargin) 2 | % function [x,obj,info,output,lambda,states] = sqopt(H, c, x0, xl, xu, A, al, au, varargin) 3 | % 4 | % This function solves the quadratic optimization problem: 5 | % minimize: 6 | % c'x + x'*H*x 7 | % subject to: 8 | % xl <= x <= xu 9 | % al <= Ax <= au 10 | % where: 11 | % x is the column vector of initial values of the unknowns 12 | % xl, xu are the lower and upper bounds of the variables 13 | % c is the linear term of the objective 14 | % H is the Hessian matrix of the objective 15 | % A is the linear constraint matrix 16 | % al, au are the lower and upper bounds of the linear constraints 17 | % 18 | % Calling sequences: 19 | % [] = sqopt(H, c, x0, xl, xu, A, al, au) 20 | % [] = sqopt(H, c, x0, xl, xu, A, al, au, options) 21 | % 22 | % [] = sqopt(H, c, x0, xl, xu, A, al, au, states, lambda) 23 | % [] = sqopt(H, c, x0, xl, xu, A, al, au, states, lambda, options) 24 | % 25 | % [x,obj,info,output,lambda,states] = sqopt(...) 26 | % 27 | % 28 | % INPUT: 29 | % x0 is the initial guess for x 30 | % 31 | % H is a Matlab function (either a function handle or string) 32 | % that computes H*x for a given x or a matrix (dense or sparse). 33 | % If the problem is an LP (H = 0), then set H = 0 or H = [] 34 | % (or call lpopt). 35 | % 36 | % c is the linear term of the quadratic objective 37 | % 38 | % xl, xu are the upper and lower bounds on x 39 | % 40 | % A is the linear constraint matrix. A can be a structure, or a 41 | % dense or sparse matrix. 42 | % If A is a structure, then A is represented as a 43 | % sparse-by-column matrix and should have fields: 44 | % A.loc -- column pointers 45 | % A.ind -- row indices 46 | % A.val -- matrix values 47 | % 48 | % al, au are the upper and lower bounds on the linear constraints A*x 49 | % 50 | % options is an (optional) input argument of type struct. SNOPT 51 | % options can be set using this structure by creating an entry with a 52 | % field name equal to the SNOPT keyword with spaces replaced by 53 | % underscores '_'. For example, 54 | % options.iterations_limit = 250; 55 | % 56 | % Additional keywords include: 57 | % 58 | % options.name is the problem name 59 | % 60 | % options.start 'Cold', 'Warm' 61 | % 62 | % options.screen is a string set to 'on' or 'off'. 63 | % Summary to the screen is controlled 64 | % by this option. (default 'on') 65 | % 66 | % options.printfile is a string denoting the print file. 67 | % By default, no print file is created. 68 | % Not setting this option or setting it to 69 | % '' turns off print output. 70 | % 71 | % options.specsfile is a string denoting the options 72 | % filename. 73 | % 74 | % options.iwork is an integer defining the integer 75 | % SNOPT workspace length. 76 | % 77 | % options.rwork is an integer defining the real 78 | % SNOPT workspace length. 79 | % 80 | % 81 | % OUTPUT: 82 | % x is the final point 83 | % 84 | % obj is the final objective value 85 | % 86 | % info is the exit flag returned by the solver 87 | % 88 | % output is a structure containing run information -- 89 | % output.iterations is the total number of iterations 90 | % output.funcCount is the total number of function evaluations 91 | % 92 | % lambda is a structure containing the multipliers 93 | % lambda.x are for the variables 94 | % lambda.linear are for the linear constraints 95 | % 96 | % states is a structure 97 | % states.x are for the variables 98 | % states.linear are for the linear constraints 99 | % 100 | 101 | name = ''; 102 | start = 'Cold'; 103 | 104 | printfile = ''; 105 | screen = 'on'; 106 | specsfile = ''; 107 | 108 | iwork = 0; 109 | rwork = 0; 110 | 111 | % Deal with options. 112 | optionsLoc = 0; 113 | if nargin == 9 || nargin == 11, 114 | optionsLoc = nargin - 8; 115 | if isstruct(varargin{optionsLoc}), 116 | options = varargin{optionsLoc}; 117 | % Name 118 | if isfield(options,'name'), 119 | name = options.name; 120 | end 121 | 122 | % Start 123 | if isfield(options,'start'), 124 | start = options.start; 125 | end 126 | 127 | % Print output 128 | if isfield(options,'printfile'), 129 | if ischar(options.printfile), 130 | printfile = options.printfile; 131 | end 132 | end 133 | 134 | % Specs file 135 | if isfield(options,'specsfile'), 136 | if ischar(options.specsfile), 137 | specsfile = options.specsfile; 138 | end 139 | end 140 | 141 | % Screen 142 | if isfield(options,'screen'), 143 | if ischar(options.screen), 144 | screen = options.screen; 145 | end 146 | end 147 | 148 | % iwork 149 | if isfield(options,'iwork'), 150 | if ischar(options.iwork), 151 | iwork = options.iwork; 152 | end 153 | end 154 | 155 | % rwork 156 | if isfield(options,'rwork'), 157 | if ischar(options.rwork), 158 | rwork = options.rwork; 159 | end 160 | end 161 | 162 | else 163 | optionsLoc = 0; 164 | end 165 | end 166 | 167 | 168 | % Set print, screen, workspace FIRST. 169 | sqprint(printfile); 170 | sqscreen(screen); 171 | sqsetwork(iwork,rwork); 172 | 173 | 174 | % Read specsfile 175 | if ~strcmp(specsfile,''), 176 | info = sqspec(specsfile); 177 | 178 | if info ~= 101 && info ~= 107, 179 | x = []; obj = 0; output = []; lambda = []; states = []; 180 | end_sqopt(); 181 | return; 182 | end 183 | end 184 | 185 | % Handle other options 186 | if (optionsLoc ~= 0), 187 | fields = fieldnames(options); 188 | for i = 1:numel(fields), 189 | if (ischar(fields{i})), 190 | keyword = strrep(fields{i}, '_', ' '); 191 | 192 | if ~strcmp(keyword,'screen') && ... 193 | ~strcmp(keyword,'printfile') && ... 194 | ~strcmp(keyword,'specsfile') && ... 195 | ~strcmp(keyword,'name') && ... 196 | ~strcmp(keyword,'iwork') && ... 197 | ~strcmp(keyword,'rwork') && ... 198 | ~strcmp(keyword,'start'), 199 | 200 | option = options.(fields{i}); 201 | 202 | if (isnumeric(option)), 203 | option = num2str(option); 204 | end 205 | string = strjoin({keyword, option}); 206 | 207 | sqset(string); 208 | end 209 | end 210 | end 211 | end 212 | 213 | if isempty(H), 214 | warning('No Hessian detected: the problem is an LP'); 215 | userHx = 0; 216 | else 217 | if isnumeric(H), 218 | if H == 0, 219 | warning('No Hessian detected: the problem is an LP'); 220 | userHx = 0; 221 | else 222 | userHx = @(x)myHx(H,x); 223 | end 224 | else 225 | userHx = checkFun(H,'SQOPT','Hx'); 226 | end 227 | end 228 | 229 | 230 | if nargin == 8 || nargin == 9, 231 | % sqopt(H, c, x0, xl, xu, A, al, au) 232 | % sqopt(H, c, x0, xl, xu, A, al, au, options) 233 | 234 | xstate = []; xmul = []; 235 | astate = []; amul = []; 236 | 237 | elseif nargin == 10 || nargin == 11, 238 | % sqopt(H, c, x0, xl, xu, A, al, au, states, lambda) 239 | % sqopt(H, c, x0, xl, xu, A, al, au, states, lambda, options) 240 | 241 | states = varargin{1}; 242 | lambda = varargin{2}; 243 | 244 | xstate = []; xmul = []; 245 | astate = []; amul = []; 246 | 247 | if isfield(states,'x'), 248 | xstate = states.x; 249 | end 250 | 251 | if isfield(lambda,'x'), 252 | xmul = lambda.x; 253 | end 254 | 255 | if isfield(states,'linear'), 256 | astate = states.linear; 257 | end 258 | 259 | if isfield(lambda,'linear'), 260 | amul = lambda.linear; 261 | end 262 | 263 | else 264 | error('SQOPT:InputArgs','Wrong number of arguments in SQOPT'); 265 | end 266 | 267 | if isempty(A), 268 | % Setup fake constraint matrix and bounds 269 | warning('SQOPT:InputArgs','No linear constraints detected; dummy constraint created'); 270 | 271 | m = 1; 272 | n = numel(x0); 273 | 274 | neA = 1; 275 | indA(1) = 1; 276 | valA(1) = 1.0; 277 | 278 | locA = zeros(n+1,1); 279 | locA(1) = 1; 280 | locA(2:n+1) = 2; 281 | al = [-inf]; au = [inf]; 282 | 283 | else 284 | if isstruct(A), 285 | if isfield(A,'ind') && isfield(A,'loc') && isfield(A,'val'), 286 | % In sparse-by-col form 287 | n = numel(x0); 288 | locA = colvec(A.loc,'A.loc',1,n+1); 289 | indA = colvec(A.ind,'A.ind',1,0); 290 | valA = colvec(A.val,'A.val',1,0); 291 | m = max(indA); 292 | neA = numel(valA); 293 | else 294 | error('SQOPT:InputArgs','Matrix must have ind, loc, and val fields') 295 | end 296 | 297 | else 298 | [m,n] = size(A); 299 | [neA,indA,locA,valA] = crd2spr(A); 300 | end 301 | end 302 | 303 | x0 = colvec(x0,'x0',1,n); 304 | xl = colvec(xl,'xl',1,n); 305 | xu = colvec(xu,'xu',1,n); 306 | al = colvec(al,'al',1,m); 307 | au = colvec(au,'au',1,m); 308 | c = colvec(c,'c',1,0); 309 | 310 | [x,obj,info,output,lambda,states] = solve_sqopt(start, name, ... 311 | m, n, userHx, c, ... 312 | x0, xl, xu, xstate, xmul, ... 313 | neA, indA, locA, valA, ... 314 | al, au, astate, amul); 315 | 316 | end_sqopt(); 317 | 318 | 319 | function [Hx] = myHx(H,x) 320 | Hx = H*x; -------------------------------------------------------------------------------- /matlab/snsolve.m: -------------------------------------------------------------------------------- 1 | function [x,fval,info,output,lambda,states] = snsolve(obj,x0,A,b,varargin) 2 | % function [x,fval,info,output,lambda,states] = snsolve(obj,x0,A,b,varargin) 3 | % 4 | % [...] = snsolve(obj,x0,A,b) 5 | % [...] = snsolve(obj,x0,A,b,options) 6 | % 7 | % [...] = snsolve(obj,x0,A,b,Aeq,beq) 8 | % [...] = snsolve(obj,x0,A,b,Aeq,beq,options) 9 | % 10 | % [...] = snsolve(obj,x0,A,b,Aeq,beq,xlow,xupp) 11 | % [...] = snsolve(obj,x0,A,b,Aeq,beq,xlow,xupp,options) 12 | % 13 | % [...] = snsolve(obj,x0,A,b,Aeq,beq,xlow,xupp,nonlcon) 14 | % [...] = snsolve(obj,x0,A,b,Aeq,beq,xlow,xupp,nonlcon,options) 15 | % 16 | % [...] = snsolve(obj,x0,A,b,Aeq,beq,xlow,xupp,nonlcon,lambda,states) 17 | % [...] = snsolve(obj,x0,A,b,Aeq,beq,xlow,xupp,nonlcon,lambda,states,options) 18 | % 19 | % 20 | % Output from snsolve: 21 | % [x,fval,info,output,lambda,states] = snsolve(...) 22 | % 23 | % 24 | % snsolve and fmincon assume problems are of the form: 25 | % minimize f(x) 26 | % such that c(x) <= 0, 27 | % c_eq(x) = 0, 28 | % Ax <= b, 29 | % A_eq x = b_eq, 30 | % xlow <= x <= xupp. 31 | % 32 | % Input: 33 | % options is an (optional) input argument of type struct. SNOPT 34 | % options can be set using this structure by creating an entry with a 35 | % field name equal to the SNOPT keyword with spaces replaced by 36 | % underscores '_'. For example, 37 | % options.iterations_limit = 250; 38 | % 39 | % Additional keywords include: 40 | % 41 | % options.name is the problem name 42 | % 43 | % options.start 'Cold', 'Warm' 44 | % 45 | % options.screen is a string set to 'on' or 'off'. 46 | % Summary to the screen is controlled 47 | % by this option. (default 'on') 48 | % 49 | % options.printfile is a string denoting the print file. 50 | % By default, no print file is created. 51 | % Not setting this option or setting it to 52 | % '' turns off print output. 53 | % 54 | % options.specsfile is a string denoting the options 55 | % filename. 56 | % 57 | % options.stop is the "snSTOP" function called at every 58 | % major iteration. 59 | % 60 | % options.iwork is an integer defining the integer 61 | % SNOPT workspace length. 62 | % 63 | % options.rwork is an integer defining the real 64 | % SNOPT workspace length. 65 | % 66 | % Output: 67 | % x solution 68 | % 69 | % fval final objective value at x 70 | % 71 | % info exit condition from SNOPT 72 | % 73 | % output is a struct with the following fields 74 | % output.info exit code from SNOPT (same as info) 75 | % output.iterations the total number of minor iterations 76 | % output.majors the total number of major iterations 77 | % 78 | % lambda are the final multipliers 79 | % lambda.x variables 80 | % lambda.ineqnonlin nonlinear inequalities 81 | % lambda.eqnonlin nonlinear equalities 82 | % lambda.ineqlin linear inequalities 83 | % lambda.eqlin linear equalities 84 | % 85 | % states are the final states 86 | % states.x variables 87 | % states.ineqnonlin nonlinear inequalities 88 | % states.eqnonlin nonlinear equalities 89 | % states.ineqlin linear inequalities 90 | % states.eqlin linear equalities 91 | % 92 | % 93 | 94 | name = ''; 95 | istart = 0; 96 | 97 | printfile = ''; 98 | screen = 'on'; 99 | specsfile = ''; 100 | 101 | iwork = 0; 102 | rwork = 0; 103 | 104 | stopFun = 0; 105 | optionsLoc = 0; 106 | 107 | 108 | % Deal with options 109 | if nargin == 5 || nargin == 7 || nargin == 9 || ... 110 | nargin == 10 || nargin == 12, 111 | optionsLoc = nargin - 4; 112 | if isstruct(varargin{optionsLoc}), 113 | options = varargin{optionsLoc}; 114 | 115 | % Name 116 | if isfield(options,'name'), 117 | name = options.name; 118 | end 119 | 120 | % Start 121 | if isfield(options,'start'), 122 | if strcmp(lower(options.start),'warm'), 123 | istart = 1; 124 | elseif strcmp(lower(options.start),'hot'), 125 | istart = 2; 126 | end 127 | end 128 | 129 | % Print output 130 | if isfield(options,'printfile'), 131 | if ischar(options.printfile), 132 | printfile = options.printfile; 133 | end 134 | end 135 | 136 | % Specs file 137 | if isfield(options,'specsfile'), 138 | if ischar(options.specsfile), 139 | specsfile = options.specsfile; 140 | end 141 | end 142 | 143 | % Screen 144 | if isfield(options,'screen'), 145 | if ischar(options.screen), 146 | screen = options.screen; 147 | end 148 | end 149 | 150 | % Stop function 151 | if isfield(options,'stop'), 152 | if ischar(options.stop), 153 | stopFun = str2func(options.stop); 154 | elseif isa(options.stop,'function_handle'), 155 | stopFun = options.stop; 156 | else 157 | error('SNOPT:InputArgs','options.stop should be a string or function handle'); 158 | end 159 | end 160 | 161 | % iwork 162 | if isfield(options,'iwork'), 163 | if ischar(options.iwork), 164 | iwork = options.iwork; 165 | end 166 | end 167 | 168 | % rwork 169 | if isfield(options,'rwork'), 170 | if ischar(options.rwork), 171 | rwork = options.rwork; 172 | end 173 | end 174 | 175 | else 176 | optionsLoc = 0; 177 | end 178 | end 179 | 180 | % Set print, screen, workspace FIRST. 181 | snprint(printfile); 182 | snscreen(screen); 183 | snsetwork(iwork,rwork); 184 | 185 | 186 | % Read specsfile 187 | if ~strcmp(specsfile,''), 188 | mexopt = 9; 189 | info = snspec(specsfile); 190 | 191 | if info ~= 101 && info ~= 107, 192 | x = []; xmul = []; xstate = []; 193 | F = []; Fmul = []; Fstate = []; 194 | output = []; 195 | 196 | end_snopt(); 197 | return; 198 | end 199 | end 200 | 201 | 202 | % Handle other options 203 | if (optionsLoc ~= 0), 204 | fields = fieldnames(options); 205 | for i = 1:numel(fields), 206 | if (ischar(fields{i})), 207 | keyword = strrep(fields{i}, '_', ' '); 208 | 209 | if ~strcmp(keyword,'screen') && ... 210 | ~strcmp(keyword,'printfile') && ... 211 | ~strcmp(keyword,'specsfile') && ... 212 | ~strcmp(keyword,'name') && ... 213 | ~strcmp(keyword,'iwork') && ... 214 | ~strcmp(keyword,'rwork') && ... 215 | ~strcmp(keyword,'stop') && ... 216 | ~strcmp(keyword,'start'), 217 | 218 | option = options.(fields{i}); 219 | 220 | if (isnumeric(option)), 221 | option = num2str(option); 222 | end 223 | string = strjoin({keyword, option}); 224 | 225 | snset(string); 226 | end 227 | end 228 | end 229 | end 230 | 231 | 232 | linear_ineq = size(A,1); 233 | linear_eq = 0; 234 | nonlin_ineq = 0; 235 | nonlin_eq = 0; 236 | nonlcon = 0; 237 | x0 = colvec(x0,'x0',0,0); 238 | n = length(x0); 239 | 240 | 241 | % Check user-defined functions 242 | myobj = checkFun(obj,'SNOPT','obj'); 243 | 244 | gotGrad = 0; 245 | try 246 | [fobj,gobj] = myobj(x0); 247 | gotGrad = 1; 248 | catch 249 | try 250 | fobj = myobj(x0); 251 | gotGrad = 0; 252 | catch 253 | error('SNOPT:InputArgs', ... 254 | 'Wrong number of output arguments for obj'); 255 | end 256 | end 257 | 258 | 259 | if nargin == 4 || nargin == 5, 260 | % snsolve(obj,x0,A,b) 261 | % snsolve(obj,x0,A,b,options) 262 | 263 | Aeq = []; beq = []; 264 | xlow = []; xupp = []; 265 | c = []; ceq = []; 266 | xmul = []; xstate = []; 267 | Fmul = []; Fstate = []; 268 | 269 | 270 | elseif nargin == 6 || nargin == 7, 271 | % snsolve(obj,x0,A,b,Aeq,beq) 272 | % snsolve(obj,x0,A,b,Aeq,beq,options) 273 | 274 | Aeq = varargin{1}; 275 | beq = varargin{2}; 276 | linear_eq = size(Aeq,1); 277 | 278 | xlow = []; xupp = []; 279 | c = []; ceq = []; 280 | xmul = []; xstate = []; 281 | Fmul = []; Fstate = []; 282 | 283 | elseif nargin == 8 || (nargin == 9 && optionsLoc ~=0), 284 | % snsolve(obj,x0,A,b,Aeq,beq,xlow,xupp) 285 | % snsolve(obj,x0,A,b,Aeq,beq,xlow,xupp,options) 286 | 287 | Aeq = varargin{1}; 288 | beq = varargin{2}; 289 | xlow = varargin{3}; 290 | xupp = varargin{4}; 291 | linear_eq = size(Aeq,1); 292 | c = []; ceq = []; 293 | xmul = []; xstate = []; 294 | Fmul = []; Fstate = []; 295 | 296 | elseif nargin >= 9 && nargin <= 12, 297 | % snsolve(obj,x0,A,b,Aeq,beq,xlow,xupp,nonlcon) 298 | % snsolve(obj,x0,A,b,Aeq,beq,xlow,xupp,nonlcon,options) 299 | % snsolve(obj,x0,A,b,Aeq,beq,xlow,xupp,nonlcon,lambda,states) 300 | % snsolve(obj,x0,A,b,Aeq,beq,xlow,xupp,nonlcon,lambda,states,options) 301 | 302 | Aeq = varargin{1}; 303 | beq = varargin{2}; 304 | xlow = varargin{3}; 305 | xupp = varargin{4}; 306 | nonlc = varargin{5}; 307 | linear_eq = size(Aeq,1); 308 | xmul = []; xstate = []; 309 | Fmul = []; Fstate = []; 310 | 311 | if nargin == 11 || nargin == 12, 312 | lambda = varargin{6}; 313 | states = varargin{7}; 314 | 315 | xmul = lambda.x; xstate = states.x; 316 | Fmul = [ 0; lambda.ineqnonlin; lambda.eqnonlin; 317 | lambda.ineqlin; lambda.eqlin]; 318 | Fstate = [ 0; states.ineqnonlin; states.eqnonlin; 319 | states.ineqlin; states.eqlin]; 320 | 321 | end 322 | 323 | nonlcon = checkFun(nonlc,'SNOPT','nonlcon'); 324 | 325 | gotDeriv = 0; 326 | try 327 | [c,ceq,J,Jeq] = nonlcon(x0); 328 | J = J'; Jeq = Jeq'; 329 | gotDeriv = 1; 330 | catch 331 | try 332 | [c,ceq] = nonlcon(x0); 333 | gotDeriv = 0; 334 | catch 335 | error('SNOPT:InputArgs', ... 336 | 'Wrong number of output arguments for nonlcon'); 337 | end 338 | end 339 | nonlin_ineq = size(c,1); 340 | nonlin_eq = size(ceq,1); 341 | 342 | else 343 | error('SNOPT:InputArgs','Wrong number of input arguments for snsolve') 344 | end 345 | 346 | 347 | % Set total number of constraints (size of F(x)). 348 | nCon = 1 + nonlin_ineq + nonlin_eq + linear_ineq + linear_eq; 349 | 350 | % snoptA problem format: 351 | % minimize F_obj (x) 352 | % such that l_f <= F(x) <= u_f 353 | % l <= x <= u 354 | % 355 | % [ F_obj ] [ F_0' ] [ 0 ] 1 356 | % [ c(x) ] [ c'(x) ] [ 0 ] nonlin_ineq 357 | % [ c_eq(x) ] [ c_eq'(x) ] [ 0 ] nonlin_eq 358 | % F(x) = [ Ax ] F'(x) = [ 0 ] + [ A ] linear_ineq 359 | % [ A_eq x ] [ 0 ] [ A_eq ] linear_eq 360 | % "G(x)" "A" 361 | 362 | [iAfun,jAvar,Aij] = find([zeros(1+nonlin_ineq+nonlin_eq,n); A; Aeq]); 363 | [iGfun,jGvar,~] = find([ones(1+nonlin_ineq+nonlin_eq,n); zeros(linear_ineq+linear_eq,n)]); 364 | 365 | iAfun = colvec(iAfun,'iAfun',1,0); 366 | jAvar = colvec(jAvar,'jAvar',1,0); 367 | Aij = colvec(Aij,'Aij',1,0); 368 | if length(Aij) ~= length(iAfun) || ... 369 | length(Aij) ~= length(jAvar) || ... 370 | length(iAfun) ~= length(jAvar), 371 | error('SNOPT:InputArgs','A, iAfun, jAvar must have the same length.'); 372 | end 373 | 374 | iGfun = colvec(iGfun,'iGfun',1,0); 375 | jGvar = colvec(jGvar,'jGvar',1,0); 376 | if length(iGfun) ~= length(jGvar), 377 | error('SNOPT:InputArgs','iGfun and jGvar must have the same length.'); 378 | end 379 | 380 | ObjAdd = 0; 381 | ObjRow = 1; 382 | Flow = [ -inf; 383 | -inf*ones(nonlin_ineq,1); 384 | zeros(nonlin_eq,1); 385 | -inf*ones(linear_ineq,1); 386 | beq ]; 387 | Fupp = [ inf; 388 | zeros(nonlin_ineq,1); 389 | zeros(nonlin_eq,1); 390 | b; 391 | beq ]; 392 | 393 | if isa(nonlcon,'function_handle'), 394 | [x,fval,info,output,lambda,states] = ... 395 | solve_snfmincon(istart, stopFun, name, ... 396 | @(x,needF,needG)snfun(x,needF,needG,myobj,gotGrad, ... 397 | nonlcon,gotDeriv,iGfun,jGvar), ... 398 | x0, ... 399 | xlow, xupp, xmul, xstate, ... 400 | Flow, Fupp, Fmul, Fstate, ... 401 | ObjAdd, ObjRow, ... 402 | Aij, iAfun, jAvar, iGfun, jGvar, ... 403 | n, nonlin_ineq, nonlin_eq, linear_ineq, linear_eq); 404 | else 405 | [x,fval,info,output,lambda,states] = ... 406 | solve_snfmincon(istart, stopFun, name, ... 407 | @(x,needF,needG)snfun(x,needF,needG,myobj,gotGrad), ... 408 | x0, ... 409 | xlow, xupp, xmul, xstate, ... 410 | Flow, Fupp, Fmul, Fstate, ... 411 | ObjAdd, ObjRow, ... 412 | Aij, iAfun, jAvar, iGfun, jGvar, ... 413 | n, nonlin_ineq, nonlin_eq, linear_ineq, linear_eq); 414 | end 415 | 416 | % End 417 | end_snopt(); 418 | 419 | 420 | 421 | function [F,G] = snfun(x,needF,needG,obj,gotGrad,varargin) 422 | % Wrapper for obj and nonlcon in snsolve call. 423 | 424 | % Compute objective function and gradients 425 | fobj = []; gobj = []; 426 | 427 | if needG > 0, 428 | if gotGrad, 429 | [fobj,gobj] = obj(x); 430 | else 431 | if needF > 0, 432 | fobj = obj(x); 433 | end 434 | end 435 | else 436 | fobj = obj(x); 437 | end 438 | 439 | % Compute constraint functions and gradients 440 | c = []; ceq = []; 441 | J = []; Jeq = []; 442 | 443 | if nargin == 9, 444 | nonlcon = varargin{1}; 445 | gotDeriv = varargin{2}; 446 | iGfun = varargin{3}; 447 | jGvar = varargin{4}; 448 | 449 | if needG > 0, 450 | if gotDeriv, 451 | [c,ceq,J,Jeq] = nonlcon(x); 452 | else 453 | if needF > 0, 454 | [c,ceq] = nonlcon(x); 455 | end 456 | end 457 | else 458 | [c,ceq] = nonlcon(x); 459 | end 460 | end 461 | 462 | F = [ fobj; c; ceq ]; 463 | G = [ gobj'; J; Jeq ]; 464 | 465 | % Convert G to vector format to match SNOPTA and (iGfun,jGvar) 466 | [~,n] = size(G); 467 | if n > 1, 468 | G = snfindG(iGfun,jGvar,G); 469 | end 470 | -------------------------------------------------------------------------------- /matlab/snopt.m: -------------------------------------------------------------------------------- 1 | function [x,F,info,xmul,Fmul,xstate,Fstate,output] = snopt(x, xlow, xupp, xmul, xstate,... 2 | Flow, Fupp, Fmul, Fstate,... 3 | userfun, varargin); 4 | % This function solves the nonlinear optimization problem: 5 | % minimize: 6 | % F(ObjRow) + ObjAdd 7 | % subject to: 8 | % xlow <= x <= xupp 9 | % Flow <= F <= Fupp 10 | % where: 11 | % x is the column vector of initial values of the unknowns. 12 | % 13 | % F is a vector of objective and constraint functions specified 14 | % in the m-file userfun. 15 | % 16 | % ObjRow is the objective row of F (default ObjRow = 1). 17 | % 18 | % userfun is the handle for a Matlab funcion that defines the elements of F 19 | % and optionally, their derivatives. 20 | % 21 | % Additional arguments allow the specification of more detailed problem information. 22 | % 23 | % Calling sequence 1: 24 | % [...] = snopt(x, xlow, xupp, xmul, xstate, 25 | % Flow, Fupp, Fmul, Fstate, userfun, 26 | % [options]) 27 | % 28 | % Calling sequence 2: 29 | % [...] = snopt(x, xlow, xupp, xmul, xstate,... 30 | % Flow, Fupp, Fmul, Fstate, userfun,... 31 | % ObjAdd, ObjRow, [options]) 32 | % 33 | % Calling sequence 3: 34 | % [...] = snopt(x, xlow, xupp, xmul, xstate,... 35 | % Flow, Fupp, Fmul, Fstate, userfun,... 36 | % ObjAdd, ObjRow, 37 | % A, G, [options]) 38 | % 39 | % Output from snopt: 40 | % [x,F,info,xmul,Fmul,xstate,Fstate,output] = snopt(...) 41 | % 42 | % 43 | % INPUT: 44 | % x is the initial guess for x. 45 | % 46 | % xlow, xupp are the upper and lower bounds on x. 47 | % 48 | % xmul contains the initial multipliers for x. 49 | % 50 | % xstate are the states of the variables x. 51 | % 52 | % Flow, Fupp are the upper and lower bounds on F. 53 | % 54 | % Fmul contains the initial multipliers for F. 55 | % 56 | % Fstate are the states of the constraints F. 57 | % 58 | % userfun is the user-defined Matlab function that computes the 59 | % objective and constraint functions and their corresponding 60 | % derivatives. 61 | % userfun can be either a function handle or a string. 62 | % 63 | % WARNING: If arguments iAfun, jAvar, and A, are provided, 64 | % then it is crucial that the associated linear terms 65 | % are not included in the calculation of F in userfun. 66 | % **Example: 67 | % >> [f,G] = userfun(x); 68 | % >> F = sparse(iAfun,jAvar,A)*x + f 69 | % >> DF = sparse(iAfun,jAvar,A) + sparse(iGfun,jGvar,G) 70 | % (where DF denotes F'). 71 | % G must be either a dense matrix, or a vector of derivatives 72 | % in the same order as the indices iGfun and jGvar, i.e., 73 | % if G is a vector, the Jacobian of f is given 74 | % by sparse(iGfun,jGvar,G). 75 | % 76 | % **More details on G: 77 | % The user maybe define, all, some, or none of the 78 | % entries of G. If the user does NOT intend to 79 | % supply ALL nonzero entries of G, it is imperative 80 | % that the proper derivative level is set 81 | % >> option.derivative_option = k; 82 | % where k = 0 or 1. Meaning: 83 | % 1 -- Default. All derivatives are provided. 84 | % 0 -- Some derivatives are not provided. 85 | % For the case k = 0 (ONLY), G may be returned as 86 | % an empty array []. 87 | % For the case k = 0, the user must denote 88 | % unknown NONZERO elements of G by NaN. 89 | % **Example: (vector case) 90 | % >> G = [1, NaN, 3, NaN, -5]'; 91 | % or (full matrix case) 92 | % >> G = [1, 0, NaN; 0 NaN 2; 0 0 3]; 93 | % 94 | % ObjAdd is the constant term in the objective function. The default 95 | % is 0. If ObjRow /= 0, then ObjAdd is added to F(ObjRow). 96 | % 97 | % ObjRow indicates which row of F acts as the objective function. 98 | % If not specified, the default is 1. 99 | % 100 | % A is either a struct type or a matrix (dense or sparse) 101 | % that defines the constant elements in the Jacobian of F. 102 | % 103 | % If A is a struct, the structure is provided in 104 | % coordinate form with fields: 105 | % A.row 106 | % A.col 107 | % A.val 108 | % If i = A.row(k) and j = A.col(k), then A.val(k) is the (i,j)-th 109 | % element in A. 110 | % 111 | % G is a struct type or a matrix (dense or sparse) defining 112 | % the nonlinear elements in the Jacobian of F. 113 | % 114 | % If G is a struct, the Jacobian structure is provided in 115 | % coordinate form with fields: 116 | % G.row 117 | % G.col 118 | % If G is a matrix, then nonzero elements in the matrix 119 | % denote the nonzero elements of the nonlinear elements of 120 | % the Jacobian. 121 | % 122 | % More IMPORTANT details: 123 | % 1) The indices (A.row,A.col) must be DISJOINT from (G.row,G.col). 124 | % A nonzero element in F' must be either an element of G or an 125 | % element of A, but not the sum of the two. 126 | % 127 | % 2) If the user does not wish to provide A.row, A.col, G.row, 128 | % G.col, then snopt() will determine them by calling snJac(). 129 | % 130 | % WARNING: In this case, the derivative level will be set to zero 131 | % if constant elements exist. This is because the linear 132 | % elements have not yet been deleted from the definition of 133 | % userfun. Furthermore, if G is given in vector form, the 134 | % ordering of G may not necessarily correspond to (iGfun,jGvar) 135 | % computed by snJac(). 136 | % 137 | % options is an (optional) input argument of type struct. SNOPT 138 | % options can be set using this structure by creating an entry with a 139 | % field name equal to the SNOPT keyword with spaces replaced by 140 | % underscores '_'. For example, 141 | % options.iterations_limit = 250; 142 | % 143 | % Additional keywords include: 144 | % 145 | % options.name is the problem name 146 | % 147 | % options.start 'Cold', 'Warm' 148 | % 149 | % options.screen is a string set to 'on' or 'off'. 150 | % Summary to the screen is controlled 151 | % by this option. (default 'on') 152 | % 153 | % options.printfile is a string denoting the print file. 154 | % By default, no print file is created. 155 | % Not setting this option or setting it to 156 | % '' turns off print output. 157 | % 158 | % options.specsfile is a string denoting the options 159 | % filename. 160 | % 161 | % options.stop is the "snSTOP" function called at every 162 | % major iteration. 163 | % 164 | % options.iwork is an integer defining the integer 165 | % SNOPT workspace length. 166 | % 167 | % options.rwork is an integer defining the real 168 | % SNOPT workspace length. 169 | % 170 | name = ''; 171 | istart = 0; 172 | 173 | printfile = ''; 174 | screen = 'on'; 175 | specsfile = ''; 176 | 177 | iwork = 0; 178 | rwork = 0; 179 | 180 | stopFun = 0; 181 | optionsLoc = 0; 182 | 183 | % Deal with options first. 184 | if nargin == 11 || nargin == 13 || nargin == 15, 185 | optionsLoc = nargin - 10; 186 | if isstruct(varargin{optionsLoc}), 187 | options = varargin{optionsLoc}; 188 | 189 | % Name 190 | if isfield(options,'name'), 191 | name = options.name; 192 | end 193 | 194 | % Start 195 | if isfield(options,'start'), 196 | if strcmp(lower(options.start),'warm'), 197 | istart = 1; 198 | elseif strcmp(lower(options.start),'hot'), 199 | istart = 2; 200 | end 201 | end 202 | 203 | % Print output 204 | if isfield(options,'printfile'), 205 | if ischar(options.printfile), 206 | printfile = options.printfile; 207 | end 208 | end 209 | 210 | % Specs file 211 | if isfield(options,'specsfile'), 212 | if ischar(options.specsfile), 213 | specsfile = options.specsfile; 214 | end 215 | end 216 | 217 | % Screen 218 | if isfield(options,'screen'), 219 | if ischar(options.screen), 220 | screen = options.screen; 221 | end 222 | end 223 | 224 | % Stop function 225 | if isfield(options,'stop'), 226 | if ischar(options.stop), 227 | stopFun = str2func(options.stop); 228 | elseif isa(options.stop,'function_handle'), 229 | stopFun = options.stop; 230 | else 231 | error('SNOPT:InputArgs','options.stop should be a string or function handle'); 232 | end 233 | end 234 | 235 | % iwork 236 | if isfield(options,'iwork'), 237 | if ischar(options.iwork), 238 | iwork = options.iwork; 239 | end 240 | end 241 | 242 | % rwork 243 | if isfield(options,'rwork'), 244 | if ischar(options.rwork), 245 | rwork = options.rwork; 246 | end 247 | end 248 | 249 | else 250 | optionsLoc = 0; 251 | end 252 | end 253 | 254 | % Set print, screen, workspace FIRST. 255 | snprint(printfile); 256 | snscreen(screen); 257 | snsetwork(iwork,rwork); 258 | 259 | 260 | % Read specsfile 261 | if ~strcmp(specsfile,''), 262 | mexopt = 9; 263 | info = snspec(specsfile); 264 | 265 | if info ~= 101 && info ~= 107, 266 | x = []; xmul = []; xstate = []; 267 | F = []; Fmul = []; Fstate = []; 268 | output = []; 269 | 270 | end_snopt(); 271 | return; 272 | end 273 | end 274 | 275 | 276 | % Handle other options 277 | if (optionsLoc ~= 0), 278 | fields = fieldnames(options); 279 | for i = 1:numel(fields), 280 | if (ischar(fields{i})), 281 | keyword = strrep(fields{i}, '_', ' '); 282 | 283 | if ~strcmp(keyword,'screen') && ... 284 | ~strcmp(keyword,'printfile') && ... 285 | ~strcmp(keyword,'specsfile') && ... 286 | ~strcmp(keyword,'name') && ... 287 | ~strcmp(keyword,'iwork') && ... 288 | ~strcmp(keyword,'rwork') && ... 289 | ~strcmp(keyword,'stop') && ... 290 | ~strcmp(keyword,'start'), 291 | 292 | option = options.(fields{i}); 293 | 294 | if (isnumeric(option)), 295 | option = num2str(option); 296 | end 297 | string = strjoin({keyword, option}); 298 | 299 | snset(string); 300 | end 301 | end 302 | end 303 | end 304 | 305 | 306 | % Check userfun 307 | userFG = checkFun(userfun,'SNOPT','userfun'); 308 | 309 | gotDeriv = 0; 310 | try 311 | [F,G] = userFG(x); 312 | gotDeriv = 1; 313 | catch 314 | try 315 | F = userFG(x); 316 | gotDeriv = 0; 317 | catch 318 | error('SNOPT:InputArgs','userfun should return 1 or 2 arguments'); 319 | end 320 | end 321 | 322 | 323 | ObjAdd = 0; 324 | ObjRow = 1; 325 | 326 | callJac = 0; 327 | 328 | if nargin == 10 || nargin == 11, 329 | % snopt(x, xlow, xupp, xmul, xstate, 330 | % Flow, Fupp, Fmul, Fstate, userfun, 331 | % [options]) 332 | % User is not providing derivative structures. 333 | 334 | warning('SNOPT:Input','User is not providing SNOPT derivatives structures'); 335 | 336 | F0 = userFG(x); 337 | nF = length(F0); 338 | n = length(x); 339 | 340 | callJac = 1; 341 | if ~gotDeriv, 342 | % User is also not providing derivatives. 343 | % Call snJac to estimate the pattern of nonzeros for the Jacobian. 344 | warning('SNOPT:Input','Derivative structures estimated via snJac'); 345 | else 346 | % User IS providing derivatives via userfun. 347 | warning('SNOPT:Input',['Derivatives provided but not structures: estimating' ... 348 | ' structure via snJac.']); 349 | end 350 | 351 | elseif nargin == 12 || nargin == 13, 352 | % snopt(x, xlow, xupp, xmul, xstate,... 353 | % Flow, Fupp, Fmul, Fstate, userfun,... 354 | % ObjAdd, ObjRow, [options]) 355 | % User is not providing derivative structures. 356 | 357 | warning('SNOPT:Input','User is not providing SNOPT derivatives structures'); 358 | 359 | F0 = userFG(x); 360 | nF = length(F0); 361 | n = length(x); 362 | 363 | callJac = 1; 364 | if ~gotDeriv, 365 | % Call snJac to estimate the pattern of nonzeros for the Jacobian. 366 | warning('SNOPT:Input','Derivative structures estimated via snJac'); 367 | else 368 | % User IS providing derivatives via userfun. 369 | warning('SNOPT:Input',['Derivatives provided but not structures: estimating' ... 370 | ' structure via snJac.']); 371 | end 372 | 373 | ObjAdd = varargin{1}; 374 | ObjRow = varargin{2}; 375 | 376 | elseif nargin == 14 || nargin == 15, 377 | % snopt(x, xlow, xupp, xmul, xstate,... 378 | % Flow, Fupp, Fmul, Fstate, userfun,... 379 | % ObjAdd, ObjRow, 380 | % A, G, [options]) 381 | % The user is providing derivatives. 382 | 383 | ObjAdd = varargin{1}; 384 | ObjRow = varargin{2}; 385 | A = varargin{3}; 386 | G = varargin{4}; 387 | 388 | if isstruct(A), 389 | if isfield(A,'row') && isfield(A,'col') && isfield(A,'val'), 390 | % In coordinate form 391 | iAfun = colvec(A.row,'A.row',1,0); 392 | jAvar = colvec(A.col,'A.col',1,0); 393 | valA = colvec(A.val,'A.val',1,0); 394 | else 395 | error('SNOPT:InputArgs','Matrix must have row, col and val fields') 396 | end 397 | 398 | elseif isnumeric(A), 399 | % Dense or sparse 400 | [iAfun,jAvar,valA] = find(A); 401 | else 402 | error('SNOPT:InputArgs','Wrong input type for A') 403 | end 404 | 405 | if isstruct(G), 406 | % In coordinate form 407 | if isfield(G,'row') && isfield(G,'col'), 408 | % In coordinate form 409 | iGfun = colvec(G.row,'G.row',1,0); 410 | jGvar = colvec(G.col,'G.col',1,0); 411 | else 412 | error('SNOPT:InputArgs','Matrix must have row and col fields') 413 | end 414 | 415 | elseif isnumeric(G), 416 | % Dense or sparse 417 | [iGfun,jGvar] = find(G); 418 | else 419 | error('SNOPT:InputArgs','Wrong input type for G') 420 | end 421 | 422 | else 423 | error('SNOPT:InputArgs','Wrong number of input arguments for SNOPT') 424 | end 425 | 426 | % Call snJac 427 | if callJac > 0, 428 | [valA,iAfun,jAvar,iGfun,jGvar] = snJac(userFG,x,xlow,xupp,nF); 429 | end 430 | 431 | [x,F,info,xmul,Fmul, ... 432 | xstate,Fstate,output] = solve_snopt(istart, stopFun, name, ... 433 | @(x,needF,needG)snfun(x,needF,needG,... 434 | userFG,gotDeriv,iGfun,jGvar), ... 435 | x, ... 436 | xlow, xupp, xmul, xstate, ... 437 | Flow, Fupp, Fmul, Fstate, ... 438 | ObjAdd, ObjRow, ... 439 | valA, iAfun, jAvar, ... 440 | iGfun, jGvar); 441 | end_snopt(); 442 | 443 | 444 | function [F,G] = snfun(x,needF,needG,userfun,gotDeriv,iGfun,jGvar) 445 | % Wrapper for userfun 446 | % Compute functions and gradients (if necessary) 447 | 448 | F = []; G = []; 449 | 450 | if needG > 0 451 | if gotDeriv, 452 | [F,G] = userfun(x); 453 | 454 | % Convert G to vector format to match SNOPTA and (iGfun,jGvar) 455 | [~,n] = size(G); 456 | if n > 1, 457 | G = snfindG(iGfun,jGvar,G); 458 | end 459 | else 460 | if needF > 0, 461 | F = userfun(x); 462 | end 463 | end 464 | 465 | else 466 | if needF > 0, 467 | F = userfun(x); 468 | end 469 | end 470 | -------------------------------------------------------------------------------- /mex/snmex.F90: -------------------------------------------------------------------------------- 1 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 | ! mxsnWork module for SNOPT Fortran mex 3 | ! 4 | ! 13 Sep 2013: First version. 5 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 | 7 | #include "fintrf.h" 8 | 9 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 | 11 | module mxsnWork 12 | implicit none 13 | public 14 | 15 | ! SNOPT workspace 16 | integer :: leniw = 5000, lenrw = 5000, lencw = 500 17 | integer, allocatable :: iw(:), iw0(:) 18 | double precision, allocatable :: rw(:), rw0(:) 19 | character*8, allocatable :: cw(:), cw0(:) 20 | 21 | ! Matlab 22 | integer*4, parameter :: mxREAL = 0 23 | 24 | ! SNOPT mex variables 25 | mwPointer :: stopHandle 26 | 27 | logical :: firstCall = .true., & 28 | memCall = .false., & 29 | printOpen = .false., & 30 | summOpen = .false., & 31 | screenON = .false. 32 | 33 | integer :: callType = 0 34 | 35 | 36 | integer, parameter :: iPrint = 9, iSpecs = 4, iSumm = 55, & 37 | systemCall = 0, userCall = 1 38 | integer, parameter :: snSolve = 1, & 39 | snSetXX = 2, & 40 | snSetIX = 3, & 41 | snSetRX = 4, & 42 | snGetXX = 5, & 43 | snGetCX = 6, & 44 | snGetIX = 7, & 45 | snGetRX = 8, & 46 | snSpecs = 9, & 47 | snOpenP = 10, & 48 | snOpenS = 11, & 49 | snClosP = 12, & 50 | snClosS = 13, & 51 | snSetWork = 14, & 52 | snscrnON = 15, & 53 | snscrnOff = 16, & 54 | snFindJac = 17, & 55 | snEnd = 999 56 | 57 | public :: resetWork, deallocI, deallocR, checkCol, checkRow, & 58 | copyMxArrayI, copyMxArrayR 59 | 60 | contains 61 | 62 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 63 | 64 | subroutine resetWork 65 | !--------------------------------------------------------------------------- 66 | ! Reset workspace, output for new problem.f 67 | !--------------------------------------------------------------------------- 68 | 69 | ! if (printOpen) close(iPrint) 70 | close(iPrint) 71 | printOpen = .false. 72 | 73 | ! if (summOpen) close(iSumm) 74 | close(iSumm) 75 | summOpen = .false. 76 | 77 | close(iSpecs) 78 | 79 | firstCall = .true. 80 | memCall = .false. 81 | 82 | leniw = 5000 83 | lenrw = 5000 84 | lencw = 500 85 | 86 | if (allocated(cw)) deallocate(cw) 87 | if (allocated(iw)) deallocate(iw) 88 | if (allocated(rw)) deallocate(rw) 89 | 90 | if (allocated(cw0)) deallocate(cw0) 91 | if (allocated(iw0)) deallocate(iw0) 92 | if (allocated(rw0)) deallocate(rw0) 93 | 94 | end subroutine resetWork 95 | 96 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 97 | 98 | subroutine deallocI(array) 99 | integer, allocatable :: array(:) 100 | 101 | if (allocated(array)) deallocate(array) 102 | 103 | end subroutine deallocI 104 | 105 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 106 | 107 | subroutine deallocR(array) 108 | double precision, allocatable :: array(:) 109 | 110 | if (allocated(array)) deallocate(array) 111 | 112 | end subroutine deallocR 113 | 114 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 115 | 116 | subroutine checkCol(pm, n, name) 117 | mwPointer :: pm 118 | integer :: n 119 | character*(*) :: name 120 | !--------------------------------------------------------------------------- 121 | ! Check column dimension of pm is equal to n. 122 | !--------------------------------------------------------------------------- 123 | character*80 :: str 124 | mwSize :: m, mxGetN 125 | 126 | m = mxGetN(pm) 127 | if (m /= n) then 128 | write(str,100) name, m, n 129 | call mexErrMsgIdAndTxt('SNOPT:InputArgs',str) 130 | end if 131 | 132 | return 133 | 134 | 100 format (a, ' has incorrect column dimension ', i5, & 135 | '. Should be length ', i5) 136 | 137 | end subroutine checkCol 138 | 139 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 140 | 141 | subroutine checkRow(pm, n, name) 142 | character*(*) :: name 143 | mwPointer :: pm 144 | integer :: n 145 | !--------------------------------------------------------------------------- 146 | ! Check row dimension of pm is equal to n. 147 | !--------------------------------------------------------------------------- 148 | character*80 :: str 149 | mwSize :: m, mxGetM 150 | 151 | m = mxGetM(pm) 152 | if (m /= n) then 153 | write(str,100) name, m, n 154 | call mexErrMsgIdAndTxt('SNOPT:InputArgs',str) 155 | end if 156 | 157 | return 158 | 159 | 100 format (a, ' has incorrect row dimension ', i5, & 160 | '. Should be length ', i5) 161 | 162 | end subroutine checkRow 163 | 164 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 165 | 166 | subroutine copyMxArrayR(name, n, mxarray, array, defval) 167 | character*(*) :: name 168 | integer :: n 169 | mwPointer :: mxarray 170 | double precision :: defval, array(n) 171 | !--------------------------------------------------------------------- 172 | ! Check if matlab array is empty. 173 | ! If not empty, copy to real array. 174 | ! Else, set array to default value. 175 | !--------------------------------------------------------------------- 176 | mwPointer :: mxGetPr 177 | mwSize :: dim 178 | integer*4 :: mxIsEmpty 179 | 180 | if (n <= 0) return 181 | 182 | if (mxIsEmpty(mxarray) > 0) then 183 | array(1:n) = defval 184 | else 185 | call checkRow(mxarray, n, name) 186 | call checkCol(mxarray, 1, name) 187 | 188 | dim = n 189 | call mxCopyPtrToReal8(mxGetPr(mxarray), array(1:n), dim) 190 | end if 191 | 192 | end subroutine copyMxArrayR 193 | 194 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 195 | 196 | subroutine copyMxArrayI(name, n, mxarray, array, defval) 197 | character*(*) :: name 198 | integer :: n, defval, array(n) 199 | mwPointer :: mxarray 200 | !--------------------------------------------------------------------- 201 | ! Check if matlab array is empty. 202 | ! If not empty, copy to real array. 203 | ! Else, set array to default value. 204 | !--------------------------------------------------------------------- 205 | mwPointer :: mxGetPr 206 | mwSize :: dim 207 | integer*4 :: mxIsEmpty 208 | double precision :: tarray(n) 209 | 210 | if (n <= 0) return 211 | 212 | if (mxIsEmpty(mxarray) > 0) then 213 | array(1:n) = defval 214 | else 215 | call checkRow(mxarray, n, name) 216 | call checkCol(mxarray, 1, name) 217 | 218 | dim = n 219 | !call mxCopyPtrToInteger4(mxGetPr(mxarray), array(1:n), dim) 220 | call mxCopyPtrToReal8(mxGetPr(mxarray), tarray(1:n), dim) 221 | array(1:n) = int(tarray(1:n)) 222 | end if 223 | 224 | end subroutine copyMxArrayI 225 | 226 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 227 | 228 | end module mxsnWork 229 | 230 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 231 | 232 | module mxNLP 233 | use mxsnWork 234 | implicit none 235 | public 236 | 237 | mwPointer :: fgHandle 238 | 239 | integer :: neG 240 | 241 | integer, allocatable :: xstate(:), Fstate(:) 242 | double precision, allocatable :: x(:), xmul(:), xlow(:), xupp(:), & 243 | F(:), Fmul(:), Flow(:), Fupp(:) 244 | 245 | integer, allocatable :: iAfun(:), jAvar(:) 246 | double precision, allocatable :: A(:) 247 | integer, allocatable :: iGfun(:), jGvar(:) 248 | 249 | double precision, allocatable :: G1(:) 250 | 251 | integer, allocatable :: tFstate(:) 252 | double precision, allocatable :: tF(:), tFmul(:), tFlow(:), tFupp(:) 253 | 254 | contains 255 | 256 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 257 | 258 | subroutine resetSNOPT 259 | !--------------------------------------------------------------------------- 260 | ! resetSNOPT for new problem. 261 | ! (Also registered with mexAtExit to deallocate workspace and close files) 262 | !--------------------------------------------------------------------------- 263 | call resetWork 264 | call deallocSNOPT 265 | 266 | end subroutine resetSNOPT 267 | 268 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 269 | 270 | subroutine allocSNOPT(n, nF, lenA, lenG) 271 | integer, intent(in) :: n, nF, lenA, lenG 272 | !--------------------------------------------------------------------------- 273 | ! Allocate space for SNOPT solve. 274 | !--------------------------------------------------------------------------- 275 | 276 | call deallocSNOPT() 277 | 278 | allocate(x(n), xlow(n), xupp(n), xmul(n), xstate(n)) 279 | allocate(F(nF), Flow(nF), Fupp(nF), Fmul(nF), Fstate(nF)) 280 | 281 | if (lenA > 0) then 282 | allocate(iAfun(lenA), jAvar(lenA), A(lenA)) 283 | end if 284 | 285 | if (lenG > 0) then 286 | allocate(G1(lenG)) 287 | allocate(iGfun(lenG), jGvar(lenG)) 288 | end if 289 | 290 | end subroutine allocSNOPT 291 | 292 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 293 | 294 | subroutine deallocSNOPT() 295 | !--------------------------------------------------------------------------- 296 | ! Deallocate x,F arrays involved in solve routine. 297 | !--------------------------------------------------------------------------- 298 | 299 | if (fgHandle /= 0) call mxDestroyArray(fgHandle) 300 | if (stopHandle /= 0) call mxDestroyArray(stopHandle) 301 | 302 | fgHandle = 0 303 | stopHandle = 0 304 | 305 | call deallocR(x) 306 | call deallocR(xmul) 307 | call deallocR(xlow) 308 | call deallocR(xupp) 309 | call deallocI(xstate) 310 | 311 | call deallocR(F) 312 | call deallocR(Fmul) 313 | call deallocR(Flow) 314 | call deallocR(Fupp) 315 | call deallocI(Fstate) 316 | 317 | call deallocI(iAfun) 318 | call deallocI(jAvar) 319 | call deallocR(A) 320 | 321 | call deallocR(G1) 322 | 323 | call deallocI(iGfun) 324 | call deallocI(jGvar) 325 | 326 | end subroutine deallocSNOPT 327 | 328 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 329 | 330 | subroutine allocJac(n, lenA, lenG) 331 | integer, intent(in) :: n, lenA, lenG 332 | !--------------------------------------------------------------------------- 333 | ! Allocate space for snJac. 334 | !--------------------------------------------------------------------------- 335 | 336 | call deallocJac 337 | 338 | allocate(x(n), xlow(n), xupp(n)) 339 | 340 | allocate(iAfun(lenA), jAvar(lenA), A(lenA)) 341 | 342 | allocate(G1(lenG)) 343 | allocate(iGfun(lenG), jGvar(lenG)) 344 | 345 | end subroutine allocJac 346 | 347 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 348 | 349 | subroutine deallocJac() 350 | !--------------------------------------------------------------------------- 351 | ! Deallocate space for snJac. 352 | !--------------------------------------------------------------------------- 353 | 354 | if (fgHandle /= 0) call mxDestroyArray(fgHandle) 355 | fgHandle = 0 356 | 357 | call deallocR(x) 358 | call deallocR(xlow) 359 | call deallocR(xupp) 360 | 361 | call deallocI(iAfun) 362 | call deallocI(jAvar) 363 | call deallocR(A) 364 | 365 | call deallocI(iGfun) 366 | call deallocI(jGvar) 367 | 368 | call deallocR(G1) 369 | call deallocI(iGfun) 370 | call deallocI(jGvar) 371 | 372 | end subroutine deallocJac 373 | 374 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 375 | 376 | subroutine allocF(nF) 377 | integer, intent(in) :: nF 378 | !--------------------------------------------------------------------------- 379 | ! Allocate F space for snSTOP. 380 | !--------------------------------------------------------------------------- 381 | 382 | call deallocF() 383 | allocate(tF(nF), tFstate(nF), tFmul(nF), tFlow(nF), tFupp(nF)) 384 | 385 | end subroutine allocF 386 | 387 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 388 | 389 | subroutine deallocF() 390 | !--------------------------------------------------------------------------- 391 | ! Deallocate F space for snSTOP. 392 | !--------------------------------------------------------------------------- 393 | 394 | if (allocated(tF)) deallocate(tF) 395 | if (allocated(tFmul)) deallocate(tFmul) 396 | if (allocated(tFlow)) deallocate(tFlow) 397 | if (allocated(tFupp)) deallocate(tFupp) 398 | if (allocated(tFstate)) deallocate(tFstate) 399 | 400 | end subroutine deallocF 401 | 402 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 403 | 404 | end module mxNLP 405 | 406 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 407 | 408 | module mxQP 409 | use mxsnWork 410 | implicit none 411 | public 412 | 413 | mwPointer :: HxHandle 414 | 415 | ! SQOPT arrays 416 | integer, allocatable :: hEtype(:), hs(:), indA(:), locA(:) 417 | double precision, allocatable :: x(:), cObj(:), pi(:), rc(:), & 418 | bl(:), bu(:), valA(:) 419 | 420 | integer, allocatable :: iAfun(:), jAvar(:) 421 | double precision, allocatable :: A(:) 422 | 423 | contains 424 | 425 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 426 | 427 | subroutine resetSQOPT 428 | !--------------------------------------------------------------------------- 429 | ! resetSQOPT for new problem. 430 | ! (Also registered with mexAtExit to deallocate workspace and close files) 431 | !--------------------------------------------------------------------------- 432 | call resetWork 433 | call deallocSQOPT 434 | 435 | end subroutine resetSQOPT 436 | 437 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 438 | 439 | subroutine allocSQOPT(n, m, nnH, ncObj, neA) 440 | integer, intent(in) :: n, m, nnH, ncObj, neA 441 | !--------------------------------------------------------------------------- 442 | ! Allocate space for SQOPT solve. 443 | !--------------------------------------------------------------------------- 444 | 445 | allocate(x(n+m), pi(m), rc(n+m)) 446 | allocate(bl(n+m), bu(n+m)) 447 | 448 | allocate(hs(n+m), hEtype(n+m)) 449 | 450 | if (ncObj > 0) then 451 | allocate(cObj(ncObj)) 452 | else 453 | allocate(cObj(1)) 454 | end if 455 | 456 | if (neA > 0) then 457 | allocate(indA(neA)) 458 | allocate(valA(neA)) 459 | allocate(locA(n+1)) 460 | end if 461 | 462 | end subroutine allocSQOPT 463 | 464 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 465 | 466 | subroutine deallocSQOPT 467 | !--------------------------------------------------------------------------- 468 | ! Deallocate space for SQOPT solve. 469 | !--------------------------------------------------------------------------- 470 | 471 | if (HxHandle /= 0) call mxDestroyArray(HxHandle) 472 | HxHandle = 0 473 | 474 | call deallocR(x) 475 | call deallocR(pi) 476 | call deallocR(rc) 477 | call deallocR(bl) 478 | call deallocR(bu) 479 | call deallocR(cObj) 480 | 481 | call deallocI(hs) 482 | call deallocI(hEtype) 483 | 484 | call deallocI(indA) 485 | call deallocI(locA) 486 | call deallocR(valA) 487 | 488 | end subroutine deallocSQOPT 489 | 490 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 491 | 492 | end module mxQP 493 | 494 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 495 | -------------------------------------------------------------------------------- /mex/sqoptmex.F90: -------------------------------------------------------------------------------- 1 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 | ! File sqoptmex.F90 3 | ! Mex function for SQOPT7. 4 | ! 5 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 | 7 | #include "fintrf.h" 8 | 9 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 | 11 | subroutine mexFunction(nlhs, plhs, nrhs, prhs) 12 | use mxQP 13 | implicit none 14 | 15 | integer*4 :: nlhs, nrhs 16 | mwPointer :: prhs(*), plhs(*) 17 | !===================================================================== 18 | ! Mex function for SQOPT7 19 | ! 20 | ! Option Action 21 | ! 1 Solve the problem (quadprog-style) 22 | ! 2 Set option 23 | ! 3 Set integer option 24 | ! 4 Set real option 25 | ! 5 Get option 26 | ! 6 Get character option 27 | ! 7 Get integer option 28 | ! 8 Get real option 29 | ! 9 Read specs file 30 | ! 10 Openprint file 31 | ! 11 Opensummary file 32 | ! 12 Closeprint file 33 | ! 13 Closesummary file 34 | ! 14 Set workspace 35 | ! 15 Screen on 36 | ! 16 Screen off 37 | ! 38 | ! 15 Feb 2017: Current version. 39 | !===================================================================== 40 | ! Matlab 41 | mwPointer :: mxGetN, mxGetPr 42 | mwSize :: dim 43 | integer*4 :: mxIsChar 44 | double precision :: mxGetScalar 45 | 46 | ! SQOPT 47 | character :: filename*80 48 | integer :: iOpt, strlen 49 | double precision :: rOpt, rleniw, rlenrw 50 | external :: sqInit 51 | 52 | ! Get option. 53 | if (nrhs < 1) call mexErrMsgIdAndTxt('SQOPT:InputArg','Need an option input argument') 54 | rOpt = mxGetScalar(prhs(1)) 55 | iOpt = rOpt 56 | 57 | call mexAtExit(resetSQOPT) 58 | 59 | 60 | ! Deal with on/off screen, file, summary files first. 61 | if (iOpt == snOpenP) then 62 | 63 | if (nrhs /= 2) & 64 | call mexErrMsgIdAndTxt('SQOPT:InputArg','Wrong number of input arguments') 65 | 66 | if (mxIsChar(prhs(2)) /= 1) & 67 | call mexErrMsgIdAndTxt('SQOPT:InputArg','Need a filename string') 68 | 69 | strlen = mxGetN(prhs(2)) 70 | if (strlen > 80) call mexErrMsgIdAndTxt('SQOPT:InputArg','Print filename is too long') 71 | 72 | if (strlen > 0) then 73 | dim = strlen 74 | call mxGetString(prhs(2), filename, dim) 75 | else 76 | call mexErrMsgIdAndTxt('SQOPT:InputArg','Empty print filename') 77 | end if 78 | 79 | if (printOpen) close(iPrint) 80 | 81 | open(iPrint, file=filename, status='unknown') 82 | printOpen= .true. 83 | return 84 | 85 | else if (iOpt == snOpenS) then 86 | 87 | if (nrhs /= 2) call mexErrMsgIdAndTxt('SQOPT:InputArg','Wrong number of input arguments') 88 | 89 | if (mxIsChar(prhs(2)) /= 1) & 90 | call mexErrMsgIdAndTxt('SQOPT:InputArg','Need a filename string') 91 | 92 | strlen = mxGetN(prhs(2)) 93 | if (strlen > 80) call mexErrMsgIdAndTxt('SQOPT:InputArg','Summary filename is too long') 94 | 95 | if (strlen > 0) then 96 | dim = strlen 97 | call mxGetString(prhs(2), filename, dim) 98 | else 99 | call mexErrMsgIdAndTxt('SQOPT:InputArg','Empty summary filename') 100 | end if 101 | 102 | if (summOpen) close(iSumm) 103 | 104 | open(iSumm, file=filename, status='unknown') 105 | summOpen= .true. 106 | return 107 | 108 | else if (iOpt == snClosP) then 109 | if (printOpen) close(iPrint) 110 | printOpen= .false. 111 | return 112 | 113 | else if (iOpt == snClosS) then 114 | if (summOpen) close(iSumm) 115 | summOpen= .false. 116 | return 117 | 118 | else if (iOpt == snscrnOn) then 119 | screenOn = .true. 120 | return 121 | 122 | else if (iOpt == snscrnOff) then 123 | screenOn = .false. 124 | return 125 | 126 | else if (iOpt == snsetwork) then 127 | rleniw = mxGetScalar(prhs(2)) 128 | rlenrw = mxGetScalar(prhs(3)) 129 | leniw = rleniw 130 | lenrw = rlenrw 131 | 132 | if (leniw < 500 .or. lenrw < 500) & 133 | call mexErrMsgIdAndTxt('SQOPT:Workspace','Workspace size must be at least 500') 134 | return 135 | 136 | end if 137 | 138 | ! What calls get here: 139 | ! sqSolve, sqSet, sqGet, sqSpecs 140 | 141 | if (firstCall) then 142 | allocate(cw(lencw), iw(leniw), rw(lenrw)) 143 | 144 | callType = userCall 145 | call sqInit(iPrint, iSumm, cw, lencw, iw, leniw, rw, lenrw) 146 | callType = systemCall 147 | 148 | memCall = .false. 149 | firstCall = .false. 150 | end if 151 | 152 | ! Do whatever we need to do. 153 | if (iOpt == snSolve) then 154 | 155 | callType = userCall 156 | call sqmxSolve(nlhs, plhs, nrhs, prhs) 157 | callType = systemCall 158 | 159 | else if (iOpt == snSetXX .or. & 160 | iOpt == snSetIX .or. & 161 | iOpt == snSetRX .or. & 162 | iOpt == snGetXX .or. & 163 | iOpt == snGetCX .or. & 164 | iOpt == snGetIX .or. & 165 | iOpt == snGetRX) then 166 | 167 | callType = userCall 168 | call snmxOptions(iOpt, nlhs, plhs, nrhs, prhs) 169 | callType = systemCall 170 | 171 | else if (iOpt == snSpecs) then 172 | 173 | callType = userCall 174 | call snmxSpecs(nlhs, plhs, nrhs, prhs) 175 | callType = systemCall 176 | 177 | else if (iOpt == snEnd) then 178 | 179 | call resetSQOPT 180 | 181 | end if 182 | 183 | return 184 | 185 | end subroutine mexFunction 186 | 187 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 188 | 189 | subroutine sqmxSolve(nlhs, plhs, nrhs, prhs) 190 | use mxQP 191 | implicit none 192 | 193 | integer*4 :: nlhs, nrhs 194 | mwPointer :: prhs(*), plhs(*) 195 | !--------------------------------------------------------------------- 196 | ! Solve the problem 197 | ! The matlab call iss 198 | ! [x, fval, exit, itn, y ] = 199 | ! qpsolve(Hx, c, A, b, Aeq, beq, lb, ub, x0) 200 | ! 201 | ! where 202 | ! Hx is a user-defined subroutine to compute H*x 203 | ! c is linear terms of the objective 204 | ! x0 is the initial point 205 | ! A, b are the linear inequality constraints A*x <= b 206 | ! Aeq, beq are the linear equality constraints Aeq*x = beq 207 | ! lb, ub are the lower and upper bounds on x 208 | !--------------------------------------------------------------------- 209 | ! Matlab 210 | mwPointer :: mxDuplicateArray, mxGetM, mxGetN, mxGetPr, & 211 | mxCreateDoubleMatrix, mxCreateDoubleScalar 212 | mwSize :: dimx, dimy 213 | integer*4 :: mxIsChar, mxIsClass, mxIsEmpty, mxIsNumeric 214 | double precision :: mxGetScalar 215 | 216 | ! SQOPT 217 | character*8 :: probName, Start 218 | integer :: Errors, info, i1, i2, strlen 219 | integer :: iObj, m, n, nnH, ncObj, neA, & 220 | mincw, miniw, minrw, nInf, nS 221 | double precision :: Obj, ObjAdd, sInf 222 | 223 | external :: sqopt, matlabHx 224 | 225 | integer, parameter :: izero = 0 226 | double precision, parameter :: zero = 0.0d+0, infBnd = 1.0d+20 227 | 228 | integer, parameter :: nNames = 1 229 | character*8 :: Names(1) 230 | 231 | 232 | ! Check number of input and output arguments. 233 | if (nrhs /= 20) & 234 | call mexErrMsgIdAndTxt('SQOPT:InputArg','Wrong number of input arguments') 235 | 236 | 237 | !----------------------------------------------------------------------------- 238 | ! Start option 239 | !----------------------------------------------------------------------------- 240 | if (mxIsChar(prhs(2)) /= 1) & 241 | call mexErrMsgIdAndTxt('SQOPT:InputArg','Wrong input type for start') 242 | dimx = min(8,mxGetN(prhs(2))) 243 | call mxGetString(prhs(2), start, dimx) 244 | 245 | 246 | !--------------------------------------------------------------------- 247 | ! Problem name 248 | !--------------------------------------------------------------------- 249 | if (mxIsChar(prhs(3)) /= 1) & 250 | call mexErrMsgIdAndTxt('SQOPT:InputArg','Wrong input type for problem name') 251 | probName = '' 252 | if (mxGetN(prhs(3)) > 0) then 253 | dimx = min(8,mxGetN(prhs(3))) 254 | call mxGetString(prhs(3), probName, dimx) 255 | end if 256 | 257 | 258 | !--------------------------------------------------------------------- 259 | ! Number of constraints and variables 260 | !--------------------------------------------------------------------- 261 | m = mxGetScalar(prhs(4)) 262 | n = mxGetScalar(prhs(5)) 263 | 264 | nnH = n 265 | neA = mxGetScalar(prhs(13)) 266 | ncObj = mxGetM(prhs(7)) 267 | 268 | 269 | call allocSQOPT(n, m, nnH, ncObj, neA) 270 | 271 | 272 | !--------------------------------------------------------------------- 273 | ! Hessian matrix 274 | !--------------------------------------------------------------------- 275 | if (mxIsNumeric(prhs(6)) == 1) then 276 | HxHandle = 0 277 | nnH = 0 278 | else 279 | if (mxIsClass(prhs(6), 'function_handle') /= 1) & 280 | call mexErrMsgIdAndTxt('SQOPT:FunArg','Wrong input type for Hx') 281 | HxHandle = mxDuplicateArray(prhs(6)) 282 | end if 283 | 284 | 285 | !--------------------------------------------------------------------- 286 | ! Linear term of objective 287 | !--------------------------------------------------------------------- 288 | call copyMxArrayR('cObj', ncObj, prhs(7), cObj, zero) 289 | 290 | 291 | !--------------------------------------------------------------------- 292 | ! Copy x info 293 | !--------------------------------------------------------------------- 294 | x(n+1:n+m) = zero 295 | call copyMxArrayR('x0', n, prhs(8), x(1:n), zero) 296 | call copyMxArrayR('xl', n, prhs(9), bl(1:n), -infBnd) 297 | call copyMxArrayR('xu', n, prhs(10), bu(1:n), infBnd) 298 | call copyMxArrayI('xstate', n, prhs(11), hs(1:n), izero) 299 | call copyMxArrayR('xmul', n, prhs(12), rc(1:n), zero) 300 | 301 | 302 | !--------------------------------------------------------------------- 303 | ! Get the linear constraint matrix 304 | !--------------------------------------------------------------------- 305 | call copyMxArrayI('indA', neA, prhs(14), indA, izero) 306 | call copyMxArrayI('locA', n+1, prhs(15), locA, izero) 307 | call copyMxArrayR('valA', neA, prhs(16), valA, zero) 308 | 309 | 310 | !--------------------------------------------------------------------- 311 | ! Set the constraint bounds 312 | !--------------------------------------------------------------------- 313 | i1 = n+1 314 | i2 = n+m 315 | call copyMxArrayR('al', m, prhs(17), bl(i1:i2), -infBnd) 316 | call copyMxArrayR('au', m, prhs(18), bu(i1:i2), infBnd) 317 | call copyMxArrayI('astate', m, prhs(19), hs(i1:i2), izero) 318 | call copyMxArrayR('amul', m, prhs(20), rc(i1:i2), zero) 319 | 320 | 321 | !--------------------------------------------------------------------- 322 | ! Set workspace 323 | !--------------------------------------------------------------------- 324 | 100 if (.not. memCall) then 325 | call sqMem & 326 | (INFO, m, n, neA, ncObj, nnH, & 327 | mincw, miniw, minrw, & 328 | cw, lencw, iw, leniw, rw, lenrw) 329 | memCall = .true. 330 | 331 | if (leniw .le. miniw) then 332 | ! Not enough integer space 333 | leniw = miniw 334 | allocate(iw0(leniw)) 335 | iw0(1:500) = iw(1:500) 336 | 337 | call move_alloc(from=iw0, to=iw) 338 | 339 | end if 340 | 341 | if (lenrw .le. minrw) then 342 | ! Not enough real space 343 | lenrw = minrw 344 | allocate(rw0(lenrw)) 345 | rw0(1:500) = rw(1:500) 346 | 347 | call move_alloc(from=rw0, to=rw) 348 | end if 349 | 350 | if (lencw .le. mincw) then 351 | ! Not enough character space 352 | lencw = mincw 353 | allocate(cw0(lencw)) 354 | cw0(1:500) = cw(1:500) 355 | 356 | call move_alloc(from=cw0, to=cw) 357 | end if 358 | 359 | call sqSeti & 360 | ('Total character workspace', lencw, 0, 0, Errors, & 361 | cw, lencw, iw, leniw, rw, lenrw) 362 | call sqSeti & 363 | ('Total integer workspace', leniw, 0, 0, Errors, & 364 | cw, lencw, iw, leniw, rw, lenrw) 365 | call sqSeti & 366 | ('Total real workspace', lenrw, 0, 0, Errors, & 367 | cw, lencw, iw, leniw, rw, lenrw) 368 | end if 369 | 370 | 371 | !--------------------------------------------------------------------- 372 | ! Solve the problem 373 | !--------------------------------------------------------------------- 374 | iObj = 0 375 | ObjAdd = 0.0 376 | hEtype(1:n+m) = 0 377 | 378 | call sqopt & 379 | (Start, matlabHx, m, n, neA, nNames, & 380 | ncObj, nnH, iObj, ObjAdd, probName, & 381 | valA, indA, locA, bl, bu, cObj, Names, & 382 | hEtype, hs, x, pi, rc, & 383 | INFO, mincw, miniw, minrw, nS, nInf, sInf, Obj, & 384 | cw, lencw, iw, leniw, rw, lenrw, & 385 | cw, lencw, iw, leniw, rw, lenrw) 386 | 387 | if (INFO == 82 .or. INFO == 83 .or. INFO == 84) then 388 | memCall = .false. 389 | go to 100 390 | end if 391 | 392 | 393 | !----------------------------------------------------------------------------- 394 | ! Set output 395 | !----------------------------------------------------------------------------- 396 | if (nlhs > 0) then 397 | dimx = n 398 | dimy = 1 399 | 400 | plhs(1) = mxCreateDoubleMatrix(dimx, dimy, mxREAL) 401 | call mxCopyReal8ToPtr(x(1:n), mxGetPr(plhs(1)), dimx) 402 | end if 403 | 404 | ! Final objective 405 | if (nlhs > 1) plhs(2) = mxCreateDoubleScalar(Obj) 406 | 407 | ! Exit flag 408 | if (nlhs > 2) plhs(3) = mxCreateDoubleScalar(dble(info)) 409 | 410 | ! Iterations 411 | if (nlhs > 3) plhs(4) = mxCreateDoubleScalar(dble(iw(421))) 412 | 413 | ! Multipliers 414 | if (nlhs > 4) then 415 | dimx = n+m 416 | dimy = 1 417 | plhs(5) = mxCreateDoubleMatrix(dimx, dimy, mxREAL) 418 | call mxCopyReal8ToPtr(rc(1:n+m), mxGetPr(plhs(5)), dimx) 419 | end if 420 | 421 | ! States 422 | if (nlhs > 5) then 423 | dimx = n+m 424 | dimy = 1 425 | plhs(6) = mxCreateDoubleMatrix(dimx, dimy, mxREAL) 426 | call mxCopyReal8ToPtr(dble(hs(1:n+m)), mxGetPr(plhs(6)), dimx) 427 | end if 428 | 429 | 430 | ! Deallocate memory 431 | call deallocSQOPT 432 | 433 | end subroutine sqmxSolve 434 | 435 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 436 | 437 | subroutine snmxOptions(iOpt, nlhs, plhs, nrhs, prhs) 438 | use mxQP 439 | implicit none 440 | 441 | integer :: iOpt 442 | integer*4 :: nlhs, nrhs 443 | mwPointer :: prhs(*), plhs(*) 444 | !--------------------------------------------------------------------- 445 | ! Set/get options. 446 | !--------------------------------------------------------------------- 447 | ! Matlab 448 | mwPointer :: mxGetN, mxGetPr, mxCreateDoubleScalar, & 449 | mxCreateString 450 | mwSize :: dim 451 | double precision :: mxGetScalar 452 | 453 | character :: buffer*50, cvalue*8 454 | integer :: Errors, ivalue, strlen 455 | double precision :: rvalue 456 | 457 | integer :: sqGet 458 | external :: sqSet, sqSetI, sqSetR, & 459 | sqGet, sqGetC, sqGetI, sqGetR 460 | 461 | 462 | if (iOpt == snSetIX .or. iOpt == snSetRX) then 463 | if (nrhs /= 3) call mexErrMsgIdAndTxt('SQOPT:InputArg','Wrong number of input arguments') 464 | else 465 | if (nrhs /= 2) call mexErrMsgIdAndTxt('SQOPT:InputArg','Wrong number of input arguments') 466 | end if 467 | 468 | 469 | ! Get string 470 | strlen = mxGetN(prhs(2)) 471 | if (strlen > 50) call mexErrMsgIdAndTxt('SQOPT:InputArg','Option string is too long') 472 | 473 | if (strlen > 0) then 474 | dim = strlen 475 | call mxGetString(prhs(2), buffer, dim) 476 | else 477 | call mexErrMsgIdAndTxt('SQOPT:InputArg','Empty option string') 478 | end if 479 | 480 | 481 | if (iOpt == snSetXX) then 482 | call sqSet(buffer, iPrint, iSumm, Errors, & 483 | cw, lencw, iw, leniw, rw, lenrw) 484 | 485 | else if (iOpt == snSetIX) then 486 | 487 | rvalue = mxGetScalar(prhs(3)) 488 | ivalue = rvalue 489 | 490 | call sqSetI(buffer, ivalue, iPrint, iSumm, Errors, & 491 | cw, lencw, iw, leniw, rw, lenrw) 492 | 493 | else if (iOpt == snSetRX) then 494 | 495 | rvalue = mxGetScalar(prhs(3)) 496 | 497 | call sqSetR(buffer, rvalue, iPrint, iSumm, Errors, & 498 | cw, lencw, iw, leniw, rw, lenrw) 499 | 500 | else if (iOpt == snGetXX) then 501 | 502 | ivalue = sqGet(buffer, Errors, cw, lencw, iw, leniw, rw, lenrw) 503 | 504 | rvalue = ivalue 505 | plhs(1) = mxCreateDoubleScalar (rvalue) 506 | 507 | else if (iOpt == snGetCX) then 508 | 509 | call sqGetC(buffer, cvalue, Errors, & 510 | cw, lencw, iw, leniw, rw, lenrw) 511 | 512 | plhs(1) = mxCreateString(cvalue) 513 | 514 | else if (iOpt == snGetIX) then 515 | 516 | call sqGetI(buffer, ivalue, Errors, & 517 | cw, lencw, iw, leniw, rw, lenrw) 518 | 519 | rvalue = ivalue 520 | plhs(1) = mxCreateDoubleScalar (rvalue) 521 | 522 | else if (iOpt == snGetRX) then 523 | 524 | call sqGetR(buffer, rvalue, Errors, & 525 | cw, lencw, iw, leniw, rw, lenrw) 526 | 527 | plhs(1) = mxCreateDoubleScalar (rvalue) 528 | 529 | end if 530 | 531 | end subroutine snmxOptions 532 | 533 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 534 | 535 | subroutine snmxSpecs(nlhs, plhs, nrhs, prhs) 536 | use mxQP 537 | implicit none 538 | 539 | integer*4 :: nlhs, nrhs 540 | mwPointer :: prhs(*), plhs(*) 541 | !--------------------------------------------------------------------- 542 | ! Read specs file. 543 | !--------------------------------------------------------------------- 544 | mwPointer :: mxCreateDoubleScalar, mxGetN 545 | mwSize :: dimx 546 | 547 | character :: filename*120 548 | integer :: info, strlen 549 | double precision :: rvalue 550 | 551 | external :: sqSpec 552 | 553 | 554 | if (nrhs /= 2) call mexErrMsgIdAndTxt('SQOPT:InputArg','Wrong number of input arguments') 555 | if (nlhs /= 1) call mexErrMsgIdAndTxt('SQOPT:InputArg','Wrong number of output arguments') 556 | 557 | strlen = mxGetN(prhs(2)) 558 | if (strlen > 120) call mexErrMsgIdAndTxt('SQOPT:InputArg','Specs filename is too long') 559 | 560 | if (strlen > 0) then 561 | dimx = strlen 562 | call mxGetString(prhs(2), filename, dimx) 563 | else 564 | call mexErrMsgIdAndTxt('SQOPT:InputArg','Empty spc filename') 565 | end if 566 | 567 | open(iSpecs, file=filename, status='unknown') 568 | call sqSpec(iSpecs, info, cw, lencw, iw, leniw, rw, lenrw) 569 | rewind (iSpecs) 570 | close(iSpecs) 571 | 572 | rvalue = info 573 | plhs(1) = mxCreateDoubleScalar (rvalue) 574 | 575 | end subroutine snmxSpecs 576 | 577 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 578 | 579 | subroutine matlabHx(nnH, x, Hx, Status, cu, lencu, iu, leniu, ru, lenru) 580 | use mxsnWork, only : checkCol, checkRow, mxREAL 581 | use mxQP, only : HxHandle 582 | implicit none 583 | 584 | integer :: Status, nnH, lencu, leniu, lenru, iu(leniu) 585 | double precision :: x(nnH), Hx(nnH), ru(lenru) 586 | character*8 :: cu(lencu) 587 | 588 | !--------------------------------------------------------------------- 589 | ! Matlab callback to evaluate H*x. 590 | !--------------------------------------------------------------------- 591 | integer*4 :: nlhs, nrhs 592 | mwPointer :: prhs(2), plhs(1) 593 | mwPointer :: mxCreateDoubleMatrix, mxGetPr, mxDuplicateArray 594 | mwSize :: dimx, dimy 595 | 596 | nlhs = 1 597 | nrhs = 2 598 | 599 | prhs(1) = mxDuplicateArray(HxHandle) 600 | 601 | dimx = nnH 602 | dimy = 1 603 | prhs(2) = mxCreateDoubleMatrix (dimx, dimy, mxREAL) 604 | call mxCopyReal8ToPtr(x, mxGetPr(prhs(2)), dimx) 605 | 606 | 607 | ! Call Matlab: [Hx] = userHx(x) 608 | call mexCallMatlab(nlhs, plhs, nrhs, prhs, 'feval') 609 | 610 | dimx = nnH 611 | call mxCopyPtrToReal8(mxGetPr(plhs(1)), Hx, dimx) 612 | 613 | ! Destroy arrays 614 | call mxDestroyArray(plhs(1)) 615 | call mxDestroyArray(prhs(1)) 616 | call mxDestroyArray(prhs(2)) 617 | 618 | end subroutine matlabHx 619 | 620 | !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 621 | --------------------------------------------------------------------------------