2016-11-21 16 views
1

Я хотел бы решить следующее уравнение: загар (х) = 1/хКак я могу получить все решения для этого уравнения в MATLAB?

Что я сделал:

syms x 
eq = tan(x) == 1/x; 
sol = solve(eq,x) 

Но это дает мне только одно числовое приближение решения. После этого я прочитал примерно следующее:

[sol, params, conds] = solve(eq, x, 'ReturnConditions', true) 

Но это говорит мне, что он не может найти явное решение.

Как найти численные решения этого уравнения в пределах заданного диапазона?

+0

Что вы подразумеваете под «получить все значения»? Существуют бесконечные решения этого уравнения (просто [зарисуйте его и посмотрите] (http://www.wolframalpha.com/input/?i=tan (x) +% 3D% 3D + 1% 2Fx + от + -20 + до +20)). –

+0

Извините, я имел в виду более одного значения. Например, в диапазоне. – user137425

+0

Я имел в виду, численные решения в некотором диапазоне – user137425

ответ

2

Чтобы найти численное решение функции в пределах некоторого диапазона, вы можете использовать fzero так:

fun = @(x)x*tan(x)-1; % Multiplied by x so fzero has no issue evaluating it at x=0. 
range = [0 pi/2]; 
sol = fzero(fun,range); 

выше будет возвращать только одно решение (0.8603). Если вам нужны дополнительные решения, вам нужно будет позвонить fzero еще раз. Это может быть сделано, например, в цикле:

fun = @(x)tan(x)-1/x; 

RANGE_START = 0; 
RANGE_END = 3*pi; 
RANGE_STEP = pi/2; 

intervals = repelem(RANGE_START:RANGE_STEP:RANGE_END,2); 
intervals = reshape(intervals(2:end-1),2,[]).'; 

sol = NaN(size(intervals,1),1); 

for ind1 = 1:numel(sol) 
    sol(ind1) = fzero(fun, mean(intervals(ind1,:))); 
end 

sol = sol(~isnan(sol)); % In case you specified more intervals than solutions. 

Что дает:

[0.86033358901938; 
1.57079632679490; % Wrong 
3.42561845948173; 
4.71238898038469; % Wrong 
6.43729817917195; 
7.85398163397449] % Wrong 

Обратите внимание, что:

  1. функция симметрична, и поэтому его корни. Это означает, что вы можете решить только положительный интервал (например) и получить отрицательные корни «бесплатно».
  2. Любая другая запись в sol неверна, потому что здесь мы имеем асимптотические разрывы (tan переходы от +Inf до -Inf), что ошибочно признано MATLAB в качестве решения. Таким образом, вы можете просто игнорировать их (т.е. sol = sol(1:2:end);.
+0

Спасибо, но отображает только одно решение. – user137425

+0

Спасибо! Хорошим диапазоном будет [-8 8] – user137425

+1

Измените уравнение на 'x * sin (x) -cos (x) == 0', чтобы де-сингуизировать еще дальше. – LutzL

3

Я никогда не любил с помощью решателей «вслепую», то есть, без какого-то приличной исходной схемы выбора значения. По моему опыту, значение, которые вы найдете, когда делая вещи вслепую, также будет без контекста. Смысл, вы часто пропускаете решения, считаете, что что-то является решением, в то время как на самом деле решатель взорвался и т. д.

Для этого конкретного случая важно понимать, что fzero использует числовые производные, чтобы находить все более качественные аппроксимации. Но производные для f(x) = x · tan(x) - 1 все труднее точно вычислить для увеличения x:

enter image description here

Как вы можете видеть, тем больше x, тем лучше f(x) приближается к вертикальной линии; fzero просто взорвется! Поэтому необходимо получить оценку как близко к решению, насколько возможно, даже после ввода fzero.

Итак, вот способ получить good начальные значения.

Рассмотрит функцию

f(x) = x · tan(x) - 1 

Зная, что tan(x) имеет Taylor expansion:

tan(x) ≈ x + (1/3)·x³ + (2/15)·x⁵ + (7/315)·x⁷ + ... 

мы можем использовать, чтобы аппроксимировать функцию f(x). Усечение после второго срока, мы можем написать:

f(x) ≈ x · (x + (1/3)·x³) - 1 

Теперь ключ, чтобы понять, является то, что tan(x) повторы с периодом π. Поэтому наиболее целесообразно рассмотреть семейство функций:

fₙ(x) ≈ x · ((x - n·π) + (1/3)·(x - n·π)³) - 1 

Оценивая это в течение нескольких кратных и собирающих терминов дает следующее обобщение:

f₀(x) = x⁴/3 - 0π·x³ + (0π² + 1)x² - (0π + (0π³)/3)·x - 1 
f₁(x) = x⁴/3 - 1π·x³ + (1π² + 1)x² - (1π + (1π³)/3)·x - 1 
f₂(x) = x⁴/3 - 2π·x³ + (4π² + 1)x² - (2π + (8π³)/3)·x - 1 
f₃(x) = x⁴/3 - 3π·x³ + (9π² + 1)x² - (3π + (27π³)/3)·x - 1 
f₄(x) = x⁴/3 - 4π·x³ + (16π² + 1)x² - (4π + (64π³)/3)·x - 1 
           ⋮ 
fₙ(x) = x⁴/3 - nπ·x³ + (n²π² + 1)x² - (nπ + (n³π³)/3)·x - 1 

Реализация все это в простом тесте MATLAB :

% Replace this with the whole number of pi's you want to 
% use as offset 
n = 5; 

% The coefficients of the approximating polynomial for this offset 
C = @(npi) [1/3 
      -npi 
      npi^2 + 1 
      -npi - npi^3/3 
      -1]; 

% Find the real, positive polynomial roots 
R = roots(C(n*pi)); 
R = R(imag(R)==0); 
R = R(R > 0); 

% And use these as initial values for fzero() 
x_npi = fzero(@(x) x.*tan(x) - 1, R) 

В цикле, это может привести следующую таблицу:

% Estimate (polynomial) Solution (fzero) 
0.889543617524132   0.860333589019380 0·π 
3.425836967935954   3.425618459481728 1·π 
6.437309348195653   6.437298179171947 2·π 
9.529336042900365   9.529334405361963 3·π 
12.645287627956868   12.645287223856643 
15.771285009691695   15.771284874815882  
18.902410011613000   18.902409956860023 
22.036496753426441   22.036496727938566 ⋮ 
25.172446339768143   25.172446326646664  
28.309642861751708   28.309642854452012 
31.447714641852869   31.447714637546234 
34.586424217960058   34.586424215288922 11·π 

Как вы можете видеть, аппроксимация в основном равна решению. Соответствующий участок:

enter image description here

+0

Почему бы просто не просто умножить на оскорбительный термин 'cos (x)', чтобы найти безполюсное уравнение 'x * sin (x) -cos (x) == 0'? – LutzL

+0

@ LutzL хм .... а потом что? По-прежнему трудно найти хорошие исходные оценки для этого. Это зависящий от угла фазор, то есть он идентичен «√ (x² + 1) · sin (x + atan2 (-1, x))». Как вы можете видеть, период не является «чистым» 2π, но зависит от 'x'. Вы можете добавить 'n · π' в первое решение, которое вы найдете для получения последующих оценок, и для этого случая я думаю, что это действительно достаточно хорошо. Но опыт показывает, что для * других * случаев, когда период не является точно *, что вы принимаете в начальных оценках, вы в конечном итоге сходитесь дважды к тому же решению и пропустите следующий ... –

+0

@LutzL хорошо, вы могут добавить ответ, который делает мой взгляд смехотворным, мне действительно нравится, когда это произойдет :) –

2

Умножить уравнение с помощью x и cos(x), чтобы избежать каких-либо знаменателей, которые могут иметь значение 0,

f(x)=x*sin(x)-cos(x)==0 

Рассмотрим нормированную функцию

h(x)=(x*sin(x)-cos(x))/(abs(x)+1) 

Для больших x это будет все больше clo se до sin(x) (или -sin(x) для больших отрицательных x). Действительно, это означает, что это уже визуально верно, вплоть до амплитудного коэффициента, для x>pi.

Для первого корня в [0,pi/2] использовать приближение Тейлора в x=0 второй степени x^2-(1-0.5x^2)==0, чтобы получить x[0]=sqrt(2.0/3) в качестве корневого приближения, для высших из них принимает синус корни x[n]=n*pi, n=1,2,3,... в качестве начальных приближений в Ньютон итерации xnext = x - f(x)/f'(x), чтобы получить

n  initial    1. Newton   limit of Newton 

0 0.816496580927726 0.863034004302817 0.860333589019380 
1 3.141592653589793 3.336084918413964 3.425618459480901 
2 6.283185307179586 6.403911810682199 6.437298179171945 
3 9.424777960769379 9.512307014150883 9.529334405361963 
4 12.566370614359172 12.635021895208379 12.645287223856643 
5 15.707963267948966 15.764435036320542 15.771284874815882 
6 18.849555921538759 18.897518573777646 18.902409956860023 
7 21.991148575128552 22.032830614521892 22.036496727938566 
8 25.132741228718345 25.169597069842926 25.172446326646664 
9 28.274333882308138 28.307365162331923 28.309642854452012 
10 31.415926535897931 31.445852385744583 31.447714637546234 
11 34.557519189487721 34.584873343220551 34.586424215288922