다음 코드는 데이터가 1x50 array
으로 전달 될 때 작동합니다. (실제로 데이터는 다른 여러 매개 변수도 전달하는 구조체입니다). 1x50
경우 4x1
매개 변수 배열이 각 i에 대해 리턴됩니다 (de.nP
의 값은 600 임).셀 배열 또는 다중 첨자 배열?
그러나 데이터 행렬이 d
날짜가되도록 dx50
행렬을 전달할 수 있도록 변경하고 싶습니다. 그러면 각 i에 대해 4xd
배열이 반환됩니다.
제 질문은 셀 배열이나 3D 배열을 사용하여 값을 저장해야합니까? 두 가지 방법 모두 작업을 수행 할 수 있다고 생각하십니까? 나는 P1
가 2x1
배열입니다
Params=vertcat(betas,P1);
를 사용해야합니다 더 코드로가는
for i=1:de.nP
betas(:,i)=NSS_betas(P1(:,i),data);
end
. 따라서 각 날짜 (i)에 대해 P (1)의 내용을 해당 날짜의 모든 베타에 연결해야합니다.
이것은 cellarray 또는 3D 배열 사용 여부에 영향을 줍니까?
저는 cellarray가 벡터화 된 코드에 더 적합하다고 생각하지만 가능한 한 많이 사용하려고합니다. 그러나 3D 배열은 vertcat
과 같은 기능을 사용하는 것이 더 쉬울 수 있습니까?
여기에 전체 코드
mats=[1:50];
mats2=[2 5 10 30];
betaTRUE=[5 -2 5 -5 1 3; 4 -3 6 -1 2 4];
for i=1:size(betaTRUE,1)
yM(i,:)=NSS(betaTRUE(i,:),mats);
y2(i,:)=NSS(betaTRUE(i,:),mats2);
end
dataList=struct('yM',yM,'mats',mats,'model',@NSS,'mats2',mats2,'y2',y2);
de=struct('min',[0; 2.5],'max', [2.5;5],'d',2,'nP',200,'nG',300,'ww',0.1,'F',0.5,'CR',0.99,'R',0,'oneElementfromPm',1);
beta=DElambdaVec(de,dataList,@OF);
function [output]=DElambdaVec(de,data,OF)
P1=zeros(de.d,de.nP);
Pu=zeros(de.d,de.nP);
for i=1:de.d
P1(i,:)=de.min(i,1)+(de.max(i,1)-de.min(i,1))*rand(de.nP,1);
end
P1(:,1:de.d)=diag(de.max);
P1(:,de.d+1:2*de.d)=diag(de.min);
for i=1:de.nP
betas(:,i)=NSS_betas(P1(:,i),data);
end
Params=vertcat(betas,P1);
Fbv=NaN(de.nG,1);
Fbest=realmax;
F=zeros(de.nP,1);
P=zeros(de.nP,1);
for i=1:de.nP
F(i)=OF(Params(:,i)',data);
P(i)=pen(P1(:,i),de,F(i));
F(i)=F(i)+P(i);
end
[Fbest indice] =min(F);
xbest=Params(:,indice);
%vF=vF+vP;
%NaN(de.nG,de.nP);
Col=1:de.nP;
for g=1:de.nG
P0=P1;
rowS=randperm(de.nP)';
colS=randperm(4)';
RS=circshift(rowS,colS(1));
R1=circshift(rowS,colS(2));
R2=circshift(rowS,colS(3));
R3=circshift(rowS,colS(4));
%mutate
Pm=P0(:,R1)+de.F*(P0(:,R2)-P0(:,R3));
%extra mutation
if de.R>0
Pm=Pm+de.r*randn(de.d,de.nP);
end
%crossover
PmElements=rand(de.d,de.nP)<de.CR;
%mPv(MI)=mP(Mi);
if de.oneElementfromPm
Row=unidrnd(de.d,1,de.nP);
ExtraPmElements=sparse(Row,Col,1,de.d,de.nP);
PmElements=PmElements|ExtraPmElements;
end
P0_Elements=~PmElements;
Pu(:,RS)=P0(:,RS).*P0_Elements+PmElements.*Pm;
for i=1:de.nP
betasPu(:,i)=NSS_betas(Pu(:,i),data);
end
ParamsPu=vertcat(betasPu,Pu);
flag=0;
for i=1:de.nP
Ftemp=OF(ParamsPu(:,i)',data);
Ptemp=pen(Pu(:,i),de,F(i));
Ftemp=Ftemp+Ptemp;
if Ftemp<=F(i);
P1(:,i)=Pu(:,i);
F(i)=Ftemp;
if Ftemp < Fbest
Fbest=Ftemp; xbest=ParamsPu(:,i); flag=1;
end
else
P1(:,i)=P0(:,i);
end
end
if flag
Fbv(g)=Fbest;
end
end
output.Fbest=Fbest; output.xbest=xbest; output.Fbv=Fbv;
end
function penVal=pen(mP,pso,vF)
minV=pso.min;
maxV=pso.max;
ww=pso.ww;
A=mP-maxV;
A=A+abs(A);
B=minV-mP;
B=B+abs(B);
C=ww*((mP(1,:)+mP(2,:))-abs(mP(1,:)+mP(2,:)));
penVal=ww*sum(A+B,1)*vF-C;
end
function betas=NSS_betas(lambda,data)
mats=data.mats2';
lambda=lambda;
yM=data.y2';
nObs=size(yM,1);
G= [ones(nObs,1) (1-exp(-mats./lambda(1)))./(mats./lambda(1)) ((1-exp(- mats./lambda(1)))./(mats./lambda(1))-exp(-mats./lambda(1))) ((1-exp(- mats./lambda(2)))./(mats./lambda(2))-exp(-mats./lambda(2)))];
betas=G\yM;
end
귀하의 질문에 약간의 배열 입력이 있음을 언급하고 확장을 원할 경우 일부 변수가 처리되기를 원합니다. 이것은 최상의 접근법이 무엇인지 판단하기가 쉽지 않다. –
OK 문맥에서 볼 수 있도록 나머지 코드를 추가했다. 나는 2D 배열 (행렬) 이상을 다룰 수 없었습니다. 그래서 저는 3D 배열에 머리를 맞 춥니 다. 아직도 명확하지 않다면 나는 더 명확히 해 드리겠습니다. – Bazman
여전히 명확하지 않습니다. 입력 내용은 이제 '1x50'입니까? 원하는 변화는 무엇입니까? 코드의 핵심 부분은 무엇입니까? '그러면 각 i에 대해 4xd 배열을 반환합니다.'라는 의미는 무엇입니까? 이 경우'i'는 무엇입니까? 'dx50' 입력을받는다면 그 코드의 결과는 무엇입니까? 나는 당신이 원하는 것을 명확히하기 위해 완전한 코드를 요구하지 않았습니다. 응답을 기대한다면 응답자들에게 쉽게 대답하십시오 .. –