the script works normally for few data but if it accepts a matrix with a lot of data it takes too long time - matlab

That script(matlab) works normally and fast for few data but if it accepts a matrix with a lot of data it takes too long time >1hr it run with no error but very very slow. What is the reason and what i can do for that (what are the main factors that make a program slow)
clear;clc;close all;
pref=input('Please enter file prefix: ','s');
fn=[pref '.mhk'];
fr=fopen(fn,'r');
k=0;
error = false;
t = fgetl(fr);
XTH = [];
Yed = [];
while ~feof(fr)
t = fgetl(fr);
[temp,~]=sscanf(t,'%f');
if ~error
k = k + 1;
XTH(k) = temp(1);
Yed(k) = temp(2);
end
end
x = [XTH(1)];
y = [Yed(1)];
XTH=[x XTH];
Yed = transpose([y Yed]);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
n = length(XTH);
l = 0;
k = 0;
Vmin = 100000000;
r=0;
for u1 = 1:XTH(end)
l = l + 1;
if ismember(u1,XTH)==1
u1 = u1 + 0.1;
end
if u1>=XTH(1)+1 && u1< XTH(end)-1
for u2 = u1:XTH(end)
k = k + 1;
if u2 == u1
u2 = u2 + 1;
end
if ismember(u2,XTH)
u2 = u2 + 1;
end
XTH = [(XTH) u1 u2];
XTH = sort(XTH);
num1 = find(XTH==u1);
num2 = find(XTH==u2);
XTH = XTH(XTH~=u1);
XTH = XTH(XTH~=u2);
a11 = XTH(1:num1);
a12 = repelem(u1,length(XTH)-num1);
a1 = transpose([a11, a12]);
a2 = ones(n,1);
a31 = transpose(zeros(num1,1));
a32 = XTH(num1+1:num2-1)-u1;
a33 = repelem(u2-u1,length(XTH(num2:end)));
a3 = transpose([a31 a32 a33]);
a41 = transpose(zeros(num2-1,1));
a42 = XTH(num2:end)-u2;
a4 = transpose([a41 a42]);
A = [a1 a2 a3 a4];
AtA = transpose(A)*A;
B = Yed;
AtB = transpose(A)*B;
if det(AtA)==0
continue
end
if det(AtA)<1e-3
continue
end
solution = linsolve(AtA, AtB);
alpha1 = solution(1,1);
beta1 = solution(2,1);
alpha2 = solution(3,1);
alpha3 = solution(4,1);
beta2 = (alpha1*u1) + beta1 - (alpha2*u1);
beta3 = (alpha1*u1) + beta1 + alpha2*(u2-u1) - (alpha3*u2);
dy1 = 0;
dy2 = 0;
dy3 = 0;
Dx = XTH(end)-XTH(1);
width = 10;
for j = 1:num1
dy1 = dy1 + abs((Yed(j)-(alpha1*XTH(j)+beta1)));
end
for j = num1:num2-1
dy2 = dy2 + abs((Yed(j) - (alpha2*XTH(j)+beta2)));
end
for j = num2:n
dy3 = dy3 + abs((Yed(j) - (alpha2*XTH(j)+beta2)));
end
V(l+k) = Dx*width*(1/length(Yed))*(dy1+dy2+dy3);
if V(l+k) < Vmin && V(l+k)~=0
aa1 = alpha1;
aa2 = alpha2;
aa3 = alpha3;
bb1 = beta1;
bb2 = beta2;
bb3 = beta3;
U1 = u1;
U2 = u2;
Vmin = V(l+k);
end
end
end
end
plot(transpose(XTH), Yed, 'k')
daspect([10,1,1]);
% ax = gca;
% ax.XLim = [XTH(1) XTH(end)];
hold on;
grid on;
x11 = XTH(1);
x21 = U1;
y11 = aa1*x11 + bb1;
y21 = aa1*x21 + bb1;
plot([x11,x21],[y11,y21], 'r')
x21 = U1;
x22 = U2;
y21 = aa2*x21 + bb2;
y22 = aa2*x22 + bb2;
plot([x21,x22],[y21,y22], 'r')
x31 = U2;
x32 = XTH(end);
y31 = aa3*x31 + bb3;
y32 = aa3*x32 + bb3;
plot([x31,x32],[y31,y32], 'r')
%line(U1,aa1*U1 + bb1)
disp('Line equation 1:')
line1 = ['y = ', num2str(aa1),'*x + ',num2str(bb1)];
disp(line1)
disp('Line equation 2:')
line2 = ['y = ', num2str(aa2),'*x + ',num2str(bb2)];
disp(line2)
line3 = ['y = ', num2str(aa3),'*x + ',num2str(bb3)];
disp(line3);
vol = [num2str(Vmin),' m^3'];
disp('Minimum volume achieved:')
disp(vol)

Related

The function contour has different outputs in Scilab than in MATLAB?

I'm trying to convert this Matlab code to Scilab, but I have some problems.
clear all; clc;
c0 = 0.8;
c1 = 1.3;
c11 = -6.1;
c12 = -0.6;
c2 = 1.7;
c22 = -1.7;
g = 0.05;
d = 0.01;
x1 = -9;
x2 = 8;
k = 1;
kmax = 100;
x1trace = [x1];
x2trace = [x2];
i = 2;
while k < kmax
gr1 = c1 + c12*x2 + 2*c11*x1;
x1 = x1 + g*gr1
x1trace(i) = x1;
x2trace(i) = x2;
i = i + 1;
gr2 = c2 + c12*x1 + 2*c22*x2;
x2 = x2 + g*gr2
x1trace(i) = x1;
x2trace(i) = x2;
i = i + 1;
if sqrt(gr1^2 + gr2^2) <= d;
break;
end
k = k + 1;
end
x = -10:0.1:10;
y = -10:0.1:10;
[X, Y] = meshgrid(x, y);
Z = c0 + c1*X + c2*Y + c12*X.*Y + c11*X.^2 + c22*Y.^2;
[C, h] = contour(X, Y, Z);
clabel(C, h);
hold on;
plot(x1trace, x2trace, '-');
text(x1trace(1) + 0.2, x2trace(1) + 0.5, 'M0');
text(x1 + 2, x2, ...
strvcat(['x1 = ' (num2str(x1))], ...
['x2 = ' (num2str(x2))], ...
['k = ' (num2str(k))]));
hold off;
I get an error for this line:
[C, h] = contour(X, Y, Z);
Wrong number of output arguments.
What should I change to fix it? Are there also any other errors in the code ?
You should have roughly the samed rendering with the following Scilab code. Scilab's contour needs (in the 4th argument) the number of level curves or the values themselves. In addition, you should use ndgrid instead of meshgrid:
clear clc;
c0 = 0.8;
c1 = 1.3;
c11 = -6.1;
c12 = -0.6;
c2 = 1.7;
c22 = -1.7;
g = 0.05;
d = 0.01;
x1 = -9;
x2 = 8;
k = 1;
kmax = 100;
x1trace = [x1];
x2trace = [x2];
i = 2;
while k < kmax
gr1 = c1 + c12*x2 + 2*c11*x1;
x1 = x1 + g*gr1
x1trace(i) = x1;
x2trace(i) = x2;
i = i + 1;
gr2 = c2 + c12*x1 + 2*c22*x2;
x2 = x2 + g*gr2
x1trace(i) = x1;
x2trace(i) = x2;
i = i + 1;
if sqrt(gr1^2 + gr2^2) <= d;
break;
end
k = k + 1;
end
x = -10:0.1:10;
y = -10:0.1:10;
[X, Y] = ndgrid(x, y);
Z = c0 + c1*X + c2*Y + c12*X.*Y + c11*X.^2 + c22*Y.^2;
clf
gcf.color_map=parulacolormap(8)($:-1:1,:)
contour(x, y, Z,0:-100:-700);
plot(x1trace, x2trace, '-');
xstring(x1trace(1) + 0.2, x2trace(1) + 0.5, 'M0');
xstring(x1 + 2, x2, ...
['x1 = '+string(x1)
'x2 = '+string(x2)
'k = '+string(k)]);

Solve a system of nonlinear equations that contain Lambert-W function

I'm trying to solve a non-linear system of equations using Newton-Raphson method. The problem is in section 2.1 from this paper. It goes only up to the second iteration, and I got incorrect answer.
I used these values for iN and VN (N=1,2,3,4,5):
V1 = 1.00400400e+00;
V2 = 1.02598500e+00;
V3 = 1.05325500e+00;
V4 = 1.08812300e+00;
V5 = 1.13388700e+00;
i1 = -2.40036700e-02;
i2 = -3.59849700e-02;
i3 = -5.32552100e-02;
i4 = -7.81225600e-02;
i5 = -1.13887200e-01;
I used:
a = Iph,
b = I0,
f = n,
c = Rs,
d = Rsh,
Vth = 0.0258
Here's my code:
clear all; clc;
N = 20;
tErr = 1e-6;
syms a b c d f
V1 = 1.00400400e+00; V2 = 1.02598500e+00; V3 = 1.05325500e+00; V4 = 1.08812300e+00; V5 = 1.13388700e+00; i1 = -2.40036700e-02; i2 = -3.59849700e-02; i3 = -5.32552100e-02; i4 = -7.81225600e-02 ; i5 = -1.13887200e-01;
m1 = d*(-i1 + a + b)/(0.0258*f); m2 = d*(-i2 + a + b)/(0.0258*f); m3 = d*(-i3 + a + b)/(0.0258*f); m4 = d*(-i4 + a + b)/(0.0258*f);
m5 = d*(-i5 + a + b)/(0.0258*f); n = .0258*f; k = b*d/n;
f1 = -i1*c-i1*d+a*d-n*lambertw(b*d*exp(m1)/n)-V1;
f2 = -i2*c-i2*d+a*d-n*lambertw(b*d*exp(m2)/n)-V2;
f3 = -i3*c-i3*d+a*d-n*lambertw(b*d*exp(m3)/n)-V3;
f4 = -i4*c-i4*d+a*d-n*lambertw(b*d*exp(m4)/n)-V4;
f5 = -i5*c-i5*d+a*d-n*lambertw(b*d*exp(m5)/n)-V5;
fs = [f1; f2; f3; f4; f5];
xs = [a; b; f; c; d];
jac = [d/lambertw(b*d*exp(m1)/n), -(n*lambertw(b*d*exp(m1)/n)-b*d)/(b*(1+lambertw(b*d*exp(m1)/n))), lambertw(b*d*exp(m1)/n)*(-n*lambertw(b*d*exp(m1)/n)-i1*d+a*d+b*d)/(f*(1+lambertw(b*d*exp(m1)/n))), -i1, -(n*lambertw(b*d*exp(m1)/n)+i1*d-a*d-b*d)/((1+lambertw(b*d*exp(m1)/n))*d);
d/lambertw(b*d*exp(m2)/n), -(n*lambertw(b*d*exp(m2)/n)-b*d)/(b*(1+lambertw(b*d*exp(m2)/n))), lambertw(b*d*exp(m2)/n)*(-n*lambertw(b*d*exp(m2)/n)-i2*d+a*d+b*d)/(f*(1+lambertw(b*d*exp(m2)/n))), -i2, -(n*lambertw(b*d*exp(m2)/n)+i2*d-a*d-b*d)/((1+lambertw(b*d*exp(m2)/n))*d);
d/lambertw(b*d*exp(m3)/n), -(n*lambertw(b*d*exp(m3)/n)-b*d)/(b*(1+lambertw(b*d*exp(m3)/n))), lambertw(b*d*exp(m3)/n)*(-n*lambertw(b*d*exp(m3)/n)-i3*d+a*d+b*d)/(f*(1+lambertw(b*d*exp(m3)/n))), -i3, -(n*lambertw(b*d*exp(m3)/n)+i3*d-a*d-b*d)/((1+lambertw(b*d*exp(m3)/n))*d);
d/lambertw(b*d*exp(m4)/n), -(n*lambertw(b*d*exp(m4)/n)-b*d)/(b*(1+lambertw(b*d*exp(m4)/n))), lambertw(b*d*exp(m4)/n)*(-n*lambertw(b*d*exp(m4)/n)-i4*d+a*d+b*d)/(f*(1+lambertw(b*d*exp(m4)/n))), -i4, -(n*lambertw(b*d*exp(m4)/n)+i4*d-a*d-b*d)/((1+lambertw(b*d*exp(m4)/n))*d);
d/lambertw(b*d*exp(m5)/n), -(n*lambertw(b*d*exp(m5)/n)-b*d)/(b*(1+lambertw(b*d*exp(m5)/n))), lambertw(b*d*exp(m5)/n)*(-n*lambertw(b*d*exp(m5)/n)-i5*d+a*d+b*d)/(f*(1+lambertw(b*d*exp(m5)/n))), -i5, -(n*lambertw(b*d*exp(m5)/n)+i5*d-a*d-b*d)/((1+lambertw(b*d*exp(m5)/n))*d)];
x = [1.2; 0.001; 1.5; 1; 15];
for i=1:N
f = double(subs(fs, xs, x));
j = double(subs(jac, xs, x));
x = x - inv(j)*f;
err = abs(inv(j)*f);
if(err<tErr)
break;
end
end
display(x);

how to Improve the speed matlab

This is my matlab code. It runs too slow and I had no clue how to improve it.
Could you help me to improve the speed?
What I would like to do is to create some random points and then remove the random points to make them similar to my target points.
syms Dx Dy p q;
a = 0;
num = 10;
x = rand(1,num);
y = rand(1,num);
figure(1)
scatter(x,y,'.','g')
%num_x = xlsread('F:\bin\test_2');% num 1024
%figure(2)
%scatter(num_x(:,1),num_x(:,2),'.','r');
q = 0;
num_q = 10;
x_q = randn(1,num_q);
y_q = randn(1,num_q);
%figure(2)
hold on;
scatter(x_q,y_q,'.','r')
for i = 1:num_q;
for j = 1:num_q;
qx(i,j) = x_q(i) - x_q(j);
qy(i,j) = y_q(i) - y_q(j);
%qx(i,j) = num_x(i,1) - num_x(j,1);
%qy(i,j) = num_x(i,2) - num_x(j,2);
%d~(s(i),s(j))
if ((qx(i,j))^2+(qy(i,j)^2))> 0.01 % find neighbours
qx(i,j) = 0;
qy(i,j) = 0;
end
end
end
for i = 1:num_q;
for j = 1:num_q;
if qx(i,j)>0&&qy(i,j)>0
q = q + exp(-(((Dx - qx(i,j))^2)+((Dy - qy(i,j))^2))/4);%exp(-(((Dx - qx(i,j))^2)+((Dy - qy(i,j))^2))/4);
end
end
end
%I = ones(num,num); % I(s) should from a grayscale image
%r = 1./sqrt(I);
for s = 1:100;
for i = 1:num;
for j = 1:num;
dx(i,j) = x(i) - x(j);
dy(i,j) = y(i) - y(j);
%d~(s(i),s(j))
if ((dx(i,j))^2+(dy(i,j)^2))> 0.05 % delta p, find neighbours
dx(i,j) = 0;
dy(i,j) = 0;
end
end
end
p = 0;
for i = 1:num;
for j = 1:num;
if dx(i,j)>0&&dy(i,j)>0
p = p + exp(-(((Dx - dx(i,j))^2)+((Dy - dy(i,j))^2))/4);
end
end
end
p = p - q;
sum = 0;
for i = 1:num;
for j = 1:num;
if dx(i,j)>0&&dy(i,j)>0;
kx(i,j) = (1/2)*(Dx-dx(i,j))*exp((-(Dx-dx(i,j))^2+(Dy-dy(i,j))^2)/4);
ky(i,j) = (1/2)*(Dy-dy(i,j))*exp((-(Dx-dx(i,j))^2+(Dy-dy(i,j))^2)/4);
end
end
end
sum_x = ones(1,num);% 1行N列0矩阵
sum_y = ones(1,num);
%fx = zeros(1,num);
for i = 1:num;
for j = 1:num;
if dx(i,j)>0&&dy(i,j)>0;
fx(i) = p*kx(i,j);% j is neighbour to i
fy(i) = p*ky(i,j);
%fx(i) = matlabFunction(fx(i));
%fy(i) = matlabFunction(fy(i));
%P =quad2d(#(Dx,Dy) fx,0,0.01,0,0.01);
%fx =quad(#(Dx) fx,0,0.01);
%fx(i) =quad(#(Dy) fx(i),0,0.01);
%Q =quad2d(#(Dx,Dy) fy,0,0.01,0,0.01);
fx(i) = double(int(int(fx(i),Dx,0,0.01),Dy,0,0.01));
fy(i) = double(int(int(fy(i),Dx,0,0.01),Dy,0,0.01));
%fx(i) = vpa(p*kx(i,j));
%fy(i) = vpa(p*ky(i,j));
%fx(i) = dblquad(#(Dx,Dy)fx(i),0,0.01,0,0.01);
%fy(i) = dblquad(#(Dx,Dy)fy(i),0,0.01,0,0.01);
sum_x(i) = sum_x(i) + fx(i);
sum_y(i) = sum_y(i) + fy(i);
end
end
end
for i = 1:num;
sum_x = 4.*sum_x./num;
sum_y = 4.*sum_y./num;
x(i) = x(i) - 0.05*sum_x(i);
y(i) = y(i) - 0.05*sum_y(i);
end
a = a+1
end
hold on;
scatter(x,y,'.','b')
The fast version of your loop should be something like:
qx = bsxfun(#minus, x_q.', x_q);
qy = bsxfun(#minus, y_q.', y_q);
il = (qx.^2 + qy.^2 >= 0.01);
qx(il) = 0;
qy(il) = 0;
il = qx>0 && qy>0;
q = sum(exp(-((Dx-qx(il)).^2 + (Dy-qy(il)).^2)/4));
%// etc. for vectorization of the inner loops

Simulate a custom function in Matlab

I'd like to simulate the following function:
l(t) = mu + Σ (1 + (t-t_i)/alpha)^(beta)
I wrote the function as follow:
function[l] = custom(m,t,H,par)
k = length(H);
n = length(t);
l = par.mu(m)*ones(n,1);
for i = 1:n
for j = 1:k
h = H{j};
h = h(h < t(i));
if ~isempty(h)
d = t(i) - h;
l(i) = l(i) + sum((1+ (d/par.alpha(m,j)))^ par.beta(m,j));
end
end
end
Now, how can I simulate this function for t=1000, par.mu= 0.5, par.alpha = 0.1, par.beta = 0.3?
I have the following code for simulation of this function but it's not efficient...How can I make it better?
function[h] = simcustom(t,par)
h = -log(rand)/par.mu;
if h < t
do5 = 1;
i = 0;
j = 0;
k = 0;
n = 1;
while true
if do5;
k = k + 1;
Lstar(k) = custom(1,h(n),{h},par); %#ok
end
j = j + 1;
U(j) = rand; %#ok
i = i + 1;
u(i) = -log(U(j))/Lstar(k); %#ok
if i == 1
Tstar(i) = u(i); %#ok
else
Tstar(i) = Tstar(i-1) + u(i);
end
if Tstar(i) > t
h = {h};
break
end
j = j + 1;
U(j) = rand;
if U(j) <= custom(1,Tstar(i),{h},par)/Lstar(k)
n = n + 1;
h = [h Tstar(i)];
do5 = true;
else
k = k + 1;
Lstar(k) = custom(1,Tstar(i),{h},par);
do5 = false;
end
end
else
h = {[]};
end
And here is the application:
par2.mu = 0.5;
par2.alpha = 0.1;
par2.beta = 0.3;
t = 1000;
h2 = simcustom(t,par2);

Perform step-by-step integral

I have this piece of code:
time = 614.4;
Uhub = 11;
HubHt = 90;
TI = 'A';
N1 = 4096;
N2 = 32;
N3 = 32;
L1 = Uhub*time;
L2 = 150;
L3 = 220;
V = L1*L2*L3;
gamma = 3.9;
c = 1.476;
b = 5.6;
if HubHt < 60
lambda1 = 0.7*HubHt;
else
lambda1 = 42;
end
L = 0.8*lambda1;
if isequal(TI,'A')
Iref = 0.16;
sigma1 = Iref*(0.75*Uhub + b);
elseif isequal(TI,'B')
Iref = 0.14;
sigma1 = Iref*(0.75*Uhub + b);
elseif isequal(TI,'C')
Iref = 0.12;
sigma1 = Iref*(0.75*Uhub + b);
else
sigma1 = str2num(TI)*Uhub/100;
end
sigma_iso = 0.55*sigma1;
%% Wave number vectors
ik1 = cat(2,(-N1/2:-1/2),(1/2:N1/2));
ik2 = -N2/2:N2/2-1;
ik3 = -N3/2:N3/2-1;
[x y z] = ndgrid(ik1,ik2,ik3);
k1 = reshape((2*pi*L/L1)*x,N1*N2*N3,1);
k2 = reshape((2*pi*L/L2)*y,N1*N2*N3,1);
k3 = reshape((2*pi*L/L3)*z,N1*N2*N3,1);
k = sqrt(k1.^2 + k2.^2 + k3.^2);
Now I should calculate
where
The procedure to calculate the integral is
At the moment I'm using this loop
E = #(k) (1.453*k.^4)./((1 + k.^2).^(17/6));
E_int = zeros(1,N1*N2*N3);
E_int(1) = 1.5;
for i = 2:(N1*N2*N3)
E_int(i) = E_int(i) + quad(E,i-1,i);
end
neglecting for the k>400 approximation. I believe that my loop is not right.
How would you suggest to calculate the integral?
I thank you in advance.
WKR,
Francesco
This is a list of correction from the more obvious to the possibly more subtle. (Indeed I start from what you wrote in the final part going upwards).
From what you write:
E = #(k) (1.453*k.^4)./((1 + k.^2).^(17/6));
E_int = zeros(1,N1*N2*N3);
E_int(1) = 1.5;
for i = 2:(N1*N2*N3)
%//No point in doing this:
%//E_int(i) = E_int(i) + quad(E,i-1,i);
%//According to what you write, it should be:
E_int(i) = E_int(i-1) + quad(E,i-1,i);
end
You could speed the whole thing up by doing
%//Independent integration on segments
Local_int = arrayfun(#(i)quad(E,i-1,i), 2:(N1*N2*N3));
Local_int = [1.5 Local_int];
%//integral additivity
E_int = cumsum(Local_int);
Moreover, if the known condition (point 2.) really is "... ( = 1.5 if k' = 0)", then the whole implementation should really be more like
%//Independent integration on segments
Local_int = arrayfun(#(i)quad(E,i-1,i), 2:(N1*N2*N3));
%//integral additivity + cumulative removal of queues
E_int = 1.5 - [0 fliplr(cumsum(fliplr(Local_int)))]; %//To remove queues