0001 function m = sldistmean(X1, X2, 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 if nargin < 3
0047 raise_lackinput('sldistmean', 3);
0048 end
0049
0050 if ~isnumeric(X1) || ~isnumeric(X2) || ndims(X1) ~= 2 || ndims(X2) ~= 2
0051 error('sltoolbox:invalidarg', ...
0052 'X1 and X2 should be numeric 2D matrices');
0053 end
0054
0055 if ischar(varargin{1})
0056 mtype = varargin{1};
0057 if nargin == 3
0058 params = {};
0059 else
0060 params = varargin(2:end);
0061 end
0062 w1 = [];
0063 w2 = [];
0064 else
0065 w1 = varargin{1};
0066 w2 = varargin{2};
0067
0068 n1 = size(X1, 2);
0069 n2 = size(X2, 2);
0070 if ~isequal(size(w1), [1 n1]) || ~isequal(size(w2), [1, n2])
0071 error('sltoolbox:invalidarg', ...
0072 'The size of w1 or w2 is illegal');
0073 end
0074
0075 mtype = varargin{3};
0076 if nargin == 5
0077 params = {};
0078 else
0079 params = varargin(4:end);
0080 end
0081 end
0082
0083
0084
0085
0086 switch mtype
0087 case {'sqdist', 'wsqdist'}
0088 d = check_samedim(X1, X2);
0089 if strcmp(mtype, 'sqdist')
0090 wc = [];
0091 else
0092 check_paramsnum(mtype, params, 1);
0093 wc = params{1};
0094 if ~isequal(size(wc), [d, 1])
0095 error('sltoolbox:sizmismatch', ...
0096 'The weights on components should be d x 1 vector');
0097 end
0098 end
0099
0100 vm1 = slmean(X1, w1, true);
0101 vm2 = slmean(X2, w2, true);
0102 vs1 = compute_vars(X1, vm1, w1);
0103 vs2 = compute_vars(X2, vm2, w2);
0104 vmd = vm1 - vm2;
0105 vsm = vmd .* vmd;
0106
0107 if isempty(wc)
0108 m = sum(vsm + vs1 + vs2);
0109 else
0110 m = sum((vsm + vs1 + vs2) .* wc);
0111 end
0112
0113 case 'quaddiff'
0114 d = check_samedim(X1, X2);
0115 check_paramsnum(mtype, params, 1);
0116 Q = params{1};
0117 if ~isequal(size(Q), [d d])
0118 error('sltoolbox:sizmismatch', ...
0119 'The Q matrix should be a d x d square matrix');
0120 end
0121
0122 vm1 = slmean(X1, w1, true);
0123 vm2 = slmean(X2, w2, true);
0124 C1 = slcov(X1, w1, vm1, true);
0125 C2 = slcov(X2, w2, vm2, true);
0126 vmd = vm1 - vm2;
0127
0128 m = vmd' * Q * vmd + sum(sum(Q .* (C1 + C2)));
0129
0130 otherwise
0131 error('sltoolbox:invalidarg', ...
0132 'Invalid metric type: %s', mtype);
0133 end
0134
0135
0136
0137
0138 function d = check_samedim(X1, X2)
0139
0140 d = size(X1, 1);
0141 if d ~= size(X2, 1)
0142 error('sltoolbox:sizmismatch', ...
0143 'X1 and X2 have different sample dimensions');
0144 end
0145
0146 function check_paramsnum(name, params, n)
0147
0148 if length(params) ~= n
0149 error('sltoolbox:invalidarg', ...
0150 'For metric %s, it has %d extra parameters.', name, n);
0151 end
0152
0153 function vs = compute_vars(X, vmean, w)
0154
0155 DX = sladdvec(X, -vmean);
0156 vs = slmean(DX .* DX, w);
0157
0158
0159
0160
0161
0162
0163
0164