Более простой способ найти решение уравнения - PullRequest
1 голос
/ 07 сентября 2010

У меня есть следующее уравнение:

f(N):  N = ((1+lam)^3 )/ ((1-lam)*(1+lam^2));

Мне нужно создать функцию, которая находит lam для указанного N.

Прямо сейчас я делаю это с помощью простого цикла:

lam = 0.9999;
n = f(lam);
pow = 0;
delta = 0.1;
while(abs(N - n)) > 0.1 & pow < 10000)
    lam = lam - 0.001;
    n = f(lam)
    pow = pow+1;
end

Как решить эту проблему более точно и без использования циклов?

Ответы [ 6 ]

3 голосов
/ 07 сентября 2010

Если у вас есть

N = ((1+lam)^3 )/ ((1-lam)*(1+lam^2))

тогда вы знаете, что

(1+lam)^3 = N*(1-lam)*(1+lam^2)

Предположим, вы расширили эти условия? Объединиться в одно простое кубическое уравнение с действительными коэффициентами, равными нулю? Есть ли функция, которая решит это за вас?

Ответ - да. Одним из решений может быть использование fzero, но поскольку уравнение является просто кубическим полиномом, корни - это ответ, если вам не нужно символическое решение. Используйте символический набор инструментов для символических проблем.

2 голосов
/ 07 сентября 2010

Вот решение для N = 10 от Wolfram Alpha:

http://www.wolframalpha.com/input/?i=(1%2Bx^3)/((1-x)*(1%2Bx^2))%3D10

Алгебраическое решение подойдет для вашего конкретного случая, потому что это не очень сложно. Проблема состоит в том, что, как правило, нелинейные уравнения требуют итеративного решения: начните с предположения, сделайте шаг в определенном направлении и, надеюсь, сходитесь к решению. Вы не можете решить нелинейные уравнения в целом без итераций и циклов.

1 голос
/ 08 сентября 2010

Вы можете решить это уравнение в замкнутой форме, как обсуждалось в других ответах, но, честно говоря, решения полиномов степени> 2 в замкнутой форме не очень полезны на практике, поскольку результаты, как правило, плохо обусловлены.

Что касается вашего конкретного полинома, я согласен с Александром, что метод Ньютона, вероятно, является подходящим вариантом.

Однако в долгосрочной перспективе я настоятельно рекомендую написать (или повторно использовать из Интернета) реализацию алгоритма поиска корня Jenkins-Traub. Википедия описывает это как «практически стандарт в полиномиальных корневых искателях черного ящика», и они не преувеличивают. Это служило всем моим потребностям решения полиномов в течение многих лет; по моему опыту, он более надежен, чем метод Ньютона (не полагаясь на хорошие начальные предположения) и методы, основанные на собственных значениях, и довольно быстро загружается.

1 голос
/ 07 сентября 2010

Графики указывают на то, что для N положительных значений в интервале [-1,1) есть ровно одно решение. Вы должны рассмотреть метод Ньютона , он сойдется для нулевого начального предположения довольно быстро.

1 голос
/ 07 сентября 2010

Переставьте уравнение в 0 = f(x)/g(x) (где f и g - полиномы).Тогда решите за 0 = f(x).Это должно быть достаточно просто, так как f будет кубическим (http://en.wikipedia.org/wiki/Cubic_function#Roots_of_a_cubic_function). На самом деле, Matlab имеет функцию roots() для этого.

0 голосов
/ 08 сентября 2010

Существует алгебраическое решение вашей задачи для большинства значений N. Вот решение, решаемое Wolfram Alpha :

if N+1!=0
   x = (20 N^3+18 N^2+3 sqrt(3) sqrt(16 N^6+32 N^5-20 N^4-72 N^3-9 N^2+54 N+27)-27 N-27)^(1/3)/(3 2^(1/3) (N+1))-(2^(1/3) (2 N^2+3 N))/(3 (N+1) (20 N^3+18 N^2+3 sqrt(3) sqrt(16 N^6+32 N^5-20 N^4-72 N^3-9 N^2+54 N+27)-27 N-27)^(1/3))+N/(3 (N+1))

Да, это ужасно.

Если оно у вас есть, точное алгебраическое решение, даже такое страшное, как у этого, всегда превосходит численное решение. Как указывало Даффимо, решение задачи с помощью численных методов требует итераций (поэтому это медленно), и решатель может застрять в локальных минимумах.

...