I am trying to plot roots of a function that is composed of multiple bessel functions being added and multiplied in Matlab. The equation is Jm(omega)*Ik(omega)+Im(omega)*Jk(omega) where Jm is the bessel function of the first kind of order m (besselj). Im is the modified bessel function of the first kind of order m (besseli). For each mode m=o,1,2,...and n=1,2,3... The frequency omega(mn) is the corresponding root of the listed equation. m=0,1,2 n-1,2,3,4. I need to solve the equation for the 12 roots. I am new to Matlab and this is a little out of my league. So far I have this code but I wasn't sure if I needed the variable omega in the script or not. I have also looked at other people's questions on the suject but didn't see any quite like this. The plots I have seen look nothing like mine which tells me I am probably wrong. Thanks for any help.
m=(0:2); k=(1:3); n=(1:4);
Jm=besselj(m,n');
Ik=besseli(k,n');
Jk=besselj(k,n');
Im=besseli(m,n');
g=Jm.*Ik+Im.*Jk
plot(g)
Plotting
besselj and besseli take what you call omega as their second parameter, so to plot your function you should try something like
m=0; k=1; omega=0:0.02:10;
Jm=besselj(m,omega);
Ik=besseli(k,omega);
Jk=besselj(k,omega);
Im=besseli(m,omega);
g=Jm.*Ik+Im.*Jk;
plot(omega,g);
hold all;
plot(omega,0,'k');
axis([min(omega) max(omega) -100 100]);
This shows you that for m=1, k=1 the first zeros are around 3.2, 6.3 and 9.4:
Finding the roots numerically
You could implement Halley's method for your function g, similar to how the roots of besselj are determined in the MatlabCentral file linked by Cheery.
Related
I'm writing a function that calculates the Taylor series of any Function.
syms x
y=cos(x);
y0=0;
a=0;
for i=0:25
diff(y,i); %%Gives the derivative formula
y0=y0+diff(y,i)*((x-a)^i)/factorial(i); %%sums every new element of the series
end
x=0:0.1:2*pi;
res = subs(y0,x);
plot(x,res,x,cos(x))
This is the Matlab code.
My problem is that it graphs cos(2x) instead of cos(x), similarly it graphs ln(2x) instead of ln(x) and so on.
I have checked the factorials and they appear to be correct.
What could be the problem, have I messed up the series or have I made a Matlab mistake?
You are constructing the Taylor polynomial around the point x with incrementx-a, that is, you are computing an approximation for
f(x+(x-a))=f(2*x-a)
Now as a=0, this means that as observed, you get f(2*x).
You would need to evaluate the derivatives at a to get the correct coefficients.
y0=y0+subs(diff(y,i),a)*((x-a)^i)/factorial(i); %%sums every new element of the series
I'm having some trouble with a script that I need to plot the TE and TM modes of a circular waveguide.
Everything is based on these formulas:
Right now I'm focused on the TE modes and what I have to plot is the field vector e_mn'' inside a squared-mesh equal to the radius of the waveguide.
To do it I need to compute the bessel function of the first kind and extract x_mn that correspond to the n-th root in which the function is equal to zero. These points are supposed to be real but positive.
I followed this example
https://www.mathworks.com/examples/matlab/community/22719-roots-of-a-bessel-function
but I get an error:
Undefined function 'isfinite' for input arguments of type> 'function_handle'. Error in roots (line 26) if ~all(isfinite(c)) Error
in circular (line 20)
x_mn=roots(J0)
This is my code. Can you help me?
clc
clear all
close all
a=20; %radius
m=0;
n=1;
%%
if m==0
ki_m=1;
else
ki_m=sqrt(2);
end
r=0:0.1:a;
J0 = #(r) besselj(0,r);
%J0 = besselj(m,r);
%plot(J0)
x_mn=roots(J0)
%plot(J0(x_mn))
%x_mn=abs(x_mn);
k_mn=x_mn./a;
F_mn=(ki_m*k_mn)./(J0(x_mn)*sqrt(pi*(x_mn^2-m^2)));
for r=0:1:a
for phi=0:1*pi/180:2*pi
e_mnR=-F_mn.*(J0(k_mn*r)/(k_mn.*r))*sin(m*phi);
e_mnPHI=F_mn.*J0(k_mn*r)*cos(m*phi);
end
end
e_mnR=abs(e_mnR);
e_mnPHI=abs(e_mnPHI);
X=0:1:a;
[X,Y] = meshgrid(1:1:a);
quiver(X,Y,e_mnR,e_mnPHI);
hold on
This is not my area of expertise so take this with a grain of salt, but I did some googling and think I know what's going on:
The code you are working from in the provided link defines:
J0 = chebfun(#(x) besselj(0,x),[0 100]);
Note the link from your reference to a Chebfun example is dead, but I read here that:
Chebfun is an open-source package for computing with functions to about 15-digit accuracy. Most Chebfun commands are overloads of familiar MATLAB commands...
The only reason the example you cited works is because J0 is defined using Chebfun, which overloads the matlab command roots with its own version that works on a function handle. Maybe read more here and try using this tool if you want to replicate that code example. Hope this helps...
You can use fzero instead of roots, but you confused polar and cartesian coordinates in the plot section and dimensions of vectors don't agree
I'm using octave 3.8.1 which works like matlab.
I have an array of thousands of values I've only included three groupings as an example below:
(amp1=0.2; freq1=3; phase1=1; is an example of one grouping)
t=0;
amp1=0.2; freq1=3; phase1=1; %1st grouping
amp2=1.4; freq2=2; phase2=1.7; %2nd grouping
amp3=0.8; freq3=5; phase3=1.5; %3rd grouping
The Octave / Matlab code below solves for Y so I can plug it back into the equation to check values along with calculating values not located in the array.
clear all
t=0;
Y=0;
a1=[.2,3,1;1.4,2,1.7;.8,5,1.5]
for kk=1:1:length(a1)
Y=Y+a1(kk,1)*cos ((a1(kk,2))*t+a1(kk,3))
kk
end
Y
PS: I'm not trying to solve for Y since it's already solved for I'm trying to solve for Phase
The formulas located below are used to calculate Phase but I'm not sure how to put it into a for loop that will work in an array of n groupings:
How would I write the equation / for loop for finding the phase if I want to find freq=2.5 and amp=.23 and the phase is unknown I've looked online and it may require writing non linear equations which I'm not sure how to convert what I'm trying to do into such an equation.
phase1_test=acos(Y/amp1-amp3*cos(2*freq3*pi*t+phase3)/amp1-amp2*cos(2*freq2*pi*t+phase2)/amp1)-2*freq1*pi*t
phase2_test=acos(Y/amp2-amp3*cos(2*freq3*pi*t+phase3)/amp2-amp1*cos(2*freq1*pi*t+phase1)/amp2)-2*freq2*pi*t
phase3_test=acos(Y/amp3-amp2*cos(2*freq2*pi*t+phase2)/amp3-amp1*cos(2*freq1*pi*t+phase1)/amp3)-2*freq2*pi*t
Image of formula below:
I would like to do a check / calculate phases if given a freq and amp values.
I know I have to do a for loop but how do I convert the phase equation into a for loop so it will work on n groupings in an array and calculate different values not found in the array?
Basically I would be given an array of n groupings and freq=2.5 and amp=.23 and use the formula to calculate phase. Note: freq will not always be in the array hence why I'm trying to calculate the phase using a formula.
Ok, I think I finally understand your question:
you are trying to find a set of phase1, phase2,..., phaseN, such that equations like the ones you describe are satisfied
You know how to find y, and you supply values for freq and amp.
In Matlab, such a problem would be solved using, for example fsolve, but let's look at your problem step by step.
For simplicity, let me re-write your equations for phase1, phase2, and phase3. For example, your first equation, the one for phase1, would read
amp1*cos(phase1 + 2 freq1 pi t) + amp2*cos(2 freq2 pi t + phase2) + amp3*cos(2 freq3 pi t + phase3) - y = 0
Note that ampX (X is a placeholder for 1, 2, 3) are given, pi is a constant, t is given via Y (I think), freqX are given.
Hence, you are, in fact, dealing with a non-linear vector equation of the form
F(phase) = 0
where F is a multi-dimensional (vector) function taking a multi-dimensional (vector) input variable phase (comprised of phase1, phase2,..., phaseN). And you are looking for the set of phaseX, where all of the components of your vector function F are zero. N.B. F is a shorthand for your functions. Therefore, the first component of F, called f1, for example, is
f1 = amp1*cos(phase1+...) + amp2*cos(phase2+...) + amp3*cos(phase3+...) - y = 0.
Hence, f1 is a one-dimensional function of phase1, phase2, and phase3.
The technical term for what you are trying to do is find a zero of a non-linear vector function, or find a solution of a non-linear vector function. In Matlab, there are different approaches.
For a one-dimensional function, you can use fzero, which is explained at http://www.mathworks.com/help/matlab/ref/fzero.html?refresh=true
For a multi-dimensional (vector) function as yours, I would look into using fsolve, which is part of Matlab's optimization toolbox (which means I don't know how to do this in Octave). The function fsolve is explained at http://www.mathworks.com/help/optim/ug/fsolve.html
If you know an approximate solution for your phases, you may also look into iterative, local methods.
In particular, I would recommend you look into the Newton's Method, which allows you to find a solution to your system of equations F. Wikipedia has a good explanation of Newton's Method at https://en.wikipedia.org/wiki/Newton%27s_method . Newton iterations are very simple to implement and you should find a lot of resources online. You will have to compute the derivative of your function F with respect to each of your variables phaseX, which is very simple to compute since you're only dealing with cos() functions. For starters, have a look at the one-dimensional Newton iteration method in Matlab at http://www.math.colostate.edu/~gerhard/classes/331/lab/newton.html .
Finally, if you want to dig deeper, I found a textbook on this topic from the society for industrial and applied math: https://www.siam.org/books/textbooks/fr16_book.pdf .
As you can see, this is a very large field; Newton's method should be able to help you out, though.
Good luck!
Say for example I have data which forms the parabolic curve y=x^2, and I want to read off the x value for a given y value. How do I go about doing this in MATLAB?
If it were a straight line, I could just use the equation of the line of best fit to calculate easily, however I can't do this with a curved line. If I can't find a solution, I'll solve for roots
Thanks in advance.
If all data are arrays (not analytical expressions), I usually do that finding minimal absolute error
x=some_array;
[~,ind]=min(abs(x.^2-y0))
Here y0 is a given y value
If your data are represented by a function, you can use fsolve:
function y = myfun(x)
y=x^2-y0
[x,fval] = fsolve(#myfun,x0,options)
For symbolic computations, one can use solve
syms x
solve(x^2 - y0)
Assuming your two curves are just two vectors of data, I would suggest you use Fast and Robust Curve Intersections from the File Exchange. See also these two similar questions: how to find intersection points when lines are created from an array and Finding where plots may cross with octave / matlab.
I'm trying to teach myself how to use MATLAB for solving state-space systems, I have what seems to be a pretty straight-forward system but have been unable to find any decent straight-forward examples for a novice thus far.
I'd like a simple walk-through of how to translate the system into MATLAB, what variables to set, and how to solve for about 50(?) seconds (from t=0 to 50 or any value really).
I'd like to use ode45 since it's a 4th order method using a Runge-Kutta variant.
Here's the 2nd-order equation:
θ''+0.03|θ'|θ'+4pi^2*sinθ=0
The state-space:
x_1'=x_2
x_2'=-4pi^2*sin(x_1)-0.03|x_2|x_2
x_1 = θ, x_2 = θ'
θ(0)=pi/9 rad, θ'(0)=0, h(step)=1
You need a derivative function function, which, given the current state of the system and the current time, returns the derivative of all of the state variables. Generally this function is of the form
function xDash=derivative(t,x)
and xDash is a vector with the derivative of each element, and x is a vector of the state variables. If your variables are called x_1, x_2 etc. it's a good idea to put x_1 in x(1), etc. Then you need a formula for the derivative of each state variable in terms of the other state variables, for example you could have xDash_1=x_1-x_2 and you would code this as xDash(1)=x(1)-x(2). Hopefully that clears something up.
For your example, the derivative function will look like
function xDash=derivative(t,x)
xDash=zeros(2,1);
xDash(1)=x(2);
xDash(2)=-4*pi^2*sin(x(1))-0.03*abs(x(2))*x(2);
end
and you would solve the system using
[T,X]=ode45(#derivative,0:50,[pi/9 0]);
This gives output at t=0,1,2,...,50.