Решение нелинейных уравнений с помощью «solve», неправильное решение

#matlab #symbolic-math

#matlab #символьная-математика

Вопрос:

Я тестирую возможности 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 правильные, но для theta я получаю:

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

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

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

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

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

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

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

 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, theta должно быть 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 
  

Комментарии:

1. И правильный ответ для theta — это просто atan (y / x) , вы уверены?

2. Я уверен, что, решая это вручную, это выглядит следующим образом: Разделите уравнение y на уравнение x => (y / x) = (d * sin (тета)) / (d * cos(тета)) d отменяют друг друга => y / x = sin (тета) / cos (тета) => y / x = tan (тета) => theta = atan(y / x). Даже если matlab решает это каким-то другим способом и получает другое выражение, оно все равно должно давать тот же конечный результат, когда я использую числа, но это не так. Для x = 1 и y = 0 тета также должна быть равна 0, для x = 1 и y = 1 тета должна составлять 45 градусов, для x = 0 и y = 1 тета должна составлять 90 градусов.

3. Хорошо, я только что проверил это снова со значениями 45 и 90 градусов для x и y, и это работает, но для x = 1 и y = 0 он по-прежнему выдает NaN в качестве одного из ответов, и это потому, что он получает 0/0 из способа его выражения => (1 — (1^2 0^2))^(1/2)/0 => (1 — 1)^(1/2)/0 => 0/0, но если оно в форме atan (y / x), результатом будет atan (0/1) => atan (0) = 0

4. да, но если вы возьмете пример, где d<1 и x>1 тогда не будет решения для eq1 .

5. @obchardon это верно, но я этого не делаю, выражение и ответы, которые я получаю для d, верны, но я не получаю правильных значений для theta, когда оно должно быть 0 градусов, как я объяснил в моем последнем ответе, поэтому ti кажется, что это единственная проблема на данный момент. Я также обновил свой основной пост. d не мешает theta.

Ответ №1:

Вы имели в виду решить это:

 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);
  

Комментарии:

1. Ну, похоже на то же самое, я не знаю, что делают ваши дополнительные аргументы, но да. Тем не менее, он по-прежнему дает неправильный ответ для theta, он дает тот же ответ, что и мой, и правильный ответ для theta — atan (y / x) или atan (b / a) в вашем случае, но он по-прежнему дает -2 * atan ((a — (a ^ 2 b ^ 2) ^ (1/2)) / b) -2 * atan((a (a ^ 2 b ^ 2) ^ (1/2)) / b), что неверно.

2. Для @Darkbound Вам следует установить IgnoreAnalyticConstraints значение false. Это даст вам условия, в sol для которых найденное решение верно. Для любых a и b вы увидите, что это даст b~=0 , но если вы укажете, что a и b равны 1 и 0, вы найдете правильное решение (смотрите здесь ).

3. @rinkert Я только что попробовал это, и это все еще дает мне NaN для b = 0, a = 1. sol = solve (eq1, eq2, d, theta, ‘IgnoreAnalyticConstraints’, false)

4. Прошу прощения за задержку. я тоже здесь в замешательстве.

Ответ №2:

При решении уравнений с помощью символьных 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 amp; in(k, 'integer')
  y ~= 0 amp; 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 возможных решения и условия для трех строк выше.

Комментарии:

1. Причина, по которой я решаю это так, заключается в том, что в конечном итоге я буду решать это для многих разных x и y, я бы не знал, когда и будет ли y когда-либо равен 0, но возможно, что это так. Например, у меня может быть t = 0: 0.01: 10, x = 5t и y = sin (t) и, используя эти векторы x и y, я должен найти соответствующие им векторы theta и d, так что это не просто один сценарий, я просто тестировал, что происходит на этом простом примере. Также обратите внимание, что уравнения x и y, которые я только что использовал, являются случайными иллюстративными, я не знаю, действительно ли они будут работать в этом случае.

2. Итак, в этом смысле мне нужно, чтобы решение было надежным без необходимости его сшивания (или, по крайней мере, если мне придется его сшивать, оно должно работать для любого варианта этих уравнений). Также мои уравнения x и y могут измениться, я хочу создать программу, которая сможет строить эти уравнения и решать их на основе ряда параметров, поэтому то, какие уравнения я получу в итоге, совершенно непредсказуемо, у меня может быть 10-20-30 различных вариантов этих уравнений, так возможно ли, что это станет надежным?

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

4. Да, у меня тоже нет опыта работы с другими, поэтому я направился к Matlab, что ж, я посмотрю, как это пойдет, и попытаюсь как-нибудь связать это в более общем виде. Спасибо