[ 簡単な説明 ] 数値微分及び数値積分ライブラリです。 下記、ライブラリ関数一覧表において、「関数定義要否」は、被積分関数または被微分関数を独立ルーチンとして準備する必要性の有無を示したものです。 (必要性ないものは、関数値や標本点を配列に入れて与えるようになっています。) 定義すべき関数名は、各ルーチンのプログラム・ソースもしくは使用例を参照して下さい。 なお、半無限区間積分および無限区間積分は、被積分関数が特殊な形のときだけ適用できます。(脚注参照) 各関数の引数に関しては、下表の呼び出し例を参考にして下さい。 |
呼び出し例 の パラメータ名 |
内容 | 型 |
xdata | 標本点配列名 | double * |
ydata | 標本点に対応する 関数値配列名 |
double * |
m、n | 要素数または分点数 | int |
x | 微分点 | double |
h、h1、h2 | 刻み、または標本点間隔 | double |
xmin、xmax | 積分範囲 | double |
eps | 収束判定値 | double |
関数名 | 微積分 | アルゴリズム | 呼び出し例 | 関数 定義 要否 |
||
lagdif( ) | 数値微分 | ラグランジェ法 | dy = lagdif(xdata, ydata, n, x); | × | ||
spldif( ) | 3次スプライン関数法 | dy = spldif(xdata, ydata, n, x); | × | |||
difm1( ) | 中点法 | 1次 | dy = difm1(x, h); | ○ | ||
difm2( ) | 2次 | dy = difm2(x, h); | ||||
difm3( ) | 3次 | dy = difm3(x, h); | ||||
difm4( ) | 4次 | dy = difm4(x, h); | ||||
difm5( ) | 5次 | dy = difm5(x, h); | ||||
difm6( ) | 6次 | dy = difm6(x, h); | ||||
difm7( ) | 7次 | dy = difm7(x, h); | ||||
difm8( ) | 8次 | dy = difm8(x, h); | ||||
diff2( ) | 前進法 | 2次 | dy = diff2(x, h); | ○ | ||
diff3( ) | 3次 | dy = diff3(x, h); | ||||
diff4( ) | 4次 | dy = diff4(x, h); | ||||
diff5( ) | 5次 | dy = diff5(x, h); | ||||
difb2( ) | 後退法 | 2次 | dy = difb2(x, h); | ○ | ||
difb3( ) | 3次 | dy = difb3(x, h); | ||||
difb4( ) | 4次 | dy = difb4(x, h); | ||||
difb5( ) | 5次 | dy = difb5(x, h); | ||||
subspl( ) | 微積分両用 | 3次スプライン関数ルーチン | − | |||
trap( ) | 数値積分 | 有限区間 | 台形法 | s = trap(xdata, ydata, n); | × | |
simpei( ) | シンプソン法 | 等間隔 | s = simpei(ydata, n, h); | × | ||
simpui( ) | 不等間隔 | s = simpui(xdata, ydata, n); | × | |||
splitg( ) | 3次スプライン関数法 | s = splitg(xdata, ydata, n); | × | |||
cheb3( ) | チェビシェフ法 | 3点法 | s = cheb3(xmin, xmax); | ○ | ||
cheb4( ) | 4点法 | s = cheb4(xmin, xmax); | ||||
cheb6( ) | 6点法 | s = cheb6(xmin, xmax); | ||||
dgl3( ) | ガウス・ ルジャンドル法 |
3分点 | s = dgl3(xmin, xmax); | ○ | ||
dgl10( ) | 10分点 | s = dgl10(xmin, xmax); | ||||
dgl20( ) | 20分点 | s = dgl20(xmin, xmax); | ||||
dgl32( ) | 32分点 | s = dgl32(xmin, xmax); | ||||
dgl48( ) | 48分点 | s = dgl48(xmin, xmax); | ||||
hardy( ) | ハーディ法 | s = hardy(xmin, xmax, n); | ○ | |||
lomberg( ) | ロンバーグ法 | s = lomberg(xmin, xmax, eps); | ○ | |||
nc1( ) | ニュートン・コーツの 数値積分式 |
第1式 | s = nc1(xmin, xmax, n); | ○ | ||
nc2( ) | 第2式 | s = nc2(xmin, xmax, n); | ||||
nc3( ) | 第3式 | s = nc3(xmin, xmax, n); | ||||
nc4( ) | 第4式 | s = nc4(xmin, xmax, n); | ||||
nc5( ) | 第5式 | s = nc5(xmin, xmax, n); | ||||
nc6( ) | 第6式 | s = nc6(xmin, xmax, n); | ||||
nc7( ) | 第7式 | s = nc7(xmin, xmax, n); | ||||
nc8( ) | 第8式 | s = nc8(xmin, xmax, n); | ||||
weddle( ) | ウェドル法 | s = weddle(xmin, xmax, n); | ○ | |||
dglg3( ) | 半無限区間 | ガウス・ ラゲール法*1 |
3分点 | s = dglg3( ); | ○ | |
dglg5( ) | 5分点 | s = dglg5( ); | ||||
dglg10( ) | 10分点 | s = dglg10( ); | ||||
dgh10( ) | 無限区間 | ガウス・ エルミート法*2 |
10分点 | s = dgh10( ); | ○ | |
dgh15( ) | 15分点 | s = dgh15( ); | ||||
simpe2( ) | 2次元 | 等間隔シンプソン法 | s = simpe2(ydata, m, n, h1, h2); | × | ||
_Normal( ) | (積分) | 積分区間正規化変換関数 | − |
/* difint.c */ #include <stdio.h> #include <stdlib.h> #include "sslib.h" double cheb3(double a, double b) { static double g[2] = { 0.0, M_SQRT_2}; double w; int mflag; if(a == b) return 0.; mflag = 0; if(a > b) { mflag = 1; w = a; a = b; b = w; } w = _f(_Normal(a, b, g[0])); w += _f(_Normal(a, b, g[1])); w += _f(_Normal(a, b, -g[1])); w *= ((b - a) / 3.); if(mflag) return -w; return w; } double cheb4(double a, double b) { static double g[2] = { 0.7946544722917661, 0.1875924740850799}; double w; int mflag; if(a == b) return 0.; mflag = 0; if(a > b) { mflag = 1; w = a; a = b; b = w; } w = _f(_Normal(a, b, g[0])); w += _f(_Normal(a, b, -g[0])); w += _f(_Normal(a, b, g[1])); w += _f(_Normal(a, b, -g[1])); w *= ((b - a) / 4.); if(mflag) return -w; return w; } double cheb6(double a, double b) { static double g[3] = { 0.2666354015167047, 0.4225186537611115, 0.8662468181078206}; double w; int mflag; if(a == b) return 0.; mflag = 0; if(a > b) { mflag = 1; w = a; a = b; b = w; } w = _f(_Normal(a, b, g[0])); w += _f(_Normal(a, b, -g[0])); w += _f(_Normal(a, b, g[1])); w += _f(_Normal(a, b, -g[1])); w += _f(_Normal(a, b, g[2])); w += _f(_Normal(a, b, -g[2])); w *= ((b - a) / 6.); if(mflag) return -w; return w; } double dgl3(double a, double b) { static double g = 0.774596669241483; static double w1 = 0.555555555555556; static double w0 = 0.88888888888889; double w; int mflag; if(a == b) return 0.; mflag = 0; if(a > b) { mflag = 1; w = a; a = b; b = w; } w = _f(_Normal(a, b, 0.)) * w0; w += (_f(_Normal(a, b, g)) + _f(_Normal(a, b, -g))) * w1; w *= ((b - a) / 2.); if(mflag) return -w; return w; } double dgl10(double a, double b) { static double g[5] = { 0.148874338981631, 0.433395394129247, 0.679409568299024, 0.865063366688985, 0.973906528517172}; static double w[5] = { 0.295524224714753, 0.269266719309996, 0.219086362515982, 0.149451349150581, 0.066671344308688}; double s; int i, mflag; if(a == b) return 0.; mflag = 0; if(a > b) { mflag = 1; s = a; a = b; b = s; } for(i = 0, s = 0.; i < 5; i++) s += w[i] *(_f(_Normal(a, b, g[i])) + _f(_Normal(a, b, -g[i]))); s *= ((b - a) / 2.); if(mflag) return -s; return s; } double dgl20(double a, double b) { static double g[10] = { 0.076526521133497333, 0.227785851141645078, 0.373706088715419561, 0.510867001950827098, 0.636053680726515025, 0.746331906460150793, 0.839116971822218823, 0.912234428251325906, 0.963971927277913791, 0.993128599185094925}; static double w[10] = { 0.152753387130725851, 0.149172986472603747, 0.142096109318382051, 0.131688638449176627, 0.118194531961518417, 0.101930119817240435, 0.083276741576704749, 0.062672048334109064, 0.040601429800386941, 0.017614007139152118}; double s; int i, mflag; if(a == b) return 0.; mflag = 0; if(a > b) { mflag = 1; s = a; a = b; b = s; } for(i = 0, s = 0.; i < 10; i++) s += w[i] *(_f(_Normal(a, b, g[i])) + _f(_Normal(a, b, -g[i]))); s *= ((b - a) / 2.); if(mflag) return -s; return s; } double dgl32(double a, double b) { static double g[16] = { 0.048307665687738316, 0.144471961582796494, 0.239287362252137075, 0.331868602282127650, 0.421351276130635345, 0.506899908932229390, 0.587715757240762329, 0.663044266930215201, 0.732182118740289680, 0.794483795967942407, 0.849367613732569970, 0.896321155766052124, 0.934906075937739690, 0.964762255587506431, 0.985611511545268335, 0.997263861849481564}; static double w[16] = { 0.096540088514727801, 0.095638720079274859, 0.093844399080804566, 0.091173878695763885, 0.087652093004403811, 0.083311924226946755, 0.078193895787070306, 0.072345794108848506, 0.065822222776361847, 0.058684093478535547, 0.050998059262376176, 0.042835898022226681, 0.034273862913021433, 0.025392065309262059, 0.016274394730905671, 0.007018610009470097}; double s; int i, mflag; if(a == b) return 0.; mflag = 0; if(a > b) { mflag = 1; s = a; a = b; b = s; } for(i = 0, s = 0.; i < 16; i++) s += w[i] *(_f(_Normal(a, b, g[i])) + _f(_Normal(a, b, -g[i]))); s *= ((b - a) / 2.); if(mflag) return -s; return s; } double dgl48(double a, double b) { static double g[24] = { 0.032380170962869362, 0.097004699209462699, 0.161222356068891718, 0.224763790394689061, 0.287362487355455577, 0.348755886292160738, 0.408686481990716730, 0.466902904750958405, 0.523160974722233034, 0.577224726083972704, 0.628867396776513624, 0.677872379632663905, 0.724034130923814655, 0.767159032515740339, 0.807066204029442627, 0.843588261624393531, 0.876572020274247886, 0.905879136715569673, 0.931386690706554333, 0.952987703160430861, 0.970591592546247250, 0.984124583722826858, 0.993530172266350758, 0.998771007252426119}; static double w[24] = { 0.064737696812683923, 0.064466164435950082, 0.063924238584648187, 0.063114192286254026, 0.062039423159892664, 0.060704439165893880, 0.059114839698395636, 0.057277292100403216, 0.055199503699984163, 0.052890189485193667, 0.050359035553854475, 0.047616658492490475, 0.044674560856694280, 0.041545082943464749, 0.038241351065830706, 0.034777222564770439, 0.031167227832798089, 0.027426509708356948, 0.023570760839324379, 0.019616160457355528, 0.015579315722943849, 0.011477234579234539, 0.007327553901276262, 0.003153346052305839}; double s; int i, mflag; if(a == b) return 0.; mflag = 0; if(a > b) { mflag = 1; s = a; a = b; b = s; } for(i = 0, s = 0.; i < 24; i++) s += w[i] *(_f(_Normal(a, b, g[i])) + _f(_Normal(a, b, -g[i]))); s *= ((b - a) / 2.); if(mflag) return -s; return s; } double dglg3(void) { int i; static double g[3] = { 0.41577455678348, 2.294280360279, 6.2899450829375}; static double w[3] = { 0.711093009929, 0.27851773356924, 0.010389256501586}; double s; for(i = 0, s = 0.; i < 3; i++) s += _f(g[i]) * w[i]; return s; } double dglg5(void) { int i; static double g[5] = { 12.64080084427578, 7.085810005858838, 3.596425771040722, 1.41340305910651679, 0.2635603197181409}; static double w[5] = { 0.0000233699723857762, 0.00361175867992205, 0.0759424496817060, 0.398666811083176, 0.521755610582809}; double s; for(i = 0, s = 0.; i < 5; i++) s += _f(g[i]) * w[i]; return s; } double dglg10(void) { int i; static double g[10] = { 29.92069701227389, 21.99658581198076, 16.27925783137810, 11.84378583790007, 8.330152746764497, 5.552496140063804, 3.401433697854900, 1.808342901740316, 0.7294545495031705, 0.1377934705404924}; static double w[10] = { 9.9118272196090e-13, 1.839564823979631e-9, 4.249313984962686e-7, 2.8259233495995656e-5, 7.530083885875388e-4, 9.5015169751811006e-3, 6.208745609867775e-2, 2.1806828761180942e-1, 4.011199291552736e-1, 3.0844111576502014e-1}; double s; for(i = 0, s = 0.; i < 10; i++) s += _f(g[i]) * w[i]; return s; } double dgh10(void) { int i; static double g[5] = { 0.3429013272237046, 1.036610829789514, 1.756683649299882, 2.532731674232790, 3.436159118837738}; static double w[5] = { 0.6108626337353258, 0.2401386110823147, 0.03387439445548106, 0.001343645746781233, 7.640432855232621e-6}; double s; for(i = 0, s = 0.; i < 5; i++) s += (_f(g[i]) + _f(-g[i])) * w[i]; return s; } double dgh15(void) { int i; static double g[8] = { 0.0, 0.56506958325557575, 1.136115585210921, 1.719992575186489, 2.325732486173858, 2.967166927905603, 3.669950373404453, 4.499990707309392}; static double w[8] = { 0.5641003087264175, 0.4120286874988986, 0.1584889157959357, 0.03078003387254608, 0.002778068842912276, 0.0001000044412324999, 1.059115547711067e-6, 1.522475804253517e-9}; double s; s = _f(g[0]) * w[0]; for(i = 1; i < 8; i++) s += (_f(g[i]) + _f(-g[i])) * w[i]; return s; } double hardy(double xmin, double xmax, int n) { double h, hh, h3, h5, hi, s, x; int i; if(n < 2) { fprintf(stderr, "Error : n < 2 in hardy()\n"); return 0.; } if(xmin == xmax) return 0.; s = _f(xmin) - 28. * _f(xmax); h = (xmax - xmin) / (double)n; hh = h / 6.; h3 = h / 2.; h5 = h / 1.2; for(i = 0, hi = 1.; i < n; i++, hi += 1.) { x = xmin + h * hi; s += (56. * _f(x) + 162. * (_f(x - h5) + _f(x - hh)) + 220. * _f(x - h3)); } return s * h / 600.; } double lomberg(double xmin, double xmax, double eps) { int idx, ierr, j, k; double t[434]; double fxmax, fxmin, fw, hi, hk, xw, w, w1; if(eps <= 0.) { fprintf(stderr, "Error : eps <= 0 in lomberg()\n"); return 0.; } if(xmin == xmax) return 0.; w = t[0] = ((fxmin = _f(xmin)) + (fxmax = _f(xmax))) * (xw = xmax - xmin) / 2.; fw = (fxmin - fxmax) / 2.; idx = 0; for(k = 2, hk = 2.; k < 30; k++, hk *= 2.) { w = xw / hk; for(hi = 1., w1 = fw; hi <= hk; hi += 1.) w1 += _f(xmin + w * hi); w = (t[++idx] = w1 * w); for(j = 1, w1 = 4.; j < k; j++, w1 *= 4.) { idx++; w = (t[idx] = (w1 * w - t[idx - k]) / (w1 - 1.)); } if(fabs(w - t[idx - k]) < fabs(eps * t[idx - k])) return w; } fprintf(stderr, "Error : No convergence in lomberg()\n"); return w; } double nc1(double xmin, double xmax, int n) { double h, hi, s; int i; if(n < 2) { fprintf(stderr, "Error : n < 2 in nc1()\n"); return 0.; } if(xmin == xmax) return 0.; s = (_f(xmin) + _f(xmax)) / 2.; h = (xmax - xmin) / (double)n; for(i = 1, hi = 1.; i < n; i++, hi += 1.) s += _f(xmin + h * hi); return s * h; } double nc2(double xmin, double xmax, int n) { double h, hh, hi, s, x; int i; if(n < 2) { fprintf(stderr, "Error : n < 2 in nc2()\n"); return 0.; } if(xmin == xmax) return 0.; s = _f(xmin) - _f(xmax); h = (xmax - xmin) / (double)n; hh = h / 2.; for(i = 0, hi = 1.; i < n; i++, hi += 1.) { x = xmin + h * hi; s += (4. * _f(x - hh) + 2. * _f(x)); } return s * h / 6.; } double nc3(double xmin, double xmax, int n) { double h, hh, h2, hi, s, x; int i; if(n < 2) { fprintf(stderr, "Error : n < 2 in nc3()\n"); return 0.; } if(xmin == xmax) return 0.; s = _f(xmin) - _f(xmax); h = (xmax - xmin) / (double)n; hh = h / 3.; h2 = h / 1.5; for(i = 0, hi = 1.; i < n; i++, hi += 1.) { x = xmin + h * hi; s += (3. * (_f(x - h2) + _f(x - hh)) + 2. * _f(x)); } return s * h / 8.; } double nc4(double xmin, double xmax, int n) { double h, hh, h2, h3, hi, s, x; int i; if(n < 2) { fprintf(stderr, "Error : n < 2 in nc4()\n"); return 0.; } if(xmin == xmax) return 0.; s = _f(xmin) - 7. * _f(xmax); h = (xmax - xmin) / (double)n; hh = h / 4.; h2 = h / 2.; h3 = h * .75; for(i = 0, hi = 1.; i < n; i++, hi += 1.) { x = xmin + h * hi; s += (14. * _f(x) + 32. * (_f(x - h3) + _f(x - hh)) + 12. * _f(x - h2)); } return s * h / 90.; } double nc5(double xmin, double xmax, int n) { double h, hh, h2, h3, h4, hi, s, x; int i; if(n < 2) { fprintf(stderr, "Error : n < 2 in nc5()\n"); return 0.; } if(xmin == xmax) return 0.; s = _f(xmin) - 19. * _f(xmax); h = (xmax - xmin) / (double)n; hh = h / 5.; h2 = h * .4; h3 = h * .6; h4 = h * .8; for(i = 0, hi = 1.; i < n; i++, hi += 1.) { x = xmin + h * hi; s += (38. * _f(x) + 75. * (_f(x - h4) + _f(x - hh)) + 50. * (_f(x - h3) + _f(x - h2))); } return s * h / 288.; } double nc6(double xmin, double xmax, int n) { double h, hh, h2, h3, h4, h5, hi, s, x; int i; if(n < 2) { fprintf(stderr, "Error : n < 2 in nc6()\n"); return 0.; } if(xmin == xmax) return 0.; s = _f(xmin) - 41. * _f(xmax); h = (xmax - xmin) / (double)n; hh = h / 6.; h2 = h / 3.; h3 = h / 2.; h4 = h / 1.5; h5 = h / 1.2; for(i = 0, hi = 1.; i < n; i++, hi += 1.) { x = xmin + h * hi; s += (82. * _f(x) + 216. * (_f(x - h5) + _f(x - hh)) + 27. * (_f(x - h4) + _f(x - h2)) + 272. * _f(x - h3)); } return s * h / 840.; } double nc7(double xmin, double xmax, int n) { double h, hh, h2, h3, h4, h5, h6, hi, s, x; int i; if(n < 2) { fprintf(stderr, "Error : n < 2 in nc7()\n"); return 0.; } if(xmin == xmax) return 0.; s = _f(xmin) - 751. * _f(xmax); h = (xmax - xmin) / (double)n; hh = h / 7.; h2 = h / 3.5; h3 = hh * 3.; h4 = h / 1.75; h5 = h / 1.4; h6 = hh * 6.; for(i = 0, hi = 1.; i < n; i++, hi += 1.) { x = xmin + h * hi; s += (1502. * _f(x) + 3577. * (_f(x - h6) + _f(x - hh)) + 1323. * (_f(x - h5) + _f(x - h2)) + 2989. * (_f(x - h4) + _f(x - h3))); } return s * h / 17280.; } double nc8(double xmin, double xmax, int n) { double h, hh, h2, h3, h4, h5, h6, h7, hi, s, x; int i; if(n < 2) { fprintf(stderr, "Error : n < 2 in nc8()\n"); return 0.; } if(xmin == xmax) return 0.; s = _f(xmin) - 989. * _f(xmax); h = (xmax - xmin) / (double)n; hh = h / 8.; h2 = h / 4.; h3 = h * .375; h4 = h / 2.; h5 = h / 1.6; h6 = h * .75; h7 = h * .875; for(i = 0, hi = 1.; i < n; i++, hi += 1.) { x = xmin + h * hi; s += (1978. * _f(x) + 5888. * (_f(x - h7) + _f(x - hh)) - 928. * (_f(x - h6) + _f(x - h2)) + 10496. * (_f(x - h5) + _f(x - h3)) - 4540. * _f(x - h4)); } return s * h / 28350.; } double weddle(double xmin, double xmax, int n) { double h, hh, h2, h3, h4, h5, hi, s, x; int i; if(n < 2) { fprintf(stderr, "Error : n < 2 in weddle()\n"); return 0.; } if(xmin == xmax) return 0.; s = _f(xmin) - _f(xmax); h = (xmax - xmin) / (double)n; hh = h / 6.; h2 = h / 3.; h3 = h / 2.; h4 = h / 1.5; h5 = h / 1.2; for(i = 0, hi = 1.; i < n; i++, hi += 1.) { x = xmin + h * hi; s += (2. * _f(x) + 5. * (_f(x - h5) + _f(x - hh)) + _f(x - h4) + _f(x - h2) + 6. * _f(x - h3)); } return s * h / 20.; } double _Normal(double a, double b, double x) { return ((b - a) * x + a + b) / 2.; } double difm1(double x, double h) { double f1; f1 = _f(x + h) - _f(x - h); return 0.5 * f1 / h; } double difm2(double x, double h) { double f1, f2; f1 = _f(x + h) - _f(x - h); f2 = _f(x + 2. * h) - _f(x - 2. * h); return (2. * f1 / 3. - f2 / 12.) / h; } double difm3(double x, double h) { double f1, f2, f3; f1 = _f(x + h) - _f(x - h); f2 = _f(x + 2. * h) - _f(x - 2. * h); f3 = _f(x + 3. * h) - _f(x - 3. * h); return (0.75 * f1 - 0.15 * f2 + f3 / 60.) / h; } double difm4(double x, double h) { double f1, f2, f3, f4; f1 = _f(x + h) - _f(x - h); f2 = _f(x + 2. * h) - _f(x - 2. * h); f3 = _f(x + 3. * h) - _f(x - 3. * h); f4 = _f(x + 4. * h) - _f(x - 4. * h); return (0.8 * f1 - 0.2 * f2 + 4. * f3 / 105. - f4 / 280.) / h; } double difm5(double x, double h) { double f1, f2, f3, f4, f5; f1 = _f(x + h) - _f(x - h); f2 = _f(x + 2. * h) - _f(x - 2. * h); f3 = _f(x + 3. * h) - _f(x - 3. * h); f4 = _f(x + 4. * h) - _f(x - 4. * h); f5 = _f(x + 5. * h) - _f(x - 5. * h); return (2100. * f1 - 600. * f2 + 150. * f3 - 25. * f4 + 2. * f5) / 2520./ h; } double difm6(double x, double h) { double f1, f2, f3, f4, f5, f6; f1 = _f(x + h) - _f(x - h); f2 = _f(x + 2. * h) - _f(x - 2. * h); f3 = _f(x + 3. * h) - _f(x - 3. * h); f4 = _f(x + 4. * h) - _f(x - 4. * h); f5 = _f(x + 5. * h) - _f(x - 5. * h); f6 = _f(x + 6. * h) - _f(x - 6. * h); return (23760. * f1 - 7425. * f2 + 2200. * f3 - 495. * f4 + 72. * f5 - 5. * f6) / 27720. / h; } double difm7(double x, double h) { double f1, f2, f3, f4, f5, f6, f7; f1 = _f(x + h) - _f(x - h); f2 = _f(x + 2. * h) - _f(x - 2. * h); f3 = _f(x + 3. * h) - _f(x - 3. * h); f4 = _f(x + 4. * h) - _f(x - 4. * h); f5 = _f(x + 5. * h) - _f(x - 5. * h); f6 = _f(x + 6. * h) - _f(x - 6. * h); f7 = _f(x + 7. * h) - _f(x - 7. * h); return (315315. * f1 - 105105. * f2 + 35035. * f3 - 9555. * f4 + 1911. * f5 - 245. * f6 + 15. * f7) / 360360. / h; } double difm8(double x, double h) { double f1, f2, f3, f4, f5, f6, f7, f8; f1 = _f(x + h) - _f(x - h); f2 = _f(x + 2. * h) - _f(x - 2. * h); f3 = _f(x + 3. * h) - _f(x - 3. * h); f4 = _f(x + 4. * h) - _f(x - 4. * h); f5 = _f(x + 5. * h) - _f(x - 5. * h); f6 = _f(x + 6. * h) - _f(x - 6. * h); f7 = _f(x + 7. * h) - _f(x - 7. * h); f8 = _f(x + 8. * h) - _f(x - 8. * h); return (1921920. * f1 - 672672. * f2 + 244608. * f3 - 76440. * f4 + 18816. * f5 - 3360. * f6 + 384. * f7 - 21. * f8) / 2162160. / h; } |
/* bibun.c */ #include <stdio.h> #include "sslib.h" double diff2(double x, double h) { double f1, f2; f1 = _f(x + h) - _f(x); f2 = _f(x + 2. * h) - _f(x); return (2. * f1 - 0.5 * f2) / h; } double diff3(double x, double h) { double f1, f2, f3; f1 = _f(x + h) - _f(x); f2 = _f(x + 2. * h) - _f(x); f3 = _f(x + 3. * h) - _f(x); return (3. * f1 - 1.5 * f2 + f3 / 3.) / h; } double diff4(double x, double h) { double f1, f2, f3, f4; f1 = _f(x + h) - _f(x); f2 = _f(x + 2. * h) - _f(x); f3 = _f(x + 3. * h) - _f(x); f4 = _f(x + 4. * h) - _f(x); return (4. * f1 - 3. * f2 + 4. * f3 / 3. - 0.25 * f4) / h; } double diff5(double x, double h) { double f1, f2, f3, f4, f5; f1 = _f(x + h) - _f(x); f2 = _f(x + 2. * h) - _f(x); f3 = _f(x + 3. * h) - _f(x); f4 = _f(x + 4. * h) - _f(x); f5 = _f(x + 5. * h) - _f(x); return (5. * (f1 - f2) + 10. * f3 / 3. - 1.25 * f4 + 0.2 * f5) / h; } double difb2(double x, double h) { double f1, f2; f1 = _f(x - h) - _f(x); f2 = _f(x - 2. * h) - _f(x); return - (2. * f1 - 0.5 * f2) / h; } double difb3(double x, double h) { double f1, f2, f3; f1 = _f(x - h) - _f(x); f2 = _f(x - 2. * h) - _f(x); f3 = _f(x - 3. * h) - _f(x); return - (3. * f1 - 1.5 * f2 + f3 / 3.) / h; } double difb4(double x, double h) { double f1, f2, f3, f4; f1 = _f(x - h) - _f(x); f2 = _f(x - 2. * h) - _f(x); f3 = _f(x - 3. * h) - _f(x); f4 = _f(x - 4. * h) - _f(x); return - (4. * f1 - 3. * f2 + 4. * f3 / 3. - 0.25 * f4) / h; } double difb5(double x, double h) { double f1, f2, f3, f4, f5; f1 = _f(x - h) - _f(x); f2 = _f(x - 2. * h) - _f(x); f3 = _f(x - 3. * h) - _f(x); f4 = _f(x - 4. * h) - _f(x); f5 = _f(x - 5. * h) - _f(x); return - (5. * (f1 - f2) + 10. * f3 / 3. - 1.25 * f4 + 0.2 * f5) / h; } |
/* simp.c */ #include <stdio.h> #include <stdlib.h> #include "sslib.h" double *h, *sp, *x, *y; int *jun; int h_malloc(int n, char *proname); int sp_malloc(int n, char *proname); int x_malloc(int n, char *proname); int y_malloc(int n, char *proname); int jun_malloc(int n, char *proname); int h_malloc(int n, char *proname) { h = (double *)calloc(n, sizeof(double)); if(h == NULL) { fprintf(stderr, "Error : Out of memory in %s()\n", proname); return -1; } return 0; } int sp_malloc(int n, char *proname) { sp = (double *)calloc(n, sizeof(double)); if(sp == NULL) { fprintf(stderr, "Error : Out of memory in %s()\n", proname); return -1; } return 0; } int x_malloc(int n, char *proname) { x = (double *)calloc(n, sizeof(double)); if(x == NULL) { fprintf(stderr, "Error : Out of memory in %s()\n", proname); return -1; } return 0; } int y_malloc(int n, char *proname) { y = (double *)calloc(n, sizeof(double)); if(y == NULL) { fprintf(stderr, "Error : Out of memory in %s()\n", proname); return -1; } return 0; } int jun_malloc(int n, char *proname) { jun = (int *)calloc(n, sizeof(int)); if(jun == NULL) { fprintf(stderr, "Error : Out of memory in %s()\n", proname); return -1; } return 0; } double lagdif(double xd[], double yd[], int n, double xx) { int flag, i, j, k; double sm0, sm1, sm2, w, xi; if(x_malloc(n, "lagdif")) return 0.; if(y_malloc(n, "lagdif")) { free(x); return 0.; } for(i = 0, flag = 0; i < n - 1; i++) { if(xd[i] >= xd[i + 1]) { flag = 1; break; } } if(flag) { if(jun_malloc(n, "lagdif")) { free(y); free(x); return 0.; } sortdi1(xd, n, jun); for(i = 0; i < n; i++) { x[i] = xd[jun[i]]; y[i] = yd[jun[i]]; } free(jun); } else { for(i = 0; i < n; i++) { x[i] = xd[i]; y[i] = yd[i]; } } if(n < 2) { fprintf(stderr, "Error : n < 2 in lagdif()\n"); free(y); free(x); return 0.; } if(xx < x[0] || xx > x[n - 1]) { fprintf(stderr, "Error : xx is out of range in lagdif()\n"); free(y); free(x); return 0.; } w = 0.; for(i = 0; i < n; i++) { sm0 = 0.; sm2 = 1.; xi = x[i]; for(j = 0; j < n; j++) { if(i != j) { sm2 *= (xi - x[j]); for(k = 0, sm1 = 1.; k < n; k++) if((k != i) && (k != j)) sm1 *= (xx - x[k]); sm0 += sm1; } } w += (y[i] * sm0 / sm2); } free(y); free(x); return w; } double spldif(double xd[], double yd[], int n, double xx) { int flag, i; double sp[100], diff, dxp2, dxm2, hi, hi2; if(h_malloc(n, "spldif")) return 0; if(sp_malloc(n, "spldif")) { free(h); return 0.; } if(x_malloc(n, "spldif")) { free(sp); free(h); return 0.; } if(y_malloc(n, "spldif")) { free(x); free(sp); free(h); return 0.; } for(i = 0, flag = 0; i < n - 1; i++) { if(xd[i] >= xd[i + 1]) { flag = 1; break; } } if(flag) { if(jun_malloc(n, "spldif")) { free(y); free(x); free(sp); free(h); return 0.; } sortdi1(xd, n, jun); for(i = 0; i < n; i++) { x[i] = xd[jun[i]]; y[i] = yd[jun[i]]; } free(jun); } else { for(i = 0; i < n; i++) { x[i] = xd[i]; y[i] = yd[i]; } } if(n < 2) { fprintf(stderr, "Error : n < 2 in spldif()\n"); free(y); free(x); return 0.; } if(xx < x[0] || xx > x[n - 1]) { fprintf(stderr, "Error : xx is out of range in spldif()\n"); free(y); free(x); return 0.; } subspl(x, y, n - 1, h, sp); for(i = 1; i < n; i++) { if(x[i - 1] <= xx && xx <= x[i]) { hi = h[i]; hi2 = hi * hi; dxp2 = (x[i] - xx); dxp2 *= dxp2; dxm2 = (xx - x[i - 1]); dxm2 *= dxm2; diff = (sp[i - 1] * (hi2 - 3. * dxp2) + sp[i] * (3. * dxm2 - hi2) + 6. * (y[i] - y[i - 1])) / 6. / hi; free(y); free(x); free(sp); free(h); return diff; } } return 0; } void subspl(double x[], double y[], int n, double h[], double sp[]) { int i; double *dc, *du, g, hip1; dc = (double *)calloc(n + 1, sizeof(double)); du = (double *)calloc(n + 1, sizeof(double)); if(dc == NULL || du == NULL) { fprintf(stderr, "Error : out of memory in subspl().\n"); return; } for(i = 1; i <= n; i++) h[i] = x[i] - x[i - 1]; for(i = 1; i < n; i++) { hip1 = x[i + 1] - x[i]; sp[i] = 6.* ((y[i + 1] - y[i]) / h[i] / hip1 - (y[i] - y[i - 1]) / h[i] / h[i]); du[i] = h[i + 1] / h[i]; dc[i] = 2. * (1. + du[i]); } dc[n] += 1.; dc[n - 1] += (h[n] / h[n - 1]); du[1] /= dc[1]; sp[1] /= dc[1]; for(i = 2; i <= n; i++) { g = 1. / (dc[i] - du[i - 1]); du[i] *= g; sp[i] = (sp[i] - sp[i - 1]) * g; } for(i = n - 1; i >= 1; i--) sp[i] -= sp[i + 1] * du[i]; sp[0] = sp[1]; sp[n] = sp[n - 1]; free(du); free(dc); } double trap(double xx[], double yy[], int n) { int flag, i; double w; if(x_malloc(n, "trap")) return 0.; if(y_malloc(n, "trap")) { free(x); return 0.; } for(i = 0, flag = 0; i < n - 1; i++) { if(xx[i] >= xx[i + 1]) { flag = 1; break; } } if(flag) { if(jun_malloc(n, "trap")) { free(y); free(x); return 0.; } sortdi1(xx, n, jun); for(i = 0; i < n; i++) { x[i] = xx[jun[i]]; y[i] = yy[jun[i]]; } free(jun); } else { for(i = 0; i < n; i++) { x[i] = xx[i]; y[i] = yy[i]; } } if(n <= 1) { fprintf(stderr, "Error : n <= 1 in trap()\n"); free(y); free(x); return 0.; } for(i = 1, w = 0.; i < n; i++) w += (x[i] - x[i - 1]) * (y[i] + y[i - 1]); free(y); free(x); return w / 2.; } double simpei(double y[], int n, double h) { int i; double w; if(n <= 2 || n % 2 == 0 || h <= 0.) { fprintf(stderr, "Error : Illegal parameter in simpei()\n"); return 0.; } w = - y[0] + y[n - 1]; for(i = 0; i < n - 1; i += 2) w += (2. * y[i] + 4. * y[i + 1]); return w * h / 3.; } double simpui(double xx[], double yy[], int n) { int flag, i; double d, h, hpd, hmd, w, ww; if(x_malloc(n, "simpui")) return 0.; if(y_malloc(n, "simpui")) { free(x); return 0.; } for(i = 0, flag = 0; i < n - 1; i++) { if(xx[i] >= xx[i + 1]) { flag = 1; break; } } if(flag) { if(jun_malloc(n, "simpui")) { free(y); free(x); return 0.; } sortdi1(xx, n, jun); for(i = 0; i < n; i++) { x[i] = xx[jun[i]]; y[i] = yy[jun[i]]; } free(jun); } else { for(i = 0; i < n; i++) { x[i] = xx[i]; y[i] = yy[i]; } } if(n <= 2 || n % 2 == 0) { fprintf(stderr, "Error : Illegal parameter in simpui()\n"); free(y); free(x); return 0.; } for(i = 2, w = 0.; i < n; i += 2) { h = (x[i] - x[i - 2]) / 2.; hpd = 1. / (x[i - 1] - x[i - 2]); d = x[i - 1] - x[i - 2] - h; hmd = 1. / (x[i] - x[i - 1]); ww = (1. + 2. * d * hpd) * y[i - 2]; ww += 2. * h * (hpd + hmd) * y[i - 1]; ww += (1. - 2. * d * hmd) * y[i]; w += ww * h; } free(y); free(x); return w / 3.; } double splitg(double xx[], double yy[], int n) { int flag, i; double hi, hi2, w; if(h_malloc(n, "splitg")) return 0.; if(sp_malloc(n, "splitg")) { free(h); return 0.; } if(x_malloc(n, "splitg")) { free(sp); free(h); return 0.; } if(y_malloc(n, "splitg")) { free(x); free(sp); free(h); return 0.; } for(i = 0, flag = 0; i < n - 1; i++) { if(xx[i] >= xx[i + 1]) { flag = 1; break; } } if(flag) { if(jun_malloc(n, "splitg")) { free(y); free(x); free(sp); free(h); return 0.; } sortdi1(xx, n, jun); for(i = 0; i < n; i++) { x[i] = xx[jun[i]]; y[i] = yy[jun[i]]; } free(jun); } else { for(i = 0; i < n; i++) { x[i] = xx[i]; y[i] = yy[i]; } } if(n <= 2 || n % 2 == 0) { fprintf(stderr, "Error : Illegal parameter in simpui()\n"); free(y); free(x); free(sp); free(h); return 0.; } subspl(x, y, n - 1, h, sp); for(i = 1, w = 0.; i < n; i++) { hi = h[i]; hi2 = hi * hi * 0.0833333333333333333; w += hi * (y[i] + y[i - 1] - hi2 * (sp[i - 1] + sp[i])); } free(y); free(x); free(sp); free(h); return w / 2.; } double simpe2(double y[], int m, int n, double h1, double h2) { int i, ij, j, m1, n1; double v; if(x_malloc(m, "simpe2")) return 0.; if(m <= 2 || n <= 2 || m % 2 == 0 || n % 2 == 0) { fprintf(stderr, "Error : Illegal parameter in simpe2()\n"); free(x); return 0.; } m1 = m - 1; n1 = n - 1; for(i = 0; i < m; i++) { v = - y[i * n] + y[i * n + n1]; for(j = 0, ij = i * n; j < n1 - 1; j += 2, ij += 2) v += (2 * y[ij] + 4 * y[ij + 1]); x[i] = v; } v = - x[0] + x[m1]; for(i = 0; i < m1 - 1; i += 2) v += (2 * x[i] + 4 * x[i + 1]); free(x); return v * h1 * h2 / 9.; } |