ご利用にあたって
はさみうち法による f(x) = 0 の解(参照:「方程式の根」)を求める。
fxは文字列として、全体を" "で囲む。
xmin~xmaxの間に唯一の実根があることを前提にしている( f(xmin) と f(xmax) が同符号ではいけません。
二分法でxmin~xmaxの範囲を狭めていき、絶対誤差 |f(x)| < eps になるまで繰り返す。epsを省略すると、(xmax-xmin)/1000とする。
入力 var fx = "x*x-1"; var xmin = 0; var xmax = 3; var eps = 0.001; 出力 var x = naFx0Hasamiuchi(fx, xmin, xmax, eps); // x:1
ニュートン法により、方程式の実根を求める。
xn = xn-1 - f(xn-1)/f'(xn-1) (f'=df/dx)
を繰り返して根に近づく。参照:「方程式の根」
x0は初期値。その値により異なる解に達したり、解が得られないことがある。
fxは文字列として、" "で囲む。eps を省略すると 0.001 になる、
入力 var fx = "x*x-1"; var x0 = 0.3;; var eps = 0.001; 出力 var x = naFx0Newton(fx, x0, eps); // x:1
a3を省略すると2次方程式、さらにa2を省略すると1次方程式になる。
2次方程式は根の公式による。3次方程式は、特殊なケースを除き、ニュートン法により一つの実根を求め、式の変形により2次方程式にして求める。
戻り値は2次元配列である。下の[出力]参照
入力 var x = naFx03ji(2, 0, -1, 1); // 2x3 - x + 1 = 0 出力 x[k][0] 実数部 x[k][1] 虚数部 x[0][0}= 1.000 x[0][1}= 0.9999 x[1][0}= 1.000 x[1][1}=-0.9999 x[2][0}=-1.000 x[2][1}= 0
数式 f(x) が最大となるxの値を戻します。
xmin~xmaxを100等分してdxとし、for (x=xmin, x<=xmax; x=x+dx) でf(x) を最大にする x を求め、次に x-dx~x+dx で同様な操作を繰り返すことにより、最終的な最適値 x を求めます。epsを省略すると(xmax-xmin)/1000になります。
入力 var fx= "x*(x-1)*(x-2)"; var xmin = -1; var xmax = 2; var eps = 0.0001; 出力 var x = naFxMax(fx, xmin, xmax, eps); // x = 0.4226
fxのxにおける微係数aを求めます。xの近傍の2点 x-d*xとx-d*xでの勾配をa0とし、dを1/2にしたときの勾配aとの差が、相対誤差 |(a-a0)/a| < eps になるまで繰り返します。
dを省略すると0.01、epsを省略すると0.001にしています。
入力 var fx= "x*x"; var x = 1; var d = 0.01; var eps = 0.001; 出力 var a = naFxDiff(fx, x, d, eps); // a = 2
一階微分 dy/dx = f(x,y) の式を与えて y(x+dx) = y(x) + a*dx の a の値を、4次のルンゲクッタ法により求めます。
ルンゲクッタ法では、次のステップで定義します。
k1 = f(x,y)
k2 = f(x+dx/2, y+k1*dx/2)
k3 = f(x+dx/2, y+k2*dx/2)
k4 = f(x+dx, y+k3*dx)
a = (k1 + 2*k2 + 2*k3 + k4) / 6
入力 var fxy= "x*y"; // 文字列 f(x,y) をJavaScript形式で記述 var x = 2; // fxy に x がなくても形式的に適当な値を与える var y = 1; // fxy に y がなくても形式的に適当な値を与える var dx = 0.01; 出力 var a = naFxRungeKutta(yx, x, y, dx);
一階微分 dy/dx = f(x,y) の式を与えて 4次のルンゲクッタ法により x = xmin~xmax に対応する y を算出します(y0 は x = xmin のときの y の値)。
rtn["x"]: x = xmin, xmin+dx, xmin+2*dx, …, xmax の値
rtn["y"]: x に対応する y の値
rtn["a"]: (x,y) における微分係数
rtn["dy"}:y の増分 a*dx
二つの一階微分 dx/dt = f(x,y), dy/dt = g(x,y) の式を与えて、
点(x,y) で x(t+dt) = x(t) + ax*dt, y(t+dt) = y(t) + ay*dt となる偏微分係数 ax, ay の値を
4次のルンゲクッタ法により求めます。
ルンゲクッタ法では、次のステップで定義します。
k1 = f(x,y)
k2 = f(x+dx/2, y+k1*dx/2)
k3 = f(x+dx/2, y+k2*dx/2)
k4 = f(x+dx, y+k3*dx)
a = (k1 + 2*k2 + 2*k3 + k4) / 6
入力 var ft = "4*x - x*y"; // dx/dt を 文字列 ft として与える var gt = "-10*x + 2*x*y"; // dy/dt を 文字列 gt として与える var x = 10; var y = 15; var dt = 0.01; 出力 var ax. ay = naFxRungeKutta2(ft, gt, x, y, dt);
二つの一階微分 dx/dt = f(x,y), dy/dt = g(x,y) の式と t = tmin における x0, y0 を与えて、t = tmin~tmax (刻み dt)での x(t), y(t) を表の形式で戻します。
rtn["t"]: t[i] = t t = tmin, tmin+dt, tmin+2*dt, …, tmax の値数式 f(x) の極値 f'(x) が正から負へ、負から正に変化する点(複数)を戻します。 まず、xmin~xmaxを100等分してdxとし、x-dx と x+dx の間で f'(x) の符号が変化したら極値があることになります。、 次に x-dx~x+dx で同様な操作を繰り返すことにより、最終的な最適値 x を求めます。精度は0.0001 になります。 戻り値の形式 極値:xi 大小:xi が極大なら1、極小なら-1
入力 var fx= "x*(x-1)*(x-2)"; var xmin = -1; var xmax = 3; var [極値, 大小] = naFxExtreme(fx, xmin, xmax); 出力 極値[0] = 0.423 大小[0] = 1 極値[1] = 1.578 大小[1] = -1
シンプソン則は、2次式で近似します。
閉区間[xmin,xmax]を2n等分して、h=(xmax-xmin)/2にすると(すなわち、
、x0(=xmin),x1,x2,....,x2n(=max)ととして、xiに対応するfxの値を yiとすると)
xmax-xmin S=─────{(y0+y2n)+4(y1+y3+...y2n-1)+2(y2+y4+...y2n-2)} 6nとなります。参照:「定積分」
最初のn2で計算した値をs0、次にn2を2倍(すなわちキザミ幅を1/2)にして計算した値を s として、相対誤差 |(s-s0)/s| <eps となるまで繰り返します。
n2を省略すると20、epsを省略すると (xmax-xmin)/1000 にしています。
入力 var fx = "x*x"; var xmin = 1; var xmax = 2; var n2 = 20; var eps = 0.001; 出力 var s = naFxSimpson(fx, xmin, xmax, n2, eps); // s = 2.333
漸化式の係数と初期値を与えて、an の一般解を「文字列」として戻します。 ここでは一般解が1命令で表現できる漸化式に限定しています。 Trace では、元の漸化式を順次計算した数列と、一般解にnを代入した数列を表示するので、 一般解の確認ができます。 (係数と初期値の値によっては、一般解が得られないこともあります)
a1 および(あるいは)p が負数のときは、q を整数に限定しています。 その場合でも、適切な解がえられないことがあります、
特性方程式の判別式 D = q2 + 4q の正負により、計算方法が異なります。 D > 0 (実根)の例:a1=0, a2=1, p=2, q=3 D = 0 (重根)の例:a1=0, a2=3, p=6. q=-9 D < 0 (虚根)の例:a1=2, a2=4, p=2, q=-3
var x = [ 0, 2, 4, 6, 8, 10, 12 ]; var y = [ 1, 20, 30, 45, 50, 60, 70 ]; var a = naLsm1(x, y); // a[0] = 6.5, a[1] = 5.48 y = 6.5 + 5.48x
var x = [ 0, 2, 4, 6, 8, 10, 12 ]; var y = [ 5, 20, 30, 45, 50, 60, 70 ]; var rtn = naLsm1Ex(x, y); // rtn['係数'] 係数[0]=8.393, 係数[1]=5.268 // rtn['相関係数']=0.993 // rtn['信頼区間'] // 信頼区間[0]=4.830, 信頼区間[1]=3.789, … , 信頼区間[6]=4.830
n次式、
y=a[0]+a[1]x+a[2]x2+・・・+a[n]xn
の a[i] は、次の連立方程式の解になります。
a[0] | a[1] | a[2] | ・・・ | a[n] | 定数項 | |
n | ∑x | ∑x2 | ・・・ | ∑xn | ∑y | |
∑x1 | ∑x2 | ∑x3 | ・・・ | ∑xn+1 | ∑yx | |
∑x2 | ∑x3 | ∑x4 | ・・・ | ∑xn+2 | ∑yx2 | |
: | : | : | : | : | : | |
∑xn | ∑xn+1 | ∑xn+2 | ・・・ | ∑x2n | ∑yxn |
var y = [ 8, 5, 2, 0, 3, 6, 8 ]; var x = [-3, -2, -1, 0, 1, 2, 4 ]; var n = 2; naLsmMDTrace(x, y, n); // a[0] = 2.1, a[1] = -0.2, a[2]=0.5 y = 2.1 - 0.2x + 0.5x2
多項一次式
y=a[0]+a[1]x[0]+a[2]x[1]+・・・+a[n]x[n-1]
の係数 a[i] は、次の連立方程式の解になります。
a[0] | a[1] | a[2] | ・・・ | a[n] | 定数項 | |
n | ∑x[0] | ∑x[1] | ・・・ | ∑x[n-1] | ∑y | |
∑x[0] | ∑x[0]x[0] | ∑x[0]x[1] | ・・・ | ∑x[0]x[n-1] | ∑yx[0] | |
∑x[1] | ∑x[1]x[0] | ∑x[1]x[1] | ・・・ | ∑x[1]x[n-1] | ∑yx[1] | |
: | : | : | : | : | : | |
∑x[n-1] | ∑x[n-1]x[0] | ∑x[n-1]x[1] | ・・・ | ∑x[n-1]x[n-1] | ∑yx[n-1] |
var y = [12, 15, 4, 2, 18, 1, 14]; var x = [ [ 0, 1, 2, 3, 4, 5, 6], [ 2, 5, 3, 1, 7, 1, 4], [ 4, 3, 0, 1, 5, 2, 6] ]; var a = naLsmMVTrace(x, y); // a[0]=1.08, a[1]=-1.046, a[2]=1.68, a[3]=1.98 // y= 1.08 - 1.04x[0]+1.68x[1]+1.98x[2]
n+1個の点(x0,y0), (x1,y1), …,(xn,yn)を通るn次式 f(x)を、
f(x)=c0 + c1(x-x0) + c2(x-x0)(x-x1)
+ … + cn(x-x0)(x-x1)…(x-xn-1)
の形で表します。そして、
f(x0)=y0、f(x1)=y1、…、f(xn+1)=yn+1
の関係から、cの値を求めて、n次式 f(x) を決定します。参照:「ニュートンの補間公式」
入力 var x = [ 0, 2, 3, 5 ]; var y = [ 1, 5, 8,10 ]; var px = [1, 4]; 出力 py = naPolNewton(x, y, px); // py = [1.614, 8.189, 6.499] // px=1 px=4 px=6
n+1組の点xa[0]~xa[n]、ya[0]~ya[n] を通るn次式をラグランジュの補間法により求め、m 個の、xa[n+1]~xa[n+1} における ya[n+1]~ya[n+m] を戻します。
n次式に一般化して、
y=c0y0+c1y1+c2y2+・・・+cnyn
としたときの、ckは、次の式になります。
ck = (x-x0)/(xk-x0) * (x-x1)/(xk-x1) * … * (x-xk-1)/(xk-xk-1)
((x-xk)/(xk-xk)の項がないことに注意)
* (x-xk+1)/(xk-xk+1) * … * (x-xn)/(xk-xn)
参照:「ラグランジュの補間法」
入力 var x = [ 0, 2, 3, 5, 7, 8 ]; var y = [ 4, 2, 6, 8, 6, 8 ]; var px = [1, 4. 6 ]; 出力 py = naPolLagrange(x, y, px); // py = [1.614, 8.189, 6.499] // px=1 px=4 px=6
スプライン補間は、n+1個の点 (x0,y0), (x1,y1), … , (xn,yn) を、2つの点の区間 [xj~xj+1]ごとに別々の式(一般には3次式)Sj(x) を設定して緩やかな曲線にし、極端な補間値にならないようにする補間法です。参照:「スプライン補間」
区間 [xj~xj+1] における3次式を
Sj=aj(x-xj)3 + bj(x-xj)2 + cj(x-xj) + dj (j=0~n-1)
とします。
ここで aj, bj, cj, dj を求めることになります。
これらの3次式が滑らかにつながっている必要があります。それで、xj におけるSj-1とSjの1次導関数(傾き)S(1) と2次導関数(滑らかさ)S(2) の値が等しいという条件を加えます。さらに、始点 x0 と終点 xn での2次導関数の値が0であるとの仮定をします。
入力 var x = [ 0, 2, 3, 5, 7, 8 ]; var y = [ 4, 2, 6, 8, 6, 8 ]; var px = [1, 4. 6 ]; 出力 py = naPolSpline(x, y, px); // py = [1.614, 8.189, 6.499] // px=1 px=4 px=6
n組の(x,y)から、最小二乗法により、r次の近似式 y=c0+a1x+c2x2+...+crxr の係数 ci を求め。この近似式により、f個の px に対応する py を計算します。;
参照:「回帰分析・最小二乗法」、
「多項式、高次式での最小二乗法」
入力 var 次数 = 3; var x = [ 0, 2, 3, 5, 7, 8 ]; var y = [ 4, 2, 6, 8, 6, 8 ]; var px = [1, 4. 6 ]; 出力 var rtn = naPolLeastSquare(表示場所, 次数, x, y, px); // c: rtn["係数"] = 3.610, -0.778 ,0.523, -0.046 近似式 = 3.610 - 0.778x + 0.523x2 - 0.0463 // py: rtn["補間値"] = 3.309, 5.894, 7.731
ベジェ曲線とは、始点と終点を固定し、その直線を制御点から引っ張るような曲線にしたものです。 その計算方法は下式の通りです。 これらの式で、t=0 ~ 1 を p個に等分して、曲線の座標を (X[i], Y[i]) i=0 ~ p で戻します。 2次ベジェ(3点を与える。始点(x[0,y[0]), 終点(x[2],y[2]), 制御点(x[1],y[1]) X[i] = (1-t)2*x[0] + 2(1-t)t*x[1] + t2*x[2] Y[i] = (1-t)2*y[0] + 2(1-t)t*y[1] + t2*y[2] 3次ベジェ(4点を与える。始点(x[0,y[0]), 終点(x[3],y[3]), 制御点(x[1],y[1]),(x[2],y[2])(x[2],y[2]) X[i] = (1-t)3*x[0] + 3(1-t)2t*x[1] + 3(1-t)*t2*x[2] + t3*x[3] Y[i] = (1-t)3*y[0] + 3(1-t)2t*y[1] + 3(1-t)*t2*y[2] + t3*y[3]
ケース1始点 制御点 終点 var x = [ 0, 1, 2, 3]; var y = [ 0, 0.5, 3.5, 3]; 等分個数 var [X, Y] = naBezier(x, y, 10); ケース2 |
説明変数や被説明変数の標本から、連立方程式の定式化を行い、解を求めるまでの一連の処理を行うには、 maMregEq関数があります。
入力 var 係数表 = [ [0, 3, 2], // 0x0 + 3x1 + 2x2 = 12 [2, 4, 0], // 2x0 + 4x1 + 0x2 = 10 [3, 1, 5] ]; // 3x0 + 1x1 + 5x2 = 20 var 定数項 = [12, 10, 20]; 出力 var 解 = naGaussJordan(係数表, 定数項); // 解[0] = 1, 解[1] = 2, 解[2] = 3
例えば、4個の点 [x0,y0], [x1,y1], [x2,y2], [x3,y3] を通る3次式 y = b[0] + b[1]x + b[2]x2 + b[3]x3 の係数 b[i] を求めます。
x0 < x1 < … < xn にしてください。xn が極端に大きくならないように単位を調整してください。
連立一次方程式(ガウス=ジョルダンの掃出し法)の応用です。
入力: 点 = [[-1,0], [0,2], [1,6], [2,8] ];
出力: b[0] = 2, b[1] = 3, b[2] = 2, b[3] = -1
行・列のサイズn の配列 a[i][j] の逆行列を、ガウス=ジョルダンの掃出法で求めます。メイン側で定義した二次元配列 x を与えれば、x に逆行列が入り、a は壊されません。xを省略すると a が逆行列になります。
入力 var 行列 = [ [0, 3, 2], [2, 4, 0], [3, 1, 5] ]; 出力 var 逆行列 = naMtxInv(行列); // 逆行列 = [ [ -0.4, 0.26, 0.16], // [ 0.2, 0.12, -0.08]. // [ 0.2, -0.18, 0.12] ]
共分散行列や相関行列のように、対角要素が0でない対称行列の逆行列を求めます。 対角要素を順に pivot とすればよいので単純になります。
var S = [ [42.00, 15.00, 24.50], [15.00, 31.50, 21.25], [24.50, 21.25, 35.88] ];
かなり高度・複雑な処理なので、次の制約を設けました。 ・次数は2次あるいは3次だけとする。 ・固有値は実固有値だけを対象にする。 多変量解析では、高次の対称行列から、実数で絶対値の大きい固定値を2,3だけ必要なことがあります。 その目的には、maEigenPowerがあります。
入力 var 行列 = [ [ -1, 2, 2], [ 2, 2, 2], [ -3, -6, -6] ]; 出力 var rtn = naMtxEigen(行列); // rtn["λ"] rtn["V"] // -3 1, 0, -1 // -2 -2, 1, 0 // 0 0, 1, -1
該当する項がないときは、係数(a)を 0 にしてください。 出力 二次形式の標準化を行います xTAx の対称行列 A 標準化したときの係数(固有ベクトル)λxX2 + λyY2 naQuad2Trace では、関連する多様な情報も出力 (参照:二次形式,楕円と双曲線のグラフ)
2変数 F(x,y) = 3x2 + 3y2 - 2xy → axx = 3, ayy = 3, axy = -2 var rtn = naQuad(axx, ayy, axy); 出力 A = rtn["A"} A[0][0] = 3 A[0][1] = -1 A[1][0] = -1 A[1][1] = 3 λ = rtn["λ"] λ[0] = 4 λ[1] = 2 3変数 F(x,y,z) = 1x2 + 2y2 - 1z2 + 0xy - 2yz + 2zx → axx=1, ayy=2, azz=-1, axy=0, ayz=-2, azx=2 var rtn = naQuad(axx, ayy, azz, axy, ayz, azx);
欠ける項は 0 を指定してください。
F(x,y) = axxx2 + ayyy2 + axyxy + axx + ay + a1 を ・x = x - u, y = y - v の変換をして、1次の項を消去する。 G(x,y) = axxx2 + ayyy2 + axyxy + a1 = 0 ・さらに標準化して、 H(x,y) = λxX2 + λyY2 + C = 0 の形式にする。
例1:F(x,y) = x2 + y2 + xy - 3x - 3y = 0 naQuad2XYTrace(表示場所, 1, 1, 1, -3, -3, 0); 例2:F(x,y) = x2 - y2 - 2xy + 4x + 4y + 4 = 0 naQuad2XYTrace(表示場所, 1, -1, -2, 4, 4, 4);
F(x,y) = axxx2 + ayyy2 + axyxy + axx + ay + a1 欠ける項は 0 を指定してください。