| Description of slnbreconweights |
slnbreconweights
PURPOSE 
SLNBRECONWEIGHTS Solve the optimal reconstruction weights on given neighbors
SYNOPSIS 
function WG = slnbreconweights(X0, X, G, varargin)
DESCRIPTION 
CROSS-REFERENCE INFORMATION 
This function calls:
- sladjmat SLADJMAT Constructs the adjacency matrix representation of a graph
- slgraphinfo SLGRAPHINFO Extracts basic information of a given graph representation
- raise_lackinput RAISE_LACKINPUT Raises an error indicating lack of input argument
- slparseprops SLPARSEPROPS Parses input parameters
This function is called by:
- sllle SLLLE Performs Locally Linear Embedding
SUBFUNCTIONS 
- function c = parse_constraints(cs)
- function w = internal_wsolver_unc(X, y, delta2)
- function w = internal_wsolver_s1(X, y, delta2)
- function w = internal_wsolver_nonneg(X, y, delta, optimopts)
- function w = internal_wsolver_nonneg_s1(X, y, delta, optimopts)
- function [G, Xty, K] = compute_G_Xty(X, y, delta2)
- function [Xa, ya, K] = augformulate(X, y, delta)
SOURCE CODE 
0001 function WG = slnbreconweights(X0, X, G, 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 if nargin < 3
0079 raise_lackinput('slnbreconweights', 3);
0080 end
0081
0082 if ~isnumeric(X0) || ndims(X0) ~= 2
0083 error('sltoolbox:invalidarg', ...
0084 'X should be a 2D numeric matrix');
0085 end
0086 [d, n0] = size(X0);
0087
0088
0089 if isempty(X)
0090 X = X0;
0091 else
0092 if ~isnumeric(X) || ndims(X) ~= 2
0093 error('sltoolbox:invalidarg', ...
0094 'X0 should be a 2D numeric matrix');
0095 end
0096 if size(X, 1) ~= d
0097 error('sltoolbox:sizmismatch', ...
0098 'The sample dimension in X is not the same as that in X0');
0099 end
0100 end
0101 n = size(X, 2);
0102
0103 gi = slgraphinfo(G);
0104 if gi.n ~= n0 || gi.nt ~= n
0105 error('sltoolbox:sizmismatch', ...
0106 'The size of the graph is not consisitent with the sample set');
0107 end
0108
0109 opts.constraint = 's1';
0110 opts.delta = 0.1;
0111 opts.solver = [];
0112 opts.thres = 1e-8;
0113 opts = slparseprops(opts, varargin{:});
0114
0115 thres = opts.thres;
0116
0117
0118
0119
0120 if ~strcmp(gi.form, 'adjmat')
0121 G = sladjmat(G, 'sparse', true, 'valtype', 'logical');
0122 end
0123
0124
0125 if isempty(opts.solver)
0126
0127
0128 cs = opts.constraint;
0129 if ~isempty(cs)
0130 if ~iscell(cs)
0131 cs = {cs};
0132 end
0133 constraint = parse_constraints(cs);
0134 else
0135 constraint = parse_constraints({});
0136 end
0137
0138
0139 if ~constraint.nonneg
0140 delta2 = opts.delta^2;
0141 if ~constraint.s1
0142 wsolver = @(X, y) internal_wsolver_unc(X, y, delta2);
0143 else
0144 wsolver = @(X, y) internal_wsolver_s1(X, y, delta2);
0145 end
0146 else
0147 optimopts = optimset('Display', 'off', 'LargeScale', 'off');
0148 if ~constraint.s1
0149 wsolver = @(X, y) internal_wsolver_nonneg(X, y, opts.delta, optimopts);
0150 else
0151 wsolver = @(X, y) internal_wsolver_nonneg_s1(X, y, opts.delta, optimopts);
0152 end
0153 end
0154
0155 else
0156 if ~isa(opts.solver, 'function_handle')
0157 error('The weight solver should be a function handle');
0158 end
0159 wsolver = opts.solver;
0160 end
0161
0162
0163
0164
0165
0166 if issparse(G)
0167 WG = spalloc(n0, n, nnz(G));
0168 else
0169 WG = zeros(n0, n);
0170 end
0171
0172
0173 for i = 1 : n
0174 nbinds = find(G(:,i));
0175 if ~isempty(nbinds)
0176 Xnb = X0(:, nbinds);
0177 y = X(:,i);
0178 w = wsolver(Xnb, y);
0179 if thres > 0
0180 absw = abs(w);
0181 curthres = thres * sum(absw) / length(w);
0182 w(absw < curthres) = 0;
0183 end
0184 WG(nbinds, i) = w;
0185 end
0186 end
0187
0188
0189
0190
0191 function c = parse_constraints(cs)
0192
0193 ncs = length(cs);
0194
0195 c = struct('nonneg', false, 's1', false);
0196
0197 for i = 1 : ncs
0198 cname = cs{i};
0199 if ~ischar(cname)
0200 error('sltoolbox:invalidarg', ...
0201 'The constraint should be given in char string');
0202 end
0203 switch cname
0204 case 'nonneg'
0205 c.nonneg = true;
0206 case 's1'
0207 c.s1 = true;
0208 otherwise
0209 error('sltoolbox:invalidarg', ...
0210 'Invalid constraint name for weight solving: %s', cname);
0211 end
0212 end
0213
0214
0215
0216
0217
0218
0219 function w = internal_wsolver_unc(X, y, delta2)
0220
0221 [G, Xty] = compute_G_Xty(X, y, delta2);
0222 w = G \ Xty;
0223
0224
0225 function w = internal_wsolver_s1(X, y, delta2)
0226
0227 [G, Xty, K] = compute_G_Xty(X, y, delta2);
0228 wu = G \ [Xty, ones(K, 1)];
0229
0230 w = wu(:,1);
0231 u = wu(:,2);
0232 lambda = (1 - sum(w)) / sum(u);
0233 w = w + lambda * u;
0234
0235
0236 function w = internal_wsolver_nonneg(X, y, delta, optimopts)
0237
0238 [Xa, ya, K] = augformulate(X, y, delta);
0239 if K <= 20
0240 w = lsqnonneg(Xa, ya, [], optimopts);
0241 else
0242 lb = zeros(K, 1);
0243 w = lsqlin(Xa, ya, [], [], [], [], lb, [], [], optimopts);
0244 end
0245
0246
0247 function w = internal_wsolver_nonneg_s1(X, y, delta, optimopts)
0248
0249 [Xa, ya, K] = augformulate(X, y, delta);
0250
0251 Aeq = ones(1, K);
0252 beq = 1;
0253 lb = zeros(K, 1);
0254 w = lsqlin(Xa, ya, [], [], Aeq, beq, lb, [], [], optimopts);
0255
0256
0257
0258
0259 function [G, Xty, K] = compute_G_Xty(X, y, delta2)
0260
0261
0262 K = size(X, 2);
0263 Xt = X';
0264 G = Xt * X;
0265 Xty = Xt * y;
0266
0267
0268 if delta2 > 0
0269 diaginds = (1:K)*(K+1) - K;
0270 rv = delta2 * sum(G(diaginds)) / K;
0271 G(diaginds) = G(diaginds) + rv;
0272 end
0273
0274 function [Xa, ya, K] = augformulate(X, y, delta)
0275
0276 K = size(X, 2);
0277 if delta ~= 0
0278 Xa = [X; delta * eye(K)];
0279 ya = [y; zeros(K, 1)];
0280 else
0281 Xa = X;
0282 ya = y;
0283 end
0284
Generated on Wed 20-Sep-2006 12:43:11 by m2html © 2003
|
|