이 주제에서는 Symbolic Math Toolbox™를 사용하여 연립방정식을 기호적으로 푸는 방법을 다룹니다. 이 툴박스는 수치 방정식 솔버 및 기호 방정식 솔버를 다 제공합니다. 수치 솔버와 기호 솔버의 비교는 Select Numeric or Symbolic Solver 항목을 참조하십시오.
다음과 같은 방정식이 있다고 가정하겠습니다.
그리고 x와 y에 대해 풀려고 한다고 하겠습니다. 먼저 필요한 기호 객체를 만듭니다.
syms x y a
solve
의 출력값을 처리하는 방법에는 여러 가지가 있습니다. 그중 하나는 출력값을 2개 갖는 호출을 사용하는 것입니다.
[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)
4개의 고유한 해가 구해집니다.
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
의 해는 S
의 “a
필드”에 있습니다.
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
값으로 설정하려면 a
에 axes
를 사용하여 axes 핸들을 가져오십시오. -2*pi
부터 2*pi
까지의 값이 pi/2
간격으로 있는 기호 배열 S
를 만듭니다. 눈금을 S
로 설정하려면 a
의 XTick
및 YTick
속성을 사용하십시오. x축과 y축의 레이블을 설정하려면 S
를 문자형 벡터로 변환하십시오. arrayfun
을 사용하여 S
의 모든 요소에 char
을 적용하여 T
를 반환합니다. a
의 XTickLabel
및 YTickLabel
속성을 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
는 x
에 대한 해가 S.x
고, y
에 대한 해가 S.y
이고, 해의 파라미터가 S.parameters
며, 해의 조건이 S.conditions
인 필드를 갖는 구조체 S
를 반환합니다. 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
에 대한 입력값의 조건을 지정하십시오.
위에 언급한 연립방정식을 -2*pi
~ 2*pi
구간에서 x
및 y
에 대해 풀어보십시오. 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
를 구하려면 S.conditions
조건 하에 -2*pi
~ 2*pi
구간에서 파라미터 S.parameters
에 대해 해 S.x
및 S.y
를 구해서 동일한 구간에서 x
및 y
값을 구합니다.
이 구간에서 x
및 y
를 구하기 전에 반환된 해가 조건을 충족하도록 assume
을 사용하여 S.conditions
의 조건을 가정합니다. 첫 번째 해에 대한 조건을 가정합니다.
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
파라미터 paramx
에 대해 x
의 첫 번째 해를 구합니다.
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)]
마찬가지로, paramy
에 대해 y
의 첫 번째 해를 구합니다.
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)]
assume
을 사용하여 S.conditions(1)
에서 설정한 가정을 지웁니다. asumptions
를 호출하여 가정이 지워졌는지 확인합니다.
assume(S.parameters,'clear') assumptions
ans = Empty sym: 1-by-0
두 번째 해에 대한 조건을 가정합니다.
assume(S.conditions(2))
파라미터 paramx
및 paramy
에 대해 x
및 y
에 대한 두 번째 해를 구합니다.
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
의 첫 번째 행은 연립방정식의 첫 번째 해를 구성하고 두 번째 행은 두 번째 해를 구성합니다.
이러한 paramx
및 paramy
값에 대한 x
및 y
의 값을 구하려면 subs
를 사용하여 S.x
및 S.y
의 paramx
및 paramy
에 값을 대입하십시오.
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
가 멈추거나, 성능을 향상시키려는 경우 Troubleshoot Equation Solutions from solve Function 항목을 참조하십시오.