How to find the roots along a real line?
4 views (last 30 days)
Show older comments
Hi guys,
I am trying to determine the first 5 eigen frequencies of a bending beam with rotational and translational spring supports. This is done by setting the determinant of the coefficient matrix equal to zero. I use vpasolve to solve the equation, as I am solving a syms variable. The first 5 values I show get are: (found using Maple)
0.00285611175
0.0279531203
0.0435503148
0.0659083580
0.0912286729
But when I try solving this in matlab I get the following output:
0.00285611175750407
0.0279531203899501
0.0435503148892885
0.091228672905353
Can someone tell me why matlab does not find the 0.0659 value?
Is there a Matlab function to find the roots along a real line? My code is not very efficient due to the fact that I must first figure out in what range the first 5 eigen values lay before I can use the function I made. My code is attached.
Any advice would be appreciated!
0 Comments
Accepted Answer
Dana
on 23 Sep 2020
Numerical solvers are not guaranteed to find all roots of an expression. That's what's happening here. The algorithm vpasolve is using doesn't "notice" the root near 0.0659. If your start/end range bracketed that value, it would find it however:
>> vpasolve(freq,B, [.99,1.01]*0.0659)
ans =
0.06590835809882684726711430520395
Unless you can find a way to bracket each root like this, you'll never be 100% sure to catch all of them. One option to increase the likelihood of finding every root is to start with a small bracket, then gradually increase the upper bound until you find a root, then shift your bracket over. So for example, if you instead make your FindBeta function something like:
function Bet = FindBeta(FrequencyEquation, StartAt, EndAt, NumberOfBetas)
Bet = zeros(NumberOfBetas,1);
syms B
incStrt = 1e-9; % increment from previous root to start search for next root
incEnd = 1e-2; % increment to add to upper bound of search range each time
StrtRg = StartAt; % initial lower bound of search range
for i = 1:NumberOfBetas
EndRg = StrtRg + incEnd; % set initial upper bound of search range
NoRoot = true; % = true when we still haven't found the i-th root
while NoRoot
% try to get a root:
Beti = vpasolve(FrequencyEquation,B, [StrtRg; EndRg]);
if isempty(Beti) % if we didn't find a root
if EndRg > EndAt % if we've already exceeded EndAt
Beti = NaN; % indicate no such root exists using NaN
NoRoot = false; % stop searching
end
EndRg = EndRg + incEnd; % increase upper bound of search range
% and then try again
else % if we found a root
if Beti > EndRg % if the root exceeds EndAt
Beti = NaN; % indicate no such root exists using NaN
end
NoRoot = false; % flag that a root has been found
end
end
if isnan(Beti) % if the upper bound has been exceeded
Bet(i:end) = NaN; % set all remaining roots to NaN
return; % and then exit function
else % otherwise
Bet(i) = Beti; % store found root
StrtRg = Beti + incStrt; % increase the start range and repeat
end
end
end
Then:
Beta =
0.00285611175750407
0.0279531203899501
0.0435503148892885
0.0659083580988268
The parameter incEnd is a key one that must be tuned somehow. Smaller values make it more likely that you'll find all the roots, but at the cost of increasing the amount of time it takes to do so.
More Answers (0)
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!