Решите систему алгебраических уравнений

Эта тема показывает вам, как решить систему уравнений символически с помощью Symbolic Math Toolbox™. Этот тулбокс предлагает и числовые и символьные решатели уравнения. Для сравнения числовых и символьных решателей смотрите, Выбирают Numeric or Symbolic Solver.

Обработайте Вывод, решают

Предположим, что у вас есть система

x2y2=0xy2=α,

и вы хотите решить для x и y. Во-первых, создайте необходимые символьные объекты.

syms x y a

Существует несколько способов обратиться к выводу solve. Один путь состоит в том, чтобы использовать 2D выходной вызов.

[solx,soly] = solve(x^2*y^2 == 0, x-y/2 == a)

Вызов возвращает следующее.

solx =
 0
 a
soly =
 -2*a
    0

Измените первое уравнение к x 2y2  = 1. Новая система имеет больше решений.

[solx,soly] = solve(x^2*y^2 == 1, x-y/2 == a)

Производятся четыре отличных решения.

solx =
 a/2 - (a^2 - 2)^(1/2)/2
 a/2 - (a^2 + 2)^(1/2)/2
 a/2 + (a^2 - 2)^(1/2)/2
 a/2 + (a^2 + 2)^(1/2)/2
soly =
 - a - (a^2 - 2)^(1/2)
 - a - (a^2 + 2)^(1/2)
   (a^2 - 2)^(1/2) - a
   (a^2 + 2)^(1/2) - a

Поскольку вы не задавали зависимые переменные, solve использует symvar, чтобы определить переменные.

Этот способ присвоить вывод от solve довольно успешен для “маленьких” систем. Например, если у вас есть 10 10 система уравнений, введение следующего является и неловким и трудоемким.

[x1,x2,x3,x4,x5,x6,x7,x8,x9,x10] = solve(...)

Чтобы обойти эту трудность, solve может возвратить структуру, поля которой являются решениями. Например, решите систему уравнений u^2 - v^2 = a^2, u + v = 1, a^2 - 2*a = 3.

syms u v a
S = solve(u^2 - v^2 == a^2, u + v == 1, a^2 - 2*a == 3)

Решатель возвращает свои результаты, заключенные в эту структуру.

S = 
  struct with fields:

    a: [2×1 sym]
    u: [2×1 sym]
    v: [2×1 sym]

Решения для a находятся в “a - поле” S.

S.a
ans =
 -1
  3

Подобные комментарии применяются к решениям за u и v. Структурой S могут теперь управлять поле и индекс, чтобы получить доступ к конкретному фрагменту решения. Например, чтобы исследовать второе решение, можно использовать следующий оператор, чтобы извлечь второй компонент каждого поля.

s2 = [S.a(2), S.u(2), S.v(2)]
s2 =
[  3,  5, -4]

Следующий оператор создает матрицу решения M, строки которого включают отличные решения системы.

M = [S.a, S.u, S.v]
M = 
[ -1, 1,  0]
[  3, 5, -4]

Очистите solx и soly для дальнейшего использования.

clear solx soly

Решите линейную систему уравнений

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

clear u v x y
syms u v x y
eqns = [x + 2*y == u, 4*x + 5*y == v];
S = solve(eqns);
sol = [S.x; S.y]

[A,b] = equationsToMatrix(eqns,x,y);
z = A\b
sol =
 (2*v)/3 - (5*u)/3
     (4*u)/3 - v/3

z =
 (2*v)/3 - (5*u)/3
     (4*u)/3 - v/3

Таким образом sol и z производят то же решение, несмотря на то, что результаты присвоены различным переменным.

Возвратите полное решение системы уравнений

solve автоматически не возвращает всех решений уравнения. Чтобы возвратить все решения наряду с параметрами в решении и условиях на решении, установите опцию ReturnConditions на true.

Рассмотрите следующую систему уравнений:

sin(x)+потому что(y)=45sin(x)потому что(y)=110

Визуализируйте систему уравнений с помощью fimplicit. Чтобы установить ось X и значения оси Y с точки зрения pi, получите указатели осей с помощью axes в a. Создайте символьный массив S значений -2*pi к 2*pi с промежутками в pi/2. Чтобы установить метки деления на S, используйте свойства XTick и YTick a. Чтобы установить метки для x-and осей Y, преобразуйте S в векторы символов. Используйте arrayfun, чтобы применить char к каждому элементу S, чтобы возвратить T. Установите свойства XTickLabel и YTickLabel a к T.

syms x y
eqn1 = sin(x)+cos(y) == 4/5;
eqn2 = sin(x)*cos(y) == 1/10;
a = axes;
fimplicit(eqn1,[-2*pi 2*pi],'b');
hold on
grid on
fimplicit(eqn2,[-2*pi 2*pi],'m');
L = sym(-2*pi:pi/2:2*pi);
a.XTick = double(L);
a.YTick = double(L);
M = arrayfun(@char, L, 'UniformOutput', false);
a.XTickLabel = M;
a.YTickLabel = M;
title('Plot of System of Equations')
legend('sin(x)+cos(y) == 4/5','sin(x)*cos(y) == 1/10',...
    'Location','best','AutoUpdate','off')

Решения лежат на пересечении двух графиков. Это показывает, что система повторилась, периодические решения. Чтобы решить эту систему уравнений для набора полного решения, используйте solve и установите опцию ReturnConditions на true.

S = solve(eqn1, eqn2, 'ReturnConditions', true)
S = 
  struct with fields:

             x: [2×1 sym]
             y: [2×1 sym]
    parameters: [1×2 sym]
    conditions: [2×1 sym]

solve возвращает структуру S с полями S.x для решения x, S.y для решения y, S.parameters для параметров в решении и S.conditions для условий на решении. Элементы того же индекса в S.x, S.y и S.conditions формируют решение. Таким образом S.x(1), S.y(1) и S.conditions(1) формируют одно решение системы уравнений. Параметры в S.parameters могут появиться во всех решениях.

Индексируйте в S, чтобы возвратить решения, параметры и условия.

S.x
S.y
S.parameters
S.conditions
ans =
 z1
 z1
ans =
 z
 z
ans =
[ z, z1]
ans =
 (in((z - acos(6^(1/2)/10 + 2/5))/(2*pi), 'integer') |...
 in((z + acos(6^(1/2)/10 + 2/5))/(2*pi), 'integer')) &...
 (in(-(pi - z1 + asin(6^(1/2)/10 - 2/5))/(2*pi), 'integer') |...
 in((z1 + asin(6^(1/2)/10 - 2/5))/(2*pi), 'integer'))
  (in((z1 - asin(6^(1/2)/10 + 2/5))/(2*pi), 'integer') |...
 in((z1 - pi + asin(6^(1/2)/10 + 2/5))/(2*pi), 'integer')) &...
 (in((z - acos(2/5 - 6^(1/2)/10))/(2*pi), 'integer') |...
 in((z + acos(2/5 - 6^(1/2)/10))/(2*pi), 'integer'))

Решите систему уравнений при условиях

Чтобы решить систему уравнений при условиях, задайте условия во входе к solve.

Решите систему уравнений, рассмотренную выше для x и y в интервале -2*pi к 2*pi. Наложите решения на графике с помощью scatter.

Srange = solve(eqn1, eqn2, -2*pi<x, x<2*pi, -2*pi<y, y<2*pi, 'ReturnConditions', true);
scatter(Srange.x, Srange.y,'k')

Работа с Решениями, Параметрами и Условиями, Возвращенными, решает

Можно использовать решения, параметры и условия, возвращенные solve, чтобы найти решения в интервале или под дополнительными условиями. Этот раздел имеет ту же цель как предыдущий раздел, чтобы решить систему уравнений в поисковой области значений, но с другим подходом. Вместо того, чтобы поместить условия непосредственно, это показывает, как работать с параметрами и условиями, возвращенными solve.

Для полного решения S системы уравнений найдите значения x и y в интервале -2*pi к 2*pi путем решения решений S.x и S.y для параметров S.parameters в том интервале при условии S.conditions.

Прежде, чем решить для x и y в интервале, примите условия в S.conditions с помощью assume так, чтобы возвращенные решения удовлетворили условие. Примите условия для первого решения.

assume(S.conditions(1))

Найдите параметры в S.x и S.y.

paramx = intersect(symvar(S.x), S.parameters)
paramy = intersect(symvar(S.y), S.parameters)
paramx =
z1
paramy =
z

Решите первое решение x для параметра paramx.

solparamx(1,:) = solve(S.x(1) > -2*pi, S.x(1) < 2*pi, paramx)
solparamx =
[ pi + asin(6^(1/2)/10 - 2/5), asin(6^(1/2)/10 - 2/5) - pi,
 -asin(6^(1/2)/10 - 2/5), - 2*pi - asin(6^(1/2)/10 - 2/5)]

Точно так же решите первое решение y для paramy.

solparamy(1,:) = solve(S.y(1) > -2*pi, S.y(1) < 2*pi, paramy)
solparamy =
[ acos(6^(1/2)/10 + 2/5), acos(6^(1/2)/10 + 2/5) - 2*pi,
 -acos(6^(1/2)/10 + 2/5), 2*pi - acos(6^(1/2)/10 + 2/5)]

Очистите предположения, установленные S.conditions(1) с помощью assume. Вызовите asumptions, чтобы проверять, что предположения очищены.

assume(S.parameters,'clear')
assumptions
ans =
Empty sym: 1-by-0

Примите условия для второго решения.

assume(S.conditions(2))

Решите второе решение x и y для параметров paramx и paramy.

solparamx(2,:) = solve(S.x(2) > -2*pi, S.x(2) < 2*pi, paramx)
solparamy(2,:) = solve(S.y(2) > -2*pi, S.y(2) < 2*pi, paramy)
solparamx =
[ pi + asin(6^(1/2)/10 - 2/5), asin(6^(1/2)/10 - 2/5) - pi,
  -asin(6^(1/2)/10 - 2/5), - 2*pi - asin(6^(1/2)/10 - 2/5)]
[ asin(6^(1/2)/10 + 2/5), pi - asin(6^(1/2)/10 + 2/5),
  asin(6^(1/2)/10 + 2/5) - 2*pi, - pi - asin(6^(1/2)/10 + 2/5)]
solparamy =
[ acos(6^(1/2)/10 + 2/5), acos(6^(1/2)/10 + 2/5) - 2*pi,
  -acos(6^(1/2)/10 + 2/5), 2*pi - acos(6^(1/2)/10 + 2/5)]
[ acos(2/5 - 6^(1/2)/10), acos(2/5 - 6^(1/2)/10) - 2*pi,
  -acos(2/5 - 6^(1/2)/10), 2*pi - acos(2/5 - 6^(1/2)/10)]

Первые строки paramx и paramy формируют первое решение системы уравнений, и вторые строки формируют второе решение.

Чтобы найти значения x и y для этих значений paramx и paramy, используйте subs, чтобы заменить paramx и paramy в S.x и S.y.

solx(1,:) = subs(S.x(1), paramx, solparamx(1,:));
solx(2,:) = subs(S.x(2), paramx, solparamx(2,:))
soly(1,:) = subs(S.y(1), paramy, solparamy(1,:));
soly(2,:) = subs(S.y(2), paramy, solparamy(2,:))
solx =
[ pi + asin(6^(1/2)/10 - 2/5), asin(6^(1/2)/10 - 2/5) - pi,
  -asin(6^(1/2)/10 - 2/5), - 2*pi - asin(6^(1/2)/10 - 2/5)]
[ asin(6^(1/2)/10 + 2/5), pi - asin(6^(1/2)/10 + 2/5),
  asin(6^(1/2)/10 + 2/5) - 2*pi,   - pi - asin(6^(1/2)/10 + 2/5)]
soly =
[ acos(6^(1/2)/10 + 2/5), acos(6^(1/2)/10 + 2/5) - 2*pi,
 -acos(6^(1/2)/10 + 2/5), 2*pi - acos(6^(1/2)/10 + 2/5)]
[ acos(2/5 - 6^(1/2)/10), acos(2/5 - 6^(1/2)/10) - 2*pi,
 -acos(2/5 - 6^(1/2)/10), 2*pi - acos(2/5 - 6^(1/2)/10)]

Обратите внимание на то, что solx и soly являются двумя наборами решений x и y. Полные наборы решений системы уравнений являются этими двумя наборами точек, сформированными всеми возможными комбинациями значений в solx и soly.

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

for i = 1:length(solx(1,:))
    for j = 1:length(soly(1,:))
        scatter(solx(1,i), soly(1,j), 'k')
        scatter(solx(2,i), soly(2,j), 'k')
    end
end

Преобразуйте символьные результаты в числовые значения

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

Используйте vpa, чтобы преобразовать символьные решения solx и soly к числовой форме.

vpa(solx)
vpa(soly)
ans =
[ 2.9859135500977407388300518406219,...
 -3.2972717570818457380952349259371,...
  0.15567910349205249963259154265761,...
 -6.1275062036875339772926952239014]
...
[ 0.70095651347102524787213653614929,...
  2.4406361401187679905905068471302,...
 -5.5822287937085612290531502304097,...
 -3.8425491670608184863347799194288]
 
ans =
[ 0.86983981332387137135918515549046,...
 -5.4133454938557151055661016110685,...
 -0.86983981332387137135918515549046,...
  5.4133454938557151055661016110685]
...
[ 1.4151172233028441195987301489821,...
 -4.8680680838767423573265566175769,...
 -1.4151172233028441195987301489821,...
  4.8680680838767423573265566175769]

Упростите сложные результаты и улучшайте производительность

Если результаты выглядят сложными, solve застревает, или если вы хотите улучшать производительность, смотрите, Решения для уравнения Поиска и устранения неисправностей от решают Функцию.