В этой теме показано, как решить систему уравнений символически, используя Symbolic Math Toolbox™. Этот тулбокс предлагает как числовые, так и символьные решатели уравнений. Для сравнения числовых и символьных решателей смотрите Select Numeric или Symbolic Solver.
Предположим, у вас есть система
и вы хотите решить для x и y. Во-первых, создайте необходимые символические объекты.
syms x y a
Существует несколько способов решить выходные параметры solve
. Один из способов - использовать вызов с двумя выходами.
[solx,soly] = solve(x^2*y^2 == 0, x-y/2 == a)
Вызов возвращает следующее.
solx = 0 a soly = -2*a 0
Измените первое уравнение таким образом x2y2 = 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
.
Рассмотрим следующую систему уравнений:
Визуализируйте систему уравнений используя fimplicit
. Чтобы задать значения осей X и Y в терминах pi
, получите маркеры осей используя axes
в a
. Создайте символьный массив S
значений -2*pi
на 2*pi
с интервалами pi/2
. Чтобы установить такты равной S
, используйте XTick
и YTick
свойства a
. Чтобы задать метки для осей X и 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
застрял, или если вы хотите улучшить эффективность, см., Поиск и устранение проблем с решениями уравнения из решения Function.