I am right now stuck on a problem in matlab. What I have done is that I have an equation that is passed on into another function which works by the bisection-method.
But I have a multiplier that I am trying to implement which somehow leads to the function crashing.
Before I introduced the multiplier it all worked, I tried breaking it down by entering the multiplier value manually and it didn't work
P_{1} = 0.6;
P_{2} = 0.2;
P_{3} = 0.2;
a_1 = 4/3;
a_2 = -7/3;
b_1 = -1/3;
b_2 = 4/3;
persistent multiplier
multiplier = exp(a_1 * 44 + a_2 * 14 + 0);
eqn = #(x) ((a_1 * x + b_1)^a_1) * ((a_2 * x + b_2)^a_2) * x ...
-(P_{1}^a_1) * (P_{2}^a_2) * P_{3} * multiplier;
Q_{3} = Bisectionmethod(a_1, a_2, b_1, b_2, eqn);
Here is the calculating part of the bisection method.
x_lower = max(0, -b_1 / a_1);
x_upper = -b_2 / a_2;
x_mid = (x_lower + x_upper)/2;
Conditional statement encompassing the method of bisection
while abs(eqn(x_mid)) > 10^(-10)
if (eqn(x_mid) * eqn(x_upper)) < 0
x_lower = x_mid;
else
x_upper = x_mid;
end
x_mid = (x_lower + x_upper)/2;
end
Based on the information you provided this is what I came up with
function Q = Stackoverflow
persistent multiplier
P{1} = 0.6;
P{2} = 0.2;
P{3} = 0.2;
a1 = 4/3;
a2 = -7/3;
b1 = -1/3;
b2 = 4/3;
multiplier = exp(a1 * 44 + a2 * 14 + 0);
eqn = #(x) ((a1 .* x + b1).^a1) .* ((a2 .* x + b2).^a2) .* x -(P{1}.^a1) .* (P{2}.^a2) .* P{3} .* multiplier;
Q{3} = Bisectionmethod(eqn, max([0, -b1/a1]), -b2/a2, 1E-10);
end
function XOut = Bisectionmethod(f, xL, xH, EPS)
if sign(f(xL)) == sign(f(xH))
XOut = [];
error('Cannot bisect interval because can''t ensure the function crosses 0.')
end
x = [xL, xH];
while abs(diff(x)) > EPS
x(sign(f(mean(x))) == sign(f(x))) = mean(x);
end
XOut = mean(x);
end
Related
I have a problem in which I have to implement the following question in Matlab.
i(t) = A2 * sin(wr*t) * exp(-alpha*t); for t [0, 10] with step 0.5s
My approach is as follows
clc;
clear;
% Given Data
Vs = 220;
L = 5e-3;
C = 10e-6;
R = 22;
Vo = 50;
% a)
alpha = R / (2 * L);
omega_not = 1 / sqrt(L*C);
omega_r = sqrt( omega_not^2 - alpha^2 );
A2 = Vs / (omega_r * L);
t = 1:0.5:10;
i = A2 * sin( omega_r * t ) .* exp(-alpha * t);
% b)
t1 = pi / omega_r;
% c)
plot(t, i);
But it yields all the values of current equal to zero. Please help me solve the problem.
I think the problem is this part of the expression:
exp(-alpha * t)
When I run your code, -alpha equals -2200. The exponential for such a large negative number is so small that the code returns zero.
>> exp(-200)
ans =
1.3839e-87
>> exp(-1000)
ans =
0
I have two lines y1 = -a1*x1 + c1 for theta =30 and y1 = -a2*x1 + c2 for theta = 45
is it possible to interpolate a equation for y1 for theta between 30 and 45 in matlab ? The lines are almost parallel to each other. Anyone has an easy way of doing this?
You can interpolate the coeff a and c:
w = (theta - 30) / (45 - 30 ); % w = 0 for theta = 30 and w = 1 for theta = 45
aTheta = a2 * w + a1 * ( 1 - w );
cTheat = c2 * w + c1 * ( 1 - w );
yTheta = -aTheta * x + cTheta * y;
x = 1:10;
a30 = 1;
a45 = 1.1;
c30 = 0;
c45 = 3;
y30 = -a1*x + c1;
y45 = -a2*x + c2;
Now to find y40 we can just interpolate the curve parameters (i.e. slope (a) and offset (c))
a40 = interp1([30,45], [a30, a45], 40);
c40 = interp1([30,45], [c30, c45], 40);
And now our interpolated y40 is
y40 = -a40*x + c40;
plot(x,y30,x,y45,x,y40);
I am trying to replicate the results of a paper (Immune Response). In short, it looks at the concentration of pathogens, antibodies and plasma cells, and the effect the immune response has on an organ. Depending on the state of the organ, a variable which affects the concentration of plasma cells will change.
I have modeled this in Matlab. My issue is that the conditional statements for the plasma-concentration-affecting variable is being ignored. By commenting out portions of the code and looking at the graphs, regardless of what the second condition is, the output is only responding to the initial condition.
How can I update values so that they are interpreted by ode45 (or ode23) and is there a better approach to approach this problem?
My code is below.
function dx = iir_2(t, x)
dx = [0; 0; 0; 0];
a11 = 1;
a31 = 1;
a41 = 1;
a12 = 1;
a22 = 3;
a32 = 1.5;
a42 = 1;
a23 = 1;
a33 = 0.5;
b1 = -1;
b2 = 1;
b3 = 1;
b4 = -1;
u1 = 0;
u2 = 0;
u3 = 0;
u4 = 0;
tau = 0.1;
if x(4) >= 0.5
a21x4 = 0;
else
a21x4 = cos(pi * x(4));
end
if x(4) > 1
x(4) = 1;
end
dx(1) = (a11 - a12 * x(3)) * x(1) + b1 * u1;
dx(2) = a21x4 * a22 * x(1) * (t - tau) * x(3) * (t - tau) - a23 * (x(2) - 2) + b2 * u2;
dx(3) = a31 * x(2) - (a32 + a33 * x(1)) * x(3) + b3 * u3;
dx(4) = a41 * x(1) - a42 * x(4) + b4 * u4;
This second script that calls the above function is..
Case = ['Subclinical' 'Clinical' 'Chronic' 'Lethal'];
x1_0 = [1.5 2 2.57 3];
x2_0 = 2;
x3_0 = (1*x2_0)/1.5;
x4_0 = 0;
for i = 1:4
if i == 1
state = 'Subclinical';
elseif i == 2
state = 'Clinical';
elseif i == 3
state = 'Chronic';
else
state = 'Lethal';
end
options = odeset('RelTol', 1e-3, 'NonNegative', [1 2 3 4]);
[t,x] = ode45(#iir_2, [0 10], [x1_0(i) x2_0 x3_0 x4_0], options); % use ode23???
figure
plot(t,x);
str = sprintf('Case Number = %d\nx(0) = %d\n%s', i, x1_0(i), state);
title(str);
axis([0,10,0,10])
legend('Pathogen', 'Plasma Cell', 'Antibody', 'Organ');
end
The conditional statements are in the function.
if x(4) >= 0.5
a21x4 = 0;
else
a21x4 = cos(pi * x(4));
end
if x(4) > 1
x(4) = 1;
end
There are two ways of doing this.
Either way you need to understand that you cannot just set x(4) to 1 and hope everything works out for the best. Matlab won't care about the preceding values of x(4) as they are all stored in memory. Furthermore, the upcoming value of x(4) is determined by dx(4) and the previously retained values of x(4) (which you cannot set).
You have two possible solutions to your problem:
A) set dx(4) = 0 when your condition is met
if x(4) > 1
dx(4) = 0;
else
dx(4) = a41 * x(1) - a42 * x(4) + b4 * u4;
end
This however will not result in a perfect x(4) = 1, rather there will be a small error.
B) Calling an event function, which can be learned about here and here, in which case you can interrupt for a new function call.
can someone help me how to show gabor filter in matlab, i can show it but its not what i want. this is my code :
[Gf,gabout] = gaborfilter1(B,sx,sy,f,theta(j));
G{m,n,i,j} = Gf;
and this is gabor filter class:
function [Gf,gabout] = gaborfilter(I,Sx,Sy,f,theta);
if isa(I,'double')~=1
I = double(I);
end
for x = -fix(Sx):fix(Sx)
for y = -fix(Sy):fix(Sy)
xPrime = x * cos(theta) + y * sin(theta);
yPrime = y * cos(theta) - x * sin(theta);
Gf(fix(Sx)+x+1,fix(Sy)+y+1) = exp(-.5*((xPrime/Sx)^2+(yPrime/Sy)^2))*cos(2*pi*f*xPrime);
end
end
Imgabout = conv2(I,double(imag(Gf)),'same');
Regabout = conv2(I,double(real(Gf)),'same');
gabout = sqrt(Imgabout.*Imgabout + Regabout.*Regabout);
Then, I imshow with this code:
imshow(G{m,n,i,j},[]);
and the results :
But i want this result, can someone help me how to slove this?
Use the following function. I hope this is useful.
----------------------------------------------------------------
gfs = GaborFilter(51,0.45,0.05,6,4);
n=0;
for s=1:6
for d=1:4
n=n+1;
subplot(6,4,n)
imshow(real(squeeze(gfs(s,d,:,:))),[])
end
end
Sample Image
----------------------------------------------------------------
function gfs = GaborFilter(winLen,uh,ul,S,D)
% gfs(SCALE, DIRECTION, :, :)
winLen = winLen + mod(winLen, 2) -1;
x0 = (winLen + 1)/2;
y0 = x0;
if S==1
a = 1;
su = uh/sqrt(log(4));
sv = su;
else
a = (uh/ul)^(1/(S-1));
su = (a-1)*uh/((a+1)*sqrt(log(4)));
if D==1
tang = 1;
else
tang = tan(pi/(2*D));
end
sv = tang * (uh - log(4)*su^2/uh)/sqrt(log(4) - (log(4)*su/uh)^2);
end
sx = 1/(2*pi*su);
sy = 1/(2*pi*sv);
coef = 1/(2*pi*sx*sy);
gfs = zeros(S, D, winLen, winLen);
for d = 1:D
theta = (d-1)*pi/D;
for s = 1:S
scale = a^(-(s-1));
gab = zeros(winLen);
for x = 1:winLen
for y = 1:winLen
X = scale * ((x-x0)*cos(theta) + (y-y0)*sin(theta));
Y = scale * (-(x-x0)*sin(theta) + (y-y0)*cos(theta));
gab(x, y) = -0.5 * ( (X/sx).^2 + (Y/sy).^2 ) + (2*pi*1j*uh)*X ;
end
end
gfs(s, d, :, :) = scale * coef * exp(gab);
end
end
Replace the "cos" component by complex part->complex(0, (2*pi*f*xprime)) ans also multiply equation by scaling factor of (1/sqrt(2*Sy*Sx)).
I'm trying to solve some ODEs in MatLab and seeing as the variables in the equations are populations they need to be constrained to being positive. So I tried using odeset() before calling the equation solver to make them non-negative but on plotting the values afterwards they are actually negative at times (in the code below it is the magenta line). What am I doing wrong?
Here's some code:
%Lots of variables
includeJ=1;
cullLIRate=1/2000;
cullDIRate=1/2000;
N = 16800;
beta = 2e-7;
delta = 0.5;
gamma = 1/50;
sigma = 1/400;
mu = 1/365;
maxTime = 30*365;
kappa = N;
gR = 0.05;
mJ = 1/3650;
initJPerAdult = 10;
numInitE = 1000;
TSpan = [0,maxTime];
initState = [N-numInitE,numInitE,0,0,0,initJPerAdult*N];
%IMPORTANT BIT HERE
options = odeset('NonNegative', 1:6)
scirSoln = ode45(#equation,TSpan,initState,[],beta,delta,gamma,sigma,mu,kappa,gR,mJ,cullLIRate,cullDIRate,includeJ);
scirVals = deval(scirSoln,timeToPlot);
plot(timeToPlot,scirVals(1,:));
hold on;
plot(timeToPlot,scirVals(3,:),'k');
plot(timeToPlot,scirVals(4,:),'g');
plot(timeToPlot,scirVals(6,:),'m');
timeToPlot = [0:max(TSpan)/1000:max(TSpan)];
The code for equation(...) is:
function retVal = equation(t,y,beta,delta,gamma,sigma,mu,kappa,gR,mJ,cullLIRate,cullDIRate,includeJ)
retVal = zeros(6,1);
S = y(1);
E = y(2);
LI = y(3);
DI = y(4);
R = y(5);
J = y(6);
retVal(1)= mJ * J - beta * S * (delta * LI + DI);
retVal(2) = beta * S * (delta * LI + DI) - gamma * E;
retVal(3) = gamma * E - (cullLIRate + sigma) * LI;
retVal(4) = sigma * LI - (mu + cullDIRate) * DI;
retVal(5) = mu * DI + cullLIRate* LI + cullDIRate * DI;
retVal(6) = gR * S * (1 - S / kappa) - mJ * J;
end
You are not passing your defined odeset (options variable) to the ODE45 - solver.
The syntax for the ODE45 is: [T,Y] = ODE45(ODEFUN,TSPAN,Y0,OPTIONS,P1,P2...)
Glad it worked! :)