Решение нелинейных уравнений с «решить», неправильное решение - PullRequest
4 голосов
/ 02 апреля 2019

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

syms theta d x y

eq1 = d * cos(theta) == x;
eq2 = d * sin(theta) == y;

sol = solve(eq1, eq2, theta, d)

sol.theta
sol.d

Решения для d верны, но для тета я получаю:

 -2*atan((x - (x^2 + y^2)^(1/2))/y)
 -2*atan((x + (x^2 + y^2)^(1/2))/y)

И правильный ответ для тэты просто atan (y / x)

Тогда, когда я оцениваю эти решения с x = 1, y = 0, я получаю:

eval(sol.d)
eval(sol.theta)

d = 1, -1
theta = NaN, -3.1416

Решения для d верны, но тэта в этом сценарии должна быть 0. Что я делаю не так?

РЕДАКТИРОВАТЬ: решение вручную, это выглядит так: Разделить уравнение у на уравнение х

y/x = (d * sin(theta)) / (d * cos(theta))
y/x = sin(theta)/cos(theta)
y/x = tan(theta)
theta = atan(y/x)

Даже если matlab решит это каким-то другим способом и получит другое выражение, он все равно должен дать тот же конечный результат, когда я использую числа, и ЧАСТИЧНО это делает.

Для x = 1 и y = 0 тета должно быть 0, => это не работает, оно дает NaN (пояснение ниже)

для x = 1 и y = 1, тета должно быть 45 градусов => это работает

для x = 0 и y = 1 тета должно быть 90 градусов => это работает

И я только что проверил это снова со значениями 45 и 90 градусов для x и y, и это работает, но для x = 1 и y = 0 это все еще дает NaN как один из ответов, и это потому, что он получает 0 / 0 по выражению

-2*atan((x - (x^2 + y^2)^(1/2))/y)
-2*(1 - (1^2 + 0^2))^(1/2)/0 
-2*(1 - 1)^(1/2)/0 
0/0

но если это в форме atan (y / x), то результат будет

theta = atan(0/1) 
theta = atan(0)
theta = 0 

Ответы [ 2 ]

0 голосов
/ 02 апреля 2019

При решении уравнений с символическими x и y решатель найдет решение с определенным условием, которое можно получить с помощью аргумента 'ReturnCondition':

syms x y theta d real

eq1 = d*cos(theta) == x;
eq2 = d*sin(theta) == y;

sol = solve([eq1; eq2],[d theta],'ReturnConditions',true);

. Это даетследующий результат для sol

>> sol.d
  (x^2 + y^2)^(1/2)
 -(x^2 + y^2)^(1/2)

>> sol.theta
  2*pi*k - 2*atan((x - (x^2 + y^2)^(1/2))/y)
  2*pi*k - 2*atan((x + (x^2 + y^2)^(1/2))/y)

>> sol.parameters
  k

>> sol.conditions
  y ~= 0 & in(k, 'integer')
  y ~= 0 & in(k, 'integer')

Как видите, y = 0 не удовлетворяет этому общему решению, заданному решателем, что приводит к вашей задаче для y = 0. Вы можете найти решения для y= 0, либо сделав y числовым вместо символьного, либо добавив допущение:

syms x y theta d real
assume(y==0)
sol = solve([eq1; eq2],[d theta],'ReturnConditions',true);

Я полагаю, проще установить y = 0 числовое для этого одного условия, поскольку уже есть 4возможные решения и условия для трех строк выше.

0 голосов
/ 02 апреля 2019

Вы хотели решить это:

syms a b theta d real

eq1 = a==d * cos(theta) ;
eq2 = b==d * sin(theta) ;

[sol] = solve([eq1 eq2],[d theta] ,'IgnoreAnalyticConstraints', true,'Real',true,'ReturnConditions',true);
...