>> which kmeans % 获取函数文件路径
D:\MATLAB_R2018b_win64\toolbox\stats\stats\kmeans.m
- 设置默认参数值:internal.stats.parseArgs
- 检查输入: internal.stats.getParamVal或 strncmpi
- 下面是节选 ```matlab function varargout = kmeans(X, k, varargin) % varargin:可变输入;varargout:可变输出 if nargin > 0 X = convertStringsToChars(X); % convertStringsToChars(X) 将字符串数组X转换为字符向量或字符向量元胞数组 end
if nargin > 2 [varargin{:}] = convertStringsToChars(varargin{:}); end
if nargin < 2 error(message(‘stats:kmeans:TooFewInputs’)); end
if ~isreal(X) % 确定数组是否使用复数存储 error(message(‘stats:kmeans:ComplexData’)); end wasnan = any(isnan(X),2); % 确定哪些数组元素为 NaN hadNaNs = any(wasnan); if hadNaNs warning(message(‘stats:kmeans:MissingDataRemoved’)); X = X(~wasnan,:); end
% n points in p dimensional space [n, p] = size(X);
%% 设置默认输入值 internal.stats.parseArgs() % parseargs Parsing name-value pairs with default property easily. pnames = { ‘distance’ ‘start’ ‘replicates’ ‘emptyaction’ ‘onlinephase’ ‘options’ ‘maxiter’ ‘display’}; dflts = {‘sqeuclidean’ ‘plus’ [] ‘singleton’ ‘off’ [] [] []}; [distance,start,reps,emptyact,online,options,maxit,display] … = internal.stats.parseArgs(pnames, dflts, varargin{:});
%% 检查输入 internal.stats.getParamVal distNames = {‘sqeuclidean’,’cityblock’,’cosine’,’correlation’,’hamming’}; distance = internal.stats.getParamVal(distance,distNames,’’’Distance’’’);
%% 根据输入参数操作 switch distance case ‘cosine’ %…… case ‘correlation’ %…… case ‘hamming’ %…… end end
%% 判断 可变参数的输入 是否与 待选值列表 匹配 startNames = {‘uniform’,’sample’,’cluster’,’plus’,’kmeans++’}; %% strncmpi - 比较字符串的前 n 个字符(不区分大小写) j = find(strncmpi(start,startNames,length(start)));
%% emptyactNames = {‘error’,’drop’,’singleton’}; emptyact = internal.stats.getParamVal(emptyact,emptyactNames,’’’EmptyAction’’’);
[~,online] = internal.stats.getParamVal(online,{‘on’,’off’},’’’OnlinePhase’’’); online = (online==1);
options = statset(statset(‘kmeans’), options); display = find(strncmpi(options.Display, {‘off’,’notify’,’final’,’iter’},… length(options.Display))) - 1; maxit = options.MaxIter;
if ~(isscalar(k) && isnumeric(k) && isreal(k) && k > 0 && (round(k)==k)) error(message(‘stats:kmeans:InvalidK’)); % elseif k == 1 % this special case works automatically elseif n < k error(message(‘stats:kmeans:TooManyClusters’)); end
% Assume one replicate if isempty(reps) reps = 1; elseif ~internal.stats.isScalarInt(reps,1) error(message(‘stats:kmeans:BadReps’)); end
[useParallel, RNGscheme, poolsz] = … internal.stats.parallel.processParallelAndStreamOptions(options,true);
usePool = useParallel && poolsz>0;
%% 输出
% Extract the best solution varargout{1} = ClusterBest{5}; %idxbest = ClusterBest{5}; varargout{2} = ClusterBest{6}; %Cbest = ClusterBest{6}; varargout{3} = ClusterBest{3}; %sumDbest = ClusterBest{3}; totsumDbest = ClusterBest{1};
if nargout > 3 varargout{4} = ClusterBest{7}; %Dbest end
```