matlab索引必须为正整数或逻辑值,MATLAB编程求解湍流k-e方程时,总是遇见‘下标索引必须为正整数类型或逻辑类型’错误...

%%%%%%%%%%%%%%%参数设置%%%%%%%%%%%%%

tic

clear

clc

%1.模型参数

LD=1;H=0.04;

mu=0.01;     %动力粘度

rou=1100;    %密度

alpha=1e5;   %罚函数

alph1=1e11;

sgmk=1.0;

sgms=1.22;

Csgm1=1.44;

Csgm2=1.92;

Cmu=0.09;

%2.边界参数

ul=1;vl=0;   %左边界速度

ub=0;vb=0;   %下边界

ur=0;vr=0;   %右边界

ut=0;vt=0;   %上边界

Re=rou*ul*H/mu;   %雷诺数

l=0.07*H;         %湍流尺度

I=0.16*Re^(-1/8); %湍流强度

k=1.5*(ul*I)^2;   %入口湍动能

s=(Cmu^(3/4))*(k^1.5)/l;  %湍流耗散率

%%%%%%%%%%%%%%输入节点数据%%%%%%%%%%%

ndivlq=20;ndivwq=20;

[x,conn1,conn2,numnod]=mesh3(LD,H,ndivlq,ndivwq);

ndivlq=20;ndivwq=20;         %划背景网格

[xc,conn,numcell,numq]=mesh2(LD,H,ndivlq,ndivwq);

dmax=1.4;                    %放大系数

xspac=LD/ndivlq;             %网格的宽度

yspac=H/ndivwq;              %网格的高度

dm(1,1:numnod)=dmax*xspac*ones(1,numnod);  %x方向节点影响域大小

dm(2,1:numnod)=dmax*yspac*ones(1,numnod);  %y方向节点影响域大小

%%%%%%%%%%%%设置高斯点%%%%%%

%1.湍流场的高斯点

quado=4;                %一维方向上采用的高斯积分点的个数

[gauss]=gauss2(quado);  %函数调用:生成一维方向上的规格化的高斯点

numq2=numcell*quado^2;  %numq2为高斯点总数

gs=zeros(4,numq2);

[gs]=egauss(xc,conn,gauss,numcell);

% plot(gs(1,

smile.gif,gs(2,

smile.gif,'.b');

% hold on

% plot(x(1,

smile.gif,x(2,

smile.gif,'ro') ;

%%%%%%%%%%%%%%%%%%%%%%%%定义边界节点%%%%%%%%%%%%

ind1=0;ind2=0;ind3=0;ind4=0;

for j=1:numnod

if(x(1,j)==0.0)

ind1=ind1+1;

nl(1,ind1)=x(1,j);     %%%左边界

nl(2,ind1)=x(2,j);

end

if(x(1,j)==LD)

ind2=ind2+1;

nr(1,ind2)=x(1,j);    %%%右边界

nr(2,ind2)=x(2,j);

end

if(x(2,j)==0)

ind3=ind3+1;

nb(1,ind3)=x(1,j);    %%%下边界

nb(2,ind3)=x(2,j);

end

if(x(2,j)==H)

ind4=ind4+1;          %%%上边界

nt(1,ind4)=x(1,j);

nt(2,ind4)=x(2,j);

end

end

%%===各个边界上节点的个数===%%

lthl=length(nl);    %左边界上节点的个数

lthb=length(nb);    %下边界上节点的个数

ltht=length(nt);    %上边界上节点的个数

lthr=length(nr);    %右边界上节点的个数

%%对各边界上的元素进行排序

nl(2,

smile.gif=bubble(nl(2,

smile.gif);

nr(2,

smile.gif=bubble(nr(2,

smile.gif);

nt(1,

smile.gif=bubble(nt(1,

smile.gif);

nb(1,

smile.gif=bubble(nb(1,

smile.gif);

%这里还是要进行节点的重新排布,否则高斯点排布就会出错

%设置边界上高斯点的坐标

quado=4;

ind=0;

gauss=gauss2(quado);

for i=1

sad.giflthl-1)

ycen=(nl(2,i+1)+nl(2,i))/2;

jcob=abs((nl(2,i+1)-nl(2,i))/2);

for j=1:quado

mark(j)=ycen-gauss(1,j)*jcob;

ind=ind+1;

gsl(1,ind)=nl(1,i);

gsl(2,ind)=mark(j);

gsl(3,ind)=gauss(2,j);

gsl(4,ind)=jcob;

end

end

quado=4;

ind=0;                              %r边界上的高斯点

gauss=gauss2(quado);

for i=1

sad.giflthr-1)

ycen=(nr(2,i+1)+nr(2,i))/2;

jcob=abs((nr(2,i+1)-nr(2,i))/2);

for j=1:quado

mark(j)=ycen-gauss(1,j)*jcob;

ind=ind+1;

gsr(1,ind)=nr(1,i);

gsr(2,ind)=mark(j);

gsr(3,ind)=gauss(2,j);

gsr(4,ind)=jcob;

end

end

quado=4;

ind=0;                              %b边界上的高斯点

gauss=gauss2(quado);

for i=1

sad.giflthb-1)

ycen=(nb(1,i+1)+nb(1,i))/2;

jcob=abs((nb(1,i+1)-nb(1,i))/2);

for j=1:quado

mark(j)=ycen-gauss(1,j)*jcob;

ind=ind+1;

gsb(1,ind)=mark(j);

gsb(2,ind)=nb(2,i);

gsb(3,ind)=gauss(2,j);

gsb(4,ind)=jcob;

end

end

quado=4;

ind=0;                              %t边界上的高斯点

gauss=gauss2(quado);

for i=1

sad.gifltht-1)

ycen=(nt(1,i+1)+nt(1,i))/2;

jcob=abs((nt(1,i+1)-nt(1,i))/2);

for j=1:quado

mark(j)=ycen-gauss(1,j)*jcob;

ind=ind+1;

gst(1,ind)=mark(j);

gst(2,ind)=nt(2,i);

gst(3,ind)=gauss(2,j);

gst(4,ind)=jcob;

end

end

%%%%%%%%%%%%%%%边界积分%%%%%%%%%%%%%%%%%

%1.湍流边界积分

fks=zeros(numnod*2,1);fkspm=zeros(numnod*2,1);

%沿左边界L积分

klk=sparse(numnod,numnod);kls=sparse(numnod,numnod);

ind=0;

for gkl=gsl

ind=ind+1;

gpos=gkl(1:2);

weight=gkl(3);

jac=gkl(4);

v=domain(gpos,x,dm,numnod);

L=length(v);

en=zeros(1,L);vn=zeros(1,L);

flk=zeros(1,L);fls=zeros(1,L);

[phi,dphix,dphiy]=shape_1(gpos,dmax,x,v,dm);

for i=1:L

en(i)=v(i);vn(i)=v(i);

flk(i)=k*phi(i);

fls(i)=s*phi(i);

end

klk(en,en)=klk(en,en)+sparse((weight*jac)*(phi'*phi));

kls(en,en)=kls(en,en)+sparse((weight*jac)*(phi'*phi));

fkspm(en)=fkspm(en)+jac*weight*flk';

fkspm(en+numnod)=fkspm(en+numnod)+jac*weight*fls';

end

%沿下边界B积分

for gksb=gsb

gpos=gksb(1:2);

weight=gksb(3);

jac=gksb(4);

v=domain(gpos,x,dm,numnod);

L=length(v);

en=zeros(1,L);

fkb=zeros(1,L);fsb=zeros(1,L);

Kb=0;Sb=0;

[phi,dphix,dphiy]=shape_1(gpos,dmax,x,v,dm);

for i=1:L

en(i)=v(i);

fkb(i)=Kb*phi(i);

fsb(i)=Sb*phi(i);

end

fks(en)=fks(en)+jac*weight*fkb';

fks(en+numnod)=fks(en+numnod)+jac*weight*fsb';

end

%沿上边界T积分

for gkst=gst

gpos=gkst(1:2);

weight=gkst(3);

jac=gkst(4);

v=domain(gpos,x,dm,numnod);

L=length(v);

en=zeros(1,L);

fkt=zeros(1,L);fst=zeros(1,L);

Kt=0;St=0;

[phi,dphix,dphiy]=shape_1(gpos,dmax,x,v,dm);

for i=1:L

en(i)=v(i);

fkb(i)=Kt*phi(i);

fsb(i)=St*phi(i);

end

fks(en)=fks(en)+jac*weight*fkt';

fks(en+numnod)=fks(en+numnod)+jac*weight*fst';

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 非牛顿迭代 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 1、计算初始黏度(viscosity)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 迭代 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 1.进行初始赋值

load ('result_of.mat');   %调用相同边界条件下NS方程解速度分布结果ux,uy

kkk=ones(1,numnod);     %湍动能初始值

kks=ones(1,numnod);     %耗散率初始值

vis=ones(1,numnod);

vis_k_1=vis;

kkk_k_1=kkk;

kks_k_1=kks;

%%%%%%%%%%%%%% 主程序迭代开始 %%%%%%%%%%%%%%%%

%1.迭代初始条件

norm_vis=1;

norm_k=1;

norm_s=1;

times=0;

fprintf('  现在开始计算,请耐心等待  \n')

while ((norm_vis>1e-3||norm_vis>1e-3||norm_k>1e-3||norm_s>1e-3)&&times<1000)

%迭代赋值:将k+1时的结果赋值给k时的值

kkk_k=kkk_k_1;

kks_k=kks_k_1;

vis_k=vis_k_1;

%%%%%%%%%%%%%%%%%%%%% 对高斯点循环,组装K矩阵 %%%%%%%%%%%%%%%%%%%%%%%%%%

% 1、更新对流项子块

% !!开始前需计算温度场上节点速度,本程序速度场与温度场节点重合,所以不需重新计算,直接利用速度场上节点的速度!

%%%%%%%%%%%%%%%%%%%%%%%%%%%计算k-e方程%%%%%%%%%%%%%%%%%%

%1.计算湍流方程扩散项K矩阵

kcl=sparse(numnod,numnod);

kcs=sparse(numnod,numnod);

for ggk=gs

gpos=ggk(1:2);

weight=ggk(3);

jac=ggk(4);

vk=domain(gpos,x,dm,numnod);

Lk=length(vk);

en=zeros(1,Lk);vn=zeros(1,Lk);

[phi,dphix,dphiy]=shape_1(gpos,dmax,x,vk,dm);

for i=1:Lk

en(i)=vk(i);

end

kcl(en,en)=kcl(en,en)+sparse((vis_k(1,i)/sgmk)*(weight*jac)*(dphix'*dphix+dphiy'*dphiy));

kcs(en,en)=kcs(en,en)+sparse((vis_k(1,i)/sgmk)*(weight*jac)*(dphix'*dphix+dphiy'*dphiy));

end

%2.计算湍流方程对流项K矩阵,

%开始前需计算湍流场上节点速度,本程序速度场与湍流场节点重合,所以不需重新计算,直接利用速度场上节点的速度!

kdl=sparse(numnod,numnod);

kds=sparse(numnod,numnod);

for ggs=gs

gpos=ggs(1:2);

weight=ggs(3);

jac=ggs(4);

v=domain(gpos,x,dm,numnod);

L=length(v);

en=zeros(1,L);

[phi,dphix,dphiy]=shape_1(gpos,dmax,x,v,dm);

for i=L

en(i)=v(i);

end

kdl(en,en)=kdl(en,en)+sparse((weight*jac)*(phi*phi'*ux_k_1*dphix'+phi*phi'*uy_k_1*dphiy'));

kds(en,en)=kds(en,en)+sparse((weight*jac)*(phi*phi'*ux_k_1*dphix'+phi*phi'*uy_k_1*dphiy'));

end

%3.计算耗散项K矩阵

%开始前需计算湍流场上节点速度,本程序速度场与湍流场节点重合,所以不需重新计算,直接利用速度场上节点的速度!

krk=sqarse(numnod,numnod);

krs=sqarse(numnod,numnod);

for ggu=gs

gpos=ggu(1:2);

weight=ggu(3);

jac=ggu(4);

v=domain(gpos,x,dm,numnod);

L=length(v);

en=zeros(1,L);

[phi,dphix,dphiy]=shape_1(gpos,dmax,x,v,dm);

for i=L

en(i)=v(i);

end

krk(en,en)=krk(en,en)+sparse((weight*jac)*vis_k(1,i)*phi*(2*(dphix'*ux_k_1*dphix'*ux_k_1)+2*(dphiy'*uy_k_1*dphiy'*uy_k_1)+(dphiy'*ux_k_1*dphiy'*ux_k_1+2*dphiy'*ux_k_1*dphix'*uy_k_1+dphix'*uy_k_1*dphix'*uy_k_1)));

krs(en,en)=krs(en,en)+sparse((weight*jac)*Csgm1*yinzi_k(1,i)*vis_k(1,i)*phi*(2*(dphix'*ux_k_1*dphix'*ux_k_1)+2*(dphiy'*uy_k_1*dphiy'*uy_k_1)+(dphiy'*ux_k_1*dphiy'*ux_k_1+2*dphiy'*ux_k_1*dphix'*uy_k_1+dphix'*uy_k_1*dphix'*uy_k_1)));

end

%4.计算湍流M矩阵

Mks=sparse(numnod,numnod);

Msk=sparse(numnod,numnod);

for ggu=gs

gpos=ggu(1:2);

weight=ggu(3);

jac=ggu(4);

v=domain(gpos,x,dm,numnod);

L=length(v);

en=zeros(1,L);

[phi,dphix,dphiy]=shape_1(gpos,dmax,x,v,dm);

for i=L

en(i)=v(i);

end

Mks(en,en)=Mks(en,en)+sparse((weight*jac)*(phi'*phi));

Msk(en,en)=Msk(en,en)+sparse((weight*jac)*Csgm2*yinzi_k(1,i)*(phi'*phi));

end

%5.构建k-e总体方程

k_ks=[kdl-kcl,Mks;zeros(numnod,numnod),kds-kcs+Msk];

k_s=[krk;krs];

k_b=[klk;kls];

f_ks=fks+k_s+k_b+aplh*fkspm;

s=k_ks\f_ks;

ks=d(1:numnod*2);

for i=1:numnod

K(i)=ks(i);

E(i)=ks(i+numnod);

end

%6.更新粘度

vis_k_1=zeros(1,numnod);            % 初始化vis

yinzi_k_1=zeros(1,numnod);

for gg=gs

gpos=gg(1:2);

weight=gg(3);

jac=gg(4);

v=domain(gpos,x,dm,numnod);

L=length(v);

en=zeros(1,L);

kk=zeros(1,L);

ks=zeros(1,L);

[phi,dphix,dphiy]=shape_1(gpos,dmax,x,v,dm);

for i=1:L

en(i)=v(i);

ke=phi(i)*K(i);

kk=(phi(i)'*phi(i))*(K(i))^2;

ks=(phi(i))*E(i);

end

vis_k_1(en)=vis_k_1(en)+(kk/ks);

yinzi_k_1(en)=yinzi_k_1(en)+(ks/ke);

end

if norm(kkk_k_1-kkk_k)<1e-3

norm_kkk=0;

else

norm_kkk=norm(kkk_k_1-kkk_k)/norm(kkk_k);

end

if norm(kks_k_1-kks_k)<1e-3

norm_kks=0;

else

norm_kks=norm(kks_k_1-kks_k)/norm(kks_k);

end

if norm(vis_k_1-vis_k)<1e-3

norm_vis=0;

else

norm_vis=norm(vis_k_1-vis_k)/norm(vis_k);

end

if norm(yinzi_k_1-yinzi_k)<1e-3

norm_yinzi=0;

else

norm_yinzi=norm(yinzi_k_1-yinzi_k)/norm(yinzi_k);

end

clear k ku11 ku12 ku21 ku22 kp11 kp12 kp21 kp22

% 7.输出迭代结果

times=times+1;

fprintf('time= %d  && norm_kkk= %6.9f && norm_kks= %6.9f && norm_vis= %6.9f && norm_yinzi= %6.9f \n',times,norm_kkk,norm_kks,norm_vis,norm_yinzi)

end

前面的NS方程检查过没有问题,但是在解k-e方程的时候,在kdl矩阵那出现了“下标索引必须为正整数类型或逻辑类型”错误,我觉得是调用ux-k-1速度错了,不知道是不是,求大神解惑?

后面应该还有很多问题,先把这个给解决再说

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
function [idx, C, sumD, D] = kmeans(X, k, varargin) % varargin:实际输入参量 if nargin 1 % 大于1刚至少有一种距离 error(sprintf('Ambiguous ''distance'' parameter value: %s.', distance)); elseif isempty(i) % 如果是空的,则表明没有合适的距离 error(sprintf('Unknown ''distance'' parameter value: %s.', distance)); end % 针对不同的距离,处理不同 distance = distNames{i}; switch distance case 'cityblock' % sort 列元素按升序排列,Xord中存的是元素在原始矩阵中的列中对应的大小位置 [Xsort,Xord] = sort(X,1); case 'cosine' % 余弦 % 计算每一行的和的平方根 Xnorm = sqrt(sum(X.^2, 2)); if any(min(Xnorm) <= eps * max(Xnorm)) error(['Some points have small relative magnitudes, making them ', ... 'effectively zero.\nEither remove those points, or choose a ', ... 'distance other than ''cosine''.'], []); end % 标量化 Xnorm(:,ones(1,p))得到n*p的矩阵 X = X ./ Xnorm(:,ones(1,p)); case 'correlation' % 线性化 X = X - repmat(mean(X,2),1,p); % 计算每一行的和的平方根 Xnorm = sqrt(sum(X.^2, 2)); if any(min(Xnorm) 1 error(sprintf('Ambiguous ''start'' parameter value: %s.', start)); elseif isempty(i) error(sprintf('Unknown ''start'' parameter value: %s.', start)); elseif isempty(k) error('You must specify the number of clusters, K.'); end start = startNames{i}; % strcmp比较两个字符串 uniform是在X中随机选择K个点 if strcmp(start, 'uniform') if strcmp(distance, 'hamming') error('Hamming distance cannot be initialized with uniform random values.'); end % 标量化后的X Xmins = min(X,1); Xmaxs = max(X,1); end elseif isnumeric(start) % 判断输入是否是一个数 这里的start是一个K*P的矩阵,表示初始聚类中心 CC = start; % CC表示初始聚类中心 start = 'numeric'; if isempty(k) k = size(CC,1); elseif k ~= size(CC,1); error('The ''start'' matrix must have K rows.'); elseif size(CC,2) ~= p error('The ''start'' matrix must have the same number of columns as X.'); end if isempty(reps) reps = size(CC,3); elseif reps ~= size(CC,3); error('The third dimension of the ''start'' array must match the ''replicates'' parameter value.'); end % Need to center explicit starting points for 'correlation'. % 线性距离需要指定具体的开始点 % (Re)normalization for 'cosine'/'correlation' is done at each % iteration.每一次迭代进行“余弦和线性”距离正规化 % 判断是否相等 if isequal(distance, 'correlation') % repmat复制矩阵1*P*1 线性化 CC = CC - repmat(mean(CC,2),[1,p,1]); end else error('The ''start'' parameter value must be a string or a numeric matrix or array.'); end % ------------------------------------------------------------------ % 如果一个聚类丢失了所有成员,这个进程将被调用 if ischar(emptyact) emptyactNames = {'error','drop','singleton'}; i = strmatch(lower(emptyact), emptyactNames); if length(i) > 1 error(sprintf('Ambiguous ''emptyaction'' parameter value: %s.', emptyact)); elseif isempty(i) error(sprintf('Unknown ''emptyaction'' parameter value: %s.', emptyact)); end emptyact = emptyactNames{i}; else error('The ''emptyaction'' parameter value must be a string.'); end % ------------------------------------------------------------------ % 控制输出的显示示信息 if ischar(display) % strvcat 垂直连接字符串 i = strmatch(lower(display), strvcat('off','notify','final','iter')); if length(i) > 1 error(sprintf('Ambiguous ''display'' parameter value: %s.', display)); elseif isempty(i) error(sprintf('Unknown ''display'' parameter value: %s.', display)); end display = i-1; else error('The ''display'' parameter value must be a string.'); end % ------------------------------------------------------------------ % 输入参数K的控制 if k == 1 error('The number of clusters must be greater than 1.'); elseif n 2 % 'iter',\t 表示向后空出8个字符 disp(sprintf(' iter\t phase\t num\t sum')); end % ------------------------------------------------------------------ % Begin phase one: batch reassignments 第一队段:分批赋值 converged = false; iter = 0; while true % Compute the distance from every point to each cluster centroid % 计算每一个点到每一个聚类中心的距离,D中存放的是N*K个数值 D(:,changed) = distfun(X, C(changed,:), distance, iter); % Compute the total sum of distances for the current configuration. % Can't do it first time through, there's no configuration yet. % 计算当前配置的总距离,但第一次不能执行,因为还没有配置 if iter > 0 totsumD = sum(D((idx-1)*n + (1:n)')); % Test for a cycle: if objective is not decreased, back out % the last step and move on to the single update phase % 循环测试:如果目标没有减少,退出到最后一步,移动到第二阶段 % prevtotsumD表示前一次的总距离,如果前一次的距离比当前的小,则聚类为上一次的,即不发生变化 if prevtotsumD 2 % 'iter' disp(sprintf(dispfmt,iter,1,length(moved),totsumD)); end if iter >= maxit, % break(2) break; % 跳出while end end % Determine closest cluster for each point and reassign points to clusters % 决定每一个点的最近分簇,重新分配点到各个簇 previdx = idx; % 大小为n*1 % totsumD 被初始化为无穷大,这里表示总距离 prevtotsumD = totsumD; % 返回每一行中最小的元素,d的大小为n*1,nidx为最小元素在行中的位置,其大小为n*1,D为n*p [d, nidx] = min(D, [], 2); if iter == 0 % iter==0,表示第一次迭代 % Every point moved, every cluster will need an update % 每一个点需要移动,每一个簇更新 moved = 1:n; idx = nidx; changed = 1:k; else % Determine which points moved 决定哪一个点移动 % 找到上一次和当前最小元素不同的位置 moved = find(nidx ~= previdx); if length(moved) > 0 % Resolve ties in favor of not moving % 重新分配而不是移动 括号中是一个逻辑运算 确定需要移动点的位置 moved = moved(D((previdx(moved)-1)*n + moved) > d(moved)); end % 如果没有不同的,即当前的是最小元素,跳出循环,得到的元素已经是各行的最小值 if length(moved) == 0 % break(3) break; end idx(moved) = nidx(moved); % Find clusters that gained or lost members 找到获得的或者丢失的成员的分簇 % 得到idx(moved)和previdx(moved)中不重复出现的所有元素,并按升序排列 changed = unique([idx(moved); previdx(moved)])'; end % Calculate the new cluster centroids and counts. 计算新的分簇中心和计数 % C(changed,:)表示新的聚类中心,m(changed)表示聚类标号在idx中出现的次数 % sort 列元素按升序排列,Xsort存放对的元素,Xord中存的是元素在原始矩阵中的列中对应的大小位置 [C(changed,:), m(changed)] = gcentroids(X, idx, changed, distance, Xsort, Xord); iter = iter + 1; % Deal with clusters that have just lost all their members % 处理丢失所有成员的分簇,empties表示丢失元素的聚类标号 不用考虑 empties = changed(m(changed) == 0); if ~isempty(empties) switch emptyact case 'error' % 默认值,一般情况下不会出现 error(sprintf('Empty cluster created at iteration %d.',iter)); case 'drop' % Remove the empty cluster from any further processing % 移走空的聚类 D(:,empties) = NaN; changed = changed(m(changed) > 0); if display > 0 warning(sprintf('Empty cluster created at iteration %d.',iter)); end case 'singleton' if display > 0 warning(sprintf('Empty cluster created at iteration %d.',iter)); end for i = empties % Find the point furthest away from its current cluster. % Take that point out of its cluster and use it to create % a new singleton cluster to replace the empty one. % 找到离聚类中心最远距离的点,把该点从它的聚类中移走,用它来创建一个新的聚类,来代替空的聚类 % 得到列的最大元素(dlarge),以及该元素在列中的标号(lonely) [dlarge, lonely] = max(d); from = idx(lonely); % taking from this cluster 从当前聚类移走 C(i,:) = X(lonely,:); m(i) = 1; idx(lonely) = i; d(lonely) = 0; % Update clusters from which points are taken % 更新那些点被移走的聚类 [C(from,:), m(from)] = gcentroids(X, idx, from, distance, Xsort, Xord); changed = unique([changed from]); end end end end % phase one % ------------------------------------------------------------------ % Initialize some cluster information prior to phase two % 为第二阶段初始化一些先验聚类信息 针对特定的距离,默认的是欧氏距离 switch distance case 'cityblock' Xmid = zeros([k,p,2]); for i = 1:k if m(i) > 0 % Separate out sorted coords for points in i'th cluster, % and save values above and below median, component-wise % 分解出第i个聚类中挑选的点的坐标,保存它的上,下中位数 % reshape把矩阵分解为要求的行列数m*p % sort 列元素按升序排列,Xord中存的是元素在原始矩阵中的列中对应的大小位置 Xsorted = reshape(Xsort(idx(Xord)==i), m(i), p); % floor取比值小或者等于的最近的值 nn = floor(.5*m(i)); if mod(m(i),2) == 0 Xmid(i,:,1:2) = Xsorted([nn, nn+1],:)'; elseif m(i) > 1 Xmid(i,:,1:2) = Xsorted([nn, nn+2],:)'; else Xmid(i,:,1:2) = Xsorted([1, 1],:)'; end end end case 'hamming' Xsum = zeros(k,p); for i = 1:k if m(i) > 0 % Sum coords for points in i'th cluster, component-wise % 对基于分量对第i个聚类的坐标点求和 Xsum(i,:) = sum(X(idx==i,:), 1); end end end % ------------------------------------------------------------------ % Begin phase two: single reassignments 第二阶段:单独赋值 % m中保存的是每一个聚类的个数,元素和为n % find(m' > 0)得到m'中大于0的元素的位置(索引) % 实际情况(默认情况下)changed=1:k changed = find(m' > 0); lastmoved = 0; nummoved = 0; iter1 = iter; while iter < maxit % Calculate distances to each cluster from each point, and the % potential change in total sum of errors for adding or removing % each point from each cluster. Clusters that have not changed % membership need not be updated. % 计算从每一个点到每一个聚类的距离,潜在由于总距离发生变化移除或添加引起的错误。 % 那些成员没有改变的聚类不需要更新。 % % Singleton clusters are a special case for the sum of dists % calculation. Removing their only point is never best, so the % reassignment criterion had better guarantee that a singleton % point will stay in its own cluster. Happily, we get % Del(i,idx(i)) == 0 automatically for them. % 单独聚类在计算距离是一个特殊情况,仅仅移除点不是最好的方法,因此重新赋值准则能够保证一个 % 单独的点能够留在它的聚类中,可喜的是,自动有Del(i,idx(i)) == 0。 switch distance case 'sqeuclidean' for i = changed % idx存放的距离矩阵D中每一行的最小元素所处的列,也即位置 mbrs = (idx == i); sgn = 1 - 2*mbrs; % -1 for members, 1 for nonmembers % 表示只有一个聚类 if m(i) == 1 % prevent divide-by-zero for singleton mbrs 防止单个成员做0处理 sgn(mbrs) = 0; end Del(:,i) = (m(i) ./ (m(i) + sgn)) .* sum((X - C(repmat(i,n,1),:)).^2, 2); end case 'cityblock' for i = changed if mod(m(i),2) == 0 % this will never catch singleton clusters ldist = Xmid(repmat(i,n,1),:,1) - X; rdist = X - Xmid(repmat(i,n,1),:,2); mbrs = (idx == i); sgn = repmat(1-2*mbrs, 1, p); % -1 for members, 1 for nonmembers Del(:,i) = sum(max(0, max(sgn.*rdist, sgn.*ldist)), 2); else Del(:,i) = sum(abs(X - C(repmat(i,n,1),:)), 2); end end case {'cosine','correlation'} % The points are normalized, centroids are not, so normalize them normC(changed) = sqrt(sum(C(changed,:).^2, 2)); if any(normC 0 % Resolve ties in favor of not moving % 重新分配而不是移动 确定移动的位置 moved = moved(Del((previdx(moved)-1)*n + moved) > minDel(moved)); end if length(moved) == 0 % Count an iteration if phase 2 did nothing at all, or if we're % in the middle of a pass through all the points if (iter - iter1) == 0 | nummoved > 0 iter = iter + 1; if display > 2 % 'iter' disp(sprintf(dispfmt,iter,2,nummoved,totsumD)); end end converged = true; break; end % Pick the next move in cyclic order moved = mod(min(mod(moved - lastmoved - 1, n) + lastmoved), n) + 1; % If we've gone once through all the points, that's an iteration if moved 2 % 'iter' disp(sprintf(dispfmt,iter,2,nummoved,totsumD)); end if iter >= maxit, break; end nummoved = 0; end nummoved = nummoved + 1; lastmoved = moved; oidx = idx(moved); nidx = nidx(moved); totsumD = totsumD + Del(moved,nidx) - Del(moved,oidx); % Update the cluster index vector, and rhe old and new cluster % counts and centroids idx(moved) = nidx; m(nidx) = m(nidx) + 1; m(oidx) = m(oidx) - 1; switch distance case 'sqeuclidean' C(nidx,:) = C(nidx,:) + (X(moved,:) - C(nidx,:)) / m(nidx); C(oidx,:) = C(oidx,:) - (X(moved,:) - C(oidx,:)) / m(oidx); case 'cityblock' for i = [oidx nidx] % Separate out sorted coords for points in each cluster. % New centroid is the coord median, save values above and % below median. All done component-wise. Xsorted = reshape(Xsort(idx(Xord)==i), m(i), p); nn = floor(.5*m(i)); if mod(m(i),2) == 0 C(i,:) = .5 * (Xsorted(nn,:) + Xsorted(nn+1,:)); Xmid(i,:,1:2) = Xsorted([nn, nn+1],:)'; else C(i,:) = Xsorted(nn+1,:); if m(i) > 1 Xmid(i,:,1:2) = Xsorted([nn, nn+2],:)'; else Xmid(i,:,1:2) = Xsorted([1, 1],:)'; end end end case {'cosine','correlation'} C(nidx,:) = C(nidx,:) + (X(moved,:) - C(nidx,:)) / m(nidx); C(oidx,:) = C(oidx,:) - (X(moved,:) - C(oidx,:)) / m(oidx); case 'hamming' % Update summed coords for points in each cluster. New % centroid is the coord median. All done component-wise. Xsum(nidx,:) = Xsum(nidx,:) + X(moved,:); Xsum(oidx,:) = Xsum(oidx,:) - X(moved,:); C(nidx,:) = .5*sign(2*Xsum(nidx,:) - m(nidx)) + .5; C(oidx,:) = .5*sign(2*Xsum(oidx,:) - m(oidx)) + .5; end changed = sort([oidx nidx]); end % phase two % ------------------------------------------------------------------ if (~converged) & (display > 0) warning(sprintf('Failed to converge in %d iterations.', maxit)); end % Calculate cluster-wise sums of distances nonempties = find(m(:)'>0); D(:,nonempties) = distfun(X, C(nonempties,:), distance, iter); d = D((idx-1)*n + (1:n)'); sumD = zeros(k,1); for i = 1:k sumD(i) = sum(d(idx == i)); end if display > 1 % 'final' or 'iter' disp(sprintf('%d iterations, total sum of distances = %g',iter,totsumD)); end % Save the best solution so far if totsumD 3 Dbest = D; end end end % Return the best solution
### 回答1: 要解决 Matlab 数组索引必须正整数逻辑值的问题,可以采取以下几种方法: 1. 使用 ceil 函数:如果索引为小数,可以使用 ceil 函数将其向上取整为正整数。 2. 使用 floor 函数:如果索引为小数,可以使用 floor 函数将其向下取整为正整数。 3. 使用 round 函数:如果索引为小数,可以使用 round 函数将其四舍五入为最接近的正整数。 4. 使用整数索引:如果索引为浮点数,可以将其强制转换为整数,例如:idx = floor(idx)。 逻辑索引可以用于指定数组中需要选择的元素。此类索引是一个逻辑数组,其中每个元素是 true 或 false,表示该位置上的元素是否需要选择。 ### 回答2: 在MATLAB中,数组索引必须正整数逻辑值,并且不能为负数或小数。如果要解决这个问题,可以考虑以下几种方法: 1. 转换为整数:可以使用MATLAB内置的函数来将小数或负数转换为整数。例如,可以使用round()函数将小数四舍五入为最接近的整数,或者使用ceil()函数向上取整,或者使用floor()函数向下取整。 2. 修改索引值:如果数组索引是负数,可以将其转换为相应的正数。例如,可以将负数索引加上数组长度,以得到相应的正数索引。同样,如果索引是小数,可以将其转换为最近的整数。 3. 使用逻辑索引:如果已知数组的逻辑关系,可以使用逻辑索引来实现数组索引逻辑索引是一个逻辑值组成的数组,其中逻辑值为true表示对应位置的元素满足条件,可以被选中。可以使用逻辑运算符(如>、<、==等)来创建逻辑索引,并将其用于数组索引操作。 4. 数据预处理:在进行数组索引操作之前,可以对数据进行预处理,将其转换为正整数逻辑值。这可以通过使用函数库中的函数(如unique())或编写自定义的数据处理函数来实现。 总结起来,解决MATLAB数组索引必须正整数逻辑值的问题,主要是通过转换索引值、使用逻辑索引、数据预处理等方法来实现。不同的情况可能需要采用不同的方法,具体应根据具体问题进行选择。 ### 回答3: 在MATLAB中,数组的索引必须正整数逻辑值。当我们尝试使用非正整数或其他类型的值作为索引MATLAB会抛出错误。解决这个问题的方法主要有以下几种: 1. 检查索引是否为正整数:首先需要确保索引正整数。可以使用MATLAB内置的函数`isinteger`和`ispositive`对索引进行检查。如果发现索引不是正整数,则需要对索引进行修改,确保其是正整数。 2. 使用逻辑索引:如果不能用正整数索引数组,可以尝试使用逻辑索引逻辑索引是使用逻辑运算符(如AND、OR)或逻辑数组来选择特定数据的方法。只需要将逻辑索引数组作为索引传递给数组即可。 3. 使用函数`find`:`find`函数可以通过给定逻辑表达式来寻找数组中满足条件的元素的索引。例如,可以使用`find`函数找到数组中所有大于某个值的元素的索引。 4. 使用`sub2ind`函数:如果我们有一个矩阵和一组以向量形式给出的行、列索引,则可以使用`sub2ind`函数将这些索引转换为线性索引。然后,可以使用线性索引访问和修改数组。 总之,我们可以通过确保索引正整数逻辑值,使用逻辑索引、`find`函数或`sub2ind`函数等方法来解决MATLAB数组索引必须正整数逻辑值的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值