diff --git a/README.md b/README.md index 6ba6280..59eb7c8 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ |[![Build Status](https://travis-ci.org/albarji/proxTV.svg?branch=master)](https://travis-ci.org/albarji/proxTV)|[![Build Status](https://travis-ci.org/albarji/proxTV.svg?branch=master)](https://travis-ci.org/albarji/proxTV)[(!)](#notes-on-mac-os-x)|Not supported (yet)| -**proxTV** is a toolbox implementing blazing fast implementations of Total Variation proximity operators, which form the basic building blocks for applications such as image denoising, image deconvolution, image inpainting, video denoising, or fused lasso models, to name a few. While the core algorithms are implemented in C to achieve top efficiency, Matlab and Python interfaces are provided for ease of use. +**proxTV** is a toolbox implementing blazing fast implementations of Total Variation proximity operators, which form the basic building blocks for applications such as image denoising, image deconvolution, image inpainting, video denoising, or fused lasso models, to name a few. While the core algorithms are implemented in C to achieve top efficiency, Matlab, GNU Octave and Python interfaces are provided for ease of use. Some examples of applications using **proxTV**: @@ -76,11 +76,11 @@ for direct access to all the package routines. The documentation of use of the package functions is maintained online at http://pythonhosted.org/prox_tv/. -## Matlab interface +## Matlab or GNU Octave interface ### Quick start guide -To install proxTV clone this repository and run `install` at the Matlab prompt once located at proxTV folder. If any problem arises please refer to the "Installation" subsection. +To install proxTV clone this repository and run `install` at the Matlab prompt (or `install_octave` at the Octave prompt) once located at proxTV folder. If any problem arises please refer to the "Installation" subsection. After that the TV solver can be invoked easily through the general purpose "TV" function. For instance, @@ -100,8 +100,8 @@ To install proxTV follow the steps: 1. Open Matlab. 2. Change directory to the folder where this README file is located. -3. Type: "install" -4. After compilation the message "proxTV successfully installed" will appear. If instead an error message shows up, check your mex compiler configuration (type "mex -setup"). If the error was produced by the "openmp" library, you might need to install it, or you can install proxTV with no multi-thread features by typing "install(1)". +3. Type: `install` (or `install_octave`) +4. After compilation the message "proxTV successfully installed" will appear. If instead an error message shows up, check your mex compiler configuration (type `mex -setup`). If the error was produced by the "openmp" library, you might need to install it, or you can install proxTV with no multi-thread features by typing `install(1)` (or `install_octave(1)`). 5. The install script automatically adds the relevant proxTV folders to your Matlab path. If this were to fail for some reason, you should manually add the /matlab subfolder to your Matlab path. You can do this e.g. by using the "pathtool()" utility. You may also add the /matlab/demos subfolder to try out the included demos. *Note*: this interface has only been tested under Linux. Installation might require LAPACK (http://www.netlib.org/lapack/) and BLAS (http://www.netlib.org/blas/) libraries. diff --git a/install_octave.m b/install_octave.m new file mode 100644 index 0000000..295e549 --- /dev/null +++ b/install_octave.m @@ -0,0 +1,107 @@ +% +% install_octave(nopar) proxTV installation +% +% Compiles the required mex -v files for the proxTV library. +% +% Inputs: +% - [mode]: compilation mode +% 0: parallelization with OpenMP (default) +% 1: no parallelization +% 2: parallelization with mwlpack +% 3: debug mode +% +function install_octave(nopar) + % Check arguments. + if ~exist('nopar', 'var'), nopar=0; + else + if ~isa(nopar, 'double'), error('Input argument must be numeric'); end + end + + disp('Installing proxTV...'); + cd matlab + + %% compilation flags + [~, CXXFLAGS] = system('mkoctfile -p CXXFLAGS'); + [~, LDFLAGS] = system('mkoctfile -p LDFLAGS'); + % some versions introduces a newline character (10) + % in the output of 'system'; this must be removed + if CXXFLAGS(end)==10, CXXFLAGS = CXXFLAGS(1:end-1); end + if LDFLAGS(end)==10, LDFLAGS = LDFLAGS(1:end-1); end + CXXFLAGSorig = CXXFLAGS; + LDFLAGSorig = LDFLAGS; + + CXXFLAGS = [CXXFLAGS ' -fPIC -DOCTAVE']; + + if nopar == 0 + CXXFLAGS = [CXXFLAGS ' -O3 -fopenmp']; + LDFLAGS = [LDFLAGS ',-fopenmp']; + setenv('CXXFLAGS', CXXFLAGS); + setenv('LDFLAGS', LDFLAGS); + elseif nopar == 1 + disp('WARNING: parallelization disabled'); + CXXFLAGS = [CXXFLAGS ' -O3']; + setenv('CXXFLAGS', CXXFLAGS); + elseif nopar == 2 + disp('Installing multisrc mwlpack version'); + CXXFLAGS = [CXXFLAGS ' -O3 -fopenmp']; + LDFLAGS = [LDFLAGS ',-fopenmp']; + else + disp('WARNING: Installing in debug mode'); + CXXFLAGS = [CXXFLAGS ' -g -fopenmp']; + LDFLAGS = [LDFLAGS ',-fopenmp']; + end + + setenv('CXXFLAGS', CXXFLAGS); + setenv('LDFLAGS', LDFLAGS); + + %% Compile C modules + deps = {'TVgenopt', 'TVL1opt', 'TVL1Wopt', 'TVL2opt', 'TVLPopt', ... + 'TV2Dopt', 'TV2DWopt', 'TVNDopt', 'LPopt', 'utils', ... + 'condat_fast_tv', 'johnsonRyanTV', 'TVL1opt_tautstring', ... + 'TVL1opt_hybridtautstring', 'TVL1opt_kolmogorov'}; + deps_obj = ''; + for dep=deps + eval(['mex -v -c ../src/' dep{:} '.cpp']); % compile dependency + deps_obj = [deps_obj ' ' dep{:} '.o']; % create list of object files + end + + fprintf('\n'); + + %% Compile MEX + solvers = {'solveTV1_condat', 'solveTV1_condattautstring', ... + 'solveTV1_johnson', 'solveTV1_PN', 'solveTV1_linearizedTautString', ... + 'solveTV1_classicTautString', 'solveTV1_hybridTautString', ... + 'solveTV1_kolmogorov', 'TVL1Weighted', 'TVL1Weighted_tautString', ... + 'solveTV2_morec', 'solveTV2_PGc', 'solveTV2_morec2', 'solveTVgen', ... + 'solveTV2D_DR', 'solveTV2D_PD', 'solveTV2D_CondatChambollePock', ... + 'solveTV2D_Yang', 'solveTV2D_Kolmogorov', 'solveTV2DL1W', ... + 'solveTV3D_Yang', 'solveTVND_PDR', 'solveTVp_GPFW', 'solveTV'}; + for solver=solvers + if nopar == 0 || nopar == 1 + eval(['mex -v -lblas -llapack -lm ' solver{:} '.cpp ' deps_obj]); + elseif nopar == 2 + eval(['mex -v -lmwlapack -lm ' solver{:} '.cpp ' deps_obj]); + else + eval(['mex -v -DDEBUG -lblas -llapack -lm' solver{:} ... + '.cpp ' deps_obj]); + end + % some octave versions keep the object files; these must be destroyed + % here to avoid multiple definitions of mexFunction() + system(['rm -f ' solver{:} '.o']); + end + clear *.mex % update mex function in octave workspace + system('rm -f *.o'); % remove dependencies object files + + cd .. + + % Add relevant proxTV folders to Matlab's path + % here = pwd(); + % addpath([here,'/matlab']); + % addpath([here,'/matlab/demos']); + % savepath(); + + setenv('CXXFLAGS', CXXFLAGSorig); + setenv('LDFLAGS', LDFLAGSorig); + + disp('proxTV successfully installed.'); +end diff --git a/src/general.h b/src/general.h index 96d7d98..f6287d6 100644 --- a/src/general.h +++ b/src/general.h @@ -16,20 +16,24 @@ #include /* Mex and LAPACK includes */ +#ifdef OCTAVE + #include "mex.h" + #define NOMATLAB +#endif #ifdef NOMATLAB -#undef lapack_int -#define lapack_int int -extern "C" { - void dpttrs_(lapack_int* n, lapack_int* nrhs, const double* d, const double* e, double* b, lapack_int* ldb, - lapack_int *info ); - void dpttrf_( lapack_int* n, double* d, double* e, lapack_int *info ); -} -inline double mxGetInf() { return INFINITY; } + #undef lapack_int + #define lapack_int int + extern "C" { + void dpttrs_(lapack_int* n, lapack_int* nrhs, const double* d, const double* e, double* b, lapack_int* ldb, + lapack_int *info ); + void dpttrf_( lapack_int* n, double* d, double* e, lapack_int *info ); + } + inline double mxGetInf() { return INFINITY; } #else -#include "mex.h" -#include "lapack.h" -#include "matrix.h" -#define lapack_int ptrdiff_t + #include "mex.h" + #include "lapack.h" + #include "matrix.h" + #define lapack_int ptrdiff_t #endif /* Uncomment to print debug messages to a debug file */