Solution of transcendental equation in with Matlab - matlab

I have an equation which goes like this:
Here, I_L(lambdap) is the modified bessel function. This and product with exponential function can be written in matlab as besseli(L,lambdap,1). "i" stands for square root of -1. I want to solve:
1+pt+it=0
where I have to vary 'k' and find values of 'w'. I had posted similar problem at mathematica stack exchange, but I couldn't solve the problem fully, though i have got a clue (please go through the comments at mathematica stack exchange site). I could not convert my equation to the code that has been posted in clue. Any help in this regards will be highly appreciated.
Thanks in advance...

I never attempted this before, but... is this returning a suitable result?
syms w k;
fun = 1 + pt(w,k) + it(w,k);
sol = vpasolve(fun == 0,w,k);
disp(sol.w);
disp(sol.k);
function res = pt(w,k)
eps_l0 = w / (1.22 * k);
lam_k = 0.25 * k^2;
res = sym('res',[5 1]);
res_off = 1;
for L = -2:2
gam = besseli(L,lam_k) * exp(-lam_k);
eps_z = (w - L) / (1.22 * k);
zeta = 1i * sqrt(pi()) * exp(-eps_z^2) * (1 + erfc(1i * eps_z));
res(res_off,:) = ((25000 * gam) / k^2) * (1 + (eps_l0 * zeta));
res_off = res_off + 1;
end
res = sum(res);
end
function res = it(w,k)
eps_l0 = (w - (0.86 * k)) / (3.46 * k);
lam_k = 0.03 * k^2;
res = sym('res',[5 1]);
res_off = 1;
for L = -2:2
gam = besseli(L,lam_k) * exp(-lam_k);
eps_z = (w - (8 * L) - (0.86 * k)) / (3.46 * k);
zeta = 1i * sqrt(pi()) * exp(-eps_z^2) * (1 + erfc(1i * eps_z));
res(res_off,:) = ((2000000 * gam) / k^2) * (1 + (eps_l0 * zeta));
res_off = res_off + 1;
end
res = sum(res);
end
EDIT
For numeric k and symbolic w:
syms w;
for k = -3:3
fun = 1 + pt(w,k) + it(w,k);
sol = vpasolve(fun == 0,w);
disp(sol.w);
end

Related

Implementing i(t) function in Matlab

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

Assignment to an array defined outside parloop inside parfor

Consider the following code.
Wx = zeros(N, N);
for ii = 1 : 1 : N
x_ref = X(ii); y_ref = Y(ii);
nghlst_Local = nghlst(ii, find(nghlst(ii, :))); Nl = length(nghlst_Local);
x_Local = X(nghlst_Local, 1); y_Local = Y(nghlst_Local, 1);
PhiU = ones(Nl+1, Nl+1); PhiU(end, end) = 0;
Phi = ones(Nl+1, Nl+1); Phi(end, end) = 0;
Bx = zeros(Nl+1,1);
for jj = 1 : 1 : Nl
for kk = 1 : 1 : Nl
rx = x_Local(jj,1) - x_Local(kk,1);
ry = y_Local(jj,1) - y_Local(kk,1);
PhiU(jj, kk) = (1 - U(1,1))) / sqrt(rx^2 + ry^2 + c^2);
end
rx = x_ref - x_Local(jj);
ry = y_ref - y_Local(jj);
Bx(jj, 1) = ( (Beta * pi * U(1,1)/(2*r_0*norm(U))) * cos( (pi/2) * (-rx * U(1,1) - ry * U(2,1)) / (r_0 * norm(U)) ) ) / sqrt(rx^2 + ry^2 + c^2) - rx * (1 - Beta * sin( (pi/2) * (-rx * U(1,1) - ry * U(2,1)) / (r_0 * norm(U)) ))/ (rx^2 + ry^2 + c^2)^(3/2);
end
invPhiU = inv(PhiU);
CX = Bx' * invPhiU; CX = CX (1, 1:end-1); Wx (ii, nghlst_Local) = CX;
end
I want to convert the first for loop into parfor loop. The rest of the code works fine, but the following assignment statement does not work when I change for to parfor.
Wx (ii, nghlst_Local) = CX;
I want to know what is this is wrong and how to remove such errors. Thank you.

Matlab: resize with custom interpolation kernel Mitchell-Netravali

I have seen that there was an interest in custom interpolation kernels for resize (MATLAB imresize with a custom interpolation kernel). Did anyone implemented the parametric Mitchell-Netravali kernel [1] that is used as default in ImageMagick and is willing to share the Matlab code? Thank you very much!
[1] http://developer.download.nvidia.com/books/HTML/gpugems/gpugems_ch24.html
// Mitchell Netravali Reconstruction Filter
// B = 0 C = 0 - Hermite B-Spline interpolator
// B = 1, C = 0 - cubic B-spline
// B = 0, C = 1/2 - Catmull-Rom spline
// B = 1/3, C = 1/3 - recommended
float MitchellNetravali(float x, float B, float C)
{
float ax = fabs(x);
if (ax < 1) {
return ((12 - 9 * B - 6 * C) * ax * ax * ax +
(-18 + 12 * B + 6 * C) * ax * ax + (6 - 2 * B)) / 6;
} else if ((ax >= 1) && (ax < 2)) {
return ((-B - 6 * C) * ax * ax * ax +
(6 * B + 30 * C) * ax * ax + (-12 * B - 48 * C) *
ax + (8 * B + 24 * C)) / 6;
} else {
return 0;
}
}
Here I got another approach with vectorization; according to my tests with upscaling (1000x1000 -> 3000x3000) this is faster than the standard bicubic even with a large Mitchell radius = 6:
function [outputs] = Mitchell_vect(x,M_B,M_C)
outputs= zeros(size(x,1),size(x,2));
ax = abs(x);
temp = ((12-9*M_B-6*M_C) .* ax.^3 + (-18+12*M_B+6*M_C) .* ax.^2 + (6-2*M_B))./6;
temp2 = ((-M_B-6*M_C) .* ax.^3 + (6*M_B+30*M_C) .* ax.^2 + (-12*M_B-48*M_C) .* ax + (8*M_B + 24*M_C))./6;
index = find(ax<1);
outputs(index)=temp(index);
index = find(ax>=1 & ax<2);
outputs(index)=temp2(index);
end
I got the following proposal for the Mitchel kernel called by imresize with the parameters B and C and a kernel radius using for-loops (and preallocation):
img_resize = imresize(img, [h w], {#(x)Mitchell(x,B,C),radius});
function [outputs] = Mitchell(x,B,C)
outputs= zeros(size(x,1),size(x,2));
for i = 1 : size(x,1)
for j = 1 : size(x,2)
ax = abs(x(i,j));
if ax < 1
outputs(i,j) = ((12-9*B-6*C) * ax^3 + (-18+12*B+6*C) * ax^2 + (6-2*B))/6;
elseif (ax >= 1) && (ax < 2)
outputs(i,j) = ((-B-6*C) * ax^3 + (6*B+30*C) * ax^2 + (-12*B-48*C) * ax + (8*B + 24*C))/6;
else
outputs(i,j) = 0;
end
end
end
end

How can I fix the link between the multiplier and eqn(x)?

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

Using NonNegative setting in Matlab odeset()

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! :)