Simulate a custom function in Matlab - 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);

Related

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

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)

Matlab - ode15s "Too many Input Arguments"

I am trying to create a program to solve a moment methods for a polymer reaction. However, when im run the code this error appears "Too many Input Arguments", any help? (sorry for bad english)
Code:
First function
function dydt = osc(t,y)
ka1 = 10^6;
ka2 = 0.15*10^6;
kp = 2952;
kd = 0.106*2952;
ks = 10^6;
%y=[C,A,ROH,I,M,Lambda,Mi] <=> y(1,:)=[C] ; y(2,:)=[A]
% y(3,:)=[ROH] ; y(4,:)=[I]
% y(5,:)=[M] ;
% y(6-8,:)=[Lambda] onde: %y(6) - lambda0 ;
y(7) - lambda1 ; y(8) - lambda2
% y(9-11,:)=[Mi] onde: %y(9) - mi0 ; y(10) -
mi1 ; y(11) - mi2
% y(12,:)=[R1] ; y(13;:) = [D1]
j = 10;
syms n
%Variables
dydt(1,1) = - ka1*y(1)*y(3) + ka2*y(4)*y(2) - ka1*y(1)
dydt(2,1) = + ka1*y(1)*y(3) - ka2*y(4)*y(2) + ka1*y(1)
dydt(3,1) = - ka1*y(1)*y(3) + ka2*y(4)*y(2) - ks*y(3)*
dydt(4,1) = - kp*y(5)*y(4) + kd*y(12) + ka1*y(1)*y(3) - ka2*y(4)*y(2)
%Living Chains
dydt(6,1) = + ka1*y(1)*symsum((n^0)*y(9), n, [1 j])
dydt(7,1) = + ka1*y(1)*symsum((n^1)*y(10), n, [1 j])
dydt(8,1) = + ka1*y(1)*symsum((n^2)*y(11), n, [1 j])
%Dormant Chains
dydt(9,1) = - ka1*y(1)*symsum((n^0)*y(9), n, [1 j])
dydt(10,1) = - ka1*y(1)*symsum((n^1)*y(10), n, [1 j]) +
dydt(11,1) = - ka1*y(1)*symsum((n^2)*y(11), n, [1 j])
%R1 e D1
dydt(12,1) = + kp*y(5)*y(4) - kp*y(5)*y(12) + kd*((y(12)+1) - y(12))
dydt(13,1) = - ka1*y(1)*y(13) + ka2*y(2)*y(13) + ks*y(3)*y(12)
end
Second function
function [t,y]= call_osc()
%Tempo
tspan = [0 1];
%Initial conditions
C = 2.582;
A = 3.9*10^3;
ROH = 0.387*10^2;
I = 10^3;
M = 1460.495;
Rn0 = 0;
Rn1 = 0;
Rn2 = 0;
Dn0 = 0;
Dn1 = 0;
Dn2 = 0;
R1 = 1;
D1 = 1;
y0 = [C; A; ROH; I; M; Rn0; Rn1; Rn2; Dn0; Dn1; Dn2; R1; D1];
[t,y] = ode15s(#osc, tspan, y0);
disp(y(:,1))
end

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

Vectorizing 4 nested for loops

I'm trying to vectorize the 2 inner nested for loops, but I can't come up with a way to do this. The FS1 and FS2 functions have been written to accept argument for N_theta and N_e, which is what the loops are iterating over
%% generate regions
for raw_r=1:visual_field_width
for raw_c=1:visual_field_width
r = raw_r - center_r;
c = raw_c - center_c;
% convert (r,c) to polar: (eccentricity, angle)
e = sqrt(r^2+c^2)*deg_per_pixel;
a = mod(atan2(r,c),2*pi);
for nt=1:N_theta
for ne=1:N_e
regions(raw_r, raw_c, nt, ne) = ...
FS_1(nt-1,a,N_theta) * ...
FS_2(ne-1,e,N_e,e0_in_deg, e_max);
end
end
end
end
Ideally, I could replace the two inner nested for loops by:
regions(raw_r,raw_c,:,:) = FS_1(:,a,N_theta) * FS_2(:,N_e,e0_in_deg,e_max);
But this isn't possible. Maybe I'm missing an easy fix or vectorization technique? e0_in_deg and e_max are parameters.
The FS_1 function is
function h = FS_1(n,theta,N,t)
if nargin==2
N = 9;
t=1/2;
elseif nargin==3
t=1/2;
end
w = (2*pi)/N;
theta = theta + w/4;
if n==0 && theta>(3/2)*pi
theta = theta - 2*pi;
end
h = FS_f((theta - (w*n + 0.5*w*(1-t)))/w);
the FS_2 function is
function g = FS_gne(n,e,N,e0, e_max)
if nargin==2
N = 10;
e0 = .5;
elseif nargin==3
e0 = .5;
end
w = (log(e_max) - log(e0))/N;
g = FS_f((log(e)-log(e0)-w*(n+1))/w);
and the FS_f function is
function f = FS_f(x, t)
if nargin<2
t = 0.5;
end
f = zeros(size(x));
% case 1
idx = x>-(1+t)/2 & x<=(t-1)/2;
f(idx) = (cos(0.5*pi*((x(idx)-(t-1)/2)/t))).^2;
% case 2
idx = x>(t-1)/2 & x<=(1-t)/2;
f(idx) = 1;
% case 3
idx = x>(1-t)/2 & x<=(1+t)/2;
f(idx) = -(cos(0.5*pi*((x(idx)-(1+t)/2)/t))).^2+1;
I had to assume values for the constants, and then used ndgrid to find the possible configurations and sub2ind to get the indices. Doing this I removed all loops. Let me know if this produced the correct values.
function RunningFunction
%% generate regions
visual_field_width = 10;
center_r = 2;
center_c = 3;
deg_per_pixel = 17;
N_theta = 2;
N_e = 5;
e0_in_deg = 35;
e_max = 17;
[raw_r, raw_c, nt, ne] = ndgrid(1:visual_field_width, 1:visual_field_width, 1:N_theta, 1:N_e);
ind = sub2ind(size(raw_r), raw_r, raw_c, nt, ne);
r = raw_r - center_r;
c = raw_c - center_c;
% convert (r,c) to polar: (eccentricity, angle)
e = sqrt(r.^2+c.^2)*deg_per_pixel;
a = mod(atan2(r,c),2*pi);
regions(ind) = ...
FS_1(nt-1,a,N_theta) .* ...
FS_2(ne-1,e,N_e,e0_in_deg, e_max);
regions = reshape(regions, size(raw_r));
end
function h = FS_1(n,theta,N,t)
if nargin==2
N = 9;
t=1/2;
elseif nargin==3
t=1/2;
end
w = (2*pi)./N;
theta = theta + w/4;
theta(n==0 & theta>(3/2)*pi) = theta(n==0 & theta>(3/2)*pi) - 2*pi;
h = FS_f((theta - (w*n + 0.5*w*(1-t)))/w);
end
function g = FS_2(n,e,N,e0, e_max)
if nargin==2
N = 10;
e0 = .5;
elseif nargin==3
e0 = .5;
end
w = (log(e_max) - log(e0))/N;
g = FS_f((log(e)-log(e0)-w*(n+1))/w);
end
function f = FS_f(x, t)
if nargin<2
t = 0.5;
end
f = zeros(size(x));
% case 1
idx = x>-(1+t)/2 & x<=(t-1)/2;
f(idx) = (cos(0.5*pi*((x(idx)-(t-1)/2)/t))).^2;
% case 2
idx = x>(t-1)/2 & x<=(1-t)/2;
f(idx) = 1;
% case 3
idx = x>(1-t)/2 & x<=(1+t)/2;
f(idx) = -(cos(0.5*pi*((x(idx)-(1+t)/2)/t))).^2+1;
end

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