Related
The following is my implementation of a paper for cauchy noise removal.
The psnr value of the noisy image is 19 as the paper but when I compute the psnr value for the restored image un, it returns 17 which is even smaller than the psnr value of the noisy image. I guess there is something wrong in psnr computation with my code.
%%
clear memory;
clear all
close all
clc;
%% Initialization
refimg = im2double(imread('cameraman256.png')); % original image
img_height = size(refimg,1);
img_width = size(refimg,2);
refimg = refimg(1:img_height,1:img_width);
padNum = 5;
refimg = padarray(refimg,[padNum,padNum],'symmetric');
[mm,nn]=size(refimg);
img_height = size(refimg,1);
img_width = size(refimg,2);
%% Producing the degraded image
A = 1; % A =1 for image denoising
sz = size(refimg);
rng(0);
r1 = randn(sz); % (using randn because I don't have the statistics toolbox)
r2 = randn(sz);
n = 0.02; % the noise level
u0 = refimg + n.*(r1./r2);
u0 = min(u0,1); % clamp large values to 1
u0 = max(u0,0); % clamp small values to 0
figure(1); imshow(u0(padNum+1:mm-padNum,padNum+1:nn-padNum),'border','tight');
%% Initial values for the primal-dual algorithm
tol = 1e-3;
nIter = 1e3;
options.order = 1; options.bound = 'sym';
un = u0;
wn = u0;
bun = un;
bwn = wn;
pxn = zeros(ny,nx);
pyn = zeros(ny,nx);
q = zeros(ny,nx);
[gxn,gyn] = grad(u0,options);
bgxn = gxn;
bgyn = gyn;
gamma = sqrt(2)/10;
lambda = 0.7;
mu = 6.25;
tau = 0.3;
sigma = 0.3;
%% Primal-dual Algorithm
for j = 1:nIter
%%%%%%%%%%solve the subproblem p
[ux,uy]=grad(bun,options);
pxn = pxn+sigma*(bgxn-ux);
pyn = pyn+sigma*(bgyn-uy);
%%%%%%%%%%%solve the subproblem q
AUk = Au(bun);
q = q+sigma*(bwn-AUk);
%%%%%%%%%%solve the subproblem g
goldxn = gxn;
goldyn = gyn;
txn = gxn-tau*pxn;
tyn = gyn-tau*pyn;
sn = max(1e-6,sqrt(txn.^2+tyn.^2));
gxn = txn./sn.*max(0,sn-tau);
gyn = tyn./sn.*max(0,sn-tau);
%%%%%%%%%%%solve the subproblem wn
u_medfilter = medfilt2(u0);
wold = wn;
a = mu.*lambda.*tau+1;
b = -(mu.*lambda.*tau.*(2.*u0+u_medfilter)-tau.*q+2.*u0+wold);
c = tau.*lambda+mu.*lambda.*tau.*(gamma.^2+u0.^2+2.*u_medfilter.*u0)-2.*tau.*q.*u0+...
gamma.^2+u0.^2+2.*wold.*u0;
d = -tau.*lambda.*u0-mu.*lambda.*tau.*u_medfilter.*(gamma.^2+u0.^2)+tau.*q.*(gamma.^2+u0.^2)...
-wold.*(gamma.^2+u0.^2);
qval = (3.*a.*c-(b.^2))./(9.*(a.^2));
rval = (9.*a.*b.*c-27.*(a.^2).*d-2.*(b.^3))./(54.*(a.^3));
deltaval = qval.^3+rval.^2;
wn = nthroot(rval+real(sqrt(deltaval)),3)+nthroot(rval-real(sqrt(deltaval)),3)-((b)./(3.*a));
%%%%%%%%%%%solve the subproblem un
uold = un;
Asqk = Atu(q);
un = un+tau*(Asqk-div(pxn,pyn,options)); % the restored image
% un = min(1,max(0.01,un));
if (norm(un-uold, 'fro')/norm(uold,'fro')<tol)
break;
end
bun = 2*un-uold;
bwn = 2*wn-wold;
bgxn = 2*gxn-goldxn;
bgyn = 2*gyn-goldyn;
% PSNR_restoredimage = psnr(refimg(padNum+1:mm-padNum,padNum+1:nn-b
padNum),un(padNum+1:mm-padNum,padNum+1:nn-padNum))
end
%% Dispaly results
New_un = un;
refimg = refimg(padNum+1:mm-padNum,padNum+1:nn-padNum);
u0 = u0(padNum+1:mm-padNum,padNum+1:nn-padNum);
u_medfilter = u_medfilter(padNum+1:mm-padNum,padNum+1:nn-padNum);
New_un = New_un(padNum+1:mm-padNum,padNum+1:nn-padNum);
PSNR_noisy = psnr(refimg,u0)
PSNR_med = psnr(refimg,u_medfilter)
PSNR_restoredimage = psnr(New_un,refimg)
figure(2); imshow([refimg,u_medfilter,New_un],'border','tight');
%%
The problem was not in psnr computation. The problem with my code in this question was that I was considering the denoising case but I had forgotten to omit the blur kernel in primal-dual algorithm. Also, the initial parameters corresponding to the deblurring case must be zero. The following is the corrected code. Now the psnr value is 28 similar to the paper.
%%
clear;
%% Initialization
refimg = im2double(imread('cameraman256.png')); % original image
img_height = size(refimg,1);
img_width = size(refimg,2);
refimg = refimg(1:img_height,1:img_width);
%% Producing the noisy image
sz = size(refimg);
rng(0);
r1 = randn(sz); % (using randn because I don't have the statistics toolbox)
r2 = randn(sz);
n = 0.02; % the noise level
u0 = refimg + n.*(r1./r2);
u0 = min(u0,1); % clamp large values to 1
u0 = max(u0,0); % clamp small values to 0
figure(1); imshow(u0,'border','tight');
%% Initial values for the primal-dual algorithm
init = u0;
[ny,nx] = size(init);
tol = 1e-3;
nIter = 1e3;
options.order = 1; options.bound = 'sym';
un = u0;
wn = zeros(ny,nx);
bun = un;
bwn = zeros(ny,nx);
pxn = zeros(ny,nx);
pyn = zeros(ny,nx);
q = zeros(ny,nx);
[gxn,gyn] = grad(u0,options);
bgxn = gxn;
bgyn = gyn;
gamma = sqrt(2)/10;
lambda = 0.7;
mu = 6.25;
tau = 0.3;
sigma = 0.3;
%% Primal-dual Algorithm
for j = 1:nIter
%%%%%%%%%%solve the subproblem p
[ux,uy]=grad(bun,options);
pxn = pxn+sigma*(bgxn-ux);
pyn = pyn+sigma*(bgyn-uy);
%%%%%%%%%%%solve the subproblem q
AUk = bun;
q = q+sigma*(bwn-AUk);
%%%%%%%%%%solve the subproblem g
goldxn = gxn;
goldyn = gyn;
txn = gxn-tau*pxn;
tyn = gyn-tau*pyn;
sn = max(1e-6,sqrt(txn.^2+tyn.^2));
gxn = txn./sn.*max(0,sn-tau);
gyn = tyn./sn.*max(0,sn-tau);
%%%%%%%%%%%solve the subproblem wn
u_medfilter = medfilt2(u0);
wold = wn;
a = mu.*lambda.*tau+1;
b = -(mu.*lambda.*tau.*(2.*u0+u_medfilter)-tau.*q+2.*u0+wold);
c = tau.*lambda+mu.*lambda.*tau.*(gamma.^2+u0.^2+2.*u_medfilter.*u0)-2.*tau.*q.*u0+...
gamma.^2+u0.^2+2.*wold.*u0;
d = -tau.*lambda.*u0-mu.*lambda.*tau.*u_medfilter.*(gamma.^2+u0.^2)+tau.*q.*(gamma.^2+u0.^2)...
-wold.*(gamma.^2+u0.^2);
qval = (3.*a.*c-(b.^2))./(9.*(a.^2));
rval = (9.*a.*b.*c-27.*(a.^2).*d-2.*(b.^3))./(54.*(a.^3));
deltaval = qval.^3+rval.^2;
wn = nthroot(rval+real(sqrt(deltaval)),3)+nthroot(rval-real(sqrt(deltaval)),3)-((b)./(3.*a));
%%%%%%%%%%%solve the subproblem un
uold = un;
Asqk = q;
un = un+tau*(Asqk-div(pxn,pyn,options)); % the restored image
if (norm(un-uold, 'fro')/norm(uold,'fro')<tol)
break;
end
bun = 2*un-uold;
bwn = 2*wn-wold;
bgxn = 2*gxn-goldxn;
bgyn = 2*gyn-goldyn;
end
%% Dispaly results
PSNR_noisy = psnr(u0,refimg)
PSNR_med = psnr(u_medfilter,refimg)
PSNR_restoredimage = psnr(un,refimg)
figure(2); imshow([refimg,u_medfilter,un],'border','tight');
%%
How can I construct the matrices G and D if I have h and w?
Please pay attention that in G there are some 0 rows and in D there are some 0 columns...
Even though i am very late with my solution for this, here it is for anybody wanting to implement it:
function g = gradientMat(w,h)
one = [-ones(w*h,1) ones(w*h,1)];
d = [0 1];
dx = spdiags(one,d,w*h,w*h);
dx(1:h:end,:) = zeros(w,w*h);
d = [0 h];
dy = spdiags(one,d,w*h,w*h);
dy(h*(w-1)+1:end,:) = zeros(h,w*h);
g = [dx;dy];
end
This solution has the advantage to use matlabs sparse diagonal matrices, which allow you to create the gradient matrix for large images and make calculation with these faster.
To obtain the divergence, simpley use:
g = gradientMat(size(image)(1),size(image)(2));
div = (-g')*g;
this is how I did it now, but there must be a more elegant way, right?!
%% construct G
% upper half
firstDiagG = ones(h, 1);
firstDiagG(h) = 0;
firstDiagG = -firstDiagG;
firstDiagG = repmat(firstDiagG,w,1);
% first = diag(firstDiagG);
firstG = spdiags(firstDiagG,0,n,n);
secondDiagG = ones(h, 1);
secondDiagG(h) = 0;
secondDiagG = repmat(secondDiagG,w,1);
% second = diag(secondDiagG);
secondG = spdiags(secondDiagG,0,n,n);
secondG = [zeros(size(secondG,1),1) secondG];
secondG = secondG(:,1:end-1);
upperHalf = firstG + secondG;
% lower half
thirdDiagG = ones(n-h, 1);
thirdDiagG = [thirdDiagG; zeros(h, 1)];
thirdDiagG = -thirdDiagG;
% thirdG = diag(thirdDiagG);
thirdG = spdiags(thirdDiagG,0,n,n);
fourthDiagG = [ones(n-2*h, 1); zeros(n-2*h, 1)];
% fourthG = diag(fourthDiagG);
fourthG = spdiags(fourthDiagG,0,n,n);
fourthG = [zeros(size(fourthG,1), h) fourthG];
fourthG = fourthG(:,1:end-h);
% fourthG = [fourthG zeros(size(fourthG,1),h)];
% fourthG = [fourthG; zeros(size(fourthG,1), size(fourthG,2))];
lowerHalf = thirdG + fourthG;
G = [upperHalf; lowerHalf];
%% construct D
% left half
firstD = firstG; % is the same as in G
secondDiagD = secondDiagG; % is the same as in G
% secondD = diag(secondDiagD);
secondD = spdiags(secondDiagD,0,n,n);
secondD = [zeros(1, size(secondD,1)); secondD];
secondD = secondD(1:end-1,:);
leftHalf = firstD + secondD;
% right half
thrirdDiagD = flip(thirdDiagG);
% thirdD = diag(thrirdDiagD);
thirdD = spdiags(thrirdDiagD,0,n,n);
fourthDiagD = ones(n, 1);
% fourthD = diag(fourthDiagD);
fourthD = spdiags(fourthDiagD,0,n,n);
fourthD = [zeros(h, size(fourthD,1)); fourthD];
fourthD = fourthD(1:end-h,:);
rightHalf = thirdD + fourthD;
D = [leftHalf rightHalf];
I'm solving a system of ODEs using RK4. I'm generating a straight line plot that seems to be due to the fact that k3_1 is capped at -3.1445e+24. I don't understand why it is capped.
function RK4system_MNModel()
parsec = 3.08*10^18;
r_1 = 8.5*1000.0*parsec; % in cm
z_1 = 0.0; % in cm also
theta_1 = 0.0;
grav = 6.6720*10^-8;
amsun = 1.989*10^33; % in grams
amg = 1.5d11*amsun; % in grams
gm = grav*amg; % constant
q = 0.9; % axial ratio
u_1 = 130.0; % in cm/sec
w_1 = 95*10^4.0; % in cm/sec
v = 180*10^4.0; % in cm/sec
vcirc = sqrt(gm/r_1); % circular speed (constant)
nsteps = 50000;
deltat = 5.0*10^11; % in seconds
angmom = r_1*v; % these are the same
angmom2 = angmom^2.0;
e = -gm/r_1+u_1*u_1/2.0+angmom2/(2.0*r_1*r_1);
time=0.0;
for i=1:nsteps
k3_1 = deltat*u_1 %%%%% THIS LINE
k4_1 = deltat*(-gm*r_1/((r_1^2.0+(1+sqrt(1+z_1^2.0))^2.0)^1.5) + angmom2/(r_1^3.0)); % u'=-dphi_dr+lz^2/(r^3.0) with lz=vi*ri this gives deltau
k5_1 = deltat*(angmom/(r_1^2.0)); % theta'=lz/r^2 this gives deltatheta
k6_1 = deltat*w_1;
k7_1 = deltat*(-gm*z_1*(1+sqrt(1+z_1^2.0))/(sqrt(1+z_1^2.0)*(r_1^2.0+(1+sqrt(1+z_1^2.0))^2.0)^1.5));
r_2 = r_1+k3_1/2.0;
u_2 = u_1+k4_1/2.0;
theta_2 = theta_1+k5_1/2.0;
z_2 = z_1 + k6_1/2.0;
w_2 = w_1 + k7_1/2.0;
k3_2 = deltat*u_2;
k4_2 = deltat*(-gm*r_2/((r_2^2.0+(1+sqrt(1+z_2^2.0))^2.0)^1.5)+angmom2/(r_2^3.0));
k5_2 = deltat*(angmom/(r_2^2.0)); % theta'=lz/r^2 =====> deltatheta
k6_2 = deltat*w_2;
k7_2 = deltat*(-gm*z_2*(1+sqrt(1+z_2^2.0))/(sqrt(1+z_2^2.0)*(r_2^2.0+(1+sqrt(1+z_2^2.0))^2.0)^1.5));
r_3 = r_1+k3_2/2.0;
u_3 = u_1+k4_2/2.0;
theta_3 = theta_1+k5_2/2.0;
z_3 = z_1 + k6_2/2.0;
w_3 = w_1 + k7_2/2.0;
k3_3 = deltat*u_3; % r'=u
k4_3 = deltat*(-gm*r_3/((r_3^2.0+(1+sqrt(1+z_3^2.0))^2.0)^1.5)+angmom2/(r_3^3.0));% u'=-dphi_dr+lz^2/(r^3.0)
k5_3 = deltat*(angmom/(r_3^2.0)); % theta'=lz/r^2
k6_3 = deltat*w_3;
k7_3 = deltat*(-gm*z_3*(1+sqrt(1+z_3^2.0))/(sqrt(1+z_3^2.0)*(r_3^2.0+(1+sqrt(1+z_3^2.0))^2.0)^1.5));
r_4 = r_1+k3_2;
u_4 = u_1+k4_2;
theta_4 = theta_1+k5_2;
z_4 = z_1 + k6_2;
w_4 = w_1 + k7_2;
k3_4 = deltat*u_4; % r'=u
k4_4 = deltat*(-gm*r_4/((r_4^2.0+(1+sqrt(1+z_4^2.0))^2.0)^1.5)+angmom2/(r_4^3.0)); % u'=-dphi_dr+lz^2/(r^3.0)
k5_4 = deltat*(angmom/(r_4^2.0)); % theta'=lz/r^2
k6_4 = deltat*w_4;
k7_4 = deltat*(-gm*z_4*(1+sqrt(1+z_4^2.0))/(sqrt(1+z_4^2.0)*(r_4^2.0+(1+sqrt(1+z_4^2.0))^2.0)^1.5));
r_1 = r_1+(k3_1+2.0*k3_2+2.0*k3_3+k3_4)/6.0; % New value of R for next step
u_1 = u_1+(k4_1+2.0*k4_2+2.0*k4_3+k4_4)/6.0; % New value of U for next step
theta_1 = theta_1+(k5_1+2.0*k5_2+2.0*k5_3+k5_4)/6.0; % New value of theta
z_1 = z_1+(k6_1+2.0*k6_2+2.0*k6_3+k6_4)/6.0;
w_1 = w_1+(k7_1+2.0*k7_2+2.0*k7_3+k7_4)/6.0;
e = -gm/r_1+u_1*u_1/2.0+angmom2/(2.0*r_1*r_1); % energy
ecc = (1.0+(2.0*e*angmom2)/(gm^2.0))^0.5; % eccentricity
x(i) = r_1*cos(theta_1)/(1000.0*parsec); % X for plotting orbit
y(i) = r_1*sin(theta_1)/(1000.0*parsec); % Y for plotting orbit
time = time+deltat;
r(i) = r_1;
z(i) = z_1;
time1(i)= time;
end
Note that the anomally occurs on the indicated line.
It's not k3_1 that's capped, it's the calculation of u_1 that returns a value of -3.1445e+24 / deltat (deltat is constant).
u_1 is calculated in the line:
u_1 = u_1+(k4_1+2.0*k4_2+2.0*k4_3+k4_4)/6.0;
After the first iteration, this returns:
u_1(1) = 6.500e+13 % Hard coded before the loop
u_1(2) = -1.432966614767040e+04 % Calculated using the equation above
u_1(3) = -2.878934017859105e+04 % Calculated using the equation above
u_1(4) = -4.324903004768405e+04
Based on the equation u_1(n+1) = u_1(n) + du it looks like du represents a relatively small difference. The difference between the two first values is very large, so I'm assuming it is this calculation that's incorrect.
If you find that that calculation is correct, then your error is in one of these lines:
k4_1 = deltat*(-gm*r_1/((r_1^2.0+(1+sqrt(1+z_1^2.0))^2.0)^1.5)+angmom2/(r_1^3.0)); % u'=-dphi_dr+lz^2/(r^3.0) with lz=vi*ri this gives delta
k4_2 = deltat*(-gm*r_2/((r_2^2.0+(1+sqrt(1+z_2^2.0))^2.0)^1.5)+angmom2/(r_2^3.0));
k4_3 = deltat*(-gm*r_3/((r_3^2.0+(1+sqrt(1+z_3^2.0))^2.0)^1.5)+angmom2/(r_3^3.0));% u'=-dphi_dr+lz^2/(r^3.0)
k4_4 = deltat*(-gm*r_4/((r_4^2.0+(1+sqrt(1+z_4^2.0))^2.0)^1.5)+angmom2/(r_4^3.0)); % u'=-dphi_dr+lz^2/(r^3.0)
I am very new to Matlab. What i am trying to do is classify the iris dataset using Cross-Validation (that means that i have to split the dataset in 3: trainingSet, validationSet, and test set) . In my mind everything i write here is ok (beeing a beginner is hard sometimes). So i could use a little help...
This is the function that splits the data (first 35(70% of the data) are the training set, the rest is the validation set(15%) and 15% i will use later for the test set)
close all; clear ;
load fisheriris;
for i = 1:35
for j = 1:4
trainSeto(i,j) = meas(i,j);
end
end
for i = 51:85
for j = 1:4
trainVers(i-50,j) = meas(i,j);
end
end
for i = 101:135
for j = 1:4
trainVirg(i-100,j) = meas(i,j);
end
end
for i = 36:43
for j = 1:4
valSeto(i-35,j) = meas(i,j);
end
end
for i = 86:93
for j = 1:4
valVers(i-85,j) = meas(i,j);
end
end
for i = 136:143
for j = 1:4
valVirg(i-135,j) = meas(i,j);
end
end
for i = 44:50
for j = 1:4
testSeto(i-43,j) = meas(i,j);
end
end
for i = 94:100
for j = 1:4
testVers(i-93,j) = meas(i,j);
end
end
for i = 144:150
for j = 1:4
testVirg(i-143,j) = meas(i,j);
end
end
And this is the main script:
close all; clear;
%%the 3 tipes of iris
run divinp
% the representation of the 3 classes(their coding)
a = [-1 -1 +1]';
b = [-1 +1 -1]';
c = [+1 -1 -1]';
%training set
trainInp = [trainSeto trainVers trainVirg];
%the targets
T = [repmat(a,1,length(trainSeto)) repmat(b,1,length(trainVers)) repmat(c,1,length(trainVirg))];
%%the training
trainCor = zeros(10,10);
valCor = zeros(10,10);
Xn = zeros(1,10);
Yn = zeros(1,10);
for k = 1:10,
Yn(1,k) = k;
for n = 1:10,
Xn(1,n) = n;
net = newff(trainInp,T,[k n],{},'trainbfg');
net = init(net);
net.divideParam.trainRatio = 1;
net.divideParam.valRatio = 0;
net.divideParam.testRatio = 0;
net.trainParam.max_fail = 2;
valInp = [valSeto valVers valVirg];
valT = [repmat(a,1,length(valSeto)) repmat(b,1,length(valVers)) repmat(c,1,length(valVirg))];
[net,tr] = train(net,trainInp,T);
Y = sim(net,trainInp);
[Yval,Pfval,Afval,Eval,perfval] = sim(net,valInp,[],[],valT);
% calculate [%] of correct classifications
trainCor(k,n) = 100 * length(find(T.*Y > 0)) / length(T);
valCor(k,n) = 100 * length(find(valT.*Yval > 0)) / length(valT);
end
end
figure
surf(Xn,Yn,trainCor/3);
view(2)
figure
surf(Xn,Yn,valCor/3);
view(2)
I get this error
Error using trainbfg (line 120) Inputs and targets have different
numbers of samples.
Error in network/train (line 106) [net,tr] =
feval(net.trainFcn,net,X,T,Xi,Ai,EW,net.trainParam);
Error in ClassIris (line 38)
[net,tr] = train(net,trainInp,T);
close all; clear ;
load fisheriris;
trainSetoIndx = 1:35;
trainVersIndx = 51:85; % or: trainVersIndx = trainSetoIndx + 50;
trainVirgIndx = 101:135;
colIndx = 1:4;
trainSeto = meas(trainSetoIndx, colIndx);
trainVers = meas(trainVersIndx, colIndx);
trainVirg = meas(trainVirgIndx, colIndx);
valSetoIndx = 36:43;
valVersIndx = 86:93;
valVirgIndx = 136:143
valSeto = meas(valSetoIndx, colIndx);
valVers = meas(valVersIndx, colIndx);
valVirg = meas(valVirgIndx, colIndx);
testSetoIndx = 44:50;
testVersIndx = 94:100;
testVirgIndx = 144:150
testSeto = meas(testSetoIndx, colIndx);
testVers = meas(testVersIndx, colIndx);
testVirg = meas(testVirgIndx, colIndx);
i have writen it with ":" also still the same problem it's something with repmat.. i don't know how to use it properly or newff :D
Just to get you started, you can rewrite your code loops as follows:
trainSetoIndx = 1:35;
trainVersIndx = 51:85; % or: trainVersIndx = trainSetoIndx + 50;
trainVirgIndx = 101:135; % or: trainVirgIndx = trainSetoIndx + 100;
colIndx = 1:4; % can't tell if this is all the columns in meas
trainSeto = meas(trainIndx, colIndx);
trainVers = meas(trainVersIndx, colIndx);
trainVirg = meas(trainVirgIndx, colIndx);
The do the same thing for all the others:
valSetoIndx = 36:43;
etc.
Next, simply type whos at the command prompt and you will see the sizes of all the arrays you have created. See whether the ones that need to be the same size have, in fact, the same dimensions.
In the first Matlab script below when I run it as shown I get no errors what so ever and the code produces the expected results, however when I take out matlabpool open and matlabpool close as well as changing the parfor loop to a for loop, I get the following error:
Running... ??? Error using ==> mldivide
Matrix is singular to working precision.
Error in ==> NSS_betas at 11
betas = G\data.y2.';
Error in ==> DElambda at 19
betas(:,ii) = NSS_betas(P1(:,ii),data); end
Error in ==> Individual_Lambdas at 46
beta{ii} = DElambda(de,dataList, #OF_NSS);
I will happily send CRM_22_12.mat if required.
Why does the error only trigger when I use a regular for loop instead if a parfor loop?
clear all, clc
load Euro_CRM_22_12.mat
matlabpool open
tic
warnState(1) = warning('error', 'MATLAB:singularMatrix');
warnState(2) = warning('error', 'MATLAB:illConditionedMatrix');
mats = 1:50;
mats2 = [2 5 10 30];
% RO: unloop these
de = struct(...
'min', [0;0],...
'max', [50;50],...
'd' , 2,...
'nP' , 500,...
'nG' , 600,...
'ww' , 0.1,...
'F' , 0.5,...
'CR' , 0.99,...
'R' , 0,...
'oneElementfromPm',1);
% RO: initialize beta
beta = cell(size(rates,1),1);
clc, fprintf('Running... ');
%for ii = 1:size(rates,1)
parfor ii = 1:size(rates,1)
% RO: use status indicator for things that take this long
%fprintf('\b\b\b\b\b\b\b%6.2f%%', ii/size(rates,1)*100);
dataList = struct(...
'yM' , rates(ii,:),...
'mats' , mats,...
'model', #NSS,...
'mats2', mats2,...
'y2' , rates(ii,mats2));
beta{ii} = DElambda(de,dataList, #OF_NSS);
end
toc
matlabpool close
%
function [output] = DElambda(de,data,OF)
% RO: also saves time
% warning off; %#ok
warning on verbose;
P1 = zeros(de.d,de.nP);
Pu = zeros(de.d,de.nP);
for ii = 1:de.d
P1(ii,:) = de.min(ii,1)+(de.max(ii,1)-de.min(ii,1))*rand(de.nP,1); end
P1(:,1:de.d) = diag(de.max);
P1(:,de.d+1:2*de.d) = diag(de.min);
% RO: pre allocate betas
betas = zeros(size(data.y2,2), de.nP);
for ii = 1:de.nP
betas(:,ii) = NSS_betas(P1(:,ii),data); end
Params = vertcat(betas,P1);
Fbv = NaN(de.nG,1);
% must pass OF as #OF
F = zeros(de.nP,1);
P = zeros(de.nP,1);
for ii = 1:de.nP
F(ii) = OF(Params(:,ii)',data);
P(ii) = pen(P1(:,ii),de,F(ii));
F(ii) = F(ii)+P(ii);
end
[Fbest indice] = min(F);
xbest = Params(:,indice);
Col = 1:de.nP;
% RO: pre allocate betasPu
betasPu = zeros(size(data.y2,2), de.nP);
% RO: if Fbest hasn't changed for 25 generations,
% it's not gonna anymore: break off
count = 0;
for g = 1:de.nG
P0 = P1;
rowS = randperm(de.nP).';
colS = randperm(4).';
% RO: replace circshift for JIT accelleration
% RS = circshift(rowS,colS(1));
% R1 = circshift(rowS,colS(2));
% R2 = circshift(rowS,colS(3));
% R3 = circshift(rowS,colS(4));
RS = rowS([end-colS(1)+1:end 1:end-colS(1)]);
R1 = rowS([end-colS(2)+1:end 1:end-colS(2)]);
R2 = rowS([end-colS(3)+1:end 1:end-colS(3)]);
R3 = rowS([end-colS(4)+1:end 1:end-colS(4)]);
% mutate
Pm = P0(:,R1) + de.F*(P0(:,R2)-P0(:,R3));
if de.R>0, Pm = Pm+de.r*randn(de.d,de.nP); end
% crossover
PmElements = rand(de.d,de.nP)<de.CR;
if de.oneElementfromPm
% RO: JIT...
%Row = unidrnd(de.d,1,de.nP);
Row = ceil(de.d .* rand(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;
% RO: inline NSS_betas, so that this loop can
% be compiled by the JIT
mats = data.mats2.';
yM = data.y2.';
nObs = size(data.y2,2);
one = ones(nObs,1);
% RO: version below is faster
% for ii = 1:de.nP
% %betasPu(:,ii) = NSS_betas(Pu(:,ii),data);
%
% lambda = Pu(:,ii);
% G = [one,...
% (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)))];
%
% betasPu(:,ii) = G\yM;
%
% end
aux = bsxfun(#rdivide, mats, Pu(:).');
aux2 = exp(-aux);
aux3 = (1-aux2)./aux;
for ii = 1:2:2*de.nP
% betasPu(:,(ii+1)/2) =[...
% one,...
% aux3(:,ii),...
% aux3(:,ii) - aux2(:,ii),...
% aux3(:,ii+1) - aux2(:,ii+1)] \ yM;
G=[one, aux3(:,ii), aux3(:,ii) - aux2(:,ii),aux3(:,ii+1) - aux2(:,ii+1)];
try
betasPu(:,(ii+1)/2) =G\yM;
catch ME
CondPen(1,(ii+1)/2)=0;
end
end
ParamsPu = [betasPu;Pu];
flag = 0;
mats = data.mats;
yM = data.yM;
for ii = 1:de.nP
% RO: inline OF_NSS.m here for JIT accelleration
%Ftemp = OF(ParamsPu(:,ii).',data);
beta = ParamsPu(:,ii).';
%model = data.model;
yy = zeros(size(yM));
for jj = 1:size(beta,3)
% RO: inline for JIT accelleration
%y(ii,:) = model(beta(:,:,ii),mats);
betai = beta(:,:,jj);
gam1 = mats/betai(5);
gam2 = mats/betai(6);
aux1 = 1-exp(-gam1);
aux2 = 1-exp(-gam2);
% I have a feeling this is the same as G and therefore
% this can be done shorter and quicker...
% something like yy(jj,:) = sum(G,2)
yy(jj,:) = ...
betai(1) + ...
betai(2)*(aux1./gam1) + ...
betai(3)*(aux1./gam1+aux1-1) + ...
betai(4)*(aux2./gam2+aux2-1);
end
yy = yy-yM;
% RO: this whole loop can be replaced...
% ObjVal = 0;
% for i = 1:size(yM,1) %dim
% ObjVal = ObjVal+dot(aux(i,:)',aux(i,:)');
% %ObjVal = sum(ObjVal);
% end
% ObjVal
% RO ...by this one-liner
Ftemp = sum(yy(:).^2);
% RO: inline penalty here as well
Ptemp = 0;%pen(Pu(:,ii),de,F(ii));
Ftemp = Ftemp+Ptemp;%+CondPen(1,ii);
if Ftemp <= F(ii);
P1(:,ii) = Pu(:,ii);
F(ii) = Ftemp;
if Ftemp < Fbest
Fbest = Ftemp; xbest = ParamsPu(:,ii);
flag = 1;
count = 0;
end
else
P1(:,ii) = P0(:,ii);
end
end
if flag
Fbv(g) = Fbest; end
% RO: if Fbest hasn't changed for 25 generatios, break off
count = count + 1;
if count > 25, break; end
end
output.Fbest = Fbest;
output.xbest = xbest;
output.Fbv = Fbv;
end
% look to inline penalty later (i.e. incoporate into code
function penVal = pen(~,~,~)%pen(beta,pso,vF,data)
penVal = 0;
end
%
function [betas r r2] = NSS_betas(lambda,data)
mats = data.mats2.';
nObs = size(data.y2,2);
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\data.y2.';
% RO: output hardly ever needed, while rank()
% is very time consuming
if nargout > 1 && ~isnan(G)
r = rank(G);
r2 = rcond(G);
end
end
It's a bit cryptic, but here's what I can tell you for sure.
Error in ==> NSS_betas at 11
betas = G\data.y2.';
Error in ==> DElambda at 19
betas(:,ii) = NSS_betas(P1(:,ii),data); end
Error in ==> Individual_Lambdas at 46
beta{ii} = DElambda(de,dataList, #OF_NSS);
Essentially, this means that the G matrix is singular, and thus doesn't have a solution. That would be this:
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\data.y2.';
What I would do to further diagnose this is to set the stop on error flag. There is a few ways to do this, one from the gui, and another via command. Take a look to see if the matrix looks correct. Odds are, something isn't right. Trace back the error, and you'll figure it out.