| Description of slfindnn |
slfindnn
PURPOSE 
SLFINDNN Finds the nearest neighbors using specified strategy
SYNOPSIS 
function [nnidx, dists] = slfindnn(X0, X, method, varargin)
DESCRIPTION 
CROSS-REFERENCE INFORMATION 
This function calls:
- annsearch ANNSEARCH Approximate Nearest Neighbor Search
- slmetric_pw SLMETRIC_PW Compute the metric between column vectors pairwisely
- raise_lackinput RAISE_LACKINPUT Raises an error indicating lack of input argument
- slparseprops SLPARSEPROPS Parses input parameters
- slpartition SLPARTITION Partition a range into blocks in a specified manner
This function is called by:
- slnngraph SLNNGRAPH Constructs a nearest neighborhood based graph
SUBFUNCTIONS 
- function [nnidx, dists] = find_knn(X0, X, excludediag, varargin)
- function [nnidx, dists] = find_ann(X0, X, excludediag, varargin)
- function [nnidx, dists] = find_eps(X0, X, excludediag, varargin)
- function dists = compute_pwdists(X0, X, fhmetric, sp, ep, excludediag)
- function fh = get_metricfunc(m)
- function C = cols_to_cells(M)
- function nnidx = select_output_indices(is_selected)
- function vals = select_output_values(vals0, is_selected)
- function K = getK(opts, X0)
- function [secs, nsecs] = getparsecs(opts, X0, X)
SOURCE CODE 
0001 function [nnidx, dists] = slfindnn(X0, X, method, varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 if nargin < 3
0082 raise_lackinput('slfindnn', 3);
0083 end
0084
0085 if ~ismember(method, {'knn', 'ann', 'eps'})
0086 error('sltoolbox:invalidarg', ...
0087 'Invalid method for nearest neighbor finding: %s', method);
0088 end
0089
0090 if isempty(X)
0091 X = X0;
0092 excludediag = true;
0093 else
0094 excludediag = false;
0095 end
0096
0097
0098
0099
0100 switch method
0101 case 'knn'
0102 if nargout < 2
0103 nnidx = find_knn(X0, X, excludediag, varargin{:});
0104 else
0105 [nnidx, dists] = find_knn(X0, X, excludediag, varargin{:});
0106 end
0107 case 'ann'
0108 if nargout < 2
0109 nnidx = find_ann(X0, X, excludediag, varargin{:});
0110 else
0111 [nnidx, dists] = find_ann(X0, X, excludediag, varargin{:});
0112 end
0113 case 'eps'
0114 if nargout < 2
0115 nnidx = find_eps(X0, X, excludediag, varargin{:});
0116 else
0117 [nnidx, dists] = find_eps(X0, X, excludediag, varargin{:});
0118 end
0119 end
0120
0121
0122
0123 function [nnidx, dists] = find_knn(X0, X, excludediag, varargin)
0124
0125
0126 opts.K = 3;
0127 opts.maxblk = 1e7;
0128 opts.metric = 'eucdist';
0129 opts = slparseprops(opts, varargin{:});
0130 fhmetric = get_metricfunc(opts.metric);
0131
0132 n = size(X, 2);
0133 K = getK(opts, X0);
0134 [secs, nsecs] = getparsecs(opts, X0, X);
0135
0136 to_output_dist = (nargout >= 2);
0137
0138
0139 nnidx = zeros(K, n);
0140 if to_output_dist
0141 dists = zeros(K, n);
0142 end
0143
0144
0145 for k = 1 : nsecs
0146
0147
0148 sp = secs.sinds(k); ep = secs.einds(k);
0149 curdists = compute_pwdists(X0, X, fhmetric, sp, ep, excludediag);
0150
0151
0152 [curdists, curnnidx] = sort(curdists, 1);
0153
0154
0155 curnnidx = curnnidx(1:K, :);
0156 nnidx(:, sp:ep) = curnnidx;
0157 if to_output_dist
0158 curdists = curdists(1:K, :);
0159 dists(:, sp:ep) = curdists;
0160 end
0161
0162 clear curnnidx curdists;
0163
0164 end
0165
0166
0167 nnidx = cols_to_cells(nnidx);
0168 if nargout >= 2
0169 dists = cols_to_cells(dists);
0170 end
0171
0172
0173 function [nnidx, dists] = find_ann(X0, X, excludediag, varargin)
0174
0175
0176 opts.K = 3;
0177 opts = slparseprops(opts, varargin{:});
0178 K = getK(opts, X0);
0179 to_output_dist = (nargout >= 2);
0180
0181 if excludediag
0182 X = [];
0183 end
0184
0185
0186 if ~to_output_dist
0187 nnidx = annsearch(X0, X, K);
0188 else
0189 [nnidx, dists] = annsearch(X0, X, K);
0190 end
0191
0192
0193 nnidx = cols_to_cells(nnidx);
0194 if to_output_dist
0195 dists = cols_to_cells(dists);
0196 end
0197
0198
0199 function [nnidx, dists] = find_eps(X0, X, excludediag, varargin)
0200
0201
0202 opts.e = 1;
0203 opts.maxblk = 1e7;
0204 opts.metric = 'eucdist';
0205 opts = slparseprops(opts, varargin{:});
0206 fhmetric = get_metricfunc(opts.metric);
0207 [secs, nsecs] = getparsecs(opts, X0, X);
0208 to_output_dist = (nargout >= 2);
0209
0210
0211 n = size(X, 2);
0212 nnidx = cell(1, n);
0213 if to_output_dist
0214 dists = cell(1, n);
0215 end
0216
0217
0218
0219 for k = 1 : nsecs
0220
0221
0222 sp = secs.sinds(k); ep = secs.einds(k);
0223 curdists = compute_pwdists(X0, X, fhmetric, sp, ep, excludediag);
0224
0225
0226 is_selected = (curdists < opts.e);
0227
0228
0229 nnidx(sp:ep) = select_output_indices(is_selected);
0230 if to_output_dist
0231 dists(sp:ep) = select_output_values(curdists, is_selected);
0232 end
0233
0234 end
0235
0236
0237
0238
0239
0240 function dists = compute_pwdists(X0, X, fhmetric, sp, ep, excludediag)
0241
0242 n0 = size(X0, 2);
0243 n = size(X, 2);
0244
0245 if sp == 1 && ep == n
0246 curX = X;
0247 else
0248 curX = X(:, sp:ep);
0249 end
0250
0251
0252 dists = fhmetric(X0, curX);
0253
0254 if excludediag
0255 curn = ep - sp + 1;
0256 inds_diag = sub2ind([n0, curn], sp:ep, 1:curn);
0257 dists(inds_diag) = inf;
0258 end
0259
0260
0261 function fh = get_metricfunc(m)
0262
0263 if ischar(m)
0264 fh = @(X, Y) slmetric_pw(X, Y, m);
0265 elseif iscell(m)
0266 fh = @(X, Y) slmetric_pw(X, Y, m{:});
0267 elseif isa(m, 'function_handle')
0268 fh = m;
0269 else
0270 error('sltoolbox:invalidarg', 'The metric is specified incorrectly');
0271 end
0272
0273
0274
0275 function C = cols_to_cells(M)
0276
0277 [m, n] = size(M);
0278 C = mat2cell(M, m, ones(1, n));
0279
0280
0281 function nnidx = select_output_indices(is_selected)
0282
0283 n = size(is_selected, 2);
0284 nnidx = cell(1, n);
0285 for i = 1 : n
0286 nnidx{i} = find(is_selected(:,i));
0287 end
0288
0289 function vals = select_output_values(vals0, is_selected)
0290
0291 n = size(is_selected, 2);
0292 vals = cell(1, n);
0293 for i = 1 : n
0294 vals{i} = vals0(is_selected(:,i), i);
0295 end
0296
0297
0298 function K = getK(opts, X0)
0299
0300 K = opts.K;
0301 n0 = size(X0, 2);
0302 if K >= n0
0303 error('sltoolbox:invalidarg', ...
0304 'The specified K should be less than the number of referenced samples');
0305 end
0306
0307 function [secs, nsecs] = getparsecs(opts, X0, X)
0308
0309 n0 = size(X0, 2);
0310 ss = max(floor(opts.maxblk / n0), 1);
0311 n = size(X, 2);
0312 secs = slpartition(n, 'maxblksize', ss);
0313 nsecs = length(secs.sinds);
0314
0315
0316
0317
0318
0319
Generated on Wed 20-Sep-2006 12:43:11 by m2html © 2003
|
|