├── .gitattributes ├── DataBase.mat ├── ReadMe.txt ├── SRC_demo.m ├── ompbox10.zip └── ompbox10 ├── Contents.m ├── faq.txt ├── omp.m ├── omp2.m ├── ompdemo.m ├── ompspeedtest.m ├── ompver.m ├── private ├── make.m ├── mexutils.c ├── mexutils.h ├── myblas.c ├── myblas.h ├── omp2mex.c ├── omp2mex.m ├── omp2mex.mexw64 ├── ompcore.c ├── ompcore.h ├── ompmex.c ├── ompmex.m ├── ompmex.mexw64 ├── ompprof.c ├── ompprof.h ├── omputils.c ├── omputils.h └── printf.m └── readme.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | *.c linguist-language=matlab 2 | -------------------------------------------------------------------------------- /DataBase.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowfallingplum/Face-classification-based-on-sparse-representation/877ead1d35818826baa364ab14b1315b52d066c5/DataBase.mat -------------------------------------------------------------------------------- /ReadMe.txt: -------------------------------------------------------------------------------- 1 | To run: 2 | - Set Matlab's path to the current folder. 3 | - Unzip ompbox10.zip and install according to the instructions in the unzipped folder. 4 | - Run SRC_demo -------------------------------------------------------------------------------- /SRC_demo.m: -------------------------------------------------------------------------------- 1 | clc;clear all;close all; 2 | addpath('./ompbox10'); 3 | data = load('DataBase.mat'); %load the provided data 4 | DataBase = data.DataBase; 5 | param.lambda = 0.002; 6 | param.sparsity = 50; 7 | 8 | %% This is a demo of SRC 9 | lambda = param.lambda; 10 | sparsity = param.sparsity; 11 | 12 | tic % Start computing time from here 13 | train = normc(DataBase.training_feats); 14 | Y = DataBase.testing_feats; 15 | W = DataBase.H_train; 16 | test_label = DataBase.H_test; 17 | Phi = train; 18 | P = (Phi' * Phi + (lambda* eye(size(Phi,2))))\Phi' ; 19 | A_check = P * Y; 20 | G = Phi'*Phi; 21 | A_hat = omp(Phi'*Y,G,sparsity); 22 | Score = W * (normc((A_check) + (A_hat))); 23 | Nt = size(Y,2); 24 | tic 25 | error_number=0; 26 | number_class=38; 27 | number_per_class=32; 28 | SRC_A=A_hat; 29 | for i=1:size(Y,2) 30 | SRC_A_each=SRC_A(:,i); 31 | test_sample=Y(:,i); 32 | error_each_class=zeros(number_class,1); 33 | score_gt = test_label(:,i); 34 | for j=1:number_class 35 | range=((j-1)*number_per_class+1:1:j*number_per_class); 36 | sub_dict=Phi(:,range); 37 | sub_coefficient= SRC_A_each(range,:); 38 | error_each_class(j)=sum(abs(test_sample-sub_dict*sub_coefficient)); 39 | end 40 | [maxv, minind_est] = min(error_each_class); 41 | [maxv, maxind_gt] = max(score_gt); 42 | if minind_est~=maxind_gt 43 | error_number=error_number+1; 44 | end 45 | end 46 | accuracy_SRC = (Nt-error_number)/Nt *100; 47 | time_SRC=toc; 48 | st = ['Classification accuracy of SRC is ', num2str(accuracy_SRC), '% in ' , num2str(time_SRC), ' seconds']; 49 | disp (st) 50 | 51 | -------------------------------------------------------------------------------- /ompbox10.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowfallingplum/Face-classification-based-on-sparse-representation/877ead1d35818826baa364ab14b1315b52d066c5/ompbox10.zip -------------------------------------------------------------------------------- /ompbox10/Contents.m: -------------------------------------------------------------------------------- 1 | %OMPBox - Implementation of Batch-OMP and OMP-Cholesky. 2 | % 3 | %Ron Rubinstein, Computer Science Department 4 | %Technion -- Israel Institute of Technology 5 | %ronrubin@cs.technion.ac.il 6 | % 7 | % 8 | %Orthogonal Matching Pursuit. 9 | % omp - Sparsity-constrained Orthogonal Matching Pursuit. 10 | % omp2 - Error-constrained Orthogonal Matching Pursuit. 11 | % 12 | %Demonstrations. 13 | % ompdemo - Demonstration of the OMP toolbox. 14 | % ompspeedtest - Test the speed of the OMP functions. 15 | % 16 | %Miscellaneous. 17 | % ompver - OMPBox version information. 18 | -------------------------------------------------------------------------------- /ompbox10/faq.txt: -------------------------------------------------------------------------------- 1 | 2 | OMPBox Frequently Asked Questions 3 | --------------------------------- 4 | 5 | 6 | Q. Your package does not work! I get an error like this: 7 | 8 | ??? Attempt to execute SCRIPT ompbox\private\ompmex as a function: 9 | C:\............................................\ompbox\private\ompmex.m 10 | 11 | Error in ==> omp at 162 12 | gamma = ompmex(D,X,DtX,G,T,sparse_gamma,msgdelta,profile); 13 | 14 | A. OMPBox comes as source code, and requires compilation. Please read the README file 15 | and follow the directions - it is actually quite easy. 16 | 17 | 18 | 19 | Q. I suspect OMP is running terribly slow. Can I verify this? What can be done? 20 | 21 | A. You can run OMPSPEEDTEST to verify your suspicion. You will note that the 22 | function uses a slightly different number of signals every run - this is because 23 | before it begins the actual test, it performs a small speed evaluation and 24 | selects the number of signals to code based on the speed of the system. If the 25 | number of selected signals is less than, say, 1000 or so, then yes, OMP is indeed 26 | running very slow. The most probabe cause of this, assuming you are using a decent 27 | Pentium IV processor or faster, is compiling OMP with a compiler that does not perform 28 | optimization (e.g. LCC). Make sure you are compiling using MS-Visual Studio on Windows, 29 | GCC on Linux, or any other descent compiler, and that you did not disable optimization 30 | (if you do not know how to do this, you probably did not). Run "mex -setup" from 31 | the Matlab prompt to verify your compiler selection, and recompile if needed. 32 | 33 | 34 | 35 | Q. Your package does not compile/run/work on my system. 36 | 37 | A. Well, unfortunately I only have access to a limited number of system configurations. 38 | So, if you are experiencing an error on your system, please let me know! These things 39 | can usually be corrected easily - for everyone's benefit. 40 | 41 | -------------------------------------------------------------------------------- /ompbox10/omp.m: -------------------------------------------------------------------------------- 1 | function gamma = omp(varargin) 2 | %OMP Sparsity-constrained Orthogonal Matching Pursuit. 3 | % GAMMA = OMP(D,X,G,T) solves the optimization problem 4 | % 5 | % min |X - D*GAMMA|_2 s.t. |GAMMA|_0 <= T 6 | % gamma 7 | % 8 | % for each of the signals in X, using Batch Orthogonal Matching Pursuit. 9 | % Here, D is a dictionary with normalized columns, X is a matrix 10 | % containing column signals, T is the # of non-zeros in each signal 11 | % representation, and G is the Gramm matrix D'*D. The output GAMMA is a 12 | % matrix containing the sparse representations as its columns. 13 | % 14 | % GAMMA = OMP(D,X,[],T) performs the same operation, but without the 15 | % matrix G, using OMP-Cholesky. This call produces the same output as 16 | % Batch-OMP, but is significantly slower. Using this syntax is only 17 | % recommended when available memory is too small to store G. 18 | % 19 | % GAMMA = OMP(DtX,G,T) is the fastest implementation of OMP, but also 20 | % requires the most memory. Here, DtX stores the projections D'*X. In this 21 | % case Batch-OMP is used, but without having to compute D'*X in advance, 22 | % which slightly improves runtime. Note that in general, the call 23 | % 24 | % GAMMA = OMP(D'*X,G,T); 25 | % 26 | % will be faster than the call 27 | % 28 | % GAMMA = OMP(D,X,G,T); 29 | % 30 | % due to optimized matrix multiplications in Matlab. However, when the 31 | % entire matrix D'*X cannot be stored in memory, one of the other two 32 | % versions can be used. Both compute D'*X for just one signal at a time, 33 | % and thus require much less memory. 34 | % 35 | % GAMMA = OMP(...,PARAM1,VAL1,PARAM2,VAL2,...) specifies additional 36 | % parameters for OMP. Available parameters are: 37 | % 38 | % 'gammamode' - Specifies the representation mode for GAMMA. Can be 39 | % either 'full' or 'sparse', corresponding to a full or 40 | % sparse matrix, respectively. By default, GAMMA is 41 | % returned as a sparse matrix. 42 | % 'messages' - Specifies whether progress messages should be displayed. 43 | % When positive, this is the number of seconds between 44 | % status prints. When negative, indicates that no messages 45 | % should be displayed (this is the default). 46 | % 'checkdict' - Specifies whether dictionary normalization should be 47 | % verified. When set to 'on' (default) the dictionary 48 | % atoms are verified to be of unit L2-norm. Setting this 49 | % parameter to 'off' disables verification and accelerates 50 | % function performance. Note that an unnormalized 51 | % dictionary will produce invalid results. 52 | % 'profile' - Can be either 'on' or 'off'. When 'on', profiling 53 | % information is displayed at the end of the funciton 54 | % execution. 55 | % 56 | % 57 | % Summary of OMP versions: 58 | % 59 | % version | speed | memory 60 | % -------------------------------------------------- 61 | % OMP(DtX,G,T) | very fast | very large 62 | % OMP(D,X,G,T) | fast | moderate 63 | % OMP(D,X,[],T) | very slow | small 64 | % -------------------------------------------------- 65 | % 66 | % 67 | % References: 68 | % [1] M. Elad, R. Rubinstein, and M. Zibulevsky, "Efficient Implementation 69 | % of the K-SVD Algorithm using Batch Orthogonal Matching Pursuit", 70 | % Technical Report - CS, Technion, April 2008. 71 | % 72 | % See also OMP2. 73 | 74 | 75 | % Ron Rubinstein 76 | % Computer Science Department 77 | % Technion, Haifa 32000 Israel 78 | % ronrubin@cs 79 | % 80 | % April 2009 81 | 82 | 83 | % default options 84 | 85 | sparse_gamma = 1; 86 | msgdelta = -1; 87 | checkdict = 1; 88 | profile = 0; 89 | 90 | 91 | % determine number of parameters 92 | 93 | paramnum = 1; 94 | while (paramnum<=nargin && ~ischar(varargin{paramnum})) 95 | paramnum = paramnum+1; 96 | end 97 | paramnum = paramnum-1; 98 | 99 | 100 | % parse options 101 | 102 | for i = paramnum+1:2:length(varargin) 103 | paramname = varargin{i}; 104 | paramval = varargin{i+1}; 105 | 106 | switch lower(paramname) 107 | 108 | case 'gammamode' 109 | if (strcmpi(paramval,'sparse')) 110 | sparse_gamma = 1; 111 | elseif (strcmpi(paramval,'full')) 112 | sparse_gamma = 0; 113 | else 114 | error('Invalid GAMMA mode'); 115 | end 116 | 117 | case 'messages' 118 | msgdelta = paramval; 119 | 120 | case 'checkdict' 121 | if (strcmpi(paramval,'on')) 122 | checkdict = 1; 123 | elseif (strcmpi(paramval,'off')) 124 | checkdict = 0; 125 | else 126 | error('Invalid checkdict option'); 127 | end 128 | 129 | case 'profile' 130 | if (strcmpi(paramval,'on')) 131 | profile = 1; 132 | elseif (strcmpi(paramval,'off')) 133 | profile = 0; 134 | else 135 | error('Invalid profile mode'); 136 | end 137 | 138 | otherwise 139 | error(['Unknown option: ' paramname]); 140 | end 141 | 142 | end 143 | 144 | 145 | % determine call type 146 | 147 | if (paramnum==3) 148 | DtX = varargin{1}; 149 | G = varargin{2}; 150 | T = varargin{3}; 151 | D = []; 152 | X = []; 153 | elseif (paramnum==4) 154 | D = varargin{1}; 155 | X = varargin{2}; 156 | G = varargin{3}; 157 | T = varargin{4}; 158 | DtX = []; 159 | else 160 | error('Invalid number of parameters'); 161 | end 162 | 163 | 164 | % verify dictionary normalization 165 | 166 | if (checkdict) 167 | if (isempty(G)) 168 | atomnorms = sum(D.*D); 169 | else 170 | atomnorms = diag(G); 171 | end 172 | if (any(abs(atomnorms-1) > 1e-2)) 173 | error('Dictionary columns must be normalized to unit length'); 174 | end 175 | end 176 | 177 | 178 | % omp 179 | 180 | gamma = ompmex(D,X,DtX,G,T,sparse_gamma,msgdelta,profile); 181 | -------------------------------------------------------------------------------- /ompbox10/omp2.m: -------------------------------------------------------------------------------- 1 | function gamma = omp2(varargin) 2 | %OMP2 Error-constrained Orthogonal Matching Pursuit. 3 | % GAMMA = OMP2(D,X,G,EPSILON) solves the optimization problem 4 | % 5 | % min |GAMMA|_0 s.t. |X - D*GAMMA|_2 <= EPSILON 6 | % gamma 7 | % 8 | % for each of the signals in X, using Batch Orthogonal Matching Pursuit. 9 | % Here, D is a dictionary with normalized columns, X is a matrix 10 | % containing column signals, EPSILON is the error target for each signal, 11 | % and G is the Gramm matrix D'*D. The output GAMMA is a matrix containing 12 | % the sparse representations as its columns. 13 | % 14 | % GAMMA = OMP2(D,X,[],EPSILON) performs the same operation, but without 15 | % the matrix G, using OMP-Cholesky. This call produces the same output as 16 | % Batch-OMP, but is significantly slower. Using this syntax is only 17 | % recommended when available memory is too small to store G. 18 | % 19 | % GAMMA = OMP2(DtX,XtX,G,EPSILON) is the fastest implementation of OMP2, 20 | % but also requires the most memory. Here, DtX stores the projections 21 | % D'*X, and XtX is a row vector containing the squared norms of the 22 | % signals, sum(X.*X). In this case Batch-OMP is used, but without having 23 | % to compute D'*X and XtX in advance, which slightly improves runtime. 24 | % Note that in general, the call 25 | % 26 | % GAMMA = OMP2(D'*X, sum(X.*X), G, EPSILON); 27 | % 28 | % will be faster than the call 29 | % 30 | % GAMMA = OMP2(D,X,G,EPSILON); 31 | % 32 | % due to optimized matrix multiplications in Matlab. However, when the 33 | % entire matrix D'*X cannot be stored in memory, one of the other two 34 | % versions can be used. Both compute D'*X for just one signal at a time, 35 | % and thus require much less memory. 36 | % 37 | % GAMMA = OMP2(...,PARAM1,VAL1,PARAM2,VAL2,...) specifies additional 38 | % parameters for OMP2. Available parameters are: 39 | % 40 | % 'gammamode' - Specifies the representation mode for GAMMA. Can be 41 | % either 'full' or 'sparse', corresponding to a full or 42 | % sparse matrix, respectively. By default, GAMMA is 43 | % returned as a sparse matrix. 44 | % 'maxatoms' - Limits the number of atoms in the representation of each 45 | % signal. If specified, the number of atoms in each 46 | % representation does not exceed this number, even if the 47 | % error target is not met. Specifying maxatoms<0 implies 48 | % no limit (default). 49 | % 'messages' - Specifies whether progress messages should be displayed. 50 | % When positive, this is the number of seconds between 51 | % status prints. When negative, indicates that no messages 52 | % should be displayed (this is the default). 53 | % 'checkdict' - Specifies whether dictionary normalization should be 54 | % verified. When set to 'on' (default) the dictionary 55 | % atoms are verified to be of unit L2-norm. Setting this 56 | % parameter to 'off' disables verification and accelerates 57 | % function performance. Note that an unnormalized 58 | % dictionary will produce invalid results. 59 | % 'profile' - Can be either 'on' or 'off'. When 'on', profiling 60 | % information is displayed at the end of the funciton 61 | % execution. 62 | % 63 | % 64 | % Summary of OMP2 versions: 65 | % 66 | % version | speed | memory 67 | % ------------------------------------------------------------- 68 | % OMP2(DtX,XtX,G,EPSILON) | very fast | very large 69 | % OMP2(D,X,G,EPSILON) | fast | moderate 70 | % OMP2(D,X,[],EPSILON) | very slow | small 71 | % ------------------------------------------------------------- 72 | % 73 | % 74 | % References: 75 | % [1] M. Elad, R. Rubinstein, and M. Zibulevsky, "Efficient Implementation 76 | % of the K-SVD Algorithm using Batch Orthogonal Matching Pursuit", 77 | % Technical Report - CS, Technion, April 2008. 78 | % 79 | % See also OMP. 80 | 81 | 82 | % Ron Rubinstein 83 | % Computer Science Department 84 | % Technion, Haifa 32000 Israel 85 | % ronrubin@cs 86 | % 87 | % April 2009 88 | 89 | 90 | % default options 91 | 92 | sparse_gamma = 1; 93 | msgdelta = -1; 94 | maxatoms = -1; 95 | checkdict = 1; 96 | profile = 0; 97 | 98 | 99 | % determine number of parameters 100 | 101 | paramnum = 1; 102 | while (paramnum<=nargin && ~ischar(varargin{paramnum})) 103 | paramnum = paramnum+1; 104 | end 105 | paramnum = paramnum-1; 106 | 107 | 108 | % parse options 109 | 110 | for i = paramnum+1:2:length(varargin) 111 | paramname = varargin{i}; 112 | paramval = varargin{i+1}; 113 | 114 | switch lower(paramname) 115 | 116 | case 'gammamode' 117 | if (strcmpi(paramval,'sparse')) 118 | sparse_gamma = 1; 119 | elseif (strcmpi(paramval,'full')) 120 | sparse_gamma = 0; 121 | else 122 | error('Invalid GAMMA mode'); 123 | end 124 | 125 | case 'maxatoms' 126 | maxatoms = paramval; 127 | 128 | case 'messages' 129 | msgdelta = paramval; 130 | 131 | case 'checkdict' 132 | if (strcmpi(paramval,'on')) 133 | checkdict = 1; 134 | elseif (strcmpi(paramval,'off')) 135 | checkdict = 0; 136 | else 137 | error('Invalid checkdict option'); 138 | end 139 | 140 | case 'profile' 141 | if (strcmpi(paramval,'on')) 142 | profile = 1; 143 | elseif (strcmpi(paramval,'off')) 144 | profile = 0; 145 | else 146 | error('Invalid profile mode'); 147 | end 148 | 149 | otherwise 150 | error(['Unknown option: ' paramname]); 151 | end 152 | 153 | end 154 | 155 | 156 | % determine call type 157 | 158 | if (paramnum==4) 159 | 160 | n1 = size(varargin{1},1); 161 | n2 = size(varargin{2},1); 162 | n3 = size(varargin{3},1); 163 | 164 | if ( (n1>1 && n2==1) || (n1==1 && n2==1 && n3==1) ) % DtX,XtX,G,EPSILON 165 | 166 | DtX = varargin{1}; 167 | XtX = varargin{2}; 168 | G = varargin{3}; 169 | epsilon = varargin{4}; 170 | D = []; 171 | X = []; 172 | 173 | else % D,X,G,EPSILON 174 | 175 | D = varargin{1}; 176 | X = varargin{2}; 177 | G = varargin{3}; 178 | epsilon = varargin{4}; 179 | DtX = []; 180 | XtX = []; 181 | 182 | end 183 | 184 | else 185 | error('Invalid number of parameters'); 186 | end 187 | 188 | 189 | % verify dictionary normalization 190 | 191 | if (checkdict) 192 | if (isempty(G)) 193 | atomnorms = sum(D.*D); 194 | else 195 | atomnorms = diag(G); 196 | end 197 | if (any(abs(atomnorms-1) > 1e-2)) 198 | error('Dictionary columns must be normalized to unit length'); 199 | end 200 | end 201 | 202 | 203 | % omp 204 | 205 | gamma = omp2mex(D,X,DtX,XtX,G,epsilon,sparse_gamma,msgdelta,maxatoms,profile); 206 | -------------------------------------------------------------------------------- /ompbox10/ompdemo.m: -------------------------------------------------------------------------------- 1 | function ompdemo 2 | %OMPDEMO Demonstration of the OMP toolbox. 3 | % OMPDEMO generates a random sparse mixture of cosines and spikes, adds 4 | % noise, and applies OMP to recover the original signal. 5 | % 6 | % To run the demo, type OMPDEMO from the Matlab prompt. 7 | % 8 | % See also OMPSPEEDTEST. 9 | 10 | 11 | % Ron Rubinstein 12 | % Computer Science Department 13 | % Technion, Haifa 32000 Israel 14 | % ronrubin@cs 15 | % 16 | % April 2009 17 | 18 | 19 | disp(' '); 20 | disp(' ********** OMP Demo **********'); 21 | disp(' '); 22 | disp(' This demo generates a random mixture of cosines and spikes, adds noise,'); 23 | disp(' and uses OMP to recover the mixture and the original signal. The graphs'); 24 | disp(' show the original, noisy and recovered signal with the corresponding SNR'); 25 | disp(' values. The true and recovered coefficients are shown in the bar graphs.'); 26 | disp(' '); 27 | 28 | 29 | % generate DCT-spike dictionary % 30 | 31 | n = 256; 32 | 33 | D = zeros(n); 34 | D(:,1) = 1/sqrt(n); 35 | for i = 2:n 36 | v = cos((0:n-1)*pi*(i-1)/n)'; 37 | v = v-mean(v); 38 | D(:,i) = v/norm(v); 39 | end 40 | 41 | D = [D eye(n)]; 42 | 43 | 44 | % generate random sparse mixture of cosines and spikes % 45 | 46 | g = sparse(2*n,1); 47 | 48 | % sinusoid coefs are random within +/-[0.5,1.5] 49 | lowfreq = 20; 50 | p = randperm(lowfreq); 51 | g(p(1:2)) = (rand(2,1)+0.5).*randsig(2,1); % two random low frequencies 52 | p = randperm(n-lowfreq); 53 | g(lowfreq+p(1:2)) = (rand(2,1)+0.5).*randsig(2,1); % two random high frequencies 54 | 55 | % spike coefs are random within +/-[0.25,0.75] 56 | p = randperm(n); 57 | g(p(1:3)+n) = (rand(3,1)/2+0.25).*randsig(3,1); % three random spikes 58 | 59 | x = D*g; 60 | 61 | 62 | % add gaussian noise % 63 | 64 | r = randn(size(x)); 65 | r = r/norm(r)*norm(x)/4; 66 | y = x + r; 67 | 68 | 69 | % perform omp % 70 | 71 | gamma = omp(D'*y, D'*D, nnz(g)); 72 | err = x-D*gamma; 73 | 74 | 75 | % show results % 76 | 77 | v=[1 n -max(abs([x;y]))*1.1 max(abs([x;y]))*1.1]; 78 | figure; plot(x); axis(v); title('Original signal'); 79 | figure; plot(y); axis(v); title(sprintf('Noisy signal, SNR=%.1fdB', 10*log10((x'*x)/(r'*r)))); 80 | figure; plot(D*gamma); axis(v); title(sprintf('Reconstructed signal, SNR=%.1fdB', 10*log10((x'*x)/(err'*err)))); 81 | 82 | v = [1 2*n -max(abs([g;gamma]))*1.1 max(abs([g;gamma]))*1.1]; 83 | figure; bar(full(g)); axis(v); title('True signal decomposition'); 84 | figure; bar(full(gamma)); axis(v); title('Decomposition recovered by OMP'); 85 | 86 | return; 87 | 88 | 89 | % random matrix with +/-1 90 | function y = randsig(varargin) 91 | y = round(rand(varargin{:}))*2 - 1; 92 | return; 93 | -------------------------------------------------------------------------------- /ompbox10/ompspeedtest.m: -------------------------------------------------------------------------------- 1 | function ompspeedtest 2 | %OMPSPEEDTEST Test the speed of the OMP functions. 3 | % OMPSPEEDTEST invokes the three operation modes of OMP and compares 4 | % their speeds. The function automatically selects the number of signals 5 | % for the test based on the speed of the system. 6 | % 7 | % To run the test, type OMPSPEEDTEST from the Matlab prompt. 8 | % 9 | % See also OMPDEMO. 10 | 11 | 12 | % Ron Rubinstein 13 | % Computer Science Department 14 | % Technion, Haifa 32000 Israel 15 | % ronrubin@cs 16 | % 17 | % August 2009 18 | 19 | 20 | 21 | % random dictionary % 22 | 23 | n = 512; 24 | L = 1000; 25 | T = 8; 26 | 27 | D = randn(n,L); 28 | D = D*diag(1./sqrt(sum(D.*D))); % normalize the dictionary 29 | 30 | 31 | % select signal number according to computer speed % 32 | 33 | x = randn(n,20); 34 | tic; omp(D,x,[],T,'messages',-1); t=toc; 35 | signum = ceil(20/(t/20)); % approximately 20 seconds of OMP-Cholesky 36 | 37 | 38 | % generate random signals % 39 | 40 | X = randn(n,signum); 41 | 42 | 43 | % run OMP % 44 | 45 | printf('\nRunning OMP-Cholesky...'); 46 | tic; omp(D,X,[],T,'messages',4); t1=toc; 47 | 48 | printf('\nRunning Batch-OMP...'); 49 | tic; omp(D,X,D'*D,T,'messages',1); t2=toc; 50 | 51 | printf('\nRunning Batch-OMP with D''*X specified...'); 52 | tic; omp(D'*X,D'*D,T,'messages',1); t3=toc; 53 | 54 | 55 | % display summary % 56 | 57 | printf('\n\nSpeed summary for %d signals, dictionary size %d x %d:\n', signum, n, L); 58 | printf('Call syntax Algorithm Total time'); 59 | printf('--------------------------------------------------------'); 60 | printf('OMP(D,X,[],T) OMP-Cholesky %5.2f seconds', t1); 61 | printf('OMP(D,X,G,T) Batch-OMP %5.2f seconds', t2); 62 | printf('OMP(DtX,G,T) Batch-OMP with D''*X %5.2f seconds\n', t3); 63 | -------------------------------------------------------------------------------- /ompbox10/ompver.m: -------------------------------------------------------------------------------- 1 | function v = ompver(history) 2 | %OMPVER OMP toolbox version information. 3 | % OMPVER displays the current OMP toolbox version information. 4 | % 5 | % OMPVER('history') also displays history information about the previous 6 | % versions of the OMP toolbox and their change logs. 7 | % 8 | % V = OMPVER returns the version number of the current OMP toolbox, and 9 | % does not display any information. 10 | 11 | 12 | % Ron Rubinstein 13 | % Computer Science Department 14 | % Technion, Haifa 32000 Israel 15 | % ronrubin@cs 16 | % 17 | % October 2009 18 | 19 | 20 | ver = 10; 21 | 22 | if (nargout>0) 23 | if (nargin>0) 24 | error('Invalid number of parameters.'); 25 | end 26 | v = ver; 27 | 28 | else 29 | 30 | if (nargin==0 || (nargin==1 && strcmpi(history,'history'))) 31 | 32 | disp(' '); 33 | disp('---------------------------------'); 34 | printf(' OMP Toolbox version %d ',ver); 35 | disp('---------------------------------'); 36 | disp(' '); 37 | 38 | else 39 | error('Unknown parameters.'); 40 | end 41 | 42 | if (nargin>0) 43 | 44 | 45 | %% changes only displayed since first public release %% 46 | 47 | 48 | % disp(' '); 49 | % disp('OMP Toolbox version 1, 28.10.07'); 50 | % disp('--------------------------------'); 51 | % disp(' '); 52 | % disp('Initial release.'); 53 | % disp(' '); 54 | % disp(' '); 55 | % disp(' '); 56 | % 57 | % disp('OMP Toolbox version 2, 30.10.07'); 58 | % disp('--------------------------------'); 59 | % disp(' '); 60 | % disp('Features:'); 61 | % disp(' '); 62 | % disp(' 1. OMP and OMP2 can now operate without specifying G, computing it on the fly.'); 63 | % disp(' 2. Improved documentation.'); 64 | % disp(' '); 65 | % disp('Bug fixes:'); 66 | % disp(' '); 67 | % disp(' 1. OMP2 uses much less memory, by allocating space for at most N coefficients'); 68 | % disp(' for each signal rather than M in v1.'); 69 | % disp(' '); 70 | % disp(' '); 71 | % disp(' '); 72 | % 73 | % disp('OMP Toolbox version 3, 16.12.07'); 74 | % disp('--------------------------------'); 75 | % disp(' '); 76 | % disp('Features:'); 77 | % disp(' '); 78 | % disp(' 1. Support for sparse output, and an optional parameter for selecting'); 79 | % disp(' between sparse and full output.'); 80 | % disp(' '); 81 | % disp('Bug fixes:'); 82 | % disp(' '); 83 | % disp(' 1. When selected atoms were dependent, OMP would cause a NaN result.'); 84 | % disp(' Added a stopping criterion to handle this case.'); 85 | % disp(' '); 86 | % disp('Internal changes:'); 87 | % disp(' '); 88 | % disp(' 1. Dynamic memory allocations now done using mxMalloc/mxCalloc.'); 89 | % disp(' 2. Integer types converted to mwSize/mwIndex to allow compilation'); 90 | % disp(' under 64-bit systems using the -largeArrayDims parameter.'); 91 | % disp(' '); 92 | % disp(' '); 93 | % disp(' '); 94 | % 95 | % disp('OMP Toolbox version 4, 03.01.08'); 96 | % disp('--------------------------------'); 97 | % disp(' '); 98 | % disp('Bug fixes:'); 99 | % disp(' '); 100 | % disp(' 1. Sparse Gamma''s are now represented correctly, with ascending row numbers.'); 101 | % disp(' '); 102 | % disp('Internal changes:'); 103 | % disp(' '); 104 | % disp(' 1. Added MAKE function for automated compilation of all OMP functions.'); 105 | % disp(' '); 106 | % disp(' '); 107 | % disp(' '); 108 | % 109 | % disp('OMP Toolbox version 5, 18.01.08'); 110 | % disp('--------------------------------'); 111 | % disp(' '); 112 | % disp('Features:'); 113 | % disp(' '); 114 | % disp(' 1. Significantly improved performance by using BLAS/LAPACK functions.'); 115 | % disp(' 2. More meaningful profiling reports.'); 116 | % disp(' '); 117 | % disp('Internal changes:'); 118 | % disp(' '); 119 | % disp(' 1. Changes to code structure: extracted core omp code to separate'); 120 | % disp(' callable functions for code re-use.'); 121 | % disp(' 2. Improved MAKE file identifies compilation platform automatically.'); 122 | % disp(' '); 123 | % disp(' '); 124 | % disp(' '); 125 | % 126 | % disp('OMP Toolbox version 6, 31.01.08'); 127 | % disp('--------------------------------'); 128 | % disp(' '); 129 | % disp('Features:'); 130 | % disp(' '); 131 | % disp(' 1. Implemented efficient incremental update of the residual norm in OMP2,'); 132 | % disp(' eliminating the need for explicit computation of the residual itself.'); 133 | % disp(' 2. Added ''maxatoms'' parameter to OMP2.'); 134 | % disp(' 3. Updated call syntax to support the changes in (1) and (2).'); 135 | % disp(' 4. Slightly improved documentation.'); 136 | % disp(' 5. Added the OMPVER function.'); 137 | % disp(' 6. Added the Contents.m file.'); 138 | % disp(' '); 139 | % disp('Bug fixes:'); 140 | % disp(' '); 141 | % disp(' 1. Better memory management in OMP2. Much less memory is consumed by using'); 142 | % disp(' dynamic reallocation of temporary helper matrices which were originaly'); 143 | % disp(' preallocated to a size proportional to G, even when G was not specified.'); 144 | % disp(' 2. OMP2: atom selection loop limited to N atoms (loop could continue beyond'); 145 | % disp(' this limit if the error target was not achieved, causing a runtime error.'); 146 | % disp(' This could occur when the error limit is very close to 0).'); 147 | % disp(' '); 148 | % disp(' '); 149 | % disp(' '); 150 | % 151 | % disp('OMP Toolbox version 7, 15.04.08'); 152 | % disp('--------------------------------'); 153 | % disp(' '); 154 | % disp('Features:'); 155 | % disp(' '); 156 | % disp(' 1. OMP2: Improved incremental computation of the residual norm requires less'); 157 | % disp(' memory and is more efficient.'); 158 | % disp(' 2. Eliminated separate profiling OMP functions, now unified into the OMP'); 159 | % disp(' and OMP2 functions.'); 160 | % disp(' 3. New ''messages'' option for displaying coding progress and remaining time.'); 161 | % disp(' '); 162 | % disp('Internal changes:'); 163 | % disp(' '); 164 | % disp(' 1. New code structure: unified all omp and omp2 variants into ompmex.c and') 165 | % disp(' omp2mex.c. Parameter parsing is now done in the Matlab omp.m and omp2.m'); 166 | % disp(' functions, allowing simpler and more advanced parsing.'); 167 | % disp(' 2. Much simpler MAKE function, and new create_blasfuncs.m function for'); 168 | % disp(' managing the BLAS function names.'); 169 | % disp(' '); 170 | % disp(' '); 171 | % disp(' '); 172 | 173 | 174 | disp(' '); 175 | disp(' '); 176 | disp('OMP Toolbox version 7, 15.04.08'); 177 | disp('--------------------------------'); 178 | disp(' '); 179 | disp('First public release.'); 180 | disp(' '); 181 | disp(' '); 182 | disp(' '); 183 | 184 | 185 | disp('OMP Toolbox version 8, 29.05.08'); 186 | disp('--------------------------------'); 187 | disp(' '); 188 | disp('Bug fixes:'); 189 | disp(' '); 190 | disp(' 1. Added OMP stopping criterion: when maximal inner product between the'); 191 | disp(' residual and the dictionary is too small.'); 192 | disp(' '); 193 | disp(' '); 194 | disp(' '); 195 | 196 | 197 | disp('OMP Toolbox version 9, 21.05.09'); 198 | disp('--------------------------------'); 199 | disp(' '); 200 | disp('Features:'); 201 | disp(' '); 202 | disp(' 1. Source code now available for compilation on any Matlab platform.'); 203 | disp(' 2. Dictionary normalization is now verified before performing OMP.'); 204 | disp(' 3. Added OMPDEMO and OMPSPEEDTEST.'); 205 | disp(' 4. Improved profiling information.'); 206 | disp(' '); 207 | disp('Internal changes:'); 208 | disp(' '); 209 | disp(' 1. Completely restructured code.'); 210 | disp(' 2. When G is not specified, OMP-Cholesky is used rather than computing G'); 211 | disp(' and using Batch-OMP (faster).'); 212 | disp(' 3. Estimated remaining time now computed with sub-second accuracy.'); 213 | disp(' '); 214 | disp(' '); 215 | disp(' '); 216 | 217 | 218 | disp('OMP Toolbox version 10, 18.10.09'); 219 | disp('---------------------------------'); 220 | disp(' '); 221 | disp('Features:'); 222 | disp(' '); 223 | disp(' 1. When the sparse-coding threshold is such that no atoms need to be'); 224 | disp(' selected, OMP now terminates without computing D''*x, leading to'); 225 | disp(' a significant speed increase.'); 226 | disp(' 2. New ''checkdict'' parameter in OMP and OMP2 allows disabling dictionary'); 227 | disp(' normalization verification for accelerated performance.'); 228 | disp(' '); 229 | disp('Internal changes:'); 230 | disp(' '); 231 | disp(' 1. Restructured and updated C libraries for compatibility with the new'); 232 | disp(' Sparse OMP Toolbox.'); 233 | disp(' 2. Slightly modified parameters in OMPSPEEDTEST for consistency with'); 234 | disp(' OMPSPEEDCOMPARE in the Sparse OMP Toolbox.'); 235 | disp(' '); 236 | disp(' '); 237 | 238 | end 239 | end 240 | -------------------------------------------------------------------------------- /ompbox10/private/make.m: -------------------------------------------------------------------------------- 1 | function make 2 | %MAKE Build the OMPBox package. 3 | % MAKE compiles all OMPBox MEX functions, using Matlab's default MEX 4 | % compiler. If the MEX compiler has not been set-up before, please run 5 | % 6 | % mex -setup 7 | % 8 | % before using this MAKE file. 9 | 10 | % Ron Rubinstein 11 | % Computer Science Department 12 | % Technion, Haifa 32000 Israel 13 | % ronrubin@cs 14 | % 15 | % August 2009 16 | 17 | 18 | % detect platform 19 | 20 | compstr = computer; 21 | is64bit = strcmp(compstr(end-1:end),'64'); 22 | 23 | 24 | % compilation parameters 25 | 26 | compile_params = cell(0); 27 | if (is64bit) 28 | compile_params{1} = '-largeArrayDims'; 29 | end 30 | 31 | 32 | % Compile files % 33 | 34 | ompsources = {'mexutils.c','ompcore.c','omputils.c','myblas.c','ompprof.c'}; 35 | 36 | disp('Compiling ompmex...'); 37 | mex('ompmex.c', ompsources{:},compile_params{:}); 38 | 39 | disp('Compiling omp2mex...'); 40 | mex('omp2mex.c',ompsources{:},compile_params{:}); 41 | 42 | -------------------------------------------------------------------------------- /ompbox10/private/mexutils.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * File name: mexutils.c 4 | * 5 | * Ron Rubinstein 6 | * Computer Science Department 7 | * Technion, Haifa 32000 Israel 8 | * ronrubin@cs 9 | * 10 | * Last Updated: 15.8.2009 11 | * 12 | *************************************************************************/ 13 | 14 | #include "mexutils.h" 15 | #include 16 | 17 | 18 | 19 | /* verify that the mxArray contains a double matrix */ 20 | 21 | void checkmatrix(const mxArray *param, char *fname, char *pname) 22 | { 23 | char errmsg[100]; 24 | sprintf(errmsg, "%.15s requires that %.25s be a double matrix.", fname, pname); 25 | if (!mxIsDouble(param) || mxIsComplex(param) || mxGetNumberOfDimensions(param)>2) { 26 | mexErrMsgTxt(errmsg); 27 | } 28 | } 29 | 30 | 31 | /* verify that the mxArray contains a 1-D double vector */ 32 | 33 | void checkvector(const mxArray *param, char *fname, char *pname) 34 | { 35 | char errmsg[100]; 36 | sprintf(errmsg, "%.15s requires that %.25s be a double vector.", fname, pname); 37 | if (!mxIsDouble(param) || mxIsComplex(param) || mxGetNumberOfDimensions(param)>2 || (mxGetM(param)!=1 && mxGetN(param)!=1)) { 38 | mexErrMsgTxt(errmsg); 39 | } 40 | } 41 | 42 | 43 | /* verify that the mxArray contains a double scalar */ 44 | 45 | void checkscalar(const mxArray *param, char *fname, char *pname) 46 | { 47 | char errmsg[100]; 48 | sprintf(errmsg, "%.15s requires that %.25s be a double scalar.", fname, pname); 49 | if (!mxIsDouble(param) || mxIsComplex(param) || mxGetNumberOfDimensions(param)>2 || 50 | mxGetM(param)!=1 || mxGetN(param)!=1) 51 | { 52 | mexErrMsgTxt(errmsg); 53 | } 54 | } 55 | 56 | 57 | /* verify that the mxArray contains a sparse matrix */ 58 | 59 | void checksparse(const mxArray *param, char *fname, char *pname) 60 | { 61 | char errmsg[100]; 62 | sprintf(errmsg, "%.15s requires that %.25s be sparse.", fname, pname); 63 | if (!mxIsSparse(param)) { 64 | mexErrMsgTxt(errmsg); 65 | } 66 | } 67 | 68 | 69 | /* verify that the mxArray contains a 1-dimensional cell array */ 70 | 71 | void checkcell_1d(const mxArray *param, char *fname, char *pname) 72 | { 73 | char errmsg[100]; 74 | sprintf(errmsg, "%.15s requires that %.25s be a 1-D cell array.", fname, pname); 75 | if (!mxIsCell(param) || mxGetNumberOfDimensions(param)>2 || (mxGetM(param)!=1 && mxGetN(param)!=1)) { 76 | mexErrMsgTxt(errmsg); 77 | } 78 | } 79 | 80 | -------------------------------------------------------------------------------- /ompbox10/private/mexutils.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * File name: mexutils.h 4 | * 5 | * Ron Rubinstein 6 | * Computer Science Department 7 | * Technion, Haifa 32000 Israel 8 | * ronrubin@cs 9 | * 10 | * Last Updated: 18.8.2009 11 | * 12 | * Utility functions for MEX files. 13 | * 14 | *************************************************************************/ 15 | 16 | 17 | #ifndef __MEX_UTILS_H__ 18 | #define __MEX_UTILS_H__ 19 | 20 | #include "mex.h" 21 | 22 | 23 | 24 | /************************************************************************** 25 | * Function checkmatrix: 26 | * 27 | * Verify that the specified mxArray is real, of type double, and has 28 | * no more than two dimensions. If not, an error message is printed 29 | * and the mex file terminates. 30 | * 31 | * Parameters: 32 | * param - the mxArray to be checked 33 | * fname - the name of the function where the error occured (15 characters or less) 34 | * pname - the name of the parameter (25 characters or less) 35 | * 36 | **************************************************************************/ 37 | void checkmatrix(const mxArray *param, char *fname, char *pname); 38 | 39 | 40 | /************************************************************************** 41 | * Function checkvector: 42 | * 43 | * Verify that the specified mxArray is 1-D, real, and of type double. The 44 | * vector may be a column or row vector. Otherwise, an error message is 45 | * printed and the mex file terminates. 46 | * 47 | * Parameters: 48 | * param - the mxArray to be checked 49 | * fname - the name of the function where the error occured (15 characters or less) 50 | * pname - the name of the parameter (25 characters or less) 51 | * 52 | **************************************************************************/ 53 | void checkvector(const mxArray *param, char *fname, char *pname); 54 | 55 | 56 | /************************************************************************** 57 | * Function checkscalar: 58 | * 59 | * Verify that the specified mxArray represents a real double scalar value. 60 | * If not, an error message is printed and the mex file terminates. 61 | * 62 | * Parameters: 63 | * param - the mxArray to be checked 64 | * fname - the name of the function where the error occured (15 characters or less) 65 | * pname - the name of the parameter (25 characters or less) 66 | * 67 | **************************************************************************/ 68 | void checkscalar(const mxArray *param, char *fname, char *pname); 69 | 70 | 71 | /************************************************************************** 72 | * Function checksparse: 73 | * 74 | * Verify that the specified mxArray contains a sparse matrix. If not, 75 | * an error message is printed and the mex file terminates. 76 | * 77 | * Parameters: 78 | * param - the mxArray to be checked 79 | * fname - the name of the function where the error occured (15 characters or less) 80 | * pname - the name of the parameter (25 characters or less) 81 | * 82 | **************************************************************************/ 83 | void checksparse(const mxArray *param, char *fname, char *pname); 84 | 85 | 86 | /************************************************************************** 87 | * Function checkcell_1d: 88 | * 89 | * Verify that the specified mxArray is a 1-D cell array. The cell array 90 | * may be arranged as either a column or a row. If not, an error message 91 | * is printed and the mex file terminates. 92 | * 93 | * Parameters: 94 | * param - the mxArray to be checked 95 | * fname - the name of the function where the error occured (15 characters or less) 96 | * pname - the name of the parameter (25 characters or less) 97 | * 98 | **************************************************************************/ 99 | void checkcell_1d(const mxArray *param, char *fname, char *pname); 100 | 101 | 102 | #endif 103 | 104 | -------------------------------------------------------------------------------- /ompbox10/private/myblas.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * File name: myblas.c 4 | * 5 | * Ron Rubinstein 6 | * Computer Science Department 7 | * Technion, Haifa 32000 Israel 8 | * ronrubin@cs 9 | * 10 | * Version: 1.1 11 | * Last updated: 13.8.2009 12 | * 13 | *************************************************************************/ 14 | 15 | 16 | #include "myblas.h" 17 | #include 18 | 19 | 20 | /* find maximum of absolute values */ 21 | 22 | mwIndex maxabs(double c[], mwSize m) 23 | { 24 | mwIndex maxid=0, k; 25 | double absval, maxval = SQR(*c); /* use square which is quicker than absolute value */ 26 | 27 | for (k=1; k maxval) { 30 | maxval = absval; 31 | maxid = k; 32 | } 33 | } 34 | return maxid; 35 | } 36 | 37 | 38 | /* compute y := alpha*x + y */ 39 | 40 | void vec_sum(double alpha, double x[], double y[], mwSize n) 41 | { 42 | mwIndex i; 43 | 44 | for (i=0; i maxval) { 412 | maxval = val; 413 | maxid = k; 414 | } 415 | } 416 | return maxid; 417 | } 418 | 419 | 420 | /* solve L*x = b */ 421 | 422 | void backsubst_L(double L[], double b[], double x[], mwSize n, mwSize k) 423 | { 424 | mwIndex i, j; 425 | double rhs; 426 | 427 | for (i=0; i=1; --i) { 445 | rhs = b[i-1]; 446 | for (j=i; j=1; --i) { 462 | rhs = b[i-1]; 463 | for (j=i; j 26 | 27 | 28 | 29 | /************************************************************************** 30 | * Squared value. 31 | **************************************************************************/ 32 | #define SQR(X) ((X)*(X)) 33 | 34 | 35 | 36 | /************************************************************************** 37 | * Matrix-vector multiplication. 38 | * 39 | * Computes an operation of the form: 40 | * 41 | * y := alpha*A*x 42 | * 43 | * Parameters: 44 | * A - matrix of size n X m 45 | * x - vector of length m 46 | * y - output vector of length n 47 | * alpha - real constant 48 | * n, m - dimensions of A 49 | * 50 | * Note: This function re-writes the contents of y. 51 | * 52 | **************************************************************************/ 53 | void mat_vec(double alpha, double A[], double x[], double y[], mwSize n, mwSize m); 54 | 55 | 56 | 57 | /************************************************************************** 58 | * Matrix-transpose-vector multiplication. 59 | * 60 | * Computes an operation of the form: 61 | * 62 | * y := alpha*A'*x 63 | * 64 | * Parameters: 65 | * A - matrix of size n X m 66 | * x - vector of length n 67 | * y - output vector of length m 68 | * alpha - real constant 69 | * n, m - dimensions of A 70 | * 71 | * Note: This function re-writes the contents of y. 72 | * 73 | **************************************************************************/ 74 | void matT_vec(double alpha, double A[], double x[], double y[], mwSize n, mwSize m); 75 | 76 | 77 | 78 | /************************************************************************** 79 | * Sparse-matrix-vector multiplication. 80 | * 81 | * Computes an operation of the form: 82 | * 83 | * y := alpha*A*x 84 | * 85 | * where A is a sparse matrix. 86 | * 87 | * Parameters: 88 | * pr,ir,jc - sparse representation of the matrix A, of size n x m 89 | * x - vector of length m 90 | * y - output vector of length n 91 | * alpha - real constant 92 | * n, m - dimensions of A 93 | * 94 | * Note: This function re-writes the contents of y. 95 | * 96 | **************************************************************************/ 97 | void mat_sp_vec(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double x[], double y[], mwSize n, mwSize m); 98 | 99 | 100 | 101 | /************************************************************************** 102 | * Sparse-matrix-transpose-vector multiplication. 103 | * 104 | * Computes an operation of the form: 105 | * 106 | * y := alpha*A'*x 107 | * 108 | * where A is a sparse matrix. 109 | * 110 | * Parameters: 111 | * pr,ir,jc - sparse representation of the matrix A, of size n x m 112 | * x - vector of length m 113 | * y - output vector of length n 114 | * alpha - real constant 115 | * n, m - dimensions of A 116 | * 117 | * Note: This function re-writes the contents of y. 118 | * 119 | **************************************************************************/ 120 | void matT_sp_vec(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double x[], double y[], mwSize n, mwSize m); 121 | 122 | 123 | 124 | /************************************************************************** 125 | * Matrix-sparse-vector multiplication. 126 | * 127 | * Computes an operation of the form: 128 | * 129 | * y := alpha*A*x 130 | * 131 | * where A is a matrix and x is a sparse vector. 132 | * 133 | * Parameters: 134 | * A - matrix of size n X m 135 | * pr,ir,jc - sparse representation of the vector x, of length m 136 | * y - output vector of length n 137 | * alpha - real constant 138 | * n, m - dimensions of A 139 | * 140 | * Note: This function re-writes the contents of y. 141 | * 142 | **************************************************************************/ 143 | void mat_vec_sp(double alpha, double A[], double pr[], mwIndex ir[], mwIndex jc[], double y[], mwSize n, mwSize m); 144 | 145 | 146 | 147 | /************************************************************************** 148 | * Matrix-transpose-sparse-vector multiplication. 149 | * 150 | * Computes an operation of the form: 151 | * 152 | * y := alpha*A'*x 153 | * 154 | * where A is a matrix and x is a sparse vector. 155 | * 156 | * Parameters: 157 | * A - matrix of size n X m 158 | * pr,ir,jc - sparse representation of the vector x, of length n 159 | * y - output vector of length m 160 | * alpha - real constant 161 | * n, m - dimensions of A 162 | * 163 | * Note: This function re-writes the contents of y. 164 | * 165 | **************************************************************************/ 166 | void matT_vec_sp(double alpha, double A[], double pr[], mwIndex ir[], mwIndex jc[], double y[], mwSize n, mwSize m); 167 | 168 | 169 | 170 | /************************************************************************** 171 | * Sparse-matrix-sparse-vector multiplication. 172 | * 173 | * Computes an operation of the form: 174 | * 175 | * y := alpha*A*x 176 | * 177 | * where A is a sparse matrix and x is a sparse vector. 178 | * 179 | * Parameters: 180 | * pr,ir,jc - sparse representation of the matrix A, of size n x m 181 | * prx,irx,jcx - sparse representation of the vector x (of length m) 182 | * y - output vector of length n 183 | * alpha - real constant 184 | * n, m - dimensions of A 185 | * 186 | * Note: This function re-writes the contents of y. 187 | * 188 | **************************************************************************/ 189 | void mat_sp_vec_sp(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double prx[], mwIndex irx[], mwIndex jcx[], double y[], mwSize n, mwSize m); 190 | 191 | 192 | 193 | /************************************************************************** 194 | * Sparse-matrix-transpose-sparse-vector multiplication. 195 | * 196 | * Computes an operation of the form: 197 | * 198 | * y := alpha*A'*x 199 | * 200 | * where A is a sparse matrix and x is a sparse vector. 201 | * 202 | * Importnant note: this function is provided for completeness, but is NOT efficient. 203 | * If possible, convert x to non-sparse representation and use matT_vec_sp instead. 204 | * 205 | * Parameters: 206 | * pr,ir,jc - sparse representation of the matrix A, of size n x m 207 | * prx,irx,jcx - sparse representation of the vector x (of length n) 208 | * y - output vector of length n 209 | * alpha - real constant 210 | * n, m - dimensions of A 211 | * 212 | * Note: This function re-writes the contents of y. 213 | * 214 | **************************************************************************/ 215 | void matT_sp_vec_sp(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double prx[], mwIndex irx[], mwIndex jcx[], double y[], mwSize n, mwSize m); 216 | 217 | 218 | 219 | /************************************************************************** 220 | * Matrix-matrix multiplication. 221 | * 222 | * Computes an operation of the form: 223 | * 224 | * X := alpha*A*B 225 | * 226 | * Parameters: 227 | * A - matrix of size n X m 228 | * B - matrix of size m X k 229 | * X - output matrix of size n X k 230 | * alpha - real constant 231 | * n, m, k - dimensions of A, B 232 | * 233 | * Note: This function re-writes the contents of X. 234 | * 235 | **************************************************************************/ 236 | void mat_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k); 237 | 238 | 239 | 240 | /************************************************************************** 241 | * Matrix-transpose-matrix multiplication. 242 | * 243 | * Computes an operation of the form: 244 | * 245 | * X := alpha*A*B 246 | * 247 | * Parameters: 248 | * A - matrix of size n X m 249 | * B - matrix of size m X k 250 | * X - output matrix of size n X k 251 | * alpha - real constant 252 | * n, m, k - dimensions of A, B 253 | * 254 | * Note: This function re-writes the contents of X. 255 | * 256 | **************************************************************************/ 257 | void matT_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k); 258 | 259 | 260 | 261 | /************************************************************************** 262 | * Tensor-matrix multiplication. 263 | * 264 | * This function accepts a 3-D tensor A of size n X m X k 265 | * and a 2-D matrix B of size l X k. 266 | * The function computes the 3-D tensor X of size n X m X l, where 267 | * 268 | * X(i,j,:) = B*A(i,j,:) 269 | * 270 | * for all i,j. 271 | * 272 | * Parameters: 273 | * A - tensor of size n X m X k 274 | * B - matrix of size l X k 275 | * X - output tensor of size n X m X l 276 | * alpha - real constant 277 | * n, m, k, l - dimensions of A, B 278 | * 279 | * Note: This function re-writes the contents of X. 280 | * 281 | **************************************************************************/ 282 | void tens_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k, mwSize l); 283 | 284 | 285 | 286 | /************************************************************************** 287 | * Tensor-matrix-transpose multiplication. 288 | * 289 | * This function accepts a 3-D tensor A of size n X m X k 290 | * and a 2-D matrix B of size k X l. 291 | * The function computes the 3-D tensor X of size n X m X l, where 292 | * 293 | * X(i,j,:) = B'*A(i,j,:) 294 | * 295 | * for all i,j. 296 | * 297 | * Parameters: 298 | * A - tensor of size n X m X k 299 | * B - matrix of size k X l 300 | * X - output tensor of size n X m X l 301 | * alpha - real constant 302 | * n, m, k, l - dimensions of A, B 303 | * 304 | * Note: This function re-writes the contents of X. 305 | * 306 | **************************************************************************/ 307 | void tens_matT(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k, mwSize l); 308 | 309 | 310 | 311 | /************************************************************************** 312 | * Vector-vector sum. 313 | * 314 | * Computes an operation of the form: 315 | * 316 | * y := alpha*x + y 317 | * 318 | * Parameters: 319 | * x - vector of length n 320 | * y - output vector of length n 321 | * alpha - real constant 322 | * n - length of x,y 323 | * 324 | * Note: This function re-writes the contents of y. 325 | * 326 | **************************************************************************/ 327 | void vec_sum(double alpha, double x[], double y[], mwSize n); 328 | 329 | 330 | 331 | /************************************************************************** 332 | * Triangular back substitution. 333 | * 334 | * Solve the set of linear equations 335 | * 336 | * T*x = b 337 | * 338 | * where T is lower or upper triangular. 339 | * 340 | * Parameters: 341 | * ul - 'U' for upper triangular, 'L' for lower triangular 342 | * A - matrix of size n x m containing T 343 | * b - vector of length k 344 | * x - output vector of length k 345 | * n - size of first dimension of A 346 | * k - the size of the equation set, k<=n,m 347 | * 348 | * Note: 349 | * The matrix A can be of any size n X m, as long as n,m >= k. 350 | * Only the lower/upper triangle of the submatrix A(1:k,1:k) defines the 351 | * matrix T (depending on the parameter ul). 352 | * 353 | **************************************************************************/ 354 | void backsubst(char ul, double A[], double b[], double x[], mwSize n, mwSize k); 355 | 356 | 357 | 358 | /************************************************************************** 359 | * Solve a set of equations using a Cholesky decomposition. 360 | * 361 | * Solve the set of linear equations 362 | * 363 | * M*x = b 364 | * 365 | * where M is positive definite with a known Cholesky decomposition: 366 | * either M=L*L' (L lower triangular) or M=U'*U (U upper triangular). 367 | * 368 | * Parameters: 369 | * ul - 'U' for upper triangular, 'L' for lower triangular decomposition 370 | * A - matrix of size n x m with the Cholesky decomposition of M 371 | * b - vector of length k 372 | * x - output vector of length k 373 | * n - size of first dimension of A 374 | * k - the size of the equation set, k<=n,m 375 | * 376 | * Note: 377 | * The matrix A can be of any size n X m, as long as n,m >= k. 378 | * Only the lower/upper triangle of the submatrix A(1:k,1:k) is used as 379 | * the Cholesky decomposition of M (depending on the parameter ul). 380 | * 381 | **************************************************************************/ 382 | void cholsolve(char ul, double A[], double b[], double x[], mwSize n, mwSize k); 383 | 384 | 385 | 386 | /************************************************************************** 387 | * Maximum absolute value. 388 | * 389 | * Returns the index of the coefficient with maximal absolute value in a vector. 390 | * 391 | * Parameters: 392 | * x - vector of length n 393 | * n - length of x 394 | * 395 | **************************************************************************/ 396 | mwIndex maxabs(double x[], mwSize n); 397 | 398 | 399 | 400 | /************************************************************************** 401 | * Maximum vector element. 402 | * 403 | * Returns the index of the maximal coefficient in a vector. 404 | * 405 | * Parameters: 406 | * x - vector of length n 407 | * n - length of x 408 | * 409 | **************************************************************************/ 410 | mwIndex maxpos(double x[], mwSize n); 411 | 412 | 413 | 414 | /************************************************************************** 415 | * Vector-vector dot product. 416 | * 417 | * Computes an operation of the form: 418 | * 419 | * c = a'*b 420 | * 421 | * Parameters: 422 | * a, b - vectors of length n 423 | * n - length of a,b 424 | * 425 | * Returns: The dot product c. 426 | * 427 | **************************************************************************/ 428 | double dotprod(double a[], double b[], mwSize n); 429 | 430 | 431 | 432 | /************************************************************************** 433 | * Indexed vector assignment. 434 | * 435 | * Perform a permutation assignment of the form 436 | * 437 | * y = x(ind) 438 | * 439 | * where ind is an array of indices to x. 440 | * 441 | * Parameters: 442 | * y - output vector of length k 443 | * x - input vector of arbitrary length 444 | * ind - array of indices into x (indices begin at 0) 445 | * k - length of the array ind 446 | * 447 | **************************************************************************/ 448 | void vec_assign(double y[], double x[], mwIndex ind[], mwSize k); 449 | 450 | 451 | 452 | /************************************************************************** 453 | * Matrix transpose. 454 | * 455 | * Computes Y := X' 456 | * 457 | * Parameters: 458 | * X - input matrix of size n X m 459 | * Y - output matrix of size m X n 460 | * n, m - dimensions of X 461 | * 462 | **************************************************************************/ 463 | void transpose(double X[], double Y[], mwSize n, mwSize m); 464 | 465 | 466 | 467 | /************************************************************************** 468 | * Print a matrix. 469 | * 470 | * Parameters: 471 | * A - matrix of size n X m 472 | * n, m - dimensions of A 473 | * matname - name of matrix to display 474 | * 475 | **************************************************************************/ 476 | void printmat(double A[], int n, int m, char* matname); 477 | 478 | 479 | 480 | /************************************************************************** 481 | * Print a sparse matrix. 482 | * 483 | * Parameters: 484 | * A - sparse matrix of type double 485 | * matname - name of matrix to display 486 | * 487 | **************************************************************************/ 488 | void printspmat(mxArray *A, char* matname); 489 | 490 | 491 | #endif 492 | 493 | -------------------------------------------------------------------------------- /ompbox10/private/omp2mex.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * File name: omp2mex.c 4 | * 5 | * Ron Rubinstein 6 | * Computer Science Department 7 | * Technion, Haifa 32000 Israel 8 | * ronrubin@cs 9 | * 10 | * Last Updated: 18.8.2009 11 | * 12 | *************************************************************************/ 13 | 14 | #include "ompcore.h" 15 | #include "omputils.h" 16 | #include "mexutils.h" 17 | 18 | 19 | /* Input Arguments */ 20 | 21 | #define IN_D prhs[0] 22 | #define IN_X prhs[1] 23 | #define IN_DtX prhs[2] 24 | #define IN_XtX prhs[3] 25 | #define IN_G prhs[4] 26 | #define IN_EPS prhs[5] 27 | #define IN_SPARSE_G prhs[6] 28 | #define IN_MSGDELTA prhs[7] 29 | #define IN_MAXATOMS prhs[8] 30 | #define IN_PROFILE prhs[9] 31 | 32 | 33 | /* Output Arguments */ 34 | 35 | #define GAMMA_OUT plhs[0] 36 | 37 | 38 | /***************************************************************************************/ 39 | 40 | 41 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[]) 42 | 43 | { 44 | double *D, *x, *DtX, *XtX, *G, eps, msgdelta; 45 | int gmode, maxatoms, profile; 46 | mwSize m, n, L; /* D is n x m , X is n x L, DtX is m x L */ 47 | 48 | 49 | /* check parameters */ 50 | 51 | checkmatrix(IN_D, "OMP2", "D"); 52 | checkmatrix(IN_X, "OMP2", "X"); 53 | checkmatrix(IN_DtX, "OMP2", "DtX"); 54 | checkmatrix(IN_XtX, "OMP2", "XtX"); 55 | checkmatrix(IN_G, "OMP2", "G"); 56 | 57 | checkscalar(IN_EPS, "OMP2", "EPSILON"); 58 | checkscalar(IN_SPARSE_G, "OMP2", "sparse_g"); 59 | checkscalar(IN_MSGDELTA, "OMP2", "msgdelta"); 60 | checkscalar(IN_MAXATOMS, "OMP2", "maxatoms"); 61 | checkscalar(IN_PROFILE, "OMP2", "profile"); 62 | 63 | 64 | /* get parameters */ 65 | 66 | x = D = DtX = XtX = G = 0; 67 | 68 | if (!mxIsEmpty(IN_D)) 69 | D = mxGetPr(IN_D); 70 | 71 | if (!mxIsEmpty(IN_X)) 72 | x = mxGetPr(IN_X); 73 | 74 | if (!mxIsEmpty(IN_DtX)) 75 | DtX = mxGetPr(IN_DtX); 76 | 77 | if (!mxIsEmpty(IN_XtX)) 78 | XtX = mxGetPr(IN_XtX); 79 | 80 | if (!mxIsEmpty(IN_G)) 81 | G = mxGetPr(IN_G); 82 | 83 | eps = mxGetScalar(IN_EPS); 84 | if ((int)(mxGetScalar(IN_SPARSE_G)+1e-2)) { 85 | gmode = SPARSE_GAMMA; 86 | } 87 | else { 88 | gmode = FULL_GAMMA; 89 | } 90 | msgdelta = mxGetScalar(IN_MSGDELTA); 91 | if (mxGetScalar(IN_MAXATOMS) < -1e-5) { 92 | maxatoms = -1; 93 | } 94 | else { 95 | maxatoms = (int)(mxGetScalar(IN_MAXATOMS)+1e-2); 96 | } 97 | profile = (int)(mxGetScalar(IN_PROFILE)+1e-2); 98 | 99 | 100 | /* check sizes */ 101 | 102 | if (D && x) { 103 | n = mxGetM(IN_D); 104 | m = mxGetN(IN_D); 105 | L = mxGetN(IN_X); 106 | 107 | if (mxGetM(IN_X) != n) { 108 | mexErrMsgTxt("D and X have incompatible sizes."); 109 | } 110 | 111 | if (G) { 112 | if (mxGetN(IN_G)!=mxGetM(IN_G)) { 113 | mexErrMsgTxt("G must be a square matrix."); 114 | } 115 | if (mxGetN(IN_G) != m) { 116 | mexErrMsgTxt("D and G have incompatible sizes."); 117 | } 118 | } 119 | } 120 | 121 | else if (DtX && XtX) { 122 | m = mxGetM(IN_DtX); 123 | L = mxGetN(IN_DtX); 124 | 125 | /* set n to an arbitrary value that is at least the max possible number of selected atoms */ 126 | 127 | if (maxatoms>0) { 128 | n = maxatoms; 129 | } 130 | else { 131 | n = m; 132 | } 133 | 134 | if ( !(mxGetM(IN_XtX)==L && mxGetN(IN_XtX)==1) && !(mxGetM(IN_XtX)==1 && mxGetN(IN_XtX)==L) ) { 135 | mexErrMsgTxt("DtX and XtX have incompatible sizes."); 136 | } 137 | 138 | if (mxGetN(IN_G)!=mxGetM(IN_G)) { 139 | mexErrMsgTxt("G must be a square matrix."); 140 | } 141 | if (mxGetN(IN_G) != m) { 142 | mexErrMsgTxt("DtX and G have incompatible sizes."); 143 | } 144 | } 145 | 146 | else { 147 | mexErrMsgTxt("Either D and X, or DtX and XtX, must be specified."); 148 | } 149 | 150 | 151 | /* Do OMP! */ 152 | 153 | GAMMA_OUT = ompcore(D, x, DtX, XtX, G, n, m, L, maxatoms, eps, gmode, profile, msgdelta, 1); 154 | 155 | return; 156 | } 157 | -------------------------------------------------------------------------------- /ompbox10/private/omp2mex.m: -------------------------------------------------------------------------------- 1 | %This is the Matlab interface to the OMP2 MEX implementation. 2 | %The function is not for independent use, only through omp2.m. 3 | 4 | 5 | %OMP2MEX Matlab interface to the OMP2 MEX implementation. 6 | % GAMMA = OMP2MEX(D,X,DtX,XtX,G,EPSILON,SPARSE_G,MSGDELTA,MAXATOMS,PROFILE) 7 | % invokes the OMP2 MEX function according to the specified parameters. Not 8 | % all the parameters are required. Those among D, X, DtX, XtX and G which 9 | % are not specified should be passed as []. 10 | % 11 | % EPSILON - the target error. 12 | % SPARSE_G - returns a sparse GAMMA when nonzero, full GAMMA when zero. 13 | % MSGDELTA - the delay in secs between messages. Zero means no messages. 14 | % MAXATOMS - the max number of atoms per signal, negative for no max. 15 | % PROFILE - nonzero means that profiling information should be printed. 16 | 17 | 18 | % Ron Rubinstein 19 | % Computer Science Department 20 | % Technion, Haifa 32000 Israel 21 | % ronrubin@cs 22 | % 23 | % April 2009 24 | -------------------------------------------------------------------------------- /ompbox10/private/omp2mex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowfallingplum/Face-classification-based-on-sparse-representation/877ead1d35818826baa364ab14b1315b52d066c5/ompbox10/private/omp2mex.mexw64 -------------------------------------------------------------------------------- /ompbox10/private/ompcore.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * File name: ompcore.c 4 | * 5 | * Ron Rubinstein 6 | * Computer Science Department 7 | * Technion, Haifa 32000 Israel 8 | * ronrubin@cs 9 | * 10 | * Last Updated: 25.8.2009 11 | * 12 | *************************************************************************/ 13 | 14 | 15 | #include "ompcore.h" 16 | #include "omputils.h" 17 | #include "ompprof.h" 18 | #include "myblas.h" 19 | #include 20 | #include 21 | 22 | 23 | 24 | /****************************************************************************** 25 | * * 26 | * Batch-OMP Implementation * 27 | * * 28 | ******************************************************************************/ 29 | 30 | mxArray* ompcore(double D[], double x[], double DtX[], double XtX[], double G[], mwSize n, mwSize m, mwSize L, 31 | int T, double eps, int gamma_mode, int profile, double msg_delta, int erroromp) 32 | { 33 | 34 | profdata pd; 35 | mxArray *Gamma; 36 | mwIndex i, j, signum, pos, *ind, *gammaIr, *gammaJc, gamma_count; 37 | mwSize allocated_coefs, allocated_cols; 38 | int DtX_specified, XtX_specified, batchomp, standardomp, *selected_atoms; 39 | double *alpha, *r, *Lchol, *c, *Gsub, *Dsub, sum, *gammaPr, *tempvec1, *tempvec2; 40 | double eps2, resnorm, delta, deltaprev, secs_remain; 41 | int mins_remain, hrs_remain; 42 | clock_t lastprint_time, starttime; 43 | 44 | 45 | 46 | /*** status flags ***/ 47 | 48 | DtX_specified = (DtX!=0); /* indicates whether D'*x was provided */ 49 | XtX_specified = (XtX!=0); /* indicates whether sum(x.*x) was provided */ 50 | 51 | standardomp = (G==0); /* batch-omp or standard omp are selected depending on availability of G */ 52 | batchomp = !standardomp; 53 | 54 | 55 | 56 | /*** allocate output matrix ***/ 57 | 58 | 59 | if (gamma_mode == FULL_GAMMA) { 60 | 61 | /* allocate full matrix of size m X L */ 62 | 63 | Gamma = mxCreateDoubleMatrix(m, L, mxREAL); 64 | gammaPr = mxGetPr(Gamma); 65 | gammaIr = 0; 66 | gammaJc = 0; 67 | } 68 | else { 69 | 70 | /* allocate sparse matrix with room for allocated_coefs nonzeros */ 71 | 72 | /* for error-omp, begin with L*sqrt(n)/2 allocated nonzeros, otherwise allocate L*T nonzeros */ 73 | allocated_coefs = erroromp ? (mwSize)(ceil(L*sqrt((double)n)/2.0) + 1.01) : L*T; 74 | Gamma = mxCreateSparse(m, L, allocated_coefs, mxREAL); 75 | gammaPr = mxGetPr(Gamma); 76 | gammaIr = mxGetIr(Gamma); 77 | gammaJc = mxGetJc(Gamma); 78 | gamma_count = 0; 79 | gammaJc[0] = 0; 80 | } 81 | 82 | 83 | /*** helper arrays ***/ 84 | 85 | alpha = (double*)mxMalloc(m*sizeof(double)); /* contains D'*residual */ 86 | ind = (mwIndex*)mxMalloc(n*sizeof(mwIndex)); /* indices of selected atoms */ 87 | selected_atoms = (int*)mxMalloc(m*sizeof(int)); /* binary array with 1's for selected atoms */ 88 | c = (double*)mxMalloc(n*sizeof(double)); /* orthogonal projection result */ 89 | 90 | /* current number of columns in Dsub / Gsub / Lchol */ 91 | allocated_cols = erroromp ? (mwSize)(ceil(sqrt((double)n)/2.0) + 1.01) : T; 92 | 93 | /* Cholesky decomposition of D_I'*D_I */ 94 | Lchol = (double*)mxMalloc(n*allocated_cols*sizeof(double)); 95 | 96 | /* temporary vectors for various computations */ 97 | tempvec1 = (double*)mxMalloc(m*sizeof(double)); 98 | tempvec2 = (double*)mxMalloc(m*sizeof(double)); 99 | 100 | if (batchomp) { 101 | /* matrix containing G(:,ind) - the columns of G corresponding to the selected atoms, in order of selection */ 102 | Gsub = (double*)mxMalloc(m*allocated_cols*sizeof(double)); 103 | } 104 | else { 105 | /* matrix containing D(:,ind) - the selected atoms from D, in order of selection */ 106 | Dsub = (double*)mxMalloc(n*allocated_cols*sizeof(double)); 107 | 108 | /* stores the residual */ 109 | r = (double*)mxMalloc(n*sizeof(double)); 110 | } 111 | 112 | if (!DtX_specified) { 113 | /* contains D'*x for the current signal */ 114 | DtX = (double*)mxMalloc(m*sizeof(double)); 115 | } 116 | 117 | 118 | 119 | /*** initializations for error omp ***/ 120 | 121 | if (erroromp) { 122 | eps2 = eps*eps; /* compute eps^2 */ 123 | if (T<0 || T>n) { /* unspecified max atom num - set max atoms to n */ 124 | T = n; 125 | } 126 | } 127 | 128 | 129 | 130 | /*** initialize timers ***/ 131 | 132 | initprofdata(&pd); /* initialize profiling counters */ 133 | starttime = clock(); /* record starting time for eta computations */ 134 | lastprint_time = starttime; /* time of last status display */ 135 | 136 | 137 | 138 | /********************** perform omp for each signal **********************/ 139 | 140 | 141 | 142 | for (signum=0; signumeps2 && T>0) { 165 | 166 | /* compute DtX */ 167 | 168 | if (!DtX_specified) { 169 | matT_vec(1, D, x+n*signum, DtX, n, m); 170 | addproftime(&pd, DtX_TIME); 171 | } 172 | 173 | 174 | /* initialize alpha := DtX */ 175 | 176 | memcpy(alpha, DtX + m*signum*DtX_specified, m*sizeof(double)); 177 | 178 | 179 | /* mark all atoms as unselected */ 180 | 181 | for (i=0; ieps2 && i=allocated_cols) { 215 | 216 | allocated_cols = (mwSize)(ceil(allocated_cols*MAT_INC_FACTOR) + 1.01); 217 | 218 | Lchol = (double*)mxRealloc(Lchol,n*allocated_cols*sizeof(double)); 219 | 220 | batchomp ? (Gsub = (double*)mxRealloc(Gsub,m*allocated_cols*sizeof(double))) : 221 | (Dsub = (double*)mxRealloc(Dsub,n*allocated_cols*sizeof(double))) ; 222 | } 223 | 224 | 225 | /* append column to Gsub or Dsub */ 226 | 227 | if (batchomp) { 228 | memcpy(Gsub+i*m, G+pos*m, m*sizeof(double)); 229 | } 230 | else { 231 | memcpy(Dsub+i*n, D+pos*n, n*sizeof(double)); 232 | } 233 | 234 | 235 | /*** Cholesky update ***/ 236 | 237 | if (i==0) { 238 | *Lchol = 1; 239 | } 240 | else { 241 | 242 | /* incremental Cholesky decomposition: compute next row of Lchol */ 243 | 244 | if (standardomp) { 245 | matT_vec(1, Dsub, D+n*pos, tempvec1, n, i); /* compute tempvec1 := Dsub'*d where d is new atom */ 246 | addproftime(&pd, DtD_TIME); 247 | } 248 | else { 249 | vec_assign(tempvec1, Gsub+i*m, ind, i); /* extract tempvec1 := Gsub(ind,i) */ 250 | } 251 | backsubst('L', Lchol, tempvec1, tempvec2, n, i); /* compute tempvec2 = Lchol \ tempvec1 */ 252 | for (j=0; j selected atoms are dependent */ 262 | break; 263 | } 264 | Lchol[i*n+i] = sqrt(1-sum); 265 | } 266 | 267 | addproftime(&pd, LCHOL_TIME); 268 | 269 | i++; 270 | 271 | 272 | /* perform orthogonal projection and compute sparse coefficients */ 273 | 274 | vec_assign(tempvec1, DtX + m*signum*DtX_specified, ind, i); /* extract tempvec1 = DtX(ind) */ 275 | cholsolve('L', Lchol, tempvec1, c, n, i); /* solve LL'c = tempvec1 for c */ 276 | addproftime(&pd, COMPCOEF_TIME); 277 | 278 | 279 | /* update alpha = D'*residual */ 280 | 281 | if (standardomp) { 282 | mat_vec(-1, Dsub, c, r, n, i); /* compute r := -Dsub*c */ 283 | vec_sum(1, x+n*signum, r, n); /* compute r := x+r */ 284 | 285 | 286 | /*memcpy(r, x+n*signum, n*sizeof(double)); /* assign r := x */ 287 | /*mat_vec1(-1, Dsub, c, 1, r, n, i); /* compute r := r-Dsub*c */ 288 | 289 | addproftime(&pd, COMPRES_TIME); 290 | matT_vec(1, D, r, alpha, n, m); /* compute alpha := D'*r */ 291 | addproftime(&pd, DtR_TIME); 292 | 293 | /* update residual norm */ 294 | if (erroromp) { 295 | resnorm = dotprod(r, r, n); 296 | addproftime(&pd, UPDATE_RESNORM_TIME); 297 | } 298 | } 299 | else { 300 | mat_vec(1, Gsub, c, tempvec1, m, i); /* compute tempvec1 := Gsub*c */ 301 | memcpy(alpha, DtX + m*signum*DtX_specified, m*sizeof(double)); /* set alpha = D'*x */ 302 | vec_sum(-1, tempvec1, alpha, m); /* compute alpha := alpha - tempvec1 */ 303 | addproftime(&pd, UPDATE_DtR_TIME); 304 | 305 | /* update residual norm */ 306 | if (erroromp) { 307 | vec_assign(tempvec2, tempvec1, ind, i); /* assign tempvec2 := tempvec1(ind) */ 308 | delta = dotprod(c,tempvec2,i); /* compute c'*tempvec2 */ 309 | resnorm = resnorm - delta + deltaprev; /* residual norm update */ 310 | deltaprev = delta; 311 | addproftime(&pd, UPDATE_RESNORM_TIME); 312 | } 313 | } 314 | } 315 | 316 | 317 | /*** generate output vector gamma ***/ 318 | 319 | if (gamma_mode == FULL_GAMMA) { /* write the coefs in c to their correct positions in gamma */ 320 | for (j=0; j= allocated_coefs) { 331 | 332 | while(gamma_count+i >= allocated_coefs) { 333 | allocated_coefs = (mwSize)(ceil(GAMMA_INC_FACTOR*allocated_coefs) + 1.01); 334 | } 335 | 336 | mxSetNzmax(Gamma, allocated_coefs); 337 | mxSetPr(Gamma, mxRealloc(gammaPr, allocated_coefs*sizeof(double))); 338 | mxSetIr(Gamma, mxRealloc(gammaIr, allocated_coefs*sizeof(mwIndex))); 339 | 340 | gammaPr = mxGetPr(Gamma); 341 | gammaIr = mxGetIr(Gamma); 342 | } 343 | 344 | /* append coefs to gamma and update the indices */ 345 | for (j=0; j0 && (clock()-lastprint_time)/(double)CLOCKS_PER_SEC >= msg_delta) 358 | { 359 | lastprint_time = clock(); 360 | 361 | /* estimated remainig time */ 362 | secs2hms( ((L-signum-1)/(double)(signum+1)) * ((lastprint_time-starttime)/(double)CLOCKS_PER_SEC) , 363 | &hrs_remain, &mins_remain, &secs_remain); 364 | 365 | mexPrintf("omp: signal %d / %d, estimated remaining time: %02d:%02d:%05.2f\n", 366 | signum+1, L, hrs_remain, mins_remain, secs_remain); 367 | mexEvalString("drawnow;"); 368 | } 369 | 370 | } 371 | 372 | /* end omp */ 373 | 374 | 375 | 376 | /*** print final messages ***/ 377 | 378 | if (msg_delta>0) { 379 | mexPrintf("omp: signal %d / %d\n", signum, L); 380 | } 381 | 382 | if (profile) { 383 | printprofinfo(&pd, erroromp, batchomp, L); 384 | } 385 | 386 | 387 | 388 | /* free memory */ 389 | 390 | if (!DtX_specified) { 391 | mxFree(DtX); 392 | } 393 | if (standardomp) { 394 | mxFree(r); 395 | mxFree(Dsub); 396 | } 397 | else { 398 | mxFree(Gsub); 399 | } 400 | mxFree(tempvec2); 401 | mxFree(tempvec1); 402 | mxFree(Lchol); 403 | mxFree(c); 404 | mxFree(selected_atoms); 405 | mxFree(ind); 406 | mxFree(alpha); 407 | 408 | return Gamma; 409 | } 410 | -------------------------------------------------------------------------------- /ompbox10/private/ompcore.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * File name: ompcore.h 4 | * 5 | * Ron Rubinstein 6 | * Computer Science Department 7 | * Technion, Haifa 32000 Israel 8 | * ronrubin@cs 9 | * 10 | * Last Updated: 18.8.2009 11 | * 12 | * Contains the core implementation of Batch-OMP / OMP-Cholesky. 13 | * 14 | *************************************************************************/ 15 | 16 | 17 | #ifndef __OMP_CORE_H__ 18 | #define __OMP_CORE_H__ 19 | 20 | 21 | #include "mex.h" 22 | 23 | 24 | 25 | /************************************************************************** 26 | * Perform Batch-OMP or OMP-Cholesky on a specified set of signals, using 27 | * either a fixed number of atoms or an error bound. 28 | * 29 | * Parameters (not all required): 30 | * 31 | * D - the dictionary, of size n X m 32 | * x - the signals, of size n X L 33 | * DtX - D'*x, of size m X L 34 | * XtX - squared norms of the signals in x, sum(x.*x), of length L 35 | * G - D'*D, of size m X m 36 | * T - target sparsity, or maximal number of atoms for error-based OMP 37 | * eps - target residual norm for error-based OMP 38 | * gamma_mode - one of the constants FULL_GAMMA or SPARSE_GAMMA 39 | * profile - if non-zero, profiling info is printed 40 | * msg_delta - positive: the # of seconds between status prints, otherwise: nothing is printed 41 | * erroromp - if nonzero indicates error-based OMP, otherwise fixed sparsity OMP 42 | * 43 | * Usage: 44 | * 45 | * The function can be called using different parameters, and will have 46 | * different complexity depending on the parameters specified. Arrays which 47 | * are not specified should be passed as null (0). When G is specified, 48 | * Batch-OMP is performed. Otherwise, OMP-Cholesky is performed. 49 | * 50 | * Fixed-sparsity usage: 51 | * --------------------- 52 | * Either DtX, or D and x, must be specified. Specifying DtX is more efficient. 53 | * XtX does not need to be specified. 54 | * When D and x are specified, G is not required. However, not providing G 55 | * will significantly degrade efficiency. 56 | * The number of atoms must be specified in T. The value of eps is ignored. 57 | * Finally, set erroromp to 0. 58 | * 59 | * Error-OMP usage: 60 | * ---------------- 61 | * Either DtX and Xtx, or D and x, must be specified. Specifying DtX and XtX 62 | * is more efficient. 63 | * When D and x are specified, G is not required. However, not providing G 64 | * will significantly degrade efficiency. 65 | * The target error must be specified in eps. A hard limit on the number 66 | * of atoms can also be specified via the parameter T. Otherwise, T should 67 | * be negative. Finally, set erroromp to nonzero. 68 | * 69 | * 70 | * Returns: 71 | * An mxArray containing the sparse representations of the signals in x 72 | * (allocated using the appropriate mxCreateXXX() function). 73 | * The array is either full or sparse, depending on gamma_mode. 74 | * 75 | **************************************************************************/ 76 | mxArray* ompcore(double D[], double x[], double DtX[], double XtX[], double G[], mwSize n, mwSize m, mwSize L, 77 | int T, double eps, int gamma_mode, int profile, double msg_delta, int erroromp); 78 | 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /ompbox10/private/ompmex.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * File name: ompmex.c 4 | * 5 | * Ron Rubinstein 6 | * Computer Science Department 7 | * Technion, Haifa 32000 Israel 8 | * ronrubin@cs 9 | * 10 | * Last Updated: 18.8.2009 11 | * 12 | *************************************************************************/ 13 | 14 | #include "ompcore.h" 15 | #include "omputils.h" 16 | #include "mexutils.h" 17 | 18 | 19 | /* Input Arguments */ 20 | 21 | #define IN_D prhs[0] 22 | #define IN_X prhs[1] 23 | #define IN_DtX prhs[2] 24 | #define IN_G prhs[3] 25 | #define IN_T prhs[4] 26 | #define IN_SPARSE_G prhs[5] 27 | #define IN_MSGDELTA prhs[6] 28 | #define IN_PROFILE prhs[7] 29 | 30 | 31 | /* Output Arguments */ 32 | 33 | #define GAMMA_OUT plhs[0] 34 | 35 | 36 | /***************************************************************************************/ 37 | 38 | 39 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[]) 40 | 41 | { 42 | double *D, *x, *DtX, *G, msgdelta; 43 | int gmode, profile, T; 44 | mwSize m, n, L; /* D is n x m , X is n x L, DtX is m x L */ 45 | 46 | 47 | /* check parameters */ 48 | 49 | checkmatrix(IN_D, "OMP", "D"); 50 | checkmatrix(IN_X, "OMP", "X"); 51 | checkmatrix(IN_DtX, "OMP", "DtX"); 52 | checkmatrix(IN_G, "OMP", "G"); 53 | 54 | checkscalar(IN_T, "OMP", "T"); 55 | checkscalar(IN_SPARSE_G, "OMP", "sparse_g"); 56 | checkscalar(IN_MSGDELTA, "OMP", "msgdelta"); 57 | checkscalar(IN_PROFILE, "OMP", "profile"); 58 | 59 | 60 | /* get parameters */ 61 | 62 | x = D = DtX = G = 0; 63 | 64 | if (!mxIsEmpty(IN_D)) 65 | D = mxGetPr(IN_D); 66 | 67 | if (!mxIsEmpty(IN_X)) 68 | x = mxGetPr(IN_X); 69 | 70 | if (!mxIsEmpty(IN_DtX)) 71 | DtX = mxGetPr(IN_DtX); 72 | 73 | if (!mxIsEmpty(IN_G)) 74 | G = mxGetPr(IN_G); 75 | 76 | T = (int)(mxGetScalar(IN_T)+1e-2); 77 | if ((int)(mxGetScalar(IN_SPARSE_G)+1e-2)) { 78 | gmode = SPARSE_GAMMA; 79 | } 80 | else { 81 | gmode = FULL_GAMMA; 82 | } 83 | msgdelta = mxGetScalar(IN_MSGDELTA); 84 | profile = (int)(mxGetScalar(IN_PROFILE)+1e-2); 85 | 86 | 87 | /* check sizes */ 88 | 89 | if (D && x) { 90 | n = mxGetM(IN_D); 91 | m = mxGetN(IN_D); 92 | L = mxGetN(IN_X); 93 | 94 | if (mxGetM(IN_X) != n) { 95 | mexErrMsgTxt("D and X have incompatible sizes."); 96 | } 97 | 98 | if (G) { 99 | if (mxGetN(IN_G)!=mxGetM(IN_G)) { 100 | mexErrMsgTxt("G must be a square matrix."); 101 | } 102 | if (mxGetN(IN_G) != m) { 103 | mexErrMsgTxt("D and G have incompatible sizes."); 104 | } 105 | } 106 | } 107 | 108 | else if (DtX) { 109 | m = mxGetM(IN_DtX); 110 | L = mxGetN(IN_DtX); 111 | 112 | n = T; /* arbitrary - it is enough to assume signal length is T */ 113 | 114 | if (mxGetN(IN_G)!=mxGetM(IN_G)) { 115 | mexErrMsgTxt("G must be a square matrix."); 116 | } 117 | if (mxGetN(IN_G) != m) { 118 | mexErrMsgTxt("DtX and G have incompatible sizes."); 119 | } 120 | } 121 | 122 | else { 123 | mexErrMsgTxt("Either D and X, or DtX, must be specified."); 124 | } 125 | 126 | 127 | /* Do OMP! */ 128 | 129 | GAMMA_OUT = ompcore(D, x, DtX, 0, G, n, m, L, T, 0, gmode, profile, msgdelta, 0); 130 | 131 | return; 132 | } 133 | 134 | -------------------------------------------------------------------------------- /ompbox10/private/ompmex.m: -------------------------------------------------------------------------------- 1 | %This is the Matlab interface to the OMP MEX implementation. 2 | %The function is not for independent use, only through omp.m. 3 | 4 | 5 | %OMPMEX Matlab interface to the OMP MEX implementation. 6 | % GAMMA = OMPMEX(D,X,DtX,G,L,SPARSE_G,MSGDELTA,PROFILE) invokes the OMP 7 | % MEX function according to the specified parameters. Not all the 8 | % parameters are required. Those among D, X, DtX and G which are not 9 | % specified should be passed as []. 10 | % 11 | % L - the target sparsity. 12 | % SPARSE_G - returns a sparse GAMMA when nonzero, full GAMMA when zero. 13 | % MSGDELTA - the delay in secs between messages. Zero means no messages. 14 | % PROFILE - nonzero means that profiling information should be printed. 15 | 16 | 17 | % Ron Rubinstein 18 | % Computer Science Department 19 | % Technion, Haifa 32000 Israel 20 | % ronrubin@cs 21 | % 22 | % April 2009 23 | -------------------------------------------------------------------------------- /ompbox10/private/ompmex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snowfallingplum/Face-classification-based-on-sparse-representation/877ead1d35818826baa364ab14b1315b52d066c5/ompbox10/private/ompmex.mexw64 -------------------------------------------------------------------------------- /ompbox10/private/ompprof.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * File name: ompprof.c 4 | * 5 | * Ron Rubinstein 6 | * Computer Science Department 7 | * Technion, Haifa 32000 Israel 8 | * ronrubin@cs 9 | * 10 | * Last Updated: 11.4.2009 11 | * 12 | *************************************************************************/ 13 | 14 | 15 | #include "ompprof.h" 16 | 17 | 18 | /* initialize profiling information */ 19 | 20 | void initprofdata(profdata *pd) 21 | { 22 | pd->DtX_time = 0; 23 | pd->XtX_time = 0; 24 | pd->DtR_time = 0; 25 | pd->maxabs_time = 0; 26 | pd->DtD_time = 0; 27 | pd->Lchol_time = 0; 28 | pd->compcoef_time = 0; 29 | pd->update_DtR_time = 0; 30 | pd->update_resnorm_time = 0; 31 | pd->compres_time = 0; 32 | pd->indexsort_time = 0; 33 | 34 | pd->DtX_time_counted = 0; 35 | pd->XtX_time_counted = 0; 36 | pd->DtR_time_counted = 0; 37 | pd->DtD_time_counted = 0; 38 | pd->update_DtR_time_counted = 0; 39 | pd->resnorm_time_counted = 0; 40 | pd->compres_time_counted = 0; 41 | pd->indexsort_time_counted = 0; 42 | 43 | pd->prevtime = clock(); 44 | } 45 | 46 | 47 | /* add elapsed time to profiling data according to specified computation */ 48 | 49 | void addproftime(profdata *pd, int comptype) 50 | { 51 | switch(comptype) { 52 | case DtX_TIME: pd->DtX_time += clock()-pd->prevtime; pd->DtX_time_counted = 1; break; 53 | case XtX_TIME: pd->XtX_time += clock()-pd->prevtime; pd->XtX_time_counted = 1; break; 54 | case DtR_TIME: pd->DtR_time += clock()-pd->prevtime; pd->DtR_time_counted = 1; break; 55 | case DtD_TIME: pd->DtD_time += clock()-pd->prevtime; pd->DtD_time_counted = 1; break; 56 | case COMPRES_TIME: pd->compres_time += clock()-pd->prevtime; pd->compres_time_counted = 1; break; 57 | case UPDATE_DtR_TIME: pd->update_DtR_time += clock()-pd->prevtime; pd->update_DtR_time_counted = 1; break; 58 | case UPDATE_RESNORM_TIME: pd->update_resnorm_time += clock()-pd->prevtime; pd->resnorm_time_counted = 1; break; 59 | case INDEXSORT_TIME: pd->indexsort_time += clock()-pd->prevtime; pd->indexsort_time_counted = 1; break; 60 | case MAXABS_TIME: pd->maxabs_time += clock()-pd->prevtime; break; 61 | case LCHOL_TIME: pd->Lchol_time += clock()-pd->prevtime; break; 62 | case COMPCOEF_TIME: pd->compcoef_time += clock()-pd->prevtime; break; 63 | } 64 | pd->prevtime = clock(); 65 | } 66 | 67 | 68 | /* print profiling info */ 69 | 70 | void printprofinfo(profdata *pd, int erroromp, int batchomp, int signum) 71 | { 72 | clock_t tottime; 73 | 74 | tottime = pd->DtX_time + pd->XtX_time + pd->DtR_time + pd->DtD_time + pd->compres_time + pd->maxabs_time + 75 | pd->Lchol_time + pd->compcoef_time + pd->update_DtR_time + pd->update_resnorm_time + pd->indexsort_time; 76 | 77 | mexPrintf("\n\n***** Profiling information for %s *****\n\n", erroromp? "OMP2" : "OMP"); 78 | 79 | mexPrintf("OMP mode: %s\n\n", batchomp? "Batch-OMP" : "OMP-Cholesky"); 80 | 81 | mexPrintf("Total signals processed: %d\n\n", signum); 82 | 83 | if (pd->DtX_time_counted) { 84 | mexPrintf("Compute DtX time: %7.3lf seconds\n", pd->DtX_time/(double)CLOCKS_PER_SEC); 85 | } 86 | if (pd->XtX_time_counted) { 87 | mexPrintf("Compute XtX time: %7.3lf seconds\n", pd->XtX_time/(double)CLOCKS_PER_SEC); 88 | } 89 | mexPrintf("Max abs time: %7.3lf seconds\n", pd->maxabs_time/(double)CLOCKS_PER_SEC); 90 | if (pd->DtD_time_counted) { 91 | mexPrintf("Compute DtD time: %7.3lf seconds\n", pd->DtD_time/(double)CLOCKS_PER_SEC); 92 | } 93 | mexPrintf("Lchol update time: %7.3lf seconds\n", pd->Lchol_time/(double)CLOCKS_PER_SEC); 94 | mexPrintf("Compute coef time: %7.3lf seconds\n", pd->compcoef_time/(double)CLOCKS_PER_SEC); 95 | if (pd->compres_time_counted) { 96 | mexPrintf("Compute R time: %7.3lf seconds\n", pd->compres_time/(double)CLOCKS_PER_SEC); 97 | } 98 | if (pd->DtR_time_counted) { 99 | mexPrintf("Compute DtR time: %7.3lf seconds\n", pd->DtR_time/(double)CLOCKS_PER_SEC); 100 | } 101 | if (pd->update_DtR_time_counted) { 102 | mexPrintf("Update DtR time: %7.3lf seconds\n", pd->update_DtR_time/(double)CLOCKS_PER_SEC); 103 | } 104 | if (pd->resnorm_time_counted) { 105 | mexPrintf("Update resnorm time: %7.3lf seconds\n", pd->update_resnorm_time/(double)CLOCKS_PER_SEC); 106 | } 107 | if (pd->indexsort_time_counted) { 108 | mexPrintf("Index sort time: %7.3lf seconds\n", pd->indexsort_time/(double)CLOCKS_PER_SEC); 109 | } 110 | mexPrintf("---------------------------------------\n"); 111 | mexPrintf("Total time: %7.3lf seconds\n\n", tottime/(double)CLOCKS_PER_SEC); 112 | } 113 | 114 | -------------------------------------------------------------------------------- /ompbox10/private/ompprof.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * File name: ompprof.h 4 | * 5 | * Ron Rubinstein 6 | * Computer Science Department 7 | * Technion, Haifa 32000 Israel 8 | * ronrubin@cs 9 | * 10 | * Last Updated: 18.8.2009 11 | * 12 | * Collection of definitions and functions for profiling the OMP method. 13 | * 14 | *************************************************************************/ 15 | 16 | 17 | #ifndef __OMP_PROF_H__ 18 | #define __OMP_PROF_H__ 19 | 20 | #include "mex.h" 21 | #include 22 | 23 | 24 | 25 | /************************************************************************** 26 | * 27 | * Constants and data types. 28 | * 29 | **************************************************************************/ 30 | 31 | 32 | /* constants denoting the various parts of the algorithm */ 33 | 34 | enum { DtX_TIME, XtX_TIME, DtR_TIME, MAXABS_TIME, DtD_TIME, LCHOL_TIME, COMPCOEF_TIME, 35 | UPDATE_DtR_TIME, UPDATE_RESNORM_TIME, COMPRES_TIME, INDEXSORT_TIME }; 36 | 37 | 38 | 39 | /* profiling data container with counters for each part of the algorithm */ 40 | 41 | typedef struct profdata 42 | { 43 | clock_t prevtime; /* the time when last initialization/call to addproftime() was performed */ 44 | 45 | clock_t DtX_time; 46 | clock_t XtX_time; 47 | clock_t DtR_time; 48 | clock_t maxabs_time; 49 | clock_t DtD_time; 50 | clock_t Lchol_time; 51 | clock_t compcoef_time; 52 | clock_t update_DtR_time; 53 | clock_t update_resnorm_time; 54 | clock_t compres_time; 55 | clock_t indexsort_time; 56 | 57 | /* flags indicating whether profiling data was gathered */ 58 | int DtX_time_counted; 59 | int XtX_time_counted; 60 | int DtR_time_counted; 61 | int DtD_time_counted; 62 | int update_DtR_time_counted; 63 | int resnorm_time_counted; 64 | int compres_time_counted; 65 | int indexsort_time_counted; 66 | 67 | } profdata; 68 | 69 | 70 | 71 | /************************************************************************** 72 | * 73 | * Initialize a profdata structure, zero all counters, and start its timer. 74 | * 75 | **************************************************************************/ 76 | void initprofdata(profdata *pd); 77 | 78 | 79 | /************************************************************************** 80 | * 81 | * Add elapsed time from last call to addproftime(), or from initialization 82 | * of profdata, to the counter specified by comptype. comptype must be one 83 | * of the constants in the enumeration above. 84 | * 85 | **************************************************************************/ 86 | void addproftime(profdata *pd, int comptype); 87 | 88 | 89 | /************************************************************************** 90 | * 91 | * Print the current contents of the counters in profdata. 92 | * 93 | * Parameters: 94 | * pd - the profdata to print 95 | * erroromp - indicates whether error-based (nonzero) or sparsity-based (zero) 96 | * omp was performed. 97 | * batchomp - indicates whether batch-omp (nonzero) or omp-cholesky (zero) 98 | * omp was performed. 99 | * signum - number of signals processed by omp 100 | * 101 | **************************************************************************/ 102 | void printprofinfo(profdata *pd, int erroromp, int batchomp, int signum); 103 | 104 | 105 | #endif 106 | 107 | -------------------------------------------------------------------------------- /ompbox10/private/omputils.c: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * File name: omputils.c 4 | * 5 | * Ron Rubinstein 6 | * Computer Science Department 7 | * Technion, Haifa 32000 Israel 8 | * ronrubin@cs 9 | * 10 | * Last Updated: 18.8.2009 11 | * 12 | *************************************************************************/ 13 | 14 | #include "omputils.h" 15 | #include 16 | 17 | 18 | const char FULL_GAMMA_STR[] = "full"; 19 | const char SPARSE_GAMMA_STR[] = "sparse"; 20 | 21 | 22 | /* convert seconds to hours, minutes and seconds */ 23 | 24 | void secs2hms(double sectot, int *hrs, int *mins, double *secs) 25 | { 26 | *hrs = (int)(floor(sectot/3600)+1e-2); 27 | sectot = sectot - 3600*(*hrs); 28 | *mins = (int)(floor(sectot/60)+1e-2); 29 | *secs = sectot - 60*(*mins); 30 | } 31 | 32 | 33 | /* quicksort, public-domain C implementation by Darel Rex Finley. */ 34 | /* modification: sorts the array data[] as well, according to the values in the array vals[] */ 35 | 36 | #define MAX_LEVELS 300 37 | 38 | void quicksort(mwIndex vals[], double data[], mwIndex n) { 39 | 40 | long piv, beg[MAX_LEVELS], end[MAX_LEVELS], i=0, L, R, swap ; 41 | double datapiv; 42 | 43 | beg[0]=0; 44 | end[0]=n; 45 | 46 | while (i>=0) { 47 | 48 | L=beg[i]; 49 | R=end[i]-1; 50 | 51 | if (L=piv && L end[i-1]-beg[i-1]) { 81 | swap=beg[i]; beg[i]=beg[i-1]; beg[i-1]=swap; 82 | swap=end[i]; end[i]=end[i-1]; end[i-1]=swap; 83 | } 84 | } 85 | else { 86 | i--; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /ompbox10/private/omputils.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * File name: omputils.h 4 | * 5 | * Ron Rubinstein 6 | * Computer Science Department 7 | * Technion, Haifa 32000 Israel 8 | * ronrubin@cs 9 | * 10 | * Last Updated: 18.8.2009 11 | * 12 | * Utility definitions and functions for the OMP library. 13 | * 14 | *************************************************************************/ 15 | 16 | 17 | #ifndef __OMP_UTILS_H__ 18 | #define __OMP_UTILS_H__ 19 | 20 | #include "mex.h" 21 | 22 | 23 | /* constants for the representation mode of gamma */ 24 | 25 | extern const char FULL_GAMMA_STR[]; /* "full" */ 26 | extern const char SPARSE_GAMMA_STR[]; /* "sparse" */ 27 | 28 | 29 | #define FULL_GAMMA 1 30 | #define SPARSE_GAMMA 2 31 | #define INVALID_MODE 3 32 | 33 | 34 | 35 | /************************************************************************** 36 | * Memory management for OMP2. 37 | * 38 | * GAMMA_INC_FACTOR: 39 | * The matrix GAMMA is allocated with sqrt(n)/2 coefficients per signal, 40 | * for a total of nzmax = L*sqrt(n)/2 nonzeros. Whenever GAMMA needs to be 41 | * increased, it is increased by a factor of GAMMA_INC_FACTOR. 42 | * 43 | * MAT_INC_FACTOR: 44 | * The matrices Lchol, Gsub and Dsub are allocated with sqrt(n)/2 45 | * columns each. If additional columns are needed, this number is 46 | * increased by a factor of MAT_INC_FACTOR. 47 | **************************************************************************/ 48 | 49 | #define GAMMA_INC_FACTOR (1.4) 50 | #define MAT_INC_FACTOR (1.6) 51 | 52 | 53 | 54 | /************************************************************************** 55 | * Convert number of seconds to hour, minute and second representation. 56 | * 57 | * Parameters: 58 | * sectot - total number of seconds 59 | * hrs, mins, secs - output hours (whole) and minutes (whole) and seconds 60 | * 61 | **************************************************************************/ 62 | void secs2hms(double sectot, int *hrs, int *mins, double *secs); 63 | 64 | 65 | 66 | /************************************************************************** 67 | * QuickSort - public-domain C implementation by Darel Rex Finley. 68 | * 69 | * Modified to sort both the array vals[] and the array data[] according 70 | * to the values in the array vals[]. 71 | * 72 | **************************************************************************/ 73 | void quicksort(mwIndex vals[], double data[], mwIndex n); 74 | 75 | 76 | #endif 77 | 78 | -------------------------------------------------------------------------------- /ompbox10/private/printf.m: -------------------------------------------------------------------------------- 1 | function str = printf(varargin) 2 | %PRINTF Print formatted text to screen. 3 | % PRINTF(FMT,VAL1,VAL2,...) formats the data in VAL1,VAL2,... according to 4 | % the format string FMT, and prints the result to the screen. 5 | % 6 | % The call to PRINTF(FMT,VAL1,VAL2,...) simply invokes the call 7 | % DISP(SPRINTF(FMT,VAL1,VAL2,...)). For a complete description of the 8 | % format string options see function SPRINTF. 9 | % 10 | % STR = PRINTF(...) also returns the formatted string. 11 | 12 | 13 | % Ron Rubinstein 14 | % Computer Science Department 15 | % Technion, Haifa 32000 Israel 16 | % ronrubin@cs 17 | % 18 | % April 2008 19 | 20 | 21 | if (nargout>0) 22 | str = sprintf(varargin{:}); 23 | disp(str); 24 | else 25 | disp(sprintf(varargin{:})); 26 | end 27 | -------------------------------------------------------------------------------- /ompbox10/readme.txt: -------------------------------------------------------------------------------- 1 | 2 | OMPBox v10 README 3 | October 18, 2009 4 | 5 | 6 | 7 | OMPBox installation: 8 | -------------------- 9 | 10 | 1. Unpack the contents of the compressed file to a new directory, named e.g. "ompbox". 11 | 2. If you have not done so before, configure Matlab's MEX compiler by entering 12 | >> mex -setup 13 | prior to using MAKE. For optimal performance, it is recommended that you select a compiler 14 | that performs optimizations. For instance, in Windows, MS Visual Studio is preferred to Lcc. 15 | 3. Within Matlab, navigate to the OMPBox directory, and then to the "private" directory within it, 16 | and enter MAKE to run the compilation script. 17 | 4. Add the OMPBox package directory to the Matlab path (you can use the ADDPATH command for this). 18 | Do not add the private directory to the path. 19 | 20 | 21 | OMPBox quick start: 22 | ------------------- 23 | 24 | 1. Enter "ompdemo" at the Matlab command prompt to run a short demo of the package. 25 | 2. Enter "ompspeedtest" to test the speed of the various OMP implementations. 26 | 3. For a complete list of functions in the package, enter 27 | >> help ompbox 28 | This assumes the package was installed to a directory named "ompbox". If not, replace ompbox 29 | in the above with the (unqualified) name of the OMPBox installation directory. 30 | 31 | Also see faq.txt for some frequently asked questions about the package. 32 | --------------------------------------------------------------------------------