이 페이지의 최신 내용은 아직 번역되지 않았습니다. 최신 내용은 영문으로 볼 수 있습니다.

연립대수방정식 풀기

이 주제에서는 Symbolic Math Toolbox™를 사용하여 연립방정식을 기호적으로 푸는 방법을 다룹니다. 이 툴박스는 수치 방정식 솔버 및 기호 방정식 솔버를 다 제공합니다. 수치 솔버와 기호 솔버의 비교는 Select Numeric or Symbolic Solver 항목을 참조하십시오.

solve 출력값 처리하기

다음과 같은 방정식이 있다고 가정하겠습니다.

x2y2=0xy2=α,

그리고 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

종속 변수를 지정하지 않았으므로 solvesymvar을 사용하여 변수를 결정합니다.

이렇게 solve에서 출력값을 할당하는 방법은 규모가 작은 연립방정식의 경우 꽤 괜찮은 방법입니다. 예를 들어, 10x10 연립방정식을 사용하는 경우 다음과 같이 입력하는 것은 시각적으로도 복잡하고 시간도 많이 걸립니다.

[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

uv의 해도 비슷합니다. 이제 구조체 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]

추후 사용을 위해 solxsoly를 지웁니다.

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

solz의 해는 결과는 서로 다른 변수에 할당되지만 동일한 해를 산출합니다.

연립방정식의 전체 해 반환하기

solve는 방정식의 전체 해를 자동으로 반환하지 않습니다. 해의 파라미터 및 해의 조건과 함께 모든 해를 반환하려면 ReturnConditions 옵션을 true로 설정하십시오.

다음과 같은 연립방정식이 있다고 가정해 보겠습니다.

sin(x)+cos(y)=45sin(x)cos(y)=110

fimplicit를 사용하여 연립방정식을 시각화합니다. x축 및 y축 값을 pi 값으로 설정하려면 aaxes를 사용하여 axes 핸들을 가져오십시오. -2*pi부터 2*pi까지의 값이 pi/2 간격으로 있는 기호 배열 S를 만듭니다. 눈금을 S로 설정하려면 aXTickYTick 속성을 사용하십시오. x축과 y축의 레이블을 설정하려면 S를 문자형 벡터로 변환하십시오. arrayfun을 사용하여 S의 모든 요소에 char을 적용하여 T를 반환합니다. aXTickLabelYTickLabel 속성을 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]

solvex에 대한 해가 S.x고, y에 대한 해가 S.y이고, 해의 파라미터가 S.parameters며, 해의 조건이 S.conditions인 필드를 갖는 구조체 S를 반환합니다. S.x, S.yS.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 구간에서 xy에 대해 풀어보십시오. 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에서 반환한 해, 파라미터 및 조건을 사용하여 어떤 구간이나 추가 조건에 맞는 해를 구할 수 있습니다. 이 섹션에서는 이전 섹션과 마찬가지로 검색 범위 내의 연립방정식을 풀지만 다른 접근 방식을 사용합니다. 조건을 직접 주는 대신 solve에서 반환한 파라미터 및 조건을 사용하여 작업하는 방법을 보여줍니다.

연립방정식의 전체 해 S를 구하려면 S.conditions 조건 하에 -2*pi ~ 2*pi 구간에서 파라미터 S.parameters에 대해 해 S.xS.y를 구해서 동일한 구간에서 xy 값을 구합니다.

이 구간에서 xy를 구하기 전에 반환된 해가 조건을 충족하도록 assume을 사용하여 S.conditions의 조건을 가정합니다. 첫 번째 해에 대한 조건을 가정합니다.

assume(S.conditions(1))

S.xS.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))

파라미터 paramxparamy에 대해 xy에 대한 두 번째 해를 구합니다.

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

paramxparamy의 첫 번째 행은 연립방정식의 첫 번째 해를 구성하고 두 번째 행은 두 번째 해를 구성합니다.

이러한 paramxparamy 값에 대한 xy의 값을 구하려면 subs를 사용하여 S.xS.yparamxparamy에 값을 대입하십시오.

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

solxsolyxy에 대한 두 개의 해 집합입니다. 연립방정식에 대한 전체 해 집합은 solxsoly에서 가능한 모든 값의 조합으로 구성된 두 개의 점 집합입니다.

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를 사용하여 기호 해 solxsoly를 수치 형식으로 변환합니다.

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 항목을 참조하십시오.