The following piece of code works when data is passed as a 1x50 array
.
(Data is in fact a struct that passes several other parameters too). In the 1x50
case a 4x1
array of parameters is returned for each i (the value of de.nP
is 600).
However I want to change it so that I can pass a matrix of data say d
dates so that the matrix has dimension dx50
. This will then return a 4xd
array for each i.
My question is should I use a cell array or a 3D array to store the values? Seems to me both methods could do the job?
for i=1:de.nP
betas(:,i)=NSS_betas(P1(:,i),data);
end
Going further into the code I will need to use
Params=vertcat(betas,P1);
Where P1
is a 2x1
array. So for each date (i) I need to concatenate the contents of P(1) to all the betas for that date.
Will this affect the choice of whether to use cellarray or 3D array?
It seems to me cellarray is better suited to vectorised code (Which is what I am trying to use as much as possible) but 3D array might be easier to use with functions like vertcat
?
Here is the whole code
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