diff --git a/demos/demo_panoc.m b/demos/demo_panoc.m new file mode 100644 index 0000000..a02414d --- /dev/null +++ b/demos/demo_panoc.m @@ -0,0 +1,30 @@ +% Only use this demo after installing the panoc library. This is only +% supported on Windows right now. Run ./external_library/setup.m to +% install panoc. + +clear all; +%% +f=@rosen; +g=indBox(-4,4); +x0=[0;0]; +aff=0; % not supported with panoc +opts.solver='panoc'; +opts.tol=1e-12; +opts.maxit=200; + +% g.name='blah'; % uncomment this line if you want to use the Matlab function constraint +tic +out = forbes(f, g, x0, aff, [], opts) % this problem should take 20 iterations +toc + +% double check the results +if(out.iterations~=20) + disp(['Error: not solved in 20 iterations as expected but in ' ... + num2str(out.iterations) 'iterations'] ); +end + +theoretical_solution = [1;1]; +if(norm(out.x-theoretical_solution)>opts.tol) + disp(['Error: solution not [1;1] as expected but[' ... + num2str(out.x(1)) ';' num2str(out.x(2)) ']' ]); +end \ No newline at end of file diff --git a/demos/rosen.m b/demos/rosen.m new file mode 100644 index 0000000..ea855ec --- /dev/null +++ b/demos/rosen.m @@ -0,0 +1,9 @@ +function [function_value,gradient] = rosen(initial_point) + a=1; + b=100; + function_value =(a-initial_point(1))^2 + b*(initial_point(2)-initial_point(1))^2; + + if nargout > 1 + gradient = [-2*(a-(b+1)*initial_point(1)+b*initial_point(2)); 2*b*(initial_point(2)-initial_point(1)) ]; + end +end diff --git a/external_library/forbes_panoc/bin/.gitignore b/external_library/forbes_panoc/bin/.gitignore new file mode 100644 index 0000000..4bc3005 --- /dev/null +++ b/external_library/forbes_panoc/bin/.gitignore @@ -0,0 +1 @@ +panoc.mexw64 \ No newline at end of file diff --git a/external_library/forbes_panoc/bin/PANOC_Mac64_clang.mexmaci64 b/external_library/forbes_panoc/bin/PANOC_Mac64_clang.mexmaci64 new file mode 100755 index 0000000..bc3a066 Binary files /dev/null and b/external_library/forbes_panoc/bin/PANOC_Mac64_clang.mexmaci64 differ diff --git a/external_library/forbes_panoc/bin/PANOC_Windows64_VStudio.lib b/external_library/forbes_panoc/bin/PANOC_Windows64_VStudio.lib new file mode 100644 index 0000000..be1f6f5 Binary files /dev/null and b/external_library/forbes_panoc/bin/PANOC_Windows64_VStudio.lib differ diff --git a/external_library/forbes_panoc/bin/PANOC_Windows64_VStudio.mexw64 b/external_library/forbes_panoc/bin/PANOC_Windows64_VStudio.mexw64 new file mode 100644 index 0000000..1906511 Binary files /dev/null and b/external_library/forbes_panoc/bin/PANOC_Windows64_VStudio.mexw64 differ diff --git a/external_library/forbes_panoc/bin/PANOC_linux64_gcc.mexa64 b/external_library/forbes_panoc/bin/PANOC_linux64_gcc.mexa64 new file mode 100755 index 0000000..387f318 Binary files /dev/null and b/external_library/forbes_panoc/bin/PANOC_linux64_gcc.mexa64 differ diff --git a/external_library/forbes_panoc/bin/readme.md b/external_library/forbes_panoc/bin/readme.md new file mode 100644 index 0000000..429e7a3 --- /dev/null +++ b/external_library/forbes_panoc/bin/readme.md @@ -0,0 +1,2 @@ +# build folder panoc +This folder contains binary's of the draft panoc library: https://github.com/Zilleplus/draf_panoc. \ No newline at end of file diff --git a/external_library/setup.m b/external_library/setup.m new file mode 100644 index 0000000..0b132f9 --- /dev/null +++ b/external_library/setup.m @@ -0,0 +1,28 @@ +% install external libs +lib_path = pwd; + +%% install panoc + + +if ismac + disp('Using mex interface Mac os'); + mex_file_location=fullfile(lib_path,'forbes_panoc','bin','PANOC_Mac64_clang.mexmaci64'); + mex_file_destination = fullfile(lib_path,'forbes_panoc','bin','panoc.mexmaci64'); +elseif isunix + disp('Using mex interface Linux'); + mex_file_location=fullfile(lib_path,'forbes_panoc','bin','PANOC_linux64_gcc.mexa64'); + mex_file_destination = fullfile(lib_path,'forbes_panoc','bin','panoc.mexa64'); +elseif ispc + disp('Using mex interface Windows'); + mex_file_location=fullfile(lib_path,'forbes_panoc','bin','panoc_Windows64VStudio.mexw64'); +else + disp('Platform not supported') +end +copyfile(mex_file_location,mex_file_destination); + + +%% add paths to path and save +addpath(fullfile(lib_path,'forbes_panoc','bin')); +addpath(fullfile(lib_path,'src_Matlab')); +savepath;% write away path variable + diff --git a/external_library/src_Matlab/readme.md b/external_library/src_Matlab/readme.md new file mode 100644 index 0000000..f3174ca --- /dev/null +++ b/external_library/src_Matlab/readme.md @@ -0,0 +1 @@ +#Matlab code that links external library's with forbes diff --git a/external_library/src_Matlab/solve_panoc.m b/external_library/src_Matlab/solve_panoc.m new file mode 100644 index 0000000..6cb8867 --- /dev/null +++ b/external_library/src_Matlab/solve_panoc.m @@ -0,0 +1,45 @@ +function [ out ] = solve_panoc( f, g ,opt , intial_solution ) + %SOLVE_PANOC Solve problem with panoc lib + + if(~isfield(g,'name')) + g.name='costum'; + end + + % parse the options into the panoc format + problem.dimension = length(intial_solution); + + if(strcmp(g.name,'box')) + problem.constraint_type = 'box'; + + problem.upper_bound=g.upper_bound; + problem.lower_bound=g.lower_bound; + else % unknown function, use the matlab version provided by the user + disp(['WARNING: No C implementation found of the constraint ' ... + 'function using the matlab implementation,'... + ' this may impact performance.']); + problem.constraint_type = 'costum'; + + % convert the function into the right format and set gamma=0 + g_function = g.makeprox(); + constraint = @(x,gamma) g_function(x,gamma); + problem.constraint = constraint; + end + + solver_params.tolerance = opt.tol; + solver_params.buffer_size = 20; + solver_params.max_iterations = opt.maxit; + + % Solve the problem with panoc, + % copy over by value the initial position. + solution=zeros(problem.dimension,1); + for i=1:problem.dimension + solution(i)=intial_solution(i); + end + + panoc('init',problem,solver_params); + number_of_iterations = panoc('solve',solution,f); + panoc('cleanup'); + + out.x=solution; + out.iterations=number_of_iterations; +end \ No newline at end of file diff --git a/forbes.m b/forbes.m index e7e32de..f06f46a 100755 --- a/forbes.m +++ b/forbes.m @@ -105,27 +105,33 @@ if nargin < 4, aff = []; end if nargin < 5, constr = []; end if nargin < 6, opt = []; end + + if(strcmp(opt.solver,'panoc')) + disp('WARNING: Using external lib, not all options are supported here.'); + % constr is not supported by panoc, ignore it + out=solve_panoc( fs, gs ,opt , init ); + else + [prob, id] = Process_Problem(fs, gs, init, aff, constr); + opt = Process_Options(opt); + lsopt = Process_LineSearchOptions(opt); - [prob, id] = Process_Problem(fs, gs, init, aff, constr); - opt = Process_Options(opt); - lsopt = Process_LineSearchOptions(opt); - - preprocess = toc(t0); + preprocess = toc(t0); - out_solver = opt.solverfun(prob, opt, lsopt); + out_solver = opt.solverfun(prob, opt, lsopt); - out.message = out_solver.message; - out.flag = out_solver.flag; - if id == 1 - out.x = out_solver.x; - else - [out.x1, out.x2, out.z] = prob.Get_DualPoints(out_solver.x, out_solver.gam); - out.y = out_solver.x; + out.message = out_solver.message; + out.flag = out_solver.flag; + if id == 1 + out.x = out_solver.x; + else + [out.x1, out.x2, out.z] = prob.Get_DualPoints(out_solver.x, out_solver.gam); + out.y = out_solver.x; + end + out.solver = out_solver; + out.prob = prob; + out.opt = opt; + out.lsopt = lsopt; + out.preprocess = preprocess; + out.time = toc(t0); end - out.solver = out_solver; - out.prob = prob; - out.opt = opt; - out.lsopt = lsopt; - out.preprocess = preprocess; - out.time = toc(t0); end diff --git a/library/indBox.m b/library/indBox.m index afa4818..55c7790 100755 --- a/library/indBox.m +++ b/library/indBox.m @@ -29,6 +29,9 @@ function obj = indBox(lower, upper) obj.isConvex = 1; obj.makeprox = @() @(x, gam) call_indBox_prox(x, lower, upper); + obj.name='box'; + obj.upper_bound=upper; + obj.lower_bound=lower; end function [prox, val] = call_indBox_prox(x, lower, upper)