source: hypertools/hypertools/sg.m

Last change on this file was 3, checked in by dtax, 15 years ago

Hypertools, first

File size: 4.6 KB
Line 
1function varargout = sg(varargin)
2%
3%
4%   Filter creating:
5%   CM = sg(w, p, m) 
6%
7%   Filter applying:
8%   Y_hat = sg(CM, Y)
9%   Y_hat = sg(CM, Y, dim)
10%
11%   Filter creating & applying:
12%   [Y_hat, CM] = sg(w, p, m, Y)
13%   [Y_hat, CM] = sg(w, p, m, Y, dim)
14%
15%
16% w     window size in points; w must be:  (odd & 3 <= w < d) or (w == d);
17%       (d is the size of the dimension of the input matrix Y along which it should be filtered,
18%       if Y is not supplied, it is assumed that d == inf)
19%
20% p     polynom order p=0,1,2,...
21%
22% m     derivative order m=0,1,2...
23%
24% Y     matrix which should be smoothed/differinate;
25%       by default (i.e. if the parameter dim is not supplied)
26%       filtering will be applied to the first non-singleton dimension;
27%
28% dim   selects the dimension along which Y should be filtered
29%
30%
31% CM    coefficient matrix (filter)
32% Y_hat result matrix
33%
34
35% Copyright: S.Verzakov, serguei@ph.tn.tudelft.nl
36% Faculty of Applied Sciences, Delft University of Technology
37% P.O. Box 5046, 2600 GA Delft, The Netherlands
38
39% $Id: sg.m,v 1.9 2007/03/15 16:10:24 serguei Exp $
40
41        if nargout > 0
42                varargout(1:nargout) = {[]};
43        end
44       
45        Y_hat  = [];
46        CM     = [];
47
48        w   = [];
49        p   = [];
50        m   = [];
51        Y   = [];
52        dim = [];
53
54        d   = [];
55
56        create_filter = 0;
57        apply_filter  = 0;
58
59        switch length(varargin)
60         case 2
61          %Y_hat = sg(CM, Y)
62          apply_filter  = 1;
63          CM  = varargin{1};
64          Y   = varargin{2};
65
66         case 3
67          %CM = sg(w, p, m) 
68          if all(size(varargin{1}) == 1)
69                  create_filter  = 1;
70                  w  = varargin{1};
71                  p  = varargin{2};
72                  m  = varargin{3};
73
74                  %Y_hat = sg(CM, Y, dim)
75          else
76                  apply_filter  = 1;
77                  CM  = varargin{1};
78                  Y   = varargin{2};
79                  dim = varargin{3};
80          end 
81
82         case 4
83          %[Y_hat, CM] = sg(w, p, m, Y)
84          create_filter = 1;
85          apply_filter  = 1;
86          w  = varargin{1};
87          p  = varargin{2};
88          m  = varargin{3};
89          Y  = varargin{4};
90
91         case 5
92          %[Y_hat, CM] = sg(w, p, m, Y, dim)
93          create_filter = 1;
94          apply_filter  = 1;
95          w   = varargin{1};
96          p   = varargin{2};
97          m   = varargin{3};
98          Y   = varargin{4};
99          dim = varargin{5};
100
101         otherwise
102          error('Invalid number of input parameters');
103        end
104
105
106        if apply_filter
107                if ~isempty(dim)
108                        if floor(dim) ~= dim | dim < 1 | dim > length(size(Y))
109                                error('dim must be integer, >=1, <=length(size(Y))');
110                        end 
111                else
112                        dim = size(Y);
113                        dim = find(dim > 1);
114
115                        if isempty(dim)
116                                error('Filter cannot be applied to the scalar Y');
117                        end
118
119                        dim = dim(1);
120                end
121
122                d = size(Y,dim);
123
124                if d < 3
125                        error('size(Y,dim) must be >= 3');
126                end
127        end
128
129
130        if create_filter
131                if ~isempty(d)
132                        if floor(w) ~= w | mod(w,2) == 0 | w < 3
133                                error('w must be odd integer >=3');
134                        end
135                else
136                        if (floor(w) ~= w | mod(w,2) == 0 | w < 3 | w > d) & w ~= d
137                                error('w must be (odd integer >=3, <=size(Y,dim)) or ==size(Y,dim)');
138                        end
139                end 
140               
141                M = floor(w/2);
142
143                if floor(p) ~= p | p < 0
144                        error('p must be 0,1,2...');
145                end
146
147                if floor(m) ~= m | m < 0
148                        error('m must be 0,1,2...');
149                end
150
151                if m > p
152                        Y_hat = zeros(size(Y));
153                        CM = zeros(3);
154
155                        WarnMsg = 'Derivative order is greater than order of approximating polinomial';
156                        if exist('prwarning')
157                                prwarning(1, WarnMsg);
158                        else
159                                warning(WarnMsg);
160                        end
161                       
162                else
163                        X = repmat([(-M):(w-M-1)]',[1 p]);
164                        X = [fliplr(cumprod(X,2)) ones(w,1)];
165
166                        CM = (X'*X)\X';
167                        %CM = X\eye(w);
168                        CM = CM(1:p-m+1,:);
169
170                        if m == 0
171                                CM = X*CM;
172                        else
173                                factors = zeros(1,p-m+1);
174                                for i=m:p
175                                        factors(p-i+1) = prod([1 (i-m+1):i]);
176                                end
177                                CM = [X(:,(m+1):(p+1))].*repmat(factors,[w 1])*CM;
178                        end
179                end
180        end
181
182
183        if apply_filter & isempty(Y_hat)
184                cms = size(CM);
185
186                if cms(1) ~= cms(2)
187                        error('size(CM,1) must be equal size(CM,2)');
188                elseif (mod(cms(2),2) == 0 | cms(2) < 3 | cms(2) > d) & cms(2) ~= d
189                        error('size(CM,2) must be (odd, >=3, <=size(Y,dim)) or == size(Y,dim)');
190                end
191
192                w = cms(2);
193                M = floor(w/2);
194
195                ys = size(Y);
196                order = [1:length(ys)];
197                order(1) = dim;
198                order(dim) = 1;
199                Y = permute(Y,order);
200                ysn = size(Y);
201
202                CM_b = CM(1:M,:);
203                CM_m = CM((M+1):(end-M),:);
204                CM_e = CM((end-M+1):end,:);
205
206                Y_b = reshape(CM_b * Y(1:w,:), [M ysn(2:end)]);
207
208                if isempty(CM_m)
209                        Y_m = [];
210                else
211                        Y_m = filter(fliplr(CM_m), 1, Y);
212      Y_m = reshape(Y_m(w:end,:),[(ysn(1)-2*M) ysn(2:end)]);
213    end
214
215                Y_e = reshape(CM_e * Y((end-w+1):end,:), [M ysn(2:end)]);
216    clear Y;
217
218    Y_hat = permute([Y_b; Y_m; Y_e], order);
219                clear Y_b Y_m Y_e;
220        end
221
222
223        if create_filter & apply_filter
224                varargout(1:2) = {Y_hat, CM};
225
226        elseif create_filter
227                varargout(1) = {CM};
228
229        elseif apply_filter
230                varargout(1) = {Y_hat};
231        end
232
233        varargout = varargout(1:nargout);
234        return;
Note: See TracBrowser for help on using the repository browser.