Main Content

関数 solve で求めた方程式の解のトラブルシューティング

solve が複雑な解を返す場合や、solve で入力を処理できない場合は、さまざまなオプションで解決できます。これらのオプションは solve の解空間を単純化します。また、これらのオプションにより、入力が複雑な場合に solve を補助し、以前に止まったところに solve が解を返すことができる場合があります。

実数解のみを返す

方程式 x^5 - 1 == 0 を解きます。この方程式には解が 5 つあります。

syms x
solve(x^5 - 1 == 0, x)
ans =
                                                     1
 - (2^(1/2)*(5 - 5^(1/2))^(1/2)*1i)/4 - 5^(1/2)/4 - 1/4
   (2^(1/2)*(5 - 5^(1/2))^(1/2)*1i)/4 - 5^(1/2)/4 - 1/4
   5^(1/2)/4 - (2^(1/2)*(5^(1/2) + 5)^(1/2)*1i)/4 - 1/4
   5^(1/2)/4 + (2^(1/2)*(5^(1/2) + 5)^(1/2)*1i)/4 - 1/4

実数解のみが必要な場合は、オプション Realtrue に設定します。関数 solve は 1 つの実数解を返します。

solve(x^5 - 1, x, 'Real', true)
ans =
1

単純化ルールの適用

次の方程式を解きます。関数 solve は複雑な解を返します。

syms x
solve(x^(5/2) + 1/x^(5/2) == 1, x)
ans =
                                                       1/(1/2 - (3^(1/2)*1i)/2)^(2/5)
                                                       1/((3^(1/2)*1i)/2 + 1/2)^(2/5)
 -(5^(1/2)/4 - (2^(1/2)*(5 - 5^(1/2))^(1/2)*1i)/4 + 1/4)/(1/2 - (3^(1/2)*1i)/2)^(2/5)
 -((2^(1/2)*(5 - 5^(1/2))^(1/2)*1i)/4 + 5^(1/2)/4 + 1/4)/(1/2 - (3^(1/2)*1i)/2)^(2/5)
 -(5^(1/2)/4 - (2^(1/2)*(5 - 5^(1/2))^(1/2)*1i)/4 + 1/4)/(1/2 + (3^(1/2)*1i)/2)^(2/5)
 -((2^(1/2)*(5 - 5^(1/2))^(1/2)*1i)/4 + 5^(1/2)/4 + 1/4)/(1/2 + (3^(1/2)*1i)/2)^(2/5)

方程式の求解時に単純化ルールを適用するには、IgnoreAnalyticConstraints オプションを true に設定します。一般的に、適用される単純化ルールは数学的に正確なものではありませんが、特に物理や工学の分野で役立つ解を生成できます。このオプションを使用すると、ソルバーによる解の正確性および完全性は保証されなくなります。

solve(x^(5/2) + 1/x^(5/2) == 1, x, 'IgnoreAnalyticConstraints', true)
ans =
 1/(1/2 - (3^(1/2)*1i)/2)^(2/5)
 1/((3^(1/2)*1i)/2 + 1/2)^(2/5)

この解はより単純で実用的です。

仮定を使用した結果の絞り込み

特定状況下の解に対し、仮定を設定して適切な解が返るようにします。次の方程式を解きます。関数 solve は 7 つの解を返します。

syms x
solve(x^7 + 2*x^6 - 59*x^5 - 106*x^4 + 478*x^3 + 284*x^2 - 1400*x + 800, x)
ans =
                  1
      - 5^(1/2) - 1
 - 17^(1/2)/2 - 1/2
   17^(1/2)/2 - 1/2
         -5*2^(1/2)
          5*2^(1/2)
        5^(1/2) - 1

x が正の数値であると仮定して方程式を再度解きます。関数 solve は 4 つの正の解のみを返します。

assume(x > 0)
solve(x^7 + 2*x^6 - 59*x^5 - 106*x^4 + 478*x^3 + 284*x^2 - 1400*x + 800, x)
ans =
                1
 17^(1/2)/2 - 1/2
        5*2^(1/2)
      5^(1/2) - 1

x は整数であるという仮定を、in(x,'integer') を使用して追加します。assumeAlso を使用して変数に仮定を追加します。

assumeAlso(in(x,'integer'))
solve(x^7 + 2*x^6 - 59*x^5 - 106*x^4 + 478*x^3 + 284*x^2 - 1400*x + 800, x)
ans =
1

solve は正で整数の解のみを x に返します。

計算を続けるため、x に設定された仮定を syms を使用して再作成することで消去します。

syms x

代わりに、複数の仮定を設定するために & 演算子を使用します。次の仮定を行い、以下の方程式を解きます。

syms a b c f g h y
assume(f == c & a == h & a~= 0)
S = solve([a*x + b*y == c, h*x - g*y == f], [x, y], 'ReturnConditions', true);
S.x
S.y
S.conditions
ans =
f/h
ans =
0
ans =
b + g ~= 0

指定された仮定の下で解は、b + g ~= 0 の場合 x = f/h およびy = 0 となります。

計算を続けるため、変数に設定された仮定を syms を使用して再作成することで消去します。

syms a c f h

解の単純化

関数 solve は最終結果に対して単純化関数を呼び出しません。解を単純化するには simplify を呼び出します。

次の方程式を解きます。sym を使用して数値をシンボリック数に変換し、シンボリックな結果を返します。

syms x
S = solve((sin(x) - 2*cos(x))/(sin(x) + 2*cos(x)) == 1/2, x)
S =
 -log(-(- 140/37 + 48i/37)^(1/2)/2)*1i
  -log((- 140/37 + 48i/37)^(1/2)/2)*1i

simplify を呼び出して解 S を単純化します。

simplify(S)
ans =
        -log(37^(1/2)*(- 1/37 - 6i/37))*1i
 log(2)*1i - (log(- 140/37 + 48i/37)*1i)/2

より多くのステップを指定した simplify を呼び出して、結果を更に単純化します。

simplify(S, 'Steps', 50)
ans =
 atan(6) - pi
      atan(6)

ヒント

  • 数値を厳密に表すには関数 sym を使用してその数値を浮動小数点オブジェクトに変換します。たとえば、13/5 ではなく sym(13)/5 を使用します。これは、13/5 を浮動小数点数に変換するよりも 13/5 を厳密に表します。大きな数値の場合は、数値を引用符で囲みます。sym(13)/5sym(133333333333333333333)/5 および sym('133333333333333333333')/5 を比較します。

    sym(13)/5
    sym(133333333333333333333)/5
    sym('133333333333333333333')/5
    ans =
    13/5
    ans =
    133333333333333327872/5
    ans =
    133333333333333333333/5

    数値を引用符で囲み、sym を使用することで精度を最大限に高められます。

  • 可能であれば、solve を使用する前に手動で方程式系を単純化してください。方程式、パラメーターおよび変数の数をできるだけ減らします。