0001 function [Y, GM] = sllocaltancoords(LM, LP, X, G, ga)
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 if nargin < 4
0051 raise_lackinput('sllocaltancoords', 4);
0052 end
0053
0054 [d, m] = size(LM);
0055 [dP, dl, m2] = size(LP);
0056 [dX, n] = size(X);
0057
0058 if d ~= dP || d ~= dX
0059 error('sltoolbox:sizmismatch', ...
0060 'The sample dimensions are inconsistent among LM, LP and X');
0061 end
0062 if m~= m2
0063 error('sltoolbox:sizmismatch', ...
0064 'The space numbers in LM and LP are inconsistent');
0065 end
0066
0067 gi = slgraphinfo(G);
0068
0069 if nargin < 5
0070 ga = 'N';
0071 end
0072 switch ga
0073 case 'N'
0074 if ~isequal([gi.n, gi.nt], [m, n])
0075 error('sltoolbox:sizmismatch', ...
0076 'The size of the graph does not match the samples and models');
0077 end
0078 case 'T'
0079 if ~isequal([gi.n, gi.nt], [n, m])
0080 error('sltoolbox:sizmismatch', ...
0081 'The size of the graph does not match the samples and models');
0082 end
0083 otherwise
0084 error('sltoolbox:invalidarg', ...
0085 'Invalid graph arrangement: %s', ga);
0086 end
0087
0088
0089
0090
0091
0092 if ~strcmp(gi.form, 'adjmat')
0093 G = sladjmat(G, 'valtype', 'logical', 'sparse', true);
0094 end
0095
0096
0097 ny = nnz(G);
0098 Y = zeros(dl, ny);
0099 GM = spalloc(gi.n, gi.nt, ny);
0100
0101
0102 cp = 0;
0103 switch ga
0104 case 'N'
0105 for k = 1 : m
0106 vm = LM(:,k);
0107 P = LP(:,:,k);
0108 ci = find(G(k,:));
0109 curX = X(:, ci);
0110 cn = length(ci);
0111 curY = P' * sladdvec(curX, -vm, 1);
0112 Y(:, cp+1:cp+cn) = curY;
0113 GM(k, ci) = cp+1:cp+cn;
0114 cp = cp + cn;
0115 end
0116 case 'T'
0117 for k = 1 : m
0118 vm = LM(:,k);
0119 P = LP(:,:,k);
0120 ci = find(G(:,k));
0121 curX = X(:, ci);
0122 cn = length(ci);
0123 curY = P' * sladdvec(curX, -vm, 1);
0124 Y(:, cp+1:cp+cn) = curY;
0125 GM(ci, k) = (cp+1:cp+cn)';
0126 cp = cp + cn;
0127 end
0128 end
0129
0130
0131