解を求める

作成日 : 2001-05-02
最終更新日 :

ゴールシーク機能

Excel でいう、ゴールシーク機能を実現してみよう。

ゴールシーク機能とは、特定の出力値になるような入力値を求める機能である。 最初に、見込み入力値を入れて、出力値がどの程度になるかを確かめる。 そして、目標となる出力値を入れて、必要な入力値を入れる。具体例で確かめよう。

まずは、見込み入力値として値 a の欄に 2 を、関数 f(x) の欄には 2 * x + 3 を入れる。 導関数 `f'(x)` には、2 を入れるか、空欄のままとする。空欄のままとした場合の処理については後に述べる。 そこで計算ボタンをクリックすると、答が 7 となる。 ここで、答が 6 となるような x を求める。目標値 (goal) に 6 を入れて解のボタンをクリックすると、 解の欄に 1.5 が表示される。

値 a
関数 `f(x)`
導関数 `f'(x)`
`f(a)`


目標値(goal)

上記例は四則演算であるので式は通常通りでよい。四則演算のほか、三角関数や指数関数、対数関数などを使う場合は、 JavaScript の Math を明示的に指定する必要がある。 例:`f(x)=−log(1−x)/x` , `f'(x) = log(1-x)/x^2 + 1/(x(1-x))` ならば、 それぞれ -Math.log(1-x)/x, Math.log(1-x)/(x*x) + 1/(x * (1-x)) と入力する。

なんらかの事情により計算が終了しなかったり、誤った値が発生したりすることがある。 これには次のような原因が考えられる。

  1. 変数 x を変えても式の値が変化しない。x * 0 + 3 や、x + 3 - xなど。
  2. 目標値が、式から決まる値の存在範囲外(値域外)である。式が x * x + 3 のときに目標値が -3 であるときなど。
  3. 見込み入力値と式が、ある特殊な関係にあるとき(条件省略)。
  4. その他、式が特殊な形のとき

3. の場合は、見込み入力値を少し増やす(あるいは減らす)と、解が得られることがある。

実装について

実装は次のいずれかで行なっている。まず、関数 `f(x)` がゴールとなる値(gとする)となるような値 `x = hat(x)` をもとめるということは、 `f(hat(x)) - g = 0 `となる `f(x)` を求めることだと考える。以下、左辺を改めて `f(x)` と置く。 さて、このとき、関数 `f(x)` の導関数 `f'(x)` が式で与えられる場合は、 ニュートン法(ニュートン・ラフソン法)が使える。 `f'(x)` を明示的に指定した場合は、この方法を適用する。

ニュートン法

ニュートン法は次の通りである。まず適当な出発点 `x_0`を用意し、`f(x_0)` と `f’(x_0)` を計算する。 `x = x_0` の近くでテイラー展開の公式から、 `f(x) ~~ f(x_0) + (x_0-x)f'(x)` である。そこで、`f(x) = 0` を代入すると、`x = x_0 - (f(x_0))/(f'(x_0))` である。 この右辺の値を `x_1` とする。この操作を繰り返して、`x_(n+1) = x_n- (f(x_n))/(f'(x_n))` をつづければ、`x_n` は `hat(x)` に近づくと考えられる。

セカント法(割線法)

ニュートン法は `f(x)` から導関数 `f'(x)` が求められ、この微分係数が計算できることが前提である。 導関数が解析的に求めるのが困難な場合でも、導関数は `h` を 0 に近づけた場合の `f'(x) ~~ (f(x+h)-f(x))/h` として求めることができる。 ここで適当な `h` が分からない場合が多いので、`h = f(x)` とおいて、 `f'(x)` を `f'(x) ~~ (f(x+f(x))-f(x))/f(x)` とする。この方法をセカント法または割線法という。 セカント法は、導関数を用いたニュートン法の場合と比べても収束の速度はそれほど変わらないという。

eval と Function

以前は eval を使っていたが、いろいろと問題があるようなので、現在は Function を使って書き直した。 eval から Function へを参照。 (2020-03-03)

インラインイベントハンドラからイベントリスナーへの書き換え

以前はボタンをクリックすると解を求めるためのイベントとして、インラインイベントハンドラの onclick を用いていたが、いろいろと問題があるようなので、現在は addEventListener を用いて書き直した。 (2021-04-20)

式表示

式表示は、MathJax を使っている。

まりんきょ学問所へJavaScript 手習い > 解を求める


MARUYAMA Satosi