2012-10-15 4 views
-1

다음 코드는 데이터가 1x50 array으로 전달 될 때 작동합니다. (실제로 데이터는 다른 여러 매개 변수도 전달하는 구조체입니다). 1x50 경우 4x1 매개 변수 배열이 각 i에 대해 리턴됩니다 (de.nP의 값은 600 임).셀 배열 또는 다중 첨자 배열?

그러나 데이터 행렬이 d 날짜가되도록 dx50 행렬을 전달할 수 있도록 변경하고 싶습니다. 그러면 각 i에 대해 4xd 배열이 반환됩니다.

제 질문은 셀 배열이나 3D 배열을 사용하여 값을 저장해야합니까? 두 가지 방법 모두 작업을 수행 할 수 있다고 생각하십니까? 나는 P12x1 배열입니다

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 
+0

귀하의 질문에 약간의 배열 입력이 있음을 언급하고 확장을 원할 경우 일부 변수가 처리되기를 원합니다. 이것은 최상의 접근법이 무엇인지 판단하기가 쉽지 않다. –

+0

OK 문맥에서 볼 수 있도록 나머지 코드를 추가했다. 나는 2D 배열 (행렬) 이상을 다룰 수 없었습니다. 그래서 저는 3D 배열에 머리를 맞 춥니 다. 아직도 명확하지 않다면 나는 더 명확히 해 드리겠습니다. – Bazman

+1

여전히 명확하지 않습니다. 입력 내용은 이제 '1x50'입니까? 원하는 변화는 무엇입니까? 코드의 핵심 부분은 무엇입니까? '그러면 각 i에 대해 4xd 배열을 반환합니다.'라는 의미는 무엇입니까? 이 경우'i'는 무엇입니까? 'dx50' 입력을받는다면 그 코드의 결과는 무엇입니까? 나는 당신이 원하는 것을 명확히하기 위해 완전한 코드를 요구하지 않았습니다. 응답을 기대한다면 응답자들에게 쉽게 대답하십시오 .. –

답변

0

이 트릭은 그러나 함수의 나머지 부분에서 광범위한 재 코딩이 필요합니다 않습니다입니다!

betas=zeros(4,size(data.y2,1),de.nP); 
for i=1:de.nP 
betas(:,:,i)=NSS_betas(P1(:,i),data); 
end