imsl c 数値計算ライブラリ - xlsoftjp.xlsoft.com/documents/vni/cmath_jpn.pdftable of...

752
IMSL C 数値計算ライブラリ By Visual Numerics, Inc.

Upload: others

Post on 18-Mar-2021

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL C 数値計算ライブラリ

By Visual Numerics, Inc.

Page 2: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに
Page 3: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Table of Contents

イントロダクション 11IMSL C Math ライブラリ ...................................................................................................... 11初めに ...................................................................................................................................... 11

ANSI C vs. 非 ANSI C.............................................................................................. 11imsl.h ファイル ........................................................................................................ 12

スレッドセーフの使用法 ...................................................................................................... 12信号操作 ................................................................................................................... 12出力ルーチン ........................................................................................................... 13入力引数 ................................................................................................................... 13

行列格納モード ...................................................................................................................... 13一般モード ............................................................................................................... 13矩形モード ............................................................................................................... 13対称モード ............................................................................................................... 14エルミートモード ................................................................................................... 14疎行列対応座標格納フォーマット ....................................................................... 14帯格納フォーマット ............................................................................................... 17帯形式と対応座標形式の選択方法 ....................................................................... 18圧縮された疎の列 (CSC) フォーマット ............................................................. 19

出力配列のためのメモリ割り当て ...................................................................................... 19正しいルーチンを見つける方法 .......................................................................................... 20本マニュアルの構成 .............................................................................................................. 20命名規則 .................................................................................................................................. 21エラー処理、アンダーフロー、オーバーフロー、ドキュメント例 .............................. 21計算結果の表示 ...................................................................................................................... 22複素数演算 .............................................................................................................................. 22欠損値 ...................................................................................................................................... 22ユーザ関数へのデータの受け渡し ..................................................................................... 22

第 1章:線形連立方程式 25ルーチン .................................................................................................................................. 25使用上の注意 .......................................................................................................................... 25

線形連立方程式を解く方法 ................................................................................... 25行列分解 ................................................................................................................... 26逆行列 ....................................................................................................................... 26複数の右辺 ............................................................................................................... 26最小二乗解と QR 分解 ............................................................................................ 26特異値分解と一般化逆行列 ................................................................................... 27悪条件と特異性 ....................................................................................................... 27

lin_sol_gen ............................................................................................................................... 27lin_sol_gen ( 複素数 ).............................................................................................................. 33lin_sol_posdef .......................................................................................................................... 37lin_sol_posdef ( 複素数 )......................................................................................................... 41

lin_sol_gen_band ..................................................................................................................... 45lin_sol_gen_band ( 複素数 ).................................................................................................... 49lin_sol_posdef_band................................................................................................................. 52lin_sol_posdef_band ( 複素数 ) ............................................................................................... 56lin_sol_gen_coordinate ............................................................................................................ 59lin_sol_gen_coordinate ( 複素数 )........................................................................................... 68lin_sol_posdef_coordinate ....................................................................................................... 74lin_sol_posdef_coordinate ( 複素数 )...................................................................................... 78lin_sol_gen_min_residual ........................................................................................................ 83

Page 4: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

lin_sol_def_cg .......................................................................................................................... 87lin_least_squares_gen............................................................................................................... 92lin_lsq_lin_constraints.............................................................................................................. 98lin_svd_gen............................................................................................................................. 101lin_svd_gen ( 複素数 ) ........................................................................................................... 105lin_sol_nonnegdef .................................................................................................................. 110

第 2 章:固有方程式解析 115ルーチン ................................................................................................................................ 115使用上の注意 ........................................................................................................................ 115

エラー分析と精度.................................................................................................. 115一般化固有値問題の再定式化.............................................................................. 116

eig_gen ................................................................................................................................... 117eig_gen ( 複素数 ).................................................................................................................. 119eig_sym................................................................................................................................... 121eig_herm ( 複素数 ) ............................................................................................................... 123eig_symgen............................................................................................................................. 126geneig ..................................................................................................................................... 128geneig ( 複素数 ).................................................................................................................... 131

第 3章: 補間と近似 135ルーチン ................................................................................................................................ 135使用上の注意 ........................................................................................................................ 135

区分化多項式 ......................................................................................................... 136スプラインと B スプライン ................................................................................. 1363 次スプライン....................................................................................................... 136テンソル積スプライン.......................................................................................... 137離散データ補間...................................................................................................... 138最小二乗.................................................................................................................. 1383 次スプラインによる平滑化............................................................................... 138スプラインと区分化多項式の構造...................................................................... 138

cub_spline_interp_e_cnd........................................................................................................ 140cub_spline_interp_shape ........................................................................................................ 146cub_spline_value .................................................................................................................... 149cub_spline_integral................................................................................................................. 152spline_interp ........................................................................................................................... 153spline_knots............................................................................................................................ 158spline_2d_interp ..................................................................................................................... 161spline_value............................................................................................................................ 166spline_integral ........................................................................................................................ 168spline_2d_value...................................................................................................................... 170spline_2d_integral .................................................................................................................. 173user_fcn_least_squares ........................................................................................................... 175spline_least_squares ............................................................................................................... 179spline_2d_least_squares ......................................................................................................... 184cub_spline_smooth ................................................................................................................. 189spline_lsq_constrained ........................................................................................................... 192smooth_1d_data...................................................................................................................... 198scattered_2d_interp................................................................................................................. 202radial_scattered_fit ................................................................................................................. 205radial_evaluate........................................................................................................................ 211

第 4章:求積法 213ルーチン ................................................................................................................................ 213使用上の注意 ........................................................................................................................ 213

単変量求積法.......................................................................................................... 213多変量求積法.......................................................................................................... 214ガウス求積法.......................................................................................................... 214

Page 5: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int_fcn_sing............................................................................................................................ 215int_fcn..................................................................................................................................... 218int_fcn_sing_pts ..................................................................................................................... 221int_fcn_alg_log....................................................................................................................... 224int_fcn_inf .............................................................................................................................. 227int_fcn_trig ............................................................................................................................. 230int_fcn_fourier........................................................................................................................ 233int_fcn_cauchy ....................................................................................................................... 236int_fcn_smooth....................................................................................................................... 239int_fcn_2d............................................................................................................................... 242int_fcn_hyper_rect ................................................................................................................. 245int_fcn_qmc............................................................................................................................ 247gauss_quad_rule ..................................................................................................................... 249fcn_derivative ........................................................................................................................ 253

第 5章:微分方程式 257ルーチン ................................................................................................................................ 257使用上の注意 ........................................................................................................................ 257

常微分方程式 ......................................................................................................... 257偏微分方程式 ......................................................................................................... 258微分代数方程式 ..................................................................................................... 259

ode_runge_kutta ..................................................................................................................... 259ode_adams_gear ..................................................................................................................... 264bvp_finite_difference ............................................................................................................. 270dea_petzold_gear.................................................................................................................... 279pde_1d_mg のイントロダクション .................................................................................... 294

説明のサマリー ..................................................................................................... 295pde_1d_mg............................................................................................................................. 296

例題 ......................................................................................................................... 300例題 1- 8 と PV-WAVE プロッティングのサンプルコード............................. 304

pde_method_of_lines ............................................................................................................. 326fast_poisson_2d...................................................................................................................... 341

第 6章:変換 347ルーチン ................................................................................................................................ 347使用上の注意 ........................................................................................................................ 135

高速フーリエ変換 ................................................................................................. 347連続 対 離散 フーリエ変換 .................................................................................. 347

fft_real .................................................................................................................................... 348fft_real_init............................................................................................................................. 352fft_complex ............................................................................................................................ 353fft_complex_init ..................................................................................................................... 355fft_cosine................................................................................................................................ 357fft_cosine_init......................................................................................................................... 358fft_sine.................................................................................................................................... 360fft_sine_init ............................................................................................................................ 361fft_2d_complex ...................................................................................................................... 363convolution............................................................................................................................. 367convolution ( 複素数 ) ........................................................................................................... 372inverse_laplace ...................................................................................................................... 377

第 7章:非線形方程式 383ルーチン ................................................................................................................................ 383使用上の注意 ........................................................................................................................ 383

多項式のゼロ点 ..................................................................................................... 383関数のゼロ点 ......................................................................................................... 383連立方程式の根 ..................................................................................................... 383

zeros_poly .............................................................................................................................. 383

Page 6: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

zeros_poly ( 複素数 ) ............................................................................................................. 385zeros_fcn................................................................................................................................. 387zeros_sys_eqn......................................................................................................................... 391

第 8章:最適化 395ルーチン ................................................................................................................................ 395使用上の注意 ........................................................................................................................ 395

制約なし最小化...................................................................................................... 395線形制約付き最小化.............................................................................................. 396非線形制約付き最小化.......................................................................................... 396

min_uncon .............................................................................................................................. 396min_uncon_deriv.................................................................................................................... 399min_uncon_multivar............................................................................................................... 403nonlin_least_squares............................................................................................................... 408read_mps................................................................................................................................. 416

MPS ファイル形式................................................................................................. 419NAME セクション ................................................................................................. 419ROWS セクション ................................................................................................. 419COLUMNS セクション ......................................................................................... 420RHS セクション ..................................................................................................... 420RANGES セクション............................................................................................. 421BOUNDS セクション ............................................................................................ 421QUADRATIC セクション ..................................................................................... 422ENDATA セクション ............................................................................................ 422

linear_programming ............................................................................................................... 423lin_prog................................................................................................................................... 428quadratic_prog........................................................................................................................ 432min_con_gen_lin .................................................................................................................... 435bounded_least_squares ........................................................................................................... 440constrained_nlp....................................................................................................................... 446

第 9章:特殊関数 453ルーチン ................................................................................................................................ 453使用上の注意 ........................................................................................................................ 455erf............................................................................................................................................ 457erfc.......................................................................................................................................... 458erfce ........................................................................................................................................ 459erfe.......................................................................................................................................... 460erf_inverse .............................................................................................................................. 461erfc_inverse ............................................................................................................................ 462beta ......................................................................................................................................... 464log_beta .................................................................................................................................. 465beta_incomplete...................................................................................................................... 466gamma .................................................................................................................................... 466log_gamma ............................................................................................................................. 468gamma_incomplete................................................................................................................. 469bessel_J0................................................................................................................................. 470bessel_J1................................................................................................................................. 472bessel_Jx................................................................................................................................. 473bessel_Y0 ............................................................................................................................... 474bessel_Y1 ............................................................................................................................... 475bessel_Yx ............................................................................................................................... 476bessel_I0 ................................................................................................................................. 478bessel_exp_I0 ......................................................................................................................... 479bessel_I1 ................................................................................................................................. 480bessel_exp_I1 ......................................................................................................................... 481bessel_Ix ................................................................................................................................. 482bessel_K0 ............................................................................................................................... 483bessel_exp_K0........................................................................................................................ 484

Page 7: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

bessel_K1 ............................................................................................................................... 485bessel_exp_K1 ....................................................................................................................... 486bessel_Kx ............................................................................................................................... 487elliptic_integral_K.................................................................................................................. 488elliptic_integral_E .................................................................................................................. 489elliptic_integral_RF................................................................................................................ 490elliptic_integral_RD ............................................................................................................... 491elliptic_integral_RJ ................................................................................................................ 492elliptic_integral_RC ............................................................................................................... 493fresnel_integral_C .................................................................................................................. 494fresnel_integral_S................................................................................................................... 494airy_Ai.................................................................................................................................... 495airy_Bi.................................................................................................................................... 496airy_Ai_derivative.................................................................................................................. 497airy_Bi_derivative.................................................................................................................. 498kelvin_ber0............................................................................................................................. 498kelvin_bei0 ............................................................................................................................. 499kelvin_ker0............................................................................................................................. 500kelvin_kei0 ............................................................................................................................. 501kelvin_ber0_derivative........................................................................................................... 501kelvin_bei0_derivative ........................................................................................................... 502kelvin_ker0_derivative........................................................................................................... 503kelvin_kei0_derivative ........................................................................................................... 504normal_cdf ............................................................................................................................. 504normal_inverse_cdf................................................................................................................ 506chi_squared_cdf ..................................................................................................................... 507chi_squared_inverse_cdf........................................................................................................ 508F_cdf....................................................................................................................................... 509F_inverse_cdf ......................................................................................................................... 510t_cdf........................................................................................................................................ 511t_inverse_cdf .......................................................................................................................... 513gamma_cdf ............................................................................................................................. 514binomial_cdf........................................................................................................................... 515hypergeometric_cdf................................................................................................................ 516poisson_cdf............................................................................................................................. 517beta_cdf .................................................................................................................................. 518beta_inverse_cdf..................................................................................................................... 520bivariate_normal_cdf ............................................................................................................. 521cumulative_interest ................................................................................................................ 522cumulative_principal .............................................................................................................. 523depreciation_db ...................................................................................................................... 524depreciation_ddb .................................................................................................................... 526depreciation_sln ..................................................................................................................... 527depreciation_syd..................................................................................................................... 528depreciation_vdb .................................................................................................................... 529dollar_decimal........................................................................................................................ 530dollar_fraction ........................................................................................................................ 531effective_rate.......................................................................................................................... 532future_value............................................................................................................................ 533future_value_schedule............................................................................................................ 534interest_payment .................................................................................................................... 535interest_rate_annuity .............................................................................................................. 536internal_rate_of_return........................................................................................................... 538internal_rate_schedule............................................................................................................ 539modified_internal_rate ........................................................................................................... 540net_present_value................................................................................................................... 542nominal_rate........................................................................................................................... 543number_of_periods................................................................................................................. 543payment .................................................................................................................................. 545present_value.......................................................................................................................... 546present_value_schedule.......................................................................................................... 547principal_payment.................................................................................................................. 548accr_interest_maturity............................................................................................................ 549

Page 8: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

accr_interest_periodic............................................................................................................. 551bond_equivalent_yield ........................................................................................................... 552convexity ................................................................................................................................ 553coupon_days ........................................................................................................................... 555coupon_number ...................................................................................................................... 556days_before_settlement .......................................................................................................... 557days_to_next_coupon ............................................................................................................. 558depreciation_amordegrc ......................................................................................................... 560depreciation_amorlinc ............................................................................................................ 561discount_price......................................................................................................................... 562discount_rate........................................................................................................................... 564discount_yield......................................................................................................................... 565duration................................................................................................................................... 566interest_rate_security.............................................................................................................. 568modified_duration .................................................................................................................. 569next_coupon_date................................................................................................................... 571previous_coupon_date............................................................................................................ 572price ........................................................................................................................................ 573price_maturity......................................................................................................................... 574received_maturity ................................................................................................................... 576treasury_bill_price.................................................................................................................. 577treasury_bill_yield.................................................................................................................. 578year_fraction........................................................................................................................... 580yield_maturity......................................................................................................................... 581yield_periodic ......................................................................................................................... 582

第 10章:統計と乱数発生 585ルーチン ................................................................................................................................ 585使用上の注意 ........................................................................................................................ 585

統計.......................................................................................................................... 585乱数発生の概要...................................................................................................... 585基本一様乱数発生器.............................................................................................. 586シャッフル版発生器.............................................................................................. 586シードの設定.......................................................................................................... 586

simple_statistics......................................................................................................................586table_onewaytable_oneway....................................................................................................590chi_squared_test .....................................................................................................................593covariances .............................................................................................................................600regression................................................................................................................................604poly_regression.......................................................................................................................611ranks .......................................................................................................................................616random_seed_get....................................................................................................................622random_seed_set ....................................................................................................................623random_option........................................................................................................................623random_uniform.....................................................................................................................624random_normal.......................................................................................................................625random_poisson...................................................................................................................... 627random_gamma ......................................................................................................................628random_beta ........................................................................................................................... 629random_exponential ............................................................................................................... 631faure_next_point.....................................................................................................................632

第 11章:プリント関数 637ルーチン ................................................................................................................................ 637write_matrix ...........................................................................................................................637page......................................................................................................................................... 642write_options .......................................................................................................................... 643

第 12章:ユーティリティー 647

Page 9: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ルーチン ................................................................................................................................ 647output_file ..............................................................................................................................648version ....................................................................................................................................651ctime ....................................................................................................................................... 651date_to_days........................................................................................................................... 652days_to_date........................................................................................................................... 653error_options ..........................................................................................................................654error_code...............................................................................................................................659constant...................................................................................................................................660machine ( 整数 )..................................................................................................................... 663machine ( 浮動小数点 )......................................................................................................... 665sort ..........................................................................................................................................667sort ( 整数 ) ............................................................................................................................668vector_norm ........................................................................................................................... 670mat_mul_rect.......................................................................................................................... 672mat_mul_rect ( 複素数 ) ........................................................................................................ 675mat_mul_rect_band................................................................................................................ 678mat_mul_rect_band ( 複素数 ) .............................................................................................. 681mat_mul_rect_coordinate....................................................................................................... 685mat_mul_rect_coordinate ( 複素数 ) ..................................................................................... 688mat_add_band ........................................................................................................................692mat_add_band ( 複素数 )....................................................................................................... 695mat_add_coordinate ............................................................................................................... 698mat_add_coordinate ( 複素数 ).............................................................................................. 700matrix_norm ........................................................................................................................... 703matrix_norm_band ................................................................................................................. 705matrix_norm_coordinate ........................................................................................................ 707generate_test_band .................................................................................................................709generate_test_band ( 複素数 ) ...............................................................................................711generate_test_coordinate ........................................................................................................ 712generate_test_coordinate ( 複素数 ) ...................................................................................... 715

参照資料 719ユーザエラー ........................................................................................................................ 719

エラー重要度をどのように決定するか ............................................................. 719エラーの種類とデフォルト操作 ......................................................................... 719低レベル関数のエラー ......................................................................................... 720エラーハンドリングの関数 ................................................................................. 720スレッドとエラーハンドリング ......................................................................... 720情報エラーを使用してプログラム作業を決定 ................................................. 721追加の例題 ............................................................................................................. 721

複素データタイプと関数 .................................................................................................... 721

製品サポート 725Contacting Visual Numerics Support...........................................................................................

Appendix A: References A-

Appendix B: Alphabetical Summary of Routines B-ルーチン .................................................................................................................................. B-

Index

Page 10: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに
Page 11: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

イントロダクション

IMSL C Math ライブラリIMSL C Math ライブラリは科学技術プログラミングに役立つ C 関数のライブラ

リです。各関数は技術専門家により、研究活動に使用されるように、設計されて文書化されています。多くの例題プログラムは、出力結果のグラフを表示しています。

初めにIMSL C Math ライブラリの関数を使用するためには、まず C 言語でその関数を

呼び出すプログラムを書く必要があります。各関数は、プログラミングと文書の中で確立された規約に従います。弊社がライブラリを開発する上で、効率的なアルゴリズム、分かりやすいドキュメント、正確な結果を最優先にしています。関数は、統一的に設計されているので、ひとつのアプリケーションの中で複数の関数を使用することが容易です。また、IMSL C Math ライブラリの関数

は、他の IMSL ライブラリの関数と同じように設計されています。

ANSI C vs. 非 ANSI Cこのユーザマニュアルの全ての例題は、 ANSI C に準拠しています。 ANSI C を

用いる場合、関数が宣言される、或いは、配列が float 型として初期化される

例題を修正する必要があります。

以下の例は、関数が宣言される ANSI C プログラムです。このプログラムは、

次の値を推定します。

1 #include <math.h> 2 #include <imsl.h> 3 4 float fcn(float x); 5 6 main() 7 { 8 float q, exact; 9 /* 積分の計算 */ 10 q = imsl_f_int_fcn_sing (fcn, 0.0, 1.0, 0); 11 /* 結果と正確な答えをプリント */ 12 exact = -4.0;

13 printf("integral = %10.3f\nexact = %10.3f\n", q, exact); 14 } 15 16 float fcn(float x) 17 { 18 return log(x)/sqrt(x); 19 }

非 ANSI C を用いる場合、4 行目と 16 行目を次の様に修正します。

4 float fcn(); /* 関数はプロトタイプではない */ . . .

( )1 1/ 2

0ln 4x x dx− = −∫

Page 12: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

16 float fcn(x) /*ここで関数の変数をだけを宣言 */16a float x; /* ここで変数の型を宣言 */

非 ANSI C では自動的な集約の初期化ができないので、ANSI C の中の float型として初期化された全ての自動 配列は、非 ANSI C の中で static float型として初期化されなければなりません。次のプログラムは、float型とし

て初期化された配列を含みます。

1 #include <imsl.h> 2 3 main() 4 { 5 int n = 3; 6 float *x; 7 float a[] = {1.0, 3.0, 3.0, 8 1.0, 3.0, 4.0, 9 1.0, 4.0, 3.0}; 10 11 float b[] = {1.0, 4.0, -1.0}; 12 /* x に対して Ax = bを解く */ 13 x = imsl_f_lin_sol_gen (n, a, b, 0); 14 /* x をプリント */ 15 imsl_f_write_matrix ("Solution, x, of Ax = b", 1, 3, x, 0); 16 }

非 ANSI C を用いる場合、7 行目と 11 行目を次の様に修正する必要がありま

す。

7 static float a[] = {1.0, 3.0, 3.0, . . .11 static float b[] = {1.0, 4.0, -1.0};

imsl.h ファイル include ファイル <imsl.h> は本マニュアルの全ての例題で使用されています。

このファイルは、全ての IMSL 定義関数、スプライン構造体(Imsl_f_ppoly、 Imsl_d_ppoly、 Imsl_f_spline、 Imsl_d_spline)、列挙データ型(Imsl_quad、 Imsl_write_options、 Imsl_page_options、 Imsl_ode、 Imsl_error)、IMSL 定義データ

型(f_complex ( これは浮動小数点複素数型) d_complex ( 倍精度複素数型))の

ためのプロトタイプを含んでいます。

スレッドセーフの使用法POSIX スレッド、又は、WIN32 スレッドのいずれかをサポートするシステム上

では IMSL C Math ライブラリはマルチスレッド・アプリケーションから安全に

呼び出すことができます。IMSL C Math ライブラリがマルチスレッド・アプリ

ケーションで使用されているとき、呼び出しプログラムはいくつかの重要な指針を厳守しなければなりません。特に、IMSL C Math ライブラリの信号処理、

エラー操作、 I/O の 実装について理解されている必要があります。

信号操作

マルチスレッド・アプリケーションから IMSL C Math ライブラリを呼び出す

場合、 C Math ライブラリの信号操作を使用停止にする必要があります。これ

は C Math ライブラリのいずれかを呼び出す前に imsl_error_optionsを 1 度

呼び出すことによって行います。IMSL C Math ライブラリの内部的な信号操作

を停止させる例は、「ユーティリティ」 の章の例題 3 を参照してください。

マルチスレッド・アプリケーションの C Math ライブラリのエラー操作はシン

グルスレッド・アプリケーションの中で行われる方法と同様です。その主な差は、C Math ライブラリ関数を呼び出す各スレッドにエラースタックが存在す

ることです。各スレッドに別々のエラースタックが存在することは各スレッドのエラーハンドラーオプションのより高度な操作を必要とします。各スレッド

Page 13: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

は imsl_error_options を使用して C Math ライブラリのエラー操作機能を

それぞれ設定することができます。それぞれのスレッドのエラー操作機能オプションの設定の例題は、「ユーティリティ」の章、imsl_error_options の例

題 3 を参照してください。

出力ルーチン

C/Math ライブラリの多くのルーチンは出力に使用することができます。 関数

imsl_output_file は出力するファイルを制御するために使用されます。 シ

ングルスレッドが実行されるアプリケーションでは、imsl_output_fileを

1 回呼び出して、出力するファイルをセットするために使用されます。マルチ

スレッドのアプリケーションでは、各スレッドは出力されるファイルのデフォルト設定を変更するために imsl_output_fileを、それぞれ呼ぶ必要があ

ります。詳細は 「ユーティリティ」の章、imsl_output_file の例題 2 を

参照してください。

入力引数

マルチスレッドのアプリケーションでは C Math ライブラリに送るデータに注

意する必要があります。入力専用に見える幾つかの引数は、呼び出しの間に一時的に修正されて、呼び出し側に元に戻されます。C Math ライブラリの関数

を呼び出す別のスレッドで、同じデータ空間の使用を回避するように注意をしなければなりません。

行列格納モード本節で、行列(matrix) という単語は数学的オブジェクトを参照するために使用され、配列 (array) という単語は C のデータ構造としての表現のために使

用されます。次の配列タイプのリストの中で、IMSL C Math ライブラリの関数

は、行列の次元数と行列入力値のための全ての値から成る入力を必要します。これらの値はその配列の中で、行並び順序で格納されます。

各関数は入力配列を処理し、通常、「結果」へのポインターを返します。例えば、線形代数連立方程式を解く際に、そのポインターはその解に対するものです。一般的に、実数固有値問題では、そのポインターはその固有値に対するものです。 通常、入力配列値はその関数によって変更されません。

IMSL C Math ライブラリの中で、配列はデータの連続するブロックへのポイン

ターです。 それらは、その行列の行へのポインターのポインターではありません。

float *a = {1, 2, 3, 4}; float b[2][2] = {1, 2, 3, 4}; float c[] = {1, 2, 3, 4};

注意:非 ANSI C を使用していて、その変数が auto 型の場合、上図の宣言は , static float 型で宣言する必要がある場合があります。

一般モード

一般的な行列は、n × n の正方行列です。一般的な配列のデータ型は、float、double、f_complex 又は d_complex にすることができます。

矩形モード

矩形行列は m × n の行列です。長方形配列のデータ型は、float、double、f_complex又は d_complexにすることができます。

Page 14: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

対称モード

対称行列は、 AT = A ( A

T は A の転置行列)のような n × n の正方行列です。 対

象行列のデータ型は、 float double にすることができます。

エルミートモード

エルミート行列は、次のような n × n の正方行列 A です。

行列 は、 A の共役複素数で、

は、A の共役転置行列です。エルミート行列のためには、 AH

= A です。エル

ミート行列のデータ型は、 f_complex または d_complex にすることができます。

疎行列対応座標格納フォーマット

疎行列の非ゼロ要素だけを関数に知らせる必要があります。疎行列対応座標格納フォーマットは、入力の行と列の指標と共に各行列入力値を格納します。 次の 4 つの非同質データ構造体が、この概念を支持するために定義されていま

す。

typedef struct {int row;int col;float val;

} Imsl_f_sparse_elem;

typedef struct {int row;int col;double val;

} Imsl_d_sparse_elem;

typedef struct {int row;int col;f_complex val;

} Imsl_c_sparse_elem;

typedef struct { int row; int col; d_complex val; } Imsl_z_sparse_elem;

詳細は、本マニュアルの最後にある複素数データ型 f_complex と d_complex の説明をご参照ください。これらの構造体の唯一の違いは内部に含まれるデータ型に違いが含まれる点を注意して下さい。疎行列は、これらのデータ型の 1つの配列を形成する事によって、疎行列対応座標フォーマットを受け取る関数に渡されます。この配列の要素の数は疎行列中の非ゼロの数に等しくなります。

一例として、 6 × 6 の行列を考えます。

H TA A A= =

A

H TA A≡

Page 15: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

この行列 A は 15 の非ゼロ要素を持ち、その疎行列対応座標表現は次の様にな

ります。

この表現は順序に依存しないので、以下の形式で表現できます。

例えば、Imsl_f_sparse_elem の配列を初期化するための方法がいくつか存在し

ます。 以下のプログラム部分を考えてみます。

#include <imsl.h>main(){Imsl_f_sparse_elem a[] = { {0, 0, 2.0}, {1, 1, 9.0}, {1, 2, -3.0}, {1, 3, -1.0}, {2, 2, 5.0}, {3, 0, -2.0}, {3, 3, -7.0}, {3, 4, -1.0}, {4, 0, -1.0}, {4, 3, -5.0}, {4, 4, 1.0}, {4, 5, -3.0}, {5, 0, -1.0}, {5, 1, -2.0}, {5, 5, 6.0} };Imsl_f_sparse_elem b[15];

b[0].row = b[0].col = 0; b[0].val = 2.0; b[1].row = b[1].col = 1; b[1].val = 9.0; b[2].row = 1; b[2].col = 2; b[2].val = -3.0; b[3].row = 1; b[3].col = 3; b[3].val = -1.0; b[4].row = b[4].col = 2; b[4].val = 5.0; b[5].row = 3; b[5].col = 0; b[5].val = -2.0; b[6].row = b[6].col = 3; b[6].val = -7.0; b[7].row = 3; b[7].col = 4; b[7].val = -1; b[8].row = 4; b[8].col = 0; b[8].val = -1.0; b[9].row = 4; b[9].col = 3; b[9].val = -5.0; b[10].row = b[10].col = 4; b[10].val = 1.0; b[11].row = 4; b[11].col = 5; b[11].val = -3.0; b[12].row = 5; b[12].col = 0; b[12].val = -1.0; b[13].row = 5; b[13] = 1; b[13].val = -2.0; b[14].row = b[14].col = 5; b[14].val = 6.0;}

行 0 1 1 1 2 3 3 3 4 4 4 4 5 5 5列 0 1 2 3 2 0 3 4 0 3 4 5 0 1 5値 2 9 −3 −1 5 −2 −7 −1 −1 −5 1 −3 −1 −2 6

row 5 4 3 0 5 1 2 1 4 3 1 4 3 5 4col 0 0 0 0 1 1 2 2 3 3 3 4 4 5 5val −1 −1 −2 2 −2 9 5 −3 −5 −7 −1 1 −1 6 −3

2 0 0 0 0 00 9 3 1 0 00 0 5 0 0 02 0 0 7 1 01 0 0 5 1 31 2 0 0 0 6

A

− −

= − − −

− − − − −

Page 16: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

a と b の両方は、疎行列 A を表しており、このモジュールの中の関数は、識別子

が引数リストを通して送られたかには関係なく全く同じ結果を生成します。

疎の対称、或いは、エルミート行列は、特別なケースで、これは対角項と、上、又は、下三角行列を格納するためだけに必要です。 一例として、5 × 5の線形連立方程式を考えてみます。

このライブラリの中のエルミートと対称正定値連立方程式解法ルーチンは、その対角項と下 3 角行列を指定されることを期待しています。この下 3 角行列の

ための疎の対応座標形式は以下の様に与えられます。

先ほどのように、以下の形式で表せます。

以下のプログラムは、a と b の両方を H に初期化します。

#include <imsl.h>main(){ Imsl_c_sparse_elem a[] = { {0, 0, {4.0, 0.0}}, {1, 1, {4.0, 0.0}}, {2, 2, {4.0, 0.0}}, {3, 3, {4.0, 0.0}}, {1, 0, {1.0, 1.0}}, {2, 1, {1.0, 1.0}}, {3, 2, {1.0, 1.0}} } Imsl_c_sparse_elem b[7];

b[0].row = b[0].col = 0; b[0].val = imsl_cf_convert (4.0, 0.0); b[1].row = 1; b[1].col = 0; b[1].val = imsl_cf_convert (1.0, 1.0); b[2].row = b[2].col = 1; b[2].val = imsl_cf_convert (4.0, 0.0); b[3].row = 2; b[3].col = 1; b[3].val = imsl_cf_convert (1.0, 1.0); b[4].row = b[4].col = 2; b[4].val = imsl_cf_convert (4.0, 0.0); b[5].row = 3; b[5].col = 2; b[5].val = imsl_cf_convert (1.0, 1.0); b[6].row = b[6].col = 3; b[6].val = imsl_cf_convert (4.0, 0.0);}

ここで注意すべき幾つかの重要な点があります。H は対称ではなく、むしろエ

ルミート形式です。エルミートデータを受け取るこの関数はこれを理解して、次を仮定することで操作します。

行 0 1 2 3 1 2 3列 0 1 2 3 0 1 2値 (4,0) (4,0) (4,0) (4,0) (1,1) (1,1) (1,1)

行 0 1 1 2 2 3 3列 0 0 1 1 2 2 3値 (4,0) (1,1) (4,0) (1,1) (4,0) (1,1) (4,0)

( ) ( )( ) ( ) ( )

( ) ( ) ( )( ) ( )

4,0 1, 1 0 01,1 4,0 1, 1 00 1,1 4,0 1, 10 0 1,1 4,0

H

− − = −

Page 17: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL C Math ライブラリは、正定値ではない行列の中に対称を有効利用するこ

とはできません。ここに意味することは、たまたま不定である対称行列はこの簡潔な対称形式に格納することができないということです。上と下の、両方の3 角行列が指定されなければならなくて、そして、疎の一般の解法ルーチンが

呼ばれなければなりません。

帯格納フォーマット

帯行列は、その非ゼロ要素の全てが主対角項に「近い」M × N 行列です。 特

に、i − j > nlca 又は j − i > nucaであれば値は Aij = 0 です。整数 m = nlca + nuca + 1は、全体のバンド幅です。 主対角項以外の対角項は共対角項と名づけらます。

M × N 行列は帯行列ですが、帯格納フォーマットは、非ゼロ共対角項の数が N よ

りそれほど多くないときだけに役立ちます。

帯格納フォーマットでは、nlca下共対角項と、nuca上共対角項はサイズ m × N の配列の行に格納されます。その要素は、行列の中にあるように、その配列

の同じ列に格納されます。バンド幅の内側の値 Aij は、線形配列内の位置 [(i - j + nuca + 1) * n + j]に格納されます。 これは、行列の 2 次元的な概念から、行

並びの、一次元マッピングになります。

例えば、1 つの下と 2 つの上共対角項を持つ 5 × 5 の行列 A を考えます。

帯格納フォーマットの中では、このデータが次のように並んでいます。

このデータは、長さ 20 の配列の中に、隣接して行優先で保存されます。

一例として、次の三重対角行列を考えます。

以下の宜言は、この行列を帯格納フォーマットで保存します。

float a[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 10.0, 20.0, 30.0, 40.0, 50.0, 5.0, 6.0, 7.0, 8.0, 0.0};

疎行列対応座標表現の中のように、帯格納のスペース節約対称バージョンがあります。一例として以下の 5x5 の対称の問題を考えます。

ij ijh h=

0,0 0,1 0,2

1,0 1,1 1,2 1,3

2,1 2,2 2,3 2,4

3,2 3,3 3,4

4,3 4,4

0 00

00 00 0 0

A A AA A A A

A A A AAA A A

A A

=

0,2 1,3 2,4

0,1 1,2 2,3 3,4

0,0 1,1 2,2 3,3 4,4

1,0 2,1 3,2 4,3

0 00

0

A A AA A A A

A A A A AA A A A

10 1 0 0 05 20 2 0 00 6 30 3 00 0 7 40 40 0 0 8 50

A

=

Page 18: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

帯対称格納フォーマットでは、そのデータは次のように並びます。

次のエルミート形式の例は、この手順を示します。

以下のプログラムの一部分では、バンド対称の記憶フォーマットを使用して hに H を格納します。

f_complex h[] = { {0.0, 0.0}, {0.0, 0.0}, {1.0, 1.0}, {1.0, 1.0}, {1.0, 1.0}, {0.0, 0.0}, {1.0, 1.0}, {1.0, 1.0}, {1.0, 1.0}, {1.0, 1.0}, {8.0, 0.0}, {8.0, 0.0}, {8.0, 0.0}, {8.0, 0.0}, {8.0, 0.0}};

あるいは、同等の

f_complex h[15]; h[0] = h[1] = h[5] = imsl_cf_convert (0.0, 0.0); h[2] = h[3] = h[4] = h[6] = h[7] = h[8] = h[9] = imsl_cf_convert (1.0, 1.0); h[10] = h[11] = h[12] = h[13] = h[14] = imsl_cf_convert (8.0, 0.0);

帯形式と対応座標形式の選択方法

どのような行列も疎対応座標形式か帯形式で格納することができます。どちらかの形式を使うかの選択は行列の疎の分布様式に依存します。主対角近くの帯の中に全ての非ゼロのデータと持つ行列は、恐らく帯形式の方が良いでしょう。非ゼロ情報が多かれ少なかれ一様に行列を通して散在するならば、疎の対応座標形式が最良の選択です。極端な例として、次の 2 つのケースが考えられ

ます。1 つ目は、主対角に全ての要素を持ち、そして、(0, n − 1) と (n − 1, 0) 入力が非ゼロの n × n 行列の場合です。疎の対応座標ベクトルは、n + 2 ユニット

の長さです。長さ n(2n − 1) の配列が帯表現を格納するために必要とされ、密

な解法ルーチンに比べ約 2 倍の記憶域が必要になる場合もあります。2 つ目

に、全ての対角項と上対角項と下対角項の入力が非ゼロである三重対角行列の場合です。帯形式で長さ 3nの配列が必要です。疎の対応座標形式の中で長さ

3n − 2 のベクトルが必要になります。しかし問題は、例えば、32 ビットマシン

上の浮動小数点精度で、対応座標形式におけるそれらの 3n − 2 ユニットのそれ

ぞれに、帯表現に必要な 3n単位と同様な 3 倍もの多くの記憶域が必要とされ

ることです。これは対応座標形式の中に、その行と列指標を伴うことによります。帯記憶は、本質的に順序付けられたリストやリストの中の位置によって元の行列の中の場所を定義することによってこの要求を避けます。

0,0 0,1 0,2

0,1 1,1 1,2 1,3

0,2 1,2 2,2 2,3 2,4

1,3 2,3 3,3 3,4

2,4 3,4 4,4

0 00

00 0

A A AA A A AA A A A AA

A A A AA A A

=

0,2 1,3 2,4

0,1 1,2 2,3 3,4

0,0 1,1 2,2 3,3 4,4

0 00

A A AA A A A

A A A A A

( ) ( ) ( )( ) ( ) ( ) ( )( ) ( ) ( ) ( ) ( )

( ) ( ) ( ) ( )( ) ( ) ( )

8,0 1,1 1,1 0 01, 1 8,0 1,1 1,1 01, 1 1, 1 8,0 1,1 1,1

0 1, 1 1, 1 8,0 1,10 0 1, 1 1, 1 8,0

H

− = − −

− − − −

Page 19: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

圧縮された疎の列 (CSC) フォーマット対応座標形式の中のデータを受け取る関数も、Harwell-Boeing Sparse Matrix Collection の Users’ Guide に記述されたフォーマットに格納されたデータを受

けることができます。その枠組は列指向で、各列は疎ベクトルとして保持され、整数配列の入力値の行指標のリストと別個になった float (double、 f_complex、 d_complex) 配列の対応する値のリストによって表現されます。各

列のデータは、連続的に格納されます。別々の整数配列は、各列の最初の入力位置と最初の自由位置を保持します。下三角形と対角項の中の入力値だけは、対称とエルミート行列のために格納されます。全ての配列は、Harwell-Boeingテストセットの、1基準配列に対比して、ゼロを基準にします。

Harwell-Boeing Users’ Guide で示されているように、記憶域枠組は、以下の 5 × 5 の行列の例によって説明されます。

上の行列は、以下の表のように、配列 colptr(最初の入力値の位置)、

rowind(行指標)と values(非ゼロ入力値)の中に格納されます。

以下のプログラムの一部分は、CSC 記憶域フォーマットと対応座標表現の関

係を示します。

k = 0; for (i=0; i<n; i++) { start = colptr[i]; stop = colptr[i+1]; for (j=start; j<stop; j++) { a[k].row = rowind[j]; a[k].col = i; a[k++].val = values[j]; } } nz =k;

出力配列のためのメモリ割り当て多くの関数は、計算結果を含んだ配列のポインターを返します。

IMSL_RETURN_USER, float a[]ただし関数呼び出しで、上のオプション引数を使用していると、計算された答えはユーザ供給の配列 a に保存され、その関数から返されるポインターは、

ユーザ供給の配列 a にセットされます。呼び出しで IMSL_RETURN_USERを使

用しない場合は、関数のポインターは内部的に初期化され(mallocのメモ

リー割当て要求によって)、そこに答えを保存します(この空間を解放するために freeを使用します。 mallocと freeの両方は、ヘッダ <stdlib.h> の

中で宣言される標準の Cライブラリ関数です)。このようにして、計算結果の

空間の割当ては、ユーザによって、もしくはその関数によって、内部的に作成することが可能です。

Subscripts 0 1 2 3 4 5 6 7 8 9 10Colptr 0 3 5 7 9 11Rowind 0 4 2 3 0 1 4 0 3 4 1Values 1 5 2 4 −3 −2 −5 −1 −4 6 3

1 3 0 1 00 0 2 0 32 0 0 0 00 4 0 4 05 0 5 0 6

− − −

− −

Page 20: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

同様に、他のオプションの引数は、追加の計算結果の配列がユーザによって割り当てられるか、又は内部的にその関数によって割り当てられるかを指定します。例えば多くの関数の中で、オプションの引数は 2 つの相互に排他的なオプ

ションの引数を指定します。 詳細は、「線形方程式」セクション内の関数のオ

プション引数を参照してください。

IMSL_INVERSE_USER, float inva[] (Output)IMSL_INVERSE, float **p_inva (Output)最初のオプションが選ばれた場合、その行列の逆行列は、ユーザ供給の配列invaに保存されます。2 番目のオプションの中で、float **p_invaは、その逆行

列のポインターのアドレスを参照します。2 番目のオプションが選ばれた場

合、返された時、そのポインターは(mallocへのメモリ割当て要求を通し

て)初期化され、その行列の逆行列はそこに保存されます。一般的に float *p_invaが宣言され、&p_invaがこの関数の引数として使用され、そして

free(p_inva) を使用してその空間を解放します

正しいルーチンを見つける方法IMSL C Math ライブラリは章ごとに分類され、各章は、同系統の計算、または

分析的な機能の関数が含まれています。必要な関数を見つけるためには、各章の紹介にある目次か、本マニュアルの最後にあるアルファベット順の「関数の要約」のいずれかを使用することができます。

ユーザが解きたい問題に似た例題を本マニュアルから見つけ、その例題を真似ることが、IMSL C Math ライブラリを素早く使えるようになる最も良い方法で

す。本マニュアルには、各関数の例題が少なくとも 1 つ以上掲載されています。

本マニュアルの構成本マニュアルには、各関数の説明に加え、それぞれの関数の対して 1 つ以上のサンプルコードが含まれています。IMSL C Math ライブラリに関連する全ての

情報は、本マニュアルで見つけることができます。更に、特別な関数に関連する全ての情報は、章の中の 1 ケ所に集められています。

各章は、イントロダクションから始まり、その章で紹介されている関数をリストしている目次と続きます。関数のドキュメンテーションは、以下の情報から構成されています。

• Section Name(文節名): 通常、 float 型と double 型で共通の文節名。

• Purpose(目的): 関数の目的。

• Synopsis(概要): リストされた必要な引数で、サブプログラムを参照す

るための形式。

• Required Arguments(必要な引数): 必要な引数の記述。以下のような

順番で表記されます。

Input(入力): 引数は初期化される必要があります。この関数によって変更さ

れません。

Input/Output(入力 / 出力): 引数は初期化される必要があります。関数は、こ

の引数を通して出力を返します。この引数は、定数あるいは数式であってはいけません。

Output(出力): 初期化は、不要です。この引数は、定数あるいは数式であっ

てはいけません。関数は、この引数を通して出力を返します。

• Return Value(戻り値): 関数から返ってくる値。

• Synopsis with Optional Arguments(オプション引数の概要): リストされ

た必要な引数とオプションの引数の両方のリストで関数を参照する形式。

• Optional Arguments(オプション引数): オプション引数の説明

Page 21: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

• Description(説明): アルゴリズムの説明と詳細な情報のリファレンス。

多くの場合、同様な機能もしくは、補足的な機能をもつほかの IMSL 関

数が示されます。

• Examples(例題): 入力とオプション引数の使い方を示す例題。

• Errors(エラー): それぞれの関数ごとに起こり得るエラーのリスト。エ

ラータイプの説明は、リファレンスマニュアルの 「User Errors」” セク

ションに載っています。エラーは、以下のようなタイプ分類されます。

Informational Errors: 関数で発生する情報を与えるエラーのリスト。

Alert Errors: 関数で発生する警報エラーのリスト。

Warning Errors: 関数で発生する警告エラーのリスト。

Fatal Errors: 関数で発生する致命的なエラーのリスト。

命名規則ほとんどの関数は、float 型と double 型の 2 バージョンで利用できます。また

いくつかの関数は int 型、あるいは IMSL が定義する f_complex 型と d_complex型で利用できます。複数の型のバージョンが存在する場合の、それぞれの型に対応する関数名の接頭辞のリストは次の通りです。

関数の文節名は、その関数をより簡単に見つけるために共通な部分だけを含みます。例えば、関数 imsl_f_lin_sol_gen と imsl_d_lin_sol_gen は、第

1章「線形方程式」の lin_sol_gen セクションにあります。

適切であれば、1 つの章を通して同じ変数名が使用されます。例えば、固有値解析のための関数の中で、evalは固有値のベクトルを示して、n_evalは計

算された、或いは、計算される固有値の数を示します。

IMSL C Math ライブラリを呼び出すプログラムを書く場合、ユーザは、IMSL 外

部関数名と矛盾しない C の名前を選ばなければなりません。名前を選ぶ際に、

次の規則に従う事で、IMSL 名と対立を避けることができます。

• 大文字と小文字のどのような組み合わせにおいても「imsl_」で始まる

名前をつけない。

エラー処理、アンダーフロー、オーバーフロー、ドキュメント例IMSL C Math ライブラリの中の関数は、エラーと不当な入力を発見し、報告し

ます。このエラー処理機能は、エラー条件の処理のための特定の準備を必要とせず、ユーザは自動的に保護されます。エラーは、重要度によって分類されて、コード番号が割り当てられます。デフォルトで、重要度が中くらい高いエラーは、その関数によって自動的にメッセージが表示されます。 更に、もっとも重要度の高いエラーは、プログラムの実行が停止します。そのエラーの一般的な性質と同様に、重要性のレベルは、記号的な名称 IMSL_FATAL、IMSL_WARNING、などを持つ「エラータイプ」によって指定されます。詳細

は参照資料の中の「ユーザ・エラー」節をご覧下さい。

一般的に、IMSL C Math ライブラリのコードは、計算がアンダーフローに影響

されず、システム(ハードウェア、又は、ソフトウェア)がアンダーフローをゼロに置き換えるように、作られています。通常、アンダーフローを示すシステム・エラー・メッセージは無視しても構いません。

型 接頭辞Float imsl_f_double imsl_d_Int imsl_i_F_complex imsl_c_D_complex imsl_z_

Page 22: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

また、IMSL コードは、オーバーフローを回避するように書かれています。 

オーバーフローを示すシステム・エラー・メッセージを生成するプログラムがある場合、不正確な入力データ、引数タイプの間違い、又は不適当なディメンジョンなどのプログラミング・エラーを調査すべきです。

多くの場合に、関数のドキュメンテーションは、そのアルゴリズムを失敗に導やすい落し穴を指摘します。

このマニュアルに記載されている例題の出力結果は、システムに依存する場合があり、ご利用のシステムにより結果が、多少異なることがあります。

計算結果の表示IMSL C Math ライブラリの多くの関数は、計算結果を表示しません。その出力

は、C 変数の中に返されます。計算結果を表示させる事は可能です。

IMSL C Math ライブラリには、配列を表示するだけのための特別な関数がいく

つか含まれています。例えば、imsl_f_write_matrixは float 型の行列を表

示するために便利な関数です。これらの関数の詳細な説明は、第 11 章「表示関数」を参照してください。

複素数演算ユーザは、IMSL の定義済みデータ型を使用することによって複素数演算が可

能です。2 つの浮動小数点精度の中でこれらのタイプが使用できます。

• 単精度複素数値のための f_complex

• 倍精度複素数値のための d_complex

複素数データタイプと関数の説明は、参照資料の中にあります。

欠損値いくつかの IMSL C Math ライブラリの関数は、データに欠損値が含まれていて

も構いません。これらの関数は欠損値を、「not a number」又は NaNとして参

照される特殊な値として認識します。実際の値はコンピュータ毎に異なりますので、詳細は第 12 章「ユーティリティ」で説明されている IMSL 関数

imsl_f_machineを参照してください。

欠落値が取り扱つかわれる方法は個別の関数に依存して、関数のドキュメンテーションで説明されています。

ユーザ関数へのデータの受け渡し ある問題特有のデータを IMSL C Math ライブラリのインターフェースを通じて、

ユーザ関数に受け渡すことが利点になる場合があります。ユーザ関数が、呼び出し関数のローカルにあるデータを必要とし、ユーザ関数がアクセス可能なグローバルデータを利用したくない場合など、この機能は有効です。ユーザ関数を受け入れる IMSL C ライブラリの関数は、データへのポインターと共にユーザ特定の

データを関数に受け渡す代わりのユーザ関数を受け入れるオプション引数があります。以下の例題は、IMSL C Math ライブラリの関数 imsl_f_min_uncon とオプ

ション引数 IMSL_FCN_W_DATAを使ってこの機能を説明します。

#include "imsl.h"#include <math.h>

static float fcn_w_data(float x, void *data_ptr);static float fcn(float);

void main()

Page 23: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{ float a = -100.0; float b = 100.0; float fx, x; float usr_data[] = {5.0, 10.0}; x = imsl_f_min_uncon (fcn, a, b,

IMSL_FCN_W_DATA, fcn_w_data, usr_data, 0);

fx = fcn_w_data(x, (void*)usr_data);

printf ("The solution is: %8.4f\n", x); printf ("The function evaluated at the solution is: %8.4f\n", fx);}

/* * (void*) ポインターの追加データを受け取るユーザ関数

* (void*) ポインターは、どの型へのキャストや修飾参照が可能 * どのような種類のデータ型や構造体も取得可能

* 例えば、この例題のデータを取得する。

* *((float*)data_ptr) には、値 5.0が含まれている。

* *((float*)data_ptr+1) には、 値 10.0が含まれている。 */static float fcn_w_data(float x, void *data_ptr){ return exp(x) - (*((float*)data_ptr))*x + *((float*)data_ptr+1);}

/* C プロトタイプを満足させるダミー関数 */static float fcn(float x){ return;}

Page 24: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに
Page 25: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

第 1章:線形連立方程式

ルーチン

密行列の線形連立方程式

一般行列の分解、解法、逆行列実行列 . . . . . . . . . . . . . . . . . . . . . . . lin_sol_gen 27複素行列 . . . . . . . . . . . . . . . . . lin_sol_gen (複素数 ) 33正定値行列の分解、解法、逆行列実行列 . . . . . . . . . . . . . . . . . . . . . lin_sol_posdef 37複素行列 . . . . . . . . . . . . . . . . lin_sol_posdef (複素数 ) 41

帯行列の線形連立方程式

帯行列の分解と解法実行列 . . . . . . . . . . . . . . . . . . . . lin_sol_gen_band 45 複素行列 . . . . . . . . . . . . . . lin_sol_gen_band (複素数 ) 49

正定値対称行列の分解と解法 実行列 . . . . . . . . . . . . . . . . . . . lin_sol_posdef_band 52 複素行列 . . . . . . . . . . . . . lin_sol_posdef_band (複素数 ) 56

一般疎行列の線形連立方程式

疎行列の分解と解法実行列 . . . . . . . . . . . . . . . . . lin_sol_gen_coordinate 59複素行列 . . . . . . . . . . . . . . . . .オプション引数の概要 389正定値行列の分解と解法実行列 . . . . . . . . . . . . . . . . . . . . . . . . . .概要 393複素行列 . . . . . . . . . . . lin_sol_posdef_coordinate (複素数 ) 78

反復改良法GMRES( 一般最小残差 ) 法. . . . . Linearly Constrained Minimization 398共役勾配法 . . . . . . . . . . . . . . . . . . . . . . . .例題 400

密行列の線形最小二乗連立方程式

最小二乗と QR 分解最小二乗解法、 QR 分解 . . . . . . . . . . . . . . . . .出力結果 404線形制約付き . . . . . . . . . . . . . . . lin_lsq_lin_constraints 98

特異値分解 (SVD) と一般化逆行列実行列 . . . . . . . . . . . . . . . . . . . . . . . . . .説明 414複素行列 . . . . . . . . . . . . . . . . . lin_svd_gen (複素数 ) 105

準正定値行列の分解、開放、一般化逆行列実行列 . . . . . . . . . . . . . . . . . . . linear_programming 425

使用上の注意

線形連立方程式を解く方法

正方線形連立方程式は、Ax = b の形式です。A はユーザ指定の n × n の行列、b は与えられた右辺の n ベクトル、x は解の n ベクトルです。A と b の各入力は、

ユーザが指定しなければなりません。全ベクトル x が出力として返されます。

Page 26: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

A が逆行列可能なとき、Ax = b の唯一の解が存在します。Ax = b を解くために最

も一般的に使用される直接法は、三角行列の積に行列 A を分解して線形方程

式の結果として生じる三角連立方程式を解く方法です。線形連立方程式を解くために直接法を使用する関数は、Ax = b の解を全て計算します。接頭辞

「imsl_f_lin_sol」をもつ関数が必要な引数と共に呼ばれる場合、x のポイン

ターがデフォルトで返されます。行列 A を三角行列の積に分解するだけであ

るような追加作業は、キーワードを使用して行うことが可能です。

行列分解

あるアプリケーションの中で、2 つの三角行列の積だけに n × n 行列 A を分解

したい場合があります。これは、線形連立方程式 Ax = b を解くための適切な

関数を呼ぶことによって行うことができます。線形連立方程式 Ax = b の解 x に

加えて、A の LU 分解が必要であると仮定します。 関数 imsl_f_lin_sol_gen の中でキーワード IMSL_FACTORを使う事でその分解の呼び出しを得ることが

できます。その分解だけが必要であれば、キーワード IMSL_FACTOR_ONLY と IMSL_FACTORを使用します。

LU と LLTなどの基本的な行列分解の他に、いくつかの行列分解を提供してい

ます。実数の行列 A のための QR 分解は、関数

imsl_f_lin_least_squares_genによって計算することができます。行列の特

異値分解((SVD)を計算するための関数は後の節の中で説明されています。

逆行列

線形連立方程式を解く関数の中の IMSL_INVERSE キーワードを使用することに

より、n × n 非特異行列の逆行列を得ることができます。その目的が複数の線

形連立方程式を解くためであれば、逆行列を計算していけません。複数の右辺であっても、逆行列を計算して、行列乗算を実行して線形連立方程式を解くことは、通常、次節で述べられる方法より更に時間がかかります。

複数の右辺

線形連立方程式が複数の右辺ベクトルを持つ場合を考えます。最初に係数行列Aを三角行列の積に分解して解ベクトルを見つけることが、最も実利的です。

その後線形方程式の結果として生じる三角連立方程式を、各右辺のために解きます。Aが実数の一般行列であるとき、Aの LU 分解の呼び出しは関数 imsl_f_lin_sol_genのキーワード IMSL_FACTOR と IMSL_FACTOR_ONLYを使

用することによって計算されます。k番目の右辺ベクトル bk の解 xk は、2 つ

の三角行列 Lyk = bk と Uxk = yk.Lyk = bk を解くことによって見つけられます。

関数 imsl_f_lin_sol_genのキーワード IMSL_SOLVE_ONLYは、各右辺を解く

ために使用されます。これらの引数は、線形連立方程式を解くための他の関数にも用意されています。

最小二乗解と QR 分解最小二乗解は通常、m > n である線形連立方程式 Am×n x = b の過剰定義システ

ムの計算を実行します。最小二乗の解 x は、残差ベクトル r = Ax − b のユーク

リッド長さを最小にします。Aが完全列階数を持つとき、関数

imsl_f_lin_least_squares_genは、x のために最小二乗法の唯一の解を計算

します。Aが階数不足の場合は,幾つかの変数のための基本解が計算されま

す。これらの変数は、その交換の後で結果として生じる列から構成されます。列交換、或いは、枢軸交換での QR 分解は、AP = QR として計算されます。

ここで、Qは直交行列、Rはその対角要素が大きさで非減少の上台形行列、

そして P は枢軸交換によって決定された置換行列です。基本解 xB はその基

本変数に対して、R(PT)x = QTb を解くことによって得られます。詳細は

imsl_f_lin_least_squares_genの「説明」を参照してください。ユーザ指

定の P を持つ AP = QR のような行列 Aの QR分解は、キーワードを使用して

計算することができます。

Page 27: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

特異値分解と一般化逆行列

ある m × n 行列 Aの SVD(特異値分解)は、行列分解 A = USVTです。

q = min(m, n) において、因子 Um×q と Vn×q は直交行列で、Sq×q は非増加の対

角項を持つ非負対角行列です。関数 imsl_f_lin_svd_genは、デフォルトで Aの特異値を計算します。キーワードを使用することで、一部、又は、全ての Uと V 行列、Aの階数の推定、Aの一般化された逆行列を得ることが可能です。

悪条件と特異性

Ax = 0 であって x ≠ 0 である場合、m × n の行列 Aは、数学的に特異とみなさ

れます。この場合、線形連立方程式 Ax = b は、解は一つではありません。一

方、行列 Aが数学的に特異行列に「近い」場合、行列 Aは数値的に特異にな

ります。そのような問題は、ill-conditioned(悪い条件 )と呼ばれます。

悪条件問題の持つ数値結果が受け入れられない場合、可能であれば(float 型を double 型に切り替えて)良い精度を使用する、もしくはその連立方程式の近似

解を得ることができます。近似の一つの形式は、Aの SVDを使用して得るこ

とが可能です。 q = min(m, n) と

それから近似解が以下によって与えられる場合、

スカラー ti,i は以下の式で定義されます。

ユーザは、tol の値を指定します。この値は、与えられた行列が特異行列にど

れくらい「近くに」あるかを決定します。合計の項目の数 k ≤ q に、これ以上

の制限が適用される場合もあります。例えば、k ≤ q の値があり、スカラー

|(bTui)|, i > k は右辺 bの中で平均不確定より小さくなります。これらのスカ

ラーはゼロに置き換えられるので、bはその問題で述べられた不確定の範囲内

にあるベクトルに取り替えられることを意味しています。

lin_sol_gen実数一般線形連立方程式 Ax = b を解きます。オプションの引数を使用して、

関連する計算を行うことができます。追加機能として、部分枢軸選択法を使用

する A の LU 分解の計算、逆行列 A-1の計算、ATx = b の解、又は、A の LU 分

解が与えられる Ax = b の解の計算があります。

概要

#include <imsl.h>

float *imsl_f_lin_sol_gen (int n, float a[], float b[], …, 0) double 型は、 imsl_d_lin_sol_gen になります。

必要な引数

int n ( 入力 )この行列の行数と列数。

float a[] ( 入力 )この行列を含むサイズ n × n の配列。

1 ,q Ti i i i iA s u v== ∑

( )1 ,k T

k i i i i ix t b u v== ∑

1, ,

,if 0

0 otherwise i i i i

i is s tol

t− ≥ >

=

Page 28: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float b[] ( 入力 )右辺を含むサイズ n の配列。

戻り値

線形連立方程式 Ax = b の解 x のポインター。 この空間を解放するために free を使用します。解が得られない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_lin_sol_gen (int n, float a[], float b[],IMSL_A_COL_DIM, int a_col_dim,IMSL_TRANSPOSE,IMSL_RETURN_USER, float x[],IMSL_FACTOR, int **p_pvt, float **p_factor,IMSL_FACTOR_USER, int pvt[], float factor[],IMSL_FAC_COL_DIM, int fac_col_dim,IMSL_INVERSE, float **p_inva,IMSL_INVERSE_USER, float inva[],IMSL_INV_COL_DIM, int inva_col_dim,IMSL_CONDITION, float *cond,IMSL_FACTOR_ONLY,IMSL_SOLVE_ONLY,IMSL_INVERSE_ONLY,0)

オプション引数

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 aの列ディメンジョン。.デフォルト: a_col_dim = n

IMSL_TRANSPOSE

ATx = b を解きます。

デフォルト: Ax = b を解きます。

IMSL_RETURN_USER, float x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_FACTOR, int **p_pvt, float **p_factor ( 出力 )p_pvt: 分解の枢軸順序を含んだ、長さ n の配列のポインターのアドレ

ス。返される時必要な空間は imsl_f_lin_sol_gen により割り当てら

れます。一般的に int *p_pvt が宣言され、&p_pvt が引数として使用

されます。

p_factor: 列枢軸交換で A の LU 分解を含んだ、サイズ n × n の配列の

ポインターのアドレス。返される時必要な空間は imsl_f_lin_sol_gen により割り当てられます。この配列の下三角部

分は L を構成するために、そして上三角部分は U を構成するために必

要な情報を含んでいます。一般的に float *p_factor が宣言され、

&p_factorが引数として使用されます。

IMSL_FACTOR_USER, int pvt[], float factor[] ( 入力 / 出力 )pvt[]: 分解の枢軸順序を含んだサイズ n のユーザ割り当ての配列。

factor[]: A の LU 分解を含んだ、サイズ n × n のユーザ割り当ての配

列。厳密には、この配列の下三角部分は L を構成するために、そして

上三角部分は U を構成するために必要な情報を含んでいます。 A が必

要でなければ factor と a は同じ記憶域を共有します。

IMSL_SOLVE が指定されると、これらのパラメータは入力です。その

他の場合は出力 になります。

IMSL_FAC_COL_DIM, int fac_col_dim ( 入力 )A の LU 分解を含む、列ディメンジョン。 デフォルト: fac_col_dim = n

Page 29: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_INVERSE, float **p_inva ( 出力 )行列 A. の逆行列を含んだサイズ n × n の配列のポインターのアドレ

ス。返される時必要な空間は imsl_f_lin_sol_gen により割り当てら

れます。一般的に float *p_invaが宣言され、&p_invaが引数として

使用されます。

IMSL_INVERSE_USER, float inva[] ( 出力 )A の逆行列を含む、サイズ n × n のユーザ割り当ての配列。

IMSL_INV_COL_DIM, int inva_col_dim ( 入力 )A の逆行列を含む、配列の列ディメンジョン。 デフォルト: inva_col_dim = n

IMSL_CONDITION, float *cond ( 出力 )行列 A の L1 ノルム条件数を含む推定値を含んだスカラーのポイン

ター。このオプションはオプション IMSL_SOLVE_ONLY と共に使用す

ることは出来ません。

IMSL_FACTOR_ONLY部分枢軸交換法で A の LU 分解を計算します。IMSL_FACTOR_ONLY を使用すると、IMSL_FACTOR 又は IMSL_FACTOR_USER のいずれかが必

要になります。引数 b はその時は無視されて、imsl_f_lin_sol_gen の戻り値は NULL になります。

IMSL_SOLVE_ONLY

imsl_f_lin_sol_gen により前もって計算された LU 分解が与えられ

て Ax = b を解きます。デフォルトで、Ax = b の解は imsl_f_lin_sol_gen. によって指定されます。IMSL_SOLVE_ONLY を使用する場合 , 引数 IMSL_FACTOR_USER が必要になり、引数 a は無

視されます。

IMSL_INVERSE_ONLY

行列 A の逆行列を計算します。IMSL_INVERSE_ONLY を使用すると、

IMSL_INVERSE 又は IMSL_INVERSE_USER が必要になります。引数 b はその時無視されて、imsl_f_lin_sol_gen の戻り値は NULLになり

ます。

説明

関数 imsl_f_lin_sol_gen は、実数係数行列 A を持つ線形代数連立方程式を

解きます。これは最初に L-1A = U となる部分枢軸選択法で A の LU 分解を計

算します。 L-1A ≡ Pn Ln-nPn-1… L1P1A ≡ U ですが、この行列 U は上三角です。

因子 Pi と Li は部分枢軸交換によって決定されます。各 Pi は行 i と、行 j ≥ i の交換なので、 Pi は j の値によって決定されます。全ての

は基本消去行列です。ベクトル mi は入力値 1, …, i でゼロです。このベクト

ルは分解情報を含んだ作業用配列の、下三角部分に列 i として格納されます。

この分解有効性はミシガン大学の Leonard J. Harding 博士の「ループ展開と妨

害 (loop unrolling and jamming)」の技術に基づいています。線形連立方程式の

この解は、それから 2 つのより簡単な連立方程式 y = L-1b と x = U

-1y を解く

ことによって見つけることができます。線形連立方程式、または逆行列の解が想定されるとき、A の L1 条件数の推定値は Dongarra その他 (1979 年 ) と同じ

アルゴリズムを使用して計算されます。もし推定した条件数が 1/ε(ε はマ

シン精度の場合)より大きい場合、警告メッセージが出ます。これは A の非

常に小さい変化が解 x の大きい変化を生成することを示しています。関数

imsl_f_lin_sol_gen は、分解の上三角部分 U が零対角要素を持つと失敗し

ます。

Ti i iL I m e= +

Page 30: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

例題 1

この例題では、3 元線形連立方程式を解きます。これはこの関数の最も簡単な

使用法です。この連立方程式は、以下の通りです。

x1 + 3x2 + 3x3 = 1

x1 + 3x2 + 4x3 = 4

x1 + 4x2 + 3x3 = −1

#include <imsl.h>

main(){ int n = 3; float *x; float a[] = {1.0, 3.0, 3.0, 1.0, 3.0, 4.0, 1.0, 4.0, 3.0}; float b[] = {1.0, 4.0, -1.0}; /* x のために Ax = b を解く */ x = imsl_f_lin_sol_gen (n, a, b, 0); /* x を表示 */ imsl_f_write_matrix ("Solution, x, of Ax = b", 1, 3, x, 0);}

出力結果

Solution, x, of Ax = b 1 2 3-2 -2 3

例題 2

この例題は転置問題 ATx = b を解いて、部分枢軸交換法で A の LU 分解を返し

ます。 最初の問題と同じデータが使用されて、メインプログラムに割り当てら

れた配列に解 x = A-Tb を返します。 L 行列は内示的な形式で返されます。

#include <imsl.h>

main(){ int n = 3, pvt[3]; float factor[9]; float x[3]; float a[] = {1.0, 3.0, 3.0, 1.0, 3.0, 4.0, 1.0, 4.0, 3.0};

float b[] = {1.0, 4.0, -1.0}; /* x のために trans(A)*x = b を解く */ imsl_f_lin_sol_gen (n, a, b, IMSL_TRANSPOSE, IMSL_RETURN_USER, x, IMSL_FACTOR_USER, pvt, factor, 0);

/* xを表示 */ imsl_f_write_matrix ("Solution, x, of trans(A)x = b", 1, n, x, 0);

/* 分解と枢軸順序をプリントする */ imsl_f_write_matrix ("LU factors of A", n, n, factor, 0); imsl_i_write_matrix ("Pivot sequence", 1, n, pvt, 0);}

Page 31: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

Solution, x, of trans(A)x = b 1 2 3 4 -4 1 LU factors of A 1 2 31 1 3 32 -1 1 03 -1 0 1 Pivot sequence 1 2 3 1 3 3

例題 3

この例題は、最初の例題の 3 × 3 の行列 A の逆行列を計算して、同じ連立方程

式を解きます。 行列積 C = A-1A が計算され、表示されます。

imsl_f_mat_mul_rect が C を計算するために使用され、近似結果 C = I が得

られます。

#include <imsl.h>

float a[] = {1.0, 3.0, 3.0, 1.0, 3.0, 4.0, 1.0, 4.0, 3.0};

float b[] = {1.0, 4.0, -1.0};

main(){ int n = 3; float *x; float *p_inva; float *C; /* Ax = bを解く */ x = imsl_f_lin_sol_gen (n, a, b, IMSL_INVERSE, &p_inva, 0);

/* 解を表示 */

imsl_f_write_matrix ("Solution, x, of Ax = b", 1, n, x, 0);

/* 入力値と逆行列を表示 */ imsl_f_write_matrix ("Input A", n, n, a, 0); imsl_f_write_matrix ("Inverse of A", n, n, p_inva, 0); /* 結果をチェックして表示 */ C = imsl_f_mat_mul_rect("A*B", IMSL_A_MATRIX, n, n, p_inva, IMSL_B_MATRIX, n, n, a, 0); imsl_f_write_matrix ("Product matrix, inv(A)*A",n,n,C,0);}

出力結果

Solution, x, of Ax = b 1 2 3 -2 -2 3 Input A 1 2 31 1 3 32 1 3 4

Page 32: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

3 1 4 3 Inverse of A 1 2 31 7 -3 -32 -1 0 13 -1 1 0 Product matrix, inv(A)*A 1 2 31 1 0 02 0 1 03 0 0 1

例題 4

この例題では 2 つの連立方程式を解きます。右辺だけが異なります。この行列

と 1 番目の右辺は最初の例題で与えられています。2 番目の右辺はベクトル

c = [0.5, 0.3, 0.4]T です。 この分解情報は、最初の解で計算され、2 番目を計算

するために使用されます。 最初のステップで実行された分解作業は 2 番目の解

を計算する際には回避されます。

#include <imsl.h>

main(){ int n = 3, pvt[3]; float factor[9]; float *x,*y;

float a[] = {1.0, 3.0, 3.0, 1.0, 3.0, 4.0, 1.0, 4.0, 3.0};

float b[] = {1.0, 4.0, -1.0}; float c[] = {0.5, 0.3, 0.4};

/* xのために A*x = b を解く */ x = imsl_f_lin_sol_gen (n, a, b, IMSL_FACTOR_USER, pvt, factor, 0);

/* xを表示 */ imsl_f_write_matrix ("Solution, x, of Ax = b", 1, n, x, 0);

/* yのために A*y = c を解く */ y = imsl_f_lin_sol_gen (n, a, c, IMSL_SOLVE_ONLY, IMSL_FACTOR_USER, pvt, factor, 0); imsl_f_write_matrix ("Solution, y, of Ay = c", 1, n, y, 0);

}

出力結果

Solution, x, of Ax = b 1 2 3 -2 -2 3 Solution, y, of Ay = c 1 2 3 1.4 -0.1 -0.2

警告エラー

IMSL_ILL_CONDITIONED この入力行列は非常に悪条件(ill-conditioned)です。L1 条件数の逆数の

Page 33: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

推定値は “rcond” = # です。解は恐らく正確

ではありません。

重大エラー

IMSL_SINGULAR_MATRIX この入力行列は特異です。

lin_sol_gen (複素数 )複素数一般線形連立方程式 Ax = b を解きます。オプションの引数を使用して、

関連する計算を行うことができます。追加機能として、部分枢軸選択法を使用

する A の LU 分解の計算、逆行列 A-1の計算、AHx = b の解、又は、A の LU 分

解が与えられる Ax = b の解の計算があります。

概要

#include <imsl.h>

f_complex *imsl_c_lin_sol_gen (int n, f_complex a[], f_complex b[], …, 0)d_complex 型は、 imsl_z_lin_sol_genです。

必要な引数

int n ( 入力 )この行列の行数と列数。

float a[] ( 入力 )この行列を含むサイズ n × n の配列。

float b[] ( 入力 )右辺を含むサイズ n の配列。

戻り値

線形連立方程式 Ax = b の解 x のポインター。 この空間を解放するために free を使用します。解が得られない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>f_complex *imsl_c_lin_sol_gen (int n, f_complex a[], f_complex b[],

IMSL_A_COL_DIM, int a_col_dim,IMSL_TRANSPOSE, IMSL_RETURN_USER, f_complex x[],IMSL_FACTOR, int **p_pvt, f_complex **p_factor,IMSL_FACTOR_USER, int pvt[], f_complex factor[],IMSL_FAC_COL_DIM, int fac_col_dim,IMSL_INVERSE, f_complex **p_inva,IMSL_INVERSE_USER, f_complex inva[],IMSL_INV_COL_DIM, int inva_col_dim,IMSL_CONDITION, float *cond,IMSL_FACTOR_ONLY,IMSL_SOLVE_ONLY,IMSL_INVERSE_ONLY,0)

オプション引数

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 aの列ディメンジョン。

デフォルト: a_col_dim = n

IMSL_TRANSPOSE

AHx = b を解きます。

デフォルト: Ax = b を解きます。

Page 34: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_RETURN_USER, float x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_FACTOR, int **p_pvt, f_complex **p_factor ( 出力 )p_pvt: 分解の枢軸順序を含んだ、長さ n の配列のポインターのアドレ

ス。返される時必要な空間は imsl_c_lin_sol_gen により割り当てら

れます。一般的に int *p_pvt が宣言され、&p_pvt が引数として使用

されます。

p_factor: 列枢軸交換で A の LU 分解を含んだ、サイズ n × n の配列の

ポインターのアドレス。返される時必要な空間は imsl_c_lin_sol_gen により割り当てられます。この配列の下三角部

分は L を構成するために、そして上三角部分は U を構成するために必

要な情報を含んでいます。一般的に f_complex *p_factor が宣言され、

&p_factorが引数として使用されます。

IMSL_FACTOR_USER, int pvt[], f_complex factor[] ( 入力 / 出力 )pvt[]: 分解の枢軸順序を含んだサイズ n のユーザ割り当ての配列。

factor[]: A の LU 分解を含んだ、サイズ n × n のユーザ割り当ての配

列。厳密には、この配列の下三角部分は L を構成するために、そして

上三角部分は U を構成するために必要な情報を含んでいます。 A が必

要でなければ factor と a は同じ記憶域を共有します。

IMSL_SOLVE が指定されると、これらのパラメータは入力です。その

他の場合は出力 になります。

IMSL_FAC_COL_DIM, int fac_col_dim ( 入力 )A の LU 分解を含む、列ディメンジョン。 デフォルト: fac_col_dim = n

IMSL_INVERSE, f_complex **p_inva ( 出力 )行列 A. の逆行列を含んだサイズ n × n の配列のポインターのアドレ

ス。返される時必要な空間は imsl_c_lin_sol_gen により割り当てら

れます。一般的に f_complex *p_invaが宣言され、&p_invaが引数と

して使用されます。

IMSL_INVERSE_USER, f_complex inva[] ( 出力 )A の逆行列を含む、サイズ n × n のユーザ割り当ての配列。

IMSL_INV_COL_DIM, int inva_col_dim ( 入力 )A の逆行列を含む、配列の列ディメンジョン。 デフォルト: inva_col_dim = n

IMSL_CONDITION, float *cond ( 出力 )行列 A の L1 ノルム条件数を含む推定値を含んだスカラーのポイン

ター。このオプションはオプション IMSL_SOLVE_ONLY と共に使用す

ることは出来ません。

IMSL_FACTOR_ONLY部分枢軸交換法で A の LU 分解を計算します。IMSL_FACTOR_ONLY を使用すると、IMSL_FACTOR 又は IMSL_FACTOR_USER のいずれかが必

要になります。引数 b はその時は無視されて、imsl_c_lin_sol_gen の戻り値は NULL になります。

IMSL_SOLVE_ONLYimsl_c_lin_sol_gen により前もって計算された LU 分解が与えられ

て Ax = b を解きます。デフォルトで、Ax = b の解は imsl_c_lin_sol_genによって指定されます。IMSL_SOLVE_ONLY を使

用する場合 , 引数 IMSL_FACTOR_USER が必要になり、引数 a は無視

されます。

IMSL_INVERSE_ONLY

行列 A の逆行列を計算します。IMSL_INVERSE_ONLY を使用すると、

IMSL_INVERSE 又は IMSL_INVERSE_USER が必要になります。引数 b

Page 35: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

はその時無視されて、imsl_c_lin_sol_gen の戻り値は NULLになり

ます。

説明

関数 imsl_c_lin_sol_gen は、複素数係数行列 A を持つ線形代数連立方程式

を解きます。これは最初に L-1A = U となる部分枢軸選択法で A の LU 分解を

計算します。 L-1A ≡ PnLn-1Pn-1 …L1P1A ≡ U ですが、この行列 U は上三角で

す。 因子 Pi と Li は部分枢軸交換によって決定されます。各 Pi は行 i と、行

j ≥ i の交換なので、 Pi は j の値によって決定されます。全ての

は基本消去行列です。ベクトル mi は入力値 1, …, i でゼロです。このベクト

ルは分解情報を含んだ作業用配列の、下三角部分に列 i として格納されます。

この分解有効性はミシガン大学の Leonard J. Harding 博士の「ループ展開と妨

害 (loop unrolling and jamming)」の技術に基づいています。線形連立方程式の

この解は、それから 2 つのより簡単な連立方程式 y = L-1b と x = U

-1y を解く

ことによって見つけることができます。線形連立方程式、または逆行列の解が想定されるとき、A の L1 条件数の推定値は Dongarra その他 (1979 年 ) と同じ

アルゴリズムを使用して計算されます。もし推定した条件数が 1/ε(ε はマ

シン精度の場合)より大きい場合、警告メッセージが出ます。これは A の非

常に小さい変化が解 x の大きい変化を生成することを示しています。関数

imsl_c_lin_sol_gen は、分解の上三角部分 U が零対角要素を持つと失敗し

ます。

例題

例題 1

この例題では、3 元線形連立方程式を解きます。これはこの関数の最も簡単な

使用法です。この連立方程式は、以下の通りです。

(1 + i) x1 + (2 + 3i) x2 + (3 − 3i) x3 = 3 + 5i

(2 + i) x1 + (5 + 3i) x2 + (7 − 5i) x3 = 22 + 10i

(−2 + i) x1 + (−4 + 4i) x2 + (5 + 3i) x3 = −10 + 4i

#include <imsl.h>

f_complex a[] = {{1.0, 1.0}, {2.0, 3.0}, {3.0, -3.0}, {2.0, 1.0}, {5.0, 3.0}, {7.0, -5.0}, {-2.0, 1.0}, {-4.0, 4.0}, {5.0, 3.0}};

f_complex b[] = {{3.0, 5.0}, {22.0, 10.0}, {-10.0, 4.0}};

main(){ int n = 3; f_complex *x; /* x のために Ax = b を解く */ x = imsl_c_lin_sol_gen (n, a, b, 0);

/* x を表示 */ imsl_c_write_matrix ("Solution, x, of Ax = b", 1, n, x, 0);}

Ti i iL I m e= +

Page 36: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

Solution, x, of Ax = b 1 2 3( 1, -1) ( 2, 4) ( 3, -0)

例題 2

この例題は転置問題 AHx = b を解いて、部分枢軸交換法で A の LU 分解を返し

ます。 この例題は最初の例題と異なり、配列の解はメインプログラムに割り当てられます。

#include <imsl.h>

f_complex a[] = {{1.0, 1.0}, {2.0, 3.0}, {3.0, -3.0}, {2.0, 1.0}, {5.0, 3.0}, {7.0, -5.0}, {-2.0, 1.0}, {-4.0, 4.0}, {5.0, 3.0}};

f_complex b[] = {{3.0, 5.0}, {22.0, 10.0}, {-10.0, 4.0}};

main(){ int n = 3, pvt[3]; f_complex factor[9]; f_complex x[3]; /* x のために ctrans(A)*x = b を解く */ imsl_c_lin_sol_gen (n, a, b, IMSL_TRANSPOSE, IMSL_RETURN_USER, x, IMSL_FACTOR_USER, pvt, factor, 0); /* xを表示 */ imsl_c_write_matrix ("Solution, x, of ctrans(A)x = b", 1, n, x, 0);

/* 分解と枢軸順序を表示 */ imsl_c_write_matrix ("LU factors of A", n, n, factor, 0); imsl_i_write_matrix ("Pivot sequence", 1, n, pvt, 0);}

出力結果

Solution, x, of ctrans(A)x = b 1 2 3( -9.79, 11.23) ( 2.96, -3.13) ( 1.85, 2.47) LU factors of A 1 2 31 ( -2.000, 1.000) ( -4.000, 4.000) ( 5.000, 3.000)2 ( 0.600, 0.800) ( -1.200, 1.400) ( 2.200, 0.600)3 ( 0.200, 0.600) ( -1.118, 0.529) ( 4.824, 1.294)Pivot sequence 1 2 3 3 3 3

例題 3

この例題は、最初の例題の 3 × 3 の行列 A の逆行列を計算して、同じ連立方程

式を解きます。 行列積 C = A-1A が計算され、表示されます。C を計算するた

めに使用され、近似結果 C = I が得られます。

#include <imsl.h>

f_complex a[] = {{1.0, 1.0}, {2.0, 3.0}, {3.0, -3.0}, {2.0, 1.0}, {5.0, 3.0}, {7.0, -5.0}, {-2.0, 1.0}, {-4.0, 4.0}, {5.0, 3.0}};

f_complex b[] = {{3.0, 5.0}, {22.0, 10.0}, {-10.0, 4.0}};

main(){

Page 37: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int n = 3; f_complex *x; f_complex *p_inva; f_complex *C;

/* x のために Ax = b を解く */ x = imsl_c_lin_sol_gen (n, a, b, IMSL_INVERSE, &p_inva, 0);

/* 解を表示 */ imsl_c_write_matrix ("Solution, x, of Ax = b", 1, n, x, 0);

/* 入力と逆行列を表示 */ imsl_c_write_matrix ("Input A", n, n, a, 0); imsl_c_write_matrix ("Inverse of A", n, n, p_inva, 0);

/* 結果をチェックし表示 */ C = imsl_c_mat_mul_rect ("A*B", IMSL_A_MATRIX, n,n, p_inva, IMSL_B_MATRIX, n,n, a, 0); imsl_c_write_matrix ("Product, inv(A)*A", n, n, C, 0);}

出力結果

Solution, x, of Ax = b 1 2 3( 1, -1) ( 2, 4) ( 3, -0) Input A 1 2 31 ( 1, 1) ( 2, 3) ( 3, -3)2 ( 2, 1) ( 5, 3) ( 7, -5)3 ( -2, 1) ( -4, 4) ( 5, 3) Inverse of A 1 2 31 ( 1.330, 0.594) ( -0.151, 0.028) ( -0.604, 0.613)2 ( -0.632, -0.538) ( 0.160, 0.189) ( 0.142, -0.245)3 ( -0.189, 0.160) ( 0.193, -0.052) ( 0.024, 0.042) Product, inv(A)*A 1 2 31 ( 1, -0) ( -0, -0) ( -0, 0)2 ( 0, 0) ( 1, 0) ( 0, -0)3 ( -0, -0) ( -0, 0) ( 1, 0)

警告エラー

IMSL_ILL_CONDITIONED この入力行列は非常に悪条件(ill-conditioned)です。L1 条件数の逆数の

推定値は “rcond” = # です。解は恐らく正確

ではありません。

重大エラー

IMSL_SINGULAR_MATRIX この入力行列は特異です。

lin_sol_posdef実対称正定値連立方程式 Ax = b を解きます。オプションの引数を使用して、関

連する計算を行うことができます。これらの追加機能に含まれるものには

A = LLT の A のコレスキー因子 L の計算、逆行列 A-1 の計算、コレスキー因子

L が与えられた Ax = b の解の計算などがあります。

Page 38: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

概要

#include <imsl.h>

float *imsl_f_lin_sol_posdef (int n, float a[], float b[], …, 0)double 型は、imsl_d_lin_sol_posdefです。

必要な引数

int n ( 入力 )この行列の行数と列数。

float a[] ( 入力 )行列を含んだサイズ n × n の配列。

float b[] ( 入力 )右辺を含んだサイズ n の配列。

戻り値

対称正定値連立方程式 Ax = b の解 x のポインター。この空間を開放するため

には freeを使用します。解が存在しなければ NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_f_lin_sol_posdef (int n, float a[], float b[],

IMSL_A_COL_DIM, int a_col_dim,IMSL_RETURN_USER, float x[], IMSL_FACTOR, float **p_factor, IMSL_FACTOR_USER, float factor[],IMSL_FAC_COL_DIM, int fac_col_dim, IMSL_INVERSE, float **p_inva, IMSL_INVERSE_USER, float inva[],IMSL_INV_COL_DIM, int inv_col_dim,IMSL_CONDITION, float *cond,IMSL_FACTOR_ONLY, IMSL_SOLVE_ONLY, IMSL_INVERSE_ONLY, 0)

オプション引数

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 a の列ディメンジョン。 デフォルト: a_col_dim = n

IMSL_RETURN_USER, float x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_FACTOR, float **p_factor ( 出力 )

A の LLT 分解を含んだサイズ n × n の配列のポインターのアドレス。

必要な空間は imsl_f_lin_sol_posdef によって割り当てられます。

この配列の下三角部分は L を含み、上三角部分は LT を含みます。一般

的には float *p_factor が宣言されて &p_factor が引数として使用

されます。

IMSL_FACTOR_USER, float factor[] ( 入力 / 出力 )

A の LLT 分解を含んだサイズ n × n のユーザ割り当ての配列。この配

列の下三角部分は L を含み、上三角部分は LT を含みます。 A が必要で

なければ、aと factor は同じ記憶域を共有できます。IMSL_SOLVE が指定されると、これらのパラメータは入力です。その他の場合は出力 になります。

IMSL_FAC_COL_DIM, int fac_col_dim ( 入力 )

A の LLT 分解を含んだ配列の列ディメンジョン。

デフォルト: fac_col_dim = n

Page 39: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_INVERSE, float **p_inva ( 出力 ) A の 逆行列を含んだサイズ n × n の配列のポインターのアドレス。返

される時に必要な空間は imsl_f_lin_sol_posdef によって割り当て

られます。一般的には float *p_inva が宣言されて &p_inva が引数と

して使用されます。

IMSL_INVERSE_USER, float inva[] ( 出力 )A の 逆行列を含んだサイズ n × n のユーザ割り当ての配列。

IMSL_INV_COL_DIM, int inva_col_dim ( 入力 )A の逆行列を含んだ配列の列ディメンジョン。

デフォルト: inva_col_dim = n

IMSL_CONDITION, float *cond ( 出力 )行列 A の L1 ノルム条件数の推定値を含んだスカラーのポインター。

このオプションは IMSL_SOLVE_ONLY と共に使用することはできませ

ん。

IMSL_FACTOR_ONLY

A のコレスキー分解 LLT を計算します。IMSL_FACTOR_ONLY が使用さ

れる場合 IMSL_FACTOR 又は IMSL_FACTOR_USER のいずれかが必要に

なります。引数 b はこの時は無視されて、imsl_f_lin_sol_posdef の戻り値は NULL になります。

IMSL_SOLVE_ONLY

以前に imsl_f_lin_sol_posdef によって計算された LLT が与えら

れて、Ax = b を解きます。 デフォルトで、Ax = b の解は imsl_f_lin_sol_posdef によって指されます。 IMSL_SOLVE_ONLY が使用されると、引数 IMSL_FACTOR_USER が必要になり、引数 a は無視

されます。

IMSL_INVERSE_ONLYA の逆行列を計算します。IMSL_INVERSE_ONLY を使用すると

IMSL_INVERSE 又は、 IMSL_INVERSE_USER が必要になります。引数 b はこの時は無視されて、imsl_f_lin_sol_posdef の戻り値は NULL になります。

説明

関数 imsl_f_lin_sol_posdef は対称正定値係数行列 A を持つ線形代数連立

方程式を解きます。この関数は最初に A のコレスキー分解 LLT を計算します。

線形連立方程式の解はそれから単純な連立方程式 y = L-1b と x = L-Ty を解くこ

とによって見つけられます。線形連立方程式の解、或いは、逆行列が考えられるとき、A の L1 条件数は Dongarra その他 (1979 年 ) と同じアルゴリズムを使

用して計算されます。もし推定された条件数が 1/ε よりも大きい場合(この

ε はマシン精度)警告メッセージが出ます。これは A の非常に小さい変化が

解 x の大きい変化を生成することを意味します。

関数 imsl_f_lin_sol_posdef は分解の下三角行列 L がゼロ対角要素を持つ場

合、失敗します。

例題

例題 1

この例題では、対称正定値係数行列を持つ 3 つの線形連立方程式を解きます。

この方程式は、以下の通りです。

x1 − 3x2 + 2x3 = 27

−3x1 + 10x2 − 5x3 = −78

2x1 − 5x2 + 6x3 = 64

Page 40: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#include <imsl.h>

main(){ int n = 3; float *x; float a[] = {1.0, -3.0, 2.0, -3.0, 10.0, -5.0, 2.0, -5.0, 6.0}; float b[] = {27.0, -78.0, 64.0};

/* xのために Ax = b を解く */ x = imsl_f_lin_sol_posdef (n, a, b, 0);

/* xをプリント */ imsl_f_write_matrix ("Solution, x, of Ax = b", 1, n, x, 0);}

出力結果

Solution, x, of Ax = b 1 2 3 1 -4 7

例題 2

この例題は最初の例題と同じ 3 つの線形連立方程式を解きますが、今回は A

の LLT 分解を返します。その解 x はメインプログラムに割り当てられた配列

に返されます。

#include <imsl.h>

main(){ int n = 3; float x[3], *p_factor; float a[] = {1.0, -3.0, 2.0, -3.0, 10.0, -5.0, 2.0, -5.0, 6.0}; float b[] = {27.0, -78.0, 64.0};

/* xのために Ax = b を解く */ imsl_f_lin_sol_posdef (n, a, b, IMSL_RETURN_USER, x, IMSL_FACTOR, &p_factor, 0);

/* x をプリント */ imsl_f_write_matrix ("Solution, x, of Ax = b", 1, n, x, 0);

/* A のコレスキー因子をプリント */ imsl_f_write_matrix ("Cholesky factor L, and trans(L), of A", n, n, p_factor, 0);}

出力結果

Solution, x, of Ax = b1 2 31 -4 7 Cholesky factor L, and trans(L), of A 1 2 31 1 -3 22 -3 1 13 2 1 1

Page 41: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題 3

この例題では最初と同じ連立方程式を解きますが、A のコレスキー因子が与え

られます。

#include <imsl.h>

main(){ int n = 3; float *x, *a; float factor[ ] = {1.0, -3.0, 2.0, -3.0, 1.0, 1.0, 2.0, 1.0, 1.0}; float b[ ] = {27.0, -78.0, 64.0};

/* xのために Ax = b を解く */ x = imsl_f_lin_sol_posdef (n, a, b, IMSL_FACTOR_USER, factor, IMSL_SOLVE_ONLY, 0);

/* xをプリント */ imsl_f_write_matrix ("Solution, x, of Ax = b", 1, n, x, 0);}

出力結果

Solution, x, of Ax = b1 2 31 -4 7

警告エラー

IMSL_ILL_CONDITIONED この入力行列は非常に悪条件(ill-conditioned)です。L1 条件数の逆数の

推定値は ”rcond”=# です。解は恐らく正

確ではありません。

重大エラー

IMSL_NONPOSITIVE_MATRIX 入力行列の先導 #× # 小行列は正定値ではあ

りません。

IMSL_SINGULAR_MATRIX 入力行列は特異です。

IMSL_SINGULAR_TRI_MATRIX 入力三角行列は特異です。最初のゼロ対角

要素の指標は # です。

lin_sol_posdef (複素数 )複素エルミート正定値連立方程式 Ax = b を解きます。オプションの引数を使用

して、関連する計算を行うことができます。これらの追加機能に含まれるもの

には A = LLT の A のコレスキー因子 L の計算、逆行列 A-1 の計算、コレスキー

因子 L が与えられた Ax = b の解の計算などがあります。

概要

#include <imsl.h>

f_complex *imsl_c_lin_sol_posdef (int n, f_complex a[], f_complex b[], …, 0)

d_complex 型は、imsl_z_lin_sol_posdefです。

Page 42: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

int n ( 入力 )この行列の行数と列数。

f_complex a[] ( 入力 )行列を含んだサイズ n × n の配列。

f_complex b[] ( 入力 )右辺を含んだサイズ n の配列。

戻り値

エルミート正定値連立方程式 Ax = b の解 x のポインター。この空間を開放す

るためには freeを使用します。解が存在しなければ NULL が返されます。

オプション引数の概要

#include <imsl.h>

f_complex *imsl_c_lin_sol_posdef (int n, f_complex a[], f_complex b[], IMSL_A_COL_DIM, int a_col_dim,IMSL_RETURN_USER, f_complex x[],IMSL_FACTOR, f_complex **p_factor,IMSL_FACTOR_USER, f_complex factor[],IMSL_FAC_COL_DIM, int fac_col_dim,IMSL_CONDITION, float *cond,IMSL_FACTOR_ONLY,IMSL_SOLVE_ONLY,0)

オプション引数

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 a の列ディメンジョン。

デフォルト: a_col_dim = n

IMSL_RETURN_USER, f_complex x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_FACTOR, f_complex **p_factor ( 出力 )

A の LLT 分解を含んだサイズ n × n の配列のポインターのアドレス。

必要な空間は imsl_c_lin_sol_posdef によって割り当てられます。

この配列の下三角部分は L を含み、上三角部分は LT を含みます。一般

的には f_complex *p_factor が宣言されて &p_factor が引数として

使用されます。

IMSL_FACTOR_USER, f_complex factor[] ( 入力 / 出力 )

A の LLH 分解を含んだサイズ n × n のユーザ割り当ての配列。この配

列の下三角部分は L を含み、上三角部分は LH を含みます。 A が必要で

なければ、aと factor は同じ記憶域を共有できます。IMSL_SOLVE が指定されると、これらのパラメータは入力です。その他の場合は出力 になります

IMSL_FAC_COL_DIM, int fac_col_dim ( 入力 )

A の LLH 分解を含んだ配列の列ディメンジョン。

デフォルト: fac_col_dim = n

IMSL_CONDITION, float *cond ( 出力 )行列 A の L1 ノルム条件数の推定値を含んだスカラーのポインター。

このオプションは IMSL_SOLVE_ONLY と共に使用することはできま

せん。

IMSL_FACTOR_ONLY

A のコレスキー分解 LLH を計算します。IMSL_FACTOR_ONLY が使用

される場合 IMSL_FACTOR 又は IMSL_FACTOR_USER のいずれかが

Page 43: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要になります。引数 b はこの時は無視されて、

imsl_c_lin_sol_posdef の戻り値は NULL になります。

IMSL_SOLVE_ONLY

以前に imsl_c_lin_sol_posdef によって計算された LLH が与えら

れて、Ax = b を解きます。 デフォルトで、Ax = b の解は imsl_c_lin_sol_posdef によって指されます。 IMSL_SOLVE_ONLY が使用されると、引数 IMSL_FACTOR_USER が必要になり、引数 a は無視されます。

説明

関数 imsl_c_lin_sol_posdef はエルミート正定値係数行列 A を持つ線形代

数連立方程式を解きます。この関数は最初に A のコレスキー分解 LLH を計算

します。線形連立方程式の解はそれから単純な連立方程式 y = L-1b と x = L-1y を解くことによって見つけられます。線形連立方程式の解、或いは、逆行列が考えられるとき、A の L1 条件数は Dongarra その他 (1979 年 ) と同じアルゴリ

ズムを使用して計算されます。もし推定された条件数が 1/ε よりも大きい場

合(この ε はマシン精度)警告メッセージが出ます。これは A の非常に小さ

い変化が解 x の大きい変化を生成することを意味します。

例題

例題 1

この例題では、エルミート正定値係数行列を持つ 5 つの線形連立方程式を解きます。この方程式は、以下の通りです。

2x1 +(−1 + i)x2 = 1 +5i

(−1 − i)x1 +4x2 + (1 + 2i)x3 = 12 − 6i

(1 − 2i)x2 +10x3 + 4ix4 = 1 − 16i

−4ix3 + 6x4 + (1 + i)x5 = −3 − 3i

(1 − i)x4 + 9x5 = 25 + 16i

#include <imsl.h>

main(){ int n = 5; f_complex *x; f_complex a[] = { {2.0,0.0}, {-1.0,1.0},{0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {-1.0,-1.0},{4.0,0.0}, {1.0,2.0}, {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {1.0,-2.0},{10.0,0.0},{0.0,4.0}, {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {0.0,-4.0},{6.0,0.0}, {1.0,1.0}, {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {1.0,-1.0},{9.0,0.0} };

f_complex b[] = { {1.0,5.0}, {12.0,-6.0}, {1.0,-16.0}, {-3.0,-3.0}, {25.0,16.0} }; /* xのために Ax = b を解く */ x = imsl_c_lin_sol_posdef(n, a, b, 0);

/* x をプリント */ imsl_c_write_matrix("Solution, x, of Ax = b", 1, n, x, 0);}

出力結果

Solution, x, of Ax = b 1 2 3( 2, 1) ( 3, -0) ( -1, -1)

Page 44: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

4 5( 0, -2) ( 3, 2)

例題 2

この例題は最初の例題と同じ 5 つの線形連立方程式を解きますが、今回は A

の the LLH 分解を返します。その解 x はメインプログラムで割り当てられた配

列に返されます。

#include <imsl.h>

main(){ int n = 5; f_complex x[5], *p_factor; f_complex a[] = { {2.0,0.0}, {-1.0,1.0},{0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {-1.0,-1.0},{4.0,0.0}, {1.0,2.0}, {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {1.0,-2.0},{10.0,0.0},{0.0,4.0}, {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {0.0,-4.0},{6.0,0.0}, {1.0,1.0}, {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {1.0,-1.0},{9.0,0.0} }; f_complex b[] = { {1.0,5.0}, {12.0,-6.0}, {1.0,-16.0}, {-3.0,-3.0}, {25.0,16.0} }; /* xのために Ax = b を解く x */ imsl_c_lin_sol_posdef(n, a, b, IMSL_RETURN_USER, x, IMSL_FACTOR, &p_factor, 0);

/* xをプリント */ imsl_c_write_matrix("Solution, x, of Ax = b", 1, n, x, 0);

/* A のコレスキー因子をプリント */ imsl_c_write_matrix("Cholesky factor L, and ctrans(L), of A", n, n, p_factor, 0);}

出力結果

Solution, x, of Ax = b 1 2 3( 2, 1) ( 3, -0) ( -1, -1) 4 5( 0, -2) ( 3, 2)

Cholesky factor L, and ctrans(L), of A 1 2 31 ( 1.414, 0.000) ( -0.707, 0.707) ( 0.000, -0.000)2 ( -0.707, -0.707) ( 1.732, 0.000) ( 0.577, 1.155)3 ( 0.000, 0.000) ( 0.577, -1.155) ( 2.887, 0.000)4 ( 0.000, 0.000) ( 0.000, 0.000) ( 0.000, -1.386)5 ( 0.000, 0.000) ( 0.000, 0.000) ( 0.000, 0.000) 4 51 ( 0.000, -0.000) ( 0.000, -0.000)2 ( 0.000, -0.000) ( 0.000, -0.000)3 ( 0.000, 1.386) ( 0.000, -0.000)4 ( 2.020, 0.000) ( 0.495, 0.495)5 ( 0.495, -0.495) ( 2.917, 0.000)

Page 45: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

警告エラー

IMSL_HERMITIAN_DIAG_REAL_1 エルミート行列の対角項が実数です。その

虚部をゼロに設定します。

IMSL_HERMITIAN_DIAG_REAL_2 エルミート行列の対角項が実数です。その

虚部は、アルゴリズム内では、ゼロとして扱われます。

IMSL_ILL_CONDITIONED この入力行列は非常に悪条件(ill-conditioned)です。L1 条件数の逆数の

推定値は ”rcond”=# です。解は恐らく正

確ではありません。

重大エラー

IMSL_NONPOSITIVE_MATRIX 入力行列の先導 #× # 小行列は正定値ではあ

りません。

IMSL_HERMITIAN_DIAG_REAL 因子分解中、行列の対角項上に大きな虚部

があります。従って、正定値になりません。

IMSL_SINGULAR_TRI_MATRIX 入力三角行列は特異です。最初のゼロ対角

要素の指標は#です。

lin_sol_gen_band実数一般線形帯連立方程式 Ax = b を解きます。オプションの引数を使用して、

関連する計算を行うことができます。これらの追加の作業に含まれるのには、

部分枢軸選択法を使用する A の LU 分解の計算、ATx = b の解、又は、A の LU 分解が与えられて Ax = b の解の計算などがあります。

概要

#include <imsl.h>

float *imsl_f_lin_sol_gen_band (int n, float a[], int nlca, int nuca, float b[], …, 0)

double 型は、 imsl_d_lin_sol_gen_bandです。

必要な引数

int n ( 入力 )この行列の行数と列数。

float a[] ( 入力 )帯格納モードで n × n の帯係数行列を含むサイズ (nlca + nuca + 1) × n の配列。

int nlca ( 入力 )a の下共対角項の数。

int nuca ( 入力 )a の上共対角項の数。

float b[] ( 入力 )右辺を含むのサイズ n の配列。

戻り値

線形連立方程式 Ax = b の解xのポインター。 この空間を解放するために free を使用します。解が得られない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_lin_sol_gen_band (int n, float a[], int nlca, int nuca, float b[],

Page 46: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_TRANSPOSE,IMSL_RETURN_USER, float x[],IMSL_FACTOR, int **p_pvt, float **p_factor,IMSL_FACTOR_USER, int pvt[], float factor[],IMSL_CONDITION, float *condition,IMSL_FACTOR_ONLY,IMSL_SOLVE_ONLY,IMSL_BLOCKING_FACTOR, int block_factor,0)

オプション引数

IMSL_TRANSPOSE

ATx = b を解きます。

デフォルト: Ax = b を解きます。

IMSL_RETURN_USER, float x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_FACTOR, int **p_pvt, float **p_factor ( 出力 )p_pvt: 分解の枢軸順序を含む、長さ n の配列のポインターのアドレ

ス。返される時必要な空間は imsl_f_lin_sol_gen_band により割り

当てられます。一般的に int *p_pvt が宣言され、&p_pvt が引数と

して使用されます。

p_factor: 列枢軸交換で A の LU 分解を含んだ、サイズ (2nlca + nuca + 1) × n の配列のポインターのアドレス。 返される時必要な空間は

imsl_f_lin_sol_gen_band により割り当てられます。一般的に  float *p_factor が宣言され、&p_factorが引数として使用されま

す。

IMSL_FACTOR_USER, int pvt[], float factor[] ( 入力 / 出力 )pvt[]: 分解の枢軸順序を含んだサイズ n のユーザ割り当ての配列。

factor[]: A の LU 分解を含んだ、サイズ (2nlca + nuca + 1) × n のユーザ割り当ての配列。厳密には、この配列の下三角部分は L を構成

するために、そして上三角部分は U を構成するために必要な情報が含

まれます。 A が必要でなければ、factor と a は最初の (2nlca + nuca + 1) × n 記憶域を共有します。

IMSL_SOLVE_ONLY が指定されると、これらのパラメータは「入力」

です。その他の場合は「出力」になります。

IMSL_CONDITION, float *condition ( 出力 )行列 A の L1 ノルム条件数の推定値を含んだスカラーのポインター。こ

のオプションはオプション IMSL_SOLVE_ONLY と共に使用することは

出来ません。

IMSL_FACTOR_ONLY部分枢軸交換法で A の LU 分解を計算します。IMSL_FACTOR_ONLY が使用されると IMSL_FACTOR 又は IMSL_FACTOR_USER のいずれかが必

要になります。引数 b はその時は無視されて、

imsl_f_lin_sol_gen_band の戻り値は NULL になります。

IMSL_SOLVE_ONLYimsl_f_lin_sol_gen_band により事前に計算された LU 分解が与えら

れて Ax = b を解きます。Ax = b の解は imsl_f_lin_sol_gen_band によってデフォルトで指定されます。IMSL_SOLVE_ONLYを使用すると

, 引数 IMSL_FACTOR_USER が必要になり、引数 a は無視されます。

IMSL_BLOCKING_FACTOR, int block_factor ( 入力 )このブロッキング因子 block_factor は 32 より大きく設定しては

いけません。デフォルト: block_factor = 1

Page 47: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

関数 imsl_f_lin_sol_gen_band は、実数帯係数行列 A を持つ線形代数連立

方程式を解きます。これは最初に Du Croz その他(1990 年)で与えられたブ

ロック化 LU 分解アルゴリズムに基づいて A の LU 分解を計算します。レベル

3 の BLAS 呼び出しが直列ループと置き換えられます。このブロッキング因子、

block_factor のデフォルトは1ですが、 32 を越えない正の値に再設定す

ることが可能です。

より簡単な 2 つの連立方程式 y = L-1b と x = U -1y を解くことにより、線形連立

方程式の解を得ることができます。線形連立方程式、又は、逆行列の解を想定するとき、A の L1 条件数の推定値は Hignam(1988 年 ) に与えられた、Hagar の方法に対する Higham の修正を使用して計算されます。もし推定した条件数が

1/ε(ここで ε はマシン精度)より大きい場合、 警告メッセージが出ます。こ

れは A の非常に小さい変化が解 x の大きい変化を生成することを示していま

す。分解の上三角部分 U がゼロ対角要素を持つ場合、関数 imsl_f_lin_sol_gen_band は失敗します。

例題

例題 1

この例題は 4 元連立方程式を解くことで、この関数の最も簡単な使用法を説明

します。これがこの関数の最も簡単な使用法です。以下の連立方程式を解きます。

2x1 − x2 = 3

−3x1 + x2 − 2x3 = 1

−x3 + 2x4 = 11

2x3 + x4 = −2

#include <imsl.h>

void main (){ int n = 4; int nuca = 1; int nlca = 1; float *x;

/* aは、帯格納モードであることに注目 */

float a[] = {0.0, -1.0, -2.0, 2.0, 2.0, 1.0, -1.0, 1.0, -3.0, 0.0, 2.0, 0.0}; float b[] = {3.0, 1.0, 11.0, -2.0};

x = imsl_f_lin_sol_gen_band (n, a, nlca, nuca, b, 0);

imsl_f_write_matrix ("Solution x, of Ax = b", 1, n, x, 0);}

出力結果

Solution x, of Ax = b 1 2 3 4 2 1 -3 4

Page 48: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題 2

この例題においては、最初の例題からのデータを使用して問題 Ax = b を解き

ます。今回は、分解が返されて、LU を再計算せずに問題 ATx = b を解きま

す。

#include <imsl.h>

void main (){ int n = 4; int nuca = 1; int nlca = 1; int *pivot; float x[4]; float *factor;

/* a は帯格納モードであることに注目 */

float a[] = {0.0, -1.0, -2.0, 2.0, 2.0, 1.0, -1.0, 1.0, -3.0, 0.0, 2.0, 0.0}; float b[] = {3.0, 1.0, 11.0, -2.0};

/* Ax = b を解き LU を返す */

imsl_f_lin_sol_gen_band (n, a, nlca, nuca, b, IMSL_FACTOR, &pivot, &factor, IMSL_RETURN_USER, x, 0);

imsl_f_write_matrix ("Solution of Ax = b", 1, n, x, 0);

/* trans(A)x = b を解くために LU を事前計算する */ /* 元の行列 A は不要 */

imsl_f_lin_sol_gen_band (n, (float*) 0, nlca, nuca, b, IMSL_FACTOR_USER, pivot, factor, IMSL_SOLVE_ONLY, IMSL_TRANSPOSE, IMSL_RETURN_USER, x, 0);

imsl_f_write_matrix ("Solution of trans(A)x = b", 1, n, x, 0);}

出力結果 Solution of Ax = b 1 2 3 4 2 1 -3 4 Solution of trans(A)x = b 1 2 3 4 -6 -5 -1 -0

警告エラー

IMSL_ILL_CONDITIONED この入力行列は非常に悪条件(ill-conditioned)で

す。L1 条件数の逆数の推定値は "rcond"=# です。

解は恐らく正確ではありません。

重大エラー

IMSL_SINGULAR_MATRIX この入力行列は特異です。

Page 49: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

lin_sol_gen_band (複素数 )複素数一般線形帯連立方程式 Ax = b を解きます。オプションの引数を使用し

て、関連する計算を行うことができます。これらの追加の作業に含まれるのに

は、部分枢軸選択法を使用する A の LU 分解の計算、AHx = b の解、又は A のLU 分解が与えられて Ax = b の解の計算などがあります。

概要

#include <imsl.h>

f_complex *imsl_c_lin_sol_gen_band (int n, f_complex a[], int nlca, int nuca, f_complex b[], …, 0)

double 型は、 imsl_z_lin_sol_gen_band. です。

必要な引数

int n ( 入力 )この行列の行数と列数。

f_complex a[] ( 入力 )帯格納モードで n × n の帯係数行列を含むサイズ (nlca + nuca + 1) × n の配列。

int nlca ( 入力 )a の下共対角項の数。

int nuca ( 入力 )a の上共対角項の数。

f_complex b[] ( 入力 )右辺を含むのサイズ n の配列。

戻り値

線形連立方程式 Ax = b の解xのポインター。 この空間を解放するために free を使用します。解が得られない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>

f_complex *imsl_c_lin_sol_gen_band (int n, f_complex a[], int nlca, int nuca, f_complex b[],IMSL_TRANSPOSE,IMSL_RETURN_USER, f_complex x[],IMSL_FACTOR, int **p_pvt, f_complex **p_factor,IMSL_FACTOR_USER, int pvt[], f_complex factor[],IMSL_CONDITION, float *condition,IMSL_FACTOR_ONLY,IMSL_SOLVE_ONLY,0)

オプション引数

IMSL_TRANSPOSE

AHx = b を解きます。

デフォルト: Ax = b を解きます。

IMSL_RETURN_USER, f_complex x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_FACTOR, int **p_pvt, f_complex **p_factor ( 出力 )p_pvt: 分解の枢軸順序を含む、長さ n の配列のポインターのアドレ

ス。返される時必要な空間は imsl_c_lin_sol_gen_band により割り

当てられます。一般的に int *p_pvt が宣言され、&p_pvt が引数とし

て使用されます。

Page 50: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

p_factor: 列枢軸交換で A の LU 分解を含んだ、サイズ (2nlca + nuca + 1) × n の配列のポインターのアドレス。 返される時必要な空間は

imsl_c_lin_sol_gen_band により割り当てられます。一般的に f_complex *p_factor が宣言され、&p_factorが引数として使用され

ます。

IMSL_FACTOR_USER, int pvt[], f_complex factor[] ( 入力 / 出力 )pvt[]: 分解の枢軸順序を含んだサイズ n のユーザ割り当ての配列。.factor[]: A の LU 分解を含んだ、サイズ (2nlca + nuca + 1) × n のユーザ割り当ての配列。厳密には、この配列の下三角部分は L を構成

するために、そして上三角部分は U を構成するために必要な情報が含

まれます。 A が必要でなければ、factor と a は最初の (2nlca + nuca + 1) × n 記憶域を共有します。

IMSL_SOLVE_ONLY が指定されると、これらのパラメータは「入力」

です。その他の場合は「出力」になります。

IMSL_CONDITION, float *condition ( 出力 )行列 A の L1 ノルム条件数の推定値を含んだスカラーのポインター。こ

のオプションはオプション IMSL_SOLVE_ONLY と共に使用することは

出来ません。

IMSL_FACTOR_ONLY

部分枢軸交換法で A の LU 分解を計算します。IMSL_FACTOR_ONLY が使用されると、IMSL_FACTOR 又は IMSL_FACTOR_USER のいずれかが

必要になります。引数 b はその時は無視されて、

imsl_c_lin_sol_gen_band の戻り値は NULL になります。

IMSL_SOLVE_ONLYimsl_c_lin_sol_gen_band により事前に計算された LU 分解が与えら

れて Ax = b を解きます。Ax = b の解は imsl_c_lin_sol_gen_band によってデフォルトで指定されます。IMSL_SOLVE_ONLYを使用すると , 引数 IMSL_FACTOR_USER が必要になり、引数 a は無視されます。

説明

関数 imsl_c_lin_sol_gen_band は、複素数帯係数行列 A を持つ線形代数連

立方程式を解きます。最初にスケーリングされた部分枢軸法を利用して A の

LU 分解を計算します。 スケーリングされた部分枢軸選択法は、各列が同じ L∝

ノルムを持つためにスケーリングされるという点において部分枢軸選択法と異なっています。U がゼロ対角要素を持つ場合、因子分解は失敗します。 このこ

とは、A が特異もしくは特異行列に近い場合に限り、起こります。

より簡単な 2 つの連立方程式 y = L-1b と x = U -1yy=L-1b と x=U-1y を解くこ

とにより、線形連立方程式の解を得ることができます。線形連立方程式、又は、

逆行列の解を想定するとき、A の L1 条件数の推定値は Hignam(1988 年 ) に与え

られた、Hagar の方法に対する Higham の修正を使用して計算されます。もし推

定した条件数が 1/ε(ここで ε はマシン精度)より大きい場合、 警告メッセー

ジが出ます。これは A の非常に小さい変化が解 x の大きい変化を生成すること

を示しています。分解の上三角部分 U がゼロ対角要素を持つ場合、関数 imsl_c_lin_sol_gen_band は失敗します。imsl_c_lin_sol_gen_band は、

LINPACK のサブルーチン CGBFA を基にしています。詳細は、Dongarra(1979年)を参照してください。CGBFA は、スケーリングされてない部分枢軸選択

法を使用しています。

例題

例題 1

次の線形方程式を解きます。

Page 51: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#include <imsl.h>

void main(){ int n = 4; int nlca = 1; int nuca = 1; f_complex *x;

/* a は、帯格納モードであることに注意 */

f_complex a[] = {{0.0, 0.0}, {4.0, 0.0}, {-2.0, 2.0}, {-4.0, -1.0}, {-2.0, -3.0}, {-0.5, 3.0}, {3.0, -3.0}, {1.0, -1.0}, {6.0, 1.0}, {1.0, 1.0}, {0.0, 2.0}, {0.0, 0.0}};

f_complex b[] = {{-10.0, -5.0}, {9.5, 5.5}, {12.0, -12.0}, {0.0, 8.0}};

x = imsl_c_lin_sol_gen_band (n, a, nlca, nuca, b, 0);

imsl_c_write_matrix ("Solution, x, of Ax = b", n, 1, x, 0);

出力結果

Solution, x, of Ax = b1 ( 3, -0)2 ( -1, 1)3 ( 3, 0)4 ( -1, 1)

例題 2

最初の例題のデータを使って、 Ax = b を解きます。この例題では、因子分解を

返し、 LU を再計算せずに AHx = b を解きます。

#include <imsl.h>

#include <stdlib.h>void main(){ int n = 4; int nlca = 1; int nuca = 1; int *pivot; f_complex *x; f_complex *factor;

/* a は、帯格納モードであることに注意 */

f_complex a[] = {{0.0, 0.0}, {4.0, 0.0}, {-2.0, 2.0}, {-4.0, -1.0}, {-2.0, -3.0}, {-0.5, 3.0}, {3.0, -3.0}, {1.0, -1.0}, {6.0, 1.0}, {1.0, 1.0}, {0.0, 2.0}, {0.0, 0.0}}; f_complex b[] = {{-10.0, -5.0}, {9.5, 5.5}, {12.0, -12.0}, {0.0, 8.0}};

/* Ax = b を解き、 LU を返す */

x = imsl_c_lin_sol_gen_band (n, a, nlca, nuca, b,

0

1

2

3

2 3 4 0 0 10 56 0.5 3 2 2 0 9.5 5.5

0 1 3 3 4 1 12 120 0 2 1 8

xi ixi i i ixi i ixi i i

− − − − + − + − + + = + − − − −

Page 52: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_FACTOR, &pivot, &factor, 0);

imsl_c_write_matrix ("solution of Ax = b", n, 1, x, 0); free (x);

/* ctrans(A)x = b をとくために計算済みの LUを使用 */

x = imsl_c_lin_sol_gen_band (n, a, nlca, nuca, b, IMSL_FACTOR_USER, pivot, factor, IMSL_TRANSPOSE, 0);

imsl_c_write_matrix ("solution of ctrans(A)x = b", n, 1, x, 0);}

出力結果

solution of Ax = b1 ( 3, -0)2 ( -1, 1)3 ( 3, 0)4 ( -1, 1) solution of ctrans(A)x = b1 ( 5.58, -2.91)2 ( -0.48, -4.67)3 ( -6.19, 7.15)4 ( 12.60, 30.20)

警告エラー

IMSL_ILL_CONDITIONED この入力行列は非常に悪条件(ill-conditioned)で

す。L1 条件数の逆数の推定値は "rcond"=# です。

解は恐らく正確ではありません。

重大エラー

IMSL_SINGULAR_MATRIX この入力行列は特異です。

lin_sol_posdef_band帯対称格納様式の実対称正定値線形連立方程式、Ax = b を解きます。オプショ

ンの引数を使用して、関連する計算を行うことができます。これらの追加作業

には、A の RTR コレスキー分解の計算、A のコレスキー分解が与えられた Ax = b の解の計算、又は、A の L1 条件数の推定などが含まれます。

概要

#include <imsl.h>

float *imsl_f_lin_sol_posdef_band (int n, float a[], int ncoda, float b[], …, 0)

double 型は、 imsl_d_lin_sol_posdef_bandです。

必要な引数

int n ( 入力 )行列の行数と列数。

float a[] ( 入力 )帯対称格納様式の n × n 正定値帯係数行列を含んだ、サイズ (ncoda + 1) × n の配列。

Page 53: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int ncoda ( 入力 )行列の上共対角項数。

float b[] ( 入力 )右辺を含んだのサイズ n の配列。

戻り値

線形連立方程式 Ax = b の解 x のポインター。この空間を開放するためには

free を使用します。解が得られない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_lin_sol_posdef_band (int n, float a[], int ncoda, float b[],IMSL_RETURN_USER, float x[],IMSL_FACTOR, float **p_factor,IMSL_FACTOR_USER, float factor[],IMSL_CONDITION, float *cond,IMSL_FACTOR_ONLY,IMSL_SOLVE_ONLY,0)

オプション引数

IMSL_RETURN_USER, float x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_FACTOR, float **p_factor ( 出力 )

Aの LLT 分解を含んだサイズ (ncoda + 1) × nの配列のポインターのアド

レス。必要な記憶域は、imsl_f_lin_sol_posdef_band によって割り

当てられます。一般的には、 float *p_factorが宣言されて、

&p_factor が引数として使用されます。

IMSL_FACTOR_USER, float factor[] ( 入力 / 出力 )

帯対称形の A の LLT 分解を含んだサイズ (ncoda + 1) × n のユーザ割り

当ての配列。A が必要でなければ、factor と a は同じ記憶域を共有

することが出来ます。

IMSL_SOLVE が指定されると、これらのパラメータは「入力」です。

その他の場合は「出力」になります。

IMSL_CONDITION, float *cond ( 出力 )行列 A の L1 ノルム条件数の推定値を含んだスカラーのポインター。

このオプションは、オプション IMSL_SOLVE_ONLY と一緒には使用で

きません。

IMSL_FACTOR_ONLY

A の LLT 分解を計算します。IMSL_FACTOR_ONLY が使用されると、

IMSL_FACTOR 又は IMSL_FACTOR_USER のいずれかが必要になります。

その時、引数 b は無視され、imsl_f_lin_sol_posdef_band の戻り

値は NULL になります。

IMSL_SOLVE_ONLY

事前に imsl_f_lin_sol_posdef_band が計算した LLT 分解が与えら

れて、 Ax = b を解きます。デフォルトによって、Ax = b の解は

imsl_f_lin_sol_posdef_band によって指されます。 IMSL_SOLVE_ONLY を使用すると、引数 IMSL_FACTOR_USER が必要に

なり、引数 a は無視されます。

説明

関数 imsl_f_lin_sol_posdef_band は実対称正定値帯係数行列 A を持つ線

形代数連立方程式を解きます。これは A の RTR コレスキー分解を計算します。

R は上三角帯行列です。

Page 54: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

線形連立方程式の解、或いは、行列の逆行列を見つけるときには、A の L1 条件

数の推定値が、Higham (1988 年 ) に与えらた Hager 法に対する、Higham の修

正を使用して計算します。推定された条件数が 1/ε(ここで ε はマシン精

度)より大きいならば、警告メッセージが出ます。これは、A の非常に小さい

変化が、x に大きい変化を生じることを示しています。

R のいずれかの小行列が正定値でない、もしくは R がゼロ対角要素を持つと、

関数 imsl_f_lin_sol_posdef_band は、失敗します。 これらのエラーは、A が特異行列、または正定値ではない行列に非常に近いときだけに発生します。

関数 imsl_f_lin_sol_posdef_band は部分的に LINPACK サブルーチン

CPBFA と SPBSL を基準にしています。 Dongarra その他 (1979 年 ) を参照して

ください。

例題 1

以下のような配列の線形方程式 Ax = b を解きます。

#include <imsl.h>

void main(){ int n = 4; int ncoda = 2; float *x;

/* a は、帯格納モードであることに注意 */

float a[] = {0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 2.0, -1.0, 2.0, 4.0, 7.0, 3.0}; float b[] = {6.0, -11.0, -11.0, 19.0};

x = imsl_f_lin_sol_posdef_band (n, a, ncoda, b, 0);

imsl_f_write_matrix ("Solution, x, of Ax = b", 1, n, x, 0);}

出力結果

Solution, x, of Ax = b 1 2 3 4 4 -6 2 9

例題 2

この例題では最初の例題と同じ問題 Ax = b を解きます。この解はユーザ割り

当ての記憶域に返され、κ1(A) が計算されます。これに加えて RTR 分解が返さ

れます。κ1(A) = ||A|| ||A-1|| であることを知りながら、その条件数を直接計算し、

Higham の方法からの推定値と比較します。

#include <imsl.h>

void main(){ int n = 4; int ncoda = 2; float a[] = {0.0, 0.0, -1.0, 1.0,

2 0 1 0 60 4 2 1 111 2 7 1 11

0 1 1 3 19

A b

− − = = − − −

Page 55: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

0.0, 0.0, 2.0, -1.0, 2.0, 4.0, 7.0, 3.0}; float b[] = {6.0, -11.0, -11.0, 19.0}; float x[4]; float e_i[4]; float *factor; float condition; float column_norm; float inverse_norm; int i; int j;

imsl_f_lin_sol_posdef_band (n, a, ncoda, b, IMSL_FACTOR, &factor, IMSL_CONDITION, &condition, IMSL_RETURN_USER, x, 0);

imsl_f_write_matrix ("Solution, x, of Ax = b", 1, n, x, 0);

/* 逆行列の 1ノルムを見つける */

inverse_norm = 0.0; for (i=0; i<n; i++) { for (j=0; j<n; j++) e_i[j] = 0.0; e_i[i] = 1.0;

/* 逆行列の各列の 1ノルムを決定 */

imsl_f_lin_sol_posdef_band (n, a, ncoda, e_i, IMSL_FACTOR_USER, factor, IMSL_SOLVE_ONLY, IMSL_RETURN_USER, x, 0); column_norm = imsl_f_vector_norm (n, x, IMSL_ONE_NORM, 0);

/* 列ノルムの最大値は、inv(A)のノルム */

if (inverse_norm < column_norm) inverse_norm = column_norm; }

/* 観測による A の1ノルムは 11 */

printf ("\nHigham’s condition estimate = %f\n", condition); printf ("Direct condition estimate = %f\n", 11.0*inverse_norm);}

出力結果 Solution, x, of Ax = b 1 2 3 4 4 -6 2 9

Higham’s condition estimate = 8.650485Direct condition estimate = 8.650485

警告エラー

IMSL_ILL_CONDITIONED この入力行列は非常に悪条件(ill-conditioned)です。L1 条件数の逆数の推定

値は "rcond"=# です。解は恐らく正確ではあ

りません。

Page 56: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

重大エラー s

IMSL_NONPOSITIVE_MATRIX 入力行列の # × #の先導小行列は正定値では

ありません。

IMSL_SINGULAR_MATRIX この入力行列は特異です。

lin_sol_posdef_band (複素数 )帯対称格納モードの複素エルミート正定値線形連立方程式、Ax = b を解きま

す。オプション引数を使用して、関連する計算を行うことができます。これら

の追加機能には、A の RHR コレスキー分解の計算、A のコレスキー分解が与え

られた Ax = b の解の計算、又は、A の L1 条件数の推定などが含まれます。

概要

#include <imsl.h>

f_complex *imsl_c_lin_sol_posdef_band (int n, f_complex a[], int ncoda, f_complex b[], …, 0)

double 型は、 imsl_z_lin_sol_posdef_bandです。

必要な引数

int n ( 入力 )行列の行数と列数。

f_complex a[] ( 入力 )帯対称格納様式の n × n 正定値帯係数行列を含んだ、サイズ (ncoda + 1) × n の配列。

int ncoda ( 入力 )行列の上共対角項数。

f_complex b[] ( 入力 )右辺を含んだのサイズ n の配列。

戻り値

線形連立方程式 Ax = b の解 x のポインター。この空間を開放するためには

free を使用します。解が得られない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>

f_complex *imsl_c_lin_sol_posdef_band (int n, f_complex a[], int ncoda, f_complex b[],IMSL_RETURN_USER, f_complex x[],IMSL_FACTOR, f_complex **p_factor,IMSL_FACTOR_USER, f_complex factor[],IMSL_CONDITION, float *condition,IMSL_FACTOR_ONLY,IMSL_SOLVE_ONLY,0)

オプション引数

IMSL_RETURN_USER, f_complex x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_FACTOR, f_complex **p_factor ( 出力 )

A のRHR 分解を含んだサイズ (ncoda + 1) × nの配列のポインターのアド

レス。必要な記憶域は、imsl_c_lin_sol_posdef_bandによって割り

当てられます。通常、f_complex *p_factor が宣言されて、

&p_factor が引数として使用されます。

Page 57: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_FACTOR_USER, f_complex factor[] ( 入力 / 出力 )

帯対称形の A の RHR 分解を含んだサイズ (ncoda + 1) × n のユーザ割り

当ての配列。A が必要でなければ、factor と a は同じ記憶域を共有

することが出来ます。IMSL_SOLVE が指定されると、これらの引数は

「入力」です。その他の場合は「出力」になります。

IMSL_CONDITION, float *condition ( 出力 )行列 A の L1 ノルム条件数の推定値を含んだスカラーのポインター。

このオプションは、オプション IMSL_SOLVE_ONLY と一緒には使用で

きません。

IMSL_FACTOR_ONLY

A の RHR 分解を計算します。IMSL_FACTOR_ONLY が使用されると、

IMSL_FACTOR 又は IMSL_FACTOR_USER のいずれかが必要になります。

その時、引数 b は無視され、imsl_c_lin_sol_posdef_band の戻り

値は NULL になります。

IMSL_SOLVE_ONLY

事前に imsl_c_lin_sol_posdef_bandによって計算された RHR 分解

が与えられて、 Ax = b を解きます。デフォルトでは、Ax = b の解は

imsl_c_lin_sol_posdef_band によって指されます。 IMSL_SOLVE_ONLY を使用すると、引数 IMSL_FACTOR_USER が必要に

なり、引数 a は無視されます。

説明

関数 imsl_c_lin_sol_posdef_band は実対称正定値帯係数行列 A を持つ線

形代数連立方程式を解きます。これは A の RHR コレスキー分解を計算します。

R は上三角帯行列です。

線形連立方程式の解、或いは、行列の逆行列を見つけるときには、A の L1 条件

数の推定値が、Higham (1988 年 ) に与えらた Hager 法に対する、Higham の修

正を使用して計算します。推定された条件数が 1/ε(ここで ε はマシン精

度)より大きいならば、警告メッセージが出ます。これは、A の非常に小さい

変化が、x に大きい変化を生じることを示しています。

R のいずれかの小行列が正定値でない、もしくは R がゼロ対角要素を持つと、

関数 imsl_c_lin_sol_posdef_band は、失敗します。 これらのエラーは、A が特異行列、または正定値ではない行列に非常に近いときだけに発生します。

関数 imsl_c_lin_sol_posdef_band は部分的に LINPACK サブルーチン

SPBFA と CPBSL を基準にしています。 Dongarra その他 (1979 年 ) を参照して

ください。

例題

例題 1

以下の行列の線形方程式 Ax = b を解きます。

#include <imsl.h>

void main(){ int n = 5; int ncoda = 1; f_complex *x;

2 1 0 0 01 4 1 2 0 00 1 2 10 4 00 0 4 6 10 0 0 1 9

ii i

A i ii i

i

− + − − + = −

− + −

Page 58: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* a 帯格納モードであることに注意 */

f_complex a[] = {{0.0, 0.0}, {-1.0, 1.0}, {1.0, 2.0}, {0.0, 4.0}, {1.0, 1.0}, {2.0, 0.0}, {4.0, 0.0}, {10.0, 0.0}, {6.0, 0.0}, {9.0, 0.0}}; f_complex b[] = {{1.0, 5.0}, {12.0, -6.0}, {1.0, -16.0},{-3.0, -3.0}, {25.0, 16.0}};

x = imsl_c_lin_sol_posdef_band (n, a, ncoda, b, 0);

imsl_c_write_matrix ("Solution, x, of Ax = b", n, 1, x, 0);}

出力結果 Solution, x, of Ax = b1 ( 2, 1)2 ( 3, -0)3 ( -1, -1)4 ( 0, -2)5 ( 3, 2)

例題 2

この例題では最初の例題と同じ問題 Ax = b を解きます。この解はユーザ割り

当ての記憶域に返され、κ1(A) が計算されます。これに加えて RHR 分解が返さ

れます。κ1(A) = ||A|| ||A-1|| であることを知りながら、その条件数を直接計算し、

Higham の方法からの推定値と比較します。

#include <imsl.h>#include <math.h>

void main(){ int n = 5; int ncoda = 1;

/* a は、帯格納モードであることに注意 */

f_complex a[] = {{0.0, 0.0}, {-1.0, 1.0}, {1.0, 2.0}, {0.0, 4.0}, {1.0, 1.0}, {2.0, 0.0}, {4.0, 0.0}, {10.0, 0.0}, {6.0, 0.0}, {9.0, 0.0}}; f_complex b[] = {{1.0, 5.0}, {12.0, -6.0}, {1.0, -16.0},{-3.0, -3.0}, {25.0, 16.0}}; f_complex x[5]; f_complex e_i[5]; f_complex *factor; float condition; float column_norm; float inverse_norm; int i; int j;

imsl_c_lin_sol_posdef_band (n, a, ncoda, b, IMSL_FACTOR, &factor, IMSL_CONDITION, &condition, IMSL_RETURN_USER, x, 0);

imsl_c_write_matrix ("Solution, x, of Ax = b", 1, n, x, 0);

Page 59: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* 逆行列の 1ノルムを見つける */

inverse_norm = 0.0; for (i=0; i<n; i++) { for (j=0; j<n; j++) e_i[j] = imsl_cf_convert (0.0, 0.0); e_i[i] = imsl_cf_convert (1.0, 0.0);

/* 逆行列の各列の 1ノルムを決定 */

imsl_c_lin_sol_posdef_band (n, a, ncoda, e_i, IMSL_FACTOR_USER, factor, IMSL_SOLVE_ONLY, IMSL_RETURN_USER, x, 0);

column_norm = imsl_c_vector_norm (n, x, IMSL_ONE_NORM, 0);

/* 列ノルムの最大値は、inv(A)のノルム */

if (inverse_norm < column_norm) inverse_norm = column_norm; }

/* Aの 1 ノルムは、14+sqrt(5) */

printf ("\nHigham’s condition estimate = %7.4f\n", condition); printf ("Direct condition estimate = %7.4f\n", (14.0+sqrt(5.0))*inverse_norm);}

出力結果

Solution, x, of Ax = b 1 2 3( 2, 1) ( 3, -0) ( -1, -1) 4 5( 0, -2) ( 3, 2)

Higham’s condition estimate = 19.3777Direct condition estimate = 19.3777

警告エラー

IMSL_ILL_CONDITIONED この入力行列は非常に悪条件(ill-conditioned)です。L1 条件数の逆数の推定値は "rcond"=# です。解は恐らく正確ではありません。

重大エラー

IMSL_NONPOSITIVE_MATRIX 入力行列の先導 # × # 小行列は正定値では

ありません。

IMSL_SINGULAR_MATRIX この入力行列は特異です。

lin_sol_gen_coordinate疎の線形連立方程式 Ax = b を解きます。オプションの引数を使用して、関連

する計算を行うことができます。これらの追加機能に含まれるものに、A のLU 分解 、LU 分解 が与えらた Ax = b の解の計算、低下許容値の設定、反復改

良法の制御などがあります。

Page 60: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

概要

#include <imsl.h>

float *imsl_f_lin_sol_gen_coordinate (int n, int nz, Imsl_f_sparse_elem *a, float *b, ..., 0)

double 型の関数は、 imsl_d_lin_sol_gen_coordinateです。

必要な引数

int n ( 入力 )この行列の行数。

int nz ( 入力 )この行列内の非ゼロの数。

Imsl_f_sparse_elem *a ( 入力 )この行列の各非ゼロ入力値の位置と値を含んだ長さ nz のベクトル。

float *b ( 入力 )右辺を含んだ長さ n のベクトル。

戻り値

疎の線形連立方程式 Ax = b の解 x のポインター。この空間を解放するために

free を使用します。解が計算できない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_lin_sol_gen_coordinate (int n, int nz, Imsl_f_sparse_elem *a, float *b,IMSL_RETURN_SPARSE_LU_FACTOR, Imsl_f_sparse_lu_factor *lu_factor,IMSL_SUPPLY_SPARSE_LU_FACTOR, Imsl_f_sparse_lu_factor *lu_factor,IMSL_FREE_SPARSE_LU_FACTOR,IMSL_RETURN_SPARSE_LU_IN_COORD, Imsl_f_sparse_elem **lu_coordinate, int **row_pivots, int **col_pivots,IMSL_SUPPLY_SPARSE_LU_IN_COORD, Imsl_f_sparse_elem *lu_coordinate, int *row_pivots, int *col_pivots,IMSL_FACTOR_ONLY,IMSL_SOLVE_ONLY,IMSL_RETURN_USER, float x[],IMSL_TRANSPOSE,IMSL_CONDITION, float *condition,IMSL_PIVOTING_STRATEGY, Imsl_pivot method,IMSL_NUM_OF_SEARCH_ROWS, int num_search_row,IMSL_ITERATIVE_REFINEMENT,IMSL_DROP_TOLERANCE, float tolerance,IMSL_HYBRID_FACTORIZATION, float density, int order_bound,IMSL_STABILITY_FACTOR, float s_factor,IMSL_GROWTH_FACTOR_LIMIT, float gf_limit,IMSL_GROWTH_FACTOR, float *gf,IMSL_SMALLEST_PIVOT, float *small_pivotIMSL_NUM_NONZEROS_IN_FACTOR, int *num_nonzeros,IMSL_CSC_FORMAT, int *col_ptr, int *row_ind, float *values,IMSL_MEMORY_BLOCK_SIZE, int block_size,0)

Page 61: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数

IMSL_RETURN_SPARSE_LU_FACTOR, Imsl_f_sparse_lu_factor *lu_factor (出力 )Imsl_f_sparse_lu_factor 型の構造体のアドレス。この構造体の内部のポ

インターは imsl_f_lin_sol_gen_coordinate による LU 分解を指す

ために初期化されます。

IMSL_SUPPLY_SPARSE_LU_FACTOR, Imsl_f_sparse_lu_factor *lu_factor ( 入力 ) Imsl_f_sparse_lu_factor 型の構造体のアドレス。

IMSL_RETURN_SPARSE_LU_FACTORオプションで 

imsl_f_lin_sol_gen_coordinateによって計算された入力行列の LU 分解がこの構造体に含まれます。

IMSL_FREE_SPARSE_LU_FACTOR, 返される前に、A の LU 分解を含むリンクされたリストデータ構造体を解

放します。この因子が必要でなくなった場合のみ、このオプションを使用します。

IMSL_RETURN_SPARSE_LU_IN_COORD, Imsl_f_sparse_elem **lu_coordinate, int **row_pivots, int **col_pivots ( 出力 )LU 分解が対応座標形式で返されます。これは Imsl_f_sparse_lu でカプセル化された内部表現より簡潔です。欠点は SOLVE_ONLYの呼び

出しの間にこの因子の内部表現が再構成されなければならないことです。しかし、もしこの因子がプログラム終了後に格納され、再度、次の実行時にロードされるものであれば、IMSL_RETURN_LU_IN_COORD と IMSL_SUPPLY_LU_IN_COORD は格納や読み込みが単純な形式なの

で、これらの組み合わせは最良の選択になります。

IMSL_SUPPLY_SPARSE_LU_IN_COORD, Imsl_f_sparse_elem *lu_coordinate, int *row_pivots, int *col_pivots ( 出力 )対応座標形式で LU 分解を提供します。その説明は、

IMSL_RETURN_SPARSE_LU_IN_COORD を参照してください。

IMSL_FACTOR_ONLY,入力行列の LU 分解を計算して、返します。引数 b は無視されます。

IMSL_SOLVE_ONLY,A の LU 分解を与えて Ax = b を解きます。このオプションはオプション

引数 IMSL_SUPPLY_SPARSE_LU_FACTOR 又は

IMSL_SUPPLY_SPARSE_LU_IN_COORD を使用する必要があります。

IMSL_RETURN_USER, float x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_TRANSPOSE,

問題 ATx = b を解きます。このオプションは分解を提供する、いずれ

かのオプションと組み合わせて使用することができます。

IMSL_CONDITION, float *condition,A の L1 条件数を推定して、その変数条件を返します。

IMSL_PIVOTING_STRATEGY, Imsl_pivot method ( 入力 )以下のうちの一つの設定方法によって、枢軸選択法を選択します。IMSL_ROW_MARKOWITZ、IMSL_COLUMN_MARKOWITZ 又はIMSL_SYMMETRIC_MARKOWITZ

デフォルト: IMSL_SYMMETRIC_MARKOWITZ.

IMSL_NUM_OF_SEARCH_ROWS, int num_search_row ( 入力 )枢軸要素のために検索される非ゼロ要素の最小数を持つ行数。デフォルト: num_search_row = 3

IMSL_ITERATIVE_REFINEMENT,反復改良法が必要な場合、このオプションを選択します。

Page 62: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_DROP_TOLERANCE, float tolerance ( 入力 )可能な fill-in が許容値に対してチェックされます。この新しい要素の

絶対値が tolerance よりは小さければ、それは捨てられます。

デフォルト: tolerance = 0.0

IMSL_HYBRID_FACTORIZATION, float density, int order_bound,アクティブな小行列の密度が 0.0 ≤ density ≤ 1.0 に到達して、アク

ティブな小行列の階数が order_bound に等しいか小さい場合、この

関数を密な分解法に切り替えることを可能にします。

IMSL_STABILITY_FACTOR, float s_factor ( 入力 )枢軸要素の絶対値は s_factor によって割られる行における絶対値で

最大の要素よりは大きくなくてはいけません。

デフォルト: s_factor = 10.0

IMSL_GROWTH_FACTOR_LIMIT, float gf_limit ( 入力 )この成長因子が gf_limit を越える場合は、計算を停止します。

デフォルト: gf_limit = 1.0e16

IMSL_GROWTH_FACTOR, float *gf ( 出力 )引数 gf は、A における絶対値で最大の要素によって割られるガウス

消去法のいずれの段階でも絶対値で最大の要素として計算されます。

IMSL_SMALLEST_PIVOT, float *small_pivot ( 出力 )分解の間に生じた最小の枢軸要素の値のポインター。

IMSL_NUM_NONZEROS_IN_FACTOR, int *num_nonzeros ( 出力 )因子にある非ゼロの合計を含んだスカラーのポインター。

IMSL_CSC_FORMAT, int *col_ptr, int *row_ind, float *values ( 入力 )圧縮された疎の列 (CSC) 形式で係数行列を受け取ります。この格納枠

組みの説明は「イントロダクション」章を参照してください。

IMSL_MEMORY_BLOCKSIZE, int blocksize ( 入力 )空間が fill-in のために割り当てられなければならない場合、

blocksize 新規非ゼロ要素に対して十分な空間を割り当てます。

デフォルト: blocksize = nz

説明

関数 imsl_f_lin_sol_gen_coordinate は、A が疎である線形連立方程式 Ax = b を解きます。デフォルトの使用法では、改良された一般対称 Markowitz 枢軸選択法を使用して A の LU 分解を最初に実行することにより、いわゆる、一

回限りの問題を解きます。行交換に加えて、消去演算が右辺に拡張されるときに saxpy 演算が実行されるので、因数 L は外示的に保存されません。従っ

て、連立方程式 Ly = b は内示的に解かれます。それから、因子 U は Ux = y から解 x を計算する三角解法ルーチンに渡されます。

複数の連立方程式 Ax = b が A を変更せず解く場合、通常、分解を一回だけ計算

して、種々の右辺に対して、何回もの前進、後退解法を実行することがより効率的です。この場合に、因子 L は明示的に保存され、列と同様に全ての行の交

換が記録されます。その後,この解法のステップは、2つの三角連立方程式の Ly = b と Ux = y を解きます。ユーザはこの分解を取得するために、

IMSL_RETURN_SPARSE_LU_FACTOR 又は IMSL_RETURN_LU_IN_COORD オプショ

ンを指定して、IMSL_SOLVE_ONLY と組み合わせて

IMSL_SUPPLY_SPARSE_LU_FACTOR 又は IMSL_SUPPLY_SPARSE_LU_IN_COORDのいずれかを使用してこの分解を受け渡します。その後で、異なる右辺を持つこの関数を呼びます .IMSL_RETURN_SPARSE_LU_FACTOR を使用する場合、

imsl_lin_sol_gen_coordinate の最終呼び出しには、L と U を保存するため

に使用された記憶域を解放するために IMSL_FREE_SPARSE_LU_FACTOR を含め

なければなりません。

もし ATx = b の解が必要であれば IMSL_TRANSPOSE オプションを指定します。

このキーワードは、この解を求めるために操作 UTy = b と LTx = y が実行され

Page 63: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

るように、前進消去と後退代入を変えるためだけのものです。こうして、分解

を生成する一回の呼び出しで、Ax = b と ATx = b の両方の解を求めることがで

きます。

オプション IMSL_CONDITION は A の L1 条件数の推定値を計算して、返すため

に使用します。使用されるアルゴリズムは Higham に由来していま

す。IMSL_CONDITION の仕様は、一回限りの問題が解かれるにしても、完全 L が計算され保存されることになります。これは Higham 法が、形式 Az = r と

ATz = r の問題の解を必要とする事実によるものです。

デフォルトの枢軸交換法は、対称 Markowitz 法です。行優先、或いは、列優

先問題の場合、IMSL_ROW_MARKOWITZ 或いは IMSL_COLUMN_MARKOWITZ のい

ずれかを選ぶことによって、fill-in の低減になります。Markowitz 法は枢

軸候補の行、又は、列の予選数を検索します。デフォルトの数は 3 ですが、

IMSL_NUM_OF_SEARCH_ROWS を使用して変更することが可能です。

オプション IMSL_DROP_TOLERANCE は fill-in を減少させることができる許容値

を設定するために使用可能です。これは、指定した低下許容値よりも小さい、新しい充填要素が、分解に追加されることを防止することにより機能します。これは、本質的なエラーをこの分解に持ち込むので、最終的な解をより正確にする為に IMSL_ITERATIVE_REFINEMENT を使用する事をお勧めします。この

場合のトレードオフは、低下許容値から記憶域の大きさを節約できることと、精度改良のために必要な反復解ステップに余剰時間がかかることです。

関数 imsl_f_lin_sol_gen_coordinate は分解の間のある点で、密な分解法

に切り替えるオプションを提供しています。IMSL_HYBRID_FACTORIZATION を

選択することによって、このオプションを可能にします。このオプションによって必要な 2 つのパラメータの1つは density で、フォーマット切り替え

が生じる前に、アクティブな小行列のために最小密度を指定します。1.0 の密

度は完全な fill-in を示します。他のパラメータ order_bound は密なフォー

マットに変換されるアクティブな小行列の階数の上限を決めます。これは、密

な分解の O(n3) 資質が性能低下の原因となるときに、余りにも早くに切り替え

が発生しない様に使用されます。このオプションは顕著に堆積記憶域を増大することに注意して下さい。

例題

例題 1

1 例として、次の行列を考えてみます。

Ax = (10, 7, 45, 33, −34, 31)T となるように xT = (1, 2, 3, 4, 5, 6) とします。 A の非ゼロの数は、nz = 15 です。

#include <imsl.h>

#include <stdlib.h>main(){ Imsl_f_sparse_elem a[] = {0, 0, 10.0, 1, 1, 10.0, 1, 2, -3.0, 1, 3, -1.0, 2, 2, 15.0, 3, 0, -2.0, 3, 3, 10.0,

10 0 0 0 0 00 10 3 1 0 00 0 15 0 0 02 0 0 10 1 01 0 0 5 1 31 2 0 0 0 6

A

− −

= − −

− − − − −

Page 64: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

3, 4, -1.0, 4, 0, -1.0, 4, 3, -5.0, 4, 4, 1.0, 4, 5, -3.0, 5, 0, -1.0, 5, 1, -2.0, 5, 5, 6.0};

float b[] = {10.0, 7.0, 45.0, 33.0, -34.0, 31.0}; int n = 6; int nz = 15; float *x; x = imsl_f_lin_sol_gen_coordinate (n, nz, a, b, 0); imsl_f_write_matrix ("solution", 1, n, x, 0); free (x);}

出力結果

solution 1 2 3 4 5 6 1 2 3 4 5 6

例題 2

この例題は A = E(1000, 10) と設定します。1つの連立方程式を解いて、LU 分解が返されます。それから分解されたばかりの同じ係数行列 A を使用して 2 番

目の連立方程式を解きます。 最大の絶対誤差と実行時間比率がプリントされて、前進と後退解法が、分解と解の計算時間の約 10 パーセントであることを

示しています。この比率は係数行列の元数、非ゼロの最初の数、そして特に消去の際に生成される充填の量によって非常に変化します。時間測定の結果は、強くマシンに依存することに注意してください。

#include <imsl.h>

#include <stdlib.h>main(){ Imsl_f_sparse_elem *a; Imsl_f_sparse_lu_factor lu_factor; float *b; float *x; float *mod_five; float *mod_ten; float error_factor_solve; float error_solve; double time_factor_solve; double time_solve; int n = 1000; int c = 10; int i; int nz; int index;

/* 係数行列を取得 */

a = imsl_f_generate_test_coordinate (n, c, &nz, 0);

/* 2 つの異なる予備決定の解を設定 */

mod_five = (float*) malloc (n*sizeof(*mod_five)); mod_ten = (float*) malloc (n*sizeof(*mod_ten)); for (i=0; i<n; i++) { mod_five[i] = (float) (i % 5);

Page 65: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

mod_ten[i] = (float) (i % 10); } /* x が近似 mod_five であるように、b を選択 */

b = imsl_f_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, mod_five, 0);

/* 分解 /求解の時間を測定 */

time_factor_solve = imsl_ctime(); x = imsl_f_lin_sol_gen_coordinate (n, nz, a, b, IMSL_RETURN_SPARSE_LU_FACTOR, &lu_factor, 0); time_factor_solve = imsl_ctime() - time_factor_solve;

/* 最大絶対誤差を計算 */

error_factor_solve = imsl_f_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_five, IMSL_INF_NORM, &index, 0); free (mod_five); free (b); free (x);

/* 新しい右辺を取得 -- b = A * mod_ten */

b = imsl_f_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, mod_ten, 0);

/* Ax = b を計算するために以前に計算した分解を使用 */

time_solve = imsl_ctime(); x = imsl_f_lin_sol_gen_coordinate (n, nz, a, b, IMSL_SUPPLY_SPARSE_LU_FACTOR, &lu_factor, IMSL_SOLVE_ONLY, 0); time_solve = imsl_ctime() - time_solve; error_solve = imsl_f_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_ten, IMSL_INF_NORM, &index, 0); free (mod_ten); free (b); free (x); /* 誤差と実行時間の比率をプリント */

printf ("absolute error (factor/solve) = %e\n", error_factor_solve); printf ("absolute error (solve) = %e\n", error_solve); printf ("time_solve/time_factor_solve = %f\n", time_solve/time_factor_solve);}

出力結果

absolute error (factor/solve) = 9.179115e-05absolute error (solve) = 2.160072e-04time_solve/time_factor_solve = 0.093750

Page 66: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題 3

この例題では、線形連立方程式 Ax = b を解きます。このとき、A は、 A = E (500, 50) です。その後、同じ連立方程式を大きい低下許容値を使用して解きま

す。最後に計算したかりの分解を使用して、同じ線形連立方程式を反復改良法で解きます。測定時間結果は強くマシンに依存することに注意してください。

#include <imsl.h>

#include <stdlib.h>

main(){ Imsl_f_sparse_elem *a; Imsl_f_sparse_lu_factor lu_factor; float *b; float *x; float *mod_five; float error_zero_drop_tol; float error_nonzero_drop_tol; float error_nonzero_drop_tol_IR; double time_zero_drop_tol; double time_nonzero_drop_tol; double time_nonzero_drop_tol_IR; int nz_nonzero_drop_tol; int nz_zero_drop_tol; int n = 500; int c = 50; int i; int nz; int index;

/* 係数行列を取得 */

a = imsl_f_generate_test_coordinate (n, c, &nz, 0); for (i=0; i<nz; i++) a[i].val *= 0.05;

/* 予備決定された解を設定 */

mod_five = (float*) malloc (n*sizeof(*mod_five)); for (i=0; i<n; i++) mod_five[i] = (float) (i % 5); /* x が mod_five を近似するように b を選択 */

b = imsl_f_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, mod_five, 0);

/* 分解 /求解の時間を測定 */

time_zero_drop_tol = imsl_ctime(); x = imsl_f_lin_sol_gen_coordinate (n, nz, a, b, IMSL_NUM_NONZEROS_IN_FACTOR, &nz_zero_drop_tol, 0); time_zero_drop_tol = imsl_ctime() - time_zero_drop_tol;

/* 最大絶対誤差を計算 */

error_zero_drop_tol = imsl_f_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_five, IMSL_INF_NORM, &index, 0); free (x);

/* 低下許容値 = 0.005 で同じ問題を解く */

Page 67: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

time_nonzero_drop_tol = imsl_ctime(); x = imsl_f_lin_sol_gen_coordinate (n, nz, a, b, IMSL_RETURN_SPARSE_LU_FACTOR, &lu_factor, IMSL_DROP_TOLERANCE, 0.005, IMSL_NUM_NONZEROS_IN_FACTOR, &nz_nonzero_drop_tol, 0); time_nonzero_drop_tol = imsl_ctime() - time_nonzero_drop_tol;

/* 最大誤差を計算 */

error_nonzero_drop_tol = imsl_f_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_five, IMSL_INF_NORM, &index, 0); free (x);

/* 同じ問題を IR で解く 最後の分解を利用 */ time_nonzero_drop_tol_IR = imsl_ctime(); x = imsl_f_lin_sol_gen_coordinate (n, nz, a, b, IMSL_SUPPLY_SPARSE_LU_FACTOR, &lu_factor, IMSL_SOLVE_ONLY, IMSL_ITERATIVE_REFINEMENT, 0); time_nonzero_drop_tol_IR = imsl_ctime() - time_nonzero_drop_tol_IR;

/* 最大絶対誤差を計算 */

error_nonzero_drop_tol_IR = imsl_f_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_five, IMSL_INF_NORM, &index, 0); free (x); free (b); /* 誤差と実行時間の比率をプリント */

printf ("drop tolerance = 0.0\n"); printf ("\tabsolute error = %e\n", error_zero_drop_tol); printf ("\tfillin = %d\n\n", nz_zero_drop_tol);

printf ("drop tolerance = 0.005\n"); printf ("\tabsolute error = %e\n", error_nonzero_drop_tol); printf ("\tfillin = %d\n\n", nz_nonzero_drop_tol);

printf ("drop tolerance = 0.005 (with IR)\n"); printf ("\tabsolute error = %e\n", error_nonzero_drop_tol_IR); printf ("\tfillin = %d\n\n", nz_nonzero_drop_tol);

printf ("time_nonzero_drop_tol/time_zero_drop_tol = %f\n", time_nonzero_drop_tol/time_zero_drop_tol); printf ("time_nonzero_drop_tol_IR/time_zero_drop_tol = %f\n", time_nonzero_drop_tol_IR/time_zero_drop_tol);}

出力結果

drop tolerance = 0.0 absolute error = 3.814697e-06 fillin = 9530

drop tolerance = 0.005 absolute error = 2.699481e+00 fillin = 8656

drop tolerance = 0.005 (with IR)

Page 68: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

absolute error = 1.907349e-06 fillin = 8656

time_nonzero_drop_tol/time_zero_drop_tol = 1.086957time_nonzero_drop_tol_IR/time_zero_drop_tol = 0.840580

反復改良法が使用されないときの誤差に注目してください。そして、反復改良法は極めて時間が掛かることに注意してください。例えば、この場合には IR 解は大体、分解と同ぐらい時間が掛かります。この問題では、大きい低下許容値の低下と反復改良法の使用は、デフォルトの 2倍にあたる時間で fill-in を 10 パーセント減少することができました。 メモリーが厳しい状況下で

は、このようなトレードオフは適切な場合があります。低下許容値は、LU に大きい誤差を持ち込み、反復改良の収束を妨げるために十分な大きさを選ばなければならないことに注意してください。

lin_sol_gen_coordinate (複素数 )疎の線形連立方程式 Ax = b を解きます。オプションの引数を使用して、関連

する計算を行うことができます。これらの追加機能に含まれるものに、A のLU 分解 、LU 分解 が与えらた Ax = b の解の計算、低下許容値の設定、反復改

良法の制御などがあります。

概要

#include <imsl.h>f_complex *imsl_c_lin_sol_gen_coordinate (int n, int nz, Imsl_c_sparse_elem *a,

f_complex *b, ..., 0)double 型関数は imsl_z_lin_sol_gen_coordinateです。

必要な引数

int n ( 入力 )この行列の行数。

int nz ( 入力 )この行列内の非ゼロの数。

Imsl_c_sparse_elem *a ( 入力 )この行列の各非ゼロ入力値の位置と値を含んだ長さ nz のベクトル。

f_complex *b ( 入力 )右辺を含んだ長さ n のベクトル。

戻り値

疎の線形連立方程式 Ax = b の解 x のポインター。この空間を解放するために

free を使用します。解が計算できない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>f_complex *imsl_c_lin_sol_gen_coordinate (int n, int nz, Imsl_c_sparse_elem *a,

f_complex *b,IMSL_RETURN_SPARSE_LU_FACTOR,

Imsl_c_sparse_lu_factor *lu_factor,IMSL_SUPPLY_SPARSE_LU_FACTOR,

Imsl_c_sparse_lu_factor *lu_factor,IMSL_FREE_SPARSE_LU_FACTOR,IMSL_RETURN_SPARSE_LU_IN_COORD,

Imsl_c_sparse_elem **lu_coordinate,int **row_pivots, int **col_pivots,

IMSL_SUPPLY_SPARSE_LU_IN_COORD, Imsl_c_sparse_elem *lu_coordinate, int *row_pivots, int *col_pivots,

IMSL_FACTOR_ONLY,IMSL_SOLVE_ONLY,

Page 69: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_RETURN_USER, f_complex x[],IMSL_TRANSPOSE,IMSL_CONDITION, float *condition,IMSL_PIVOTING_STRATEGY, Imsl_pivot method,IMSL_NUM_OF_SEARCH_ROWS, int num_search_row,IMSL_ITERATIVE_REFINEMENT,IMSL_DROP_TOLERANCE, float tolerance,IMSL_HYBRID_FACTORIZATION, float density,

int order_bound,IMSL_GROWTH_FACTOR_LIMIT, float gf_limit,IMSL_GROWTH_FACTOR, float *gf,IMSL_SMALLEST_PIVOT, float *small_pivotIMSL_NUM_NONZEROS_IN_FACTOR, int *num_nonzeros,IMSL_CSC_FORMAT, int *col_ptr, int *row_ind,

f_complex *values,IMSL_MEMORY_BLOCK_SIZE, int block_size,0)

オプション引数

IMSL_RETURN_SPARSE_LU_FACTOR, Imsl_c_sparse_lu_factor *lu_factor (出力)Imsl_c_sparse_lu_factor 型の構造体のアドレス。この構造体の内部のポ

インターは imsl_c_lin_sol_gen_coordinate による LU 分解を指す

ために初期化されます。

IMSL_SUPPLY_SPARSE_LU_FACTOR, Imsl_c_sparse_lu_factor *lu_factor (入力)Imsl_c_sparse_lu_factor 型の構造体のアドレス。

IMSL_RETURN_SPARSE_LU_FACTORオプションで 

imsl_c_lin_sol_gen_coordinateによって計算された入力行列の LU 分解がこの構造体に含まれます。

IMSL_FREE_SPARSE_LU_FACTOR, 返される前に、A の LU 分解を含むリンクされたリストデータ構造体

を解放します。この因子が必要でなくなった場合のみ、このオプションを使用します。

IMSL_RETURN_SPARSE_LU_IN_COORD, Imsl_c_sparse_elem **lu_coordinate, int **row_pivots, int **col_pivots ( 出力 )LU 分解が対応座標形式で返されます。これは Imsl_c_sparse_lu でカプセル化された内部表現より簡潔です。欠点は SOLVE_ONLYの呼び

出しの間にこの因子の内部表現が再構成されなければならないことです。しかし、もしこの因子がプログラム終了後に格納され、再度、次の実行時にロードされるものであれば、IMSL_RETURN_LU_IN_COORD と IMSL_SUPPLY_LU_IN_COORD は格納や読み込みが単純な形式なの

で、これらの組み合わせは最良の選択になります。

IMSL_SUPPLY_SPARSE_LU_IN_COORD, Imsl_c_sparse_elem *lu_coordinate, int *row_pivots, int *col_pivots ( 出力 )対応座標形式で LU 分解を提供します。その説明は、

IMSL_RETURN_SPARSE_LU_IN_COORD を参照してください。

IMSL_FACTOR_ONLY,入力行列の LU 分解を計算して、返します。引数 b は無視されます。

IMSL_SOLVE_ONLY,A の LU 分解を与えて Ax = b を解きます。このオプションはオプション

引数 IMSL_SUPPLY_SPARSE_LU_FACTOR 又は

IMSL_SUPPLY_SPARSE_LU_IN_COORD を使用する必要があります。

IMSL_RETURN_USER, f_complex x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_TRANSPOSE,

問題 ATx = b を解きます。このオプションは分解を提供する、いずれ

かのオプションと組み合わせて使用することができます。

Page 70: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_CONDITION, float *condition,A の L1 条件数を推定して、その変数条件を返します。

IMSL_PIVOTING_STRATEGY, Imsl_pivot method ( 入力 )以下のうちの一つの設定方法によって、枢軸選択法を選択します。IMSL_ROW_MARKOWITZ、IMSL_COLUMN_MARKOWITZ 又はIMSL_SYMMETRIC_MARKOWITZデフォルト: IMSL_SYMMETRIC_MARKOWITZ.

IMSL_NUM_OF_SEARCH_ROWS, int num_search_row ( 入力 )枢軸要素のために検索される非ゼロ要素の最小数を持つ行数。.デフォルト: num_search_row = 3

IMSL_ITERATIVE_REFINEMENT,反復改良法が必要な場合、このオプションを選択します。

IMSL_DROP_TOLERANCE, float tolerance ( 入力 )可能な fill-in が許容値に対してチェックされます。この新しい要素の

絶対値が tolerance よりは小さければ、それは捨てられます。

デフォルト: tolerance = 0.0

IMSL_HYBRID_FACTORIZATION, float density, int order_bound,アクティブな小行列の密度が 0.0 ≤ density ≤ 1.0 に到達して、アク

ティブな小行列の階数が order_bound に等しいか小さい場合、この

関数を密な分解法に切り替えることを可能にします。

IMSL_GROWTH_FACTOR_LIMIT, float gf_limit ( 入力 )この成長因子が gf_limit を越える場合は、計算を停止します。

デフォルト: gf_limit = 1.e16

IMSL_GROWTH_FACTOR, float *gf ( 出力 )引数 gf は、A における絶対値で最大の要素によって割られるガウス

消去法のいずれの段階でも絶対値で最大の要素として計算されます。

IMSL_SMALLEST_PIVOT, float *small_pivot ( 出力 )分解の間に生じた最小の枢軸要素の値のポインター。

IMSL_NUM_NONZEROS_IN_FACTOR, int *num_nonzeros ( 出力 )因子にある非ゼロの合計を含んだスカラーのポインター。

IMSL_CSC_FORMAT, int *col_ptr, int *row_ind, f_complex *values ( 入力 )圧縮された疎の列 (CSC) 形式で係数行列を受け取ります。この格納枠

組みの説明は「イントロダクション」章を参照してください。

IMSL_FACTOR_RESIZE_INCREMENT, int increment ( 入力 )現在の割り当てが不十分な場合、因子に追加する非ゼロの数を提供します。デフォルト: increment = nz

説明

関数 imsl_c_lin_sol_gen_coordinate は、A が疎である線形連立方程式 Ax = b を解きます。デフォルトの使用法では、改良された一般対称 Markowitz 枢軸選択法を使用して A の LU 分解を最初に実行することにより、いわゆる、一

回限りの問題を解きます。行交換に加えて、消去演算が右辺に拡張されるときに saxpy 演算が実行されるので、因数 L は外示的に保存されません。従っ

て、連立方程式 Ly = b は内示的に解かれます。それから、因子 U は Ux = y から解 x を計算する三角解法ルーチンに渡されます。

複数の連立方程式 Ax = b が A を変更せず解く場合、通常、分解を一回だけ計算

して、種々の右辺に対して、何回もの前進、後退解法を実行することがより効率的です。この場合に、因子 L は明示的に保存され、列と同様に全ての行の交

換が記録されます。その後,この解法のステップは、2つの三角連立方程式の Ly = b と Ux = y を解きます。ユーザはこの分解を取得するために、

IMSL_RETURN_SPARSE_LU_FACTOR 又は IMSL_RETURN_LU_IN_COORD オプショ

ンを指定して、IMSL_SOLVE_ONLY と組み合わせて

Page 71: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_SUPPLY_SPARSE_LU_FACTOR 又は IMSL_SUPPLY_SPARSE_LU_IN_COORDのいずれかを使用してこの分解を受け渡します。その後で、異なる右辺を持つこの関数を呼びます .IMSL_RETURN_SPARSE_LU_FACTOR を使用する場合、

imsl_lin_sol_gen_coordinate の最終呼び出しには、L と U を保存するため

に使用された記憶域を解放するために IMSL_FREE_SPARSE_LU_FACTOR を含め

なければなりません。

もし ATx = b の解が必要であれば IMSL_TRANSPOSE オプションを指定します。

このキーワードは、この解を求めるために操作 UTy = b と LTx = y が実行され

るように、前進消去と後退代入を変えるためだけのものです。こうして、分解

を生成する一回の呼び出しで、Ax = b と ATx = b の両方の解を求めることがで

きます。

オプション IMSL_CONDITION は A の L1 条件数の推定値を計算して、返すため

に使用します。使用されるアルゴリズムは Higham に由来していま

す。IMSL_CONDITION の仕様は、一回限りの問題が解かれるにしても、完全 L が計算され保存されることになります。これは Higham 法が、形式 Az = r と

ATz = r の問題の解を必要とする事実によるものです。

デフォルトの枢軸交換法は、対称 Markowitz 法です。行優先、或いは、列優

先問題の場合、IMSL_ROW_MARKOWITZ 或いは IMSL_COLUMN_MARKOWITZ のい

ずれかを選ぶことによって、fill-in の低減になります。Markowitz 法は枢

軸候補の行、又は、列の予選数を検索します。デフォルトの数は 3 ですが、

IMSL_NUM_OF_SEARCH_ROWS を使用して変更することが可能です。

オプション IMSL_DROP_TOLERANCE は fill-in を減少させることができる許容値

を設定するために使用可能です。これは、指定した低下許容値よりも小さい、新しい充填要素が、分解に追加されることを防止することにより機能します。これは、本質的なエラーをこの分解に持ち込むので、最終的な解をより正確にする為に IMSL_ITERATIVE_REFINEMENT を使用する事をお勧めします。この

場合のトレードオフは、低下許容値から記憶域の大きさを節約できることと、精度改良のために必要な反復解ステップに余剰時間がかかることです。

関数 imsl_c_lin_sol_gen_coordinate は分解の間のある点で、密な分解法

に切り替えるオプションを提供しています。IMSL_HYBRID_FACTORIZATION を

選択することによって、このオプションを可能にします。このオプションによって必要な 2 つのパラメータの1つは density で、フォーマット切り替え

が生じる前に、アクティブな小行列のために最小密度を指定します。1.0 の密

度は完全な fill-in を示します。他のパラメータ order_bound は密なフォー

マットに変換されるアクティブな小行列の階数の上限を決めます。これは、密

な分解の O(n3) 資質が性能低下の原因となるときに、余りにも早くに切り替え

が発生しない様に使用されます。このオプションは顕著に堆積記憶域を増大することに注意して下さい。

例題

例題 1

1 例として、次の行列を考えてみます。

10 7 0 0 0 0 00 3 2 3 1 2 0 00 0 4 2 0 0 0

2 4 0 0 1 6 1 3 05 4 0 0 5 12 2 7 71 12 2 8 0 0 0 3 7

ii i

iA

i i ii i ii i i

+ + − − + +

= − − + − +

− + − + − + − + − + +

Page 72: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

xT = (1 + i, 2 + 2i, 3 + 3i, 4 + 4i, 5 + 5i, 6 + 6i)

なので、以下のようになります。

Ax = (3 + 17i, −19 + 5i, 6 + 18i, − 38 + 32i, −63 + 49i, −57 + 83i)T

#include <imsl.h>

#include <stdlib.h>

main(){ static Imsl_c_sparse_elem a[] = {0, 0, {10.0, 7.0}, 1, 1, {3.0, 2.0}, 1, 2, {-3.0, 0.0}, 1, 3, {-1.0, 2.0}, 2, 2, {4.0, 2.0}, 3, 0, {-2.0, -4.0}, 3, 3, {1.0, 6.0}, 3, 4, {-1.0, 3.0}, 4, 0, {-5.0, 4.0}, 4, 3, {-5.0, 0.0}, 4, 4, {12.0, 2.0}, 4, 5, {-7.0, 7.0}, 5, 0, {-1.0, 12.0}, 5, 1, {-2.0, 8.0}, 5, 5, {3.0, 7.0}};

static f_complex b[] = {{3.0, 17.0}, {-19.0, 5.0}, {6.0, 18.0}, {-38.0, 32.0}, {-63.0, 49.0}, {-57.0, 83.0}}; int n = 6; int nz = 15; f_complex *x; x = imsl_c_lin_sol_gen_coordinate (n, nz, a, b, 0); imsl_c_write_matrix ("solution", n, 1, x, 0); free (x);}

出力結果

solution1 ( 1, 1)2 ( 2, 2)3 ( 3, 3)4 ( 4, 4)5 ( 5, 5)6 ( 6, 6)

例題 2

この例題は A = E(1000, 10) と設定します。1つの連立方程式を解いて、LU 分解が返されます。それから分解されたばかりの同じ係数行列 A を使用して 2 番

目の連立方程式を解きます。 最大の絶対誤差と実行時間比率がプリントされて、前進と後退解法が、分解と解の計算時間の約 10 パーセントであることを

示しています。この比率は係数行列の元数、非ゼロの最初の数、そして特に消去の際に生成される充填の量によって非常に変化します。時間測定の結果は、強くマシンに依存することに注意してください。

#include <imsl.h>

#include <stdlib.h>main(){ Imsl_c_sparse_elem *a;

Page 73: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Imsl_c_sparse_lu_factor lu_factor; f_complex *b; f_complex *x; f_complex *mod_five; f_complex *mod_ten; float error_factor_solve; float error_solve; double time_factor_solve; double time_solve; int n = 1000; int c = 10; int i; int nz; int index;

/* 係数行列を取得 */

a = imsl_c_generate_test_coordinate (n, c, &nz, 0);

/* 2 つの異なる予備決定の解を設定 */

mod_five = (f_complex*) malloc (n*sizeof(*mod_five)); mod_ten = (f_complex*) malloc (n*sizeof(*mod_ten)); for (i=0; i<n; i++) { mod_five[i] = imsl_cf_convert ((float)(i % 5), 0.0); mod_ten[i] = imsl_cf_convert ((float)(i % 10), 0.0); } /* x が近似 mod_five であるように、b を選択 */

b = imsl_c_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, mod_five, 0);

/* 分解 /求解の時間を測定 */

time_factor_solve = imsl_ctime(); x = imsl_c_lin_sol_gen_coordinate (n, nz, a, b, IMSL_RETURN_SPARSE_LU_FACTOR, &lu_factor, 0); time_factor_solve = imsl_ctime() - time_factor_solve;

/* 最大絶対誤差を計算 */

error_factor_solve = imsl_c_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_five, IMSL_INF_NORM, &index, 0); free (b); free (x);

/* 新しい右辺を取得 -- b = A * mod_ten */

b = imsl_c_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, mod_ten, 0);

/* Ax = b を計算するために以前に計算した分解を使用 */

time_solve = imsl_ctime(); x = imsl_c_lin_sol_gen_coordinate (n, nz, a, b, IMSL_SUPPLY_SPARSE_LU_FACTOR, &lu_factor, IMSL_SOLVE_ONLY, 0);

Page 74: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

time_solve = imsl_ctime() - time_solve; error_solve = imsl_c_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_ten, IMSL_INF_NORM, &index, 0); free (b); free (x); /* 誤差と実行時間の比率をプリント */

printf ("absolute error (factor/solve) = %e\n", error_factor_solve); printf ("absolute error (solve) = %e\n", error_solve); printf ("time_solve/time_factor_solve = %f\n", time_solve/time_factor_solve);}

出力結果

absolute error (factor/solve) = 2.389053e-06absolute error (solve) = 7.656095e-06time_solve/time_factor_solve = 0.070313

lin_sol_posdef_coordinate疎実対称正定値の線形連立方程式 Ax = b を解きます。オプションの引数を使

用して、関連する計算を行うことができます。これらの追加機能には、A の記

号的分解の戻し、A の数値的分解の戻し、記号的、又は、数値的分解のいずれ

かが与えらた Ax = b の解の計算が含まれています。

概要

#include <imsl.h>

float *imsl_f_lin_sol_posdef_coordinate (int n, int nz, Imsl_f_sparse_elem *a, float *b, ..., 0)double 型関数は、 imsl_d_lin_sol_posdef_coordinateです。

必要な引数

int n ( 入力 )行列の行数。

int nz ( 入力 )行列の下三角にある非ゼロの数。

Imsl_f_sparse_elem *a ( 入力 )行列の下三角にある非ゼロ入力値の位置と値を含んだ、長さ nz のベ

クトル。

float *b ( 入力 )右辺を含んだ、長さ n のベクトル。

戻り値

疎実対称正定値の線形連立方程式 Ax = b の解 x へのポインター。この空間を開放

するために、 freeを使用します。解が計算できない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_lin_sol_posdef_coordinate (int n, int nz, Imsl_f_sparse_elem *a, float *b,IMSL_RETURN_SYMBOLIC_FACTOR,

Imsl_symbolic_factor *sym_factor,IMSL_SUPPLY_SYMBOLIC_FACTOR,

Imsl_symbolic_factor *sym_factor,IMSL_SYMBOLIC_FACTOR_ONLY,

Page 75: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_RETURN_NUMERIC_FACTOR, Imsl_f_numeric_factor *num_factor,

IMSL_SUPPLY_NUMERIC_FACTOR, Imsl_f_numeric_factor *num_factor,

IMSL_NUMERIC_FACTOR_ONLY,IMSL_SOLVE_ONLY,IMSL_MULTIFRONTAL_FACTORIZATION,IMSL_RETURN_USER, float x[],IMSL_SMALLEST_DIAGONAL_ELEMENT, float *small_element,IMSL_LARGEST_DIAGONAL_ELEMENT, float *largest_element,IMSL_NUM_NONZEROS_IN_FACTOR, int *num_nonzeros,IMSL_CSC_FORMAT, int *col_ptr, int *row_ind,

float *values,0)

オプション引数

IMSL_RETURN_SYMBOLIC_FACTOR, Imsl_symbolic_factor *sym_factor ( 出力 )返される時に、入力行列のシンボリック分解を含む、 Imsl_symbolic_factor 型の構造体のポインター。

IMSL_SUPPLY_SYMBOLIC_FACTOR, Imsl_symbolic_factor *sym_factor ( 入力 )Imsl_symbolic_factor 型の構造体のポインター。この構造体は入力行列

のシンボリック分解を含んで、IMSL_RETURN_SYMBOLIC_FACTOR オプ

ションを持つ imsl_f_lin_sol_posdef_coordinate によって計算さ

れます。

IMSL_SYMBOLIC_FACTOR_ONLY,入力行列のシンボリック分解を計算して返します。引数 b は無視され

ます。

IMSL_RETURN_NUMERIC_FACTOR, Imsl_f_numeric_factor *num_factor ( 出力 )返される時に、入力行列の数値分解を含む、 Imsl_f_numeric_factor 型の

構造体のポインター。

IMSL_SUPPLY_NUMERIC_FACTOR, Imsl_f_numeric_factor *num_factor ( 入力 )Imsl_f_numeric_factor 型 の構造体を指すポインター。この構造体は

IMSL_RETURN_NUMERIC_FACTOR オプションを持つ

imsl_f_lin_sol_posdef_coordinate によって計算された、入力行

列の数値分解を含んでいます。

IMSL_NUMERIC_FACTOR_ONLY,入力行列の数値分解を計算して返します。引数 b は無視されます。

IMSL_SOLVE_ONLY,A の数値分解又は、シンボリック分解が与えられて、Ax = b を解きま

す。このオプションは IMSL_SUPPLY_NUMERIC_FACTOR 又は

IMSL_SUPPLY_SYMBOLIC_FACTOR の使用する必要があります。

IMSL_MULTIFRONTAL_FACTORIZATION,多重正面技法を使用して数値分解を実行します。デフォルトで、標準分解が疎圧縮記憶域枠組みに基づいて計算されます。

IMSL_RETURN_USER, float x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_SMALLEST_DIAGONAL_ELEMENT, float *small_element ( 出力 )数値分解の間に発生する最小の対角要素を含んだスカラーのポインター。数値分解が imsl_f_lin_sol_posdef_coordinate の呼び出し

の間に計算される場合のみ、このオプションは有効です。

IMSL_LARGEST_DIAGONAL_ELEMENT, float *large_element ( 出力 )数値分解の間に発生する最大の対角要素を含んだスカラーのポインター。数値分解が imsl_f_lin_sol_posdef_coordinate の呼び出し

の間に計算される場合のみ、このオプションは有効です。

Page 76: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_NUM_NONZEROS_IN_FACTOR, int *num_nonzeros ( 出力 )因子にある非ゼロの合計を含んだスカラーのポインター。

IMSL_CSC_FORMAT, int *col_ptr, int *row_ind, float *values ( 入力 )圧縮された疎の列 (CSC) 形式で係数行列を受け取ります。この格納枠

組みの説明は本マニュアルの最初にある「イントロダクション」章を参照してください。

説明

関数 imsl_f_lin_sol_posdef_coordinate は疎の対称正定値係数行列 A を持つ線形代数連立方程式を解きます。この関数のデフォルトの使用法では、最初に係数行列の置換のシンボリック分解が計算されます。その後、数値分解が計算されます。線形連立方程式の解は、それからこの数値分解因子を使用して見つけることができます。

計算のシンボリック分解ステップは、最小次数順序付けの決定と、コレスキー因子L の疎のデータ構造体の設定から構成されます。このステップは疎の係数行列の

「パターン」だけを必要とします。すなわち、非ゼロ要素の位置ですが要素そのものではありません。こうして、Imsl_f_sparse_elem 構造体の val 欄は無視さ

れます。あるアプリケーションが、全て同じ疎のパターンを持つ、異なる疎の対称正定値係数行列を生成する場合は、IMSL_RETURN_SYMBOLIC_FACTOR と IMSL_SUPPLY_SYMBOLIC_FACTOR を使用することによって、シンボリック分解は

一度だけ計算する必要があります。

シンボリック因子によって提供されるように、コレスキー因子 L の疎のデータ

構造体が与えられると、数値的分解は次式のように、L に入力値を生成します。

PAPT

= LLT

この P は最小次数順序付けによって決定される置換行列です。

この数値分解は 2 方法の 1 つで実行することができます。デフォルトによっ

て、標準の分解は疎の圧縮記憶方式を基にして実行されます。この方法は George と Liu (1981 年 ) に完全に記述されています。オプションで多重前面技法

を使用することができます。この多重前面法は多くの記憶域を必要としますが、場合によってにはより高速になります。 この多重前面分解は Liu (1987 年 ) のルーチンに基づいています。この方法の詳細な説明は、Liu (1990 年) 又 Duff と Reid (1983 年、1984 年)、 Ashcraft (1987 年)、Ashcraft その他 (1987年)、Liu (1986 年、1989 年) を参照してください。

あるアプリケーションが、係数行列は同じであるが、右辺が違う幾つかの線形連立方程式を解く必要がある場合は、オプション IMSL_RETURN_NUMERIC_FACTOR と IMSL_SUPPLY_NUMERIC_FACTOR を使って

コレスキー分解因子の前計算をする事が可能です。その後,IMSL_SOLVE_ONLY オプションを使い全ての継続する連立方程式を効率良く解くことができます。

数値分解が与えられると、その解 x は次の計算によって得られます。

Ly1 = Pb

Lty2 = y1

x = Pty2

置換情報 P、は数値因子構造体で実行されます。

例題

例題 1

例題として次の 5 × 5 係数行列を考えます。

Page 77: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Ax = (55, 83, 103, 97, 82)T になるように、xT = (5, 4, 3, 2, 1) とします。 A の下三

角の非ゼロの数は nz = 10 です。下三角の疎の対応形式は次の様に与えられま

す。

この表現はユニークではないので、同等の形式は次のようになります。

#include <imsl.h>

#include <stdlib.h>main(){ Imsl_f_sparse_elem a[] = {0, 0, 10.0, 1, 1, 20.0, 2, 0, 1.0, 2, 2, 30.0, 3, 2, 4.0, 3, 3, 40.0, 4, 0, 2.0, 4, 1, 3.0, 4, 3, 5.0, 4, 4, 50.0}; float b[] = {55.0, 83.0, 103.0, 97.0, 82.0}; int n = 5; int nz = 10; float *x; x = imsl_f_lin_sol_posdef_coordinate (n, nz, a, b, 0); imsl_f_write_matrix ("solution", 1, n, x, 0); free (x);}

出力結果

solution 1 2 3 4 5 5 4 3 2 1

例題 2

この例題では、A を A = E(2500, 50) と設定します。そして連立方程式 Ax = bl を解いて、その呼び出しから生じる数値的分解を返します。そして、計算されたこの数値的分解を使用して連立方程式 Ax = b2 を解き、実行時間の比率がプリ

ントされます。この時間の測定結果は強くマシンに依存することに注意して下さい。

行 0 1 2 2 3 3 4 4 4 4列 0 1 0 2 2 3 0 1 3 4値 10 20 1 30 4 40 2 3 5 50

行 3 4 4 4 0 1 2 2 3 4列 3 0 1 3 0 1 0 2 2 4値 40 2 3 5 10 20 1 30 4 50

10 0 1 0 20 20 0 0 31 0 30 4 00 0 4 40 52 3 0 5 50

a

=

Page 78: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#include <imsl.h>

main(){ Imsl_f_sparse_elem *a; Imsl_f_numeric_factor numeric_factor; float *b_1; float *b_2; float *x_1; float *x_2; int n; int ic; int nz; double time_1; double time_2;

ic = 50; n = ic*ic;

/* 2 つの右辺を生成 */

b_1 = imsl_f_random_uniform (n*sizeof(*b_1), 0); b_2 = imsl_f_random_uniform (n*sizeof(*b_2), 0);

/* 係数行列 a を構成 */

a = imsl_f_generate_test_coordinate (n, ic, &nz, IMSL_SYMMETRIC_STORAGE, 0);

/* ここで Ax_1 = b_1 を解いて数値分解を返す */

time_1 = imsl_ctime (); x_1 = imsl_f_lin_sol_posdef_coordinate (n, nz, a, b_1, IMSL_RETURN_NUMERIC_FACTOR, &numeric_factor, 0); time_1 = imsl_ctime () - time_1;

/* ここで数値的分解が与えられて Ax_2 = b_2 を解く */

time_2 = imsl_ctime (); x_2 = imsl_f_lin_sol_posdef_coordinate (n, nz, a, b_2, IMSL_SUPPLY_NUMERIC_FACTOR, &numeric_factor, IMSL_SOLVE_ONLY, 0); time_2 = imsl_ctime () - time_2;

printf("time_2/time_1 = %lf\n", time_2/time_1);}

出力結果

time_2/time_1 = 0.037037

lin_sol_posdef_coordinate (複素数 )疎のエルミート正定値の線形連立方程式 Ax = b を解きます。オプション引数

を使用して、関連する計算を行うことができます。これらの追加機能には、A の記号的分解の戻し、A の数値的分解の戻し、シンボリック分解又は、数値分

解のいずれかが与えらた Ax = b の解の計算が含まれています。

概要

#include <imsl.h>

Page 79: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

f_complex *imsl_c_lin_sol_posdef_coordinate (int n, int nz, Imsl_c_sparse_elem *a, f_complex *b, ..., 0)

d_complex 型関数は、 imsl_z_lin_sol_posdef_coordinateです。

必要な引数

int n ( 入力 )行列の行数。

int nz ( 入力 )行列の下三角にある非ゼロの数。

Imsl_c_sparse_elem *a ( 入力 )行列の下三角にある非ゼロ入力値の位置と値を含んだ、長さ nz のベ

クトル。

f_complex *b ( 入力 )右辺を含んだ、長さ n のベクトル。

戻り値

疎のエルミート正定値線形連立方程式 Ax = b の解 x のポインター。この記憶域

を開放するためには free を使用します。解が得られない場合、NULL が返さ

れます。

オプション引数の概要

#include <imsl.h>

f_complex *imsl_c_lin_sol_posdef_coordinate (int n, int nz, Imsl_c_sparse_elem *a, f_complex *b,IMSL_RETURN_SYMBOLIC_FACTOR, Imsl_symbolic_factor *sym_factor,IMSL_SUPPLY_SYMBOLIC_FACTOR, Imsl_symbolic_factor *sym_factor,IMSL_SYMBOLIC_FACTOR_ONLY,IMSL_RETURN_NUMERIC_FACTOR, Imsl_c_numeric_factor *num_factor,IMSL_SUPPLY_NUMERIC_FACTOR, Imsl_c_numeric_factor *num_factor,IMSL_NUMERIC_FACTOR_ONLY,IMSL_SOLVE_ONLY,IMSL_MULTIFRONTAL_FACTORIZATION,IMSL_RETURN_USER, f_complex x[],IMSL_SMALLEST_DIAGONAL_ELEMENT, float *small_element,IMSL_LARGEST_DIAGONAL_ELEMENT, float *largest_element,IMSL_NUM_NONZEROS_IN_FACTOR, int *num_nonzeros,IMSL_CSC_FORMAT, int *col_ptr, int *row_ind, float *values,0)

オプション引数

IMSL_RETURN_SYMBOLIC_FACTOR, Imsl_symbolic_factor *sym_factor ( 出力 )返される時に、入力行列のシンボリック分解を含む、 Imsl_symbolic_factor 型の構造体のポインター。

IMSL_SUPPLY_SYMBOLIC_FACTOR, Imsl_symbolic_factor *sym_factor ( 入力 )Imsl_symbolic_factor 型の構造体のポインター。この構造体は入力行列

のシンボリック分解を含んで、IMSL_RETURN_SYMBOLIC_FACTOR オプ

ションを持つ imsl_c_lin_sol_posdef_coordinate によって計算さ

れます。

IMSL_SYMBOLIC_FACTOR_ONLY,入力行列のシンボリック分解を計算して返します。引数 b は無視され

ます。

Page 80: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_RETURN_NUMERIC_FACTOR, Imsl_c_numeric_factor *num_factor ( 出力 )返される時に、入力行列の数値分解を含む、 Imsl_c_numeric_factor 型の構造体のポインター。

IMSL_SUPPLY_NUMERIC_FACTOR, Imsl_c_numeric_factor *num_factor ( 入力 )IMSL_RETURN_NUMERIC_FACTOR オプションを持つ

Imsl_c_numeric_factor 型の構造体へのポインター。

imsl_c_lin_sol_posdef_coordinate によって計算された、入力行

列の数値分解を含んでいます。

IMSL_NUMERIC_FACTOR_ONLY,入力行列の数値分解を計算して返します。引数 b は無視されます。

IMSL_SOLVE_ONLY,A の数値分解又は、シンボリック分解が与えられて、Ax = b を解きま

す。このオプションは IMSL_SUPPLY_NUMERIC_FACTOR 又は

IMSL_SUPPLY_SYMBOLIC_FACTOR の使用する必要があります。

IMSL_MULTIFRONTAL_FACTORIZATION,多重正面技法を使用して数値分解を実行します。デフォルトで、標準分解が疎圧縮記憶域枠組みに基づいて計算されます。

IMSL_RETURN_USER, f_complex x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_SMALLEST_DIAGONAL_ELEMENT, float *small_element ( 出力 )数値分解の間に発生する最小の対角要素を含んだスカラーのポインター。数値分解が imsl_c_lin_sol_posdef_coordinate の呼び出し

の間に計算される場合のみ、このオプションは有効です。

IMSL_LARGEST_DIAGONAL_ELEMENT, float *large_element ( 出力 )数値分解の間に発生する最大の対角要素を含んだスカラーのポインター。数値分解が imsl_c_lin_sol_posdef_coordinate の呼び出し

の間に計算される場合のみ、このオプションは有効です。

IMSL_NUM_NONZEROS_IN_FACTOR, int *num_nonzeros ( 出力 )因子にある非ゼロの合計を含んだスカラーのポインター。

IMSL_CSC_FORMAT, int *col_ptr, int *row_ind, float *values ( 入力 )圧縮された疎の列 (CSC) 形式で係数行列を受け取ります。この格納枠

組みの説明は本マニュアルの最初にある「イントロダクション」章を参照してください。

説明

関数 imsl_c_lin_sol_posdef_coordinate は疎のエルミート正定値係数行列

A を持つ線形代数連立方程式を解きます。この関数のデフォルトの使用法で

は、最初に係数行列の置換のシンボリック分解が計算されます。その後、数値分解が計算されます。線形連立方程式の解は、それからこの数値分解因子を使用して見つけることができます。

計算のシンボリック分解ステップは、最小次数順序付けの決定と、コレスキー因子L の疎のデータ構造体の設定から構成されます。このステップは疎の係数行列の

「パターン」だけを必要とします。すなわち、非ゼロ要素の位置ですが要素そのものではありません。こうして、Imsl_c_sparse_elem 構造体の val 欄は無視さ

れます。あるアプリケーションが、全て同じ疎のパターンを持つ、異なる疎のエルミート正定値係数行列を生成する場合は、IMSL_RETURN_SYMBOLIC_FACTOR と IMSL_SUPPLY_SYMBOLIC_FACTOR を使用することによって、シンボリック分解は

一度だけ計算する必要があります。

シンボリック因子によって提供されるように、コレスキー因子 L の疎のデータ

構造体が与えられると、数値分解は次式のように、L に入力値を生成します。

PAPT = LL

T

Page 81: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

この P は最小次数順序付けによって決定される置換行列です。

この数値分解は 2 方法の 1 つで実行することができます。デフォルトによっ

て、標準の分解は疎の圧縮記憶方式を基にして実行されます。この方法は George と Liu (1981 年 ) に完全に記述されています。オプションで多重前面技法

を使用することができます。この多重前面法は多くの記憶域を必要としますが、場合によってにはより高速になります。 この多重前面分解は Liu (1987 年 ) のルーチンに基づいています。この方法の詳細な説明は、Liu (1990 年) 又 Duff と Reid (1983 年、1984 年)、 Ashcraft (1987 年)、Ashcraft その他 (1987年)、Liu (1986 年、1989 年) を参照してください。

あるアプリケーションが、係数行列は同じであるが、右辺が違う幾つかの線形連立方程式を解く必要がある場合は、オプション IMSL_RETURN_NUMERIC_FACTOR と IMSL_SUPPLY_NUMERIC_FACTOR を使って

コレスキー分解因子の前計算をする事が可能です。その後,IMSL_SOLVE_ONLY オプションを使い全ての継続する連立方程式を効率良く解くことができます。

数値分解が与えられると、その解 x は次の計算によって得られます。

Ly1 = Pb

Lty2 = y1

x = Pty2

置換情報 P、は数値因子構造体で実行されます。

例題

例題 1

簡単なデフォルトでの使用法の例題として、以下のようなエルミート正定値行列を考えます。

Ax = (−2 + 2i, 5 +15i, 36 + 28i)T になるように、xT = (1 + i, 2 + 2i, 3 + 3i) とします。 A の下三角の非ゼロの数は nz = 5 です。

#include <imsl.h>

main(){ Imsl_c_sparse_elem a[] = {0, 0, {2.0, 0.0}, 1, 1, {4.0, 0.0}, 2, 2, {10.0, 0.0}, 1, 0, {-1.0, -1.0}, 2, 1, {1.0, -2.0}}; f_complex b[] = {{-2.0, 2.0}, {5.0, 15.0}, {36.0, 28.0}}; int n = 3; int nz = 5; f_complex *x; x = imsl_c_lin_sol_posdef_coordinate (n, nz, a, b, 0); imsl_c_write_matrix ("Solution, x, of Ax = b", n, 1, x, 0); free (x);}

2 1 01 4 1 20 1 2 10

iA i i

i

− + = − − + −

Page 82: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

Solution, x, of Ax = b1 ( 1, 1)2 ( 2, 2)3 ( 3, 3)

例題 2

この例題では、A を A = E(2500, 50) と設定します。そして連立方程式 Ax = b1 を解いて、その呼び出しから生じる数値分解を返します。そして、計算されたこの数値的分解を使用して連立方程式 Ax = b2 を解き、実行時間の比率がプリ

ントされます。

#include <imsl.h>

main(){ Imsl_c_sparse_elem *a; Imsl_c_numeric_factor numeric_factor; f_complex b_1[2500]; f_complex b_2[2500]; f_complex *x_1; f_complex *x_2; int n; int ic; int nz; int i; int index; double time_1; double time_2; float *rand_vec;

ic = 50; n = ic*ic; index = 0;

/* 2 つの右辺を発生 */

rand_vec = imsl_f_random_uniform (4*n*sizeof(*rand_vec), 0); for (i=0; i<n; i++) { b_1[i].re = rand_vec[index++]; b_1[i].im = rand_vec[index++]; b_2[i].re = rand_vec[index++]; b_2[i].im = rand_vec[index++]; } /* 係数行列 a を構成 */

a = imsl_c_generate_test_coordinate (n, ic, &nz, IMSL_SYMMETRIC_STORAGE, 0);

/* ここで Ax_1 = b_1 を解いて数値分解を返す */

time_1 = imsl_ctime (); x_1 = imsl_c_lin_sol_posdef_coordinate (n, nz, a, b_1, IMSL_RETURN_NUMERIC_FACTOR, &numeric_factor, 0); time_1 = imsl_ctime () - time_1;

/* ここで数値分解が与えられて Ax_2 = b_2 を解く */

time_2 = imsl_ctime (); x_2 = imsl_c_lin_sol_posdef_coordinate (n, nz, a, b_2, IMSL_SUPPLY_NUMERIC_FACTOR, &numeric_factor, IMSL_SOLVE_ONLY, 0);

Page 83: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

time_2 = imsl_ctime () - time_2;

printf("time_2/time_1 = %lf\n", time_2/time_1);}

出力結果

time_2/time_1 = 0.096386

lin_sol_gen_min_residual再開された一般化最小残差法 (GMRES) を使用して線形連立方程式 Ax = b を解

きます。

概要

#include <imsl.h>

float *imsl_f_lin_sol_gen_min_residual (int n, void amultp (float *p, float *z), float *b, ..., 0)

double 型関数は、imsl_d_lin_sol_gen_min_residualです。

必要な引数

int n ( 入力 )行列の行数。

void amultp (float *p, float *z)z = Ap を計算するユーザ提供の関数。

float *b ( 入力 )右辺に含まれる長さ n のベクトル。

戻り値

線形連立方程式 Ax = b の解 x のポインター。この空間を解放するために free を使用します。解が得られない場合 NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_lin_sol_gen_min_residual (int n, void amultp (), float *b,IMSL_RETURN_USER, float x[],IMSL_MAX_ITER, int *maxit,IMSL_REL_ERR, float tolerance,IMSL_PRECOND, void precond(),IMSL_MAX_KRYLOV_SUBSPACE_DIM, int kdmax,IMSL_HOUSEHOLDER_REORTHOG,IMSL_FCN_W_DATA, void amultp (), void *data,IMSL_PRECOND_W_DATA, void precond(), void *data, 0)

オプション引数

IMSL_RETURN_USER, float x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_MAX_ITER, int *maxit ( 入力 / 出力 )整数のポインター。最初に許される GMRES 反復の最大数に設定しま

す。終了時に使用された反復数が返されます。デフォルト: maxit = 1000

IMSL_REL_ERR, float tolerance ( 入力 )このアルゴリズムは ||b − Ax||2 ≤ τ||b||2 のような x を生成します。ここで

τ は、τ = 許容値です。

デフォルト: tolerance = sqrt(imsl_f_machine(4))

Page 84: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_PRECOND, void precond (float *r, float *z) ( 入力 )

z = M -1r を設定するユーザ提供の関数で , M は前処理行列です。

IMSL_MAX_KRYLOV_SUBSPACE_DIM, int kdmax, ( 入力 )最大 Krylov 部分空間ディメンジョンで、それは再開される前に許さ

れる、GMRES 反復の最大許容数です。

デフォルト: kdmax = imsl_i_min(n, 20)

IMSL_HOUSEHOLDER_REORTHOG,Gram-Schmidt プロセスを置き換えて Householder 変換による直交化を

実行します。

IMSL_FCN_W_DATA, void amultp (float *p, float *z, void *data), void *data, (入力 )z = Ap を計算するユーザ提供の関数。また、ユーザにより提供された

データへのポインターも受け入れます。 data は、ユーザ提供の関数に

データを受け渡すポインターです。 詳細は、「イントロダクション」の

「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_PRECOND_W_DATA, void precond (float *r, float *z, void *data), void *data ( 入力 )

z = M -1r を設定するユーザ提供の関数で , M は前処理行列です。また、

ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータを受け渡すポインターです。 詳細は、

「イントロダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

H.F. Walker による FORTRAN サブルーチン GMRES に基づいた関数である

imsl_f_lin_sol_gen_min_residual は GMRES を使用して線形連立方程式 Ax = b を解きます。 この方法は Saad と Schultz (1986 年 ) それに Walker (1988 年 ) に詳細が説明されています。The function

GMRES 法は近似解 x0 と初期残差 r0 = b − Ax0 で始まります。反復 m での修

正 zm は次の Krylov 部分空間で決定され

κm (v) = span (v, Av, …, Am-1

v)

最小二乗問題解く ν=r0

そして反復 m で、xm = x0 + zm.

Householder 変換による直交化は Gram-Schmidt 法よりは記憶域を必要としま

せんが、時間が掛かります。しかし Walker (1988 年 ) は、特に残差減少が限

界に達するときに、Householder 法の方がより安定していることを報告してい

ます。

例題

例題 1

例題として、次の行列を考えます。

( ) ( )0

min0( ) 2mz r b A x zκ∈ − +

Page 85: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Ax = (10, 7, 45, 33, −34, 31)T. となるように xT = (1, 2, 3, 4, 5, 6) にします。関

数 imsl_f_mat_mul_rect_coordinate は積 Ax を形成するために使用します。

#include <imsl.h>

void amultp (float*, float*);

main(){ float b[] = {10.0, 7.0, 45.0, 33.0, -34.0, 31.0}; int n = 6; float *x;

x = imsl_f_lin_sol_gen_min_residual (n, amultp, b, 0);

imsl_f_write_matrix ("Solution, x, to Ax = b", 1, n, x, 0);}

void amultp (float *p, float *z){ Imsl_f_sparse_elem a[] = {0, 0, 10.0, 1, 1, 10.0, 1, 2, -3.0, 1, 3, -1.0, 2, 2, 15.0, 3, 0, -2.0, 3, 3, 10.0, 3, 4, -1.0, 4, 0, -1.0, 4, 3, -5.0, 4, 4, 1.0, 4, 5, -3.0, 5, 0, -1.0, 5, 1, -2.0, 5, 5, 6.0}; int n = 6; int nz = 15; imsl_f_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, p, IMSL_RETURN_USER_VECTOR, z, 0);}

出力結果

Solution, x, to Ax = b 1 2 3 4 5 6 1 2 3 4 5 6

例題 2

この例題では、最初の例題と同じ連立方程式を解きます。今回は前処理行列が用意されています。前処理行列は、A の対角項として選ばれます。

#include <imsl.h>

10 0 0 0 0 00 10 3 1 0 00 0 15 0 0 02 0 0 10 1 01 0 0 5 1 31 2 0 0 0 6

A

− −

= − −

− − − − −

Page 86: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

void amultp (float*, float*);void precond (float*, float*);

main(){ float b[] = {10.0, 7.0, 45.0, 33.0, -34.0, 31.0}; int n = 6; float *x; int maxit = 1000;

x = imsl_f_lin_sol_gen_min_residual (n, amultp, b, IMSL_MAX_ITER, &maxit, IMSL_PRECOND, precond, 0);

imsl_f_write_matrix ("Solution, x, to Ax = b", 1, n, x, 0); printf ("\nNumber of iterations taken = %d\n", maxit);}

/* z = Apに設定 */

void amultp (float *p, float *z){ static Imsl_f_sparse_elem a[] = {0, 0, 10.0, 1, 1, 10.0, 1, 2, -3.0, 1, 3, -1.0, 2, 2, 15.0, 3, 0, -2.0, 3, 3, 10.0, 3, 4, -1.0, 4, 0, -1.0, 4, 3, -5.0, 4, 4, 1.0, 4, 5, -3.0, 5, 0, -1.0, 5, 1, -2.0, 5, 5, 6.0}; int n = 6; int nz = 15; imsl_f_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, p, IMSL_RETURN_USER_VECTOR, z, 0);} /* Mz = rを解く */

void precond (float *r, float *z){ static float diagonal_inverse[] = {0.1, 0.1, 1.0/15.0, 0.1, 1.0, 1.0/6.0}; int n = 6; int i;

for (i=0; i<n; i++) z[i] = diagonal_inverse[i]*r[i];}

出力結果

Solution, x, to Ax = b 1 2 3 4 5 6 1 2 3 4 5 6

Number of iterations taken = 5

Page 87: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

lin_sol_def_cg共役勾配法を用いて実対称正定値連立方程式を解きます。オプション引数や、前処理演算子も使用できます。

概要

#include <imsl.h>

float *imsl_f_lin_sol_def_cg (int n, void amultp ( ), float *b, ..., 0)

double 型関数は、 imsl_d_lin_sol_def_cgです。

必要な引数

int n ( 入力 )行列の行数。

void amultp (float *p, float *z)z = Ap を計算するユーザ提供の関数。

float *b ( 入力 )右辺に含まれる長さ n のベクトル。

戻り値

線形連立方程式 Ax = b の解 x のポインター。この空間を解放するために free を使用します。解が得られない場合 NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_lin_sol_def_cg (int n, void amultp(), float *b,IMSL_RETURN_USER, float x[],IMSL_MAX_ITER, int *maxit,IMSL_REL_ERR, float relative_error,IMSL_PRECOND, void precond(),IMSL_JACOBI, float *diagonal,IMSL_FCN_W_DATA, void amultp(), void *data,IMSL_PRECOND_W_DATA, void precond(), void *data,0)

オプション引数

IMSL_RETURN_USER, float x[] ( 出力 )解 x を含んだ長さ n のユーザ割り当ての配列。

IMSL_MAX_ITER, int *maxit ( 入力 / 出力 )整数のポインター。最初に許される 反復の最大数に設定します。終了

時に使用された反復数が返されます。

IMSL_REL_ERR, float relative_error ( 入力 )望ましい相対誤差。デフォルト: relative_error = sqrt(imsl_f_machine(4))

IMSL_PRECOND, void precond (float *r, float *z) ( 入力 )

z = M -1r を設定するユーザ提供の関数で , M は前処理行列です。

IMSL_JACOBI, float diagonal[] ( 入力 )ヤコビの前処理、すなわち M = diag(A) を使用します。ユーザ提供のベ

クトル diagonal が設定されるので、 diagonal[i] = Aii になります。

IMSL_FCN_W_DATA, void amultp (float *p, float *z, void *data), void *data, (入力 )z = Ap を計算するユーザ提供の関数。また、ユーザにより提供された

データへのポインターも受け入れます。 data は、ユーザ提供の関数に

Page 88: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

データを受け渡すポインターです。 詳細は、「イントロダクション」の

「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_PRECOND_W_DATA, void precond (float *r, float *z, void *data), void *data, ( 入力 )

z = M -1r を設定するユーザ提供の関数で , M は前処理行列です。また、

ユーザによって提供されるデータへのポインタを受け入れます。 data は、ユーザ提供の関数に受け渡すデータへのポインターです。詳細は、「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_lin_sol_def_cg は、オプションの前処理を持つ共役勾配法を

使って、対称正定値連立方程式 Ax = b を解きます。 この手法は、 Golub と Van Loan (1983 年、第 10 章 )、 Hageman と Young (1981 年、第 7 章 ) で詳しく説明

されています。

前処理行列 M は、 A の近似を求める行列で、線形方程式 Mz = r が簡単に解けま

す。 これら 2 つの性質は、相反します。これらのバランスをとることが、現在の

研究トピックになっています。 imsl_f_lin_sol_def_cgのデフォルトでの使用で

は、 M = I です。 オプション IMSL_JACOBI が選択されると、 M は A の対角項です。

必要な反復回数は、行列や誤差の許容度によります。大まかには以下のようになります。

詳細は、上記の参考資料を参照してください。

M が前処理行列、 b、 p、 r、 x、 z がベクトル、 τ が望ましい相対誤差とします。使

用されるアルゴリズムは以下の通りです。

for 1n n= >>itmax

( ) ( )

( ) ( )

( )( )

( )( )

0 0

1

1

1 1

1 1

2 2

2 2

1

for 1, ,

if 1 then1

else

/

endif

/

if || || 1 || || then

recompute

if || || 1 || ||

k k

k

k k

T Tk k k k k

k k k k

k

T Tk k k k k

k k k k

k k k k

k k

k k

p xr b Ap

kz M r

k

p z

z r z r

p z p

z Ap

z z z p

x x pr r z

z x

z x

λ

β

β

β

α

αα

τ λ

λ

τ λ

− −

− −

= −=

= −=

=

===

=

= +

=

=

= += −

≤ −

≤ −

itmaxK

exit

endifendfor

Page 89: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで λ は、 λmax(G) の推定、 the largest eigenvalue of the iteration matrix 反復行列

G = I −M -1 A の最大固有値 です。停止基準は結果を基にします。 (Hageman と

Young 1981 年、148-151 ページ )

ここで

次の様に考えられます

Tn は対称の 3 重対角行列です。

µk= 1 − βk/αk-1 − 1/αk, µ1 = 1 − 1/α1

通常、固有値の計算には、数回の反復が必要です。

例題

例題 1

この例題では線形方程式の解を求めます。係数行列は、密行列として格納されます。

#include <imsl.h>

static void amultp (float*, float*);

void main(){ int n = 3; float b[] = {27.0, -78.0, 64.0}; float *x;

x = imsl_f_lin_sol_def_cg (n, amultp, b, 0);

imsl_f_write_matrix ("x", 1, n, x, 0);}

static void amultp (float *p, float *z){ static float a[] = {1.0, -3.0, 2.0,

-3.0, 10.0, -5.0, 2.0, -5.0, 6.0}; int n = 3;

imsl_f_mat_mul_rect ("A*x", IMSL_A_MATRIX, n, n, a,

( )max

11

k kM M

kM M

x x zx G xλ

− ≤ −

2 TM

x x Mx=

( ) ( ) ( )max 1 max 2 max 1T T Gλ λ λ≤ ≤ ≤ <K

1 2

2 2 3

3 3nT

µ ωω µ ω

ω µ

=

O

O O

1/k k kBω α −=

Page 90: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_X_VECTOR, n, p, IMSL_RETURN_USER, z, 0);}

出力結果

x 1 2 3 1 -4 7

例題 2

この例題では、2 つの異なる前処理演算子を用いて、線形方程式を解きます。最

初は、ヤコビの前処理を選択し、 M = diag (A) になる対角項を提供します。反復

回数と最大絶対誤差が、表示されます。次に、A 対称 3 重対角部分を含む、より

複雑な前処理行列 M を使用します。

#include <imsl.h>

static void amultp (float*, float*);static void precond (float*, float*);static Imsl_f_sparse_elem *a;static int n = 2500;static int c = 50;static int nz;

void main(){ int maxit = 1000; int i; int index; float *b; float *x; float *mod_five; float *diagonal; float norm;

n = c*c; mod_five = (float*) malloc (n*sizeof(*mod_five)); diagonal = (float*) malloc (n*sizeof(*diagonal)); b = (float*) malloc (n*sizeof(*b));

/* 係数行列を生成 */

a = imsl_f_generate_test_coordinate (n, c, &nz, 0);

/* すでに決まっている応えと対角項を設定 */

for (i=0; i<n; i++) { mod_five[i] = (float) (i % 5); diagonal[i] = 4.0; }

/* 右辺を取得 */

amultp (mod_five, b);

/* ヤコビの前処理を使用して解く */

x = imsl_f_lin_sol_def_cg (n, amultp, b, IMSL_MAX_ITER, &maxit, IMSL_JACOBI, diagonal, 0);

/* 最大絶対誤差を見つけ、結果を表示 */

Page 91: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

norm = imsl_f_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_five, IMSL_INF_NORM, &index, 0); printf ("iterations = %d, norm = %e\n", maxit, norm); free (x);

/* 同じ方程式を異なる前処理演算子を使って解く */

x = imsl_f_lin_sol_def_cg (n, amultp, b, IMSL_MAX_ITER, &maxit, IMSL_PRECOND, precond, 0);

norm = imsl_f_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_five, IMSL_INF_NORM, &index, 0); printf ("iterations = %d, norm = %e\n", maxit, norm);}

/* z = Ap に設定 */

static void amultp (float *p, float *z){ imsl_f_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, p, IMSL_RETURN_USER_VECTOR, z, 0);}

/* Mz = r を解く j*/

static void precond (float *r, float *z){ static float *m; static float *factor; static int first = 1; float *null = (float*) 0;

if (first) {

/* 1 回目の分解 */

m = imsl_f_generate_test_band (n, 1, IMSL_SYMMETRIC_STORAGE, 0); imsl_f_lin_sol_posdef_band (n, m, 1, null, IMSL_FACTOR, &factor, IMSL_FACTOR_ONLY, 0); first = 1; }

/* 解を求める */

imsl_f_lin_sol_posdef_band (n, m, 1, r, IMSL_FACTOR_USER, factor, IMSL_SOLVE_ONLY, IMSL_RETURN_USER, z, 0);}

出力結果

iterations = 115, norm = 1.382828e-05iterations = 75, norm = 7.319450e-05

Page 92: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

lin_least_squares_gen線形最小二乗問題 Ax = b を解きます。オプション引数を使用して A の QR 分解 AP = QR と、この分解に基づいた解法ステップを計算します。

概要

#include <imsl.h>

float *imsl_f_lin_least_squares_gen (int m, int n, float a[], float b[], …, 0)

double 型は、 imsl_d_lin_least_squares_genです。

必要な引数

int m ( 入力 )行列の行数。

int n ( 入力 )行列の列数。

float a[] ( 入力 )行列を含むサイズ m × n の配列。

float b[] ( 入力 )右辺を含むサイズ m の配列。

戻り値

オプションの引数が使用されなければ、関数 imsl_f_lin_least_squares_genが線形最小二乗問題 Ax = b の解 x のポイン

ターを返します。この空間を解放するために free を使用します。値が計算で

きない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_f_lin_least_squares_gen (int m, int n, float a[], float b[],

IMSL_A_COL_DIM, int a_col_dim,IMSL_RETURN_USER, float x[],IMSL_BASIS, float tol, int *kbasis,IMSL_RESIDUAL, float **p_res,IMSL_RESIDUAL_USER, float res[],IMSL_FACTOR, float **p_qraux, float **p_qr,IMSL_FACTOR_USER, float qraux[], float qr[],IMSL_FAC_COL_DIM, int qr_col_dim,IMSL_Q, float **p_q,IMSL_Q_USER, float q[],IMSL_Q_COL_DIM, int q_col_dim,IMSL_PIVOT, int pvt[],IMSL_FACTOR_ONLY,IMSL_SOLVE_ONLY,0)

オプション引数

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 a の列ディメンジョン。 デフォルト: a_col_dim = n

IMSL_RETURN_USER, float x[] ( 出力 )最小二乗解 x を含んだ長さ n のユーザ割り当ての配列。 IMSL_RETURN_USER が使用されると、関数の戻り値は、配列 xに対す

るポインターになります。

IMSL_BASIS, float tol, int *kbasis ( 入力 , 入力 / 出力 )

Page 93: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

tol: この解に含まれるための A の列のサブセットを決定するために使

用される非負の許容値。

デフォルト: tol = sqrt (imsl_amach(4))kbasis: 解の中で使用される列の数を含んだ整数。

kbasis = k if |rk+1,+1| < |tol|*|r1.1| and |ri.i|≥ tol*|r1.1| for i = 1, 2, …, k.r このオプションの詳細は 「説明」の欄を参照してください。

デフォルト: kbasis = min (m, n)

IMSL_RESIDUAL, float **p_res ( 出力 )残差ベクトル b − Ax を含んだサイズ m の配列のポインターのアドレ

ス。返される時、必要な空間はこの関数によって割り当てられます。一般に、宣言されるのは float *p_res で、引数として使用されるのは

&p_res です。

IMSL_RESIDUAL_USER, float res[] ( 出力 )残差ベクトル b − Ax を含んだ、サイズ m のユーザ割り当ての配列。

IMSL_FACTOR, float **p_qraux, float **p_qr ( 出力 )**p_qraux: 最初の min (m, n) 位置で Householder 変換のスカラー τk を含ん

だサイズn の配列のポインター qraux のアドレス。 返される時、必要な空

間はこの関数によって割り当てられます。通常、宣言されるのは float *qrauxで、引数として使用されるのは &qraux です。

**p_qr: この分解を定義する Householder 変換を含むサイズ m × n の配列のポインターのアドレス。この配列の厳密な下三角形部分は Q を構成する情報を含み、そして上三角形部分は R を構成する情報を含み

ます。返される時、必要な空間はこの関数によって割り当てられます。通常、宣言されるのは float *qr で、引数として使用されるのは &qr です。

IMSL_FACTOR_USER, float qraux[], float qr[] ( 入力 / 出力 )qraux[]: 最初の min (m, n) 位置で Householder 変換のスカラー τk を

含んだサイズ n のユーザ割り当ての配列。

qr[]: この分解を定義する Householder 変換を含むサイズ m × n のユーザ割り当ての配列。この配列の厳密な下三角形部分は Q を構成す

る情報を含み、上三角形部分は R を構成する情報を含みます。a の中

のデータが必要でなければ、別の引数 qr の代わりに a を使用して

qr は a と同じ記憶域を共有する事が出来ます。

IMSL_SOLVE が指定されると、これらのパラメータは「入力」です。

その他の場合は「出力」になります。

IMSL_FAC_COL_DIM, int qr_col_dim ( 入力 )QR 分解を含んだ配列の列ディメンジョン。

デフォルト: qr_col_dim = n

IMSL_Q, float **p_q ( 出力 )分解の直交行列を含んだ、サイズ m × m の配列のポインターのアドレ

ス。返される時、必要な空間はこの関数によって割り当てられます。 一般的に、宣言されるのは float *q で、引数として使用されるのは &q です。

IMSL_Q_USER, float q[] ( 出力 )QR 分解の直交行列 Q を含んだサイズ m × m のユーザ割り当ての配列。

IMSL_Q_COL_DIM, int q_col_dim ( 入力 )分解の Q 行列を含んだ配列の列ディメンジョン。

デフォルト: q_col_dim = m

IMSL_PIVOT, int pvt[] ( 入力 / 出力 )必要な変数順序と使用法情報を含んだサイズ n の配列。この引数

は IMSL_FACTOR_ONLY 又は IMSL_SOLVE_ONLY と共に使用されます。

Page 94: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

入力において、pvt [k − 1] > 0 であれば、A の k 列が最初の列になりま

す。pvt [k − 1] = 0 であれば、 A の列は自由列で、列枢軸交換において

交換する事が出来ます。pvt [k − 1] < 0 であれば、A の列 k は最終列に

なります。全ての列が、最初 ( 又は最終 ) 列として指定されると、枢

軸交換は実行されません。

出力において、pvt [k − 1] は列 k に交換された元の行列の標識を含み

ます。 デフォルト: pvt [k − 1] = 0, k = 1, …, n

IMSL_FACTOR_ONLYpvt と更に自由列を含む枢軸交換によって定義された置換行列 P で、

行列 AP の QR 分解だけを計算します。IMSL_FACTOR_ONLY が使用さ

れると、追加の引数 IMSL_PIVOT と IMSL_FACTOR が必要になります。

この場合には、必要な引数 b は無視されて、この関数の戻り値は NULL になります。

IMSL_SOLVE_ONLYこの関数によって、事前に計算された QR 分解が与えられて最小二乗

問題 Ax = b の解を計算します。IMSL_SOLVE_ONLY が使用されると、

引数 IMSL_FACTOR, IMSL_PIVOT と IMSL_BASIS が要求され、必要な引

数 a は無視されます。

説明

関数 imsl_f_lin_least_squares_gen は列枢軸選択法で、線形最小二乗問題 Ax = b を解きます。行列 AP の QR 分解を計算しますが、ここで P は枢軸交換

によって定義される置換行列です。そして、出力変数 kbasis に |rk+1,k+1| < |tol|*|r1,1| を満足する最小整数 k を計算します。

k = 1, …, min (m − 1, n) は、分解を計算するために使用されます。この分解は、

Q = Q1…Qmin(m-1, n) である AP = QR であるように、Qmin(m-1, n)…Q1AP = R, の形式で計算されます。各 Householder ベクトル uk 最初の k − 1 入力値にゼロを

持つので、qr の列 k の一部として格納されます。上台形行列 R は qr の最初の min (m, n) 行の上台形部の中に格納されます。最小二乗問題の解 x は、k = kbasisで線形上三角連立方程式 R(1:k, 1:k) y (1:k) = (QTb) (1:k) を解くことにより

計算されます。 この解は y(k + 1 : n) をゼロに設定して、変数を x = Py と再割り当

てして完成します。

IMSL_FACTOR_ONLY が指定されると、この関数は入力値 pvt と「自由」列間

の列枢軸選択によって定義された P で AP の QR 分解を計算します。分解に先

立って最初の列はこの配列の頭に、最終列は末尾に移動されます。最初と最後の両方の列は、この計算の間、それ以上は置き換えられず、自由列だけが移動されます。

IMSL_SOLVE_ONLY を指定すると、この関数は以前に定義された QR 分解が与

えられ Ax = b の最小二乗解を計算します。この解の中で使用される kbasis 列が存在します。ですから、この場合は,全ての列が自由であり,x はデフォ

ルトの場合で説明されるように計算します。

例題

例題 1

この例題は列枢軸交換を使用する 3 つの未知数で 4 つの線形連立方程式の最小

二乗解を説明します。この問題は 4 つのデータ値の最小二乗 2 次多項式当ては

めと同等です。多項式を p(t) = x1 + tx2 + t2x3 と書き、データの組を (ti, bi), ti = 2i, i = 1, 2, 3, 4 とします。 Ax = b の解のポインターが、関数

imsl_f_lin_least_squares_gen によって返されます。

Tk k k kQ l u u Qτ= −

Page 95: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#include <imsl.h>

float a[] = {1.0, 2.0, 4.0, 1.0, 4.0, 16.0, 1.0, 6.0, 36.0, 1.0, 8.0, 64.0};

float b[] = {4.999, 9.001, 12.999, 17.001};

main(){ int m = 4, n = 3; float *x; /* x のために Ax = b を解く */

x = imsl_f_lin_least_squares_gen (m, n, a, b, 0);

/* x をプリント */ imsl_f_write_matrix ("Solution vector", 1, n, x, 0);}

出力結果

Solution vector 1 2 30.999 2.000 0.000

例題 2

この例題は最初の例題と同じ係数行列 A を使用します。列枢軸交換法で A の QR 分解を計算します。 最終と自由列は pvt により指定され、枢軸交換は自由

列間だけで行われます。

#include <imsl.h>

float a[] = {1.0, 2.0, 4.0, 1.0, 4.0, 16.0, 1.0, 6.0, 36.0, 1.0, 8.0, 64.0};

int pvt[] = {0, 0, -1};

main(){ int m = 4, n = 3; float *x, *b; float *p_qraux, *p_qr; float *p_q; /* 部分列枢軸交換で A の */ /* QR 分解を計算 */ x = imsl_f_lin_least_squares_gen (m, n, a, b, IMSL_PIVOT, pvt, IMSL_FACTOR, &p_qraux, &p_qr, IMSL_Q, &p_q, IMSL_FACTOR_ONLY, 0);

/* Q をプリント */ imsl_f_write_matrix ("The matrix Q", m, m, p_q, 0);

/* R をプリント */ imsl_f_write_matrix ("The matrix R", m, n, p_qr, IMSL_PRINT_UPPER, 0);

/* 枢軸をプリント */ imsl_i_write_matrix ("The Pivot Sequence", 1, n, pvt, 0);

Page 96: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

}

出力結果

The matrix Q 1 2 3 41 -0.1826 -0.8165 0.5000 -0.22362 -0.3651 -0.4082 -0.5000 0.67083 -0.5477 0.0000 -0.5000 -0.67084 -0.7303 0.4082 0.5000 0.2236

The matrix R 1 2 31 -10.95 -1.83 -73.032 -0.82 16.333 8.00 The Pivot Sequence 1 2 3 2 1 3

例題 3

この例題は最初の例題の行列 A の列交換で QR 分解を計算します。これは i = 1, 2, 3 に対して、Ax = bi の最小二乗解を計算します。

#include <imsl.h>

float a[] = {1.0, 2.0, 4.0, 1.0, 4.0, 16.0, 1.0, 6.0, 36.0, 1.0, 8.0, 64.0};

float b[] = {4.999, 9.001, 12.999, 17.001, 2.0, 3.142, 5.11, 0.0, 1.34, 8.112, 3.76, 10.99};

int pvt[] = {0, 0, 0};

main(){ int m = 4, n = 3; int i, k = 3; float *p_qraux, *p_qr; float tol = 1.e-4; int *kbasis; float *x, *p_res; /* 全ての変数を自由に設定する */ /* 与えられた pvt を持つ因子 */ imsl_f_lin_least_squares_gen (m, n, a, b, IMSL_BASIS, tol, &kbasis, IMSL_PIVOT, pvt, IMSL_FACTOR, &p_qraux, &p_qr, IMSL_FACTOR_ONLY, 0); /* 幾つかの分解情報をプリント */

printf("Number of Columns in the base\n%2d", kbasis);imsl_f_write_matrix ("Upper triangular R Matrix", m, n, p_qr,

IMSL_PRINT_UPPER, 0);

imsl_i_write_matrix ("The output column order ", 1, n, pvt, 0);

/* 分解が与えられて */ /* 各 x に対して Ax = b を解く */ for ( i = 0; i < k; i++) { x = imsl_f_lin_least_squares_gen (m, n, a, &b[i*m],

Page 97: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_BASIS, tol, &kbasis, IMSL_PIVOT, pvt, IMSL_FACTOR_USER, p_qraux, p_qr, IMSL_RESIDUAL, &p_res, IMSL_SOLVE_ONLY, 0); /* 右辺 b と解 x をプリント */ imsl_f_write_matrix ("Right-hand side, b ", 1, m, &b[i*m], 0); imsl_f_write_matrix ("Solution, x ", 1, n, x, 0); /* 残差 b - Ax をプリント */ imsl_f_write_matrix ("Residual, b - Ax ", 1, m, p_res, 0); }

}

出力結果

Number of Columns in the base 3 Upper triangular R Matrix 1 2 31 -75.26 -10.63 -1.592 -2.65 -1.153 0.36 The output column order 1 2 3 3 2 1 Right-hand side, b 1 2 3 4 5 9 13 17 Solution, x 1 2 3 0.999 2.000 0.000 Residual, b - Ax 1 2 3 4 -0.0004 0.0012 -0.0012 0.0004

Right-hand side, b 1 2 3 4 2.000 3.142 5.110 0.000 Solution, x 1 2 3 -4.244 3.706 -0.391 Residual, b - Ax 1 2 3 4 0.395 -1.186 1.186 -0.395

Right-hand side, b 1 2 3 4 1.34 8.11 3.76 10.99

Solution, x 1 2 3 0.4735 0.9437 0.0286 Residual, b - Ax

Page 98: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1 2 3 4 -1.135 3.406 -3.406 1.135

重大エラー

IMSL_SINGULAR_TRI_MATRIX 入力三角行列は特異です。最初のゼロ対角

項は#です。

lin_lsq_lin_constraints線形制約付き最小二乗問題を解きます。

概要

#include <imsl.h>

float *imsl_f_lin_lsq_lin_constraints (int nra, int nca, int ncon, float a[], float b[], float c[], float bl[], float bu[], int con_type[], float xlb[], float xub[], ..., 0)

double 型関数は、imsl_d_lin_lsq_lin_constraintsです。

必要な引数

int nra ( 入力 )最小二乗方程式の数。

int nca ( 入力 )変数の数。

int ncon ( 入力 )制約の数。

float a[] ( 入力 ) nra 最小二乗方程式の係数を含む、サイズ nra × nca の配列。

float b[] ( 入力 )最小二乗方程式の右辺を含む、長さ nra の配列。

float c[] ( 入力 )ncon制約の係数を含む、サイズ ncon × nca の配列。

float bl[] ( 入力 )制約の下限値を含む、長さ ncon の配列。 i 番目の制約がない場合、 bl[i] は、参照されません。

float bu[] ( 入力 )制約の上限値を含む、長さ ncon の配列。i 番目の制約がない場合、 bu[i] は、参照されません。範囲の制約がない場合、 bl と bu は、同じ

格納領域を共有します。

int con_type[] ( 入力 )単純な範囲を除く制約の種類を示す、長さ ncon の配列。con_type[i] = 0、 1、 2、 3 が =、 <=、 >= や範囲制約を示します。

float xlb[] ( 入力 )変数上の下界を含む、長さ nca の配列。 i 番目の変数上に下界が存在し

ない場合、 xlb[i] は、 1.0e30 に設定されます。

float xub[] ( 入力 )変数上の上界を含む、長さ nca の配列。 i 番目の変数上に上界が存在し

ない場合、xub[i] は、 −1.0e30 に設定されます。

戻り値

近似解を含む、長さ nca のベクトルへのポインター。 空間を開放するには、 freeを使用します。解が計算されない場合は、 NULL が返されます。

Page 99: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数の概要

#include <imsl.h>

float *imsl_f_lin_lsq_lin_constraints (int nra, int nca, int ncon, float a[], float b[], float c[], float bl[], float bu[], int con_type[], float xlb[], float xub[],IMSL_RETURN_USER, float x[],IMSL_RESIDUAL, float **residual,IMSL_RESIDUAL_USER, float residual_user[],IMSL_PRINT,IMSL_MAX_ITER, int max_iter,IMSL_REL_FCN_TOL, float rel_tol,IMSL_ABS_FCN_TOL, float abs_tol,0)

オプション引数

IMSL_RETURN_USER, float x[] ( 出力 )長さ ncaのユーザ提供のベクトルに解を格納します。

IMSL_RESIDUAL, float **residual ( 出力 )近似解での最小二乗方程式の残差 b − Ax を含む、配列へのポインター

のアドレス。

IMSL_RESIDUAL_USER, float residual_user[] ( 出力 )長さ nra のユーザ提供のベクトルに残差を格納。

IMSL_PRINT,デバッグ出力のフラッグ。 より詳細な出力を希望する場合、このオプ

ションを選択します。

IMSL_MAX_ITER, int max_iter ( 入力 )add/drop 反復の最大数を設定します。

デフォルト: max_iter = 5*max(nra, nca)

IMSL_REL_FCN_TOL, float rel_tol ( 入力 )相対ランクの判定許容誤差。デフォルト: rel_tol = sqrt(imsl_f_machine(4))

IMSL_ABS_FCN_TOL, float abs_tol ( 入力 )絶対ランクの判定許容誤差。デフォルト: abs_tol = sqrt(imsl_f_machine(4))

説明

関数 imsl_f_lin_lsq_lin_constraints は、線形制約付最小二乗問題を解き

ます。これらが、最小二乗方程式です。

Ax ≅ b

以下が前提条件です。

bl ≤ Cx ≤ bu

xl ≤ x ≤ xu

ここで、 A は最小二乗方程式 の係数行列、b は右辺、C は制約の係数行列です。 ベクトル bl, bu, xl と xu は、変数上の下限と上限です。従属変数 y ≡ Cx を定義

し、x と y の上限と下限で最小二乗方程式を解くことにより、その方程式は解

かれます。方程式 Cx − y = 0 は、等式制約に設定されます。 これらの制約は、

重量で実現されます。すなわち、Hanson (1986 年、 826-834 ページ ) のペナル

ティ法です。

Page 100: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

例題 1

以下の方程式を最小二乗法で解きます。

3x1 + 2x2 + x3 = 3.3

4x1 +2x2 + x3 = 2.2

2x1 + 2x2 + x3 = 1.3

x1 + x2 + x3 = 1.0

以下が前提条件です。

x1 = x2 + x3 ≤ 1

0 ≤ x1 ≤ 0.5

0 ≤ x2 ≤ 0.5

0 ≤ x3 ≤ 0.5

#include <imsl.h>

main(){ int nra = 4; int nca = 3;

int ncon = 1; float *x; float a[] = {3.0, 2.0, 1.0, 4.0, 2.0, 1.0, 2.0, 2.0, 1.0, 1.0, 1.0, 1.0}; float b[] = {3.3, 2.3, 1.3, 1.0}; float c[] = {1.0, 1.0, 1.0}; float xlb[] = {0.0, 0.0, 0.0}; float xub[] = {0.5, 0.5, 0.5}; int con_type[] = {1}; float bc[] = {1.0};

x = imsl_f_lin_lsq_lin_constraints (nra, nca, ncon, a, b, c, bc, bc, con_type, xlb, xub, 0);

imsl_f_write_matrix ("Solution", 1, nca, x, 0);}

出力結果 Solution 1 2 3 0.5 0.3 0.2

例題 2

最初の例題と同じ問題を解きます。今回は、近似界での最小二乗方程式の残差が返され、残差ベクトルのノルムが表示されます。ユーザ提供の空間に解と、残差の療法が返されます。

#include <imsl.h>

main(){ int nra = 4;

Page 101: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int nca = 3; int ncon = 1; float x[3]; float residual[4]; float a[] = {3.0, 2.0, 1.0, 4.0, 2.0, 1.0, 2.0, 2.0, 1.0, 1.0, 1.0, 1.0}; float b[] = {3.3, 2.3, 1.3, 1.0}; float c[] = {1.0, 1.0, 1.0}; float xlb[] = {0.0, 0.0, 0.0}; float xub[] = {0.5, 0.5, 0.5}; int con_type[] = {1}; float bc[] = {1.0};

imsl_f_lin_lsq_lin_constraints (nra, nca, ncon, a, b, c, bc, bc, con_type, xlb, xub, IMSL_RETURN_USER, x, IMSL_RESIDUAL_USER, residual, 0);

imsl_f_write_matrix ("Solution", 1, nca, x, 0); imsl_f_write_matrix ("Residual", 1, nra, residual, 0); printf ("\n\nNorm of residual = %f\n", imsl_f_vector_norm (nra, residual, 0));}

出力結果

Solution 1 2 3 0.5 0.3 0.2 Residual 1 2 3 4 -1.0 0.5 0.5 -0.0

Norm of residual = 1.224745

lin_svd_gen実数矩形行列 A の SVD(特異値分解)A = USVT を計算します。近似の一般

化逆行列と A のランクも計算します。

概要

#include <imsl.h>

float *imsl_f_lin_svd_gen (int m, int n, float a[], …, 0)double 型関数は、 imsl_d_lin_svd_genです。

必要な引数

int m ( 入力 )行列の行数。

int n ( 入力 )行列の列数。

float a[] ( 入力 )行列を含む、サイズ m × n の配列。

Page 102: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

オプション引数を使用しない場合は、imsl_f_lin_svd_gen は、行列の順序

付けられた特異値を含む、サイズ min (m, n) の配列へのポインターが返されま

す。この空間を開放するために free を使用します。値が計算できない場合、

NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_f_lin_svd_gen (int m, int n, float a[],

IMSL_A_COL_DIM, int a_col_dim,IMSL_RETURN_USER, float s[],IMSL_RANK, float tol, int *rank,IMSL_U, float **p_u,IMSL_U_USER, float u[],IMSL_U_COL_DIM, int u_col_dim,IMSL_V, float **p_v,IMSL_V_USER, float v[],IMSL_V_COL_DIM, int v_col_dim,IMSL_INVERSE, float **p_gen_inva,IMSL_INVERSE_USER, float gen_inva[],IMSL_INV_COL_DIM, int gen_inva_col_dim,0)

オプション引数

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 a の列ディメンジョン。 デフォルト: a_col_dim = n

IMSL_RETURN_USER, float s[] ( 出力 )非増加の順番で、最初の min (m, n) 位置に A の特異値を含んだサイズ

min (m+1, n) のユーザ割り当ての配列。IMSL_RETURN_USER を使用す

ると imsl_f_lin_svd_gen の戻り値は s になります。

IMSL_RANK, float tol, int *rank ( 入力 / 出力 )tol: 特異値が無視できるかゼロで置き換えられるとき、決定するた

めに使用される許容値を含んだスカラー。 tol > 0 の場合、特異値 si i は s i.i ≤ tolであれば無視できると考えられます。 tol < 0 の場合、特

異値 si.i は si.i ≤ |tol|*||A||∝. であれば無視できると考えられます。この

場合 |tol| は相対誤差の推定値又はデータの不確定性です。

*rank:A のランクの推定値を含んだ整数。

IMSL_U, float **p_u ( 出力 )**p_u: A の左特異ベクトルを含んだサイズ m × min (m, n) の配列のポ

インターのアドレス。返されるときその必要な空間はimsl_f_lin_svd_gen によって割り当てられます。通常、float *p_u が宣言されて &p_u が引数として使用されます。

IMSL_U_USER, float u[] ( 出力 )u[]: A の左特異ベクトルを含んだサイズ m × min (m, n) のユーザ割り

当ての配列。 m ≥ n であれば、左特異ベクトルは配列 a の記憶場所を使

用して返すことができます。

IMSL_U_COL_DIM, int u_col_dim ( 入力 )左特異ベクトルを含んだ配列の列ディメンジョン。 デフォルト: u_col_dim = min (m, n)

IMSL_V, float **p_v ( 出力 )**p_v: A の右特異ベクトルを含んだサイズ n × n の配列のポインター

のアドレス。返されるとき、その必要な空間は imsl_f_lin_svd_gen によって割り当てられます。通常、 float *p_v が宣言されて &p_v が引

数として使用されます。

Page 103: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_V_USER, float v[] ( 出力 )v[]: A の右特異ベクトルを含んだサイズ n × min (m, n) のユーザ割り

当ての配列。右特異ベクトルは配列 a の記憶場所を使用して返すこと

ができます。左と右の特異ベクトルの戻り値は同時に a の記憶場所を

使用できないことに注意してください。

IMSL_V_COL_DIM, int v_col_dim ( 入力 )右特異ベクトルを含んだ配列の列ディメンジョン。 デフォルト: v_col_dim = n

IMSL_INVERSE, float **p_gen_inva ( 出力 )A の一般化された逆行列を含むサイズ n × m の配列のポインターのア

ドレス。返されるとき、その必要な空間は imsl_f_lin_svd_gen によって割り当てられます。一般的に float *p_gen_inva が宣言されて、

&p_gen_inva が引数として使用されます。

IMSL_INVERSE_USER, float gen_inva[] ( 出力 )A の一般化された逆行列を含んだサイズ n × m のユーザ割り当ての配

列。

IMSL_INV_COL_DIM, int gen_inva_col_dim ( 入力 )行列 A の一般化された逆行列ベクトルを含んだ配列の列ディメン

ジョン。デフォルト: gen_inva_col_dim = m

説明

関数 imsl_f_lin_svd_gen は実数行列 A の特異値分解を計算します。それは

最初に前と後に掛け合わせるハウスホルダー変換によって行列 A を二重対角

行列 B に縮約します。それから B の特異値分解が、陰型推移 QR アルゴリズ

ムを使用して計算されます。 行列 A のランクの推定値は sk,k ≤ tol 或いは sk,k ≤ |tol|*||A||∝ などの最小整数 k を見つけることによって得られます。 si+1,i+1 ≤ si,i, であるので、全ての si,i は、 i = k, …, min (m, n) − 1 に対して同じ不等号を

満足します。そのランクは値 k − 1 に設定されます。 A = USVT であればその一

般化された逆行列は A+ = VS+ UT になります。ここで

無視できない特異値だけが逆数にされます。IMSL_INVERSE 又は

IMSL_INVERSE_USER が指定されると、この関数は最初に行列 A の特異値分解

を計算します。一般化された逆行列はそれから計算されます。関数 imsl_f_lin_svd_gen は QR アルゴリズムが各特異値を分離します。 30 回の反

復の後に収束しない場合、失敗します。

例題

例題 1

この例題では 6 × 4 の実数行列の特異値を計算します。

#include <imsl.h>

float a[] = {1.0, 2.0, 1.0, 4.0, 3.0, 2.0, 1.0, 3.0, 4.0, 3.0, 1.0, 4.0, 2.0, 1.0, 3.0, 1.0, 1.0, 5.0, 2.0, 2.0, 1.0, 2.0, 2.0, 3.0};

main(){ int m = 6, n = 4; float *s;

( )1 11,1 ,, , ,0, ,0i iS diag s s+ − −= K K

Page 104: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* 特異値を計算 */ s = imsl_f_lin_svd_gen (m, n, a, 0); /* 特異値をプリント */ imsl_f_write_matrix ("Singular values", 1, n, s, 0);}

出力結果

Singular values 1 2 3 411.49 3.27 2.65 2.09

例題 2

この例題は 6 × 4 の実数 行列 A の特異値を計算します。この特異値はユーザ

提供の配列に返されます。行列 U と V は関数 imsl_f_lin_svd_gen によって

提供される記憶域に返されます。

#include <imsl.h>

float a[] = {1.0, 2.0, 1.0, 4.0, 3.0, 2.0, 1.0, 3.0, 4.0, 3.0, 1.0, 4.0, 2.0, 1.0, 3.0, 1.0, 1.0, 5.0, 2.0, 2.0, 1.0, 2.0, 2.0, 3.0};

main(){ int m = 6, n = 4; float s[4], *p_u, *p_v; /* SVD を計算 */ imsl_f_lin_svd_gen (m, n, a, IMSL_RETURN_USER, s, IMSL_U, &p_u, IMSL_V, &p_v, 0); /* 分解をプリント */

imsl_f_write_matrix ("Singular values, S", 1, n, s, 0); imsl_f_write_matrix ("Left singular vectors, U", m, n, p_u, 0); imsl_f_write_matrix ("Right singular vectors, V", n, n, p_v, 0);}

出力結果

Singular values, S 1 2 3 4 11.49 3.27 2.65 2.09 Left singular vectors, U 1 2 3 41 -0.3805 0.1197 0.4391 -0.56542 -0.4038 0.3451 -0.0566 0.21483 -0.5451 0.4293 0.0514 0.43214 -0.2648 -0.0683 -0.8839 -0.21535 -0.4463 -0.8168 0.1419 0.32136 -0.3546 -0.1021 -0.0043 -0.5458 Right singular vectors, V 1 2 3 41 -0.4443 0.5555 -0.4354 0.55182 -0.5581 -0.6543 0.2775 0.42833 -0.3244 -0.3514 -0.7321 -0.48514 -0.6212 0.3739 0.4444 -0.5261

Page 105: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題 3

この例題は 3 × 2 の実数行列 A のランクと一般化逆行列を計算します。この

ランクと 2 × 3 の一般化逆行列 A + がプリントされます。

#include <imsl.h>

float a[] = {1.0, 0.0, 1.0, 1.0, 100.0, -50.0};

main(){ int m = 3, n = 2; float tol; float gen_inva[6]; float *s; int *rank; /* 一般化逆行列を計算 */ tol = 1.e-4; s = imsl_f_lin_svd_gen (m, n, a, IMSL_RANK, tol, &rank, IMSL_INVERSE_USER, gen_inva, IMSL_INV_COL_DIM, m, 0); /* ランク、特異値、 */ /* 一般化された逆行列をプリント */

printf ("Rank of matrix = %2d", rank);

imsl_f_write_matrix ("Singular values", 1, n, s, 0);

imsl_f_write_matrix ("Generalized inverse", n, m, gen_inva, IMSL_A_COL_DIM, m, 0);}

出力結果

Rank of matrix = 2 Singular values 1 2 111.8 1.4 Generalized inverse 1 2 31 0.100 0.300 0.0062 0.200 0.600 -0.008

警告エラー

IMSL_SLOWCONVERGENT_MATRIX 30 回の反復の後で収束に達しませんでした。

lin_svd_gen (複素数 )複素数矩形行列 A の SVD(特異値分解)A = USVH を計算します。近似の一

般化逆行列と A のランクも計算します。

概要

#include <imsl.h>

f_complex *imsl_c_lin_svd_gen (int m, int n, f_complex a[], …, 0)d_complex 型関数は、 imsl_z_lin_svd_genです。

Page 106: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

int m ( 入力 )行列の行数。

int n ( 入力 )行列の列数。

f_complex a[] ( 入力 )行列を含むサイズ m × n の配列。

戻り値

オプション引数を使用しない場合は、imsl_c_lin_svd_gen 行列の順序付け

られた特異値を含んだサイズ min (m, n) の配列のポインターが返されます。こ

の空間を開放するために free を使用します。値が計算できない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>f_complex *imsl_c_lin_svd_gen (int m, int n, f_complex a[],

IMSL_A_COL_DIM, int a_col_dim,IMSL_RETURN_USER, f_complex s[],IMSL_RANK, float tol, int *rank,IMSL_U, f_complex **p_u,IMSL_U_USER, f_complex u[],IMSL_U_COL_DIM, int u_col_dim,IMSL_V, f_complex **p_v,IMSL_V_USER, f_complex v[],IMSL_V_COL_DIM, int v_col_dim,IMSL_INVERSE, f_complex **p_gen_inva,IMSL_INVERSE_USER, f_complex gen_inva[],IMSL_INV_COL_DIM, int gen_inva_col_dim,0)

オプション引数

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 a の列ディメンジョン。 デフォルト: a_col_dim = n

IMSL_RETURN_USER, f_complex s[] ( 出力 )非増加の順番で、最初の min (m, n) 位置に A の特異値を含んだ長さ min (m, n) のユーザ割り当ての配列。IMSL_RETURN_USER を使用すると

imsl_c_lin_svd_gen の戻り値は s になります。

IMSL_RANK, float tol, int *rank ( 入力 / 出力 )tol: 特異値が無視できるかゼロで置き換えられるとき、決定するた

めに使用される許容値を含んだスカラー。 tol > 0 の場合、特異値 si i は s i.i ≤ tolであれば無視できると考えられます。 tol < 0 の場合、特

異値 si.i は si.i ≤ |tol|*||A||∝. であれば無視できると考えられます。この

場合 |tol| は相対誤差の推定値又はデータの不確定性です。

*rank:A のランクの推定値を含んだ整数。

IMSL_U, f_complex **p_u ( 出力 ) A の左特異ベクトルを含んだサイズ m × min (m, n) の配列のポイン

ターのアドレス。返されるときその必要な空間はimsl_c_lin_svd_gen によって割り当てられます。通常、f_complex *p_u が宣言されて &p_u が引数として使用されます。

IMSL_U_USER, f_complex u[] ( 出力 ) A の左特異ベクトルを含んだサイズ m × min (m, n) のユーザ割り当て

の配列。 m ≥ n であれば、左特異ベクトルは配列 a の記憶場所を使用し

て返すことができます。

Page 107: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_U_COL_DIM, int u_col_dim ( 入力 )左特異ベクトルを含んだ配列の列ディメンジョン。 デフォルト: u_col_dim = min (m, n)

IMSL_V, f_complex **p_v ( 出力 ) A の右特異ベクトルを含んだサイズ n × n の配列のポインターのアド

レス。返されるとき、その必要な空間は imsl_c_lin_svd_gen によっ

て割り当てられます。通常、 f_complex *p_v が宣言されて &p_v が引

数として使用されます。

IMSL_V_USER, f_complex v[] ( 出力 )A の右特異ベクトルを含んだサイズ n × n の配列へのポインターのアド

レス。右特異ベクトルは配列 a の記憶場所を使用して返すことができ

ます。左と右の特異ベクトルの戻り値は同時に a の記憶場所を使用で

きないことに注意してください。

IMSL_V_COL_DIM, int v_col_dim ( 入力 )右特異ベクトルを含んだ配列の列ディメンジョン。

デフォルト: v_col_dim = n

IMSL_INVERSE, f_complex **p_gen_inva ( 出力 )A の一般化逆行列を含むサイズ n × m の配列へのポインターのアドレ

ス。返されるとき、その必要な空間は imsl_c_lin_svd_gen によって

割り当てられます。通常、 f_complex *p_gen_inva が宣言されて、

&p_gen_inva が引数として使用されます。

IMSL_INVERSE_USER, f_complex gen_inva[] ( 出力 )A の一般化された逆行列を含んだサイズ n × m のユーザ割り当ての配

列。

IMSL_INV_COL_DIM, int gen_inva_col_dim ( 入力 )行列 A の一般化された逆行列ベクトルを含んだ配列の列ディメン

ジョン。デフォルト: gen_inva_col_dim = m

説明

関数 imsl_c_lin_svd_gen は複素数行列 A の特異値分解を計算します。それ

は最初に前と後に掛け合わせるハウスホルダー変換によって行列 A を二重対

角行列 B に縮約します。それから B の特異値分解が、陰型推移 QR アルゴリ

ズムを使用して計算されます。 行列 A のランクの推定値は sk,k ≤ tol 或いは sk,k ≤ |tol|*||A||∝ などの最小整数 k を見つけることによって得られます。 si+1, ≤ si,i, であるので、全ての si,i は、 i = k, …, min (m, n) − 1 に対して同じ不等

号を満足します。そのランクは値 k − 1 に設定されます。A = USVH であればそ

の一般化された逆行列は A+ = VS+ UT になります。ここで

無視できない特異値だけが逆数にされます。IMSL_INVERSE 又は

IMSL_INVERSE_USER が指定されると、この関数は最初に行列 A の特異値分解

を計算します。一般化逆行列はそれから計算されます。関数 imsl_c_lin_svd_gen は QR アルゴリズムが各特異値を分離します。 30 回の反

復の後に収束しない場合、失敗します。

例題

例題 1

この例題は実数 6 × 3 の行列の特異値を計算します。

#include <imsl.h> main(){

( )1 11,1 ,diag , , ,0, ,0i iS s s+ − −= K K

Page 108: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int m = 6, n = 3; f_complex *s; f_complex a[] = {{1.0, 2.0}, {3.0, 2.0}, {1.0,-4.0}, {3.0,-2.0}, {2.0,-4.0}, {1.0, 3.0}, {4.0, 3.0}, {-2.0,1.0}, {1.0, 4.0}, {2.0,-1.0}, {3.0, 0.0}, {3.0,-1.0}, {1.0,-5.0}, {2.0,-5.0}, {2.0, 2.0}, {1.0, 2.0}, {4.0,-2.0}, {2.0,-3.0}}; /* 特異値を計算 */ s = imsl_c_lin_svd_gen (m, n, a, 0); /* 特異値をプリント */ imsl_c_write_matrix ("Singular values", 1, n, s, 0);}

出力結果

Singular values 1 2 3( 11.77, 0.00) ( 9.30, 0.00) ( 4.99, 0.00)

例題 2

この例題は 6 × 3 の複素数行列 A の特異値を計算します。この特異値はユー

ザ提供の配列に返されます。行列 U と V は関数 imsl_c_lin_svd_gen によっ

て提供される記憶域に返されます。

#include <imsl.h>

main(){ int m = 6, n = 3; f_complex s[3], *p_u, *p_v; f_complex a[] = {{1.0, 2.0}, {3.0, 2.0}, {1.0,-4.0}, {3.0,-2.0}, {2.0,-4.0}, {1.0, 3.0},

{4.0, 3.0}, {-2.0,1.0}, {1.0, 4.0}, {2.0,-1.0}, {3.0, 0.0}, {3.0,-1.0}, {1.0,-5.0}, {2.0,-5.0}, {2.0, 2.0}, {1.0, 2.0}, {4.0,-2.0}, {2.0,-3.0}}; /* aの SVD を計算 */ imsl_c_lin_svd_gen (m, n, a, IMSL_RETURN_USER, s, IMSL_U, &p_u, IMSL_V, &p_v, 0); /* 分解因子をプリント */ imsl_c_write_matrix ("Singular values, S", 1, n, s, 0); imsl_c_write_matrix ("Left singular vectors, U", m, n, p_u, 0); imsl_c_write_matrix ("Right singular vectors, V", n, n, p_v, 0); }

出力結果

Singular values, S 1 2 3( 11.77, 0.00) ( 9.30, 0.00) ( 4.99, 0.00) Left singular vectors, U 1 2 31 ( 0.1968, 0.2186) ( 0.5011, 0.0217) ( -0.2007, -0.1003)2 ( 0.3443, -0.3542) ( -0.2933, 0.0248) ( 0.1155, -0.2338)3 ( 0.1457, 0.2307) ( -0.5424, 0.1381) ( -0.4361, -0.4407)4 ( 0.3016, -0.0844) ( 0.2157, 0.2659) ( -0.0523, -0.0894)5 ( 0.2283, -0.6008) ( -0.1325, 0.1433) ( 0.3152, -0.0090)6 ( 0.2876, -0.0350) ( 0.4377, -0.0400) ( 0.0458, -0.6205) Right singular vectors, V 1 2 3

Page 109: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1 ( 0.6616, 0.0000) ( -0.2651, 0.0000) ( -0.7014, 0.0000)2 ( 0.7355, 0.0379) ( 0.3850, -0.0707) ( 0.5482, 0.0624)3 ( 0.0507, -0.1317) ( 0.1724, 0.8642) ( -0.0173, -0.4509)

例題 3

この例題は 6 × 4 の行列 A のランクと一般化逆行列を計算します。このラン

クと 4 × 6 一般化逆行列 A+ がプリントされます。

#include <imsl.h>main(){ int m = 6, n = 4; int *rank; float tol; f_complex gen_inv[24], *s; f_complex a[] = {{1.0, 2.0}, {3.0, 2.0}, {1.0,-4.0}, {1.0,0.0}, {3.0,-2.0}, {2.0,-4.0}, {1.0, 3.0}, {0.0,1.0}, {4.0, 3.0}, {-2.0,1.0}, {1.0, 4.0}, {0.0,0.0}, {2.0,-1.0}, {3.0, 0.0}, {3.0,-1.0}, {2.0,1.0}, {1.0,-5.0}, {2.0,-5.0}, {2.0, 2.0}, {1.0,3.1}, {1.0, 2.0}, {4.0,-2.0}, {2.0,-3.0}, {1.4,1.9}}; /* 因子 a */ tol = 1.e-4; s = imsl_c_lin_svd_gen (m, n, a, IMSL_RANK, tol, &rank, IMSL_INVERSE_USER, gen_inv, IMSL_INV_COL_DIM, m, 0); /* ランク、特異値、 */ /* 一般化逆行列をプリント */

printf ("Rank = %2d", rank);

imsl_c_write_matrix ("Singular values", 1, n, s, 0);

imsl_c_write_matrix ("Generalized inverse", n, m, gen_inv, IMSL_A_COL_DIM, m, 0);}

出力結果

Rank = 4 Singular values 1 2 3( 12.13, 0.00) ( 9.53, 0.00) ( 5.67, 0.00) 4( 1.74, 0.00) Generalized inverse 1 2 31 ( 0.0266, 0.0164) ( -0.0185, 0.0453) ( 0.0720, 0.0700)2 ( 0.0061, 0.0280) ( 0.0820, -0.1156) ( -0.0410, -0.0242)3 ( -0.0019, -0.0572) ( 0.1174, 0.0812) ( 0.0499, 0.0463)4 ( 0.0380, 0.0298) ( -0.0758, -0.2158) ( 0.0356, -0.0557) 4 5 61 ( -0.0220, -0.0428) ( -0.0003, -0.0709) ( 0.0254, 0.1050)2 ( 0.0959, 0.0885) ( -0.0187, 0.0287) ( -0.0218, -0.1109)3 ( -0.0234, 0.1033) ( -0.0769, 0.0103) ( 0.0810, -0.1074)4 ( 0.2918, -0.0763) ( 0.0881, 0.2070) ( -0.1531, 0.0814)

警告エラー

IMSL_SLOWCONVERGENT_MATRIX 30回の反復の後で収束に達しませんでし

た。

Page 110: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

lin_sol_nonnegdef実対称非負定値線形連立方程式 Ax = b を解きます。オプションを使用して

A = RTR = LLT のように行列 A のコレスキー分解を計算します。コレスキー因

子が与えられて Ax = b の解を計算します。

概要

#include <imsl.h>

float *imsl_f_lin_sol_nonnegdef (int n, float a[], float b[], …, 0) double 型の関数は、 is imsl_d_lin_sol_nonnegdefです。

必要な引数

int n ( 入力 )行列の行数と列数。

float a[] ( 入力 )行列を含んだサイズ n × n の配列。

float b[] ( 入力 )右辺を含んだサイズ n の配列。

戻り値

必要な引数を使用して、 imsl_f_lin_sol_nonnegdef は連立線形方程式の解

のポインターを返します。この空間を開放するために、free を使用します。

値が計算されない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_f_lin_sol_nonnegdef (int n, float a[], float b[],

IMSL_RETURN_USER, float x[],IMSL_A_COL_DIM, int a_col_dim,IMSL_FACTOR, float **p_factor,IMSL_FACTOR_USER, float factor[],IMSL_FAC_COL_DIM, int fac_col_dim,IMSL_INVERSE, float **p_inva,IMSL_INVERSE_USER, float inva[],IMSL_INV_COL_DIM, int inv_col_dim,IMSL_TOLERANCE, float tol,IMSL_FACTOR_ONLY,IMSL_SOLVE_ONLY,IMSL_INVERSE_ONLY,0)

オプション引数

IMSL_RETURN_USER, float x[] ( 出力 )解 x を含む、長さ n のユーザ割り当ての配列。このオプションが指定

されると、解のための格納領域は割り当てられず、 imsl_f_lin_sol_nonnegdef は、 xへのポインターを返します。.

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 a の列ディメンジョン。

デフォルト: a_col_dim = n

IMSL_FACTOR, float **p_factor ( 出力 )

A の LLT 分解を含んだサイズ n × n の配列のポインターのアドレス。

このオプションが指定されると因子行列の記憶域は imsl_f_lin_sol_nonnegdef によって割り当てられます。この因子行

列の下三角部分は L を含み、上三角部分は LTR を含みます。通常、

float *p_factor が宣言されて、&p_factor が引数として使用されま

す。

Page 111: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_FACTOR_USER, float factor[] ( 入力 / 出力 )

A の LLT 分解を含んだサイズ n × n のユーザ割り当ての配列。factor

の下三角部分は L を含み、上三角部分は LT を含みます。a が必要でな

ければ、 a と factorは同じ記憶域位置にすることができます。

IMSL_SOLVE が指定されると、これらのパラメータは「入力」です。

その他の場合は「出力」になります。

IMSL_FAC_COL_DIM, int fac_col_dim ( 入力 )

LLT 分解を含んだ配列の列ディメンジョン。

デフォルト: fac_col_dim = n

IMSL_INVERSE, float **p_inva ( 出力 )A の 逆行列を含んだサイズ n × n の配列のポインターのアドレス。こ

の配列の空間は imsl_f_lin_sol_nonnegdef によって割り当てられ

ます。通常、float *p_factor が宣言されて、&p_factor が引数とし

て使用されます。

IMSL_INVERSE_USER, float inva[] ( 出力 )A の逆行列を含んだサイズ n × n のユーザ割り当ての配列。a が必要で

なければ、 a と factor は同じ記憶域位置にすることができます。A の記憶位置は、同時に A の分解と逆行列にはなりません。

IMSL_INV_COL_DIM, int inva_col_dim ( 入力 )A の逆行列を含んだ配列の列ディメンジョン。

デフォルト: inva_col_dim = n

IMSL_TOLERANCE, float tol ( 入力 )線形依存性の決定に使用される許容値。デフォルト: tol = 100* imsl_f_machine(4)第 12 章「ユーティリティ」内 imsl_f_machine も参照してください。

IMSL_FACTOR_ONLY

A の LLT 分解のみを計算します。引数 b は無視されます。オプション

引数 IMSL_FACTOR 又は、 IMSL_FACTOR_USER が必要です。

IMSL_SOLVE_ONLYこの関数で計算された分解を使って、Ax = b を解きます。オプション

引数 a は、無視されます。IMSL_FACTOR_USERが必要です。

IMSL_INVERSE_ONLYA の逆行列だけを計算します。引数 b は無視されて、どちらかのオ

プションの引数 IMSL_INVERSE 又は IMSL_INVERSE_USER が必要で

す。

説明

関数 imsl_f_lin_sol_nonnegdef は対称非負定値(準正定値)係数行列を持

つ線形代数連立方程式を解きます。これは最初に係数行列 A のコレスキー分解

(LLT 又は RTR)を計算します。

この分解アルゴリズムは、Healy (1968 年 ) の成果に基づき、列毎に逐次進展

します。次項が成立すれば、 i 番目の列は、最初の i − 1 列に線形依存すると宣

言されます。

この ε(tol で指定される) はユーザによって設定されます。線形依存性が宣

言されると、 ( L の列の ) R の i 番目の列の全要素はゼロにセットされます。

Farebrother と Berry (1974 年 ) 、それに Barrett と Healy (1978 年 ) によって非負

定値ではない行列をチェックする為の修正が統合されました。関数

12

1

i

ii ji iij

a r aε−

=

− ≤∑

Page 112: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

imsl_f_lin_sol_nonnegdef は A が非負定値にならないことを宣言して、次

のいずれかの条件を満足するとエラー・メッセージを出します。

Healy (1968年) のアルゴリズムと関数 imsl_f_lin_sol_nonnegdef は行列 A と R が、同じ記憶域を占有することを許可します。この注意に対して、Barrett と Healy (1978 年 ) はこの事実を否定しています。関数 imsl_f_lin_sol_nonnegdef はこの問題を補完するために、上の条件 2 の aii のために次項を使用します。

行列 A の逆行列が要求されて、この行列が(数値的に)正定値でなければ、計

算される逆行列は A の対称 g2 逆行列になります。行列 A の対称 g2 逆行列であ

る行列 G に対しては、G は次の Moore-Penrose 逆行列の条件 1 と 2 を満足しな

くてはなりません。一般には条件 3 と 4 は失敗します。A の Moore-Penrose 逆行列になる G の 4 つの条件は次の通りです。

1. AGA = A2. GAG = G

3. AG は対称

4. GA は対称

線形連立方程式 Ax = b の解は、2 つの連続する三角線形連立方程式として線形

連立方程式の分解バージョン RTRx = b を解くことによって計算されます。 三角

線形連立方程式を解くことにおいて、R の行の要素が全てゼロである場合、解

ベクトルの対応する要素はゼロにセットされます。このアルゴリズムの詳細な説明は、Sallas と Lionti (1988 年 ) の第 2 節を参照してください。

例題

例題 1

4つの線形連立方程式の解が得られる。Maindonald (1984年、 83 −86ページと104− 105ページ ) はこの問題の分解と解の計算を説明します。

#include <imsl.h>

main(){ int n = 4; float *x; float a[] = {36.0, 12.0, 30.0, 6.0, 12.0, 20.0, 2.0, 10.0, 30.0, 2.0, 29.0, 1.0, 6.0, 10.0, 1.0, 14.0}; float b[] = {18.0, 22.0, 7.0, 20.0};

/* Ax = b を x について解く */ x = imsl_f_lin_sol_nonnegdef(n, a, b, 0); /* Ax =b の解、x をプリント */ imsl_f_write_matrix("Solution, x", 1, n, x, 0);}

1 21

1

1

1.

2. 0 and ,

iii ji iij

i

ii ik ji jk ii kkj

a r a

r a r r a a k i

ε

ε

=

=

− < −

= − > >

1 21

iijj

r−

=∑

Page 113: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

Solution, x 1 2 3 40.167 0.500 0.000 1.000

例題 2

最初の例題の対称非負定値行列が、最初の lin_sol_nonnegdef の呼び出しで

分解を計算するだけに使用されます。この因子に必要な記憶域はユーザによっ

て提供されます。2 番目の呼び出しで、LLT 分解と最初の例題の右辺ベクトル

が、解 x を計算する入力として使用されます。これは解配列 x を得る別の方法

を説明しています。

#include <imsl.h>

main(){ int n = 4, a_col_dim = 6; float factor[36], x[5]; float a[] = {36.0, 12.0, 30.0, 6.0, 12.0, 20.0, 2.0, 10.0, 30.0, 2.0, 29.0, 1.0, 6.0, 10.0, 1.0, 14.0}; float b[] = {18.0, 22.0, 7.0, 20.0}; /* A を分解 */ imsl_f_lin_sol_nonnegdef(n, a, b, IMSL_FACTOR_USER, factor, IMSL_FAC_COL_DIM, a_col_dim, IMSL_FACTOR_ONLY, 0); /* この場合は NULL が返されます */ /* 分解を得る他の方法は */ /* IMSL_FACTOR オプション を使用 */ imsl_f_write_matrix("factor", n, n, factor, IMSL_A_COL_DIM, a_col_dim, 0); /* 分解した行列を使用して */ /* 解を取得 */ imsl_f_lin_sol_nonnegdef(n, a, b, IMSL_FACTOR_USER, factor, IMSL_FAC_COL_DIM, a_col_dim, IMSL_RETURN_USER, x, , 0); imsl_f_write_matrix("Solution, x, of Ax = b", 1, n, x, 0);}

出力結果

factor 1 2 3 41 6 2 5 12 2 4 -2 23 5 -2 0 04 1 2 0 3 Solution, x, of Ax = b 1 2 3 4 0.167 0.500 0.000 1.000

例題 3

この例題は最初の例題の、対称非負行列の対称 g 逆行列を計算するために、IMSL_INVERSE オプションを使用します。Maindonald (1984 年、106 ページ ) はこの問題の計算を説明しています。

Page 114: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#include <stdio.h>#include <imsl.h>

void main(){ int n = 4; float *p_a_inva, *p_a_inva_a, *p_inva; float a[] = {36.0, 12.0, 30.0, 6.0, 12.0, 20.0, 2.0, 10.0, 30.0, 2.0, 29.0, 1.0, 6.0, 10.0, 1.0, 14.0}; /* g2_inverse(a) を取得 */ imsl_f_lin_sol_nonnegdef(n, a, NULL, IMSL_INVERSE, &p_inva, IMSL_INVERSE_ONLY, 0); /* a*g2_inverse(a)を形成 */ p_a_inva = imsl_f_mat_mul_rect("A*B", IMSL_A_MATRIX, n, n, a, IMSL_B_MATRIX, n, n, p_inva, 0); /* a*g2_inverse(a)*aを形成 */ p_a_inva_a = imsl_f_mat_mul_rect("A*B", IMSL_A_MATRIX, n, n, p_a_inva, IMSL_B_MATRIX, n, n, a, 0); imsl_f_write_matrix("The g2 inverse of a", n, n, p_inva, 0); imsl_f_write_matrix("a*g2_inverse(a)\nviolates condition 3 of" " the M-P inverse", n, n, p_a_inva, 0); imsl_f_write_matrix("a = a*g2_inverse(a)*a\ncondition 1 of" " the M-P inverse", n, n, p_a_inva_a, 0);}

出力

The g2 inverse of a 1 2 3 41 0.0347 -0.0208 0.0000 0.00002 -0.0208 0.0903 0.0000 -0.05563 0.0000 0.0000 0.0000 0.00004 0.0000 -0.0556 0.0000 0.1111 a*g2_inverse(a) violates condition 3 of the M-P inverse 1 2 3 41 1.0 -0.0 0.0 0.02 0.0 1.0 0.0 0.03 1.0 -0.5 0.0 0.04 0.0 -0.0 0.0 1.0 a = a*g2_inverse(a)*a condition 1 of the M-P inverse 1 2 3 41 36 12 30 62 12 20 2 103 30 2 29 14 6 10 1 14

警告エラー

IMSL_INCONSISTENT_EQUATIONS_2 この線形連立方程式は矛盾しています。

IMSL_NOT_NONNEG_DEFINITE この行列 A は非負定値です。

Page 115: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

第 2 章:固有方程式解析

ルーチン

線形固有方程式問題

一般行列固有値と固有ベクトル . . . . . . . . . . . . . . . . . eig_gen 117固有値と固有ベクトル . . . . . . . . . . . . . eig_gen (複素数 ) 119

実対称行列固有値と固有ベクトル . . . . . . . . . . . . . . . . . eig_sym 121

複素エルミート行列固有値と固有ベクトル . . . . . . . . . . . . eig_herm (複素数 ) 123

一般線形固有方程式

実対称行列と B 正定値固有値と固有ベクトル . . . . . . . . . . . . . . . eig_symgen 126実数行列 . . . . . . . . . . . . . . . . . . . . . . . . geneig 128複素行列 . . . . . . . . . . . . . . . . . . . geneig (複素数 ) 131

使用上の注意通常の線形固有方程式問題は、方程式 Ax = λx で表されます。ここで A は

n × n 行列を示しています。値 λ は固有値で x ≠ 0 は対応する固有ベクトルで

す。この固有ベクトルはスカラー因子まで決定されます。全ての関数では、x はユークリッド長さ1を持ち、最大の大きさの x の成分が正である因子が選ば

れています。もしも x が複素数ベクトルの場合、最大の大きさのこの成分は、

実数で正になるように尺度化されます。この成分が発生する入力値は多様な最大の値を持った固有ベクトルを任意にする事が出来ます。

一般化された線形固有方程式問題は、方程式 Ax = λBx で表されます。ここで

A と B は n × n 行列を示しています。値 λ は一般化された固有値で x は対応す

る一般化された固有ベクトルです。一般化された固有ベクトルは通常の線形固有方程式問題と同じ方法で正規化されます。

エラー分析と精度

この節の注意事項は通常の固有値問題のためのものです。特殊な場合を除いては、関数は通常の固有方程式問題 Ax = λx に対して正確な固有値 - 固有ベクト

ルの組を返しません。一般的に、計算されたその組

は「近傍」行列 A + E の正確な固有値 - 固有ベクトルの組になります。E に関

する情報はその式 ||E||2 ≤ f (n) ||A||2ε. の境界の項目としてだけが知られていま

す。f(n) の値はそのアルゴリズムに依存しますが、一般的には n の小さな分数

羃乗です。Bauer と Fike (Golub と Van Loan 1989 年、342 ページ ) による理

論では

,x λ%%

( ) ( )2min for all in X E Aλ λ κ λ σ− ≤%

Page 116: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここでは σ(A) は A の全ての固有値 (A のスペクトルと呼ばれる ) のセットで、X

は固有ベクトルの行列、|| ⋅ ||2 はユークリッド長さ、κ(X) は κ(X) = ||X||2||X-1||2 とし

て定義される X の条件数になります。A が実数対称、或いは、複素数エルミート

行列であれば、その固有ベクトル行列 X はそれぞれ直交行列、又は、ユニタリ行

列です。これらの行列に対しては κ(X) = 1 になります。

この計算された固有値

と固有ベクトル

の精度はその性能指標 τ を計算してチェックすることができます。その性能

は次式で定義されます。

ε は再びマシン精度です。

ここで E は次の式の「近傍」行列なので、性能指標 τ はエラー解析に関係し

ています。

τ の正確な値は精度とデータに依存しますが、固有方程式解析関数の性能は τ < 1 であれば卓越、1 ≤ τ ≤ 100 ならば良好、τ > 100 であれば劣悪として定義され

ます。これは独断的な定義ですが、τ の大きい値はこの計算の中に重大なエ

ラーが存在するとの警告として扱うことができます。

固有ベクトル行列 X の条件数 κ(X) が大きい場合、τ が小さくても固有値の中に

大きいエラーが存在します。特に数値結果から近傍の多数の固有値、又は、不安定な数学上の問題を認識することは、しばしば困難になります。固有値問題の多面性はユーザには理解することがしばしば困難です。個々の固有値の精度が望まれていると考えています。これは個々の固有値の条件数 を計算することにより近似的に回答されます。(Goulb と Van Loan 1989 年、344-345 ページ)。正規化された固有ベクトル X の計算された配列が逆数にできるような行

列 A に対しては、λj の条件数

は X-1 の j 番目の行のユークリッド長さです。ユーザは第1章「線形連立方程

式」の関数 imsl_c_lin_sol_gen を使用してこの行列を計算することも可能

です。計算された固有値の精度の近似的な境界は κj ε||A|| によって与えられま

す。固有値の相対精度の近似的な境界は、この境界が |λj| で割られます。

一般化固有値問題の再定式化

一般化された固有値問題 Ax = λBx は、しばしば悪条件なのでユーザには解析

が困難なことが多くあります。時には、変数を変更する事で、この問題の悪条件を緩和する事が出来ます。B が特異であるが A は非特異であると仮定しま

す。ここで、逆数 µ = λ-1 を定義し、 A を定値であると想定すると、A と B の役

割が交換されるので、再定式化問題 Bx = µAx が解かれます。これらの一般化

jλ%

jx%

2

12 2

maxj j j

j nj

Ax x

n A x

λτ

ε≤ ≤

−=

%% %

%

2 2j j j jEx Ax xλ= − %% % %

1Tj je Xκ −=

Page 117: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

された固有値 µj = 0 は固有値 λj = ∞ に対応します。残りは、 λj = µj-1 です。λj

の一般化された固有ベクトルは µj の一般化された固有ベクトルに対応します。

ここで B は非特異と仮定します。 ユーザは C = B-1A である通常の固有値問題

Cx = λx を解くことが出来ます。 この行列 C は B-1A を計算するときに悪条件と

丸め誤差による摂動を受けます。 しかし、C の固有値の条件数を計算する事

は、一般化された問題の結果の精度解析に非常に役立ちます。

この一般化された問題を代わりの通常問題に縮約するために考えられる他の方法が存在します。この技術は P と Q の両方が「簡単に」逆に出来る行列であ

る行列分解 B = PQ を最初に計算することを基にしています。すると、一般化

された問題は通常の固有値問題 Fy = λy と同じになります。一般化された問題

の行列 F = P-1AQ-1 と正規化されない固有ベクトルは x = Q-1y によって与えら

れます。この再定式化の例題は A と B が実数対称で B が正定値の場合に使用

されます。関数 imsl_f_eig_symgen は P = RT と Q = R を使用しています。

ここで R はコレスキー分解 B = RTR から得られる上三角行列です。行列 F = R-

TAR-1 は対称で実数です。F の固有値 - 固有ベクトル展開は、関数 imsl_f_eig_sym を基にしています。

eig_gen実数行列 A の固有展開を計算します。

概要

#include <imsl.h>

f_complex *imsl_f_eig_gen (int n, float *a, …, 0)d_complex 型の関数は、 imsl_d_eig_genです。

必要な引数

int n ( 入力 )行列の行数と列数。

float *a ( 入力 )行列を含んだサイズ n × n の配列。

戻り値

行列の n 個の複素数固有値のポインター。この空間を解放するために freeを

使用します。計算できない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>f_complex *imsl_f_eig_gen (int n, float *a,

IMSL_VECTORS, f_complex **evec, IMSL_VECTORS_USER, f_complex evecu[], IMSL_RETURN_USER, f_complex evalu[], IMSL_A_COL_DIM, int a_col_dim, IMSL_EVECU_COL_DIM, int evecu_col_dim, 0)

オプション引数

IMSL_VECTORS, f_complex **evec ( 出力 )この行列の固有ベクトルを含んだサイズ n x n の配列へのポインター

のアドレス。返される時に、必要な空間はこの関数によって割り当てられます。通常、 f_complex *evec が宣言され、引数として &evec が使用されます。

Page 118: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_VECTORS_USER, f_complex evecu[] ( 出力 )この行列の固有ベクトルを計算します。固有ベクトルの行列を含んだサイズ n × n の配列が空間 evecu に返されます。

IMSL_RETURN_USER, f_complex evalu[] ( 出力 )空間 evaluに n 固有値を格納します。

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 a の列ディメンジョン。

デフォルト: a_col_dim = n

IMSL_EVECU_COL_DIM, int evecu_col_dim ( 入力 )evecu の列ディメンジョン。

デフォルト: evecu_col_dim = n

説明

関数 imsl_f_eig_gen は 2 段階過程で実数行列の固有値を計算します。この

行列は基本直交変換、又は、ガウス同等変換によって、上ヘッセンベルグ形に縮約されます。その後、固有値は QR もしくは、 組み合わせ LR-QR アルゴリズ

ム (Golub と Van Loan 1989 年、 373−382 ページ そして Watkins と Elsner 1990 年) を使用して計算されます。この組み合わせ LR-QR アルゴリズムは Jeff Haag と David Watkins による実装に基づいています。固有ベクトルは、その後必要

に応じて計算されます。固有ベクトルが計算される時 QR アルゴリズムが固有

展開を計算するために使用されます。固有値だけが必要な時、組み合わせ LR-QR アルゴリズムが使用されます。

例題

例題 1#include <imsl.h>

main(){ int n = 3; float a[] = {8.0, -1.0, -5.0, -4.0, 4.0, -2.0, 18.0, -5.0, -7.0}; f_complex *eval; /* A の固有値を計算 */ eval = imsl_f_eig_gen (n, a, 0); /* 固有値をプリント */ imsl_c_write_matrix ("Eigenvalues", 1, n, eval, 0);}

出力結果

Eigenvalues 1 2 3( 2, 4) ( 2, -4) ( 1, 0)

例題 2

この例題は最初の例題の変形です。 ここでは固有値と固有ベクトルを計算します。

#include <imsl.h>

main(){ int n = 3; float a[] = {8.0, -1.0, -5.0, -4.0, 4.0, -2.0, 18.0, -5.0, -7.0}; f_complex *eval; f_complex *evec; /* A の固有値を計算 */ eval = imsl_f_eig_gen (n, a,

Page 119: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_VECTORS, &evec, 0); /* 固有値と固有ベクトルをプリント */ imsl_c_write_matrix ("Eigenvalues", 1, n, eval, 0); imsl_c_write_matrix ("Eigenvectors", n, n, evec, 0);}

出力結果 Eigenvalues 1 2 3( 2, 4) ( 2, -4) ( 1, 0) Eigenvectors 1 2 31 ( 0.3162, 0.3162) ( 0.3162, -0.3162) ( 0.4082, 0.0000)2 ( 0.0000, 0.6325) ( 0.0000, -0.6325) ( 0.8165, 0.0000)3 ( 0.6325, 0.0000) ( 0.6325, 0.0000) ( 0.4082, 0.0000)

警告エラー

IMSL_SLOW_CONVERGENCE_GEN 固有値の繰り返しは # 回の反復後も収束

しませんでした。

eig_gen (複素数 )複素行列 A の固有展開を計算します。

概要

#include <imsl.h>

f_complex *imsl_c_eig_gen (int n, f_complex *a, …, 0)d_complex 型は、 imsl_z_eig_genです。

必要な引数

int n ( 入力 )行列の行数と列数。

f_complex *a ( 入力 )行列を含むサイズ n × n の配列。

戻り値

行列の n 個の複素数固有値のポインター。この空間を解放するために freeを

使用します。計算できない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>f_complex *imsl_c_eig_gen (int n, f_complex *a,

IMSL_VECTORS, f_complex **evec, IMSL_VECTORS_USER, f_complex evecu[], IMSL_RETURN_USER, f_complex evalu[], IMSL_A_COL_DIM, int a_col_dim,IMSL_EVECU_COL_DIM, int evecu_col_dim,0)

オプション引数

IMSL_VECTORS, f_complex **evec ( 出力 )行列の固有ベクトルを含むサイズ n x n の配列へのポインターのアド

レス。返される時に、必要な空間はこの関数によって割り当てられます。通常、 f_complex *evec が宣言され、引数として &evec が使用さ

れます。

Page 120: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_VECTORS_USER, f_complex evecu[] ( 出力 )行列の固有ベクトルを計算します。固有ベクトルの行列を含むサイズ n × n の配列が空間 evecu に返されます。

IMSL_RETURN_USER, f_complex evalu[] ( 出力 )空間 evalu に n 個の 固有値を格納します。

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 A の列ディメンジョン。

デフォルト: a_col_dim = n

IMSL_EVECU_COL_DIM, int evecu_col_dim ( 入力 )evecu の列ディメンジョン。

デフォルト: evecu_col_dim = n

説明

関数 imsl_c_eig_gen は 2 段階過程で複素行列の固有値を計算します。この

行列は基本のガウス変換によって、上ヘッセンベルグ形に縮約されます。その後、固有値は明示的にシフトされた LR アルゴリズム を使用して計算されま

す。固有ベクトルは、固有値計算のための反復中に計算されます。 (Martin と Wilkinson 1971 年 )。

例題

例題 1#include <imsl.h>

main(){ int n = 4; f_complex a[] = { {5,9}, {5,5}, {-6,-6}, {-7,-7}, {3,3}, {6,10}, {-5,-5}, {-6,-6}, {2,2}, {3,3}, {-1, 3}, {-5,-5}, {1,1}, {2,2}, {-3,-3}, { 0, 4} }; f_complex *eval; /* 固有値の計算 */ eval = imsl_c_eig_gen (n, a, 0); /* 固有値をプリント */ imsl_c_write_matrix ("Eigenvalues", 1, n, eval, 0);}

出力結果 Eigenvalues 1 2 3( 4, 8) ( 3, 7) ( 2, 6) 4( 1, 5)

例題 2

この例題は最初の例題の変形です。ここでは、固有値だけではなく、固有ベクトルも計算されます。

#include <imsl.h>

main(){ int n = 4; f_complex a[] = { {5,9}, {5,5}, {-6,-6}, {-7,-7}, {3,3}, {6,10}, {-5,-5}, {-6,-6}, {2,2}, {3,3}, {-1, 3}, {-5,-5}, {1,1}, {2,2}, {-3,-3}, { 0, 4} }; f_complex *eval; f_complex *evec; /* 固有値と固有ベクトルの計算 */ eval = imsl_c_eig_gen (n, a,

Page 121: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_VECTORS, &evec, 0); /* 固有値と固有ベクトルをプリント */ imsl_c_write_matrix ("Eigenvalues", 1, n, eval, 0); imsl_c_write_matrix ("Eigenvectors", n, n, evec, 0);}

出力結果

Eigenvalues 1 2 3( 4, 8) ( 3, 7) ( 2, 6) 4( 1, 5) Eigenvectors 1 2 31 ( 0.5773, -0.0000) ( 0.5774 0.0000) ( 0.3780, -0.0000)2 ( 0.5773, -0.0000) ( 0.5773, -0.0000) ( 0.7559, 0.0000)3 ( 0.5774, 0.0000) ( -0.0000, -0.0000) ( 0.3780, 0.0000)4 ( -0.0000, -0.0000) ( 0.5774, 0.0000) ( 0.3780, -0.0000) 41 ( 0.7559, 0.0000)2 ( 0.3780, 0.0000)3 ( 0.3780, 0.0000)4 ( 0.3780, 0.0000)

重大エラー

IMSL_SLOW_CONVERGENCE_GEN 固有値の繰り返しは # 回の反復後も収束

しませんでした。

eig_sym実数対称行列 A の固有展開を計算します。

概要

#include <imsl.h>

float *imsl_f_eig_sym (int n, float *a, …, 0)double 型は、 imsl_d_eig_symです。

必要な引数

int n ( 入力 )行列の行数と列数。

float *a ( 入力 )対称行列を含むサイズ n × n の配列。

戻り値

対称行列の n 個の固有値のポインター。 この空間を開放するために、free を使用します。値が計算できない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_f_eig_sym (int n, float *a,

IMSL_VECTORS, float **evec,IMSL_VECTORS_USER, float evecu[],IMSL_RETURN_USER, float evalu[],IMSL_RANGE, float elow, float ehigh,IMSL_A_COL_DIM, int a_col_dim,IMSL_EVECU_COL_DIM, int evecu_col_dim,

Page 122: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_RESULT_NUMBER, int *n_eval,0)

オプション引数

IMSL_VECTORS, float **evec ( 出力 )行列の固有ベクトルを含むサイズ n x n の配列へのポインターのアド

レス。返される時に、必要な空間はこの関数によって割り当てられます。通常、 f_complex *evec が宣言され、引数として &evec が使用さ

れます。

IMSL_VECTORS_USER, float evecu[] ( 出力 )行列の固有ベクトルを計算します。固有ベクトルの行列を含むサイズ n × n の配列が空間 evecu に返されます。

IMSL_RETURN_USER, float evalu[] ( 出力 )空間 evalu に n 個の 固有値を格納します。

IMSL_RANGE, float elow, float ehigh ( 入力 )下限 elow と上限 ehigh の区間内にある固有値と、オプションで固

有ベクトルを返します。デフォルト: (elow, ehigh) = (−∞, +∞)

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 a の列ディメンジョン。

デフォルト: a_col_dim = n

IMSL_EVECU_COL_DIM, int evecu_col_dim ( 入力 )evecu の列ディメンジョン。

デフォルト: evecu_col_dim = n

IMSL_RESULT_NUMBER, int *n_eval ( 出力 )範囲 elow, ehigh の出力の固有値と固有ベクトルの数。

説明

関数 imsl_f_eig_sym は 2段階プロセスによって、対称実数行列の固有値を

計算します。この行列は基本直交相似変換によって3対角項形に縮約されます。その後、固有値は、有理 QR 又は二等分アルゴリズムを使用して計算され

ます。固有ベクトルは必要であれば計算されます (Parlett 1980 年、169- 173ページ )。

例題

例題 1#include <imsl.h>

main(){ int n = 3; float a[] = {7.0, -8.0, -8.0, -8.0, -16.0, -18.0, -8.0, -18.0, 13.0}; float *eval; /* 固有値を計算 */ eval = imsl_f_eig_sym(n, a, 0); /* 固有値をプリント */ imsl_f_write_matrix ("Eigenvalues", 1, 3, eval, 0);}

出力結果

Eigenvalues 1 2 3 -27.90 22.68 9.22

Page 123: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題 2

この例題は最初の例題の変形です。ここでは固有ベクトルが固有値と共に計算されます。

#include <imsl.h>

main(){ int n = 3; float a[] = {7.0, -8.0, -8.0, -8.0, -16.0, -18.0, -8.0, -18.0, 13.0}; float *eval; float *evec; /* 固有値と固有ベクトルを計算 */ eval = imsl_f_eig_sym(n, a, IMSL_VECTORS, &evec, 0); /* 固有値と固有ベクトルをプリント */ imsl_f_write_matrix ("Eigenvalues", 1, n, eval, 0); imsl_f_write_matrix ("Eigenvectors", n, n, evec, 0);}

出力結果

Eigenvalues 1 2 3 -27.90 22.68 9.22

Eigenvectors 1 2 31 0.2945 -0.2722 0.91612 0.8521 -0.3591 -0.38063 0.4326 0.8927 0.1262

警告エラー

IMSL_SLOW_CONVERGENCE_SYM 固有値の反復は、縮約前に 100 回以下の

反復での収束に失敗しました。

IMSL_SLOW_CONVERGENCE_2 逆反復は収束しませんでした。固有ベク

トルは指定した固有値に対して正しくありません。

IMSL_LOST_ORTHOGONALITY_2 固有ベクトルは直交性を失いました。

IMSL_NO_EIGENVALUES_RETURNED 指定した区間の固有値の数が mxeval を超えました。 引数 n_eval は区間の固有

値の数を含みます。固有値は1つも返されません。

eig_herm (複素数 )複素エルミート行列 A の固有展開を計算します。

概要

#include <imsl.h>

float *imsl_c_eig_herm (int n, f_complex *a, …, 0)double 型は、 imsl_d_eig_hermです。

必要な引数

int n ( 入力 )行列の行数と列数。

Page 124: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

f_complex *a ( 入力 )行列を含んだサイズ n × n の配列。

戻り値

行列の n 個の固有値のポインター。この空間を開放するために free を使用し

ます。値が計算できない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_c_eig_herm (int n, f_complex *a,

IMSL_VECTORS, f_complex **evec,IMSL_VECTORS_USER, f_complex evecu[],IMSL_RETURN_USER, float evalu[],IMSL_RANGE, float elow, float ehigh,IMSL_A_COL_DIM, int a_col_dim,IMSL_EVECU_COL_DIM, int evecu_col_dim,IMSL_RESULT_NUMBER, int *n_eval,0)

オプション引数

IMSL_VECTORS, f_complex **evec ( 出力 )行列の固有ベクトルを含むサイズ n x n の配列へのポインターのアド

レス。返される時に、必要な空間はこの関数によって割り当てられます。通常、 f_complex *evec が宣言され、引数として &evec が使用さ

れます。

IMSL_VECTORS_USER, f_complex evecu[] ( 出力 )行列の固有ベクトルを計算します。固有ベクトルの行列を含むサイズ n × n の配列が空間 evecu に返されます。

IMSL_RETURN_USER, float evalu[] ( 出力 )空間 evalu に n 個の 固有値を格納します。

IMSL_RANGE, float elow, float ehigh ( 入力 )下限 elow と上限 ehigh の区間内にある固有値と、オプションで固

有ベクトルを返します。デフォルト: (elow, ehigh) = (−∞, +∞).

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 A の列ディメンジョン。

デフォルト: a_col_dim = n

IMSL_EVECU_COL_DIM, int evecu_col_dim ( 入力 )X の列ディメンジョン。

デフォルト: evecu_col_dim = n

IMSL_RESULT_NUMBER, int *n_eval ( 出力 )範囲 elow, ehigh の出力の固有値と固有ベクトルの数。

説明

関数 imsl_c_eig_herm は 2 段階処理によって複素エルミート行列の固有値を

計算します。この行列は基本直交相似変換によって 3 対角項形に縮約されま

す。それから固有値が、有理 QR 又は二等分アルゴリズムを使用して計算され

ます。固有ベクトルは必要であれば計算されます。

例題

例題 1#include <imsl.h>

main(){ int n = 3; f_complex a[] = { {1,0}, {1,-7}, {0,-1},

Page 125: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{1,7}, {5,0}, {10,-3}, {0,1}, {10,3}, {-2,0} }; float *eval; /* 固有値を計算 */ eval = imsl_c_eig_herm(n, a, 0); /* 固有値をプリント */ imsl_f_write_matrix ("Eigenvalues", 1, n, eval, 0);}

出力結果 Eigenvalues 1 2 3 15.38 -10.63 -0.75

例題 2

この例題は最初の例題の変形です。ここでは固有ベクトルが固有値と共に計算されます。

#include <imsl.h>

main(){ int n = 3; f_complex a[] = { {1,0}, {1,-7}, {0,-1}, {1,7}, {5,0}, {10,-3}, {0,1}, {10,3}, {-2,0} }; float *eval; f_complex *evec; /* 固有値と固有ベクトルを計算 */ eval = imsl_c_eig_herm(n, a, IMSL_VECTORS, &evec, 0); /* 固有値と固有ベクトルをプリント */ imsl_f_write_matrix ("Eigenvalues", 1, n, eval, 0); imsl_c_write_matrix ("Eigenvectors", n, n, evec, 0);}

出力結果

Eigenvalues 1 2 3 15.38 -10.63 -0.75 Eigenvectors 1 2 31 ( 0.0631, -0.4075) ( -0.0598, -0.3117) ( 0.8539, 0.0000)2 ( 0.7703, 0.0000) ( -0.5939, 0.1841) ( -0.0313, -0.1380)3 ( 0.4668, 0.1366) ( 0.7160, 0.0000) ( 0.0808, -0.4942)

警告エラー

IMSL_LOST_ORTHOGONALITY 少なくとも 1 つの固有ベクトルの反復が

収束に失敗しました。幾つかの固有ベクトルは不正確な可能性があります。

IMSL_NEVAL_MXEVAL_MISMATCH 区間 (#, #) の固有値の決定された数は # ですが、この区間の固有値の最大値の入力値は # です。

重大エラー

IMSL_SLOW_CONVERGENCE_GEN 固有値の反復は収束しませんでした。

IMSL_HERMITIAN_DIAG_REAL 行列要素 A (#, #) = # です。エルミート

行列の対角項は実数でなければなりません。

Page 126: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

eig_symgen連立方程式 Ax = λBx の一般化された固有展開を計算します。行列 A と B は実

数対称で、B は正定値です。

概要

#include <imsl.h>

float *imsl_f_eig_symgen (int n, float *a, float *b, …, 0)double 型は、 imsl_d_eig_symgenです。

必要な引数

int n ( 入力 )行列の行数と列数。

float *a ( 入力 )対称係数行列 A を含んだサイズ n × n の配列。

float *b ( 入力 )正定値対称係数行列 B を含むサイズ n × n の配列。

戻り値

この対称行列の n 個の固有値のポインター。この空間を解放するために freeを使用します。計算できない場合、 NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_f_eig_symgen (int n, float *a, float *b,

IMSL_VECTORS, float **evec,IMSL_VECTORS_USER, float evecu[],IMSL_RETURN_USER, float evalu[],IMSL_RANGE, float elow, float ehigh,IMSL_A_COL_DIM, int a_col_dim,IMSL_B_COL_DIM, int b_col_dim,IMSL_EVECU_COL_DIM, int evecu_col_dim,0)

オプション引数

IMSL_VECTORS, float **evec ( 出力 )行列の固有ベクトルを含むサイズ n x n の配列へのポインターのアド

レス。返される時に、必要な空間はこの関数によって割り当てられます。通常、 f_complex *evec が宣言され、引数として &evec が使用さ

れます。

IMSL_VECTORS_USER, float evecu[] ( 出力 )行列の固有ベクトルを計算します。固有ベクトルの行列を含むサイズ n × n の配列が空間 evecu に返されます。

IMSL_RETURN_USER, float evalu[] ( 出力 )空間 evalu に n 個の 固有値を格納します。

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 A の列ディメンジョン。

デフォルト: a_col_dim = n

IMSL_B_COL_DIM, int b_col_dim ( 入力 )The column dimension of B.デフォルト: b_col_dim = n

IMSL_EVECU_COL_DIM, int evecu_col_dim ( 入力 )evecu の列ディメンジョン。

デフォルト: evecu_col_dim = n

Page 127: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

関数 imsl_f_eig_symgen は 3 段階処理によって対称、正定値固有値問題の固

有値を計算します (Martin と Wilkinson 1971 年 )。 行列 B はコレスキー分解を使

用して分解形に縮約されます。これらの分解は、その固有展開が得られる対称実数行列が生じる合同変換を形成するために使用されます。問題はそれから元の座標形に変換される。固有ベクトルは必要であれば計算され変換されます。

例題

例題 1#include <imsl.h>

main(){ int n = 3; float a[] = {1.1, 1.2, 1.4, 1.2, 1.3, 1.5, 1.4, 1.5, 1.6}; float b[] = {2.0, 1.0, 0.0, 1.0, 2.0, 1.0, 0.0, 1.0, 2.0}; float *eval; /* 固有値を解 */ eval = imsl_f_eig_symgen (n, a, b, 0); /* 固有値をプリント */ imsl_f_write_matrix ("Eigenvalues", 1, n, eval, 0);}

出力結果 Eigenvalues 1 2 3 1.386 -0.058 -0.003

例題 2

この例題は最初の例題の変形です。ここでは、固有ベクトルが固有値と共に計算されます。

#include <imsl.h>

main(){ int n = 3; float a[] = {1.1, 1.2, 1.4, 1.2, 1.3, 1.5, 1.4, 1.5, 1.6}; float b[] = {2.0, 1.0, 0.0, 1.0, 2.0, 1.0, 0.0, 1.0, 2.0}; float *eval; float *evec; /* 固有値と固有ベクトルを解く */ eval = imsl_f_eig_symgen (n, a, b, IMSL_VECTORS, &evec, 0); /* 固有値と固有ベクトルをプリント */ imsl_f_write_matrix ("Eigenvalues", 1, n, eval, 0); imsl_f_write_matrix ("Eigenvectors", n, n, evec, 0);}

出力結果 Eigenvalues 1 2 3 1.386 -0.058 -0.003 Eigenvectors 1 2 3

Page 128: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1 0.6431 -0.1147 -0.68172 -0.0224 -0.6872 0.72663 0.7655 0.7174 -0.0858

警告エラー

IMSL_SLOW_CONVERGENCE_SYM 固有値の繰り返しは収縮の前に 100 回の

反復で収束に失敗しました。

重大エラー

IMSL_SUBMATRIX_NOT_POS_DEFINITE 入力行列の先導 # × # 小行列は正定値で

はありません。

IMSL_MATRIX_B_NOT_POS_DEFINITE 行列 B は正定値ではありません。

geneigA と B が実数である連立方程式 Ax = λBx の一般化された固有展開を計算しま

す。

概要

#include <imsl.h>void imsl_f_geneig (int n, float *a, float *b, f_complex *alpha, float *beta, ..., 0)double 型は、imsl_d_geneigです。

必要な引数

int n ( 入力 ) A と B の行数と列数。

float *a ( 入力 )係数行列 A を含む、サイズ n × n の配列。

float *b ( 入力 )係数行列 B を含む、サイズ n × n の配列。

f_complex *alpha ( 出力 )スカラーαi を含んだサイズ n のベクトル。βi ≠ 0 であれば i = 0, …, n − 1 に対しての λi = αi/βi は連立方程式の固有値です。

float *beta ( 出力 )サイズ n のベクトル。

オプション引数の概要

#include <imsl.h>

void imsl_f_geneig (int n, float *a, float *b,IMSL_VECTORS, f_complex **evec,IMSL_VECTORS_USER, f_complex evecu[],IMSL_A_COL_DIM, int a_col_dim,IMSL_B_COL_DIM, int b_col_dim,IMSL_EVECU_COL_DIM, int evecu_col_dim,0)

オプション引数

IMSL_VECTORS, f_complex **evec ( 出力 )行列の固有ベクトルを含むサイズ n x n の配列へのポインターのアド

レス。返される時に、必要な空間はこの関数によって割り当てられます。通常、 f_complex *evec が宣言され、引数として &evec が使用さ

れます。

IMSL_VECTORS_USER, f_complex evecu[] ( 出力 )行列の固有ベクトルを計算します。固有ベクトルの行列を含むサイズ

Page 129: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

n × n の配列が空間 evecu に返されます。各ベクトルは、ユークリッ

ドの長さが値1と等しくなるように正規化されます。

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 A の列ディメンジョン。

デフォルト: a_col_dim = n

IMSL_B_COL_DIM, int b_col_dim ( 入力 )The column dimension of B.デフォルト: b_col_dim = n.

IMSL_EVECU_COL_DIM, int evecu_col_dim ( 入力 )evecu の列ディメンジョン。

デフォルト: evecu_col_dim = n

説明

関数 imsl_f_geneig は QZ アルゴリズムを使用して一般化された固有連立方

程式 Ax = λBx の固有値と固有ベクトルを計算します。ここでは、A と B は次

数 n の実数行列です。α と β が λ の代わりに返されるので、この問題の固

有値は無限個になります。β が非ゼロであれば、λ = α/β です。

QZ アルゴリズムの最初のステップは、A を上ヘッセンベルグ形に、B を上三

角形に同時に、縮約することです。その後、直交変換が、A を擬似上三角形に

縮約するために使用されますが、B は上三角形のままです。この縮約問題の一

般化された固有値と固有ベクトルがそれから計算されます。

関数 imsl_f_geneig は、EISPACK ルーチン QZHES、QZIT、QZVAL に設置

された、 Moler と Stewart (1973 年 ) に由来する QZ アルゴリズムに基づいてい

ます。Garbow その他を参照してください。

例題

例題 1

この例題では、連立方程式 Ax = λBx の固有値、λ が計算されます、ここで、

配列 A と B は、以下の通りです。

#include <imsl.h>

main(){ int n = 3; f_complex alpha[3]; float beta[3]; int i; f_complex eval[3]; float a[] = {1.0, 0.5, 0.0, -10.0, 2.0, 0.0, 5.0, 1.0, 0.5}; float b[] = {0.5, 0.0, 0.0, 3.0, 3.0, 0.0, 4.0, 0.5, 1.0};

/* 固有値を計算 */

imsl_f_geneig (n, a, b, alpha, beta, 0); for (i=0; i<n; i++) if (beta[i] != 0.0) eval[i] = imsl_c_div(alpha[i], imsl_cf_convert(beta[i], 0.0));

1.0 0.5 0.0 0.5 0.0 0.010.0 2.0 0.0 and 3.0 3.0 0.05.0 1.0 0.5 4.0 0.5 1.0

A B = − =

Page 130: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

else printf ("Infinite eigenvalue\n");

/* 固有値をプリント */

imsl_c_write_matrix ("Eigenvalues", 1, n, eval, 0);}

出力結果 Eigenvalues 1 2 3( 0.833, 1.993) ( 0.833, -1.993) ( 0.500, 0.000)

例題 2

この例題は、前の例題に与えられた同じ連立方程式の、固有値と固有ベクトルを見つけます。

#include <imsl.h> main(){ int n = 3; f_complex alpha[3]; float beta[3]; int i; f_complex eval[3]; f_complex *evec; float a[] = {1.0, 0.5, 0.0, -10.0, 2.0, 0.0, 5.0, 1.0, 0.5}; float b[] = {0.5, 0.0, 0.0, 3.0, 3.0, 0.0, 4.0, 0.5, 1.0}; imsl_f_geneig (n, a, b, alpha, beta, IMSL_VECTORS, &evec, 0); for (i=0; i<n; i++) if (beta[i] != 0.0) eval[i] = imsl_c_div(alpha[i], imsl_cf_convert(beta[i], 0.0)); else printf ("Infinite eigenvalue\n"); /* 固有値をプリント */ imsl_c_write_matrix ("Eigenvalues", 1, n, eval, 0); /* 固有ベクトルをプリント */

imsl_c_write_matrix ("Eigenvectors", n, n, evec, 0);}

出力結果 Eigenvalues 1 2 3( 0.833, 1.993) ( 0.833, -1.993) ( 0.500, -0.000) Eigenvectors 1 2 31 ( -0.197, 0.150) ( -0.197, -0.150) ( -0.000, 0.000)2 ( -0.069, -0.568) ( -0.069, 0.568) ( -0.000, 0.000)3 ( 0.782, 0.000) ( 0.782, 0.000) ( 1.000, 0.000)

Page 131: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

geneig (複素数 )A と B が複素数である、連立方程式 Ax = λBx の一般化された固有展開を計算

します。

概要

#include <imsl.h>void imsl_c_geneig (int n, f_complex *a, f_complex *b, f_complex *alpha, f_complex float

*beta, ..., 0)double 型は、 imsl_z_geneigです。

必要な引数

int n ( 入力 ) A と B の行数と列数。

f_complex *a ( 入力 )係数行列 A を含む、サイズ n × n の配列。

f_complex *b ( 入力 )係数行列 B を含む、サイズ n × n の配列。

f_complex *alpha ( 出力 )スカラーαi を含んだサイズ n のベクトル。βi ≠ 0 であれば i = 0, …, n − 1 に対しての λi = αi/β は連立方程式の固有値です。

f_complex *beta ( 出力 )サイズ n のベクトル。

オプション引数の概要

#include <imsl.h>

void imsl_c_geneig (int n, f_complex *a, f_complex *b, f_complex *alpha, f_complex *betaIMSL_VECTORS, f_complex **evec,IMSL_VECTORS_USER, f_complex evecu[],IMSL_A_COL_DIM, int a_col_dim,IMSL_B_COL_DIM, int b_col_dim,IMSL_EVECU_COL_DIM, int evecu_col_dim,0)

オプション引数

IMSL_VECTORS, f_complex **evec ( 出力 )行列の固有ベクトルを含むサイズ n x n の配列へのポインターのアド

レス。返される時に、必要な空間はこの関数によって割り当てられます。通常、 f_complex *evec が宣言され、引数として &evec が使用さ

れます。

IMSL_VECTORS_USER, f_complex evecu[] ( 出力 )行列の固有ベクトルを計算します。固有ベクトルの行列を含むサイズ n × n の配列が空間 evecu に返されます。各ベクトルは、ユークリッ

ドの長さが値1と等しくなるように正規化されます。

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 A の列ディメンジョン。

デフォルト: a_col_dim =

IMSL_B_COL_DIM, int b_col_dim ( 入力 )B の列ディメンジョン。The column dimension of B.デフォルト: b_col_dim = n.

Page 132: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_EVECU_COL_DIM, int evecu_col_dim ( 入力 )evecu の列ディメンジョン。

デフォルト: evecu_col_dim = n.

説明

関数 imsl_c_geneig は QZ アルゴリズムを使用して一般化された固有連立方

程式 Ax = λBx の固有値と固有ベクトルを計算します。ここでは、A と B は次数

n の複素行列です。α と β が λ の代わりに返されるので、この問題の固有値は

無限個になります。β が非ゼロであれば、λ = α/β です。

QZ アルゴリズムの最初のステップは、A を上ヘッセンベルグ形に、B を上三

角形に同時に、縮約することです。その後、直交変換が、A を擬似上三角形に

縮約するために使用されますが、B は上三角形のままです。この縮約問題の一

般化された固有値と固有ベクトルがそれから計算されます。

関数 imsl_c_geneig は、 Moler と Stewart (1973 年 ) に由来する QZ アルゴリ

ズムに基づいています。

例題

例題 1

この例題では、連立方程式 Ax = λBx の固有値、λ が計算されます、ここで、

配列 A と B は、以下の通りです。

#include <imsl.h>

main(){ int n = 3; f_complex alpha[3]; f_complex beta[3]; int i; f_complex eval[3]; f_complex zero = {0.0, 0.0}; f_complex a[] = {{1.0, 0.0}, {0.5, 1.0}, {0.0, 5.0}, {-10.0, 0.0}, {2.0, 1.0}, {0.0, 0.0}, {5.0, 1.0}, {1.0, 0.0}, {0.5, 3.0}}; f_complex b[] = {{0.5, 0.0}, {0.0, 0.0}, {0.0, 0.0}, {3.0, 3.0}, {3.0, 3.0}, {0.0, 1.0}, {4.0, 2.0}, {0.5, 1.0}, {1.0, 1.0}};

/* 固有値を計算 */

imsl_c_geneig (n, a, b, alpha, beta, 0);

for (i=0; i<n; i++) if (!imsl_c_eq(beta[i], zero)) eval[i] = imsl_c_div(alpha[i], beta[i]); else printf ("Infinite eigenvalue\n");

/* 固有値をプリント */

imsl_c_write_matrix ("Eigenvalues", 1, n, eval, 0);}

出力結果 Eigenvalues 1 2 3( -8.18, -25.38) ( 2.18, 0.61) ( 0.12, -0.39)

1 0.5 5 0.5 0 010 2 0 and 3 3 3 3

5 1 0.5 3 4 2 0.5 1

i iA i B i i i

i i i i i

+ = − + = + + + + + + +

Page 133: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題 2

この例題は、前の例題に与えられた同じ連立方程式の、固有値と固有ベクトル

を見つけます。

#include <imsl.h> main(){ int n = 3; f_complex alpha[3]; f_complex beta[3]; int i; f_complex eval[3]; f_complex *evec; f_complex zero = {0.0, 0.0}; f_complex a[] = {{1.0, 0.0}, {0.5, 1.0}, {0.0, 5.0}, {-10.0, 0.0}, {2.0, 1.0}, {0.0, 0.0}, {5.0, 1.0}, {1.0, 0.0}, {0.5, 3.0}}; f_complex b[] = {{0.5, 0.0}, {0.0, 0.0}, {0.0, 0.0}, {3.0, 3.0}, {3.0, 3.0}, {0.0, 1.0}, {4.0, 2.0}, {0.5, 1.0}, {1.0, 1.0}}; /* 固有値と固有ベクトルを計算 */ imsl_c_geneig (n, a, b, alpha, beta, IMSL_VECTORS, & evec, 0); for (i=0; i<n; i++) if (!imsl_c_eq(beta[i], zero)) eval[i] = imsl_c_div(alpha[i], beta[i]); else printf ("Infinite eigenvalue\n"); /* 固有値をプリント */ imsl_c_write_matrix ("Eigenvalues", 1, n, eval, 0); /*固有ベクトルをプリント */ imsl_c_write_matrix ("Eigenvectors", n, n, evec, 0);}

出力結果 Eigenvalues 1 2 3( -8.18, -25.38) ( 2.18, 0.61) ( 0.12, -0.39) Eigenvectors 1 2 31 ( -0.3267, -0.1245) ( -0.3007, -0.2444) ( 0.0371, 0.1518)2 ( 0.1767, 0.0054) ( 0.8959, 0.0000) ( 0.9577, 0.0000)3 ( 0.9201, 0.0000) ( -0.2019, 0.0801) ( -0.2215, 0.0968)

Page 134: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに
Page 135: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

第 3章: 補間と近似

ルーチン

3 次スプライン補間導関数と条件 . . . . . . . . . . . . . .cub_spline_interp_e_cnd 140形状保存法 . . . . . . . . . . . . . . .cub_spline_interp_shape 146

3 次スプライン計算と積分計算と微分 . . . . . . . . . . . . . . . . . . cub_spline_value 149積分 . . . . . . . . . . . . . . . . . . . . cub_spline_integral 152

スプライン補間1 次元補間. . . . . . . . . . . . . . . . . . . . . spline_interp 153補間データが与えられたノット順序 . . . . . . . . . spline_knots 1582 次元、テンソル積補間. . . . . . . . . . . . . spline_2d_interp 161

スプライン計算と積分1 次元計算と微分. . . . . . . . . . . . . . . . . . spline_value 1661 次元積分. . . . . . . . . . . . . . . . . . . . spline_integral 1682 次元計算と微分. . . . . . . . . . . . . . . . .spline_2d_value 1702 次元積分. . . . . . . . . . . . . . . . . . .spline_2d_integral 173

最小二乗近似と平滑化一般的な関数 . . . . . . . . . . . . . . user_fcn_least_squares 175固定したノットを持つスプライン . . . . . . spline_least_squares 179固定したノットを持つテンソル積スプライン spline_2d_least_squares 1843 次元平滑化スプライン. . . . . . . . . . . . cub_spline_smooth 189制約付きスプライン . . . . . . . . . . . .spline_lsq_constrained 192エラー検出による 1 次元データの平滑化 . . . . . smooth_1d_data 198

離散データ補間Akima の曲面当てはめ方 . . . . . . . . . . . scattered_2d_interp 202

離散データ最小時乗法動径基底関数を使用した当てはめ . . . . . . . radial_scattered_fit 205動径基底当てはめを評価 . . . . . . . . . . . . . radial_evaluate 211

使用上の注意本章の大部分の関数は、与えられたデータを補間、又は、近似する、或いは、これらの関数の計算と積分を支援する 3 次区分化多項式、又は、一般スプライ

ン関数を生成します。 関数の 2 つの主要な小区分が提供されます。3 次スプラ

イン関数は前置辞「cub_spline_」で始まり、次で説明する区分化多項式数

式を使用します。スプライン関数は前置辞「spline_」で始まり、次で説明

する B スプライン数式を使用します。 スプライン関数の多くは、de Boor (1978 年 ) の本に記載されているルーチンを基にしています。

一般的なデータの最小二乗当てはめ用の汎用目的の数種のルーチンと、2 次元

離散データの補間を生成する 1 つのルーチンを提供しています。

Page 136: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

区分化多項式 単変量区分化多項式(関数)p は区分点列 ξ ∈ Rn、その多項式区分の階数 k ( 次

数 k − 1)、その局所多項式係数の k × (n − 1) 行列 c を与えることで指定されます。

この情報の各項目で区分化多項式 ( ppoly ) 関数は次式で与えられます。

区分点列 ξ は、完全に増加していると仮定し、 ppoly 関数を最初と最後の区間

から補間によって全体の実軸に拡げています。この ppoly 関数平滑化されてい

るとき、この表現は、冗長です。例えば、もし p が連続している場合、次の様

に cii から c1,i+1 を計算することができます。

平滑な ppoly に対して、少なくともこのような関数が決定される最初の時に、

「基底関数」或いは、B スプラインの各項にこの非冗長な数式を使用すること

を優先します。

スプラインと BスプラインB スプラインは平滑な ppoly 関数の与えられたクラスのための特定の適切な基

底を提供します。そのようなクラスは、その区分点列、その順序 k 、内側の区

分点上の必要な平滑により指定されます。対応する B- スプラインの基底は

ノット列 t ∈ RM を与えて指定します。指定規則は次の通りです。クラスが、

内部区分点上に続いている j- 番目を含む全ての導関数を持っている場合、ξi は

ノット列内に k − j − 1 回現れます。 ξ1 と ξn が該当の両端点であると仮定する

と、最初の k ノットは ξ1 と等しく、最後の k ノットは ξn と等しくなります。

これは、B- スプラインが ξ1 の近くで右連続、ξn の近くで左連続であるので行

われます。

上述の構成が完成した時に、長さ M のノット列 t が生成され、例えば、示され

た平滑さでこの区間を ppoly の関数で張る Β0,...., Βm−1 、階数 k の m::=M− k B-スプラインが存在します。この事は、この等級の各 ppoly 関数は、 B スプライ

ンの線形結合として次の独自な数式を持ちます。

B-スプラインは特に簡潔なppoly 関数です。Βι 関数は区間 [ti,ti+k] 上では非ゼロ

の非負関数で、更に正確に言えば、i 番目の B- スプラインの成立範囲は区間 [ti,ti+k] です。同じ等級(ゼロ関数以外)の ppoly 関数で B- スプラインよりは

小さい成立範囲(例えば、より多くの区間で消滅する)を持つものはありません。これは、どれか特別な B- スプラインの係数の影響が数個の区間だけに広

がるだけなので、B- スプラインを特別に魅力のある基底関数にしています。

そのパラメータに B- スプラインの従属性を強調することが必要である場合は、

ノット列 t に対して階数 k の i- 番目の B- スプラインを示すために記法 Bi,k,t を使用します。

3次スプライン3 次スプラインは平滑 ( 例、 C1 又は C2 )、4 階 ppoly 関数です。歴史的に、そし

て他の理由で、3 次スプラインは、ppoly 関数の中で最もよく使用されていま

す。そのために、それらの構成と計算に特殊な関数を提供しています。 これら

( ) ( )( )

1

11

for 1 !

jki

ji i ij

xp x c x

ξ ξ−

+=

−= ≤ ≤

−∑

( ) ( )( )

11

1, 1 11 1 !

jki i

i i jij

c p cj

ξ ξξ

−+

+ +=

−= =

−∑

0 0 1 1 1 1m mp a B a B a B− −= + + +K

Page 137: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

のルーチンは一般的な ppoly 関数 (k = 4) のために、上述のように ppoly 表現

を使用します。

2 個の 3 次スプライン補間関数:imsl_f_cub_spline_interp_e_cnd とimsl_f_cub_spline_interp_shape を提供しています。関数 imsl_f_cub_spline_interp_e_cnd はユーザが種々の両端点条件(右端点と

左端点で 1 次、又は、2 次の微係数の値など)を指定することが出来ます。こ

れは両端点で 2 次微係数をゼロに設定することにより、この関数を使用した自

然 3次スプラインが得られることを意味しています。 関数 imsl_f_cub_spline_interp_shape は曲線の形状がデータの形状に一致する

ように設計されています。特に、この関数の1つのオプションは、そのデフォルトは振動を最小にする事を試みるが、データの凸状性を保存します。

この 3次スプライン補間関数は不満足な結果を生み出すこともあります。例え

ばその補間関数はユーザの求める形状を持たないとか、そのデータはノイズが多くて最小二乗当てはめが必要であるなどです。ノットとスプライン補間関数の階数を選択することができるのでこの補間関数 imsl_f_spline_interp は更に柔軟性があります。ユーザはこのルーチンを使用して、提供される柔軟性を探求することをお勧めします。

テンソル積スプライン

多変量補間関数と近似関数を得る最も簡単な方法は、単変量法を採用し、テンソル積を使用して多変量法を形成することです。2 次元スプライン補間の場合

には、その導出過程は以下の通りです。 tx を 階数 kx, のノット列として、tv を 階数 kv のノット列とします。Nx + kx を tx の長さとして、Nv + kx を ty の長さ

とします。その時、テンソル積スプラインは次の形状を持ちます。

与えられる点の 2 つのセットは

これに対して、対応する単変量補間問題が解かれて、テンソル積補間問題は、次のようにしてその係数 cnm を見つけます。

この問題は de Boor (1978 年、347 ページ ) に記述されているように単変量補間

問題を繰り返して解くことによって効率的に解くことが出来ます。3 次元補間

は類似の方法で操作することが出来ます。 本章が提供するのは、2 次元補間

データが与えられて 2 次元、テンソル積スプライン係数を計算する関数

(imsl_f_spline_2d_interp)、並びに、テンソル積、最小二乗問題のテンソル

積スプライン係数を計算する関数 (imsl_f_spline_2d_least_squares) です。

これに加えて、2 次元テンソル積スプライン関数の計算、微分、積分関数を提

供しています。関連する関数には imsl_f_spline_2d_value と imsl_f_spline_2d_integral があります。

( ) ( )1 1

, , , ,0 0

y x

x x y y

N N

nm n k m km n

c B x B y− −

= =∑ ∑ t t

{ } 1xN

i ix=

{ } 1yN

i iy=

( ) ( )1 1

, , , ,0 0

y x

x x y y

N N

nm n k i m k j ijm n

c B x B y f− −

= =

=∑ ∑ t t

Page 138: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

離散データ補間

IMSL C Math ライブラリは関数 imsl_f_scattered_2d_interp を提供してお

り、これは平面の離散データに補間関数の値を返します。この関数は、三角

メッシュ上に C 1 区分 5 次方程式を使用する Akima (1978 年 ) による成果に基

づいています。

最小二乗

IMSL C Math ライブラリはノイズの多いデータを平滑にする関数を含んでいま

す。この関数 imsl_f_user_fcn_least_squares はユーザの提供する関数で

回帰を計算します。関数 imsl_f_spline_least_squares は固定ノット、又

は、可変ノットのスプラインを使用して最小二乗当てはめを計算します。これらの関数はデフォルトで 3次スプライン、最小二乗当てはめを生成します。オ

プションの引数でユーザは階数とノット列を選択する事が出来ます。IMSL C Math ライブラリは又、上述のテンソル積スプライン回帰関数 (imsl_f_spline_2d_least_squares) を含んでいます。関数 imsl_f_radial_scattered_fit は動径ベースの関数を使用して RN の中の散

乱データの近似を計算します。

上に列挙した関数に加えて、第 10 章:統計と乱数発生の中の幾つかの関数が多項式回帰と一般線形回帰のために提供されています。

3次スプラインによる平滑化1 つの「平滑化スプライン」関数が提供されています。

imsl_f_cub_spline_smooth のデフォルトの操作は、相互確認により平滑化

パラメータを推定してこのデータを平滑にする 3次スプラインを返します。

ユーザが平滑化パラメータを提供する場合、この関数はそれに対応した 3次ス

プラインを返します。

スプラインと区分化多項式の構造

このオプションの節はスプラインと区分化多項式の構造に関係するより詳細な説明を含んでいます。

あるスプラインは d と r が正の整数である領域 Rd と目的領域 Rr の写像と見

なす事が出来ます。このバージョンの IMSL C/Math ライブラリでは、 r = 1 だけ

がその範囲に含まれます。こうして s がスプラインであれば、ある d と r に対

しては、以下のようになります。

s : Rd → Rr

この事は、このようなスプライン s は d ノット順と階数 ( 各領域ディメンジョ

ンに 1 つ ) を持たなければならない事を意味しています。このために s に関連

して、次のノットと階数を持つ

t0, …, td-1

k0, …, kd-1

このスプラインの正確な形は以下の通りです。

s(x) = (s0(x), …, sr-1(x)) x = (x1, …, xd) ∈ Rd

ここでは、次の式は真になります。

ni は ti のノット数引く階数 kI であることに注意してください。

( )1 0

0 10 1 0 0 1 11 0

1 1

, , , , , ,0 0

:d

dd d dd

n ni

i j j j k j kj j

s x c B B−

−− − −

− −

= =

= ∑ ∑ t tKKL

Page 139: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1つのスプラインに関する全ての情報を Imsl_f_spline ( double 型であれば、

その構造体名は Imsl_d_spline で float は double になる )と呼ばれる構造

体に格納します。この構造体の仕様は以下の通りです。

typedef struct {int domain_dim;int target_dim;int *order;int *num_coef;int *num_knots;float **knots;float **coef;

} Imsl_f_spline;

明示的に、 sp が Imsl_f_spline のポインターの場合、以下の表のようになりま

す。

ppoly 関数に対しては、ppoly を d と r が正の整数である領域 Rd と目的領

域 Rr の写像と見なす事が出来ます。こうして p が ppoly であれば、ある d と r に対して次式は真になります。

p : Rd → Rr

このバージョンの IMSL C Math ライブラリでは、 r = 1 だけがその範囲に含まれ

ます。この事は、このような ppoly p は d 区分点順と階数 ( 各領域ディメン

ジョンに 1 つ ) を持たなければならない事を意味します。このために p に関

連して、次の区分点と階数を持ちます。

ξ1, …, ξd

k1, …, kd

このスプラインの正確な形は以下の通りです。

p(x) = (p0x), …, prx))x = (x1, …, xd) ∈ Rd

Lj : = max {1, min {Mj, nj − 1}}

ここで Mj は次で選択されます。

sp-> domain_dim = dsp-> target_dim = rsp-> order [i] = ki i = 0, …, d − 1sp-> num_coef [i] = mi i = 0, …, d − 1sp-> num_knots [i] = ni + ki i = 0, …, d − 1sp-> knots [i] [j]

I = 0, …, d − 1 j = 0, …, ni + ki − 1sp-> coef [i] [j]

I = 0, …, r − 1 j = j0 + j1 n0 + … + jd-1 n0nd-2

ijt=

ijc=

( )( ) ( )1 1

11

1

11 11

, , , , ,0 0 1

:! !

dd d

dd

d

ldk kdL Li

i L L l ll l d

x xp x c

l l

ξ ξ− −

= =

− −= ∑ ∑ K K

K K

1 1, ,j jj j

jM Mx j dξ ξ +≤ < = K

Page 140: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

nj は ξ j の区分点数であることに注意してください。

1 つの ppoly の全ての情報を Imsl_f_ppoly, ( double 型であれば、その構

造体名は Imsl_d_ppoly で float は double になる )と呼ばれる構造体に格

納します。

typedef struct {int domain_dim;int target_dim;int *order;int *num_coef;int *num_breakpoints;float **breakpoints;float **coef;

} Imsl_f_ppoly;

特に ppoly が Imsl_f_ppoly 型の構造体のポインターであれば、以下の通りで

す。

cub_spline_interp_e_cnd種々の端点条件を指定して、3 次スプライン関数を計算します。デフォルトの

補間関数は「ノットは無い」条件を満足します。

概要

#include <imsl.h>

Imsl_f_ppoly *imsl_f_cub_spline_interp_e_cnd (int ndata, float xdata[], float fdata[], …, 0)

Imsl_d_ppoly 型関数は、 imsl_d_cub_spline_interp_e_cndです。

必要な引数

int ndata ( 入力 )データ点数。

float xdata[] ( 入力 )補間問題の横座標を含む ndata 成分の配列。

float fdata[] ( 入力 )補間問題の縦座標を含む ndata 成分の配列。

戻り値

3 次スプライン補間関数を表現する構造体のポインター。補間関数が計算され

なければ、NULL が返されます。この空間を解放するためには、free を使用

します。

ppoly-> domain_dim = dppoly-> target_dim = rppoly-> order [i] = ki i = 0, …, d − 1ppoly-> num_coef [i] = ki (ni − 1) i = 0, …, d − 1ppoly-> num_breakpoints [i] = ni i = 0, …, d − 1ppoly-> breakpoints [i] [j]

i = 0, …, d − 1 j = 0, …, ni − 1ppoly->coef [i[ [j]

i = 0, …, r − 1j = 0, …, k0(n0 − 1)…kd-1(nd-1 − 1)

0 1 and j

j jnξ ξ += −∞ = ∞

ijξ=

ijc=

Page 141: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数の概要

#include <imsl.h>Imsl_f_ppoly *imsl_f_cub_spline_interp_e_cnd (int ndata, float xdata[], float fdata[],

IMSL_LEFT, int ileft, float left,IMSL_RIGHT, int iright, float right,IMSL_PERIODIC,0)

オプション引数

IMSL_LEFT, int ileft, float left ( 入力 )左端点の補間関数の1次、又は2次微係数の値を設定します。 ileft=i であれば、この補間関数 s は次式を満足します 。

s(i)(xL) = left

ここで xL は左端の横座標です。 ileft の正当な値は 1 又は 2 だけです。

IMSL_RIGHT, int iright, float right ( 入力 )右端点の補間関数の1次、又は2次微係数の値を設定します。iright = i であれば、この補間関数 s は次式を満足します。

s(i)(xR) = right

ここで xR は右端の横座標です。 irightの正当な値は 1 又は 2 だけです。

IMSL_PERIODIC

データの C2 周期的補間関数を計算します。これには、次式が要求さ

れます。

s(i)(xL) = s(i)(xR)i = 0, 1, 2

ここの s、 xL,、 xRs は、上で定義されます。

説明

関数 imsl_f_cub_spline_interp_e_cnd は i = 0, ... , ndata − 1 = n に対する

データ点のセット (xi , fi ) の C 2 3 次スプライン補間関数を計算します。このス

プラインの区分点は横軸です。全ての単変量補間関数に対して横軸はソートする必要がないことを強調します。端点条件はユーザによって選択されなければなりません。ユーザは「ノットがない」、又は、各端点の 1 次微係数、或いは、

2 次微係数を指定することが可能、或いは、C 2 周期性を要求することが可能で

す ( de Boor 1978 年、第 4 章 ) 。デフォルトが選択されなければ、「ノットがな

い」スプライン補間関数が計算されます。IMSL_PERIODICキーワードが選択

されたならば、他のすべてのキーワードは無視されます。そして C 2 周期補間

関数が計算されます。この場合には、左端と右端の fdata 値が同じでなけれ

ば、警告メッセージが出て、右の値を左に等しくします。IMSL_LEFT 又は、

IMSL_RIGHT IMSL_RIGHT が選択されたならば ( IMSL_PERIODIC が無くて )、その時は、ユーザはどちらかの端点の 1 次微係数、或いは、2 次微係数の値を

選択する機会が与えられます。 デフォルトの場合は(キーワードが使用されない時)、端点に「ノットがない」条件になります。 このために、オプションの引数が選ばれないときはこの関数は「ノットがない」補間関数を生成します。

データ(端点条件を含めて)が平滑 (C 4) 関数 f いわゆる fi = f(xi ) から生じる

と、この誤差は予想されるようになります。を上述の補間関数の区分点ベク

トルとします。その時、最大絶対誤差は次式を満足します。

ここで

ζ

[ ]( )

[ ]0 0

44, ,n n

f s C fξ ξ ξ ξ

ξ− ≤

Page 142: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

詳細は、 de Boor (1978 年、第 4 章と第 5 章 ) を参照してください。

この関数の戻り値は構造体 Imsl_f_ppoly のポインターです。呼び出しプログラ

ムは、これをポインター Imsl_f_ppoly *ppoly の中で受け取らなければなりま

せん。この構造体は、この関数によって計算されるスプライン(区分的多項式として格納される)を決定する全ての情報を含んでいます。例えば、次のコード列はこのスプラインを x で計算してその値を y に返します。

y = imsl_f_cub_spline_value (x, ppoly, 0)

このデフォルト (「ノットは無い」) スプラインと左端で 1 次微係数を 1 に

セットして右端で 2 次微係数を -90 にセットする補間 3 次スプラインとの相違

は次の図の様になります。

Figure 3- 1 Two Interpolating Splines

例題

例題 1

この例題では、関数 f の 3 次スプライン補間関数を計算します。このスプライ

ンの値を正確な関数値と比較します。ここではデフォルト設定を使用しているので、この補間関数は「ノットは無い」条件によって決定されます ( de Boor 1978 年を参照 )。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11 /* 関数を定義 */#define F(x) (float)(sin(15.0*x))

main(){ int i; float fdata[NDATA], xdata[NDATA], x, y; Imsl_f_ppoly *ppoly; /* xdata と fdataを計算 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]); } /* 3 次スプライン補間を計算 */ ppoly = imsl_f_cub_spline_interp_e_cnd (NDATA, xdata, fdata, 0);

/* 結果をプリント */

10, , 1: max i ii n

ξ ξ ξ+= −= −

K

Page 143: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

printf(" x F(x) Interpolant Error\n"); for (i = 0; i < 2*NDATA-1; i++){ x = (float) i /(float)(2*NDATA-2); y = imsl_f_cub_spline_value(x,ppoly,0); printf(" %6.3f %10.3f %10.3f %10.4f\n", x, F(x), y, fabs(F(x)-y)); }}

出力結果

x F(x) Interpolant Error0.000 0.000 0.000 0.00000.050 0.682 0.809 0.12700.100 0.997 0.997 0.00000.150 0.778 0.723 0.05520.200 0.141 0.141 0.00000.250 -0.572 -0.549 0.02280.300 -0.978 -0.978 0.00000.350 -0.859 -0.843 0.01620.400 -0.279 -0.279 0.00000.450 0.450 0.441 0.00930.500 0.938 0.938 0.00000.550 0.923 0.903 0.01990.600 0.412 0.412 0.00000.650 -0.320 -0.315 0.00490.700 -0.880 -0.880 0.00000.750 -0.968 -0.938 0.02950.800 -0.537 -0.537 0.00000.850 0.183 0.148 0.03470.900 0.804 0.804 0.00000.950 0.994 1.086 0.09261.000 0.650 0.650 0.0000

例題 2

この例題では、関数 f の 3 次スプライン補間関数を計算します。左端の 1 次微

係数の値と右端の 2 次微係数の値を指定します。それからこのスプラインの値

と正確な関数値を比較します。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11 /* 関数を定義 */#define F(x) (float)(sin(15.0*x))

main(){ int i, ileft, iright; float left, right, x, y, fdata[NDATA], xdata[NDATA]; Imsl_f_ppoly *pp; /* xdata と fdata を計算 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)(i)/(NDATA-1); fdata[i] = F(xdata[i]); } /* 端点条件を指定 */ ileft = 1; left = 0.0; iright = 2; right =-225.0*sin(15.0); /* 3次スプライン補間関数を計算 */ pp = imsl_f_cub_spline_interp_e_cnd(NDATA, xdata, fdata, IMSL_LEFT, ileft, left, IMSL_RIGHT, iright, right, 0); /* 区間の最初の半分の */

Page 144: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* 結果をプリント */ printf(" x F(x) Interpolant Error\n\n"); for (i=0; i<NDATA; i++){ x = (float)(i)/(float)(2*NDATA-2); y = imsl_f_cub_spline_value(x,pp,0); printf(" %6.3f %10.3f %10.3f %10.4f\n", x, F(x), y, fabs(F(x)-y)); }}

出力結果

x F(x) Interpolant Error0.000 0.000 0.000 0.00000.050 0.682 0.438 0.24410.100 0.997 0.997 0.00000.150 0.778 0.822 0.04420.200 0.141 0.141 0.00000.250 -0.572 -0.575 0.00380.300 -0.978 -0.978 0.00000.350 -0.859 -0.836 0.02330.400 -0.279 -0.279 0.00000.450 0.450 0.439 0.01110.500 0.938 0.938 0.0000

例題 3

この例題は、両端点で補間関数の 2 次微係数をゼロにして関数 f の自然 3 次ス

プライン補間関数を計算します。前の例のように正確な関数値とこのスプラインの値を比較します。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11 /* 関数を定義 */#define F(x) (float)(sin(15.0*x))

main(){ int i, ileft, iright; float left, right, x, y, fdata[NDATA], xdata[NDATA]; Imsl_f_ppoly *pp; /* xdata と fdata を計算 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)(i)/(NDATA-1); fdata[i] = F(xdata[i]); } /*端点条件を指定 */ ileft = 2; left = 0.0; iright = 2; right = 0.0; /* 3 次スプライン補間を計算 */ pp = imsl_f_cub_spline_interp_e_cnd(NDATA, xdata, fdata, IMSL_LEFT, ileft, left, IMSL_RIGHT, iright, right, 0); /* 区間の最初の半分の */ /* 結果をプリント */ printf(" x F(x) Interpolant Error\n\n"); for (i = 0; i < NDATA; i++){ x = (float)(i)/(float)(2*NDATA-2); y = imsl_f_cub_spline_value(x,pp,0); printf(" %6.3f %10.3f %10.3f %10.4f\n", x, F(x), y, fabs(F(x)-y)); }}

Page 145: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果 x F(x) Interpolant Error0.000 0.000 0.000 0.00000.050 0.682 0.667 0.01500.100 0.997 0.997 0.00000.150 0.778 0.761 0.01720.200 0.141 0.141 0.00000.250 -0.572 -0.559 0.01260.300 -0.978 -0.978 0.00000.350 -0.859 -0.840 0.01890.400 -0.279 -0.279 0.00000.450 0.450 0.440 0.00980.500 0.938 0.938 0.0000

例題 4

この例題は関数の 3 次スプライン補間関数を計算して、周期的端点条件、s(a) = s(b)、s’(a) = s’(b)、 s"(a) = s"(b) を付加しますが、 a は最左端横軸座標で、b は最右端横軸座標です。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11 /* 関数を定義 */#define F(x) (float)(sin(x))

main(){ int i; float x, y, twopi, fdata[NDATA], xdata[NDATA]; Imsl_f_ppoly *pp; /* xdata と fdata を計算 */ twopi = 2.0*imsl_f_constant("pi", 0); for (i = 0; i < NDATA; i++) { xdata[i] = twopi*(float)(i)/(NDATA-1); fdata[i] = F(xdata[i]); } fdata[NDATA-1] = fdata[0]; /* 周期的 3次スプライン補間関数を計算 */ pp = imsl_f_cub_spline_interp_e_cnd(NDATA, xdata, fdata, IMSL_PERIODIC, 0); /* 区間の最初の半分の */ /* 結果をプリント */ printf(" x F(x) Interpolant Error\n\n"); for (i = 0; i < NDATA; i++){ x = (twopi/20.)*i; y = imsl_f_cub_spline_value(x, pp, 0); printf(" %6.3f %10.3f %10.3f %10.4f\n",x,F(x), y, fabs(F(x)-y)); }}

出力結果

x F(x) Interpolant Error0.000 0.000 0.000 0.00000.314 0.309 0.309 0.00010.628 0.588 0.588 0.00000.942 0.809 0.809 0.00041.257 0.951 0.951 0.00001.571 1.000 1.000 0.00041.885 0.951 0.951 0.00002.199 0.809 0.809 0.00042.513 0.588 0.588 0.00002.827 0.309 0.309 0.00013.142 -0.000 -0.000 0.0000

Page 146: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

警告エラー

IMSL_NOT_PERIODIC データが周期的ではありません。最右端

の fdata 値が最左端の fdata 値にセット

されます。重大エラー

IMSL_DUPLICATE_XDATA_VALUES xdata 値は区別されなければなりません。

cub_spline_interp_shape形状を保存する 3 次スプラインを計算します。

概要

#include <imsl.h>

Imsl_f_ppoly *imsl_f_cub_spline_interp_shape (int ndata, float xdata[], float fdata[], …, 0)

Imsl_d_ppoly 型関数は、 imsl_d_cub_spline_interp_shapeです。

必要な引数

int ndata ( 入力 )データ点数。

float xdata[] ( 入力 )補間問題の横座標を含む ndata 成分の配列。

float fdata[] ( 入力 )補間問題の縦座標を含む ndata 成分の配列。

戻り値

3 次スプライン補間関数を表現する構造体のポインター。補間関数が計算され

なければ、NULL が返されます。この空間を解放するためには、free を使用

します。

オプション引数の概要

#include <imsl.h>

Imsl_f_ppoly *imsl_f_cub_spline_interp_shape (int ndata,float xdata[], float fdata[], IMSL_CONCAVE,IMSL_CONCAVE_ITMAX, int itmax,0)

オプション引数

IMSL_CONCAVE

データの凹面を保存する 3 次スプライン補間を生成します。

IMSL_CONCAVE_ITMAX, int itmax ( 入力 )このオプションでは、Newton 法の反復の最大数を設定することができ

ます。. デフォルト: itmax = 25.

説明

関数 imsl_f_cub_spline_interp_shape は、i = 0, …, ndata − 1 = n に対する

データ点のセット (xi, fi) の C1 3 次スプライン補間関数を計算します。 このスプ

ラインの区分点は横軸です。この計算は、Akima(1970 年)による手法を基に

しており補間関数での細かな動きを抑えます。端点条件は、プログラムによって自動的決定されます。 Akima (1970 年 ) 又は、 de Boor (1978 年 ) を参照してく

ださい。

オプション引数 IMSL_CONCAVE が指定されると、この関数は 3 次スプライン補

間を計算します。 本来はデータをソートする必要はありませんが、説明を簡素

Page 147: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

化するために、xi < xi+1 であると仮定します。データが完全に凸面の場合、計

算されたスプラインは凸面で、表現を最小化します。

全ての凸面 C1 関数は、データを補間します。 通常、データが凸面、凹面の領

域を持つ時、スプラインの凸面は、データと一致して、上記の微分は適正な制約以下に最小化されます。この補間の考え方に関する詳細は Michelli とその他 (1985 年 ) 、Irvine e とその他 (1986 年 ) を参照してください。

この関数により生成されるスプラインの 1 つの重要な機能は補間結果の区分点

の数を予測できないことです。多くの場合、データの場所以外に区分点が存在します。 データによって示される凸区域と凹区域を保存が重要な時はこの関数

を使用すべきです。

両方の手法は、非線形です。補間関数は、区分的 3 次ですが、3 次多項式は、

再生成されません。 ( しかし、線形多項式は再生成されます。) これで、以下の

ような理論的な誤差推定の説明をします。

データ点が、平滑化関数 f(例えば C4)の値から生じる場合、つまり fi = f(xi)の場合、誤差は予想可能です。 ξ を上記のスプライン補間関数の区分点ベクト

ルとします。 細大絶対誤差は、以下のことを満足します。

ここで

ξm は、最後の区分点です。

この関数の戻り値は、 Imsl_f_ppoly 型のポインターです。呼び出しプログラム

は、 ポインター Imsl_f_ppoly *ppolyにこれを受け取らなければ成りません。. この構造体は、この関数によって計算されたスプライン(区分的多項式として格納されている)を決定する全ての情報を含んでいます。例えば、以下のコードは、x でスプラインを計算し、値を y に返却します。

y = imsl_f_cub_spline_value (x, ppoly, 0)

凸状を保存しているスプラインと Akima のスプラインの違いは、次の様に表

されます。凸状を保存している補間関数が、凸状の制約が拘束されている直線的なセグメントを示すのに注意してください。

Figure 3- 2 Two Shape-Preserving Splines

( )1

2nx

xg ′′∫

[ ]( )

[ ]0 0

22, ,m m

f s C fξ ξ ξ ξ

ξ− ≤

10, , 1: max i ii m

ξ ξ ξ+= −= −

K

Page 148: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

例題 1

この例題では、関数 f に対する 3 次スプライン補間を計算します。このスプラ

インの値は、実際の関数の値と比較されます。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11 /* 関数を定義 */#define F(x) (float)(sin(15.0*x))

main(){ int i; float fdata[NDATA], xdata[NDATA], x, y; Imsl_f_ppoly *pp; /* xdata と fdata を計算 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)(i)/(NDATA-1); fdata[i] = F(xdata[i]); } /* 3 次スプライン補間を計算 */ pp = imsl_f_cub_spline_interp_shape(NDATA, xdata, fdata, 0); /* 結果をプリント */ printf(" x F(x) Interpolant Error\n\n"); for (i = 0; i < 2*NDATA-1; i++) { x = (float) i /(float)(2*NDATA-2); y = imsl_f_cub_spline_value(x, pp, 0); printf(" %6.3f %10.3f %10.3f %10.4f\n", x, F(x), y, fabs(F(x)-y)); }}

出力結果

x F(x) Interpolant Error0.000 0.000 0.000 0.00000.050 0.682 0.818 0.13600.100 0.997 0.997 0.00000.150 0.778 0.615 0.16350.200 0.141 0.141 0.00000.250 -0.572 -0.478 0.09340.300 -0.978 -0.978 0.00000.350 -0.859 -0.812 0.04640.400 -0.279 -0.279 0.00000.450 0.450 0.386 0.06450.500 0.938 0.938 0.00000.550 0.923 0.854 0.06830.600 0.412 0.412 0.00000.650 -0.320 -0.276 0.04330.700 -0.880 -0.880 0.00000.750 -0.968 -0.889 0.07890.800 -0.537 -0.537 0.00000.850 0.183 0.149 0.03380.900 0.804 0.804 0.00000.950 0.994 0.932 0.06131.000 0.650 0.650 0.0000

例題 2

この例題では、関数 f に対する 3 次スプライン補間を計算します。このスプラ

インの値は、実際の関数の値と比較されます。

#include <imsl.h>#include <stdio.h>#include <math.h>

Page 149: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#define NDATA 11 /* 関数を定義 */#define F(x) (float)(sin(15.0*x))

main(){ int i; float fdata[NDATA], xdata[NDATA], x, y; Imsl_f_ppoly *pp; /* xdata と fdataを計算 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)(i)/(NDATA-1); fdata[i] = F(xdata[i]); } /* 3 次スプライン補間を計算 */ pp = imsl_f_cub_spline_interp_shape(NDATA, xdata, fdata, IMSL_CONCAVE, 0); /* 結果をプリント */ printf(" x F(x) Interpolant Error\n\n"); for (i = 0; i < 2*NDATA-1; i++){ x = (float) i /(float)(2*NDATA-2); y = imsl_f_cub_spline_value(x, pp, 0); printf(" %6.3f %10.3f %10.3f %10.4f\n", x, F(x), y, fabs(F(x)-y)); }}

出力結果

x F(x) Interpolant Error0.000 0.000 0.000 0.00000.050 0.682 0.667 0.01500.100 0.997 0.997 0.00000.150 0.778 0.761 0.01720.200 0.141 0.141 0.00000.250 -0.572 -0.559 0.01260.300 -0.978 -0.978 0.00000.350 -0.859 -0.840 0.01890.400 -0.279 -0.279 0.00000.450 0.450 0.440 0.00980.500 0.938 0.938 0.00000.550 0.923 0.902 0.02080.600 0.412 0.412 0.00000.650 -0.320 -0.311 0.00860.700 -0.880 -0.880 0.00000.750 -0.968 -0.952 0.01560.800 -0.537 -0.537 0.00000.850 0.183 0.200 0.01740.900 0.804 0.804 0.00000.950 0.994 0.892 0.10201.000 0.650 0.650 0.0000

警告エラー

IMSL_MAX_ITERATIONS_REACHED 反復の最大数に達しました。最良の近似

を返却します。

重大エラー

IMSL_DUPLICATE_XDATA_VALUES xdata の値が同じではいけません。

cub_spline_value3 次スプラインの値、或いは、導関数の値を計算します。

Page 150: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

概要

#include <imsl.h>

float imsl_f_cub_spline_value (float x, Imsl_f_ppoly *ppoly, …, 0)double 型関数は、imsl_d_cub_spline_valueです。

必要な引数

float x ( 入力 )3 次スプラインの計算点。

Imsl_f_ppoly *ppoly ( 入力 )3 次スプラインを表わす区分的多項式構造体のポインター。

戻り値

3 次スプラインの値、或いは、点 x の微係数の1つの値。値が計算出来ない場

合、NaN が返されます。

オプション引数の概要

#include <imsl.h>float imsl_f_cub_spline_value (float x, Imsl_f_ppoly *ppoly,

IMSL_DERIV, int deriv, IMSL_GRID, int n, float *xvec, float **value,IMSL_GRID_USER, int n, float *xvec, float value_user[],0)

オプション引数

IMSL_DERIV, int deriv ( 入力 ) d = deriv として s を構造体 *ppolyによって表現される3次スプライ

ンとすると、このオプションは x における s の d 次微係数 s (d) (x) を生成します。

IMSL_GRID, int n, float *xvec, float **value ( 入力 / 出力 )長さ n の配列 xvec は 3 次スプラインが計算される点を含みます。

xvecの中の点におけるスプラインの d 次微係数が value に返されま

す。

IMSL_GRID_USER, int n, float *xvec, float value_user[] ( 入力 / 出力 )長さ n の配列 xvec は 3 次スプラインが計算される点を含みます。

xvec の中の点におけるスプラインの d- 次微係数がユーザ提供の空間 value_user に返されます。

説明

関数 imsl_f_cub_spline_value は 3 次スプラインの値、或いは、その微係

数の 1 つを計算します。この 3 次スプラインの最初と最後の区分は外挿されま

す。その結果、この 3 次スプラインルーチンによって返される 3 次スプライン

構造体は定義され、全体の実線上で評価する事が出来ます。このルーチンは de Boor (1978 年、89 ページ ) によるルーチン PPVALU に基づいています。

例題

例題 1

この例では、関数 f の 3 次スプライン補間関数が計算されます。このスプライ

ンの値はそれから正確な関数値と比較されます。デフォルト設定が使用されているので、この補間関数は「ノットは無い」条件で決定されます ( de Boor 1978 年を参照 )。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11 /* 関数を定義 */

Page 151: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#define F(x) (float)(sin(15.0*x))

main(){ int i; float fdata[NDATA], xdata[NDATA], x, y; Imsl_f_ppoly *pp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]); } /* 3 次スプライン補間を計算 */ pp = imsl_f_cub_spline_interp_e_cnd (NDATA, xdata, fdata, 0); /* 結果をプリント */ printf(" x F(x) Interpolant Error\n"); for (i = NDATA/2; i < 3*NDATA/2; i++) { x = (float) i /(float)(2*NDATA-2); y = imsl_f_cub_spline_value(x, pp, 0); printf(" %6.3f %10.3f %10.3f %10.4f\n", x, F(x), y, fabs(F(x)-y)); }}

出力結果

x F(x) Interpolant Error0.250 -0.572 -0.549 0.02280.300 -0.978 -0.978 0.00000.350 -0.859 -0.843 0.01620.400 -0.279 -0.279 0.00000.450 0.450 0.441 0.00930.500 0.938 0.938 0.00000.550 0.923 0.903 0.01990.600 0.412 0.412 0.00000.650 -0.320 -0.315 0.00490.700 -0.880 -0.880 0.00000.750 -0.968 -0.938 0.0295

例題 2

最初の例題を呼び出して関数 f の補間関数を計算します。このスプラインの値

を正確な関数値と比較します。この例題は 1 次微係数を比較します。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11 /* 関数を定義 */#define F(x) (float)(sin(15.0*x))#define FP(x) (float)(15.*cos(15.0*x))

main(){ int i; float fdata[NDATA], xdata[NDATA], x, y; Imsl_f_ppoly *pp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]); } /* 3 次スプライン補間を計算 */ pp = imsl_f_cub_spline_interp_e_cnd (NDATA, xdata,fdata, 0); /* 結果をプリント */ printf(" x FP(x) Interpolant Deriv Error\n"); for (i = NDATA/2; i < 3*NDATA/2; i++){ x = (float) i /(float)(2*NDATA-2);

Page 152: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

y = imsl_f_cub_spline_value(x, pp, IMSL_DERIV, 1, 0); printf(" %6.3f %10.3f %10.3f %10.4f\n", x, FP(x), y, fabs(FP(x)-y)); }}

出力結果

x FP(x) Interpolant Deriv Error0.250 -12.308 -12.559 0.25100.300 -3.162 -3.218 0.05600.350 7.681 7.796 0.11510.400 14.403 13.919 0.48330.450 13.395 13.530 0.13460.500 5.200 5.007 0.19260.550 -5.786 -5.840 0.05350.600 -13.667 -13.201 0.46600.650 -14.214 -14.393 0.17980.700 -7.133 -6.734 0.39900.750 3.775 3.911 0.1359

cub_spline_integral3 次スプラインの積分を計算します。

概要

#include <imsl.h>

float imsl_f_cub_spline_integral (float a, float b, Imsl_f_ppoly *ppoly) double 型関数は、 imsl_d_cub_spline_integralです。

必要な引数

float a ( 入力 )

float b ( 入力 )積分のための端点。

Imsl_f_ppoly *ppoly ( 入力 )3 次スプラインを表す区分的多項式構造体のポインター。

戻り値

積分。値が計算されない場合、NaN が返されます。

説明

関数 imsl_f_cub_spline_integral は、a から b への 3 次スプラインの積分

を計算します。

例題

この例題では、関数 f に対する 3 次スプライン補間関数を計算します。このス

プラインの積分の値は、実際の積分の値と比較されます。フォルト設定が使用されているので、この補間関数は「ノットは無い」条件で決定されます ( de Boor 1978 年 )。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 21

( )b

as x dx∫

Page 153: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* 関数を定義 */#define F(x) (float)(sin(15.0*x)) /* 0 から x まで積分 */#define FI(x) (float)((1.-cos(15.0*x))/15.)

main(){ int i; float fdata[NDATA], xdata[NDATA], x, y; Imsl_f_ppoly *pp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]); } /* 3 次スプライン補間を計算 */ pp = imsl_f_cub_spline_interp_e_cnd (NDATA, xdata, fdata, 0); /* 結果をプリント */ printf(" x FI(x) Interpolant Integral Error\n"); for (i = NDATA/2; i < 3*NDATA/2; i++){ x = (float) i /(float)(2*NDATA-2); y = imsl_f_cub_spline_integral(0.0, x, pp); printf(" %6.3f %10.3f %10.3f %10.4f\n", x, FI(x), y, fabs(FI(x)-y)); }}

出力結果

x FI(x) Interpolant Integral Error0.250 0.121 0.121 0.00010.275 0.104 0.104 0.00010.300 0.081 0.081 0.00010.325 0.056 0.056 0.00010.350 0.033 0.033 0.00010.375 0.014 0.014 0.00020.400 0.003 0.003 0.00020.425 0.000 0.000 0.00020.450 0.007 0.007 0.00020.475 0.022 0.022 0.00010.500 0.044 0.044 0.00010.525 0.068 0.068 0.00010.550 0.092 0.092 0.00010.575 0.113 0.113 0.00010.600 0.127 0.128 0.00010.625 0.133 0.133 0.00010.650 0.130 0.130 0.00010.675 0.118 0.118 0.00010.700 0.098 0.098 0.00010.725 0.075 0.075 0.00010.750 0.050 0.050 0.0001

spline_interpスプライン補間関数を計算します。

概要

#include <imsl.h>

Imsl_f_spline *imsl_f_spline_interp (int ndata, float xdata[], float fdata[], …, 0)

Imsl_d_spline 型関数は、 imsl_d_spline_interpです。

Page 154: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

int ndata ( 入力 )データ点数。

float xdata[] ( 入力 )補間問題の横軸を含む ndata 成分の配列。

float fdata[] ( 入力 )補間問題の縦軸を含む ndata 成分の配列。

戻り値

スプライン補間関数を表現する構造体のポインター。値が計算できない場合,NaN が返されます。この空間を解放するためには free を使用します。

オプション引数の概要

#include <imsl.h>Imsl_f_spline *imsl_f_spline_interp (int ndata, float xdata[],

float fdata[], IMSL_ORDER, int order, IMSL_KNOTS, float knots[], 0)

オプション引数

IMSL_ORDER, int order ( 入力 )ノットが必要なスプライン部分空間の階数。このオプションはスプライン部分空間の階数を通信するために使用します。デフォルト: order = 4、これは 3 次スプラインです。

IMSL_KNOTS, float knots[] ( 入力 )このオプションはユーザがノットを提供するために必要です。デフォルト: ノットはそのデフォルトを使用する関数

imsl_f_spline_knots によって選択されます。

説明

データ点 x = xdata、f = fdataと、xdata と fdata の要素の数 n = ndata が与えられて、imsl_f_spline_interp のデフォルト操作は imsl_f_spline_knots により生成されるデフォルトノット順を使用してデー

タの 3 次 (k = 4) スプライン補間関数 s を計算します。

オプション引数 IMSL_ORDER でスプライン補間関数の階数を選択することが

出来ます。オプション引数 IMSL_KNOTS はノットの指定が出来ます。

関数 imsl_f_spline_interp は de Boor (1978 年、p. 204) によるルーチン SPLINT を基にしています。

最初に imsl_f_spline_interp は、xdata ベクトルをソートして x に結果を

格納します。fdata ベクトルの要素は、適切に置換されて、 i = 0 から n − 1 に対して同等なデータ (xi, fi) を生成する f に保存されます。

次の事前チエックがこのデータに実行される。次式を検証します。

xi < xi+1 i = 0, …, n − 2

ti < ti+k i = 0, …., n − 1

ti < ti+1 i = 0, …, n + k − 2

最初の検定は横軸が区別されていることを知るためにチエックします。2 番目

と 3 番目の不等式は正当なノット順が指定されていることを検定します。

• 補間行列が非特異であるためには、i = 0 から n − 1 に対して、tk-1 ≤ xi ≤ tn をチエックします。補間行列の入力値を生成するために使用するこの方法が xi, で k のこの可能な非ゼロ B- スプラインを要求するので、最終チ

エックの最初の 不等式は、xi, で k のこの可能な非ゼロ B- スプラインを

要求するので必要です、

Page 155: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Bj-i+1k+1, …, Bj ここで j は tj ≤ xi < tj+1 を満足します。

は良好に定義されます ( これは、 j − k + 1 ≥ 0).

スプライン補間における誤差の正確な挙動についての一般条件は知られていま

せんが、t と x が適切に選択されて、データ点が平滑 ( C k とする ) 関数 f、 即ち fi = f(x i ) の値から生じるならば、誤差は予想できるように挙動します。 そ

の最大の絶対誤差は次式を満足します

ここで

この問題の更に詳しい情報は de Boor (1978 年、第 13 章 ) と彼の文献を参照し

てください。 IMSL 関数 imsl_f_cub_spline_interpの代わりにこの関数が使

用されます。de Boor (1978 年、 da, Chapter 13) 。

この関数の戻り値は Imsl_f_spline 型のポインターです。呼び出しプログラムは

ポインター Imsl_f_spline *spの中にこれを受け取らなければなりません。この

構造体は関数によって計算されるスプライン(B- スプラインの線形組み合わ

せとして格納される) を決定する全ての情報を含んでいます。例えば、次の

コード列は x でこのスプラインを計算して y にこの値を返します。

y = imsl_f_spline_value (x, sp, 0)

階数 2、3、5 の 3 つのスプライン補間関数がプロットされます。これらのスプ

ラインはデフォルトのノットを使用します。

Figure 3- 3 Three Spline Interpolants

例題 1

この例題では、関数 f の 3 次スプライン補間関数を計算します。このスプライ

ンの値を、正確な関数値と比較します。デフォルトの設定が使用されるので、この補間関数は「ノットは無い」条件によって決定されます ( de Boor 1978 年を参照してください )。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11 /* 関数を定義 */

[ ]( )

[ ]1 1, ,k n k n

kkf s C f− −

− ≤t t t t

t

11, , 1: max i ii k n += − −= −t t t

K

Page 156: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#define F(x) (float)(sin(15.0*x))

main(){ int i; float xdata[NDATA], fdata[NDATA], x, y; Imsl_f_spline *sp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]); } /* 3 次スプライン補間を計算 */ sp = imsl_f_spline_interp (NDATA, xdata, fdata, 0); /* 結果をプリント */ printf(" x F(x) Interpolant Error\n"); for (i = 0; i < 2*NDATA-1; i++){ x = (float) i /(float)(2*NDATA-2); y = imsl_f_spline_value(x, sp, 0); printf(" %6.3f %10.3f %10.3f %10.4f\n", x, F(x), y, fabs(F(x)-y)); }}

出力結果

x F(x) Interpolant Error0.000 0.000 0.000 0.00000.050 0.682 0.809 0.12700.100 0.997 0.997 0.00000.150 0.778 0.723 0.05520.200 0.141 0.141 0.00000.250 -0.572 -0.549 0.02280.300 -0.978 -0.978 0.00000.350 -0.859 -0.843 0.01620.400 -0.279 -0.279 0.00000.450 0.450 0.441 0.00930.500 0.938 0.938 0.00000.550 0.923 0.903 0.01990.600 0.412 0.412 0.00000.650 -0.320 -0.315 0.00490.700 -0.880 -0.880 0.00000.750 -0.968 -0.938 0.02950.800 -0.537 -0.537 0.00000.850 0.183 0.148 0.03470.900 0.804 0.804 0.00000.950 0.994 1.086 0.09261.000 0.650 0.650 0.0000

例題 2

この最初の例題と同じように、関数 f の 3 次スプライン補間関数が計算されま

す。それからこのスプラインの値を正確な関数値と比較します。この例題は、デフォルト値の代わりにこのデータに 2 次 (k = 3) と 5 次 (k = 6) スプライン

補間関数を使用することを選択します。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11 /* 関数を定義 */#define F(x) (float)(sin(15.0*x))

main(){ int i, order; float fdata[NDATA], xdata[NDATA], x, y; Imsl_f_spline *sp;

Page 157: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]); } for (order =3; order<7; order += 3) { /* 3次スプラインを計算 */ sp = imsl_f_spline_interp (NDATA, xdata, fdata, IMSL_ORDER, order, 0); /* 結果をプリント */ printf("\nThe order of the spline is %d\n", order); printf(" x F(x) Interpolant Error\n"); for (i = NDATA/2; i < 3*NDATA/2; i++){ x = (float) i /(float)(2*NDATA-2); y = imsl_f_spline_value(x,sp,0); printf(" %6.3f %10.3f %10.3f %10.4f\n", x, F(x), y, fabs(F(x)-y)); } }}

出力結果

The order of the spline is 3 x F(x) Interpolant Error 0.250 -0.572 -0.542 0.0299 0.300 -0.978 -0.978 0.0000 0.350 -0.859 -0.819 0.0397 0.400 -0.279 -0.279 0.0000 0.450 0.450 0.429 0.0210 0.500 0.938 0.938 0.0000 0.550 0.923 0.879 0.0433 0.600 0.412 0.412 0.0000 0.650 -0.320 -0.305 0.0149 0.700 -0.880 -0.880 0.0000 0.750 -0.968 -0.922 0.0459

The order of the spline is 6 x F(x) Interpolant Error 0.250 -0.572 -0.573 0.0016 0.300 -0.978 -0.978 0.0000 0.350 -0.859 -0.856 0.0031 0.400 -0.279 -0.279 0.0000 0.450 0.450 0.448 0.0020 0.500 0.938 0.938 0.0000 0.550 0.923 0.922 0.0003 0.600 0.412 0.412 0.0000 0.650 -0.320 -0.322 0.0025 0.700 -0.880 -0.880 0.0000 0.750 -0.968 -0.959 0.0090

警告エラー

IMSL_ILL_COND_INTERP_PROB この補間行列は悪条件です。この解は不

正確の可能性があります。

重大エラー

IMSL_DUPLICATE_XDATA_VALUES xdata の値は区別されなければなりま

せん。

IMSL_KNOT_MULTIPLICITY ノットの多重度はこのスプラインの階数

を超えることは出来ません。

IMSL_KNOT_NOT_INCREASING ノットは非減少でなければなりません。

Page 158: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_KNOT_XDATA_INTERLACING xdata (xj) の i- 番目の最小要素は、t がノット列である tj ≤ xj < tj+order を満足し

なければなりません。

IMSL_XDATA_TOO_LARGE 配列 xdata は i = 1, ..., ndata に対し

て xdataj ≤ tndata, を満足しなければなり

ません。

IMSL_XDATA_TOO_SMALL 配列 xdata は i = 1, ..., ndata に対して

xdatai ≥ torder-1 を満足しなければなりませ

ん。

spline_knotsスプライン補間関数のためのノットを計算します。

概要

#include <imsl.h>

float *imsl_f_spline_knots (int ndata, float xdata[], …, 0) double 型関数は、 imsl_d_spline_knotsです。

必要な引数

int ndata ( 入力 )データ点数。

float xdata[] ( 入力 )補間問題の横軸を含む ndata 成分の配列。

戻り値

ノットへのポインター。ノットが計算できない場合、NULL が返されます。空

間を開放するには、free を使用します。

オプション引数の概要

#include <imsl.h> float *imsl_f_spline_knots (int ndata, float xdata[],

IMSL_ORDER, int order, IMSL_OPT, IMSL_OPT_ITMAX, int itmax, IMSL_RETURN_USER, float knots[], 0)

オプション引数

IMSL_ORDER, int order ( 入力 )ノットが必要なスプライン部分空間の階数。このオプションはスプライン部分空間の階数を通信するために使用します。デフォルト: order = 4 これは、3次スプラインです。

IMSL_OPT最適性基準を満足するノットを生成します。

IMSL_OPT_ITMAX, int itmax ( 入力 )Newton 法の最大反復回数を設定できます。

デフォルト: itmax = 10

IMSL_RETURN_USER, float knots[] ( 出力 )返却するノットのための空間を提供する必要があります。例えば、ユーザは、 float knots[100]; と宣言し、knotsのなかに渡します。 戻り値は、knotsに設定されます。

Page 159: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

データ点を x = xdata、スプラインの階数を k = order、xdata内の要素数を n = ndata とすると、デフォルトでは関数 imsl_f_spline_knots は、k 階数

(デフォルト階数は、k = 4)のスプラインによる x 上のデータの補間に適した

ノット列へのポインターを返します。ノット列は、初めの n + k の位置に含ま

れます。 k が同等の場合、入力ベクトル x 内の入力は増加し、結果のノット列 t は、次の様に返されます。

tj = x0 for i = 0, …, k − 1

tj = xj-k/2-1for i = k, …, n − 1

tj = xn-1 for i = n, …, n + k − 1

de Boor (1978 年、 211 ページ ) の中にノットの選択に関する記述があります。 k が奇数の場合、 t は次の様に返されます。

xdataの値をソートする必要はありません。

IMSL_OPT オプションを選択すると、ノット列は、誤差推定値の定数 c を最小

化します。

||f − s|| ≤ c|| f (k)||

上記の公式では、f は Ck 内の関数、s はノット列 t の横軸 x での f に対す

るスプライン補間関数です。

このアルゴリズムは、Micchelli とその他 (1976 年 ) の定理を基にした de Boor(1978 年、204 ページ)で説明されているルーチンを基にしています。

例題

例題 1

この例題では、3次スプラインのためのノットが、生成・表示されます。 ノッ

トは端点で積み重ねられることと、最後と最後から1つ前のデータ点はノットではないことに注意してください。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 6

main(){ int i; float *knots, xdata[NDATA];

for(i = 0; i < NDATA; i++) xdata[i] = i; knots = imsl_f_spline_knots(NDATA, xdata, 0); imsl_f_write_matrix("The knots for the cubic spline are:\n", 1, NDATA+4, knots, IMSL_COL_NUMBER_ZERO, 0);}

出力結果

The knots for the cubic spline are:

0 1 2 3 4 5

0

1 21 12 2

1

for 0, , 1( ) / 2 for , , 1

for , , 1

i

i k ki i

i n

x i kx x i k n

x i n n k

− −− − − −

= = −

= + = −

= = = −

tt

t

K

K

K

Page 160: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

0 0 0 0 2 3 6 7 8 9 5 5 5 5

例題 2

これは imsl_f_spline_interpの例題の続きです。 関数 f の3次スプライン補

間関数が最初に計算されます。このスプラインの値は、実際の関数の値と比較されます。2番目の例題では、 quadratic (k = 3) と quintic (k = 6) のスプライン補

間関数を使用します。今回は、デフォルトのノットを使用する代わりに、上で説明しているような「最適な」ノットを選択します。この場合、実際には誤差が大きくなることに注意してください。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11 /* 関数を定義 */#define F(x) (float)(sin(15.0*x))

main(){ int i, order; float fdata[NDATA], xdata[NDATA], *knots, x, y; Imsl_f_spline *sp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]); } for(order = 3; order < 7; order += 3) { knots = imsl_f_spline_knots(NDATA, xdata, IMSL_ORDER, order, IMSL_OPT, 0); /* スプライン補間を計算 */ sp = imsl_f_spline_interp (NDATA, xdata,fdata, IMSL_ORDER, order, IMSL_KNOTS, knots, 0); /* 結果をプリント */ printf("\nThe order of the spline is %d\n", order); printf(" x F(x) Interpolant Error\n"); for (i = NDATA/2; i < 3*NDATA/2; i++) { x = (float) i /(float)(2*NDATA-2); y = imsl_f_spline_value(x, sp, 0); printf(" %6.3f %10.3f %10.3f %10.4f\n", x, F(x), y, fabs(F(x)-y)); } }}

出力結果

The order of the spline is 3 x F(x) Interpolant Error 0.250 -0.572 -0.543 0.0290 0.300 -0.978 -0.978 0.0000 0.350 -0.859 -0.819 0.0401 0.400 -0.279 -0.279 0.0000 0.450 0.450 0.429 0.0210 0.500 0.938 0.938 0.0000 0.550 0.923 0.879 0.0433 0.600 0.412 0.412 0.0000 0.650 -0.320 -0.305 0.0150 0.700 -0.880 -0.880 0.0000 0.750 -0.968 -0.920 0.0478

Page 161: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

The order of the spline is 6 x F(x) Interpolant Error 0.250 -0.572 -0.578 0.0061 0.300 -0.978 -0.978 0.0000 0.350 -0.859 -0.854 0.0054 0.400 -0.279 -0.279 0.0000 0.450 0.450 0.448 0.0019 0.500 0.938 0.938 0.0000 0.550 0.923 0.920 0.0022 0.600 0.412 0.412 0.0000 0.650 -0.320 -0.317 0.0020 0.700 -0.880 -0.880 0.0000 0.750 -0.968 -0.966 0.0023

警告エラー

IMSL_NO_CONV_NEWTON Newton 法の反復が収束しません。

重大エラー

IMSL_DUPLICATE_XDATA_VALUES xdata の値は区別されなければなりま

せん。

IMSL_ILL_COND_LIN_SYS 補間行列は、特異です。 xdata の値が、

近すぎるかもしれません。

spline_2d_interp2 次元のテンソル積データから 2 次元、テンソル積スプライン補間を計算しま

す。

概要

#include <imsl.h>

Imsl_f_spline *imsl_f_spline_2d_interp (int num_xdata, float xdata[], int num_ydata, float ydata[], float fdata[], …, 0)

Imsl_d_spline 型関数は、 imsl_d_spline_2d_interpです。

必要な引数

int num_xdata ( 入力 ) X 方向のデータ点数。

float xdata[] ( 入力 ) X 方向のデータ点を含む num_xdata要素を持った配列。

int num_ydata ( 入力 ) Y 方向のデータ点数。

float ydata[] ( 入力 )Y 方向のデータ点を含む num_ydata要素を持った配列。

float fdata[] ( 入力 )補完される値を含むサイズ num_xdata × num_ydata の配列。 fdata[i][j] は、(xdata[i], ydata[j]) での値です。

戻り値

テンソル積スプライン補間を表す構造体へのポインター。補間関数が計算できない場合、NULL が返されます。空間を開放するには、free を使用します。

オプション引数の概要

#include <imsl.h> Imsl_f_spline *imsl_f_spline_2d_interp (int num_xdata, float xdata[], int num_ydata, float

ydata[], float fdata[],

Page 162: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_ORDER, int xorder, int yorder, IMSL_KNOTS, float xknots[], float yknots[], IMSL_FDATA_COL_DIM, int fdata_col_dim, 0)

オプション引数

IMSL_ORDER, int xorder, int yorder ( 入力 )このオプションはスプライン部分空間の階数を通信するために使用します。デフォルト: xorder, yorder = 4, ( すなわち、テンソル積3次スプラ

イン )。

IMSL_KNOTS, float xknots[], float yknots[] ( 入力 )このオプションでは、ユーザはノットを提供する必要があります。デフォルトノットは、関数 imsl_f_spline_knotsによって選択されま

す。

IMSL_FDATA_COL_DIM, int fdata_col_dim ( 入力 )行列 fdataの列ディメンジョン。

デフォルト: fdata_col_dim = num_ydata

説明

関数 imsl_f_spline_2d_interp は、テンソル積スプライン補間を計算しま

す。 0 ≤ i ≤ nx − 1 と 0 ≤ j ≤ ny − 1 であるデータ {(xj, yj, fjj)} のテンソル積スプラ

イン補間は、次の形式をもっています。

ここで kx と ky は、スプラインの階数です。この数は、デフォルトでは 4 に設

定されていますが、IMSL_ORDERキーワードを使って、どの正の整数の値にで

も変更することが可能です。同様に、 tx と ty は、対応するノット列 (xknots と yknots) です。これらの値は、 imsl_f_spline_knotsで返されるノットがデ

フォルトとして設定されています。アルゴリズムは、次のことを必要としています。

tx(kx − 1) ≤ xi ≤ tx(nx) 0 ≤ i ≤ nx − 1

ty(ky − 1) ≤ yj ≤ ty(ny − 1) 0 ≤ j ≤ ny − 1

2 次元のテンソル積スプライン補間は、2 つの単変量補間問題を(繰り返し)

解くことにより、非常に効率的に計算することができます。

理由は、以下の通りです。方程式を解く必要があります。

次の様にセットします。

0 から nx − 1 間での固定の i のために、以下のように , 未知の数と同じだけの

ny 線形方程式があることに注意してください。

( ) ( )1 1

, , , ,0 0

y x

x x y y

n n

nm n k m km n

c B x B y− −

= =∑ ∑ t t

( ) ( )1 1

, , , ,0 0

y x

x x y y

n n

nm n k i m k j ijm n

c B x B y f− −

= =

=∑ ∑ t t

( )1, ,0

x

x x

nmi nm n k in

h c B x−

== ∑ t

( )1

, ,0

y

y y

n

mi m k i ijm

h B y f−

=

=∑ t

Page 163: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

次の様にセットします。

1 から nx − 1 までのそれぞれ固定された i のために、以下のように , 未知の数と

同じだけの ny − 1 線形方程式があることに注意してください。

上記全ての方程式に、同じ行列が現れます。

従って、1 回だけこの行列を因子分解し、この因子分解を nx 右辺に適用させ

ます。一旦、これが完了すると、 hmi が計算され、次の関係を使用して係数 cnm を解きます。

m は、 0 から ny − 1 で、1 つの因数分解と異なる右辺に対する ny の解が含まれ

ます。関数 imsl_f_spline_2d_interp は、de Boor (1978 年、 347 ページ ) による SPLI2D ルーチンを基にしています。

この関数の戻り値は、構造体 imsl_f_splineへのポインターです。呼び出しプ

ログラムは、ポインター imsl_f_spline *spで受け取る必要があります。こ

の構造体は、スプライン(B スプライン形式で保存)を決定する全ての情報を

含んでいます。例えば、次のコードでは、 (x,y) でのスプラインを評価し、値を z に返します。

z = imsl_f_spline_2d_value (x, y, sp, 0);

例題

例題 1

この例題では、関数 f のテンソル積補間を計算します。補間の値と 4 × 4 グ

リッドに誤差を表示します。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11#define OUTDATA 2 /* 関数を定義 */#define F(x, y) (float)(x*x*x+y*y)

main(){ int i, j, num_xdata, num_ydata; float fdata[NDATA][NDATA], xdata[NDATA], ydata[NDATA]; float x, y, z; Imsl_f_spline *sp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = ydata[i] = (float)i / ((float)(NDATA-1));

( ) ( )1 1

, , , ,0 0

y x

x x y y

n n

nm n k i m k j ijm n

c B x B y f− −

= =

=∑ ∑ t t

( )1, ,0

x

x x

nmi nm n k in

h c B x−

== ∑ t

( )1

, ,0

y

y y

n

mi m k i ijm

h B y f−

=

=∑ t

( ), , 1 , 1y ym k j yB y m j n ≤ ≤ − t

( )1

, ,0

x

x x

n

nm n k i min

c B x h−

=

=∑ t

Page 164: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

} for (i = 0; i < NDATA; i++) { for (j = 0; j < NDATA; j++) { fdata[i][j] = F(xdata[i], ydata[j]); } } num_xdata = num_ydata = NDATA; /* テンソル積補間を計算 */ sp = imsl_f_spline_2d_interp(num_xdata, xdata, num_ydata, ydata, fdata, 0); /* 結果をプリント */ printf(" x y F(x, y) Interpolant Error \n"); for (i = 0; i < OUTDATA; i++) { x = (float) i / (float) (OUTDATA); for (j = 0; j < OUTDATA; j++) { y = (float) j / (float) (OUTDATA); z = imsl_f_spline_2d_value(x, y, sp, 0); printf(" %6.3f %6.3f %10.3f %10.3f %10.4f\n", x, y, F(x,y), z, fabs(F(x,y)-z)); } }}

出力結果

x y F(x, y) Interpolant Error0.000 0.000 0.000 0.000 0.00000.000 0.500 0.250 0.250 0.00000.500 0.000 0.125 0.125 0.00000.500 0.500 0.375 0.375 0.0000

例題 2

最初の例題のように、関数 f のテンソル積スプライン補間を計算します。補間

関数の値と 誤差を 4 × 4グリッドで表示します。 order = 3 を使った最初の補間

関数は、3 次データを生成せずに、order = 6 を使った 2 番目の補間関数は

データを生成することに注意してください。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 7#define OUTDATA 4 /* 関数を定義 */#define F(x,y) (float)(x*x*x+y*y)

main(){ int i, j, num_xdata, num_ydata, order; float fdata[NDATA][NDATA], xdata[NDATA], ydata[NDATA]; float x, y, z; Imsl_f_spline *sp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = ydata[i] = (float) i / ((float) (NDATA - 1)); } for (i = 0; i < NDATA; i++) { for (j = 0; j < NDATA; j++) { fdata[i][j] = F(xdata[i], ydata[j]); } } num_xdata = num_ydata = NDATA;

for(order = 3; order < 7; order += 3) { /* テンソル積補間を計算 */ sp = imsl_f_spline_2d_interp(num_xdata, xdata, num_ydata, ydata, fdata, IMSL_ORDER, order, order, 0); /* 結果をプリント */ printf("\nThe order of the spline is %d \n", order);

Page 165: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

printf(" x y F(x, y) Interpolant Error\n"); for (i = 0; i < OUTDATA; i++) { x = (float) i / (float) (OUTDATA); for (j = 0; j < OUTDATA; j++) { y = (float) j / (float) (OUTDATA); z = imsl_f_spline_2d_value(x, y, sp, 0); printf(" %6.3f %6.3f %10.3f %10.3f %10.4f \n", x, y, F(x,y), z, fabs(F(x,y)-z)); } } }}

出力結果

The order of the spline is 3 x y F(x, y) Interpolant Error 0.000 0.000 0.000 0.000 0.0000 0.000 0.250 0.062 0.063 0.0000 0.000 0.500 0.250 0.250 0.0000 0.000 0.750 0.562 0.562 0.0000 0.250 0.000 0.016 0.016 0.0002 0.250 0.250 0.078 0.078 0.0002 0.250 0.500 0.266 0.266 0.0002 0.250 0.750 0.578 0.578 0.0002 0.500 0.000 0.125 0.125 0.0000 0.500 0.250 0.188 0.188 0.0000 0.500 0.500 0.375 0.375 0.0000 0.500 0.750 0.688 0.687 0.0000 0.750 0.000 0.422 0.422 0.0002 0.750 0.250 0.484 0.484 0.0002 0.750 0.500 0.672 0.672 0.0002 0.750 0.750 0.984 0.984 0.0002

The order of the spline is 6 x y F(x, y) Interpolant Error 0.000 0.000 0.000 0.000 0.0000 0.000 0.250 0.062 0.063 0.0000 0.000 0.500 0.250 0.250 0.0000 0.000 0.750 0.562 0.562 0.0000 0.250 0.000 0.016 0.016 0.0000 0.250 0.250 0.078 0.078 0.0000 0.250 0.500 0.266 0.266 0.0000 0.250 0.750 0.578 0.578 0.0000 0.500 0.000 0.125 0.125 0.0000 0.500 0.250 0.188 0.188 0.0000 0.500 0.500 0.375 0.375 0.0000 0.500 0.750 0.688 0.688 0.0000 0.750 0.000 0.422 0.422 0.0000 0.750 0.250 0.484 0.484 0.0000 0.750 0.500 0.672 0.672 0.0000 0.750 0.750 0.984 0.984 0.0000

警告エラー

IMSL_ILL_COND_INTERP_PROB この補間行列は悪条件です。この解は不正

確な可能性があります。

重大エラー

IMSL_XDATA_NOT_INCREASING xdata の値は、完全に増加でなければなりませ

ん。

IMSL_YDATA_NOT_INCREASING ydata の値は、完全に増加でなければなり

ません。

IMSL_KNOT_MULTIPLICITY ノットの多重度はこのスプラインの階数を

超えることは出来ません。

IMSL_KNOT_NOT_INCREASING ノットは非減少でなければなりません。

Page 166: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_KNOT_DATA_INTERLACING データ配列xdata と ydataの i 番目の最小

要素は、t がノット列である

ti ≤ datai < ti+order を満足しなければな

りません。

IMSL_DATA_TOO_LARGE データ配列 xdata と ydata は、i = 1, …, num_dataの場合にdatai ≤ tnum_dataを満

足しなければなりません。

IMSL_DATA_TOO_SMALL データ配列 xdata と ydata は、i = 1, …, num_dataの場合に datai ≥ torder-1 を満

足しなければなりません。

spline_valueスプラインの値、又は、その微係数の値を計算します。

概要

#include <imsl.h>

float imsl_f_spline_value (float x, Imsl_f_spline *sp, …, 0)double 型関数は、imsl_d_spline_valueです。

必要な引数

float x ( 入力 )スプラインの点を計算します。

Imsl_f_spline *sp ( 入力 )このスプラインを表現する構造体のポインター。

戻り値

スプラインの値、又は、点 x のその微係数の 1 つの値。値が計算出来ない場

合、NaN が返されます。

オプション引数の概要

#include <imsl.h>float imsl_f_spline_value (float x, Imsl_f_spline *sp,

IMSL_DERIV, int deriv, IMSL_GRID, int n, float *xvec, float **value,IMSL_GRID_USER, int n, float *xvec, float value_user[],0)

オプション引数

IMSL_DERIV, int deriv ( 入力 )d = deriv として s を構造体 *sp によって表現されるスプラインとし

ます。するとこのオプションは x での s の d 次微係数 s (d)(x) を生成し

ます。デフォルト: deriv = 0

IMSL_GRID, int n, float *xvec, float **value ( 入力 / 出力 )引数 xvec は、スプラインが計算される点を含む長さ n の配列です。

xvec の中の点でのスプラインの d- 次微係数は value に返されます。

IMSL_GRID_USER int n, float *xvec, float value_user[] ( 入力 / 出力 )引数 xvec は長さ n の配列でこのスプラインが計算される点を含みま

す。 xvec の中の点でのスプラインの d- 次微係数は value_user に返

されます。

Page 167: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

関数 imsl_f_spline_value は、スプラインの値、もしくはその微係数を計算

します。この関数は、de Boor (1978 年、144 ページ ) による BVALUE ルーチ

ンを基にしています。

例題

例題 1

この例題では、関数 f の 3 次スプライン補間関数を計算します。その後,この

スプラインの値を、正確な関数値と比較します。デフォルトの設定が使用されるので、この補間関数は「ノットは無い」条件によって決定されます (de Boor 1978 年を参照 )。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11 /* 関数を定義 */#define F(x) (float)(sin(15.0*x))

main(){ int i; float fdata[NDATA], xdata[NDATA], x, y; Imsl_f_spline *sp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]); } /* Compute cubic spline interpolant */ sp = imsl_f_spline_interp (NDATA, xdata,fdata, 0); /* 結果をプリント */ printf(" x F(x) Interpolant Error\n"); for (i = NDATA/2; i < 3*NDATA/2; i++){ x = (float) i /(float)(2*NDATA-2); y = imsl_f_spline_value(x, sp, 0); printf(" %6.3f %10.3f %10.3f %10.4f\n", x, F(x), y, fabs(F(x)-y)); }}

出力結果

x F(x) Interpolant Error0.250 -0.572 -0.549 0.02280.300 -0.978 -0.978 0.00000.350 -0.859 -0.843 0.01620.400 -0.279 -0.279 0.00000.450 0.450 0.441 0.00930.500 0.938 0.938 0.00000.550 0.923 0.903 0.01990.600 0.412 0.412 0.00000.650 -0.320 -0.315 0.00490.700 -0.880 -0.880 0.00000.750 -0.968 -0.938 0.0295

例題 2

最初の例題のように、関数 f の 3 次スプライン補間関数を計算します。それか

らこのスプラインの値を正確な関数値と比較します。この例題は、1 次微係数

の値を比較します。

#include <imsl.h>#include <stdio.h>#include <math.h>

Page 168: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#define NDATA 11 /* 関数を定義 */#define F(x) (float)(sin(15.0*x))#define FP(x) (float)(15.*cos(15.0*x))

main(){ int i; float fdata[NDATA], xdata[NDATA], x, y; Imsl_f_spline *sp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]); } /* 3 次スプライン補間を計算 */ sp = imsl_f_spline_interp (NDATA, xdata, fdata, 0); /* 結果をプリント */ printf(" x FP(x) Interpolant Deriv Error\n"); for (i = NDATA/2; i < 3*NDATA/2; i++) { x = (float) i /(float)(2*NDATA-2); y = imsl_f_spline_value(x, sp, IMSL_DERIV, 1, 0); printf(" %6.3f %10.3f %10.3f %10.4f \n", x, FP(x), y, fabs(FP(x)-y)); }}

出力結果

x FP(x) Interpolant Deriv Error0.250 -12.308 -12.559 0.2510 0.300 -3.162 -3.218 0.0560 0.350 7.681 7.796 0.1151 0.400 14.403 13.919 0.4833 0.450 13.395 13.530 0.1346 0.500 5.200 5.007 0.1926 0.550 -5.786 -5.840 0.0535 0.600 -13.667 -13.201 0.4660 0.650 -14.214 -14.393 0.1798 0.700 -7.133 -6.734 0.3990 0.750 3.775 3.911 0.1359

重大エラー

IMSL_KNOT_MULTIPLICITY ノットの多重度はこのスプラインの階数を

超えることは出来ません。

IMSL_KNOT_NOT_INCREASING ノットは非減少でなければなりません。

spline_integralスプラインの積分を計算します。

概要

#include <imsl.h>

float imsl_f_spline_integral (float a, float b, Imsl_f_spline *sp)double 型関数は、imsl_d_spline_integralです。

必要な引数

float a ( 入力 )

float b ( 入力 )積分の端点。

Page 169: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Imsl_f_spline *sp ( 入力 )スプラインを表す構造体へのポインター。

戻り値

スプラインの積分。値が計算されない場合、NaN が返されます。

説明

関数 imsl_f_spline_integral は、a から b へのスプラインの積分を計算しま

す。

このルーチンは、de Boor (1978 年 )151 ページにある identity (22) を使用しま

す。

例題

この例題では、関数 f の 3 次スプライン補間関数を計算します。その後,この

スプラインの値を、正確な関数値と比較します。デフォルトの設定が使用されるので、この補間関数は「ノットは無い」条件によって決定されます (de Boor 1978 年を参照 )。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 21 /* 関数を定義 */#define F(x) (float)(sin(15.0*x)) /* 0 から x への積分 */#define FI(x) (float)((1.-cos(15.0*x))/15.)

main(){ int i; float fdata[NDATA], xdata[NDATA], x, y; Imsl_f_spline *sp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = (float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]); } /* 3 次スプライン補間を計算 */ sp = imsl_f_spline_interp (NDATA, xdata, fdata, 0); /* 結果をプリント */ printf(" x FI(x) Interpolant Integral Error\n"); for (i = NDATA/2; i < 3*NDATA/2; i++) { x = (float) i /(float)(2*NDATA-2); y = imsl_f_spline_integral(0.0, x, sp); printf(" %6.3f %10.3f %10.3f %10.4f \n", x, FI(x), y, fabs(FI(x)-y)); }}

出力結果

x FI(x) Interpolant Integral Error0.250 0.121 0.121 0.0001 0.275 0.104 0.104 0.0001 0.300 0.081 0.081 0.0001 0.325 0.056 0.056 0.0001 0.350 0.033 0.033 0.0001 0.375 0.014 0.014 0.0002 0.400 0.003 0.003 0.0002 0.425 0.000 0.000 0.0002 0.450 0.007 0.007 0.0002

( )b

as x dx∫

Page 170: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

0.475 0.022 0.022 0.0001 0.500 0.044 0.044 0.0001 0.525 0.068 0.068 0.0001 0.550 0.092 0.092 0.0001 0.575 0.113 0.113 0.0001 0.600 0.127 0.128 0.0001 0.625 0.133 0.133 0.0001 0.650 0.130 0.130 0.0001 0.675 0.118 0.118 0.0001 0.700 0.098 0.098 0.0001 0.725 0.075 0.075 0.0001 0.750 0.050 0.050 0.0001

警告エラー

IMSL_SPLINE_SMLST_ELEMNT データ配列 xdata と ydata は、i = 1, …, num_dataにおいて datai ≤ torder-1 を満足

しなければいけません。

IMSL_SPLINE_EQUAL_LIMITS 積分の上端点と下端点が同等です。無限

積分はゼロです。

IMSL_LIMITS_LOWER_TOO_SMALL 左端点が、torder-1 以下です。積分は、

torder-1 から bまでだけに起こります。

IMSL_LIMITS_UPPER_TOO_SMALL 右端点が、torder-1 以下です。積分は、

torder-1 から aまでだけに起こります。

IMSL_LIMITS_UPPER_TOO_BIG 右端点が、tspline_space_dim-1 より大きく

なっています。積分は、a から tspline_space_dim-1 までだけ起こります。

IMSL_LIMITS_LOWER_TOO_BIG 左端点が、tspline_space_dim-1 より大きく

なっています。積分は、b から tspline_space_dim-1 までだけ起こります。

重大エラー

IMSL_KNOT_MULTIPLICITY ノットの多重度はこのスプラインの階数を

超えることは出来ません。

IMSL_KNOT_NOT_INCREASING ノットは非減少でなければなりません。

spline_2d_valueテンソル積スプラインの値、もしくはその偏微係数の値を計算します。

概要

#include <imsl.h>

float imsl_f_spline_2d_value (float x, float y, Imsl_f_spline *sp, …, 0)double 型関数は、imsl_d_spline_2d_valueです。

必要な引数

float x ( 入力 )float y ( 入力 )

テンソル積スプラインを計算する点の (x, y) 座標。

Imsl_f_spline *sp ( 入力 )スプラインを表す構造体へのポインター。

戻り値

テンソル積スプラインの値、もしくは (x, y) における微係数の値。

Page 171: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数の概要

#include <imsl.h>float imsl_f_spline_2d_value (float x, float y, Imsl_f_spline *sp,

IMSL_DERIV, int x_partial, int y_partial, IMSL_GRID, int nx, float *xvec, int ny, float *yvec, float **value,IMSL_GRID_USER, int nx, float *xvec, int ny, float *yvec, float value_user[],0)

オプション引数

IMSL_DERIV, int x_partial, int y_partial ( 入力 )p = x_partial、 q = y_partialとして s を構造体 *sp によって表現さ

れるスプラインとします。するとこのオプションは (x, y), s(p,q) (x, y) において、s の (p, q) 番目の微係数を生成します。

デフォルト: x_partial = y_partial = 0

IMSL_GRID, int nx, float *xvec, int ny, float *yvec, float **value ( 入力 / 出力 )引数 xvec は、スプラインが計算される X 座標を含む長さ nx の配列

です。引数 yvec は、スプラインが計算される Y 座標を含む長さ ny の配列です。xvec の中の点でのスプラインの d- 次微係数は value に返されます。 nx × nyグリッド上のスプラインの値は、value に返されま

す。

IMSL_GRID_USER, int nx, float *xvec, int ny, float *yvec, float value_user[] ( 入力 / 出力 )引数 xvec は、スプラインが計算される X 座標を含む長さ nx の配列

です。引数 yvec は、スプラインが計算される Y 座標を含む長さ ny の配列です。xvec の中の点でのスプラインの d- 次微係数は value に返されます。 nx × nyグリッド上のスプラインの値は、ユーザ提供の空間

value_user に返されます。

説明

関数 imsl_f_spline_2d_value は、テンソル積スプラインの値、もしくはそ

の微係数の値を計算します。この関数は、de Boor(1978 年、 351−353 ページ )を基にしています。

例題

例題 1

imsl_f_spline_2d_interp 関数を使って補間関数を計算し、

imsl_f_spline_2d_value は、 s(x, y) を計算するために使用します。この偏微

係数と誤差の値は、4 × 4 のグリッドで計算され、表示されます。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11#define OUTDATA 2 /* 関数を定義 */#define F(x,y) (float)(x*x*x+y*y)

main(){ int i, j, num_xdata, num_ydata; float fdata[NDATA][NDATA], xdata[NDATA], ydata[NDATA]; float x, y, z; Imsl_f_spline *sp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = ydata[i] = (float) i / ((float) (NDATA - 1)); }

Page 172: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

for (i = 0; i < NDATA; i++) { for (j = 0; j < NDATA; j++) { fdata[i][j] = F(xdata[i], ydata[j]); } } num_xdata = num_ydata = NDATA; /* テンソル積補間関数を計算 */ sp = imsl_f_spline_2d_interp(num_xdata, xdata, num_ydata, ydata, fdata, 0); /* 結果をプリント */ printf(" x y F(x, y) Value Error\n"); for (i = 0; i < OUTDATA; i++) { x = (float) (1+i) / (float) (OUTDATA+1); for (j = 0; j < OUTDATA; j++) { y = (float) (1+j) / (float) (OUTDATA+1); z = imsl_f_spline_2d_value(x, y, sp, 0); printf(" %6.3f %6.3f %10.3f %10.3f %10.4f\n", x, y, F(x,y), z, fabs(F(x,y)-z)); } }}

出力結果

x y F(x, y) Value Error0.333 0.333 0.148 0.148 0.00000.333 0.667 0.481 0.481 0.00000.667 0.333 0.407 0.407 0.00000.667 0.667 0.741 0.741 0.0000

例題 2

imsl_f_spline_2d_interp 関数を使って補間関数を計算し、

imsl_f_spline_2d_value は、 s(2,1) (x, y) を計算するために使用します。この偏

微係数と誤差の値は、4 × 4 のグリッドで計算され、表示されます。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11#define OUTDATA 2 /* 関数を定義 */#define F(x, y) (float)(x*x*x*y*y)#define F21(x,y) (float)(6.*x*2.*y)

main(){ int i, j, num_xdata, num_ydata; float fdata[NDATA][NDATA], xdata[NDATA], ydata[NDATA]; float x, y, z; Imsl_f_spline *sp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = ydata[i] = (float)i / ((float)(NDATA-1)); } for (i = 0; i < NDATA; i++) { for (j = 0; j < NDATA; j++) { fdata[i][j] = F(xdata[i], ydata[j]); } } num_xdata = num_ydata = NDATA; /* テンソル積補間関数を計算 */ sp = imsl_f_spline_2d_interp(num_xdata, xdata, num_ydata, ydata, fdata, 0); /* 結果をプリント */ printf(" x y F21(x, y) 21InterpDeriv Error\n"); for (i = 0; i < OUTDATA; i++) {

Page 173: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

x = (float) (1+i) / (float) (OUTDATA+1); for (j = 0; j < OUTDATA; j++) { y = (float) (1+j) / (float) (OUTDATA+1); z = imsl_f_spline_2d_value(x, y, sp, IMSL_DERIV, 2, 1, 0); printf(" %6.3f %6.3f %10.3f %10.3f %10.4f\n", x, y, F21(x, y), z, fabs(F21(x,y)-z)); } }}

出力結果

x y F21(x, y) 21InterpDeriv Error0.333 0.333 1.333 1.333 0.00000.333 0.667 2.667 2.667 0.00000.667 0.333 2.667 2.667 0.00000.667 0.667 5.333 5.333 0.0001

警告エラー

IMSL_X_NOT_WITHIN_KNOTS x の値が、ノット列範囲内にありません。

IMSL_Y_NOT_WITHIN_KNOTS y の値が、ノット列範囲内にありません。

重大エラー

IMSL_KNOT_MULTIPLICITY ノットの多重度はこのスプラインの階数を

超えることは出来ません。

IMSL_KNOT_NOT_INCREASING ノットは非減少でなければなりません。

spline_2d_integral矩形領域でのテンソル積スプラインの積分を計算します。

概要

#include <imsl.h>

float imsl_f_spline_2d_integral (float a, float b, float c, float d, Imsl_f_spline *sp)

double 型関数は、 imsl_d_spline_2d_integralです。

必要な引数

float a ( 入力 )

float b ( 入力 )テンソル積スプラインの最初の変数のための積分限界。

float c ( 入力 )

float d ( 入力 )テンソル積スプラインの 2 番目の変数のための積分限界。

Imsl_f_spline *sp ( 入力 )スプラインを表す構造体へのポインター。

戻り値

矩形 [a, b] × [c, d] 上のテンソル積スプラインの積分の値。値が計算されない場

合、 NaN が返されます。

説明

関数 imsl_f_spline_2d_integral は、テンソル積スプラインの積分を計算し

ます。 s がスプラインの場合、関数は、以下を返します。

Page 174: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

この関数は、de Boor (1978 年、151 ページ ) の(単変量積分)identity (22) を用

いています。

ここで、 t0 ≤ x ≤ tr です。

(全てのノット列のために)最初と最後の k ノットは積み重ねられます。すな

わち、k が x 又は y 方向でのスプラインの階数である時、t0 = … = tk-1 になりま

す。

例題

この例題では、矩形 [0, x] × [0, y] 上で 2 次元テンソル積スプラインを積分しま

す。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 11#define OUTDATA 2 /* 関数を定義 */#define F(x,y) (float)(x*x*x+y*y) /* 0から x と 0 からy への F の積分 */#define FI(x,y) (float)(y*x*x*x*x/4. + x*y*y*y/3.)

main(){ int i, j, num_xdata, num_ydata; float fdata[NDATA][NDATA], xdata[NDATA], ydata[NDATA]; float x, y, z; Imsl_f_spline *sp; /* グリッドを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = ydata[i] = (float) i / ((float)(NDATA-1)); } for (i = 0; i < NDATA; i++) { for (j = 0; j < NDATA; j++) { fdata[i][j] = F(xdata[i],ydata[j]); } } num_xdata = num_ydata = NDATA; /* テンソル積補間を計算 */ sp = imsl_f_spline_2d_interp(num_xdata, xdata, num_ydata, ydata, fdata, 0); /* 結果をプリント */ printf(" x y FI(x, y) Integral Error\n"); for (i = 0; i < OUTDATA; i++) { x = (float) (1+i) / (float) (OUTDATA+1); for (j = 0; j < OUTDATA; j++) { y = (float) (1+j) / (float) (OUTDATA+1); z = imsl_f_spline_2d_integral(0.0, x, 0.0, y, sp); printf(" %6.3f %6.3f %10.3f %10.3f %10.4f\n", x, y, FI(x, y), z, fabs(FI(x,y)-z)); } }}

( ),b d

a cs x y dydx∫ ∫

( ) ( )0

1 1

, , 10 0 0

n r ix j k ji i k j i k

i i j

B d B xk

α τ τ α−

++

= = =

− =

∑ ∑ ∑∫

-

t

t t

Page 175: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

x y FI(x, y) Integral Error0.333 0.333 0.005 0.005 0.00000.333 0.667 0.035 0.035 0.00000.667 0.333 0.025 0.025 0.00000.667 0.667 0.099 0.099 0.0000

警告エラー

IMSL_SPLINE_LEFT_ENDPT X 積分の左端点は、ノット列内の範囲にあ

りません。積分は、torder-1 から bでのみ存在

します。

IMSL_SPLINE_RIGHT_ENDPT X 積分の右端点は、ノット列内の範囲にあ

りません。積分は、torder-1 から aでのみ存在

します。

IMSL_SPLINE_LEFT_ENDPT_1 X 積分の左端点は、ノット列内の範囲にあ

りません。積分は、b から tspline_space_dim-1でのみ存在します。

IMSL_SPLINE_RIGHT_ENDPT_1 X 積分の右端点は、ノット列内の範囲にあ

りません。積分は、a から tspline_space_dim-1でのみ存在します。

IMSL_SPLINE_LEFT_ENDPT_2 Y 積分の左端点は、ノット列内の範囲にあり

ません。積分は、torder-1 から dでのみ存在し

ます。

IMSL_SPLINE_RIGHT_ENDPT_2 Y 積分の右端点は、ノット列内の範囲にあり

ません。積分は、torder-1 から cでのみ存在し

ます。

IMSL_SPLINE_LEFT_ENDPT_3 Y 積分の左端点は、ノット列内の範囲にあり

ません。積分は、d から tspline_space_dim-1 での

み存在します。

IMSL_SPLINE_RIGHT_ENDPT_3 Y 積分の右端点は、ノット列内の範囲にあり

ません。積分は、c から tspline_space_dim-1 での

み存在します。

重大エラー

IMSL_KNOT_MULTIPLICITY ノットの多重度はこのスプラインの階数を

超えることは出来ません。

IMSL_KNOT_NOT_INCREASING ノットは非減少でなければなりません。

user_fcn_least_squaresユーザ提供の関数を使用して最小二乗当てはめを計算します。

概要

#include <imsl.h>

float *imsl_f_user_fcn_least_squares (float fcn (int k, float x), int nbasis, int ndata, float xdata[], float ydata[], …, 0)

double 型関数は、 imsl_d_user_fcn_least_squaresです。

必要な引数

float fcn (int k, float x) ( 入力 )最小二乗当てはめが実行される部分空間を定義するユーザ提供の関数。x で計算される k 番目の基底関数は f(k, x)で、ここでは k = 1, 2, ..., nbasis になります。

Page 176: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int nbasis ( 入力 )基底関数の数。

int ndata ( 入力 )データ点数。

float xdata[] ( 入力 )最小二乗問題の横軸を含む ndata 成分の配列。

float ydata[] ( 入力 )最小二乗問題の縦軸を含む ndata 成分の配列。

戻り値

基底関数の係数を含むベクトルのポインター。当てはめが計算出来ない場合、NULL が返されます。この空間を解放するために free を使用します。

オプション引数の概要

#include <imsl.h> float *imsl_f_user_fcn_least_squares (), int nbasis, int ndata,

float xdata[], float ydata[], IMSL_RETURN_USER, float coef[], IMSL_INTERCEPT, float *intercept, IMSL_SSE, float *ssq_err, IMSL_WEIGHTS, float weights[], IMSL_FCN_W_DATA, float fcn ( ), void *data,0)

オプション引数

IMSL_RETURN_USER, float coef[] ( 出力 )係数はユーザ提供の配列に保存されます。

IMSL_INTERCEPT, float *intercept ( 出力 )このオプションはモデルに切片を追加します。こうして、最小二乗当てはめは定数関数によって強化されたユーザ提供の基底関数を使用して計算されます。定数関数の係数は intercept に保存されます。T

IMSL_SSE, float *ssq_err ( 出力 )このオプションは誤差二乗和を返します。

IMSL_WEIGHTS, float weights[] ( 入力 )このオプションはユーザが加重を提供する必要があります。 デフォルト: 全ての加重は 1 に等しくなります。

IMSL_FCN_W_DATA, float fcn (int k, float x, float *data), void *data, ( 入力 )最小二乗の当てはめが実行される部分空間を定義するユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータを受け渡すポインターで

す。 詳細は、「イントロダクション」の「ユーザ提供関数へのデータの

受け渡し」を参照してください。

説明

関数 imsl_f_user_fcn_least_squares は次の形状の与えられた単変数デー

タに最高の最小二乗近似を計算します。

これは M 基底関数による

( ここでは M = nbasisです。) 特に、この関数のデフォルトは、次式を最小

化する係数 a を返します。

( ){ } 1

0,

ni i i

x f−

=

{ }1

M

j jF

=

Page 177: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここでは w = weights、n = ndata、x = xdata そして f = ydata です。

オプション引数 IMSL_INTCERCEPT が選択されたならば、切片はこのモデルに

置かれて、imsl_f_user_fcn_least_squares によって返される係数 a は下

で示されるような誤差二乗和を最小にします。

例題

例題 1

この例題は次の 2 つの関数を当てはめます ( δ によって示される )。

1 + sinx + 7 sin3x + δε

ここで ε は 区間 [−1, 1] での無作為な一様な偏差で、そして δ は最初の関数で 0 、2 番目の関数で 1 になります。これらの関数は区間 [0, 6] 上の 90 の等間隔な

点で計算されます。4 つの基底関数(1、 sinx、 sin2x、 sin3x)が使用されます。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 90 /* 関数を定義 */#define F(x) (float)(1.+ sin(x)+7.*sin(3.0*x))

float fcn(int n, float x);

main(){ int nbasis = 4, i, delta; float ydata[NDATA], xdata[NDATA], *random, *coef; /* 乱数を発生 */ imsl_random_seed_set(1234567); random = imsl_f_random_uniform(NDATA, 0); /* データを設定 */ for(delta = 0; delta < 2; delta++) { for (i = 0; i < NDATA; i++) { xdata[i] = 6.*(float)i /((float)(NDATA-1)); ydata[i] = F(xdata[i]) + (delta)*2.*(random[i]-.5); } coef = imsl_f_user_fcn_least_squares(fcn, nbasis, NDATA, xdata, ydata, 0); printf("\nFor delta = %1d", delta); imsl_f_write_matrix("the computed coefficients are\n", 1, nbasis, coef, 0); }}

float fcn(int n, float x){ return (n == 1) ? 1.0 : sin((n-1)*x);}

出力結果

For delta = 0 the computed coefficients are

( )2

1

10 1

n M

i i j j ii j

w f a F x−

−= =

∑ ∑

( )2

1

10 1

interceptn M

i i j j ii j

w f a F x−

−= =

− −

∑ ∑

Page 178: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1 2 3 4 1 1 -0 7

For delta = 1 the computed coefficients are

1 2 3 4 0.979 0.998 0.096 6.839

例題 2

次の 2 つの関数を当てはめる最初の例題を考えます (δ によって示される)。

1 + sinx + 7 sin3x + δε

ここで ε は 区間 [−1, 1] での無作為な一様な偏差で、そして δ は最初の関数で 0 、2 番目の関数で 1 になります。これらの関数は区間 [0, 6] 上の 90 の等間隔な

点で計算されます。以前では、4 つの基底関数(1、sinx、 sin2x、 sin3x)が使用

されます。この例題では intercept オプションで結合される 4 つの基底関数

(sinx、 sin2x、 sin3x、 sin4x)を使用します。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 90 /* 関数を定義 */#define F(x) (float)(1.+ sin(x)+7.*sin(3.0*x))

float fcn(int n, float x);

main(){ int nbasis = 4, i, delta; float ydata[NDATA], xdata[NDATA], *random, *coef, intercept; /* 乱数を発生 */ imsl_random_seed_set(1234567); random = imsl_f_random_uniform(NDATA, 0); /* データを設定 */ for(delta = 0; delta < 2; delta++){ for (i = 0; i < NDATA; i++) { xdata[i] = 6.*(float)i /((float)(NDATA-1)); ydata[i] = F(xdata[i]) + (delta)*2.*(random[i]-.5); } coef = imsl_f_user_fcn_least_squares(fcn, nbasis, NDATA, xdata, ydata, IMSL_INTERCEPT, &intercept, 0); printf("\nFor delta = %1d\n", delta); printf("The predicted intercept value is %10.3f\n" , intercept); imsl_f_write_matrix("the computed coefficients are\n", 1, nbasis, coef, 0); }}

float fcn(int n, float x){ return sin(n*x);}

出力結果

For delta = 0The predicted intercept value is 1.000

Page 179: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

the computed coefficients are

1 2 3 4 1 0 7 -0

For delta = 1The predicted intercept value is 0.978 the computed coefficients are

1 2 3 4 0.998 0.097 6.841 0.075

警告エラー

IMSL_LINEAR_DEPENDENCE 基底関数の線形従属が存在します。

coef の 1 つ以上の成分をゼロにセット

されます。

IMSL_LINEAR_DEPENDENCE_CONST 定数関数と基底関数の線形従属が存在し

ます。coef の 1 つ以上の成分をゼロに

セットしなければなりません。

重大エラー

IMSL_NEGATIVE_WEIGHTS_2 全ての加重はゼロより大きいか、ゼロに

等しくなければなりません。

spline_least_squares最小二乗スプライン近似を計算します。

概要

#include <imsl.h>

Imsl_f_spline *imsl_f_spline_least_squares (int ndata, float xdata[], float fdata[], int spline_space_dim, …, 0)

Imsl_d_spline 型関数は、imsl_d_spline_least_squaresです。

必要な引数

int ndata ( 入力 )データ点数。

float xdata[] ( 入力 )最小二乗問題の横軸を含む ndata 成分の配列。

float fdata[] ( 入力 )最小二乗問題の縦軸を含む ndata 成分の配列。

int spline_space_dim ( 入力 )スプライン部分空間の線形次元。ndataよりも小さく、order(デフォル

ト値は 4)と等しいか、それ以上でなければなりません。

戻り値

スプラインの当てはめを表す構造体へのポインター。当てはめが計算されない場合、NULL が返されます。空間を開放するには、 freeを使用します。

オプション引数の概要

#include <imsl.h> Imsl_f_spline *imsl_f_spline_least_squares (int ndata, float xdata[], float fdata[],

int spline_space_dim,IMSL_SSE, float *sse_err, IMSL_WEIGHTS, float weights[], IMSL_ORDER, int order,

Page 180: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_KNOTS, float knots[], IMSL_OPTIMIZE, 0)

オプション引数

IMSL_SSE, float *sse ( 出力 )このオプションは、sseで指し示された場所に、加重誤差二乗和を

セットします。

IMSL_WEIGHTS, float weights[] ( 入力 )ユーザが加重を提供します。デフォルト: 全ての加重は 1 に等しくなります。

IMSL_ORDER, int order ( 入力 )ノットが必要なスプライン部分空間の階数。このオプションはスプライン部分空間の階数を通信するために使用します。デフォルト: order = 4, ( すなわち、3次スプライン)。

IMSL_KNOTS, float knots[] ( 入力 )ユーザがノットを提供します。ユーザは、長さがspline_space_dimension + orderのノット列を提供しなければなりませ

ん。

デフォルト: 適切なノット列が選択されます。詳細は、以下を参照し

てください。

IMSL_OPTIMIZE

ノットの関数として最小二乗誤差を最小化することによりノットの位置を最適化します。最適なノットは、返されたスプライン構造体内で利用可能です。

説明

識別を作成します。

n = ndatax = xdataf = fdatam = spline_space_dimk = order

関数は必要としませんが、列 x は、増加していると仮定します。

デフォルトでは、k = 4 で、選択したノット列は、明確な xi を通じてノットを

平等に分布します。特に、m + k ノットは、各極値に積み重なった k ノットを

使って [x1, xn] に生成されます。内部ノットは、空間に等しく配置されます。

ノット t と加重 w が決定すると(IMSL_OPTIMIZEオプションが選択されていない

と仮定)、関数は、線形係数 aj を最小化することによりデータのスプライン最

小二乗当てはめを計算します。

ここで、Bj, j = 1, …, m は、スプライン部分空間のための(B スプライン)基底

関数です。

オプション引数 IMSL_ORDER を使用すると、スプライン当てはめの階数を選択

することが可能です。オプション引数 IMSL_KNOTS は、ノットのユーザ指定を

可能にします。関数 imsl_f_spline_least_squares は、de Boor (1978 年、

255 ページ ) のルーチン L2APPR を基にしています。

オプション IMSL_OPTIMIZE を選択すると、スプラインの階数 k で m 係数によ

り階数与えられたデータの最小二乗誤差を最小にする最適なノットを見つけます。この問題を道理にあるようにするためには、 m > k である必要があります。

. そして、次の関数の最小を見つけます。

( )2

1

0 1

n m

i i j j ii j

w f a B x−

= =

∑ ∑

Page 181: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

固定されたノット列 t にとって、a の最小化は容易に解くことができる線形最

小二乗問題であるということが、ここで使用しているテックニックです。従って、以下のように設定し、目的関数 F を単に t の関数として考えることができ

ます。

A Gauss-Seidel ( 循環座標 ) 法は、新しい目的関数 G の値を減少させるために使

用されます。このローカルな方法 に加えて、データが平滑化関数から発生さ

れる場合に有効であるグローバルなヒューリスティックがこのアルゴリズムに備わっています。このヒューリスティックは、de Boor (1978 年、 184 と 258−261 ページ ) の NEWNOT ルーチンが基になっています。

ノット列の最初の推定 tg, は、ユーザによって提供される、または、デフォル

トです。この推定は、 k 階数のスプラインのための有効なノット列でなければ

なりません。

tg は非増加です。

実行速度に関しては、この関数は、単純な最小二乗の当てはめに比べてかなり遅くなることがあります。.

この関数の戻り値は、Imsl_f_spline型のポインターです。呼び出しプログ

ラムは、このポインターを Imsl_f_spline *spポインターで受け取る必要が

あります。 この構造体は、スプライン(B スプライン形式で保存)を決定する

全ての情報を含んでいます。例えば、次のコードでは、 x でのスプラインを評

価し、値を y に返します。

y = imsl_f_spline_value (x, sp, 0);

次の図では、2つの3次スプラインが当てはめられます。

両方のスプラインは、同じ spline_space_dim = 8 での 3 次方程式です。 初め

のスプラインは、デフォルト設定で計算されます。2 番目のスプラインは、

IMSL_OPTIMIZEキーワードを使用したノット位置の最適化をして計算されま

す。

( ) ( )1 1

, ,0 0

,n m

i i j j k ii j

F a w f a B x− −

= =

= −

∑ ∑ tt

( ) ( )min ,a

G F a=t t

0 1 1 1, ,g g g gk i m m kx i M+ −≤ ≤ ≤ ≤ ≤ ≤ =-t t t tK K K

for 0, , 1g gi i k i m+< = −t t K

x

Page 182: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Figure 3- 4 Two Fits to Noisy

例題

例題 1

この例題は、三角多項式から生成されたデータの当てはめを行います。

1 + sinx + 7 sin3x + ε

このとき ε は、範囲 [−1, 1] の無作為な一様偏差です。データは、空間 [0, 6] 上90 の等間隔の点の関数を計算することにより小得します。このデータは 12 の

自由度(8 つの等間隔の内部ノット)を持つ 3 次スプラインで当てはめられま

す。10 の等間隔の点での誤差がプリントされます。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 90 /* 関数を定義 */#define F(x) (float)(1.+ sin(x)+7.*sin(3.0*x))

main(){ int i, spline_space_dim = 12; float fdata[NDATA], xdata[NDATA], *random; Imsl_f_spline *sp; /* 乱数を発生 */ imsl_random_seed_set(123457); random = imsl_f_random_uniform(NDATA, 0); /* データを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = 6.*(float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]) + 2.*(random[i]-.5); } sp = imsl_f_spline_least_squares(NDATA, xdata, fdata, spline_space_dim, 0); printf(" x error \n"); for(i = 0; i < 10; i++) { float x, error; x = 6.*i/9.; error = F(x) - imsl_f_spline_value(x, sp, 0); printf("%10.3f %10.3f\n", x, error); }}

x

Page 183: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

x Error 0.000 -0.3560.667 -0.0041.333 0.4342.000 -0.0692.667 -0.4943.333 0.3624.000 -0.2734.667 -0.2475.333 0.3036.000 0.578

例題 2

この例題は、三角多項式から生成されたデータを当てはめた最初の例題の続きです。

1 + sinx + 7 sin3x + ε

このとき ε は、範囲 [−1, 1] の無作為な一様偏差です。データは、空間 [0, 6] 上90 の等間隔の点の関数を計算することにより小得します。このデータは 12 の

自由度(この場合、デフォルトでは 8 つの等間隔の内部ノットが与えられま

す)を持つ 3 次スプラインで当てはめられ、誤差二乗和がプリントされます。

ます。この例題では、ノット位置が最適化され、誤差二乗和がプリントされます。その後、10 の等間隔の点での誤差がプリントされます。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 90 /* 関数を定義 */#define F(x) (float)(1.+ sin(x)+7.*sin(3.0*x))

main(){ int i, spline_space_dim = 12; float fdata[NDATA], xdata[NDATA], *random, sse1, sse2; Imsl_f_spline *sp; /* 乱数を発生 */ imsl_random_seed_set(123457); random = imsl_f_random_uniform(NDATA, 0); /* Set up data */ for (i = 0; i < NDATA; i++) { xdata[i] = 6.*(float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]) + 2.*(random[i]-.5); } sp = imsl_f_spline_least_squares(NDATA, xdata, fdata, spline_space_dim, IMSL_SSE, &sse1, 0); sp = imsl_f_spline_least_squares(NDATA, xdata, fdata, spline_space_dim, IMSL_OPTIMIZE, IMSL_SSE, &sse2, 0); printf("The error sum of squares before optimizing is %10.1f\n",

sse1); printf("The error sum of squares after optimizing is %10.1f\n\n",

sse2); printf(" x error\n"); for(i = 0; i < 10; i++){ float x, error; x = 6.*i/9.; error = F(x) - imsl_f_spline_value(x, sp, 0); printf("%10.3f %10.3f\n", x, error);

Page 184: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

}}

出力結果

The error sum of squares before optimizing is 32.6The error sum of squares after optimizing is 27.0

x Error 0.000 -0.656 0.667 0.107 1.333 0.055 2.000 -0.243 2.667 -0.063 3.333 -0.015 4.000 -0.424 4.667 -0.138 5.333 0.133 6.000 0.494

警告エラー

IMSL_OPT_KNOTS_STACKED_1 最良とされるノットが、階数以上に積み重

ねられています。これは、数少ないノットが同じ誤差二乗和を生成することを示しています。ノットは、多少分離されました。

重大エラー

IMSL_XDATA_TOO_LARGE 配列 xdata は、 i = 1, …, ndataのために xdatai ≤ tndata を満たさなければなりませ

ん。

IMSL_XDATA_TOO_SMALL 配列 xdata は、 i = 1, …, ndataのために xdatai ≥ torder-1 を満たさなければなりませ

ん。

IMSL_NEGATIVE_WEIGHTS 全ての加重はゼロより大きいか、ゼロに等

しくなければなりません。

IMSL_KNOT_MULTIPLICITY ノットの多重度はこのスプラインの階数を

超えることは出来ません。

IMSL_KNOT_NOT_INCREASING ノットは非減少でなければなりません。

IMSL_OPT_KNOTS_STACKED_2 最良とされるノットが、階数以上に積み重

ねられています。これは、数少ないノットが同じ誤差二乗和を生成することを示しています。

spline_2d_least_squares最小二乗法を使って2次元のテンソル積スプライン近似を計算します。

概要

#include <imsl.h>

Imsl_f_spline *imsl_f_spline_2d_least_squares (int num_xdata, float xdata[], int num_ydata, float ydata[], float fdata[], int x_spline_space_dim, int y_spline_space_dim, …, 0)

Imsl_d_spline 型関数は、 imsl_d_spline_2d_least_squaresです。

必要な引数

int num_xdata ( 入力 )X 方向のデータ点数。

Page 185: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float xdata[] ( 入力 )X 方向のデータ点を含む num_xdata 要素を持つ配列。

int num_ydata ( 入力 )Y 方向のデータ点数。

float ydata[] ( 入力 )Y 方向のデータ点を含む num_ydata 要素を持つ配列。

float fdata[] ( 入力 )近似する値を含むサイズ num_xdata × num_ydata の配列。fdata[i][j] は、 (xdata[i], ydata[j]) での ( ノイズを含んでいる可能性がある ) 値です。

int x_spline_space_dim ( 入力 )x 変数のスプライン部分空間の線形ディメンジョン。 num_xdata より

小さく、xorder ( デフォルト値は 4) と等しいか大きくすべきです。

int y_spline_space_dim ( 入力 )y 変数のスプライン部分空間の線形ディメンジョン。 num_ydata より

小さく、yorder ( デフォルト値は 4) と等しいか大きくすべきです。

戻り値

テンソル積スプライン補間を表す構造体へのポインター。補間関数が計算されない場合、 NULL が返されます。この空間を開放するには、 freeを使用します。

オプション引数の概要

#include <imsl.h> Imsl_f_spline *imsl_f_spline_2d_least_squares (int num_xdata, float xdata[], int num_ydata,

float ydata[], float fdata[], int x_spline_space_dim, int y_spline_space_dim, IMSL_SSE, float *sse, IMSL_ORDER, int xorder, int yorder, IMSL_KNOTS, float xknots[], float yknots[], IMSL_FDATA_COL_DIM, int fdata_col_dim, IMSL_WEIGHTS, float xweights[], float yweights[], 0)

オプション引数

IMSL_SSE, float *sse ( 出力 )このオプションは、sseで指し示された場所に、加重誤差二乗和を

セットします。

IMSL_ORDER, int xorder, int yorder ( 入力 )このオプションはスプライン部分空間の階数を通信するために使用します。デフォルト: xorder, yorder = 4 ( すなわち、テンソル積3次スプラ

イン )。

IMSL_KNOTS, float xknots[], float yknots[] ( 入力 )このオプションはユーザがノットを提供する必要があります。デフォルト: デフォルトノットは、x と y 次元において均等に分かれ

ています。

IMSL_FDATA_COL_DIM, int fdata_col_dim ( 入力 )fdataの列ディメンジョン。

デフォルト: fdata_col_dim = num_ydata

IMSL_WEIGHTS, float xweights[], float yweights[] ( 入力 )このオプションは最小二乗当てはめのために、ユーザが加重を提供する必要があります。デフォルト: 全ての加重は、1と等しくなります。

説明

関数 imsl_f_spline_2d_least_squares は、加重テンソル積データのテンソ

ル積スプライン最小二乗近似を計算します。この関数の入力は、データのため

Page 186: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

のテンソル積グリッド、加重(オプション、デフォルトは 1)を持つ 2 つのベ

クトル、グリッド表面の値、 テンソル積スプラインの仕様(オプション、デ

フォルトが選択)を指定する、データベクトルから成っています。グリッドは、それぞれの長さが n = num_xdataと m = num_ydataである 2 つのベクト

ル x = xdata と y = ydataによって指定されます。 2 次元配列 f = fdata は、当

てはめられるデータの値を含んでいます。2 つのベクトル wx = xweights と wy = yweights は、加重最小二乗問題のための加重を含んでいます。テンソル

積スプラインを近似するための情報は、IMSL_ORDERキーワードや

IMSL_KNOTSキーワードを使用することで取得できます。この情報は、スプラ

インの最初の変数のための kx = xorder、 tx = xknots、 N = xspline_space_dim やスプラインの 2 番目の変数のための ky = yorder、 ty = yknots、 M = y_spline_space_dim の中に含まれます。

この関数は、de Boor (1978 年、第 17 章 ) で述べられているように、テンソル

積形式での正規方程式を解くことにより、テンソル積スプラインのための係数を計算します。興味のある方は、Grosse (1980 年 ) の論文も参考にしてくださ

い。

計算が進むにつれ、次を最小化する係数 c を取得します。

ここでは、関数 Bkl は、階数 kx と ky の 2 つの B スプラインのテンソル積です。

特に以下を持っています。

スプライン

とその微係数は、imsl_f_spline_2d_valueを使って計算されます。

この関数の戻り値は、構造体 Imsl_f_spline へのポインターです。 呼び出しプロ

グラムは、これを Imsl_f_spline 型で受け取らなければなりません。この構造体

は、この関数によって計算されるスプラインを決定する全ての情報を含んでいます。例えば、次のコードは、 (x, y) での構造体に格納されるスプラインを計算

し、値を v に返却します。

v = imsl_f_spline_2d_value (x, y, sp, 0)

例題

例題 1

この例題のデータは、[0, 3] × [0, 5] 上の関数 ex sin (x + y) からできています。

この関数は、50 × 25 のグリッドを抽出します。次に、それをテンソル積 3 次

スプラインを使って戻します。関数 ex sin (x + y) の値は、 2 × 2 のグリッドにプ

リントされ、テンソル積スプライン最小二乗当てはめとと比較されます。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NXDATA 50#define NYDATA 25#define OUTDATA 2 /* 関数を定義 */#define F(x,y) (float)(exp(x)*sin(x+y))

( ) ( ) ( )21 1 1 1

0 0 0 0,

n m N M

x y kl kl i i iji j k l

w i w j c B x y f− − − −

= = = =

∑∑ ∑ ∑

( ) ( ) ( ), , , ,,x x y ykl k k l kB x y B x B y= t t

1 1

0 0

N M

kl klk l

c B− −

= =∑∑

Page 187: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

main(){ int i, j, num_xdata, num_ydata; float fdata[NXDATA][NYDATA]; float xdata[NXDATA], ydata[NYDATA], x, y, z; Imsl_f_spline *sp; /* グリッドを設定 */ for (i = 0; i < NXDATA; i++) { xdata[i] = 3.*(float) i / ((float)(NXDATA-1)); } for (i = 0; i < NYDATA; i++) { ydata[i] = 5.*(float) i / ((float)(NYDATA-1)); } /* グリッド上の関数の値を計算 */ for (i = 0; i < NXDATA; i++) { for (j = 0; j < NYDATA; j++) { fdata[i][j] = F(xdata[i], ydata[j]); } } num_xdata = NXDATA; num_ydata = NYDATA; /* テンソル積補間関数を計算 */ sp = imsl_f_spline_2d_least_squares(num_xdata, xdata, num_ydata, ydata, fdata, 5, 7, 0); /* 結果をプリント */ printf(" x y F(x, y) Fitted Values Error\n"); for (i = 0; i < OUTDATA; i++) { x = (float)i / (float)(OUTDATA); for (j = 0; j < OUTDATA; j++) { y = (float)j / (float)(OUTDATA); z = imsl_f_spline_2d_value(x, y, sp, 0); printf(" %6.3f %6.3f %10.3f %10.3f %10.4f\n", x, y, F(x, y), z, fabs(F(x,y)-z)); }

}}

出力結果

x y F(x, y) Fitted Values Error0.000 0.000 0.000 -0.020 0.02040.000 0.500 0.479 0.500 0.02080.500 0.000 0.790 0.816 0.02530.500 0.500 1.387 1.384 0.0031

例題 2

先の例題で使用したデータを使用します。オプション引数 IMSL_SSE を使っ

て、誤差二乗和を戻します。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NXDATA 0 50#define NYDATA 25#define OUTDATA 2 /* 関数を定義 */#define F(x,y) (float)(exp(x)*sin(x+y))

main(){ int i, j, num_xdata, num_ydata; float fdata[NXDATA][NYDATA]; float xdata[NXDATA], ydata[NYDATA], x, y, z; Imsl_f_spline *sp; /* グリッドを設定 */ for (i = 0; i < NXDATA; i++) {

Page 188: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

xdata[i] = 3.*(float) i / ((float) (NXDATA - 1)); } for (i = 0; i < NYDATA; i++) { ydata[i] = 5.*(float) i / ((float) (NYDATA - 1)); } /* グリッド上の関数の値を計算 */ for (i = 0; i < NXDATA; i++) { for (j = 0; j < NYDATA; j++) { fdata[i][j] = F(xdata[i], ydata[j]); } } num_xdata = NXDATA; num_ydata = NYDATA; /* テンソル積補間関数を計算 */ sp = imsl_f_spline_2d_least_squares(num_xdata, xdata, num_ydata, ydata, fdata, 5, 7, IMSL_SSE, &x, 0); /* 結果をプリント */ printf("The error sum of squares is %10.3f\n\n", x); printf(" x y F(x, y) Fitted Values Error\n"); for (i = 0; i < OUTDATA; i++) { x = (float) i / (float) (OUTDATA); for (j = 0; j < OUTDATA; j++) { y = (float) j / (float) (OUTDATA); z = imsl_f_spline_2d_value(x, y, sp, 0); printf(" %6.3f %6.3f %10.3f %10.3f %10.4f\n", x, y, F(x,y), z, fabs(F(x,y)-z)); } }}

出力結果

The error sum of squares is 3.753

x y F(x, y) Fitted Values Error0.000 0.000 0.000 -0.020 0.02040.000 0.500 0.479 0.500 0.02080.500 0.000 0.790 0.816 0.02530.500 0.500 1.387 1.384 0.0031

警告エラー

IMSL_ILL_COND_LSQ_PROB 最小二乗行列は、悪条件です。解が正確で

ない可能性があります。

IMSL_SPLINE_LOW_ACCURACY 最小二乗当てはめの精度が 1桁以下の可能性

があります。可能であれば、より高い精度で試みてください。

重大エラー

IMSL_KNOT_MULTIPLICITY ノットの多重度はこのスプラインの階数を

超えることは出来ません。

IMSL_KNOT_NOT_INCREASING ノットは非減少でなければなりません。

IMSL_SPLINE_LRGST_ELEMNT データ配列 xdata と ydata は、i = 1, …, num_dataのために、 datai ≤ tspline_space_dim を

満たさなければなりません。

IMSL_SPLINE_SMLST_ELEMNT データ配列 xdata と ydata は、i = 1, …, num_dataのために、 datai ≥ torder-1を満たさな

ければなりません。

IMSL_NEGATIVE_WEIGHTS 全ての加重はゼロより大きいか、ゼロに等

しくなければなりません。

Page 189: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_DATA_DECREASING xdata の値は、非増加でなければなりませ

ん。

cub_spline_smooth平滑化パラメータの推定に交差検定(cross-validation)を使う、もしくは直接、

平滑化パラメータを選択することにより、ノイズを含むデータに対する平滑化3 次スプライン近似を計算します。

概要

#include <imsl.h>

Imsl_f_ppoly *imsl_f_cub_spline_smooth (int ndata, float xdata[], float fdata[], …, 0)

Imsl_d_ppoly 型関数は、 imsl_d_cub_spline_smoothです。

必要な引数

int ndata ( 入力 )データ点数。

float xdata[] ( 入力 )問題の横軸を含む ndata 要素を持つ配列。

float fdata[] ( 入力 )問題の縦座標を含む ndata 要素を持つ配列。

戻り値

3 次スプラインを表す構造体へのポインター。平滑化 3 次スプラインが計算さ

れない場合、NULL が返されます。空間を開放するには、 freeを使用します。

オプション引数の概要

#include <imsl.h>Imsl_f_ppoly *imsl_f_cub_spline_smooth (int ndata, float xdata[], float fdata[],

IMSL_WEIGHTS, float weights[], IMSL_SMOOTHING_PAR, float sigma, 0)

オプション引数

IMSL_WEIGHTS, float weights[] ( 入力 )このオプションは、ユーザが加重を提供する必要があります。 デフォルト: 全ての加重は1に等しくなります。

IMSL_SMOOTHING_PAR, float sigma ( 入力 )平滑化パラメータ σ = sigma を明示的に設定します。

説明

関数 imsl_f_cub_spline_smooth は、ノイズを含んだデータセットに対する C2 3 次スプライン近似 を計算します。このスプラインは、 平滑化スプラインと

呼ばれています。

まず、オプション引数 IMSL_SMOOTHING_PAR が選択される時を考えます。 

その際、全てのデータの横軸 x = xdataでのノットを持つ普通の 3 次スプラインが

計算されます。しかし、データ (xi, fi) は、補間されません。平滑化スプラインは、

次を最小化する一意的な C2 関数です。

次の定数を前提とします。

( )2b

a

s x dx′′∫

Page 190: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで、 w = weights、 σ = sigma が平滑化パラメータ、 n = ndataになります。

σ の推奨値は、加重 w に依存します。値 fi の誤差の標準偏差のための推定が、

利用可能な場合、wi には、この値の逆が設定されます。そして、平滑化パラ

メータ σ は、上記の不等式の左辺に関連する信頼区間内で選択されるべきで

す。つまり、次の様に表されます。

関数 imsl_f_cub_spline_smooth は、Reinsch (1967 年 ) のアルゴリズムを基

にしています。このアルゴリズムは、de Boor (1978 年、235−243 ページ ) でも

論じられています。

この関数のデフォルトでは、交差検定(cross-validation)と呼ばれる統計手法

を用いて、平滑化パラメータ σ を選択します。 このトッピックに関する詳細は

Craven and Wahba (1979 年 ) を参照してください。

この関数の戻り値は、構造体 Imsl_f_ppoly へのポインターです。 呼び出しプロ

グラムは、これをポインター Imsl_f_ppoly *ppで受け取らなければなりません。

この構造体は、この関数によって計算されるスプライン(区分的多項式として保存される)を決定する全ての情報を含んでいます。例えば、次のコードは、 x での構造体に格納されるスプラインを計算し、値を y に返却します。

y = imsl_f_cub_spline_value (x, pp, 0);

例題

例題 1

この例題では、正確な値に無作為な値を加えることによりこの関数値を汚染します。関数 imsl_f_cub_spline_smooth を使って、オリジナルの汚染されて

いないデータの近似を求めます。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 90 /* 関数を定義 */#define F(x) (float)(1.+ sin(x)+7.*sin(3.0*x))

main(){ int i; float fdata[NDATA], xdata[NDATA], *random; Imsl_f_ppoly *pp; /* 乱数を発生 */ imsl_random_seed_set(123457); random = imsl_f_random_uniform(NDATA, 0); /* データを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = 6.*(float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]) + .5*(random[i]-.5); } pp = imsl_f_cub_spline_smooth(NDATA, xdata, fdata, 0); printf(" x error \n"); for(i = 0; i < 10; i++){ float x, error; x = 6.*i/9.; error = F(x) - imsl_f_cub_spline_value(x, pp, 0); printf("%10.3f %10.3f\n", x, error);

( )( )21

0

n

i i ii

s x f w σ−

=

− ≤∑

2 2n n n nσ− ≤ ≤ +

Page 191: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

}}

出力結果

x Error 0.000 -0.2010.667 0.0701.333 -0.0082.000 -0.0582.667 -0.0253.333 0.0764.000 -0.0024.667 -0.0085.333 0.0456.000 0.276

例題 2

最初の例題のように、本来の値に不規則な値を加えることで、関数値が汚染されます。その後、関数 imsl_f_cub_spline_smooth を使って、オリジナルの

汚染されていないデータの近似を求めます。この例題では、平滑化パラメータを 5 として、明示的に入力します。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 90 /* 関数を定義 */#define F(x) (float)(1.+ sin(x)+7.*sin(3.0*x))

main(){ int i; float fdata[NDATA], xdata[NDATA], *random; Imsl_f_ppoly *pp; /* 乱数を発生 */ imsl_random_seed_set(123457); random = imsl_f_random_uniform(NDATA, 0); /* データを設定 */ for (i = 0; i < NDATA; i++) { xdata[i] = 6.*(float)i /((float)(NDATA-1)); fdata[i] = F(xdata[i]) + .5*(random[i]-.5); } pp = imsl_f_cub_spline_smooth(NDATA, xdata, fdata, IMSL_SMOOTHING_PAR, 5.0, 0); printf(" x error \n"); for(i = 0; i < 10; i++){ float x, error; x = 6.*i/9.; error = F(x) - imsl_f_cub_spline_value(x, pp, 0); printf("%10.3f %10.3f\n", x, error); }}

出力結果

x Error 0.000 -0.5930.667 0.2301.333 -0.1162.000 -0.1062.667 0.1763.333 -0.0714.000 -0.1714.667 0.1965.333 -0.0366.000 0.971

Page 192: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

警告エラー

IMSL_MAX_ITERATIONS_REACHED 反復の最大数に達しました。最良の近似

を返却します。

重大エラー

IMSL_DUPLICATE_XDATA_VALUES xdata 値は区別されなければなりません。

IMSL_NEGATIVE_WEIGHTS 全ての加重はゼロより大きいか、ゼロに

等しくなければなりません。

spline_lsq_constrained最小二乗制約付きスプライン近似を計算します。

概要

#include <imsl.h>

Imsl_f_spline *imsl_f_spline_lsq_constrained (int ndata, float xdata[], float fdata[], int spline_space_dim, int num_con_pts, f_constraint_struct constraints[], …, 0)

Imsl_d_spline 型関数は、imsl_d_spline_lsq_constrainedです。

必要な引数

int ndata ( 入力 )データ点数。

float xdata[] ( 入力 )最小二乗問題の横軸を含む ndata 成分の配列。

float fdata[] ( 入力 )最小二乗問題の縦軸を含む ndata 成分の配列。

int spline_space_dim ( 入力 )スプライン部分空間の線形次元。ndataよりも小さく、order(デフォル

ト値は 4)と等しいか、それ以上でなければなりません。

int num_con_pts ( 入力 )ベクトル制約の点数。

f_constraint_struct constraints[] ( 入力 )当てはめが制約される地点、スプラインの微係数が制約される地点、制約の種類、上限、下限での横軸を含む構造体。 構造体のフィールド

に関する説明は、以下の通りです。

注意: 閉じられた区間 (c, d) 上でのスプラインの積分をする場合、 constraints[i].der = constraints [i+1].der = −1 と constraints[i].xval = c and constraints[i+1].xval = d を設定し

ます。 無矛盾性のために、 constraints[i].type = constraints[i+1].type ≥ 0 と c ≤ dを主張

フィールド 説明xval 当てはめが制約される地点der スプラインが制約される微係数の値type 一般的な制約の種類bl 一般的な制約の下限bu 一般的な制約の上限 s

Page 193: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

します。全ての der は、少なくとも -1 でなければならないことに注意

してください。

2 点の制約を持つために、

constraints[i].type = constraints[i+1].typeである必要がありま

す。

戻り値

スプラインの当てはめを表す構造体へのポインター。当てはめが計算されない場合、 NULL が返されます。この空間を開放する場合は、 freeを使用します。

オプション引数の概要

#include <imsl.h> Imsl_f_spline *imsl_f_spline_lsq_constrained (int ndata, float xdata[], float fdata[], int

spline_space_dim, int num_con_pts, f_constraint_struct constraints[],IMSL_NHARD, int nhard, IMSL_WEIGHTS, float weights[], IMSL_ORDER, int order, IMSL_KNOTS, float knots[], 0)

オプション引数IMSL_NHARD, int nhard ( 出力 )

引数 nhard は、「hard」制約に関連する制約の数です。 0 ≤ nhard ≤ num_con_ptsであることに注意してください。 デフォルト nhard = 0 では、常に当てはめられ、nhard = num_con_pts を設定する

ことで、全ての制約が満たされるよう強制されます。「hard」制約が、

満たされなければならない、もしくは、関数が失敗を示します。「soft」制約は、満たされる必要はありませんが、「soft」制約が満たさ

れるよう試みます。制約は、最も重要な制約が先にくるようにリストされなければなりません。従って、全ての「hard」制約は、「soft」制

制約 [i].type i 番目の制約1

2

3

4

5

6

7

8

20 周期的な終端条件99 この制約を無視

constraints [i]. type i 番目の制約9

10

11

12

( ) ( )idi ibl f x=( ) ( )id

i if x bu≤( ) ( )id

i if x bl≥( ) ( )id

i i ibl f x bu≤ ≤

( )d

i cbl f t dt= ∫

( )d

icf t dt bu≤∫

( )d

icf t dt bl≥∫

( )d

i icbl f t dt bu≤ ≤∫

( ) ( ) ( ) ( )11

i id di i ibl f x f x+

+= −( ) ( )id

i if x bu≤( ) ( ) ( ) ( )1

1i id d

i i if x f x bl++− ≥

( ) ( ) ( ) ( )11

i id di i i ibl f x f x bu+

+≤ − ≤

Page 194: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

約の前にこなければなりません。「soft」制約の間に、不可能なことが

発見された場合、順番にできるだけ多くの 「soft」制約を満たします。

デフォルト: nhard = 0

IMSL_WEIGHTS, float weights[] ( 入力 )このオプションは、ユーザが加重を提供する必要があります。デフォルト: 全ての加重は1に等しくなります。

IMSL_ORDER, int order ( 入力 )ノットが必要なスプライン部分空間の階数。このオプションはスプライン部分空間の階数を通信するために使用します。デフォルト: order = 4( すなわち、3次スプライン)。

IMSL_KNOTS, float knots[] ( 入力 )このオプションでは、ユーザがノットを提供する必要があります。ユーザは、長さ spline_space_dimension + orderのノット列を提供

しなければなりません。デフォルト: 適切なノット列が選択されます。詳細は、以下を参照し

てください。説明

関数 imsl_f_spline_lsq_constrained は、スプラインの部分空間からの

データの制約され、加重された最小二乗の当てはめを生成します。一点、二点、もしくは区間上の積分を含む制約が利用できます。この関数がサポートしていく制約は、次の 4 種類です。

区間 Ip(点、有限区間、半無限区間の場合あり)は、各制約に関連していま

す。この関数の入力は、いくつかの項目から成り立っています。最初は、データの当てはめをするデータ (xi, fi) for i = 1, …, N (where N = NDATA) です。二番目に、

最小二乗当てはめ (w = WEIGHT、デフォルトは 1) で使用する加重です。ベクト

ル制約は、制約の種類や制約区間の情報や、制約の指定に関連する横軸の点を含んでいます。

nf が上記の説明のように利用可能な制約の数を示すこととします。関数は、

次の問題を解きます。

以下を前提にしています。

線形に制約された最小二乗問題は、2 次問題として扱われ、関数

imsl_f_quadratic_prog ( 第 8 章、「最適化」を参照 ) を呼び出すことによって

解かれます。

加重の選択は問題におけるデータの不確実性に依存します。場合によっては、データ点の誤差推定を基にした加重の選択があります。

Ep[f]

Or

Or

Or = periodic end conditions

( ) ( )pjpf y=

( ) ( ) ( ) ( )1

1p pj j

p pf y f y+

+= −

( )1p

p

y

yf t dt+= ∫

( )2

1 1

n m

i j j i ii j

f a B x w= =

−∑ ∑

11, ,

m

p j j p fj

E a B I p n=

∈ =

∑ K

Page 195: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

線形制約の可能性の決定は、数値的に敏感な課題です。困難に直面した場合、簡単な解決策は、制約区間 Ip を広げることです。

例題

例題 1

この例題は、 imsl_f_lsq_constrainedの簡単なアプリケーションです。データは

次の関数によって生成され、不規則なノイズが加えられます。

そして、3 次スプラインを使って当てはめます。関数は増加するので、最小二

乗の当てはめも増加します。 imsl_f_spline_least_squaresによって生成され

た制約されていない最小二乗の当てはめの場合は異なります。その後、微係数は、 等間隔の num_con_pts = 15 で 0 以上になるように強制され、

imsl_f_lsq_constrainedが、呼ばれます。結果の曲線は、単調です。100 の

均等な点上に平均化された 2 つの当てはめのために、誤差がプリントされま

す。

#include <imsl.h>#include <math.h>

#define MXKORD 4#define MXNCOF 20#define MXNDAT 51#define MXNXVL 15

main(){ f_constraint_struct constraint[MXNXVL]; int i, korder, ncoef, ndata, nxval; float *noise, errlsq, errnft, grdsiz, x; float fdata[MXNDAT], xdata[MXNDAT]; Imsl_f_spline *sp, *spls;

#define F1(x) (float)(.5*(x) + sin( .5*(x) ))

korder = 4; ndata = 15; nxval = 15; ncoef = 8; /* * 無作為のノイズを持ったオリジナルの xdata と fdata を計算

*/ imsl_random_seed_set (234579); noise = imsl_f_random_uniform (ndata, 0); grdsiz = 10.0; for (i = 0; i < ndata; i++) { xdata[i] = grdsiz * ((float) (i) / (float) (ndata - 1)); fdata[i] = F1 (xdata[i]) + (noise[i] - .5); }

/* 最小二乗の当てはめを計算 */

spls = imsl_f_spline_least_squares (ndata, xdata, fdata, ncoef, 0); /* * 制約を構築 */ for (i = 0; i < nxval; i++) { constraint[i].xval = grdsiz * (float)(i) / (float)(nxval - 1); constraint[i].type = 3; constraint[i].der = 1; constraint[i].bl = 0.0; }

sin( )2 2x x

+

Page 196: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* 制約付き最小二乗の当てはめを計算 */ sp = imsl_f_spline_lsq_constrained (ndata, xdata, fdata, ncoef, nxval, constraint, 0); /* * 区間内における 100 点の平均誤差を計算 */ errlsq = 0.0; errnft = 0.0; for (i = 0; i < 100; i++) { x = grdsiz * (float) (i) / 99.0; errnft += fabs (F1 (x) - imsl_f_spline_value(x,sp,0)); errlsq += fabs (F1 (x) - imsl_f_spline_value(x,spls,0)); } /* 結果をプリント */ printf (" Average error with spline_least_squares fit: %8.5f\n", errlsq / 100.0); printf (" Average error with spline_lsq_constrained fit: %8.5f\n", errnft / 100.0);}

出力結果

Average error with spline_least_squares fit: 0.20250Average error with spline_lsq_constrained fit: 0.14334

例題 2

ノイズの入ったデータから次の関数を回復させます。

最初に、 関数 imsl_f_spline_least_squares使って制約されていない最小二

乗の当てはめを計算します。 当てはめを見つけるときに満足していない時、い

くつかの制約は、imsl_f_spline_lsq_constrainedを使って適用されます。

最初に、非制約の当てはめは、区間の両端での本来の関数を通じて振動します。この振幅を取り除くために、最初と最後 4 ノットでの、ゼロ個の 2 番目の

微係数を持つように、制約されます。 これは、最初と最後 3 つのノット区間に

おける線形多項式に減少させるように 3 次スプリ案を強制します加えて、当て

はめは以下のように制約されます。

s(−7) ≥ 0

s(−7) = s(7)

周期オプション ( ゼロ 番目の微係数を周期的にするためだけに必要 ) を使って

最後の制約が、生成されることに注意します。 誤差は、均等に分けられた 100点上の平均化された当てはめのためにプリントされます。

#include <imsl.h>#include <math.h>

#define KORDER 4#define NDATA 51#define NXVAL 12#define NCOEF 13

main(){ f_constraint_struct constraint[NXVAL];

4

11 x+

( )7

72.3s x dx

−≤∫

Page 197: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int i; float *noise, errlsq, errnft, grdsiz, x; float fdata[NDATA], xdata[NDATA], xknot[NDATA+KORDER]; Imsl_f_spline *sp, *spls;

#define F1(x) (float)(1.0/(1.0+x*x*x*x))

/* 無作為なノイズを持ったオリジナル xdata と fdata を計算 */

imsl_random_seed_set (234579); noise = imsl_f_random_uniform (NDATA, 0); grdsiz = 14.0; for (i = 0; i < NDATA; i++) { xdata[i] = grdsiz * ((float)(i)/(float)(NDATA - 1)) - grdsiz/2.0; fdata[i] = F1 (xdata[i]) + 0.125*(noise[i] - .5); }

/* ノットを生成 */ for (i = 0; i < NCOEF-KORDER+2; i++) { xknot[i+KORDER-1] = grdsiz * ((float)(i)/ (float)(NCOEF-KORDER+1)) - grdsiz/2.0; } for (i = 0; i < KORDER - 1; i++) { xknot[i] = xknot[KORDER-1]; xknot[i+NCOEF+1] = xknot[NCOEF]; }

/* spline_least_squares の当てはめを計算 */

spls = imsl_f_spline_least_squares (NDATA, xdata, fdata, NCOEF, IMSL_KNOTS, xknot, 0);

/* CONFTのための制約を構築 */

for (i = 0; i < 4; i++) { constraint[i].xval = xknot[KORDER+i-1]; constraint[i+4].xval = xknot[NCOEF-3+i]; constraint[i].itype = 1; constraint[i+4].itype = 1; constraint[i].ider = 2; constraint[i+4].ider = 2; constraint[i].bl = 0.0; constraint[i+4].bl = 0.0; } constraint[8].xval = -7.0; constraint[8].itype = 3; constraint[8].ider = 0; constraint[8].bl = 0.0;

constraint[9].xval = -7.0; constraint[9].itype = 6; constraint[9].bu = 2.3;

constraint[10].xval = 7.0; constraint[10].itype = 6; constraint[10].bu = 2.3;

constraint[11].xval = -7.0; constraint[11].itype = 20; constraint[11].ider = 0;

sp = imsl_f_spline_lsq_constrained (NDATA, xdata, fdata, NCOEF, NXVAL, constraint, IMSL_KNOTS, xknot, 0);

/* 区間内における 100 点の平均誤差を計算 */

Page 198: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

errlsq = 0.0; errnft = 0.0; for (i = 0; i < 100; i++) { x = grdsiz * (float) (i) / 99.0 - grdsiz/2.0; errnft += fabs (F1 (x) - imsl_f_spline_value(x,sp,0)); errlsq += fabs (F1 (x) - imsl_f_spline_value(x,spls,0)); } /* 結果をプリント */ printf (" Average error with BSLSQ fit: %8.5f\n",

errlsq / 100.0); printf (" Average error with CONFT fit: %8.5f\n", errnft / 100.0);}

出力結果

Average error with BSLSQ fit: 0.01783Average error with CONFT fit: 0.01339

smooth_1d_dataエラー検出による1次元データの平滑化を行います。

概要

#include <imsl.h>

float *imsl_f_smooth_1d_data (int ndata, float xdata[], float fdata[], …, 0)double 型関数は、 imsl_d_smooth_1d_dataです。

必要な引数

int ndata ( 入力 )データ点数。

float xdata[] ( 入力 )データ点の横軸を含む ndata 成分の配列。

float ydata[] ( 入力 )データ点の縦軸を含む ndata 成分の配列。

戻り値

平滑化されたデータを含む長さ ndata のベクトルへのポインター。

オプション引数の概要

#include <imsl.h> float * imsl_f_smooth_1d_data (int ndata,

float xdata[], float fdata[],IMSL_RETURN_USER, float sdata[], IMSL_ITMAX, int itmax, IMSL_DISTANCE, float dis, IMSL_STOPPING_CRITERION, float sc, 0)

オプション引数

IMSL_RETURN_USER, float sdata[] ( 出力 )平滑化されたデータは、ユーザ提供の配列に格納されます。

IMSL_ITMAX, int itmax ( 入力 )許可される最大反復数。 デフォルト: itmax = 500

Page 199: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_DISTANCE, float dis ( 入力 )エラー縦座標の距離の割合は曲線を補間するのに動かされます 0.0 から 1.0 の範囲でなければなりません。 デフォルト: dis = 1.0

IMSL_STOPPING_CRITERION, float sc ( 入力 )収束判定条件。 sc は、ゼロ以上にすべきです。

デフォルト: sc = 0.0

アルゴリズム

関数 imsl_f_smooth_1d_data は、隔離されたエラーで若干汚染されている

データセットを平滑化するように設計されています。通常、この関数は、データ点の 25%以上が誤っている場合、正常に機能しません。関数

imsl_f_smooth_1d_data は、 Guerra と Tapia (1974年 )のアルゴリズムを基にし

ています。

ndata = n、 ydata = f、 sdata = s 、 xdata = x と設定すると、アルゴリズムは以下

のように処理されます。ユーザは、xdata順序列を入力する必要がありませんが、

官位にするために x は増加していると仮定します。アルゴリズムは、xdata の値

を増加している列にソートし、続けます。各 6 点のデータセット(初期設定 s = f)のために、3 次スプライン補間を計算します。

(xj, sj) j = i − 3, …, i + 3 j ≠ i,

ここで、 i = 4, …, n − 3 です。 各 i のために、補間関数 Si は、si の現在の値と比

較され、「point energy」が次の様に計算されます。

pei = Si(xi) − si

sc = sc と設定し、itmax 反復に達した場合や、次式の場合、アルゴリズムは , 終了します。

上記の不等式が、 i のために違反される場合、d = disである si = si + d(pei) を設

定することにより s の i 番目の要素が更新されます。最初の 3 つ、もしくは最

後の 4 つのデータ点は変更されないことに注意してください。従って、これら

の点が不正確な場合、結果を解釈するための配慮が必要です。

この関数を上手く使用するには、引数 d、 sc、 itmax の選択は非常に重要です。 ユーザが、汚染の範囲に関する特定の情報をもっている場合、d = 1、 sc = 0 、 そして itmax をエラーのデータ点の数としてパラメータを選択すべきです。一

方、そのような特定の情報がない場合、 d = .5、 itmax ≤ 2n、そして次の様に選

択します。

どのような場合においても、これらの値を試してみることをお勧めします。

例題

区間 [1, 10] の関数 5 + (5 + t2 sin t)/t から、91 の一様の標本を取り出します。そ

の後、10 の標本を汚染し、オリジナルの関数の値を取り戻します。

#include "imsl.h"

#include "stdlib.h"

#include "math.h"

( )3 3 / 6 4, , 3i i ipe sc x x i n+ −≤ − = −K

( )1

max min.5n

s sscx x

−=

Page 200: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#define NDATA 91

#define F(X) (X*X*sin((double)(X))+5.0)/X + 5.0

main()

{

int i, maxit;

int isub[10] = {5, 16, 25, 33, 41, 48, 55, 61, 74, 82};

float dis, fdata[NDATA], sc, *sdata=NULL;

float xdata[NDATA], s_user[NDATA];

float rnoise[10] = {2.5, -3., -2., 2.5, 3.,

-2., -2.5, 2., -2., 3.};

/* 例題 1:特定の情報がない場合 */

dis = .5;

sc = .56;

maxit = 182;

/* xdata と fdataの値を設定 */

xdata[0] = 1.;

fdata[0] = F(xdata[0]);

for (i=1;i<NDATA;i++) {

xdata[i] = xdata[i-1]+.1;

fdata[i] = F(xdata[i]);

}

/* データを汚染 */

for (i=0;i<10;i++) fdata[isub[i]] += rnoise[i];

/* データを平滑化 */

sdata = imsl_f_smooth_1d_data(NDATA, xdata, fdata,

IMSL_DISTANCE, dis,

IMSL_STOPPING_CRITERION, sc,

IMSL_ITMAX, maxit,

0);

/* 結果を出力 */

printf("Case A - No specific information available. \n");

printf(" F(X) F(X)+noise sdata\n");

for (i=0;i<10;i++) printf("%7.3f\t%15.3f\t%15.3f\n",

F(xdata[isub[i]]),

fdata[isub[i]],

sdata[isub[i]]);

/* 例題 2:特定の情報がない場合 */

dis = 1.0;

sc = 0.0;

maxit = 10;

Page 201: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/*

* 最大反復回数に達したため、警告メッセージが生成される */

/* データを平滑化 */

sdata = imsl_f_smooth_1d_data(NDATA, xdata, fdata,

IMSL_DISTANCE, dis,

IMSL_STOPPING_CRITERION, sc,

IMSL_ITMAX, maxit,

IMSL_RETURN_USER, s_user,

0);

/* 結果を出力 */

printf("Case B - Specific information available. \n");

printf(" F(X) F(X)+noise sdata\n");

for (i=0;i<10;i++) printf("%7.3f\t%15.3f\t%15.3f\n",

F(xdata[isub[i]]),

fdata[isub[i]],

s_user[isub[i]]);

}

出力結果

Case A - No specific information available.

F(X) F(X)+noise sdata

9.830 12.330 9.870

8.263 5.263 8.215

5.201 3.201 5.168

2.223 4.723 2.264

1.259 4.259 1.308

3.167 1.167 3.138

7.167 4.667 7.131

10.880 12.880 10.909

12.774 10.774 12.708

7.594 10.594 7.639

*** WARNING Error IMSL_ITMAX_EXCEEDED from imsl_f_smooth_1d_data.

*** Maximum number of iterations limit "itmax" = 10 exceeded.

*** The best answer found is returned.

Case B - Specific information available.

F(X) F(X)+noise sdata

9.830 12.330 9.831

8.263 5.263 8.262

5.201 3.201 5.199

2.223 4.723 2.225

1.259 4.259 1.261

3.167 1.167 3.170

7.167 4.667 7.170

10.880 12.880 10.878

12.774 10.774 12.770

Page 202: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

7.594 10.594 7.592

scattered_2d_interp局所的に 2 変数の 5 次の多項式である離散データの 2 変量補間関数を計算しま

す。

概要

#include <imsl.h>

float *imsl_f_scattered_2d_interp (int ndata, float xydata[], float fdata[], int nx_out, int ny_out, float x_out[], float y_out[], …, 0)

double 型関数は、imsl_d_scattered_2d_interpです。

必要な引数

int ndata ( 入力 )データ点数。

float xydata[] ( 入力 )補間問題のデータ点を含む ndata*2 成分の配列。i 番目のデータ点 (xi , yi ) は xydata の 2i と 2i + 1 位置に連続的に保管されます。

float fdata[] ( 入力 )補間される値を含んだサイズ ndata の配列。

int nx_out ( 入力 )出力グリッドの x 方向のデータ点数。

int ny_out ( 入力 )出力グリッドの y 方向のデータ点数。

float x_out[] ( 入力 )出力グリッドの x 値を指定する長さ nx_out の配列。それは厳密に増

加でなければなりません。

float y_out[] ( 入力 )出力グリッドの y 値を指定する長さ ny_out の配列。それは厳密に増

加でなければなりません。

戻り値

補間関数の値の nx_out × ny_out グリッドのポインター。解が計算できない

場合、NULL が返されます。この空間を解放するために free を使用します。

オプション引数の概要

#include <imsl.h>float *imsl_f_scattered_2d_interp (int ndata, float xydata[], float fdata[], int nx_out, int

ny_out, float x_out[], float y_out[],IMSL_RETURN_USER, float surface[],IMSL_SUR_COL_DIM, int surface_col_dim, 0)

オプション引数

IMSL_RETURN_USER, float surface[] ( 出力 )このオプションでユーザはその結果のために自分の空間を提供する事が出来ます。この場合は、その解答が surface に返ります。

IMSL_SUR_COL_DIM, int surface_col_dim ( 入力 )このオプションはユーザに 2 次元配列 surface に列ディメンジョン

を与えることを要求します。デフォルト: surface_col_dim = ny_out

Page 203: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

関数 imsl_f_scattered_2d_interp は平面の離散データに対して C1 補間関

数を計算します。 n = ndata である次のデータ点

が R3 に与えられると、imsl_f_scattered_2d_interp はユーザ指定のグ

リッド上に補間関数の s を返します。s の計算は次の通りです。最初に点群の

ドローネー三角化が計算されます。

この三角化の各三角形 T 上で、s は次の形状を持ちます。

これで s は三角化の各三角形上で 2 変量 5 次多項式です。これに加えて、次式

を持ちます。

そして s は隣接する三角形の境界を通じ、連続して微分できます。これらの条

件は上述の表現に含まれる自由度を使い尽くしません。この追加の自由度は、このデータに含まれる全体的な形状性質に忠実な補間関数を生成する目的で利用されます。この手順の更に詳しい情報は Akima (1978 年 ) による論文を参照

して下さい。この出力グリッドは最初(2 番目)変数のグリッド点数を表す 2つの整数変数 nx_out と ny_out 、それにグリッドの最初(2 番目)座標を

表す 2 つの実数ベクトルによって指定されます。

例題

例題 1

この例題では線形関数 (3 + 7x + 2y) の補間関数を、半径 3 の円上で等間隔の 20データ点から計算します。それから、その値は 3 × 3 グリッド上にプリントさ

れます。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 20#define OUTDATA 3 /* 関数を定義 */#define F(x,y) (float)(3.+7.*x+2.*y)

#define SURF(I,J) surf[(J) +(I)*OUTDATA]

main(){ int i, j; float fdata[NDATA], xydata[2*NDATA], *surf; float x, y, z, x_out[OUTDATA], y_out[OUTDATA], pi;

pi = imsl_f_constant("pi", 0); /* 出力グリッドを設定 */ for (i = 0; i < OUTDATA; i++) { x_out[i] = y_out[i] = (float) i / ((float) (OUTDATA - 1)); }

( ){ } 1

0, ,

ni i i i

x y f−

=

( ){ } 1

0,

ni i i

x y−

=

( )5

, ,T m nmn

m ns x y c x y x y T

+ ≤

= ∀ ∈∑

( ), for 0, , 1i i is x y f i n= = −K

Page 204: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

for (i = 0; i < 2*NDATA; i += 2) { xydata[i] = 3.*cos(pi*i/NDATA); xydata[i+1] = 3.*sin(pi*i/NDATA); fdata[i/2] = F(xydata[i], xydata[i+1]); } /* 離散データ補間関数を計算 */ surf = imsl_f_scattered_2d_interp (NDATA, xydata, fdata, OUTDATA, OUTDATA, x_out, y_out, 0); /* 結果をプリント */ printf(" x y F(x, y) Interpolant Error\n"); for (i = 0; i < OUTDATA; i++) { for (j = 0; j < OUTDATA; j++) { x = x_out[i]; y = y_out[j]; z = SURF(i,j); printf(" %6.3f %6.3f %10.3f %10.3f %10.4f\n", x, y, F(x,y), z, fabs(F(x,y)-z)); }

}}

出力結果

x y F(x, y) Interpolant Error0.000 0.000 3.000 3.000 0.00000.000 0.500 4.000 4.000 0.00000.000 1.000 5.000 5.000 0.00000.500 0.000 6.500 6.500 0.00000.500 0.500 7.500 7.500 0.00000.500 1.000 8.500 8.500 0.00001.000 0.000 10.000 10.000 0.00001.000 0.500 11.000 11.000 0.00001.000 1.000 12.000 12.000 0.0000

例題 2

最初の例題と同じ様に、線形関数 (3 + 7x + 2y) の補間関数を、半径 3 の円で等

間隔の 20 のデータ点から計算します。その後、3 × 3 グリッドにこの値をプリ

ントします。この例題では,解は列ディメンジョンが 11 に等しい 2 次元配列 surf に格納されている事を示すオプション引数を使用しています。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 20#define OUTDATA 3#define COLDIM 11 /* 関数を定義 */#define F(x,y) (float)(3.+7.*x+2.*y)

main(){ int i, j; float fdata[NDATA], xydata[2*NDATA]; float surf[OUTDATA][COLDIM]; float x, y, z, x_out[OUTDATA], y_out[OUTDATA], pi;

pi = imsl_f_constant("pi", 0); /* 出力グリッドを設定 */ for (i = 0; i < OUTDATA; i++) { x_out[i] = y_out[i] = (float) i / ((float) (OUTDATA - 1)); } for (i = 0; i < 2*NDATA; i += 2) { xydata[i] = 3.*cos(pi*i/NDATA); xydata[i+1] = 3.*sin(pi*i/NDATA); fdata[i/2] = F(xydata[i], xydata[i+1]);

Page 205: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

} /* 離散データ補間関数を計算 */ imsl_f_scattered_2d_interp (NDATA, xydata, fdata, OUTDATA, OUTDATA, x_out, y_out, IMSL_RETURN_USER, surf, IMSL_SUR_COL_DIM, COLDIM, 0); /* 結果をプリント */ printf(" x y F(x, y) Interpolant Error\n"); for (i = 0; i < OUTDATA; i++) { for (j = 0; j < OUTDATA; j++) { x = x_out[i]; y = y_out[j]; z = surf[i][j]; printf(" %6.3f %6.3f %10.3f %10.3f %10.4f\n", x, y, F(x,y), z, fabs(F(x,y)-z)); } }}

出力結果

x y F(x, y) Interpolant Error0.000 0.000 3.000 3.000 0.00000.000 0.500 4.000 4.000 0.00000.000 1.000 5.000 5.000 0.00000.500 0.000 6.500 6.500 0.00000.500 0.500 7.500 7.500 0.00000.500 1.000 8.500 8.500 0.00001.000 0.000 10.000 10.000 0.00001.000 0.500 11.000 11.000 0.00001.000 1.000 12.000 12.000 0.0000

重大エラー

IMSL_DUPLICATE_XYDATA_VALUES 2 次元データ値は区別されなけれ

ばなりません。

IMSL_XOUT_NOT_STRICTLY_INCRSING ベクトル x_outs は、厳密に増加

しなければなりません。

IMSL_YOUT_NOT_STRICTLY_INCRSING ベクトル y_outs は、厳密に増加

しなければなりません。

radial_scattered_fit動径基底関数を使用して n ≥ 1 の Rn における離散データの近似を計算しま

す。

概要

#include <imsl.h>

Imsl_f_radial_basis_fit *imsl_f_radial_scattered_fit (int dimension,int num_points, float abscissae[], float fdata[], int num_centers, …, 0)

Imsl_d_radial_basis_fit 型関数は、imsl_d_radial_scattered_fitです。

必要な引数

int dimension ( 入力 )ディメンジョン数。

int num_points ( 入力 )データ点数。

Page 206: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float abscissae[] ( 入力 )データ点の横軸を含む、サイズ dimension × num_points の配列。

引数 abscissae[i][j] は (j+1) 番目のディメンジョンの (j+1) 番目の

データ点の横軸値。

float fdata[] ( 入力 )問題の縦軸を含む num_points 成分の配列。

int num_centers ( 入力 )動径基底当てはめを計算するとき使用される中心の数。引数 num_centers は num_points より小さいか、或いは、等しくなく

てはいけません。

戻り値

動径基底当てはめを表現する構造体のポインター。当てはめが計算出来ない場合,NULL が返されます。この空間を解放するためには free を使用します。

オプション引数の概要

#include <imsl.h>

Imsl_f_radial_basis_fit *imsl_f_radial_scattered_fit (int dimension, int num_points, float abscissae[], float fdata[],int num_centers,IMSL_CENTERS, float centers[],IMSL_CENTERS_RATIO, float ratio,IMSL_RANDOM_SEED, int seed,IMSL_SUPPLY_BASIS, float radial_function(),IMSL_SUPPLY_BASIS_W_DATA, float radial_function(), void *data,IMSL_SUPPLY_DELTA, float delta,IMSL_WEIGHTS, float weights[],IMSL_NO_SVD,0)

オプション引数

IMSL_CENTERS ( 入力 )ユーザ提供の中心。詳細はこの関数の「説明」節を参照してください。

IMSL_CENTERS_RATIO, float ratio ( 入力 )中心の総数に対して等間隔なグリッド上に置かれた中心の望ましい比率。中心の同じ数が各ディメンジョンに対して置かれる条件は等しくならなくてはならなりません。こうして1つのグリッドに置かれる中心の実際の数は、通常 ratio*num_centers より少ないが、

ratio*num_centers より決して多くてはなりません。残りの中心は

abscissae に与えられた横軸セットから無作為に選択されます。 rデフォルト: ratio = 0.5

IMSL_RANDOM_SEED, int seed中心として使用するために、横軸の無作為部分集合を決定するときに使用される乱数シードの値。同じデータセットであっても imsl_f_radial_scattered_fit の異なる呼び出しでシードの値を変

更すると無作為中心の異なる集合が選択されます。 seed をゼロに

セットすると乱数シードはシステム時計に基にしますので、プログラムが実行されるたびに、異なる中心が選択される可能性があります。デフォルト: seed = 234579

IMSL_SUPPLY_BASIS, float radial_function (float distance) ( 入力 )動径関数の値を計算するユーザ提供の関数。デフォルト: Hardy multiquadric

IMSL_SUPPLY_BASIS_W_DATA, float radial_function (float distance, void *data), void *data ( 入力 )ユーザ提供のデータへのポインターを受け入れる動径関数の値を計算するユーザ提供の関数。 data は、ユーザ提供関数へ受け渡されるデー

タへのポインターです。詳細は、本マニュアルの最初にある「イント

Page 207: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ロダクション 」節の「ユーザ提供関数へのデータの受け渡し」を参照

してください。

デフォルト: Hardy multiquadric

IMSL_SUPPLY_DELTA, float delta ( 入力 )次のデフォルト基底関数に使用される デルタ。

デフォルト: delta = 1

IMSL_WEIGHTS, float weights[]このオプションは、ユーザが加重を提供する必要があります。デフォルト: 全ての加重は1に等しくなります。

IMSL_NO_SVD

このオプションは特異値分解の代わりに QR 分解を強制する。これは

大規模問題のために空間の節約になることがあります。

説明

関数 imsl_f_radial_scattered_fit は、d = dimensionである Rd 空間で、

離散データの最小二乗当てはめを計算します。更に正確には、n = ndata、 x = abscissae、 f = fdata、 d = dimensionとします。 その後次の関係を得ます。

この関数は、上記のデータを近似する関数 F を計算します。ある意味、誤差平

方二乗和を最小にします。

ここでは w = weightsです。勿論、Fの関数形を限定しなければなりません。

これは次のように行われます。

この関数 φ は動径関数と呼ばれます。それは、非負整数だけに定義される、

R1 から R1 に写像されます。このルーチンの目的はユーザ提供の関数が次

式になります。

δ の値はデフォルトで 1 であることに注意します。キーワード IMSL_DELTA

を使用してユーザが設定する事も可能です。 パラメータ はこの問題を尺度化するために使用されています。一般的に δ を中心の最小間隔近くになるよう

に選びます。

デフォルトの基底関数は Hardyの多重 2 次式と呼ばれて、次式で定義されま

す。

このルーチンの重要な機能は、この基底関数の選択に対するユーザ操作です。

( ) 2 2r rφ δ= +

0 1 10 1, , , ,n d

nx x f f−−⊂ ⊂R RK K

( )( )1 2

0

ni

i ii

w F x f−

=

−∑

( )1 2 2

0:

k

j jj

F x x cα φ δ−

=

= − +

( ) ( )2 2r rφ δ= +

δ

( ) ( )2 2r rφ δ= +

Page 208: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

中心のデフォルトの選択を得るためには、最初に、グリッド上の中心の数と横軸の無作為な部分集合に中心がいくつあるかを計算します。その次に、グリッド上の中心を計算します。最後に、どこに中心が置かれるかを決定する横軸の無作為な部分集合が得られます。より詳しく、中心の選択方法を検証してみます。

最初に、計算されたグリッドが各 dimension 方向でグリッド値の同じ数を持

つように制限します。すると 1 つのグリッド上の中心の数、num_gridded は次のように計算されます。

α = (centers_ratio) (num_centers)

β = α1/dimension

num_gridded = βdimension

各 dimension 方向に β グリッド値が存在する事に注意してください。その

後、以下の式を得ます。

num_random = (num_centers) − (num_gridded)

ここで、中心がグリッド上にいくつあり、横軸の無作為な部分集合上にいくつあるかが分かります。グリッドにある中心は、それらが各 dimension 方向に

等間隔であるように計算されます。 最後の問題は、置き換え無しで、横軸の無作為な部分集合を計算することです。この選択は乱数シードに基づいています。このデフォルトのシードは 234579 です。ユーザはオプションの引数

IMSL_RANDOM_SEEDを使用してこれを変更する事が出来ます。 部分集合が計算

された後、中心として横座標を使用します。

現時点では、特定の問題の為の良好な中心の選択は、未解決な問題なので、ユーザに最高の柔軟性を与えています。キーワード IMSL_CENTERS を使用し

て自分自身で、中心の選択することができます。原則的には、中心は横軸に散在しなければなりません。

この関数の戻り値は、当てはめを計算するために必要なすべての情報を含む構造体のポインターです。このポインターは当てはめ関数の値を生成するために、関数 imsl_f_radial_evaluate に渡されます。

例題

例題 1

この例題はある関数からデータを生成して、それを 10 の等間隔のグリッド上

でノイズを加えます。この当てはめは、細分されたグリッド上で計算し実際の関数値と比較します。

#include <imsl.h>#include <math.h>

#define NDATA 10 #define NUM_CENTERS 5#define NOISE_SIZE 0.25#define F(x) ((float)(sin(2*pi*x)))

main (){ int i; int dim = 1; float fdata[NDATA]; float *fdata2; float xdata[NDATA]; float xdata2[2*NDATA]; float pi; float *noise; Imsl_f_radial_basis_fit *radial_fit;

pi = imsl_f_constant ("pi", 0);

Page 209: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

imsl_random_seed_set (234579); noise = imsl_f_random_uniform(NDATA, 0);

/* ノイズを含んだサンプルのデータ点を設定 */

for (i = 0; i < NDATA; ++i) { xdata[i] = (float)(i)/(float)(NDATA-1); fdata[i] = F(xdata[i]) + NOISE_SIZE*(1.0 - 2.0*noise[i]); }/* 動径当てはめを計算 */

radial_fit = imsl_f_radial_scattered_fit (dim, NDATA, xdata, fdata, NUM_CENTERS, 0); /* 元のデータ点の 2 倍の大きさの値で元の関数と結果を比較 */

for (i = 0; i < 2*NDATA; ++i) xdata2[i] = (float)(i/(float)(2*(NDATA-1)));/* 新しい点で当てはめを計算 */ fdata2 = imsl_f_radial_evaluate(2*NDATA, xdata2, radial_fit, 0);

printf(" I TRUE APPROX ERROR\n"); for (i = 0; i < 2*NDATA; ++i) printf("%5d %10.5f %10.5f %10.5f\n",i+1,F(xdata2[i]), fdata2[i], F(xdata2[i])-fdata2[i]); }

出力結果

I TRUE APPROX ERROR 1 0.00000 -0.08980 0.08980 2 0.34202 0.38795 -0.04593 3 0.64279 0.75470 -0.11191 4 0.86603 0.99915 -0.13312 5 0.98481 1.11597 -0.13116 6 0.98481 1.10692 -0.12211 7 0.86603 0.98183 -0.11580 8 0.64279 0.75826 -0.11547 9 0.34202 0.46078 -0.1187610 -0.00000 0.11996 -0.1199611 -0.34202 -0.23007 -0.1119512 -0.64279 -0.55348 -0.0893113 -0.86603 -0.81624 -0.0497914 -0.98481 -0.98752 0.0027115 -0.98481 -1.04276 0.0579516 -0.86603 -0.96471 0.0986817 -0.64279 -0.74472 0.1019318 -0.34202 -0.38203 0.0400119 0.00000 0.11600 -0.1160020 0.34202 0.73553 -0.39351

例題 2

この例題はある関数からデータを生成して、ノイズを加えます。このデータをサイズ 10, 20, ..., 100 のグリッド上で連続的に当てはめます。ここで、補間さ

れた結果と実際の関数値の間の差の 2 ノルムを補間してプリントします。高精

度のために倍精度が使用されることに注意してください。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define NDATA 100#define NUM_CENTERS 100#define NRANDOM 200#define NOISE_SIZE 1.0

Page 210: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#define G(x,y) (exp((y)/2.0)*sin(x) - cos((y)/2.0))

double radial_function (double r);

main(){ int i; int ndata; double *fit; double ratio; double fdata[NDATA+1]; double xydata[2 * NDATA+1]; double pi; double *noise; int num_centers; Imsl_d_radial_basis_fit *radial_struct;

pi = imsl_d_constant ("pi", 0);

/* ノイズに使用するための乱数を取得 */

imsl_random_seed_set (234579); noise = imsl_d_random_uniform (NRANDOM+1, 0); for (i = 0; i < NRANDOM; ++i) noise[i] = 1.0 - 2.0 * noise[i]; printf(" NDATA || Error ||_2 \n");

for (ndata = 10; ndata <= 100 ; ndata += 10) { num_centers = ndata;

/* ノイズを含んだサンプルデータ点を設定 */ for (i = 0; i < 2 * ndata; i += 2) { xydata[i] = 3. * (noise[i]); xydata[i + 1] = 3. * (noise[i + 1]); fdata[i / 2] = G(xydata[i], xydata[i + 1]) + NOISE_SIZE * noise[i]; }

/* 動径当てはめを計算 */ ratio = 0.5; radial_struct= imsl_d_radial_scattered_fit (2, ndata, xydata, fdata, num_centers, IMSL_CENTERS_RATIO, ratio, IMSL_SUPPLY_BASIS, radial_function, 0); fit = imsl_d_radial_evaluate (ndata, xydata, radial_struct, 0);

for (i = 0; i < ndata; ++i) fit[i] -= fdata[i];

printf("%8d %17.8f \n", ndata, imsl_d_vector_norm(ndata, fit, 0)); }

}

double radial_function (double r){ return log(1.0+r);}

出力結果

NDATA || Error ||_2 10 0.00000000 20 0.00000000 30 0.00000000 40 0.00000000 50 0.00000000 60 0.00000000 70 0.00000000

Page 211: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

80 0.00000000 90 0.00000000 100 0.00000000

radial_evaluate動径基底当てはめを計算します。

概要

#include <imsl.h>

float *imsl_f_radial_evaluate (int n, float x[], Imsl_d_radial_basis_fit *radial_fit, …, 0)

double 型関数は、imsl_d_evaluateです。

必要な引数

int n ( 入力 )当てはめが計算される点の数。

float x[] ( 入力 )当てはめが計算されるデータ点の横軸を含むサイズ (radial_fit − > dimension) × n の配列。引数 x[i][j] は、(j+1) 番目のディメンジョ

ンの (i+1) 番目のデータ点の横軸の値です。

Imsl_f_radial_basis_fit *radial_fit ( 入力 )計算に使用される動径基底構造体へのポインター。 ( 入力 ).

戻り値

望ましい値での動径基底当てはめの値を含む長さ n の配列へのポインター。値

が計算されない場合、 NULL が返されます。空間を開放するには、 freeを使用し

ます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_radial_evaluate (int n, float x[],Imsl_f_radial_basis_fit *radial_fitIMSL_RETURN_USER, float value[], 0)

オプション引数

IMSL_RETURN_USER, value[] ( 入力 )戻り値を含む長さ n のユーザ割り当ての配列。

説明

関数 imsl_f_radial_evaluate は、 imsl_f_radial_scattered_fitによって

生成されたデータから動径基底当てはめを計算します。

例題

#include <imsl.h>#include <math.h>

#define NDATA 10 #define NUM_CENTERS 5#define NOISE_SIZE 0.25#define F(x) ((float)(sin(2*pi*x)))

main (){ int i; int dim = 1; float fdata[NDATA];

Page 212: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float *fdata2; float xdata[NDATA]; float xdata2[2*NDATA]; float pi; float *noise; Imsl_f_radial_basis_fit *radial_fit;

pi = imsl_f_constant ("pi", 0);

imsl_random_seed_set (234579); noise = imsl_f_random_uniform(NDATA, 0);

/* ノイズを含むサンプルのデータ点を設定 */

for (i = 0; i < NDATA; ++i) { xdata[i] = (float)(i)/(float)(NDATA-1); fdata[i] = F(xdata[i]) + NOISE_SIZE*(1.0 - 2.0*noise[i]); }/* 動径当てはめを計算 */

radial_fit = imsl_f_radial_scattered_fit (dim, NDATA, xdata, fdata, NUM_CENTERS, 0); /* 元のデータ点の 2 倍の大きさの値で元の関数と結果を比較 */

for (i = 0; i < 2*NDATA; ++i) xdata2[i] = (float)(i/(float)(2*(NDATA-1)));

/* 新しい点で当てはめを計算 */ fdata2 = imsl_f_radial_evaluate(2*NDATA, xdata2, radial_fit, 0);

printf(" I TRUE APPROX ERROR\n"); for (i = 0; i < 2*NDATA; ++i) printf("%5d %10.5f %10.5f %10.5f\n",i+1,F(xdata2[i]), fdata2[i], F(xdata2[i])-fdata2[i]); }

出力結果 I TRUE APPROX ERROR 1 0.00000 -0.08980 0.08980 2 0.34202 0.38795 -0.04593 3 0.64279 0.75470 -0.11191 4 0.86603 0.99915 -0.13312 5 0.98481 1.11597 -0.13116 6 0.98481 1.10692 -0.12211 7 0.86603 0.98183 -0.11580 8 0.64279 0.75826 -0.11547 9 0.34202 0.46078 -0.1187610 -0.00000 0.11996 -0.1199611 -0.34202 -0.23007 -0.1119512 -0.64279 -0.55348 -0.0893113 -0.86603 -0.81624 -0.0497914 -0.98481 -0.98752 0.0027115 -0.98481 -1.04276 0.0579516 -0.86603 -0.96471 0.0986817 -0.64279 -0.74472 0.1019318 -0.34202 -0.38203 0.0400119 0.00000 0.11600 -0.1160020 0.34202 0.73553 -0.39351

Page 213: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

第 4章:求積法

ルーチン

単変量求積適応型汎用端点特異 . . . . . . . . . . . . . . . . int_fcn_sing 217適応型汎用 . . . . . . . . . . . . . . . . . . . . . . . int_fcn 218適応型汎用特異点 . . . . . . . . . . . . . . . .int_fcn_sing_pts 221適応型加重付き代数的特異 . . . . . . . . . . . . int_fcn_alg_log 224適応型無限区間 . . . . . . . . . . . . . . . . . . . int_fcn_inf 227適応型加重付き振動 (3 角関数 ) . . . . . . . . . . . . . . . . . . . . . . . . . int_fcn_trig 230適応型加重付きフーリエ (3 角関数 ) . . . . . . . . . . . . . . . . int_fcn_fourier 233コーシーの主値 . . . . . . . . . . . . . . . . . int_fcn_cauchy 236非適応型汎用 . . . . . . . . . . . . . . . . . . int_fcn_smooth 239

多変量求積2 次元累次積分. . . . . . . . . . . . . . . . . . . . int_fcn_2d 242超矩形上の累次積分 . . . . . . . . . . . . . .int_fcn_hyper_rect 245準モンテカルロ法を使用する累次積分 . . . . . . . . int_fcn_qmc 247

ガウス求積ガウス求積公式 . . . . . . . . . . . . . . . . gauss_quad_rule 249

微分ユーザ提供の関数の導関数計算 . . . . . . . . . . fcn_derivative 253

使用上の注意

単変量求積法

本章の最初の 9 つの関数は次式の積分の近似を計算するために設計されまし

た。

加重関数 w は既知の特異性を統合化する ( 代数的、又は、対数的 ) 或いは、

振動を統合化するために使用されます。汎用積分に対しては、imsl_f_int_fcn_sing ( 例え、端点特異が存在しなくても ) の使用を推奨し

ています。もし、より効率を望む場合、更に特殊化された関数の 1 つの使用を

お勧めします。これらの関数は次のように構成されます。

• w = 1imsl_f_int_fcn_sing

imsl_f_int_fcn

imsl_f_int_fcn_sing_pts

imsl_f_int_fcn_inf

imsl_f_int_fcn_smooth

• w(x) = sinωx 又は w(x) = cosωximsl_f_int_fcn_trig ( 有限区間用 ) imsl_f_int_fcn_fourier ( 無限区間用 )

( ) ( )b

cf x w x dx∫

Page 214: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

• w(x) = (x − a)a(b − x)bln(x − a)ln(b − x) ここで ln 因子はオプション

imsl_f_int_fcn_alg_log

• w(x) = 1/(x − c)imsl_f_int_fcn_cauchy

これらの関数の呼び出し順序は非常に似ています。積分される関数は常に fcn で、下限と上限はそれぞれ a と b です。要求される絶対誤差 ε は err_abs です

が、要求される相対誤差 ρ は err_rel です。これらの積分関数は推定され

る解 R を返えします。オプションの値 err_est = E は誤差を推定します。こ

れらの数値は次式のように関連します。

単変量積分関数の幾つかは、 Imsl_quad 型の引数を持ち、これは imsl.h で定義されています。

表形式データだけが与えられる時、単変量求積に時々生じる 1 つの状況は、積分

の近似に影響します。上で述べられた関数は、直接この問題には関係しません。しかし、この問題を解決する標準的な方法は、最初にこのデータを補間して、その後この補間関数を積分することです。これは、第3章「補間と近似」にあるスプライン積分関数の 1 つと共に、IMSL スプライン補間関数を使用する事によって

達成する事ができます。

多変量求積法

ある多変量積分を近似するために使用される 2 つの関数が本章に含まれていま

す。特に、関数 imsl_f_int_fcn_2d は次式の 2 次元累次積分の近似を返し

ます。

2 番目の関数、 imsl_f_int_fcn_hpyer_rect は超矩形上の n 変数の関数の積

分の近似を返します。

2 次元テンソル積の表形式データで作業している時には、 IMSL スプライン補間

関数の imsl_f_spline_2d_interp 、第3章「補間と近似」で述べられる IMSL スプライン積分関数 imsl_f_spline_2d_integral と続けて使用しま

す。

ガウス求積法

ガウス求積を計算する前に、出来るだけ高次の多項式を積分する、いわゆるガウス求積規則を計算しなければなりません。これらの求積規則は、次式を満足する i = 1, ..., N に対して点 {wi} を生成する関数 imsl_f_gauss_quad_rule を使用して、2N より小さい次数の多項式である全ての関数 f に対して容易に計

算する事ができます。

加重関数 w は次の表から選択されます。

( ) ( ) ( ) ( )max{ , }b b

a a

f x w x dx R E f x w x dxε ρ− ≤ ≤∫ ∫

( )( )

( ),

b h x

a g xf x y dydx∫ ∫

( )1

11 1, ,n

n

b b

n na af x x dx dx∫ ∫K K K

( ) ( ) ( )1

Nb

i iai

f x w x dx f x w=

= ∑∫

Page 215: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

差し支えなければ imsl_f_gauss_quad_rule は又 Gauss-Radau と Gauss-Lobatto 求積規則を計算します。

int_fcn_singGauss-Kronrod 規則に基づく全体適応枠組みを使用して、端点特異性を持つ関

数を積分します。

概要

#include <imsl.h>

float imsl_f_int_fcn_sing (float fcn(), float a, float b, …, 0)double 型関数は、 imsl_d_int_fcn_singです。

必要な引数

float fcn (float x) ( 入力 )積分されるユーザ提供の関数。

float a ( 入力 )積分の下限。

float b ( 入力 )積分の上限。

戻り値

次式の推定値。

値が計算されない場合、NaN が返されます。

オプション引数の概要

#include <imsl.h> float imsl_f_int_fcn_sing (float fcn(), float a, float b,

IMSL_ERR_ABS, float err_abs,IMSL_ERR_REL, float err_rel,IMSL_ERR_EST, float *err_est, IMSL_MAX_SUBINTER, int max_subinter,IMSL_N_SUBINTER, int *n_subinter,IMSL_N_EVALS, int *n_evals,IMSL_FCN_W_DATA, float fcn(), void *data,0)

w(x) 区間 名称1 (−1, 1) Legendre

(−1, 1) Chebyshev 第 1 種

(−1, 1) Chebyshev 第 2 種

(−∞, ∞) Hermite

(1 + x)a (1 − x)b (−1, 1) Jacobi(0, ∞) 一般化 Laguerre

1/cosh (x) (−∞, ∞) 双曲余弦

21/( 1 )x−

21 x−2xe−

x ae x−

( )fcnb

ax dx∫

Page 216: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数

IMSL_ERR_ABS, float err_abs ( 入力 )必要な絶対精度。

デフォルト: ここで ε は、マシン精度です。

IMSL_ERR_REL, float err_rel ( 入力 )必要な相対精度。

デフォルト:

ここで ε は、マシン精度です。

IMSL_ERR_EST, float *err_est ( 出力 )誤差の絶対値の推定値を格納するアドレス。

IMSL_MAX_SUBINTER, int max_subinter ( 入力 )許される部分区間の数。デフォルト: max_subinter = 500

IMSL_N_SUBINTER, int *n_subinter ( 出力 )生成される部分区間の数を格納するアドレス。

IMSL_N_EVALS, int *n_evals ( 出力 )fcn の計算数を格納するアドレス。

IMSL_FCN_W_DATA, float fcn (float x, void *data), void *data ( 入力 )統合されるユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータ

を受け渡すポインターです。 詳細は、「イントロダクション」の「ユー

ザ提供関数へのデータの受け渡し」を参照してください。

説明

この関数は端点特異性を持つ関数を処理するために設計されていますが、端点特異性を持たない関数の性能もとても良くできています。

関数 imsl_f_int_fcn_sing は絶対誤差を減少するために、全体的に適応的汎

用積分器です。それは区間 [a, b] を分割して各部分区間の積分を推定するため

に 21 点 の Gauss-Kronrod 規則を使用します。各部分区間の誤差は、10 点の ガウス 求積規則と比較することにより推定されます。最大の推定誤差を持つ部

分区間はそれから二分割されて同じ手順が両方の半分に適用されます。二分割過程は、誤差規準が満足されるか、丸め誤差が検出されるか、部分区間が余りにも小さくなるか、許される部分区間の最大数に到達するかのいずれかになるまで継続されます。この関数は ε アルゴリズムとして知られる外挿手順を使用

します。

関数 imsl_f_int_fcn_sing は Piessens その他 (1983 年 ) によるサブルーチン QAGS が、基になっています。

例題

例題 1

の値が推定されます。

#include <math.h>#include <imsl.h>

float fcn(float x);

main(){

err_abs ε=

ε=err_rel

( )1 1/ 2

0ln 4x x dx− = −∫

Page 217: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float q, exact; /* 積分を計算 */ q = imsl_f_int_fcn_sing (fcn, 0.0, 1.0, 0); /* 結果と正確な解答をプリント */ exact = -4.0; printf("integral = %10.3f\nexact = %10.3f\n", q, exact);}

float fcn(float x){ return log(x)/sqrt(x);}

出力結果

integral = -4.000exact = -4.000

例題 2

の値が再び推定されます。同様に実際と推定の誤差の値がプリントされます。これらの数はマシンに依存している事に注意してください。更に、通常、誤差推定は悲観的です。このために、この例題に於けるように、通常は実際の誤差は推定誤差よりは小さくなります。

#include <math.h>#include <imsl.h>

float fcn(float x);

main(){ float q, exact, err_est, exact_err; /* 積分を計算 */ q = imsl_f_int_fcn_sing (fcn, 0.0, 1.0, IMSL_ERR_EST, &err_est, 0); /* 結果と正確な解をプリント */ exact = -4.0; exact_err = fabs(exact - q); printf("integral = %10.3f\nexact = %10.3f\n", q, exact); printf("error estimate = %e\nexact error = %e\n", err_est, exact_err);}

float fcn(float x){ return log(x)/sqrt(x);}

出力結果

integral = -4.000exact = -4.000error estimate = 3.175735e-04exact error = 6.556511e-05

警告エラー

IMSL_ROUNDOFF_CONTAMINATION 要求される許容誤差が達成されることを

妨げる丸め誤差が検出されました。

IMSL_PRECISION_DEGRADATION 精度の低下が検出されました。

( )1 1/ 2

0ln 4x x dx− = −∫

Page 218: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_EXTRAPOLATION_ROUNDOFF 要求される許容誤差が達成されることを

妨げる補外テーブルの中に丸め誤差が検出されました。

重大エラー

IMSL_DIVERGENT 積分は発散、又は、ゆっくりと収束しま

す。

IMSL_MAX_SUBINTERVALS 部分区間の許容最大数に到達しました。

int_fcnGauss-Kronrod 規則に基づく全体適応枠組みを使用して、関数を積分します。

概要

#include <imsl.h>

float imsl_f_int_fcn (float fcn(), float a, float b, …, 0)double 型関数は、 imsl_d_int_fcnです。

必要な引数

float fcn (float x) ( 入力 )積分されるユーザ提供の関数。

float a ( 入力 )積分の下限。

float b ( 入力 )積分の上限。

戻り値

次の式が返されます。

値が計算できない場合、 NaN が返されます。

オプション引数の概要

#include <imsl.h> float imsl_f_int_fcn (float fcn(float x), float a, float b,

IMSL_RULE, int rule, IMSL_ERR_ABS, float err_abs,IMSL_ERR_REL, float err_rel,IMSL_ERR_EST, float *err_est,IMSL_MAX_SUBINTER, int max_subinter,IMSL_N_SUBINTER, int *n_subinter,IMSL_N_EVALS, int *n_evals,IMSL_FCN_W_DATA, float fcn(), void *data,0)

オプション引数

IMSL_RULE, int rule ( 入力 )求積規則の選択。

規則 Gauss-Kronrod 規則1 7-15 points2 10-21 points3 15-31 points4 20-41 points5 25-51 points6 30-61 points

( )fcnb

ax dx∫

Page 219: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

デフォルト: rule = 1

IMSL_ERR_ABS, float err_abs ( 入力 )必要な絶対精度。

デフォルト:

ここで ε は、マシン精度です。

IMSL_ERR_REL, float err_rel ( 入力 )必要な相対精度。

デフォルト: ここで ε は、マシン精度です。

IMSL_ERR_EST, float *err_est ( 出力 )誤差の絶対値の推定値を格納するアドレス。

IMSL_MAX_SUBINTER, int max_subinter ( 入力 )許される部分区間の数。デフォルト: max_subinter = 500

IMSL_N_SUBINTER, int *n_subinter ( 出力 )生成される部分区間の数を格納するアドレス。

IMSL_N_EVALS, int *n_evals ( 出力 )fcn の計算数を格納するアドレス。

IMSL_FCN_W_DATA, float fcn (float x, void *data), void *data ( 入力 )統合されるユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータ

を受け渡すポインターです。 詳細は、「イントロダクション」の「ユー

ザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_int_fcn は絶対誤差を減少するために、総括的に適応枠組みを

使用する汎用積分器です。これは区間 [a, b] を分割して、そして各部分の積分

を推定するため (2k + 1) 点の Gauss-Kronrod 規則を使用します。各部分の誤差

は k 点ガウス求積規則と比較することによって推定されます。最大の推定誤差

を持つ部分は二分されて、そして同様の手順が両方の半分に適用されます。この二分割過程は、誤差基準が満足されるか、丸め誤差が検出されるか、部分が余りにも小さくなるか、又は、許される部分の最大数に到達するかのいずれかになるまで継続されます。この関数 imsl_f_int_fcn は Piessens その他 (1983年 ) によるサブルーチン QAG を基にしています。

imsl_f_int_fcn が容認できる結果を生成することに失敗すれば、本章に記述

されるもっと特殊化された関数の 1 つを使用する事をお勧めします。

例題

例題 1

次式の値を計算します。

この被積分関数は振動しないので、全てのデフォルト値が使用されます。実際と推定誤差の値はマシンに依存します。

#include <math.h>#include <imsl.h>

float fcn(float x);float q;float exact;

err_abs ε=

err_r ε=el

2 2

01xxe dx e= +∫

Page 220: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

main(){ /* 積分を計算 */ q = imsl_f_int_fcn (fcn, 0.0, 2.0, 0); /* 結果と正確な答えをプリント */ exact = exp(2.0) + 1.0; printf("integral = %10.3f\nexact = %10.3f\n", q, exact);}

float fcn(float x){ float y; y = x * (exp(x)); return y;}

出力結果

integral = 8.389exact = 8.389

例題 2

次式の値を計算します。

この被積分関数は振動的なので、rule = 6 が使用されます。正確な値は

0.50406706 です。実際と推定される誤差の値はマシンに依存します。

#include <math.h>#include <imsl.h>

float fcn(float x);

main(){float q, err_est, err_abs= 0.0001, exact = 0.50406706, error;

/* fcn(x) を 0 から 1 まで積分 */ q = imsl_f_int_fcn (fcn, 0.0, 1.0, IMSL_ERR_ABS, err_abs,/* 絶対誤差を設定 */ IMSL_RULE, 6, IMSL_ERR_EST, &err_est, /* アドレスに渡す */ 0); error = q - exact; /* 結果と正確な解答をプリント */ printf(" integral = %10.3f\n exact = %10.3f\n error = %10.3f\n ", q, exact , error); printf(" err_est = %g\n", err_est); }

float fcn(float x){ /* ゼロによる除算を避けて sin(1/x) を計算 */ return ((x)>1.0e-5) ? sin(1.0/(x)) : 0.0;}

出力結果

integral = 0.504 exact = 0.504 error = 0.000 err_est = 0.000170593

( )1

0sin 1/ x dx∫

Page 221: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

警告エラー

IMSL_ROUNDOFF_CONTAMINATION 要求される許容誤差が達成されることを

妨げる丸め誤差が検出されました。

IMSL_PRECISION_DEGRADATION 精度の低下が検出されました。

重大エラー

IMSL_MAX_SUBINTERVALS 部分区間の許容最大数に到達しました。

int_fcn_sing_pts与えられた特異点を持つ関数を積分します。

概要

#include <imsl.h>

float imsl_f_int_fcn_sing_pts (float fcn(), float a, float b, int npoints, float points[], …, 0)

double 型関数は、imsl_d_int_fcn_sing_ptsです。

必要な引数

float fcn (float x) ( 入力 )積分されるユーザ提供の関数。

float a ( 入力 )積分の下限。

float b ( 入力 )積分の上限。

int npoints ( 入力 )被積分関数の特異点の数。

float points[] ( 入力 )特異点の横座標。これらの値は区間 [a, b] の内部になければならなり

ません。

戻り値

次式の値が返されます。

結果が計算されない場合、NaN が返されます。

オプション引数の概要

#include <imsl.h> float imsl_f_int_fcn_sing_pts (float fcn(), float a, float b, int npoints, float points[],

IMSL_ERR_ABS, float err_abs,IMSL_ERR_REL, float err_rel, IMSL_ERR_EST, float *err_est, IMSL_MAX_SUBINTER, int max_subinter, IMSL_N_SUBINTER, int *n_subinter, IMSL_N_EVALS, int *n_evals, IMSL_FCN_W_DATA, float fcn(),void *data,0)

オプション引数

IMSL_ERR_ABS, float err_abs ( 入力 )必要な絶対精度。

デフォルト:

( )fcnb

ax dx∫

err_abs ε=

Page 222: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで ε は、マシン精度です。

IMSL_ERR_REL, float err_rel ( 入力 )必要な相対精度。

デフォルト: ここで ε は、マシン精度です。

IMSL_ERR_EST, float *err_est ( 出力 )誤差の絶対値の推定値を格納するアドレス。

IMSL_MAX_SUBINTER, int max_subinter ( 入力 )許される部分区間の数。デフォルト: max_subinter = 500

IMSL_N_SUBINTER, int *n_subinter ( 出力 )生成される部分区間の数を格納するアドレス。

IMSL_N_EVALS, int *n_evals ( 出力 )fcn の計算数を格納するアドレス。

IMSL_FCN_W_DATA, float fcn (float x, void *data), void *data ( 入力 )統合されるユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータ

を受け渡すポインターです。 詳細は、「イントロダクション」の「ユー

ザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_int_fcn_sing_pts は絶対誤差を減少するために、総括的な適

応枠組みを使用する特殊目的の積分器です。これは、区間 [a, b] を npoints + 1 のユーザ提供の部分区間に分割して、各部分区間の積分を推定するために 21 点 の Gauss-Kronrod 規則を使用します。各部分区間の誤差は 10 点のガウス求積

規則と比較して推定されます。最大の推定誤差を持つ部分区間は二等分されて、同じ手順が両方の半分に適用されます。この二等分過程は、誤差基準が満足されるか、丸め誤差が検出されるか、部分区間が小さくなりすぎるか、部分区間の許される最大数に到達するまで継続されます。この関数は ε アルゴリズムとして知られる外挿手順を使用します。

関数 imsl_f_int_fcn_sing_pts は、Piessens その他 (1983 年 ) によるサブ

ルーチン QAGP に基づいています。

例題

例題 1

次式の値を計算します。

この実際と推定誤差の値はマシンに依存します。この関数はユーザ提供の切点でユーザ提供の関数を決して計算しないことに注意してください。

#include <math.h>#include <imsl.h>

float fcn(float x); main(){ int npoints = 2; float q, exact, points[2]; /* 特異点を設定 */ points[0] = 1.0; points[1] = sqrt(2.); /* 積分を計算 */

err_ ε=rel

( )( )3 3 2 2

0

77ln 1 2 61ln 2 ln 7 274

x x x dx− − = + −∫

Page 223: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

q = imsl_f_int_fcn_sing_pts (fcn, 0.0, 3.0, npoints, points, 0); /* 結果と正確な解答をプリント */ exact = 61.*log(2.) + (77./4)*log(7.) - 27.; printf("integral = %10.3f\nexact = %10.3f\n", q, exact);}

float fcn(float x){ return x*x*x*(log(fabs((x*x-1.)*(x*x-2.))));}

出力結果

integral = 52.741exact = 52.741

例題 2

次式の値を再び計算します。

実際と推定された誤差の値が同様にプリントされます。これらの値はマシン依存する事に注意してください。更に、この誤差推定値は通常は悲観的である。この事は、実際の誤差はこの例題のように、誤差推定値よりは通常は小さいと言うことです。又、関数計算の数がプリントされます。

#include <math.h>#include <imsl.h>

float fcn(float x); main(){ int n_evals, npoints = 2; float q, exact, err_est, exact_err, points[2]; /* 特異点を設定 */ points[0] = 1.0; points[1] = sqrt(2.); /* 積分を計算して */ /* 誤差推定値と */ /* 計算回数を取得 */ q = imsl_f_int_fcn_sing_pts (fcn, 0.0, 3.0, npoints, points, IMSL_ERR_EST, &err_est, IMSL_N_EVALS, &n_evals, 0); /* 結果と正確な解答をプリント */ exact = 61.*log(2.) + (77./4)*log(7.) - 27.; exact_err = fabs(exact - q); printf("integral = %10.3f\nexact = %10.3f\n", q, exact); printf("error estimate = %e\nexact error = %e\n", err_est, exact_err); printf("The number of function evaluations = %d\n", n_evals);}

float fcn(float x){ return x*x*x*(log(fabs((x*x-1.)*(x*x-2.))));}

出力結果

integral = 52.741exact = 52.741error estimate = 1.258850e-04exact error = 3.051758e-05The number of function evaluations = 819

( )( )3 3 2 2

0

77ln 1 2 61ln 2 ln 7 274

x x x dx− − = + −∫

Page 224: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

警告エラー

IMSL_ROUNDOFF_CONTAMINATION 要求される許容誤差が達成されることを

妨げる丸め誤差が検出されました。

IMSL_PRECISION_DEGRADATION 精度の低下が検出されました。

IMSL_EXTRAPOLATION_ROUNDOFF 要求される許容誤差が達成されることを

妨げる補外テーブルの中に丸め誤差が検出されました。

重大エラー

IMSL_DIVERGENT 積分は発散、又は、ゆっくりと収束しま

す。

IMSL_MAX_SUBINTERVALS 部分区間の許容最大数に到達しました。

int_fcn_alg_log代数的、対数的特異点を持つ関数を積分します。

概要

#include <imsl.h>

float imsl_f_int_fcn_alg_log (float fcn(), float a, float b, Imsl_quad weight, float alpha, float beta, …, 0)

double 型関数は、 imsl_d_int_fcn_alg_logです。

必要な引数

float fcn (float x) ( 入力 )積分されるユーザ提供の関数。

float a ( 入力 )積分の下限。

float b ( 入力 )積分の上限。

Imsl_quad weight, float alpha, float beta ( 入力 )これらの 3 つのパラメータは、端点で代数的、又は、対数的な特異点

を持つ加重関数を説明するために使用されます。パラメータ weight は次に説明される 4 つの値を取ることができます。パラメータ alpha = α と beta = β は a 又は b の特異性の強さを指定して、それで

- 1 より大きくなければなりません。

戻り値

次式の値が返されます。

Weights Integration WeightIMSL_ALG (x − a)a (b − x)bIMSL_ALG_LEFT_LOG (x − a)a (b − x)blog (x − a)IMSL_ALG_RIGHT_LOG (x − a)a (b − x)blog (b − x)IMSL_ALG_LOG (x − a)a (b − x)blog (x − a) log (b − x)

( ) ( )fcnb

ax w x dx∫

Page 225: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで、 w(x) 上の表の4つの Weights の1つです。 値が計算できない場合、

NaN が返されます。

オプション引数の概要

#include <imsl.h>float imsl_f_int_fcn_alg_log (float fcn(float x), float a, float b,

Imsl_quad weight, float alpha, float beta, IMSL_ERR_ABS, float err_abs, IMSL_ERR_REL, float err_rel, IMSL_ERR_EST, float *err_est, IMSL_MAX_SUBINTER, int max_subinter, IMSL_N_SUBINTER, int *n_subinter, IMSL_N_EVALS, int *n_evals, IMSL_FCN_W_DATA, float fcn(), void *data,0)

オプション引数

IMSL_ERR_ABS, float err_abs ( 入力 )必要な絶対精度。

デフォルト:

ここで ε は、マシン精度です。

IMSL_ERR_REL, float err_rel ( 入力 )Relative accuracy desired.

デフォルト:

ここで ε は、マシン精度です。

IMSL_ERR_EST, float *err_est ( 出力 )誤差の絶対値の推定値を格納するアドレス。

IMSL_MAX_SUBINTER, int max_subinter ( 入力 )許される部分区間の数。デフォルト: max_subinter = 500

IMSL_N_SUBINTER, int *n_subinter ( 出力 )生成される部分区間の数を格納するアドレス。

IMSL_N_EVALS, int *n_evals ( 出力 )fcn の計算数を格納するアドレス。

IMSL_FCN_W_DATA, float fcn (float x, void *data), void *data ( 入力 )統合されるユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータ

を受け渡すポインターです。 詳細は、「イントロダクション」の「ユー

ザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_int_fcn_alg_log は絶対誤差を減少するために、総括的に適応

枠組みを使用する特殊目的の積分器です。これは被積分関数が特殊な形式 w(x)f(x) を持つ積分を計算し、ここでの w(x) は先に述べた加重関数です。修正 Clenshaw-Curtis と Gauss-Kronrod 公式の組み合わせが使用されています。この

関数は Piessens その他 (1983 年 ) によるサブルーチン QAGP に基づいていま

す。

例題

例題 1

次式の値が計算されます。

err_abs ε=

err_ ε=rel

( ) ( ) ( ) ( )1/ 21

0

3ln 2 41 1 ln

9x x x x dx

−+ − = ∫

Page 226: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#include <math.h>#include <imsl.h>

float fcn(float x); main(){ float q, exact; /* 積分を計算 */ q = imsl_f_int_fcn_alg_log (fcn, 0.0, 1.0, IMSL_ALG_LEFT_LOG, 1.0, 0.5, 0); /* 結果と正確な答えをプリント */ exact = (3.*log(2.)-4.)/9.; printf("integral = %10.3f\nexact = %10.3f\n", q, exact);}

float fcn(float x){ return sqrt(1+x);}

出力結果

integral = -0.213exact = -0.213

例題 2

次式の値が再び計算されます。

そして、実際と推定誤差の値がプリントされます。これらの数値はマシン依

存であることに注意してください。更に誤差推定値は通常は悲観的です。つまり、実際の誤差は、この例題におけるように誤差推定値よりは通常は小さくなります。関数計算の回数も又プリントされます。

#include <math.h>#include <imsl.h>

float fcn(float x); main(){ int n_evals; float q, exact, err_est, exact_err; /* 積分を計算 */ q = imsl_f_int_fcn_alg_log (fcn, 0.0, 1.0, IMSL_ALG_LEFT_LOG, 1.0, 0.5, IMSL_ERR_EST, &err_est, IMSL_N_EVALS, &n_evals, 0); /* 結果と正確な答えをプリント */ exact = (3.*log(2.)-4.)/9.; exact_err = fabs(exact - q); printf("integral = %10.3f\nexact = %10.3f\n", q, exact); printf("error estimate = %e\nexact error = %e\n", err_est, exact_err); printf("The number of function evaluations = %d\n", n_evals);}

float fcn(float x){

( ) ( ) ( ) ( )1/ 21

0

3ln 2 41 1 ln

9x x x x dx

−+ − = ∫

Page 227: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

return sqrt(1+x);}

出力結果

integral = -0.213exact = -0.213error estimate = 3.725290e-09exact error = 1.490116e-08The number of function evaluations = 50

警告エラー

IMSL_ROUNDOFF_CONTAMINATION 要求される許容誤差が達成されることを

妨げる丸め誤差が検出されました。

IMSL_PRECISION_DEGRADATION 精度の低下が検出されました。

重大エラー

IMSL_MAX_SUBINTERVALS 部分区間の許容最大数に到達しました。

int_fcn_inf無限区間、或いは、半無限区間の関数を積分します。

概要

#include <imsl.h>

float imsl_f_int_fcn_inf (float fcn(), float bound, Imsl_quad interval, …, 0)

double 型関数は、imsl_d_int_fcn_infです。

必要な引数

float fcn (float x) ( 入力 )積分されるユーザ提供の関数。

float bound ( 入力 )積分の有限限界。interval が値 IMSL_INF_INF を持つ場合、この引

数は無視されます。

Imsl_quad interval ( 入力 )積分の限界を示すフラッグ。次の設定が許されます。

戻り値

次式の値が返されます。

ここで a と b は適切な積分範囲です。 値が計算できない場合,NaN が返されま

す。

オプション引数の概要

#include <imsl.h>float imsl_f_int_fcn_inf (float fcn, float bound, Imsl_quad interval,

IMSL_ERR_ABS, float err_abs,

Interval Integration LimitsIMSL_INF_BOUND (−∞, bound)IMSL_BOUND_INF (bound, ∞)IMSL_INF_INF (−∞, ∞)

( )fcnb

ax dx∫

Page 228: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_ERR_REL, float err_rel,IMSL_ERR_EST, float *err_est,IMSL_MAX_SUBINTER, int max_subinter,IMSL_N_SUBINTER, int *n_subinter,IMSL_N_EVALS, int *n_evals,IMSL_FCN_W_DATA, float fcn(), void *data,0)

オプション引数

IMSL_ERR_ABS, float err_abs ( 入力 )必要な絶対精度。

デフォルト: ここで ε は、マシン精度です。

IMSL_ERR_REL, float err_rel ( 入力 )必要な相対精度。

デフォルト: ここで ε は、マシン精度です。

IMSL_ERR_EST, float *err_est ( 出力 )誤差の絶対値の推定値を格納するアドレス。

IMSL_MAX_SUBINTER, int max_subinter ( 入力 )許される部分区間の数。デフォルト: max_subinter = 500

IMSL_N_SUBINTER, int *n_subinter ( 出力 )生成される部分区間の数を格納するアドレス。

IMSL_N_EVALS, int *n_evals ( 出力 )fcn の計算数を格納するアドレス。

IMSL_FCN_W_DATA, float fcn (float x, void *data), void *data ( 入力 )統合されるユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータ

を受け渡すポインターです。 詳細は、「イントロダクション」の「ユー

ザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_int_fcn_inf は絶対誤差を減少するために、総括的に適応枠組

みを使用する特殊目的の積分器です。これは最初に無限、又は。半無限区間を有限区間 [0, 1] に変換します。それから関数 imsl_f_int_fcn_sing と同じ方

法を使用します。

関数 imsl_f_int_fcn_inf は、Piessens その他 (1983 年 ) によるサブルーチン

QAGP に基づいています。

例題

例題 1

次式の値が計算されます。

#include <math.h>#include <imsl.h>

float fcn(float x); main(){

err_abs ε=

err_ ε=rel

( )( )

( )20

ln ln 10201 10

xdx

x

π∞ −=

+∫

Page 229: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float q, exact, pi;

pi = imsl_f_constant("pi", 0); /* 積分を計算 */ q = imsl_f_int_fcn_inf (fcn, 0.0, IMSL_BOUND_INF, 0); /* 結果と正確な答えをプリント */ exact = -pi*log(10.)/20.; printf("integral = %10.3f\nexact = %10.3f\n", q, exact);}

float fcn(float x){ float z; z = 10.*x; return log(x)/(1+ z*z);}

出力結果

integral = -0.362exact = -0.362

例題 2

次式の値が再び計算されます。

実際と推定誤差の値がプリントされます。これらの数値はマシン依存であることに注意してください。更に誤差推定値は通常は悲観的です。つまり、実際の誤差は、この例題におけるように誤差推定値よりは通常は小さくなります。関数計算の回数も又プリントされます。

#include <math.h>#include <imsl.h>

float fcn(float x); main(){ int n_evals; float q, exact, err_est, exact_err, pi;

pi = imsl_f_constant("pi", 0); /* 積分を計算 */ q = imsl_f_int_fcn_inf (fcn, 0.0, IMSL_BOUND_INF, IMSL_ERR_EST, &err_est, IMSL_N_EVALS, &n_evals, 0); /* 結果と正確な答えをプリント */ exact = -pi*log(10.)/20.; exact_err = fabs(exact - q); printf("integral = %10.3f\nexact = %10.3f\n", q, exact); printf("error estimate = %e\nexact error = %e\n", err_est, exact_err); printf("The number of function evaluations = %d\n", n_evals);}

float fcn(float x){ float z; z = 10.*x;

( )( )

20

ln 10ln201 10

x dxx

π∞ −=

+∫

Page 230: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

return log(x)/(1+ z*z);}

出力結果

integral = -0.362exact = -0.362error estimate = 2.801418e-06exact error = 2.980232e-08The number of function evaluations = 285

警告エラー

IMSL_ROUNDOFF_CONTAMINATION 要求される許容誤差が達成されることを

妨げる丸め誤差が検出されました。

IMSL_PRECISION_DEGRADATION 精度の低下が検出されました。

IMSL_EXTRAPOLATION_ROUNDOFF 要求される許容誤差が達成されることを

妨げる補外テーブルの中に丸め誤差が検出されました。

重大エラー

IMSL_DIVERGENT 積分は発散、又は、ゆっくりと収束しま

す。

IMSL_MAX_SUBINTERVALS 部分区間の許容最大数に到達しました。

int_fcn_trig正弦、または余弦の要素を含む関数を積分します。

概要

#include <imsl.h>

float imsl_f_int_fcn_trig (float fcn(), float a, float b, Imsl_quad weight, float omega, …, 0)

double 型関数は、 imsl_d_int_fcn_trigです。

必要な引数

float fcn (float x) ( 入力 )積分されるユーザ提供の関数。

float a ( 入力 )積分の下限。

float b ( 入力 )積分の上限。

Imsl_quad weight and float omega ( 入力 )これらの 2 つのパラメータは、三角法の重みを説明するために使用さ

れます。パラメータ weight は次に説明される 2 つの値を取ることが

できます。パラメータ omega = ω は 、三角法の加重関数の頻度を指

定します。

戻り値

weight = IMSL_COSの場合、次式の値が返されます。

weight Integration WeightIMSL_COS cos (ωx)IMSL_SIN sin (ωx)

Page 231: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

weight = IMSL_SINの場合、余弦の要素は、正弦の要素に置き換えられます。

値が計算できない場合、 NaN が返されます。

オプション引数の概要

#include <imsl.h> float imsl_f_int_fcn_trig (float fcn(), float a, float b, Imsl_quad weight, float omega,

IMSL_ERR_ABS, float err_abs, IMSL_ERR_REL, float err_rel, IMSL_ERR_EST, float *err_est, IMSL_MAX_SUBINTER, int max_subinter, IMSL_N_SUBINTER, int *n_subinter, IMSL_N_EVALS, int *n_evals, IMSL_MAX_MOMENTS, int max_moments, IMSL_FCN_W_DATA, float fcn(), void *data,0)

オプション引数

IMSL_ERR_ABS, float err_abs ( 入力 )必要な絶対精度。

デフォルト:

ここで ε は、マシン精度です。

IMSL_ERR_REL, float err_rel ( 入力 )必要な相対精度。

デフォルト:

ここで ε は、マシン精度です。

IMSL_ERR_EST, float *err_est ( 出力 )誤差の絶対値の推定値を格納するアドレス。

IMSL_MAX_SUBINTER, int max_subinter ( 入力 )許される部分区間の数。デフォルト: max_subinter = 500

IMSL_N_SUBINTER, int *n_subinter ( 出力 )生成される部分区間の数を格納するアドレス。

IMSL_N_EVALS, int *n_evals ( 出力 )fcn の計算数を格納するアドレス。

IMSL_MAX_MOMENTS, int max_moments ( 入力 )格納することができる Chebyshev のモーメントの数の上限。この数の

増加(減少)は、実行速度や使用空間の増加(減少)に繋がります。

デフォルト: max_moments = 21

IMSL_FCN_W_DATA, float fcn (float x, void *data), void *data ( 入力 )統合されるユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータ

を受け渡すポインターです。 詳細は、「イントロダクション」の「ユー

ザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_int は絶対誤差を減少するために、総括的に適応枠組みを使用する

特殊目的の積分器です。これは被積分関数が特殊な形式 w(x)f(x) を持つ積分を

計算し、ここでの w(x) は cos(ωx) もしくは sin(ωx) です。 ω のサイズに関連し

た部分区間の長さにより、修正 Clenshaw-Curtis 又は Gauss-Kronrod 則が、部分

区間上の積分を近似するために使用されています。それから、この関数は、関

( ) ( )fcn cosb

ax x dxω∫

err_abs ε=

err_ ε=rel

Page 232: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

数 imsl_f_int_fcn_sing と同じ方法を使用します。関数

imsl_f_int_fcn_trig は、P iessens その他 (1983 年 ) によるサブルーチン

QAWO を基にしています。

例題

例題 1

次式が計算されます。

特異性をゼロとしてプログラムしていることに注意してください。 2つの端点

での被積分関数を計算するので、これが必要です。

#include <math.h>#include <imsl.h>

float fcn(float x); main(){ float q, exact, omega;

omega = 10*imsl_f_constant("pi", 0); /* 積分を計算 */ q = imsl_f_int_fcn_trig (fcn, 0.0, 1.0, IMSL_SIN, omega, 0); /* 結果と正確な答えをプリント */ exact = -.1281316; printf("integral = %10.3f\nexact = %10.3f\n", q, exact);}

float fcn(float x){ return (x==0.0) ? 0.0 : log(x);}

出力結果

integral = -0.128exact = -0.128

例題 2

次式の値が再び計算されます。

実際と推定誤差の値がプリントされます。これらの数値はマシン依存である

ことに注意してください。更に誤差推定値は通常は悲観的です。つまり、実際の誤差は、この例題におけるように誤差推定値よりは通常は小さくなりなす。関数計算の回数も又プリントされます。

#include <math.h>#include <imsl.h>

float fcn(float x); main(){ int n_evals; float q, exact, omega, err_est, exact_err;

( ) ( )1

0ln sin 10x x dxπ∫

( ) ( )1

0ln sin 10x x dxπ∫

Page 233: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

omega = 10*imsl_f_constant("pi", 0); /* 積分を計算 */ q = imsl_f_int_fcn_trig (fcn, 0.0, 1.0, IMSL_SIN, omega, IMSL_ERR_EST, &err_est, IMSL_N_EVALS, &n_evals, 0); /* 結果と正確な答えをプリント */ exact = -.1281316; exact_err = fabs(exact - q); printf("integral = %10.3f\nexact = %10.3f\n", q, exact); printf("error estimate = %e\nexact error = %e\n", err_est, exact_err); printf("The number of function evaluations = %d\n", n_evals);}

float fcn(float x){ return (x==0.0) ? 0.0 : log(x);}

出力結果

integral = -0.128exact = -0.128error estimate = 7.504603e-05exact error = 5.245209e-06The number of function evaluations = 215

警告エラー

IMSL_ROUNDOFF_CONTAMINATION 要求される許容誤差が達成されることを

妨げる丸め誤差が検出されました。

IMSL_PRECISION_DEGRADATION 精度の低下が検出されました。

IMSL_EXTRAPOLATION_ROUNDOFF 要求される許容誤差が達成されることを

妨げる補外テーブルの中に丸め誤差が検出されました。

重大エラー

IMSL_DIVERGENT 積分は発散、又は、ゆっくりと収束しま

す。

IMSL_MAX_SUBINTERVALS 部分区間の許容最大数に到達しました。

int_fcn_fourierフーリエ正弦変換又は、フーリエ余弦変換を計算します。

概要

#include <imsl.h>

float imsl_f_int_fcn_fourier (float fcn(), float a, Imsl_quad weight, float omega, …, 0)

double 型関数 imsl_d_int_fcn_fourierです。

必要な引数

float fcn (float x) ( 入力 )積分されるユーザ提供の関数。

float a ( 入力 )積分の下限。 積分の上限は ∞ です。

Page 234: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Imsl_quad weight and float omega ( 入力 )これらの 2 つのパラメータは、三角法の重みを説明するために使用さ

れます。パラメータ weight は次に説明される 2 つの値を取ることが

できます。パラメータ omega = ω は 、三角法の加重関数の頻度を指

定します。

戻り値

weight = IMSL_COSの場合、次式の値が返されます。

weight = IMSL_SINの場合、余弦の要素は、正弦の要素に置き換えられます。値が計

算できない場合、 NaN が返されます。

オプション引数の概要

#include <imsl.h> float imsl_f_int_fcn_fourier (float fcn(), float a, Imsl_quad weight, float omega,

IMSL_ERR_ABS, float err_abs, IMSL_ERR_EST, float *err_est, IMSL_MAX_SUBINTER, int max_subinter, IMSL_MAX_CYCLES, int max_cycles, IMSL_MAX_MOMENTS, int max_moments, IMSL_N_CYCLES, int *n_cycles, IMSL_N_EVALS, int *n_evals, IMSL_FCN_W_DATA, float fcn(), void *data,0)

オプション引数

IMSL_ERR_ABS, float err_abs ( 入力 )必要な絶対精度。

デフォルト: ここで ε は、マシン精度です。

IMSL_ERR_EST, float *err_est ( 出力 )誤差の絶対値の推定値を格納するアドレス。

IMSL_MAX_SUBINTER, int max_subinter ( 入力 )許される部分区間の数。デフォルト: max_subinter = 500

IMSL_MAX_CYCLES, int max_cycles ( 入力 )許される周期の数。デフォルト: max_subinter = 50

IMSL_MAX_MOMENTS, int max_moments ( 入力 )各周期の区画において許される部分区間の数。デフォルト: max_moments = 21

IMSL_N_CYCLES, int *n_cycles ( 出力 )生成された周期の数を格納するアドレス。

IMSL_N_EVALS, int *n_evals ( 出力 )fcn の計算数を格納するアドレス。

weight Integration WeightIMSL_COS cos (ωx)IMSL_SIN sin (ωx)

( ) ( )fcn cosa

x x dxω∞

err_abs ε=

Page 235: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_FCN_W_DATA, float fcn (float x, void *data), void *data ( 入力 )統合されるユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータ

を受け渡すポインターです。 詳細は、「イントロダクション」の「ユー

ザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_int_fcn_fourier は絶対誤差を減少するために、総括的に適応

枠組みを使用する特殊目的の積分器です。これは被積分関数が特殊な形式 w(x)f(x) を持つ積分を計算し、ここでの w(x) は cos(ωx) もしくは sin(ωx) です。

積分区間は、常に [a, ∞] 形式の半無限区間です。 これらのフーリエ積分は、関

数 imsl_f_int_fcn_trig を呼び出した後に補外を繰り返すことで近似されま

す。

関数 imsl_f_int_fcn_fourier は、P iessens その他 (1983 年 ) によるサブ

ルーチン QAWF を基にしています。

例題

例題 1

次式の値が計算されます。

被積分関数が、ゼロの特異点のために保護するようにプログラムされていることに注意してください。

#include <math.h>#include <imsl.h>

float fcn(float x); main(){ float q, exact, omega;

omega = imsl_f_constant("pi",0) / 2.; /* 積分を計算 */ q = imsl_f_int_fcn_fourier (fcn, 0.0, IMSL_COS, omega, 0); /* 結果と正確な答えをプリント */ exact = 1.0; printf("integral = %10.3f\nexact = %10.3f\n", q, exact);}

float fcn(float x){ return (x==0.) ? 0. : 1./sqrt(x);}

出力結果

integral = 1.000exact = 1.000

例題 2

次式の値が再度計算されます。

実際と推定誤差の値がプリントされます。これらの数値はマシン依存である

ことに注意してください。更に誤差推定値は通常は悲観的です。つまり、実際

( )1/ 2

0cos / 2 1x x dxπ

∞ − =∫

( )1/ 2

0cos / 2 1x x dxπ

∞ − =∫

Page 236: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

の誤差は、この例題におけるように誤差推定値よりは通常は小さくなりなす。関数計算の回数も又プリントされます。被積分関数が、ゼロでの特異点のために保護するようにプログラムされていることに注意してください。

#include <math.h>#include <imsl.h>

float fcn(float x); main(){ int n_evals; float q, exact, omega, err_est, exact_err;

omega = imsl_f_constant("pi",0) / 2.0; /* 積分を計算 */ q = imsl_f_int_fcn_fourier (fcn, 0.0, IMSL_COS, omega, IMSL_ERR_EST, &err_est, IMSL_N_EVALS, &n_evals, 0); /* 結果と正確な答えをプリント */ exact = 1.; exact_err = fabs(exact - q); printf("integral = %10.3f\nexact = %10.3f\n", q, exact); printf("error estimate = %e\nexact error = %e\n", err_est, exact_err); printf("The number of function evaluations = %d\n", n_evals);}

float fcn(float x){ return (x==0.) ? 0. : 1./sqrt(x);}

出力結果

integral = 1.000exact = 1.000error estimate = 1.803637e-04exact error = 1.013279e-06The number of function evaluations = 405

警告エラー

IMSL_BAD_INTEGRAND_BEHAVIOR 悪い被積分項の振舞いが、1 周期以上で

起こりました。

IMSL_EXTRAPOLATION_PROBLEMS 周期の積分の結果から形成された列の収

束を加速させるために構築された補外表は、要求された精度に収束しません。

重大エラー

IMSL_MAX_CYCLES 許可される最大の周期数に達しました。

int_fcn_cauchyコーシーの主値を用いて次式の積分を計算します。

概要

#include <imsl.h>

( )b

a

f xdx

x c−∫

Page 237: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float imsl_f_int_fcn_cauchy (float fcn(), float a, float b, float c, …, 0)double 型関数は、imsl_d_int_fcn_cauchyです。

必要な引数

float fcn (float x) ( 入力 )積分されるユーザ提供の関数。

float a ( 入力 )積分の下限。

float b ( 入力 )積分の上限。

float c ( 入力 )特異点 c は、 a もしくは b と同じではいけません。

戻り値

次式の値が返されます。

値を計算することができない場合、NaN が返されます。

オプション引数の概要

#include <imsl.h>float imsl_f_int_fcn_cauchy (float fcn(), float a, float b, float c,

IMSL_ERR_ABS, float err_abs,IMSL_ERR_REL, float err_rel, IMSL_ERR_EST, float *err_est, IMSL_MAX_SUBINTER, int max_subinter, IMSL_N_SUBINTER, int *n_subinter, IMSL_N_EVALS, int *n_evals, IMSL_FCN_W_DATA, float fcn(), void *data,0)

オプション引数

IMSL_ERR_ABS, float err_abs ( 入力 )必要な絶対精度。

デフォルト: ここで ε は、マシン精度です。

IMSL_ERR_REL, float err_rel ( 入力 )必要な相対精度。

デフォルト:

ここで ε は、マシン精度です。

IMSL_ERR_EST, float *err_est ( 出力 )誤差の絶対値の推定値を格納するアドレス。

IMSL_MAX_SUBINTER, int max_subinter ( 入力 )許される部分区間の数。デフォルト: max_subinter = 500

IMSL_N_SUBINTER, int *n_subinter ( 出力 )生成される部分区間の数を格納するアドレス。

IMSL_N_EVALS, int *n_evals ( 出力 )fcn の計算数を格納するアドレス。

IMSL_FCN_W_DATA, float fcn (float x, void *data), void *data ( 入力 )統合されるユーザ提供の関数。また、ユーザにより提供されたデータ

( )fcnb

a

xdx

x c−∫

err_abs ε=

err_r ε=el

Page 238: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

へのポインターも受け入れます。 data は、ユーザ提供の関数にデータ

を受け渡すポインターです。 詳細は、「イントロダクション」の「ユー

ザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_int_fcn_cauchy は絶対誤差を減少するために、総括的に適応枠

組みを使用します。これは被積分関数が特殊な形式 w(x)f(x) を持つ積分を計算

し、ここでは、w(x) = 1/(x − c) になります。 c が、積分の区間内に位置する場

合、積分は、コーシーの主値として解釈されます。修正 Clenshaw-Curtis と Gauss-Kronrod 則の組み合わせが使用されます。

関数 imsl_f_in は、Piessens とその他(1983 年)によるサブルーチン QAWCの実装です。

例題

例題 1

次式のコーシーの主値が計算されます。

#include <math.h>#include <imsl.h>

float fcn(float x);

main(){ float q, exact; /* 積分を計算 */ q = imsl_f_int_fcn_cauchy (fcn, -1.0, 5.0, 0.0, 0); /* 結果と正確な答えをプリント */ exact = log(125./631.)/18.; printf("integral = %10.3f\nexact = %10.3f\n", q, exact);}

float fcn(float x){ return 1.0/(5.0*x*x*x+6.0);}

出力結果

integral = -0.090exact = -0.090

例題 2

次式のコーシーの主値が、再度計算されます。

実際と推定誤差の値がプリントされます。これらの数値はマシン依存である

ことに注意してください。更に誤差推定値は通常は悲観的です。つまり、実際の誤差は、この例題におけるように誤差推定値よりは通常は小さくなりなす。関数計算の回数も又プリントされます。

#include <math.h>#include <imsl.h>

float fcn(float x);

( )( )5

31

ln 125 / 6311185 6

dxx x−

=+∫

( )( )5

31

ln 125 / 6311185 6

dxx x−

=+∫

Page 239: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

main(){ int n_evals; float q, exact, err_est, exact_err; /* 積分を計算 */ q = imsl_f_int_fcn_cauchy (fcn, -1.0, 5.0, 0.0, IMSL_ERR_EST, &err_est, IMSL_N_EVALS, &n_evals, 0); /* 結果と正確な答えをプリント */ exact = log(125./631.)/18.; exact_err = fabs(exact - q); printf("integral = %10.3f\nexact = %10.3f\n", q, exact); printf("error estimate = %e\nexact error = %e\n", err_est, exact_err); printf("The number of function evaluations = %d\n", n_evals);}

float fcn(float x){ return 1.0/(5.0*x*x*x+6.0);}

出力結果

integral = -0.090exact = -0.090error estimate = 2.160174e-06exact error = 0.000000e+00The number of function evaluations = 215

警告エラー

IMSL_ROUNDOFF_CONTAMINATION 要求される許容誤差が達成されることを

妨げる丸め誤差が検出されました。

IMSL_PRECISION_DEGRADATION 精度の低下が検出されました。

重大エラー

IMSL_MAX_SUBINTERVALS 部分区間の許容最大数に到達しました。

int_fcn_smooth非適応則を使って平滑化関数を積分します。

概要

#include <imsl.h>

float imsl_f_int_fcn_smooth (float fcn(), float a, float b, …, 0)double 型関数は、imsl_d_int_fcn_smoothです。

必要な引数

float fcn (float x) ( 入力 )積分されるユーザ提供の関数。

float a ( 入力 )積分の下限。

float b ( 入力 )積分の上限。

戻り値

次式の値が返されます。

Page 240: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

値が計算されない場合、 NaN が返されます。

オプション引数の概要

#include <imsl.h> float imsl_f_int_fcn_smooth (float fcn(), float a, float b,

IMSL_ERR_ABS, float err_abs, IMSL_ERR_REL, float err_rel, IMSL_ERR_EST, float *err_est, IMSL_FCN_W_DATA, float fcn(), void *data,0)

オプション引数

IMSL_ERR_ABS, float err_abs ( 入力 )必要な絶対精度。

デフォルト: ここで ε は、マシン精度です。

IMSL_ERR_REL, float err_rel ( 入力 )必要な相対精度。

デフォルト: ここで ε は、マシン精度です。

IMSL_ERR_EST, float *err_est ( 出力 )誤差の絶対値の推定値を格納するアドレス。

IMSL_FCN_W_DATA, float fcn (float x, void *data), void *data ( 入力 )統合されるユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータ

を受け渡すポインターです。 詳細は、「イントロダクション」の「ユー

ザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_int_fcn_smooth は、平滑化関数を積分するように設計されてい

ます。入れ子になった Paterson 則の順序 10、 21、 43、87 を基にした非適応的な

求積手順を実装しています。これらの法則は、それぞれ 19、 31、 64、130 精度

をもつ正の求積法です。関数 imsl_f_int_fcn_smooth は、引き続きこれらの

法則を適用し、誤差推定がユーザ提供の制約を満たすか、最後の法則が適応されるまで、誤差を推定します。

この関数は、それ程堅牢ではありませんが、平滑化関数向けには、効率的です。 imsl_f_int_fcn_smooth のパフォーマンス良くない場合は、関数 imsl_f_int_fcn_sing の使用をお勧めします。

関数 imsl_f_int_fcn_smooth は、Piessens とその他 (1983 年)によるサブ

ルーチン QNG が基になっています。

例題

例題 1

次式の値が計算されます。

#include <math.h>#include <imsl.h>

float fcn(float x);

( )fcnb

ax dx∫

err_abs ε=

err_rel ε=

2 2

01xxe dx e= +∫

Page 241: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

main(){ float q, exact; /* 積分を計算 */ q = imsl_f_int_fcn_smooth (fcn, 0., 2., 0); /* 結果と正確な答えをプリント */ exact = exp(2.0) + 1.0; printf("integral = %10.3f\nexact = %10.3f\n", q, exact);}

float fcn(float x){ return x * exp(x);}

出力結果

integral = 8.389exact = 8.389

例題 2

次式の値が再度計算されます。

実際と推定誤差の値がプリントされます。これらの数値はマシン依存であることに注意してください。更に誤差推定値は通常は悲観的です。つまり、実際の誤差は、この例題におけるように誤差推定値よりは通常は小さくなりなす。

#include <math.h>#include <imsl.h>

float fcn(float x);

main(){ float q, exact, err_est, exact_err; /* 積分を計算 */ q = imsl_f_int_fcn_smooth (fcn, 0.0, 2.0, IMSL_ERR_EST, &err_est, 0); /* 結果と正確な答えをプリント */ exact = exp(2.0) + 1.0; exact_err = fabs(exact - q); printf("integral = %10.3f\nexact = %10.3f\n", q, exact); printf("error estimate = %e\nexact error = %e\n", err_est, exact_err);}

float fcn(float x){ return x * exp(x);}

出力結果

integral = 8.389exact = 8.389error estimate = 5.000267e-05exact error = 9.536743e-07

重大エラー

IMSL_MAX_STEPS 許可される最大ステップ数に達しました。この

ルーチンにとって被積分関数は困難です。

2 2

01xxe dx e= +∫

Page 242: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int_fcn_2d2 次元累次積分を計算します。

概要

#include <imsl.h>

float imsl_f_int_fcn_2d (float fcn(), float a, float b, float gcn (float x), float hcn (float x), …, 0)

double 型関数は、 imsl_d_int_fcn_2d.

必要な引数

float fcn (float x, float y) ( 入力 )積分されるユーザ提供の関数。

float a ( 入力 )外側積分の下限。

float b ( 入力 )外側積分の上限。

float gcn (float x) ( 入力 )内側積分の下限を計算するためのユーザ提供の関数。

float hcn (float x) ( 入力 )内側積分の上限を計算するためのユーザ提供の関数。

戻り値

次式の値が返されます。

値が計算できない場合、 NaN が返されます。

オプション引数の概要

#include <imsl.h> float imsl_f_int_fcn_2d (float fcn(), float a, float b, float gcn (), float hcn (),

IMSL_ERR_ABS, float err_abs, IMSL_ERR_REL, float err_rel, IMSL_ERR_EST, float *err_est, IMSL_MAX_SUBINTER, int max_subinter, IMSL_N_SUBINTER, int *n_subinter, IMSL_N_EVALS, int *n_evals, IMSL_FCN_W_DATA, float fcn(), void *data,IMSL_GCN_W_DATA, float gcn(), void *data,IMSL_HCN_W_DATA, float hcn(), void *data,0)

オプション引数

IMSL_ERR_ABS, float err_abs ( 入力 )必要な絶対精度。

デフォルト: ここで ε は、マシン精度です。

IMSL_ERR_REL, float err_rel ( 入力 )必要な相対精度。

デフォルト: ここで ε は、マシン精度です。

( )( )

( )fcn ,

b hcn x

a gcn xx y dydx∫ ∫

err_abs ε=

err_rel ε=

Page 243: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_ERR_EST, float *err_est ( 出力 )誤差の絶対値の推定値を格納するアドレス。

IMSL_MAX_SUBINTER, int max_subinter ( 入力 )許される部分区間の数。デフォルト: max_subinter = 500

IMSL_N_SUBINTER, int *n_subinter ( 出力 )生成される部分区間の数を格納するアドレス。

IMSL_N_EVALS, int *n_evals ( 出力 )fcn の計算数を格納するアドレス。

IMSL_FCN_W_DATA, float fcn (float x, float y, void *data), void *data ( 入力 )統合されるユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータ

を受け渡すポインターです。 詳細は、「イントロダクション」の「ユー

ザ提供関数へのデータの受け渡し」を参照してください。

IMSL_GCN_W_DATA, float gcn (float x, void *data), void *data ( 入力 )内側積分の下限を計算するためのユーザ提供の関数。ユーザ提供のデータへのポインターも受け取ります。詳細は、本マニュアルの先頭にある 「イントロダクション」 内にある「ユーザ提供関数へのデータ

の受け渡し」を参照してください。

IMSL_HCN_W_DATA, float hcn (float x, void *data), void *data ( 入力 )内側積分の上限を計算するためのユーザ提供の関数。ユーザ提供のデータへのポインターも受け取ります。詳細は、本マニュアルの先頭にある 「イントロダクション」 内にある「ユーザ提供関数へのデータ

の受け渡し」を参照してください。

説明

関数 imsl_f_int_fcn_2d は 2 次元累次積分を近似します。

誤差の推定値は err_est に返されます。 低次元規則は非平滑積分関数に使用

されますが、高次元規則は平滑(振動)積分関数により有効です。

例題

例題 1

この例題は次の積分の値を計算します。

#include <math.h>#include <imsl.h>

float fcn(float x, float y), gcn(float x), hcn(float x);

main(){ float q, exact; /* 積分を計算 */ q = imsl_f_int_fcn_2d (fcn, 0.0, 1.0, gcn, hcn, 0); /* 結果と正確な解をプリント */ exact = 0.5*(cos(9.0)+cos(2.0)-cos(10.0)-cos(1.0)); printf("integral = %10.3f\nexact = %10.3f\n", q, exact);}

float fcn(float x, float y)

( )( )

( ),

b h x

a g xf x y dydx∫ ∫

( )1 3 2

0 1cosy x y dydx+∫ ∫

Page 244: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{ return y * cos(x+y*y);}

float gcn(float x){ return 1.0;}

float hcn(float x){ return 3.0;}

出力結果

integral = -0.514exact = -0.514

例題 2

この例題は、次の積分の値を計算します。

同様に実際と推定の誤差の値がプリントされます。これらの数はマシン依存であることに注意してください。更に、通常、誤差推定は悲観的です。このために、この例題に於けるように通常は、実際の誤差は推定誤差よりは小さくなります。 関数計算の数が又プリントされます。

#include <math.h>#include <imsl.h>

float fcn(float x, float y), gcn(float x), hcn(float x); main(){ int n_evals; float q, exact, err_est, exact_err; /* 積分を計算 */ q = imsl_f_int_fcn_2d (fcn, 0., 1., gcn, hcn, IMSL_ERR_EST, &err_est, IMSL_N_EVALS, &n_evals, 0); /* 結果と正確な解をプリント */ exact = 0.5*(cos(9.0)+cos(2.0)-cos(10.0)-cos(1.0)); exact_err = fabs(exact - q);

printf("integral = %10.3f\nexact = %10.3f\n", q, exact); printf("error estimate = %e\nexact error = %e\n", err_est, exact_err); printf("The number of function evaluations = %d\n", n_evals);}

float fcn(float x, float y){ return y * cos(x+y*y);}

float gcn(float x){ return 1.0;}

float hcn(float x)

( )1 3 2

0 1cosy x y dydx+∫ ∫

Page 245: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{ return 3.0;}

出力結果

integral = -0.514exact = -0.514error estimate = 3.065193e-06exact error = 1.192093e-07The number of function evaluations = 441

警告エラー

IMSL_ROUNDOFF_CONTAMINATION 要求される許容誤差が達成されることを

妨げる丸め誤差が検出されました。

IMSL_PRECISION_DEGRADATION 精度の低下が検出されました。

重大エラー

IMSL_MAX_SUBINTERVALS 部分区間の許容最大数に到達しました。

int_fcn_hyper_rect次の超矩形上の関数を積分します。

概要

#include <imsl.h>

float imsl_f_int_fcn_hyper_rect (float fcn(), int ndim, float a[], float b[], …, 0)

double 型関数は、 imsl_d_int_fcn_hyper_rectです。

必要な引数

float fcn (int ndim, float x[]) ( 入力 )積分されるユーザ提供の関数。

int ndim ( 入力 )超矩形の次元。

float a[] ( 入力 )積分の下限。

float b[] ( 入力 )積分の上限。

戻り値

次式の値が返されます。

値が計算できない場合、NaN が返されます。

オプション引数の概要

#include <imsl.h> float imsl_f_int_fcn_hyper_rect (float fcn(), int ndim, float a[], float b[], IMSL_ERR_ABS,

float err_abs, IMSL_ERR_REL, float err_rel, IMSL_ERR_EST, float *err_est,

( )0 1

0 10 1 1 0, ,n

n

b b

n na af x x dx dx−

−− −∫ ∫K K K

( )0 1

0 10 1 1 0, ,n

n

b b

n na af x x dx dx−

−− −∫ ∫K K K

Page 246: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_MAX_EVALS, int max_evals, IMSL_FCN_W_DATA, float fcn(), void *data,0)

オプション引数

IMSL_ERR_ABS, float err_abs ( 入力 )必要な絶対精度。

デフォルト: ここで ε は、マシン精度です。

IMSL_ERR_REL, float err_rel ( 入力 )必要な相対精度。

デフォルト: ここで ε は、マシン精度です。

IMSL_ERR_EST, float *err_est ( 出力 )誤差の絶対値の推定値を格納するアドレス。

IMSL_MAX_EVALS, int max_evals ( 入力 )許される計算回数。デフォルト: max_evals = 32n.

IMSL_FCN_W_DATA, float fcn (int ndim, float x[], void *data), void *data (入力 )統合されるユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータ

を受け渡すポインターです。 詳細は、「イントロダクション」の「ユー

ザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_int_fcn_hyper_rect は n 次元累次積分を近似します。

誤差の推定値はオプション引数 err_est に返されます。近似はガウス公式の

繰り返し適用によって達成されます。この積分は各方向の 2点テンソル積公式

によって最初に推定されます。その後、 i = 1, ..., n に対してこの関数は i 番目の

方向の点数を 2 倍にして新しい推定を計算して、この新しい推定がかなり変わ

らなかったならばすぐにその後で点数を半分にします。このプロセスはいずれの1つの完全な全体実行も、どの方向でも標本点数で増加しない結果になるまで繰り返されます。一方向のガウス点数が 256 を超える又は 1 つの全体実行を

完成するために必要な関数計算数が max_evals を超えるまで繰り返されます。

例題

この例題では拡大する立方体の次式の積分を計算します。

誤差推定値の値はマシンに依存します。R 3 の積分は π3/2 です。

#include <math.h>#include <imsl.h>

float fcn(int n, float x[]); main(){ int i, j, ndim = 3; float q, limit, a[3], b[3];

err_abs ε=

err_rel ε=

( )1

0 10 1 1 0, ,n

n

b b

n na af x x dx dx−

−− −∫ ∫K K K

( )2 2 21 2 3x x xe− + +

Page 247: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

printf(" integral limit \n"); limit = pow(imsl_f_constant("pi",0), 1.5); /* 積分を計算 */ for (i = 0; i < 6; i++) { for (j = 0; j < 3; j++) { a[j] = -(i+1)/2.; b[j] = (i+1)/2.; } q = imsl_f_int_fcn_hyper_rect (fcn, ndim, a, b, 0); /* 結果と制限解をプリント */ printf(" %10.3f %10.3f\n", q, limit); }}

float fcn(int n, float x[]){ float s; s = x[0]*x[0] + x[1]*x[1] + x[2]*x[2]; return exp(-s);}

出力結果

integral limit 0.785 5.568 3.332 5.568 5.021 5.568 5.491 5.568 5.561 5.568 5.568 5.568

警告エラー

IMSL_MAX_EVALS_TOO_LARGE 引数 max_evals が 28n 以上に設定されまし

た。

重大エラー

IMSL_NOT_CONVERGENT 最大の計算回数に達しましたが、収束には

達していません。

int_fcn_qmc準モンテカルロ法を使用して超幾何空間上の関数を積分します。

概要

#include <imsl.h>

float imsl_f_int_fcn_qmc (float fcn(), int ndim, float a[], float b[], …, 0)

double 型関数は、 imsl_d_int_fcn_qmcです。

必要な引数

float fcn (int ndim, float x[]) ( 入力 )積分されるユーザ提供の関数。

int ndim ( 入力 )超矩形の次元。

float a[] ( 入力 )積分の下限。

Page 248: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float b[] ( 入力 )積分の上限。

戻り値

次式の値が返されます。

値が計算できない場合、NaN が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_int_fcn_qmc (float fcn(), int ndim, float a[], float b[],IMSL_ERR_ABS, float err_abs,

IMSL_ERR_REL, float err_rel, IMSL_ERR_EST, float *err_est,IMSL_MAX_EVALS, int max_evals,IMSL_BASE, int base,IMSL_SKIP, int skip,IMSL_FCN_W_DATA, float fcn(), void *data,0)

オプション引数

IMSL_ERR_ABS, float err_abs ( 入力 )必要な絶対精度。デフォルト: err_abs = 1.0e-4.

IMSL_ERR_REL, float err_rel ( 入力 )必要な相対精度。デフォルト: err_abs = 1.0e-4.

IMSL_ERR_EST, float *err_est ( 出力 )誤差の絶対値の推定値を格納するアドレス。

IMSL_MAX_EVALS, int max_evals ( 入力 )許される計算回数。デフォルト: No limit.

IMSL_BASE, int base ( 入力 )Faure 列を計算するために使用される IMSL_BASE の値。

IMSL_SKIP, int skip ( 入力 )Faure 列を計算するために使用される IMSL_SKIP の値。

IMSL_FCN_W_DATA, float fcn (int ndim, float x[], void *data), void *data (入力 )統合されるユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータ

を受け渡すポインターです。 詳細は、「イントロダクション」の「ユー

ザ提供関数へのデータの受け渡し」を参照してください。

説明

imsl_f_fcn_hyper_rect 等の直接法による超立方体の関数の積分は、かなり

低次元の超立方体だけに実用的です。これは次元が増加するにつれて必要な作業量が指数的に増加するからです。

直接法の代わりとしてモンテカルロ法があり、その積分は無作為に選択された点の列の平均された関数の値として計算されます。この関数の控えめの仮定で

は、この方法は 1/n 1/2 のように収束して、この n はこの関数が計算される点数

です。

関数が計算する点を注意深く選ぶ事によってモンテカルロ法の性能を向上することが可能です。無作為に分布する点は非一様に分散される傾向があります。

( )0 1

0 10 1 1 0, ,n

n

b b

n na af x x dx dx−

−− −∫ ∫K K K

Page 249: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

無作為点の列の代わりが低不適合(low-discrepancy)列です。 低不適合列は高

度に一様化されたものです。

この関数は imsl__f_faure_next_point によって計算される低不適合 Faure 列を基にしています。 ( 第 10 章:統計と乱数発生を参照してください。)

例題

#include <imsl.h>#include <math.h>

float fcn(int ndim, float x[]);

main(){ int k, ndim = 10; float q, a[10], b[10];

for (k = 0; k < ndim; k++) { a[k] = 0.0; b[k] = 1.0; } q = imsl_f_int_fcn_qmc (fcn, ndim, a, b, 0); printf ("integral=%10.3f\n”, q);}

float fcn (int ndim, float x[]){ int i, j; float prod, sum = 0.0, sign = -1.0;

for (i = 0; i < ndim; i++) { prod = 1.0; for (j = 0; j <= i; j++) { prod *= x[j]; } sum += sign * prod; sign = -sign; } return sum;}

出力結果

q = -0.333

重大エラー

IMSL_NOT_CONVERGENT 最大の計算回数に達しましたが、収束には

達していません。

gauss_quad_rule種々の古典的加重関数で Gauss、Gauss-Radau、又は Gauss-Lobatto 求積法を計

算します。

概要

#include <imsl.h>

void imsl_f_gauss_quad_rule (int n, float weights[], float points[], …, 0)

double 型関数は、imsl_d_gauss_quad_ruleです。

Page 250: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

int n ( 入力 )積分点数。

float weights[] ( 出力 )求積加重を含んだ長さ n の配列。

float points[] ( 出力 )積分点を含んだ長さ n の配列。 このルーチンのデフォルトの操作は Gauss Legendre 点と加重を生成することです。

オプション引数の概要

#include <imsl.h>void imsl_f_gauss_quad_rule (int n, float weights[], float points[],

IMSL_CHEBYSHEV_FIRST, IMSL_CHEBYSHEV_SECOND, IMSL_HERMITE, IMSL_COSH, IMSL_JACOBI, float alpha, float beta, IMSL_GEN_LAGUERRE, float alpha, IMSL_FIXED_POINT, float a, IMSL_TWO_FIXED_POINTS, float a, float b, 0)

オプション引数

IMSL_CHEBYSHEV_FIRST

区間 (−1, 1) で次の加重関数を使用して Gauss 点と加重を計算します。

IMSL_CHEBYSHEV_SECOND

区間 (−1, 1) で次の加重関数を使用して Gauss 点と加重を計算します。

IMSL_HERMITE

区間 (−∞, ∞) で加重関数 exp (−x 2 ) を使用して Gauss 点と加重を計算し

ます。

IMSL_COSH区間 (−∞, ∞) で加重関数 1/(cosh(x)) を使用して Gauss 点と加重を計算

します。

IMSL_JACOBI, float alpha, float beta ( 入力 )区間 (−1, 1) で加重関数 (1 − x)α(1 + x)β を使用して Gauss 点と加重を

計算します。

IMSL_GEN_LAGUERRE, float alpha ( 入力 )区間 (0, ∞) で加重関数 exp (−x)x α を使用して Gauss 点と加重を計算し

ます。

IMSL_FIXED_POINT, float a ( 入力 )指定された加重関数と固定点 a を使用して Gauss-Radau 点と加重を計

算します。この公式は、2n − 1 より小さい次数の多項式を正確に積分し

ます。

IMSL_TWO_FIXED_POINTS, float a, float b ( 入力 )指定された加重関数と固定点 a と b を使用して Gauss--Lobatto 点と加

重を計算します。 この公式は、2n − 2 より小さい次数の多項式を正確に

積分します。

21/ 1 x−

21 x−

Page 251: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

関数 imsl_f_gauss_quad_rule は、最も一般的な加重のための Gauss、Gauss-Radau、又は Gauss-Lobatto 求積公式の点と加重を生成します。デフォル

トの関数は区間 (−1, 1) で1に全く等しい加重関数です。実際には、指定され

るかも知れない 1 点、又は 2 点はこの区間の端点にある必要がないので、この

提唱よりも少し概括的になっています。この関数は、サブルーチン GAUSSQUADRULE ( Golub と Welsch 1969 年 ) の修正です。

デフォルトの場合において、2n より小さい次数の多項式である全ての関数 f に対して、次式であるようにこの関数は x = points の点と w = weights の加重を

返します。

IMSL_FIXED_POINTキーワードが指定されると、上述の xi の 1 つは a に等しく

なります。同様に、IMSL_TWO_FIXED_POINTSキーワード が指定されると、x の成分の 2 つは a と b に等しくなります。一般的に、上述の求積公式の精度は n が増加すると低下します。この求積規則は、F が固定点の数である 2n − F より小さい次数の多項式である全ての関数 f を積分します。

例題

例題 1

3 点 Gauss Legendre 積分点と加重が計算されて、次の積分を近似するために使

用されます。

この積分は最初の6つの単項式に対しては正確ですが、最後の近似は誤差があることに注意してください。一般的に、k 点を持つ Gauss 規則は 2k より小さい

次数を持つ多項式を正確に積分します。

#include <math.h>#include <imsl.h>

#define QUADPTS 3#define POWERS 7

main(){ int i, j; float weights[QUADPTS], points[QUADPTS], s[POWERS]; /* Gauss Legendre 求積点を生成 */ /* quadrature points */ imsl_f_gauss_quad_rule (QUADPTS, weights, points, 0); /* 次の関数を積分 */ /* 1, x, ..., pow(x,POWERS-1) */ for(i = 0; i < POWERS; i++) { s[i] = 0.0; for(j = 0; j < QUADPTS; j++) { s[i] += weights[j]*imsl_fi_power(points[j], i); } } printf("The integral from -1 to 1 of pow(x, i) is\n"); printf("Function Quadrature Exact\n\n"); for(i = 0; i < POWERS; i++){ float z; z = (1-i%2)*2./(i+1.); printf("pow(x, %d) %10.3f %10.3f\n", i, s[i], z); }}

( ) ( ) ( )1

Nb

i iai

f x w x dx f x w=

= ∑∫

1

10, , 6ix dx i

−=∫ K

Page 252: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

The integral from -1 to 1 of pow(x, i) isFunction Quadrature Exact

pow(x, 0) 2.000 2.000pow(x, 1) 0.000 0.000pow(x, 2) 0.667 0.667pow(x, 3) 0.000 0.000pow(x, 4) 0.400 0.400pow(x, 5) 0.000 0.000pow(x, 6) 0.240 0.286

例題 2

3 点 Gauss Legendre 求積点と加重が計算されて、次の積分を近似するために使

用されます。

この積分は最初の 6 つの単項式に対しては正確ですが、最後の近似は誤差があ

ることに注意してください。一般的に、k 点を持つ Gauss 規則は 2k より小さい

次数を持つ多項式を正確に積分します。

#include <math.h>#include <imsl.h>

#define QUADPTS 3#define POWERS 7

main(){ int i, j; float weights[QUADPTS], points[QUADPTS], s[POWERS], z; /* Gauss Legendre 積分点を生成 */ imsl_f_gauss_quad_rule (QUADPTS, weights, points, IMSL_GEN_LAGUERRE, 1.0,

0); /* 次の関数を積分 */ /* 1, x, ..., pow(x,POWERS-1) */ for(i = 0; i < POWERS; i++) { s[i] = 0.0; for(j = 0; j < QUADPTS; j++){ s[i] += weights[j]*imsl_fi_power(points[j], i); } } printf("The integral from 0 to infinity of pow(x, i)*x*exp(x) is\n"); printf("Function Quadrature Exact\n\n"); for(z = 1.0, i = 0; i < POWERS; i++){ z *= (i+1); printf("pow(x, %d) %10.3f %10.3f \n", i, s[i], z); }}

出力結果

The integral from 0 to infinity of pow(x, i)*x*exp(x) isFunction Quadrature Exact

pow(x, 0) 1.000 1.000 pow(x, 1) 2.000 2.000 pow(x, 2) 6.000 6.000

0! 0, , 6i xx xe dx i i

∞ − = =∫ K

Page 253: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

pow(x, 3) 24.000 24.000 pow(x, 4) 120.000 120.000 pow(x, 5) 720.000 720.000 pow(x, 6) 4896.000 5040.000

fcn_derivative ユーザ提供の関数の 1 次、2 次、3 次導関数を計算します。

概要

#include <imsl.h>

float imsl_f_fcn_derivative (float fcn(), float x, …, 0)

double 型関数は、 imsl_d_fcn_derivativeです。

必要な引数

float fcn(float x) ( 入力 )x の導関数が計算されるユーザ提供の関数。

float x ( 入力 )導関数が計算される点。

戻り値

x での fcn の 1 次、2 次、3 次導関数の推定値。値が計算できない場合,NaN が返されます。

オプション引数の概要

#include <imsl.h>float imsl_f_fcn_derivative (float fcn(), float x, IMSL_ORDER, int order,IMSL_INITIAL_STEPSIZE, float stepize,IMSL_RELATIVE_ERROR, float tolerance,IMSL_FCN_W_DATA, float fcn(), void *data,0)

オプション引数

IMSL_ORDER, int order ( 入力 )望ましい導関数の次数 (1、2 又は 3)。デフォルト: order = 1

IMSL_INITIAL_STEPSIZE, float stepsize ( 入力 )導関数を近似するために区間のサイズを計算するために使用される開始値。ステップサイズは fcn が定義され、区間 (x − 4.0*stepsize, x + 4.0*stepsize) で適度に平滑であるためには十分小さく、しかも 丸め誤差問題を避けるためには十分大きく選択しなければなりません。デフォルト: stepsize = .01

IMSL_RELATIVE_ERROR, float tolerance ( 入力 )導関数推定に望ましい相対誤差。収束は2つの連続する導関数推定値 d1 と d2 に対して (2/3) |d2− d1 | < tolerance の時と想定されます。

デフォルト: tolerance =

IMSL_FCN_W_DATA, float fcn (float x, void *data), void *data ( 入力 )x でのデリバティブが計算されるユーザ提供の関数。また、ユーザに

より提供されたデータへのポインターも受け入れます。 data は、ユー

ザ提供の関数にデータを受け渡すポインターです。 詳細は、「イントロ

ダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

4 ε

Page 254: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

関数 imsl_f_fcn_derivative は関数の 1 次、2 次、又は 3 次の導関数の推定

値を生成します。この推定値は、最初に区間 (x − 4.0*stepsize, x + 4.0*stepsize) 内の値を使用して入力関数のスプライン補間関数を計算するこ

とから始めて、それから x でこのスプラインを微分します。

例題

例題 1

この例題は、点 x = 2 での関数 f(x) = −2sin(3x/2) の 1 次導関数の近似値を得ま

す。

#include <imsl.h>#include <math.h>

void main(){ float fcn(float); float x; float deriv;

x = 2.0;

deriv = imsl_f_fcn_derivative(fcn, x, 0); printf ("f’(x) = %7.4f\n", deriv);}

float fcn(float x){

return -2.0*sin(1.5*x);}

出力結果

f’(x) = 2.9701

例題 2

この例題は、点 x = 2 での関数 f(x) = −2sin(3x/2) の一次、2 次、3 次導関数の近

似値を得ます。

#include "imsl.h"#include <math.h>

void main(){ double fcn(double); double x; double tolerance; double deriv;

x = 2.0;

deriv = imsl_d_fcn_derivative(fcn, x, 0); printf ("f'(x) = %7.3f, error = %5.2e\n", deriv, fabs(deriv+3.0*cos(1.5*x)));

deriv = imsl_d_fcn_derivative(fcn, x, IMSL_ORDER, 2, 0); printf ("f''(x) = %7.4f, error = %5.2e\n", deriv, fabs(deriv-4.5*sin(1.5*x)));

deriv = imsl_d_fcn_derivative(fcn, x, IMSL_ORDER, 3, 0);

Page 255: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

printf ("f'''(x) = %7.4f, error = %5.2e\n", deriv, fabs(deriv-6.75*cos(1.5*x)));}

double fcn(double x){ return -2.0*sin(1.5*x);}

出力結果

f’(x) = 2.970, error = 1.11e-07f’’(x) = 0.6350, error = 8.52e-09f’’’(x) = -6.6824, error = 1.12e-08

Page 256: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに
Page 257: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

第 5章:微分方程式

ルーチン

一階常微分方程式

ODE のための初期値問題の解Runge-Kutta 法 . . . . . . . . . . . . . . . . . ode_runge_kutta 259Adams 法 又は Gear 法. . . . . . . . . . . . . . ode_adams_gear 264 ODE のための初期値問題の解

有限差分法 . . . . . . . . . . . . . . . . .bvp_finite_difference 270微分代数方程式の解Petzold-Gear 法 . . . . . . . . . . . . . . . . . dea_petzold_gear 279

偏微分方程式1 次元 PDE の解

可変グリッドを使った直線法 . . . pde_1d_mg のイントロダクション 294移動グリッドインターフェースを使った 1 次元時間依存偏微分方程式のシステ

ムの解 . . . . . . . . . . . . . . . . . . . . . . pde_1d_mg 2963 次エルミート多項式を使った直線法. . . . . pde_method_of_lines 3262 次元 PDE の解

高速 Poisson 解法 . . . . . . . . . . . . . . . . fast_poisson_2d 341

使用上の注意

常微分方程式

常微分方程式 (ODE)は y i と呼ばれる1つ、又はそれ以上の従属変数、1 つの

独立変数 t と、t に関する y i の微係数を含んだ方程式です。

初期値問題(IVP)では、既知の値 t =t 0 での従属変数 y i の初期値、或いは、

出発値が与えられます。t > t 0 又は t < t 0 の y i (t) の値が要求されます。

関数 imsl_f_ode_runge_kutta と imsl_f_ode_runge_kutta は次式の形 ODE の IVP を解きます。

これは y i = (t = t 0) が指定されます。ここで fi はユーザが提供する関数で (t, y 1 , ..., y N ) i = 1, ..., N の値のあるセットで計算されなければなりません。

この問題の表現法は、この問題が初期値 y(t 0 ) を持つ y’ = f(t, y) になるので、1

次 ODE y’(t) = [y1(t),…,yN(t)]T 、f(t,y) = [f1(t,y),…,fN(t,y)]T の連立方程式としてこ

れを書くことにより簡略化されます。

この連立方程式

は次のヤコビ行列の幾つかの固有値が大きくて負であれば硬いと言われます。

( )1, 1, ,,..., ...ii Ni

dyy t y y i N

dtf′ == =

( ),dy y f t ydt

′= =

Page 258: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

これは、しばしば、亜種が効果的に異なる時期にその反応を終了する平衡に進行する化学反応のような物理系の挙動をモデル化する微分方程式の場合です。別のモデルでは、システムの異なる部分が広範囲に崩壊率(又は時間定数)を変えるような放電コンデンサーに関連します。

imsl_f_ode_runge_kutta のような数値的な微分方程式解法ルーチンは非効

率、もしくは完全に失敗するという事実によって、ユーザは特に硬いシステムを同定しがちです。しかし、特殊な方法が時には必要になります。ソフトウェアの精度と安定性要求を満たす為に、多くの f(t, y) の計算(それで大量のコン

ピュータ計算時間)が必要である事が非効率である事は知られています。このような場合には IMSL 関数 imsl_f_ode_adams_gear を使用します。 硬いシス

テムについての詳細は Gear (1971 年、第 11 章 ) 或いは Shampine と Gear (1979 年 ) を参照してください。

偏微分方程式

ルーチン imsl_f_pde_method_of_lines は次式の形のシステムの IVP 問題を

解きます。

これは、次の境界条件に従います。

そして、i = 1, ..., N に対して 次の初期条件に従います。

ここで、 fi、 gi、

です。

ここで j = 1, 2 に対する  はユーザ提供の関数です。

ルーチン imsl_f_bvp_finite_differenceは、次式の境界値問題(BVP)を

解きます。

次の境界条件に従います。

{ }/i jy y′∂ ∂

221 1

1 2 2, , , , , , , , , ,i N N

i N

u u uu uf x t u ut x x x x

∂ ∂ ∂∂ ∂∂ ∂ ∂ ∂ ∂

=

K K K

( ) ( ) ( ) ( ) ( )

( ) ( ) ( ) ( ) ( )

1 1 1

2 2 2

i i ii

i i ii

uu a a t

xu

u b b tx

∂α β γ

∂∂

α β γ∂

+ =

+ =

( ) ( )0,i iu x t t g x= =

( ) ( ), andi ij jα β

fi , gi ,α j( i), βj

( i )

221 1

1 2 2, , , , , , , , , ,i N N

i N

u u uu uf x t u u

t x x x x∂ ∂ ∂∂ ∂∂ ∂ ∂ ∂ ∂

=

K K K

221 1

1 2 2, , , , , , , , , ,i N N

i N

u u uu uf x t u ut x x x x

∂ ∂ ∂∂ ∂∂ ∂ ∂ ∂ ∂

=

K K K

Page 259: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

また、i = 1, …, N であるこの初期条件にも従います。

ここで、 が、ユーザ提供で

す。

この公式の中で、 p はオプションの継続パラメータです。これは、非線形問題

を解くのに有用です。 p=0 は、解きやすい問題に対応し、 p=1 は、実際に解かれ

る問題に対応します。

ルーチン imsl_f_fast_poisson_2dは、 二次元におけるラプラス、ポアソン、

又は、ヘルムホルツの方程式を解きます。このルーチンは矩形の各4辺に境界条件が従う、次式の形の PDE を解くために、高速ポアソン法を使用します。

このスカラー定数 c と関数 f はユーザ指定です。

微分代数方程式

常微分方程式のセットとして動的なシステムのモデルを表現することは、不可能、もしくは不便です。むしろ陰的な方程式が、次の形式で利用されます。

gi は、ユーザ提供の関数です。 このシステムは、次の様に短縮されます。

初期値 y(t0) を使用して、どのような常微分方程式のシステムも次式を定義す

ることで、微分代数連立方程式として自明に書くことができます。

ルーチン imsl_f_dea_petzold_gear は指標1、若しくは指標0の微分代数連

立方程式を解きます。微分代数連立方程式の指数の定義としては、(Brenan その他 . 1989 年 ) を参照して下さい。そして又使用される計算法の概略は Gear と Petzold (1984 年 ) を参照してください。

ode_runge_kuttaルンゲ - クッタ - ヴァーナー 5 次と 6 次法を使用して常微分方程式の初期値問

題を解きます。

概要

#include <imsl.h>

float imsl_f_ode_runge_kutta_mgr (int task, void **state, …, 0)

221 1

1 2 2, , , , , , , , , ,i N N

i N

u u uu uf x t u u

t x x x x∂ ∂ ∂∂ ∂∂ ∂ ∂ ∂ ∂

=

K K K

221 1

1 2 2, , , , , , , , , ,i N N

i N

u u uu uf x t u ut x x x x

∂ ∂ ∂∂ ∂∂ ∂ ∂ ∂ ∂

=

K K K

221 1

1 2 2, , , , , , , , , ,i N N

i N

u u uu uf x t u u

t x x x x∂ ∂ ∂∂ ∂∂ ∂ ∂ ∂ ∂

=

K K K

( )2 2

2 2,u u cu f x y

x y∂ ∂∂ ∂

+ + =

( )1, , , , , , 0 1, ,i N Ng t y y y y i N′ ′ = =K K K

( ) ( ) ( )1, , , , , , , , 0T

Ng t y y g t y y g t y y′ ′ ′= = K

( ) ( ), , ,g t y y f t y y′ ′= −

Page 260: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

void imsl_f_ode_runge_kutta (int neq, float *t, float tend, float y[], void *state, void fcn())

double 型関数は、 imsl_d_ode_runge_kutta_mgr と imsl_d_ode_runge_kuttaです。

imsl_ f_ode_runge_kutta_mgrに必要な引数

int task ( 入力 )この関数は、ODE システムを解くために IMSL_ODE_INITIALIZEが設

定された taskと、問題が解かれた後に削除するために

IMSL_ODE_RESETが設定された taskを呼び出す必要があります。taskの値は、include ファイル imsl.h で定義されます。

void **state ( 入力 / 出力 )ODE 解の現在の状態は state によって指される構造体に保持されま

す。これを直接操作する事はできません。

imsl_f_ode_runge_kuttaに必要な引数

int neq ( 入力 )微分方程式の数。

float *t ( 入力 / 出力 )独立変数。入力では tは初期独立変数で、 出力ではエラー条件が発生

しなければ t は tend によって置き換えられます。

float tend ( 入力 )解が望まれる t の値。 tend の値は tの初期値より小さくなる場合が

あります。

float y[] ( 入力 / 出力 )独立変数のベクトルを含む neq 成分の配列。入力では yは初期値を

含みます。出力では yは近似値を含みます。

void *state ( 入力 / 出力 )ODE 解の現在の状態は state によって指される構造体に保持されま

す。それは imsl_f_ode_runge_kutta_mgr の呼び出しによって初期

化されなければなりません。これは直接操作する事ができません。

void fcn (int neq, float t, float *y, float *yprime)float *yprime である右辺を計算するユーザ提供の関数。( 出力 )

ベクトル y’ を含んだ neq 成分の配列。この関数は以下の式を計算し

ます。

そして neq、t、そして *y はこの関数に先立って直接定義されます。

オプション引数の概要

#include <imsl.h> float imsl_f_ode_runge_kutta_mgr (int task, void **state,

IMSL_TOL, float tol,IMSL_HINIT, float hinit,IMSL_HMIN, float hmin,IMSL_HMAX, float hmax,IMSL_MAX_NUMBER_STEPS, int max_steps,IMSL_MAX_NUMBER_FCN_EVALS, int max_fcn_evals,IMSL_SCALE, float scale,IMSL_NORM, int norm,IMSL_FLOOR, float floor,IMSL_NSTEP, int *nstep,IMSL_NFCN, int *nfcn,

yprimedydt------ y′ f t y,( )= = =

Page 261: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_HTRIAL, float *htrial,IMSL_FCN_W_DATA, void fcn (), void *data,0)

オプション引数

IMSL_TOL, float tol ( 入力 )誤差制御の許容値。意図は全体誤差が tol に比例するように局所誤差

のノルムを制御することにあります。

デフォルト: tol = 100.0*imsl_f_machine(4)

IMSL_HINIT, float hinit ( 入力 )ステップサイズ h の初期値。 ステップは積分の方向に適用されます。 デフォルト: hinit = 0.001|tend − t|

IMSL_HMIN, float hmin ( 入力 )ステップサイズ h のための最小値。 デフォルト: hmin − 0.0

IMSL_HMAX, float hmax ( 入力 )ステップサイズ h のための最大値。 デフォルト: hmax = 2.0

IMSL_MAX_NUMBER_STEPS, int max_steps ( 入力 )最大許容ステップ数。 デフォルト: max_steps = 500

IMSL_MAX_NUMBER_FCN_EVALS, int max_fcn_evals ( 入力 )最大許容関数計算数。 デフォルト: max_fcn_evals = 強制される制限はありません。

IMSL_SCALE, float scale ( 入力 )軌線に沿ったヤコビ行列の近似などの、問題の尺度の規準。 デフォルト: scale = 1

IMSL_NORM, int norm ( 入力 )誤差ノルムを決定するスイッチ。次項において ei は yi の誤差推定値の

絶対値です。

0 — 絶対誤差、相対誤差の最小値で i = 1, …, neg に対して ei / max (|yi |, 1) の最大値に等しい。

1 — 絶対誤差、 maxiei に等しい。

2 — maxi(ei / wi) ここでは、wi = max (|yi |, floor)。floor の値は IMSL_FLOOR を使用してリセットされます。

デフォルト: norm = 0

IMSL_FLOOR, float floor ( 入力 )これは IMSL_NORM と共に使用されます。これは値 2 の誤差ノルムオ

プションの正の下限値を提供します。デフォルト: floor = 1.0

IMSL_NSTEP, int *nstep ( 出力 )行われたステップ数を返します。

IMSL_NFCN, int *nfcn ( 出力 )使用された関数計算の数を返します。

IMSL_HTRIAL, float *htrial ( 出力 )現在の試行ステップサイズを返します。

IMSL_FCN_W_DATA, void fcn (int neq, float t, float *y, float *yprime, void *data), void *data, ( 入力 )右辺を評価するためのユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関

Page 262: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

数にデータを受け渡すポインターです。 詳細は、「イントロダクショ

ン」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_ode_runge_kutta は次の形の、1 次連立微分方程式の解の近似

値を見つけます。

これは t の出発値で y の与えられた初期値を持っています。この関数はユー

ザ指定の許容値に比例する全体誤差を保つようにしています。この比例性はその微分方程式と積分の範囲に依存します。

関数 imsl_f_ode_runge_kutta は f(t, y) の計算に時間の掛からないような、

硬くないシステムに効果的です。このコードは Hull その他 (1976 年、1978 年 ) により設計されたアルゴリズムに基づいています。それは J.H. Verner によって

開発された次数 5 と 6 のルンゲ - クッタの公式を使用します。

例題

例題 1

この例題は初期条件 y(0) = 1 で、区間 [0, 1] で次式を解きます。

その解は y(t) = e –t です。

ODE ソルバーは IMSL_ODE_INITIALIZE と共に imsl_f_ode_runge_kutta_mgr を呼び出すことによって初期化されます。こ

れは、このソルバーの最も簡単な使用法であるので、デフォルト値は何も変更しません。関数 imsl_f_ode_runge_kutta は t = 0 から t = 1 まで積分するた

めに呼ばれます。

#include <imsl.h>#include <math.h>

void fcn (int neq, float t, float y[], float yprime[]);

main(){ int neq = 1; /* odeの数 */ float t = 0.0; /* 初期時間 */ float tend = 1.0; /* 終了時間 */ float y[1] = {1.0}; /* 初期条件 */ void *state; /* ODE ソルバーの初期化 */ imsl_f_ode_runge_kutta_mgr(IMSL_ODE_INITIALIZE, &state, 0); /* t=0 から tend=1まで積分 */ imsl_f_ode_runge_kutta (neq, &t, tend, y, state, fcn); /* 解と誤差をプリント */ printf("y[%f] = %f\n", t, y[0]); printf("Error is: %e\n", exp( (double)(-tend) )-y[0]);}

void fcn (int neq, float t, float y[], float yprime[]){ yprime[0] = -y[0];}

出力結果

y[1.000000] = 0.367879Error is: -9.149755e-09

dydt------ y′ f t y,( )= =

dydt

y= −

Page 263: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題 2

兎と狐の「捕食者と被食者」問題を考えてみます。r を兎の生存密度として、 f を狐の生存密度とします。「捕食者と被食者」の干渉が無ければ、兎はその数に比例した割合で増加して、狐はその数に比例した割合で餓死します。数学的には、種族抗争無しのモデルは次式で近似されます。

r′ = 2r

ƒ′= −ƒ

種族抗争ありでは、兎が狐によって補食される割合は値 2rf に等しいものと想

定されます。狐が増加する割合は、それらが兎を補食するので rf に等しくな

ります。 こうしてモデルの微分方程式は、以下のようになります。

r′ = 2r − 2rƒ

ƒ′ = −ƒ + rƒ

実例として、その初期条件は r(0) = 1 そして f(0) = 3 であるとします。積分の区

間は 0 ≤ t ≤ 10 です。このプログラムでは y[0] = r そして y[1] = f です。ODE ソ

ルバーは imsl_f_ode_runge_kutta_mgr の呼び出しで初期化されます。誤差

許容値は 0.0005 にセットされます。絶対誤差制御は IMSL_NORM を値1に

セットする事により選択されます。又、nstep がこの積分の現在のステップ

数にセットされる必要があります。関数 imsl_f_ode_runge_kutta はそれか

ら δt = 1 のステップの中で t = 0 から t = 10 まで積分するため一つのループで呼

ばれます。各ステップで解がプリントされます。nstep はこの関数の引数で

はないにもかかわらず更新されることに注意してください。そのアドレスは imsl_f_ode_runge_kutta_mgr の内部の state によって指される場所

の中に格納されます。IMSL_ODE_RESETを持つ imsl_f_ode_runge_kutta_mgr の最後の呼び出しは作業空間を解放します。

#include <imsl.h>

void fcn(int neq, float t, float y[], float yprime[]);

main(){ int neq = 2; float t = 0.0; /* 初期時間 */ float tend; /* 終了時間 */ float y[2] = {1.0, 3.0}; /* 初期条件 */ int k; int nstep; void *state; /* ODE ソルバーの初期化 */ imsl_f_ode_runge_kutta_mgr(IMSL_ODE_INITIALIZE, &state, IMSL_TOL, 0.0005, IMSL_NSTEP, &nstep, IMSL_NORM, 1, 0);

printf("\n Start End Density of Density of Number of" ); printf("\n Time Time Rabbits Foxes Steps\n\n");

for (k = 0; k < 10; k++) { tend = k + 1; imsl_f_ode_runge_kutta (neq, &t, tend, y, state, fcn); printf("%3d %12.3f %12.3f %12.3f %12d\n", k, t, y[0], y[1], nstep); } imsl_f_ode_runge_kutta_mgr(IMSL_ODE_RESET, &state, 0);}

Page 264: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

void fcn (int neq, float t, float y[], float yprime[]){ /* Density change rate for Rabbits: */ yprime[0] = 2*y[0]*(1 - y[1]); /* Density change rate for Foxes: */ yprime[1] = -y[1]*(1 - y[0]);}

出力結果

Start End Density of Density of Number ofTime Time Rabbits Foxes Steps

0 1.000 0.078 1.465 4 1 2.000 0.085 0.578 6 2 3.000 0.292 0.250 7 3 4.000 1.449 0.187 8 4 5.000 4.046 1.444 11 5 6.000 0.176 2.256 15 6 7.000 0.066 0.908 18 7 8.000 0.148 0.367 20 8 9.000 0.655 0.188 21 9 10.000 3.157 0.352 23

重大エラー

IMSL_ODE_TOO_MANY_EVALS 次のステップを終了すると関数計算数は # 達しますが、# 回の計算数だけしか許可され

ていません。

IMSL_ODE_TOO_MANY_STEPS 許されるステップの最大数 #、が使用され

ました。この問題は硬い可能性があります。

IMSL_ODE_FAIL エラー要求を満足することが出来ません。

“tol” = # が余りにも小さ過ぎます。

ode_adams_gearAdams-Gear 法を使用して常微分方程式の硬い初期値問題を解きます。

概要

#include <imsl.h>

float imsl_f_ode_adams_gear_mgr (int task, void **state, …, 0)

void imsl_f_ode_adams_gear (int neq, float *t, float tend, float y[], void *state, void fcn())

double 型関数は、imsl_d_ode_adams_gear_mgr と imsl_d_ode_adams_gearです。

imsl_f_ode_adams_gear_mgrに必要な引数

int task ( 入力 )この関数は、ODE システムを解くために IMSL_ODE_INITIALIZEが設

定された taskと、問題が解かれた後に削除するために

IMSL_ODE_RESETが設定された taskを呼び出す必要があります。task

の値は、include ファイル imsl.h で定義されます。

void **state ( 入力 / 出力 )ODE 解の現在の状態は state によって指される構造体に保持されま

す。これを直接操作する事はできません。

imsl_f_ode_adams_gearに必要な引数

int neq ( 入力 )微分方程式の数。

Page 265: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float *t ( 入力 / 出力 )独立変数。入力では tは初期独立変数で、 出力ではエラー条件が発生

しなければ t は tend によって置き換えられます。

float tend ( 入力 )解が望まれる t の値。 tend の値は tの初期値より小さくなる場合が

あります。

float y[] ( 入力 / 出力 )独立変数のベクトルを含む neq 成分の配列。入力では yは初期値を

含みます。出力では yは近似値を含みます。

void *state ( 入力 / 出力 )ODE 解の現在の状態は、state によって指される構造体に保存され

ます。これは imsl_f_ode_adams_gear_mgr の呼び出しによって初期

化しなければなりません。これは直接操作することはできません。

void fcn (int neq, float t, float *y, float *yprime)float *yprime である右辺を計算するユーザ提供の関数 ( 出力 )

ベクトル y’ を含んだ neq 要素の配列。この関数は次式を計算します。

そして neq, t, *y はこの関数に先行して直接定義されます。

オプション引数の概要

#include <imsl.h>float imsl_f_ode_adams_gear_mgr (int task, void **state,

IMSL_JACOBIAN, void fcnj (),IMSL_METHOD, int method,IMSL_MAXORD, int maxord,IMSL_MITER, int miter,IMSL_TOL, float tol,IMSL_HINIT, float hinit,IMSL_HMIN, float hmin,IMSL_HMAX, float hmax,IMSL_MAX_NUMBER_STEPS, int max_steps,IMSL_MAX_NUMBER_FCN_EVALS, int max_fcn_evals,IMSL_SCALE, float scale,IMSL_NORM, int norm,IMSL_FLOOR, float floor,IMSL_NSTEP, int *nstep,IMSL_NFCN, int *nfcn,IMSL_NFCNJ, int *nfcnj,IMSL_FCN_W_DATA, void fcn (), void *data,IMSL_JACOBIAN_W_DATA, void fcn (), void *data,0)

オプション引数

IMSL_JACOBIAN, void fcnj (int neq, float t, float *y, float yprime[], float dypdy[])float yprime[] であるヤコビ行列を計算するためのユーザ提供関数 (入力 )ベクトル y’= f(t,y) を含んだ neq 要素の配列。

float dypdy[] ( 出力 )偏微分を含んだサイズ neq × neq の配列。各微係数

∂y¢i / ∂yi は提供された (t, y) 値で計算されて、配列位置

dypdy[(i − 1)*n + j − 1]に返されます。そして neq、t、*y は「必要な引数」節で説明されています。

yprimedydt------ y′ f t y,( )= = =

Page 266: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_METHOD, int method ( 入力 )積分法のクラスを選びます。1 — 陰的アダムス法を使用。

2 — 後退微分公式 (BDF) 法を使用。

デフォルト: method = 2

IMSL_MAXORD, int maxord ( 入力 )陰的アダムス・タイプ、又は、BDF タイプを使用するために最高次数

公式を定義します。このデフォルトはアダムス公式では値 12 で、

BDF 公式では値 5 です。

IMSL_MITER, int miter ( 入力 )公式方程式を解くための方法を選びます。

1 — 関数繰り返し、又は、逐次代入を使用。

2 — コード法、もしくは修正ニュートン法とユーザ提供のヤコビ行列

を使用

3 — ヤコビ行列が分割差分により関数内で近似される以外は、2 と同

じ。デフォルト: miter = 3

IMSL_TOL, float tol ( 入力 )誤差制御の許容値。意図は全体誤差が tol に比例するように局所誤差

のノルムを制御することにあります。

デフォルト: tol = 0.001

IMSL_HINIT, float hinit ( 入力 )ステップサイズ h の初期値。 ステップは積分の方向に適用されます。

デフォルト: hinit = 0.001|tend − t|

IMSL_HMIN, float hmin ( 入力 )ステップサイズ h のための最小値。 デフォルト: hmin = 0.0

IMSL_HMAX, float hmax ( 入力 )ステップサイズ h のための最大値。 デフォルト: hmax = imsl_amach(2)

IMSL_MAX_NUMBER_STEPS, int max_steps ( 入力 )最大許容ステップ数。 デフォルト: max_steps = 500

IMSL_MAX_NUMBER_FCN_EVALS, int max_fcn_evals ( 入力 )許容される y′ の計算の最大数

デフォルト: max_fcn_evals = 強制される制限はありません。

IMSL_SCALE, float scale ( 入力 )軌線に沿ったヤコビ行列の近似など、問題の尺度の規準。 デフォルト: scale = 1

IMSL_NORM, int norm ( 入力 )誤差ノルムを決定するスイッチ。次項において ei は yi の誤差推定値の

絶対値です。

0 — 絶対誤差、相対誤差の最小値で i = 1, …, neg に対して ei / max (|yi |, 1) の最大値に等しい。

1 — 絶対誤差、 maxiei に等しい。

2 — maxi(ei / wi) ここでは、wi = max (|yi |, floor)。floor の値は IMSL_FLOOR を使用してリセットされます。

デフォルト: norm = 0.

IMSL_FLOOR, float floor ( 入力 )これは IMSL_NORM と共に使用されます。これは値 2 の誤差ノルムオ

Page 267: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

プションの正の下限値を提供します。デフォルト: floor = 1.0

IMSL_NSTEP, int *nstep ( 出力 )行われたステップ数を返します。

IMSL_NFCN, int *nfcn ( 出力 )使用された y′ の計算数を返します。

IMSL_NFCNJ, int *nfcnj ( 出力 )使用したヤコビ行列の計算回数を返します。この値は、オプション IMSL_JACOBIAN が使用される時だけ非ゼロになります。

IMSL_FCN_W_DATA, void fcn (int neq, float t, float *y, float *yprime, void *data), void *data, ( 入力 )右辺を評価するためのユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関

数にデータを受け渡すポインターです。 詳細は、「イントロダクショ

ン」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_JACOBIAN_W_DATA, void jacobian (int m, int n, float x[], float fjac[], int fjac_col_dim, void *data), void *data ( 入力 )ヤコビ行列を計算するユーザ提供の関数。ユーザにより提供されるデータへのポインターを受け取ります。data は、ユーザ提供関数に渡

されるデータへのポインターです。詳細は、本マニュアルの初めにある「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_ode_adams_gear は次の形の一階連立微分方程式の解の近似を見

つけます。

これは t の初期値で y の初期条件が与えられます。この関数はユーザ指定の

許容値に比例する全体誤差を保つようにし、この比例度は微分方程式と積分の範囲に依存します。

このコードは Gear (1971 年 ) に概説され Hindmarsh (1974 年 ) によって導入され

たように五階を越えない後退差分公式の使用を基準にしています。陰的アダムス公式を使用するコードのオプションの使用法があります。この使用は計算時間の掛かる関数 y’= f(t,y) の硬くない問題に適しています。

例題

例題 1

これは Enright と Pryce(1987 年 ) の試行セットからの、幾分硬い例題 (F2) です。

この常微分方程式(ODE)ソルバーは IMSL_ODE_INITIALIZE を持つ関数

imsl_f_ode_adams_gear_mgr の呼び出しによって初期化されます。これはデ

y′1 = −y1 − y1y2 + k1y2y′2 = −k2y2 + k3 (1 − y2) y1

y1 (0) = 1y2 (0) = 0

k1 = 294.k2 = 3.k3 = 0.01020408

tend = 240.

dydt------ y′ f t y,( )= =

Page 268: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

フォルト値に変更がない最も簡単なソルバーの使用法です。関数 imsl_f_ode_adams_gear は、t = 0 から t = 240 までを積分するために呼び出

されます。

#include <stdio.h>#include <imsl.h>

void fcn (int neq, float t, float y[], float yprime[]);

float k1 = 294.0; /* モデルデータ */float k2 = 3.0;float k3 = 0.01020408;

main(){ int neq = 2; /* odeの数 */ float t = 0.0; /* 初期時間 */ float tend = 240.0; /* 終了時間 */ float y[2] = {1.0, 0.0}; /* 初期条件 */ void *state; /* ODE ソルバーを初期化 */ imsl_f_ode_adams_gear_mgr(IMSL_ODE_INITIALIZE, &state, 0); /* t=0 から tend=240まで積分 */ imsl_f_ode_adams_gear (neq, &t, tend, y, state, fcn); /* 解をプリント */ printf("y[%f] = %f, %f\n", t, y[0], y[1]);}

void fcn (int neq, float t, float y[], float yprime[]){ yprime[0] = -y[0] - y[0]*y[1] + k1*y[1]; yprime[1] = -k2*y[1] + k3*(1.0-y[1])*y[0];}

出力結果

y[240.000000] = 0.392391, 0.001334

例題 2

この例題は Enright と Pryce(1987 年 ) の試行セットからの、硬い例題 (F5) で

す。h = 10-7 の初期ステップ幅がこれらの著者によって提議されています。y’のより多くの計算と許容デフォルト値より多くのステップ数を提供することが必要です。両方とも 4000 に設定されています。

y′1 = k1 (− k2y1y2 + k3y4 − k4y1y3)y′2 = −k1k2y1y2 + k5y4y′3 = k1 (−k4y1y3 + k6y4)y′4 = k1 (k2y1y2 − k3y4 + k4y1y3)

y1(0) = 3.365 × 10-7

y2(0) = 8.261 × 10-3

y3(0) = 1.641 × 10-3

y4(0) = 9.380 × 10-6

k1 = 1011

k2 = 3.k3 = 0.0012k4 = 9.k5 = 2 × 107

k6 = 0.001tend = 100.

Page 269: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_ODE_RESET を持つ imsl_f_ode_adams_gear_mgr の最後の呼び出しは

作業空間を開放します。

#include <stdio.h>#include <imsl.h>

void fcn (int neq, float t, float y[], float yprime[]);

float k1 = 1.e11; /* モデルデータ */float k2 = 3.0;float k3 = 0.0012;float k4 = 9.0; float k5 = 2.e7;float k6 = 0.001;

main(){ int neq = 4; /* odeの数 */ float t = 0.0; /* 初期時間 */ float tend = 100.0; /* 終了時間 */ /* 初期時間 */ float y[4] = {3.365e-7, 8.261e-3, 1.642e-3, 9.380e-6}; void *state; int int nfcn; /* ODE ソルバーを初期化 */ imsl_f_ode_adams_gear_mgr(IMSL_ODE_INITIALIZE, &state, IMSL_HINIT, 1.e-7, IMSL_MAX_NUMBER_STEPS, 4000, IMSL_MAX_NUMBER_FCN_EVALS, 4000, IMSL_NFCN, &nfcn, 0); /* t=0 から tend=100まで積分 */ imsl_f_ode_adams_gear (neq, &t, tend, y, state, fcn); /* 作業空間と解放し、リセット */ imsl_f_ode_adams_gear_mgr(IMSL_ODE_RESET, &state, 0); /* 解をプリント */ printf("y[%f] = %f, %f, %f, %f\n", t, y[0], y[1], y[2], y[3]); /* yprime[]の計算回数をプリント */ printf("Number of yprime[] evaluations: %d\n", nfcn);}

void fcn (int neq, float t, float y[], float yprime[]){ yprime[0] = k1*(-k2*y[0]*y[1]+k3*y[3]-k4*y[0]*y[2]); yprime[1] = -k1*k2*y[0]*y[1] + k5*y[3]; yprime[2] = k1*(-k4*y[0]*y[2] + k6*y[3]); yprime[3] = k1*(k2*y[0]*y[1] - k3*y[3] + k4*y[0]*y[2]);}

出力結果

y[100.000000] = 0.000000, 0.003352, 0.005586, 0.000009Number of yprime[] evaluations: 3630

重大エラー

IMSL_ODE_TOO_MANY_EVALS 次のステップを終了すると関数計算数は # 達しますが、# 回の計算数だけしか許可され

ていません。

IMSL_ODE_TOO_MANY_STEPS 許されるステップの最大数 #、が使用され

ました。最大許容ステップ数を増やすか、許容値を増やしてみてください。

Page 270: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

bvp_finite_difference2 点の境界条件を持つ微分方程式のシステムを、可変次数、可変ステップサイ

ズの繰り延べ修正を持つ有限差分法を使って解きます。

概要

#include <imsl.h>

float *imsl_f_bvp_finite_difference (void fcneq(), void fcnjac(), void fcnbc(), int n, int nleft, int ncupbc, float tleft, float tright, int linear, float *nfinal, float *xfinal, float *yfinal, …, 0)

double 型関数は、 imsl_d_bvp_finite_differenceです。

必要な引数

void fcneq (int n, float t, float y[], float p, float dydt[]) ( 入力 )微分係数を計算するユーザ提供関数。

int n ( 入力 )微分方程式の数。

float t ( 入力 )独立変数、 t。

float y[] ( 入力 )従属変数 y(t) を含むサイズ n の配列。

float p ( 入力 )継続パラメータ、 p。オプション引数

IMSL_PROBLEM_EMBEDDEDを参照してください。

float dydt[] ( 出力 )微分係数 y′(t) を含むサイズ n の配列。

void fcnjac(int n, float t, float y[], float p, float dypdy[]) ( 入力 )ヤコビ行列の計算をするユーザ提供の関数。

int n ( 入力 )微分方程式の数。

float t ( 入力 )独立変数、t。

float y[] ( 入力 )従属変数 y(t) を含むサイズ n の配列。

float p ( 入力 )継続パラメータ、 p。オプション引数 IMSL_PROBLEM_EMBEDDEDを参照してください。

float dypdy[] ( 出力 )(t, y) で計算される偏微分係数 ai,j = ∂ fi / ∂ yj を含む n × n配列。 値 ai,j は、dypdy[(i-1)*n+(j-1)] に返されます。

void fcnbc(int n, float yleft[], float yright[], float p, float h[]) ( 入力 )境界条件を計算するユーザ提供関数。

int n ( 入力 )微分方程式の数。

float yleft[] ( 入力 )左端での従属変数の値を含むサイズ n の配列。

float yright[] ( 入力 )右端での従属変数の値を含むサイズ n の配列。

Page 271: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float p ( 入力 )継続パラメータ、 p。オプション引数 IMSL_PROBLEM_EMBEDDEDを参照してください。

float h[] ( 出力 )境界条件の残差を含むサイズ n の配列。境界条件は、 hi = 0, for i = 0, …, n-1 によって定義されます。左端条件が最

初に定義され、その後、両端を含む条件、そして最後に右端が定義されます。

int n ( 入力 )微分方程式の数。

int nleft ( 入力 )初期条件の数。値 nleft は、 zero 以上で、 n未満でなければなりませ

ん。

int ncupbc ( 入力 )連結した境界条件の数。値 nleft + ncupbc は、 zero より大きく、 n 以下でなければなりません。.

float tleft ( 入力 )左端。

float tright ( 入力 )右端。

int linear ( 入力 )微分方程式と境界条件が線形かどうかを示す整数のフラッグ。 微分方

程式と境界条件が線形の場合、 linear を 1 に設定し、それ以外は linear を 0 に設定します。

int *nfinal ( 出力 )端点を含む最後のグリッド点数。

float *tfinal ( 出力 )最後のグリッド点を含むサイズ mxgrid の配列。 最初の nfinal 点だけ

が重要です。 mxgridの定義はオプション引数 IMSL_MAX_SUBINTER を参照してください。

float *yfinal ( 出力 )tfinalの点での Yの値を含むサイズmxgrid × nの配列。mxgridの定義

は、オプション引数 IMSL_MAX_SUBINTER を参照してください。

オプション引数の概要

#include <imsl.h>

float *imsl_f_bvp_finite_difference (void fcneq(), void fcnjac(),void fcnbc(), int n, int nleft, int ncupbc, float tleft, float tright, int linear, float *nfinal, float *xfinal[], float *yfinal,IMSL_TOL, float tol,IMSL_HINIT, int ninit, float tinit[], float yinit[][],IMSL_PRINT, int iprint,IMSL_MAX_SUBINTER, int mxgrid,IMSL_PROBLEM_EMBEDDED, float pistep, void fcnpeq(),void fcnpbc(),IMSL_ERR_EST, float **errest,IMSL_ERR_EST_USER, float errest[],IMSL_FCN_W_DATA, void fcneq (),void *data,IMSL_JACOBIAN_W_DATA, void fcnjac (),void *data,IMSL_FCN_BC_W_DATA, void fcnbc (),void *data,IMSL_PROBLEM_EMBEDDED_W_DATA, float pistep,(),void *data, void fcnpeq(),void fcnpbc(),void *data, 0)

Page 272: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数

IMSL_TOL, float tol ( 入力 )相対誤差の操作パラメータ。 以下の場合、計算が終了します。

デフォルト: tol = .001.

IMSL_HINIT, int ninit, float tinit[], float yinit[][], ( 入力 )初期のグリッド点。端点を含む初期のグリッド点の数は、 ninitで与

えられます。 tinit は、初期グリッド点を含むサイズ ninit の配列で

す。 yinit は、 tinit内の点での Y の値の初期推定を含むサイズ ninit × nの配列です。 デフォルト: ninit =10、 tinit[*] 等間隔の [tleft, tright]、 yinit[*][*] = 0 です。

IMSL_PRINT, int iprint ( 入力 )望ましい出力レベルを示すパラメータ。

デフォルト: iprint = 0.

IMSL_MAX_SUBINTER, int mxgrid ( 入力 )最大許容グリッド点数。 デフォルト: mxgrid = 100

IMSL_PROBLEM_EMBEDDED, float pistep, void fcnpeq(), void fcnpbc()このオプションが提供されると、関数 imsl_f_bvp_finite_difference は、p = 0 の時に問題を簡単にする

ように、問題を 1 パラメータの問題に組み込んだと仮定します。

p = 1 の場合は、オリジナルの問題に戻されます。 関数 imsl_f_bvp_finite_difference は、自動的に p = 0 から p = 1 に増や

すように試みます。 値 pistep は、この継続で使用される最初の増分で

す。 通常、増分は、関数 imsl_f_bvp_finite_differenceによって変

更されますが、任意の最小の 0.01 が課せられます。

引数 p は、初期増分サイズ forp です。関数 fcnpeq と fcnpbc は、

ユーザ提供関数で、次の様に定義されます。

void fcnpeq(int n, float t, float y[], float p, float dypdp[]) ( 入力 )パラメータ p に関する微分係数 y′ を計算するユーザ提供

関数。

int n ( 入力 )微分方程式の数。

Iprint Action0 出力のプリントなし1 中間出力のプリント

( ), ,

, ,

/ max ,1.0 for all 0, 1, and 0, 1

Here is the estimated error on i j i j

i j i j

E y tol i n j ngrid

E y

< = = = −

y = y ( ) t, y, p′ ′

( , , ) = 0h pyleft yright

Page 273: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float t ( 入力 )独立変数、t。

float y[] ( 入力 )従属変数の値を含むサイズ n の配列。

float p ( 入力 )継続パラメータ、 p。

float dypdp[] ( 出力 )p at (t, y) でのパラメータ p に関する微分係数 y′ を含むサ

イズ n の配列。

void fcnpbc(int n, float yleft[], float yright[], float p, float h[])( 入力 )パラメータ p に関する境界条件の微分係数を計算する

ユーザ提供関数。

int n ( 入力 )微分方程式の数。

float yleft[] ( 入力 )左端での従属変数の値を含むサイズ n の配列。

float yright[] ( 入力 )右端での従属変数の値を含むサイズ n の配列。

float p ( 入力 )継続パラメータ、 p。

float h[] ( 出力 )p に関する fi の微分係数を含むサイズ n の配列。

IMSL_ERR_EST, float **errest ( 出力 )y の推定誤差を含むサイズ n の配列へのポインターのアドレス。

IMSL_ERR_EST_USER, float errest[] ( 出力 )y の推定誤差を含むサイズ n のユーザ割り当て配列。

IMSL_FCN_W_DATA, void fcneq (int n, float t, float y[], float p, float dydt[], void *data) ,void *data, ( 入力 )デリバティブを評価するためのユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ

提供の関数にデータを受け渡すポインターです。 詳細は、「イントロダ

クション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_JACOBIAN_W_DATA, void fcnjac(int n, float t, float y[], float p, float dypdy[], void *data) ,void *data, ( 入力 )ヤコビ行列を計算するユーザ提供の関数。ユーザにより提供されるデータへのポインターを受け取ります。data は、ユーザ提供関数に渡

されるデータへのポインターです。詳細は、本マニュアルの初めにある「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_FCN_BC_W_DATA, void fcnbc(int n, float yleft[], float yright[], float p, float h[], void *data) ,void *data, ( 入力 )境界条件を計算するユーザ提供の関数。ユーザにより提供されるデータへのポインターを受け取ります。data は、ユーザ提供関数に渡され

るデータへのポインターです。詳細は、本マニュアルの初めにある「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_PROBLEM_EMBEDDED_W_DATA, float pistep, void fcnpeq(void *data), void fcnpbc(),void *data, ( 入力 )ユーザ提供関数が、ユーザにより提供されるデータへのポインターを受け取る以外は、オプション引数 IMSL_PROBLEM_EMBEDDED と同じで

Page 274: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

す。data は、ユーザ提供関数に渡されるデータへのポインターです。

詳細は、本マニュアルの初めにある「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_bvp_finite_difference は、 M. Lentini と V. Pereyra (Pereyra 1978を参照 ) によるサブプログラム PASVA3 を基にしています。基本的な離散化は、

非一様メッシュ上の台数公式です。このメッシュは、ローカルの誤差をどこでも大体同じサイズにするために選択されます。より高次の離散化は、繰り延べ修正によって得られます。 グローバルな誤差推定が、計算を制御するために生

成されます。その結果の非線形代数システムは、ステップコントロールを持つ Newton 法で解かれます。 方程式の線形化されたシステムは、疎の状態を保つ

ガウス消去法の特殊な形式によって解かれます。

例題 1

この例題では、境界条件 y(0) = y(2π) and y′(0) = y′(2π) = 1 を前提とした以下の 3次の線形方程式を解きます。( その解は、 y = sin t。)

To use imsl_f_bvp_finite_difference を使うために、問題は、y1 = y、 y2 = y′、 y3 = y″ を定義することで 1 次の方程式に減らされます。その結果、次のよ

うなシステムになります。

左端 t = 0 での境界条件が 1 つと左端と右端が結合している境界条件が 1 つあ

ることに注意してください。 最後の境界条件は、右端にあります。境界条件の

合計数は、方程式の数と同じである必要があります(今回のケースでは、3)。

#include <math.h>#include "imsl.h"

void fcneqn( int n, float t, float y[], float p, float dydt[]);void fcnjac( int n, float t, float y[], float p, float dfdy[]);void fcnbc( int n, float yleft[], float yright[], float p, float h[]);

#define MXGRID 100#define N 3void main(){ int n = N; int nleft = 1; int ncupbc = 1; float tleft = 0; float tright; int linear = 1; int nfinal; float tfinal[MXGRID]; float yfinal[MXGRID][N]; float errest[N]; int i;

tright = 2.0*imsl_f_constant("pi", 0);

imsl_f_bvp_finite_difference( fcneqn, fcnjac, fcnbc, n, nleft, ncupbc, tleft, tright,linear, &nfinal, tfinal,

2 siny y y y t′′′ ′′ ′− + − =

( )( ) ( )( )

1 22

2 1 13

3 3 2 1 2

0 1 0

0 2 0

2 sin 2 1 0

y y y

y y y y

y y y y t y

π

π

′ = − =

′ = − =

′ = − + + − =

Page 275: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

(float*)(&yfinal[0][0]), IMSL_ERR_EST_USER, errest, 0);

printf(" tfinal y0 y1 y2 \n" ); for( i=0; i<nfinal; i++ ) { printf( "%5d%15.6e%15.6e%15.6e%15.6e\n", i, tfinal[i], yfinal[i][0], yfinal[i][1], yfinal[i][2] ); } printf("Error Estimates "); printf("%15.6e%15.6e%15.6e\n",errest[0],errest[1],errest[2]); return;}

void fcneqn( int n, float t, float y[], float p, float dydt[] ){ dydt[0] = y[1]; dydt[1] = y[2]; dydt[2] = 2*y[2] - y[1] + y[0] + sin(t);}

void fcnjac( int n, float t, float y[], float p, float dfdy[] ){ dfdy[0*n+0] = 0; /* df1/dy1 */ dfdy[1*n+0] = 0; /* df2/dy1 */ dfdy[2*n+0] = 1; /* df3/dy1 */ dfdy[0*n+1] = 1; /* df1/dy2 */ dfdy[1*n+1] = 0; /* df2/dy2 */ dfdy[2*n+1] = -1; /* df3/dy2 */ dfdy[0*n+2] = 0; /* df1/dy3 */ dfdy[1*n+2] = 1; /* df2/dy3 */ dfdy[2*n+2] = 2; /* df3/dy3 */}

void fcnbc( int n, float yleft[], float yright[], float p, float h[] ){ h[0] = yleft[1] - 1; h[1] = yleft[0] - yright[0]; h[2] = yright[1] - 1;}

出力結果 tfinal y0 y1 y2 0 0.000000e+00 -1.123446e-04 1.000000e+00 6.245916e-05 1 3.490659e-01 3.419106e-01 9.397087e-01 -3.419581e-01 2 6.981317e-01 6.426907e-01 7.660918e-01 -6.427230e-01 3 1.396263e+00 9.847531e-01 1.737333e-01 -9.847453e-01 4 2.094395e+00 8.660527e-01 -4.998748e-01 -8.660057e-01 5 2.792527e+00 3.421828e-01 -9.395475e-01 -3.420647e-01 6 3.490659e+00 -3.417236e-01 -9.396111e-01 3.418948e-01 7 4.188790e+00 -8.656881e-01 -5.000588e-01 8.658734e-01 8 4.886922e+00 -9.845795e-01 1.734572e-01 9.847519e-01 9 5.585054e+00 -6.427722e-01 7.658259e-01 6.429526e-01 10 5.934120e+00 -3.420819e-01 9.395434e-01 3.423984e-01 11 6.283185e+00 -1.123446e-04 1.000000e+00 6.739637e-04Error Estimates 2.840487e-04 1.792839e-04 5.587848e-04

例題 2

この例題では、y(0) = y(π) = 0 を持つ 次の非線形問題を解きます。

y″ − y3 + (1 + sin2 t) sin t = 0

その解は、 y = sin t です。例題 1 にあるように、この方程式は、 y1 = y と y2 = y′を定義することにより 1 次微分方程式のシステムに減らされます。その結果、

システムは、次の様になります。

Page 276: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

この問題では、左端に一つと右端に一つの境界条件がありますが、結合された境界条件はありません。

#include <math.h>#include “imsl.h”

void fcneqn(int n, float x, float y[], float p, float dydx[]);void fcnjac(int n, float x, float y[], float p, float dfdy[]);void fcnbc(int n, float yleft[], float yright[], float p, float h[]);

#define MXGRID 100#define NINIT 12#define N 2

void main(){ int n = N, nleft = 1, ncupbc = 0, linear = 0; int i, nfinal, ninit = NINIT; float tleft = 0, tright; float tinit[NINIT], yinit[N][NINIT]; float tfinal[MXGRID], yfinal[N][MXGRID]; float *errest, step;

tright = imsl_f_constant("pi", 0); step = (tright-tleft) / (ninit-1);

for( i=0; i<ninit; i++ ) { tinit[i] = tleft + i*step; yinit[i][0] = 0.4 * (tinit[i]-tleft) * (tright-tinit[i]); yinit[i][1] = 0.4 * (tright+tleft-2*tinit[i]); } imsl_f_bvp_finite_difference(fcneqn, fcnjac, fcnbc,

n, nleft, ncupbc, tleft, tright, linear, &nfinal, tfinal, (float*)(&yfinal[0][0]), IMSL_HINIT, ninit, tinit, yinit, IMSL_ERR_EST, &errest, 0);

printf(" t y0 y1\n" ); for( i=0; i<nfinal; i++ ) { printf( "%5d%15.6e%15.6e%15.6e\n", i, tfinal[i], yfinal[i][0], yfinal[i][1]); } printf("Error Estimates "); printf("%15.6e%15.6e\n",errest[0],errest[1]); return;}

void fcneqn(int n, float t, float y[], float p, float dydt[]){ float sx = sin(t); dydt[0] = y[1]; dydt[1] = y[0]*y[0]*y[0] - (sx*sx+1)*sx;}

void fcnjac(int n, float t, float y[], float p, float dfdy[]){ dfdy[0*n+0] = 0; /* df1/dy1 */ dfdy[1*n+0] = 3*y[0]*y[0]; /* df2/dy1 */ dfdy[0*n+1] = 1; /* df1/dy2 */ dfdy[1*n+1] = 0; /* df2/dy2 */

( )

( ) ( )1 2 1

2 1 13 2

0 0

1 sin sin 0

y y y

y y t t y π

′ = =

′ = − + =

Page 277: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

}

void fcnbc(int n, float yleft[], float yright[], float p, float h[]){ h[0] = yleft[0]; h[1] = yright[0];}

出力結果 t y0 y1 0 0.000000e+00 0.000000e+00 9.999277e-01 1 2.855994e-01 2.817682e-01 9.594315e-01 2 5.711987e-01 5.406458e-01 8.412407e-01 3 8.567981e-01 7.557380e-01 6.548904e-01 4 1.142397e+00 9.096186e-01 4.154530e-01 5 1.427997e+00 9.898143e-01 1.423307e-01 6 1.713596e+00 9.898143e-01 -1.423308e-01 7 1.999195e+00 9.096185e-01 -4.154530e-01 8 2.284795e+00 7.557380e-01 -6.548902e-01 9 2.570394e+00 5.406460e-01 -8.412405e-01 10 2.855994e+00 2.817682e-01 -9.594312e-01 11 3.141593e+00 0.000000e+00 -9.999274e-01Error Estimates 3.907291e-05 7.124317e-05

例題 3

この例題では、y(0) = y(1) = π/2 を持つ非線形問題が解かれます。

前の例題と同じように、この方程式は、y1 = y 、 y2 = y′ を定義することにより 1次の微分方程式に減らされます。その結果、以下のようになります。

パラメータ p を取り入れ、2 番目の微分方程式を次の様に変えることによっ

て、問題は、問題群に組み込まれます。

p = 0 では、問題は線形で、 p = 1 では、オリジナルの問題が戻されます。 微分

係数 ∂y′/∂p は、サブルーチン fcnpeq内で指定されなければなりません。 微分

係数 ∂f/∂p は、fcnpbc内ではゼロです。

#include <stdio.h>#include <math.h>#include <imsl.h>void fcneqn(int n, float t, float y[], float p, float dydt[]);void fcnjac(int n, float t, float y[], float p, float dfdy[]);void fcnbc(int n, float yleft[], float yright[], float p, float h[]);void fcnpeq(int n, float t, float y[], float p, float dfdp[]);void fcnpbc(int n, float yleft[], float yright[], float p, float dhdp[]);

#define MXGRID 45#define NINIT 12#define N 2

2 / 3 83 40 1 1

9 2 2y y t t ′′ − = − − −

( )

( )

1 2 1

2 / 3 8

2 131

0 / 2

40 1 1 1 / 29 2 2

y y y

y y t t y

π

π

′ = =

′ = − − + − =

2 / 3 8

231

40 1 19 2 2

y py t t ′ = + − −

Page 278: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

void main(){ int n = 2; int nleft = 1; int ncupbc = 0; float tleft = 0; float tright = 1; float pistep = 0.1; int ninit = 5; float tinit[NINIT] = { 0.0, 0.4, 0.5, 0.6, 1.0 }; float yinit[N][NINIT] = { 0.15749, 0.00215,

0.0, 0.00215, 0.15749, -0.83995, -0.05745, 0.0, 0.05745, 0.83995 };

int linear = 0; int nfinal; float tfinal[MXGRID]; float yfinal[MXGRID][N]; float *errest; int i;

imsl_f_bvp_finite_difference( fcneqn, fcnjac, fcnbc, n, nleft, ncupbc, tleft, tright,linear, &nfinal, tfinal, (float*)(&yfinal[0][0]),

IMSL_MAX_SUBINTER, MXGRID, IMSL_PROBLEM_EMBEDDED, fcnpeq, fcnpbc, pistep,IMSL_HINIT, ninit, tinit, yinit, IMSL_ERR_EST, &errest, 0 );

printf(" t y0 y1\n" ); for( i=0; i<nfinal; i++ ) { printf("%5d%15.6e%15.6e%15.6e\n", i, tfinal[i], yfinal[i][0],

yfinal[i][1]); } printf("Error Estimates "); printf("%15.6e%15.6e\n",errest[0],errest[1]); return;}

void fcneqn(int n, float t, float y[], float p, float dydt[]){ float z = t - 0.5; dydt[0] = y[1]; dydt[1] = p*y[0]*y[0]*y[0] + 40./9.*pow(z*z,1./3.) - pow(z,8);}void fcnjac(int n, float t, float y[], float p, float dfdy[]){ dfdy[0*n+0] = 0; /* df0/dy0 */ dfdy[0*n+1] = 1; /* df0/dy1 */ dfdy[1*n+0] = 3.*(p)*(y[0]*y[0]); /* df1/dy0 */ dfdy[1*n+1] = 0; /* df1/dy1 */}void fcnbc(int n, float yleft[], float yright[], float p, float h[]){ float pi2 = imsl_f_constant("pi", 0)/2.0; h[0] = yleft[0] - pi2; h[1] = yright[0] - pi2;}void fcnpeq(int n, float t, float y[], float p, float dfdp[]){ dfdp[0] = 0; dfdp[1] = y[0]*y[0]*y[0];}void fcnpbc(int n, float yleft[], float yright[], float p, float dhdp[]){

Page 279: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

dhdp[0] = 0; dhdp[1] = 0;}

出力結果

t y0 y1 0 0.000000e+00 1.570796e+00 -1.949336e+00 1 4.444445e-02 1.490495e+00 -1.669566e+00 2 8.888889e-02 1.421951e+00 -1.419465e+00 3 1.333333e-01 1.363953e+00 -1.194307e+00 4 2.000000e-01 1.294526e+00 -8.958461e-01 5 2.666667e-01 1.243628e+00 -6.373191e-01 6 3.333334e-01 1.208785e+00 -4.135206e-01 7 4.000000e-01 1.187783e+00 -2.219351e-01 8 4.250000e-01 1.183038e+00 -1.584200e-01 9 4.500000e-01 1.179822e+00 -9.973146e-02 10 4.625000e-01 1.178748e+00 -7.233893e-02 11 4.750000e-01 1.178007e+00 -4.638249e-02 12 4.812500e-01 1.177756e+00 -3.399763e-02 13 4.875000e-01 1.177582e+00 -2.205548e-02 14 4.937500e-01 1.177480e+00 -1.061177e-02 15 5.000000e-01 1.177447e+00 -1.496867e-07 16 5.062500e-01 1.177480e+00 1.061153e-02 17 5.125000e-01 1.177582e+00 2.205518e-02 18 5.187500e-01 1.177756e+00 3.399727e-02 19 5.250000e-01 1.178007e+00 4.638219e-02 20 5.375000e-01 1.178748e+00 7.233876e-02 21 5.500000e-01 1.179822e+00 9.973124e-02 22 5.750000e-01 1.183038e+00 1.584199e-01 23 6.000000e-01 1.187783e+00 2.219350e-01 24 6.666667e-01 1.208786e+00 4.135206e-01 25 7.333333e-01 1.243628e+00 6.373190e-01 26 8.000000e-01 1.294526e+00 8.958461e-01 27 8.666667e-01 1.363953e+00 1.194307e+00 28 9.111111e-01 1.421951e+00 1.419465e+00 29 9.555556e-01 1.490495e+00 1.669566e+00 30 1.000000e+00 1.570796e+00 1.949336e+00Error Estimates 3.451270e-06 5.550027e-05

dea_petzold_gearPetzold−Gear BDF BDF(後退微分公式)法を使用して、1階微分代数連立方式 g(t, y, y′) = 0 を解きます。

概要

#include <imsl.h>

void imsl_f_dea_petzold_gear_mgr (int task, void **state, …,0)int imsl_f_dea_petzold_gear (int neq, float *t, float tend, float y[],

float yprime[], void *state, int gcn(), …,0) double 型関数は、imsl_d_dea_petzold_gear_mgr と imsl_d_dea_petzold_gearです。

関数 imsl_f_dea_petzold_gear_mgr は問題を初期化してリセットするために使用

され、関数 imsl_f_dea_petzold_gear はその積分器になります。以下に、これら

の関数の説明がされています。

imsl_f_dea_petzold_gear_mgrに必要な引数

int task ( 入力 )この関数は、方程式を解くために IMSL_DEA_INITIALIZEが設定され

た taskと、問題が解かれた後に削除するために IMSL_DEA_RESET が

Page 280: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

設定された taskを呼び出す必要があります。taskの値は、includeファイル imsl.h で定義されます。

void **state ( 入力 / 出力 ) 解の現在の状態は state によって指される構造体に保持されます。

これを直接操作する事はできません。

imsl_f_dea_petzold_gearに必要な引数

int neq ( 入力 )方程式、 g(t, y, y′) = 0 の数。

float *t ( 入力 / 出力 )独立変数。入力では tは初期独立変数の値で、 出力ではエラー条件が

発生しなければ t は tend によって置き換えられます。

float tend ( 入力 )解が望まれる t の数学的な値。

float y[] ( 入力 / 出力 )独立変数値を含んだ neq 要素の配列。この配列は、積分が開始される

時の初期値を含まなければなりません。

float yprime[] ( 入力 / 出力 )微分値 y′ を含んだ neq 要素の配列。 この配列は初期値を含まなければ

なりませんが、それは一貫性がある必要はありません。この関数は出発点で方程式を満足するために y′ の一貫した値について解きます。

void *state ( 入力 / 出力 )この解の現在状態は state によって指される構造体の中に保持されま

す。それは imsl_f_dea_petzold_gear_mgr の呼び出しによて初期化され

なければなりません。 それは直接操作することはできません。

int gcn (int neq, float t, float *y, float *yprime, float *gval) ( 入力 )g(t, y, y′) を計算するユーザ提供関数。

float *gval ( 出力 )関数値 g(t, y, y′) を含んだ neq 要素の配列。

gcn は、パニックフラッグを表す int 値を返します。 g の計算の後で、このパニック・フラッグはチェックされます。g の値は、このフラッグが 0 であれば使用されます。この値が −1 であれ

ば、この関数はそのステップサイズと恐らく BDF の次数を減少しま

す。この値が −2 であれば、関数は制御を直ちにユーザに返します。

戻り値

この関数が実行した内容を報告するフラッグを返します。

値 説明0 通常の戻り。1 ステップが、中間出力モードに取られました。値 tend に

は、到達しませんでした。2 t_barrier までの積分が終了しました。3 t_barrier の積分は、 t_barrier の後のステップと y と y′

の計算のための補間を行うことで終了しました。−1 ステップが多すぎます。

−2 誤差許容値が小さすぎます。

−3 真の相対誤差許容値は、満足されません。

−6 最後のステップで、繰り返し誤差検定の失敗があります。

−7 BDF 修正方程式ソルバーは、収束しませんでした。

−8 偏微分の行列は、特異です。

−10 計算失敗のフラッグが生じたので、BDF 修正方程式ソルバーは収束しませんでした。

−11 終了するために、計算失敗のフラッグが生じました。

Page 281: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

imsl_f_dea_petzold_gear_mgrのオプション引数の概要#include <imsl.h>

void imsl_f_dea_petzold_gear_mgr (int task, void **state, IMSL_INITIAL_STEPSIZE, float intitial_stepsize, IMSL_T_BARRIER, float t_barrier,IMSL_MAX_BDF_ORDER, int max_bdf_order,IMSL_INITIAL_VALUES_INCONSISTENT, IMSL_JACOBIAN, void jgcn(), IMSL_JACOBIAN_W_DATA, void jgcn(), void *data,IMSL_GCN_W_DATA, int gcn(), void *data,IMSL_NORM_FCN, float norm_fcn(), IMSL_NORM_FCN_W_DATA, float norm_fcn(),void *data,IMSL_USER_JAC_FACTOR_SOLVE, void jgcn(), int fac(),

void sol(),IMSL_USER_JAC_FACTOR_SOLVE_W_DATA, void jgcn(),

int fac(), void sol(), void *data,0)

オプション引数

IMSL_INITIAL_STEPSIZE, float initial_stepsize ( 入力 )初期ステップサイズ。 デフォルト: 内部的に計算されます。

IMSL_T_BARRIER, float t_barrier ( 入力 )このオプション引数は、このコードが特別な点 t_barrier を過ぎて積分

して、それから点 tend で y と y′ を得るために補間するかどうかを制御

します。このオプション引数が存在しなければ、これが許されます。 このオプション引数が存在すれば、このコードは,方程式が t_barrier の反対側に変わるか,或いは、そこで未定義にされるかを想定します。この場合には、このコードは積分の方向で t_barrier まで進みます。

IMSL_MAX_BDF_ORDER, int max_bdf_order ( 入力 )使用される後退差分公式 (BDF) の最大階数。

デフォルト: 5

IMSL_INITIAL_VALUES_INCONSISTENT, ( 入力 )このオプション引数は初期値 (t, y, y′) が矛盾していないかを制御しま

す。このオプション引数が提供されなければ、初期点の g(t, y, y′) = 0 で、それ以外はこの関数はこの方程式を満足するために y′ を解くこと

を試みます。

IMSL_JACOBIAN, void jgcn(int neq, float t, float y[], float yprime[], float cj, float *pdg) ( 入力 ) g(t, y, y′) の偏微分を計算するユーザ提供の関数で、この cj はステッ

プサイズと BDF を計算するために使用される値 cj でそして pdg は偏微

分 A = [∂g/∂y + cj∂g/∂y′] を含んだサイズ neq × neq の配列です。各非ゼ

ロ微分入力値 aij は計算されて配列位置 pdg[i*neq+j] に返されます。

jgcn が呼ばれる時はこの配列内容はゼロです。 このために非ゼロ微分

だけが jgcn に定義されなければなりません。

デフォルト: 偏微分は、分割された差分を使用して計算されます。

IMSL_JACOBIAN_W_DATA, void jgcn(int neq, float t, float y[], float yprime[], float cj, float *pdg, void *data), void *data ( 入力 )

−12 y′ の初期値の反復は収束しませんでした。−33 致命的なエラーが存在します。恐らく、不当な入力が原因

です。

Page 282: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

g(t, y, y′) の偏微分を計算するユーザ提供の関数。ユーザにより提供さ

れるデータへのポインターを受け取ります。data は、ユーザ提供関数

に渡されるデータへのポインターです。詳細は、本マニュアルの初めにある「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_GCN_W_DATA, int gcn(int neq, float t, float *y, float *yprime, float *gval, void *data), void *data ( 入力 )g(t, y, y′) を計算するユーザ提供関数。 data は、ユーザ提供関数に渡さ

れるデータへのポインターです。詳細は、本マニュアルの初めにある「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_NORM_FCN, float norm_fcn(int neq, float v[], float wt[]) ( 入力 )各ステップで推定される誤差のサイズを測定するユーザ提供の関数。 デフォルト: 次式で与えられる RMS 重み付きノルム。

IMSL_NORM_FCN_W_DATA, float norm_fcn(int neq, float v[], float wt[], void *data), void *data ( 入力 )各ステップで推定される誤差のサイズを測定するユーザ提供の関数。

data は、ユーザ提供関数に渡されるデータへのポインターです。詳細

は、本マニュアルの初めにある「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_USER_JAC_FACTOR_SOLVE, void jgcn(int neq, float t, float y[], float yprime[], float cj), int fac(), void sol(int neq, float *g, float *y) (入力 )偏微分 A = [∂g/∂y + cj∂g/∂y′]、因子 A を計算して、方程式 A∆y = ∆g を解

くユーザ提供の関数。このオプション引数を使用すると、問題指定の方法で因子分解と解決ステップを操作することが可能です。成功なら fac が 0 を返し、不成功なら fac は非ゼロ値を返します。このオプショ

ン引数の使用法は 例題 5 を参照してください。

IMSL_USER_JAC_FACTOR_SOLVE_W_DATA, void jgcn(int neq, float t, float y[], float yprime[], float cj, void *data), int fac(void *data), void sol(int neq, float *g, float *y, void *data), void *data ( 入力 )偏微分 A = [∂g/∂y + cj∂g/∂y′]、因子 A を計算して、方程式 A∆y = ∆g を解

くユーザ提供の関数。data を呼び出す引数ははユーザ提供の関数に渡

されるデータへのポインターです。このオプション引数の使用法は 例題 5 を参照してください。

imsl_f_dea_petzold_gearのオプション引数の概要#include <imsl.h>

int imsl_f_dea_petzold_gear (int neq, float *t, float tend, float y[], float yprime[], void **state, int gcn(),

IMSL_ATOL_RTOL_ARRAYS, float *atol, float *rtol,IMSL_ATOL_RTOL_SCALARS, float atol, float rtol,IMSL_MAX_NUMBER_STEPS,int max_steps,IMSL_MAX_STEP, float max_stepsize, IMSL_ALL_NONNEGATIVE, IMSL_BDF_ORDER_NEXT_STEP, int next_bdf_order, IMSL_BDF_ORDER_PREVIOUS_STEP, *int prev_bdf_order, IMSL_NSTEPS_TAKEN, int *nsteps_taken, IMSL_NFCN, int *nfcn, IMSL_NFCNJ, int *nfcnj, IMSL_NERROR_TEST_FAILURES, int *nerror_test_failures, IMSL_NCONV_TEST_FAILURES, int *nconv_test_failures,

( )12 2/ /0neqRMS v wt neqi ii

−∑= =

Page 283: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_CONDITION, float *condition, 0)

オプション引数

IMSL_ATOL_RTOL_ARRAYS, float *atol, float *rtol ( 入力 )要素毎の許容値がこの解に使用されます。 引数 atol と rtol は解 y の各要素に適用される絶対許容値と相対許容値に使用される長さ neq の配列のポインターです。 絶対許容値と相対許容値のスカラー値が全て

の要素に適用される場合、オプション引数 IMSL_ATOL_RTOL_SCALARS を参照してください。 デフォルト: atol と rtol の全ての要素は、 sqrt(imsl_f_machine(4)) に設定されます。

IMSL_ATOL_RTOL_SCALARS, float atol, float rtol ( 入力 )y の全ての要素のエラー推定に適用されるスカラー値。 y の各要素に別の許容値が適用される場合、オプション引数 IMSL_ATOL_RTOL_ARRAYS を参照してください。

Default : atol と rtol は、 sqrt(imsl_f_machine(4)) です。

IMSL_MAX_NUMBERSTEPS, int max_steps ( 入力 )最大ステップ数。 デフォルト: 500

IMSL_MAX_STEP, float max_stepsize ( 入力 )最大許容ステップサイズ。 デフォルト: imsl_f_machine(2)

IMSL_ALL_NONNEGATIVE ( 入力 )このオプション引数制御は全ての要素が非負になるように制約することを試みます。 デフォルト: この制約は、強制されません。

IMSL_BDF_ORDER_NEXT_STEP, int next_bdf_order ( 入力 )次のステップで使用される BDF 法の階数。

デフォルト: 内部的に計算されます。

IMSL_BDF_ORDER_PREVIOUS_STEP, int *prev_bdf_order, ( 出力 )最後のステップで使用される BDF 法の階数。

IMSL_NSTEPS_TAKEN, int *nsteps_taken ( 出力 )現在までのステップ数。

IMSL_NFCN, int *nfcn ( 出力 ) g が計算された回数。

IMSL_NFCNJ, int *nfcn ( 出力 )偏微分行列が計算された回数。

IMSL_NERROR_TEST_FAILURES, int *nerror_test_failures ( 出力 )現在までの誤差検定失敗の総数。

IMSL_NCONV_TEST_FAILURES, int *nerror_test_failures, ( 出力 )現在までの収束検定失敗の総数。これは特異反復行列を含みます。

IMSL_CONDITION, float *condition ( 出力 )行列 A の条件数の逆数。 オプション引数 IMSL_USER_EVAL_FACTOR_SOLVE がimsl_f_petzold_gear_mgr を呼び

出すために使用される場合、このオプション引数は使用できません。

説明

関数 imsl_f_dea_petzold_gear は y と y′ の初期データ与えられて、連立微

分代数方程式 g(t, y, y′) = 0 の解の近似を見つけます。

imsl_f_dea_petzold_gearは、硬い連立常微分方程式に適応した BDF 公式を

使用して , ユーザ指定の許容値に釣り合った総括誤差を保持します。Brenan そ

Page 284: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

の他 . (1989 年 ) を参照して下さい。imsl_f_dea_petzold_gear は指標 1 或い

は 指標 0 の硬い連立微分代数方程式に有効です。指標 の定義は Brenan その他

. (1989 年 ) を参照して下さい。ユーザは短浮動小数点精度を持つマシン上で倍

精度を使用する事が薦められます。次に与えられる例題は、その他の IMSL C 数値ライブラリ例題と互換性が望まれるので短浮動小数点精度です。関数 imsl_f_dea_petzold_gear は Petzold (1982 年 -1990 年 ) によって設計された

コード DASSL を基にしています。

例題 1

Van der Pol 方程式 u″ + (u2 − 1) u′ + u = 0, µ > 0 は周期的リミット・サイクルを持

つ単一常微分方程式です。Hartman (1964 年 , 181 ページ ) を参照して下さい。

値 µ = 5 に対して、この方程式は t = 0 から、リミットが t = 26 で明らかに発展

するまで積分されます。ここで使用される ( 任意の ) 初期条件は u(0) = 2 と u′(0) = − 2/3 です。これらの初期条件と最終 t 値を除いて、これは Enright とPryce (1987 年 ) 検定パッケージの問題 (E2) です。 この方程式は1階連立方程式

を定義することによって微分代数方程式として解かれます。

この例題の初期条件 t = 0 で g ≠ 0 なので矛盾していることに注目して下さい。

これを反映するためにオプション引数 IMSL_INITIAL_VALUES_INCONSISTENT が使用されます。

•#include <stdio.h>#include "imsl.h"

static int gcn(int n, float t, float y[], float ypr[], float gval[]);

#define N 2void main(){ int istep, nstep, n = N; float delt, t, tend, y[N], ypr[N]; char *state;

/* ソルバーを初期化 */ imsl_f_dea_petzold_gear_mgr(IMSL_DEA_INITIALIZE, &state,

IMSL_INITIAL_VALUES_INCONSISTENT, 0);

t = 0.0; tend = 26.0; delt = 0.1; nstep = (int)(tend/delt)+1; y[0] = 2.0; y[1] = -2.0/3.0; ypr[0] = y[1]; ypr[1] = 0.0;

for (istep = 0; istep < nstep; istep++) { tend = t+delt; imsl_f_dea_petzold_gear(n, &t, tend, y, ypr, state, gcn, 0); }

/* ソルバーをリセット */ imsl_f_dea_petzold_gear_mgr(IMSL_DEA_RESET, &state, 0);

/* 結果を出力 */

( ) ( )

1

1 2 1

22 1 2 1 2

1/

0

1 0

y ug y y

g y y y y

ε µ

ε

==

′= − =

′= − − + =

Page 285: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

printf(" T y[0] y[1] y'[0] y'[1]\n"); printf("%10.2f %10.5f %10.5f %10.5f %10.5f\n", tend, y[0], y[1], ypr[0], ypr[1]);}

static int gcn(int n, float t, float y[], float ypr[], float gval[]){ float eps = 0.2; gval[0] = y[1] - ypr[0]; gval[1] = (1.0-y[0]*y[0])*y[1] - eps*(y[0]+ypr[1]);

return 0;}

出力結果

T y[0] y[1] y'[0] y'[1] 26.00 1.46223 -0.24127 -0.24274 -0.09163

Figure 5-1 Van der Pol Cycle, (u(t), u′(t)), µ = 5.

例題 2

直交座標系 (p, q) において 重力 mg 、張力値 λ の影響下で , 長さ l の質量無しの

ワイヤーに吊り下げられた質点 m の1階運動方程式は、じ式で表されます。

これは純粋な微分代数システムです。この問題は、値 3 に等しい指標数を持ち

ます。このために、直接 imsl_f_dea_petzold_gearで解くことはできませ

ん。残念ながら、この指標が1よりも大きい事実を間接的に推定されなければなりません。通常、 (BDF) 補正方程式が収束されないことを述べるエラーがあ

ります。それでユーザはこの制約方程式を微分して置き換えます。 この例題は

最後の方程式を2回微分することによって値1の指標番号の問題に変換されます。与えられた方程式を置き換えるこの結果の方程式は次の全体エネルギー・バランスになります。

2 2 2 0

p uq vmu pmv q mgp q

λλ

′ =′ =

′ = −′ = − −

+ − =l

Page 286: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

従属変数の初期条件と体系的定義では、このシステムは次項になります。

この問題は英国測定単位フィート、ポンド、秒で与えられます。このワイヤーの長さ 6.5 フィートで、端の質量は 98 ポンドです。このソフトウエアの使用

法はそれを要求しませんが、数値モデルには標準又は「SI」 単位が使用されま

す。この単位の変換がユーザ提供計算関数 gcn の中で最初のステップとして実

行されます。 水平位置でスタートする振り子に対応する1セットの初期条件は

n = 0 の入力信号の出力として提供されます。張力パラメータ λ(t) = y5(t) の最

大の大きさは出力点 t = 0.1, π, (0.1) で計算されます。この極値は英国単位に変

換されてプリントされます。

#include <stdio.h>#include <stdlib.h>#include <math.h>#include "imsl.h"

static int gcn(int n, float t, float y[], float ypr[], float gval[]);

#define N 5void main(){ int istep, nstep, n = N; float delt, gval[N], maxlb, maxten, t, tend, tmax, y[N], ypr[N]; char *state;

/* ソルバーを初期化 */ imsl_f_dea_petzold_gear_mgr(IMSL_DEA_INITIALIZE, &state, 0); /* 初期データを定義 */ t = 0.0; tend = imsl_f_constant("pi", 0); delt = 0.1; nstep = (int)(tend/delt); /* 初期条件を取得 */ gcn(0, t, y, ypr, gval); maxten = 0;

for (istep =0; istep < nstep; istep++) { tend = t+delt; imsl_f_dea_petzold_gear(n, &t, tend, y, ypr, state, gcn, 0); /* 最大張力値 */ if (fabs(y[4]) > fabs(maxten)) { tmax = t; maxten = y[4]; } }

/* ソルバーをリセット */ imsl_f_dea_petzold_gear_mgr(IMSL_DEA_RESET, &state, 0);

printf("max tension = %f at tmax = %f\n", maxten/.4536, tmax);} static int gcn(int n, float t, float y[], float ypr[], float gval[])

2 2 2( ) 0m u v mgq λ+ − − =l

( )

1 3 1

2 4 2

3 1 5 3

4 2 5 4

2 2 25 3 4 2 5

00

00

0

g y yg y yg y y myg y y mg my

g m y y mgy y

′= − =′= − =

′= − − =′= − − − =

= + − − =l

Page 287: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{ static int first = 1; static float feetl, grav, lensq, masskg, masslb, meterl, mg; switch (first) { case 1: first = 0; /* 英国式単位からメートル単位に変換 */ feetl = 6.5; masslb = 98.0; meterl = 1.9812000; masskg = 44.4520531; grav = 9.8066502; mg = masskg*grav; lensq = meterl*meterl; /* * 初期条件を定義

* 振り子は y値と水平 */ y[0] = meterl; y[1] = y[2] = y[3] = y[4] = 0.; ypr[0] = ypr[1] = ypr[2] = ypr[3] = ypr[4] = 0.; break; default: /* 残差を計算 */ gval[0] = y[2]-ypr[0]; gval[1] = y[3]-ypr[1]; gval[2] = -y[0]*y[4]-masskg*ypr[2]; gval[3] = -y[1]*y[4]-masskg*ypr[3] - mg; gval[4] = masskg*(y[2]*y[2] + y[3]*y[3]) - mg*y[1] - lensq*y[4]; break; } return 0;}

出力結果

max tension = 1457.800218 at tmax = 2.500000

例題 3

この例題では、Enright と Pryce (1987 年 ) の検定パッケージから硬い常微分方

程式 (E5) を解きます。この問題は非実数固有値を持つ非線形です。これが硬

い問題で , その偏微分がユーザ提供の関数に提供されるので、これが例題とし

て含まれています。偏微分の明示的な公式を提供することは、関数 g(t, y, y′) の計算に時間の掛かる問題とって考慮すべき重要な点です。加えて、初期積分ステップサイズはこの検定問題に与えられます。誤差許容値はデフォルトから 0.1 * sqrt(imsl_f_machine(4)) の純粋な絶対誤差許容値に変更されます。

#include <stdio.h>#include <math.h>#include "imsl.h"

static int gcn(int n, float t, float y[], float ypr[], float gval[]);static void jgcn(int n, float t, float y[], float ypr[], float cj, float *pdg);

#define N 4void main(){ int n = N; float c0, t, tend, y[N], ypr[N]; char *state;

/* ソルバーを初期化 */ imsl_f_dea_petzold_gear_mgr(IMSL_DEA_INITIALIZE, &state,

Page 288: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_INITIAL_STEPSIZE, 5.0e-5, IMSL_JACOBIAN, jgcn, 0);

/* 初期データを定義 */ t = 0.0; tend = 1000.0; c0 = 1.76E-3; y[0] = c0; y[1] = y[2] = y[3] = 0.; ypr[0] = ypr[1] = ypr[2] = ypr[3] = 0;

/* DEA/ODEを積分 */ imsl_f_dea_petzold_gear(n, &t, tend, y, ypr, state, gcn, IMSL_ATOL_RTOL_SCALARS, 0.1*sqrt(imsl_f_machine(4)), 0.0, 0);

printf("\nt = %f", t); imsl_f_write_matrix("Y", 1, 4, y, IMSL_WRITE_FORMAT, "%10.5f", 0); imsl_f_write_matrix("YPR", 1, 4, ypr, IMSL_WRITE_FORMAT, "%10.5f", 0);

/* ソルバーをリセット */ imsl_f_dea_petzold_gear_mgr(IMSL_DEA_RESET, &state, 0);}

static int gcn(int n, float t, float y[], float ypr[], float gval[]){ float C1, C2, C3, C4; C1 = 7.89E-10; C2 = 1.1E7; C3 = 1.13E9; C4 = 1.13E3; gval[0] = -C1*y[0] - C2*y[0]*y[2] - ypr[0]; gval[1] = C1*y[0] - C3*y[1]*y[2] - ypr[1]; gval[2] = C1*y[0] - C2*y[0]*y[2] + C4*y[3] - C3*y[1]*y[2] - ypr[2]; gval[3] = C2*y[0]*y[2] - C4*y[3] - ypr[3]; return 0;}

static void jgcn(int n, float t, float y[], float ypr[], float cj, float *pdg){#define PDG(I,J) *(pdg+(I)*(n)+(J)) float C1, C2, C3, C4;

C1 = 7.89E-10; C2 = 1.1E7; C3 = 1.13E9; C4 = 1.13E3;

PDG(0,0) = -C1 - C2*y[2] - cj; PDG(0,2) = -C2*y[0]; PDG(1,0) = C1; PDG(1,1) = -C3*y[2] - cj; PDG(1,2) = -C3*y[1]; PDG(2,0) = C1 - C2*y[2]; PDG(2,1) = -C3*y[2]; PDG(2,2) = -C2*y[0] - C3*y[1] - cj; PDG(2,3) = C4; PDG(3,0) = C2*y[2]; PDG(3,2) = C2*y[0]; PDG(3,3) = -C4 - cj;}

出力結果

t = 1000.000000 Y

Page 289: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1 2 3 4 0.00162 0.00000 0.00000 0.00000 YPR 1 2 3 4 -0.00000 -0.00000 -0.00000 -0.00000

例題 4

この例題では、y(0) = y0 = (1, 1, …, 1)Tである n = 10 常微分方程式 g = Hy − y′ の

解を計算します。 t = 1 で次の値が計算されます。

定数行列 H は入力値 hi,j = min(j − i, 0) を持つのでこれは下 Hessenberg 形です。

次の中間量の評価のためのユーザ提供の関数に H を渡すためにオプション引

数 IMSL_FCN_W_DATA と IMSL_JACOBIAN_W_DATA を使用します。

1. 関数 g,

2. 偏微分行列 A = ∂g/∂y + cj∂g/∂y′ = H − cj I,

•#include <stdio.h>#include <math.h>#include "imsl.h"static int gcn(int n, float t, float y[], float ypr[], float gval[],

void *data);static void jgcn(int n, float t, float y[], float ypr[], float cj,

float *pdg, void *data);#define N 10void main(){#define H(I,J) h[(I)*N+(J)]

int n = N, i, j; float t, tend, y[N], ypr[N], sumy, h[N*N]; char *state;

/* * ソルバーを初期化。問題固有のデータをユーザ

* 提供関数に渡すためにオプション引数を使用。

*/ imsl_f_dea_petzold_gear_mgr(IMSL_DEA_INITIALIZE, &state,

IMSL_GCN_W_DATA, gcn, h, IMSL_JACOBIAN_W_DATA, jgcn, h, 0);

t = 0.0; tend = 1.0; for (i = 0; i < n; i++) { y[i] = 1; ypr[i] = 0; for (j = 0; j < n; j++) H(i,j) = 0; } /* Hessenberg 行列を初期化 */ for (i = 0; i < n - 1; i++) { for (j = 0; j < i + 2; j++) H(i,j) = j-i; } for (j = 0; j < n; j++) H(N-1,j) = j-N+1;

/* * DEA/ODEを積分。 g()を計算する関数が定義される。 */ imsl_f_dea_petzold_gear(n, &t, tend, y, ypr, state, NULL, 0);

( )1ni iy t=∑

Page 290: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

sumy = 0.0; for (i = 0; i < N; i++) sumy += y[i];

printf(" T Sum of y[i]\n"); printf(" %15.5f %15.5f\n", tend, sumy); /* ソルバーをリセット */ imsl_f_dea_petzold_gear_mgr(IMSL_DEA_RESET, &state, 0);}

static int gcn(int n, float t, float y[], float ypr[], float gval[],void *data)

{ int i, j; float *Hy; float *h = (float *)data;

/* Gの計算 */ Hy = imsl_f_mat_mul_rect("A*x",

IMSL_A_MATRIX, n, n, h, IMSL_X_VECTOR, n, y, 0);

for (i = 0; i < n; i++) gval[i] = Hy[i] - ypr[i];

free(Hy); return 0;}

static void jgcn(int n, float t, float y[], float ypr[], float cj, float *pdg, void *data)

{#define PDG(I,J) *(pdg+(I)*(n)+(J)) float *h = (float *)data; int i;

for (i = 0; i < n * n; i++) pdg[i] = h[i]; for (i = 0; i < n; i++) PDG(i,i) -= cj;}

出力結果

T Sum of y[i] 1.00000 65.17458

例題 5

この例題では例題 4 と同じ問題を解きますが、偏微分 A = [∂g/∂y + cj∂g/∂y′]′、因子 A を計算するための関数を供給するために、オプション引数

IMSL_EVAL_FACTOR_SOLVE_W_DATA を使用して、システム A∆y = ∆g を解

きます。オプション引数 IMSL_EVAL_FACTOR_SOLVE_W_DATA は、

imsl_f_dea_petzold_gear から呼ばれる時にユーザ提供の関数に渡される問題指

定のデータのポインターを供給することができます。 この例題の問題指定デー

タは下 Hessenberg 行列 H と 偏微分 A = [∂g/∂y + cj∂g/∂y′]′ を含む配列 A とこの

行列の分解された形式です。注意:この例題で偏微分を含む行列 A とこの行

列の分解された形式はこの例題の局所に格納されます。オプション引数 IMSL_EVAL_FACTOR_SOLVE_W_DATA を使用すると、 因子 A に問題指定の

技法を適用することができ、システム A∆y = ∆g を解くことが出来ます。

この例題は大きく、構造化された ( 或いは、非線形 ) DAE 問題のプロトタイプ

として役立たせることも出来て、ここではユーザは行列 A を格納して分解す

る特殊な方法を使用して、線形システム A∆y = ∆g を解かなければなりません。

単語「因子」はここでは文字的に使用されます。例えば、ユーザはシステムを

Page 291: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

反復法を使用して解くことが出来ます。一般的に、分解ステップは後の解法ステップに必要な準備段階になります。

#include <stdio.h>#include <math.h>#include "imsl.h"

/* ローカル関数のためのプロトタイプ */static int gcn(int n, float t, float y[], float ypr[], float gval[],

void *h);static void jgcn(int n, float t, float y[], float ypr[], float cj,

void *data);static int fac(void *data);static void sol(int neq, float *wk, float *gval, void *data);static void srotg (float *sa, float *sb, float *sc, float *ss);

#define N 10/* * ユーザデータをユーザ提供関数に渡す時に使われる

* 構造体を定義 */typedef struct { float *a; float *h;} problem_data;

#define H(I,J) h[(I)*N+(J)]#define A(I,J) a[(I)*N+(J)]

void main(){ int n = N, i, j; float h[N*N]; float a[N*N]; float t, tend, y[N], ypr[N], sumy; problem_data data; char *state;

/* データを初期化 */ t = 0.0; tend = 1.0; for (i = 0; i < n; i++) { y[i] = 1; ypr[i] = 0; for (j = 0; j < n; j++) H(i,j) = 0; }` /* 下 Hessenberg行列の初期化 */ for (i = 0; i < n - 1; i++) { for (j = 0; j < i + 2; j++) H(i,j) = j-i; } for ( j = 0; j < n; j++) H(N-1,j) = j-N+1; /* * ユーザ提供関数に渡されるユーザデータ内で使用されるポインターを

* 設定。 data.a は、偏微分行列 Aの配列を指し、

* data.h は、下 Hessenberg matrix Hを指す。 */ data.a = a; data.h = h; /* * ソルバーを初期化。ユーザ提供関数にユーザデータを渡すための

* オプション引数を使用。 */ imsl_f_dea_petzold_gear_mgr(IMSL_DEA_INITIALIZE, &state,

IMSL_GCN_W_DATA, gcn, &data, IMSL_USER_JAC_FACTOR_SOLVE_W_DATA, jgcn, fac, sol, &data, 0);

Page 292: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* * DEA/ODEを積分。 g()を計算する関数が定義される。 */ imsl_f_dea_petzold_gear(n, &t, tend, y, ypr, state, NULL, 0);

/* 結果を出力 */ sumy = 0.0; for (i = 0; i < N; i++) sumy += y[i];

printf(" T Sum of y[i]\n"); printf(" %15.5f %15.5f\n", tend, sumy); /* ソルバーをリセット */ imsl_f_dea_petzold_gear_mgr(IMSL_DEA_RESET, &state, 0);}

/* * g(t, y, y')を計算する関数 */static int gcn(int n, float t, float y[], float ypr[], float gval[],

void *data){ int i, j; float *h = ((problem_data*)data)->h; float *Hy;

/* Gの計算 */ Hy = imsl_f_mat_mul_rect("A*x",

IMSL_A_MATRIX, n, n, h, IMSL_X_VECTOR, n, y, 0);

for (i = 0; i < n; i++) gval[i] = Hy[i] - ypr[i];

free(Hy); return 0;}

/* * 偏微分を計算するための関数 */static void jgcn(int n, float t, float y[], float ypr[], float cj, void *data){ int i; float *a = ((problem_data*)data)->a; float *h = ((problem_data*)data)->h;

for (i = 0; i< n * n; i++) a[i] = h[i]; for (i = 0; i < n; i++) A(i,i) -= cj;}

/* * Aの因子分解を計算するための関数 */static int fac( void *data){ int i, j, n = N; float stemp, ss, sc; float *a = ((problem_data*)data)->a; float *h = ((problem_data*)data)->h;

for (j = 0; j < n - 1; j++) { /* Givens 変換を構成 */ srotg(&(A(j,j)), &(A(j,j+1)), &sc, &ss); /* Givens 変換を適用 */for (i = 0; i < n - j - 1; i++) {

stemp = sc * A(j+1+i, 0) + ss * A(j+1+i, j+1);

Page 293: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

A(j+1+i, j+1) = sc * A(j+1+i, j+1) - ss * A(j+1+i, 0);A(j+1+i, 0) = stemp;

} } return 0;}

/* * Ay = gを計算するための関数 */static void sol(int n, float *g, float *y, void *data){ int i, j; float z; float stemp, ss, sc; float *a = ((problem_data*)data)->a;

for (j = 0; j < n; j++) y[j] = g[j]; for (j = 0; j < n - 1; j++) { y[j] = y[j]/A(j,j); for (i = 0; i < n - j - 1; i++) y[j+1+i] += -y[j]*A(j+1+i,j); } y[n-1] = y[n-1]/A(n-1,n-1); /* Givens 回転を再構成 */ for (j = n - 2; j >= 0; j--) { z = A(j,j+1); if (fabs(z) < 1.0) { sc = sqrt(1.0e0 - pow(z, 2)); ss = z; } else if (fabs(z) > 1.0) { sc = 1.0/z; ss = sqrt(1.0e0 - pow(sc, 2)); } else { sc = 0.0; ss = 1.0; } stemp = sc * y[j] + ss * y[j+1]; y[j+1] = sc * y[j+1] - ss * y[j]; y[j] = stemp; } }

/* * Givens面回転を構成するための Aの因子分解で

* 使用されるローカル関数 */static void srotg (float *sa, float *sb, float *sc, float *ss){ /* Givens 面回転を構成 */ float r, u, v; if (fabs (*sa) > fabs (*sb)) { u = *sa + *sa; v = *sb / u; r = sqrt (.25 + v*v) * u; *sc = *sa / r; *ss = v * (*sc + *sc); *sb = *ss; *sa = r; } else { if (*sb != 0.0) { u = *sb + *sb; v = *sa / u; *sa = sqrt (.25 + v*v) * u; *ss = *sb / *sa; *sc = v * (*ss + *ss); if (*sc != 0.0) {

Page 294: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

*sb = 1.0 / *sc; } else { *sb = 1.0; } } else { *sc = 1.0; *ss = *sa = *sb = 0.0; } } return;}

pde_1d_mgのイントロダクション本節は連立偏微分方程式を解くためのアルゴリズムと次の対応する積分器ルーチン imsl_f_pde_1d_mg を説明します。

方程式 1

このソフトウエアは一次元の微分方程式ソルバーです。それは の評価のた

めの機能に加えて、初期条件と境界条件をユーザが提供することが必要になり

ます。 この積分方法は、空間変数 の中のグリッド線の保守のために注目する

価値があります。 新しいグリッド線の選択に関する詳細は Blom と Zegeling, (1994 年 ) にあります。 imsl_f_pde_1d_mgを使って解かれる問題のクラスは方

程式1によって表され次式によってより詳細に与えられます。

方程式 2

ベクトル は、その解です。 整数値 は、微分方程式

の数です。関数 と は、特別な場合に流束項とソース項と見なされます。

関数 は連続であるものと期待されています Allowed values for the

整数 に許される値は、 のいずれかです。これらは、それぞれデカル

ト座標、円筒極座標、球座標の問題のためのものです。 の 2 つのケースの

場合、間隔 は、内部点として を含んではいけません。

この境界条件は次のマスター方程式形式を持ちます。

方程式 3

この境界条件の中で関数 と は連続です。 0 で の端点を持つ

の2つのケースの場合、 での解の有限値が保証されなければなりま

せん。 これは、 での解の仕様を必要とするか、 又は を

( ) 0, , , ,t L R

uu f u x t x x x t tt

∂≡ = < < >

tu

x

( ) ( )( ) ( )

{ }

,1

, 0

, , , , , , , , , ,

1, , , , 0,1,2

kNPDEm m

j k x j x j xk

L R

uC x t u u x x R x t u u Q x t u ut x

j NPDE x x x t t m

=

∂ ∂= −

∂ ∂= < < > ∈

∑K

1 , ,TNPDEu u u≡ K 1NPDE ≥

jR jQ

,, , ,j k j ju C R Q

m 0,1, 2m =

0m >

[ ],L Rx x 0x =

( ) ( ) ( ), , , , , , , ,at and , 1,...,

j j x j x

L R

x t R x t u u x t u ux x x x j NPDE

β γ=

= = =

jβ jγ [ ],L Rx x

0m > 0x =

0x = 0L

j x xR

== 0

Rj x x

R=

=

Page 295: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

意味します。 この初期値は、 を満たします。ここで、

は、 要素を持つ の区分連続ベクトル関数です。

数学的定義が、次の関数のために知られるようにユーザは問題を提起しなければなりません。

これらの関数は2つのユーザ提供の形式でルーチン imsl_f_pde_1d_mg に提供

されます。 この形式のインターフェース使用法は、以下に説明といくつかの例

題あります。 は入力引数 u 又はオプションのユーザ提供の関数によって供給

されます。このアルゴリズムの説明に不安がないユーザは直接この例題節にスキップすることが出来ます。

説明のサマリー

方程式 1 は、 時間依存グリッド値

で近似されます。 全体微分 を使用して、微分方程式を次の形に変換します。

因子 のために中心分割差分を使用して、次の陰型の連立常微分方程式に導

きます。

項 は、それぞれ偏微分方程式の近似解と点 での

の値を表しています。 この近似からの打ち切り誤差は空間変数 の中

で 2 次になります。 上述の常微分方程式は未決定であるので,追加の式がこの

時間依存グリッド点を決定するために追加されます。これらの追加の式はユーザによって調整されるパラメータを含みます。時には,難しい問題を解くために、これらのパラメータを修正することが必要になります。この目的のためには次の数量が必要になります。

値 はグリッドの点集中と呼ばれます。パラメータ は空間平滑値を示します。ここでこのグリッド点は暗黙の中に次式のように定義されます。

パラメータ 時間平滑値を示します。 値 が大きくなるように選ばれる

と、これは固定された空間グリッドになります。 デフォルト値から を増加す

ることで、グリッド線が交差するエラー条件を避けます。その除数は次式で定義されます。

( ) ( ) [ ]0 0, , ,L Ru x t u x x x x= ∈

0u NPDE x

, 0, , , , andj k j j j jC R Q uβ γ

0u

N = ngrids

( )0 1 1L i N Rx x x x t x x+= < < < < < =K K t x

du dxu udt dt

= +

( ), , ,t x L R

du dxu u f u x t x x xdt dt

= − = < <

xu

( )( )

1 10

1 1

, , 1, ,i ii ii

i i

U UdU dxF t t i N

dt x x dt+ −

+ −

−− = > =

−K

,i iU F ( )( , , ) ( , , )i iu x t U x t t=

( ), ,f u x t x

( )( )

11

1 1

1 0 1

,1 2 , 0

,

i i i i i

i i i i i

N N

x x x n xn n n n i N

n n n nµ κ κ

−+

+ −

− +

∆ = − = ∆

= − + − + ≤ ≤

≡ ≡

in 0κ ≥

11

1

, 1i i

i i

i i

du dudt dt i N

M M

µ τ µ τ−−

+ += ≤ ≤

0τ ≥ ττ

Page 296: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

値 はクラスター化のレベル或いはグリッド点の空間の平滑化を決定します。 デフォルト値から が減少すると空間平滑化の量が減少します。パラメータ

は孤長を近似してグリッドの形状や、 分布の形状を決定する手助けをしま

す。パラメータ はグリッドの移動が の新しい値に直接調整されることを

妨げるので、その解の大きい相対誤差の原因となるグリッドの中の振動を避けます。 急な勾配を持つ解に適用される時にこれは重要になります。

微分方程式の離散形式と平滑化方程式は微分方程式の陰的なシステムを生じるために組み合わせられます。

これは通常、硬い連立微分代数方程式です。 本章に載っている 積分器

imsl_f_dea_petzold_gear を使用してこれを解きます。

imsl_f_dea_petzold_gearr が微分方程式や境界条件の計算のときに必要な場

合、imsl_f_dea_petzold_gear の imsl_f_pde_1d_mg の内部使用で起こり得

る問題を避けるために別スレッドで実行されなければなりません。imsl_f_pde_1d_mg によってセットされる imsl_f_dea_petzold_gear だけの

オプションは、最大 BDF 階数と絶対と相対誤差で IMSL_MAX_BDF_ORDERと IMSL_ATOL_RTOL_SCALARS として載っています。

pde_1d_mg移動グリッドインターフェースを使用する 1 次元時間依存偏微分方程式のシス

テムを解きます。

概要

#include <imsl.h>

void imsl_f_pde_1d_mg_mgr (int task, void **state, …,0)void imsl_f_pde_1d_mg (int npdes, int ngrids, float *t, float tend,

float u[], float xl, float xr, void *state, void pde_systems(), void boundary_conditions(),…,0)

void 型関数 imsl_d_pde_1d_mg_mgr と imsl_d_pde_1d_mg は、double 型算術

精度用です。

関数 imsl_f_pde_1d_mg_mgr は問題を初期化してリセットするために使用さ

れ、関数 imsl_f_pde_1d_mg はその積分器です。

注: 積分器は、単精度又は倍精度計算で提供されます。倍精度インターフェー

ス imsl_d_pde_1d_mgの使用をお勧めします。

imsl_f_pde_1d_mg_mgrに必要な引数

int task ( 入力 )この関数は、方程式を解くために IMSL_PDE_INITIALIZEが設定され

た taskと、問題が解かれた後に削除するために IMSL_PDE_RESETが

設定された taskを呼び出す必要があります。taskの値は、includeファイル imsl.h で定義されます。

( )( )

2

12 12

1

j jNPDEi i

ij i

U UM NPDE

xα +−

=

−= +

∆∑

κκ

iM ix

τ iM

( )11 1 1

( ) ,

, , , ,TNPDE

dYA Y L Ydt

Y U U x

=

= K K

Page 297: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

void **state ( 入力 / 出力 )PDE 解の現在の状態は state によって指される構造体に保持されま

す。これを直接操作する事はできません。

imsl_f_pde_1d_mgに必要な引数

int npdes ( 入力 ) 微分方程式の数。

int ngrids ( 入力 )境界点 xL と xR を含む空間グリッド / メッシュ点の数。

float *t ( 入力 / 出力 )入力では tは初期独立変数の値で、 出力ではエラー条件が発生しなけ

れば t は tend によって置き換えられます。 これは ut の積分が開始さ

れる独立変数 t0 の値に最初にセットされます。 戻りには値 tend にセッ

トされます。

float tend ( 入力 )ut の積分が終了する t の数学的な値。注意: t < tend の出発値は前進方

向の積分を意味し、t > tend の値は後退方向の積分を意味します。どち

らの方向も許されます。

float u[] ( 入力 / 出力 )サイズ npdes+1 × ngridsの配列。 入力では、最初の npdes 行は値の

等間隔グリッドのシステムの全要素の初期値を含みます。uの最後の

行のグリッド値を定義する必要はありません。出力では、u[] は配列

位置 u[i*ngrids+j]に近似解値 を含みます。 グ

リッド値 は、位置 u[(npdes*ngrids) +j] にあリます。 通常、

グリッド値は積分開始と同じように等間隔です。可変グリッド値はimsl_f_pde_1d_mg_mgr の IMSL_INITIAL_CONDITIONS、又は IMSL_INITIAL_CONDITIONS_W_DATA オプション引数の何れかによって

供給されるユーザ関数 initial_conditions からの出力としてそれら

を定義することによって提供されます。

float xl ( 入力 )下グリッド境界、xL 。

float xr ( 入力 )上グリッド境界、xR 。

void *state ( 入力 / 出力 )解の現在状態は state によって指される構造体の中に保持されます。

imsl_f_pde_1d_mg_mgr の呼び出しによってそれは初期化されなけれ

ばなりません。 それは直接操作できません。

void pde_systems(float t, float x, int npdes, int ngrids, float *full_u, float *grid_u, float *dudx, float *c, float *q, float *r, int *ires) ( 入力 ) 方程式 2 で表わされる微分方程式を評価するためのユーザ提供の関

数。各アプリケーションはこのタスクのために特別に設計された関数を必要として、この関数は通常積分器のユーザによって書かれます。

方程式 2 のシステムの項目を評価します。m=0 のデフォルト値が、推

定されますが、選択 m=1,2 の一つに変更可能です。 m = 0,1,2 のそれぞ

れの値のために、オプション引数 IMSL_CART_COORDINATES、 IMSL_CYL_COORDINATES、 IMSL_SPH_COORDIANTES を使用します。 示さ

れるように配列の中の値を返します。

( )( ),i jU x tend tend

( )jx tend

Page 298: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

どの関数も計算できない場合、ires=3を設定します。それ以外では、 iresの値を変更しないでください。

void boundary_conditions (float t, float *beta, float *gamma, float *full_u,float *grid_u, float *dudx, int npdes, int grids, int left, int *ires) ( 入力 )方程式 2 で表されている境界条件を供給するためのユーザ提供の関数。

値 と のためのフラッグ。フラッグは のために値 left=0を持ちます。どの関数も計算できない場合、 ires=3を設定します。それ以外

では、 iresの値を変更しないでください。

imsl_f_pde_1d_mg_mgrのオプション引数の概要 #include <imsl.h>

void imsl_f_pde_1d_mg_mgr (int task, void **state,IMSL_CART_COORDINATES, 又はIMSL_CYL_COORDINATES, 又はIMSL_SPH_COORDINATES,IMSL_TIME_SMOOTHING, float tau,IMSL_SPATIAL_SMOOTHING, float kappa,IMSL_MONITOR_REGULARIZING, float alpha,IMSL_MAX_BDF_ORDER, int max_bdf_order,IMSL_USER_FACTOR_SOLVE, int fac(), void sol(),IMSL_USER_FACTOR_SOLVE_W_DATA, int fac(), void sol(),void data,IMSL_INITIAL_CONDITIONS, void initial_conditions()IMSL_INITIAL_CONDITIONS_W_DATA, void initial_conditions(), void data,0)

オプション引数

IMSL_CART_COORDINATES、又は

IMSL_CYL_COORDINATES、又は

IMSL_SPH_COORDINATES

IMSL_CART_COORDINATES は、方程式 2の中でm = 0であるデカルト座標

を指定します。 IMSL_CYL_COORDINATES は、方程式 2 の中で m = 1 であ

る円柱座標、もしくは極座標を指定します。IMSL_SPH_COORDINATES

は、方程式 2 の中で m = 2 である球座標を指定します。

デフォルト: IMSL_CART_COORDINATES

[ ]

[ ]

[ ][ ] ( )[ ] ( )[ ] ( )

, , , ,

, , ,

, , ,, 0,..., 1

j

jj

x

j k x

j x

j x

u jU

u u jxj k C x t u u

j r x t u u

j q x t u uj k NPDE

∂∂

=

=

= =

=

=

=

= −

grid_u

full_u

dudx

c

r

q

[ ]

[ ]

[ ] ( )[ ] ( )

, , ,

, , ,0,..., 1

j

jj

x

j x

j x

u jU

u u jx

j x t u u

j x t u uj NPDE

∂∂

β

γ

=

=

= =

=

=

= −

grid_u

full_u

dudx

beta

gamma

{ },L Rx x x∈Lx x= Rx x=

Page 299: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_TIME_SMOOTHING, float tau, ( 入力 )

パラメータ の値をリセットします。

デフォルト: .

IMSL_SPATIAL_SMOOTHING, float kappa, ( 入力 )

パラメータ の値をリセットします。 デフォルト: .

IMSL_MONITOR_REGULARIZING, float alpha, ( 入力 )

パラメータ の値をリセットします。 デフォルト: a = 0.01

IMSL_MAX_BDF_ORDER, int max_bdf_order, ( 入力 ) imsl_f_dea_petzold_gear に使用される bdf 公式の最大次数をリ

セットします。この新しい値は 1 と 5 の間の整数になります。 ある問

題はこれを変更することにより恩恵を受けます。max_bdf_order のデ

フォルト値が選ばれたのは、imsl_f_dea_petzold_gear が次数のそ

の選択で循環して max_bdf_order のステップサイズが値 2 よりも大き

いからです。デフォルト: max_bdf_order=2.

IMSL_USER_FACTOR_SOLVE, int fac(int neq, int iband, float *a), void sol(int neq, int iband, float *g, float *y) ( 入力 )因子 A へのユーザ提供の関数で、システム A∆y = ∆g を解きます。この

オプション引数を使用すると問題特定の方法で分解と解ステップの操作が出来ます。成功すれば、fac は 0 を返して、不成功であれば、fac は非ゼロ値を返します。このオプション引数の使用法は例題 5 を参照

して下さい。

IMSL_USER_FACTOR_SOLVE_W_DATA, int fac(int neq, int iband, float *a, void *data), void sol(int neq, int iband, float *g, float *y, void *data), void *data ( 入力 )因子 A へのユーザ提供の関数で、システム A∆y = ∆g を解きます。引数 data はユーザ提供の関数に渡されるデータへのポインターです。

IMSL_INITIAL_CONDITIONS, void initial_conditions(int npdes, int ngrids, float *u) ( 入力 )出発独立変数値 t にシステムの初期値を供給するユーザ提供の関数。

このルーチンは又、初期値に非一様グリッドを提供します。この npdes は微分方程式の数、 ngrids はグリッド点の数、u は位置

u[i*ngrids+j]に近似解値 を含んだサイズ npdes+1 × ngrids の配列です。グリッド値は入力では等間隔ですが、要望通

りに更新でき、増加する値が提供されます。0 ≤ j < ngridsの配列位置 u[(npdes*ngrids) +j] のグリッド値を更新します。

IMSL_INITIAL_CONDITIONS_W_DATA, void initial_conditions(int npdes, int ngrids, float *u, float *grid, void *data), void *data ( 入力 )出発独立変数値 t でシステムの初期値を供給するユーザ提供の関数。

このルーチンは又、初期値に非一様グリッドを提供します。引数 data はユーザ提供の関数に渡されるデータへのポインターです。

imsl_f_pde_1d_mgのオプション引数の概要#include <imsl.h>

void imsl_f_pde_1d_mg (int npdes, int ngrids, float *t, float tend, float u[], float xl, float xr, void *state, void pde_systems(), void boundary_conditions(),IMSL_RELATIVE_TOLERANCE, float rtol,IMSL_ABSOLUTE_TOLERANCE, float atol,IMSL_PDE_SYS_W_DATA, void pde_systems(), void *data,IMSL_BOUNDARY_COND_W_DATA, void bounary_conditions(),

0τ ≥

0τ =

0κ ≥

2κ =

0α ≥

( )( ),i jU x tend tend

Page 300: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

void *data,0)

オプション引数

IMSL_RELATIVE_TOLERANCE, float rtol, ( 入力 )このオプションは imsl_f_dea_petzold_gear に使用される相対精度

パラメータの値をリセットします。デフォルト: rtol=1.0E-2 単精度用、rtol=1.0E-4 倍精度用

IMSL_ABSOLUTE_TOLERANCE, float atol, ( 入力 )このオプションは imsl_f_dea_petzold_gear に使用される絶対精度

パラメータの値をリセットします。デフォルト: atol=1E-2 単精度用、atol=1E-4 倍精度用

IMSL_PDE_SYS_W_DATA, void pde_systems(float t, float x, int npdes, int ngrids, float *full_u, float *grid_u, float *dudx, float *c, float *q, float *r, int *ires, void *data), void *data ( 入力 )方程式 2 で表現される微分方程式を評価するユーザ提供の関数。引数 data はユーザ提供の関数に渡されるデータへのポインターです。

IMSL_BOUNDARY_COND_W_DATA, void boundary_conditions (float t, float *beta, float *gamma, float *full_u, float *grid_u, float *dudx, int npdes, int ngrids, int left, int *ires, void *data), void *data ( 入力 )方程式 2 で表現される境界条件を供給するユーザ提供の関数。引数 data はユーザ提供の関数に渡されるデータへのポインターです。

例題

例題上の所見

imsl_f_pde_1d_mgは、重要かつインターフェースが複雑なので、いくつかの

例題を載せています。 多くのプログラムの特性が行使されます。問題を解くの

にオプション引数の変更が必要な場合を除いて、オプション引数の変更をすることなく問題は終了します。

多くのアプリケーションでは、PDE の解は補助変数として、恐らく大きいデ

ザイン、或いは、シミュレーション過程の一部として使用されます。近似解の打ち切り誤差は、各出力点の値のグリッド上の区分的な線形補間に相当します。この解が妥当なことを示すためには、図で表示したほうが分かりやすく有用です。ドキュメントの一部として図を提供しませんが、ユーザは、弊社製品の PV-WAVE を持っているかも知れません。例題 1-8 は、PV-WAVE で視覚化

できる files pde_ex0#.out ファイルに結果を書き出します。 ここでは、解を視的

に確認するためにコマンドのスクリプト pde_1d_mg_plot.pro を提供します。こ

れは後でリストされます。値のグリッドとそれぞれ連続した解要素は別のウインドウに表示されます。 SUN-SPARC システム上の例題 1-8 によって書かれた

スクリプトとデータ・ファイルは IMSL C 数値ライブラリ例題集のディレクト

リの中にあります。PV-WAVE の実行の際に、特定の例題の出力を見るために

次のコマンド行を使用します 。pde_1d_mg_plot,filename=’pde_ex0#.out’

ここでの ‘#’ には、1 から 8 までの数字を入れます。しかしながら、これらの

例題を実行するために PV-WAVE がインストールされている必要はありませ

ん。

コードは、 PV-WAVE プロッティングのためのコードを参照してください。

例題 1 -電気力学モデル

この例題は、Blom と Zegeling (1994 年 ) から引用しています。システムは次の

通りです。

Page 301: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

モデル問題文と例題をつなげます。

境界条件は次の通りです。

この例題のコードは例題 1 理論的説明 を参照してください。

例題 2 - 平板上の非粘性の流れ

この例題は Pennington と Berzins (1994 年 ) からの連立1次方程式です。方程式

は、次の通りです。

w を消去した後でも、 NPDE = 2 微分方程式のままです。変数 t は、時間ではな

く 2 番目の空間変数です。積分は、t = 0 から t = 5 に進みます。xmax = xR = 25 というように、有限値での変数 x を切り捨てる必要があります。積分器に関し

ては,このシステムは m = 0 と次式で定義されます。

境界条件は、以下によって満たされます。

N = 10 + 51 = 61 グリッド点を使って、Δt = 0.1 ステップでの解を出力します。

この例題のコードは、 例題 2 – 理論的説明 を参照してください。

( )( ),

where ( ) ( / 3) ( 2 / 3)0 1,0 4

0 and 0at 01 and 0at 10.143, 0.1743, 17.19

t xx

t xx

x

x

u pu g u vv pv g u v

g z exp z exp zx t

u v xu v x

p

ε

η η

ε η

= − −= + −

= − −≤ ≤ ≤ ≤= = =

= = == = =

2

1 2

1 2 1

0, ,( ),

1 and 0 at 1

x x

C Im R pu R pvQ g u v Q Qu v t

ε== = == − = −

= = =

1 2 1 2

1 2 1 2

1, 0, 0, , at 00, 1, 1, 0, at 1

L

R

v x xu x x

β β γ γβ β γ γ

= = = = = == = = − = = =

( ) ( ) ( ) ( )( ) ( )

, implying that 0, 0, 0, , , 1, 0

,0 1, ,0 0, 0

t x

t x xx

x t x xx

R

u vuu vu ww u uu vu uu t v t u t u x t t

u x v x x

= −= − +

= = − +

= = ∞ = = ≥

= = ≥

{ } 01 0, ,

0v

C C R Qjk u vuu x x

− = = = =

( )200, ,at

10, ,at

L

Rx

u exp tx x

vu

x xv

β γ

β γ

− −= = =

−= = =

Page 302: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題 3 - ポピュレーションダイナミクス

この例題は、Pennington と Berzins (1994 年 ) から引用しています。 システムは

次の通りです。

これは領域全体を通した次の未知量を含むので注意すべき問題です。

このソフトウエアは次の2つの従属代数方程式を導入することによって問題

を解くことができます。

これは、次の修正されたシステムに導かれます。

微分方程式と境界条件の計算のインターフェース中で,グリッド上の u (x,t) の値を使って計算される積分を評価すること必要があります。この積分は,台形則を使用して近似されて、積分器の中の打ち切り誤差に相当します。

この例題のコードは、 例題 3 - 理論的説明を参照してください。

例題 4 - 円筒座標のモデル

この例題は、Blom と Zegeling (1994 年 ) から引用しています。 このシステムは

反応器拡散問題をモデル化します。

( )

( ) ( )

( ) ( )( )

( ) ( )( ) ( )

( ) ( )( )

( )( ) ( )( )

( )( ) ( ) ( )( )( ) ( )( )

0

0

2

2

, 0 , 0

,

,02

0, , , , , where

, , and1

g

4 2 21 1 1 2 2 1

t x L R

a

a

u u I t u x x a x t

I t u x t dx

exp xu x

exp a

u t g b x I t u x t dx t

xy exp xb x y

y

z,t

z exp a exp texp a a exp a exp a exp t

= − − = ≤ ≤ = ≥

=

−=

− −

=

=+

=

− − + −

− − − + − − − + −

( ) ( )( ) ( )

,1

exp xu x t

exp a exp t−

=− − + −

( )

( ) ( )

10

20

( ) , ,

( ) ,

a

a

v t u x t dx

v t x exp x u x t dx

=

= −

( ) ( )( )

1

1 22

1

, 0 , 01,

0,1

t xu u v u x a tg t v v

u tv

= − − ≤ ≤ ≥

=+

( )

( ) ( )( )

1

4

10, 0, 1, 0, 0

,0 0,0 1

10 , 1, 0.1

rz

r

rT TT r expr T

T z T z z

T r r

βγ

ε

β γ ε

∂ = + ∂ + = = >

= ≤ <

= = =

Page 303: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

軸方向 z は時間座標として扱われます。半径 r は、1 つの空間変数として扱わ

れます。

この例題のコードは、 例題 4 - 理論的説明 を参照してください。

例題 5 - 火災伝播モデル

この例題は、Verwer とその他 (1989 年 ) でより詳しく紹介されています。 シス

テムは質量密度 u (x,t) と温度 v (x,t) に関して正規化された問題です。

この例題のコードは、 例題 5 - 理論的説明 を参照してください。

例題 6 - 「ホットスポット」モデル

この例題は、Verwer とその他 (1989 年 ) でより詳しく紹介されています。 シス

テムは化学系の反応物の温度 u (x,t) に関して正規化された問題です。h(z) の公

式は、彼らの例題と同等です。

この例題のコードは、 例題 6 - 理論的説明 を参照してください。

例題 7 - 進行波

この例題は、Verwer とその他 (1989 年 ) でより詳しく紹介されています。 シス

テムは反対方向に進む 2 つの波 u (x,t) と v (x,t) の相互作用に関連した正規化さ

れた問題です。 この 2 つの波動はぶつかって、方程式の非線形項によって振幅

が減衰します。 それからこれらは分離して、減衰した振幅で前方に進行しま

す。

( )( )

( ) ( )

( ) ( )

( )( )

6

4

3 4

,

where / , 4, 3.52 100 1, 0 t 0.006

,0 1, ,0 0.20, 0

0, , 1, where

1.2, for 2 10 ,and

= 0.2 + 5 10 , for 0 2 10

t xx

t xx

x x

x

u u uf v

v v uf v

f z exp zx

u x v xu v xu v b t x

b t t

t t

γ β β γ

= −

= +

= − = = ×

≤ ≤ ≤ ≤

= =

= = =

= = =

= ≥ ×

× ≤ ≤ ×

( )

( ) ( ) ( )( )

( )

,

where 1 1/ 1 ,

1, 20, 50 1,0 0.29

,0 10, 0

1, 1

t xx

x

u u h uRh z a z exp z

aa R

x tu xu xu x

δδ

δ

= +

= + − − −

= = =≤ ≤ ≤ ≤

=

= == =

( ) ( )( ) [ ]

( ) ( )( ) [ ]

100 ,100 ,

0.5 0.5,0 0.5

,0 0.5 1 10 , 0.3, 0.1 ,and

0,otherwise,

,0 0.5 1 10 0.1,0.3 ,and

0,otherwise,0 at both ends, t 0

t x

t x

u u uvv v uv

x t

u x cos x x

v x cos x x

u v

π

π

= − −= −

− ≤ ≤ ≤ ≤

= + ∈ − −

=

= + ∈

== = ≥

Page 304: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

この例題のコードは、 例題 7 - 理論的説明 を参照してください。

例題 8 - ブラック - ショールズ

行使価格 e と満期日 T を持つヨーロッパ型の「コールオプション」 c (s,t) の値は

「アセット・オア・ナッシング」 を満足します。 満期に

先立って、c (s,t) は、ブラック - ショールズ微分方程式

によって推定されま

す。モデル内のパラメータは、リスクフリーな利率 r と株価の変動率 です。

境界条件は、c (0,t) = 0 と です。この開発は、Wilmott とその

他 (1995 年 ) 41-57 ページに記述されています。確率の正規分布曲線に基づい

たこの方程式の明確な解が存在します。正規分布曲線と解そのものは IMSL 関数 imsl_f_normal_cdf (第 9 章:特殊関数を参照)で効率的に計算されま

す。数値積分で、この方程式自身、或いは、利益は、他の公式 c (s,T) と対応

する境界条件を含めるために容易に変更することができます。

を使用します。

この例題のコードは、 例題 8 - 理論的説明 を参照してください。

例題 1- 8 と PV-WAVE プロッティングのサンプルコード

例題 1 – 理論的説明

これは t = 0 近くで急激に変化する非線形問題です。積分パラメータのデフォ

ルト設定でこの問題が解かれます。imsl_f_pde_1d_mg を使用すると、微分方

程式と境界条件を記述するために、ユーザによって提供される 2 つのサブルー

チンが必要になります。

#include <stdio.h>#include <math.h>#include "imsl.h"

/* プロトタイプ */static void initial_conditions (int npdes, int ngrids, double u[]);static void pde_systems (double t, double x, int npdes, int ngrids,

double full_u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires);

static void boundary_conditions (double t, double beta[], double gamma[], double full_u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires);

#define MIN(X,Y) (X<Y)?X:Y#define NPDE 2#define NFRAMES 5#define N 51#define U(I_,J_) u[I_ * ngrids + J_]voidmain (){ char *state = NULL; int i, j; double u[(NPDE + 1) * N]; double t0 = 0.0, tout; double delta_t = 10.0, tend = 4.0; int npdes = NPDE, ngrids = N; double xl = 0.0, xr = 1.0; FILE *file1;

file1 = fopen ("pde_ex01.out", "w"); imsl_output_file (IMSL_SET_OUTPUT_FILE, file1, 0); fprintf (file1, " %d\t%d\t%d", npdes, ngrids, NFRAMES); fprintf (file1, "\t%f\t%f\t%f\t%f\n", xl, xr, t0, tend);

( ), , ; 0,c s T s s e s e= ≥ = <

( ) ( )2 2

2 2 2 02 2t ss s t s ss

c s c rsc rc c s c r sc rcσ σ σ+ + − ≡ + + − − =

σ

( ), 1,sc s t s≈ → ∞

2100, 0.08, 0.25, 0.04, 0 and 150L Re r T t s sσ= = − = = = =

Page 305: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* uの初期化 */ initial_conditions (npdes, ngrids, u);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_INITIALIZE, &state, 0); tout = 1e-3; do { imsl_d_pde_1d_mg (npdes, ngrids, &t0, tout, u, xl, xr, state,

pde_systems, boundary_conditions, 0);

fprintf (file1, "%f\n", tout); for (i = 0; i < npdes + 1; i++){ for (j = 0; j < ngrids; j++) { fprintf (file1, "%16.10f ", U (i, j)); if (((j + 1) % 4) == 0)

fprintf (file1, "\n"); } fprintf (file1, "\n");}

t0 = tout; tout = tout * delta_t; tout = MIN (tout, tend); } while (t0 < tend);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_RESET, &state, 0);

#undef MIN#undef NPDE#undef NFRAMES#undef N#undef U}

static voidinitial_conditions (int npdes, int ngrids, double u[]){#define U(I_,J_) u[I_ * ngrids + J_]

int i; for (i = 0; i < ngrids; i++) { U (0, i) = 1.0; U (1, i) = 0.0; }

#undef U}static voidpde_systems (double t, double x, int npdes, int ngrids, double full_u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires){#define C(I_,J_) c[I_ * npdes + J_] double z; static double eps = 0.143; static double eta = 17.19; static double pp = 0.1743;

Page 306: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

C (0, 0) = 1.0; C (0, 1) = 0.0; C (1, 0) = 0.0; C (1, 1) = 1.0; r[0] = pp * dudx[0] * eps; r[1] = pp * dudx[1]; z = eta * (grid_u[0] - grid_u[1]) / 3.0; q[0] = exp (z) - exp (-2.0 * z); q[1] = -q[0]; return;#undef C}

static voidboundary_conditions (double t, double beta[], double gamma[], double full_u[], double grid_u[], double dudx[], int ngrids, int npdes, int left, int *ires){ if (left) { beta[0] = 1.0; beta[1] = 0.0; gamma[0] = 0.0; gamma[1] = grid_u[1]; } else { beta[0] = 0.0; beta[1] = 1.0; gamma[0] = grid_u[0] - 1.0; gamma[1] = 0.0; } return;}

例題 2 - 理論的説明

これは、t = 0 の近傍で急激に条件が変化する非線形境界層問題です。この問題

文は境界条件が t = 0 の近傍で連続であるように修正されました。 この修正を行

わなければ、使用する積分ソフトウエア imsl_f_dea_petzold_gear はこの問

題を解くことが出来ません。連続混合関数 u - exp(-20t) は任意で、技巧的に選

ばれます。 これはこの問題への数学的な変更で t = 0 で規定された不連続のため

に必要になります。逆通信がこの問題データのために使用されます。 逆通信を

使用する時は,追加のユーザが書いたサブルーチンは一切必要ではありません。この近くでは解に急激な変化が予想される xL = 0 の近傍に集中する 10 の

初期格子点を選びました。オプションの変更が,真の絶対誤差許容値と非ゼロ時間平滑化を使用するために行われました。

#include <stdio.h>#include <math.h>#include "imsl.h"

/* prototypes */static void initial_conditions (int npdes, int ngrids, double u[]);

static void pde_systems (double t, double x, int npdes, int ngrids, double full_u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires);static void boundary_conditions (double t, double beta[], double gamma[], double full_u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires);

#define MIN(X,Y) (X<Y)?X:Y

Page 307: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#define NPDE 2#define N1 10#define N2 51#define N (N1+N2)#define U(I_,J_) u[I_ * ngrids + J_]FILE *file1;voidmain (){ char *state; int i, j; int nframes; double u[(NPDE + 1) * N]; double t0 = 0.0, tout; double delta_t = 1e-1, tend = 5.0; int npdes = NPDE, ngrids = N; double xl = 0.0, xr = 25.0; double tau = 1.0e-3; double atol = 1e-2; double rtol = 0.0;

file1 = fopen ("pde_ex02.out", "w"); imsl_output_file (IMSL_SET_OUTPUT_FILE, file1, 0); nframes = (int) ((tend + delta_t) / delta_t); fprintf (file1, " %d\t%d\t%d", npdes, ngrids, nframes); fprintf (file1, "\t%f\t%f\t%f\t%f\n", xl, xr, t0, tend);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_INITIALIZE, &state, IMSL_TIME_SMOOTHING, tau, IMSL_INITIAL_CONDITIONS, initial_conditions, 0);

t0 = 0.0; tout = delta_t; do { imsl_d_pde_1d_mg (npdes, ngrids, &t0, tout, u, xl, xr, state, pde_systems, boundary_conditions, IMSL_RELATIVE_TOLERANCE, rtol, IMSL_ABSOLUTE_TOLERANCE, atol, 0);

t0 = tout; fprintf (file1, "%f\n", tout); for (i = 0; i < npdes + 1; i++) { for (j = 0; j < ngrids; j++) { fprintf (file1, "%16.10f ", U (i, j)); if (((j + 1) % 4) == 0) fprintf (file1, "\n"); } fprintf (file1, "\n"); } tout = tout + delta_t; tout = MIN (tout, tend); } while (t0 < tend);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_RESET, &state, 0); fclose (file1);

#undef MIN#undef NPDE#undef NFRAMES#undef N#undef U}

Page 308: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

static voidinitial_conditions (int npdes, int ngrids, double u[]){#define U(I_,J_) u[I_* ngrids + J_]

int i, j, i_, n1 = 10, n2 = 51, n; double dx1, dx2; double xl = 0.0, xr = 25.0;

n = n1 + n2; for (i = 0; i < ngrids; i++) { U (0, i) = 1.0; U (1, i) = 0.0; U (2, i) = 0.0; }

dx1 = xr / n2; dx2 = dx1 / n1;

/* グリッド */ for (i = 1; i <= n1; i++) { i_ = i - 1; U (2, i_) = (i - 1) * dx2; } for (i = n1 + 1; i <= n; i++) { i_ = i - 1; U (2, i_) = (i - n1) * dx1; } for (i = 0; i < npdes + 1; i++) { for (j = 0; j < ngrids; j++) { fprintf (file1, "%16.10f ", U (i, j)); if (((j + 1) % 4) == 0) fprintf (file1, "\n"); } fprintf (file1, "\n"); }

#undef U}

static voidpde_systems (double t, double x, int npdes, int ngrids, double full_u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires){#define C(I_,J_) c[I_ * npdes + J_] double z;

C (0, 0) = 1.0; C (1, 0) = 0.0; C (0, 1) = grid_u[0]; C (1, 1) = 0.0;

r[0] = -grid_u[1]; r[1] = dudx[0]; q[0] = 0.0; q[1] = grid_u[1] * dudx[0]; return;#undef C

Page 309: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

}

static voidboundary_conditions (double t, double beta[], double gamma[], double full_u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires){ double dif;

beta[0] = 0.0; beta[1] = 0.0; if (left) { dif = exp (-20.0 * t); gamma[0] = grid_u[0] - dif; gamma[1] = grid_u[1]; } else { gamma[0] = grid_u[0] - 1.0; gamma[1] = dudx[1]; } return;}

例題 3 - 理論的説明

これは、微分方程式と境界条件のための非局所条件を含んだ非線形積分微分問題です。これらの条件の評価のための呼び出しはオプション引数 IMSL_PDE_SYS_W_DATA と IMSL_BOUNDARY_COND_W_DATA を使用して提供され

ます。オプションの変更は絶対誤差許容値と非ゼロ時間平滑化を使用して行わ

れます。時間平滑化値 はグリッド線が交差することを防ぎます。

#include <stdio.h>#include <math.h>#include "imsl.h"

/* プロトタイプ */

static void initial_conditions (int npdes, int ngrids, double u[]);static void pde_systems (double t, double x, int npdes, int ngrids, double full_u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires);static void boundary_conditions (double t, double beta[], double gamma[], double full_u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires);static double fcn_g (double z, double t);

#define MIN(X,Y) (X<Y)?X:Y#define NPDE 1#define N 101#define U(I_,J_) u[I_ * ngrids + J_]FILE *file1;voidmain (){ int i, j, nframes; double u[(NPDE + 1) * N], mid[N - 1]; int npdes = NPDE, ngrids = N; double t0 = 0.0, tout; double delta_t = 1e-1, tend = 5.0, a = 5.0; char *state;

1τ =

Page 310: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

double xl = 0.0, xr = 5.0; double *ptr_u; double tau = 1.0; double atol = 1e-2; double rtol = 0.0;

file1 = fopen ("pde_ex03.out", "w"); imsl_output_file (IMSL_SET_OUTPUT_FILE, file1, 0); nframes = (int) (tend + delta_t) / delta_t; fprintf (file1, " %d\t%d\t%d", npdes, ngrids, nframes); fprintf (file1, "\t%f\t%f\t%f\t%f\n", xl, xr, t0, tend);

ptr_u = u;

imsl_d_pde_1d_mg_mgr (IMSL_PDE_INITIALIZE, &state, IMSL_TIME_SMOOTHING, tau, IMSL_INITIAL_CONDITIONS, initial_conditions, 0);

tout = delta_t; fprintf (file1, "%f\n", t0); do { imsl_d_pde_1d_mg (npdes, ngrids, &t0, tout, u, xl, xr, state, pde_systems, boundary_conditions, IMSL_RELATIVE_TOLERANCE, rtol, IMSL_ABSOLUTE_TOLERANCE, atol, 0);

t0 = tout; if (t0 <= tend) { fprintf (file1, "%f\n", tout); for (i = 0; i < npdes + 1; i++) { for (j = 0; j < ngrids; j++) { fprintf (file1, "%16.10f ", U (i, j)); if (((j + 1) % 4) == 0) fprintf (file1, "\n"); } fprintf (file1, "\n"); } } tout = MIN (tout + delta_t, tend); } while (t0 < tend); imsl_d_pde_1d_mg_mgr (IMSL_PDE_RESET, &state, 0);

fclose (file1);

#undef MIN#undef NPDE#undef N#undef XL#undef XR#undef U}

static voidinitial_conditions (int npdes, int ngrids, double u[]){#define U(I_,J_) u[I_ * ngrids + J_]#define XL 0.0#define XR 5.0

Page 311: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int i, j; double dx, xi;

dx = (XR - XL) / (ngrids - 1); for (i = 0; i < ngrids; i++) { U (0, i) = exp (-U (1, i)) / (2.0 - exp (-XR)); }

for (i = 0; i < npdes + 1; i++) { for (j = 0; j < ngrids; j++) { fprintf (file1, "%16.10f ", U (i, j)); if (((j + 1) % 4) == 0) fprintf (file1, "\n"); } fprintf (file1, "\n"); }

#undef U#undef XL#undef XR}

static voidpde_systems (double t, double x, int npdes, int ngrids, double full_u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires){#define U(I_,J_) full_u[I_ * ngrids + J_]

double v1; double sum = 0.0; int i;

c[0] = 1.0; r[0] = -1 * grid_u[0];

for (i = 0; i < ngrids - 1; i++) { sum += (U (0, i) + U (0, i + 1)) * (U (1, i + 1) - U (1, i)); }

v1 = 0.5 * sum; q[0] = v1 * grid_u[0];

return;#undef U}

static voidboundary_conditions (double t, double beta[], double gamma[], double full_u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires){#define U(I_,J_) full_u[I_ * ngrids + J_] double v1, v2, mid; double sum = 0.0; double sum1 = 0.0, sum2 = 0.0, sum3 = 0.0, sum4 = 0.0; int i;

for (i = 0; i < ngrids - 1; i++) { sum += (U (0, i) + U (0, i + 1)) * (U (1, i + 1) - U (1, i));

Page 312: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

mid = 0.5 * (U (1, i) + U (1, i + 1)); sum1 += mid * exp (-mid) * ((U (0, i) + U (0, i + 1)) * (U (1, i + 1) - U (1, i))); }

if (left) { v1 = 0.5 * sum; v2 = 0.5 * sum1; beta[0] = 0.0; gamma[0] = fcn_g (1.0, t) * v1 * v2 / ((v1 + 1.0) * (v1 + 1.0)) - grid_u[0]; } else { beta[0] = 0.0; gamma[0] = dudx[0]; } return;#undef U}

static doublefcn_g (double z, double t){ double g, a = 5.0;

g = 4.0 * z * (2.0 - 2.0 * exp (-a) + exp (-t)) * (2.0 - 2.0 * exp (-a) + exp (-t)); g = g / ((1.0 - exp (-a)) * (1.0 - (1.0 + 2.0 * a) * exp (-2.0 * a)) * (1.0 - exp (-a) + exp (-t))); return g;}

例題 4 - 理論的説明

これは円筒座標の非線形問題です。この問題は方程式2に m = 1 を割り当てる

方法を説明します。デフォルト値 m = 0 から値をリセットするためのオプショ

ン引数 IMSL_CYL_COORDINATESが提供されています。

#include <stdio.h>#include <math.h>#include "imsl.h"

/* プロトタイプ */static void initial_conditions (int npdes, int ngrids, double t[]);static void pde_systems (double t, double x, int npdes, int ngrids, double u[], double grid_u[], double dudx[], double *c,

double q[], double r[], int *ires);static void boundary_conditions (double t, double beta[],

double gamma[], double u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires);

#define MIN(X,Y) (X<Y)?X:Y#define NPDE 1#define N 41#define T(I_,J_) t[I_ * ngrids + J_]voidmain (){ int i, j, ido; int nframes; double t[(NPDE + 1) * N]; double z0 = 0.0, zout; double dx1, dx2, diff; double delta_z = 1e-1, zend = 1.0, zmax = 1.0;

Page 313: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

double beta = 1e-4, gamma = 1.0, eps = 1e-1; char *state; int npdes = NPDE, ngrids = N; double xl = 0.0, xr = 1.0; FILE *file1; int m = 1;

file1 = fopen ("pde_ex04.out", "w"); imsl_output_file (IMSL_SET_OUTPUT_FILE, file1, 0); nframes = (int) ((zend + delta_z) / delta_z) - 1; fprintf (file1, " %d\t%d\t%d", npdes, N, nframes); fprintf (file1, "\t%f\t%f\t%f\t%f\n", xl, xr, z0, zend);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_INITIALIZE, &state, IMSL_CYL_COORDINATES, 0); initial_conditions (npdes, ngrids, t);

zout = delta_z; do { imsl_d_pde_1d_mg (npdes, ngrids, &z0, zout, t, xl,

xr, state, pde_systems, boundary_conditions, 0);

z0 = zout; if (z0 <= zend){ fprintf (file1, "%f\n", zout); for (i = 0; i < npdes + 1; i++) { for (j = 0; j < ngrids; j++)

{ fprintf (file1, "%16.10f ", T (i, j)); if (((j + 1) % 4) == 0) fprintf (file1, "\n");}

fprintf (file1, "\n"); }

} zout = MIN ((zout + delta_z), zend); } while (z0 < zend);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_RESET, &state, 0); fclose (file1);#undef MIN#undef NPDE#undef N#undef T}

static voidinitial_conditions (int npdes, int ngrids, double t[]){#define T(I_,J_) t[I_ * ngrids + J_] int i;

for (i = 0; i < ngrids; i++) { T (0, i) = 0.0; }#undef T}

static void

Page 314: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

pde_systems (double t, double x, int npdes, int ngrids, double u[],double grid_u[], double dudx[], double *c,double q[], double r[], int *ires){#define C(I_,J_) c[I_ * npdes + J_] static double beta = 01e-4, gamma = 1.0, eps = 1e-1;

C (0, 0) = 1.0;

r[0] = beta * dudx[0]; q[0] = -1.0 * gamma * exp (grid_u[0] / (1.0 + eps * grid_u[0])); return;#undef C}

static voidboundary_conditions (double t, double beta[], double gamma[], double u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires){

if (left) { beta[0] = 1.0; gamma[0] = 0.0; } else { beta[0] = 0.0; gamma[0] = grid_u[0]; } return;}

例題 5 - 理論的説明

これは非線形問題です。この例題は、ユーザの選択でソフトウエアの中の帯行列ソルバーを置き換えるためのモデルステップを示します。imsl_lin_sol_gen_band (第 1 章:線形連立方程式を参照)の行列分解の計

算に従うと、条件数の逆数が作業中の精度よりも小さい時は、このシステムは特異であると宣言します。この選択は全ての問題に対して適切というわけではありません。このオプションが使用されるときは特異性を検出するために注意を払わなければなりません。

#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <math.h>#include "imsl.h"

/* プロトタイプ */static void initial_conditions (int npdes, int ngrids, double u[]);static void pde_systems (double t, double x, int npdes, int ngrids, double u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires);static void boundary_conditions (double t, double beta[], double gamma[], double u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires);static int fac (int neq, int iband, double *a);static void sol (int neq, int iband, double *g, double *y);static double fcn (double z);

int *ipvt = NULL;double *factor = NULL;

Page 315: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#define MIN(X,Y) (X<Y)?X:Y#define NPDE 2#define N 40#define NEQ ((NPDE+1)*N)#define U(I_,J_) u[I_ * ngrids + J_]voidmain (){ int i, j, nframes; double u[(NPDE + 1) * N]; double t0 = 0.0, tout; double delta_t = 1e-4, tend = 6e-3; char *state; int npdes = NPDE, ngrids = N; double xl = 0.0, xr = 1.0; FILE *file1; double work[NEQ], rcond; double xmax = 1.0, beta = 4.0, gamma = 3.52e6; int max_bdf_order = 5;

file1 = fopen ("pde_ex05.out", "w"); imsl_output_file (IMSL_SET_OUTPUT_FILE, file1, 0); nframes = (int) ((tend + delta_t) / delta_t) - 1; fprintf (file1, " %d\t%d\t%d", npdes, ngrids, nframes); fprintf (file1, "\t%f\t%f\t%f\t%f\n", xl, xr, t0, tend);

initial_conditions (npdes, ngrids, u); imsl_d_pde_1d_mg_mgr (IMSL_PDE_INITIALIZE, &state, IMSL_MAX_BDF_ORDER, max_bdf_order, IMSL_USER_FACTOR_SOLVE, fac, sol, 0); tout = delta_t; do { imsl_d_pde_1d_mg (npdes, ngrids, &t0, tout, u, xl, xr, state, pde_systems, boundary_conditions, 0); t0 = tout; if (t0 <= tend) { fprintf (file1, "%f\n", tout); for (i = 0; i < npdes + 1; i++) { for (j = 0; j < ngrids; j++) { fprintf (file1, "%16.10f ", U (i, j)); if (((j + 1) % 4) == 0) fprintf (file1, "\n"); } }

} tout = MIN ((tout + delta_t), tend);

} while (t0 < tend);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_RESET, &state, 0);

fclose (file1);

if (factor != NULL) { free (factor); } if (ipvt != NULL) { free (ipvt);

Page 316: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

}}#undef MIN#undef U

static voidinitial_conditions (int npdes, int ngrids, double u[]){#define U(I_,J_) u[I_ * ngrids + J_]

int i;

for (i = 0; i < ngrids; i++) { U (0, i) = 1.0; U (1, i) = 2e-1; }

#undef U}static voidpde_systems (double t, double x, int npdes, int ngrids, double u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires){#define C(I_,J_) c[I_ * npdes + J_]

C (0, 0) = 1.0; C (0, 1) = 0.0; C (1, 0) = 0.0; C (1, 1) = 1.0; r[0] = dudx[0]; r[1] = dudx[1];

q[0] = grid_u[0] * fcn (grid_u[1]); q[1] = -1.0 * q[0]; return;#undef C}

static voidboundary_conditions (double t, double beta[], double gamma[], double u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires){ if (left) { beta[0] = 0.0; beta[1] = 0.0; gamma[0] = dudx[0]; gamma[1] = dudx[1]; } else { beta[0] = 1.0; gamma[0] = 0.0; beta[1] = 0.0; if (t >= 2e-4) { gamma[1] = 12e-1; } else { gamma[1] = 2e-1 + 5e3 * t; } gamma[1] -= grid_u[1];

Page 317: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

} return;}

/* 帯行列を因子分解。これは、内部的に使用されているソルバーと

* 同じだが、必要ではない。ユーザは、自身のもので代用可能。

* 注意:lin_sol_gen_bandが ipvt と factor変数を割り当ててから、

* sol関数内で使用する。 */static intfac (int neq, int iband, double *a){ double rcond, panic_flag; int i, j; double b[NEQ];

/* factor と pivot 列が割り当てられている場合、それらを解放 */ if (factor != NULL) { free (factor); factor = NULL; } if (ipvt != NULL) { free (ipvt); ipvt = NULL; }

imsl_d_lin_sol_gen_band (neq, a, iband, iband, b, IMSL_FACTOR, &ipvt, &factor, IMSL_FACTOR_ONLY, IMSL_CONDITION, &rcond, 0);

panic_flag = 0; if (1.0 / rcond <= imsl_d_machine (4)) panic_flag = 3; return panic_flag;}

static voidsol (int neq, int iband, double *g, double *y){ imsl_d_lin_sol_gen_band (neq, (double *) NULL, iband, iband, g, IMSL_SOLVE_ONLY, IMSL_FACTOR_USER, ipvt, factor, IMSL_RETURN_USER, y, 0); return;}

static doublefcn (double z){ double beta = 4.0, gamma = 3.52e6;

return gamma * exp (-1.0 * beta / z);}

例題 6 - 理論的説明

これは非線形問題です。この出力は、前面,又はホットスポットの急激な変化が、積分のあらゆる方法の後で展開されます。これはグリッドに対して急激な変化を生じます。あるオプションは 最大次数 BDF 公式をデフォルト値の 2 か

ら理論的に安定した最大値 5 にセットします。

#include <stdio.h>#include <math.h>#include "imsl.h"

Page 318: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* プロトタイプ */

static void initial_conditions (int npdes, int ngrids, double u[]);static void pde_systems (double t, double x, int npdes, int ngrids, double full_u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires);static void boundary_conditions (double t, double beta[], double gamma[], double full_u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires);static double fcn_h (double z);

#define MIN(X,Y) (X<Y)?X:Y#define NPDE 1#define N 80#define U(I_,J_) u[I_ * ngrids + J_]voidmain (){ int i, j, nframes; double u[(NPDE + 1) * N]; double t0 = 0.0, tout; double delta_t = 1e-2, tend = 29e-2; double u0 = 1.0, u1 = 0.0, tdelta = 1e-1, tol = 29e-2; double a = 1.0, delta = 20.0, r = 5.0; char *state; int npdes = NPDE, ngrids = N; double xl = 0.0, xr = 1.0; FILE *file1; int max_bdf_order = 5;

file1 = fopen ("pde_ex06.out", "w"); imsl_output_file (IMSL_SET_OUTPUT_FILE, file1, 0); nframes = (int) ((tend + delta_t) / delta_t) - 1; fprintf (file1, " %d\t%d\t%d", npdes, ngrids, nframes); fprintf (file1, "\t%f\t%f\t%f\t%f\n", xl, xr, t0, tend);

initial_conditions (npdes, ngrids, u);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_INITIALIZE, &state, IMSL_MAX_BDF_ORDER, max_bdf_order, 0); tout = delta_t; do { imsl_d_pde_1d_mg (npdes, ngrids, &t0, tout, u, xl, xr, state, pde_systems, boundary_conditions, 0);

t0 = tout; if (t0 <= tend) { fprintf (file1, "%f\n", tout); for (i = 0; i < npdes + 1; i++) { for (j = 0; j < ngrids; j++) { fprintf (file1, "%16.10f ", U (i, j)); if (((j + 1) % 4) == 0) fprintf (file1, "\n"); } }

} tout = MIN ((tout + delta_t), tend); }

Page 319: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

while (t0 < tend);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_RESET, &state, 0); fclose (file1);#undef MIN#undef NPDE#undef N#undef U}

static voidinitial_conditions (int npdes, int ngrids, double u[]){#define U(I_,J_) u[I_ * ngrids + J_] int i;

for (i = 0; i < ngrids; i++) { U (0, i) = 1.0; }#undef U}

static voidpde_systems (double t, double x, int npdes, int ngrids, double full_u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires){#define C(I_,J_) c[I_ * npdes + J_]

c[0] = 1.0; r[0] = dudx[0]; q[0] = -fcn_h (grid_u[0]);

return;#undef C}

static voidboundary_conditions (double t, double beta[], double gamma[], double full_u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires){ if (left) { beta[0] = 0.0; gamma[0] = dudx[0]; } else { beta[0] = 0.0; gamma[0] = grid_u[0] - 1.0; } return;}static doublefcn_h (double z){ double a = 1.0, delta = 2e1, r = 5.0;

return (r / (a * delta)) * (1.0 + a - z) * exp (-delta * (1.0 / z - 1.0));}

例題 7 - 理論的説明

これは 1 次方程式の非線形システムです。

Page 320: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#include <stdio.h>#include <math.h>#include "imsl.h"

/* プロトタイプ */static void initial_conditions (int npdes, int ngrids, double u[]);static void pde_systems (double t, double x, int npdes, int ngrids, double full_u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires);static void boundary_conditions (double t, double beta[], double gamma[], double full_u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires);

#define MIN(X,Y) (X<Y)?X:Y#define NPDE 2#define N 50#define XL (-0.5)#define XR 0.5#define U(I_,J_) u[I_ * ngrids + J_]FILE *file1;voidmain (){ int i, j, nframes; double u[(NPDE + 1) * N]; double t0 = 0.0, tout; double delta_t = 5e-2, tend = 5e-1; char *state; int npdes = NPDE, ngrids = N; double xl = XL, xr = XR; double tau = 1e-3; double atol = 1e-3; double rtol = 0.0; int max_bdf_order = 3;

file1 = fopen ("pde_ex07.out", "w"); imsl_output_file (IMSL_SET_OUTPUT_FILE, file1, 0); nframes = (int) ((tend + delta_t) / delta_t); fprintf (file1, " %d\t%d\t%d", npdes, ngrids, nframes); fprintf (file1, "\t%f\t%f\t%f\t%f\n", xl, xr, t0, tend);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_INITIALIZE, &state, IMSL_TIME_SMOOTHING, tau, IMSL_MAX_BDF_ORDER, max_bdf_order, IMSL_INITIAL_CONDITIONS, initial_conditions, 0); fprintf (file1, "%f\n", t0); tout = delta_t; do { imsl_d_pde_1d_mg (npdes, ngrids, &t0, tout, u, xl, xr, state, pde_systems, boundary_conditions, IMSL_RELATIVE_TOLERANCE, rtol, IMSL_ABSOLUTE_TOLERANCE, atol, 0);

t0 = tout; if (t0 <= tend) { fprintf (file1, "%f\n", tout); for (i = 0; i < npdes + 1; i++) { for (j = 0; j < ngrids; j++) { fprintf (file1, "%16.10f ", U (i, j));

Page 321: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

if (((j + 1) % 4) == 0) fprintf (file1, "\n"); } fprintf (file1, "\n"); }

} tout = MIN ((tout + delta_t), tend); } while (t0 < tend);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_RESET, &state, 0);

fclose (file1);#undef MIN#undef NPDE#undef N#undef XL#undef XR#undef U}

static voidinitial_conditions (int npdes, int ngrids, double u[]){#define U(I_,J_) u[I_ * ngrids + J_]#define XL -0.5#define XR 0.5

int i, j; double _pi, pulse; double dx, xi;

_pi = imsl_d_constant("pi",0); for (i = 0; i < ngrids; i++) { pulse = (0.5 * (1.0 + cos (10.0 * _pi * U (npdes, i)))); U (0, i) = pulse; U (1, i) = pulse; } for (i = 0; i < ngrids; i++) { if ((U (npdes, i) < -3e-1) || (U (npdes, i) > -1e-1)) { U (0, i) = 0.0; } if ((U (npdes, i) < 1e-1 || U (npdes, i) > 3e-1)) { U (1, i) = 0.0; }

} for (i = 0; i < npdes + 1; i++) { for (j = 0; j < ngrids; j++) { fprintf (file1, "%16.10f ", U (i, j)); if (((j + 1) % 4) == 0) fprintf (file1, "\n"); } fprintf (file1, "\n"); }

Page 322: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#undef XL#undef XR#undef U}

static voidpde_systems (double t, double x, int npdes, int ngrids, double full_u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires){#define C(I_,J_) c[I_ * npdes + J_]

C (0, 0) = 1.0; C (0, 1) = 0.0; C (1, 0) = 0.0; C (1, 1) = 1.0;

r[0] = -1.0 * grid_u[0]; r[1] = grid_u[1]; q[0] = 100.0 * grid_u[0] * grid_u[1]; q[1] = q[0]; return;#undef C}

static voidboundary_conditions (double t, double beta[], double gamma[], double full_u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires){

beta[0] = 0.0; beta[1] = 0.0; gamma[0] = grid_u[0]; gamma[1] = grid_u[1];

return;}

例題 8 - 理論的説明

これは線形問題ですが初期条件が不連続です。グリッド線が交差しないようにするために正の時間平滑な値を使用することが必要になります。絶対許容値

10-3 を使用しました。 米国ドルではこれは,10 の 1 セントです。

#include <stdio.h>#include "imsl.h"

/* プロトタイプ */static void initial_conditions (int npdes, int ngrids, double u[]);static void pde_systems (double t, double x, int npdes, int ngrids,

double full_u[], double grid_u[], double dudx[], double *c, double q[], double r[], int *ires);

static void boundary_conditions (double t, double beta[], double gamma[], double full_u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires);

#define MIN(X,Y) (X<Y)?X:Y#define NPDE 1#define N 100#define XL 0.0#define XR 150.0#define U(I_,J_) u[I_ * ngrids + J_]voidmain (){

Page 323: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int i, j, nframes; double u[(NPDE + 1) * N]; double t0 = 0.0, tout, xval; double delta_t = 25e-3, tend = 25e-2; double xmax = 150.0; char *state; int npdes = NPDE, ngrids = N; double xl = XL, xr = XR; FILE *file1; double tau = 5e-3; double atol = 1e-2; double rtol = 0.0; int max_bdf_order = 5;

file1 = fopen ("pde_ex08.out", "w"); imsl_output_file (IMSL_SET_OUTPUT_FILE, file1, 0); nframes = (int) ((tend + delta_t) / delta_t); fprintf (file1, " %d\t%d\t%d", npdes, ngrids, nframes); fprintf (file1, "\t%f\t%f\t%f\t%f\n", xl, xr, t0, tend);

initial_conditions (npdes, ngrids, u);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_INITIALIZE, &state,IMSL_TIME_SMOOTHING, tau,IMSL_MAX_BDF_ORDER, max_bdf_order, 0);

tout = delta_t; do { imsl_d_pde_1d_mg (npdes, ngrids, &t0, tout, u, xl,

xr, state, pde_systems, boundary_conditions,IMSL_RELATIVE_TOLERANCE, rtol,IMSL_ABSOLUTE_TOLERANCE, atol, 0);

t0 = tout; if (t0 <= tend){ fprintf (file1, "%f\n", tout); for (i = 0; i < npdes + 1; i++) { for (j = 0; j < ngrids; j++)

{ fprintf (file1, "%16.10f ", U (i, j)); if (((j + 1) % 4) == 0) fprintf (file1, "\n");}

}

} tout = MIN ((tout + delta_t), tend); } while (t0 < tend);

imsl_d_pde_1d_mg_mgr (IMSL_PDE_RESET, &state, 0);

fclose (file1);

#undef MIN#undef NPDE#undef N#undef XL#undef XR#undef U}

static voidinitial_conditions (int npdes, int ngrids, double u[]){

Page 324: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#define U(I_,J_) u[I_ * ngrids + J_]#define XL 0.0#define XR 150.0

int i; double dx, xi, xval, e = 100.0;

dx = (XR - XL) / (ngrids - 1); for (i = 0; i < ngrids; i++) { xi = XL + i * dx; if (xi <= e){ U (0, i) = 0.0;} else{ U (0, i) = xi;} }#undef U#undef XL#undef XR}static voidpde_systems (double t, double x, int npdes, int ngrids, double full_u[], double grid_u[], double dudx[], double *c,double q[], double r[], int *ires){ double sigsq, sigma = 2e-1, rr = 8e-2; sigsq = sigma * sigma;

c[0] = 1.0; r[0] = dudx[0] * x * x * sigsq * 0.5; q[0] = -(rr - sigsq) * x * dudx[0] + rr * grid_u[0];

return;}static voidboundary_conditions (double t, double beta[], double gamma[], double full_u[], double grid_u[], double dudx[], int npdes, int ngrids, int left, int *ires){ if (left) { beta[0] = 0.0; gamma[0] = grid_u[0]; } else { beta[0] = 0.0; gamma[0] = dudx[0] - 1.0; } return;}

PV-WAVE プロッティングのコード

PRO PDE_1d_mg_plot, FILENAME = filename, PAUSE = pause; if keyword_set(FILENAME) then file = filename else file = "res.dat" if keyword_set(PAUSE) then twait = pause else twait = .1;; データファイルの最初の列から読み込むための

; 浮動小数点の変数を定義 xl = 0D0 xr = 0D0 t0 = 0D0

Page 325: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

tlast = 0D0;; データファイルを開き、パラメータ内に読み込む

openr, lun, filename, /get_lun readf, lun, npde, np, nt, xl, xr, t0, tlast

; 解とグリッドの配列を定義 u = dblarr(nt, npde, np) g = dblarr(nt, np) times = dblarr(nt);; データを読み込むための一時的な配列を定義

tmp = dblarr(np) t_tmp = 0D0;; データの読み込み

for i = 0, nt-1 do begin ; 時間ごとにステップ

readf, lun, t_tmp times(i) = t_tmp

for k = 0, npde-1 do begin ; 各 PDEごと rmf, lun, tmp u(i,k,*) = tmp ; 要素の読み込み

end

rmf, lun, tmp g(i,*) = tmp ; グリッド内に読み込み end;; データファイルを閉じ、ユニットを解放 close, lun free_lun, lun; ; 解とグリッドの全てがあります

;; 現在開いているウインドウを削除 while (!d.window NE -1) do WDELETE;; 解とグリッドをプロットするための 2つのウインドウを開く; window, 0, xsize = 550, ysize = 420 window, 1, xsize = 550, ysize = 420;; グリッドをプロット wset, 0 plot, [xl, xr], [t0, tlast], /nodata, ystyle = 1, $ title = "Grid Points", xtitle = "X", ytitle = "Time" for i = 0, np-1 do begin oplot, g(*, i), times, psym = -1 end;; 解をプロット wset, 1 for k = 0, npde-1 do begin umin = min(u(*,k,*)) umax = max(u(*,k,*)) for i = 0, nt-1 do begin title = strcompress("U_"+string(k+1), /remove_all)+ $ " at time "+string(times(i)) plot, g(i, *), u(i,k,*), ystyle = 1, $ title = title, xtitle = "X", $ ytitle = strcompress("U_"+string(k+1), /remove_all), $ xr = [xl, xr], yr = [umin, umax], $ psym = -4 wait, twait end end

Page 326: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

end

pde_method_of_lines直線法を使用して、形式 ut = f(x, t, u, ux, uxx) の偏微分連立方程式を解きます。

この解は 3 次エルミート多項式で表されます。

概要

#include <imsl.h>

void imsl_f_pde_method_of_lines_mgr (int task, void **state, ..., 0)

void imsl_f_pde_method_of_lines (int npdes, float *t, float tend, int nx, float xbreak[], float y[], void *state, void fcn_ut(), void fcn_bc())

double 型関数は、 imsl_d_pde_method_of_lines_mgr と imsl_d_pde_method_of_linesです。

imsl_f_pde_method_of_lines_mgrに必要な引数

int task ( 入力 )この関数は、問題を解く前にメモリやデフォルト値の設定をするIMSL_PDE_INITIALIZEが設定された taskと、問題が解かれた後に削除

するために IMSL_PDE_RESETが設定された taskを呼び出す必要があ

ります。taskの値は、include ファイル imsl.h で定義されます。

void **state ( 入力 / 出力 )PDE 解の現在の状態は state によって指される構造体に保持されま

す。これを直接操作する事はできません。

imsl_f_pde_method_of_linesに必要な引数

int npdes ( 入力 )微分方程式の数。

float *t ( 入力 / 出力 )独立変数。 入力では、 t は初期時間 t0 を提供します。出力において、 t には積分が更新される値が設定されます。通常、この新しい値は、 tendです。

float tend ( 入力 )解が望まれる t = tend の値。

int nx ( 入力 )メッシュ点、又は、直線の数。

float xbreak[] ( 入力 )x 区分化に使用される 3 次エルミート・スプラインの区分点を含む長さ nx の配列。xbreak の中の点は厳密に増加しなければなりません。

Xbreak[0] と xbreak[nx – 1] はこの区間の端点です。

float y[] ( 入力 / 出力 )解を含むサイズ npdes × nx の配列。配列 y は x = xbreak[i] にお

いてその解 y[k,i] = uk(x, tend) を含みます。 入力では y は初期値を含

みます。これは境界条件を満足しなければいけません。出力では、y は計算された解を含みます。

void *state ( 入力 / 出力 )偏微分方程式(PDE)解の現在の状態は、state によって指される構

造体に保持されます。これは imsl_f_pde_method_of_lines_mgr の呼び出しによって初期化されなければなりません。これは直接操作することは出来ません。

Page 327: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

void fcn_ut(int npdes, float x, float t, float u[], float ux[], float uxx[], float ut[])ut を計算するユーザ提供の関数

int npdes ( 入力 )方程式の数。

float x ( 入力 )空間変数 x 。

float t ( 入力 )時間変数 t 。

float u[] ( 入力 )従属値 u を含む長さ npdes の配列。

float ux[] ( 入力 )一次導関数 ux を含む長さ npdes の配列。

float uxx[] ( 入力 )二次導関数 uxx を含む長さ npdes の配列。

float ut[] ( 出力 )計算された導関数 ut を含む長さ npdes の配列。

void fcn_bc(int npdes, float x, float t, float alpha[], float beta[], float gammap[])境界条件を計算するユーザ提供の関数。 imsl_f_pde_method_of_lines によって受け入れられる境界条件は、

以下の式で表されます。

注意: ユーザは値 γk を決定する値 αk と βk を提供する必要がありま

す。 γk は t に依存するので、 γk′ の値も必要になります。

int npdes ( 入力 )方程式の数。

float x ( 入力 )空間変数 x 。

float t ( 入力 )時間変数 t 。

float alpha[] ( 出力 )αk 値を含む長さ npdes の配列。

float beta[] ( 出力 )βk 値を含む長さ npdes の配列。

float gammap[] ( 出力 )次の微係数 を含む長さ npdes の配列。

オプション引数の概要

#include <imsl.h>

void imsl_f_pde_method_of_lines_mgr (int task, void **state,IMSL_TOL, float tol,IMSL_HINIT, float hinit,

kk k k k

uu

∂β γ

∂+ =

kk

ddtγ

γ ′=

Page 328: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_INITIAL_VALUE_DERIVATIVE, float initial_deriv[],IMSL_HTRIAL, float *htrial,IMSL_FCN_UT_W_DATA, void fcn_ut (), void *data,IMSL_FCN_BC_W_DATA, void fcn_bc (), void *data, 0)

オプション引数

IMSL_TOL, float tol ( 入力 )微分方程式誤差の許容値。意図は全体誤差が tol に比例するように局

所誤差のノルムを制御することにあります。

デフォルト: tol = 100.0*imsl_f_machine(4)

IMSL_HINIT, float hinit ( 入力 )t 積分の初期ステップ幅。この値は非負でなければなりません。

hinit がゼロであれば、初期ステップ幅 0.001|tend – t0| が任意に

使用されます。このステップは積分の方向に適用されます。

デフォルト: hinit = 0.0

IMSL_INITIAL_VALUE_DERIVATIVE, float initial_deriv[] ( 入力 / 出力 )微係数値 ux(x, t0) を供給します。この微係数情報は次式のように入力

します。

配列 initial_deriv contains は出力として、次の微係数値を含みます。

デフォルト: 微係数は三次スプライン補間を使用して計算されます。

IMSL_HTRIAL, float *htrial ( 出力 )現在の試行ステップサイズを返します。

IMSL_UT_FCN_W_DATA, void fcn_ut(int npdes, float x, float t, float u[], float ux[], float uxx[], float ut[], void *data), void *data ( 入力 )ut の計算するユーザ提供の関数。ユーザにより提供されるデータへの

ポインターを受け取ります。data は、ユーザ提供関数に渡されるデー

タへのポインターです。詳細は、本マニュアルの初めにある「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_BC_FCN_W_DATA, void fcn_bc(int npdes, float x, float t, float alpha[], float beta[], float gammap[], void *data), void *data ( 入力 )境界条件の計算するユーザ提供の関数。ユーザにより提供されるデータへのポインターを受け取ります。data は、ユーザ提供関数に渡され

るデータへのポインターです。詳細は、本マニュアルの初めにある「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

M = npdes、 N = nx、 xi = xbreaK(I) とします。ルーチン

imsl_f_pde_method_of_lines は偏微分連立方程式を解くために直線法を使

用します。

( ) ( )( ), 0k x tux

∂∂

=initial_deriv k,i

( ) ( ) [ ]atk xu x x ix

∂∂

= =tendinitial_deriv k,i

Page 329: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

k = 1, …, M の場合の初期条件

uk = uk(x, t) at t = t0

境界条件

3 次エルミート多項式は試行解が次の数列に展開されるように x 変数近似に使

用されます。

ここで Φi(x) と Ψi(x) はノット x1 < x2 < … < xN を持つ 3 次エルミート多

項式の標準基底関数で、これらは連続 1 次微係数を持つ区分的 3 次多項式で

す。区分点でこれらは、次の件条件を満足します。

選点法に従って、この近似の係数は、試行解が j = 1, ..., N の場合の次の各小区

間の 2 つのガウス点で微分方程式を満足するように得られます。

この微分方程式も選点近似は、k = 1, …, M で j = 1, …, 2(N − 1) の場合、以下の

ようになります。

これは 2M N 未知係数関数 ai,k と bi,k の 2M(N − 1) 常微分連立方程式です。この

連立方程式は c(t0) = c0 である A dc/dt = F (t, y) のような行列-ベクトル形式で

書かれて、この c は長さ 2M N の係数のベクトルで、c0 はこの係数の初期値を

保持します。最後の 2M の方程式は、k = 1, ..., M の場合、次のように境界条件

を微分して得られます。

2 21 1

1 2 2, , , ... , , ... , , ...k M M

k M

u u u u uf x t u u

t x x x x∂ ∂ ∂ ∂ ∂∂ ∂ ∂ ∂ ∂

=

α β∂∂

γk k kk

k Nuux

x x x x+ = = =at and at 1

( ) ( ) ( ) ( ) ( )( ), ,1

ˆ ,k i k i i k ii

N

u x t a t x b t xφ ψ=

= +∑

illili

liilli

dxxd

dxxd

xx

δ

δ

=Ψ=Φ)(

0)(

0)()(

)(6

33

)(6

33

12

112

jjjj

jjjj

xxxp

xxxp

+−

+=

−−

+=

+

+−

( ) ( )( ) ( ) ( ) ( ) ( ) ( )( )

, ,

1 1ˆ ˆ ˆ ˆ, , , , , , , ,

i k i ki j i j

k j j M j j M jxx xx

da dbp p

dt dtf p t u p u p u p u p

φ ψ+ =

K K K

α βγ

kk

kk kda

dtdbdt

ddt

+ =

Page 330: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

初期条件 uk(x, t0) は境界条件を満足しなくてはなりません。又 γk(t) は連続で

あり、平滑な微係数を持たなければならない、もしくは、境界条件は t > t0 で不適切になります。

αk = βk = 0 の場合、境界条件は左端点の k 番目の未知は望まないと想定されま

す。同様の注意が右端点に対して当てはまります。こうして選点は端点で実行されます。これは、一般的に 1 次偏微分連立方程式の有用な特徴です。

偏微分方程式の数が M = 1 で、分割点の数が N = 4 の場合、であれば、次の様

に表されます。

ベクトル c は、

c = [a1, b1, a2, b2, a3, b3, a4, b3]Tで、

右辺 F は、次の様に表されます。

M > 1 であれば、上の行列の各入力値は M × M 対角行列によって置き換えら

れます。要素 α1 は diag( α1,1,…, α 1,M) によって置き換えられます。要素

αΝ 、β1 と βN は同じ方法で操作されます。φi(pj) と ψi(pj) 要素は φi(pj)IM と

ψi(pj)IM によって置き換えられ、IM は階数 M の単位行列になります。打ち切

り誤差とヤコブ行列構造についての詳細は Madsen と Sincovec (1979 年 ) を参

照してください。

入力 / 出力 配列 Y は ak,i の値を含みます。bk,i の初期値は、 である

ような関数 を構成するために IMSL 3 次スプラインルーチン

imsl_f_cub_spline_interp_e_cnd ( 第 3 章: 補間と近似 ) を使用して得られま

す。

IMSL ルーチン imsl_f_cub_spline_value(第 3 章: 補間と近似) は、次の値

を近似するために使用されます。

bk,iの初期値をユーザが提供することが出来る imsl_f_pde_method_of_lines

のオプションの使用法が存在します。

行列 A の階数は 2M N でその最大バンド幅は 6M - 1 です。c に関する F のヤコ

ブ行列のバンド構造は A のバンド構造と同じです。この連立方程式は、

=

44

66666565

56565555

44444343

34343333

22222121

12121111

11

)()()()()()()()(

)()()()()()()()(

)()()()()()()()(

βαψφψφψφψφ

ψφψφψφψφ

ψφψφψψφ

βα

pppppppp

pppppppp

ppppppφpp

A

[ ]TxpfpfpfpfpfpfxF )('),(),(),(),(),(),(),(' 46543211 γγ=

kiik atxu =),(ˆ 0

),(ˆ 0txuk

ikik b

dxtxud

,0 ),(ˆ

Page 331: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

imsl_f_ode_adams_gear の修正版を使用して解かれます。線形ソルバーの幾つ

かが削除されています。数値ヤコブ行列が広範囲に使用されています。このアルゴリズムは変更されていません。Gear の BDF 法はこの方程式が通常硬いのでデ

フォルトとして使用されています。

ここでは、PDE に関する 4 つの例題が提供されており、ユーザが IMSL PDEソルバーを使って、どのように問題が解けるかを示しています。この例題は小規模で、多くのユーザが直面するような複雑性は示していません。7つの標本アプリケーション問題のセットが Sincovec と Madsen (1975 年 ) にあります。

その例題のいくつかは 1 つ以上の方程式を使用しています。更に 2 つ例題が Madsen と Sincovec (1979 年 ) にあります。

例題

例題 1

正規化された線形拡散 PDE ut = uxx、 0 ≤ x ≤ 1、 t > t0 を解きます。その初期値は

t0 = 0、 u(x, t0) = u0 = 1 です。x = 1 即ち ux(1, t) = 0, (t > t0) に「ゼロ束」境界条件

が存在します。u(0, t) の境界値は、突然に u0 から値 u1 = 0.1 に変わります。こ

の遷移は t = tδ = 0.09 によって終了します。

imsl_f_pde_method_of_lines によってうまく処理される境界条件のタイプの

制限のために、x = 0 と x = 1 の微分境界関数 γ’を提供することが必要です。x = 0 での関数 γ は、 t = t0 での値 u0 から t = tδ での値 u1 へのスムーズな移行を行

います。γ’の移行段階は 3 次補間多項式を計算することによって行われます。この目的のために、関数サブプログラム imsl_f_cub_spline_value(第 3 章: 補間と近似) が使用されます。この補間はユーザ提供のルーチン fcn_bc の最

初のステップとして実行されます。関数と微分値 γ(t0) = u0、 γ′(t0) = 0、 γ(tδ) = u1、

γ′(tδ) = 0 は imsl_f_cub_spline_value によって計算される係数を得るために、

ルーチン imsl_f_cub_spline_interp_e_cnd の入力として使用されます。γ′(t) = 0、 t > tδ であることに注意してください。評価ルーチン

imsl_f_cub_spline_value はルーチン fcn_bc のロジックが γ′(t) = 0、 t > tδ を割り当てるので、この値を生じません。

#include <imsl.h>#include <math.h>

main(){ void fcnut(int, float, float, float *, float *, float *, float *); void fcnbc(int, float, float, float *, float *, float *); int npdes = 1; int nx = 8; int i; int j = 1; int nstep = 10; float t = 0.0; float tend; float xbreak[8]; float y[8]; char title[50]; void *state;

/* 区分点と初期条件を設定 */

for (i = 0; i < nx; i++) { xbreak[i] = (float) i / (float) (nx - 1); y[i] = 1.0; }

/* ソルバーを初期化 */

Page 332: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

imsl_f_pde_method_of_lines_mgr(IMSL_PDE_INITIALIZE, &state, 0);

while (j <= nstep) { tend = (float) j++ / (float) nstep; tend *= tend;

/* 問題を解く */

imsl_f_pde_method_of_lines(npdes, &t, tend, nx, xbreak, y, state, fcnut, fcnbc);

/* 現在の t=tendで結果をプリント */

sprintf(title, "solution at t = %4.2f\0", t); imsl_f_write_matrix(title, npdes, nx, y, 0); }}

void fcnut(int npdes, float x, float t, float *u, float *ux, float *uxx, float *ut){ /* PDEを定義 */

*ut = *uxx;}

void fcnbc(int npdes, float x, float t, float *alpha, float *beta, float *gamp){ static int ndata; static int first = 1; static float delta = 0.09; static float u0 = 1.0; static float u1 = 0.1; static float dfdata[2]; static float xdata[2]; static float fdata[2]; static Imsl_f_ppoly *ppoly;

/* 最初だけ補間を計算 */

if (first) { first = 0; ndata = 2; xdata[0] = 0.0; xdata[1] = delta; fdata[0] = u0; fdata[1] = u1; dfdata[0] = dfdata[1] = 0.0; ppoly = imsl_f_cub_spline_interp_e_cnd(ndata, xdata, fdata, IMSL_LEFT, 1, dfdata[0], IMSL_RIGHT, 1, dfdata[1], 0); }

/* 境界条件を定義 */

if (x == 0.0) {

/* x = 0の場合 */

*alpha = 1.0; *beta = 0.0; *gamp = 0.0;

Page 333: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* 境界層にあれば、非ゼロ、ガンマダッシュを計算 */

if (t <= delta) *gamp = imsl_f_cub_spline_value(t, ppoly, IMSL_DERIV, 1, 0); } else { /* x = 1の場合 */

*alpha = 0.0; *beta = 1.0; *gamp = 0.0; }}

出力結果

solution at t = 0.01 1 2 3 4 5 6 0.969 0.997 1.000 1.000 1.000 1.000 7 8 1.000 1.000 solution at t = 0.04 1 2 3 4 5 6 0.625 0.871 0.962 0.991 0.998 1.000 7 8 1.000 1.000 solution at t = 0.09 1 2 3 4 5 6 0.1000 0.4602 0.7169 0.8671 0.9436 0.9781 7 8 0.9917 0.9951 solution at t = 0.16 1 2 3 4 5 6 0.1000 0.3130 0.5071 0.6681 0.7893 0.8708 7 8 0.9168 0.9315 solution at t = 0.25 1 2 3 4 5 6 0.1000 0.2567 0.4045 0.5354 0.6428 0.7224 7 8 0.7710 0.7874 solution at t = 0.36 1 2 3 4 5 6 0.1000 0.2176 0.3292 0.4292 0.5125 0.5751 7 8 0.6139 0.6270 solution at t = 0.49 1 2 3 4 5 6 0.1000 0.1852 0.2661 0.3386 0.3992 0.4448 7 8 0.4731 0.4827 solution at t = 0.64 1 2 3 4 5 6 0.1000 0.1588 0.2147 0.2648 0.3066 0.3381

Page 334: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

7 8 0.3577 0.3643 solution at t = 0.81 1 2 3 4 5 6 0.1000 0.1387 0.1754 0.2083 0.2358 0.2565 7 8 0.2694 0.2738 solution at t = 1.00 1 2 3 4 5 6 0.1000 0.1242 0.1472 0.1678 0.1850 0.1980 7 8 0.2060 0.2087

例題 2

問題 C は Sincovec と Madsen (1975 年 ) から解かれたものです。この方程式は

不連続係数を持つ拡散―対流タイプです。この問題は微係数 ut の計算ルーチ

ンをプログラムする単純な方法を説明します。x = 0.5 の弱い不連続性は ut の

式では計算されません。問題は次式で定義されます。

ut = ∂ u/ ∂ t = ∂ / ∂ x(D(x) ∂ u/ ∂ x) - v(x) ∂ u/ ∂ x

D(x) = 5 ならば

=1 ならば

v(x) = 1000.0 ならば

= 1 ならば

u(x,0) = 1 x = 0 ならば

= 0 x > 0 ならば

u(0,t) = 1, u(1,t) = 0

#include <imsl.h>#include <math.h>

main(){ void fcnut(int, float, float, float *, float *, float *, float *); void fcnbc(int, float, float, float *, float *, float *); int npdes = 1; int nx = 100; int i; int j = 1; int nstep = 10; float t = 0.0; float tend; float xbreak[100]; float y[100]; float tol, hinit; char title[50]; void *state;

/* 区分点と初期条件を設定 */

for (i = 0; i < nx; i++) { xbreak[i] = (float) i / (float) (nx - 1); y[i] = 0.0; }

x 0 1,[ ] t 0>,∈

0 x 0.5<≤

0.5 x 1.0≤<

0 x 0.5<≤

0.5 x 1.0≤<

Page 335: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

y[0] = 1.0;

/*ソルバーを初期化 */

tol = sqrt(imsl_f_machine(4)); hinit = 0.01*tol; imsl_f_pde_method_of_lines_mgr(IMSL_PDE_INITIALIZE, &state, IMSL_TOL, tol, IMSL_HINIT, hinit, 0);

while (j <= nstep) { tend = (float) j++ / (float) nstep;

/* 問題を解く */

imsl_f_pde_method_of_lines(npdes, &t, tend, nx, xbreak, y, state, fcnut, fcnbc); } /* t=tendでの結果をプリント */

sprintf(title, "solution at t = %4.2f\0", t); imsl_f_write_matrix(title, npdes, nx, y, 0);}

void fcnut(int npdes, float x, float t, float *u, float *ux, float *uxx, float *ut){ /* PDEを定義 */

float v; float d;

if (x <= 0.5) { d = 5.0; v = 1000.0; } else d = v = 1.0;

ut[0] = d*uxx[0] - v*ux[0];}

void fcnbc(int npdes, float x, float t, float *alpha, float *beta, float *gamp){ *alpha = 1.0; *beta = 0.0; *gamp = 0.0;}

出力結果

solution at t = 1.00 1 2 3 4 5 6 1.000 1.000 1.000 1.000 1.000 1.000 7 8 9 10 11 12 1.000 1.000 1.000 1.000 1.000 1.000 13 14 15 16 17 18 1.000 1.000 1.000 1.000 1.000 1.000 19 20 21 22 23 24 1.000 1.000 1.000 1.000 1.000 1.000 25 26 27 28 29 30

Page 336: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1.000 1.000 1.000 1.000 1.000 1.000 31 32 33 34 35 36 1.000 1.000 1.000 1.000 1.000 1.000 37 38 39 40 41 42 1.000 1.000 1.000 1.000 1.000 1.000 43 44 45 46 47 48 1.000 1.000 1.000 1.000 1.000 1.000 49 50 51 52 53 54 1.000 0.997 0.984 0.969 0.953 0.937 55 56 57 58 59 60 0.921 0.905 0.888 0.872 0.855 0.838 61 62 63 64 65 66 0.821 0.804 0.786 0.769 0.751 0.733 67 68 69 70 71 72 0.715 0.696 0.678 0.659 0.640 0.621 73 74 75 76 77 78 0.602 0.582 0.563 0.543 0.523 0.502 79 80 81 82 83 84 0.482 0.461 0.440 0.419 0.398 0.376 85 86 87 88 89 90 0.354 0.332 0.310 0.288 0.265 0.242 91 92 93 94 95 96 0.219 0.196 0.172 0.148 0.124 0.100 97 98 99 100 0.075 0.050 0.025 0.000

例題 3

imsl_f_pde_method_of_lines を使って線形正規化拡散偏微分方程式 ut = uxx 初期データの微係数の値 ux を提供するオプションので解きます。スプライン

補間により計算される数値微係数の誤差の理由によって、初期データが u(x, 0) = 1 + cos[(2n - 1)π x), n > 1 のときに、より正確な微係数が要求されます。この

境界条件は t > 0 に対して「ゼロフラックス (Zero flux)」条件です。導関数は次

式で x = 0 と x = 1 でゼロになるので、この初期データはこれら両端条件と等

しいことに注意してください。

このオプションの使用法は、初期データの微係数はユーザによって渡されることを合図しています。値 u(x, tend) と ux(x, tend) はオプションの使用法で区分

点に出力されます。

#include <imsl.h>#include <math.h>

main(){ void fcnut(int, float, float, float *, float *, float *, float *); void fcnbc(int, float, float, float *, float *, float *); int npdes = 1;

[ ]πxnπndx

xduxu x )12(sin)12()0,()0,( −−−==

Page 337: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int nx = 10; int i; int j = 1; int nstep = 10; float t = 0.0; float tend = 0.0; float xbreak[10]; float y[10], deriv[10]; float tol, hinit; float pi, arg; char title1[50]; char title2[50]; void *state;

pi = imsl_d_constant("pi", 0); arg = 9.0 * pi;

/* 区分点と初期条件を設定 */

for (i = 0; i < nx; i++) { xbreak[i] = (float) i / (float) (nx - 1); y[i] = 1.0 + cos(arg * xbreak[i]); deriv[i] = -arg * sin(arg * xbreak[i]); }

/* ソルバーを初期化 */

tol = sqrt(imsl_f_machine(4)); imsl_f_pde_method_of_lines_mgr(IMSL_PDE_INITIALIZE, &state, IMSL_TOL, tol, IMSL_INITIAL_VALUE_DERIVATIVE, deriv, 0);

while (j <= nstep) { j++; tend += 0.001;

/* 問題を解く */

imsl_f_pde_method_of_lines(npdes, &t, tend, nx, xbreak, y, state, fcnut, fcnbc);

/* 他全ての t=tendの結果をプリント */

if (j % 2) { sprintf(title1, "\nsolution at t = %5.3f\0", t); sprintf(title2, "\nderivative at t = %5.3f\0", t); imsl_f_write_matrix(title1, npdes, nx, y, 0); imsl_f_write_matrix(title2, npdes, nx, deriv, 0); } }

}

void fcnut(int npdes, float x, float t, float *u, float *ux, float *uxx, float *ut){ /* PDEを定義 */

ut[0] = uxx[0];}

void fcnbc(int npdes, float x, float t, float *alpha, float *beta, float *gamp){ /* 境界条件を定義 */

Page 338: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

alpha[0] = 0.0; beta[0] = 1.0; gamp[0] = 0.0;}

出力結果

solution at t = 0.002 1 2 3 4 5 6 1.233 0.767 1.233 0.767 1.233 0.767 7 8 9 10 1.233 0.767 1.233 0.767 derivative at t = 0.002 1 2 3 4 5 6 0.000e+00 -5.172e-07 1.911e-06 1.818e-06 -5.230e-07 2.408e-06 7 8 9 10-2.517e-06 3.194e-06 -3.608e-06 2.023e-06 solution at t = 0.004 1 2 3 4 5 6 1.053 0.947 1.053 0.947 1.053 0.947 7 8 9 10 1.053 0.947 1.053 0.947 derivative at t = 0.004 1 2 3 4 5 6 0.000e+00 -1.332e-06 -9.059e-06 -4.401e-06 5.006e-06 -2.134e-06 7 8 9 10-1.733e-06 4.625e-06 6.741e-07 2.023e-06

solution at t = 0.006 1 2 3 4 5 6 1.012 0.988 1.012 0.988 1.012 0.988 7 8 9 10 1.012 0.988 1.012 0.988 derivative at t = 0.006 1 2 3 4 5 6 0.000e+00 -1.408e-06 -1.018e-06 -6.572e-07 -8.213e-07 -1.151e-06 7 8 9 10 1.051e-06 1.257e-06 -2.920e-07 2.023e-06 solution at t = 0.008 1 2 3 4 5 6 1.003 0.997 1.003 0.997 1.003 0.997 7 8 9 10 1.003 0.997 1.003 0.997 derivative at t = 0.008 1 2 3 4 5 6 0.000e+00 -1.028e-06 4.270e-06 3.114e-06 -3.085e-06 -1.492e-06

Page 339: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

7 8 9 10 2.126e-06 -1.280e-06 -1.541e-06 2.023e-06 solution at t = 0.010 1 2 3 4 5 6 1.001 0.999 1.001 0.999 1.001 0.999 7 8 9 10 1.001 0.999 1.001 0.999 derivative at t = 0.010 1 2 3 4 5 6 0.000e+00 -7.596e-07 2.819e-07 1.547e-07 -1.469e-06 -9.516e-07 7 8 9 10 2.889e-07 8.956e-08 5.992e-07 2.023e-06

例題 4

この例題では、線形正規化双曲型偏微分方程式 utt = uxx、「振動弦」方程式を

考えます。これは自然に 1 次連立偏微分方程式に導かれます。新しい従属変数 ut = v を定義します。すると、vt = uxx はこの連立方程式の 2 番目の方程式になり

ます。初期データとして、u(x, 0) = sin( πx) と ut(x, 0) = v(x, 0) = 0 を取ります。

この弦の両端は、u(0, t) = u(1, t) = v(0, t) = v(1, t) = 0 になるように固定します。こ

の問題の正確な解は u(x, t) = sin(π x) cos( πt) になります。残差は 0 < t ≤ 2 の範

囲の t の出力値で計算されます。出力は 0.01 の増分の 200 ステップで得られま

す。

標本コード imsl_f_pde_method_of_lines がこの偏微分方程式の満足な結果

を与えるとしても、ユーザは、非線形問題に対して「ショック」がこの解に進展することに気をつける必要があります。ショックの出現はこのコードが予期しない方法で失敗する原因になる場合があります。双曲型連立方程式のショックの初歩的な説明は Courant と Hilbert (1962 年 ) の 488-490 ページ を参照し

てください。

#include <imsl.h>#include <math.h>

main(){ void fcnut(int, float, float, float *, float *, float *, float *); void fcnbc(int, float, float, float *, float *, float *); int npdes = 2; int nx = 10; int i; int j = 1; int nstep = 200; float t = 0.0; float tend = 0.0; float xbreak[20]; float y[20], deriv[20]; float tol, hinit; float pi; float error[10], erru; void *state;

pi = imsl_d_constant("pi", 0);

/* 区分点と初期条件を設定 */

for (i = 0; i < nx; i++) { xbreak[i] = (float) i / (float) (nx - 1); y[i] = sin(pi * xbreak[i]);

Page 340: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

y[nx + i] = 0.0; deriv[i] = pi * cos(pi * xbreak[i]); deriv[nx + i] = 0.0; }

/* ソルバーを初期化 */

tol = sqrt(imsl_f_machine(4)); imsl_f_pde_method_of_lines_mgr(IMSL_PDE_INITIALIZE, &state, IMSL_TOL, tol, IMSL_INITIAL_VALUE_DERIVATIVE, deriv, 0);

while (j <= nstep) { j++; tend += 0.01; /* 問題を解く */

imsl_f_pde_method_of_lines(npdes, &t, tend, nx, xbreak, y, state, fcnut, fcnbc);

/* 0.01のステップでの出力を確認し、誤差を計算 */

for (i = 0; i < nx; i++) { error[i] = y[i] - sin(pi * xbreak[i]) * cos(pi *tend); erru = imsl_f_max(erru, fabs(error[i])); } } printf("Maximum error in u(x,t) = %e\n", erru);

}

void fcnut(int npdes, float x, float t, float *u, float *ux, float *uxx, float *ut){ /* PDEを定義 */

ut[0] = u[1]; ut[1] = uxx[0];}

void fcnbc(int npdes, float x, float t, float *alpha, float *beta, float *gamp){ /* 境界条件を定義 */

alpha[0] = 1.0; beta[0] = 0.0; gamp[0] = 0.0; alpha[1] = 1.0; beta[1] = 0.0; gamp[1] = 0.0;}

出力結果Maximum error in u(x,t) = 6.228203e-04

Page 341: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

fast_poisson_2d一様メッシュ上の HODIE 有限差分スキームを基にした高速ポアソンソルバー

を使用して二次元矩形上のポアソン、又は、ヘルムホルツ方程式を解きます。

概要

#include <imsl.h>

float *imsl_f_fast_poisson_2d (float rhs_pde(), float rhs_bc(), float coeff_u, int nx, int ny, float ax, float bx, float ay, float by, Imsl_bc_type bc_type[], ..., 0)

double 型関数は imsl_d_fast_poisson_2dです。

必要な引数

float rhs_pde (float x, float y)x と y で偏微分方程式の右辺を計算するユーザ提供の関数。

float rhs_bc(Imsl_pde_side side, float x, float y)x と y でサイド side 上の境界条件の右辺を計算するユーザ提供の関

数。 side の値は次の 1 つです。IMSL_RIGHT、IMSL_BOTTOM、IMSL_LEFT、IMSL_TOP

float coeff_u ( 入力 )微分方程式の u の係数の値。

int nx ( 入力 )x 方向のグリッド線の数。nx は少なくとも 4 でなければなりません。

nx の制限事項は「説明」節を参照してください。

int ny ( 入力 )y 方向のグリッド線の数。ny は少なくとも 4 でなければなりません。

ny の制限事項は「説明」節を参照してください。

float ax ( 入力 )領域の左側に沿った x の値。

float bx ( 入力 )領域の右側に沿った x の値。

float ay ( 入力 )領域の下側に沿った y の値。

float by ( 入力 )領域の上側に沿った y の値。

Imsl_bc_type bc_type[4] ( 入力 )領域の各サイドの境界条件の種類、又は解が周期的であることを示すサイズ 4 の配列。このサイドは次のように番号が振られます。

Side   位置

IMSL_RIGHT_SIDE(0)    x = bxIMSL_BOTTOM_SIDE(1)   y = ayIMSL_LEFT_SIDE(2)    x = axIMSL_TOP_SIDE(3)    y = byこの 3 つの可能な条件は次の通りです。

Type 条件

IMSL_DIRICHLET   u の値が与えられる

IMSL_NEUMANN     du/dx(右、又は左側)もしくは、du/dy (領域の下側、または上側)の値が与えられる。IMSL_PERIODIC  周期的

オプション引数の概要

#include <imsl.h>

Page 342: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float *imsl_f_fast_poisson_2d (float rhs_pde(), float rhs_bc(), float coeff_u, int nx, int ny, float ax, float bx, float ay, float by, Imsl_bc_type bc_type[],IMSL_RETURN_USER, float u_user[],IMSL_ORDER, int order,IMSL_RHS_PDE_W_DATA, float rsh_pde (), void *data,IMSL_RHS_BC_W_DATA, float rsh_bc (), void *data, 0)

オプション引数

IMSL_RETURN_USER, float u_user[] ( 出力 )グリッド点の解を含むサイズ nx × ny のユーザ提供の配列。

IMSL_ORDER, int order ( 入力 )有限差分近似の精度の次数。これは、2 又は 4 でなければなりません。 デフォルト: order = 4

IMSL_RSH_PDE_W_DATA, float rhs_pde (float x, float y, void *data), void *data, ( 入力 )x と y での偏微分方程式の右辺を計算するユーザ提供関数。また、

ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータを受け渡すポインターです。 詳細は、

「イントロダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_RSH_BC_W_DATA, float rhs_bc(Imsl_pde_side side, float x, float y, void *data) , void *data, ( 入力 )境界条件の右辺を計算するユーザ提供関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の

関数にデータを受け渡すポインターです。 詳細は、「イントロダクショ

ン」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

c = coeff_u、ax = ax、bx = bx、ay = ay、by = by、nx = nx、ny = ny とします。

imsl_f_fast_poisson_2d は、Boisvert (1984 年 ) によるコード HFFT2D に基

づいています。これは以下の方程式を解きます。

これは矩形領域 (ax, bx) × (ay, by) 上の、Dirichlet ( 解は与えられる )、

Neumann(1 次微係数が与えられる )、又は、周期的境界条件のユーザ指定の組

み合わせを持っています。 サイドは右側から始まって時計回りに番号が振られ

ます。

∂∂

∂∂

2

2

2

2u

xu

ycu p+ + =

Page 343: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

c = 0 と Neumann だけ、又は、周期的境界条件が与えられると、定数が問題の

他の解を得るためにその解に追加されます。この場合には、最小 ∞ ノルムの

解が返されます。

この解は連続方程式の 2 次、又は、4 次の精度の有限差分近似を使用して計算

されます。線形代数連立方程式のシステムは高速フーリエ変換を使用して解かれます。このアルゴリズムは、 nx − 1 は高度に複合化される(小さい素数の積)

と言う事実に依存しています。このアルゴリズムの詳細は、Boisvert (1984 年 ) を参照してください。nx − 1 が高度に複合化される場合、

imsl_f_fast_poisson_2d の実行時間は nxny log2 nx に比例します。p(x, y) の計算に時間が掛かれば、order = 2 と order = 4 の実行時間の差は小さくな

ります。

グリッド間隔は(等間隔)グリッド線の間の距離です。これは公式 hx = (bx -ax)/(nx −1) と hy = (by −ay)/(ny –1) によって与えられます。 x 方向と y 方向のグリッド間隔は同じでなければなりません。すなわち nx と ny は hx が hy に等しくなければなりません。又、前述のように、nx と ny は少なくと

も、4 でなければいけません。高速フーリエ変換の速度を増加するためには、

nx −1 は小さい素数の積でなければなりません。良い選択としては、17、33、65 があります。

-coeff_u が同次境界条件を持つラプラス方程式の固有値にほぼ等しい場合、

計算された解の誤差が大きくなることがあります。

例題

この例題では、 方程式

下側の境界条件

他の 3 つのサイドの境界条件

by

y

Side 4

Side 2

Side 3 Side 1

a yxa bx

x

yxeyxuyu

xu 32

2

2

2

2

16)2sin(23 +++−=+∂∂

+∂∂

yxeyxyu 323)2cos(2 +++=

∂∂

( ) 2 32sin x yx yu e ++= +

Page 344: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

で、問題を解きます。 この領域は矩形 [0, ¼] × [0, ½] です。

imsl_f_fast_poisson_2d の出力は、その値の 17 × 33 テーブルです。 関数

imsl_f_spline_2d_value は値の異なるテーブルをプリントするために使用

されます。

#include <imsl.h>#include <math.h>

main(){ float rhs_pde(float, float); float rhs_bc(Imsl_pde_side, float, float);

int nx = 17; int nxtabl = 5; int ny = 33; int nytabl = 5;

int i; int j; Imsl_f_spline *sp; Imsl_bc_type bc_type[4];

float ax, ay, bx, by; float x, y, xdata[17], ydata[33]; float coefu, *u; float u_table; float abs_error;

/* 矩形サイズを設定 */

ax = 0.0; bx = 0.25; ay = 0.0; by = 0.50;

/* 境界条件を設定 */

bc_type[IMSL_RIGHT_SIDE] = IMSL_DIRICHLET_BC; bc_type[IMSL_BOTTOM_SIDE] = IMSL_NEUMANN_BC; bc_type[IMSL_LEFT_SIDE] = IMSL_DIRICHLET_BC; bc_type[IMSL_TOP_SIDE] = IMSL_DIRICHLET_BC;

/* uの係数 */ coefu = 3.0;

/* PDEを解く */

u = imsl_f_fast_poisson_2d(rhs_pde, rhs_bc, coefu, nx, ny, ax, bx, ay, by, bc_type, 0);

/* 補間を設定 */

for (i = 0; i < nx; i++) xdata[i] = ax + (bx - ax) * (float) i / (float) (nx - 1);

for (i = 0; i < ny; i++) ydata[i] = ay + (by - ay) * (float) i / (float) (ny - 1);

/* 補間関数を計算 */

sp = imsl_f_spline_2d_interp(nx, xdata, ny, ydata, u, 0);

printf(" x y u error\n\n"); for (i = 0; i < nxtabl; i++) for (j = 0; j < nytabl; j++) { x = ax + (bx - ax) * (float) j / (float) (nxtabl -

Page 345: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1); y = ay + (by - ay) * (float) i / (float) (nytabl - 1); u_table = imsl_f_spline_2d_value(x, y, sp, 0); abs_error = fabs(u_table - sin(x + 2.0 * y) - exp(2.0 * x + 3.0 * y));

/* nxtabl × nytabl グリッドの計算結果と絶対誤差をプリント */

printf(" %6.4f %6.4f %6.4f %8.2e\n", x, y, u_table, abs_error); }}

float rhs_pde(float x, float y){ /* PDEの右辺を定義 */

return (-2.0 * sin(x + 2.0 * y) + 16.0 * exp(2.0 * x + 3.0 * y));}

float rhs_bc(Imsl_pde_side side, float x, float y){ /* 境界条件を定義 */

if (side == IMSL_BOTTOM_SIDE) return (2.0 * cos(x + 2.0 * y) + 3.0 * exp(2.0 * x + 3.0 * y)); else return (sin(x + 2.0 * y) + exp(2.0 * x + 3.0 * y));}

出力結果

x y u error 0.0000 0.0000 1.0000 0.00e+00 0.0625 0.0000 1.1956 5.12e-06 0.1250 0.0000 1.4087 7.19e-06 0.1875 0.0000 1.6414 5.10e-06 0.2500 0.0000 1.8961 8.67e-08 0.0000 0.1250 1.7024 1.73e-07 0.0625 0.1250 1.9562 6.39e-06 0.1250 0.1250 2.2345 9.50e-06 0.1875 0.1250 2.5407 6.36e-06 0.2500 0.1250 2.8783 1.66e-07 0.0000 0.2500 2.5964 2.60e-07 0.0625 0.2500 2.9322 9.25e-06 0.1250 0.2500 3.3034 1.34e-05 0.1875 0.2500 3.7148 9.27e-06 0.2500 0.2500 4.1720 9.40e-08 0.0000 0.3750 3.7619 4.84e-07 0.0625 0.3750 4.2163 9.16e-06 0.1250 0.3750 4.7226 1.36e-05 0.1875 0.3750 5.2878 9.44e-06 0.2500 0.3750 5.9199 5.72e-07 0.0000 0.5000 5.3232 5.93e-07 0.0625 0.5000 5.9520 9.84e-07 0.1250 0.5000 6.6569 1.34e-06 0.1875 0.5000 7.4483 4.55e-07 0.2500 0.5000 8.3380 2.27e-06

Page 346: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに
Page 347: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

第 6章:変換

ルーチン

実三角法高速フーリエ変換( FFT)実高速フーリエ変換( FFT). . . . . . . . . . . . . . . . fft_real 348実高速フーリエ変換初期化 . . . . . . . . . . . . . . fft_real_init 352

複素指数高速フーリエ変換(FFT)複素高速フーリエ変換(FFT) . . . . . . . . . . . . . fft_complex 353複素高速フーリエ変換初期化 . . . . . . . . . . . fft_complex_init 355

実正弦と実余弦高速フーリエ変換(FFT)フーリエ余弦変換 . . . . . . . . . . . . . . . . . . fft_cosine 357フーリエ余弦変換初期化 . . . . . . . . . . . . . . fft_cosine_init 358フーリエ正弦変換 . . . . . . . . . . . . . . . . . . . .fft_sine 360フーリエ正弦変換初期化 . . . . . . . . . . . . . . . fft_sine_init 361

2 次元高速フーリエ変換(FFT)複素 2 次元高速フーリエ変換(FFT) . . . . . . . . fft_2d_complex 363

たたみ込みと相関実たたみ込み / 相関. . . . . . . . . . . . . . . . . . convolution 367複素たたみ込み / 相関. . . . . . . . . . . . convolution (複素数 ) 372

ラプラス変換複素関数の逆ラプラス変換の近似 . . . . . . . . .inverse_laplace 377

使用上の注意

高速フーリエ変換

高速フーリエ変換 (FFT) は効率的に計算する単なる離散フーリエ変換です。基

本的に、フーリエ変換を計算する直接法は、n を変換における点の数とすると

近似的に n2 回の処理が必要ですが、FFT ( 同じ値を計算する ) は近似的に n log n 回の処理が必要になります。この章のアルゴリズムは、Cooley-Tukey (1965 年 ) のアルゴリズムをモデルにしています。従って、この関数は高度に

構成される整数、即ち、小さい素数の積である整数に対して最も効率的です。

2 つの関数 imsl_f_fft_0real と imsl_c_fft_complex に対して対応する初

期化関数が存在します。反復して同じ長さの数列を変換するときだけにこれらの関数を使用します。この状態に於いて、この初期化関数は初期設定を一度だけ計算します。 その後、ユーザは適切なオプションを持つ、対応する主関数を

呼び出します。これは、本質的な計算上の節減になる場合があります。これらの関数の使用法のより詳細な情報は、適切な関数名の下の説明文書を調べて下さい。

先に説明した 1 次元変換に加えて、複素 2 次元高速フーリエ変換とその逆変換

を提供します。

連続 対 離散 フーリエ変換離散フーリエ変換と連続フーリエ変換との間には、密接な関係があります。連続フーリエ変換は次式のように定義される事(Brigham 1974 年)を考えてみま

す。

Page 348: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

次の近似から始めます。

この最後の積分を h = T / n の間隔で矩形規則を使用して近似する場合、次式が

得られます。

最終的に、 j = 0, ..., n − 1 に対して ω = j/T を設定して、次式が生じます。

ここでは、ベクトル f h = (f(−T/2), ..., f( (n − 1)h − T/2)) になります。 こうして、 (−1)j h によって要素を調整した後で、imsl_c_fft_complex ( 入力 f h を持つ ) で計算される離散フーリエ変換は、上式による連続フーリエ変換の近似に関係しています。

関数 f が C 関数として表される場合は、連続フーリエ変換

は、IMSL 関数 imsl_f_int_fcn_fourier ( 第 4 章、「求積法」を使用して近

似することが可能です。

fft_real実数列の実離散フーリエ変換を計算します。

概要

#include <imsl.h>

float *imsl_f_fft_real (int n, float p[], …, 0)double 型関数は、 imsl_d_fft_realです。

必要な引数

int n ( 入力 )変換される数列の長さ。

float p[] ( 入力 )周期数列を含んだ n 成分の配列。

戻り値

変換された数列のポインター。 この空間を解放するために free を使用しま

す。 値が計算されなければ、NULL が返されます。

( ) ( )( ) ( ) 2ˆ i tf f f t e dtπ ωω ω∞ −

−∞= ℑ = ∫

( ) ( )

( ) ( )

( )

/ 2 2

/ 2

2 / 2

0

2

0

ˆ

/ 2

/ 2

T i t

TT i t T

Ti T i t

f f t e dt

f t T e dt

e f t T e dt

π ω

π ω

π ω π ω

ω −

− −

= −

= −

∫∫

( ) ( )1

2

0

ˆ / 2n

i T i kh

kf e h e f kh Tπ ω π ωω

−−

=

≈ −∑

( ) ( ) ( )1 1

2 / 2 /

0 0

ˆ / / 2 1n n

jij ijk n ijk n hk

k kf j T e h e f kh T e fπ π π

− −− −

= =

≈ − = −∑ ∑

f

Page 349: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数の概要

#include <imsl.h> float *imsl_f_fft_real (int n, float p[],

IMSL_BACKWARD,IMSL_PARAMS, float params[],IMSL_RETURN_USER, float q[],0)

オプション引数

IMSL_BACKWARD

後退変換を計算して、( 後退 ) 変換された数列のポインターを返します。

IMSL_PARAMS, float params[] ( 入力 )imsl_f_fft_real_init の事前の呼び出しによって返されるポイン

ター。もし imsl_f_fft_realが、同じ n の値で繰り返して使用され

る場合、これらのパラメータを1回だけ計算するとより効率的です。

IMSL_RETURN_USER, float q[] ( 出力 )q によって指されるユーザ提供の空間にこの結果が格納されます。こ

のために、どのような記憶域もこの解のために割り当てられないで、imsl_f_fft_real は q を返します。配列 q は少なくとも n の長さで

なければなりません。

説明

関数 imsl_f_fft_real は n の長さの実数ベクトルの離散フーリエ変換を計算

します。 使用される方法は Cooley-Tukey アルゴリズムの変形で、これは n が小

さい素数因子の積であるときに、最も効率的です。n がこの条件を満足する

と、計算消費時間は n log n に比例します。

デフォルトでは、 imsl_f_fft_real 前方変換で計算します。 n が等しい場合、

前方変換は、次の様になります。

n が奇数であれば、qm は m に対して 1 から (n − 1)/2 までの上式で定義されます。

f が時間の実数値関数であるとし、時間 t0 から出発する長さ ∆ 秒の n 個の等間

隔時間区間で f を抽出するものとします。こうして次式が得られます。

pi:= f(t0 + i∆)i = 0, 1, …, n − 1

これからの説明では n は奇数であるとします。関数 imsl_f_fft_real はこの

数列を周期 n の周期性であるかのように処置します。特にそれは f(t0 ) = f(t0 + n∆) と想定します。こうして、この関数の周期は T = n∆ であると推定されま

す。上の変換を p に対して次のように逆変換することが可能です。

この公式は非常に啓示的です。これは、次のように解釈することができます。係数 q は imsl_f_fft_real によって生成され、そのデータに補間する三角法

多項式を決定します。つまり、次式を定義する場合、

1

2 10

1

20

1

00

2cos 1, , / 2

2sin 1, , / 2 1

n

m kk

n

m kk

n

kk

kmq p m nn

kmq p m nn

q p

π

π

−=

=

=

= =

= − = −

=

K

K

( ) ( ) ( ) ( )3 / 2 3 / 2

0 2 1 2 20 0

2 1 2 11 2 cos 2 sinn n

m k kk k

k m k mp q q q

n n nπ π− −

+ += =

+ += + −

∑ ∑

Page 350: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

次式を得ます。

f(t0 + i∆) = g(t0 +i∆)

ここで、次のように長さ (n + 1)/2 のベクトル P を形成して、主要な振動数を見

つけたいと仮定します。

これらの数値は信号のスペクトルのエネルギーに対応します。特に、P k は次

の振動数のエネルギーレベルに対応しています。

更に n 回の観測が行われたとき、 (n + 1)/2 = T/(2∆) の分解可能な振動数だけが存

在することに注意してください。これは連続信号の離散サンプリングによって導出されるところの Nyquist 現象に関連します。 同様な関係は n が偶数の場合

に対して保持されます。

オプション引数 IMSL_BACKWARD が指定されると、後退変換が計算されます。 n が偶数のとき、その後退転換は 次式になります。

n が奇数の場合、次の通りです。

後退フーリエ変換は、前進フーリエ変換の正規化されない逆変換です。

関数 imsl_f_fft_real は国立大気圏研究所の Paul Swarztrauber 氏によって開

発された、FFTPACK の実数 FFT に基づいています。

例題

例題 1

この例題では、純粋余弦波がデータベクトルとして使用され、そのフーリエ級数が回復されます。このフーリエ級数は n を持つ適切な振動数を除いては、全

ての成分にゼロを持つベクトルです。

#include <imsl.h>#include <math.h>#include <stdio.h>

main(){ int k, n = 7; float two_pi = 2*imsl_f_constant("pi", 0);

( )( ) ( )( ) ( ) ( )( )

( ) ( )( ) ( ) ( )( )

3 / 2 3 / 20 0

0 2 1 2 20 0

3 / 2 3 / 20 0

0 2 1 2 20 0

2 1 2 11 2 cos 2 sin

2 1 2 11 2 cos 2 sin

n n

k kk k

n n

k kk k

k t t k t tg t q q q

n n n

k t t k t tq q q

n T T

π π

π π

− −

+ += =

− −

+ += =

+ − + −= + −

∆ ∆ + − + −

= + −

∑ ∑

∑ ∑

( )0 0

2 22 1 2

:

: 1, 2, , 1 / 2k k k

P q

P q q k n−

=

= + = −K

10, 1, ,2

k k nkT n

−= =

∆K

( ) ( ) ( )/ 2 2 / 2 2

0 1 2 1 2 20 0

2 1 2 11 2 cos 2 sin

n nm

m n k kk k

k m k mq p p p p

n nπ π− −

− + += =

+ += + − + −∑ ∑

( ) ( ) ( ) ( )3 / 2 3 / 2

0 2 1 2 20 0

2 1 2 12 cos 2 sin

n n

m k kk k

k m k mq p p p

n nπ π− −

+ += =

+ += + −∑ ∑

Page 351: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float p[8], *q; /* 純粋指数信号で q を埋める */ for (k = 0; k < n; k++) p[k] = cos(k*two_pi/n);

q = imsl_f_fft_real (n, p, 0);

printf(" index p q\n"); for (k = 0; k < n; k++) printf("%11d%10.2f%10.2f\n", k, p[k], q[k]);}

出力結果

index p q 0 1.00 0.00 1 0.62 3.50 2 -0.22 0.00 3 -0.90 -0.00 4 -0.90 -0.00 5 -0.22 0.00 6 0.62 -0.00

例題 2

この例題は j = 0 から n − 1 に対して x j = (−1)j であるベクトル x のフーリエ変換を計算し

ます。このベクトルの後退変換がオプションの引数 IMSL_BACKWARD を使用して計算さ

れます。 s = nx 、つまり j = 0 から n − 1 に対して s j = (−1)j n であることに注意してくださ

い。

#include <imsl.h>#include <stdio.h>

main(){ int k, n = 7; float *q, *s, x[8]; /* データベクトルを埋める */ x[0] = 1.0; for (k = 1; k<n; k++) x[k] = -x[k-1]; /* x の前進変換を計算 */ q = imsl_f_fft_real (n, x, 0); /* x の後退変換を計算 */ s = imsl_f_fft_real (n, q, IMSL_BACKWARD, 0); printf(" index x q s\n"); for (k = 0; k < n; k++) printf("%11d%10.2f%10.2f%10.2f\n", k, x[k], q[k], s[k]);}

出力結果

index x q s 0 1.00 1.00 7.00 1 -1.00 1.00 -7.00 2 1.00 0.48 7.00 3 -1.00 1.00 -7.00 4 1.00 1.25 7.00 5 -1.00 1.00 -7.00 6 1.00 4.38 7.00

Page 352: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

fft_real_initimsl_f_fft_realのパラメータを計算します。

概要

#include <imsl.h>

float *imsl_f_fft_real_init (int n)double 型関数は、imsl_d_fft_real_initです。

必要な引数

int n ( 入力 )変換される数列の長さ。

戻り値

オプション引数 IMSL_PARAMSが指定された場合、imsl_f_fft_realで使用される

長さ 2n + 15 のパラメータベクトルへのポインター。

説明

列の長さ n を変更せずに imsl_f_fft_realを多く呼び出すとき、関数 imsl_f_fft_real_init を使用するべきです。この関数は、実フーリエ変換で

必要とされるパラメータを計算します。

関数 imsl_f_fft_real_init は、は国立大気圏研究所の Paul Swarztrauber 氏に

よって開発された、FFTPACK の RFFTI ルーチンを基にしています。

例題

この例題では、 imsl_f_fft_real_init を 1 度呼び出した後、 imsl_f_fft_real を 3 回呼び出すことにより、3 つの異なる実数 FFT を計算

します。

#include <imsl.h>#include <math.h>#include <stdio.h>

main(){ int k, j, n = 7; float two_pi = 2*imsl_f_constant("pi", 0); float p[8], *q, *work; work = imsl_f_fft_real_init (n); for (j = 0; j < 3; j++){ /* 純粋な正弦信号で p を埋める */ for (k = 0; k < n; k++) p[k] = cos(k*two_pi*j/n);

q = imsl_f_fft_real (n, p, IMSL_PARAMS, work, 0);

printf(" index p q\n"); for (k = 0; k < n; k++) printf("%11d%10.2f%10.2f\n", k, p[k], q[k]); }}

出力結果

index p q 0 1.00 7.00 1 1.00 0.00 2 1.00 0.00 3 1.00 0.00 4 1.00 0.00

Page 353: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

5 1.00 -0.00 6 1.00 0.00

index p q 0 1.00 0.00 1 0.62 3.50 2 -0.22 0.00 3 -0.90 -0.00 4 -0.90 -0.00 5 -0.22 0.00 6 0.62 -0.00

index p q 0 1.00 -0.00 1 -0.22 0.00 2 -0.90 -0.00 3 0.62 3.50 4 0.62 -0.00 5 -0.90 0.00 6 -0.22 0.00

fft_complex複素数列の複素離散フーリエ変換を計算します。

概要

#include <imsl.h>

f_complex *imsl_c_fft_complex (int n, f_complex p[], …, 0)d_complex 型関数は、 imsl_z_fft_complexです。

必要な引数

int n ( 入力 )変換される数列の長さ。

f_complex p[] ( 入力 )周期数列を含んだ n 成分の配列。

戻り値

オプション引数が使用されない場合、 imsl_c_fft_complex は、 変換された数

列のポインターを返します。 この空間を解放するために free を使用します。 値が計算されなければ、NULL が返されます。

オプション引数の概要

#include <imsl.h>f_complex *imsl_c_fft_complex (int n, f_complex p[],

IMSL_BACKWARD,IMSL_PARAMS, float params[],IMSL_RETURN_USER, f_complex q[],0)

オプション引数

IMSL_BACKWARD

後退変換を計算します。

IMSL_PARAMS, float params[] ( 入力 )imsl_c_fft_complex_initの呼び出しによって返されるポインター。 If imsl_c_fft_complex が、同じ nの値で繰り返し使用される場合、こ

のパラメータを一度だけ計算するほうがより効率的です。

IMSL_RETURN_USER, f_complex q[] ( 出力 ) qによって指されるユーザ提供空間に結果が格納されます。 その結果、解の

ための格納場所は割り当てられず、imsl_c_fft_complexは qを返し

ます。配列 q は、少なくとも長さ nでなければなりません。

Page 354: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

関数 imsl_c_fft_complex は、サイズ n の十スベクトルの離散フーリエ変換

を計算します。使用される手法は、 n が小さい素数の積である時に最も効率的

な Cooley-Tukey アルゴリズムの改良型です。 n がこの条件を満たす場合、計算

時間は、 n log n に比例します。

デフォルトでは、 imsl_c_fft_complex は、次式の前方変換を計算します。

次式のようにフーリエ変換を逆転することが可能なことに注意してください。

この公式は、フーリエ係数を正しく正規化した後には、多項式を補間する三角法のための係数を持つことを示しています。 関数 imsl_c_fft_complex は国

立大気圏研究所の Paul Swarztrauber 氏によって開発された、FFTPACK の複素

数 FFT を基にしています。

IMSL_BACKWARD オプションが選択されると、次の計算が実行されます。

その結果、前方と後退変換の関係は、それぞれに対する非正規化の逆になります。つまり、 次のコードの一部は、ベクトル p で始まり、ベクトル p2 = np で

終了します。

q = imsl_c_fft_complex(n, p, 0);

p2 = imsl_c_fft_complex(n, q, IMSL_BACKWARD, 0);

例題

例題 1

この例題では、純粋指数データベクトルを入力し、そのフーリエ級数が回復されます。このフーリエ級数は n を持つ適切な振動数を除いては、全ての成分に

ゼロを持つベクトルです。

#include <imsl.h>#include <math.h>#include <stdio.h> main(){ int k, n = 7; float two_pi = 2*imsl_f_constant("pi", 0); f_complex p[8], *q, z; /* 純粋指数信号 p で埋める */ for (k = 0; k < n; k++) { z.re = 0.; z.im = k*two_pi/n; p[k] = imsl_c_exp(z); } q = imsl_c_fft_complex (n, p, 0);

printf(" index p.re p.im q.re q.im\n"); for (k = 0; k < n; k++) printf("%11d%10.2f%10.2f%10.2f%10.2f\n", k, p[k].re, p[k].im, q[k].re, q[k].im);}

12 /

0

nimj n

j mm

q p e π−

=

= ∑

11 2 /

0

nijm n

m n jj

p q e π−

=

= ∑

12 /

0

nimj n

j mm

q p e π−

=

= ∑

Page 355: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

index p.re p.im q.re q.im 0 1.00 0.00 0.00 -0.00 1 0.62 0.78 7.00 0.00 2 -0.22 0.97 -0.00 -0.00 3 -0.90 0.43 0.00 -0.00 4 -0.90 -0.43 0.00 0.00 5 -0.22 -0.97 -0.00 0.00 6 0.62 -0.78 0.00 -0.00

例題 2

後退変換を使用し、元の列を回復します。前方変換の後の後退変換は、元の列の入力を列の長さで掛けます。

#include <imsl.h>#include <math.h>#include <stdio.h>

main(){ int k, n = 7; float two_pi = 2*imsl_f_constant("pi", 0); f_complex p[7], *q, *pp; /* 増加する信号で p を埋める */ for (k = 0; k < n; k++) { p[k].re = (float) k; p[k].im = 0.; } q = imsl_c_fft_complex (n, p, 0); pp = imsl_c_fft_complex (n, q, IMSL_BACKWARD, 0); printf(" index p.re p.im pp.re pp.im \n"); for (k = 0; k < n; k++) printf("%11d%10.2f%10.2f%10.2f%10.2f\n", k, p[k].re, p[k].im, pp[k].re , pp[k].im);}

出力結果

index p.re p.im pp.re pp.im 0 0.00 0.00 0.00 0.00 1 1.00 0.00 7.00 0.00 2 2.00 0.00 14.00 0.00 3 3.00 0.00 21.00 0.00 4 4.00 0.00 28.00 0.00 5 5.00 0.00 35.00 0.00 6 6.00 0.00 42.00 0.00

fft_complex_initimsl_c_fft_complexのパラメータを計算します。

概要

#include <imsl.h>

float *imsl_c_fft_complex_init (int n)double 型関数は、imsl_z_fft_complex_initです。

必要な引数

int n ( 入力 )変換される数列の長さ。

Page 356: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

オプション引数 IMSL_PARAMSが指定される時、 imsl_c_fft_complexで使用さ

れる float 型で長さ 2n + 15 のパラメータベクトルへのポインター。 この空間を

解放するために free を使用します。 値が計算されなければ、NULL が返されま

す。

説明

列の長さ n を変更せずに imsl_c_fft_complexを多く呼び出すとき、関数 imsl_c_fft_complex_init を使用するべきです。この関数は、実フーリエ変

換で必要とされる定数を計算します。

関数 imsl_c_fft_complex_init は、は国立大気圏研究所の Paul Swarztrauber 氏によって開発された、FFTPACK の CFFTI ルーチンを基にしています。

例題

この例題では、imsl_c_fft_complex_init を 1 度呼び出した後、 imsl_c_fft_complex を 3 回呼び出すことにより、3 つの異なる実数 FFT を計

算します。

#include <imsl.h>#include <math.h>#include <stdio.h> main(){ int k, j, n = 7; float two_pi = 2*imsl_f_constant("pi", 0), *work; f_complex p[8], *q, z; work = imsl_c_fft_complex_init (n); for (j = 0; j < 3; j++){ /* 純粋指数信号で p を埋める */ for (k = 0; k < n; k++) { z.re = 0.; z.im = k*two_pi*j/n; p[k] = imsl_c_exp(z); } q = imsl_c_fft_complex (n, p, IMSL_PARAMS, work, 0);

printf("\n index p.re p.im q.re q.im\n"); for (k = 0; k < n; k++) printf("%11d%10.2f%10.2f%10.2f%10.2f\n", k, p[k].re, p[k].im, q[k].re, q[k].im); }}

出力結果

index p.re p.im q.re q.im 0 1.00 0.00 7.00 0.00 1 1.00 0.00 0.00 0.00 2 1.00 0.00 0.00 0.00 3 1.00 0.00 0.00 0.00 4 1.00 0.00 0.00 0.00 5 1.00 0.00 0.00 0.00 6 1.00 0.00 0.00 0.00

index p.re p.im q.re q.im 0 1.00 0.00 0.00 -0.00 1 0.62 0.78 7.00 0.00 2 -0.22 0.97 -0.00 -0.00 3 -0.90 0.43 0.00 -0.00 4 -0.90 -0.43 0.00 0.00 5 -0.22 -0.97 -0.00 0.00 6 0.62 -0.78 0.00 -0.00

Page 357: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

index p.re p.im q.re q.im 0 1.00 0.00 -0.00 -0.00 1 -0.22 0.97 0.00 -0.00 2 -0.90 -0.43 7.00 0.00 3 0.62 -0.78 -0.00 -0.00 4 0.62 0.78 0.00 -0.00 5 -0.90 0.43 0.00 0.00 6 -0.22 -0.97 -0.00 0.00

fft_cosine偶数級数の離散フーリエ余弦変換を計算します。

概要

#include <imsl.h>float *imsl_f_fft_cosine (int n, float p[], …, 0)

double 型関数は、 imsl_d_fft_cosineです。

必要な引数

int n ( 入力 )変換される数列の長さ。1 以上でなければなりません。

float p[] ( 入力 )変換される級数を含んだサイズ n の配列。

戻り値

変換された級数のポインター。この空間を解放するために free を使用しま

す。解が得られない場合,NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_fft_cosine (int n, float p[],IMSL_RETURN_USER, float q[],IMSL_PARAMS, float params[],0)

オプション引数

IMSL_RETURN_USER, float q[] ( 出力 )q によって指されるユーザ提供の空間にこの結果を保存します。その

ために解のために割り当てられる記憶域はなく、imsl_f_fft_cosine は q を返します。この配列は少なくとも長さ n でなければなりません。

IMSL_PARAMS, float params[] ( 入力 )imsl_f_fft_cosine_init の事前の呼び出しによって返されるポイ

ンター。imsl_f_fft_cosine が n の同じ値で繰り返して使用され

る場合、これらのパラメータを一度だけ計算するとより効率的です。デフォルト: imsl_f_fft_cosine が入力される度に、パラメータの

初期化が計算されます。

説明

関数 imsl_f_fft_cosine はサイズ N の実数ベクトルの離散フーリエ余弦変

換を計算します。ここで使用される方法は、N − 1 が小さな素数因子の積であ

るときに最も効率的な Cooley-Tukey アルゴリズムの改良型です。もしも N がこの条件を満たせば、計算消費時間は N logN に比例します。特に N- ベクトル p が与えられると、imsl_f_fft_cosineは、qの中に次式を返します。

( )2

0 11

2 sin( ) 11

Nm

m n Nn

mnq p s sN

π−

−=

= + + −−∑

Page 358: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

最後に、フーリエ余弦変換はそれ自身の(正規化されない)逆変換であることに注意してください。imsl_f_fft_cosine は FFTPACK の余弦 FFT を基にし

ています。このパッケージ FFTPACK は国立大気圏研究所の Paul Swarztrauber氏 によって開発されました。

例題

この例題はデータベクトルとして、純粋余弦波を入力して、適切な振動数を除いた、n − 1 の全ての成分にゼロ を持つベクトルであるそのフーリエ余弦級数

を回復します。

#include <imsl.h>#include <math.h>

main(){ int n = 7; int i; float p[7]; float *q; float pi;

pi = imsl_f_constant("pi", 0);

/* 純粋余弦波で p を埋める */

for (i=0; i<n; i++) p[i] = cos((float)(i)*pi/(float)(n-1));

q = imsl_f_fft_cosine (n, p, 0);

printf (" index\t p\t q\n"); for (i=0; i<n; i++) printf("\t%1d\t%5.2f\t%5.2f\n", i, p[i], q[i]);}

出力結果 index p q 0 1.00 -0.00 1 0.87 6.00 2 0.50 0.00 3 -0.00 0.00 4 -0.50 -0.00 5 -0.87 -0.00 6 -1.00 -0.00

fft_cosine_initimsl_f_fft_cosineで必要とされるパラメータを計算します。

概要

#include <imsl.h>float *imsl_f_fft_cosine_init (int n)

double 型関数は、 imsl_d_fft_cosine_initです。

必要な引数

int n ( 入力 )変換される数列の長さ。 1 以上でなければなりません。

Page 359: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

オプション引数 IMSL_PARAMSが指定される時、 imsl_f_fft_cosineで使用され

る長さ (3*n + 15) のパラメータベクトルへのポインター。 この空間を解放する

ために free を使用します。 値が計算されなければ、NULL が返されます。

説明

列の長さ n を変更せずに imsl_f_fft_cosineを多く呼び出すとき、関数 imsl_f_fft_cosine_init を使用するべきです。この関数は、実フーリエ変換

で必要とされる定数を計算します。関数 imsl_f_fft_cosine_init は、

FFTPACK の COSTI を基にしています。パッケージ FFTPACK は国立大気圏研

究所の Paul Swarztrauber 氏 によって開発されました。

例題

この例題では、imsl_f_fft_cosine_init を 1 度呼び出した後、 imsl_f_fft_cosine を 3 回呼び出すことにより、3 つの異なる正弦 FFT を計

算します。 imsl_f_fft_cosine の内部パラメータの初期化は、省略していま

す。

#include <imsl.h>#include <math.h>

main(){ int n = 7; int i, k; float p[7]; float q[7]; float pi; float *params;

pi = imsl_f_constant("pi", 0);

/* 長さ n の変換変換のためのパラメータを計算 */

params = imsl_f_fft_cosine_init (n);

/* 異なる周波数に変換 */ for (k=0; k<3; k++) { printf("\n");

/* 純粋余弦波で p を埋める */

for (i=0; i<n; i++) p[i] = cos((float)((k+1)*i)*pi/(float)(n-1));

/* p の変換を計算 */

imsl_f_fft_cosine (n, p, IMSL_PARAMS, params, IMSL_RETURN_USER, q, 0);

printf (" index\t p\t q\n"); for (i=0; i<n; i++) printf("\t%1d\t%5.2f\t%5.2f\n", i, p[i], q[i]);

}}

出力結果

index p q 0 1.00 -0.00 1 0.87 6.00 2 0.50 0.00

Page 360: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

3 -0.00 0.00 4 -0.50 -0.00 5 -0.87 -0.00 6 -1.00 -0.00

index p q 0 1.00 0.00 1 0.50 -0.00 2 -0.50 6.00 3 -1.00 0.00 4 -0.50 0.00 5 0.50 0.00 6 1.00 -0.00

index p q 0 1.00 -0.00 1 -0.00 0.00 2 -1.00 -0.00 3 0.00 6.00 4 1.00 0.00 5 -0.00 -0.00 6 -1.00 0.00

fft_sine奇数級数の離散フーリエ正弦変換を計算します。

概要

#include <imsl.h>float *imsl_f_fft_sine (int n, float p[], …, 0)

double 型関数は、 imsl_d_fft_sineです。

必要な引数

int n ( 入力 )変換される数列の長さ。 1 以上でなければなりません。

float p[] ( 入力 )変換される級数を含んだサイズ n の配列。

戻り値

変換された級数のポインター。この空間を解放するために free を使用します。

解が得られない場合,NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_fft_sine (int n, float p[],IMSL_RETURN_USER, float q[],IMSL_PARAMS, float params[],0)

オプション引数

IMSL_RETURN_USER, float q[] ( 出力 )qによって指されるユーザ提供空間に結果が格納されます。 その結果、解の

ための格納場所は割り当てられず、imsl_f_fft_sineは qを返しま

す。配列 は、少なくとも長さ n + 1 でなければなりません。

IMSL_PARAMS, float params[] ( 入力 )imsl_f_fft_sine_init の事前の呼び出しによって返されるポイン

ター。imsl_f_fft_sine が n の同じ値で繰り返して使用される場合、

これらのパラメータを一度だけ計算するとより効率的です。

Page 361: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

デフォルト:imsl_f_fft_sine が入力される度に、パラメータの初

期化が計算されます。

説明

関数 imsl_f_fft_sine はサイズ N の実数ベクトルの離散フーリエ正弦変換

を計算します。ここで使用される手法は、N + 1 が小さな素数因子の積である

ときに最も効率的な Cooley-Tukey アルゴリズムの改良型です。もしも N がこ

の条件を満たせば、計算消費時間は N logN に比例します。特に N ベクトル p が与えられると、imsl_f_fft_sineは、qの中に次式を返します。

最後に、フーリエ正弦変換はそれ自身の(正規化されない)逆変換であることに注意してください。関数 imsl_f_fft_sine は FFTPACK の正弦 FFT を基

にしています。このパッケージ FFTPACK は国立大気圏研究所の Paul Swarztrauber 氏 によって開発されました。

例題

この例題はデータベクトルとして、純粋正弦波を入力して、適切な振動数を除いた、n の全ての成分にゼロ を持つベクトルであるそのフーリエ正弦級数を

回復します。

#include <imsl.h>#include <math.h>

main(){ int n = 7; int i; float p[7]; float *q; float pi;

pi = imsl_f_constant("pi", 0);

/* 純粋正弦波で p を埋める */

for (i=0; i<n; i++) p[i] = sin((float)(i+1)*pi/(float)(n+1));

q = imsl_f_fft_sine (n, p, 0);

printf (" index\t p\t q\n"); for (i=0; i<n; i++) printf("\t%1d\t%5.2f\t%5.2f\n", i, p[i], q[i]);}

出力結果

index p q 0 0.38 8.00 1 0.71 0.00 2 0.92 0.00 3 1.00 0.00 4 0.92 0.00 5 0.71 0.00 6 0.38 0.00

fft_sine_initimsl_f_fft_sineで必要とされるパラメータを計算します。

( )( )1

0

1 12 sin

1

N

m nn

m nq p

Nπ−

=

+ + =

+ ∑

Page 362: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

概要

#include <imsl.h>float *imsl_f_fft_sine_init (int n)

double 型関数は、imsl_d_fft_sine_initです。

必要な引数

int n ( 入力 )変換される数列の長さ。 1 以上でなければなりません。

戻り値

オプション引数 IMSL_PARAMSが指定される時、 imsl_f_fft_sineで使用される

長さ (int) (2.5*n + 15) のパラメータベクトルへのポインター。 この空間を解放

するために free を使用します。 値が計算されなければ、NULL が返されます。

説明

列の長さ n を変更せずに imsl_f_fft_sineを多く呼び出すとき、関数 imsl_f_fft_sine_init を使用するべきです。関数 imsl_f_fft_sine_initは、FFTPACK の SINTI を基にしています。パッケージ FFTPACK は国立大気

圏研究所の Paul Swarztrauber 氏 によって開発されました。

例題

この例題では、imsl_f_fft_sine_init を 1 度呼び出した後、 imsl_f_fft_sine を3回呼び出すことにより、3つの異なる正弦FFTを計算しま

す。

#include <imsl.h>#include <math.h>

main(){ int n = 7; int i, k; float p[7]; float q[8]; float pi; float *params;

pi = imsl_f_constant("pi", 0);

/* 長さ nの変換のためのパラメータを計算 */

params = imsl_f_fft_sine_init (n);

/* 異なる周波数に変換 */ for (k=0; k<3; k++) { printf("\n");

/* 純粋正弦波で p を埋める */

for (i=0; i<n; i++) p[i] = sin((float)((k+1)*(i+1))*pi/(float)(n+1));

/* p の変換を計算 */

imsl_f_fft_sine (n, p, IMSL_PARAMS, params, IMSL_RETURN_USER, q, 0);

printf (" index\t p\t q\n"); for (i=0; i<n; i++) printf("\t%1d\t%5.2f\t%5.2f\n", i, p[i], q[i]);

Page 363: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

}}

出力結果

index p q 0 0.38 8.00 1 0.71 0.00 2 0.92 0.00 3 1.00 0.00 4 0.92 0.00 5 0.71 0.00 6 0.38 0.00

index p q 0 0.71 -0.00 1 1.00 8.00 2 0.71 0.00 3 -0.00 -0.00 4 -0.71 0.00 5 -1.00 -0.00 6 -0.71 0.00

index p q 0 0.92 0.00 1 0.71 -0.00 2 -0.38 8.00 3 -1.00 0.00 4 -0.38 0.00 5 0.71 0.00 6 0.92 0.00

fft_2d_complex複素 2 次元配列の複素離散 2 次元フーリエ変換を計算します。

概要

#include <imsl.h>

f_complex *imsl_c_fft_2d_complex (int n, int m, f_complex p[], …, 0)d_complex 型関数は、imsl_z_fft_2d_complexです。

必要な引数

int n ( 入力 )2 次元変換の行数。

int m ( 入力 )2 次元変換の列数。

f_complex p[] ( 入力 )変換される数列を含んだサイズ n × m の 2 次元配列。

戻り値

変換された配列のポインター。 この空間を解放するために free を使用しま

す。解が得られない場合,NULL が返されます。この空間を解放するために free を使用します。 値が計算されなければ、NULL が返されます。

オプション引数の概要

#include <imsl.h> f_complex *imsl_c_fft_2d_complex (int n, int m, f_complex p[],

IMSL_P_COL_DIM, int p_col_dim,

Page 364: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_BACKWARD,IMSL_RETURN_USER, f_complex q[],IMSL_Q_COL_DIM, int q_col_dim,0)

オプション引数

IMSL_P_COL_DIM, int p_col_dim ( 入力 )p の列ディメンジョン。

デフォルト: p_col_dim = m

IMSL_BACKWARD後退変換を計算します。

IMSL_RETURN_USER, f_complex q[] ( 出力 )qによって指されるユーザ提供空間に結果が格納されます。 その結果、解の

ための格納場所は割り当てられず、imsl_c_fft_2d_complexは qを

返します。配列 は、少なくとも長さ n × m でなければなりません。

IMSL_Q_COL_DIM, int q_col_dim ( 入力 )qの列ディメンジョン。

デフォルト: q_col_dim = m

説明

関数 imsl_c_fft_2d_complex はサイズ n × m の 2 次元複素配列の離散フー

リエ変換を計算します。使用される方法は n と m の両方が小さい素数因子の

積であるときに最も効率的である Cooley-Tukey アルゴリズムの改良型です。n と m がこの条件を満足するときに計算消費時間は nm log nm に比例します。

デフォルトで imsl_c_fft_2d_complex は次の前進変換を計算します。

次のようにフーリエ逆変換が出来ることに注目します。

この公式は、適切にフーリエ係数を正規化した後で、そのデータに対して三角法補間多項式の係数を得るという事を示しています。関数 imsl_c_fft_2d_complex は国立大気圏研究所の Paul Swarztrauber 氏によって

開発された FFTPACK の complex FFT を基にしています。

オプション IMSL_BACKWARD が選択されると、つぎの計算が実行されます。

前進変換と後退変換の間の関係は、それらが互いに正規化されない逆変換であることです。この事により、次のコード部分が、ベクトル p で始まり、ベクト

ル p 2 = nmp で終わります。

q = imsl_c_fft_2d_complex(n, m, p, 0);

p2 = imsl_c_fft_2d_complex(n, m, q, IMSL_BACKWARD, 0);

例題

例題 1

この例題は 0 ≤ n ≤ 4 と 0 ≤ m ≤ 3 の 5 × 4 配列の純粋振動数入力のフーリエ変換

を計算します。

1 12 / 2 /

0 0

n mijs n ikt m

jk sts t

q p e eπ π− −

− −

= =

= ∑ ∑

1 12 / 2 /

0 0

1 n mijs n ikt m

jk sts t

p q e enm

π π− −

= =

= ∑ ∑

1 12 / 2 /

0 0

n mijs n ikt m

jk sts t

p q e eπ π− −

= =

= ∑ ∑

Page 365: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

その結果、 , は、[2][3] 位置を除いて全てゼロを持ちます。

#include <imsl.h>#include <math.h>#include <stdio.h> main(){ int s, t, n = 5, m =4; float two_pi = 2*imsl_f_constant("pi", 0); f_complex p[5][4], *q, z, w; /* 純粋指数信号で p を埋める */ for (s = 0; s < n; s++) { z.re = 0.; z.im = s*two_pi*2./n; for(t =0; t < m; t++){ w.re = 0.; w.im = t*two_pi*3./m; p[s][t] = imsl_c_mul(imsl_c_exp(z),imsl_c_exp(w)); } } q = imsl_c_fft_2d_complex (n, m, (f_complex*)p, 0); /* 入力をプリント */ imsl_c_write_matrix ("The input matrix is ", 5, 4, (f_complex*)p, IMSL_ROW_NUMBER_ZERO, IMSL_COL_NUMBER_ZERO, 0); imsl_c_write_matrix ("The output matrix is ", 5, 4, q, IMSL_ROW_NUMBER_ZERO, IMSL_COL_NUMBER_ZERO, 0); }

出力結果 The input matrix is 0 1 20 ( 1.000, 0.000) ( 0.000, -1.000) ( -1.000, -0.000)1 ( -0.809, 0.588) ( 0.588, 0.809) ( 0.809, -0.588)2 ( 0.309, -0.951) ( -0.951, -0.309) ( -0.309, 0.951)3 ( 0.309, 0.951) ( 0.951, -0.309) ( -0.309, -0.951)4 ( -0.809, -0.588) ( -0.588, 0.809) ( 0.809, 0.588) 30 ( -0.000, 1.000)1 ( -0.588, -0.809)2 ( 0.951, 0.309)3 ( -0.951, 0.309)4 ( 0.588, -0.809) The output matrix is 0 1 20 ( -0, -0) ( 0, -0) ( 0, -0)1 ( 0, 0) ( 0, -0) ( -0, 0)2 ( -0, -0) ( 0, -0) ( 0, -0)3 ( 0, 0) ( 0, -0) ( -0, 0)4 ( -0, -0) ( 0, -0) ( 0, -0) 30 ( 0, -0)1 ( 0, -0)2 ( 20, 0)3 ( -0, -0)4 ( -0, -0)

2 2 / 2 3 / 4 = i s S itPst e eπ π

p q=

Page 366: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題 2

この例題は、元の数列を回復するために後退変換を使用します。後退変換が続く前進変換は、2 つのディメンジョンの長さの積によって元の数列の入力値を

掛け合わせることに注意してください。

#include <imsl.h>#include <math.h>#include <stdio.h> main(){ int s, t, n = 5, m =4; f_complex p[5][4], *q, *p2; /* 純粋指数信号で p を埋める */ for (s = 0; s < n; s++) { for(t =0; t < m; t++){ p[s][t].re = s + 5*t; p[s][t].im = 0.; } } /* 前進変換 */ q = imsl_c_fft_2d_complex (n, m, (f_complex*)p, 0); /* 後退変換 */ p2 = imsl_c_fft_2d_complex (n, m, q, IMSL_BACKWARD, 0); /* 入力をプリント */ imsl_c_write_matrix ("The input matrix is ", 5, 4, (f_complex*)p, IMSL_ROW_NUMBER_ZERO, IMSL_COL_NUMBER_ZERO, 0); imsl_c_write_matrix ("The output matrix is ", 5, 4, p2, IMSL_ROW_NUMBER_ZERO, IMSL_COL_NUMBER_ZERO, 0); }

出力結果

The input matrix is 0 1 20 ( 0, 0) ( 5, 0) ( 10, 0)1 ( 1, 0) ( 6, 0) ( 11, 0)2 ( 2, 0) ( 7, 0) ( 12, 0)3 ( 3, 0) ( 8, 0) ( 13, 0)4 ( 4, 0) ( 9, 0) ( 14, 0) 30 ( 15, 0)1 ( 16, 0)2 ( 17, 0)3 ( 18, 0)4 ( 19, 0) The output matrix is 0 1 20 ( 0, 0) ( 100, 0) ( 200, 0)1 ( 20, 0) ( 120, 0) ( 220, 0)2 ( 40, 0) ( 140, 0) ( 240, 0)3 ( 60, 0) ( 160, 0) ( 260, 0)4 ( 80, 0) ( 180, 0) ( 280, 0) 30 ( 300, 0)1 ( 320, 0)2 ( 340, 0)3 ( 360, 0)4 ( 380, 0)

Page 367: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

convolutionたたみ込みとオプションで 2 つの実数ベクトルの相関を計算します。

概要

#include <imsl.h>

float *imsl_f_convolution (int nx, float x[], int ny, float y[], int *nz, …, 0)

double 型関数は、 imsl_d_convolutionです。

必要な引数

int nx ( 入力 )ベクトル x の長さ。

float x[] ( 入力 )長さ nx の実数ベクトル。

int ny ( 入力 )ベクトル y の長さ。

float y[] ( 入力 )長さ ny の実数ベクトル。

int *nz ( 出力 )出力ベクトルの長さ。

戻り値

x と y のたたみ込みを含んだ、長さ nz の配列のポインター。この空間を解

放するために free を使用します。ゼロが計算されると NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_f_convolution (int nx, float x[], int ny, float y[], int *nz,

IMSL_PERIODIC,IMSL_CORRELATION,IMSL_FIRST_CALL,IMSL_CONTINUE_CALL,IMSL_LAST_CALL,IMSL_RETURN_USER, float z[],IMSL_Z_TRANS, float **zhatIMSL_Z_TRANS_USER, float *zhat,0)

オプション引数

IMSL_PERIODIC入力は周期的です。

IMSL_CORRELATIONx と y の相関を返します。

IMSL_FIRST_CALL

この関数が同じ nx と ny で何回も呼ばれる場合、最初の呼び出しで

このオプションを選択します。

IMSL_CONTINUE_CALL

この関数が同じ nx と ny で何回も呼ばれる場合、中間の呼び出しで

このオプションを選択します。

IMSL_LAST_CALLこの関数が同じ nx と ny で何回も呼ばれる場合、最後の呼び出しで

このオプションを選択します。

Page 368: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_RETURN_USER, float z[] ( 出力 )たたみ込み、或いは、x と y の相関を含んだ、少なくとも長さ nz のユーザ提供の配列。

IMSL_Z_TRANS, float **zhat[] ( 出力 )出力に z の離散フーリエ変換を含んだ、少なくとも長さ nz の配列へ

のポインターのアドレス。

IMSL_Z_TRANS_USER, float zhat[] ( 出力 )出力に z の離散フーリエ変換を含んだ、少なくとも長さ nz のユーザ

提供の配列。

説明

関数 imsl_f_convolution はデフォルトで 2 つの数列 x と y の離散たたみ

込みを計算します。更に正確には、nx を x の長さ、ny が y の長さを表すもの

とします。もし巡回たたみ込みが必要であれば、IMSL_PERIODIC を選択する

必要があります。次式をセットします。

nz = max {ny, nx},

そして、ゼロで短いベクトルに詰め合わせ、次式を計算します。

ここで x の指標は 1 と nz 、モジュロ nz の間の正数として解釈されます。

z I を計算するために使用されるこの技法は(複素離散)フーリエ変換が、た

たみ込みを乗算に写像する事実に基づいています。こうして、z のフーリエ変換は次式で与えられます。

ここで、以下の式が成立します。

たたみ込みを計算するために、ここで使用されるこの技法は、x と y の離散

フーリエ変換を得て、その結果を成分順に乗算して、この積の逆変換を得ることです。もし、オプション IMSL_PERIODIC が選択されているなら、nz は小さ

い素数の積であることを確かめることがとても重要です。もし nz が小さい素

数の積であれば、その時、計算消費時間は、nz log(nz ) に比例します。もし、

オプション IMSL_PERIODIC が選択されていなければ、フーリエ変換が効率的

で nz ≥ nx + ny − 1 であるように、良い値が nz のために選択されます。 これば、

両方のベクトルがゼロで埋められることを意味しています。

両方の数列は実数であり、実数変換は、上述の複素変換を模擬できるので、x 又は y の複素変換は取られません。このような技法は速度が 6 倍で、複素変換

を使用するときよりも必要になる空間は少なくなります。

オプションで、関数 imsl_f_convolution は 2 つの数列 x と y の離散相関を

計算します。もっと正確には、 n を x と y の長さとしてみます。もし巡回相関

が必要であれば、オプション IMSL_PERIODIC が選択されなければなりませ

ん。次をセットします。

nz = n IMSL_PERIODIC が選択される場合。

(nz = 2a3b5g ≥ 2n − 1) IMSL_PERIODIC が選択されない場合。

11

zn

i i j jj

z x y− +=

= ∑

( ) ( ) ( )ˆ ˆz n x n y n=

( ) ( )( )2 1 1 /

1

ˆz

z

ni m n n

mm

z n z e π− − −

=

= ∑

Page 369: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで α、β と γ は 非負の整数で、不等を満足するタイプ 2α 3β 5γ の小さな

数である。一度 n z が決定されると、このベクトルをゼロで埋め合わせる。そ

の後、以下の式を計算します。

ここで x 上の指標は1と n z 、モジュロ n z の間の正の数と解釈されます。こ

の事は、次を意味することに注意してください。

k = 0, 1, ..., n z /2 として x(k − 1) と y の相関を含みます。こうして全ての k に対

して x(k − 1) = y(k) であれば、

は z の最大成分であることになります。 zi を計算するために使用される技法は、

(複素離散)フーリエ変換が相関を乗算に写像する事実に基づいています。こうして z のフーリエ変換は以下の式で与えられます。

ここで、次式も成立します。

こうして、相関を計算するためにここで使用される技法は、x の離散フーリエ

変換と y の離散フーリエ変換の共役を得て、結果を成分毎に乗算して、この積

の逆変換を得ることです。IMSL_PERIODIC が選択されたると、nz を確実に

小さい素数の積にすることがとても重要です。nz が小さい素数の積であれ

ば、計算消費時間は nz log (nz). に比例します。 IMSL_PERIODIC が選択され

ない場合、フーリエ変換が効率的で、nz ≥ 2n − 1 であるように良好な値が nz のために選ばれます。これは両方のベクトルがゼロで埋められることを意味します。

両方の数列は実数であり、実数変換は、上述の複素変換を模擬できるので、x 又は y の複素変換は取られません。このような技法は、速度が 6 倍で、複素変

換を使用するときよりも必要になる空間は少なくなります。

例題

例題 1

この例題は、非周期的たたみ込みを計算します。ここに使用される考え方は、この関数を使用してデジタルフィルターに存在するこのタイプの移動平均を計算する事が出来ることです。この場合における平均演算子は特に単純で、数列の 5 つの連続点を平均することにより与えられます。ノイズによって汚染された指数関数の値を回復することを試行します。最後の値の大きい誤差は、このたたみ込みが関数値よりも「埋め込み」におけるゼロを平均するという事実で行うことです。 信号サイズは 100 ですが、10 点だけで誤差を報告することに注

意して下さい。

#include "imsl.h"#include <math.h>

#define NFLTR 5#define NY 100

11

zn

i i j jj

z x y+ −=

= ∑

zn kz −

znz

ˆˆ j j jz x y=

( )( )2 1 1 /

1

ˆz

z

ni m j n

j mm

z z e π− − −

=

= ∑

Page 370: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* 関数を定義 */

#define F1(A) exp(A)main(){ int i, k, nz; float fltr[NFLTR], fltrer, origer, total1, total2, twopi, x, y[NY], *z, *noise;

/* フィルタを設定 */ for (i = 0; i < NFLTR; i++) fltr[i] = 0.2; /* * 非周期性の場合の y-ベクトルを設定 */

twopi = 2.0*imsl_f_constant ("Pi", 0); imsl_random_seed_set(1234579); noise = imsl_f_random_uniform(NY, 0);

for (i = 0; i < NY; i++) { x = (float)(i) / (NY - 1); y[i] = F1(x) + 0.5 *noise[i] - 0.25; } /* * 非周期性の場合のたたみ込みルーチンを呼ぶ */

z = imsl_f_convolution(NFLTR, fltr, NY, y, &nz, 0); /* * z と zhat をチエックするためにテストルーチンを呼び結果をプリント */ printf("\n Nonperiodic Case\n"); printf(" x F1(x) Original Error"); printf(" Filtered Error\n");

total1 = 0.0; total2 = 0.0; for (i = 0; i < NY; i++) { if (i >= NY-2) k = i - NY + 2; else k = i + 2; x = (float)(i) / (float) (NY - 1); origer = fabs(y[i] - F1(x)); fltrer = fabs(z[i+2] - F1(x)); if ((i % 11) == 0) { printf(" %10.4f%13.4f%18.4f%18.4f\n", x, F1(x), origer, fltrer); } total1 += origer; total2 += fltrer; } printf(" Average absolute error before filter:%10.5f\n", total1 / (NY)); printf(" Average absolute error after filter:%11.5f\n", total2 / (NY));

}

出力結果

Nonperiodic Case x F1(x) Original Error Filtered Error 0.0000 1.0000 0.0811 0.3523 0.1111 1.1175 0.0226 0.0754

Page 371: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

0.2222 1.2488 0.1526 0.0488 0.3333 1.3956 0.0959 0.0161 0.4444 1.5596 0.1747 0.0276 0.5556 1.7429 0.1035 0.0250 0.6667 1.9477 0.0402 0.0562 0.7778 2.1766 0.0673 0.0835 0.8889 2.4324 0.1044 0.0050 1.0000 2.7183 0.0154 1.1255Average absolute error before filter: 0.12481Average absolute error after filter: 0.06785

例題 2

この例題は 2 つの区別される信号 x と y の間の周期的相関の両方を計算しま

す。区間 [0, 2π] に 100 の等間隔点が存在し、 f 1 (x) = sin (x) です。x と y を次式

で定義します。

z の最大値 (x との相関) はオフセットに対応する i = 25 で発生することに注意

してください。

#include "imsl.h"#include <math.h>

#define N 100

/* 関数を定義 */

#define F1(A) sin(A)

main(){ int i, k, nz; float pi, max, x[N], y[N], *z, xnorm, ynorm;

/* * 非周期性の場合の y-ベクトルを設定 */

pi = imsl_f_constant ("Pi", 0);

for (i = 0; i < N; i++) { x[i] = F1(2.0*pi*(float)(i) / (N-1)); y[i] = F1(2.0*pi*(float)(i) / (N-1) + pi/2.0); } /* * 非周期性の場合の相関関数を呼び出す */

z = imsl_f_convolution(N, x, N, y, &nz, IMSL_CORRELATION, IMSL_PERIODIC,0);

xnorm = imsl_f_vector_norm (N, x, 0); ynorm = imsl_f_vector_norm (N, y, 0); for (i = 0; i < N; i++) { z[i] /= xnorm*ynorm; }

max = z[0]; k = 0; for (i = 1; i < N; i++) {

1

1

2 0, , 11

2 0, , 11 2

i

i

ix f i nn

iy f i nn

π

π π

= = − − = + = − −

K

K

Page 372: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

if (max < z[i]) { max = z[i]; k = i; } }

printf("The element of Z with the largest normalized\n"); printf("value is Z(%2d).\n", k); printf("The normalized value of Z(%2d) is %6.3f\n", k, z[k]); }

出力結果

The element of Z with the largest normalizedvalue is Z(25).The normalized value of Z(25) is 1.000

convolution (複素数 )たたみ込みとオプションで 2 つの複素数ベクトルの相関を計算します。

概要

#include <imsl.h>

f_complex *imsl_c_convolution (int nx, f_complex x[], int ny, f_complex y[], int *nz, …, 0)

double 型関数は、imsl_d_convolutionです。

必要な引数

int nx ( 入力 )ベクトル x の長さ。

f_complex x[] ( 入力 )長さ nx の実数ベクトル。

int ny ( 入力 )ベクトル y の長さ。

f_complex y[] ( 入力 )長さ ny の実数ベクトル。

int *nz ( 出力 )出力ベクトルの長さ。

戻り値

x と y のたたみ込みを含んだ、長さ nz の配列のポインター。この空間を解放

するために free を使用します。ゼロが計算されると NULL が返されます。

オプション引数の概要

#include <imsl.h>

f_complex *imsl_c_convolution (int nx, f_complex x[], int ny, f_complex y[], int*nz,IMSL_PERIODIC,IMSL_CORRELATION,IMSL_FIRST_CALL,IMSL_CONTINUE_CALL,IMSL_LAST_CALL,IMSL_RETURN_USER, f_complex z[],IMSL_Z_TRANS, f_complex **zhatIMSL_Z_TRANS_USER, f_complex *zhat,0)

Page 373: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数

IMSL_PERIODIC入力は周期的です。

IMSL_CORRELATIONx と y の相関を返します。

IMSL_FIRST_CALL

この関数が同じ nx と ny で何回も呼ばれる場合、最初の呼び出しでこ

のオプションを選択します。

IMSL_CONTINUE_CALL

この関数が同じ nx と ny で何回も呼ばれる場合、中間の呼び出しでこ

のオプションを選択します。

IMSL_LAST_CALL

この関数が同じ nx と ny で何回も呼ばれる場合、最後の呼び出しでこ

のオプションを選択します。

IMSL_RETURN_USER, f_complex z[] ( 出力 )たたみ込み、或いは、x と y の相関を含んだ、少なくとも長さ nz のユーザ提供の配列。

IMSL_Z_TRANS, f_complex **zhat[] ( 出力 )出力に z の離散フーリエ変換を含んだ、少なくとも長さ nz の配列へ

のポインターのアドレス。

IMSL_Z_TRANS_USER, f_complex zhat[] ( 出力 )出力に z の離散フーリエ変換を含んだ、少なくとも長さ nz のユーザ提

供の配列。

説明

関数 imsl_c_convolution はデフォルトで 2 つの数列 x と y の離散たたみ

込みを計算します。更に正確には、nx を x の長さ、ny が y の長さを表すもの

とします。もし巡回たたみ込みが必要であれば、IMSL_PERIODIC を選択する

必要があります。次式をセットします。

nz = max {ny, nx}

そして、ゼロで短いベクトルに詰め合わせ、次式を計算します。

ここで x の指標は 1 と nz 、モジュロ nz の間の正数として解釈されます。

z I を計算するために使用されるこの技法は(複素離散)フーリエ変換が、た

たみ込みを乗算に写像する事実に基づいています。こうして、z のフーリエ変換は次式で与えられます。

ここで、以下の式が成立します。

たたみ込みを計算するために、ここで使用されるこの技法は、x と y の離散

フーリエ変換を得て、その結果を成分順に乗算して、この積の逆変換を得ることです。もし、オプション IMSL_PERIODIC が選択されているなら、nz は小さ

い素数の積であることを確かめることがとても重要です。もし nz が小さい素

11

zn

i i j jj

z x y− +=

= ∑

( ) ( ) ( )ˆ ˆz n x n y n=

( ) ( )( )2 1 1 /

1

ˆz

z

ni m n n

mm

z n z e π− − −

=

= ∑

Page 374: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

数の積であれば、その時、計算消費時間は、nz log(nz ) に比例します。もし、

オプション IMSL_PERIODIC が選択されていなければ、フーリエ変換が効率的

で nz ≥ nx + ny − 1 であるように、良い値が nz のために選択されます。 これば、

両方のベクトルがゼロで埋められることを意味しています。

オプションで、関数 imsl_c_convolution は 2 つの数列 x と y の離散相関を

計算します。もっと正確には、 n を x と y の長さとしてみます。もし巡回相関

が必要であれば、オプション IMSL_PERIODIC が選択されなければなりませ

ん。次をセットします。

nz = n IMSL_PERIODIC が選択される場合。

(nz = 2α3β5γ ≥ 2n − 1)  IMSL_PERIODIC が選択される場合。

ここで α、β と γ は 非負の整数で、不等を満足するタイプ 2α 3β 5γ の小さな

数である。一度 n z が決定されると、このベクトルをゼロで埋め合わせる。そ

の後、以下の式を計算します。

ここで x 上の指標は1と n z 、モジュロ n z の間の正の数と解釈されます。こ

の事は、次を意味することに注意してください。

k = 0, 1, ..., n z /2 として x(k − 1) と y の相関を含みます。こうして全ての k に対

して x(k − 1) = y(k) であれば、

は z の最大成分であることになります。 zi を計算するために使用される技法は、

(複素離散)フーリエ変換が相関を乗算に写像する事実に基づいています。

こうして z のフーリエ変換は以下の式で与えられます。

ここで、次式も成立します。

こうして、相関を計算するためにここで使用される技法は、x の離散フーリエ

変換と y の離散フーリエ変換の共役を得て、結果を成分毎に乗算して、この積

の逆変換を得ることです。IMSL_PERIODIC が選択されたると、nz を確実に

小さい素数の積にすることがとても重要です。nz が小さい素数の積であれ

ば、計算消費時間は nz log (nz). に比例します。 IMSL_PERIODIC が選択され

ない場合、フーリエ変換が効率的で、nz ≥ 2n − 1 であるように良好な値が nz のために選ばれます。これは両方のベクトルがゼロで埋められることを意味します。

両方の数列は実数であり、実数変換は、上述の複素変換を模擬できるので、x 又は y の複素変換は取られません。このような技法は、速度が 6 倍で、複素変

換を使用するときよりも必要になる空間は少なくなります。

11

zn

i i j jj

z x y+ −=

= ∑

zn kz −

znzℜ

ˆˆ j j jz x y=

( )( )2 1 1 /

1

ˆz

z

ni m j n

j mm

z z e π− − −

=

= ∑

Page 375: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

例題 1

この例題は、非周期的たたみ込みを計算します。ここに使用される考え方は、この関数を使用してデジタルフィルターに存在するこのタイプの移動平均を計算する事が出来ることです。この場合における平均演算子は特に単純で、数列の 5 つの連続点を平均することにより与えられます。ノイズによって汚染された指数関数の値を回復することを試行します。最後の値の大きい誤差は、このたたみ込みが関数値よりも「埋め込み」におけるゼロを平均するという事実で行うことです。 信号サイズは 100 ですが、10 点だけで誤差を報告することに注

意して下さい。

#include "imsl.h"#include <math.h>

#define NFLTR 5#define NY 100

#define F1(A) (imsl_c_mul(imsl_cf_convert(exp(A),0.0), \ imsl_cf_convert(cos(A),sin(A)) ))

main(){ int i, nz; f_complex fltr[NFLTR], temp, y[NY], *z; float x, twopi, total1, total2, *noise, origer, fltrer;

/* フィルターを設定 */ for (i = 0; i < NFLTR; i++) fltr[i] = imsl_cf_convert(0.2,0.0); /* 非周期性の場合の y-ベクトルを設定 */ twopi = 2.0*imsl_f_constant ("Pi", 0); imsl_random_seed_set(1234579); noise = imsl_f_random_uniform(2*NY, 0);

for (i = 0; i < NY; i++) { x = (float)(i) / (NY - 1); temp = imsl_cf_convert(0.5*noise[i]-0.25, 0.5*noise[NY+i]-0.25); y[i] = imsl_c_add(F1(x), temp); } /* 周期性の場合のたたみ込みルーチンを呼ぶ */ z = imsl_c_convolution(NFLTR, fltr, NY, y, &nz, 0);

/* 結果をプリント */ printf(" Periodic Case\n"); printf(" x F1(x) Original Error"); printf(" Filtered Error\n"); total1 = 0.0; total2 = 0.0; for (i = 0; i < NY; i++) { x = (float)(i) / (NY - 1); origer = imsl_c_abs(imsl_c_sub(y[i],F1(x))); fltrer = imsl_c_abs(imsl_c_sub(z[i+2],F1(x))); if ((i % 11) == 0) printf(" %10.4f (%6.4f,%6.4f) %12.4f %15.4f\n", x, (F1(x)).re, (F1(x)).im, origer, fltrer); total1 += origer; total2 += fltrer; } printf(" Average absolute error before filter:%10.5f\n", total1 / (NY)); printf(" Average absolute error after filter:%11.5f\n",

Page 376: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

total2 / (NY));}

出力結果

Periodic Case x F1(x) Original Error Filtered Error 0.0000 (1.0000,0.0000) 0.1684 0.3524 0.1111 (1.1106,0.1239) 0.0582 0.0822 0.2222 (1.2181,0.2752) 0.1991 0.1054 0.3333 (1.3188,0.4566) 0.1487 0.1001 0.4444 (1.4081,0.6706) 0.2381 0.1004 0.5556 (1.4808,0.9192) 0.1037 0.0708 0.6667 (1.5307,1.2044) 0.1312 0.0904 0.7778 (1.5508,1.5273) 0.1695 0.0856 0.8889 (1.5331,1.8885) 0.1851 0.0698 1.0000 (1.4687,2.2874) 0.2130 1.0760Average absolute error before filter: 0.19057Average absolute error after filter: 0.10024

例題 2

この例題は 2 つの区別される信号 x と y の間の周期的相関の両方を計算しま

す。区間 [0, 2π] に 100 の等間隔点が存在し、 f 1 (x) = cos (x) + i sin (x) です。x と y を次式で定義します。

z の最大値 (x との相関) はオフセットに対応する i = 25 で発生することに注意

してください。

#include "imsl.h"#include <math.h>

#define N 100

/* 関数を定義 */

#define F1(A) imsl_cf_convert(cos(A),sin(A))

main(){ int i, k, nz; float zreal[4*N], pi, max, xnorm, ynorm, sumx, sumy; f_complex x[N], y[N], *z;

/* 非周期性の場合の y-ベクトルを設定 */ pi = imsl_f_constant ("Pi", 0);

for (i = 0; i < N; i++) { x[i] = F1(2.0*pi*(float)(i) / (N-1)); y[i] = F1(2.0*pi*(float)(i) / (N-1) + pi/2.0); } /* 周期性の場合のたたみ込みルーチンを呼ぶ */

z = imsl_c_convolution(N, x, N, y, &nz, IMSL_CORRELATION, IMSL_PERIODIC,0);

sumx = sumy = 0.0; for (i = 0; i < N; i++) { sumx += imsl_c_abs(imsl_c_mul(x[i], x[i]));

( )

( )

1

1

2 11, ,

1

2 11, ,

1 2

i

i

ix f i n

n

iy f i n

n

π

π π

− = =

− −

= + = −

K

K

Page 377: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

sumy += imsl_c_abs(imsl_c_mul(y[i], y[i])); } xnorm = sqrt((sumx)); ynorm = sqrt((sumy)); for (i = 0; i < N; i++) { zreal[i] = (z[i].re/(xnorm*ynorm)); }

max = zreal[0]; k = 0; for (i = 1; i < N; i++) { if (max < zreal[i]) { max = zreal[i]; k = i; } }

printf("The element of Z with the largest normalized\n"); printf("value is Z(%2d).\n", k); printf("The normalized value of Z(%2d) is %6.3f\n", k, zreal[k]); }

出力結果

The element of Z with the largest normalizedvalue is Z(25).The normalized value of Z(25) is 1.000

inverse_laplace 複素関数の逆ラプラス変換を計算します。

概要

#include <imsl.h>

float *imsl_f_inverse_laplace (f_complex fcn(), float sigma0, int n, float t[], …, 0)

double 型関数は、 imsl_d_inverse_laplaceです。

必要な引数

f_complex fcn(f_complex z) ( 入力 )逆ラプラス変換が計算されるユーザ提供の関数。

float sigma0 ( 入力 )fcn の特異点の実数部分の最大値の推定値。 分からなければ、sigma0 = 0.0 とセットします。

int n ( 入力 )逆ラプラス変換が望まれる点数。

float t[] ( 入力 )逆ラプラス変換が望まれるサイズ n の配列。

戻り値

長さ n の配列のポインターで、その i 番目の成分が点 t[i] の逆ラプラス変換の

近似値を含みます。この空間を解放するために free を使用します。解が得ら

れない場合,NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_inverse_laplace (f_complex fcn(), float sigma0, int n, float t[],

Page 378: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_RETURN_USER, float x[], IMSL_PSEUDO_ACCURACY, float pseudo_accuracy,IMSL_FIRST_LAGUERRE_PARAMETER, float sigma,IMSL_SECOND_LAGUERRE_PARAMETER, float bvalue,IMSL_MAXIMUM_COEFFICIENTS, int mtop,IMSL_ERROR_EST, float *error_est,IMSL_DISCRETIZATION_ERROR_EST, float *disc_error_est,IMSL_TRUNCATION_ERROR_EST, float *trunc_error_est,IMSL_CONDITION_ERROR_EST, float *cond_error_est,IMSL_DECAY_FUNCTION_COEFFICIENT, float *k,IMSL_DECAY_FUNCTION_BASE, float *r,IMSL_LOG_LARGEST_COEFFICIENTS, float *log_largest_coefs,IMSL_LOG_SMALLEST_COEFFICIENTS, float *log_smallest_coefs,IMSL_UNDER_OVERFLOW_INDICATORS, Imsl_laplace_flow *indicators,IMSL_FCN_W_DATA, f_complex fcn ( ), void *data,0)

オプション引数

IMSL_RETURN_USER, float x[] ( 出力 )逆ラプラス変換の近似値を含む長さ n のユーザ提供の配列。

IMSL_PSEUDO_ACCURACY, float pseudo_accuracy ( 入力 )係数と逆ラプラス変換値の必要な絶対一様疑似精度。

デフォルト: pseudo_accuracy = 。ε は、マシン精度。

IMSL_FIRST_LAGUERRE_PARAMETER, float sigma ( 入力 )ラゲール展開の最初のパラメータ。 sigma が sigma0 より大きくなけ

れば、sigma0+ 0.7 にリセットします。

デフォルト: sigma = sigma0 + 0.7

IMSL_SECOND_LAGUERRE_PARAMETER, float bvalue ( 入力 )ラゲール展開の2番目のパラメータ。bvalue が 2.0*(sigma − sigma0) より小さければ、それを 2.5*(sigma − sigma0) にリセット

します。デフォルト: bvalue = 2.5*(sigma − sigma0)

IMSL_MAXIMUM_COEFFICIENTS, int mtop ( 入力 )ラゲール展開で計算される係数の数の上限。引数 mtop は 4 の倍数で

なくてはなりません。デフォルト: mtop = 1024

IMSL_ERROR_EST, float *error_est ( 出力 )疑似誤差の全体推定量、 disc_error_est + trunc_error_est + cond_error_est。詳細は説明の欄を参照してください。

IMSL_DISCRETIZATION_ERROR_EST, float *disc_error_est ( 出力 )疑似打ち切り誤差の推定値。

IMSL_TRUNCATION_ERROR_EST, float *trunc_error_est ( 出力 )疑似切り捨て誤差の推定値。

IMSL_CONDITION_ERROR_EST, float *cond_error_est ( 出力 )関数値における最小ノイズレベルの規準上の疑似条件誤差の推定値。

IMSL_DECAY_FUNCTION_COEFFICIENT, float *k ( 出力 )減衰関数の係数。詳細は説明の欄を参照してください。

IMSL_DECAY_FUNCTION_BASE, float *r ( 出力 )減衰関数の基底。詳細は説明の欄を参照してください。

IMSL_LOG_LARGEST_COEFFICIENTS, float *log_largest_coefs ( 出力 )減衰関数の最大 coefficient の対数。詳細は説明の欄を参照してく

ださい。

ε

Page 379: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_LOG_SMALLEST_COEFFICIENTS, float *log_smallest_coefs ( 出力 )減衰関数の最小非ゼロ coefficient の対数。詳細は説明の欄を参照

してください。

IMSL_UNDER_OVERFLOW_INDICATORS, Imsl_laplace_flow **indicators ( 出力 )計算された近似逆ラプラス変換の、オーバーフロー / アンダーフロー

指示標識を含んだ長さ n の配列を指す imsl_f_inverse_laplace によって初期化されたポインターのアドレス。変換が計算された i 番目

の点に対して、指示標識は次を意味します。

IMSL_FCN_W_DATA, f_complex fcn(f_complex z, void *data) ,void *data, ( 入力 )逆 Laplace 変換を行うためのユーザ提供の関数。また、ユーザにより

提供されたデータへのポインターも受け入れます。 data は、ユーザ提

供の関数にデータを受け渡すポインターです。 詳細は、「イントロダク

ション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_inverse_laplace は複素値関数の逆ラプラス変換を計算しま

す。f が負の実数軸で消失する関数であるならば、f のラプラス変換は、次式で

定義されます。

s のある値に対して、積分関数は絶対的に積分可能であることが想定されま

す。

逆ラプラス変換のこの計算は Garbow その他 (1988 年 ) による Weeks の方法 (Weeks (1966 年 ) 参照 ) が基になっています。 f が [0, ∞] 上で全ての次数の連続

微係数を持つときにこの方法は適切です。特に、複素値関数 F(s) = L[f] (s) が与

えられると、f はその係数が F によって終了するラゲール級数に展開すること

ができます。この事は Garbow その他 (1988 年 ) と Lyness と Giunta (1986 年 ) で全て説明されています。

このアルゴリズムは、次式を満たす f(t) に対して近似 g(t) を返します。

指示標識 [i] 意味IMSL_NORMAL_TERMINATION 通常終了IMSL_TOO_LARGE 逆ラプラス変換の値は表現するに

は大きすぎます。この結果の要素は NaN に設定されます。

IMSL_TOO_SMALL 逆ラプラス変換の値は、表現するには小さすぎます。この結果の要素は 0.0 に設定されます。

IMSL_TOO_LARGE_BEFORE_EXPANSION 逆ラプラス変換の値は、級数展開の前でさえ、表現されるには大き過ぎると推定されます。この結果の要素は NaN に設定されます。

IMSL_TOO_SMALL_BEFORE_EXPANSON 逆ラプラス変換の値は、級数展開の前でさえ、表現されるにはも小さ過ぎると推定されます。この結果の要素は 0.0 に設定されます。

[ ]( ) ( )0

sxL f s e f x dx∞ −= ∫

( ) ( )t

g t f teσ ε−

<

Page 380: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで ε= pseudo_accuracy、そして σ = sigma > sigma0 です。 左の式

は疑似誤差と呼ばれます。疑似誤差の推定値は error_est で利用されます。

この方法の最初のステップは F を φ に変換することです。

それから、 f が平滑であれば、φ は複素平面の単位円盤で解析的であることが

知られていますので、テイラー級数展開を持ちます。

それは、その絶対値が収束半径 R c よりは小さい全ての z に対して収束しま

す。この数値はオプション引数 IMSL_DECAY_FUNCTION_BASE により得られる r で推定されます。. オプション引数 IMSL_DECAY_FUNCTION_COEFFICIENT を使

用すると最少数 K が次式を満足して推定されます。

全ての R < Rc に対して

φ に対するテイラー級数の係数は、ラゲール級数の f を展開するために使用す

ることが出来ます。

例題

例題 1

この例題は、関数 (s − 1)-2 の逆ラプラス変換を計算して、計算された近似値、

正しい変換値、5 点の差分をプリントします。正しい逆変換は、xex です。 Abramowitz と Stegun (1964 年 ) に由来します。

#include <imsl.h>#include <math.h>

main(){ f_complex f(f_complex); int n = 5; float t[5]; float true_inverse[5]; float relative_diff[5]; int i; float *inverse;

/* t を初期化して、逆変換を計算 */ for (i=0; i<n; i++) t[i] = (float)i + 0.5;

inverse = imsl_f_inverse_laplace(f, 1.5, n, t, 0);

/* 正しい逆変換、相対偏差を計算 */

for (i=0; i<n; i++) { true_inverse[i] = t[i]*exp(t[i]); relative_diff[i] = fabs(inverse[i] - true_inverse[i])/

( ) ( )1 1 2

b b bz Fz z

φ σ= − +− −

( )0

ss

sz a zφ

=

= ∑

| |s s

KaR

<

( ) ( )/ 2

0

t bts s

sf t e a e L btσ

∞−

=

= ∑

Page 381: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

true_inverse[i]; }

printf("\t t\t\t f_inv\t\t true\t\t diff\n"); for (i=0; i<n; i++) printf ("\t%5.1f\t\t%7.3f\t\t%7.3f\t\t%6.1e\n", t[i], inverse[i], true_inverse[i], relative_diff[i]);

}

f_complex f(f_complex s){ /* 1/(s-1)**2を返す */

f_complex one = {1.0, 0.0};

return (imsl_c_div(one, imsl_c_mul(imsl_c_sub(s, one), imsl_c_sub(s, one))));}

出力結果

t f_inv true diff 0.5 0.824 0.824 1.5e-05 1.5 6.722 6.723 1.0e-05 2.5 30.456 30.456 5.6e-07 3.5 115.906 115.904 1.8e-05 4.5 405.054 405.077 5.8e-05

例題 2

この例題は関数 e –1/s /s の逆ラプラス変換を計算して、計算された近似値、正

しい変換値、5点の差分をプリントします。これに加えて、逆変換はユーザ提供の空間に返されて、逆変換の必要な精度が指定されます。正しい逆変換は、次の様になります。

Abramowitz と Stegun (1964 年 ) に由来します。

#include <imsl.h>#include <math.h>

main(){ f_complex f(f_complex); int n = 5; int i; float t[5]; float true_inverse[5]; float relative_diff[5]; float inverse[5]; Imsl_laplace_flow *indicators;

/* t を初期化し、逆変換を計算 */

for (i=0; i<n; i++) t[i] = (float)i + 0.5;

imsl_f_inverse_laplace(f, 0.0, n, t, IMSL_PSEUDO_ACCURACY, 1.0e-6, IMSL_UNDER_OVERFLOW_INDICATORS, &indicators, IMSL_RETURN_USER, inverse, 0); /* 正しい逆変換と相対偏差を計算 */

for (i=0; i<n; i++) { true_inverse[i] = imsl_f_bessel_J0(2.0*sqrt(t[i])); relative_diff[i] = fabs((inverse[i] - true_inverse[i])/

( )0 2J x

Page 382: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

true_inverse[i]); }

/* 結果がオーバーフローかアンダーフローかを

知らせ、結果をプリント */

printf("\t T\t\t f_inv\t\t true\t\t diff\n"); for (i=0; i<n; i++) if (indicators[i] == IMSL_NORMAL_TERMINATION) printf ("\t%5.1f\t\t%7.3f\t\t%7.3f\t\t%6.1e\n", t[i], inverse[i], true_inverse[i], relative_diff[i]); else printf("Overflow or underflow noted.\n");}

f_complex f(f_complex s){

/* (1/s)(exp(-1/s)を返す */

f_complex one = {1.0, 0.0}; f_complex s_inverse;

s_inverse = imsl_c_div(one, s); return (imsl_c_mul(s_inverse, imsl_c_exp(imsl_c_neg(s_inverse))));}

出力結果

T f_inv true diff 0.5 0.559 0.559 2.1e-07 1.5 -0.023 -0.023 8.5e-06 2.5 -0.310 -0.310 9.6e-08 3.5 -0.401 -0.401 7.4e-08 4.5 -0.370 -0.370 6.4e-07

Page 383: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

第 7章:非線形方程式

ルーチン

多項式のゼロ点Jenkins-Traub 法を用いた実係数 . . . . . . . . . . . . zeros_poly 383Jenkins-Traub 法を用いた複素係数 . . . . . . zeros_poly (複素数 ) 385

関数のゼロ点実関数の実ゼロ点 . . . . . . . . . . . . . . . . . . zeros_fcn 387

連立方程式の根Powell のハイブリッド法 . . . . . . . . . . . . . zeros_sys_eqn 391

使用上の注意

多項式のゼロ点

次数 n の多項式関数は次のように表すことができます。

p(z) = anzn + an-1 zn-1 + … + a1z + a0

ここで、an ≠ 0 です。関数 imsl_f_zeros_poly は Jenkins-Traub 法を使用し

て、実係数の多項式のゼロ点を見つけます。

関数のゼロ点

関数 imsl_f_zeros_fcn は Müllerの方法を使用して、実数値関数の実数ゼ

ロ値を見つけます。

連立方程式の根

連立方程式は次のように述べることができます。

fi(x) = 0, for i = 1, 2, …, n

ここでは、 x ∈ R n 、そして fi : R n −> R です。関数 imsl_f_zeros_sys_eqn は非線形連立方程式のゼロ点を見つけるために、M.J.D. Powell による修正ハイブ

リッド法を使用します。

zeros_polyJenkins-Traub の3段階アルゴリズムを使用して、実係数の多項式のゼロ点を見

つけます。

概要

#include <imsl.h>

f_complex *imsl_f_zeros_poly (int ndeg, float coef[], …, 0)d_complex 型関数は、 imsl_d_zeros_polyです。

Page 384: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

int ndeg ( 入力 )多項式の次数。Degree of the polynomial.

float coef[] ( 入力 )ndeg + 1 要素を持つ配列で、次数による増加順の多項式の係数を含み

ます。その多項式は、以下のようになります。 coef[n] zn + coef [n − 1] zn-1 + … + coef [0]、ここで n = ndegです。

戻り値

多項式のゼロ点の複素配列のポインター。この空間を解放するために free を使用します。 ゼロ点が計算されなければ、NULL が返されます。

オプション引数の概要

#include <imsl.h>f_complex *imsl_f_zeros_poly (int ndeg, float coef[],

IMSL_RETURN_USER, f_complex root[],0)

オプション引数

IMSL_RETURN_USER, f_complex root[] ( 出力 )多項式のゼロ点を含む ndeg 要素の配列。

説明

関数 imsl_f_zeros_poly は次の多項式の n ゼロ点を計算します。

ここに i = 0, 1, ..., n に対する係数 ai は実数で、n は多項式の係数です。

関数 imsl_f_zeros_poly は Jenkins-Traub、三段階アルゴリズム (Jenkins と Traub 1970 年 ; Jenkins 1975 年 ) を使用します。ゼロ点は 実数ゼロに対して一度

に1つ、又は、複素共役の組に対して、一度に2つが計算されます。ゼロ点が見つけられると、実数ゼロ点、又は、二次因子が多項式剰余によって除かれます。

例題 1

この例題は次の三次多項式のゼロ点を見つけます。

p(z) = z3 − 3z2 + 4z − 2

ここで z は複素変数です。

#include <imsl.h>

#define NDEG 3

main(){ f_complex *zeros; static float coeff[NDEG + 1] = {-2.0, 4.0, -3.0, 1.0};

zeros = imsl_f_zeros_poly(NDEG, coeff, 0);

imsl_c_write_matrix ("The complex zeros found are", 1, 3, zeros, 0);}

( ) 11 1 0

n nn np z a z a z a z a−

−= + + + +K

Page 385: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

The complex zeros found are 1 2 3( 1, 0) ( 1, 1) ( 1, -1)

例題 2

同じ問題を IMSL_RETURN_USER オプションを使用して解きます。

#include <imsl.h>

#define NDEG 3

main(){ f_complex zeros[3]; static float coeff[NDEG + 1] = {-2.0, 4.0, -3.0, 1.0};

imsl_f_zeros_poly(NDEG, coeff, IMSL_RETURN_USER, zeros, 0);

imsl_c_write_matrix ("The complex zeros found are", 1, 3, zeros, 0);}

出力結果 The complex zeros found are 1 2 3( 1, 0) ( 1, 1) ( 1, -1)

警告エラー

IMSL_ZERO_COEFF この多項式の最初の幾つかの係数がゼロに

等しくなります。最後の幾つかの根は、この問題を代償するためにマシン無限大にセットされます。

IMSL_FEWER_ZEROS_FOUND ndeg ゼロより少ない根が見つかりました。

根ベクトルはゼロを含まない場所にマシン無限大の値を含みます。

zeros_poly (複素数 )Jenkins-Traub の3段階アルゴリズムを使用して、複素係数の多項式のゼロ点を

見つけます。

概要

#include <imsl.h>

f_complex *imsl_c_zeros_poly (int ndeg, f_complex coef[], …, 0)d_complex 型関数は、 imsl_z_zeros_polyです。

必要な引数

int ndeg ( 入力 )多項式の次数。

f_complex coef[] ( 入力 )ndeg + 1 要素を持つ配列で、次数による増加順の多項式の係数を含み

ます。その多項式は次の様になります。

coef [n] zn + coef [n − 1] zn-1 + … + coef [0]

ここで、 n = ndegです。

Page 386: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

多項式のゼロ点の複素配列のポインター。この空間を解放するために free を使

用します。 ゼロ点が計算されなければ、NULL が返されます。

オプション引数の概要

#include <imsl.h>

f_complex *imsl_c_zeros_poly (int ndeg, f_complex coef[],IMSL_RETURN_USER, f_complex root[],0)

オプション引数

IMSL_RETURN_USER, f_complex root[] ( 出力 )多項式のゼロ点を含む ndeg 要素の配列。

説明

関数 imsl_c_zeros_poly は次の多項式の n ゼロ点を計算します。

p(z) = anzn + an-1 zn-1 + … + a1z + a0

ここに i = 0, 1, ..., n に対する係数 ai は実数で、n は多項式の係数です。

関数 imsl_c_zeros_poly は Jenkins-Traub、三段階複素アルゴリズム (Jenkins と Traub 1970 年 ; Jenkins 1975 年 ) を使用します。ゼロ点は 対数係数の増加す

る順に、一つづつ計算されます。各ゼロ点が見つけられると、多項式は一つしたの次数に減次じされます。

例題 1

この例題は次の三次多項式のゼロ点を見つけます。

p(z) = z3 − (3 + 6i) z2 − (8 − 12i) z + 10

ここで z は複素変数です。

#include <imsl.h>

#define NDEG 3

main(){ f_complex *zeros; f_complex coeff[NDEG + 1] = { {10.0, 0.0}, {-8.0, 12.0}, {-3.0, -6.0}, { 1.0, 0.0} };

zeros = imsl_c_zeros_poly(NDEG, coeff, 0);

imsl_c_write_matrix ("The complex zeros found are", 1, 3, zeros, 0);}

出力結果 The complex zeros found are 1 2 3( 1, 1) ( 1, 2) ( 1, 3)

例題 2

同じ問題を IMSL_RETURN_USER オプションを使用して解きます。

#include <imsl.h>

#define NDEG 3

main(){ f_complex zeros[3];

Page 387: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

f_complex coeff[NDEG + 1] = { {10.0, 0.0}, {-8.0, 12.0}, {-3.0, -6.0}, { 1.0, 0.0} };

imsl_c_zeros_poly(NDEG, coeff, IMSL_RETURN_USER, zeros, 0);

imsl_c_write_matrix ("The complex zeros found are", 1, 3, zeros, 0);}

出力結果

The complex zeros found are 1 2 3( 1, 1) ( 1, 2) ( 1, 3)

警告エラー

IMSL_ZERO_COEFF この多項式の最初の幾つかの係数がゼロに

等しくなります。最後の幾つかの根は、この問題を代償するためにマシン無限大にセットされます。

IMSL_FEWER_ZEROS_FOUND ndeg ゼロより少ない根が見つかりました。

根ベクトルはゼロを含まない場所にマシン無限大の値を含みます。

zeros_fcnMüller の方法を使用して実関数の実ゼロ点を見つけます。

概要

#include <imsl.h>float *imsl_f_zeros_fcn (float fcn(), …, 0)

double 型関数は、imsl_d_zeros_fcnです。

必要な引数

float fcn (float x) ( 入力 / 出力 )ゼロが見つけられる関数の値を計算するためにユーザが提供する関数で、x はこの関数が計算される点。

戻り値

関数のゼロ x のポインター。この空間を解放するために free を使用します。

ゼロが見つけられなければ NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_f_zeros_fcn (float fcn(),

IMSL_XGUESS, float xguess[],IMSL_NUM_ROOTS, int nroot,IMSL_ERR_ABS, float err_abs,IMSL_ERR_REL, float err_rel,IMSL_ETA, float eta,IMSL_EPS, float eps,IMSL_MAX_ITN, int max_itn,IMSL_RETURN_USER, float x[],IMSL_INFO, int **info,IMSL_INFO_USER, int info[],IMSL_FCN_W_DATA, float fcn ( ), void *data,0)

Page 388: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数

IMSL_XGUESS, float xguess[] ( 入力 )ゼロの初期値を含んだ nroot 要素の配列。

デフォルト: xguess = 0

IMSL_NUM_ROOTS, int nroot ( 入力 )imsl_f_zeros_fcn によって見つけられるゼロの数。

デフォルト: nroot = 1

IMSL_ERR_ABS, float err_abs ( 入力 )最初の停止規準。|f(xi)| < err_absの場合、ゼロ xi は受け入れられま

す。デフォルト:

where e は、マシン精度です。

IMSL_ERR_REL, float err_rel ( 入力 )二番目の停止規準。xi の2つの連続する近似の相対変化が err_rel より小さい場合は、ゼロ xi は受け入れられます。

デフォルト:

where ε は、マシン精度です。

IMSL_ETA, float eta ( 入力 )多数のゼロ点の拡大規準。もしゼロ xi が計算されて、| xi − xj | < eps の時 xj は以前に計算されたゼロ点である場合、計算は xi + eta に等しい

初期値でリスタートします。デフォルト: eta = 0.01

IMSL_EPS, float eps ( 入力 )eta を参照してください。

デフォルト:

where ε は、マシン精度です。

IMSL_MAX_ITN, int max_itn ( 入力 )ゼロ点あたりの最大反復回数。デフォルト: max_itn = 100

IMSL_RETURN_USER, float x[] ( 出力 )計算されたゼロ点を含む nroot 要素の配列。

IMSL_INFO, int **info ( 出力 )収束情報を含んだ長さ nroot の配列ポインター info のアドレス。

返されると、必要な空間は imsl_f_zeros_fcn によって割り当てられ

ます。値 info[j − 1] は収束に達したとき j 番目のゼロを見つけるため

に使用された反復回数。収束が max_itn 反復で得られなかったなら

ば、info[j − 1] は max_itn よりも大きくなります。

IMSL_INFO_USER, int info[] ( 出力 )nroot 要素を持つユーザ割り当ての配列。 返されると、値 info[j − 1] は収束に達したとき j 番目のゼロ点を見つけるために使用された反復

回数。収束が max_itn 反復で得られなかったならば、info[j − 1] は max_itn よりは大きくなります。

err_abs = ε

err_rel = ε

eps = ε

Page 389: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_FCN_W_DATA, float fcn (float x, void *data) , void *data ( 入力 ) ゼロを見つける関数の値を計算するためのユーザ提供の関数。また、

ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータを受け渡すポインターです。 詳細は、

「イントロダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_zeros_fcn 実関数 f の n 実ゼロ点を計算します。 ユーザ提供の関

数 f(x) と初期値 x 1、 x 2、...、x n の n- ベクトルが与えられると、この関数は f の n 実数ゼロを探すために Müller の方法を使用します。この関数は 2 つの収

束規準があります。その最初のものは

が err_abs よりも小さいことを要求し、2 番目は x i の 2 つの連続近似の相

対変化が err_rel よりも小さいことを要求します。ここで

は x i の m- 番目の近似です。err_abs が ε1 で表され err_rel が ε2 で表さ

れるものとします。この規準は数学的に次のように述べられます。

基準 1:

基準 2:

「収束」はどちらかの規準を満たすことになります。

例題

例題 1

この例題は 3 次多項式の実ゼロ点を見つけます。

f(x) = x3 − 3x2 + 3x − 1

#include <imsl.h>

float fcn(float x);

main(){ float *x; /* x に対して fcn(x)=0 を解く */ x = imsl_f_zeros_fcn (fcn, 0); /* xをプリント */ imsl_f_write_matrix ("x", 1, 1, x, 0);}

float fcn(float x){ return x * x * x - 3.0 * x * x + 3.0 * x - 1.0;}

( )( )mif x

( )mix

( )( ) 1m

if x ε<

( ) ( )

( )

1

2

m mi i

mi

x xx

ε+ −

<

Page 390: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果 x 1

例題 2

この例題は三次多項式の 3 つの実ゼロ点を見つけます。

f(x) = x3 + 3x2 − 4x − 6

これは 3 つの初期値 (4.6, 0.0, −193.3) を持ちます。

#include <imsl.h>

float fcn(float x);

main(){ float xguess[ ] = {4.6, 0.0, -193.3}; int nroot = 3; float eps = 1.0e-5; float err_abs = 1.0e-5; float err_rel = 1.0e-5; float eta = 1.0e-2; int max_itn = 100; float *x; /* x に対して fcn(x)=0 を解く */ x = imsl_f_zeros_fcn (fcn, IMSL_XGUESS, xguess, IMSL_ERR_REL, err_rel, IMSL_ERR_ABS, err_abs, IMSL_ETA, eta, IMSL_EPS, eps, IMSL_NUM_ROOTS, nroot, IMSL_MAX_ITN, max_itn, 0); /* xをプリント */ imsl_f_write_matrix ("x", 1, 3, x, 0);}

float fcn(float x){ return x * x * x + 3.0 * x * x - 4.0 * x - 6.0;}

出力結果 x 1 2 3 1.646 -1.000 -3.646

次のプロットで 初期値 x = 0.0 と x = 4.6 は中空円で標識され、その解は黒円で

標識されました。その他の初期値 x = −193.3 はこのプロットに当てはまりませ

んでした。

Page 391: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Figure 7- 1 Plot of x3 + 3x2 − 4x − 6

警告エラー

IMSL_NO_CONVERGE_MAX_ITER max_itn 以内では nroot 根の少なくとも

1つの反復回数 収束に失敗しました。

zeros_sys_eqn修正 Powell ハイブリッドアルゴリズムを使用して、n 個の非線形連立方程式 f(x) = 0 を解きます。

概要

#include <imsl.h>

float *imsl_f_zeros_sys_eqn (void fcn(), int n, …, 0)double 型関数は、imsl_d_zeros_sys_eqnです。

必要な引数

void fcn (int n, float x[], float f[]) ( 入力 / 出力 )解かれる連立方程式を計算するためのユーザ提供の関数。ここで n は x と fのサイズで、x は関数が計算される点で、 f は点 x で計算され

る関数値を含みます。

int n ( 入力 )解かれる方程式の数と未知数の数。

戻り値

連立方程式の解であるベクトル x のポインター。 この空間を解放するために free を使用します。解が得られない場合,NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_f_zeros_sys_eqn (void fcn(), int n,

IMSL_XGUESS, float xguess[],IMSL_JACOBIAN, void jacobian(),IMSL_ERR_REL, float err_rel,IMSL_MAX_ITN, int max_itn,IMSL_RETURN_USER, float x[],IMSL_FNORM, float *fnorm,IMSL_FCN_W_DATA, void fcn ( ), void *data,IMSL_JACOBIAN_W_DATA, void jacobian(), void *data,0)

Page 392: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数

IMSL_XGUESS, float xguess[] ( 入力 )根の初期値を含んだ n 要素の配列。

デフォルト: xguess = 0

IMSL_JACOBIAN, void jacobian (int n, float x[], float fjac[]) ( 入力 / 出力 )ヤコビ行列を計算するためのユーザ提供の関数。ここで n は x の要素

の数、 x はヤコビ行列が計算される点、fjac は点 x の計算された

n × n ヤコビ行列です。各微係数 ∂fi / ∂xj は fjac[(i-1)*n+j-1] に返さな

ければならないことに注意してください。

IMSL_ERR_REL, float err_rel ( 入力 )停止規準。この根の 2 つの連続する近似の間の相対誤差が err_rel よりも小さい場合、この根が受け入れられます。デフォルト:

where ε は、マシン精度です。

IMSL_MAX_ITN, int max_itn ( 入力 )反復の最大許容回数。デフォルト: max_itn = 200

IMSL_RETURN_USER, float x[] ( 出力 )f_zeros_sys_eqn によって見つけられた根の最高推定値を含んだ n 成分の配列。

IMSL_FNORM, float *fnorm ( 出力 )点 x で次の値を持つスカラー。

IMSL_FCN_W_DATA, void fcn (int n, float x[], float f[] , void *data) , void *data ( 入力 )解く方程式を評価するためのユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提

供の関数にデータを受け渡すポインターです。 詳細は、「イントロダク

ション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_JACOBIAN_W_DATA, void jacobian (int m, int n, float x[], float fjac[], int fjac_col_dim, void *data), void *data ( 入力 )ヤコビ行列を計算するユーザ提供の関数。ユーザにより提供されるデータへのポインターを受け取ります。data は、ユーザ提供関数に渡

されるデータへのポインターです。詳細は、本マニュアルの初めにある「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_zeros_sys_eqn は M.J.D. Powell 氏によるハイブリッドアルゴリ

ズムの修正を使用する MINPACK サブルーチン HYBRDJ を基にしています。

このアルゴリズムは不必要な大きいステップ、或いは増加する残差を回避するニュートン法の改良型です。更に詳しい記述は Moré その他 (1980 年 ) を参照

してください。

例題 1

次の 2 × 2 の非線形連立方程式を解きます。

err_rel = ε

2 21 nf f+ +K

Page 393: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#include <imsl.h>#include <stdio.h>

#define N 2

void fcn(int, float[], float[]);

void main(){ float *x;

x = imsl_f_zeros_sys_eqn(fcn, N, 0); imsl_f_write_matrix("The solution to the system is", 1, N, x, 0);}

void fcn(int n, float x[], float f[]){ f[0] = x[0] + x[1] - 3.0; f[1] = x[0]*x[0] + x[1] * x[1] - 9.0;}

出力結果

The solution to the system is 1 2 0 3

例題 2

次の 3 × 3 の非線形連立方程式を初期値 (4.0, 4.0, 4.0) を使用して解きます。

#include <imsl.h>#include <stdio.h>#include <math.h>

#define N 3

void fcn(int, float[], float[]);

void main(){ int maxitn = 100; float *x, err_rel = 0.0001, fnorm; float xguess[N] = {4.0, 4.0, 4.0};

x = imsl_f_zeros_sys_eqn(fcn, N, IMSL_ERR_REL, err_rel, IMSL_MAX_ITN, maxitn, IMSL_XGUESS, xguess, IMSL_FNORM, &fnorm, 0); imsl_f_write_matrix("The solution to the system is", 1, N, x, 0);

( )( )

1 1 2

2 22 1 2

3

9

f x x x

f x x x

= + −

= + −

( ) ( )( )( ) ( )

1

2

211 1 2 3

2 22 1 3

23 3 2 2

27

/ 10

sin 2 7

x

x

f x x e x x

f x e x x

f x x x x

= + + + −

= + −

= + − + −

Page 394: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

printf("\nwith fnorm = %5.4f\n", fnorm);}

void fcn(int n, float x[], float f[]){ f[0] = x[0] + exp(x[0] - 1.0) + (x[1] + x[2]) * (x[1] + x[2]) - 27.0; f[1] = exp(x[1] - 2.0) / x[0] + x[2] * x[2] - 10.0; f[2] = x[2] + sin(x[1] - 2.0) + x[1] * x[1] - 7.0; }

出力結果The solution to the system is 1 2 3 1 2 3

with fnorm = 0.0000

警告エラー

IMSL_TOO_MANY_FCN_EVALS 関数の計算回数が max_itn を超えました。

新しい初期値が試行されます。

IMSL_NO_BETTER_POINT 引数 t err_rel が小さ過ぎます。近似解の

これ以上の改良は不可能です。

IMSL_NO_PROGRESS 反復は良好に進行しません。新しい初期値

が試行されます。

Page 395: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

第 8章:最適化

ルーチン

制約なし最小化

単変量関数関数値のみ使用 . . . . . . . . . . . . . . . . . . . min_uncon 396関数値と 1 次微分値のみ使用 . . . . . . . . . . min_uncon_deriv 399

多変量関数擬似 Newton 法を使用 . . . . . . . . . . . . . min_uncon_multivar 403

非線形最小二乗法Levenberg-Marquardt アルゴリズムを使用 . . . nonlin_least_squares 408

線形制約付き最小化線形計画問題、又は二次計画問題を含む MPS ファイルの読み込み . . . . . . . . . . . . . . . read_mps 416線形計画問題の解 . . . . . . . . . . . . . . linear_programming 423密線形計画法 . . . . . . . . . . . . . . . . . . . . . lin_prog 4282 次計画法. . . . . . . . . . . . . . . . . . . . quadratic_prog 432一般目的関数の最小化 . . . . . . . . . . . . . min_con_gen_lin 435変数に単純境界を持つ非線形最小二乗法 . . bounded_least_squares 440

非線形制約付き最小化逐次 2 次計画法を使用 . . . . . . . . . . . . . . constrained_nlp 446

使用上の注意

制約なし最小化

制約なし最小化問題は次のように説明する事ができます。

ここで f : Rn → R は連続で、このアルゴリズムによって要求される全ての次数

の微係数を持っています。非制約最小化の関数は、単変量関数、多変量関数、非線形最小二乗関数の 3 つのカテゴリに分類されます。

単変量関数に対しては、この関数は指定された区間では単峰形であると仮定されます。単峰性についての説明は、Brent (1973 年 ) を参照してください。

多変量関数 imsl_f_min_uncon_multivar は、疑似 Newton 法を使用してい

ます。そのデフォルトは f(x) の勾配の有限差分近似を使用することです。ここ

ではその勾配は次のベクトルになるように定義されます。

しかし、正確な勾配が容易に提供される時は、キーワード IMSL_GRAD を使用

しなければなりません。

非線形最小二乗関数は、修正 Levenberg-Marquardt アルゴリズムを使用します。

この関数の最も一般的な適用は、非線形データ当てはめ問題です。

( )minnx

f x∈ R

( ) ( ) ( ) ( )1 2

, , ...,n

f x f x f xf x

x x x∂ ∂ ∂

∇ = ∂ ∂ ∂

Page 396: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

これらの関数は局所最小点だけを見つけるように設計されています。しかし、関数は多数の局所最小点を持っています。より良い局所解を得るためには、異なる出発点と区間を試行しなければなりません。

ユーザが関数値だけを提供する時には、倍精度演算をお勧めします。

線形制約付き最小化

線形制約付き最小化問題は次のように説明されます。

こでは、 f : Rn → R、A 1 と A 2 は係数行列、そして b 1 と b 2 はベクトルです。

f(x) が線形であれば、この問題は線形計画問題です。 f(x) が二次であれば、この

問題は二次計画問題になります。

関数 imsl_f_linear_programmingは、active set 法を使用して線形計画問題を

解き、関数 imsl_f_lin_progの代用として考えられています。2 つの関数は、

似たようなインターフェースを持っているので、imsl_f_lin_prog から imsl_f_linear_programming への移行は比較的容易です。一般的に、

imsl_f_linear_programming の法が imsl_f_lin_prog よりも効率的に計算

を行います。imsl_f_linear_programming と imsl_f_lin_progの両関数は、

中小規模の線形計画問題で使用することを意図しています。係数は、完全行列の形式で保存されるので、疎行列向きではありません。

関数 imsl_f_quadratic_prog は双対二次計画アルゴリズムを使用して凸二次

計画問題を解くために設計されました。与えられたヘッセ行列が正定値でなければ imsl_f_quadratic_prog は正定値になるように修正します。この場合

に、問題は多少変更されているので、出力は注意して解釈される必要があります。ここで f(x) のヘッセ行列は n × n 行列になるように定義されます。

非線形制約付き最小化

非線形制約最小化問題は次のように説明することができます。

ここでは、 i = 1, 2, ..., m に対して、 f : Rn → R そして gi : Rn → R になります。

関数 imsl_f_constrained_nlp はこの問題を解くために逐次 2 次計画アルゴ

リズムを使用します。このアルゴリズムのより完全な説明は本書の中で見つけることができます。

min_uncon関数計算だけを使用して、単一変数の平滑関数 f(x) の最小点を見つけます。

概要

#include <imsl.h>

float imsl_f_min_uncon (float fcn(), float a, float b, …, 0)

( )

1 1

min

subject to

nxf x

A x b∈

=R

( ) ( )2

2

i j

f x f xx x∂

∂ ∂

∇ =

( )

( )( )

1

1

min

subject to 0 for 1, 2, ...,

0 for 1, ...,

nx

i

i

f x

g x i m

g x i m m

= =

≥ = +

R

Page 397: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

double 型関数は、 imsl_d_min_unconです。

必要な引数

float fcn(float x) ( 入力 / 出力 )最小化される関数の値を計算するユーザ提供の関数。ここで x はこの

関数が計算される点で、そして fcn は点 x で計算される関数値です。

float a ( 入力 )fcn の最小点が位置する区間の下端点。

float b ( 入力 )fcn の最小点が位置する区間の上端点。

戻り値

fcn の最小値が見つけられる点。値が計算できない場合,NaN が返されます。

オプション引数の概要

#include <imsl.h>float imsl_f_min_uncon (float fcn(), float a, float b,

IMSL_XGUESS, float xguess, IMSL_STEP, float step, IMSL_ERR_ABS, float err_abs, IMSL_MAX_FCN, int max_fcn, IMSL_FCN_W_DATA, float fcn(), void *data,0)

オプション引数

IMSL_XGUESS, float xguess ( 入力 )fcn の最小点の初期推定値。

デフォルト: xguess = (a + b)/2

IMSL_STEP, float step ( 入力 )x の必要な変更の大きさ推定値の等級。 デフォルト: step = 1.0

IMSL_ERR_ABS, float err_abs ( 入力 )x の最終値の必要な絶対精度。正常に返されると fcn が x での fcn よりは小さくない距離 err_abs の範囲の x のどちらかの側

に点が存在します。デフォルト: err_abs = 0.0001

IMSL_MAX_FCN, int max_fcn ( 入力 )最大許容関数計算数。デフォルト: max_fcn = 1000

IMSL_FCN_W_DATA, float fcn(float x, void *data), void *data, ( 入力 )最小化される関数の値を計算するためのユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータを受け渡すポインターです。 詳細は、

「イントロダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_min_uncon は単変量関数の最小点を見つけるために保護された

2 次補間法を使用します。このコードと基底にあるアルゴリズムの両方はケン

ブリッジ大学の M.J.D. Powell によって書かれたサブルーチン ZXLSF を基にし

ています。

関数 imsl_f_min_uncon は関数 fcn によって指定された単変量関数 f の最小

値を見つけます。その他の必要なデータは 2 点 a と b です。2 点は、x 0 = xguess である解の最初の推定値 x 0 から最小値を見つけるための区間を定義

します。このアルゴリズムは x 0 から x = x 0 + s に移動することにより検索を

Page 398: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

始めます。ここで s = step は x の必要な変更の推定値であり、正、或い

は、負になります。この最初の 2つの関数計算は最小点の方向を示し、その検

索は最小点上の受け口が見つかるか、或いは、x が端点 a 又は b の 1 つに到

達するまで、この方向に沿って続けられます。この段階では、ステップ長さは、一回の関数計算で 2 倍から 9 倍の倍数で増加されます。この倍数は、3 回

の最近の関数値から 2 次補間によって予想される最小点の位置に依存します。

解を含んだ区間が見つかった時に、次の 3 点を持ちます。

x1、 x2、 x3  x1 < x2 < x3、 f(x1) ≥ f(x2)、f(x2) ≤ f(x3) である点 。

これらの 3 点から新しいxを選ぶための技術に 3 つの主要な規則があります。 それらは、 (i) 3つの関数値の 2次補間によって与えられる最小点の推定値、 (ii) 2次式で f の接近に依存する許容パラメータ値、 (iii) x 2 が x 1 と x 3 の間の範囲

の中心近くにあるか、或いは、この範囲の端に相対的に近いです。 概要とし

て、この x の新しい値が、x 2 から少なくとも ε であることを条件とし、x 2 が特に x 1 又は x 3 に接近しているとき、x 1 と x 2 又は x 2 と x 3 の間の長い

間隔であることを条件として、予想される最小点に出来る限り近くなります。

このアルゴリズムは、最小点で f が正で、連続の 2 次微係数を持つ時、素早い

収束を提供することを目的としています。 又、このアルゴリズムは次のような異常な場合に、ひどく非効率な点を回避します。

f(x) = x + 1.001|x|

アルゴリズムは、異常なケースでは、自動的に ε を大きくします。この場合、

x の新しい値を最小に計算された関数値の近傍にあるより長い区間の中間点にするのが普通です。f がコンピュータの丸め誤差に支配される時、この中間

点法はよく利用されます。ユーザがマシン精度の平方根より低い精度を要求すると、これはほぼ確実に起こります。このような場合、f 内の丸め誤差は、近

くに別の局所最小点を存在させる原因になる場合があるにもかかわらず、サブルーチンが、δ = err_abs である x の距離 d 内に局所最小点があると決定すると、

それは要求されている精度に達したと主張します。

例題

例題 1

f(x) = ex − 5x の最小点を見つけます。

#include <imsl.h>#include <math.h>

float fcn(float);

void main (){ float a = -100.0; float b = 100.0; float fx, x;

x = imsl_f_min_uncon (fcn, a, b, 0); fx = fcn(x);

printf ("The solution is: %8.4f\n", x); printf ("The function evaluated at the solution is: %8.4f\n", fx);}

float fcn(float x){ return exp(x) - 5.0*x;}

Page 399: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

The solution is: 1.6094The function evaluated at the solution is: -3.0472

例題 2

初期推定値 x 0 = 3 で f(x) = x(x 3 − 1) + 10 の最小値を見つけます。

#include <imsl.h>

float fcn(float);

void main (){ int max_fcn = 50; float a = -10.0; float b = 10.0; float xguess = 3.0; float step = 0.1; float err_abs = 0.001; float fx, x;

x = imsl_f_min_uncon (fcn, a, b, IMSL_XGUESS, xguess, IMSL_STEP, step, IMSL_ERR_ABS, err_abs, IMSL_MAX_FCN, max_fcn, 0); fx = fcn(x);

printf ("The solution is: %8.4f\n", x); printf ("The function evaluated at the solution is: %8.4f\n", fx);} float fcn(float x){ return x*(x*x*x-1.0) + 10.0;}

出力結果

The solution is: 0.6298The function evaluated at the solution is: 9.5275

警告エラー

IMSL_MIN_AT_BOUND xの最終値は境界にあります。

IMSL_NO_MORE_PROGRESS コンピュータ丸め誤差が xの改良を妨げま

す。

IMSL_TOO_MANY_FCN_EVAL 関数計算の最大数を超えました。

min_uncon_deriv関数と 1 次微係数計算の両方を使用して、1 変数の平滑関数 f(x) の最小点を見

つけます。

概要

#include <imsl.h>

float imsl_f_min_uncon_deriv (float fcn(), float grad(), float a, float b, …, 0)

double 型関数は、 imsl_d_min_uncon_derivです。

Page 400: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

float fcn (float x) ( 入力 / 出力 )最小化される関数の値を計算するユーザ提供の関数。ここで x はこの

関数が計算される点で、そして fcn は点 x で計算される関数値です。

float grad (float x) ( 入力 / 出力 )関数の 1 次微係数を計算するユーザ提供の関数で、x は微係数が計算

される点で、grad は x で計算された微係数の値です。

float a ( 入力 )fcn の最小点が位置する区間の下端点。

float b ( 入力 )fcn の最小点が位置する区間の上端点。

戻り値

fcn の最小値が見つけられる点。値が計算できない場合,NaN が返されます。

オプション引数の概要

#include <imsl.h>float imsl_f_min_uncon_deriv (float fcn(), float grad(), float a, float b,

IMSL_XGUESS, float xguess, IMSL_ERR_REL, float err_rel, IMSL_GRAD_TOL, float grad_tol, IMSL_MAX_FCN, int max_fcn, IMSL_FVALUE, float *fvalue, IMSL_GVALUE, float *gvalue, IMSL_FCN_W_DATA, float fcn(), void *data,IMSL_GRADIENT_W_DATA, float grad(), void *data, 0)

オプション引数

IMSL_XGUESS, float xguess ( 入力 )fcn の最小点の初期推定値。

デフォルト: xguess = (a + b)/2

IMSL_ERR_REL, float err_rel ( 入力 )x の最終値の必要な相対精度。これは最初の停止基準です。通常に戻ると、解 x は局所最小値を含む区間内にあって max (1.0, |x|) * err_rel より小さいか等しくなります。与えられた err_rel がゼロよ

り小さいと、

が err_rel として使用されます。ε はマシン精度です。

デフォルト:

IMSL_GRAD_TOL, float grad_tol ( 入力 )現在点が局所最小かどうかを決定するために使用される微係数許容値。これは 2 番目の停止基準です。x が解として返されるのは grad が grad_tol より小さいか等しいときです。 grad_tol は非負でなければ

なりません。そうでない場合、ゼロが使用されます。デフォルト:

ε

err_rel = ε

grad_tol = ε

Page 401: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

where ε は、マシン精度です。

IMSL_MAX_FCN, int max_fcn ( 入力 )最大許容関数計算数。デフォルト: max_fcn = 1000

IMSL_FVALUE, float *fvalue ( 出力 )点 x の関数値。

IMSL_GVALUE, float *gvalue ( 出力 )点 x の微係数値。

IMSL_FCN_W_DATA, float fcn (float x, void *data), void *data, ( 入力 )最小化する関数の計算をするためのユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、

ユーザ提供の関数にデータを受け渡すポインターです。 詳細は、「イン

トロダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_GRADIENT_W_DATA, float grad (float x, void *data), void *data, ( 入力 )関数の最初の微分係数を計算するためのユーザ提供関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、

ユーザ提供の関数にデータを受け渡すポインターです。 詳細は、「イン

トロダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 f_min_uncon_deriv は単変量関数の最小点を見つけるためにセカント法

か三次補間のいずれかの降下法を使用します。これは初期推定値と 2 つの端点

で始めます。この 3 点のいずれかが局所最小点で最小関数値を持てば、関数は

1つの解で終了します。そうでなければ、最小関数値を持つ点が出発点として使用されます。

この出発点 xc から関数値 fc = f(xc)、 微係数値 gc = g(xc)、 xn = xc - gc によって定

義される新しい点 xn が計算されます。関数 fn = f(xn) と微係数 gn = g(xn) はそれ

から計算されます。もし、fn ≥ fc もしくは gn が gc の反対の符号を持てば、そ

のときに xc と xn の間に最小点が存在して最初の区間が得られます。その他

では xc は最小の関数値を持つ点として保持されるので xc と xn の間で交換が

実行されます。そのときセカント法が新しい点を得るために使用されます。

xn = xs として、最小を含んだ区間が見つかるまで、或いは収束基準の 1 つが満足

されるまでこのプロセスを繰り返します。この収束基準は以下の通りです。

基準 1: |xc − xn| ≤ εc

基準 2: |gc| ≤ εg

ここで εc = max {1.0, |xc|} ε 、ε は誤差許容値、そして εg は、勾配の許容値で

す。

収束が達成されなかったとき、新しい点を得るために 3 次補間が実行されます。

関数と微係数はその点で計算されます。従って最小点を含む小さい区間が選ばれます。その区間が以前の区間の少なくとも一部分によりの縮小されることを保証するために保護法が使用されます。その他の 3 次補間も実行されてこの関

数は停止基準の 1 つに合致するまで繰り返されます。

例題

例題 1

この例題は、f(x) = e x − 5x の最小点を見つけます。

n cs c c

n c

g gx x g

x x −

= − −

Page 402: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#include <imsl.h>#include <math.h>

float fcn(float);float deriv(float);

void main (){ float a = -10.0; float b = 10.0; float fx, gx, x;

x = imsl_f_min_uncon_deriv (fcn, deriv, a, b, 0); fx = fcn(x); gx = deriv(x);

printf ("The solution is: %7.3f\n", x); printf ("The function evaluated at the solution is: %9.3f\n", fx); printf ("The derivative evaluated at the solution is: %7.3f\n", gx);}

float fcn(float x){ return exp(x) - 5.0*(x);}

float deriv (float x){ return exp(x) - 5.0;}

出力結果

The solution is: 1.609The function evaluated at the solution is: -3.047The derivative evaluated at the solution is: -0.001

例題 2

初期値 x0 = 3 で f(x) = x(x3 −1) + 10 の最小点を見つけます。

#include <imsl.h>#include <stdio.h>

float fcn(float);float deriv(float);

void main (){ int max_fcn = 50; float a = -10.0; float b = 10.0; float xguess = 3.0; float fx, gx, x;

x = imsl_f_min_uncon_deriv (fcn, deriv, a, b, IMSL_XGUESS, xguess, IMSL_MAX_FCN, max_fcn, IMSL_FVALUE, &fx, IMSL_GVALUE, &gx, 0); printf ("The solution is: %7.3f\n", x); printf ("The function evaluated at the solution is: %7.3f\n", fx); printf ("The derivative evaluated at the solution is: %7.3f\n", gx);} float fcn(float x)

Page 403: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{ return x*(x*x*x-1) + 10.0;}

float deriv(float x){ return 4.0*(x*x*x) - 1.0;}

出力結果

The solution is: 0.630The function evaluated at the solution is: 9.528The derivative evaluated at the solution is: 0.000

警告エラー

IMSL_MIN_AT_LOWERBOUND x の最終値は下限値です。

IMSL_MIN_AT_UPPERBOUND x の最終値は上限値です。

IMSL_TOO_MANY_FCN_EVAL 関数計算の最大数を超えました。

min_uncon_multivar擬似 Newton 法を使って n 変数の関数 f(x) を最小化します。

概要

#include <imsl.h>

float *imsl_f_min_uncon_multivar (float fcn(), int n, …, 0)double 型関数は、 imsl_d_min_uncon_multivarです。

必要な引数

float fcn (int n, float x[]) ( 入力 / 出力 )最小化される関数の値を計算するユーザ提供の関数。ここで x はこの

関数が計算される点で、そして fcn は点 x で計算される関数値です。

int n ( 入力 )変数の数。

戻り値

関数の最小点 x のポインター。この空間を解放するために free を使用しま

す。 解が得られない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_f_min_uncon_multivar (float fcn(), int n,

IMSL_XGUESS, float xguess[],IMSL_GRAD, void grad(),IMSL_XSCALE, float xscale[],IMSL_FSCALE, float fscale,IMSL_GRAD_TOL, float grad_tol,IMSL_STEP_TOL, float step_tol,IMSL_MAX_STEP, float max_step,IMSL_GOOD_DIGIT, int ndigit,IMSL_MAX_ITN, int max_itn,IMSL_MAX_FCN, int max_fcn,IMSL_MAX_GRAD, int max_grad,IMSL_INIT_HESSIAN, int ihess,IMSL_RETURN_USER, float x[],IMSL_FVALUE, float *fvalue,IMSL_FCN_W_DATA, float fcn(), void *data,IMSL_GRADIENT_W_DATA, void grad(), void *data,0)

Page 404: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数

IMSL_XGUESS, float xguess[] ( 入力 )計算される解の初期値を含んだ n 成分の配列。

デフォルト: xguess = 0

IMSL_GRAD, void grad (int n, float x[], float g[]) ( 入力 / 出力 )点 x で勾配を計算するユーザ提供の関数。ここで n は x のサイズ、

x はこの勾配が計算される点で、g は点 x で計算される勾配値です。

IMSL_XSCALE, float xscale[] ( 入力 )この変数の尺度化ベクトルを含んだ n 成分の配列。xscale は主と

して勾配と2点間の距離を尺度化するために使用されます。詳細は、 IMSL_GRAD_TOL と IMSL_STEP_TOL キーワードを参照してくださ

い。

デフォルト: xscale[] = 1.0

IMSL_FSCALE, float fscale ( 入力 )機能尺度化を含むスカラー。fscale は主として勾配を尺度化するた

めに使用されます。詳細は IMSL_GRAD_TOL キーワードを参照してく

ださい。

デフォルト: fscale = 1.0

IMSL_GRAD_TOL, float grad_tol ( 入力 )尺度化された勾配許容値。x の尺度化された勾配の i 番目の成分は次

のように計算されます。

ここで、 g = ∇ f(x)、 s = xscale、 fs = fscaleです。

デフォルト: 、 は倍精度、 ε は、マシン精度です。

IMSL_STEP_TOL, float step_tol ( 入力 )尺度化されたステップ許容値。2点 x と y の間の尺度化されたス

テップの i 番目の成分は次のように計算されます。

ここで、 s = xscaleです。

デフォルト: step_tol = ε2/3

IMSL_MAX_STEP, float max_step ( 入力 )最大許容ステップサイズ。デフォルト: max_step = 1000max (ε1, ε2)。ここで、

ε2 = ||s||2、 s = xscale、 t = xguessです。

IMSL_GOOD_DIGIT, int ndigit ( 入力 )この関数の良好な桁数。このデフォルトはマシンに依存します。

IMSL_MAX_ITN, int max_itn ( 入力 )最大反復回数。デフォルト: max_itn = 100

( )( )( )

max , 1/

max ,i i i

s

g x s

f x f

grad_tol = ε 3 ε

( )max , 1/i i

i i

x yx s−

( )21 1

ni ii

s tε=

= ∑

Page 405: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_MAX_FCN, int max_fcn ( 入力 )関数計算の最大回数。デフォルト: max_fcn = 400

IMSL_MAX_GRAD, int max_grad ( 入力 )勾配計算の最大回数。デフォルト: max_grad = 400

IMSL_INIT_HESSIAN, int ihess ( 入力 )ヘッセ行列初期化パラメータ。ihess がゼロの場合、ヘッセ行列は

単位行列に初期化されます。その他は、対角項に次ぎを含む対角行列に初期化されます。

ここで、 t = xguess、 fs = fscale、 s = xscaleです。

デフォルト: ihess = 0

IMSL_RETURN_USER, float x[] ( 出力 )計算された解を含む n 成分のユーザ提供の配列。

IMSL_FVALUE, float *fvalue ( 出力 )計算された解の関数の値を格納するアドレス。

IMSL_FCN_W_DATA, float fcn (int n, float x, void *data), void *data, ( 入力 )最小化の関数の値を計算するためのユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、

ユーザ提供の関数にデータを受け渡すポインターです。 詳細は、「イン

トロダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_GRADIENT_W_DATA, void grad (int n, float x[], float g[], void *data), void *data, ( 入力 )点 x での勾配を計算するためのユーザ提供の関数。また、ユーザによ

り提供されたデータへのポインターも受け入れます。 data は、ユーザ

提供の関数にデータを受け渡すポインターです。 詳細は、「イントロダ

クション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 f_min_uncon_multivar は、疑似ニュートン法を使用して n 変数の関

数 f(x) の最小値を見つけます。この問題は次のように説明されます。

出発点 x c が与えられて探索方向は、次式に従って計算されます。

ここで B はヘッセ行列の正定値近似で gc は x c で計算される勾配です。直線

探索は次の新しい点を見つけるために使用されます。

xn =xc + λd, λ > 0

次のようになります。

f(xn) ≤ f(xc) + αgTd, α ∈ (0, 0.5)

最終的に最適化条件 ||g(x)|| ≤ ε はチェックされます。ここで ε は、勾配許容値

です。e ožMn1¼$gYB は BFGS 公式に従って更新されます。

最適性が達成されないと、B は次の BFGS 公式に従って更新されます。

( )( ) 2max , s if t f s∗

( )minnx

f x∈ R

1d B g c= − −

Page 406: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで、 s = xn − xc と y = gn − gc です。 その他の探索は次の反復を始めるために

計算されます。より詳しいことは Dennis と Schnabel (1983 年、付録 A) を参照

してください。

この実装に於いて、imsl_f_min_uncon_multivar の最初の停止基準は、この

勾配のノルムが与えられた勾配許容値 grad_tolよりも小さい時に生じます。 imsl_f_min_uncon_multivarの 2 番目の停止基準は、最後の 2 ステップ間の尺

度化された距離がステップ許容値 step_tolよりも小さい時に生じます。

デフォルトによって、有限差分法が幾つかの単精度計算で勾配を推定するために使用されるので、勾配の不正確な推定がこのアルゴリズムを重要でない点で停止させる原因になる場合があります。このような場合には、高精度演算をおすすめします。正確な勾配計算を提供するために、キーワード IMSL_GRAD 使用してください。

Figure 8- 1 Plot of the Rosenbrock Function

例題

例題 1

関数

が最小化されます。上のプロットで塗りつぶしの円が最小点を記録します。

#include <stdio.h>#include <imsl.h>

void main(){ int i, n=2; float *result, fx; static float rosbrk(int, float[]); /* Rosenbrock 関数を最小化 */

result = imsl_f_min_uncon_multivar(rosbrk, n, 0);

T T

T T

Bss B yyB Bs Bs y s

← − +

( ) ( ) ( )2 222 1 1100 1f x x x x= − + −

Page 407: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

fx = rosbrk(n, result);

/* 結果をプリント */

printf(" The solution is "); for (i = 0; i < n; i++) printf("%8.3f", result[i]); printf("\n\n The function value is %8.3f\n", fx);} /* メインの最後 */

static float rosbrk(int n, float x[]){ float f1, f2;

f1 = x[1] - x[0]*x[0]; f2 = 1.0 - x[0];

return 100.0 * f1 * f1 + f2 * f2;} /* 関数の最後 */

出力結果

The solution is 1.000 1.000

The function value is 0.000

例題 2

関数

を、初期推定 x = (−1.2, 1.0) で最小化します。初期推定は、figure 8-1 の図上で

オープンな円として表示されています。

#include <stdio.h>#include <imsl.h>

void main(){ int i, n=2; float *result, fx; static float rosbrk(int, float[]); static void rosgrd(int, float[], float[]); static float xguess[2] = {-1.2e0, 1.0e0}; static float grad_tol = .0001;

/* -1.2 と 1.0の初期推定で Rosenbrock 関数を最小化 */

result = imsl_f_min_uncon_multivar(rosbrk, n, IMSL_XGUESS, xguess, IMSL_GRAD, rosgrd, IMSL_GRAD_TOL, grad_tol, IMSL_FVALUE, &fx, 0);

/* 結果をプリント */

printf(" The solution is "); for (i = 0; i < n; i++) printf("%8.3f", result[i]); printf("\n\n The function value is %8.3f\n", fx);} /* メインの最後 */

static float rosbrk(int n, float x[]){ float f1, f2;

f1 = x[1] - x[0]*x[0];

( ) ( ) ( )2 222 1 1100 1f x x x x= − + −

Page 408: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

f2 = 1.0e0 - x[0];

return 100.0 * f1 * f1 + f2 * f2;} /* 関数の最後 */

static void rosgrd(int n, float x[], float g[]){

g[0] = -400.0*(x[1]-x[0]*x[0])*x[0] - 2.0*(1.0-x[0]); g[1] = 200.0*(x[1]-x[0]*x[0]);

} /* 関数の最後 */

出力結果

The solution is 1.000 1.000

The function value is 0.000

情報エラー

IMSL_STEP_TOLERANCE 尺度化されたステップ許容値が満足されま

した。現在の点は近似された局所解であるかも知れませんが、このアルゴリズムが非常に遅く進行して、解の近くではなく、或いは step_tol が余りにも大きすぎる可

能性もあります。

警告エラー

IMSL_TOO_MANY_ITN 反復の最大数を超えました。

IMSL_TOO_MANY_FCN_EVAL 関数計算の最大数を超えました。

IMSL_TOO_MANY_GRAD_EVAL 勾配計算の最大値を超えました。

IMSL_UNBOUNDED 5 回の連続ステップが最大ステップ長で取ら

れました。

IMSL_NO_FURTHER_PROGRESS 最後の全体ステップが現在の x値よりも小さ

い点を見つけることに失敗しました。

重大エラー

IMSL_FALSE_CONVERGENCE 偽の収束 — 反復は重要ではない点に収束

するように見えます。恐らく不正確な勾配情報が使用されている、又は、この関数が不連続である、又は、その他の停止許容値が余りにも強すぎます。

nonlin_least_squares修正 Levenberg-Marquardt アルゴリズムを使用して非線形最小二乗問題を解き

ます。

概要

#include <imsl.h>

float *imsl_f_nonlin_least_squares (void fcn(), int m, int n, …, 0)double 型関数は、 imsl_d_nonlin_least_squaresです。

必要な引数

void fcn (int m, int n, float x[], float f[]) ( 入力 / 出力 )最小二乗問題を定義する関数の値を計算するユーザ提供の関数。 関数

が計算される点で、x は長さ n のベクトル、f は点 x での関数値を含む長さ m のベクトルです。

Page 409: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int m ( 入力 )関数の数。

int n ( 入力 ) n ≤ mである変数の数。

戻り値

非線形最小二乗問題の解 x のポインター。この空間を解放するために free を使用します。 解が得られない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_f_nonlin_least_squares (void fcn(), int m, int n,

IMSL_XGUESS, float xguess[],IMSL_JACOBIAN, void jacobian(),IMSL_XSCALE, float xscale[],IMSL_FSCALE, float fscale[],IMSL_GRAD_TOL, float grad_tol,IMSL_STEP_TOL, float step_tol, IMSL_REL_FCN_TOL, float rfcn_tol,IMSL_ABS_FCN_TOL, float afcn_tol,IMSL_MAX_STEP, float max_step,IMSL_INIT_TRUST_REGION, float trust_region,IMSL_GOOD_DIGIT, int ndigit,IMSL_MAX_ITN, int max_itn,IMSL_MAX_FCN, int max_fcn,IMSL_MAX_JACOBIAN, int max_jacobian,IMSL_INTERN_SCALE,IMSL_TOLERANCE, float tolerance,IMSL_RETURN_USER, float x[],IMSL_FVEC, float **fvec,IMSL_FVEC_USER, float fvec[],IMSL_FJAC, float **fjac,IMSL_FJAC_USER, float fjac[],IMSL_FJAC_COL_DIM, int fjac_col_dim,IMSL_RANK, int *rank,IMSL_JTJ_INVERSE, float **jtj_inv,IMSL_JTJ_INVERSE_USER, float jtj_inv[],IMSL_JTJ_INV_COL_DIM, int jtj_inv_col_dim,IMSL_FCN_W_DATA, void fcn(), void *data,IMSL_JACOBIAN_W_DATA, void jacobian(), void *data,0)

オプション引数

IMSL_XGUESS, float xguess[] ( 入力 )初期推定値を含む n 成分の配列。

デフォルト: xguess = 0

IMSL_JACOBIAN, void jacobian (int m, int n, float x[], float fjac[],int fjac_col_dim)( 入力 )ヤコブ行列を計算するユーザ提供関数。ヤコブ行列が計算される点における x は、長さ n のベクトルで、fjac は点 x での計算された

m × n のヤコブ行列で、fjac_col_dim は、fjac の列ディメンジョン

です。 各導関数 ∂fi/∂xj は fjac[(i1)*fjac_col_dim+j-1] に返さなければ

ならない事に注意してください。

IMSL_XSCALE, float xscale[] ( 入力 )変数の尺度ベクトル含んだ n 成分の配列。xscale は主として 2 点

間の勾配と距離を尺度化するために使用されます。詳細はキーワードの IMSL_GRAD_TOL と IMSL_STEP_TOL を参照して下さい。 デフォルト: xscale[] = 1

IMSL_FSCALE, float fscale[] ( 入力 )この関数の対角尺度行列を含んだ m 成分の配列。fscale の i 番目

Page 410: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

の成分はこの問題の i 番目の成分関数の逆数の大きさを指定する正の

スカラーです。デフォルト: fscale[] = 1

IMSL_GRAD_TOL, float grad_tol ( 入力 )尺度化された勾配の許容値。x での尺度化された勾配の i 番目の成

分は、次のように計算されます。

ここで g = ∇ F(x)、 s = xscale、

です。

デフォルト:

は倍精度、 ε はマシン精度です。

IMSL_STEP_TOL, float step_tol ( 入力 )尺度化されたステップ許容値。 x と y の 2 点間の尺度化されたステップ

の i 番目の成分は、次のように計算されます。

ここで、 s = xscaleです。

デフォルト: step_tol = ε2/3 。ここで、 ε は、マシン精度です。

IMSL_REL_FCN_TOL, float rfcn_tol ( 入力 )相対関数許容値。

デフォルト: rfcn_tol = max (10-10, ε2/3)、 max (10-20, ε2/3) は倍精度で、 ε は、マシン精度です。

IMSL_ABS_FCN_TOL, float afcn_tol ( 入力 )絶対関数許容値。

デフォルト: afcn_tol = max (10-20, ε2)、 max (10-40, ε2) は倍精度で、 ε はマシン精度です。

IMSL_MAX_STEP, float max_step ( 入力 )最大許容ステップサイズ。デフォルト: max_step = 1000 max (ε1, ε2)。ここで、

s = xscale、 t = xguessです。

IMSL_INIT_TRUST_REGION, float trust_region ( 入力 )初期信頼領域半径のサイズ。このデフォルトは初期尺度化コーシィステップを基準にします。

IMSL_GOOD_DIGIT, int ndigit ( 入力 )この関数の良好な桁数。デフォルト: マシン依存

( )( ) 2

2

max , 1/12

i i ig x s

F x

( ) ( )2 2

12

mii

F x f x=

= ∑

grad_tol ε=

3 ε

( )max , 1/i y

i i

x y

x s

( )21 2 21

,ni ii

s t sε ε=

= =∑

Page 411: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_MAX_ITN, int max_itn ( 入力 )最大反復回数。デフォルト: max_itn = 100

IMSL_MAX_FCN, int max_fcn ( 入力 )関数計算の最大回数。デフォルト: max_fcn = 400

IMSL_MAX_JACOBIAN, int max_jacobian ( 入力 )ヤコブ行列計算の最大回数。デフォルト: max_jacobian = 400

IMSL_INTERN_SCALE

内部変数尺度化オプション。このオプションで、xscale の値が内部的

にセットされます。

IMSL_TOLERANCE, float tolerance ( 入力 )J TJ の逆行列の計算のために線形依存を決定するためにこの許容値は

使用されます。imsl_f_nonlin_least_squares に対して、

IMSL_JACOBIAN が指定されると、tolerance = 100 ximsl_d_machine(4) がデフォルトになります。その他の場合には imsl_f_machine(4) の平方根がデフォルトになります。

imsl_d_nonlin_least_squares に対して IMSL_JACOBIAN が指定

されると、tolerance = 100 ximsl_machine(4) がデフォルトにな

ります。その他の場合には imsl_d_machine(4) の平方根がデフォル

トになります。imsl_f_machine ( 第 12 章:ユーティリティー ) を参照してください。

IMSL_RETURN_USER, float x[] ( 出力 )計算された解を含む n 成分の配列。

IMSL_FVEC, float **fvec ( 出力 )近似解の残差を含む長さ m の実数配列のポインターのアドレス。返さ

れる時に必要な空間が、imsl_f_nonlin_least_squares によって割

り当てられます。通常、 float *fvec が宣言されて、&fvec が引数と

して使用されます。

IMSL_FVEC_USER, float fvec[] ( 出力 )近似解の残差を含むサイズ m のユーザ割り当ての配列。

IMSL_FJAC, float **fjac ( 出力 )近似解にヤコブ行列を含むサイズ m × n の配列のポインターのアドレ

ス。返される時に必要な空間が、imsl_f_nonlin_least_squares によって割り当てられます。一般的に float *fjac が宣言されて、

&fjac が引数として使用されます。

IMSL_FJAC_USER, float fjac[] ( 出力 )近似解でヤコブ行列を含むサイズ m × n のユーザ割り当ての配列。

IMSL_FJAC_COL_DIM, int fjac_col_dim ( 入力 )fjac の列ディメンジョン。

デフォルト: fjac_col_dim = n

IMSL_RANK, int *rank ( 出力 )ヤコブ行列の階数が *rank に返されます。

IMSL_JTJ_INVERSE, float **jtj_inv ( 出力 )J が最終ヤコブ行列である J TJ の逆行列を含んだサイズ n × n の配列のポ

インターのアドレス。 J TJ が特異であればその逆行列は、J TJ の対称 g 2 逆行列になります。( 一般化された逆行列と g 2 逆行列の定義についての

説明は、第 1章:線形連立方程式 imsl_f_lin_sol_nonnegdef を参照し

てください。) 返される時に必要な空間が、

imsl_f_nonlin_least_squares によって割り当てられます。

Page 412: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_JTJ_INVERSE_USER, float jtj_inv[] ( 出力 )J が解のヤコブ行列である J TJ の逆行列を含んだサイズ n × n のユー

ザ割り当ての配列。

IMSL_JTJ_INV_COL_DIM, int jtj_inv_col_dim ( 入力 )jtj_invの列ディメンジョン。

デフォルト: jtj_inv_col_dim = n

IMSL_FCN_W_DATA, void fcn (int m, int n, float x[], float f[], void *data), void *data ( 入力 )最小二乗問題を定義する関数を評価するユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータを受け渡すポインターです。 詳細は、

「イントロダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_JACOBIAN_W_DATA, void jacobian (int m, int n, float x[], float fjac[], int fjac_col_dim, void *data), void *data ( 入力 )ヤコビ行列を計算するユーザ提供の関数。ユーザにより提供されるデータへのポインターを受け取ります。data は、ユーザ提供関数に渡

されるデータへのポインターです。詳細は、本マニュアルの初めにある「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_nonlin_least_squares は Moré その他 (1980 年 ) の文献によ

る MINPACK ルーチン LMDER を基にしています。それは非線形最小二乗問題

を解くために修正 Levenberg-Marquardt 法を使用します。この問題は次のよう

に述べられます。

ここで、m ≥ n, F : Rn → Rm , そして fi (x) は F(x) の I 番目の成分関数です。現

在の点からこのアルゴリズムは信頼領域手法を使用します。

新しい点 x n を 次のように計算します。

xn = xc − (J(xc)T J(xc) + µcI)-1 J(xc)T F(xc)

ここで、 δc ≥ ||(J(xc)T J(xc))-1 J(xc)T F(xc)||2 であれば、 µc = 0 そうでなければ、 µc > 0 です。 値 μc は関数によって定義されます。関数 F(x c) と J(x c) はそれぞ

れが、現在の点 x c で計算された関数値とヤコブ行列です。この関数は停止基

準が満たされるまで繰り返されます。

imsl_f_nonlin_least_squares の最初の停止基準は、この関数のノルムが絶

対関数許容値 fcn_tol より小さいときに生じます。2 番目の停止基準は尺度

化された勾配のノルムが与えられた勾配許容値 fcn_tolより小さいときに生

じます。imsl_f_nonlin_least_squares の 3 番目の停止基準は、最後の 2 ス

テップ間の尺度化された距離がステップ許容値 step_tolより小さいときに

生じます。その詳細については Levenberg (1944 年 )、Marquardt (1963 年 ) 又

は Dennis と Schnabel (1983 年、第10章 ) を参照してください。

( ) ( ) ( )2

1

1 1min2 2

mT

ii

F x F x f x=

= ∑

( ) ( )( )2

2

min

subject to

n c c n cx

n c c

F x J x x x

x x δ∈

+ −

− ≤R

Page 413: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Figure 8-2 Plot of the Nonlinear Fit

例題

例題 1

この例題の、非線形データ当てはめ問題は Dennis と Schnabel (1983 年 , 225ページ ) にあります。

ここで、

これが、データ t = (1, 2, 3) と y = (2, 4, 3) で解かれます。

#include <stdio.h>#include <imsl.h>#include <math.h>

void fcn(int, int, float[], float[]);

void main(){ int m=3, n=1; float *result, fx[3];

result = imsl_f_nonlin_least_squares(fcn, m, n, 0); fcn(m, n, result, fx);

/* 結果をプリント */

imsl_f_write_matrix("The solution is", 1, 1, result, 0); imsl_f_write_matrix("The function values are", 1, 3, fx, 0);} /* メインの最後 */

void fcn(int m, int n, float x[], float f[]){ int i; float y[3] = {2.0, 4.0, 3.0}; float t[3] = {1.0, 2.0, 3.0};

for (i=0; i<m; i++) f[i] = exp(x[0]*t[i]) - y[i];

( )3

2

1

1min2 i

i

f x=∑

( ) it xi if x e y= −

Page 414: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

} /* 関数の最後 /

出力結果

The solution is 0.4401 The function values are 1 2 3 -0.447 -1.589 0.744

例題 2

この例題は、Neter その他 (1983 年、475−478 ページ ) によって述べられた、

次の非線形回帰モデルに当てはめるために imsl_f_nonlin_least_squares が最初に呼ばれます。

ここでは、εi はそれぞれが独立に平均 0,分散 σ2 の正規分布です。σ2 の

推定値は以下の式で計算されます。

ここで ei は i 番目の残差で、 J はヤコブ行列です。 と の推定される近似分

散 - 共分散行列は次の様に計算されます。

2

終わりに、imsl_f_t_inverse_cdf ( 第 9 章:特殊関数を参照 ) と共に使用して、

θ1 and θ2 の 95 % 信頼区間を計算します。

#include <math.h>#include <imsl.h>

void exampl(int, int, float[], float[]);

void main(){ int i, j, m=15, n=2, rank; float a, *result, e[15], jtj_inv[4], s2, dfe; char *fmt="%12.5e"; static float xguess[2] = {60.0, -0.03}; static float grad_tol = 1.0e-3;

result = imsl_f_nonlin_least_squares(exampl, m, n, IMSL_XGUESS, xguess, IMSL_GRAD_TOL, grad_tol, IMSL_FVEC_USER, e, IMSL_RANK, &rank, IMSL_JTJ_INVERSE_USER, jtj_inv, 0); dfe = (float) (m - rank); s2 = 0.0; for (i=0; i<m; i++) s2 += e[i] * e[i]; s2 = s2 / dfe; j = n * n; for (i=0; i<j; i++) jtj_inv[i] = s2 * jtj_inv[i];

21 1, 2, ..., 15ix

i iy e iθθ ε= + =

( )

15 22 1

15 rankii

es

J==

−∑

1θ 2θ

( ) ( ) 12ˆest. asy. var Ts J Jθ−

=

Page 415: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* 結果をプリント */

imsl_f_write_matrix ( "Estimated Asymptotic Variance-Covariance Matrix", 2, 2, jtj_inv, IMSL_WRITE_FORMAT, fmt, 0); printf(" \n 95%% Confidence Intervals \n "); printf(" Estimate Lower Limit Upper Limit \n "); for (i=0; i<n; i++) { j = i * (n+1); a = imsl_f_t_inverse_cdf (0.975, dfe) * sqrt(jtj_inv[j]); printf(" %10.3f %12.3f %12.3f \n", result[i], result[i] - a, result[i] + a); }} /* メインの最後 */

void exampl(int m, int n, float x[], float f[]){ int i; float y[15] = { 54.0, 50.0, 45.0, 37.0, 35.0, 25.0, 20.0, 16.0, 18.0, 13.0, 8.0, 11.0, 8.0, 4.0, 6.0 }; float xdata[15] = { 2.0, 5.0, 7.0, 10.0, 14.0, 19.0, 26.0, 31.0, 34.0, 38.0, 45.0, 52.0, 53.0, 60.0, 65.0 };

for (i=0; i<m; i++) f[i] = y[i] - x[0]*exp(x[1]*xdata[i]);

} /* 関数の最後 */出力結果

Estimated Asymptotic Variance-Covariance Matrix 1 2 1 2.17524e+00 -1.80141e-03 2 -1.80141e-03 2.97216e-06 95% Confidence Intervals Estimate Lower Limit Upper Limit 58.608 55.422 61.795 -0.040 -0.043 -0.036

情報エラー

IMSL_STEP_TOLERANCE 尺度化されたステップ許容値が満足され

ました。現在の点は近似された局所解であるかも知れませんが、このアルゴリズムが非常に遅く進行して、解の近くではなく、或いは step_tol が余りにも

大きすぎる可能性もあります。

警告エラー

IMSL_LITTLE_FCN_CHANGE この関数の中の、実際と予想された集計

の両方が、相対関数許容値より小さいか、等しくなります。

IMSL_TOO_MANY_ITN 反復の最大数を超えました。

IMSL_TOO_MANY_FCN_EVAL 関数計算の最大数を超えました。

IMSL_TOO_MANY_JACOBIAN_EVAL ヤコブ行列計算の最大数を超えました。

IMSL_UNBOUNDED 5 回の連続ステップが最大ステップ長で

取られました。

重大エラー

IMSL_FALSE_CONVERGE 反復は非臨界点に収束するように見えま

す。

Page 416: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

read_mps線形計画問題や二次計画問題を含む MPS ファイルを読み込みます。

概要

#include <imsl.h>

imsl_f_mps* imsl_f_read_mps(char* filename, …, 0)void imsl_f_free_mps(imsl_f_msp *mps)double 型関数は、 imsl_d_read_mpsです。

必要な引数

char* filename ( 入力 )読み込む MPS ファイルの名前。オプション引数 IMSL_FILE が使用さ

れると NULLになります。

戻り値

MPS ファイルからのデータの読み込みを含む構造体へのポインター。この空

間を開放するには、 imsl_f_free_mpsを使用します。

返却される構造体は、次のフィールドが含まれています。

フィールド 説明char* filename MPS ファイルの名前。char name[9] 問題の名前。int nrows 制約行列の行数。int ncolumns 制約行列の列数。これは変数の数でもありま

す。int nonzeros 制約行列内の非ゼロの数int nhessian ヘッセ行列内の非ゼロの数。ゼロの場合、

ヘッセ行列はありません。int ninteger 整数である必要がある変数の数。これは、2

進数の変数も含みます。int nbinary 2 進数 (0 又は 1) である必要がある変数の数。float* objective 目的ベクトルを含む長さ ncolumns の浮動小

数点配列。Imsl_f_sparse_elem* constraint 制約行列の疎行列表現を含む長さ nonzeros

の imsl_f_sparse_elem 配列。詳細は、以下

を参照してください。Imsl_f_sparse_elem* hessian ヘッセ行列の疎行列表現を含む長さ

nhessian の imsl_f_sparse_elem配列。 nhessian がゼロの場合、このフィールドは NULLになります。

float* lower_range 下制約境界を含む長さ nrows の浮動小数点配

列。下に制約に境界がない場合、lower_range 内の対応する入力は、以下で定

義される negative_infinityに設定されま

す。float* upper_range 上制約境界を含む長さ nrows の浮動小数点配

列。上に制約に境界がない場合、upper_range 内の対応する入力は、以下で定

義される positive_infinityに設定されま

す。float* lower_bound 下変数境界を含む長さ ncolumns の浮動小数点

配列。下に変数に境界がない場合、lower_bound 内の対応する入力は、以下で定

義される negative_infinityに設定されま

す。

Page 417: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

この構造体は、制約行列とヘッセ行列を単純な疎行列の形式で格納します。行列内のそれぞれの非ゼロ要素のために、行インデックス、列インデックス、値は与えられます。次に示すコードでは、 mps によって指される構造体内の疎の

制約行列を密行列に拡張します。

/* 配列の割り当て */int nr = mps->nrows;int nc = mps->ncolumns;float* matrix = (float*)calloc(nr*nc, sizeof(float));

/* 疎行列の拡張 */for (k = 0; k < mps->nonzeros; k++) {

i = mps->constraint[k].row; j = mps->constraint[k].col; matrix[nc*i+j] = mps->constraint[k].val;

}

オプション引数

IMSL_FILE, FILE, FILE* file, ( 入力 )MPS ファイルのためのハンドル。 ファイルは読み込まれますが、ク

ローズしません。このオプションは、このオプションは、引数が必要とするファイル名を無効にします。

IMSL_NAME_RHS, char* name_rhs ( 入力 )使用される RHS セットの名前。MPS ファイルは、複数の RHS セット

を含むことが可能です。 デフォルトでは、MPS ファイルの最初の RHS セットが使用されます。

この名前は、大文字小文字の区別があります。

float* upper_bound 上変数境界を含む長さ ncolumns の浮動小数点

配列。上に変数に境界がない場合、upper_bound 内の対応する入力は、以下で定

義される positive_infinityに設定されま

す。int* variable_type 各変数の種類を含む長さ ncolumns の int 型配

列。変数は次の通りです。0 連続 1 整数2 2 進数 (0 又は 1)3 半連続

char name_objective[9] 目的行のために使用される ROWS にセットさ

れる名前char name_rhs[9] 使用される RHS セットの名前。char name_ranges[9] 使用される RANGES セットの名前、もしく

は、ファイルに RANGES セクションが無い場

合、空の文字列。char name_bounds[9] 使用される BOUNDS セットの名前、もしく

は、ファイルに BOUNDS セクションが無い場

合、空の文字列。char** name_row 行の名前を含む長さ nrows の配列。 i 番目の制

約行は、 name_row[i]です。char** name_column 列の名前を含む長さ ncolumns の配列。 i 番目

の制約列は、 name_column[i]です。float positive_infinity 上に制約や境界が無い場合、制約、又は境界

の上限で使用される値。オプション引数を使用してこの値を設定することができます。デフォルトは、1.0e+30 です。

float negative_infinity 下に制約や境界が無い場合、制約、又は境界の下限で使用される値。オプション引数を使用してこの値を設定することができます。デフォルトは、–1.0e+30 です。

Page 418: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_NAME_RANGES, char* name_ranges ( 入力 )使用される RANGES セットの名前。MPS ファイルは、複数の RANGES セットを含むことが可能です。 デフォルトでは、MPS ファイルの最初の RANGES セットが使用され

ます。この名前は、大文字小文字の区別があります。

IMSL_NAME_BOUNDS, char* name_bounds ( 入力 )使用される BOUNDS セットの名前。MPS ファイルは、複数の BOUNDS セットを含むことが可能です。

デフォルトでは、MPS ファイルの最初の BOUNDS セットが使用され

ます。この名前は、大文字小文字の区別があります。

IMSL_POSITIVE_INFINITY, float positive_infinity ( 入力 )上に制約や境界が無い場合、制約や境界の下限で使用される値。デフォルト: 1.0e+30.

IMSL_NEGATIVE_INFINITY, float negative_infinity ( 入力 )下に制約や境界が無い場合、制約や境界の下限で使用される値。デフォルト: -1.0e+30.

説明

MPS ファイルは、線形計画問題や二次計画問題を定義します。

線形計画問題は、次の形式を持つと仮定されます。

二次計画問題は、次の形式を持つと仮定されます。

次のテーブルは、この表記とリーダーによって返される構造体のフィールドの関連を説明します。

C 目的A 制約行列Q ヘッセ行列

lower_range

upper_range

lower_bound

upper_bound

xcT

xmin

UL bAxb ≤≤

UL xxx ≤≤

xcQxx TT

x+

21min

UL bAxb ≤≤

UL xxx ≤≤

LbUbLxUx

Page 419: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

MPS ファイルが、等号制約もしくは、境界を指定すると、返された構造体内

の対応する下限値と上限値は、ちょうど等しくなります。

問題の公式化は、制約と境界は 2 つのサイドがあると仮定します。特定の制

約、又は境界が、加減を持たない場合、構造体の対応する入力は -1.0e+30 に設

定されます。上限が無い場合、構造体の対応する入力は、 +1.0e+30 に設定され

ます。

MPS ファイル形式MPS 形式にはばらつきがあります。本セクションでは、このリーダが読み込

み可能な MPS 形式について説明します。

MPS ファイルは、複数のセクションから成り立っています。各セクションは、

列 1 の名前から始まります。NAME セクションは例外として、この行の全て

は無視されます。列 1 内の ‘*’ や ‘$’ は、コメント行と考えられ、無視されま

す。

各セクションの主部は、次の様なフィールドに分けられた行列から構成されています。

この形式は、 MPS 名を 8 文字、値を 12 文字に制限します。フィールド 2、3、5 の名前は、大文字小文字の区別があります。文字列の最初と最後のスペース

は無視されます。しかし文字列内のスペースは、有効です。

MPS ファイル内のセクションは、以下の通りです。

• NAME

• ROWS

• COLUMNS

• RHS

• RANGES (optional)

• BOUNDS (optional)

• QUADRATIC (optional)

• ENDATAセクションは、上記の順番でなければなりません。

MPS キーワード、セクション名、インジケータの値は、大文字小文字の区別

がありません。行名、列名、セット名は、大文字小文字の区別があります。

NAME セクションNAME セクションは、1 行が含まれます。問題名は、NAME の後でコラム 62の前のどこかに存在します。問題名は、8 文字に切り詰められます。

ROWS セクションROWS セクションは、各行の名前や種類を定義します。フィールド 1 は行の形

式、フィールド 2 は行名を含みます。行の形式の値は、大文字小文字の区別が

ありません。行の名前は、大文字小文字の区別があります。次の行形式が使用できます。

フィールド番号 列 内容1 2-3 インジケーター2 5-12 名前3 15-22 名前4 25-36 値5 40-47 名前6 50-61 値

Page 420: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

COLUMNS セクションCOLUMNS セクションは、目的行列や制約行列内の非ゼロ入力を定義します。

行名は、ROWS セクションで定義されている必要があります。

注意: フィールド 5 と 6 は、オプションです。

COLUMNS セクションは、マーカーも含むことが可能です。マーカーは、

フィールド 3 の名前 ‘MARKER’ ( コーテーション付き ) とフィールド 4 と 5 の

マーカータイプによって示されます。

マーカータイプ ‘INTORG’ ( コーテーション付き ) は、整数グループを開始し

ます。マーカータイプ ‘INTEND’ ( コーテーション付き ) は、このグループを

終了します。 このグループ内で定義された列に対応する変数は、整数である必

要があります。

RHS セクションRHS セクションは、制約の右辺を定義します。 MPS ファイルは、RHS セット

名で区別される複数の RHS セットを含むことができます。行名は、ROWS セクションで定義されなければなりません。

行の形式 意味 E 等号制約L Less than or equal

constraint.G Greater than or

equal constraint.N 目的行または空の

フィールド 内容2 列名3 行名4 Value for the entry

whose row and column are given by fields.

5 行名6 Value for the entry

whose row and column are given by fields 5 and 2.

フィールド 内容2 RHS セット名3 行名4 フィールド 2、3

によって与えられたセットと行の入力値。

5 Row name.6 フィールド 2、5

によって与えられたセットと行の入力値。

Page 421: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

注意: フィールド 5 と 6 は、オプションです。

RANGES セクションオプションの RANGES セクションは、2 つのサイドの制約を定義します。

MPS は、範囲セット名で区別される複数の範囲セットを含むことができます。

行名は、 ROWS セクションで定義されていなければなりません。

注意: フィールド 5 と 6 はオプションです。

Ranges は、RHS セクション内で定義されている、1 サイドの制約を 2 サイドの

制約に変更します。行 i の 2 サイドの制約は、このセクションで定義されてい

る範囲の値 に依存します。右辺の値 は、RHS セクションで定義されま

す。 i のための 2 サイド制約は、次の表に示されます。

BOUNDS セクションオプションの BOUNDS セクションは、変数の境界を定義します。デフォルト

では、境界は、 です。境界は、変数が整数ではならないことを示すためにも使用されます。

1 つの変数のために、複数の境界を設定することが可能です。例えば、

を設定する場合、 を設定するために値 2 を持つ LO 境界を使

用します。条件 を加えるために値 6 を持つ UP 境界を使用します。

MPS ファイルは、境界セット名で区別される複数の境界を含むことができま

す。

フィールド 内容2 範囲セット名3 行名4 フィールド 2、3 によって与えら

れたセットと行の入力値。5 行名6 フィールド 2、5 によって与えら

れたセットと行の入力値。

行形式 下制約 上制約G

L

E

フィールド 内容1 境界の形式2 境界セット名3 列名4 フィールド 2、3 によって与えられるセット

や列の入力値5 列名

ir ib

ib || ii rb +

|| ii rb − ib

),0min( ii rb + ),0max( ii rb +

∞≤≤ ix0

62 ≤≤ ix ix≤2

6≤ix

Page 422: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

注意: フィールド 5 と 6 はオプションです。

境界の形式は以下の通りです。ここで、 はこのセクションで定義された境界

値、 は変数、 I は整数のセットです。

境界の形式名は、大文字小文字の区別はありません。

境界の形式が UP もしくは UI で の場合、下界は、 に設定されます。

QUADRATIC セクションオプション QUADRATIC セクションは、二次計画問題のためのヘッセ行列を

定義します。名前 HESSIAN、 QUADS、 QUADOBJ、 QSECTION、QMATRIX も QUADRATIC セクションの始まりとして認識されます。

注意: フィールド 5 と 6 はオプションです。

ENDATA セクションENDATA セクションは、 MPS ファイルを終了します。

6 フィールド 2、5 によって与えられるセット

や列の入力値

境界の形式 定義 公式LO 下界

UP 上界

FX 固定された変数

FR 自由な変数

MI 下界が負の無限大

PL 上界が正の無限大

BV 2 進数変数 ((変

数は 0 か 1)UI 上界と整数

and LI 下界と整数

and SC 半連続

0 or

フィールド 内容2 列名3 列名4 フィールド 2、3 によって与えられる行や列

の入力値。5 列名6 フィールド 2、4 によって与えられる行や列

の入力値。

ib

ix

ij xb ≤

ii bx ≤

ii bx =

∞≤≤∞− ix

ix≤∞−

∞≤ix

}1,0{∈ix

ii bx ≤ Ixi ∈

ii xb ≤ Ixi ∈

ii xb ≤

0<jb ∞−

Page 423: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

linear_programming線形計画問題を解きます。

概要

#include <imsl.h>

double *imsl_d_linear_programming (int m, int n, double a[], double b[], double c[], …, 0)

必要な引数

int m ( 入力 )制約数。

int n ( 入力 )変数の数。

double a[] ( 入力 )m 個の制約式の係数を持つ行列を含むサイズ m × n の配列。

double b[] ( 入力 )制約式の右辺を含む m 要素の配列で、制約式の両辺に制限が無けれ

ば、b は制約式の下限を含みます。

double c[] ( 入力 )目的関数の係数を含む n 要素の配列。

戻り値

線形計画問題の解 x へのポインター。 この空間を開放するには free を使用しま

す。計算される解が存在しなければ、NULL が返されます。

オプション引数の概要

#include <imsl.h>double *imsl_d_linear_programming (int m, int n, double a[], double b[],

double c[],IMSL_A_COL_DIM, int a_col_dim,IMSL_UPPER_LIMIT, double bu[],IMSL_CONSTR_TYPE, int irtype[],IMSL_LOWER_BOUND, double xlb[],IMSL_UPPER_BOUND, double xub[],IMSL_REFINEMENT, IMSL_EXTENDED_REFINEMENT, IMSL_OBJ, double *obj,IMSL_RETURN_USER, double x[],IMSL_DUAL, double **y,IMSL_DUAL_USER, double y[],0)

オプション引数

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 a の列ディメンジョン。

デフォルト: a_col_dim = n

IMSL_UPPER_LIMIT, double bu[] ( 入力 )下と上の両方の境界を持つ制約式の上限を含む m 要素の配列。そのよ

うな制約式が存在しなければ、bu は必要ありません。

IMSL_CONSTR_TYPE, int irtype[] ( 入力 )行列 a の一般制約式のタイプを示す m 要素の配列。

ri = ai1x1 + … + ainxn とします。すると、irtype[I] の値は次を示しま

す。

Page 424: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

デフォルト: irtype = 0

IMSL_LOWER_BOUND, double xlb[] ( 入力 )変数の下境界を含む n 要素の配列。変数に下境界が存在しなければ、

1030 を下境界としてセットしなければなりません。

デフォルト: xlb = 0

IMSL_UPPER_BOUND, double xub[] ( 入力 )変数の上境界を含む n 要素の配列。変数に上境界が存在しなければ、 

-1030 を上境界としてセットしなければなりません。

デフォルト: 上境界なし

IMSL_REFINEMENT ( 入力 )係数行列とその他のデータは計算の始めに保存されます。終了時には得られた解と共にこのデータの正当性がチェックされます。食い違いが大きいならば、求解過程は等号の処理のすぐ後でこの問題データを使用して、しかも最終 x 値と最終の動作中のセットで再スタートされ

ます。デフォルト: 改良法は実行されません。

IMSL_EXTENDED_REFINEMENT ( 入力 )これ以上の進行が不可能であるというサインがあるまで繰り返されることを除いて、IMSL_REFINEMENT と同様です。 ( 全ての正確可能性が

望まれる場合、推奨されます ) 。デフォルト: 拡張された改良法は実行されません。

IMSL_OBJ, double *obj ( 出力 )目的関数の最適値。

IMSL_ITERATION_COUNT, int *iterations ( 出力 )反復数。

IMSL_RETURN_USER, double x[] ( 出力 )主要解を含む n 成分の配列。

IMSL_DUAL, double **y ( 出力 )双対問題の解を含む m 要素の配列のポインター のアドレス。返される

時、必要な空間は imsl_d_linear_programming によって割り当てら

れます。通常、double *y が宣言されて、&y が引数として使用されま

す。

IMSL_DUAL_USER, double y[] ( 出力 )サイズ m のユーザ割り当ての配列。返される時に、y は双対問題の解

を含みます。

説明

関数 imsl_d_linear_programming は、active set 法を使用して、 次の形式の問

題のような線形計画問題を解きます。

ここで、 c は、目的係数ベクトル、 A は係数行列、ベクトル bl、 bu、 xl、xu はそ

れぞれ制約と変数の上界と下界です。

Irtype[I] Constraint0 ri = bi1 ri ≤ bui2 ri ≥ bi3 bi ≤ ri ≤ bui4 この制約を無視

min subject to n

Tl x u

x

l u

c x b A b

x x x∈

≤ ≤

≤ ≤R

Page 425: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

詳細は、次の論文を参照してください。 Krogh, Fred, T. (2005), An Algorithm for Linear Programming, http://mathalacarte.com/fkrogh/pub/lp.pdf , Tujunga, CA.

例題

例題 1

標準形式の線形計画問題を解きます。

#include <imsl.h>

main(){ int m = 4; int n = 6; double a[ ] = {1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; double b[ ] = {1.5, 0.5, 1.0, 1.0}; double c[ ] = {-1.0, -3.0, 0.0, 0.0, 0.0, 0.0}; double *x; /* LP 問題を解く */

x = imsl_d_linear_programming (m, n, a, b, c, 0); /* xをプリント */ imsl_d_write_matrix ("x", 1, 6, x, 0);}

出力結果

x 1 2 3 4 5 6 0.5 1.0 0.0 1.0 0.5 0.0

例題 2

この問題は MPS に定義された線形計画法問題を解くために関数 imsl_d_read_mps がimsl_d_linear_programmingと一緒に使用される方法を

説明します。 この例題で使用される MPS ファイルは http://

www.netlib.org/lp/data/ から利用できる形式のファイル「afiro」の非圧縮

バージョンです。この例題は又、imsl_d_linear_programming の反復改良法

を稼動させるためにオプション引数 IMSL_REFINEMENTの使用法を説明します。

#include <stdio.h>

#include <malloc.h>

#include <imsl.h>

void main()

{

#define A(I, J) a[(I)*problem->ncolumns+J]

Imsl_d_mps* problem;

int i, j, k, *irtype;

double *x, objective, *a, *b, *bl, *bu, *xlb, *xub;

/* MPS ファイルの読み込み */

( ) 1 2

1 2 3

1 2 4

1 5

2 6

min 31.5subject to0.5

1.01.0

0, for 1, , 6i

f x x xx x xx x xx x

x xx i

= − −

+ + =+ − =

+ =+ =

≥ = K

Page 426: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

problem = imsl_d_read_mps("afiro", 0);

/*

* 制約タイプ配列を設定

*/

irtype = (int*)malloc(problem->nrows*sizeof(int));

for (i = 0; i < problem->nrows; i++)

irtype[i] = 3;

/*

* 制約行列の設定

*/

a = (double*)calloc(problem->nrows*problem->ncolumns*sizeof(double),

sizeof(double));

for (k = 0; k < problem->nonzeros; k++) {

i = problem->constraint[k].row;

j = problem->constraint[k].col;

A(i, j) = problem->constraint[k].val;

}

/*

* 制約境界を設定

*/

bl = (double*)malloc(problem->nrows*sizeof(double));

bu = (double*)malloc(problem->nrows*sizeof(double));

for (i = 0; i < problem->nrows; i++) {

bl[i] = problem->lower_range[i];

bu[i] = problem->upper_range[i];

}

/*

* 変数境界を設定。境界の無い変数がどのように設定されるかを

* 明らかにする

*/

xlb = (double*)malloc(problem->ncolumns*sizeof(double));

xub = (double*)malloc(problem->ncolumns*sizeof(double));

for (i = 0; i < problem->ncolumns; i++) {

xlb[i] = (problem->lower_bound[i] == problem->negative_infinity)?

1.0e30:problem->lower_bound[i];

xub[i] = (problem->upper_bound[i] == problem->positive_infinity)?

-1.0e30:problem->upper_bound[i];

}

/*

* LP 問題を解く

*/

x = imsl_d_linear_programming(problem->nrows, problem->ncolumns,

a, bl, problem->objective,

IMSL_UPPER_LIMIT, bu,

IMSL_CONSTR_TYPE, irtype,

IMSL_LOWER_BOUND, xlb,

Page 427: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_UPPER_BOUND, xub, IMSL_REFINEMENT,

IMSL_OBJ, &objective,

0);

/*

* 出力結果

*/

printf("Problem Name: %s\n", problem->name);

printf("objective : %e\n", objective);

imsl_d_write_matrix("Solution", problem->ncolumns, 1, x, 0);

/*

* メモリーを解放

*/

imsl_d_mps_free(problem);

free(irtype);

free(a);

free(bu);

free(bu);

free(xlb);

free(xub);

}出力結果

Problem Name: AFIRO

objective : -4.647531e+02

Solution

1 80.0

2 25.5

3 54.5

4 84.8

5 57.9

6 0.0

7 0.0

8 0.0

9 0.0

10 0.0

11 0.0

12 0.0

13 18.2

14 39.7

15 61.3

16 500.0

17 475.9

18 24.1

19 0.0

20 215.0

21 363.9

22 0.0

Page 428: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

23 0.0

24 0.0

25 0.0

26 0.0

27 0.0

28 0.0

29 339.9

30 20.1

31 156.5

32 0.0

注意エラー

IMSL_MULTIPLE_SOLUTIONS 本質的に同じ最小を与える複数の解が存在

します。

警告エラー

IMSL_SOME_CONSTRAINTS_DISCARDED ある制約式は他のアクティブな制約

式と余りにも線形依存であるので破棄されます。

IMSL_ALL_CONSTR_NOT_SATISFIED 全ての制約は満足されません。実現

可能な解があり得る場合、オプション引数 IMSL_REFINEMENT を提供することにより改

良法を使用ることを試してください。

IMSL_CYCLING_OCCURRING このアルゴリズムは循環していると思われ

ます。改良法の使用が役立つかも知れません。

重大エラー

IMSL_PROB_UNBOUNDED この問題は境界がありません。

IMSL_PIVOT_NOT_FOUND 満足できる枢軸が見つかりませんでした。

lin_prog改訂シンプレックス法を使用して線形計画問題を解きます。

注意: 倍精度の場合、関数 lin_prog は関数 linear_programmingに取って代

わられます。関数 lin_prog は、既存の呼び出しの互換性を確保するために残

してあります。

概要

#include <imsl.h>

float *imsl_f_lin_prog (int m, int n, float a[], float b[], float c[], …, 0)

double 型関数は、 imsl_d_lin_progです。

必要な引数

int m ( 入力 )制約数。

int n ( 入力 )変数の数。

Page 429: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float a[] ( 入力 )m 制約の係数の行列を含むサイズ m × n の配列。

float b[] ( 入力 )制約の右辺を含む m 成分の配列。この制約の両側に限界が存在すれ

ば、b は制約の下限を含みます。

float c[] ( 入力 )目的関数の係数を含む n 成分の配列。

戻り値

線形計画問題の解 x のポインター。この空間を解放するために free を使用

します。解が得られない場合,NULL が返されます。

オプション引数の概要

#include <imsl.h>float *imsl_f_lin_prog (int m, int n, float a[], float b[], float c[],

IMSL_A_COL_DIM, int a_col_dim,IMSL_UPPER_LIMIT, float bu[],IMSL_CONSTR_TYPE, int irtype[],IMSL_LOWER_BOUND, float xlb[],IMSL_UPPER_BOUND, float xub[],IMSL_MAX_ITN, int max_itn,IMSL_OBJ, float *obj,IMSL_RETURN_USER, float x[],IMSL_DUAL, float **y,IMSL_DUAL_USER, float y[],0)

オプション引数

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 a の列ディメンジョン。

デフォルト: a_col_dim = n

IMSL_UPPER_LIMIT, float bu[] ( 入力 )下限と上限の両方を持つ制約の上限を含む m 成分の配列。このよう

な制約が存在しなければ bu は必要ありません。

IMSL_CONSTR_TYPE, int irtype[] ( 入力 )行列 a の一般制約のタイプを示す m 成分の配列。

ri=ai1x1+…+ainxn とします。その時は irtype(i) の値は次を示し

ます。

デフォルト: irtype = 0

IMSL_LOWER_BOUND, float xlb[] ( 入力 )変数の下限を含む n 成分の配列。変数の下限がなければ、その下限

として 1030 をセットする必要があります。デフォルト: xlb = 0

IMSL_UPPER_BOUND, float xub[] ( 入力 )変数の上限を含む n 成分の配列。変数の上限がなければ、その上限

として -1030 をセットする必要があります。

デフォルト: xub = ∞

irtype(i) 制約0 ri = bi1 ri ≤ bui2 ri ≥ bi3 bi ≤ ri ≤ bui

Page 430: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_MAX_ITN, int max_itn ( 入力 )最大反復回数。デフォルト: max_itn = 10000

IMSL_OBJ, float *obj ( 出力 )目的関数の最適値。

IMSL_RETURN_USER, float x[] ( 出力 )主要解を含む n 成分の配列。

IMSL_DUAL, float **y ( 出力 )双対解を含む m 成分の配列のポインター y のアドレス。返されると

き必要な空間は imsl_f_lin_prog によって割り当てられます。通常、

float *yが宣言されて、&y が引数として使用されます。

IMSL_DUAL_USER, float y[] ( 出力 )サイズ mのユーザ割り当ての配列。 返される時、 yは双対解を含みま

す。

IMSL_USE_UPDATED_LP_ALGORITHM ( 入力 )関数 imsl_d_linear_programming を呼び出して、問題を解きます。 このオプション引数が指定されると、オプション引数 IMSL_MAX_ITN は無視されます。このオプション引数は、倍精度の場合のみ有効です。

説明

関数 imsl_f_lin_prog は、改訂シンプレックス法を使用して次の形式の問題

のような線形計画問題を解きます。

ここで c は目的関数係数ベクトルです。A は係数行列で、bl、bu、xl、xu  は

それぞれ制約と変数の上限と下限です。

改訂シンプレックス法の完全な説明は Murtagh (1981 年 ) 或いは Murty (1983 年 ) を参照してください。

例題

例題 1

次のような一般的な形式の線形計画問題を解きます。

#include <imsl.h>

main(){ int m = 4; int n = 6; float a[ ] = {1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; float b[ ] = {1.5, 0.5, 1.0, 1.0}; float c[ ] = {-1.0, -3.0, 0.0, 0.0, 0.0, 0.0}; float *x; /* Solve the LP problem */

min subject to n

Tl x u

x

l u

c x b A b

x x x∈

≤ ≤

≤ ≤R

( ) 1 2

1 2 3

1 2 4

1 5

2 6

min 31.5subject to0.5

1.01.0

0, for 1, , 6i

f x x xx x xx x xx x

x xx i

= − −

+ + =+ − =

+ =+ =

≥ = K

Page 431: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

x = imsl_f_lin_prog (m, n, a, b, c, 0); /* Print x */ imsl_f_write_matrix ("x", 1, 6, x, 0);}

出力結果

x 1 2 3 4 5 6 0.5 1.0 0.0 1.0 0.5 0.0

例題 2

例題 1 の線形計画問題は、次のの形式にすることができます。

この問題のほうが、より効率的に解かれます。

#include <imsl.h>

main(){ int irtype[ ] = {3}; int m = 1; int n = 2; float xub[ ] = {1.0, 1.0}; float a[ ] = {1.0, 1.0}; float b[ ] = {0.5}; float bu[ ] = {1.5}; float c[ ] = {-1.0, -3.0}; float d[1]; float obj, *x; /* LP 問題を解く */

x = imsl_f_lin_prog (m, n, a, b, c, IMSL_UPPER_LIMIT, bu, IMSL_CONSTR_TYPE, irtype, IMSL_UPPER_BOUND, xub, IMSL_DUAL_USER, d, IMSL_OBJ, &obj, 0); /* xをプリント */ imsl_f_write_matrix ("x", 1, 2, x, 0); /* dをプリント */ imsl_f_write_matrix ("d", 1, 1, d, 0); printf("\n obj = %g \n", obj);}

出力結果

x 1 2 0.5 1.0 d -1

obj = -3.5

警告エラー

IMSL_PROB_UNBOUNDED この問題は境界がありません。

IMSL_TOO_MANY_ITN 反復の最大数を超えました。

1 2

1

2

minsubject to 0.5 x + x 1.5 0 1.0 0 1.0

1 2 f(x) = - x - 3x

xx

≤ ≤≤ ≤≤ ≤

Page 432: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_PROB_INFEASIBLE この問題は実行不可能です。

重大エラー

IMSL_NUMERIC_DIFFICULTY 数値上の困難が生じました。現在、float を使用している場合、double を使用したほう

が良い場合があります。

IMSL_BOUNDS_INCONSISTENT 境界が矛盾しています。

quadratic_prog線形等号制約、又は不等号制約を受ける二次計画問題を解きます。

概要

#include <imsl.h>

float *imsl_f_quadratic_prog (int m, int n, int meq, float a[], float b[], float g[], float h[], …, 0)

double 型関数は、 imsl_d_quadratic_progです。

必要な引数

int m ( 入力 )線形制約の数。

int n ( 入力 )変数の数。

int meq ( 入力 )線形等号制約の数。

float a[] ( 入力 )最初の meq 行に等号制約を含むサイズ m × n の配列で、不等号制約が

続きます。

float b[] ( 入力 )線形制約の右辺を含む m 要素の配列。

float g[] ( 入力 )目的関数の線形項の係数を含む n 要素の配列。

float h[] ( 入力 )目的関数のヘッセ行列を含むサイズ n × n の配列。これは対称正定値で

なければなりません。h が正定値でなければこのアルゴリズムは、

h + diag* I によって置き換えられる h を持つ QP 問題を解きますの

で、h + diag* I は、正定値になります。

戻り値

QP 問題の解のポインター。この空間を開放するために freeを使用します、

解が得られない場合,NULL が返されます。

オプション引数の概要

#include <imsl.h> float *imsl_f_quadratic_prog (int m, int n, int meq, float a[], float b[], float g[], float h[],

IMSL_A_COL_DIM, int a_col_dim,IMSL_H_COL_DIM, int h_col_dim,

IMSL_RETURN_USER, float x[],IMSL_DUAL, float **y,IMSL_DUAL_USER, float y[],IMSL_ADD_TO_DIAG_H, float *diag,IMSL_OBJ, float *obj,0)

Page 433: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数

IMSL_A_COL_DIM, int a_col_dim ( 入力 )呼び出しプログラムのディメンジョン文で指定されているような A の先導ディメンジョン。デフォルト: a_col_dim = n

IMSL_H_COL_DIM, int h_col_dim ( 入力 )呼び出しプログラムのディメンジョン文で指定されているような h の先導ディメンジョン。デフォルト: n_col_dim = n

IMSL_RETURN_USER, float x[] ( 出力 )解を含む n 要素の配列。

IMSL_DUAL, float **y ( 出力 )ラグランジュ乗数推定を含んだ n 要素の配列のポインター y のアド

レス。返されるとき必要な空間は imsl_f_quadratic_prog によって

割り当てられます。通常、float *y が宣言されて、 &y が引数として使

用されます。

IMSL_DUAL_USER, float y[] ( 出力 )m 要素のユーザ提供の配列。返されるとき y はラグランジュ乗数推

定を含みます。

IMSL_ADD_TO_DIAG_H, float *diag ( 出力 )正定値行列を与えるために、h に加えられた単位行列の倍数に等しい

スカラー。

IMSL_OBJ, float *obj ( 出力 ) 見つけられた最適な目的関数。

説明

関数 imsl_f_quadratic_prog は一般線形等号 /不等号制約を受ける、凸二

次計画問題の Goldfarb と Idnani 相対 2 次計画 (QP) アルゴリズム (Goldfarb と Idnani1983 年;次式 ) の M.J.D. Powell の実装に基づいています。

ベクトル b1、b2、g と行列 H、A1、と A2 が与えられます。H は正定値になる

ために必要です。この場合には、唯一の x が問題を解くか、或いは制約が矛

盾します。H が正定値でなければ、H の正定摂動が H の代わりに使用されます。

この詳細は Powell (1983 年 , 1985 年 ) を参照してください。

H の摂動 H + αI、が QP 問題に使用されると、 H + αI はラグランジュ乗数の

定義にも使用されなければなりません。

例題

例題 1

次の二次計画問題を解きます。

#include <imsl.h>

main()

1 1

2 2

1min2

subject to

n

T T

xg x x Hx

A x bA x b

∈+

=≥

R

( ) 2 2 2 2 21 2 3 4 5 2 3 4 5 1

1 2 3 4 5

3 4 5

min 2 2 2subject to 5

2 2 3

f x x x x x x x x x x xx x x x xx x x

= + + + + − − −

+ + + + =

− − = −

Page 434: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{ int m = 2; int n = 5; int meq = 2; float *x; float h[ ] = {2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0,-2.0, 0.0, 0.0, 0.0,-2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0,-2.0, 0.0, 0.0, 0.0,-2.0, 2.0}; float a[ ] = {1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0,-2.0,-2.0}; float b[ ] = {5.0, -3.0}; float g[ ] = {-2.0, 0.0, 0.0, 0.0, 0.0}; /* Solve the QP problem */ x = imsl_f_quadratic_prog (m, n, meq, a, b, g, h, 0); /* Print x */ imsl_f_write_matrix ("x", 1, 5, x, 0);}

出力結果

x 1 2 3 4 5 1 1 1 1 1

例題 2

別の二次計画問題を解きます。

#include <imsl.h>

float h[ ] = {2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 2.0};float a[ ] = {1.0, 2.0, -1.0, 1.0, -1.0, 1.0};float b[ ] = {4.0, -2.0};float g[ ] = {0.0, 0.0, 0.0};main(){ int m = 2; int n = 3; int meq = 2; float obj; float d[2]; float *x; /* QP問題を解く */

x = imsl_f_quadratic_prog (m, n, meq, a, b, g, h, IMSL_OBJ, &obj, IMSL_DUAL_USER, d, 0); /* xをプリント */ imsl_f_write_matrix ("x", 1, 3, x, 0); /* dをプリント */ imsl_f_write_matrix ("d", 1, 2, d, 0); printf("\n obj = %g \n", obj); }

出力結果

x 1 2 3 0.286 1.429 -0.857 d

( ) 2 2 21 2 3 1 2 3

1 2 3

min subject to 2 42

f x x x x x x xx x x

= + + + − =

− + = −

Page 435: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1 2 1.143 -0.571

obj = 2.85714

警告エラー

IMSL_NO_MORE_PROGRESS コンピュータ丸め誤差の影響により、変数

の中の変化が目的関数値の改良に失敗した。通常その解は最適に近くなります。

重大エラー

IMSL_SYSTEM_INCONSISTENT 連立方程式に矛盾があります。解は存在し

ません。

min_con_gen_lin線形等号 / 不等号制約をうける一般目的関数を最小化します。

概要

#include <imsl.h>

float *imsl_f_min_con_gen_lin (void fcn(), int nvar, int ncon, int neq, float a[], float b[], float xlb[], float xub[], ..., 0)

double 型関数は、 imsl_d_min_con_gen_lin.

必要な引数

void fcn (int n, float x[], float *f ) ( 入力 / 出力 )最小化される関数を評価するユーザ提供の関数。引数 x は、関数が計

算される点での長さ n のベクトルで、f は x の関数値を含みます。

int nvar ( 入力 )変数の数。

int ncon ( 入力 )線形制約 ( 単純境界を除く ) の数。

int neq ( 入力 )線形等号制約の数。

float a[] ( 入力 )サイズ ncon × nvar の配列で、最初の neq 行に等号制約勾配が含ま

れ、不等号制約勾配がそれに続きます。

float b[] ( 入力 )線形制約の右辺を含むサイズ ncon の配列。特に、変数 xi、 i = 0、 nvar-1 の制約 は ak,0x0 + ... + ak,nvar-1xnvar-1 = bk, k = 0, ... ,neq−1 そし

て ak,0x0 + ... + ak,nvar-1xnvar-1 ≤bk, k = neq, ... , ncon-1 です。等号制約を

定義するデータは不等号のデータの前に来ることに注意してください。

float xlb[] ( 入力 )変数の下境界を含んだ長さ nvar の配列。もし要素が無限に小さけれ

ば非常に大きい負の値を選び、又は i 番目の変数を固定するならば

xub[i] = xub[i] に設定します。特に、これらの単純境界は xlib[i] ≤ xi , i = 1, ... , nvar です。

float xub[] ( 入力 )変数の上境界を含んだ長さ nvar の配列。もし要素が無限に大きいな

らば非常に大きい正の値を選びます。 特に、これらの単純境界は xi ≤ xub[i] , i = 1, ... , nvar になります。

Page 436: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

解 x のポインター。この空間を開放するために freeを使用します。解が得ら

れない場合,NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_min_con_gen_lin (void fcn(), int nvar, int ncon, int a, float b, float xlb[], float xub[],IMSL_XGUESS, float xguess[],IMSL_GRADIENT, void gradient(),IMSL_MAX_FCN, int max_fcn,IMSL_NUMBER_ACTIVE_CONSTRAINTS, int *nact,IMSL_ACTIVE_CONSTRAINT, int **iact,IMSL_ACTIVE_CONSTRAINT_USER, int *iact_user,IMSL_LAGRANGE_MULTIPLIERS, float **lagrange,IMSL_LAGRANGE_MULTIPLIERS_USER, float *lagrange_user,IMSL_TOLERANCE, float tolerance,IMSL_OBJ, float *obj,IMSL_RETURN_USER, float x[],IMSL_FCN_W_DATA, void fcn(), void *data,IMSL_GRADIENT_W_DATA, void grad(), void *data,0)

オプション引数

IMSL_XGUESS, float xguess[] ( 入力 )初期推定値を含む n 成分の配列。

デフォルト: xguess = 0

IMSL_GRADIENT, void gradient (int n, float x[], float g[]) ( 入力 )点 x の勾配を計算するユーザ提供の関数。この x は長さ n のベクトルで、g は目的関数の概要の値を含んだ長さ n のベクトルです。

IMSL_MAX_FCN, int max_fcn ( 入力 )関数計算の最大回数。デフォルト: max_fcn = 400

IMSL_NUMBER_ACTIVE_CONSTRAINTS, int *nact ( 出力 )アクティブな制約の最終的な数。

IMSL_ACTIVE_CONSTRAINT, int **iact ( 出力 ) int へのポインターのアドレスで、終了時に最後のアクティブな制約

の nact 指標を含む配列を指します。

IMSL_ACTIVE_CONSTRAINT_USER, int *iact_user ( 出力 )最初の nact 位置に最終アクティブな制約のを含む、少なくとも長さ

2*nvar のユーザ提供の配列。

IMSL_LAGRANGE_MULTIPLIERS, float **lagrange ( 出力 )ポインターのアドレスで、終了時に最初の nact 位置にある最後のア

クティブな制約のラグランジュ乗数推定を含む配列を指します。

IMSL_LAGRANGE_MULTIPLIERS_USER, float *lagrange_user ( 出力 )最初の nact 位置にある最後のアクティブな制約のラグランジュ乗数

推定を含む少なくとも nvar の長さのユーザ提供の配列。

IMSL_TOLERANCE, float tolerance ( 入力 )計算された解の 1 次条件の非負許容値。

デフォルト: tolerance = 。ここで ε は、マシンイプシロン。

IMSL_OBJ, float *obj ( 出力 )目的関数の値。

IMSL_RETURN_USER, float x[] ( 出力 )計算された解を含む nvar 要素のユーザ提供の配列。

ε

Page 437: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_FCN_W_DATA, void fcn (int n, float x[], float *f , void *data), void *data ( 入力 )最小化の関数の値を計算するための統合されるユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータを受け渡すポインターです。 詳細

は、「イントロダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_GRADIENT_W_DATA, void gradient (int n, float x[], float g[],void *data) , void *data ( 入力 )点 x での勾配を計算するユーザ提供関数。また、ユーザにより提供さ

れたデータへのポインターも受け入れます。 data は、ユーザ提供の関

数にデータを受け渡すポインターです。 詳細は、「イントロダクショ

ン」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_min_con_gen_lin は、次の形式の問題のような線形制約付き最

適化問題を解く M.J.D. Powell の TOLMIN に基づいています。

min f (x)

次の従います。

ベクトル b1、b2、xl と xu と行列 A1 と A2 が与えられます。

このアルゴリズムは矛盾と冗長のために等号制約をチェックすることから始まります。もし等号制約が矛盾していなければ、この方法は次式を満足するため

に初期推定値 x0 を改定します。

その次に x0 は単純境界と不等号制約を満足するために調整されます。このこ

とは制約の和、又は、境界侵害を最小にするために二次計画サブプログラムの系列を解くことによって実行されます。

ここで、可能な xk の各反復に対して、Jk を 小さい残差を持つ不等号制約の指

標のセットにします。ここでは、単純境界は不等号制約として扱われます。Ik をアクティブな制約の指標のセットとします。 次の二次計画問題

次の条件に従う

が (d k , λk ) を得るために解かれて、この aj は A1 又は A2 のいずれかの制約

、或いは、x の境界制約を表す行ベクトルです。この後の場合では、境界制約xi ≤ (xu)i に対しては aj = ei そして拘束 −xi ≤ (xl)i に対しては - aj = ei です。こ

こで ei は i 番目の要素が 1 、その他は0を持つベクトルです。変数 λk はラグ

ランジュの乗数で Bk は 2 次微係数 ▽ 2 f(xk) の正定値近似です。

1 1

2 2

t u

A x b

A x b

x x z

=

≤ ≤

1 1A x b=

( ) ( ) 1min2

k T k T kf x d f x d B d+ ∇ +

0,

0,j k

j k

a d j I

a d j J

= ∈

≤ ∈

Page 438: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

探索方向 d k が得られた後で、直線探索がより良い点を見つけるために実行され

ます。新しい点、x k+1 = x k + αk d k は次の条件を満足しなければなりません。

セット Jk を形成する主な考えは、等号制約のいずれかがステップ長 α k を制

限するとその指標は Jk の中に存在しないと言うことです。このために、小さ

いステップは避けらます。

終わりに、 2 次微係数近似 B K は次の条件が保持されると BFGS 公式によって

更新されます。

x k ← x k+1 として、他の反復を開始します。

この反復は次の停止基準が満足されるまで繰り返されます。

この τ は提供される許容値です。この詳細は Powell (1988 年、1989 年 ) を参

照してください。

有限差分法が幾つかの単精度計算の勾配を近似するために使用されるので、勾配の不正確な推定がこのアルゴリズムの重要でない点で停止する原因になる場合があります。この場合は、高精度演算をお勧めします。そして又、この勾配が容易に提供される場合、オプション IMSL_GRADIENT の使用をお勧めしま

す。

例題 1

この例題では、次の問題を解きます。

#include "imsl.h"

main(){ void fcn(int, float *, float *); int neq = 2; int ncon = 2; int nvar = 5;

float a[] = {1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, -2.0, -2.0}; float b[] = {5.0, -3.0}; float xlb[] = {0.0, 0.0, 0.0, 0.0, 0.0};

( ) ( ) ( ) ( )0.1Tk k k k k k kf x d f x d f xα α+ ≤ + ∇

( ) ( ) ( ) ( )0.7T TK k k k k Kd f x d d f xα∇ + ≥ ∇

( ) ( ) ( ) 0TK k k k Kd f x d f xα∇ + − ∇ >

( )2

k k Kf x A λ τ∇ − ≤

( ) 2 2 2 2 21 2 3 4 5 2 3 4 5 1

1 2 3 4 5

3 4 5

min 2 2 2subject to 5

2 2 30 10

f x x x x x x x x x x xx x x x x

x x xx

= + + + + − − −

+ + + + =

− − = −

≤ ≤

Page 439: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float xub[] = {10.0, 10.0, 10.0, 10.0, 10.0}; float *x;

x = imsl_f_min_con_gen_lin(fcn, nvar, ncon, neq, a, b, xlb, xub, 0);

imsl_f_write_matrix("Solution", 1, nvar, x, 0);}

void fcn(int n, float *x, float *f){ *f = x[0]*x[0] + x[1]*x[1] + x[2]*x[2] + x[3]*x[3] + x[4]*x[4] - 2.0*x[1]*x[2] - 2.0*x[3] * x[4] - 2.0*x[0];}

出力結果

Solution 1 2 3 4 5 1 1 1 1 1

例題 2

この例題では、 初期推定値 x0 = 10、 x1 = 10、x2 = 10 を用いて、 Schittkowski (1987年 ) からの問題を解きます。

#include "imsl.h"

main(){ void fcn(int, float *, float *); void grad(int, float *, float *); int neq = 0; int ncon = 2; int nvar = 3; int lda = 2; float obj, x[3]; float a[] = {-1.0, -2.0, -2.0, 1.0, 2.0, 2.0}; float xlb[] = {0.0, 0.0, 0.0}; float xub[] = {20.0, 11.0, 42.0}; float xguess[] = {10.0, 10.0, 10.0}; float b[] = {0.0, 72.0};

imsl_f_min_con_gen_lin(fcn, nvar, ncon, neq, a, b, xlb, xub, IMSL_GRADIENT, grad, IMSL_XGUESS, xguess, IMSL_OBJ, &obj, IMSL_RETURN_USER, x, 0);

imsl_f_write_matrix("Solution", 1, nvar, x, 0); printf("Objective value = %f\n", obj);}

void fcn(int n, float *x, float *f){

( ) 0 1 2

0 1 2

0 1 2

0

1

2

minsubject to 2 2 0

2 2 720 200 110 42

f x x x x- x x x

x x xxxx

= −

− − ≤

+ + ≤

≤ ≤

≤ ≤≤ ≤

Page 440: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

*f = -x[0] * x[1] * x[2];}

void grad(int n, float *x, float *g){ g[0] = -x[1]*x[2]; g[1] = -x[0]*x[2]; g[2] = -x[0]*x[1];}

出力結果

Solution 1 2 3 20 11 15Objective value = -3300.000000

bounded_least_squares修正 Levenberg-Marquardt アルゴリズムを使用して変数の境界に従う非線形最

小二乗問題を解きます。

概要

#include <imsl.h>

float *imsl_f_bounded_least_squares (void fcn(), int m, int n, int ibtype, float xlb[], float xub[], ..., 0)

double 型関数は、 imsl_d_bounded_least_squaresです。

必要な引数

void fcn (int m, int n, float x[], float f[]) ( 入力 / 出力 )最小二乗問題を定義する関数を計算するユーザ提供の関数。この x は関数が計算される点の長さ n のベクトルで、f は点 x の関数値を含

んだ長さ mのベクトルです。

int m ( 入力 )関数の数。

int n ( 入力 )n ≤ mである変数の数。

int ibtype ( 入力 )変数の境界のタイプを示すスカラー。

float xlb[] ( 入力 , 出力 , or 入力 / 出力 )変数の下限を含んだ n 成分の配列。( ibtype = 0 であれば入力、

ibtype = 1 又は 2 であれば出力、ibtype = 3 であれば入力 / 出力 )

変数に下限が存在しなければ、対応する xlb 値は −10 6 にセットする

必要があります。

float xub[] ( 入力 , 出力 , or 入力 / 出力 )変数の上限を含んだ n 成分の配列。( ibtype = 0 であれば入力、

ibtype = 1 又は 2 であれば出力、ibtype = 3 であれば入力 / 出力 )

ibtype Action0 ユーザが全ての境界を提供します。1 全ての変数は、非負です。2 全ての変数は、非正です。3 ユーザは、最初の変数の境界だけを提供します。

他の全ての変数は、同じ境界を持ちます。

Page 441: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

変数に上限が存在しなければ、対応する xlb 値は 10 6 にセットする必

要があります。

戻り値

非線形最小二乗問題の解 x のポインター。この空間を開放するために free を使用します。解が得られない場合,NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_bounded_least_squares (void fcn(), int m, int n, int ibtype, float xlb[], float xub[],IMSL_XGUESS, float xguess[],IMSL_JACOBIAN, void jacobian(),IMSL_XSCALE, float xscale[],IMSL_FSCALE, float fscale[],IMSL_GRAD_TOL, float grad_tol,IMSL_STEP_TOL, float step_tol, IMSL_REL_FCN_TOL, float rfcn_tol,IMSL_ABS_FCN_TOL, float afcn_tol,IMSL_MAX_STEP, float max_step,IMSL_INIT_TRUST_REGION, float trust_region,IMSL_GOOD_DIGIT, int ndigit,IMSL_MAX_ITN, int max_itn,IMSL_MAX_FCN, int max_fcn,IMSL_MAX_JACOBIAN, int max_jacobian,IMSL_INTERN_SCALE,IMSL_RETURN_USER, float x[],IMSL_FVEC, float **fvec,IMSL_FVEC_USER, float fvec[],IMSL_FJAC, float **fjac,IMSL_FJAC_USER, float fjac[],IMSL_FJAC_COL_DIM, int fjac_col_dim,IMSL_FCN_W_DATA, void fcn(), void *data,IMSL_JACOBIAN_W_DATA, void jacobian(), void *data,0)

オプション引数

IMSL_XGUESS, float xguess[] ( 入力 )初期推定値を含む n 成分の配列。

デフォルト: xguess = 0

IMSL_JACOBIAN, void jacobian (int m, int n, float x[], float fjac[], int fjac_col_dim) ( 入力 )ヤコビアンを計算するユーザ提供の関数で、この x はヤコビアンが計算

される点の長さ nのベクトル、 fjac は点 x で計算された m × n ヤコ

ビアン、そして fjac_col_dim は fjac の列ディメンジョンです。各

微係数 fi/xj は、fjac[(t-1)*fjac_col_dim+j-1] に返されなけれ

ばならないことに注意してください。

IMSL_XSCALE, float xscale[] ( 入力 )変数の尺度化ベクトルを含んだ n 要素の配列。引数 xscale は勾配

と2点の距離を尺度化するために主として使用されます。この詳細はキーワード IMSL_GRAD_TOL と IMSL_STEP_TOL を参照してくださ

い。デフォルト: xscale[] = 1

IMSL_FSCALE, float fscale[] ( 入力 )関数の対角項尺度化行列を含んだ m 要素の配列。fscale の i 番目の

要素はこの問題の i 番目の要素関数の逆数の大きさを指定する正のス

カラーです。デフォルト: fscale[] = 1

Page 442: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_GRAD_TOL, float grad_tol ( 入力 )尺度化された勾配の許容値。尺度化された x での勾配の i 番目の要素

は次式で計算されます。

ここで、 g = ∇ F(x)、 s = xscale、

です。

デフォルト: grad_tol = は、倍精度。 ε はマシン精度です。

IMSL_STEP_TOL, float step_tol ( 入力 )尺度化されたステップ許容値。x と y の 2 点間の尺度化された i 番

目の要素は、次式で計算されます。

ここで、 s = xscaleです。

デフォルト: step_tol = ε2/3。ε はマシン精度です。

IMSL_REL_FCN_TOL, float rfcn_tol ( 入力 )相対関数許容値。

デフォルト: rfcn_tol = max(10-10, ε2/3)、 max(10-20, ε2/3) は、倍精度。 ε はマシン精度です。

IMSL_ABS_FCN_TOL, float afcn_tol ( 入力 )絶対関数許容値。

デフォルト: afcn_tol = max(10-20, ε2)、 max(10-40, ε2) は、倍精度。 ε はマシン精度です。

IMSL_MAX_STEP, float max_step ( 入力 )最大許容ステップサイズ。デフォルト: max_step = 1000 max(ε1, ε2)。

s = xscale と t = xguessの場合。

IMSL_INIT_TRUST_REGION, float trust_region ( 入力 )初期信頼領域半径のサイズ。このデフォルトは初期尺度化されたコーシー(Cauchy )ステップに基づいています。

IMSL_GOOD_DIGIT, int ndigit ( 入力 )この関数の良好な桁数。デフォルト: マシン依存

IMSL_MAX_ITN, int max_itn ( 入力 )最大反復回数。デフォルト: max_itn = 100

IMSL_MAX_FCN, int max_fcn ( 入力 )関数計算の最大回数。デフォルト: max_fcn = 400

( )( ) 2

2

| | max ,1/1 || ||2

i i ig x s

F x

( ) ( )22

12

mii

F x f x=

= ∑

3,ε ε

( )| |

max | |,1/i y

i i

x yx s−

( )21 2 21

, || ||ni ii

s t sε ε=

= =∑

Page 443: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_MAX_JACOBIAN, int max_jacobian ( 入力 )ヤコブ行列計算の最大回数。デフォルト: max_jacobian = 400

IMSL_INTERN_SCALE内部的変数尺度化オプション。このオプションで xscale の値は内

部的に設定されます。

IMSL_RETURN_USER, float x[] ( 出力 )計算された解を含む n 成分の配列。

IMSL_FVEC, float **fvec ( 出力 )近似解の残差を含む長さ m の実数配列のポインターのアドレス。戻されると必要な記憶域が imsl_f_bounded_least_squares によって割

り当てられます。通常、 float *fvec が宣言されて、&fvec が引数と

して使用されます。

IMSL_FVEC_USER, float fvec[] ( 出力 )近似解の残差を含むサイズ m のユーザ割り当ての配列。

IMSL_FJAC, float **fjac ( 出力 )近似解のヤコビアンを含むサイズ m × n の配列のポインターのアドレ

ス。戻されると必要な記憶域が imsl_f_bounded_least_squares によって割り当てられます。通常、 float *fjac が宣言されて、&fjac が引数として使用されます。

IMSL_FJAC_USER, float fjac[] ( 出力 )近似解のヤコビアンを含むサイズ m × n のユーザ割り当ての配列。

IMSL_FJAC_COL_DIM, int fjac_col_dim ( 入力 )fjac の列ディメンジョン。

デフォルト: fjac_col_dim = n

IMSL_FCN_W_DATA, void fcn (int m, int n, float x[], float f[], void *data), void *data, ( 入力 )最小二乗問題を定義する関数を評価するユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータを受け渡すポインターです。 詳細は、

「イントロダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_JACOBIAN_W_DATA, void jacobian (int m, int n, float x[], float fjac[], int fjac_col_dim, void *data), void *data, ( 入力 )ヤコビ行列を計算するユーザ提供の関数。ユーザにより提供されるデータへのポインターを受け取ります。data は、ユーザ提供関数に渡

されるデータへのポインターです。詳細は、本マニュアルの初めにある「イントロダクション」「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_bounded_least_squares は、修正 Levenberg-Marquardt 法と

active set 法を使って、変数の単純境界に従う非線形最小二乗問題を解きます。

この問題は次のように述べられます。

l ≤ x ≤ u に従います。

ここで m ≥ n、 F : Rn → Rm 、そして fi(x) は F(x) の i 番目の関数です。与えら

れた出発点からその境界に変数の指標を含んだ active set IA が構築されま

す。変数が active set になければ「自由変数」と呼ばれます。このルーチンはそれから次の公式に従ってこの自由変数の探索方向を計算します。

( ) ( ) ( )2

1

1 1min2 2

mT

ii

F x F x f x=

= ∑

Page 444: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

d = −(JTJ + µ I)-1 JTF

ここに μ は Levenberg-Marquardt パラメータで、F = F(x) そして J は自由変数

に関するヤコビアンです。IA の変数の探索方向はゼロにセットされます。

Dennis と Schnabel (1983年) によって述べられた信頼領域手法が新しい点を見つ

けるために使用されます。最終的に最適化条件がチェックされます。この条件は以下の通りです。

||g (xi)|| ≤ ε, li < xi < ui

g (xi) < 0, xi = ui

g (xi) >0, xi = li

ここで ε は勾配許容値です。このプロセスは最適基準が達成されるまで繰り返されます。

この active set は反復の間に 1 つの自由変数がその境界に当たるか、又は、

その最適条件が自由変数に適切であるが IA 全ての変数、active set では適切

ではないときだけに変更されます。後者の場合では、最適条件に違反する変数は IA から落とされます。Levenberg-Marquardt 法の詳細は Levenberg (1944 年 ) 又は Marquardt (1963 年 ) を参照してください。active set 法の詳細は Gill と Murray (1976 年 ) を参照してください。

有限差分法が単精度計算ではヤコビアンを推定するために使用されるので、このヤコビアンの不正確な推定がこのアルゴリズムが重要でない点で停止する原因になる場合があります。この場合は、高精度演算をお勧めします。そして又、正確なヤコビアンが容易に提供される場合、オプション IMSL_JACOBIAN の使用をお勧めします。

例題

例題 1

この例題では、 初期推定値 (−1.2, 1.0) を用いて、非線形最小二乗問題を解きま

す。

#include "imsl.h"#include <math.h>

#define M 2#define N 2#define LDFJAC 2

main(){ void rosbck(int, int, float *, float *); int ibtype = 0; float xlb[N] = {-2.0, -1.0}; float xub[N] = {0.5, 2.0}; float *x;

x = imsl_f_bounded_least_squares (rosbck, M, N, ibtype, xlb, xub, 0);

printf("x[0] = %f\n", x[0]);

( )1

2

0

0

1

1min2

2 0.51 2

ii

f x

xx

=

− ≤ ≤− ≤ ≤

20 1 0 1 0( ) 10( ) and ( ) (1 )f x x x f x x= − = −

Page 445: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

printf("x[1] = %f\n", x[1]);}

void rosbck (int m, int n, float *x, float *f){ f[0] = 10.0*(x[1] - x[0]*x[0]); f[1] = 1.0 - x[0];}

出力結果

x[0] = 0.500000x[1] = 0.250000

例題 2

次の非線形最小二乗問題を解きます。

ここで

です。

今回は、分析的ヤコビアンと初期推定値 (−1.2, 1.0) が与えられます。近似解で

の残差が返されます。

#include "imsl.h"#include <math.h>

#define M 2#define N 2#define LDFJAC 2

main(){ void rosbck(int, int, float *, float *); void jacobian(int, int, float *, float *, int); int ibtype = 0; float xlb[N] = {-2.0, -1.0}; float xub[N] = {0.5, 2.0}; float xguess[N] = {-1.2, 1.0}; float *fvec; float *x;

x = imsl_f_bounded_least_squares (rosbck, M, N, ibtype, xlb, xub, IMSL_JACOBIAN, jacobian, IMSL_XGUESS, xguess, IMSL_FVEC, &fvec, 0);

printf("x[0] = %f\n", x[0]); printf("x[1] = %f\n\n", x[1]); printf("fvec[0] = %f\n", fvec[0]); printf("fvec[1] = %f\n\n", fvec[1]);}

void rosbck (int m, int n, float *x, float *f){ f[0] = 10.0*(x[1] - x[0]*x[0]);

( )1

2

0

0

1

1min2

2 0.51 2

ii

f x

xx

=

− ≤ ≤− ≤ ≤

20 1 0 1 0( ) 10( ) and ( ) (1 )f x x x f x x= − = −

Page 446: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

f[1] = 1.0 - x[0];}

void jacobian (int m, int n, float *x, float *fjac, int fjac_col_dim){ fjac[0] = -20.0*x[0]; fjac[1] = 10.0; fjac[2] = -1.0; fjac[3] = 0.0;}

出力結果

x[0] = 0.500000x[1] = 0.250000

fvec[0] = 0.000000fvec[1] = 0.500000

constrained_nlp逐次等号制約二次計画法を使用して一般非線形計画問題を解きます。

概要

#include <imsl.h>

float *imsl_f_constrained_nlp (void fcn(), int m, int meq, int n, int ibtype, float xlb[], float xub[], …, 0)

double 型関数は、 imsl_d_constrained_nlpです。

必要な引数

void fcn(int n, float x[], int iact, float *result, int *ierr) ( 入力 )与えられた点の目的関数と制約式を計算するためのユーザ提供の関数。

int n ( 入力 )変数の数。

float x[] ( 入力 )目的関数、又は、制約式が計算される点。

int iact ( 入力 )関数の計算が要求されるか、又は、制約式の計算されるかを示す整数。 iact がゼロならば、目的関数の計算が要求

されます。 iact が非ゼロであれば iact の値は計算される制

約式の指標を示します。

float result[] ( 出力 )iact がゼロであれば、result は点 x で計算された目的関数

値です。 iact が非ゼロであれば、result は点 x の要求され

た制約式の値でになります。

int *ierr ( 出力 )整数のアドレス。 入力では ierr は 0 にセットされます。計

算の間にエラー、或いは、その他の望ましくない条件が発生したならば、ierr は 1 にセットされなければなりま

せん。ierr が 1 にセットされると、ステップサイズが縮

小されてそのステップが再び試行されます。 ( もしも ierr が xguess で 1 にセットされるとエラーが発生されます。)

int m ( 入力 )制約式の総数。

int meq ( 入力 )等号制約式の数。

Page 447: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int n ( 入力 )変数の数。

int ibtype ( 入力 )変数の境界のタイプを示すスカラー。

float xlb[] ( 入力 , 出力 , or 入力 / 出力 )変数の下限を含む n 要素の配列。 (ibtype = 0 の場合入力、ibtype = 1 又は 2 の場合出力、ibtype = 3 の場合 入力 / 出力 )

変数に下限が存在しなければ、対応する xlb 値は imsl_f_machine(8) にセッ

トしなければなりません。

float xub[] ( 入力 , 出力 , or 入力 / 出力 )変数の上限を含む n 要素の配列。(ibtype = 0 の場合入力、ibtype = 1 又は 2 の場合出力、ibtype = 3 の場合 入力 / 出力 )

変数に下限が存在しなければ、対応する xub 値は imsl_f_machine(7) にセッ

トしなければなりません。

戻り値

非線形計画法問題の解 x のポインター。この空間を開放するためには free を使

用します。解を計算する事ができなかったならば NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_constrained_nlp (void fcn(), int m, int meq, int n, i int nt ibtype, float xlb[], float xub[],IMSL_GRADIENT, void grad(),IMSL_PRINT, int iprint,IMSL_XGUESS, float xguess[],IMSL_ITMAX, int itmax,IMSL_TAU0, float tau0,IMSL_DEL0, float del0,IMSL_SMALLW, float smallw,IMSL_DELMIN, float delmin,IMSL_SCFMAX, float scfmax,IMSL_RETURN_USER, float x[],IMSL_OBJ, float *obj,IMSL_DIFFTYPE, int difftype,IMSL_XSCALE, float xscale[],IMSL_EPSDIF, float epsdif,IMSL_EPSFCN, float epsfcn,IMSL_TAUBND, float taubnd,IMSL_FCN_W_DATA, void fcn(), void *data,IMSL_GRADIENT_W_DATA, void grad(), void *data, 0)

ibtype Action0 ユーザが全ての変数を提供1 全ての変数は非負2 全ての変数は非正3 ユーザは最初の変数の境界だけを提供し、そ

の他全ての変数は同じ境界を持つ

Page 448: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数

IMSL_GRADIENT, void grad(int n, float x[], int iact, float result[]) ( 入力 )次の引数を持つ、与えられた点で勾配を計算するためのユーザ提供の関数

int n ( 入力 )変数の数。

float x[] ( 入力 )目的関数の勾配、或いは、制約式の勾配が計算される点。

int iact ( 入力 )目的関数勾配の計算が要求されるか、或いは、制約式勾配の計算が要求されるかを示す整数。iact がゼロであれ

ば目的関数勾配計算が要求されます。iact が非ゼロであ

れば、iact の値は計算される制約式勾配の指標を示す。

float result[] ( 出力 )iact がゼロであれば、result は点 x の目的関数の計算さ

れた勾配です。iact が非ゼロであれば、result は点 x の

要求された制約値の計算された勾配になります。

IMSL_PRINT, int iprint ( 入力 )必要な出力レベルを示すパラメータ。 ( 入力 )

デフォルト: iprint = 0.

IMSL_XGUESS, float xguess[] ( 入力 )解の初期値を含む長さ n の配列。 ( 入力 )

デフォルト: xguess = X、境界を満足する ( の最小値 )

IMSL_ITMAX, int itmax ( 入力 )最大許容反復回数。 ( 入力 )デフォルト: itmax = 200.

IMSL_TAU0, float tau0 ( 入力 )未測定のペナルティ項がどれだけゼロから外れているかを説明する普遍的な境界。 ( 入力 ) imsl_f_constrained_nlp は次式によって記述される領域内で

すべての関数は安全に計算されるものと想定しています。しかし初期条件はこれらの要件を侵害することがあります。この場合には、初期

Iprint Action0 出力はプリントされない。1 中間結果の1行が反復毎にプリントされ

る。2 各ステップの最も重要なデータを要約す

る中間結果の行がプリントされる。3 全ての主要変数と相対変数が示す詳細な

中間結果、作業用セットからの関連する値、後戻り処理の進行、その他の行がプリントされる。

4 全ての主要変数と相対変数が示す詳細な中間結果、作業用セットからの関連する値、後戻り処理の進行、作業用セットの勾配、更新された擬似ニュートン値、その他の行がプリントされる。

x 2

( ) ( )( )1 1

min 0,e

e

M M

i ii i M

g x g x= = +

− ≤∑ ∑ tau0

Page 449: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

の実現可能性改良段階ではこのような点が見つけられるまで、imsl_f_constrained_nlp により実行されます。小さい tau0 はその反

復が可能なセットの境界に密接に追従するので imsl_f_constrained_nlp の効率を減退します。それとは逆に大きい tau0 はこのコードの信頼性を低下します。

デフォルト tau0 = 1.0

IMSL_DEL0, float del0 ( 入力 )最小化の初期段階で次式が成立すれば制約式は束縛と考えられます。

良好な値は .01 と 1.0 の間にあります。 del0 の選択が小さすぎると、束

縛制約式の正しいセットの確定は遅れるかも知れません。逆に del0 が大き過ぎると、この方法は非常に時間がかかるアクティブな制約のための個々のスラック変数を使って完全に規則化された SQP 法に逃避し

ます。 釣り合いの取れた問題では del0 = 1.0 が適当です。 デフォルト: del0 = .5* tau0

IMSL_SMALLW, float smallw ( 入力 )乗算子に許されるエラーを含むスカラー。例えば、不等号制約式の負の乗算子はその絶対値が smallw よりも小さい場合、 ( ゼロとして ) 受け

入れられます。 デフォルト: smallw = exp(2*log(eps/3)) ここで eps は、マシン精度で

す。

IMSL_DELMIN, float delmin ( 入力 )最終的に受け取られた結果の許容される制約式違反を定義するスカ

ラー。制約式は等号制約式に対して |gi(x)| delmin 、そして等号制約

式に対して gi(x) (-delmin ) であれば満足されます。 デフォルト: delmin = min(.1*del0, max(epsdif, max(1.e-6*del0, smallw))

IMSL_SCFMAX, float scfmax ( 入力 )目的関数の内部的自動スケーリングの限界値を含んだスカラー。 デフォルト: scfmax = 1.0e4

IMSL_RETURN_USER, float x[] ( 出力 )解 x を含む、長さ n のユーザ割り当ての配列。

IMSL_OBJ, float *obj ( 出力 )計算された解での目的関数の値を含むスカラー。

IMSL_LAGRANGE_MULTIPLIERS, float **lagrange ( 出力 )終了時に Lagrange 乗数推定を含む配列を指すポインターのアドレス。

IMSL_LAGRANGE_MULTIPLIERS_USER, float lagrange_user[] ( 出力 )制約式の Lagrange 乗数推定を含む長さ ncon のユーザ提供配列。

IMSL_CONSTRAINT_RESIDUALS, float **const_res ( 出力 )終了時に制約式の残差を含む配列を指すポインターのアドレス。

IMSL_CONSTRAINT_RESIDUALS_USER, float const_res_user[] ( 出力 )制約式の残差を含む長さ ncon のユーザ提供の配列。

IMSL_FCN_W_DATA, void fcn(int n, float x[], int iact, float *result, int *ierr, void *data), void *data, ( 入力 )目的関数やある点での制約を評価するためのユーザ提供の関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータを受け渡すポインターです。 詳細は、

( )( )( )max

1, ,1,

ie

i

M Mg x

ig x

≤ = +∇

del0 K

Page 450: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

「イントロダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

IMSL_GRADIENT_W_DATA, void grad(int n, float x[], int iact, float result[], void *data), void *data, ( 入力 )任意の点での勾配を計算するユーザ提供関数。また、ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供

の関数にデータを受け渡すポインターです。 詳細は、「イントロダク

ション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

以下のオプション引数は、 IMSL_GRADIENT が指定されていない場合に限り有効

です。

IMSL_DIFFTYPE, int difftype ( 入力 )使用される数値微分の種類。デフォルト: difftype = 1

IMSL_XSCALE, float xscale[] ( 入力 )変数の内部尺度を設定する長さ n のベクトル。しかし、与えられる初

期値と目的関数と勾配計算は常に元の尺度化されない変数です。最初の内部変数は値 x[i] を xscale[i] で割ることによって得られます。

他の情報が無い場合、全ての入力値を 1.0 に設定します。

デフォルト: xscale[] = 1.0.

IMSL_EPSDIF, float epsdif ( 入力 )勾配の相対精度。デフォルト: epsdif = ε 、ここで ε はマシン精度。

IMSL_EPSFCN, float epsfcn ( 入力 )関数計算ルーチンの相対精度。デフォルト: epsfcn = ε、 ここで ε はマシン精度。

IMSL_TAUBND, float taubnd ( 入力 )境界が数値微分の間に違反される数量。境界は変数が境界上にあって有限差分が勾配計算のため取られる場合だけに(多くとも) taubnd によって侵犯されます。デフォルト: taubnd = 1.0

説明

関数 constrained_nlp は、 Peter Spellucci 氏 (1998 年 ) が開発したサブルーチ

ン DONLP2 のライセンス版とのインターフェースを提供します。それは active set 法を使用した逐次等号制約二次計画法と、臨時制約の場合(即ち、「作業用

セット」の線形依存勾配)に完全に規則化された混合制約化問題の選択的な使用法を使用します。これは ラグランジュ関数の ヘッセ行列 の Pantoja-Mayne 更新の少々修正したバージョン、変数二重尺度化、改良された Armjijo 型ス

テップサイズ アルゴリズムを使用します。変数の境界は勾配投影法のように

取り扱います。詳細は次の2つの論文に述べられます。 P. Spellucci: An SQP method for general nonlinear programs using only equality constrained subproblems. Math. Prog. 82, (1998), 413-448.

Difftype Action1 打ち切りステップサイズ 0.1(epsfcn)1/2 要素

的な相対を持つ前進差分商 を使用する。2 打ち切りステップサイズ 0.1(epsfcn)1/3 要素

的な相対を持つ対称差分商 を使用する。3 3 つの対称差分商の Richardson 補外を計算す

る 6 次近似を使用する。これは打ち切りス

テップサイズ 0.01(epsfcn)1/7 を使用する。

Page 451: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

P. Spellucci: A new technique for inconsistent problems in the SQP method. Math. Meth. of Oper. Res. 47, (1998), 355-500. (published by Physica Verlag, Heidelberg, Germany).

問題は、次の様に表されます。

デフォルト値はオプションの入力引数で提供されますが、問題によってはこれらの値を調節する必要があります。オプションの引数の使用によって、imsl_f_constrained_nlp は問題の特性を明らかにするために、このアルゴリ

ズムのパラメータを調節することが出来ます。 DONLP2 ユーザガイドは、これ

らのパラメータの詳細な説明と、アルゴリズムの性能を最大化するための戦略を用意しています。DONLP2 ユーザガイドはメイン IMSL 製品ディレクトリの

“help”サブディレクトリで利用されます。これに加えて次項目は imsl_f_constrained_nlp を使用する時に考慮される指針です。

• 良好な出発点は非常に問題特有で、出来るがぎり呼び出しプログラムに

よって提供されなければりません。オプション引数 IMSL_XGUESS を参

照して下さい。

• 勾配近似法は imsl_f_constrained_nlp の成功に影響があります。ある

問題のためには、より高次な近時方が必要な場合があります。 オプション

引数 IMSL_DIFFTYPE を参照して下さい。

• 両側制約式 が2つの制約式   と

に変換されると、 を選択するか、又は少

なくともこの値の推定値を提供することを試みます。これはこのアルゴリズムの効率を高めます。オプション引数 IMSL_DEL0 を参照して下さい。

• ユーザ提供の関数 fcn とのインターフェースに提供されるパラメータ ierr は、計算が可能ではない、又は合理的ではない点で要求される場合には非常に有用です。例えば、要求される点の計算が浮動小数点例外の結果になる場合、ierr を 1 に設定し、計算を行わないで返すことで、この例外が避

けられます。imsl_f_constrained_nlp はステップ幅を減らし、このステップ

を再び試みます。初期推定のために ierr を 1 に設定すると、エラーが発生

することに注意してください。

例題

次の問題を解きます。

include "imsl.h"#define M 2#define ME 1#define N 2void grad(int n, float x[], int iact, float result[]);

( )minnx

f x∈R

( )( )

subject to 0, for 1, ,

0, for 1, ,

j e

j e

l u

g x j m

g x j m m

x x x

= =

≥ = +

≤ ≤

K

K

( )i i il g x u≤ ≤ 2 ( ) 0ig x ≥ 2 1( ) 0ig x+ ≥

( )1del0 ( ) / {1, }2 i i iu l max g x< − ∇

( ) ( ) ( )( )( )

2 21 2

1 1 2

22 1 2

min 2 1

subject to 2 1 02 / 4 1 0

F x x x

g x x x

g x x x

= − + −

= − + =

= − − + ≥

Page 452: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

void fcn(int n, float x[], int iact, float *result, int *ierr);

void main(){ int ibtype = 0; float *x, ans[2]; static float xlb[N], xub[N];

xlb[0] = xlb[1] = imsl_f_machine(8); xub[0] = xub[1] = imsl_f_machine(7); x = imsl_f_constrained_nlp(fcn, M, ME, N, ibtype, xlb, xub, 0); imsl_f_write_matrix ("The solution is", 1, N, x, 0);} /* Himmelblau 問題 1 */void fcn(int n, float x[], int iact, float *result, int *ierr){ float tmp1, tmp2; tmp1 = x[0] - 2.0e0; tmp2 = x[1] - 1.0e0; switch (iact) { case 0: *result = tmp1 * tmp1 + tmp2 * tmp2; break; case 1: *result = x[0] - 2.0e0 * x[1] + 1.0e0; break; case 2: *result = -(x[0]*x[0]) / 4.0e0 - x[1]*x[1] + 1.0e0; break; default: ; break; } *ierr = 0; return;}

出力結果 The solution is 1 2 0.8229 0.9114

Page 453: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

第 9章:特殊関数

ルーチン

誤差関数とガンマ関数

誤差関数誤差関数の計算 . . . . . . . . . . . . . . . . . . . . . . .erf 457相補誤差関数の計算 . . . . . . . . . . . . . . . . . . . . erfc 458指数関数的誤差関数の計算 . . . . . . . . . . . . . . . . .erfce 459スケーリングされた関数の計算 . . . . . . . . . . . . . . . erfe 460逆誤差関数の計算 . . . . . . . . . . . . . . . . . . erf_inverse 461逆相補誤差関数の計算 . . . . . . . . . . . . . . . erfc_inverse 462ベータ関数の計算 . . . . . . . . . . . . . . . . . . . . . beta 464対数ベータ関数の計算 . . . . . . . . . . . . . . . . . log_beta 465不完全ベータ関数の計算 . . . . . . . . . . . . beta_incomplete 466

ガンマ関数ガンマ関数の計算 . . . . . . . . . . . . . . . . . . . gamma 466対数ガンマ関数 . . . . . . . . . . . . . . . . . . .log_gamma 468不完全ガンマ関数の計算 . . . . . . . . . . . gamma_incomplete 469

ベッセル関数ベッセル関数 J0の計算 . . . . . . . . . . . . . . . . bessel_J0 470ベッセル関数 J1の計算 . . . . . . . . . . . . . . . . bessel_J1 472ベッセル関数 Jnの計算 . . . . . . . . . . . . . . . . bessel_Jx 473ベッセル関数 Y0の計算 . . . . . . . . . . . . . . . . bessel_Y0 474ベッセル関数 Y1の計算 . . . . . . . . . . . . . . . . bessel_Y1 475ベッセル関数 Yvの計算 . . . . . . . . . . . . . . . . bessel_Yx 476ベッセル関数 I0の計算 . . . . . . . . . . . . . . . . bessel_I0 478ベッセル関数 e-|x|I0(x)の計算. . . . . . . . . . . . bessel_exp_I0 479ベッセル関数 I1の計算 . . . . . . . . . . . . . . . . bessel_I1 480ベッセル関数 e-|x|I1(x) の計算 . . . . . . . . . . . bessel_exp_I1 481ベッセル関数 Iv の計算 . . . . . . . . . . . . . . . . .bessel_Ix 482ベッセル関数 K0の計算 . . . . . . . . . . . . . . . . bessel_K0 483ベッセル関数 exK0(x)の計算 . . . . . . . . . . . . bessel_exp_K0 484ベッセル関数 K1の計算 . . . . . . . . . . . . . . . . bessel_K1 485ベッセル関数 exK1(x)の計算 . . . . . . . . . . . . bessel_exp_K1 486ベッセル関数 Kvの計算 . . . . . . . . . . . . . . . . bessel_Kx 487

楕円積分第1種完全楕円積分の計算 . . . . . . . . . . . elliptic_integral_K 488第2種完全楕円積分の計算 . . . . . . . . . . . elliptic_integral_E 489第1種カールソンの楕円積分の計算 . . . . . . elliptic_integral_RF 490第 2 種カールソンの楕円積分の計算 . . . . . . elliptic_integral_RD 491第 3 種カールソンの楕円積分の計算 . . . . . . elliptic_integral_RJ 492カールソンの楕円積分の特例 . . . . . . . . . elliptic_integral_RC 493

フレネル積分余弦フレネル積分の計算 . . . . . . . . . . . . fresnel_integral_C 494正弦フレネル積分の計算 . . . . . . . . . . . . fresnel_integral_S 494

Page 454: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

エアリー関数エアリー関数の計算 . . . . . . . . . . . . . . . . . . . airy_Ai 495第 2 種エアリー関数の計算 . . . . . . . . . . . . . . . . airy_Bi 496エアリー関数の導関数の計算 . . . . . . . . . . airy_Ai_derivative 497第 2 種エアリー関数の導関数の計算 . . . . . . . airy_Bi_derivative 498

ケルビン関数第1種0次ケルビン関数 ber の計算 . . . . . . . . . . kelvin_ber0 498第1種0次ケルビン関数 bei の計算 . . . . . . . . . . kelvin_bei0 499第2種0次ケルビン関数 ker の計算 . . . . . . . . . . kelvin_ker0 500第2種0次ケルビン関数 kei の計算 . . . . . . . . . . kelvin_kei0 501ケルビン関数 ber の導関数の計算 . . . . . . kelvin_ber0_derivative 501ケルビン関数 bei の導関数の計算 . . . . . . kelvin_bei0_derivative 502ケルビン関数 ker の導関数の計算 . . . . . . kelvin_ker0_derivative 503ケルビン関数 kei の導関数の計算 . . . . . . kelvin_kei0_derivative 504

統計関数正規 ( ガウス ) 分布関数の計算 . . . . . . . . . . . . normal_cdf 504逆正規分布関数の計算 . . . . . . . . . . . . normal_inverse_cdf 506カイ二乗分布関数の計算 . . . . . . . . . . . . .chi_squared_cdf 507逆カイ二乗分布関数の計算 . . . . . . . . chi_squared_inverse_cdf 508F 分布関数の計算 . . . . . . . . . . . . . . . . . . . . F_cdf 509逆 F 分布関数の計算 . . . . . . . . . . . . . . . .F_inverse_cdf 510スチューデント t 分布関数の計算 . . . . . . . . . . . . . . t_cdf 511逆スチューデント t 分布関数の計算 . . . . . . . . . t_inverse_cdf 513ガンマ分布関数の計算 . . . . . . . . . . . . . . . . gamma_cdf 514二項分布関数の計算 . . . . . . . . . . . . . . . . binomial_cdf 515超幾何分布関数の計算 . . . . . . . . . . . . hypergeometric_cdf 516ポアソン分布関数の計算 . . . . . . . . . . . . . . .poisson_cdf 517ベータ分布関数の計算 . . . . . . . . . . . . . . . . . beta_cdf 518逆ベータ分布関数の計算 . . . . . . . . . . . . beta_inverse_cdf 520二変量正規分布関数の計算 . . . . . . . . . .bivariate_normal_cdf 521

基本金融関数累積利息の計算 . . . . . . . . . . . . . . . cumulative_interest 522元本累計の計算 . . . . . . . . . . . . . . . cumulative_principal 523減価償却の計算(定率法). . . . . . . . . . . . . depreciation_db 524減価償却の計算(倍率法). . . . . . . . . . . . depreciation_ddb 526減価償却の計算(定額法). . . . . . . . . . . . .depreciation_sln 527減価償却の計算(算術級数法) . . . . . . . . . . . . . . . . . . . .depreciation_syd 528減価償却の計算(倍率逓減法). . . . . . . . . . depreciation_vdb 529分数価格から小数価格への変換 . . . . . . . . . . dollar_decimal 530小数価格から小数価格への変換 . . . . . . . . . . .dollar_fraction 531実効年利率の計算 . . . . . . . . . . . . . . . . . effective_rate 532将来価値の計算 . . . . . . . . . . . . . . . . . . future_value 533複利予定表に基づく初期元金の将来価値の計算 future_value_schedule 534利息の計算 . . . . . . . . . . . . . . . . . . interest_payment 535利率の計算 . . . . . . . . . . . . . . . . . interest_rate_annuity 536内部収益率の計算 . . . . . . . . . . . . . internal_rate_of_return 538キャッシュフロー表のための内部収益率の計算 internal_rate_schedule 539修正内部収益率の計算 . . . . . . . . . . . modified_internal_rate 540正味現在価値の計算 . . . . . . . . . . . . . . net_present_value 542名目年利率の計算 . . . . . . . . . . . . . . . . . nominal_rate 543支払期間数の計算 . . . . . . . . . . . . . . number_of_periods 543定期的支払額の計算 . . . . . . . . . . . . . . . . . . payment 545現在価値の計算 . . . . . . . . . . . . . . . . . .present_value 546キャッシュフロー表のための現在価値の計算 present_value_schedule 547元金支払額の計算 . . . . . . . . . . . . . . . principal_payment 548

Page 455: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

債券関数満期日に利息を払う債券の累積利息の計算 . . accr_interest_maturity 549定期的に利息を払う債券の累積利息の計算 . . accr_interest_periodic 551米国財務省短期債券の債券換算利回りの計算 . bond_equivalent_yield 552証券のコンベクシティの計算 . . . . . . . . . . . . . .convexity 553決済日を含む利払い期間の日数の計算 . . . . . . . . coupon_days 555決済日と満期日の間の支払うクーポン数の計算 . . .coupon_number 556決済日までの日数の計算 . . . . . . . . . days_before_settlement 557次の利払い日までの日数の計算 . . . . . . . days_to_next_coupon 558各会計期間の減価償却費の計算 . . . . . . depreciation_amordegrc 560減価償却費の計算 . . . . . . . . . . . . . depreciation_amorlinc 561割引債の価格の計算 . . . . . . . . . . . . . . . discount_price 562債券の割引率の計算 . . . . . . . . . . . . . . . . discount_rate 564割引債の年利回りの計算 . . . . . . . . . . . . . discount_yield 565マコーレー・デュレーションの計算 . . . . . . . . . . . duration 566債券の利率の計算 . . . . . . . . . . . . . interest_rate_security 568修正マコーレー・デュレーションの計算 . . . . . modified_duration 569決済日以降のクーポン期日の計算 . . . . . . . .next_coupon_date 571決済日直前のクーポン期日の計算 . . . . . .previous_coupon_date 572定期的に利息を払う額面 $100 あたりの債券価格の計算. . . . .price 573満期日に利息を払う額面 $100 あたりの債券価格の計算 price_maturity 574満期日の受取額の計算 . . . . . . . . . . . . . received_maturity 576米国財務省短期債券価格の計算 . . . . . . . . . treasury_bill_price 577米国財務省短期債券利回りの計算 . . . . . . . . treasury_bill_yield 5782つの日付間の総日数で表される1年の端数の計算 . . year_fraction 580満期日に利息を払う債券の年利回りの計算 . . . . . .yield_maturity 581定期的に利息を払う債券の年利回りの計算 . . . . . .yield_periodic 582

使用上の注意ユーザはすでに定義されているデータ型を使用して金融計算を実行することが出来ます。金融関数の大部分は次の 1 つ以上を必要とします。

• 日付

• 1 年あたりの支払い回数

• 支払い期日を示す変数

• 日数のカウント基準

IMSL C/Math/Library は毎年の支払い回数を示す入力、回数の識別名を提供し

ます。その識別名は IMSL_ANNUAL、IMSL_SEMIANNUAL と IMSL_QUARTERLY です。

IMSL C/Math/Library は支払い期日を示す入力、時期の識別名を提供しま

す。その識別名は IMSL_AT_END_OF_PERIOD、IMSL_AT_BEGINNING_OF_PERIODです。

識別名(frequency) 意味IMSL_ANNUAL 1 年に 1 回の支払い

( 年払い )IMSL_SEMIANNUAL 1 年に 2 回の支払い

( 半年払い )IMSL_QUARTERLY 1 年に 4 回の支払い

( 四半期払い )

Page 456: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL C/Math/Library は日数基準のタイプを示す入力、基準の識別名を提

供します。日数基準は2つの日付の間の日数を計算する方法です。その識別名は IMSL_DAY_CNT_BASIS_NASD、IMSL_DAY_CNT_BASIS_ACTUALACTUAL IMSL_DAY_CNT_BASIS_ACTUAL360、IMSL_DAY_CNT_BASIS_ACTUAL365 と IMSL_DAY_CNT_BASIS_30E360 になります。

IMSL C/Math/Library は日付を表現するために標準ヘッダー <time.h> に収納される Cプログラミング言語構造体 tm を使用します。tmの詳細な説

明は Kernighan と Richtie 1988 年、The C Programming Language, Second Edition、255 ページを参照して下さい。

構造体 tm は次のように <time.h> 内部で宣言されます。

struct tm {int tm_sec;int tm_min;int tm_hour;int tm_mday;int tm_mon;int tm_year;int tm_wday;int tm_yday;int tm_isdst;

};

例えば、Jan 1, 2001 を表現する変数を宣言するために、次のコード部分を

使用します。

struct tm date;

date.tm_year = 101;date.tm_mon = 0;date.tm_mday = 1;

注意: IMSL C/Math/Library は構造体 tm の中の tm_year、tm_mon、tm_mday 欄だけを使用します。

追加情報

金融と債券関数を追加するにあたり、 SIA Standard Securities Calculation Methods を基準にしています。

金融と債券の機能に関するより詳細な情報は以下のマニュアルをご参照下さい。

識別名 (when) 意味IMSL_AT_END_OF_PERIOD 期間の終わりが支払い期日IMSL_AT_BEGINNING_OF_PERIOD 期間の初めが支払い期日

識別名 (basis) 日数基準IMSL_DAY_CNT_BASIS_NASD US (NASD - 全米証券業協会 )

30/360IMSL_DAY_CNT_BASIS_ACTUALACTUAL Actual/ActualIMSL_DAY_CNT_BASIS_ACTUAL360 Actual/360IMSL_DAY_CNT_BASIS_ACTUAL365 Actual/365IMSL_DAY_CNT_BASIS_30E360 European 30/360

Page 457: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

• SIA Standard Securities Calculation Methods 1993, vols. 1 & 2, Third Edition.

• Accountants' Handbook, Volume 1, Sixth Edition.

• Microsoft Excel 5, Worksheet Function Reference.

erf実数誤差関数 erf(x) を計算します。

概要

#include <imsl.h>

float imsl_f_erf (float x)double 型関数は、 imsl_d_erfです。

必要な引数

float x ( 入力 )この誤差関数が計算される点。

戻り値

誤差関数 erf(x) の値。

説明

誤差関数 erf(x) は以下の式で定義されます。

x の全ての値で成立します。

Figure 9- 1 erf(x) のプロット

例題

x = 1/2 の誤差関数を計算します。

#include <imsl.h>

main(){ float x = 0.5; float ans;

ans = imsl_f_erf(x);

( ) 2

0

2erfx tx e dt

π−= ∫

Page 458: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

printf("erf(%f) = %f\n", x, ans);}

出力結果

erf(0.500000) = 0.520500

erfc実数相補誤差関数 erfc(x) を計算します。

概要

#include <imsl.h>

float imsl_f_erfc (float x) double 型関数は、 imsl_d_erfcです。

必要な引数

float x ( 入力 )この相補誤差関数が計算される点。

戻り値

相補誤差関数 erfc(x) の値。

説明

相補誤差関数 erfc(x) は以下の式で定義されます。

引数 x は、結果がアンダーフローになるので、あまり大きすぎてはいけませ

ん。 x は、おおむね次の値よりも小さくなります。

ここで、 s 表示可能で最初の浮動小数点数です。

Figure 9- 2 erfc(x) のプロット

( ) 22erfc t

xx e dt

π

∞ −= ∫

( ) 1/ 2ln sπ −

Page 459: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

x = 1/2 の相補誤差関数を計算します。

#include <imsl.h>

main(){ float x = 0.5; float ans;

ans = imsl_f_erfc(x); printf("erfc(%f) = %f\n", x, ans);}

出力結果

erfc(0.500000) = 0.479500

警告エラー

IMSL_LARGE_ARG_UNDERFLOW 引数 x が大きすぎるので、結果がアンダー

フローです。

erfce指数関数的にスケーリングされた相補誤差関数を計算します。

概要

#include <imsl.h>

float imsl_f_erfce (float x)double 型関数は、imsl_d_erfceです。

必要な引数

float x ( 入力 )関数の値を望ましくするための引数。

戻り値

指数関数的にスケーリングされた 相補誤差関数の値。

説明

関数 imsl_f_erfce は、以下を計算します。

ここで、erfc(x) は、相補誤差関数です。この関数の定義は、 imsl_f_erfc を参

照してください。

結果がアンダーフローになるのを防ぐためには、 x が次の値より大きくなくて

はなりません。

ここでは、 b = imsl_f_machine(2) は、表示可能な最大の浮動小数点数です。

例題

この例題では、imsl_f_erfce(1.0) が計算され、出力されます。

#include "imsl.h"

main()

( )2

erfc xe x

min ln( / 2)x b− −%

Page 460: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{

float value, x;

x = 1.0;

value = imsl_f_erfce(x);

printf("erfce(%6.3f) = %6.3f \n", x, value);

}

出力結果

erfce( 1.000) = 0.428

erfeerfc(z) に関連したスケーリングされた関数を計算します。

概要

#include <imsl.h>

f_complex imsl_c_erfe (f_complex z)double complex 型関数は、imsl_z_erfeです。

必要な引数

f_complex z ( 入力 )関数の値が望ましくなるための複素数の引数。

戻り値

erfc(z) に関連したスケーリングされた複素数の関数の値。

説明

関数 imsl_c_erfe は、次の様に定義されます。

b = imsl_f_machine(2) は、最大の浮動小数点数です。引数 z は、次を満足さ

せなければなりません。

もしくは、返される値はゼロです。引数 z が、以下を満たさない場合、

(ℑz)2 − (ℜz)2 ≤ log b

b が返されます。他の全ての値は、成立します (Gautschi 1969 年、 1970 年 )。

例題

この例題では、imsl_c_erfe(2.5 + 2.5i) が計算され、結果が表示されます。

#include "imsl.h"

main()

{

f_complex value, z;

2 2 22erfc( )z z t

ze iz ie e dt

π

∞− −− = − ∫

z b≤

Page 461: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

z = imsl_cf_convert(2.5, 2.5);

value = imsl_c_erfe(z);

printf("\n erfe(%2.3f + %2.3fi) = %2.3f + %2.3fi \n", z.re, z.im, value.re, value.im);

z.re, z.im, value.re, value.im);

}

出力結果

erfe(2.500 + 2.500i) = 0.117 + 0.108i

erf_inverse逆誤差関数 erf-1 (x) を計算します。

概要

#include <imsl.h>

float imsl_f_erf_inverse (float x)double 型関数は、imsl_d_erf_inverseです。

必要な引数

float x ( 入力 )逆誤差関数が計算される点。値は、 −1 から 1 の間でなければなりませ

ん。

戻り値

逆誤差関数 erf-1 (x) の値。

説明

x = erf (y) という逆誤差関数 erf-1 (x) があります。

逆誤差関数は、 −1 < x < 1. の間で定義されます。

Figure 9- 3 erf -1 (x) のプロット

例題

x = 1/2 の逆誤差関数を計算します。

#include <imsl.h>

( ) 2

0

2erfy ty e dt

π−= ∫

Page 462: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

main(){ float x = 0.5; float ans;

ans = imsl_f_erf_inverse(x); printf("inverse erf(%f) = %f\n", x, ans);}

出力結果

inverse erf(0.500000) = 0.476936

警告エラー

IMSL_LARGE_ABS_ARG_WARN |x| が、大きすぎるので答えの精度が半精度

以下です。

重大エラー

IMSL_REAL_OUT_OF_RANGE 逆誤差関数は、−1 < x < 1 で定義されなけれ

ばなりません。

erfc_inverse実数逆相補誤差関数 erfc-1 (x) を計算します。

概要

#include <imsl.h>

float imsl_f_erfc_inverse (float x)double 型関数は、imsl_d_erfc_inverseです。

必要な引数

float x ( 入力 )逆相補誤差関数が計算される点。引数 x は、 0 < x < 2 の範囲でなければ

なりません。

戻り値

逆相補誤差関数の値。

説明

y = erfc-1 (x) is such that x = erfc (y) という逆相補誤差関数 y = erfc-1 (x) がありま

す。

( ) 22erfc t

yy e dt

π

∞ −= ∫

Page 463: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Figure 9- 4 erfc-1 (x) のプロット

例題

x = 1/2 の逆相補誤差関数を計算します。

#include <imsl.h>

main(){ float x = 0.5; float ans;

ans = imsl_f_erfc_inverse(x); printf("inverse erfc(%f) = %f\n", x, ans);}

出力結果

inverse erfc(0.500000) = 0.476936

警告エラー

IMSL_LARGE_ARG_UNDERFLOW 結果がアンダーフローになるので、引数 x は、大きすぎてはいけません。 x は、次の値

より小さくなります。

ここで、ε はマシン精度です。

警告エラー

IMSL_LARGE_ARG_WARN |x| は、答えが半精度以下にならないように

より小さくすべきです。ここで、 ε はマシン精度です。

重大エラー

IMSL_ERF_ALGORITHM アルゴリズムが収束に失敗しました。

IMSL_SMALL_ARG_OVERFLOWの計算は、オーバーフローしてはい

けません。

IMSL_REAL_OUT_OF_RANGE 関数は、 0 < x < 2 の範囲で定義されます。

( )2 / 4ε π−

1/ ε

2

erfcxe x

Page 464: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

beta実数ベータ関数 β(x, y) を計算します。

概要

#include <imsl.h>

float imsl_f_beta (float x, float y)double 型関数は、 imsl_d_betaです。

必要な引数

float x ( 入力 )ベータ関数が計算される点。正でなければなりません。

float y ( 入力 )ベータ関数が計算される点。 正でなければなりません。

戻り値

ベータ関数 β (x, y) の値。結果が計算できない場合、NaN が返されます。

説明

ベータ関数 β (x, y) は、次の様に定義されます。

ベータ関数は、 x > 0 で y > 0 である必要があります。大きな引数にはアンダー

フローします。

Figure 9- 5 β(x,y) のプロット

例題

ベータ関数 β (0.5, 0.2) を計算します。

#include <imsl.h>

main(){ float x = 0.5; float y = 0.2; float ans;

( ) ( ) ( )( ) ( )

1 11

0, 1 yxx y

x y t t dtx y

β −−Γ Γ= = −

Γ + ∫

Page 465: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ans = imsl_f_beta(x, y); printf("beta(%f,%f) = %f\n", x, y, ans);}

出力結果

beta(0.500000,0.200000) = 6.268653

警告エラー

IMSL_BETA_UNDERFLOW 結果がアンダーフローするので、引数は、

あまり大きすぎてはいけません。

重大エラー

IMSL_ZERO_ARG_OVERFLOW 引数の一つが、ゼロに近いので、結果が

オーバーフローします。

log_beta実数ベータ関数 の対数 ln β(x, y) を計算します。

概要

#include <imsl.h>

float imsl_f_log_beta (float x, float y)double 型関数は、 imsl_d_log_betaです。

必要な引数

float x ( 入力 )ベータ関数の対数が計算される点。 正でなければなりません。

float y ( 入力 )ベータ関数の対数が計算される点。 正でなければなりません。

戻り値

ベータ関数 β(x, y) の対数の値。

説明

ベータ関数 β (x, y) は、次の様に定義されます。

imsl_f_log_beta は、ln β(x, y) を返します。

ベータ関数の対数は、 x > 0 で y > 0 である必要があります。非常に大きな引数

にはオーバフローします。

例題

ベータ関数 ln β(0.5, 0.2) の対数を計算します。

#include <imsl.h>

main(){ float x = 0.5; float y = 0.2; float ans;

ans = imsl_f_log_beta(x, y); printf("log beta(%f,%f) = %f\n", x, y, ans);}

( ) ( ) ( )( ) ( )

1 11

0, 1 yxx y

x y t t dtx y

β −−Γ Γ= = −

Γ + ∫

Page 466: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

log beta(0.500000,0.200000) = 1.835562

警告エラー

IMSL_X_IS_TOO_CLOSE_TO_NEG_1 式 −x/(x + y) が、 −1 に近すぎるので、結

果の精度は 1 精度以下です。

beta_incomplete不完全ベータ関数 Ix = βx(a,b)/β(a,b) を計算します。

概要

#include <imsl.h>

float imsl_f_beta_incomplete (float x, float a, float b)double 型関数は、imsl_d_beta_incompleteです。

必要な引数

float x ( 入力 )不完全ベータ関数が計算される点。

float a ( 入力 )不完全ベータ関数が計算される点。

float b ( 入力 )不完全ベータ関数が計算される点。

戻り値

不完全ベータ関数の値。

説明

不完全ベータ関数は、次の様に定義されます。

不完全ベータ関数は、 0 ≤ x ≤ 1、 a > 0、 b > 0 である必要があります。 十分小さい x と大きな a のためにアンダーフローします。 このアンダーフローは、誤差と

して報告されません。その代わりに、値ゼロが戻されます。

gamma実数ガンマ関数 Γ(x) を計算します。

概要

#include <imsl.h>

float imsl_f_gamma (float x)double 型関数は、imsl_d_gammaです。

必要な引数

float x ( 入力 )計算されるガンマ関数の点。

戻り値

ガンマ関数 Γ(x) の値。

説明

ガンマ関数 Γ(x) は、次の様に定義されます。

( ) ( )( ) ( ) ( ) 11

0

, 1, 1, ,

x bx ax

a bI a b t t dt

a b a bββ β

−−= = −∫

Page 467: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

x < 0 のために、上の定義は、解析接続によって拡張されます。

ガンマ関数は、ゼロ以下の整数に定義されません。 x がゼロ以下でアンダーフ

ローし、 x が大きいとオーバーフローします。 負の整数に近い値でオーバーフ

ローします。

Figure 9- 6 Γ(x) と 1/Γ(x) のプロット

例題

この例題では、Γ(1.5) が計算され、プリントされます。

#include <stdio.h>#include <imsl.h>

main(){ float x = 1.5; float ans; ans = imsl_f_gamma(x); printf("Gamma(%f) = %f\n", x, ans);}

出力結果

Gamma(1.500000) = 0.886227

警告エラー

IMSL_SMALL_ARG_UNDERFLOW 引数 x は、 Γ(x) がアンダーフローしないだけ

の十分な大きさがなくてはなりません。このアンダーフロー限界は、大きい負の半整数に近い引数に対して最初に生じます。これらの半整数から離れた他の引数が Γ(x) のマシンが表現できる値を生み出すとしても、これらの引数は異常だと考えらます。これらの値を必要とするユーザは logΓ(x) 関数

imsl_f_log_gamma を使用しなければなり

ません。ように、十分大きくなければなりません。

警告エラー

IMSL_NEAR_NEG_INT_WARN x が負の整数に近すぎるので、解が半精度

より低くなります。

( ) 1

0

x tx t e dt∞ − −Γ = ∫

Page 468: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

重大エラー

IMSL_ZERO_ARG_OVERFLOW ガンマ関数の引数がゼロに近すぎます。

IMSL_NEAR_NEG_INT_FATAL ガンマ関数の引数が負の整数に近すぎます。

IMSL_LARGE_ARG_OVERFLOW x が大きすぎるので、関数がオーバーフ

ローします。

IMSL_CANNOT_FIND_XMIN xmin を見つけるために使用したアルゴリズ

ムが失敗しました。このエラーが起きてはいけません。

IMSL_CANNOT_FIND_XMAX xmax を見つけるために使用したアルゴリズ

ムが失敗した。このエラーが起きてはいけません。

log_gammaガンマ関数の絶対値の対数 log |Γ(x)| を計算します。

概要

#include <imsl.h>

float imsl_f_log_gamma (float x)double 型関数は、 imsl_d_log_gammaです。

必要な引数

float x ( 入力 )ガンマ関数の絶対値の対数が計算される点。

戻り値

ガンマ関数の対数 log |Γ(x)| の値。

説明

ガンマ関数の絶対値の対数 log |Γ(x)| が計算されます。

Figure 9- 7 log |Γ(x)| のプロット

例題

この例題では、 log |Γ(3.5)| が計算され、プリントされます。

#include <stdio.h>#include <imsl.h>

Page 469: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

main(){ float x = 3.5; float ans;

ans = imsl_f_log_gamma(x); printf("log gamma(%f) = %f\n", x, ans);}

出力結果

log gamma(3.500000) = 1.200974

警告エラー

IMSL_NEAR_NEG_INT_WARN x が負の整数に近すぎるので、解が半精

度より低くなります。

重大エラー

IMSL_NEGATIVE_INTEGER この関数の引数は、負の整数ではいけま

せん。

IMSL_NEAR_NEG_INT_FATAL この関数の引数は、負の整数に近すぎま

す。

IMSL_LARGE_ABS_ARG_OVERFLOW 結果がオーバーフローするので、|x| が大きすぎてはいけません。

gamma_incomplete不完全ガンマ関数 γ(a, x) を計算します。

概要

#include <imsl.h>

float imsl_f_gamma_incomplete (float a, float x)double 型関数は、imsl_d_gamma_incompleteです。

必要な引数

float a ( 入力 )計算される不完全ガンマ関数の引数。正でなければなりません。

float x ( 入力 )計算される不完全ガンマ関数の点。非負でなければなりません。

戻り値

不完全ガンマ関数 γ(a, x) の値。

説明

不完全ガンマ関数は、 γ(a, x) 次の様に定義されます。

不完全ガンマ関数は、a > 0 の時に定義されます。 γ(a, x) は、 x > −∞ が明確です

が、このアルゴリズムは、xが負の値の時に γ(a, x) を計算しません。a が大き

く、 xが十分大きい場合、 γ(a, x) は、オーバーフローする可能性があります。 γ(a, x) は、 Γ (a)によって境界とされ , この境界が aの成立する値を決定する有用

な指針になるので便利な場合があります。

( ) 1

0, for 0

x a ta x t e dt xγ − −= >∫

Page 470: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Figure 9- 8 γ(a, x) のプロット

例題

a = 1 と x = 3 での不完全ガンマ関数を計算します。

#include <stdio.h>#include <imsl.h>

main(){ float x = 3.0; float a = 1.0; float ans;

ans = imsl_f_gamma_incomplete(a, x); printf("incomplete gamma(%f,%f) = %f\n", a, x, ans);}

出力結果

incomplete gamma(1.000000,3.000000) = 0.950213

重大エラー

IMSL_NO_CONV_200_TS_TERMS 関数は、テイラー級数の 200 項で収束しませ

んでした。

IMSL_NO_CONV_200_CF_TERMS 関数は、連分数の 200 項で収束しませんでし

た。

bessel_J0第 1 種 0 次実数ベッセル関数 J 0 (x) を計算します。

概要

#include <imsl.h>

float imsl_f_bessel_J0 (float x) double 型関数は、imsl_d_bessel_J0です。

必要な引数

float x ( 入力 )ベッセル関数が計算される点。

Page 471: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

以下の式で表されるベッセル関数の値。

解が計算できない場合、NaN が返されます。

説明

ベッセル関数 J 0 (x) は振動するので、その計算は |x| が増加すると不正確にな

ります。

Figure 9- 9 J0 (x) と J1 (x) のプロット

例題

ベッセル関数 J 0 (1.5) が計算されます。

#include <imsl.h>

main(){ float x = 1.5; float ans;

ans = imsl_f_bessel_J0(x); printf("J0(%f) = %f\n", x, ans);}

出力結果

J0(1.500000) = 0.511828

警告エラー

IMSL_LARGE_ABS_ARG_WARN 解が半精度よりも低くなる事を防ぐ為に、

|x| は より小さくなければなりません。ここで ε は、マシン精度です。

重大エラー

IMSL_LARGE_ABS_ARG_FATAL 解がある精度を保つ為には、 |x| は 1/ε より小

さくなければなりません。

( ) ( )0 0

1 cos sinJ x x dπ

θ θπ

= ∫

1/ ε

Page 472: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

bessel_J1第 1 種 1 次実数ベッセル関数 J1(x) を計算します。

概要

#include <imsl.h>

float imsl_f_bessel_J1 (float x)double 型関数は、 imsl_d_bessel_J1です。

必要な引数

float x ( 入力 )ベッセル関数が計算される点。

戻り値

以下の式で表されるベッセル関数の値。

解が計算できない場合、NaN が返されます。

説明

ベッセル関数 J1(x) は振動するので、その計算は |x| が増加すると不正確になり

ます。

例題

ベッセル関数 J1(1.5) が計算されます。

#include <imsl.h> main(){ float x = 1.5; float ans;

ans = imsl_f_bessel_J1(x); printf("J1(%f) = %f\n", x, ans);}

出力結果

J1(1.500000) = 0.557937

警報エラー

IMSL_SMALL_ABS_ARG_UNDERFLOW J1(x) がアンダーフローするのを防ぐた

めには、x がゼロであるか |x| > 2s でなけ

ればいけません。ここで、 s は、表現可

能な最小の正の数です。

警告エラー

IMSL_LARGE_ABS_ARG_WARN 解が半精度よりも低くなる事を防ぐ為

に、|x| は より小さくなければなり

ません。ここで ε は、マシン精度です。

重大エラー

IMSL_LARGE_ABS_ARG_FATAL 解がある精度を保つ為には、 |x| は 1/ε より小さくなければなりません。 ε はマシ

ン精度です。

( ) ( )1 0

1 cos sinJ x x dπ

θ θ θπ

= −∫

1/ ε

Page 473: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

bessel_Jx実数の次数と複素数の引数を持つ第 1 種ベッセル関数の数列を計算します。

概要

#include <imsl.h>

f_complex *imsl_c_bessel_Jx (float xnu, f_complex z, int n, …, 0)d_complex 型関数は、imsl_z_bessel_Jxです。

必要な引数

float xnu ( 入力 )望ましい最小の次数。引数 xnu は、-1/2 より大きくなければなりませ

ん。

f_complex z ( 入力 )ベッセル関数の数列が計算されるための引数。

int n ( 入力 )数列内の要素数。

戻り値

数列を通った関数の n 値へのポインター。要素 i は、ベッセル関数の次数 xnu + i for i = 0, …, n − 1 の値を含んでいます。

オプション引数の概要

f_complex *imsl_c_bessel_Jx (float xnu, f_complex z, int nIMSL_RETURN_USER, f_complex bessel[],0)

オプション引数

IMSL_RETURN_USER, f_complex bessel[] ( 出力 )ベッセル関数の数列をユーザ提供の配列 bessel[]に格納します。

説明

ベッセル関数 Jn(z) は、次の様に定義されます。

この関数は、Barnett (1981 年 ) および Thompson と Barnett (1987 年 ) のコード

BESSCC を基にしています。このコードは、 ρ = eiπ/2 を持つ次の関係を使って

修正ベッセル関数 Iv(z) から Jv(z) を計算します。

例題

この例題では、 J0.3+ν-1 (1.2 + 0.5i)、 ν = 1, …, 4 が計算され、プリントされます。

#include <imsl.h>

main(){ int n = 4; int i; float xnu = 0.3; static f_complex z = {1.2, 0.5}; f_complex *sequence;

( ) ( ) ( ) sinh

0 0

sin1 cos sin

for arg2

z t tJ z z d e dt

z

π νν

νπθ νθ θ

π ππ

∞ −= − −

<

∫ ∫

( )( )( )3 3

/ for / 2 arg

for arg / 2

I z zY z

I z zν

νν

ρ ρ π π

ρ ρ π π

− < ≤= − < ≤

Page 474: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

sequence = imsl_c_bessel_Jx(xnu, z, n, 0);

for (i = 0; i < n; i++) printf("I sub %4.2f ((%4.2f,%4.2f)) = (%5.3f,%5.3f)\n", xnu+i, z.re, z.im, sequence[i].re, sequence[i].im);}

出力結果

I sub 0.30 ((1.20,0.50)) = (0.774,-0.107)I sub 1.30 ((1.20,0.50)) = (0.400,0.159)I sub 2.30 ((1.20,0.50)) = (0.087,0.092)I sub 3.30 ((1.20,0.50)) = (0.008,0.024)

bessel_Y0第 2 種 0 次実数ベッセル関数 Y0(x) を計算します。

概要

#include <imsl.h>

float imsl_f_bessel_Y0 (float x)double 型関数は、imsl_d_bessel_Y0です。

必要な引数

float x ( 入力 )ベッセル関数が計算される点。

戻り値

以下の式で表されるベッセル関数の値。

解が計算できない場合、NaN が返されます。

説明

この関数は、ノイマン関数 N0(x) もしくは、 Weber の関数と呼ばれます。

Y0(x) は、 x が負の時は複素数で、 x = 0 では定義されないので、 imsl_f_bessel_Y0は、 x > 0 の時にのみ定義されます。 ベッセル関数 Y0(x) は振

動するので、その計算は x が増加すると不正確になります。

( ) ( ) sinh0 0 0

1 2sin sin z tY x x d e dtπ

θ θπ π

∞ −= −∫ ∫

Page 475: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Figure 9- 10 Y0(x) と Y1(x) のプロット

例題

ベッセル関数 Y0(1.5) が、計算されます。

#include <imsl.h>

main(){ float x = 1.5; float ans;

ans = imsl_f_bessel_Y0(x); printf("Y0(%f) = %f\n", x, ans);}

出力結果

Y0(1.500000) = 0.382449

警告エラー

IMSL_LARGE_ABS_ARG_WARN 解が半精度よりも低くなる事を防ぐ為に、

|x| は より小さくなければなりません。ここで ε は、マシン精度です。

重大エラー

IMSL_LARGE_ABS_ARG_FATAL 解がある精度を保つ為には、 |x| は 1/ε より小

さくなければなりません。 ε はマシン精度で

す。

bessel_Y1第 2 種 1次実数ベッセル関数 Y1(x) を計算します。

概要

#include <imsl.h>

float imsl_f_bessel_Y1 (float x)double 型関数は、imsl_d_bessel_Y1です。

1/ ε

Page 476: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

float x ( 入力 )ベッセル関数が計算される点。

戻り値

以下の式で表されるベッセル関数の値。

解が計算できない場合、NaN が返されます。

説明

この関数は、ノイマン(Neumann)関数 N1(x) もしくは、Weber の関数と呼ば

れます。

Y1(x) は、 x が負の時は複素数で、 x = 0 では定義されないので、 imsl_f_bessel_Y1 は、 x > 0の時にのみ定義されます。 ベッセル関数 Y1(x) は振

動するので、その計算は x が増加すると不正確になります。

例題

ベッセル関数 Y1(1.5) が計算されます。

#include <imsl.h>

main(){ float x = 1.5; float ans;

ans = imsl_f_bessel_Y1(x); printf("Y1(%f) = %f\n", x, ans);}

出力結果

Y1(1.500000) = -0.412309

警告エラー

IMSL_LARGE_ABS_ARG_WARN 解が半精度よりも低くなる事を防ぐ為に、

|x| は より小さくなければなりません。ここで ε は、マシン精度です。

重大エラー

IMSL_SMALL_ARG_OVERFLOW 引数 x は、Y1(x) がアンダーフローしないた

めに十分な大きさ(x > max (1/b, s)、s が表

せる最小の正の数、b が表せる最大の数)で

なければなりません。

IMSL_LARGE_ABS_ARG_FATAL 解がある精度を保つ為には、 |x| は 1/ε より小

さくなければなりません。 ε はマシン精度で

す。

bessel_Yx実数の次数と複素数の引数を持つベッセル関数の数列を計算します。

概要

#include <imsl.h>

f_complex *imsl_c_bessel_Yx (float xnu, f_complex z, int n, …, 0)

( ) ( ) { } sinh1 0 0

1 1sin sin t t z tY x x d e e e dtπ

θ θ θπ π

∞ − −= − − − −∫ ∫

1/ ε

Page 477: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

d_complex 型関数は、imsl_z_bessel_Yxです。

必要な引数

float xnu ( 入力 )望ましい最小の次数。引数 xnu は、−1/2 より大きくなければなりませ

ん。

f_complex z ( 入力 )ベッセル関数の数列が計算されるための引数。

int n ( 入力 )数列内の要素数。

戻り値

数列を通った関数の n 値へのポインター。要素 i は、ベッセル関数の次数 xnu + i for i = 0, …, n − 1 の値を含んでいます。

オプション引数の概要

f_complex *imsl_c_bessel_Yx (float xnu, f_complex z, int n,IMSL_RETURN_USER, f_complex bessel[],0)

オプション引数

IMSL_RETURN_USER, f_complex bessel[] ( 出力 )ベッセル関数の数列をユーザ提供の配列 bessel[]に格納します。

説明

ベッセル関数 Yv(z) は、次の様に定義されます。

この関数は、Barnett (1981 年 ) および Thompson と Barnett (1987 年 ) のコード

BESSCC を基にしています。このコードは、 次の関係を使って修正ベッセル関

数 Iv(z) と Kv(z) から Yv(z) を計算します。

例題

この例題では、 Y0.3+v-1 (1.2 + 0.5i)、 ν = 1, …, 4 が計算され、プリントされます。

#include <imsl.h>

main(){ int n = 4; int i; float xnu = 0.3; static f_complex z = {1.2, 0.5}; f_complex *sequence;

sequence = imsl_c_bessel_Yx(xnu, z, n, 0);

for (i = 0; i < n; i++) printf("Y sub %4.2f ((%4.2f,%4.2f)) = (%5.3f,%5.3f)\n", xnu+i, z.re, z.im, sequence[i].re, sequence[i].im);}

( ) ( ) ( ) sinh t

0 0

1 1sin sin cos

for arg2

t t zY z z d e e e dt

z

π ν νν θ νθ θ νπ

π ππ

∞ − − = − − +

<

∫ ∫

( ) ( ) ( ) ( )1 / 2/ 2 / 22 for arg2

ii iY z e e I z e K z zν ππ νπν ν ν

πππ

+ −= − − < ≤

Page 478: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

Y sub 0.30 ((1.20,0.50)) = (-0.013,0.380)Y sub 1.30 ((1.20,0.50)) = (-0.716,0.338)Y sub 2.30 ((1.20,0.50)) = (-1.048,0.795)Y sub 3.30 ((1.20,0.50)) = (-1.625,3.684)

bessel_I0第 1 種 0次実数修正ベッセル関数 I0(x) を計算します。

概要

#include <imsl.h>

float imsl_f_bessel_I0 (float x)double 型関数は、imsl_d_bessel_I0です。

必要な引数

float x ( 入力 )修正ベッセル関数が計算される点。

戻り値

以下の式で表されるベッセル関数の値。

解が計算できない場合、NaN が返されます。

説明

|x| が大きい場合、 imsl_f_bessel_I0 はオーバーフローします。

Figure 9- 11 I0(x) と I1(x) のプロット

例題

ベッセル関数 I0(1.5) が計算されます。

#include <imsl.h>

main(){ float x = 1.5; float ans;

( ) ( )0 0

1 cosh cosI x x dπ

θ θπ

= ∫

Page 479: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ans = imsl_f_bessel_I0(x); printf("I0(%f) = %f\n", x, ans);}

出力結果

I0(1.500000) = 1.646723

重大エラー

IMSL_LARGE_ABS_ARG_FATAL x の絶対値が大きすぎるので、 e|x| がオー

バーフローします。

bessel_exp_I0第 1 種 0 次の指数関数的にスケーリングされた修正ベッセル関数を計算しま

す。

概要

#include <imsl.h>float imsl_f_bessel_exp_I0 (float x)

double 型関数は、imsl_d_bessel_exp_I0です。

必要な引数

float x ( 入力 )ベッセル関数が計算される点。

戻り値

スケーリングされたベッセル関数 e-|x| I0(x) の値。 解が計算できない場合、NaN が返されます。

説明

ベッセル関数 I0(x) は、次の様に定義されます。

例題

式 e-4.5I0 (4.5) は、直接 imsl_f_bessel_exp_I0 を呼び、imsl_f_bessel_I0を

非直接的に呼び出すことにより計算されます。絶対差がプリントされます。大きな xの場合、 imsl_f_bessel_I0で起こるかもしれないオーバーフローを防

ぎます。

#include <imsl.h>#include <math.h>

main(){ float x = 4.5; float ans; float error;

ans = imsl_f_bessel_exp_I0 (x); printf("(e**(-4.5))I0(4.5) = %f\n\n", ans);

error = fabs(ans - (exp(-x)*imsl_f_bessel_I0(x))); printf ("Error = %e\n", error);}

( ) ( )0 0

1 cosh cosI x x dπ

θ θπ

= ∫

Page 480: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

(e**(-4.5))I0(4.5) = 0.194198

Error = 4.898845e-09

bessel_I1第 1 種 1次実数修正ベッセル関数を計算します。

概要

#include <imsl.h>

float imsl_f_bessel_I1 (float x)double 型関数は、imsl_d_bessel_I1です。

必要な引数

float x ( 入力 )ベッセル関数が計算される点。

戻り値

以下の式で表されるベッセル関数の値。

解が計算できない場合、NaN が返されます。

説明

For large |x| が大きい場合、imsl_f_bessel_I1 は、オーバーフローします。ゼ

ロ付近ではアンダーフローします。

例題

ベッセル関数 I1(1.5) が、計算されます。

#include <imsl.h>

main(){ float x = 1.5; float ans;

ans = imsl_f_bessel_I1(x); printf("I1(%f) = %f\n", x, ans);}

出力結果

I1(1.500000) = 0.981666

警報エラー

IMSL_SMALL_ABS_ARG_UNDERFLOW I1(x) ≈ x/2 がアンダーフローするので、

引数はそれ程ゼロに近づけるべきではありません。

重大エラー

IMSL_LARGE_ABS_ARG_FATAL e|x| がオーバーフローするので、 x の絶

対値は、あまり大きすぎてはいけません。

( ) cos1 0

1 cosxI x e dπ θ θ θ

π= ∫

Page 481: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

bessel_exp_I1第 1 種 1 次の指数関数的にスケーリングされた修正ベッセル関数を計算しま

す。

概要

#include <imsl.h>float imsl_f_bessel_exp_I1 (float x)

double 型関数は、imsl_d_bessel_exp_I1です。

必要な引数

float x ( 入力 )ベッセル関数が計算される点。

戻り値

スケーリングされた Bessel 関数 e-|x| I1(x) の値。 解が計算できない場合、NaN が返されます。

説明

|x| / 2 がアンダーフローすると、関数 imsl_f_bessel_I1は、アンダーフローし

ます。ベッセル関数 I1(x) は、次の様に定義されます。

例題

式 e-4.5I0 (4.5) は、直接 imsl_f_bessel_exp_I1 を呼び、imsl_f_bessel_I1を

非直接的に呼び出すことにより計算されます。絶対差がプリントされます。大きな xの場合、 imsl_f_bessel_exp_I1よって提供される内部的なスケーリングは、

imsl_f_bessel_I1で起こるかもしれないオーバーフローを防ぎます。

#include <imsl.h>#include <math.h>

main(){ float x = 4.5; float ans; float error;

ans = imsl_f_bessel_exp_I1 (x); printf("(e**(-4.5))I1(4.5) = %f\n\n", ans);

error = fabs(ans - (exp(-x)*imsl_f_bessel_I1(x))); printf ("Error = %e\n", error);}

出力結果

(e**(-4.5))I1(4.5) = 0.170959

Error = 1.469216e-09

( ) cos1 0

1 cosxI x e dπ θ θ θ

π= ∫

Page 482: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

bessel_Ix実数の次数と複素数の引数を持つ第 1 種修正ベッセル関数の数列を計算します。

概要

#include <imsl.h>

f_complex *imsl_c_bessel_Ix (float xnu, f_complex z, int n, …, 0)d_complex 型関数は、 imsl_z_bessel_Ixです。

必要な引数

float xnu ( 入力 )望ましい最小の次数。引数 xnu は、−1/2 より大きくなければなりませ

ん。

f_complex z ( 入力 )ベッセル関数の数列が計算されるための引数。

int n ( 入力 )数列内の要素数。

戻り値

数列を通った関数の n 値へのポインター。要素 i は、ベッセル関数の次数 xnu + i for i = 0, …, n − 1 の値を含んでいます。

オプション引数の概要

f_complex *imsl_c_bessel_Ix (float xnu, f_complex z, int n,IMSL_RETURN_USER, f_complex bessel[],0)

オプション引数

IMSL_RETURN_USER, f_complex bessel[] ( 出力 )ベッセル関数の数列をユーザ提供の配列 bessel[ ] に格納します。

説明

ベッセル関数 Iv(z) は、次の様に定義されます。

zが大きな引数の場合、 Temme (1975 年 ) のアルゴリズムを使って Iv(z) を見つ

けます。 (安定している場合)、 Iv(z) の値は、上向きに再発します。これは連分

数の計算が含まれます。 この計算が収束しないと、答えは正確でない場合があ

ります。

引数がそれ程大きくないか、小さい場合は、 Miller の手法が使用されます。

例題

この例題では、 J0.3+v-1 (1.2 + 0.5i)、 ν = 1, …, 4 が計算され、プリントされます。

#include <imsl.h>

main(){ int n = 4; int i; float xnu = 0.3; static f_complex z = {1.2, 0.5}; f_complex *sequence;

sequence = imsl_c_bessel_Ix(xnu, z, n, 0);

( ) ( )/ 2 / 2 for < arg2

i iI z e J ze zνπ πν ν

ππ−= − ≤

Page 483: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

for (i = 0; i < n; i++) printf("I sub %4.2f ((%4.2f,%4.2f)) = (%5.3f,%5.3f)\n", xnu+i, z.re, z.im, sequence[i].re, sequence[i].im);}

出力結果

I sub 0.30 ((1.20,0.50)) = (1.163,0.396)I sub 1.30 ((1.20,0.50)) = (0.447,0.332)I sub 2.30 ((1.20,0.50)) = (0.082,0.127)I sub 3.30 ((1.20,0.50)) = (0.006,0.029)

bessel_K0第 2 種 0 次実数修正ベッセル関数 K0(x) を計算します。

概要

#include <imsl.h>

float imsl_f_bessel_K0 (float x)double 型関数は、imsl_d_bessel_K0です。

必要な引数

float x ( 入力 )修正ベッセル関数が計算される点。 正でなければなりません。

戻り値

以下の式で表される修正ベッセル関数の値。

解が計算できない場合、NaN が返されます。

説明

K0(x) は、 x が負の時は複素数で、 x = 0 では定義されないので、 imsl_f_bessel_K0 は、 x > 0 の時にのみ定義されます。 x が大きい場合、

imsl_f_bessel_K0 はアンダーフローします。

Figure 9- 12 K0(x) と K1(x) のプロット

( ) ( )0 0cos sinhK x x t dt

∞= ∫

Page 484: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

ベッセル関数 K0(1.5) が計算されます。

#include <imsl.h>

main(){ float x = 1.5; float ans;

ans = imsl_f_bessel_K0(x); printf("K0(%f) = %f\n", x, ans);}

出力結果

K0(1.500000) = 0.213806

警報エラー

IMSL_LARGE_ARG_UNDERFLOW 結果がアンダーフローになるので、引数 x は、大きすぎてはいけません。 (結果はお

おむね、次の値と等しくなります)

bessel_exp_K0第 2 種 0 次の指数関数的にスケーリングされた修正ベッセル関数を計算しま

す。

概要

#include <imsl.h>float imsl_f_bessel_exp_K0 (float x)

double 型関数は、imsl_d_bessel_exp_K0です。

必要な引数

float x ( 入力 )ベッセル関数が計算される点。

戻り値

スケーリングされたベッセル関数 exK0(x) の値。 解が計算できない場合、NaN が返されます。

説明

結果が定義されるために引数はゼロ以上でなければなりません。ベッセル関数 K0(x) は、次の様に定義されます。

例題

上の式は、直接 imsl_f_bessel_exp_K0 を呼び、非直接的に

imsl_f_bessel_K0を呼ぶことによって計算されます。 絶対差がプリントされ

ます。 xが大きい場合、imsl_f_bessel_exp_K0 により提供される内部スケーリ

ングが imsl_f_bessel_K0で起こり得るアンダーフローを防ぎます。

#include <imsl.h>#include <math.h>

( )/ 2 xx eπ −

( ) ( )0 0cos sinhK x x t dt

∞= ∫

0 (0.5)eK

Page 485: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

main(){ float x = 0.5; float ans; float error;

ans = imsl_f_bessel_exp_K0 (x); printf("(e**0.5)K0(0.5) = %f\n\n", ans);

error = fabs(ans - (exp(x)*imsl_f_bessel_K0(x))); printf ("Error = %e\n", error);}

出力結果

(e**0.5)K0(0.5) = 1.524109

Error = 2.028498e-08

bessel_K1第 2 種 1次実数修正ベッセル関数 K1(x) を計算します。

概要

#include <imsl.h>

float imsl_f_bessel_K1 (float x)double 型関数は、imsl_d_bessel_K1です。

必要な引数

float x ( 入力 )ベッセル関数が計算される点。 正でなければなりません。

戻り値

以下の式で表されるベッセル関数の値。

解が計算できない場合、NaN が返されます。

説明

K1(x) は、 x が負の時は複素数で、 x = 0 では定義されないので、 imsl_f_bessel_K1 は、 x > 0 の時にのみ定義されます。 x が大きい場合、

imsl_f_bessel_K1 はアンダーフローします。

K1(x) のグラフは Figure 9-12 を参照してください。

例題

ベッセル関数 K1(1.5) が計算されます。

#include <imsl.h>

main(){ float x = 1.5; float ans;

ans = imsl_f_bessel_K1(x); printf("K1(%f) = %f\n", x, ans);}

( ) ( )1 0sin sinh sinhK x x t t dt

∞= ∫

Page 486: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

K1(1.500000) = 0.277388

警報エラー

IMSL_LARGE_ARG_UNDERFLOW 結果がアンダーフローになるので、引数 x は、大きすぎてはいけません。 (結果はお

おむね、次の値と等しくなります)

重大エラー

IMSL_SMALL_ARG_OVERFLOW 引数 x は、K1(x) がアンダーフローしないた

めに十分な大きさ(x > max (1/b, s)、s が表

せる最小の正の数、b が表せる最大の数)で

なければなりません。

bessel_exp_K1第 2 種 1 次の指数関数的にスケーリングされた修正ベッセル関数を計算しま

す。

概要

#include <imsl.h>float imsl_f_bessel_exp_K1 (float x)

double 型関数は、imsl_d_bessel_exp_K1です。

必要な引数

float x ( 入力 )ベッセル関数が計算される点。

戻り値

スケーリングされたベッセル関数 exK1(x) の値。 解が計算できない場合、NaN が返されます。

説明

x がゼロに近すぎると、次の結果はオーバーフローします。

ベッセル関数の定義は以下のようになります。

例題

上の式は、直接 imsl_f_bessel_exp_K1 を呼び、非直接的に

imsl_f_bessel_K1を呼ぶことによって計算されます。 絶対差がプリントされ

ます。 xが大きい場合、imsl_f_bessel_exp_K1 により提供される内部スケーリ

ングが imsl_f_bessel_K1で起こり得るアンダーフローを防ぎます。

#include <imsl.h>

( )/ 2 xx eπ −

( )1imsl_f_bessel_exp_K11xe K xx

= ≈

( ) ( )1 0sin sinh sinhK x x t t dt

∞= ∫

( )1 0.5eK

Page 487: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#include <math.h>

main(){ float x = 0.5; float ans; float error;

ans = imsl_f_bessel_exp_K1 (x); printf("(e**0.5)K1(0.5) = %f\n\n", ans);

error = fabs(ans - (exp(x)*imsl_f_bessel_K1(x))); printf ("Error = %e\n", error);}

出力結果

(e**0.5)K1(0.5) = 2.731010

Error = 5.890406e-08

bessel_Kx実数の次数と複素数の引数を持つ第 3 種修正ベッセル関数の数列を計算しま

す。

概要

#include <imsl.h>

f_complex *imsl_c_bessel_Kx (float xnu, f_complex z, int n, …, 0)d_complex 関数は、imsl_z_bessel_Jxです。

必要な引数

float xnu ( 入力 )望ましい最小の次数。引数 xnu は、−1/2 より大きくなければなりませ

ん。

f_complex z ( 入力 )ベッセル関数の数列が計算されるための引数。

int n ( 入力 )数列内の要素数。

戻り値

数列を通った関数の n 値へのポインター。要素 i は、ベッセル関数の次数 xnu + i for i = 0, …, n − 1 の値を含んでいます。

オプション引数の概要

f_complex *imsl_c_bessel_Kx (float xnu, f_complex z, int IMSL_RETURN_USER, f_complex bessel[],0)

オプション引数

IMSL_RETURN_USER, f_complex bessel[] ( 出力 )ベッセル関数の数列をユーザ提供の配列 bessel[ ] に格納します。

説明

Kv(z) は、次の様に定義されます。

( ) ( ) ( )/ 2 / 2 / 2 for arg2 2

i i iK z e iJ ze Y ze zνπ π πν ν ν

π ππ = − − < ≤

Page 488: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

この関数は、 Barnett (1981 年 ) および Thompson と Barnett (1987 年 ) のコード

BESSCC を基になっています。

zが大きな引数の場合、 Temme (1975 年 ) のアルゴリズムを使って kv(z) を見

つけます。 これは連分数の計算が含まれます。 この計算が収束しないと、答え

は正確でない場合があります。 z が小さい場合には、kv(z) の計算にノイマン数

列が使用されます。kv(z) の上向きの再発は、常に安定しています。

例題

この例題では、 K0.3+v-1 (1.2 + 0.5i)、 ν = 1, …, 4 が計算され、プリントされます。

#include <imsl.h>

main(){ int n = 4; int i; float xnu = 0.3; static f_complex z = {1.2, 0.5}; f_complex *sequence;

sequence = imsl_c_bessel_Kx(xnu, z, n, 0);

for (i = 0; i < n; i++) printf("K sub %4.2f ((%4.2f,%4.2f)) = (%5.3f,%5.3f)\n", xnu+i, z.re, z.im, sequence[i].re, sequence[i].im);}

出力結果

K sub 0.30 ((1.20,0.50)) = (0.246,-0.200)K sub 1.30 ((1.20,0.50)) = (0.336,-0.362)K sub 2.30 ((1.20,0.50)) = (0.587,-1.126)K sub 3.30 ((1.20,0.50)) = (0.719,-4.839)

elliptic_integral_K第 1 種の完全楕円積分 K(x) を計算します。

概要

#include <imsl.h>float imsl_f_elliptic_integral_K (float x)

double 型関数は、imsl_d_elliptic_integral_Kです。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

完全楕円積分 K(x)。

説明

第 1 種の完全楕円積分は次式で定義されます。

引数 x は、 0 ≤ x < 1 を満たさなければなりません。そうでなければ、 imsl_f_elliptic_integral_K は、最大の浮動小数点数 imsl_f_machine(2)を返します。

( )/ 2

1/ 20 2 for 0 1

1 sin

dK x xx

π θ

θ= ≤ <

− ∫

Page 489: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

関数 K(x) は、ルーチン imsl_f_elliptic_integral_RF と関係 K(x) = RF(0, 1 − x, 1) を使

用して計算されます。

例題

積分 K(0) が計算されます。

#include <imsl.h>

main(){ float x = 0.0; float ans;

x = imsl_f_elliptic_integral_K (x);

printf ("K(0.0) = %f\n", x);}

出力結果

K(0.0) = 1.570796

elliptic_integral_E第 2 種の完全楕円積分 E(x) を計算します。

概要

#include <imsl.h>float imsl_f_elliptic_integral_E (float x)

double 型関数は、imsl_d_elliptic_integral_Eです。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

完全楕円積分 E(x)。

説明

第 2 種の完全楕円積分は次式で定義されます。

引数 x は 0 ≤ x < 1 を満たさなければなりません。 そうでなければ、

imsl_f_elliptic_integral_E は最大の浮動小数点数 imsl_f_machine(2) を返します。

関数 E(x) はルーチン imsl_f_elliptic_integral_RF とimsl_f_elliptic_integral_RDを使って計算されます。関係 K(x) = R F (0, 1 − x, 1) を使用して計算されます。計算は、以下の関係を使って行われます。

例題

積分 E(0.33) が計算されます。

#include <imsl.h>

main()

( )/ 2 1/ 22

01 sin for 0 1E x x d x

πθ θ = − ≤ < ∫

( ) ( ) ( )0,1 ,1 0,1 ,13F DxE x R x R x= − − −

Page 490: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{ float x = 0.33; float ans;

x = imsl_f_elliptic_integral_E (x);

printf ("E(0.33) = %f\n", x);}

出力結果

E(0.33) = 1.431832

elliptic_integral_RF第 1 種の Carlson の楕円積分 RF(x, y, z) を計算します。

概要

#include <imsl.h>

float imsl_f_elliptic_integral_RF (float x, float y, float z)

double 型関数は、imsl_d_elliptic_integral_RFです。

必要な引数

float x ( 入力 )不完全楕円積分の最初の変数。 非負でなければなりません。

float y ( 入力 )不完全楕円積分の 2 番目の変数。 非負でなければなりません。

float z ( 入力 )不完全楕円積分の 3 番目の変数。 非負でなければなりません。

戻り値

完全楕円積分 RF(x, y, z)。

説明

第 1 種の Carlson の楕円積分は、次の様に定義されます。

引数は、非負で b/5 と等しいか、小さくなければなりません。更に、x + y、 x + z、 y + z は、5s と等しいか、大きくなければなりません。これらの条件が満た

されないと、imsl_f_elliptic_integral_RF は、 b に設定されます。ここで、

b = imsl_f_machine(2) は最大で、 s = imsl_f_machine(1) が最小の数になりま

す。

関数は、imsl_f_elliptic_integral_RFは、Carlson と Notis (1981 年 ) と Carlson の研究 (1979 年 ) によるコードを基にしています。

例題

積分 RF(0, 1, 2) が計算されます。

#include <imsl.h>

main(){ float x = 0.0; float y = 1.0; float z = 2.0;

( )( )( )( ) 1/ 2

0

1, ,2F

dtR x y zt x t y t z

=+ + +

Page 491: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float ans;

x = imsl_f_elliptic_integral_RF (x, y, z);

printf ("RF(0, 1, 2) = %f\n", x);}

出力結果

RF(0, 1, 2) = 1.311029

elliptic_integral_RD第 2 種の Carlson の楕円積分 RD(x, y, z) を計算します。

概要

#include <imsl.h>float imsl_f_elliptic_integral_RD (float x, float y, float z)

double 型関数は、imsl_d_elliptic_integral_RDです。

必要な引数

float x ( 入力 )不完全楕円積分の最初の変数。 非負でなければなりません。

float y ( 入力 )不完全楕円積分の 2 番目の変数。 非負でなければなりません。

float z ( 入力 )不完全楕円積分の 3 番目の変数。 正でなければなりません。

戻り値

完全楕円積分 RD(x, y, z)。

説明

第 2 種の Carlson の楕円積分は、次の様に定義されます。

引数は、非負で 0.69(−lnε)1/9s-2/3 と等しいか、小さくなくてはいけません。こ

こで、ε = imsl_f_machine(4) はマシン精度で、 s = imsl_f_machine(1) は最小

の正の数です。更に、x + y と z は、 max{3s2/3, 3/b2/3} より大きくなければいけ

ません。ここで、 b = imsl_f_machine(2) は、最大の浮動小数点数です。これ

らの条件が満たされないと、 imsl_f_elliptic_integral_RD は、 b を返しま

す。

関数 imsl_f_elliptic_integral_RD は、Carlson と Notis (1981 年 ) と Carlsonの研究 (1979 年 ) によるコードを基にしています。

例題

積分 RD(0, 2, 1) が計算されます。

#include <imsl.h>

main(){ float x = 0.0; float y = 2.0; float z = 1.0; float ans;

( )( )( )( )

1/ 230

3, ,2D

dtR x y zt x t y t z

= + + +

Page 492: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

x = imsl_f_elliptic_integral_RD (x, y, z);

printf ("RD(0, 2, 1) = %f\n", x);}

出力結果

RD(0, 2, 1) = 1.797210

elliptic_integral_RJ第 3 種の Carlson の楕円積分 RJ (x, y, z, ρ) を計算します。

概要

#include <imsl.h>

float imsl_f_elliptic_integral_RJ (float x, float y, float z, float rho)

double 型関数は、imsl_d_elliptic_integral_RJです。

必要な引数

float x ( 入力 )不完全楕円積分の最初の変数。 非負でなければなりません。

float y ( 入力 )不完全楕円積分の 2 番目の変数。 非負でなければなりません。

float z ( 入力 )不完全楕円積分の 3 番目の変数。 正でなければなりません。

float rho ( 入力 )不完全楕円積分の 4 番目の変数。正でなければなりません。

戻り値

完全楕円積分 RJ (x, y, z, ρ)

説明

第 3 種の Carlson の楕円積分は、次の様に定義されます。

引数は、非負でなければなりません。更に、 x + y、 x + z、 y + z 、 ρ は、 (5s)1/3 と等

しいか大きく、 0.3(b/5)1/3 と等しいか小さくなければなりません。ここで、s = imsl_f_machine(1) は、最小の浮動小数点数です。これらの条件が満たされな

い場合、 imsl_f_elliptic_integral_RJ は、最大の浮動小数点である b = imsl_f_machine(2) に設定されます。

関数 imsl_f_elliptic_integral_RJ は、Carlson と Notis (1981 年 ) と Carlsonの研究 (1979 年 ) によるコードを基にしています。

例題

積分 RJ (2, 3, 4, 5) が計算されます。

#include <imsl.h>

main(){ float x = 2.0; float y = 3.0; float z = 4.0;

( )( )( )( )( )

1/ 220

3, , ,2J

dtR x y zt x t y t z t

ρρ

= + + + +

Page 493: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float rho = 5.0; float ans;

x = imsl_f_elliptic_integral_RJ (x, y, z, rho);

printf ("RJ(2, 3, 4, 5) = %f\n", x);}

出力結果

RJ(2, 3, 4, 5) = 0.142976

elliptic_integral_RC 逆円関数、対数と逆双曲線関数が計算される初期積分を計算します。

概要

#include <imsl.h>float imsl_f_elliptic_integral_RC (float x, float y)

double 型関数は、 imsl_d_elliptic_integral_RCです。

必要な引数

float x ( 入力 )不完全楕円積分の最初の変数。 非負で以下の条件を満たさなければな

りません。

float y ( 入力 )不完全楕円積分の 2 番目の変数。非負で以下の条件を満たさなければ

なりません。

戻り値

楕円積分 RC (x, y)。

説明

第 3 種の Carlson の積分は次の様に定義されます。

引数 x は非負で、 y は正で、 x + y は、 b/5 と等しいか小さく、 5s と等しいか大き

くなければなりません。 これらの条件を満たさない場合、

imsl_f_elliptic_integral_RC は、b に設定されます。ここで、b = imsl_f_machine(2) は最大で、 s = imsl_f_machine(1) は最小の浮動小数点数で

す。

関数 imsl_f_elliptic_integral_RC は、Carlson と Notis (1981 年 ) と Carlsonの研究 (1979 年 ) によるコードを基にしています。

例題

積分 RC (2.25, 2) が計算されます。

#include <imsl.h>

main(){ float x = 2.25; float y = 2.0; float ans;

x = imsl_f_elliptic_integral_RC (x, y);

( )( )( )

1/ 220

1,2C

dtR x yt x t y

= + +

Page 494: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

printf ("RC(2.25, 2.0) = %f\n", x);}

出力結果

RC(2.25, 2.0) = 0.693147

fresnel_integral_C余弦フレネル積分を計算します。

概要

#include <imsl.h>float imsl_f_fresnel_integral_C (float x)

double 型関数は、imsl_d_fresnel_integral_Cです。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

余弦フレネル積分。

説明

余弦フレネル積分は、以下の式で定義されます。

例題

フレネル積分 C(1.75) が計算されます。

#include <imsl.h>

main(){ float x = 1.75; float ans;

x = imsl_f_fresnel_integral_C (x);

printf ("C(1.75) = %f\n", x);}

出力結果

C(1.75) = 0.321935

fresnel_integral_S正弦フレネル積分を計算します。

概要

#include <imsl.h>float imsl_f_fresnel_integral_S (float x)

double 型関数は、imsl_d_fresnel_integral_Sです。

2

0

( ) cos( )2

x

C x t dtπ= ∫

Page 495: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

正弦フレネル積分。

説明

正弦フレネル積分は、以下のように定義されます。

例題

フレネル積分 S(1.75) が計算されます。

#include <imsl.h>

main(){ float x = 1.75; float ans;

x = imsl_f_fresnel_integral_S (x);

printf ("S(1.75) = %f\n", x);}

出力結果

S(1.75) = 0.499385

airy_Aiエアリー関数を計算します。

概要

#include <imsl.h>float imsl_f_airy_Ai (float x)

double 型関数は、 imsl_d_airy_Aiです。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

x で計算されたエアリー関数、 Ai(x)。

説明

エアリー関数 Ai(x) は、以下のように定義されます。

ベッセル関数 Kv(x) は、 bessel_exp_K0で定義されています。

x < −1.31ε-2/3 の場合、答えは精度を持ちません。 もし x < −1.31ε-1/3 であれば、

答えは半精度よりも精度が低くなります。ここで ε = imsl_f_machine(4) はマシン精度です。

2

0

( ) sin( )2

x

S x t dtπ= ∫

3 3/ 21/ 32

0

1 1 2( ) cos( ) ( )3 33

xAi x xt t dt K xπ π

= + =∫

Page 496: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

終わりに、答えがアンダーフローしないように、 x は x max よりは小さくなけ

ればなりません。x max はおおよそ x max = −1.5lns}2/3 です。ここで、 s = imsl_f_machine(1) は、最小の正の数です。

例題

この例題では、 Ai(−4.9) が計算されます。

#include <imsl.h>

main(){ float x = -4.9; float ans;

x = imsl_f_airy_Ai (x);

printf ("Ai(-4.9) = %f\n", x);}

出力結果

Ai(-4.9) = 0.374536

airy_Bi第 2 種のエアリー関数を計算します。

概要

#include <imsl.h>float imsl_f_airy_Bi (float x)

double 型関数は、imsl_d_airy_Biです。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

x で計算される第 2 種のエアリー関数、Bi(x)。

説明

エアリー関数 Bi(x) は、以下の式で定義されます。

第 1 種の修正ベッセル関数 Iv(x) や 第 1 種ベッセル関数 Jv(x) で表すことも可能

です。( bessel_Ix と bessel_Jx を参照。)

および

3 3

0 0

1 1 1 1Bi( ) exp( ) sin( )3 3

x xt t dt xt t dtπ π

∞ ∞

= − + +∫ ∫

3 / 2 3 / 21/ 3 1/ 3

2 2Bi( ) ( ) ( ) for 03 3 3xx I x I x x−

= + >

3 / 2 3/ 21/ 3 1/ 3

2 2Bi( ) ( | | ) ( | | ) for 03 3 3xx J x J x x−

− = − <

Page 497: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ε = imsl_f_machine(4) をマシン精度とします。 x < −1.31ε-2/3 の場合、答えは精

度を持ちません。 もし x < −1.31ε-1/3 であれば、答えは半精度よりも精度が低く

なります。加えて、exp[(2/3)x3/2] がオーバーフローするので、 x をあまり大き

くすべきではありません。

例題

この例題では、Bi(−4.9) が計算されます。

#include <imsl.h>

main(){ float x = -4.9; float ans;

x = imsl_f_airy_Bi (x);

printf ("Bi(-4.9) = %f\n", x);}

出力結果

Bi(-4.9) = -0.057747

airy_Ai_derivativeエアリー関数の導関数を計算します。

概要

#include <imsl.h>float imsl_f_airy_Ai_derivative (float x)

double 型関数は、imsl_d_airy_Ai_derivativeです。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

エアリー関数の導関数。

説明

エアリー関数 Ai′(x) は、エアリー関数 Ai(x) の導関数として定義されます。 x < −1.31ε-2/3 の場合、答えは精度を持ちません。x < −1.31ε-1/3 の場合、答えは半精

度以下になります。ここで、ε = imsl_f_machine(4) は、マシン精度です。最

後に、答えがアンダーフローになるので、 x は xmax より小さくなるべきです。 s = imsl_f_machine(1) が、最小の正の数を表す時、だいたい xmax = {−1.51lns}になります。

例題

この例題では、Ai′(−4.9) が計算されます。

#include <imsl.h>

main(){ float x = -4.9; float ans;

x = imsl_f_airy_Ai_derivative (x);

printf ("Ai’(-4.9) = %f\n", x);}

Page 498: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

Ai’(-4.9) = 0.146958

airy_Bi_derivative第 2 種のエアリー関数の導関数を計算します。

概要

#include <imsl.h>float imsl_f_airy_Bi_derivative (float x)

double 型関数は、imsl_d_airy_Bi_derivativeです。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

第 2 種のエアリー関数の導関数。

説明

エアリー関数 Bi′(x) は、第 2 種のエアリー関数 Bi(x) の導関数として定義され

ます。 x < −1.31ε-2/3 の場合、 答えは精度を持ちません。x < −1.31ε-1/3 の場合、答

えは半精度以下になります。ここで、ε = imsl_f_machine(4) は、マシン精度

です。加えて、exp[(2/3)x3/2] がオーバーフローするので、x はあまり大きくす

べきではありません。

例題

この例題では、 Bi′(−4.9) が計算されます。

#include <imsl.h>

main(){ float x = -4.9; float ans;

x = imsl_f_airy_Bi_derivative (x);

printf ("Bi’(-4.9) = %f\n", x);}

出力結果

Bi’(-4.9) = 0.827219

kelvin_ber0次数ゼロの第 1 種ケルビン関数 ber を計算します。

概要

#include <imsl.h>float imsl_f_kelvin_ber0 (float x)

double 型関数は、imsl_d_kelvin_ber0です。

必要な引数

float x ( 入力 )関数値が必要な引数。

Page 499: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

x で計算される次数ゼロの第 1 種ケルビン関数 ber 。

説明

ケルビン関数 ber0(x) は、 ℜJ0(xe3πi/4) として定義されます。ベッセル関数 J0(x)は、次式で定義されます。

関数 imsl_f_kelvin_ber0 は、Burgoyne の研究 (1963 年 ) を基にしています。

例題

この例題では、 ber0 (0.4) が計算されます。

#include <imsl.h>

main(){ float x = 0.4; float ans;

x = imsl_f_kelvin_ber0 (x);

printf ("ber0(0.4) = %f\n", x);}

出力結果

ber0(0.4) = 0.999600

kelvin_bei0次数ゼロの第 1 種ケルビン関数 bei を計算します。

概要

#include <imsl.h>float imsl_f_kelvin_bei0 (float x)

double 型関数は、imsl_d_kelvin_bei0です。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

x で計算される次数ゼロの第 1 種ケルビン関数 bei。

説明

ケルビン関数 bie0(x) は、 ℑJ0(xe3πi/4) として定義されます。ベッセル関数 J0(x) は、次式で定義されます。

関数 imsl_f_kelvin_bei0 は、 Burgoyne の研究 (1963 年 ) が基になっていま

す。

imsl_f_kelvin_bei0では、x は 119 未満でなければなりません。

( ) ( )0 0

1 cos sinJ x x dπ

θ θπ

= ∫

( ) ( )0 0

1 cos sinJ x x dπ

θ θπ

= ∫

Page 500: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

この例題では、 bei0(0.4) が計算されます。

#include <imsl.h>

main(){ float x = 0.4; float ans;

x = imsl_f_kelvin_bei0 (x);

printf ("bei0(0.4) = %f\n", x);}

出力結果

bei0(0.4) = 0.039998

kelvin_ker0次数ゼロの第 2 種ケルビン関数 ker を計算します。

概要

#include <imsl.h>float imsl_f_kelvin_ker0 (float x)

double 型関数は、 imsl_d_kelvin_ker0です。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

x で計算される次数ゼロの第 2 種ケルビン関数。

説明

修正ケルビン関数 ker0(x) は、 ℜK0(xeπi/4) として定義されます。ベッセル関数 K0(x) は、次式で定義されます。

関数 imsl_f_kelvin_ker0 は、 Burgoyne の研究 (1963 年 ) が基になっていま

す。

x < 0 の場合、 NaN (Not a Number) が返されます。 x ≥ 119 の場合、ゼロが返され

ます。

例題

この例題では、 ker0(0.4) が計算されます。

#include <imsl.h>

main(){ float x = 0.4; float ans;

x = imsl_f_kelvin_ker0 (x);

printf ("ker0(0.4) = %f\n", x);}

( ) ( )0 0cos sinK x x t dt

∞= ∫

Page 501: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

ker0(0.4) = 1.062624

kelvin_kei0次数ゼロの第 2 種ケルビン関数 kei を計算します。

概要

#include <imsl.h>float imsl_f_kelvin_kei0 (float x)

double 型関数は、imsl_d_kelvin_kei0です。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

x で計算される次数ゼロの第 2 種ケルビン関数 kei。

説明

修正ケルビン関数 kei0(x) は、 ℑK0(xeπi/4) として定義されます。ベッセル関数 K0(x) は、次式で定義されます。

関数 imsl_f_kelvin_kei0 は、Burgoyne の研究(1963 年)を基にしています。

x < 0 の場合、NaN (Not a Number) が返されます。 x ≥ 119 の場合、ゼロが返され

ます。

例題

この例題では、 kei0(0.4) が計算されます。

#include <imsl.h>

main(){ float x = 0.4; float ans;

x = imsl_f_kelvin_kei0 (x);

printf ("kei0(0.4) = %f\n", x);}

出力結果

kei0(0.4) = -0.703800

kelvin_ber0_derivative次数ゼロの第 1 種ケルビン関数 ber の導関数を計算します。

概要

#include <imsl.h>float imsl_f_kelvin_ber0_derivative (float x)

double 型関数は、imsl_d_kelvin_ber0_derivativeです。

( ) ( )0 0cos sinK x x t dt

∞= ∫

Page 502: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

x で計算される次数ゼロの第 1 種ケルビン関数の導関数。

説明

関数 ber0′(x) は、以下のように定義されます。

関数 imsl_f_kelvin_ber0_derivative は、Burgoyne の研究(1963 年)を基

にしています。

|x| > 119 の場合、 NaN が返されます。

例題

この例題では、 ber0′ (0.6) が計算されます。

#include <imsl.h> main(){ float x = 0.6; float ans; x = imsl_f_kelvin_ber0_derivative (x); printf ("ber0'(0.6) = %f\n", x);}

出力結果ber0'(0.6) = -0.013498

kelvin_bei0_derivative次数ゼロの第 1 種ケルビン関数 bei の導関数を計算します。

概要

#include <imsl.h>float imsl_f_kelvin_bei0_derivative (float x)

double 型関数は、imsl_d_kelvin_bei0_derivativeです。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

x で計算される次数ゼロの第 1 種ケルビン関数の導関数。

説明

関数 bei0′(x) は、次の様に定義されます。

0ber ( )d xdx

0bei ( )d xdx

Page 503: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

関数 imsl_f_kelvin_bei0_derivative は、Burgoyne の研究(1963 年)を基

にしています。

|x| > 119 の場合、 NaN が返されます。

例題

この例題では、 bei0′(0.6) が計算されます。

#include <imsl.h>main(){ float x = 0.6; float ans;

x = imsl_f_kelvin_bei0_derivative (x);

printf ("bei0’(0.6) = %f\n", x);}

出力結果

bei0’(0.6) = 0.299798

kelvin_ker0_derivative次数ゼロの第 2 種ケルビン関数 ker の導関数を計算します。

概要

#include <imsl.h>float imsl_f_kelvin_ker0_derivative (float x)

double 型関数は、 imsl_d_kelvin_ker0_derivativeです。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

x で計算された次数ゼロの第 2 種ケルビン関数 ker の導関数。

説明

関数 ker0′(x) は、次の様に定義されます。

関数 imsl_f_kelvin_ker0_derivative は、Burgoyne の研究(1963 年)を基

にしています。

x < 0 の場合、NaN (Not a Number) が返されます。 x ≥ 119 の場合、ゼロが返されます。

例題

この例題では、 ker0′(0.6) が計算されます。

#include <imsl.h>

main(){ float x = 0.6; float ans;

x = imsl_f_kelvin_ker0_derivative (x);

printf ("ker0’(0.6) = %f\n", x);

0ker ( )d xdx

Page 504: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

}

出力結果

ker0’(0.6) = -1.456538

kelvin_kei0_derivative次数ゼロの第 2 種ケルビン関数 kei の導関数を計算します。

概要

#include <imsl.h>float imsl_f_kelvin_kei0_derivative (float x)

double 型関数は、 imsl_d_kelvin_kei0_derivativeです。

必要な引数

float x ( 入力 )関数値が必要な引数。

戻り値

x で計算される次数ゼロの第 2 種ケルビン関数 keiの導関数。

説明

関数 kei0′(x) は、次の様に定義されます。

関数 imsl_f_kelvin_kei0_derivative は、Burgoyne の研究(1963 年)を基

にしています。

x < 0 の場合、NaN (Not a Number) が返されます。 x ≥ 119 の場合、ゼロが返され

ます。

例題

この例題では、 kei0′(0.6) が計算されます。

#include <imsl.h>

main(){ float x = 0.6; float ans;

x = imsl_f_kelvin_kei0_derivative (x);

printf ("kei0’(0.6) = %f\n", x);}

出力結果

kei0’(0.6) = 0.348164

normal_cdf標準正規 ( ガウス ) 分布関数を計算します。

概要

#include <imsl.h>

float imsl_f_normal_cdf (float x)

0kei ( )d xdx

Page 505: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

double 型関数は、 imsl_d_normal_cdfです。

必要な引数

float x ( 入力 )正規分布関数が計算される点。

戻り値

正規乱数変数が x より小さい、もしくは等しい値を取る確率。

説明

関数 imsl_f_normal_cdf 次式の標準正規(ガウス)乱数変数の分布関数、Φ、

を計算します。

点 x の分布関数の値は、乱数変数が x. より小さい、もしくは等しい値を取る確

率です。

平均 μ と分散 σ2 を持つ正規確率変数が y より小さい確率は、

imsl_f_normal_cdf によって (y − µ)/σ で計算されます。

Φ(x) は誤差補関数 imsl_f_erfc を使用して計算されます。その関係は、以

下の式で表されます。

Figure 9- 13 Φ(x) のプロット

例題

X を平均が 100 で分散が 225 の正規乱数変数とします。この例題では、X が 90 よりも小さい確率と X が 105 と 110 の間にある確率を見つけます。

#include <imsl.h>

main(){ float p, x1, x2;

x1 = (90.0-100.0)/15.0; p = imsl_f_normal_cdf(x1); printf("The probability that X is less than 90 is %6.4f\n\n", p);

x1 = (105.0-100.0)/15.0; x2 = (110.0-100.0)/15.0;

( ) 2 / 212

x tx e dtπ

−∞Φ = ∫

( ) ( )erfc / 2.0 / 2x xΦ = −

Page 506: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

p = imsl_f_normal_cdf(x2) - imsl_f_normal_cdf(x1); printf("The probability that X is between 105 and 110 is %6.4f\n", p); }

出力結果

The probability that X is less than 90 is 0.2525

The probability that X is between 105 and 110 is 0.1169

normal_inverse_cdf標準正規 ( ガウス ) 分布関数の逆を計算します。

概要

#include <imsl.h>

float imsl_f_normal_inverse_cdf (float p)double 型関数は、imsl_d_normal_inverse_cdfです。

必要な引数

float p ( 入力 )正規分布関数の逆が計算される確率。引数 p は、開区間 (0.0, 1.0) 内で

なければなりません。

戻り値

pで計算される正規分布関数の逆。 標準正規乱数の変数が

imsl_f_normal_inverse_cdfより小さいか等しい値をとる確率は、 pです。

説明

関数 imsl_f_normal_inverse_cdf は、標準正規(ガウス)乱数変数の分布関

数 Φ の逆を計算します。つまり、imsl_f_normal_inverse_cdf(p) = Φ-1 (p) になります。

点 x での分布関数の値は、乱数変数が x より小さいか等しい値をとる確率で

す。 標準正規分布は、平均値が 0 で分散が 1 です。

関数 imsl_f_normal_inverse_cdf(p) は、誤差関数の逆のためにミニマックス

の有理関数近似を使って計算されます。これらの近似に関する解説は、Hart とその他 (1968 年 ) や Strecok (1968 年 ) にあります。. The rational functions used in imsl_f_normal_inverse_cdf で使われている有理関数は、 Kinnucan と Kuki (1968 年 ) によって説明されています。

例題

この例題では、確率が 0.9 になる点を計算するので、正規乱数変数はこの点よ

りも小さいか等しくなります。

#include <imsl.h>

main(){ float x; float p = 0.9;

x = imsl_f_normal_inverse_cdf(p); printf("The 90th percentile of a standard normal is %6.4f.\n", x);}

( ) 2 / 212

x tx e dtπ

−∞Φ = ∫

Page 507: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

The 90th percentile of a standard normal is 1.2816.

chi_squared_cdfカイ二乗分布関数を計算します。

概要

#include <imsl.h>

float imsl_f_chi_squared_cdf (float chi_squared, float df)double 型関数は、 imsl_d_chi_squared_cdfです。

必要な引数

float chi_squared ( 入力 )カイ二乗分布関数が計算されるための引数。

float df ( 入力 )カイ二乗分布の自由度の数。引数 df は、 0.5 以上でなければなりませ

ん。

戻り値

カイ二乗乱数変数が、chi_squared以下の値をとる確率。

説明

関数 imsl_f_chi_squared_cdf は、カイ二乗乱数変数 x = chi_squaredと

ν = df の分布関数 F を計算します。

ここで、 Γ(⋅) は、ガンマ関数です。 点 x で分布関数の値は、確率変数が x 以下の

値をとる確率です。

ν > 65 の場合、 imsl_f_chi_squared_cdf は、正規分布のために Wilson-Hilferty 近似 (Abramowitz と Stegun 1964 年、 Equation 26.4.17) を使い、関数 imsl_f_normal_cdf が、正規分布を計算するために使用されます。

ν ≤ 65 の場合は、imsl_f_chi_squared_cdf は、分布関数を計算するために級

数展開を使います。x < max (ν/2, 26) の場合、imsl_f_chi_squared_cdf は、

Abramowitz と Stegun (1964 年 ) の級数 6.5.29 を使用し、そうでなければ、 Abramowitz と Stegun の漸近展開 6.5.32 を使用します。

例題

X が、2 つの自由度を持つカイ二乗の確率変数とします。この例題では、 X が 0.15 未満である確率と X が 3.0 以上の確率を見つけます。

#include <imsl.h>

void main(){ float chi_squared = 0.15; float df = 2.0; float p;

p = imsl_f_chi_squared_cdf(chi_squared, df); printf("%s %s %6.4f\n", "The probability that chi-squared", "with 2 df is less than 0.15 is", p);

chi_squared = 3.0; p = 1.0 - imsl_f_chi_squared_cdf(chi_squared, df);

( ) ( )/ 2 / 2 1

/ 2 0

12 / 2

x tF x e t dtνν ν

− −=Γ ∫

Page 508: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

printf("%s %s %6.4f\n", "The probability that chi-squared", "with 2 df is greater than 3.0 is", p);}

出力結果

The probability that chi-squared with 2 df is less than 0.15 is 0.0723The probability that chi-squared with 2 df is greater than 3.0 is 0.2231

情報エラー

IMSL_ARG_LESS_THAN_ZERO 入力変数 chi_squaredは、ゼロ未満です。

警報エラー

IMSL_NORMAL_UNDERFLOW 大きな自由度のための正規分布が使用され

ているので、アンダーフローが起こりました。

chi_squared_inverse_cdfカイ二乗分布関数の逆を計算します。

概要

#include <imsl.h>

float imsl_f_chi_squared_inverse_cdf (float p, float df)double function is imsl_d_chi_squared_inverse_cdf.

必要な引数

float p ( 入力 )カイ二乗分布関数の逆が計算される確率。引数 p は、開区間 (0.0, 1.0)内でなければなりません。

float df ( 入力 )カイ二乗分布関数の自由度の数。引数 df は、 0.5 以上でなければなり

ません。

戻り値

pで計算されるカイ二乗分布関数の逆。 カイ二乗の確率変数が、

imsl_f_chi_squared_inverse_cdf以下の値を取る確率は pです。

説明

関数 imsl_f_chi_squared_inverse_cdf は、 ν = df と確率 p を持つカイ二乗

の確率変数の逆分布関数を計算します。 つまり、次式になるような x = imsl_f_chi_squared_inverse_cdf(p,df) を決定します。

ここで Γ(⋅) は、ガンマ関数です。確率変数が、x 以下の値をとる確率は p で

す。

ν < 40 の場合、imsl_f_chi_squared_inverse_cdf は、二分法 ( ν ≤ 2 または p > 0.98 の時 ) を使い、もしくは、 カイ二乗分布関数が p と等しくなる点を見

つけるためにはさみうち法(regula falsi)を使用します。 この分布関数は、関

数 imsl_f_chi_squared_cdfを使って計算されます。

40 ≤ ν < 100 の場合、正規分布のための修正 Wilson-Hilferty 近似 (Abramowitz と Stegun 1964 年、 equation 26.4.18) が使用されます。 関数 imsl_f_normal_cdf は、

正規分布関数の逆を計算するために使用されます。ν ≥ 100 の場合、通常の

Wilson-Hilferty 近似 (Abramowitz と Stegun 1964 年、 equation 26.4.17) が使用され

ます。

( )/ 2 / 2 1

/ 2 0

12 / 2

x tp e t dtνν ν

− −=Γ ∫

Page 509: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

この例題では、 99 番目のパーセントポイントが 2 つの自由度を持つカイ二乗確

率変数のために計算されます。同じ計算が、64 の自由度を持つ似たような変

数でも行われます。

#include <imsl.h>

void main (){ float df, x; float p = 0.99;

df = 2.0; x = imsl_f_chi_squared_inverse_cdf(p, df); printf("For p = .99 with 2 df, x = %7.3f.\n", x);

df = 64.0; x = imsl_f_chi_squared_inverse_cdf(p,df); printf("For p = .99 with 64 df, x = %7.3f.\n", x);}

出力結果

For p = .99 with 2 df, x = 9.210.For p = .99 with 64 df, x = 93.217.

警告エラー

IMSL_UNABLE_TO_BRACKET_VALUE p を囲む範囲が見つかりません。 imsl_f_chi_squared_inverse_cdf のため

の近似が返されます。

IMSL_CHI_2_INV_CDF_CONVERGENCE カイ二乗の逆の値は、指定した反復数内

で見つけることができませんでした。 imsl_f_chi_squared_inverse_cdf のため

に近似が返されます。

F_cdfF 分布関数を計算します。

概要

#include <imsl.h>

float imsl_f_F_cdf (float f, float df_denominator, float df_numerator)double 型関数は、 imsl_d_F_cdfです。

必要な引数

float f ( 入力 )F 分布関数が計算される点。

float df_numerator ( 入力 )分子の自由度。 引数 df_numerator は、正である必要があります。

float df_denominator ( 入力 )分母の自由度。引数 df_denominator は、正である必要があります。

戻り値

F 確率変数が、入力点 f 以下の値をとる確率。

説明

関数 imsl_f_F_cdf は、df_numerator と df_denominatorを持つ Snedecor の F 確率変数の分布関数を計算します。ベータ確率変数に変換し、不完全ベータ

関数を計算することで、その関数は計算されます。X が、ν1 と ν2 の自由度を

Page 510: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

持つ F 変量で、Y = (ν1 X)/(ν2 + ν1 X) の場合、Y は、引数 p = ν1/2 と q = ν2/2 を

持つベータ変量です。

関数 imsl_f_F_cdf は、次の様に表すことができる F 確率変数の間の関係も使

用します。

FF(f, ν1, ν2 ) = 1 − FF(1/f, ν2, ν1 ) で、 FF は、F 確率変数のための分布関数です。

Figure 9-3 FF (f, 1.0, 1.0) のプロット

例題

この例題は、1 つの分子と 1 つの分母の自由度を持つ F 確率変数が、 648 より

大きくなる確率を求めます。

#include <imsl.h>

main(){ float p; float F = 648.0; float df_numerator = 1.0; float df_denominator = 1.0;

p = 1.0 - imsl_f_F_cdf(F,df_numerator, df_denominator); printf("%s %s %6.4f.\n", "The probability that an F(1,1) variate", "is greater than 648 is", p);}

出力結果The probability that an F(1,1) variate is greater than 648 is 0.0250.

F_inverse_cdfF 分布関数の逆を計算します。

概要

#include <imsl.h>

float imsl_f_F_inverse_cdf (float p, float df_numerator, float df_denominator)

double 型関数は、 imsl_d_F_inverse_cdfです。

Page 511: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

float p ( 入力 )F 分布関数の逆が計算される確率。引数 p は、開区間 (0.0, 1.0) 内でな

ければなりません。

float df_numerator ( 入力 )分子の自由度。引数 df_numerator は、正である必要があります。

float df_denominator ( 入力 )分母の自由度。引数 df_denominator は、正である必要があります。

戻り値

pで計算される F 分布関数の逆の値。 F 確率変数が、imsl_f_F_inverse_cdf以

下の値をとる確率は、 pです。

説明

関数 imsl_f_F_inverse_cdf は、ν1 = df_numeratorの分子の自由度と ν2 = df_denominatorの分母の自由度を持つ Snedecorの F 確率変数の逆分布関数

を計算します。ベータ確率変数に変換し、不完全ベータ関数の逆を計算することで、その関数は計算されます。X が、ν1 と ν2 の自由度を持つ F 変量で、

Y = (ν1 X)/(ν2 + ν1 X) の場合、Y は、引数 p = ν1/2 と q = ν2/2 を持つベータ変量

です。 P ≤ 0.5 の場合、imsl_f_F_inverse_cdf は、直接関係を使用します。そ

うでなければ、次の様に表せられる F 確率変数間の関係も使用します。

FF(f, ν1, ν2) = 1 − FF(1/f, ν2 , ν1)

例題

この例題では、 99 番目のパーセントポイントが 7 つの自由度を持つカイ二乗確

率変数のために計算されます。同じ計算が、1 つの自由度を持つ似たような変

数でも行われます。

#include <imsl.h>

main(){ float df_denominator = 1.0; float df_numerator = 7.0; float f; float p = 0.99;

f = imsl_f_F_inverse_cdf(p, df_numerator, df_denominator);

printf("The F(7,1) 0.01 critical value is %6.3f\n", f);}

出力結果

The F(7,1) 0.01 critical value is 5928.370

重大エラー

IMSL_F_INVERSE_OVERFLOW 逆ベータ分布から得た結果を持つ F 分布の

逆の値を修正することでオーバーフローが起こるので、関数 imsl_f_F_inverse_cdf は、マシンの無限性に設定されます。

t_cdfスチューデントの t 分布関数を計算します。

概要

#include <imsl.h>

Page 512: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float imsl_f_t_cdf (float t, float df)double 型関数は、 imsl_d_t_cdfです。

必要な引数

float t ( 入力 )スチューデントの t 分布関数が計算されるための引数。

float df ( 入力 )自由度。引数 df は、1.0 以上でなければなりません。

戻り値

スチューデントの t 確率変数が、入力 t以下の値をとる確率。

説明

関数 imsl_f_t_cdf は、 ν1 = df 自由度を持つスチューデントの t 確率変数の分

布関数を計算します。 t の二乗が ν 以上の場合、 F 確率変数 ( その後は、ベータ

確率変数 ) との t の関係が活用され、 ベータ分布からのパーセントが使われま

す。 そうでなければ、Hill (1970 年 ) が説明している手法が使用されます。 ν が整数ではないか、 ν が 19 以上、もしくは、 ν が 200 以上である場合、Cornish-Fisher 展開を使って分布関数を計算します。 ν が 20 未満で、 |t| が 2.0 未満の場

合、三角級数 (Abramowitz と Stegun 1964 年、 equations 26.7.3 と 26.7.4 を参照 )が使用されます。残りの場合、大きな t の値でも正常に収束する Hill (1970 年 )によって与えられた級数が使用されます。

例題

この例題では 6 つの自由度を持つ t 確率変数が、絶対値 2.447 より大きい確率

を見つけます。

#include <imsl.h>

main (){ float p; float t = 2.447; float df = 6.0;

p = 2.0*imsl_f_t_cdf(-t,df); printf("Pr(|t(6)| > 2.447) = %6.4f\n", p);}

出力結果

Pr(|t(6)| > 2.447) = 0.0500

Figure 9-4 Ft(t, 6.0) のプロット

Page 513: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

t_inverse_cdfスチューデントの t 分布関数の逆を計算します。

概要

#include <imsl.h>

float imsl_f_t_inverse_cdf (float p, float df)double 型関数は、 imsl_d_t_inverse_cdfです。

必要な引数

float p ( 入力 )スチューデントの t 分布関数の逆が計算される確率。引数 p は、開区

間 (0.0, 1.0) でなければなりません。

float df ( 入力 )自由度。引数 df は、 1.0 以上でなければなりません。

戻り値

pで計算されるスチューデントの t の分布関数の逆。 スチューデントの t 確率変

数が、imsl_f_t_inverse_cdf 以下をとる確率は pです。

説明

関数 imsl_f_t_inverse_cdf は、ν = df 自由度を持つスチューデントの t 確率

変数の逆分布関数を計算します。 ν が 1 または 2 と等しい場合、その逆は閉形

式で取得されることができます。ν が 1 と 2 の間の場合、ベータ確率変数との t の関係が活用され、ベータ分布の逆を使って、その逆を計算します。そうで

なければ、 Hill (1970 年 ) のアルゴリズムが使用されます。2 より大きい ν の小

さな値の場合、 Hill のアルゴリズムは、 t 密度の 1/(1 + t2/ν) の統合された展開を

逆にします。 大きな値の場合、正規分布に関する漸近的な逆 Cornish-Fisher 型展開が使用されます。

例題

この例題では、6 つの自由度を持つ 2 面の t 検定のための 0.05 臨界値を見つけ

ます。#include <imsl.h>

void main(){ float df = 6.0; float p = 0.975; float t;

t = imsl_f_t_inverse_cdf(p,df);

printf("The two-sided t(6) 0.05 critical value is %6.3f\n", t);}

出力結果The two-sided t(6) 0.05 critical value is 2.447

情報エラー

IMSL_OVERFLOW 逆ベータ分布から得た結果を持つ F 分布の逆の値

を修正することでオーバーフローが起こるので、関数 imsl_f_t_inverse_cdf は、マシンの無限

性に設定されます。

Page 514: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

gamma_cdfガンマ分布関数を計算します。

概要

#include <imsl.h>

float imsl_f_gamma_cdf (float x, float a)double 型関数は、imsl_d_gamma_cdfです。

必要な引数

float x ( 入力 )ガンマ分布関数が計算されるための引数。

float a ( 入力 )ガンマ分布の形状パラメータ。このパラメータは、正でなければなりません。

戻り値

ガンマ確率変数が、x 以下の値をとる確率。

説明

関数 imsl_f_gamma_cdf は、形状パラメータ a を持つガンマ確率変数の分布関

数 F を計算します。つまり、次式で表すことができます。

ここで、 Γ(⋅) はガンマ関数です ( ガンマ関数は、ゼロから上と同じ被積分関数

の無限までの積分です )。 点 x での分布関数の値は、確率変数が x 以下の値を

とる確率です。

ガンマ分布は、スケールパラメータ b ( 正でなければならない ) を持つ 2 つの

パラメータ分布、もしくは、3 番目のパラメータ c が位置パラメータである 3つのパラメータ分布として定義されます。

最も一般的な場合、(c, ∞) の確率密度関数は、次式で表されます。

T がパラメータ a、 b、 c を持つ確率変数の場合、T ≤ t0 である確率は、x = (t0 −c)/b を設定することで imsl_f_gamma_cdf から得ることができます。

x が a 未満か x が 1.0 以下の場合 , imsl_f_gamma_cdf は、級数展開を使用しま

す。そうでなければ、連分数展開法が使用されます。(Abramowitz と Stegun 1964 年を参照してください。)

例題

X を 4 つの形状パラメータを持つガンマ確率変数とします。 ( この場合、形状

パラメータが整数なので、アーラン分布を持ちます。) この例題では、 X が 0.5 未満の確率と X が 0.5 から 1.0 になる確率を見つけます。.

#include <imsl.h>

main(){ float p, x; float a = 4.0;

x = 0.5;

( ) ( )1

0

1 x t aF x e t dta

− −=Γ ∫

( ) ( )( ) ( ) 1/1 at c b

af t e x cb a

−− −= −Γ

Page 515: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

p = imsl_f_gamma_cdf(x,a); printf("The probability that X is less than 0.5 is %6.4f\n", p);

x = 1.0; p = imsl_f_gamma_cdf(x,a) - p; printf("The probability that X is between 0.5 and 1.0 is %6.4f\n", p);}

出力結果

The probability that X is less than 0.5 is 0.0018The probability that X is between 0.5 and 1.0 is 0.0172

情報エラー

IMSL_LESS_THAN_ZERO 入力引数 xは、ゼロ未満です。

重大エラー

IMSL_X_AND_A_TOO_LARGE x と a が大きすぎるので、この関数はオー

バーフローします。

binomial_cdf2 項分布関数を計算します。

概要

#include <imsl.h>

float imsl_f_binomial_cdf (int k, int n, float p)double 型関数は、imsl_d_binomial_cdfです。

必要な引数

int k ( 入力 )2 項分布関数が計算されるための引数。

int n ( 入力 )ベルヌーイ試行の数。

float p ( 入力 )各試行の成功する確率。

戻り値

n 回の独立したベルヌーイ試行で k またはより 少ない成功が起こる確率。各試

行は、成功の確率 p を持っています。

説明

関数 imsl_f_binomial_cdf は、パラメータ n と p を持つ 2 項確率変数の分布

関数を計算します。 これは、その範囲内の指定した値を獲得する確率変数の確

率を合計することで行われます。これらの確率は、再起的な関係によって計算されます。

アンダーフローの可能性を避けるために、k が n × p より大きくない場合は、

確率はゼロから前方に計算されます。そうでなければ、n から後方に計算され

ます。最小の正のマシン数 ε が、確率を合計するための最初の値として使用さ

れます。確率は、前方への計算が行われる場合、(1 − p)n ε によって再スケーリ

ングされ、後方への計算が行われる場合、pnε によって再スケーリングされま

す。

( ) ( )( ) ( )1

11

n j pPr X j Pr X j

j p+ −

= = = −−

Page 516: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

p がゼロである特殊なケースの場合、imsl_f_binomial_cdf が 1 に設定され

ます。p が 1 の場合、 k = n なら imsl_f_binomial_cdf が1に設定され、 そのほ

かは、ゼロが設定されます。

例題

X を n = 5 と p = 0.95 を持つ 2 項確率変数とします。 この例題では、 X が 3 以下

になる確率を見つけます。

#include <imsl.h>

void main(){ int k = 3; int n = 5; float p = 0.95; float pr;

pr = imsl_f_binomial_cdf(k,n,p); printf("Pr(x <= 3) = %6.4f\n", pr);}

出力結果

Pr(x <= 3) = 0.0226

情報エラー

IMSL_LESS_THAN_ZERO 入力引数 k がゼロ未満です。

IMSL_GREATER_THAN_N 入力引数 k は、ベルヌーイ試行の数より多くなっ

ています。

hypergeometric_cdf超幾何分布関数を計算します。

概要

#include <imsl.h>

float imsl_f_hypergeometric_cdf (int k, int n, int m, int l)double 型関数は、imsl_d_hypergeometric_cdfです。

必要な引数

int k ( 入力 )超幾何分布関数が計算されるための引数。

int n ( 入力 )標本サイズ n は、 k以上でなければなりません。

int m ( 入力 )ロット内の不良の数。

int l ( 入力 )ロットサイズ l は、 n と m以上でなければなりません。.

戻り値

m 個の不良を含むサイズ l のロットから取り出されたサイズ n の標本の中か

ら、k もしくはより少ない不良の確率。

説明

関数 imsl_f_hypergeometric_cdf は、パラメータ n、 l、 m を持つ超幾何確率

変数の分布関数を計算します。超幾何確率変数 x は、m 個のアイテムを含むサ

イズ l の母集団から交換することなく取り出され、サイズ n の無作為な標本内

で与えられたタイプのアイテムの数として考えることができます。確率関数は、次式で表されます。

Page 517: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで、 i = max (0, n − l + m) になります。

k が i 以上で、 min (n, m) 以下の場合、imsl_f_hypergeometric_cdf は、この

式において i から k まであがっていく j のための項目を足していきます。そう

でなければ、必要に応じて 0 か 1 が返されます。

累積された値の丸めを防ぐために、imsl_f_hypergeometric_cdfは、k が(m + 1) (n + 1)/(l + 2) 内で最大の整数である分布の最頻値より大きいかどうかに

より、異なる合計方法を用います。

例題

X は、n = 100、 l = 1000、m = 70 を持つ超幾何確率変数とします。 個の例題で

は、 7 での分布関数を計算します。

#include <imsl.h>

void main(){ int k = 7; int l = 1000; int m = 70; int n = 100; float p;

p = imsl_f_hypergeometric_cdf(k,n,m,l); printf("\nPr (x <= 7) = %6.4f", p);}

出力結果

Pr (x <= 7) = 0.599

情報エラー

IMSL_LESS_THAN_ZERO 入力引数 k は、ゼロ未満です。

IMSL_K_GREATER_THAN_N 入力引数 k は、標本サイズより大きくなり

ます。

重大エラー

IMSL_LOT_SIZE_TOO_SMALL ロットサイズは、 n と m 以上でなければなり

ません。

poisson_cdfポワソン分布関数を計算します。

概要

#include <imsl.h>

float imsl_f_poisson_cdf (int k, float theta)double 型関数は、 imsl_d_poisson_cdfです。

必要な引数

int k ( 入力 )ポワソン分布関数が計算されるための引数。

float theta ( 入力 )ポワソン分布の平均値。引数 theta は、正でなければなりません。

( )( )( )

( ) ( )for , 1, , min ,m l mj n j

ln

Pr x j j i i n m−−

= = = + K

Page 518: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

ポワソン確率変数が、k 以下の値をとる確率。

説明

関数 imsl_f_poisson_cdf は、引数 theta を持つポワソン確率変数の分布関

数を計算します。ポワソン確率変数の平均値 theta は、正でなければなりま

せん。確率関数 ( θ = thetaを持つ ) は、次式で表されます。

f(x) = e-θ θx/x!, for x = 0, 1, 2, …

個々の項は、分布のテールから分布の平均値まで計算され、合計されます。 関数 imsl_f_poisson_cdf は、再帰的な関係を使用します。

f(x + 1) = f(x)q/(x + 1), for x = 0, 1, 2, …, k - 1

with f(0) = e-θ

Figure 9-5 Fp(k, θ) のプロット

例題

X は、 θ = 10 を持つポワソン確率変数とします。 この例題では、 X ≤ 7 の確率を

計算します。

#include <imsl.h>

void main(){ int k = 7; float theta = 10.0; float p;

p = imsl_f_poisson_cdf(k, theta); printf("Pr(x <= 7) = %6.4f\n", p);}

出力結果

Pr(x <= 7) = 0.2202

情報エラー

IMSL_LESS_THAN_ZERO 入力引数 k がゼロ未満です。

beta_cdfベータ確率分布関数を計算します。

概要

#include <imsl.h>

Page 519: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float imsl_f_beta_cdf (float x, float pin, float qin)double 型関数は、 imsl_d_beta_cdfです。

必要な引数

float x ( 入力 )ベータ確率分布関数が計算されるための引数。

float pin ( 入力 )最初のベータ分布のパラメータ。引数 pinは、正でなければなりませ

ん。

float qin ( 入力 )2 番目のベータ分布パラメータ。引数 qin は、正でなければなりませ

ん。

戻り値

ベータ確率変数が、 x 以下の値をとる確率。

説明

関数 imsl_f_beta_cdf は、パラメータ pin と qinを持つベータ確率変数の分布

関数を計算します。この関数は、時々不完全ベータ比率と呼ばれ、p = pin と q = qinを持つと Ix (p, q) と表示されます。次式から与えられます。

ここで、Γ(⋅) は、ガンマ関数です。 Ix (p, q) による分布関数の値は、確率変数

が、x 以下の値をとる確率です。

上の式での積分は、不完全ベータ関数と呼ばれ、 βx (p, q) で表されます。 この式

での定数は、ベータ関数 (1 で計算される不完全関数 ) の逆数で、 β(p, q) で表さ

れます。

関数 beta_cdf は、 Bosten と Battiste (1974 年 ) の手法を用いています。

例題

Suppose X は、パラメータが 12 と 12 のベータ確率変数とします。 (X は、対称

分布です。この例題では、 X が 0.6 未満の確率と X が 0.5 と 0.6 の間になる確率

を見つけます。 ( X は、対称ベータ確率変数なので、 0.5 未満になる確率は 0.5 で

す。)

#include <imsl.h>

main(){ float p, pin, qin, x;

pin = 12.0; qin = 12.0; x = 0.6; p = imsl_f_beta_cdf(x, pin, qin); printf(" The probability that X is less than 0.6 is %6.4f\n", p); x = 0.5; p -= imsl_f_beta_cdf(x, pin, qin); printf(" The probability that X is between 0.5 and 0.6 is %6.4f\n", p);}

出力結果

The probability that X is less than 0.6 is 0.8364 The probability that X is between 0.5 and 0.6 is 0.3364

( ) ( ) ( )( ) ( ) 11

0, 1

x qpx

p qI p q t t dt

p q−−Γ Γ

= −Γ + ∫

Page 520: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

beta_inverse_cdfベータ分布関数の逆を計算します。

概要

#include <imsl.h>

float imsl_f_beta_inverse_cdf (float p, float pin, float qin)double 型関数は、 imsl_d_beta_inverse_cdfです。

必要な引数

float p ( 入力 )ベータ分布関数の逆が計算される確率。 引数は開区間 (0.0 ,1.0) 内でなけ

ればなりません。

float pin ( 入力 )最初のベータ分布パラメータ。引数 pin は、正でなければなりませ

ん。

float qin ( 入力 )二番目のベータ分布パラメータ。引数 qin は、正でなければなりませ

ん。

戻り値

関数 imsl_f_beta_inverse_cdf は、パラメータ pin と qin を持つベータ確率

変数の逆分布関数を計算します。

説明

P = p、 p = pin、 q = qinとして、次式になるよう関数 imsl_f_beta_inverse_cdf は、 x を返します。

ここで Γ(⋅) は、ガンマ関数です確率変数が、 x 以下の値をとる確率は P です。

例題

X が、パラメータ 12 と 12 を持つベータ確率変数とします。 (X は、対称分布を

持ちます。) X ≤ x が 0.9 になる確率になるような値 x を見つけます。

#include <imsl.h>

main(){ float p, pin, qin, x;

pin = 12.0; qin = 12.0; p = 0.9; x = imsl_f_beta_inverse_cdf(p, pin, qin); printf(" X is less than %6.4f with probability 0.9.\n", x);}

出力結果

X is less than 0.6299 with probability 0.9.

( )( ) ( ) ( ) 11

01

x qpp qP t t dt

p q−−Γ +

= −Γ Γ ∫

Page 521: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

bivariate_normal_cdf二変量正規分布関数を計算します。

概要

#include <imsl.h>

float imsl_f_bivariate_normal_cdf (float x, float y, float rho)double 型関数は、 imsl_d_bivariate_normal_cdfです。

必要な引数

float x ( 入力 )二変量正規分布関数が計算される点の x 座標。

float y ( 入力 )二変量正規分布関数が計算される点の y 座標。

float rho ( 入力 )回帰係数。

戻り値

回帰係数 rho を持つ二変量正規確率変数が、 x 以下で y 以下の値をとる確率。

説明

関数 imsl_f_bivariate_normal_cdf は、ゼロ平均の二変量正規分布、分散が 1、回帰

係数が rhoの分布関数 F を計算します。ρ = rho、 |ρ| < 1 として次式で表されま

す。

(U, V)T が平均 µ = (µU, µV)T と次の分散共分散行列を持つ二変量正規確率変数

のとき、U ≤ u0 で V ≤ v0 の確率を決めるためには (U, V)T を平均ゼロとユニッ

ト分散を持つベクトル変換します。

imsl_f_bivariate_normal_cdf への入力は、 X = (u0 − µU)/σU、 Y = (v0 − µV)/σV、 ρ = σUV/(σUσV) です。

関数 imsl_f_bivariate_normal_cdf は、 Owen の手法 (1962 年、 1965 年 ) を用

いています。 Owen の T 関数の計算は、 M. Patefield と D. Tandy (2000 年 ) による

コードが基になっています。 |ρ| = 1 の場合、分布関数は、二変量統計 Z = min(x,y)、第 11 章「確率分布関数とその逆 .」にある正規分布関数 imsl_f_normal_cdf

を基にして計算されます。

例題

(X, Y) は、平均 (0, 0) と以下の分散共分散行列を持つ二変量正規確率変数とし

ます。

この例題では、 X が −2.0 未満で Y が 0.0 未満になる確率を見つけます。

#include <imsl.h>

2 2

22

1 2( , ) exp2(1 )2 1

yx u uv vF x y du dvρρπ ρ −∞ −∞

− += − −−

∫ ∫

2

2U UV

UV V

σ σσ σ

∑ =

1.0 0.90.9 1.0

Page 522: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

main(){ float p, rho, x, y;

x = -2.0; y = 0.0; rho = 0.9; p = imsl_f_bivariate_normal_cdf(x, y, rho); printf(" The probability that X is less than -2.0" " and Y is less than 0.0 is %6.4f\n", p);

}

出力結果

The probability that X is less than -2.0 and Y is less than 0.0 is 0.0228

cumulative_interest2 期間の間に支払われる累積利息を計算します。

概要

#include <imsl.h>

float imsl_f_cumulative_interest (float rate, int n_periods, float present_value, int start, int end, int when)

double 型関数は、 imsl_d_cumulative_interestです。

必要な引数

float rate ( 入力 )利率。

int n_periods ( 入力 )支払い期間の合計数。n_periods は0以下に設定できません。

float present_value ( 入力 )特定の利率での支払い額を差し引いた後の、将来の支払い額の現在価値。

int start ( 入力 )計算の開始期間。start は 1 未満、または end を超える値には設定

できません。

int end ( 入力 )計算の終了期間。

int when ( 入力 )IMSL_AT_END_OF_PERIOD 又は IMSL_AT_BEGINNING_OF_PERIOD のい

ずれかの支払いを行う各期間の時間。when の詳細は「使用上の注意」

を参照してください。

戻り値

最初の期間と最後の期間の間に支払われる累積利息。結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_cumulative_interest は最初の期間と最後の期間の間に支払わ

れる累積利息を計算します。

以下の式で計算されます。

interestend

ii start=∑

Page 523: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで、interesti は imsl_f_interest_payment で計算された i 番目の期間

の利率を示します。

例題

この例題では imsl_f_cumulative_interest は 年利 7.25% での 200,000 ド

ルの 30 年ローンで最初の年に支払われる合計利息を計算します。この支払い

は各月末に行なわれます。

#include <stdio.h>#include "imsl.h"

void main(){ float rate = 0.0725 / 12; int n_periods = 12 * 30; float present_value = 200000; int start = 1; int end = 12; float total;

total = imsl_f_cumulative_interest (rate, n_periods, present_value, start, end, IMSL_AT_END_OF_PERIOD);

printf ("First year interest = $%.2f.\n", total);}

出力結果

First year interest = $-14436.52.

cumulative_principal2 期間の間に支払われた累積元金を計算します。

概要

#include <imsl.h>

float imsl_f_cumulative_principal (float rate, int n_periods,float present_value, int start, int end, int when)

double 型関数は、 imsl_d_cumulative_principalです。

必要な引数

float rate ( 入力 )利率。

int n_periods ( 入力 )支払い期間の合計数。 n_periods は0以下に設定できません。

float present_value ( 入力 )特定の利率での支払い額を差し引いた後の、将来の支払い額の現在価値。

int start ( 入力 )計算の開始期間。start は 1 未満または end を超える値には設定できま

せん。

int end ( 入力 )計算の終了期間。

int when ( 入力 )IMSL_AT_END_OF_PERIOD 又は IMSL_AT_BEGINNING_OF_PERIOD

Page 524: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

のいずれかの支払いを行う各期間の時間。when の詳細は「使用上の注

意」を参照してください。

戻り値

最初の期間と最後の期間の間に支払われる累積元金。 結果が計算できない場

合、NaN が返されます。

説明

関数 imsl_f_cumulative_principal は最初の期間と最後の期間の間に支払わ

れる累積元金を計算します。

以下の式で計算されます。

principali は i 番目の期間の imsl_f_principal_payment から計算されます。

例題

この例題では、imsl_f_cumulative_principal は 年利 7.25% での 200,000ドルの 30 年ローンで最初の年に支払われる元金合計を計算します。この支払

いは各月末に行なわれます。

#include <stdio.h>#include "imsl.h"

voidmain (){ float rate = 0.0725 / 12; int n_periods = 12 * 30; float present_value = 200000; int start = 1; int end = 12; float total;

total = imsl_f_cumulative_principal (rate, n_periods, present_value, start, end, IMSL_AT_END_OF_PERIOD);

printf ("First year principal = $%.2f.\n", total);}

出力結果

First year principal = $-1935.73.

depreciation_db定率法を使用した資産の減価償却を計算します。

概要

#include <imsl.h>

float imsl_f_depreciation_db (float cost, float salvage, int life, int period, int month)

double 型関数は、 imsl_d_depreciation_dbです。

必要な引数

float cost ( 入力 )資産の初期価額。

float salvage ( 入力 )償却期間終了時の資産価額。

principalend

ii start=∑

Page 525: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int life ( 入力 )資産の減価償却期間数。

int period ( 入力 )償却を計算する期間。period は0以下、または、life +1 を超える値

に設定できません。

int month ( 入力 )初年度の月数。month は 12 を超える値、または 1 未満には設定できま

せん。

戻り値

指定した期間での、定率法を使用した資産の減価償却額。 結果が計算できない

場合、NaN が返されます。

説明

関数 imsl_f_depreciation_db は、指定した期間での、定率法を使用した資

産の減価償却を計算します。下表が示すように、ルーチン imsl_f_depreciation_db は引数 period の指定値によって異なります。

ここで

注意: rate は小数点以下3桁に丸められます。

例題

この例題では、imsl_f_depreciation_db は、取得価額が 2,500ドル、太陽

年数が 3、減価償却期間終了時の価額が 500ドルである資産の減価償却額を計

算します。

#include <stdio.h>#include "imsl.h"

void main(){ float cost = 2500; float salvage = 500; int life = 3; int month = 6; float db; int period;

for (period = 1; period <= life + 1; period++) { db = imsl_f_depreciation_db (cost, salvage, life, period, month); printf ("For period %i, db = $%.2f.\n", period, db); }}

期間 公式period = 1

period = life

period other than 1 or life

monthcost rate12

× ×

( ) 12-monthcost totaldepreciation from periods rate12

− × ×

( )cost totaldepreciation from prior periods rate− ×

1

salvage1cost

liferate

= −

Page 526: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

For period 1, db = $518.75.For period 2, db = $822.22.For period 3, db = $481.00.For period 4, db = $140.69.

depreciation_ddb倍率法を使用して資産の減価償却額を計算します。

概要

#include <imsl.h>

float imsl_f_depreciation_ddb (float cost, float salvage, int life, int period, float factor)

double 型関数は、 imsl_d_depreciation_ddbです。

必要な引数

float cost ( 入力 )資産の初期価額。

float salvage ( 入力 )償却期間終了時の資産価額。

int life ( 入力 )資産の減価償却期間数。

int period ( 入力 )償却を計算する期間。period は life を超える値には設定できませ

ん。

float factor ( 入力 )残高の逓減率。 factor は正でなければならなりません。

戻り値

指定した期間での,倍率法を使用した資産の減価償却額。結果が計算できない場合は、 NaN を返します。

説明

関数 imsl_f_depreciation_ddb は指定された期間での、倍率法を使用した

資産の減価償却額を計算します。

以下の式で計算されます。

例題

この例題では、imsl_f_depreciation_ddb は取得価額が 2,500 ドル、耐用年

数が 24 年、減価償却期間終了後の価額が 500ドルの資産の減価償却費を計算

します。

#include <stdio.h>#include "imsl.h"

void main(){ float cost = 2500; float salvage = 500; float factor = 2; int life = 24; int period;

( )total depreciation from prior periodscost salvage factorlife

Page 527: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float ddb;

for (period = 1; period <= life; period++) { ddb = imsl_f_depreciation_ddb (cost, salvage, life, period, factor); printf ("For period %i, ddb = $%.2f.\n", period, ddb); }}

出力結果

For period 1, ddb = $208.33.For period 2, ddb = $190.97.For period 3, ddb = $175.06.For period 4, ddb = $160.47.For period 5, ddb = $147.10.For period 6, ddb = $134.84.For period 7, ddb = $123.60.For period 8, ddb = $113.30.For period 9, ddb = $103.86.For period 10, ddb = $95.21.For period 11, ddb = $87.27.For period 12, ddb = $80.00.For period 13, ddb = $73.33.For period 14, ddb = $67.22.For period 15, ddb = $61.62.For period 16, ddb = $56.48.For period 17, ddb = $51.78.For period 18, ddb = $47.46.For period 19, ddb = $22.09.For period 20, ddb = $0.00.For period 21, ddb = $0.00.For period 22, ddb = $0.00.For period 23, ddb = $0.00.For period 24, ddb = $0.00.

depreciation_sln定額法を使用して資産の減価償却額を計算します。

概要

#include <imsl.h>

float imsl_f_depreciation_sln (float cost, float salvage, int life)double 型関数は、 imsl_d_depreciation_slnです。

必要な引数

float cost ( 入力 )資産の初期価額。

float salvage ( 入力 )償却期間終了時の資産価額。

int life ( 入力 )資産の減価償却期間数。

戻り値

減価償却期間に応じた,定額法による減価償却額。結果が計算できない場合は、NaN を返します。

説明

関数 imsl_f_depreciation_sln は、減価償却期間に応じた定額法による減

価償却額を計算します。

以下の式で計算されます。

Page 528: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

この例題では、imsl_f_depreciation_sln は、取得価額が 2,500 ドル、耐用

年数が 24 年、減価償却期間終了後の価額が 500ドルの資産の減価償却費を期

間ごとに計算します。

#include <stdio.h>#include "imsl.h"

void main(){ float cost = 2500; float salvage = 500; int life = 24; float depreciation_sln;

depreciation_sln = imsl_f_depreciation_sln (cost, salvage, life); printf ("The straight line depreciation of the asset for one "); printf ("period is $%.2f.\n", depreciation_sln);}

出力結果

The straight line depreciation of the asset for one period is $83.33.

depreciation_syd算術級数法を使用して資産の減価償却費を計算します。

概要

#include <imsl.h>

float imsl_f_depreciation_syd (float cost, float salvage, int life, int period)

double 型関数は、 imsl_d_depreciation_sydです。

必要な引数

float cost ( 入力 )資産の初期価額。

float salvage ( 入力 )償却期間終了時の資産価額。

int life ( 入力 )資産の減価償却期間数。

int period ( 入力 )償却を計算する期間。period は、life を超える値には設定できませ

ん。

戻り値

指定した期間の、算術級数法による減価償却費。 結果が計算できない場合、

NaN が返されます。

説明

関数 imsl_f_depreciation_syd は、指定した期間の、算術級数法による資

産の減価償却額を計算します。

以下の式で計算されます。

(cost-salvage)/life

Page 529: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

この例題では imsl_f_depreciation_syd は取得費用が 2,500 ドル、耐用年

数が 15 年、減価償却期間終了後の価額が 5000 ドルの資産の、14年目の減価

償却額を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ float cost = 25000; float salvage = 5000; int life = 15; int period = 14; float depreciation_syd;

depreciation_syd = imsl_f_depreciation_syd (cost, salvage, life, period); printf ("The depreciation allowance for the 14th year "); printf ("is $%.2f.\n", depreciation_syd);}

出力結果

The depreciation allowance for the 14th year is $333.33.

depreciation_vdb倍率逓減法により指定した期間の資産の減価償却額を計算します。

概要

#include <imsl.h>

float imsl_f_depreciation_vdb (float cost, float salvage, int life, int start, int end, float factor, int sln)

double 型関数は、 imsl_d_depreciation_vdbです。

必要な引数

float cost ( 入力 )資産の初期価額。

float salvage ( 入力 )償却期間終了時の資産価額。

int life ( 入力 )資産の減価償却期間数。

int start ( 入力 )計算の開始期間。start は 1 未満または end を超える値には設定でき

ません。

int end ( 入力 )計算の終了期間。end は life を超える値には設定できません。F

float factor ( 入力 )残高の逓減率。factor は正でなければなりません。

int sln ( 入力 )ゼロの場合は,減価償却額が定率法による額よりも大きい場合でも、定額法に変更しません。

( )( 1)( )( )

2life life

cost salvage period+

Page 530: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

指定した期間(部分的な期間を含む)での、倍率逓減法を使用した資産の減価償却額。結果を計算できない場合は,NaN を返します。

説明

関数 imsl_f_depreciation_vdb は、指定した期間の,倍率逓減法による資

産の減価償却額を評価します。

sln = 0 の場合

sln ≠ 0 の場合

ここで、 ddb i は関数 imsl_f_depreciation_ddb で計算した i 番目の期間の利

率を示します。 k は、定額法による減価償却額が倍率法による減価償却額より

も大きくなる最初の期間です。 .

例題

この例題では、imsl_f_depreciation_vdb は、取得価額が 25,000 ドル、耐

用年数が 15 年、減価償却期間終了後の価額が 5000 ドルである資産の、10 年目と 15 年目の間の減価償却費を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ float cost = 25000; float salvage = 5000; int life = 15; int start = 10; int end = 15; float factor = 2.; int sln = 0; float vdb;

vdb = imsl_f_depreciation_vdb (cost, salvage, life, start, end, factor, sln); printf ("The depreciation allowance between the 10th and 15th "); printf ("year is $%.2f.\n", vdb);}

出力結果

The depreciation allowance between the 10th and 15th year is $976.69.

dollar_decimal分数表記の金額を小数表記に変換します。

概要

#include <imsl.h>

float imsl_f_dollar_decimal (float fractional_dollar, int fraction)

1

end

ii start

ddb= +∑

cost1

end

i k

A salvageAend k=

− −+

− +∑

1

1

k

ii start

A ddb−

= +

= ∑

Page 531: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

double 型関数は、 imsl_d_dollar_decimalです。

必要な引数

float fractional_dollar ( 入力 )分数の整数部分と分子を少数で表した値を加えたドル価。

int fraction ( 入力 )分数表記のドルの分母。fraction は正の値を設定する必要がありま

す。

戻り値

少数表記のドルの金額。ドルの金額は分数表記のドルの整数部と分子を少数で表した値を fraction で割った値になります。結果を計算できない場合は,

NaN を返します。

説明

関数 imsl_f_dollar_decimal は、分数表記のドルの金額を少数表記に変換し

ます。

以下の式で計算されます。

ここで idollar は fractional_dollar の整数部、ifrac は log(fraction) の整数部です。

例題

この例題では , imsl_f_dollar_decimal は $ 1 1/4 を $1.25 に変換します。

#include <stdio.h>#include "imsl.h"

void main(){ float fractional_dollar = 1.1; int fraction = 4; float dollardec;

dollardec = imsl_f_dollar_decimal (fractional_dollar, fraction); printf ("The fractional dollar $1 1/4 = $%.2f.\n", dollardec);}

出力結果

The fractional dollar $1 1/4 = $1.25.

dollar_fraction小数表記の金額を分数表記に変換します。

概要

#include <imsl.h>

float imsl_f_dollar_fraction (float decimal_dollar, int fraction)double 型関数は、 imsl_d_dollar_fractionです。

必要な引数

float decimal_dollar ( 入力 )小数表記のドルの金額。

[ ]( )110 ifrac

idollar fractional_dollar idollarfraction

+

+ − ∗

Page 532: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int fraction ( 入力 )分数表記のドルの分母。fraction は正の値を設定する必要がありま

す。

戻り値

分数表記のドルの金額。分子は、戻り値の小数部になります。 結果が計算でき

ない場合、NaN が返されます。

説明

関数 imsl_f_dollar_fraction は、小数表記のドルの金額を分数表記に変

換します。結果を計算できない場合は,NaN を返します。

以下の式で計算されます。

ここで idollar は decimal_dollar の整数部、ifracc は log(fraction) の整数部です。

例題

この例題では、imsl_f_dollar_fraction は $ 1.25 を $1 1/4 に変換します。

#include <stdio.h>#include "imsl.h"

void main(){ float decimal_dollar = 1.25; int fraction = 4; int numerator; float dollarfrc;

dollarfrc = imsl_f_dollar_fraction (decimal_dollar, fraction); numerator = dollarfrc*10.-((int)dollarfrc)*10; printf ("The decimal dollar $1.25 as a fractional dollar = $%i %i/%i.\n", (int)dollarfrc, numerator, fraction);}

出力結果

The decimal dollar $1.25 as a fractional dollar = $1 1/4.

effective_rate実効年利率を計算します。

概要

#include <imsl.h>

float imsl_f_effective_rate (float nominal_rate, int n_periods)double 型関数は、 imsl_d_effective_rateです。

必要な引数

float nominal_rate ( 入力 )債券の額面上に明記された利率。

int n_periods ( 入力 )年あたりの複利期間数。

戻り値

実効年利率。 結果が計算できない場合、NaN が返されます。

[ ]( )1

_i

10 /ifrac

decimal dollar idollardollar

fraction+

−+

Page 533: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

関数 imsl_f_effective_rate は、特定の定期的複利利率に等しい継続的複利

利率を計算します。名目利率は,債券に記載されている定期的複利利率です。

以下の式で計算されます。

例題

この例題では、 imsl_f_effective_rate は四半期複利で名目利率 6% の実効

年率を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ float nominal_rate = .06; int n_periods = 4; float effective_rate;

effective_rate = imsl_f_effective_rate (nominal_rate, n_periods); printf ("The effective rate of the nominal rate, 6.0%%, "); printf ("compounded quarterly is %.2f%%.\n", effective_rate * 100.);}

出力結果

The effective rate of the nominal rate, 6.0%, compounded quarterly is 6.14%.

future_value投資の将来価値を計算します。

概要

#include <imsl.h>

float imsl_f_future_value (float rate, int n_periods, float payment, float present_value, int when)

double 型関数は、 imsl_d_future_valueです。

必要な引数

float rate ( 入力 )利率。

int n_periods ( 入力 )支払い期間の合計数。

float payment ( 入力 )各期に支払う金額。

float present_value ( 入力 )特定の利率での支払い額を差し引いた後の、将来の支払い額の現在価値。

int when ( 入力 )IMSL_AT_END_OF_PERIOD 又は IMSL_AT_BEGINNING_OF_PERIOD のいずれかの支払いを行う各期間の時間。when の詳細は「使用上の注

意」を参照してください。

戻り値

投資の将来価値。結果が計算できない場合、NaN が返されます。

( )_nominal1 1

_

n periods_rate

n periods

+ −

Page 534: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

関数 imsl_f_future_value は投資の将来価値を計算します。将来価値は、将

来のある時点での,現在の金額及び一連の支払い額の価値です。

以下の式で計算されます。

rate = 0 の場合

rate ≠ 0 の場合

例題

この例題では、imsl_f_future_value は 30,000 ドルの支払いを、年の初め

に、年利 5 % で 20 年間かけて行った場合の価値を計算します。

#include <stdio.h>#include "imsl.h"

voidmain (){ float rate = .05; int n_periods = 20; float payment = -30000.00; float present_value = -30000.00; int when = IMSL_AT_BEGINNING_OF_PERIOD; float future_value;

future_value = imsl_f_future_value (rate, n_periods, payment, present_value, when); printf ("After 20 years, the value of the investments "); printf ("will be $%.2f.\n", future_value);}

出力結果

After 20 years, the value of the investments will be $1121176.63.

future_value_schedule初期元金の将来価値を、複利利率の表を考慮して計算します。

概要

#include <imsl.h>

float imsl_f_future_value_schedule (float principal, int count, float schedule[])

double 型関数は、 imsl_d_future_value_scheduleです。

必要な引数

float principal ( 入力 )元金または現在価値。

int count ( 入力 )schedule の利率の数。

float schedule[] ( 入力 )適用する利率の count の大きさの配列。

( )( ) =0present_value payment n_periods future_value+ +

( )n_periods(1 ) 1n_periods(1 ) 1+

future_value=0

ratepresent_value rate payment rate whenrate

+ −+ +

+

Page 535: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

複利利率の表を適用した後の初期元金の将来価値。結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_future_value_schedule は複利利率の表を適用した後の初期元

金の将来価値を計算します。

以下の式で計算されます。

ここで schedulei 番目の期間の利率です。

例題

この例題では、imsl_f_future_value_schedule は、各年の利率をそれぞれ

5 %、 5.1 %、5.2 %、5.3 % 、5.4 % とした場合の、5 年後の 10,000 ドルの投資の

価値を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ float principal = 10000.0; float schedule[5] = { .050, .051, .052, .053, .054 }; float fvschedule;

fvschedule = imsl_f_future_value_schedule (principal, 5, schedule); printf ("After 5 years the $10,000 investment will have grown "); printf ("to $%.2f.\n", fvschedule);}

出力結果

After 5 years the $10,000 investment will have grown to $12884.77.

interest_payment任意の期間の投資の利息支払いを計算します。

概要

#include <imsl.h>

float imsl_f_interest_payment (float rate, int period, int n_periods, float present_value, float future_value, int when)

double 型関数は、 imsl_d_interest_paymentです。

必要な引数

float rate ( 入力 )利率。

int period ( 入力 )支払い期間。

int n_periods ( 入力 )期間の合計数。

float present_value ( 入力 )特定の利率での支払い額を差し引いた後の、将来の支払い額の現在価値。

( )1

count

ii

principal schedule=

∗∑

Page 536: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float future_value ( 入力 )現在の金額及び一連の支払い額の将来のある時点における価値。

int when ( 入力 )IMSL_AT_END_OF_PERIOD 又は IMSL_AT_BEGINNING_OF_PERIOD のい

ずれかの支払いを行う各期間の時間。when の詳細は「使用上の注意」

を参照してください。

戻り値

任意の期間の投資の支払い利息額。 結果が計算できない場合、NaN が返されま

す。

説明

関数 imsl_f_interest_payment は、与えられた期間の投資の利息支払いを計

算します。

以下の式で計算されます。

例題

この例題では、imsl_f_interest_payment は、 年利 8 %、での 100,000 ドル の 25 年ローンの 2 年目に支払われる利息を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ float rate = .08; int period = 2; int n_periods = 25; float present_value = 100000.00; float future_value = 0.0; int when = IMSL_AT_END_OF_PERIOD; float interest_payment;

interest_payment = imsl_f_interest_payment (rate, period, n_periods, present_value, future_value, when); printf ("The interest due the second year on the $100,000 "); printf ("loan is $%.2f.\n", interest_payment);}

出力結果

The interest due the second year on the $100,000 loan is $-7890.57.

interest_rate_annuity年金の期間あたりの利率を計算します。

概要

#include <imsl.h>

float imsl_f_interest_rate_annuity (int n_periods, float payment, float present_value, float future_value, int when, …, 0)

double 型関数は、 imsl_d_interest_rate_annuityです。

必要な引数

int n_periods ( 入力 )期間の合計数。

( ) ( ) ( )_ 1

_ 1 1_ 1 1 *

n periods

n periods ratepresent value rate payment rate when rate

rate

− + + + +

Page 537: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float payment ( 入力 )各期間の支払い額。

float present_value ( 入力 )特定の利率での支払い額を差し引いた後の、将来の支払い額の現在価値。

float future_value ( 入力 )現在の金額及び一連の支払い額の将来のある時点における価値。

int when ( 入力 )IMSL_AT_END_OF_PERIOD 又は IMSL_AT_BEGINNING_OF_PERIOD のい

ずれかの支払いを行う各期間の時間。when の詳細は「使用上の注意」

を参照してください。

戻り値

年金の期間あたりの利率。 結果が計算できない場合、NaN が返されます。

オプション引数の概要

#include <imsl.h>

float imsl_f_interest_rate_annuity (int n_periods, float payment, float present_value, float future_value, int when, IMSL_XGUESS, float guess, IMSL_HIGHEST, float max, 0)

オプション引数

IMSL_XGUESS, float guess ( 入力 )利率の初期推測値。

IMSL_HIGHEST, float max ( 入力 )最大許容利率。デフォルト: 1.0 (100%)

説明

関数 imsl_f_interest_rate_annuity は年金の期間あたりの利率を計算しま

す。. 年金は等間隔で固定金額を支払う保証です。

以下の式で計算されます。

rate = 0 の場合

rate ≠ 0 の場合

例題

この例題では、imsl_f_interest_rate_annuity は、完済するのに 350 ドル

の支払いを 70 回行う必要のある 20,000 ドルのローンの利率を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ float rate; int n_periods = 70; float payment = -350.; float present_value = 20000; float future_value = 0.;

( )( ) =0present_value payment n_periods future_value+ +

( )n_periods(1 ) 1n_periods(1 ) 1+

future_value=0

ratepresent_value rate payment rate whenrate

+ −+ +

+

Page 538: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int when = IMSL_AT_BEGINNING_OF_PERIOD;

rate = imsl_f_interest_rate_annuity (n_periods, payment, present_value, future_value, when, 0) * 12; printf ("The computed interest rate on the loan is "); printf ("%.2f%%.\n", rate * 100.);}

出力結果

The computed interest rate on the loan is 7.35%.

internal_rate_of_returnキャッシュフロー表の内部収益率を計算します。

概要

#include <imsl.h>

float imsl_f_internal_rate_of_return (int count, float values[], …, 0)double 型関数は、 imsl_d_internal_rate_of_returnです。

必要な引数

int count ( 入力 )values の中のキャッシュフローの数。count は 1 以上に設定する必

要があります。

float values[] ( 入力 )定期的に発生し、初期投資を含みャッシュフローを示す countの大き

さの配列。

戻り値

キャッシュフロー表の内部収益率。 結果が計算できない場合、NaN が返されま

す。

オプション引数の概要

#include <imsl.h>

float imsl_f_internal_rate_of_rtn (int count, float values[], IMSL_XGUESS, float guess, 0)

オプション引数

IMSL_XGUESS, float guess ( 入力 )内部収益率の初期推測値。

IMSL_HIGHEST, float max ( 入力 )最大許容内部収益率。デフォルト: 1.0 (100%).

説明

関数 imsl_f_internal_rate_of_return は、キャッシュフロー表の内部収益

率を計算します。内部収益率は、一連の支払い純現在価値がゼロになる利率です。

関数 imsl_f_internal_rate_of_return は、キャッシュフローの一覧の

内部収益率を計算します。内部収益率は、一連の支払い純現在価値がゼロになる利率です。次の式で計算されます。

ここで valuei = i 番目のキャッシュフロー、 rate は内部収益率です。

( )1

01

counti

ii

valuerate=

=+

Page 539: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

この例題では、imsl_f_internal_rate_of_return は、初期投資が 4,500 ド

ルの、-800 ドル、800 ドル、800 ドル、600 ドル、600 ドル、800 ドル、800 ド

ル、700 ドル、3,000 ドルの 9 つのキャッシュフローの内部収益率を計算しま

す。

#include <stdio.h>#include "imsl.h"

void main(){ float values[] = { -4500., -800., 800., 800., 600., 600., 800., 800., 700., 3000. }; float internal_rate;

internal_rate = imsl_f_internal_rate_of_return (10, values, 0); printf ("After 9 years, the internal rate of return on the "); printf ("cows is %.2f%%.\n", internal_rate * 100.);}

出力結果

After 9 years, the internal rate of return on the cows is 7.21%.

internal_rate_scheduleキャッシュフロー表の内部収益率を計算します。キャッシュフローが周期的である必要はありません。

概要

#include <imsl.h>

float imsl_f_internal_rate_schedule (int count, float values[], struct tm dates[], …, 0)

double 型関数は、 imsl_d_internal_rate_scheduleです。

必要な引数

int count ( 入力 )values の中のキャッシュフローの数。count は 1 以上に設定する必要

があります。

float values[] ( 入力 )初期投資を含みキャッシュフローを示す、サイズ countの配列。

struct tm dates[] ( 入力 )キャッシュフローが発生する日付を示す、サイズ count の配列。「使

用上の注意」を参照してください。

戻り値

キャッシュフロー表の内部収益率。キャッシュフローが定期的に発生する必要はありません。 結果が計算できない場合、NaN が返されます。

オプション引数の概要

#include <imsl.h>

float imsl_f_internal_rate_schedule (int count, float values[], struct tm dates[], IMSL_XGUESS, float guess, IMSL_HIGHEST, float max, 0)

オプション引数

IMSL_XGUESS, float guess ( 入力 )内部収益率の初期推測値。

Page 540: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_HIGHEST, float max ( 入力 )最大許容内部収益率。デフォルト: 1.0 (100%)

説明

関数 imsl_f_internal_rate_schedule は、キャッシュフロー表の内部収益

率を計算します。キャッシュフローが定期的に発生する必要はありません。内部収益率は,一連の支払いの純現在価値がゼロになる利率です。

以下の式で計算されます。

上の式で、di は i 番目の支払い日を示します。 d1 は 最初の支払い日を示しま

す。 valuei は i 番目のキャッシュフローを示します。rate は内部収益率を示しま

す。

例題

この例題では、imsl_f_internal_rate_schedule は初期投資が 4,500 ドル

の、-800 ドル、800 ドル、800 ドル、600 ドル、600 ドル、800 ドル、800 ドル、

700 ドル、3,000 ドルの 9 つのキャッシュフローの内部収益率を計算します。この

#include <stdio.h>#include "imsl.h"

void main(){ float values[10] = { -4500., -800., 800., 800., 600., 600., 800., 800., 700., 3000. }; struct tm dates[10]; float xirr;

dates[0].tm_year = 98; dates[0].tm_mon = 0; dates[0].tm_mday = 1; dates[1].tm_year = 98; dates[1].tm_mon = 9; dates[1].tm_mday = 1; dates[2].tm_year = 99; dates[2].tm_mon = 4; dates[2].tm_mday = 5; dates[3].tm_year = 100; dates[3].tm_mon = 4; dates[3].tm_mday = 5; dates[4].tm_year = 101; dates[4].tm_mon = 5; dates[4].tm_mday = 1; dates[5].tm_year = 102; dates[5].tm_mon = 6; dates[5].tm_mday = 1; dates[6].tm_year = 103; dates[6].tm_mon = 7; dates[6].tm_mday = 30; dates[7].tm_year = 104; dates[7].tm_mon = 8; dates[7].tm_mday = 15; dates[8].tm_year = 105; dates[8].tm_mon = 9; dates[8].tm_mday = 15; dates[9].tm_year = 106; dates[9].tm_mon = 10; dates[9].tm_mday = 1;

xirr = imsl_f_internal_rate_schedule (10, values, dates, 0); printf ("After approximately 9 years, the internal\n"); printf ("rate of return on the cows is %.2f%%.\n", xirr * 100.);}

出力結果

After approximately 9 years, the internalrate of return on the cows is 7.69%.

modified_internal_rate定期的なキャッシュフロー表の修正内部収益率を計算します。

概要

#include <imsl.h>

float imsl_f_modified_internal_rate (int count, float values[], float finance_rate, float reinvest_rate)

( )1

1 365

01

i

countid d

i

value

rate−

=

=+

Page 541: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

double 型関数は、 imsl_d_modified_internal_rateです。

必要な引数

int count ( 入力 )values の中のキャッシュフローの数。count は 1 以上を設定する必

要があります。

float values[] ( 入力 )サイズ countのキャッシュフローの配列。

float finance_rate ( 入力 )借入金に対して支払う利息。

float reinvest_rate ( 入力 )キャッシュフローに対して受け取る利息。

戻り値

定期的なキャッシュフロー表の修正内部収益率。 結果が計算できない場合、

NaN が返されます。

説明

関数 imsl_f_modified_internal_rate は、定期的なキャッシュフロー表の

修正内部収益率を計算します。修正内部収益率は、通常の内部収益率と異なり、キャッシュフローが内部収益率ではなく元金で再投資されることを前提としています。

また、複数の収益率の問題も解消されます。

以下の式で計算されます。

ここで pnpv は reinvest_rate を使用する values の正の値に対して

imsl_f_net_present_value で計算します。nnpv は finance_rate を使用す

る values の負の値に対して imsl_f_net_present_value で計算します。

例題

この例題では、imsl_f_modified_internal_rate は、初期投資が 4,500 ド

ルで 9 年間のキャッシュフロー、-800 ドル、800 ドル、800 ドル、600 ドル、

600 ドル、800 ドル、800 ドル、700 ドル、3,000 ドルの修正内部収益率を計算し

ます。

#include <stdio.h>#include "imsl.h"

void main(){ float value[] = { -4500., -800., 800., 800., 600., 600., 800., 800., 700., 3000. }; float finance_rate = .08; float reinvest_rate = .055; float mirr;

mirr = imsl_f_modified_internal_rate (10, value, finance_rate, reinvest_rate); printf ("After 9 years, the modified internal rate of return "); printf ("on the cows is %.2f%%.\n", mirr * 100.);}

出力結果

After 9 years, the modified internal rate of return on the cows is 6.66%.

( )( )( )( )

1_ _ 1pnpv 1 reinvest_rate

11 finance_rate

n periods n periods

nnpv

− + −

+

Page 542: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

net_present_value一連の均等でない定期的キャッシュフローの純現在価値を計算します。この値は,割引率によって変化します。

概要

#include <imsl.h>

float imsl_f_net_present_value (float rate, int count, float values[])double 型関数は、 imsl_d_net_present_valueです。

必要な引数

float rate ( 入力 )期間あたりの利率。

int count ( 入力 )values の中のキャッシュフローの数。

float values[] ( 入力 )等間隔のキャッシュフローを示す count の大きさの配列。

戻り値

投資の純現在価値。 結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_net_present_value は、投資の純現在価値を計算します。純現

在価値は、特定の利率での支払い額を差し引いた後の,一連の支払いの現在価値です。

次の式で計算されます。

ここで, valuei は i 番目のキャッシュフローです。

例題

この例題では、imsl_f_net_present_value は、10,000,000 ドルの賞金を、

年利 6%で 20 年間支払われる(1年あたり 50,000 ドル)場合の純現在価値を

計算します。

#include <stdio.h>#include "imsl.h"

void main(){ float rate = 0.06; int count = 20; float value[20]; float net_present_value; int i;

for (i = 0; i < count; i++) value[i] = 500000.;

net_present_value = imsl_f_net_present_value (rate, count, value);

printf ("The net present value of the $10 million prize is $%.2f.\n", net_present_value);}

( )1 1

counti

ii

valuerate= +

Page 543: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

The net present value of the $10 million prize is $5734963.00.

nominal_rate名目年利率を計算します。

概要

#include <imsl.h>

float imsl_f_nominal_rate (float effective_rate, int n_periods)double 型関数は、 imsl_d_nominal_rateです。

必要な引数

float effective_rate ( 入力 )利息をローン終了時に一括で支払う場合の利率。

int n_periods ( 入力 )年あたりの複利期間数。

戻り値

名目年利率。 結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_nominal_rate は、名目年利率を計算します。この名目年利率と

は債券の額面に記載された利率です。

以下の式で計算されます。

例題

この例題では、imsl_f_nominal_rate は、四半期複利で実効利率が 6.14% の名目年利率を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ double effective_rate = .0614; int n_periods = 4; double nominal_rate;

nominal_rate = imsl_d_nominal_rate (effective_rate, n_periods); printf ("The nominal rate of the effective rate, 6.14%%, \n"); printf ("compounded quarterly is %.2f%%.\n", nominal_rate * 100.);}

出力結果

The nominal rate of the effective rate, 6.14%, compounded quarterly is 6.00%.

number_of_periods定期的な定額の支払いかつ利率が一定である投資の期間数を計算します。

概要

#include <imsl.h>

( )1

1 effective _ rate 1 *n_periodsn_periods

+ −

Page 544: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float imsl_f_number_of_periods (float rate, float payment, float present_value, float future_value, int when)

double 型関数は、 imsl_d_number_of_periodsです。

必要な引数

float rate ( 入力 )投資の利率。

float payment ( 入力 )投資の支払い額。

float present_value ( 入力 )特定の利率での支払い額を差し引いた後の、将来の支払い額の現在価値。

float future_value ( 入力 )現在の金額及び一連の支払い額の将来のある時点における価値。

int when ( 入力 )IMSL_AT_END_OF_PERIOD 又は IMSL_AT_BEGINNING_OF_PERIOD のいずれかの支払いを行う各期間の時間。when の詳細は「使用上の注

意」を参照してください。

戻り値

投資の期間数。

説明

関数 imsl_f_number_of_periods は定期的で一定支払いかつ利率が一定で投

資を行うために要する期間数を計算します。

以下の式で計算されます。

rate = 0 の場合

rate ≠ 0 の場合

例題

この例題では、imsl_f_number_of_periods は、年利 7.25% の 20,000 ドルの

ローンで、毎月 350 ドル支払った場合に、完済に必要な期間数を計算します。

支払いは,各期間の最初に行われます。

#include <stdio.h>#include "imsl.h"

void main(){ float rate = 0.0725 / 12; float payment = -350.; float present_value = 20000; float future_value = 0.; int when = IMSL_AT_BEGINNING_OF_PERIOD; float number_of_periods;

number_of_periods = imsl_f_number_of_periods (rate, payment, present_value, future_value, when);

printf ("Number of payment periods = %f.\n", number_of_periods);

( )( ) =0present_value payment n_periods future_value+ +

( )n_periods(1 ) 1n_periods(1 ) 1+

future_value=0

ratepresent_value rate payment rate whenrate

+ −+ +

+

Page 545: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

}

出力結果

Number of payment periods = 70.

payment投資の定期的な支払い額を計算します。

概要

#include <imsl.h>

float imsl_f_payment (float rate, int n_periods, float present_value, float future_value, int when)

double 型関数は、 imsl_d_paymentです。

必要な引数

float rate ( 入力 )利率。

int n_periods ( 入力 )期間の合計数。

float present_value ( 入力 )特定の利率での支払い額を差し引いた後の、将来の支払い額の現在価値。

float future_value ( 入力 )現在の金額及び一連の支払い額の将来のある時点における価値。

int when ( 入力 )IMSL_AT_END_OF_PERIOD 又は IMSL_AT_BEGINNING_OF_PERIOD のい

ずれかの支払いを行う各期間の時間。when の詳細は「使用上の注意」

を参照してください。

戻り値

投資のための定期的な支払い額。結果が計算できない場合、NaN が返されま

す。

説明

関数 imsl_f_payment は投資のための定期的な支払い額を計算します。

以下の式で計算されます。

rate = 0 の場合

rate ≠ 0 の場合

例題

この例題では、imsl_f_payment は、年利 8% で 100,000 ドルの 25 年ローン

の定期的な支払い額を計算します。支払いは、各期間の最後に行います。

#include <stdio.h>#include "imsl.h"

void main(){

( )( ) =0present_value payment n_periods future_value+ +

( )n_periods(1 ) 1n_periods(1 ) 1+

future_value=0

ratepresent_value rate payment rate whenrate

+ −+ +

+

Page 546: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float rate = .08; int n_periods = 25; float present_value = 100000.00; float future_value = 0.0; int when = IMSL_AT_END_OF_PERIOD; float payment;

payment = imsl_f_payment (rate, n_periods, present_value, future_value, when); printf ("The payment due each year on the $100,000 "); printf ("loan is $%.2f.\n", payment);}

出力結果

The payment due each year on the $100,000 loan is $-9367.88.

present_value一連の均等で定期的なキャッシュフローの純現在価値を計算します。この値は、割引率によって変化します。

概要

#include <imsl.h>

float imsl_f_present_value (float rate, int n_periods, float payment, float future_value, int when)

double 型関数は、 imsl_d_present_value です。

必要な引数

float rate ( 入力 )利率。

int n_periods ( 入力 )期間の合計数。

float payment ( 入力 )各期に支払う金額。

float future_value ( 入力 )現在の金額及び一連の支払い額の将来のある時点における価値。

int when ( 入力 )IMSL_AT_END_OF_PERIOD 又は IMSL_AT_BEGINNING_OF_PERIOD のいずれかの支払いを行う各期間の時間。when の詳細は「使用上の注

意」を参照してください。

戻り値

投資の現在価値。結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_present_value は投資の現在価値を計算します。

以下の式で計算されます。

rate = 0 の場合

rate ≠ 0 の場合

( )( ) =0present_value payment n_periods future_value+ +

( )n_periods(1 ) 1n_periods(1 ) 1+

future_value=0

ratepresent_value rate payment rate whenrate

+ −+ +

+

Page 547: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

この例題では、imsl_f_present_value は、年利 6% で 500,000 ドルの支払

いを 20 回(10,000,000 ドル)行う場合の現在価値を計算します。支払いは、

各期間の最後に行います。

#include <stdio.h>#include "imsl.h"

void main(){ float rate = 0.06; float payment = 500000.; float future_value = 0.; int n_periods = 20; int when = IMSL_AT_END_OF_PERIOD; float present_value;

present_value = imsl_f_present_value (rate, n_periods, payment, future_value, when);

printf ("The present value of the $10 million prize is "); printf ("$%.2f.\n", present_value);}

出力結果 The present value of the $10 million prize is $-5734961.00.

present_value_scheduleキャッシュフロー表の現在価値を計算します。キャッシュフローが定期的である必要はありません。

概要

#include <imsl.h>

float imsl_f_present_value_schedule (float rate, int count, float values[], struct tm dates[])

double 型関数は、 imsl_d_present_value_schedule です。

必要な引数

float rate ( 入力 )利率。

int count ( 入力 )values のキャッシュフローの数、或いは、dates の日付の数。

float values[] ( 入力 )キャッシュフローを示す count の大きさの配列。

struct tm dates[] ( 入力 )キャッシュフローが発生する日付を示す count の大きさの配列。こ

れの詳細は「使用上の注意」の dates を参照してください。

戻り値

キャッシュフロー表の現在価値。結果が計算できない場合、NaN が返されま

す。

説明

関数 imsl_f_present_value_schedule は、キャッシュフローの一覧の現在

価値を計算します。キャッシュフローが定期である必要はありません。

以下の式で計算されます。

Page 548: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

上の式において、di は i 番目の支払い日、d1 は最初の支払い日、valuei は i 番目のキャッシュフローを表しています。

例題

この例題では imsl_f_present_value_schedule は、年利 5% で、1,000 ド

ル、2,000 ドル、そして 1,000 ドルの 3 回の支払いを 1997 年 1 月 3 日、1999 年

1 月 3 日、2000 年 1 月 3 日に行う場合の現在価値を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ float rate = 0.05; float values[3] = { 1000.0, 2000.0, 1000.0 }; struct tm dates[3]; float xnpv;

dates[0].tm_year = 97; dates[0].tm_mon = 0; dates[0].tm_mday = 3; dates[1].tm_year = 99; dates[1].tm_mon = 0; dates[1].tm_mday = 3; dates[2].tm_year = 100; dates[2].tm_mon = 0; dates[2].tm_mday = 3;

xnpv = imsl_f_present_value_schedule (rate, 3, values, dates); printf ("The present value of the cash flows is $%.2f.\n", xnpv);}

出力結果 The present value of the cash flows is $3677.90.

principal_payment指定した期間の元金の支払い額を計算します。

概要

#include <imsl.h>

float imsl_f_principal_payment (float rate, int period, int n_periods, float present_value, float future_value, int when)

double 型関数は、 imsl_d_principal_paymentです。

必要な引数

float rate ( 入力 )利率。

int period ( 入力 )支払い期間。

int n_periods ( 入力 )期間の合計数。

float present_value ( 入力 )特定の利率での支払い額を差し引いた後の、将来の支払い額の現在価値。

float future_value ( 入力 )現在の金額及び一連の支払い額の将来のある時点における価値。

int when ( 入力 )IMSL_AT_END_OF_PERIOD 又は IMSL_AT_BEGINNING_OF_PERIOD のい

( )( )1 / 3651 1 i

counti

d di

value

rate −= +∑

Page 549: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ずれかの支払いを行う各期間の時間。when の詳細は「使用上の注意」

を参照してください。

戻り値

指定した期間の元金の支払い額。 結果が計算できない場合、NaN が返されま

す。

説明

関数 imsl_f_principal_payment は、指定した期間の元金支払い額を計算し

ます。

以下の式で計算されます。

ここで paymenti は、imsl_f_payment で計算される i 番目の期間の値、

interesti は imsl_f_interest_payment で計算される i 番目の期間の値です。

例題

この例題では、imsl_f_principal_payment は、年利 8% で、100,000 ドルの

30 年ローンの 1 年目に支払われる元金を計算します。この支払いは、毎年の終

わりに行います。

#include <stdio.h>#include "imsl.h"

void main(){ float rate = .08; int period = 1; int n_periods = 30; float present_value = 100000.00; float future_value = 0.0; int when = IMSL_AT_END_OF_PERIOD; float principal;

principal = imsl_f_principal_payment (rate, period, n_periods, present_value, future_value, when); printf ("The payment on the principal for the first year of \n"); printf ("the $100,000 loan is $%.2f.\n", principal);}

出力結果

The payment on the principal for the first year ofthe $100,000 loan is $-882.74.

accr_interest_maturity満期時に利息を支払う債券の累積利息を計算します。

概要

#include <imsl.h>

float imsl_f_accr_interest_maturity (struct tm issue, struct tm maturity, float coupon_rate, float par_value, int basis)

double 型関数は、 imsl_d_accr_interest_maturityです。

必要な引数

struct tm issue ( 入力 )利息が付き始める日付。日付(dates)の詳細な説明は、「使用上の注

意」を参照してください。

i ipayment interest−

Page 550: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

float coupon_rate ( 入力 )債券に記載されている年利;表面利率。

float par_value ( 入力 )利息支払いを計算するために使用される債券の名目または額面価値。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360. の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

満期時に利息を支払う債券の累積利息。 結果が計算できない場合、NaN が返さ

れます。

説明

関数 imsl_f_accr_interest_maturity は、満期時に利息を支払う債券の累

積利息を計算します。

上の式では、A は発行日から数えた満期日までの日数、D は 1 年の日数です。

例題

この例題では imsl_f_accr_interest_maturity は、満期時に利息を支払う

債券の累積利息を、US (NASD) 30/360 日数法を使用して計算します。この債

券は、額面価格が 1,000 ドル、発行日が 2000 年 10 月1日、満期日が 2000 年

11 月 3 日、表面利率が 6 % です。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm issue, maturity; float rate = .06; float par = 1000.; int basis = IMSL_DAY_CNT_BASIS_NASD; float accrintm;

issue.tm_year = 100; issue.tm_mon = 9; issue.tm_mday = 1;

maturity.tm_year = 100; maturity.tm_mon = 10; maturity.tm_mday = 3;

accrintm = imsl_f_accr_interest_maturity (issue, maturity, rate, par, basis);

printf ("The accrued interest is $%.2f.\n", accrintm);}

出力結果

The accrued interest is $5.33.

( )( )_ Apar value rateD

=

Page 551: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

accr_interest_periodic定期的に利息を支払う債券の累積利息を計算します。

概要

#include <imsl.h>

float imsl_f_accr_interest_periodic (struct tm issue, struct tm first_coupon, struct tm settlement, float coupon_rate, float par_value, int frequency, int basis)

double 型関数は、 imsl_d_accr_interest_periodicです。

必要な引数

struct tm issue ( 入力 )利息が付き始める日付。日付(dates)の詳細な説明は、「使用上の注

意」を参照してください。

struct tm first_coupon ( 入力 )債券の利息の最初の支払日(クーポン期日)。日付(dates)の詳細な

説明は、「使用上の注意」を参照してください。

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

float coupon_rate ( 入力 )債券に記載されている年利。表面利率。

float par_value ( 入力 )利息支払いを計算するために使用される債券の名目または額面価値。

int frequency ( 入力 )利息支払いの頻度。IMSL_ANNUAL、IMSL_SEMIANNUAL、IMSL_QUARTERLY のいずれか1つである必要があります。頻度

(frequency)の詳細は「使用上の注意」を参照してください。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、 IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365, or IMSL_DAY_CNT_BASIS_30E360のいずれか 1 つである必要がありま

す。詳細な説明は、「使用上の注意」を参照してください。

戻り値

定期的に利息を支払う債券の累積利息。結果が計算できない場合、NaN が返

されます。

説明

関数 imsl_f_accr_interest_periodic は、定期的に利息を支払う債券の累

積利息を計算します。

次の式では、Ai は臨時期間内で i 番目の準クーポン期間までの累積日数を表し

ます。準クーポン期間は、均等な支払い期間を実際の支払い期間の前後に短縮または順延することで取得する期間です。NC は、臨時期間内の準クーポン期

間数を、次の最大整数で丸めた値です。臨時期間は,支払いが行われる通常の等間隔の期間とは異なる、支払い期間の間の期間です。NLi は臨時期間内の通

常の i 番目の準クーポン期間の長さを表します。NLI は日数で表します。

関数 imsl_f_accr_interest_periodic は、以下の式で計算されます。

( )1

_NC

i

i i

Aratepar valuefrequency NL=

Page 552: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

この例題では imsl_f_accr_interest_periodic は、定期的に利息を支

払う債券の累積利息を, US (NASD) 30/360 日数法を使用して計算します。こ

の債券は 額面価格が 1,000 ドル、発行日が 1999 年 10 月1日、決済日が 1999年 11 月 3 日、最初のクーポン期日が 2000 年 3 月 31 日、表面利率が 6 % です。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm issue, first_coupon, settlement; float rate = .06; float par = 1000.; int frequency = IMSL_SEMIANNUAL; int basis = IMSL_DAY_CNT_BASIS_NASD; float accrint;

issue.tm_year = 99; issue.tm_mon = 9; issue.tm_mday = 1;

first_coupon.tm_year = 100; first_coupon.tm_mon = 2; first_coupon.tm_mday = 31;

settlement.tm_year = 99; settlement.tm_mon = 10; settlement.tm_mday = 3;

accrint = imsl_f_accr_interest_periodic (issue, first_coupon, settlement, rate, par, frequency, basis);

printf ("The accrued interest is $%.2f.\n", accrint);}

出力結果

The accrued interest is $5.33.

bond_equivalent_yield米国財務省短期債券の債券換算の利回りを計算します。

概要

#include <imsl.h>

float imsl_f_bond_equivalent_yield (struct tm settlement, struct tm maturity, float discount_rate)

double 型関数は、 imsl_d_bond_equivalent_yieldです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

float discount_rate ( 入力 )利息支払いの代わりに、満期時の価値よりも低い価値で債券を売却した場合の利率。

Page 553: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

米国財務省短期債券の債券換算の利回り。結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_bond_equivalent_yield は、米国財務省短期債券の債券換算の

利回りを計算します。

以下の式で計算されます。

その他

上の式では、 DSM は決済日から満期日までの日数を表しています。

例題

この例題では imsl_f_bond_equivalent_yieldは、決済日が 1999 年7月 1日、満期日が 2000 年 7 月 1 日、発行日での割引率が 5% の米国財務省短期債

券の等価利回りを計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float discount = .05; float yield;

settlement.tm_year = 99; settlement.tm_mon = 6; settlement.tm_mday = 1;

maturity.tm_year = 100; maturity.tm_mon = 6; maturity.tm_mday = 1;

yield = imsl_f_bond_equivalent_yield (settlement, maturity, discount); printf ("The bond-equivalent yield for the T-bill is %.2f%%.\n", yield * 100.);}

出力結果

The bond-equivalent yield for the T-bill is 5.29%.

convexity債券のコンベクシティを計算します。

概要

#include <imsl.h>

182if DSM <=

365 _360 _

discount ratediscount rate DSM

∗− ∗

2 _2 1365 365 365 _ 360

0.5365

DSM DSM DSM discount rate DSMdiscount rate DSM

DSM

∗ − + − ∗ − ∗ ∗ −

Page 554: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float imsl_f_convexity (struct tm settlement, struct tm maturity, float coupon_rate, float yield, int frequency, int basis)

double 型関数は、 imsl_d_convexityです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。 日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

float coupon_rate ( 入力 )債券に記載されている年利。表面利率。

float yield ( 入力 )債券の年利回り。

int frequency ( 入力 )利息支払いの頻度。 IMSL_ANNUAL、 IMSL_SEMIANNUAL、 IMSL_QUARTERLYのいずれか1つを指定します。 頻度(frequency)の詳

細は「使用上の注意」を参照してください。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、 IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360のいずれか1つである必要があります。

詳細な説明は、「使用上の注意」を参照してください。

戻り値

債券のコンベクシティ。結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_convexity は債券のコンベクシティを計算します。コンベクシ

ティとは、利回りの変化に対する債券のデュレーションの感度です。

以下の式で計算されます。

この n は imsl_coupon_numberと次の式から計算します。 .

例題

この例題では imsl_f_convexity は、 Actual/365 日数法を使用して 決済日が

1990年7月1日、満期日が2000年7月1日の債券のコンベクシティを計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float coupon = .075; float yield = .09; int frequency = IMSL_SEMIANNUAL;

( )( ) ( )2

1

1

1 1 1n

t n

t

nt n

t

ratet t q n n qfrequencyq frequency

rate q qfrequency

− −

=

− −

=

+ + +

+

1 yieldqfrequency

= +

Page 555: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int basis = IMSL_DAY_CNT_BASIS_ACTUAL365; float convexity;

settlement.tm_year = 90; settlement.tm_mon = 6; settlement.tm_mday = 1;

maturity.tm_year = 100; maturity.tm_mon = 6; maturity.tm_mday = 1;

convexity = imsl_f_convexity (settlement, maturity, coupon, yield, frequency, basis);

printf ("The convexity of the bond with "); printf ("semiannual interest payments is %.4f.\n", convexity);}

出力結果

The convexity of the bond with semiannual interest payments is 59.4050.

coupon_days決済日を含むクーポン期間の日数を計算します。

概要

#include <imsl.h>

float imsl_f_coupon_days (struct tm settlement, struct tm maturity, int frequency, int basis)

double 型関数は、 imsl_d_coupon_daysです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

int frequency ( 入力 )利息支払いの頻度。IMSL_ANNUAL、IMSL_SEMIANNUAL、IMSL_QUARTERLY のいずれか1つである必要があります。頻度

(frequency)の詳細は「使用上の注意」を参照してください。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、 IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360のいずれか1つである必要があります。

basis の詳細な説明は、「使用上の注意」を参照してください。

戻り値

決済日を含むクーポン期間の日数。 結果が計算できない場合、NaN が返されま

す。

説明

関数 imsl_f_coupon_days は決済日を含むクーポン期間の日数を計算します。

日数のカウント基準(basis)の完全な説明は SIA Standard Securities Calculation Methods 1993, vol. 1, 17-35 ページ を参照してください。

Page 556: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

この例題では imsl_f_coupon_days は Actual/365 は日数法を使用して、決済

日が 1996 年 11 月 11 日、満期日が 2009 年 3 月 1 日である債券のクーポン期間

の日数を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; int frequency = IMSL_SEMIANNUAL; int basis = IMSL_DAY_CNT_BASIS_ACTUAL365; float coupdays;

settlement.tm_year = 96; settlement.tm_mon = 10; settlement.tm_mday = 11;

maturity.tm_year = 109; maturity.tm_mon = 2; maturity.tm_mday = 1;

coupdays = imsl_f_coupon_days (settlement, maturity, frequency, basis); printf ("The number of days in the coupon period that\n"); printf ("contains the settlement date is %.2f.\n", coupdays);}

出力結果

The number of days in the coupon period thatcontains the settlement date is 182.50.

coupon_number決済日と満期日の間の支払われるクーポン数を計算します。

概要

#include <imsl.h>

int imsl_coupon_number (struct tm settlement, struct tm maturity, int frequency, int basis)

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。 日付(dates)の詳細な説明は、

「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

int frequency ( 入力 )利息支払いの頻度。IMSL_ANNUAL、IMSL_SEMIANNUAL、IMSL_QUARTERLY のいずれか1つである必要があります。頻度

(frequency)の詳細は「使用上の注意」を参照してください。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、 IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360のいずれか1つである必要があります。

basis の詳細な説明は、「使用上の注意」を参照してください。

Page 557: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

決済日と満期日の間の支払われるクーポン数。

説明

関数 imsl_coupon_number は決済日と満期日の間の支払われるクーポン数を

計算します。日数のカウント基準(basis)の説明は SIA Standard Securities Calculation Methods 1993, vol. 1, 17-35 ページ を参照してください。

例題

この例題では imsl_coupon_number は、 Actual/365 日数法を使用して、決済

日が 1996 年 11 月 11 日、満期日が 2009 年 3 月 1 日の支払われるべきクーポン

数を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; int frequency = IMSL_SEMIANNUAL; int basis = IMSL_DAY_CNT_BASIS_ACTUAL365; int coupnum; settlement.tm_year = 96; settlement.tm_mon = 10; settlement.tm_mday = 11;

maturity.tm_year = 109; maturity.tm_mon = 2; maturity.tm_mday = 1;

coupnum = imsl_coupon_number (settlement, maturity, frequency, basis); printf ("The number of coupons payable between the\n"); printf ("settlement date and the maturity date is %d.\n", coupnum);}

出力結果

The number of coupons payable between thesettlement date and the maturity date is 25.

days_before_settlementクーポン期間の最初の日から決済日までの日数を計算します。

概要

#include <imsl.h>

int imsl_days_before_settlement (struct tm settlement, struct tm maturity, int frequency, int basis)

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

int frequency ( 入力 )利息支払いの頻度。 IMSL_ANNUAL、 IMSL_SEMIANNUAL、IMSL_QUARTERLYのいずれか 1 つである必要があります。 頻度(frequency)の詳細は「使用上の注意」を参照してください。

Page 558: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int basis ( 入力 )2つの日付間の日数を計算する方法。この方法は、 IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360のいずれか 1 つである必要があります。

basis の詳細な説明は、「使用上の注意」を参照してください。

戻り値

クーポン期間の最初の日から決済日までの日数。

説明

関数 imsl_days_before_settlement は、クーポン期間の最初の日から決済

日までの日数を計算します。日数のカウント基準(basis)の完全な説明は SIA Standard Securities Calculation Methods 1993, vol. 1, 17-35 ページを参照してく

ださい。

例題

この例題では imsl_days_before_settlement は Actual/365 日数法を使用し

て、満期日が 2009 年 3 月 1 日の債券の、クーポン期間の最初から 1996 年 11月 11 日までの日数を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; int frequency = IMSL_SEMIANNUAL; int basis = IMSL_DAY_CNT_BASIS_ACTUAL365; int days;

settlement.tm_year = 96; settlement.tm_mon = 10; settlement.tm_mday = 11;

maturity.tm_year = 109; maturity.tm_mon = 2; maturity.tm_mday = 1;

days = imsl_days_before_settlement (settlement, maturity, frequency, basis);

printf ("The number of days from the beginning of the\n"); printf ("coupon period to the settlement date is %d.\n", days);}

出力結果

The number of days from the beginning of thecoupon period to the settlement date is 71.

days_to_next_coupon決済日から次のクーポン期日までの日数を計算します。

概要

#include <imsl.h>

int imsl_days_to_next_coupon (struct tm settlement, struct tm maturity, int frequency, int basis)

Page 559: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

int frequency ( 入力 )利息支払いの頻度。 IMSL_ANNUAL、IMSL_SEMIANNUAL、 IMSL_QUARTERLYのいずれか1つである必要があります。 頻度

(frequency)の詳細は「使用上の注意」を参照してください。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、IMSL_DAY_CNT_BASIS_NASD、IMSL_DAY_CNT_BASIS_ACTUAL360、IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E36の1つである必要があります。basis の詳細な説明は、「使用上の注意」を参

照してください。

戻り値

決済日から次のクーポン期日までの日数。

説明

関数 imsl_days_to_next_coupon は、決済日から次のクーポン期日で終わる

日数を計算します。日数のカウント基準(basis)の完全な説明は SIA Standard Securities Calculation Methods 1993, vol. 1, 17-35 ページを参照してくだ

さい。

例題

この例題では imsl_days_to_next_coupon は Actual/365 日数法を使用して、

満期日が 2009 年 3 月 1 日の債券の、1996 年 11 月 11 日から次のクーポン期日

までの日数を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; int frequency = IMSL_SEMIANNUAL; int basis = IMSL_DAY_CNT_BASIS_ACTUAL365; int days;

settlement.tm_year = 96; settlement.tm_mon = 10; settlement.tm_mday = 11;

maturity.tm_year = 109; maturity.tm_mon = 2; maturity.tm_mday = 1;

days = imsl_days_to_next_coupon (settlement, maturity, frequency, basis); printf ("The number of days from the settlement date to "); printf ("the next coupon date is %d.\n", days);}

出力結果

The number of days from the settlement date to the next coupon date is 110.

Page 560: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

depreciation_amordegrc各会計期間の減価償却を計算します。関数の計算中は、資産耐用年数に基づく減価償却係数が適用されます。

概要

#include <imsl.h>

float imsl_f_depreciation_amordegrc (float cost, struct tm issue, struct tm first_period, float salvage, int period, float rate, int basis)

double 型関数は、 imsl_d_depreciation_amordegrcです。

必要な引数

float cost ( 入力 )資産の初期価額。

struct tm issue ( 入力 )利息が付き始める日付。 日付(dates)の詳細な説明は、「使用上の注

意」を参照してください。

struct tm first_period ( 入力 )最初の期間の終了日。日付(dates)の詳細な説明は、「使用上の注意」

を参照してください。

float salvage ( 入力 )償却期間終了時の資産価額。

int period ( 入力 )減価償却を計算する会計期間。

float rate ( 入力 )減価償却率。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、 IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E36のいずれか1つである必要があります。 basis の詳細な説明は、使用上の注意を参照してください。

戻り値

各会計期間の減価償却。 結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_depreciation_amordegrc は各会計期間の減価償却を計算しま

す。この関数は depreciation_amorlinc と似ていますが、関数の計算中に資

産の耐用年数に基づく減価償却係数が適用される点が異なります。

例題

この例題では imsl_f_depreciation_amordegrc は、2 番目の会計期間の減

価償却を、 US (NASD) 30/360 日数法を使用して計算します。この債券は 発行日

が 1999 年 11 月 1 日、最初の期間の終了日が 2000 年 11 月 30 日、原価が 2,400ドル、償却期間終了後の価値が 300 ドル、減価償却率 15 % です。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm issue, first_period; float cost = 2400.; float salvage = 300.;

Page 561: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int period = 2; float rate = .15; int basis = IMSL_DAY_CNT_BASIS_NASD; float amordegrc;

issue.tm_year = 99; issue.tm_mon = 10; issue.tm_mday = 1;

first_period.tm_year = 100; first_period.tm_mon = 10; first_period.tm_mday = 30;

amordegrc = imsl_f_depreciation_amordegrc (cost, issue, first_period, salvage, period, rate, basis);

printf ("The depreciation for the second accounting period "); printf ("is $%.2f.\n", amordegrc);}

出力結果

The depreciation for the second accounting period is $335.00.

depreciation_amorlinc各会計期間の減価償却を計算します。depreciation_amordegrc と似ていま

すが、depreciation_amordegrc では関数の計算時に資産の耐用年数に基づ

く減価償却係数が適用される点が異なります。

概要

#include <imsl.h>

float imsl_f_depreciation_amorlinc (float cost, struct tm issue, struct tm first_period, float salvage, int period, float rate, int basis)

double 型関数は、 imsl_d_depreciation_amordegrcです。

必要な引数

float cost ( 入力 )資産の初期価額。

struct tm issue ( 入力 )利息が付き始める日付。 日付(dates)の詳細な説明は、「使用上の注

意」を参照してください。

struct tm first_period ( 入力 )最初の期間終了日。日付(dates)の詳細な説明は、「使用上の注意」

を参照してください。

float salvage ( 入力 )償却期間終了時の資産価額。

int period ( 入力 )減価償却を計算する会計期間。

float rate ( 入力 )減価償却率。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

Page 562: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

各会計期間の減価償却。 結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_depreciation_amorlinc は各会計期間の減価償却を計算しま

す。

例題

この例題では imsl_f_depreciation_amorlinc は、2 番目の会計期間の減価

償却を、 US (NASD) 30/360 日数法を使用して計算します。この債券は、発行日

が 1999 年 11 月 1 日、最初の期間の終了日が 2000 年 11 月 30 日、原価が 2,400ドル、償却期間終了後の価値が 300 ドル、原価償却率が 15 % です。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm issue, first_period; float cost = 2400.; float salvage = 300.; int period = 2; float rate = .15; int basis = IMSL_DAY_CNT_BASIS_NASD; float amorlinc;

issue.tm_year = 99; issue.tm_mon = 10; issue.tm_mday = 1;

first_period.tm_year = 100; first_period.tm_mon = 10; first_period.tm_mday = 30;

amorlinc = imsl_f_depreciation_amorlinc (cost, issue, first_period, salvage, period, rate, basis); printf ("The depreciation for the second accounting period "); printf ("is $%.2f.\n", amorlinc);}

出力結果

The depreciation for the second accounting period is $360.00.

discount_price債券を額面より低い価格で売却する時の価格を計算します。

概要

#include <imsl.h>

float imsl_f_discount_price (struct tm settlement, struct tm maturity, float discount_rate, float redemption, int basis)

double 型関数は、 imsl_d_discount_priceです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

Page 563: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float discount_rate ( 入力 )利息支払いの代わりに、満期時の価値よりも低い価値で債券を売却した場合の利率。

float redemption ( 入力 )債券の額面 100 ドルあたりの償還価格。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

割引債券の額面あたりの価格。 結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_discount_price は、割引債券の額面 100 ドルあたりの価格を計

算します。

以下の式で計算されます。

ここで、 DSM は決済日から満期日までの日数を表します。B は、1 年の日数を

表します。

例題

この例題では imsl_f_discount_price は、 US (NASD) 30/360 日数法を使用

して 決済日が 2000 年 7 月 1 日、満期日が 2001 年 7 月 1 日、割引率が 5 % の

割引債券の価格を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float discount = .05; float redemption = 100.; int basis = IMSL_DAY_CNT_BASIS_NASD; float price;

settlement.tm_year = 100; settlement.tm_mon = 6; settlement.tm_mday = 1;

maturity.tm_year = 101; maturity.tm_mon = 6; maturity.tm_mday = 1;

price = imsl_f_discount_price (settlement, maturity, discount, redemption, basis);

printf ("The price of the discounted bond is $%.2f.\n", price);}

出力結果

The price of the discounted bond is $95.00.

( )_ DSMredemption discount rate redemptionB

Page 564: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

discount_rate利息支払いの代わりに、債券を満期時の価値よりも低い価格で売却した場合の利率を計算します。

概要

#include <imsl.h>

float imsl_f_discount_rate (struct tm settlement, struct tm maturity, float price, float redemption, int basis)

double 型関数は、 imsl_d_discount_rateです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。 日付(dates)の詳細な説明は、

「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

float price ( 入力 )債券の額面 100 ドルあたりの価格。

float redemption ( 入力 )債券の額面 100 ドルあたりの償還価格。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

債券の割引率。 結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_discount_rate は債券の割引率を計算します。この割引率とは

債券が利息支払いの代わりに満期日の価値より低い価格で売却した場合の利率をです。

以下の式で計算されます。

上の式では、B は 1 年の日数、DSM は決済日から満期日までの日数を表しま

す。

例題

この例題では imsl_f_discount_rate は Actual/365 日数法を使用して、決済

日が 2000 年 2 月 15 日、満期日が 2000 年 6 月 10 日、売却価格が 97.975 ドル

の債券の割引率を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float price = 97.975;

redemption price Bprice DSM

Page 565: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float redemption = 100.; int basis = IMSL_DAY_CNT_BASIS_ACTUAL365; float rate;

settlement.tm_year = 100; settlement.tm_mon = 1; settlement.tm_mday = 15;

maturity.tm_year = 100; maturity.tm_mon = 5; maturity.tm_mday = 10;

rate = imsl_f_discount_rate (settlement, maturity, price, redemption, basis);

printf ("The discount rate for the security is %.2f%%.\n", rate * 100.);}

出力結果

The discount rate for the security is 6.37%.

discount_yield割引債券の年利回りを計算します。

概要

#include <imsl.h>

float imsl_f_discount_yield (struct tm settlement, struct tm maturity, float price, float redemption, int basis)

double 型関数は、 imsl_d_discount_yieldです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。 日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

float price ( 入力 )債券の額面 100 ドルあたりの価格。

float redemption ( 入力 )債券の額面 100 ドルあたりの償還価格。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

割引債券の年利回り。 結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_discount_yield は割引債券の年利回りを計算します。

redemption price Bprice DSM

Page 566: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

上の式では、B は 1 年の日数、DSM は決済日から満期日までの日数を表しま

す。

例題

この例題では imsl_f_discount_yieldは、US (NASD) 30/360 日数法を使用し

て決済日が 1995 年 7 月 1 日、満期日が 2005 年 7 月 1 日、売却価格が 95.40663 ドルの割引債券の年利回りを計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float price = 95.40663; float redemption = 105.; int basis = IMSL_DAY_CNT_BASIS_NASD; float yielddisc;

settlement.tm_year = 95; settlement.tm_mon = 6; settlement.tm_mday = 1;

maturity.tm_year = 105; maturity.tm_mon = 6; maturity.tm_mday = 1;

yielddisc = imsl_f_discount_yield (settlement, maturity, price, redemption, basis); printf ("The yield on the discounted bond is "); printf ("%.2f%%.\n", yielddisc * 100.);}

出力結果

The yield on the discounted bond is 1.01%.

duration定期的に利息が支払われる債券の 1 年のデュレーションを計算します。

概要

#include <imsl.h>

float imsl_f_duration (struct tm settlement, struct tm maturity, float coupon_rate, float yield, int frequency, int basis)

double 型関数は、 imsl_d_durationです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。 詳細な説明は、「使用上の注

意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。 詳細な説明は、

「使用上の注意」を参照してください。

float coupon_rate ( 入力 )債券に記載されている年利。表面利率。

float yield ( 入力 )債券の年利回り。

Page 567: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int frequency ( 入力 )利息支払いの頻度。 IMSL_ANNUAL, IMSL_SEMIANNUAL、 IMSL_QUARTERLYのどれか1つである必要があります。詳細は使用上

の注意の頻度(frequency)を参照してください。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

定期的に利息が支払われる債券の 1 年のデュレーション。 結果が計算できない

場合、NaN が返されます。

説明

関数 imsl_f_duration は、定期的に利息が支払われる債券の マコーレー

(Maccaluey) のデュレーションを計算します。この マコーレー(Maccaluey)のデュレーションとは、支払いまでの加重平均時間です。この場合の重みは、支払い額の現在価値になります。

以下の式で計算されます。

上の式では、 DSC は決済日から次のクーポン期日までの日数を示します。E はクーポン期間内の日数を示します。N は決済日から満期日まで間に支払われる

クーポン数を示します。freq は 1 年のクーポン支払いの頻度を示します。

例題

この例題では imsl_f_duration は Actual/365 法を使用して、決済日が 1995 年 7 月 1 日、満期日が 2005 年7月 1 日の債券のデュレーションを計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float coupon = .075; float yield = .09; int frequency = IMSL_SEMIANNUAL; int basis = IMSL_DAY_CNT_BASIS_ACTUAL365; float duration;

settlement.tm_year = 95; settlement.tm_mon = 6; settlement.tm_mday = 1;

maturity.tm_year = 105;

1 11

1 1

100 100 _ 1

1 1

100 100 _

1 1

N

DSC DSCN kkE E

N

DSCN kE

DSCcoupon rate DSCE k

Eyield yieldfreqfreq freq

coupon rate

yield yfreqfreq

− + − + =

− + =

∗ ∗ + ∗ − + + ∗ +

∗+

+ ∗ +

∑1

1

DSCkE

freq

ieldfreq

− +

Page 568: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

maturity.tm_mon = 6; maturity.tm_mday = 1;

duration = imsl_f_duration (settlement, maturity, coupon, yield, frequency, basis); printf ("The annual duration of the bond with "); printf ("semiannual interest payments is %.4f.\n", duration);}

出力結果

The annual duration of the bond with semiannual interest payments is 7.0420.

interest_rate_security全額投資された債券の利率を計算します。

概要

#include <imsl.h>

float imsl_f_interest_rate_security (struct tm settlement, struct tm maturity, float investment, float redemption, int basis)

double 型関数は、 imsl_d_interest_rate_securityです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。 詳しい説明は「使用上」の注

意を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。詳しい説明は「使用上」の注意を参照してください。

float investment ( 入力 )債券への総投資額。

float redemption ( 入力 )満期時の受取額。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

全額投資した債券の利率。 結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_interest_rate_security は、全額投資した債券の利率を計算

します。

以下の式で計算されます。

上の式では、 B は 1 年の日数、 DSM は決済日から満期日魔での期間の日数を示

します。

redemption investment Binvestment DSM

Page 569: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

この例題では imsl_f_interest_rate_security は、 Actual/365 日数法を使

用して決済日が 1995 年 7 月 1 日、満期日が 2005 年7月 1 日である 7,000 ドル

の投資に対する利率を計算します。この投資の終わりに受け取る総額は 10,000ドルです。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float investment = 7000.; float redemption = 10000.; int basis = IMSL_DAY_CNT_BASIS_ACTUAL365; float intrate;

settlement.tm_year = 95; settlement.tm_mon = 6; settlement.tm_mday = 1;

maturity.tm_year = 105; maturity.tm_mon = 6; maturity.tm_mday = 1;

intrate = imsl_f_interest_rate_security (settlement, maturity, investment, redemption, basis);

printf ("The interest rate of the bond is %.2f%%.\n", intrate * 100.);}

出力結果

The interest rate of the bond is 4.28%.

modified_duration債券の修正マコーレー(Macauley)デュレーションを計算します。

概要

#include <imsl.h>

float imsl_f_modified_duration (struct tm settlement, struct tm maturity, float coupon_rate, float yield, int frequency, int basis)

double 型関数は、 imsl_d_modified_durationです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。 日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

float coupon_rate ( 入力 )債券に記載されている年利。表面利率。

float yield ( 入力 )債券の年利回り。

int frequency ( 入力 )利息支払いの頻度。 IMSL_ANNUAL、 IMSL_SEMIANNUAL、

Page 570: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_QUARTERLYのどれか 1 つである必要があります。 頻度(frequency)の詳細は「使用上の注意」を参照してください。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

債券の修正 デュレーション。この債券の想定額面価格は 100 ドルです。 結果が

計算できない場合、NaN が返されます。

説明

関数 imsl_f_modified_duration は想定額面価格が 100 ドルの債券の修正 マコーレー(Macauley)のデュレーションを計算します。

以下の式で計算されます。

この duration は imsl_f_duration で計算されます。

例題

この例題では imsl_f_modified_duration は Actual/365 日数法を使用して 決済日が 1995 年 7 月 1 日、満期日が 2005 年7月 1 日の債券の修正 デュレー

ションを計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float coupon = .075; float yield = .09; int frequency = IMSL_SEMIANNUAL; int basis = IMSL_DAY_CNT_BASIS_ACTUAL365; float mduration;

settlement.tm_year = 95; settlement.tm_mon = 6; settlement.tm_mday = 1;

maturity.tm_year = 105; maturity.tm_mon = 6; maturity.tm_mday = 1;

mduration = imsl_f_modified_duration (settlement, maturity, coupon, yield, frequency, basis);

printf ("The modified Macauley duration of the bond with\n"); printf ("semiannual interest payments is %.4f.\n", mduration);}

出力結果

The modified Macauley duration of the bond withsemiannual interest payments is 6.7387.

1

durationyield

frequency

+

Page 571: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

next_coupon_date決済日後の最初のクーポン期日を計算します。

概要

#include <imsl.h>

struct tm imsl_next_coupon_date (struct tm settlement, struct tm maturity, int frequency, int basis)

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

int frequency ( 入力 )利息支払いの頻度。IMSL_ANNUAL、 IMSL_SEMIANNUAL、 IMSL_QUARTERLYのいずれか1つである必要があります。 頻度(frequency)の詳細は「使用上の注意」を参照してください。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

決済日後の最初のクーポン期日。

説明

関数 imsl_next_coupon_date は、決済日後の最初のクーポン期日を計算しま

す。日数のカウント基準(basis)の完全な説明は SIA Standard Securities Calculation Methods 1993, vol. 1, 17-35 ページを参照してください。

例題

この例題では imsl_next_coupon_date は Actual/365 日数法を使用して、決済

日が 1996 年 11 月 11 日、満期日が 2009 年 3 月 1 日の債券の次のクーポン期日

を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity, date; char* month[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September",

"October", "November", "December" }; int frequency = IMSL_SEMIANNUAL; int basis = IMSL_DAY_CNT_BASIS_ACTUAL365;

settlement.tm_year = 96; settlement.tm_mon = 10; settlement.tm_mday = 11;

maturity.tm_year = 109; maturity.tm_mon = 2; maturity.tm_mday = 1;

Page 572: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

date = imsl_next_coupon_date (settlement, maturity, frequency, basis); printf ("The next coupon date after the settlement date "); printf ("is %s %d, %d.\n", month[date.tm_mon], date.tm_mday, date.tm_year+1900);}

出力結果

The next coupon date after the settlement date is March 1, 1997.

previous_coupon_date決済日直前のクーポン期日を計算します。

概要

#include <imsl.h>

struct tm imsl_previous_coupon_date (struct tm settlement, struct tm maturity, int frequency, int basis)

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

int frequency ( 入力 )利息支払いの頻度。 IMSL_ANNUAL, IMSL_SEMIANNUAL、 IMSL_QUARTERLYのどれか 1 つである必要があります。 頻度(frequency)の詳細は「使

用上の注意」を参照してください。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

決済日の直前のクーポン期日。

説明

関数 imsl_previous_coupon_date は、決済日の直前のクーポン日を計算し

ます。日数のカウント基準(basis)の完全な説明は SIA Standard Securities Calculation Methods 1993, vol. 1, 17-35 ページ を参照してください。

例題

この例題では imsl_previous_coupon_date は、 Actual/365 日数法を使用し

て、決済日が 1986 年 11 月 11 日、満期日が 1999 年 3 月 1 日の債券の前のクー

ポン期日を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity, date; char* month[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September",

"October", "November", "December" };

Page 573: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int frequency = IMSL_SEMIANNUAL; int basis = IMSL_DAY_CNT_BASIS_ACTUAL365;

settlement.tm_year = 96; settlement.tm_mon = 10; settlement.tm_mday = 11;

maturity.tm_year = 109; maturity.tm_mon = 2; maturity.tm_mday = 1;

date = imsl_previous_coupon_date (settlement, maturity, frequency, basis); printf ("The previous coupon date before the settlement "); printf ("date is %s %d, %d.\n", month[date.tm_mon], date.tm_mday, date.tm_year+1900);}

出力結果

The previous coupon date before the settlement date is September 1, 1996.

price定期的に利息を支払う債券の額面価格 100 ドルあたりの価格を計算します。

概要

#include <imsl.h>

float imsl_f_price (struct tm settlement, struct tm maturity, float rate, float yield, float redemption, int frequency, int basis)

double 型関数は、 imsl_d_priceです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

float rate ( 入力 )債券に記載されている年利。表面利率。

float yield ( 入力 )債券の年利回り。

float redemption ( 入力 )債券の額面 100 ドルあたりの償還価格。

int frequency ( 入力 )利息支払いの頻度。IMSL_ANNUAL、IMSL_SEMIANNUAL、IMSL_QUARTERLY のいずれか1つである必要があります。頻度

(frequency)の詳細は「使用上の注意」を参照してください。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

Page 574: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

定期的に利息を支払う債券の額面価格 100 ドルあたりの価格。結果が計算でき

ない場合、NaN が返されます。

説明

関数 imsl_f_price は定期的利息を支払う債券の額面価格 100 ドルあたりの価

格を計算します。

以下の式で計算されます。

ここで DSC は決済日から次のクーポン日までの日数を示します。E はクーポ

ン期間内の日数を示します。N は決済日から満期日までの間に支払われるべき

クーポン数を示します。A はクーポン期間の最初の日から決済日までの日数を

示します。

例題

この例題では imsl_f_price は、 US (NASD) 30/360 日数法を使用して、決済日

が 1995 年7月 1 日、満期日が 2005 年7月 1 日、年利 6 % 、年利回り 7%、償

還価額が 105 ドルの 6ヶ月毎に支払う債券の価格を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float rate = .06; float yield = .07; float redemption = 105.; int frequency = IMSL_SEMIANNUAL; int basis = IMSL_DAY_CNT_BASIS_NASD; float price;

settlement.tm_year = 95; settlement.tm_mon = 6; settlement.tm_mday = 1;

maturity.tm_year = 105; maturity.tm_mon = 6; maturity.tm_mday = 1;

price = imsl_f_price (settlement, maturity, rate, yield, redemption, frequency, basis); printf ("The price of the bond is $%.2f.\n", price);}

出力結果

The price of the bond is $95.41.

price_maturity満期日に利息を支払う債券の額面価格 100 ドルあたりの価格を計算します。

概要

#include <imsl.h>

1 11

100100

1 1

N

DSC DSCN kkE E

rateredemption rate Afrequency

frequency Eyield yield

frequency frequency

− + − + =

+ − ∗ ∗ + +

Page 575: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float imsl_f_price_maturity (struct tm settlement, struct tm maturity, struct tm issue, float rate, float yield, int basis)

double 型関数は、 imsl_d_price_maturityです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

struct tm issue ( 入力 )利息が付き始める日付。日付(dates)の詳細な説明は、「使用上の注

意」を参照してください。

float rate ( 入力 )債券に記載されている年利。表面利率。

float yield ( 入力 )債券の年利回り。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

満期日に利息を支払う債券の、額面価格 100 ドルあたりの価格。結果が計算で

きない場合、NaN が返されます。

説明

関数 imsl_f_price_maturity は、満期日に利息を支払う債券の額面価格 100ドルあたりの価格を計算します。

以下の式で計算されます。

上の式では、B は 1 年の日数を示します。DSM は決済日から満期日までの日

数を示します。DIM は発行日から満期日までの日数を示します。A は発行日か

ら決済日までの日数を示します。

例題

この例題では imsl_f_price_maturity は US (NASD) 30/360 日数法を使用し

て、決済日が 2000 年8月 1 日、満期日が 2001 年7月 1 日、発行日が 2000 年

7月 1 日の債券の満期日の価格を計算します。債券の年利回りは 5 % 、発行日

の利率は 5 % です。

#include <stdio.h>#include "imsl.h"

#include <stdio.h>#include "imsl.h"

void main()

100 100100

1

DIM rateAB rate

DSM ByieldB

+ ∗ ∗ − ∗ ∗ + ∗

Page 576: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{ struct tm settlement, maturity, issue; float rate = .05; float yield = .05; int basis = IMSL_DAY_CNT_BASIS_NASD; float pricemat;

settlement.tm_year = 100; settlement.tm_mon = 7; settlement.tm_mday = 1;

maturity.tm_year = 101; maturity.tm_mon = 6; maturity.tm_mday = 1;

issue.tm_year = 100; issue.tm_mon = 6; issue.tm_mday = 1;

pricemat = imsl_d_price_maturity (settlement, maturity, issue, rate, yield, basis);

printf ("The price of the bond is $%.2f.\n", pricemat);}

出力結果

The price of the bond is $99.98.

received_maturity全額投資した債券が満期日を迎えた時の受取額を計算します。

概要

#include <imsl.h>

float imsl_f_received_maturity (struct tm settlement, struct tm maturity, float investment, float discount_rate, int basis)

double 型関数は、 imsl_d_received_maturityです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

float investment ( 入力 )債券への総投資額。

float discount_rate ( 入力 )利息支払いの代わりに、満期時の価値よりも低い価値で債券を売却した場合の利率。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

Page 577: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

全額投資した債券が満期日を迎えた時の受取額。結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_received_maturity は、全額投資した債券が満期日を迎えた時

の受取額を計算します。

以下の式で計算されます。

上の式では、 B は 1 年の日数を、DIM は発行日から満期日までの日数を示しま

す。

例題

この例題では imsl_f_received_maturity は、 Actual/365 日数法を使用して、

決済日が 1995 年7月 1 日、満期日が 2005 年7月 1 日、割引率が 6 % の 7,000ドル投資の受取額を計算します。

include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float investment = 7000.; float discount = .06; int basis = IMSL_DAY_CNT_BASIS_ACTUAL365; float received;

settlement.tm_year = 95; settlement.tm_mon = 6; settlement.tm_mday = 1;

maturity.tm_year = 105; maturity.tm_mon = 6; maturity.tm_mday = 1;

received = imsl_f_received_maturity (settlement, maturity, investment, discount, basis); printf ("The amount received at maturity for the "); printf ("bond is $%.2f.\n", received);}

出力結果

The amount received at maturity for the bond is $17521.60.

treasury_bill_price米国財務省短期債券の額面 100 ドルあたりの価格を計算します。

概要

#include <imsl.h>

float imsl_f_treasury_bill_price (struct tm settlement, struct tm maturity, float discount_rate)

double 型関数は、 imsl_d_treasury_bill_priceです。

1 _

investmentDIMdiscount rate

B − ∗

Page 578: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

float discount_rate ( 入力 )利息支払いの代わりに、満期時の価値よりも低い価値で債券を売却した場合の利率。

戻り値

米国財務省短期債券の額面 100 ドルあたりの価格。 結果が計算できない場合、

NaN が返されます。

説明

関数 imsl_f_treasury_bill_price は、米国財務省短期債券の額面 100 ドル

あたりの価格を計算します。

以下の式で計算されます。

上の式では、 DSM は決済日から満期日までの日数を示します(決済日よりも暦

年で 1 年より後の満期日は除外します)。

例題

この例題では imsl_f_treasury_bill_price は、決済日が 2000 年7月 1 日、

満期日が 2001 年7月 1 日、発行日での割引率が 5 % の米国財務省短期債券の

価格を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float discount = .05; float price;

settlement.tm_year = 100; settlement.tm_mon = 6; settlement.tm_mday = 1;

maturity.tm_year = 101; maturity.tm_mon = 6; maturity.tm_mday = 1;

price = imsl_f_treasury_bill_price (settlement, maturity, discount); printf ("The price per $100 face value for the T-bill "); printf ("is $%.2f.\n", price);}

出力結果

The price per $100 face value for the T-bill is $94.93.

treasury_bill_yield米国財務省短期債券の利回りを計算します。

_100 1360

discount rate DSM∗ −

Page 579: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

概要

#include <imsl.h>

float imsl_f_treasury_bill_yield (struct tm settlement, struct tm maturity, float price)

double 型関数は、 imsl_d_treasury_bill_yieldです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

float price ( 入力 )米国財務省短期債券の額面 100 ドルあたりの価格。

戻り値

米国財務省短期債券の利回り。 結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_treasury_bill_yield は、米国財務省短期債券の利回りを計算

します。

以下の式で計算されます。

上の式では、 DSM はは決済日から満期日までの日数を示します(決済日よりも

暦年で 1 年より後の満期日は除外します)。

例題

この例題では imsl_f_treasury_bill_yield は、決済日が 2000 年7月 1 日、

満期日が 2001 年7月 1 日、価格が 94.93 ドルの米国財務省短期債券の利回り

を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float price = 94.93; float yield;

settlement.tm_year = 100; settlement.tm_mon = 6; settlement.tm_mday = 1;

maturity.tm_year = 101; maturity.tm_mon = 6; maturity.tm_mday = 1;

yield = imsl_f_treasury_bill_yield (settlement, maturity, price); printf ("The yield for the T-bill is %.2f%%.\n", yield * 100.);}

出力結果

The yield for the T-bill is 5.27%.

100 360priceprice DSM

Page 580: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

year_fraction2 つの日付の間の日数を 1 年に対する割合で表します。

概要

#include <imsl.h>

float imsl_f_year_fraction (struct tm start, struct tm end, int basis)double 型関数は、 imsl_d_year_fractionです。

必要な引数

struct tm start ( 入力 )最初の日付。日付(dates)の詳しい説明は使用上の注意を参照してく

ださい。

struct tm end ( 入力 )終わりの日付。日付(dates)の詳細な説明は、「使用上の注意」を参

照してください。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

2 つの日付間の日数を 1 年に対する割合に変換した値。結果を計算できない場合

は,NaN を返します。結果が計算できない場合、NaN が返されます。

説明

関数 imsl_f_year_fraction は、1 年の割合を計算します。

以下の式で計算されます。

ここで A は start から end までの日数、 D は 1 年の日数を示します。

例題

この例題では imsl_f_year_fraction は、 NASD 日数法を使用して、2000 年

8 月 1 日から 2001 年7月 1 日までの期間の 1 年に対する割合を計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm start, end; int basis = IMSL_DAY_CNT_BASIS_NASD; float yearfrac;

start.tm_year = 100; start.tm_mon = 7; start.tm_mday = 1;

end.tm_year = 101; end.tm_mon = 6;

A/D

Page 581: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

end.tm_mday = 1;

yearfrac = imsl_f_year_fraction (start, end, basis); printf ("The year fraction of the 30/360 period is %f.\n", yearfrac);}

出力結果

The year fraction of the 30/360 period is 0.916667.

yield_maturity満期日に利息を支払う債券の年利回りを計算します。

概要

#include <imsl.h>

float imsl_f_yield_maturity (struct tm settlement, struct tm maturity, struct tm issue, float rate, float price, int basis)

double 型関数は、 imsl_d_yield_maturityです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

struct tm issue ( 入力 )利息が付き始める日付。日付(dates)の詳細な説明は、「使用上の注

意」を参照してください。

float rate ( 入力 )債券の発行日での利率。Interest rate at date of issue of the security.

float price ( 入力 )債券の額面 100 ドルあたりの価格。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

満期日に利息を支払う債券の年利回り。結果が計算できない場合、NaN が返

されます。

説明

関数 imsl_f_yield_maturity は、満期日に利息を支払う債券の年利回りを計

算します。

以下の式で計算されます。

1100

100

DIM price Arate rateB B B

price A DSMrateB

+ ∗ − + ∗ ∗ + ∗

Page 582: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで DIM は発行日から満期日までの日数、DSM は決済日から満期日までの

日数を示します。A は発行日から決済日までの日数を示します。B は 1 年の日

数を示します。

例題

この例題では imsl_f_yield_maturity は、US (NASD) 30/360 日数法を使用

して、販売価格が 95.40663 ドルで、決済日が 2000 年 8 月 1 日、発行日が 2000年 7 月 1 日、満期日が 2010 年 7 月 1 日、発行日での利率が 6 % の、満期日に

利息が支払われる債券の年利回りを計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity, issue; float rate = .06; float price = 95.40663; int basis = IMSL_DAY_CNT_BASIS_NASD; float yieldmat;

settlement.tm_year = 100; settlement.tm_mon = 7; settlement.tm_mday = 1;

maturity.tm_year = 110; maturity.tm_mon = 6; maturity.tm_mday = 1;

issue.tm_year = 100; issue.tm_mon = 6; issue.tm_mday = 1;

yieldmat = imsl_f_yield_maturity (settlement, maturity, issue, rate, price, basis); printf ("The yield on a bond which pays at maturity is "); printf ("%.2f%%.\n", yieldmat * 100.);}

出力結果

The yield on a bond which pays at maturity is 6.74%.

yield_periodic定期的に利息を支払う債券の利回りを計算します。

概要

#include <imsl.h>

float imsl_f_yield_periodic (struct tm settlement, struct tm maturity, float coupon_rate, float price, float redemption, int frequency, int basis, …, 0)

double 型関数は、 imsl_d_yield_periodicです。

必要な引数

struct tm settlement ( 入力 )支払いが行われて取引が確定する日付。日付(dates)の詳細な説明

は、「使用上の注意」を参照してください。

struct tm maturity ( 入力 )債券が満期になり、元金と累積利息が支払われる日付。日付(dates)の詳細な説明は、「使用上の注意」を参照してください。

Page 583: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float coupon_rate ( 入力 )1 年の表面利率。

float price ( 入力 )債券の額面 100 ドルあたりの価格。

float redemption ( 入力 )債券の額面 100 ドルあたりの償還価格。

int frequency ( 入力 )利息支払いの頻度。IMSL_ANNUAL、IMSL_SEMIANNUAL、IMSL_QUARTERLY のいずれか1つである必要があります。頻度

(frequency)の詳細は「使用上の注意」を参照してください。

int basis ( 入力 )2 つの日付の間の日数を計算する方法。この方法は、

IMSL_DAY_CNT_BASIS_ACTUALACTUAL、 IMSL_DAY_CNT_BASIS_NASD、 IMSL_DAY_CNT_BASIS_ACTUAL360、 IMSL_DAY_CNT_BASIS_ACTUAL365、 IMSL_DAY_CNT_BASIS_30E360 の1つである必要があります。詳細な

説明は、「使用上の注意」を参照してください。

戻り値

定期的に利息を支払う債券の年利回り。 結果が計算できない場合、NaN が返さ

れます。

オプション引数の概要

#include <imsl.h>

float imsl_f_yield_periodic (struct tm settlement, struct tm maturity, float coupon_rate, float price, float redemption, int frequency, int basis, IMSL_XGUESS, float guess, IMSL_HIGHEST, float max, 0)

オプション引数

IMSL_XGUESS, float guess ( 入力 )内部利益率の初期推測値。

IMSL_HIGHEST, float max ( 入力 )最大許容内部利益率。デフォルト: 1.0 (100%)

説明

関数 imsl_f_yield_periodic は、定期的に利息を支払う債券の年利回りを計

算します。クーポン期間が 1 の場合、次の式で計算されます。

ここで DSR は決済日から満期日までの日数を示します。E はクーポン期間内

の日数を示します。A はクーポン期間の最初の日から決済日までの示します。

クーポン期間が 1 以上であれば、次の式を使用します。

ここで , DSC は決済日から次のクーポン日までの日数を示します。E はクーポ

ン期間内の日数を示します。N は決済日から満期日までの期間中に支払われる

_ _100 100

_100

redemption coupon rate price A coupon ratefrequency E frequency frequency E

DSRprice A coupon rateE frequency

+ − + ∗

∗ + ∗

1 11

100100 0

1 1

N

DSC DSCN kkE E

rateredemption rate Afrequencyprice

frequency Eyield yield

frequency frequency

− + − + =

∗ − + − ∗ ∗ = + +

Page 584: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

クーポン数を示します。A はクーポン期間の最初の日から決済日までの日数を

示します。

例題

この例題では imsl_f_yield_periodic は、 US (NASD) 30/360 日数法を使用

して、販売価格が 95.40663 ドルで、決済日が 1985 年 7 月 1 日、満期日が 1995年 7 月 1 日、発行日の表面利率が 6 % の債券の利回りを計算します。

#include <stdio.h>#include "imsl.h"

void main(){ struct tm settlement, maturity; float coupon_rate = .06; float price = 95.40663; float redemption = 105.; int frequency = IMSL_SEMIANNUAL; int basis = IMSL_DAY_CNT_BASIS_NASD; float yield;

settlement.tm_year = 100; settlement.tm_mon = 6; settlement.tm_mday = 1;

maturity.tm_year = 110; maturity.tm_mon = 6; maturity.tm_mday = 1;

yield = imsl_f_yield_periodic (settlement, maturity, coupon_rate, price, redemption, frequency, basis, 0); printf ("The yield of the bond is %.2f%%.\n", yield * 100.);}

出力結果 The yield of the bond is 7.00%.

Page 585: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

第 10章:統計と乱数発生

ルーチン

統計単変量要約統計量 . . . . . . . . . . . . . . . simple_statistics 586一元度数分布表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .table_oneway 590カイ二乗 1 標本適合度検定 . . . . . . . . . . . chi_squared_test 593相関 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . covariances 600多重線形回帰 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . regression 604多項式回帰 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . poly_regression 611数値の順位付け . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ranks 616

乱数発生シードの現在値の取得 . . . . . . . . . . . . . random_seed_get 622乱数シードの初期化. . . . . . . . . . . . . . . . . . . . . . . . . . random_seed_set 623一様 (0, 1) 乱数生成器の選択 . . . . . . . . . . . . . . . . . . . . . .random_option 623擬似乱数の生成 . . . . . . . . . . . . . . . . random_uniform 624擬似一様乱数の生成. . . . . . . . . . . . . . . . . . . . . . . . . . . . random_normal 625擬似ポアソン乱数の生成 . . . . . . . . . . . . . . . . . . . . . . . random_poisson 627擬似ガンマ乱数の生成 . . . . . . . . . . . . . . . . . . . . . . . . . .random_gamma 628擬似ベータ乱数の生成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . random_beta 632擬似標準指数乱数の生成 . . . . . . . . . . . . . . . . . . . . random_exponential 631

Low-discrepancy 数列(LDS : 低食い違い量列)シャッフルされた Faure 数列の生成 . . . . . . . . . . . . . . faure_next_point 632

使用上の注意

統計

この節の関数は、幾つかの一般的な単変量要約統計量の計算、1 標本適合度検

定の実行、相関の尺度の生成、多重と多項式回帰解析の実行、順位(又は、正規又は指数スコアーなどの順位の変換)の計算に使用する事ができます。統計関数に関する詳細は、ユーザは追加の情報については、IMSL C Stat ライブラ

リを参照してください。

乱数発生の概要

「乱数発生」は乱数と無作為標本と置換の発生の関数を説明しています。これらの関数は、モンテカルロ、或いは、シミュレーション研究におけるアプリケーションに役立ちます。乱数発生器のいずれかを使用する前に、その発生器はあるシード、又は、初期値を選択して初期化する必要があります。これは関数 imsl_random_seed_set を呼ぶことによって行う事が可能です。 ユーザが

シードを選択しない場合、システム時計を使用して生成されます。複数の乱数の別々のストリームを保持するのでなければ、シードはプログラムの中で一度だけ選択します。本章の中に、基本発生器の形式選択用、シミュレーションの再開始用、そして、別シミュレーションストリームの保持用に、ユーティリティ関数が存在します。

次の説明において、「乱数」、「乱数偏差値」、「偏差値」、「変量」は互換的に使用されます。「疑似乱数」は、発生された数が、確定過程で生じるものなので、実際には「無作為」ではないことを強調するために使用されます。疑似乱数の有用性は、疑似乱数の標本の、指定された分布からの観測の標本に移る、統計的な意味での類似性から導かれます。簡単に言えば、疑似乱数は、完全に確定

Page 586: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

的で反復可能ですが、それらは、独立で、同等に分布する乱数変数の実現化をシミュレーションします。

基本一様乱数発生器

本章の乱数発生器は乗算合同法を使用しています。この発生器の形態は、以下の通りです。

xi = cxi-1 mod (231 − 1)

各 xi は、単位区間 (0,1). に尺度化されます。乗算子 c が原始根係数 2 31 − 1 ( こ

れは素数 ) であれば、この発生器は 2 31 − 2 の最大周期を持ちます。しかしその

他の幾つかの考えが存在します。一般的な説明は Knuth (1981 年 ) を参照してく

ださい。IMSL 発生器の c の可能な値は 16807、397204094、950706376 です。こ

の選択は関数 imsl_random_ optionで行われます。16807 は最速の実行時間に

なりますが、950706376 の性能がこれらの 3 つの選択の中で最高であることを他

の実証論文が示しています (Fishman と Moore 1982 年 ) 。 選択が外示的に行われ

なければ、この関数は、ある時 (Lewis その他 1969 年 ) から使用されるように

なった乗算子 16807 を使用します。

一様 (0,1) 乱数の発生器は、関数 imsl_f_random_uniform によって行われま

す。この関数は、同じシードが与えられると、それは全てのコンピュータ / コンパイラー環境で同じ系列を発生する意味において、移植性 があるといえます。

シャッフル版発生器

ユーザは、又、imsl_random_ option を使用して、これらの発生器のシャッ

フル版を選択する事が可能です。シャッフル型発生器は Learmonth と Lewis (1973 年 ) による枠組みを使用しています。この枠組みにおいて、1つのテー

ブルが、単純乗算合同発生器からの、最初の 128 一様 (0,1) 乱数で埋められま

す。それから単純発生器からの、各 , xi に対して、xi の低次ビットが 1 から 128 の乱数整数、j、を選択するために使用されます。このテーブル中の j 番目

の入力値は乱数として発行されて、単位区間に尺度化された後の、xi は、この

テーブルの j 番目の位置に挿入されます。この枠組みは、Bays と Durham (1976年 ) のものと同様で、それらの分析は同様にこの枠組みに適用できます。

シードの設定

この発生器のシードは imsl_random_seed_set で設定され、 imsl_random_seed_get によって取得されます。この節の発生器を呼び出す前

に、1 と 2147483647 の間の値を持つ整数変数であるシードを初期化するため

に、ユーザは imsl_random_seed_set を呼び出すことができます。

imsl_random_seed_set によって初期化することが出来ない場合,乱数シード

はシステム時計から得られます。一度初期化された場合、シードを再びセットする必要はありません。

ユーザがシミュレーションを再実行したい場合、imsl_random_seed_getを使

用することで、最後のシード値を取得し、引き続きの実行の出発値として使用することができます。又、2 つの同時の乱数発生ストリームが、1 回の実行で

必要な場合、 imsl_random_seed_set と imsl_random_seed_get を各スト

リームの発生器の呼び出し前と後に使用することができます。

simple_statistics基本単変量統計量を計算します。

概要

#include <imsl.h>

Page 587: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float *imsl_f_simple_statistics (int n_observations, int _variables, float x[] ,…, 0)

double 型関数は、 imsl_d_simple_statisticsです。

必要な引数

int n_observations ( 入力 )観測数。

int n_variables ( 入力 )変数の数。

float x[] ( 入力 )データ行列を含むサイズ n_observations × n_variables の配列。

戻り値

x における各列に、幾つかの単純統計量を含んだ配列のポインター。引数として、もしも MEDIAN と MEDIAN_AND_SCALE が使用されない時は、その行列の

サイズは 14 × n_variables になります。この行列の列は x の列に対応して、

その行は、次の統計量を含みます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_simple_statistics (int n_observations, int n_variables, float x[],IMSL_CONFIDENCE_MEANS, float confidence_means,IMSL_CONFIDENCE_VARIANCES, float confidence_variances,IMSL_X_COL_DIM, int x_col_dim,IMSL_STAT_COL_DIM, int stat_col_dim,IMSL_MEDIAN,IMSL_MEDIAN_AND_SCALE,IMSL_RETURN_USER, float simple_statistics[],0)

オプション引数

IMSL_CONFIDENCE_MEANS, float confidence_means ( 入力 )パーセントでの平均(正規性を仮定して)の両側区間推測の信頼レベル。引数 confidence_means は 0.0 と 100.0 、そしてしばしば 90.0、95.0、又は 99.0. の間でなければなりません。信頼レベル c の片側信

頼区間に対しては、 confidence_means = 100.0 - 2.0 × (100 - c) にセッ

トします。IMSL_CONFIDENCE_MEANS が指定されなければ 95 パーセン

ト信頼区間が計算されます。

行 統計量0 平均1 分散2 標準偏差3 歪度の係数4 尖度(超過)の係数5 最小値6 最大値7 範囲8 変動係数(定義された時)

変動係数が定義されなければ0が返される9 観測数(回数)。10 平均の下信頼限界(正規性を仮定)

デフォルトは 95 パーセント信頼区間11 平均の上信頼限界(正規性を仮定)12 分散の下信頼限界(正規性を仮定)

デフォルトは 95 パーセント信頼区間13 分散の上信頼限界(正規性を仮定)

Page 588: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_CONFIDENCE_VARIANCES, float confidence_variances ( 入力 )パーセントでの分散(正規性を仮定して)の両側区間推測の信頼レベル。この信頼区間は(長さでなくて)確率において対称になります。信頼レベル c の片側信頼区間に対しては、confidence_means = 100.0 - 2.0 × (100 - c) にセットします。IMSL_CONFIDENCE_VARIANCES が指

定されなければ 95 パーセント信頼区間が計算されます。

IMSL_X_COL_DIM, int x_col_dim ( 入力 )配列 x の列ディメンジョン。

デフォルト: x_col_dim = n_variables

IMSL_STAT_COL_DIM, int stat_col_dim ( 入力 )戻り値配列の列ディメンジョン。もしくは、 IMSL_RETURN_USER が指

定されている場合は、配列 simple_statistics の列ディメンジョン。

デフォルト: stat_col_dim = n_variables

IMSL_MEDIAN, orIMSL_MEDIAN_AND_SCALE

正確にこれらのオプションの引数の1つを計算される追加の単純ロバスト統計を示すために指定することができます。もし IMSL_MEDIAN が指定されると中位数が計算されて 単純統計量の戻り値行列の1つの追

加の行 ( 行番号 14) に格納されます。 IMSL_MEDIAN_AND_SCALE が指定

される場合、中位数、中位数からの絶対偏差の中位数、尺度のロバスト推測値が計算されて、単純統計量の戻り値行列の3つの追加の行 (行番号 14, 15, と 16) に格納されます。

IMSL_RETURN_USER, float simple_statistics[] ( 出力 )ユーザ提供の配列 simple_statisticsに統計量の行列が格納されます。

もし IMSL_MEDIAN も IMSL_MEDIAN_AND_SCALEも指定されなければ、

その行列は 14 × n_variables です。 IMSL_MEDIAN が指定されると、

その行列は 15 × n_variables です。IMSL_MEDIAN_AND_SCALE が指定

されると、その行列は 17 × n_variables です。

説明

x の各列内のデータのために、 imsl_f_simple_statistics は、標本の平均、

分散、最小値、最大値、その他の基本統計量を計算します。また、平均と分散の信頼区間も求めます(標本が正規化母集団と仮定します)。

i 番目のデータが xi である x である単一の変数について、統計の定義を以下に

示しています。

平均

分散

歪度

ixx

n= ∑

( )22

1ix x

sn

−=

−∑

( )( )

3

2 3/ 2

/

[ / ]i

i

x x n

x x n

−∑

Page 589: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

超度もしくは尖度

最小値

最大値

範囲

変動係数

中央値

中央絶対偏差

尺度の単純ロバスト推定

ここで Φ-1(3/4) ≈ 0.6745 は 3/4 で計算された標準正規分布関数の逆関数です。 これは尺度推測を、標準偏差を推測するための正規分布に一致させるために、MAD を標準化します (Huber 1981 年、p. 107-108)。

例題

Draper と Smith (1981 年 ) のデータがこの例題に使用されていて、それは 5 変数と 13 観測値を含んでいます。

#include <imsl.h>

#define N_VARIABLES 5#define N_OBSERVATIONS 13

main(){ float *simple_statistics; float x[] = {7., 26., 6., 60., 78.5, 1., 29., 15., 52., 74.3, 11., 56., 8., 20., 104.3, 11., 31., 8., 47., 87.6, 7., 52., 6., 33., 95.9,

( )( )

4

2 2

/3

[ / ]i

i

x x n

x x n

−−

−∑∑

( )min min ix x=

( )max max ix x=

max minx x−

/ for 0s x x ≠

{ }middle after sorting if is odd

median average of middle two 's if is even

ii

i

x nx

x n

=

{ }{ }MAD=median mediani jx x−

( )1MAD/ 3/ 4−Φ

Page 590: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

11., 55., 9., 22., 109.2, 3., 71., 17., 6., 102.7, 1., 31., 22., 44., 72.5, 2., 54., 18., 22., 93.1, 21., 47., 4., 26., 115.9, 1., 40., 23., 34., 83.8, 11., 66., 9., 12., 113.3, 10., 68., 8., 12., 109.4}; char *row_labels[] = {"means", "variances", "std. dev", "skewness", "kurtosis", "minima", "maxima", "ranges", "C.V.", "counts", "lower mean", "upper mean", "lower var", "upper var"};

simple_statistics = imsl_f_simple_statistics(N_OBSERVATIONS, N_VARIABLES, x, 0);

imsl_f_write_matrix("* * * Statistics * * *\n", 14, N_VARIABLES, simple_statistics, IMSL_ROW_LABELS, row_labels, IMSL_WRITE_FORMAT, "%7.3f", 0);}

出力結果

* * * Statistics * * *

1 2 3 4 5means 7.462 48.154 11.769 30.000 95.423variances 34.603 242.141 41.026 280.167 226.314std. dev 5.882 15.561 6.405 16.738 15.044skewness 0.688 -0.047 0.611 0.330 -0.195kurtosis 0.075 -1.323 -1.079 -1.014 -1.342minima 1.000 26.000 4.000 6.000 72.500maxima 21.000 71.000 23.000 60.000 115.900ranges 20.000 45.000 19.000 54.000 43.400C.V. 0.788 0.323 0.544 0.558 0.158counts 13.000 13.000 13.000 13.000 13.000lower mean 3.907 38.750 7.899 19.885 86.332upper mean 11.016 57.557 15.640 40.115 104.514lower var 17.793 124.512 21.096 144.065 116.373upper var 94.289 659.817 111.792 763.434 616.688

table_oneway観測値を一元度数分布表内に集計します。

概要

#include <imsl.h>

float *imsl_f_table_oneway (int n_observations, float x[], int _intervals, …, 0)

double 型関数は、 imsl_d_table_onewayです。

必要な引数

int n_observations ( 入力 )観測数。

float x[] ( 入力 )観測を含む長さ n_observations の配列。

int n_intervals ( 入力 )区間(bin)の数。

Page 591: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

回数を含んだ長さ n_intervals の配列。

オプション引数の概要

#include <imsl.h>

float *imsl_f_table_oneway (int n_observations, float x[], int n_intervals,IMSL_DATA_BOUNDS, float *minimum, float *maximum,IMSL_KNOWN_BOUNDS, float lower_bound, float upper_bound,IMSL_CUTPOINTS, float cutpoints[], IMSL_CLASS_MARKS, float class_marks[], IMSL_RETURN_USER, float table_oneway[], 0)

オプション引数

IMSL_DATA_BOUNDS, float *minimum, float *maximum ( 出力 )又は

IMSL_KNOWN_BOUNDS, float lower_bound, float upper_bound ( 入力 )又は

IMSL_CUTPOINTS, float cutpoints[] ( 入力 )又は

IMSL_CLASS_MARKS, float class_marks[] ( 入力 )一元表の区間もしくは bin を定義するために、これらのオプション引

数のうちの一つを指定するか、まったく指定しないことが可能です。まったく指定されない場合、又は IMSL_DATA_BOUNDS が指定される場

合、同じ長さの区間である n_intervals が x に於ける最小値で始ま

る初期区間と x に於ける最大値で終わる最終区間と共に使用されます。 初期区間は左と右が閉じます。残りの区間は左が開いて右が閉じ

ます。IMSL_DATA_BOUNDS が外示的に指定されると x の最小値と最大

値が minimum と maximum に出力されます。このオプションでは長さ (maximum−minimum)/ n_intervalsです。IMSL_KNOWN_BOUNDS が指定

されると、2 つの半無限区間が初期区間と最終区間として使用されま

す。初期区間は右が閉じていて、その右端点として lower_bound を含

みます。 最終区間は左が開いていて upper_ bound より大きい全ての

値を含みます。 残りの n_intervals − 2 区間は、それぞれ次の長さで、

左が開いて右が閉じます。

引数 n_intervals はこのオプションでは 3 より大きいか等しい必要が

あります。IMSL_CLASS_MARKS が指定されると、昇順の等間隔のクラ

ス標識を長さ n_intervals の配列 class_marksの中に用意しなけれ

ばなりません。このクラス標識は、各 n_intervals の中間点です。こ

の各中間点は、長さ class_marks [1] - class_marks [0] を持つものと

仮定されます。引数 n_intervals はこのオプションでは 2 以上でなけ

ればなりません。IMSL_ CUTPOINTS が指定されると、切断点(境界)

は長さ n_intervals − 1 の配列 cutpoints に用意されなければなりま

せん。このオプションは不等区間長さにすることができます。初期区間は右が閉じていて、その右端点として初期切断点を含みます。最終区間は左が閉じていて、最後の切断点より大きい全ての値を含みます。残りの n_intervals − 2 区間は左が開いて、右が閉じます。引数 n_intervals はこのオプションでは 3 以上でなければなりません。

IMSL_RETURN_USER, float table[] ( 出力 )回数はユーザによって提供された長さ n_intervals の配列 table に保存されます。

upper_bound lower_boundn_intervals

-2−

Page 592: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

例題 1

この例題のデータは Hinkley (1977 年 ) と Velleman と Hoaglin (1981 年 ) のもの

です。 この測定 ( 単位はインチ ) は、30連続年の4月のミネアポリス / セン

トポールの降水量です。

#include <imsl.h>main(){ int n_intervals=10; int n_observations=30; float *table; float x[] = {0.77, 1.74, 0.81, 1.20, 1.95, 1.20, 0.47, 1.43, 3.37, 2.20, 3.00, 3.09, 1.51, 2.10, 0.52, 1.62, 1.31, 0.32, 0.59, 0.81, 2.81, 1.87, 1.18, 1.35, 4.75, 2.48, 0.96, 1.89, 0.90, 2.05}; table = imsl_f_table_oneway (n_observations, x, n_intervals, 0); imsl_f_write_matrix("counts", 1, n_intervals, table, 0); }

出力結果

counts 1 2 3 4 5 6 4 8 5 5 3 1 7 8 9 10 3 0 0 1

例題 2

この例題では IMSL_KNOWN_BOUNDS が使用されて、8 つの各内部区間の幅が、

(4.5 - 0.5)/(10 - 2) = 0.5 を持つように lower_bound = 0.5 と upper_bound = 4.5 にセットされます。10 の区間は (−∞, 0.5]、 (0.5, 1.0]、 …、 (4.0, .5] と (4.5, ∞] です。

#include <imsl.h>main(){ int n_observations=30; int n_intervals=10; float *table; float lower_bound=0.5, upper_bound=4.5; float x[] = {0.77, 1.74, 0.81, 1.20, 1.95, 1.20, 0.47, 1.43, 3.37, 2.20, 3.00, 3.09, 1.51, 2.10, 0.52, 1.62, 1.31, 0.32, 0.59, 0.81, 2.81, 1.87, 1.18, 1.35, 4.75, 2.48, 0.96, 1.89, 0.90, 2.05}; table = imsl_f_table_oneway (n_observations, x, n_intervals, IMSL_KNOWN_BOUNDS, lower_bound, upper_bound, 0); imsl_f_write_matrix("counts", 1, n_intervals, table, 0); }

出力結果

counts 1 2 3 4 5 6 2 7 6 6 4 2 7 8 9 10 2 0 0 1

例題 3

この例題では 10 クラス標識 0.25、 0.75、 1.25、 ...、 4.75 が入力されます。 これは

クラス区間 (0.0, 0.5]、 (0.5, 1.0]、 …、 (4.0, 4.5]、 (4.5, 5.0] を定義します。 前の例題

と違って、その初期と最終区間は残りの区間と同じ長さであることに注意します。

Page 593: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#include <imsl.h>main(){ int n_intervals=10; int n_observations=30; double *table; double x[] = {0.77, 1.74, 0.81, 1.20, 1.95, 1.20, 0.47, 1.43, 3.37, 2.20, 3.00, 3.09, 1.51, 2.10, 0.52, 1.62, 1.31, 0.32, 0.59, 0.81, 2.81, 1.87, 1.18, 1.35, 4.75, 2.48, 0.96, 1.89, 0.90, 2.05}; double class_marks[] = {0.25, 0.75, 1.25, 1.75, 2.25, 2.75, 3.25, 3.75, 4.25, 4.75}; table = imsl_d_table_oneway (n_observations, x, n_intervals, IMSL_CLASS_MARKS, class_marks, 0); imsl_d_write_matrix("counts", 1, n_intervals, table, 0);}

出力結果

counts 1 2 3 4 5 6 2 7 6 6 4 2 7 8 9 10 2 0 0 1

例題 4

この例題では 切断点 0.5、 1.0、 1.5、 2.0、 ...、 4.5, が入力され、例題 2 と同じ 10 区間を定義します。 ここでは再び初期と最終区間が半無限区間になっています。

#include <imsl.h>main(){ int n_intervals=10; int n_observations=30; double *table; double x[] = {0.77, 1.74, 0.81, 1.20, 1.95, 1.20, 0.47, 1.43, 3.37, 2.20, 3.00, 3.09, 1.51, 2.10, 0.52, 1.62, 1.31, 0.32, 0.59, 0.81, 2.81, 1.87, 1.18, 1.35, 4.75, 2.48, 0.96, 1.89, 0.90, 2.05}; double cutpoints[] = {0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5}; table = imsl_d_table_oneway (n_observations, x, n_intervals, IMSL_CUTPOINTS, cutpoints, 0); imsl_d_write_matrix("counts", 1, n_intervals, table, 0);}

出力結果

counts1 2 3 4 5 62 7 6 6 4 2 7 8 9 102 0 0 1

chi_squared_testカイ二乗適合度検定を実行します。

概要

#include <imsl.h>

Page 594: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float imsl_f_chi_squared_test (float user_proc_cdf(), int n_observations, int n_categories, float x[], …, 0)

double 型関数は、 imsl_d_chi_squared_testです。

必要な引数

float user_proc_cdf (float y) ( 入力 ) 点 y の仮説化された累積分布関数を返すユーザ提供の関数。

int n_observations ( 入力 )x のデータ要素入力数。

int n_categories ( 入力 )観測が記録されるセルの数。

float x[] ( 入力 )この検定のデータ要素のベクトルを含んだ n_observations 成分の

配列。

戻り値

適合度カイ二乗統計の p 値。

オプション引数の概要

#include <imsl.h> float imsl_f_chi_squared_test (float *user_proc_cdf(),

int n_observations, int n_categories, float x[], IMSL_N_PARAMETERS_ESTIMATED, int n_parameters,IMSL_CUTPOINTS, float **p_cutpoints,IMSL_CUTPOINTS_USER, float cutpoints[],IMSL_CUTPOINTS_EQUAL,IMSL_CHI_SQUARED, float *chi_squared,IMSL_DEGREES_OF_FREEDOM, float *df,IMSL_FREQUENCIES, float frequencies[],IMSL_BOUNDS, float lower_bound, float upper_bound,IMSL_CELL_COUNTS, float **p_cell_counts,IMSL_CELL_COUNTS_USER, float cell_counts[],IMSL_CELL_EXPECTED, float **p_cell_expected,IMSL_CELL_EXPECTED_USER, float cell_expected[],IMSL_CELL_CHI_SQUARED, float **p_cell_chi_squared,IMSL_CELL_CHI_SQUARED_USER, float cell_chi_squared[],IMSL_FCN_W_DATA, float user_proc_cdf(), void *data,0)

オプション引数

IMSL_N_PARAMETERS_ESTIMATED, int n_parameters ( 入力 )累積分布関数の計算において推定されるパラメータ数。

IMSL_CUTPOINTS, float **p_cutpoints ( 出力 )カットポイント配列へのポインターのアドレス。(mallocへのメモ

リー割り当て要求を通して)ポインターは初期化され、配列はそこに格納されます。通常、 float *p_cutpoints が宣言され、 &p_cutpoints がこの関数への引数として使用されます。free(p_cutpoints) を使っ

てこの配列を解放します。

IMSL_CUTPOINTS_USER, float cutpoints[] ( 入力 or 出力 )ユーザによって提供される配列 cutpoints の記憶域。

IMSL_CUTPOINTS を参照。セル間隔を定義するカットポイントのベク

トルを含んだ長さ n_categories − 1 の配列。このカットポイントに

よって定義される間隔は下端点が間隔に含まれず、上端点が間隔に含まれるものです。 IMSL_CUTPOINTS_EQUAL が指定されると、等確率の

カットポイントが計算され、cutpoints に返されます。

IMSL_CUTPOINTS_EQUAL

IMSL_CUTPOINTS_USER が指定されて、加えて

IMSL_CUTPOINTS_EQUAL が指定されると等確率のカットポイントが更

Page 595: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

に使用されます。IMSL_CUTPOINTS_USERが指定されなければ、等確率

のカットポイントがデフォルトで使用されます。

IMSL_CHI_SQUARED, float *chi_squared ( 出力 )指定されると、カイ二乗検定統計量が *chi_squaredに返されます。

IMSL_DEGREES_OF_FREEDOM, float *df ( 出力 )指定されると、カイ二乗適合度検定の自由度が *df に返されます。

IMSL_FREQUENCIES, float frequencies[] ( 入力 )x に格納される観測のベクトル度数を含む n_observations 成分の

配列。

IMSL_BOUNDS, float lower_bound, float upper_bound ( 入力 )IMSL_BOUNDS が指定される時、lower_bound は分布の範囲の下限

で、upper_bound はこの範囲の上限です。lower_bound = upper_bound であれば全体の実線の範囲が使用されます(デフォル

ト)。下端点と上端点が異なればこれらの限界の外側の点は無視されます。IMSL_BOUNDS が使用される時、範囲の分布条件を指定する事が出

来ます。規定として、lower_bound は最初の間隔から除外されます

が、upper_bound は最後の間隔に含まれます。

IMSL_CELL_COUNTS, float **p_cell_counts ( 出力 )セル回数を含む配列のポインターのアドレス。セル回数は、各 n_categories セルの観測された度数です。 (mallocへのメモリー

割り当て要求を通して)ポインターは初期化され、配列はそこに格納されます。通常、 float *p_cell_counts が宣言され、 &p_cell_counts がこの関数への引数として使用されます。free(p_cell_counts) を使ってこの配列を解放します。

IMSL_CELL_COUNTS_USER, float cell_counts[] ( 出力 )指定されると、n_categoriesのセル回数は、ユーザ提供の配列

cell_countsに返されます。

IMSL_CELL_EXPECTED, float **p_cell_expected ( 出力 )セル期待値へのポインターのアドレス。仮説化された分布が正しいとすれば、セルの期待値はセルの予期された回数です。(mallocへのメ

モリー割り当て要求を通して)ポインターは初期化され、配列はそこに格納されます。通常、 float *p_cell_expected が宣言され、 &p_cell_expected がこの関数への引数として使用されます。

free(p_cell_expected) を使ってこの配列を解放します。

IMSL_CELL_EXPECTED_USER, float cell_expected[] ( 出力 )指定されると、n_categoriesのセル期待値は、ユーザによって提供され

た配列配列 cell_expectedに返されます。

IMSL_CELL_CHI_SQUARED, float **p_cell_chi_squared ( 出力 )カイ二乗のセルの寄与を含む長さ n_categoriesの配列へのポイン

ターのアドレス。 (mallocへのメモリー割り当て要求を通して)ポイ

ンターは初期化され、配列はそこに格納されます。通常、 float *p_cell_chi_squared が宣言され、 &p_cell_chi_squared がこの関

数への引数として使用されます。free(p_cell_chi_squared) を使っ

てこの配列を解放します。

IMSL_CELL_CHI_SQUARED_USER, float cell_chi_squared[] ( 出力 )指定されると、カイ二乗へのセルの寄与は、ユーザによって提供される配列 cell_chi_squaredに返されます。

IMSL_FCN_W_DATA, float user_proc_cdf (float y, void *data), void *data, (入力 )y 点における仮定された累積分布関数を戻すユーザ提供の関数。また、

ユーザにより提供されたデータへのポインターも受け入れます。 data は、ユーザ提供の関数にデータを受け渡すポインターです。 詳細は、

Page 596: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

「イントロダクション」の「ユーザ提供関数へのデータの受け渡し」を参照してください。

説明

関数 imsl_f_chi_squared_test は観測の無作為標本が、指定された理論累

積分布に従って分布されたカイ二乗適合度検定を実行します。連続、離散、離散と連続の混合であるこの理論分布は、ユーザ定義の関数 user_proc_cdf によって指定されます。ユーザは観測の範囲を与える事が出来るので、指定された範囲の条件が付いた検定が実行されます。

引数 n_categories は観測が分割される間隔数を与えます。デフォルトで同

程度の確率の間隔は imsl_f_chi_squared_test によって計算されますが、同

程度の確率でない間隔はオプション引数 IMSL_CUTPOINTS の使って指定する事

ができます。

カットポイントを得るために使用される方法には関係無く、その間隔は下端点が間隔に含まれず上端点は常に含まれます。累積分布関数が離散要素を持てば、imsl_f_chi_squared_test は離散分布の中の離散要素を決定できないの

で、ユーザ提供のカットポイントが常に使用されなければなりません。

デフォルトで、最初と最後の間隔の下端点と上端点は、それぞれ −∞ η +∞ です。IMSL_BOUNDS が指定されると、その両端点は2つの引数 lower_bound と upper_bound を使用してユーザによって定義されます。

x の観測に対して回数の集計は次のように行われます。 カットポイントがユー

ザによって指定される場合、集計は x i が属する間隔で行われます。 カットポイ

ントが imsl_f_chi_squared_test によって 決定されると、x i の累積確率 F(x

i) は関数 user_proc_cdf によって計算されます。

x i の記録は間隔番号 mF(xI ) + 1 に作られて、ここに m = n_categories で · は関数の引数よりは大きくない最大の整数を取る関数です。こうして、累

積分布関数を計算するコンピュータの時間が大きくても、ユーザ指定の分離点は全計算時間を減少するために優先される可能性があります。

セルの期待される回数が1より小さいならば、カイ二乗近似が推測されます。この結果の警告メッセージは期待値が5より小さい場合と同様にこの場合にも発行されます。

プログラミングの注意点

ユーザは、呼び出し列 user_proc_cdf(y) を持つ関数 user_proc_cdfを提供

する必要があります。その関数は、(指定した範囲内の(オプション))どのy における累積分布関数の値を返します。第 9 章「特殊関数」ないの累積分

布関数の多くは、関数 user_proc_cdf は、(オプションによって)コーリン

グシーケンス user_proc_cdf(y) (指定した範囲のある点 y の累積分布関

数の値を返す) を指定しなければなりません。第 9 章「特殊関数」の多くの累

積分布関数「確率分布数と逆関数」は、呼び出し順が正しければ直接的に、又は例えば標本平均と標準偏差が理論的累積分布関数を計算するために使用されるのなら間接的に、user_proc_cdf によって使用されます。

例題

例題 1

この例題は imsl_f_chi_squared_test の正規分布から無作為に生成された

標本上の使用法を説明します。1,000 の無作為に生成された観測は、ほぼ等間

隔に 10 分類で記録されます。標本が正規分布からの帰無仮説は仮説された分

布関数として imsls_f_normal_cdf ( 第 9 章「特殊関数」) の使用によって

指定されます。この例題では帰無仮説は棄却されません。

#include <imsl.h>

#define SEED 123457#define N_CATEGORIES 10#define N_OBSERVATIONS 1000

main()

Page 597: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{ float *x, p_value;

imsl_random_seed_set(SEED); /* 標準偏差を生成 */ x = imsl_f_random_normal (N_OBSERVATIONS, 0); /* カイ二乗検定を実行 */ p_value = imsl_f_chi_squared_test (imsl_f_normal_cdf, N_OBSERVATIONS, N_CATEGORIES, x, 0); /* 結果をプリント */ printf ("p value %7.4f\n", p_value);}

出力結果

p value 0.1546

例題 2

この例題は、最初の例題にオプション引数が使用されています。

#include <imsl.h>

#define SEED 123457#define N_CATEGORIES 10#define N_OBSERVATIONS 1000

main(){ float *cell_counts, *cutpoints, *cell_chi_squared; float chi_squared_statistics[3], *x; char *stat_row_labels[] = {"chi-squared", "degrees of freedom", "p-value"}; imsl_random_seed_set(SEED); /* Generate Normal deviates */ x = imsl_f_random_normal (N_OBSERVATIONS, 0); /* カイ二乗検定の実行 */ chi_squared_statistics[2] = imsl_f_chi_squared_test (imsl_f_normal_cdf, N_OBSERVATIONS, N_CATEGORIES, x, IMSL_CUTPOINTS, &cutpoints, IMSL_CELL_COUNTS, &cell_counts, IMSL_CELL_CHI_SQUARED, &cell_chi_squared, IMSL_CHI_SQUARED, &chi_squared_statistics[0], IMSL_DEGREES_OF_FREEDOM, &chi_squared_statistics[1], 0); /* 結果をプリント */ imsl_f_write_matrix ("\nChi Squared Statistics\n", 3, 1, chi_squared_statistics, IMSL_ROW_LABELS, stat_row_labels, 0); imsl_f_write_matrix ("Cut Points", 1, N_CATEGORIES-1, cutpoints, 0); imsl_f_write_matrix ("Cell Counts", 1, N_CATEGORIES, cell_counts, 0); imsl_f_write_matrix ("Cell Contributions to Chi-Squared", 1, N_CATEGORIES, cell_chi_squared, 0);}

出力結果

Chi Squared Statistics

chi-squared 13.18degrees of freedom 9.00p-value 0.15

Page 598: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Cut Points 1 2 3 4 5 6 -1.282 -0.842 -0.524 -0.253 -0.000 0.253 7 8 9 0.524 0.842 1.282

Cell Counts 1 2 3 4 5 6 106 109 89 92 83 87 7 8 9 10 110 104 121 99 Cell Contributions to Chi-Squared 1 2 3 4 5 6 0.36 0.81 1.21 0.64 2.89 1.69 7 8 9 10 1.00 0.16 4.41 0.01

例題 3

この例題では、パラメータ θ = 5.0 を持つサイズ 1,000 の離散ポアソン無作為

標本が関数 imsl_f_random_poisson (627 ページ) によって発生されます。

imsl_f_chi_squared_test の呼び出しに、関数 imsl_f_poisson_cdfが、関

数 user_proc_cdf として使用されます。

#include <imsl.h>

#define SEED 123457#define N_CATEGORIES 10#define N_PARAMETERS_ESTIMATED 0#define N_NUMBERS 1000#define THETA 5.0

float user_proc_cdf(float);

main(){ int i, *poisson; float cell_statistics[3][N_CATEGORIES]; float chi_squared_statistics[3], x[N_NUMBERS]; float cutpoints[] = {1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5}; char *cell_row_labels[] = {"count", "expected count", "cell chi-squared"}; char *cell_col_labels[] = {"Poisson value", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; char *stat_row_labels[] = {"chi-squared", "degrees of freedom", "p-value"};

imsl_random_seed_set(SEED); /* dataを生成 */ poisson = imsl_random_poisson(N_NUMBERS, THETA, 0); /* 浮動小数点ベクトルにデータをコピー */ for (i = 0; i < N_NUMBERS; i++) x[i] = poisson[i];

chi_squared_statistics[2] = imsl_f_chi_squared_test(user_proc_cdf, N_NUMBERS, N_CATEGORIES, x, IMSL_CUTPOINTS_USER, cutpoints, IMSL_CELL_COUNTS_USER, &cell_statistics[0][0], IMSL_CELL_EXPECTED_USER, &cell_statistics[1][0], IMSL_CELL_CHI_SQUARED_USER, &cell_statistics[2][0], IMSL_CHI_SQUARED, &chi_squared_statistics[0],

Page 599: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_DEGREES_OF_FREEDOM, &chi_squared_statistics[1], 0); /* 結果をプリント */ imsl_f_write_matrix("\nChi-squared statistics\n", 3, 1, &chi_squared_statistics[0], IMSL_ROW_LABELS, stat_row_labels, 0); imsl_f_write_matrix("\nCell Statistics\n", 3, N_CATEGORIES, &cell_statistics[0][0], IMSL_ROW_LABELS, cell_row_labels, IMSL_COL_LABELS, cell_col_labels, 0);}

float user_proc_cdf(float k){ float cdf_v;

cdf_v = imsl_f_poisson_cdf ((int) k, THETA); return cdf_v;}

出力結果

Chi-squared statistics

chi-squared 10.48degrees of freedom 9.00p-value 0.31 Cell Statistics

Poisson value 0 1 2 3 4count 41.0 94.0 138.0 158.0 150.0expected count 40.4 84.2 140.4 175.5 175.5cell chi-squared 0.0 1.1 0.0 1.7 3.7 Poisson value 5 6 7 8 9count 159.0 116.0 75.0 37.0 32.0expected count 146.2 104.4 65.3 36.3 31.8cell chi-squared 1.1 1.3 1.4 0.0 0.0

警告エラー

IMSL_EXPECTED_VAL_LESS_THAN_1 期待値は、1 未満です。

IMSL_EXPECTED_VAL_LESS_THAN_5 期待値は、5 未満です。

重大エラー

IMSL_ALL_OBSERVATIONS_MISSING 全ての観測に欠損値が含まれています。

IMSL_INCORRECT_CDF_1 関数 user_proc_cdf は、累積分布関数

ではありません。下限での値は非負ので、上限の値は 1 以上でなければなりま

せん。

IMSL_INCORRECT_CDF_2 関数 user_proc_cdf は、累積分布関数

ではありません。分布の範囲の確率は、正ではありません

IMSL_INCORRECT_CDF_3 関数 user_proc_cdf は、累積分布関数

ではありません。x 内の要素での計算

は、下限もしくは上限での計算と不整合です。

Page 600: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_INCORRECT_CDF_4 関数 user_proc_cdf は、累積分布関数

ではありません。 カットポイントでの計

算は、下限もしくは上限での計算と不整合です。

IMSL_INCORRECT_CDF_5 累積分布関数を逆にする際、エラーが発

生しました。この関数は、連続し、全て実数線上で定義されなければなりません。

covariances標本の分散共分散行列、又は相関行列を計算します。

概要

#include <imsl.h>

float *imsl_f_covariances (int n_observations, int n_variables, float x[], …, 0)

double 型関数は、 imsl_d_covariancesです。

必要な引数

int n_observations ( 入力 )観測数。

int n_variables ( 入力 )変数の数。

float x[] ( 入力 )データの行列を含んだサイズ n_observations × n_variables の配

列。

戻り値

オプション引数が使用されなければ imsl_f_covariances は観測の標本分

散共分散行列を含んだ n_variables × n_variables 行列のポインターを

返します。この行列の行と列は x の列に対応します。

オプション引数の概要

#include <imsl.h> float *imsl_f_covariances (int n_observations, int n_variables,

float x[], IMSL_X_COL_DIM, int x_col_dim,IMSL_VARIANCE_COVARIANCE_MATRIX,IMSL_CORRECTED_SSCP_MATRIX,IMSL_CORRELATION_MATRIX,IMSL_STDEV_CORRELATION_MATRIX,IMSL_MEANS, float **p_means,IMSL_MEANS_USER, float means[],IMSL_COVARIANCE_COL_DIM, int covariance_col_dim,IMSL_RETURN_USER, float covariance[],0)

オプション引数

IMSL_X_COL_DIM, int x_col_dim ( 入力 )配列 x の列ディメンジョン。

デフォルト: x_col_dim = n_variables

IMSL_VARIANCE_COVARIANCE_MATRIX, orIMSL_CORRECTED_SSCP_MATRIX, orIMSL_CORRELATION_MATRIX, orIMSL_STDEV_CORRELATION_MATRIX

正確にこれらのオプションの1つが計算される行列のタイプを指定するために使用することが出来ます。

Page 601: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_MEANS, float **p_means ( 出力 )x の中の変数の平均を含んだ配列のポインターのアドレス。この配列

の要素は x の列に対応します。返されると、このポインターは初期化

され( malloc を要求するメモリ割り当てを通して)、配列はそこに格

納されます。通常、float *p_means が宣言され、&p_means がこの関

数の引数として使用されて、free(p_means) がこの配列を開放するた

めに使用されます。

IMSL_MEANS_USER, float means[] ( 出力 )n_variables の平均が計算され、それらがユーザによって提供され

る記憶域に格納されます。means の要素は x の列に対応します。

IMSL_COVARIANCE_COL_DIM, int covariance_col_dim ( 入力 )IMSL_RETURN_USER が指定された場合は、配列 covariance の列

ディメンジョン。その他の場合は、戻り値の列ディメンジョン。デフォルト: covariance_col_dim = n_variables

IMSL_RETURN_USER, float covariance[] ( 出力 )これが指定されると、出力はサイズ n_variables × n_variables のユーザによって提供される配列 covariance に格納されます。

説明

関数 imsl_f_covariances はデータ行列 x の相関、共分散、又は平方和とク

ロス積和の推定を計算します。平均、( 修正 ) 平方和、( 修正 ) クロス積和は暫

定平均法を使用して計算されます。

k 番目の変数の i 観測に基づく平均を示すものとして、cjki を i 観測に基づく

クロス積和(又は j = k であれば平方和)であるものとします。すると暫定平

均法は次式のような新しい平均とクロス積和を見つけます。

この平均とクロス積は次のように初期化されます。

この p は変数の数を示しています。x k,i+1 を観測 i + 1 の k 番目の変数とする

と、各新しい観測は更新定数 r i+1 を使用します。

と cjki の次の更新に導かれます。

キーワード 行列の種類IMSL_VARIANCE_COVARIANCE_MATRIX 分散共分散行列 ( デフォルト )IMSL_CORRECTED_SSCP_MATRIX 修正平方和とクロス積和行列IMSL_CORRELATION_MATRIX 相関行列IMSL_STDEV_CORRELATION_MATRIX 標準偏差の対角項を除いた相関行列

kix

0

0

0.0 1, ,0.0 , 1, ,

k

jk

x k pc j k p

= == =

K

K

kix

( )( ) ( ) ( )

1

, 1 , 1 1

, 1 , 1 , 1 1

11

1

i

k i ki k i ki i

jk i jki j i ji k i ki i

ri

x x x x r

c c x x x x r

+

+ + +

+ + + +

=+

= + −

= + − − −

Page 602: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

使用法

関数 imsl_f_covariances 標本平均の次式の定義を使用します。

この n は観測数です。次の公式は変数 j と k の間の標本共分散 sj k を定義しま

す。

変数 j と k の間の標本相関、rjk は次のように定義されます。

例題

例題 1

この最初の例題は、Fisher のアイリス・データ (Fisher 1936 年 ) の最初の 50 観

測に対する imsl_f_covariances の使用を説明します。

#include <imsl.h>

#define N_VARIABLES 5#define N_OBSERVATIONS 50

main(){ float *covariances; float x[] = {1.0, 5.1, 3.5, 1.4, .2, 1.0, 4.9, 3.0, 1.4, .2, 1.0, 4.7, 3.2, 1.3, .2, 1.0, 4.6, 3.1, 1.5, .2, 1.0, 5.0, 3.6, 1.4, .2, 1.0, 5.4, 3.9, 1.7, .4, 1.0, 4.6, 3.4, 1.4, .3, 1.0, 5.0, 3.4, 1.5, .2, 1.0, 4.4, 2.9, 1.4, .2, 1.0, 4.9, 3.1, 1.5, .1, 1.0, 5.4, 3.7, 1.5, .2, 1.0, 4.8, 3.4, 1.6, .2, 1.0, 4.8, 3.0, 1.4, .1, 1.0, 4.3, 3.0, 1.1, .1, 1.0, 5.8, 4.0, 1.2, .2, 1.0, 5.7, 4.4, 1.5, .4, 1.0, 5.4, 3.9, 1.3, .4, 1.0, 5.1, 3.5, 1.4, .3, 1.0, 5.7, 3.8, 1.7, .3, 1.0, 5.1, 3.8, 1.5, .3, 1.0, 5.4, 3.4, 1.7, .2, 1.0, 5.1, 3.7, 1.5, .4, 1.0, 4.6, 3.6, 1.0, .2, 1.0, 5.1, 3.3, 1.7, .5, 1.0, 4.8, 3.4, 1.9, .2, 1.0, 5.0, 3.0, 1.6, .2, 1.0, 5.0, 3.4, 1.6, .4, 1.0, 5.2, 3.5, 1.5, .2, 1.0, 5.2, 3.4, 1.4, .2, 1.0, 4.7, 3.2, 1.6, .2, 1.0, 4.8, 3.1, 1.6, .2, 1.0, 5.4, 3.4, 1.5, .4, 1.0, 5.2, 4.1, 1.5, .1, 1.0, 5.5, 4.2, 1.4, .2, 1.0, 4.9, 3.1, 1.5, .2, 1.0, 5.0, 3.2, 1.2, .2, 1.0, 5.5, 3.5, 1.3, .2, 1.0, 4.9, 3.6, 1.4, .1, 1.0, 4.4, 3.0, 1.3, .2, 1.0, 5.1, 3.4, 1.5, .2, 1.0, 5.0, 3.5, 1.3, .3, 1.0, 4.5, 2.3, 1.3, .3, 1.0, 4.4, 3.2, 1.3, .2, 1.0, 5.0, 3.5, 1.6, .6, 1.0, 5.1, 3.8, 1.9, .4, 1.0, 4.8, 3.0, 1.4, .3, 1.0, 5.1, 3.8, 1.6, .2, 1.0, 4.6, 3.2, 1.4, .2, 1.0, 5.3, 3.7, 1.5, .2, 1.0, 5.0, 3.3, 1.4, .2};

covariances = imsl_f_covariances (N_OBSERVATIONS, N_VARIABLES, x, 0); imsl_f_write_matrix ("The default case: variances/covariances", N_VARIABLES, N_VARIABLES, covariances,

1

nkii

k

xx

n== ∑

( )( )1

1

nji j ki ki

jk

x x x xs

n=

− −=

−∑

jkjk

jj kk

sr

s s=

Page 603: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_PRINT_UPPER, 0);}

出力結果

The default case: variances/covariances 1 2 3 4 51 0.0000 0.0000 0.0000 0.0000 0.00002 0.1242 0.0992 0.0164 0.01033 0.1437 0.0117 0.00934 0.0302 0.00615 0.0111

例題 2

この例題で、imsl_f_covariances の幾つかのオプション引数の使用が説明

されます。もう一度、Fisher のアイリス・データの最初の 50 観測が使用され

ています。

#include <imsl.h>

#define N_VARIABLES 5#define N_OBSERVATIONS 50

main(){ char *title; float *means, *correlations; float x[] = {1.0, 5.1, 3.5, 1.4, .2, 1.0, 4.9, 3.0, 1.4, .2, 1.0, 4.7, 3.2, 1.3, .2, 1.0, 4.6, 3.1, 1.5, .2, 1.0, 5.0, 3.6, 1.4, .2, 1.0, 5.4, 3.9, 1.7, .4, 1.0, 4.6, 3.4, 1.4, .3, 1.0, 5.0, 3.4, 1.5, .2, 1.0, 4.4, 2.9, 1.4, .2, 1.0, 4.9, 3.1, 1.5, .1, 1.0, 5.4, 3.7, 1.5, .2, 1.0, 4.8, 3.4, 1.6, .2, 1.0, 4.8, 3.0, 1.4, .1, 1.0, 4.3, 3.0, 1.1, .1, 1.0, 5.8, 4.0, 1.2, .2, 1.0, 5.7, 4.4, 1.5, .4, 1.0, 5.4, 3.9, 1.3, .4, 1.0, 5.1, 3.5, 1.4, .3, 1.0, 5.7, 3.8, 1.7, .3, 1.0, 5.1, 3.8, 1.5, .3, 1.0, 5.4, 3.4, 1.7, .2, 1.0, 5.1, 3.7, 1.5, .4, 1.0, 4.6, 3.6, 1.0, .2, 1.0, 5.1, 3.3, 1.7, .5, 1.0, 4.8, 3.4, 1.9, .2, 1.0, 5.0, 3.0, 1.6, .2, 1.0, 5.0, 3.4, 1.6, .4, 1.0, 5.2, 3.5, 1.5, .2, 1.0, 5.2, 3.4, 1.4, .2, 1.0, 4.7, 3.2, 1.6, .2, 1.0, 4.8, 3.1, 1.6, .2, 1.0, 5.4, 3.4, 1.5, .4, 1.0, 5.2, 4.1, 1.5, .1, 1.0, 5.5, 4.2, 1.4, .2, 1.0, 4.9, 3.1, 1.5, .2, 1.0, 5.0, 3.2, 1.2, .2, 1.0, 5.5, 3.5, 1.3, .2, 1.0, 4.9, 3.6, 1.4, .1, 1.0, 4.4, 3.0, 1.3, .2, 1.0, 5.1, 3.4, 1.5, .2, 1.0, 5.0, 3.5, 1.3, .3, 1.0, 4.5, 2.3, 1.3, .3, 1.0, 4.4, 3.2, 1.3, .2, 1.0, 5.0, 3.5, 1.6, .6, 1.0, 5.1, 3.8, 1.9, .4, 1.0, 4.8, 3.0, 1.4, .3, 1.0, 5.1, 3.8, 1.6, .2, 1.0, 4.6, 3.2, 1.4, .2, 1.0, 5.3, 3.7, 1.5, .2, 1.0, 5.0, 3.3, 1.4, .2};

correlations = imsl_f_covariances (N_OBSERVATIONS, N_VARIABLES-1, x+1, IMSL_STDEV_CORRELATION_MATRIX, IMSL_X_COL_DIM, N_VARIABLES, IMSL_MEANS, &means, 0); imsl_f_write_matrix ("Means\n", 1, N_VARIABLES-1, means, 0); title = "Correlations with Standard Deviations on the Diagonal\n"; imsl_f_write_matrix (title, N_VARIABLES-1, N_VARIABLES-1, correlations, IMSL_PRINT_UPPER, 0);}

Page 604: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

Means

1 2 3 45.006 3.428 1.462 0.246 Correlations with Standard Deviations on the Diagonal

1 2 3 41 0.3525 0.7425 0.2672 0.27812 0.3791 0.1777 0.23283 0.1737 0.33164 0.1054

警告エラー

IMSL_CONSTANT_VARIABLE 相関が要求されたが、1 つかそれ以上の観測

が一定値です。対応する相関は NaN に設定

されます。

regression最小二乗法を使用して多重線形回帰モデルを当てはめます。

概要

#include <imsl.h>

float *imsl_f_regression (int n_observations, int n_independent, float x[], float y[], …, 0)

double 型関数は、 imsl_d_regressionです。

必要な引数

int n_observations ( 入力 )観測数。

int n_independent ( 入力 )独立 ( 説明 ) 変数の数。

float x[] ( 入力 )独立 ( 説明 ) 変数の行列を含んだサイズ n_observations × n_independent の配列。

float y[] ( 入力 )従属(応答)変数を含んだ長さ n_observations の配列。

戻り値

オプション引数 IMSL_NO_INTERCEPT が使用されない場合は、

imsl_f_regression は回帰係数の最小二乗解を含んだ長さ

n_independent + 1 の配列のポインターを返します。推定される切片はこの

配列の最初の要素です。

オプション引数の概要

#include <imsl.h>float *imsl_f_regression (int n_observations, int n_independent,

float x[], float y[],IMSL_X_COL_DIM, int x_col_dim,IMSL_NO_INTERCEPT,IMSL_TOLERANCE, float tolerance,IMSL_RANK, int *rank,IMSL_COEF_COVARIANCES, float **p_coef_covariances,IMSL_COEF_COVARIANCES_USER, float coef_covariances[],IMSL_COV_COL_DIM, int cov_col_dim, IMSL_X_MEAN, float **p_x_mean,

Page 605: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_X_MEAN_USER, float x_mean[], IMSL_RESIDUAL, float **p_residual, IMSL_RESIDUAL_USER, float residual[], IMSL_ANOVA_TABLE, float **p_anova_table, IMSL_ANOVA_TABLE_USER, float anova_table[], IMSL_RETURN_USER, float coefficients[], 0)

オプション引数

IMSL_X_COL_DIM, int x_col_dim ( 入力 )x の列ディメンジョン。

デフォルト: x_col_dim = n_independent

IMSL_NO_INTERCEPTデフォルトによって、観測 i の当てはめ値は、以下のように表されま

す。

ここで k = n_independent です。 IMSL_NO_INTERCEPT が指定され

ると、切片項

はモデルから外されます。

IMSL_TOLERANCE, float tolerance ( 入力 )線形依存を決定に使用される許容値。imsl_f_regression に対して

は tolerance = 100 × imsl_f_machine(4) がデフォルト選択しま

す。imsl_d_regression に対しては tolerance = 100 × imsl_d_machine(4) がデフォルト。imsl_f_machine (635 ページ ) を参照してください。

IMSL_RANK, int *rank ( 出力 )当てはめモデルの階数が *rank に返されます。

IMSL_COEF_COVARIANCES, float **p_coef_covariances ( 出力 )推定される回帰係数の推定される分散と共分散を含んだ m × m 配列

のポインターのアドレス。m はモデルの回帰係数の数です。

IMSL_NO_INTERCEPT が指定される場合は, m = n_independent、その他の場合は m = n_independent + 1 になります。返されると、

このポインターは初期化されて( malloc を要求するメモリ割り当て

を通して)、配列はそこに格納されます。一般的には float *p_coef_covariances が宣言されて、&p_coef_covariances がこの

関数の引数として使用され、この配列を開放するために free(p_coef_covariances) が使用されます。

IMSL_COEF_COVARIANCES_USER, float coef_covariances[] ( 出力 )これが指定されると coef_covariances は m がモデルの回帰係数

の数で推定される係数の推定される分散と共分散を含んだ長さ m × m の配列になります。

IMSL_COV_COL_DIM, int cov_col_dim ( 入力 )配列 coef_covariance の列ディメンジョン。

デフォルト: cov_col_dim = m ここで m は、モデルの回帰係数の数。

IMSL_X_MEAN, float **p_x_mean ( 出力 )独立変数の推定される平均を含んだ配列のポインターのアドレス。返されると、このポインターは初期化されて( malloc を要求するメモ

リ割り当てを通して)、配列はそこに格納されます。一般的には float *p_x_meanが宣言されて、&p_x_meanがこの関数の引数として使用さ

れ、この配列を開放するために free(p_x_mean) が使用されます。

0 1 1ˆ ˆ ˆ

k kx xβ β β+ + +K

Page 606: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_X_MEAN_USER, float x_mean[] ( 出力 )これが指定されると x_mean はユーザによって提供される長さ n_independent の配列になります。返されると x_mean は独立変

数の平均を含みます。

IMSL_RESIDUAL, float **p_residual ( 出力 )残差ベクトル b − Ax を含んだサイズ m の配列のポインターのアドレ

ス。返される時、(malloc へのメモリ割り当て要求を通して)ポインターが初期化され、配列はそこに格納されます。通常、宣言されるのは float *p_residual で、引数として使用されるのは &p_residualで

す。free(p_residual) を使ってこの配列を解放します。

IMSL_RESIDUAL_USER, float residual[] ( 出力 )これが指定されると residual はユーザによって提供される長さ n_observations の配列になります。返されると residual はその

残差を含みます。

IMSL_ANOVA_TABLE, float **p_anova_table ( 出力 )分散表の解析結果を含んだ配列のポインターのアドレス。返されると、このポインターは初期化されて( malloc を要求するメモリ割り当て

を通して)、配列はそこに格納されます。通常、 float *p_anova_table が宣言されて、&p_anova_table がこの関数の引数として使用され、

そしてこの配列を開放するために free(p_anova_table) が使用され

ます。

分散統計の解析は、次の様に与えられます。

IMSL_ANOVA_TABLE_USER, float anova_table[] ( 出力 )これが指定されると上にリストされた分散の 15 解析が計算されて、

ユーザによって提供される配列 anova_table に格納されます。

IMSL_RETURN_USER, float coefficients[] ( 出力 )これが指定されるとき、回帰係数の最小二乗解がユーザによって提供される配列 coefficients に格納されます。IMSL_NO_INTERCEPT が指定されるときには、この配列は記憶域の m = n_independent 単位を要求します。そうでない場合は、記憶域の単位は m = n_independent + 1 です。

説明

関数 imsl_f_regression は切片が有る、又は無しの多重線形回帰モデルを当

てはめます。デフォルトによって、この多重線形回帰モデルは、以下の様になります。

yi = β0 + β1xi1 +β2xi2 + … + βkxik + εi i = 1, 2, …, n

要素 分散統計の解析0 モデルの自由度1 誤差の自由度2 全 ( 修正 ) 自由度3 モデルの平方和4 誤差の平方和5 全 ( 修正 ) 平方和6 モデル平均二乗7 エラー平均二乗8 総括 F 統計9 p 値10 R 2 ( パーセント )11 修正された R 2 ( パーセント )12 標準偏差の推定13 y の総括平均14 分散の係数 ( パーセント )

Page 607: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで yi (y の入力 ) の観測値は従属変数の値の応答、 xi1、 xi2、…、xik (x の入

力 ) は k ( n_independent の入力 ) 独立変数の設定、 β0、β1、… β k は回帰

係数でその推定された値が imsl_f_regression による出力となります。そ

して εi はそれぞれが平均0と分散 σ2 を持つ独立に分散された正規誤差にな

ります。ここで n は増加された行列 (x, y) の行数、即ち n は

n_observations に等しくなります。デフォルトでは β0 はモデルの中に含ま

れることに注意してください。

関数 imsl_f_regression は n 観測の当てはめられた応答

から観測された応答 yi との偏差の二乗和を最小化することによって回帰係数

の推定を計算します。この二乗和の最小化(誤差二乗和)はIMSL_ANOVA_TABLE (又はIMSL_ANOVA_TABLE_USER)が指定されていると

分散統計の解析の1つとして出力されて、次式として計算されます。for the n

分散統計の他の解析は全平方和です。デフォルトによって、全平方和は、その平均

からの yi の偏差の二乗和で、いわゆる修整全平方和です。この統計値は以下

の式で計算されます。

IMSL_NO_INTERCEPT が指定されるとき、全平方和は yi の二乗和でいわゆる

無修整全平方和です。これは次式で計算されます。

多重線形回帰モデル、その解析、そして多くの例題の一般取り扱いは Draper と Smith (1981 年 ) を参照してください。

最小二乗解を計算するために、imsl_f_regression は回帰子の行列の上三角

形式への直交縮役を実行します。この縮約は高速 Givens 変換を使用する増加

された行列 (x, y) の行を通る 1 パスに基づいています。 (Golub と Van Loan 1983年、156、 162 ページ; Gentleman 1974 年を参照。) この方法は正規方程式に使

用されるクロス積行列の形成に起因する精度の欠落を回避する利点を持っています。

デフォルトによって、従属と独立変数の現在の平均が。改良された精度のために内部的にデータを中心に置くために使用されます。 xi を独立変数のデータの

j 番目の行を含んだ列ベクトルとします。 を行 1, 2, ..., i のデータが与えられ

た独立変数の平均ベクトルを表すものとします。現在の平均ベクトルは次式になるものと定義されます。

ˆiy

( )2

1

ˆSSEn

i ii

y y=

= −∑

y

( )2

1

SSTn

ii

y y=

= −∑

2

1

SSTn

ii

y=

= ∑

ix

1

ijj

i

xx

i==

Page 608: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

データの i 番目の行はそれから引かれた を持ち、 i/(i - 1) によって加重され

ます。クロス積行列は計算されませんが、この中心揃えの正当性は平方和とクロス積和の次の公式から知ることが可能です。

中心揃え行列の直交縮約が計算されます。最終の計算が実行されるとき、元の(中心揃えがされない)データの統計量を反映するために、切片の推定、推定係数の推定共分散行列の最初の行と列が更新されます (IMSL_COEF_COVARIANCES 又は IMSL_COEF_COVARIANCES_USER が指定

されるならば ) 。これは切片の推定が、中心揃えされないデータのためである

ことを意味します。

最終計算の一部として、imsl_f_regression は線形依存回帰子をチェックし

ます。特に回帰子の線形依存は次の 3 つの条件が満足されたときに宣言されま

す。

• 回帰子がゼロに等しい。

• 2 つ以上の回帰子が定数である。

が tolerance 以下である。ここで、 R i• 1,2, …, i-1 は、最初に i - 1 の独立変数を持つ、i 番目の独立変数の多重相関係数です。このモデル

の切片がなければ「多重回帰」係数が平均の調整なしに計算されます。

最終計算の完了で、i 番目の回帰子が、 i - 1 回帰子に線形依存であると宣言さ

れる場合、i 番目の係数推定と、推定される係数の推定される分散-共分散行

列の i 番目の行と i 番目の列の全ての要素が( IMSL_COEF_COVARIANCES 又は IMSL_COEF_COVARIANCES_USER が指定されるならば)ゼロにセット

されます。終わりに、線形依存が宣言される場合、情報を与える (エラー )メッセージ、コード IMSL_RANK_DEFICIENT がこのモデルが完全階数ではな

いことを示します。

例題

例題 1

次の回帰モデルをを Maindonald (1984 年、203-204 ページ ) から得られたデー

タに当てはめます。

#include <imsl.h>

#define INTERCEPT 1#define N_INDEPENDENT 3#define N_COEFFICIENTS (INTERCEPT + N_INDEPENDENT)#define N_OBSERVATIONS 9

main(){ float *coefficients; float x[][N_INDEPENDENT] = {7.0, 5.0, 6.0, 2.0,-1.0, 6.0, 7.0, 3.0, 5.0, -3.0, 1.0, 4.0, 2.0,-1.0, 0.0, 2.0, 1.0, 7.0,

ix

( )( ) ( )( )1 2 1

n nT T

i n i n i i i ii i

ix x x x x x x xi= =

− − = − −−∑ ∑

21,2, , 11 i iR ⋅ −− K

0 1 1 2 2 3 3 1, 2, , 9i i i i iy x x x iβ β β β ε= + + + + = K

Page 609: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

-3.0,-1.0, 3.0, 2.0, 1.0, 1.0, 2.0, 1.0, 4.0}; float y[] = {7.0,-5.0, 6.0, 5.0, 5.0, -2.0, 0.0, 8.0, 3.0};

coefficients = imsl_f_regression(N_OBSERVATIONS, N_INDEPENDENT, (float *)x, y, 0); imsl_f_write_matrix("Least-Squares Coefficients", 1, N_COEFFICIENTS, coefficients, IMSL_COL_NUMBER_ZERO, 0);}

出力結果

Least-Squares Coefficients 0 1 2 37.733 -0.200 2.333 -1.667

例題 2

Maindonald (1984 年、67、 68 ページ ) によって説明されている加重付き最小二

乗当てはめが次式のモデルと加重 1/i 2 を使用して計算されます。

yi = β0xi0 +β1xi1 + β2xi2 + εi i= 1, 2, …, 4

通常の最小二乗関数 (imsl_f_regression) を使用して加重付き最小二乗当て

はめを計算するためには、回帰子(切片項の1つの列を含んだ)と応答はimsl_f_regression の呼び出しの前に変換されなければなりません。特に、i 番目の応答と回帰子は i 番目の加重の平方根によって掛けられます。

IMSL_NO_INTERCEPT が指定されなければなりませんが、その理由は、未変換モデ

ルの切片項に対応する行列の列は加重によって変換され、追加の独立変数と見なされるからです。

この例題では IMSL_ANOVA_TABLE が指定されます。元の未変換回帰子の項の誤差

の最小二乗和とこの加重付き回帰の応答は次の様になります。

ここで wi = 1/i 2 です。そして又、IMSL_NO_INTERCEPT が指定されるので元の未

変換応答の無修正全二乗和項は、以下のようになります。

#include <imsl.h>#include <math.h>

#define N_INDEPENDENT 3#define N_COEFFICIENTS N_INDEPENDENT#define N_OBSERVATIONS 4

main(){ int i, j; float *coefficients, w, anova_table[15], power; float x[][N_INDEPENDENT] = {1.0, -2.0, 0.0, 1.0, -1.0, 2.0, 1.0, 2.0, 5.0, 1.0, 7.0, 3.0}; float y[] = {-3.0, 1.0, 2.0, 6.0}; char *anova_row_labels[] = { "degrees of freedom for regression",

( )4

2

1

ˆSSE i i ii

w y y=

= −∑

42

1

SST i ii

w y=

= ∑

Page 610: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

"degrees of freedom for error", "total (uncorrected) degrees of freedom", "sum of squares for regression", "sum of squares for error", "total (uncorrected) sum of squares", "regression mean square", "error mean square", "F-statistic", "p-value", "R-squared (in percent)", "adjusted R-squared (in percent)", "est. standard deviation of model error", "overall mean of y", "coefficient of variation (in percent)"}; power = 0.0; for (i = 0; i < N_OBSERVATIONS; i++) { power += 1.0; /* 加重の平方根 */ w = sqrt(1.0 / (power*power)); /* 応答の平方根 */ y[i] *= w; /* 回帰子の変換 */ for (j = 0; j < N_INDEPENDENT; j++) x[i][j] *= w; }

coefficients = imsl_f_regression(N_OBSERVATIONS, N_INDEPENDENT, (float *)x, y, IMSL_NO_INTERCEPT, IMSL_ANOVA_TABLE_USER, anova_table, 0);

imsl_f_write_matrix("Least-Squares Coefficients", 1, N_COEFFICIENTS, coefficients, 0); imsl_f_write_matrix("* * * Analysis of Variance * * *\n", 15, 1, anova_table, IMSL_ROW_LABELS, anova_row_labels, IMSL_WRITE_FORMAT, "%10.2f", 0);}

出力結果

Least-Squares Coefficients 1 2 3-1.431 0.658 0.748 * * * Analysis of Variance * * *

degrees of freedom for regression 3.00degrees of freedom for error 1.00total (uncorrected) degrees of freedom 4.00sum of squares for regression 10.93sum of squares for error 1.01total (uncorrected) sum of squares 11.94regression mean square 3.64error mean square 1.01F-statistic 3.60p-value 0.37R-squared (in percent) 91.52adjusted R-squared (in percent) 66.08est. standard deviation of model error 1.01overall mean of y -0.08coefficient of variation (in percent) -1207.73

警告エラー

IMSL_RANK_DEFICIENT このモデルは完全階数ではありません。唯一の最

小二乗解は存在しません。

Page 611: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

poly_regression多項式の最小二乗回帰を実行します。

概要

#include <imsl.h>

float *imsl_f_poly_regression (int n_observations, float x[], float y[], int degree, …, 0)

double 型関数は、imsl_d_poly_regressionです。

必要な引数

int n_observations ( 入力 )観測数。

float x[] ( 入力 )独立変数を含んだ長さ n_observations の配列。

float y[] ( 入力 )従属変数を含んだ長さ n_observations の配列。

int degree ( 入力 )多項式の次数。

戻り値

当てはめられた多項式の係数を含むサイズ degree + 1 のベクトルのポイン

ター。当てはめが計算できない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_poly_regression (int n_observations, float xdata[], float ydata[], int degree, IMSL_WEIGHTS, float weights[],IMSL_SSQ_POLY, float **p_ssq_poly,IMSL_SSQ_POLY_USER, float ssq_poly[],IMSL_SSQ_POLY_COL_DIM, int ssq_poly_col_dim,IMSL_SSQ_LOF, float **p_ssq_lof,IMSL_SSQ_LOF_USER, float ssq_lof[],IMSL_SSQ_LOF_COL_DIM, int ssq_lof_col_dim,IMSL_X_MEAN, float *x_mean,IMSL_X_VARIANCE, float *x_variance,IMSL_ANOVA_TABLE, float **p_anova_table, IMSL_ANOVA_TABLE_USER, float anova_table[], IMSL_DF_PURE_ERROR, int *df_pure_error, IMSL_SSQ_PURE_ERROR, float *ssq_pure_error, IMSL_RESIDUAL, float **p_residual, IMSL_RESIDUAL_USER, float residual[],IMSL_RETURN_USER, float coefficients[],0)

オプション引数

IMSL_WEIGHTS, float weights[] ( 入力 )観測の加重のベクトルを含んだ、n_observations 要素を持つ配列。

このオプションが指定されなければ、全ての観測は1の等しい加重を持ちます。

IMSL_SSQ_POLY, float **p_ssq_poly (Output)連続する二乗和と他の統計量を含んだ配列のポインターのアドレス。返されると、このポインターは初期化されて ( malloc のメモリー割

り当て要求により )、配列はそこに格納されます。一般的に、float *p_ssq_poly が宣言されて、&p_ssq_poly がこの関数の引数として

使用され、そして free(p_ssq_poly) がこの配列を解放するために使

Page 612: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

用されます。行 i は xi , i = 1, ..., degree、に対応して、列は次のように

説明されます。

IMSL_SSQ_POLY_USER, float ssq_poly[] (Output)オプション引数 IMSL_SSQ_POLY の下で説明される多項式当てはめの

連続二乗和を含んむサイズ degree × 4 の配列。

IMSL_SSQ_POLY_COL_DIM, int ssq_poly_col_dim ( 入力 )ssq_poly の列ディメンジョン。

デフォルト: ssq_poly_col_dim = 4

IMSL_SSQ_LOF, float **p_ssq_lof ( 出力 )不適合度統計量を含んだ配列のポインターのアドレス。返されると、このポインターは初期化されて (malloc のメモリ割り当て要求を通

して )、配列はそこに格納されます。一般的に、float *p_ssq_lof が宣言されて、&p_ssq_lof がこの関数の引数として使用され、そして

free(p_ssq_lof) がこの配列を解放するために使用されます。行 i は

xi, i=1,…, degree に対応して、その列は次の表に説明されます。

IMSL_SSQ_LOF_USER, float ssq_lof[] ( 出力 )オプション IMSL_SSQ_LOF の下で記述される、不適合度統計量の行

列を含んだ、サイズ degree × 4 の配列。

IMSL_SSQ_LOF_COL_DIM, int ssq_lof_col_dim ( 入力 )ssq_lof の列ディメンジョン。

デフォルト: ssq_lof_col_dim = 4

IMSL_X_MEAN, float *x_mean ( 出力 )x の平均。

IMSL_X_VARIANCE, float *x_variance ( 出力 )x の分散。

IMSL_ANOVA_TABLE, float **p_anova_table ( 出力 )分散分析テーブルを含んだ配列のポインターのアドレス。返されると、このポインターは初期化されて (malloc のメモリ割り当て要求を通

して )、配列はそこに格納されます。一般的に、float *p_anova_table が宣言されて、&p_anova_table がこの関数の引数として使用され、

そして free(p_anova_table) がこの配列を解放するために使用され

ます。

列 説明1 自由度2 二乗和3 F 統計量4 p 値

列 説明1 自由度2 不適合度二乗和3 次数 i の多項式モデルの不適合度検

定の F 統計量4 検定用の p 値

要素 分散統計の解析0 モデルの自由度1 誤差の自由度2 全 ( 修整 ) 自由度

Page 613: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_ANOVA_TABLE_USER, float anova_table[] ( 出力 )オプション引数 IMSL_ANOVA_TABLE の下で列挙され、分散分析の統

計量を含むサイズ 15 の配列。

IMSL_DF_PURE_ERROR, int *df_pure_error ( 出力 )これが指定されると、純粋誤差の自由度が df_pure_error に返され

ます。

IMSL_SSQ_PURE_ERROR, float *ssq_pure_error ( 出力 )これが指定されると、純粋誤差の二乗和が ssq_pure_error に返さ

れます。

IMSL_RESIDUAL, float **p_residual ( 出力 )残差を含んだ配列のポインターのアドレス。返されると、このポインターは初期化されて (malloc のメモリ割り当て要求を通して )、配列

はそこに格納されます。一般的に、float *p_residual が宣言されて、

&p_residual がこの関数の引数として使用され、そして

free(p_residual) がこの配列を解放するために使用されます。

IMSL_RESIDUAL_USER, float residual[] ( 出力 )これが指定されると、residual はユーザによって提供される長さ

n_observations の配列になります。返されると、residual は残

差を含みます。

IMSL_RETURN_USER, float coefficients[] ( 出力 )これが指定されると、ユーザによって提供されるサイズ degree + 1 の配列 coefficients に回帰係数の最小二乗解が格納されます。

説明

関数 imsl_f_poly_regression は多項式(曲線の)回帰モデルの回帰係数の

推定値を計算します。当てはめの計算に加えて、imsl_f_poly_regression は幾つかの要約統計量を計算します。独立変数 (ssq_poly に格納される ) の各べき乗に影響を与える連続二乗和が計算されます。これらは、当てはめにおいて、高次べき乗の重要性を査定するために有用です。 Draper と Smith (1981年、 101、 102 ページ ) と Neter と Wasserman (1974 年、278、287 ページ ) は連

続二乗和の解釈を述べています。統計量 R 2 は多項式曲線によって説明される

その平均に関する y の二乗和の百分率です。本質的に、以下のように表されま

す。

ここで は xi での当てはめられた y 値で、 は y の平均です。この統計量は

データへの曲線の全体的な当てはめの査定に有用です。R 2 は両端を含めて 0% と 100% の間にかければなりません。R 2 = 100% はデータへの完全な当てはめ

を示しています。

3 モデルの平方和4 誤差の平方和5 全 ( 修整 ) 平方和6 モデル平均二乗7 エラー平均二乗8 総括 F 統計9 p 値10 R 2 ( パーセント )11 修整された R 2 ( パーセント )12 標準偏差の推定13 y の総括平均14 分散の係数 ( パーセント )

( )( )

22

21

ˆ100%iy y

Ry y

−=

−∑∑

ˆiy y

Page 614: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

多項式モデルの回帰係数の推定血値は、回帰変数として直交多項式を使用して計算されます。直交多項式の項でのこの多項式モデルの再パラメータ化は、x値のべき乗を形成することから生じる精度の損失を回避する利点を持っています。全ての結果は原型モデル(べき乗形)に対してユーザに返されます。

関数 imsl_f_poly_regression は Forsythe (1957 年 ) のアルゴリズムを基にし

ています。Shampine (1975 年 ) によって示唆された Forsythe のアルゴリズムの

修整が多項式係数の計算に使用されています。Forsythe のアルゴリズムと

Shampine の修整の説明は Kennedy と Gentle (1980 年、342、 347 ページ ) にありま

す。

例題

例題 1

多項式モデルが、Neter と Wasserman (1974 年、279、 285 ページ ) によって述べ

られたデータに当てはめられます。このデータ・セットは、コーヒー販売(100 ガロン)を測る応答変数 y とセルフサービスのコーヒー自動販売機の数を含ん

でいます。14 の同様なカフェテリアの応答がこのデータ・セットに含まれま

す。この結果のグラフも又、与えられています。

#include <imsl.h>

#define DEGREE 2#define NOBS 14

main(){ float *coefficients; float x[] = {0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 4.0, 4.0, 5.0, 5.0, 6.0, 6.0, 7.0, 7.0}; float y[] = {508.1, 498.4, 568.2, 577.3, 651.7, 657.0, 755.3, 758.9, 787.6, 792.1, 841.4, 831.8, 854.7, 871.4};

coefficients = imsl_f_poly_regression (NOBS, x, y, DEGREE, 0);

imsl_f_write_matrix("Least-Squares Polynomial Coefficients", DEGREE + 1, 1, coefficients, IMSL_ROW_NUMBER_ZERO, 0);}

出力結果

Least-Squares Polynomial Coefficients 0 503.3 1 78.9 2 -4.0

Figure 10-6 A Polynomial Fit

Page 615: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題 2

この例題は最初の例題の続きです。ここでは、多くのオプションの引数が使用されています。

#include <stdio.h>#include <imsl.h>

#define DEGREE 2#define NOBS 14

void main(){ int iset = 1, dfpe; float *coefficients, *anova, sspe, *sspoly, *sslof; float x[] = {0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 4.0, 4.0, 5.0, 5.0, 6.0, 6.0, 7.0, 7.0}; float y[] = {508.1, 498.4, 568.2, 577.3, 651.7, 657.0, 755.3, 758.9, 787.6, 792.1, 841.4, 831.8, 854.7, 871.4}; char *coef_rlab[2]; char *coef_clab[] = {" ", "intercept", "linear", "quadratic"}; char *stat_clab[] = {" ", "Degrees of\nFreedom", "Sum of\nSquares", "\nF-Statistic", "\np-value"}; char *anova_rlab[] = { "degrees of freedom for regression", "degrees of freedom for error", "total (corrected) degrees of freedom", "sum of squares for regression", "sum of squares for error", "total (corrected) sum of squares", "regression mean square", "error mean square", "F-statistic", "p-value", "R-squared (in percent)", "adjusted R-squared (in percent)", "est. standard deviation of model error", "overall mean of y", "coefficient of variation (in percent)"};

coefficients = imsl_f_poly_regression (NOBS, x, y, DEGREE, IMSL_SSQ_POLY, &sspoly, IMSL_SSQ_LOF, &sslof, IMSL_ANOVA_TABLE, &anova, IMSL_DF_PURE_ERROR, &dfpe, IMSL_SSQ_PURE_ERROR, &sspe, 0); imsl_write_options(-1, &iset); imsl_f_write_matrix("Least-Squares Polynomial Coefficients", 1, DEGREE + 1, coefficients, IMSL_COL_LABELS, coef_clab, 0); coef_rlab[0] = coef_clab[2]; coef_rlab[1] = coef_clab[3]; imsl_f_write_matrix("Sequential Statistics", DEGREE, 4, sspoly, IMSL_COL_LABELS, stat_clab, IMSL_ROW_LABELS, coef_rlab, IMSL_WRITE_FORMAT, "%3.1f%8.1f%6.1f%6.4f", 0); imsl_f_write_matrix("Lack-of-Fit Statistics", DEGREE, 4, sslof, IMSL_COL_LABELS, stat_clab, IMSL_ROW_LABELS, coef_rlab, IMSL_WRITE_FORMAT, "%3.1f%8.1f%6.1f%6.4f", 0); imsl_f_write_matrix("* * * Analysis of Variance * * *\n", 15, 1, anova, IMSL_ROW_LABELS, anova_rlab, IMSL_WRITE_FORMAT, "%9.2f", 0);}

Page 616: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

Least-Squares Polynomial Coefficients intercept linear quadratic 503.3 78.9 -4.0 Sequential Statistics Degrees of Sum of Freedom Squares F-Statistic p-value linear 1.0 220644.2 3415.8 0.0000 quadratic 1.0 4387.7 67.9 0.0000 Lack-of-Fit Statistics Degrees of Sum of Freedom Squares F-Statistic p-value linear 5.0 4793.7 22.0 0.0004 quadratic 4.0 405.9 2.3 0.1548 * * * Analysis of Variance * * *

degrees of freedom for regression 2.00 degrees of freedom for error 11.00 total (corrected) degrees of freedom 13.00 sum of squares for regression 225031.94 sum of squares for error 710.55 total (corrected) sum of squares 225742.48 regression mean square 112515.97 error mean square 64.60 F-statistic 1741.86 p-value 0.00 R-squared (in percent) 99.69 adjusted R-squared (in percent) 99.63 est. standard deviation of model error 8.04 overall mean of y 710.99 coefficient of variation (in percent) 1.13

警告エラー

IMSL_CONSTANT_YVALUES y は定数です。0 次の多項式が当てはめ

られます。高次の係数は 0 にセットされ

ます。

IMSL_FEW_DISTINCT_XVALUES 必要な次数の多項式に当てはめるために

区別される x 値が少な過ぎます。高次の

係数は0にセットされます。

IMSL_PERFECT_FIT 完全な当てはめは、degree より小さい

次数の多項式で得られました。高次の係数は 0 にセットされます。

重大エラー

IMSL_NONNEG_WEIGHT_REQUEST_2 全ての加重は非負でなければなりませ

ん。

IMSL_ALL_OBSERVATIONS_MISSING 各 (x, y) 点は NaN (not a number) を含み

ます。正当なデータは存在しません。

IMSL_CONSTANT_XVALUES この x 値は定数です。

ranks観測のベクトルに対する順位、標準得点、又は指数得点を計算します。

概要

#include <imsl.h>

float *imsl_f_ranks (int n_observations, float x[], …, 0)

Page 617: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

double 型関数は、 imsl_d_ranksです。

必要な引数

int n_observations ( 入力 )観測数。

float x[] ( 入力 )順位付けされる観測を含む長さ n_observations の配列。

戻り値

各観測の順位 ( 又はオプションで順位の変換 ) を含む長さ n_observations のベクトルへのポインター。

オプション引数の概要

#include <imsl.h> float* imsl_f_ranks (int n_observations, float x[],

IMSL_AVERAGE_TIE, IMSL_HIGHEST, IMSL_LOWEST, IMSL_RANDOM_SPLIT, IMSL_FUZZ, float fuzz_value, IMSL_RANKS, IMSL_BLOM_SCORES, IMSL_TUKEY_SCORES, IMSL_VAN_DER_WAERDEN_SCORES, IMSL_EXPECTED_NORMAL_SCORES, IMSL_SAVAGE_SCORES, IMSL_RETURN_USER, float ranks[], 0)

オプション引数

IMSL_AVERAGE_TIE, 又は

IMSL_HIGHEST, 又は

IMSL_LOWEST, 又は

IMSL_RANDOM_SPLIT

これらのオプション引数の1つを指定することで、同順位観測へ得点を割り当てるために使用される方法を変更することができます。

IMSL_FUZZ, float fuzz_value ( 入力 )2 つの項目が同順位であるときに決定するために使用される値。

abs(x[i] - x[j]) が fuzz_value 以下の場合、 x[i] と x[j] は同順位と言えま

す。 fuzz_value のデフォルト値は、 0.0 です。

IMSL_RANKS, 又は

IMSL_BLOM_SCORES, 又は

IMSL_TUKEY_SCORES, 又は

IMSL_VAN_DER_WAERDEN_SCORES、又はIMSL_EXPECTED_NORMAL_SCORES, 又はIMSL_SAVAGE_SCORES

これらのオプション引数で、返される答えの型を指定することが可能です。

キーワード 手法IMSL_AVERAGE_TIE 同順位観測の得点の平均 ( デフォ

ルト )IMSL_HIGHEST 同順位グループの最高得点IMSL_LOWEST 同順位グループの最低得点IMSL_RANDOM_SPLIT 同順位観測は乱数発生器を使用し

て無作為に分離される

Page 618: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_RETURN_USER, float ranks[] ( 出力 )指定されると、順位がユーザ提供の配列 ranksに返されます。

説明

同順位

同順位ではないデータにおいて、出力値は x のデータの通常の順位 ( 又は順

位の変換)です。x[i] が x の値の中で最小値を持ち、この値を持つ x の他の

要素が存在しなければ、ranks [i] = 1 です。 x[i] と x[j] の両方が同じ最小値を持

つ場合、その出力値は同順位を分けるために使用するオプションに依存します。

同順位が無作為に分解される時、関数 imsl_f_random_uniform が乱数を発生

するために使用されます。乱数発生器の「シード」が関数imsl_random_seed_set の使って明白にセットされなければプログラムの実行

の度に異なる結果が生じる可能性があります。

得点

オプションで、順位の標準や他の関数を返すことができます。標準得点は正規分布から順序統計の期待値、あるいは期待値の近似として定義することができます。最も単純な近似は、開区間 (0, 1) に尺度化された順位で、逆累積正規分

布関数 imsl_f_normal_inverse_cdfを計算することにより得られます。 Blom バージョン ( Blom 1958 年を参照 ) では、順位 ri (1 ≤ ri ≤ n、 ここに n は標本サイ

ズ、n_observations) の順位尺度変換は (ri - 3/8)/(n + 1/4) です。順位 ri にを持つ

観測に対応する Blom 標準得点は次の通りです。

ここで Φ(⋅) は、正規累積分布関数です。

同順位の調整は標準得点変換の後で行われます。これは、もしも x[i] が x[j] に等しくて(fuzz_value 以内)、それらの値がそのデータセットの中で k 番目に

最小であるならば、Blom 標準得点は k と k + 1 の順位で決定されます。その

後、これらの標準得点は平均されるか、指定されるかして選択されます。( 変換が最初に行われるか、又は,同順位が最初に解決されるかは、IMSL_AVERAGE が指定されるときを除いて違いはありません。)

キーワード 結果IMSL_RANKS 順位 ( デフォルト )IMSL_BLOM_SCORES Blom バージョンの標準得点IMSL_TUKEY_SCORES Tukey バージョンの標準得点IMSL_VAN_DER_WAERDEN_SCORES Van der Waerden バージョンの標準

得点IMSL_EXPECTED_NORMAL_SCORES 正規順序統計の期待値(同順位観

測では期待標準得点の平均)IMSL_SAVAGE_SCORES Savage 得点 ( 指数順序統計の期待

値 )

キーワード 結果IMSL_AVERAGE_TIE ranks[i] = ranks[j] = 1.5IMSL_HIGHEST ranks[i] = ranks[j] = 2.0IMSL_LOWEST ranks[i] = ranks [j] = 1.0IMSL_RANDOM_SPLIT ranks[i] = 1.0 と ranks[j] = 2.0

又は、無作為に

ranks[i] = 2.0 と ranks[j] = 1.0

1 3 / 8( )

1/ 4irn

− −Φ

+

Page 619: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Tukey バージョン (Tukey 1962 年 ) では、順位 ri の尺度化変換は (ri - 1/3)/(n + 1/3) です。順位 ri の観測に対応する Tukey 標準得点は次の通りです。

同順位は Blom 標準得点と同様な方法で操作されます。

Van der Waerden バージョン ( Lehmann 1975 年、97 ページ ) では、順位 ri の尺

度化変換は ri /(n + 1) です。順位 ri の観測に対応する Van der Waerden 標準得点

は次の通りです。

同順位は Blom 標準得点と同様な方法で操作されます。

オプション IMSL_EXPECTED_NORMAL_SCORES が使用されると、その出力値はサ

イズ n_observations の標本からの正規順序統計の期待値です。 x[i] の値が k 番目の最小であるならば、ranks [i] の値出力は E(zk) で、ここに E(・) は期待値

演算子で、zk は標準正規分布からのサイズ n_observations の標本の k 番目の

順序統計である。同順位は Blom 標準得点と同様な方法で操作されます。

Savage 得点はサイズ n_observations の標本から指数順序統計の期待値です。こ

れらの値は、Savage (1956 年) ( 又、Lehmann 1975 年を参照 ) によって説明さ

れた検定に使用されたので、 Savage 得点と呼ばれます。x[i] の値が k 番目の最

小であるならば、ranks [i] の値出力は E(yk) で、yk は標準指数分布からのサイ

ズ n_observations の標本の k 番目の順序統計です。サイズ n (n_observations) の指数標本からの k 番目の順序統計の期待値は次の通りで

す。

同順位は Blom 標準得点と同様な方法で操作されます。

例題

例題 1

この例題のデータは Hinkley (1977 年 ) のもので 30 観測を含んでいます。4 番

目と 6 番目の観測は同順位で、3 番目と 20 番目の観測は同順位であることに

注意します。

#include <imsl.h>

#define N_OBSERVATIONS 30

main(){ float *ranks; float x[] = {0.77, 1.74, 0.81, 1.20, 1.95, 1.20, 0.47, 1.43, 3.37, 2.20, 3.00, 3.09, 1.51, 2.10, 0.52, 1.62, 1.31, 0.32, 0.59, 0.81, 2.81, 1.87, 1.18, 1.35, 4.75, 2.48, 0.96, 1.89, 0.90, 2.05};

ranks = imsl_f_ranks(N_OBSERVATIONS, x, 0); imsl_f_write_matrix("Ranks" , 1, N_OBSERVATIONS, ranks, 0);}

1 1/ 3( )

1/ 3ir

n− −

Φ+

1( )1

irn

−Φ+

1 1 11 1n n n k

+ + +− − +K

Page 620: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

Ranks 1 2 3 4 5 65.0 18.0 6.5 11.5 21.0 11.5 7 8 9 10 11 122.0 15.0 29.0 24.0 27.0 28.0 13 14 15 16 17 1816.0 23.0 3.0 17.0 13.0 1.0 19 20 21 22 23 244.0 6.5 26.0 19.0 10.0 14.0 25 26 27 28 29 3030.0 25.0 9.0 20.0 8.0 22.0

例題 2

この例題は、いくつかの同順位を含んだ同じデータセットに全ての得点オプションを使用します。この例題では、同順位はいくつかの異なる方法で操作されます。

#include <imsl.h>

#define N_OBSERVATIONS 30

void main(){ float fuzz_value=0.0, score[4][N_OBSERVATIONS], *ranks; float x[] = {0.77, 1.74, 0.81, 1.20, 1.95, 1.20, 0.47, 1.43, 3.37, 2.20, 3.00, 3.09, 1.51, 2.10, 0.52, 1.62, 1.31, 0.32, 0.59, 0.81, 2.81, 1.87, 1.18, 1.35, 4.75, 2.48, 0.96, 1.89, 0.90, 2.05}; char *row_labels[] = {"Blom", "Tukey", "Van der Waerden", "Expected Value"};

/* 同順位のための最大順位を使用した Blom 得点 */ imsl_f_ranks(N_OBSERVATIONS, x, IMSL_HIGHEST, IMSL_BLOM_SCORES, IMSL_RETURN_USER, &score[0][0], 0); /* 同順位のための最大順位を使用した Tukey */ /* 標準得点 */ imsl_f_ranks(N_OBSERVATIONS, x, IMSL_LOWEST, IMSL_TUKEY_SCORES, IMSL_RETURN_USER, &score[1][0], 0); /* 同順位を無作為に分解する Van der Waerden 得点 */ imsl_random_seed_set(123457); imsl_f_ranks(N_OBSERVATIONS, x, IMSL_RANDOM_SPLIT, IMSL_VAN_DER_WAERDEN_SCORES, IMSL_RETURN_USER, &score[2][0], 0); /* 同順位を破るために平均化を使った */ /* 正規順序統計の期待値 */ imsl_f_ranks(N_OBSERVATIONS, x, IMSL_EXPECTED_NORMAL_SCORES, IMSL_RETURN_USER, &score[3][0], 0); imsl_f_write_matrix("Normal Order Statistics", 4, N_OBSERVATIONS, (float *)score, IMSL_ROW_LABELS, row_labels, 0); /* 同順位を破るために平均化を使った */

Page 621: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* Savage 得点 */ ranks = imsl_f_ranks(N_OBSERVATIONS, x, IMSL_SAVAGE_SCORES, 0); imsl_f_write_matrix("Expected values of exponential order " "statistics", 1, N_OBSERVATIONS, ranks, 0);}

出力結果

Normal Order Statistics 1 2 3 4 5Blom -1.024 0.209 -0.776 -0.294 0.473Tukey -1.020 0.208 -0.890 -0.381 0.471Van der Waerden -0.989 0.204 -0.753 -0.287 0.460Expected Value -1.026 0.209 -0.836 -0.338 0.473 6 7 8 9 10Blom -0.294 -1.610 -0.041 1.610 0.776Tukey -0.381 -1.599 -0.041 1.599 0.773Van der Waerden -0.372 -1.518 -0.040 1.518 0.753Expected Value -0.338 -1.616 -0.041 1.616 0.777 11 12 13 14 15Blom 1.176 1.361 0.041 0.668 -1.361Tukey 1.171 1.354 0.041 0.666 -1.354Van der Waerden 1.131 1.300 0.040 0.649 -1.300Expected Value 1.179 1.365 0.041 0.669 -1.365 16 17 18 19 20Blom 0.125 -0.209 -2.040 -1.176 -0.776Tukey 0.124 -0.208 -2.015 -1.171 -0.890Van der Waerden 0.122 -0.204 -1.849 -1.131 -0.865Expected Value 0.125 -0.209 -2.043 -1.179 -0.836 21 22 23 24 25Blom 1.024 0.294 -0.473 -0.125 2.040Tukey 1.020 0.293 -0.471 -0.124 2.015Van der Waerden 0.989 0.287 -0.460 -0.122 1.849Expected Value 1.026 0.294 -0.473 -0.125 2.043 26 27 28 29 30Blom 0.893 -0.568 0.382 -0.668 0.568Tukey 0.890 -0.566 0.381 -0.666 0.566Van der Waerden 0.865 -0.552 0.372 -0.649 0.552Expected Value 0.894 -0.568 0.382 -0.669 0.568 Expected values of exponential order statistics 1 2 3 4 5 6 0.179 0.892 0.240 0.474 1.166 0.474 7 8 9 10 11 12 0.068 0.677 2.995 1.545 2.162 2.495 13 14 15 16 17 18 0.743 1.402 0.104 0.815 0.555 0.033 19 20 21 22 23 24 0.141 0.240 1.912 0.975 0.397 0.614 25 26 27 28 29 30 3.995 1.712 0.350 1.066 0.304 1.277

Page 622: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

random_seed_getIMSL 乱数生成器で使用されるシードの現在値を取得します。

概要

#include <imsl.h>

int imsl_random_seed_get ( )

戻り値

シードの値。

説明

関数 imsl_random_seed_get は乱数生成器で使用される「シード」の現在値

を取得します。これを行う理由は、シードをリセットするために imsl_random_seed_set を使用して、シミュレーションを再スタートする

ことにあります。

例題

この例題は、imsl_random_seed_get と imsl_random_seed_set を使用する

シミュレーションを再スタートするために必要な文を説明します。 又この例題

は、最後に生成されたシードの値で乱数の系列の再スタートは、全てを一度に乱数を生成することと同じであることを示します。

#include <imsl.h>

#define N_RANDOM 5

main(){ int seed = 123457; float *r1, *r2, *r; imsl_random_seed_set(seed); r1 = imsl_f_random_uniform(N_RANDOM, 0); imsl_f_write_matrix ("First Group of Random Numbers", 1, N_RANDOM, r1, 0); seed = imsl_random_seed_get();

imsl_random_seed_set(seed); r2 = imsl_f_random_uniform(N_RANDOM, 0); imsl_f_write_matrix ("Second Group of Random Numbers", 1, N_RANDOM, r2, 0);

imsl_random_seed_set(123457); r = imsl_f_random_uniform(2*N_RANDOM, 0); imsl_f_write_matrix ("Both Groups of Random Numbers", 1, 2*N_RANDOM, r, 0);}

出力結果

First Group of Random Numbers 1 2 3 4 50.9662 0.2607 0.7663 0.5693 0.8448 Second Group of Random Numbers 1 2 3 4 50.0443 0.9872 0.6014 0.8964 0.3809 Both Groups of Random Numbers 1 2 3 4 5 60.9662 0.2607 0.7663 0.5693 0.8448 0.0443

Page 623: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

7 8 9 100.9872 0.6014 0.8964 0.3809

random_seed_setIMSL 乱数生成器で使用するための乱数シードを初期化します。

概要

#include <imsl.h>

void imsl_random_seed_set (int seed)

必要な引数

int seed ( 入力 )乱数生成器のシード。引数 seed は範囲 (0, 2147483646) になければ

なりません。この seed がゼロであれば、この値はシステム時計を使

用して計算されます。従って IMSL 乱数生成器を使用するプログラム

の結果は、常に異なります。

説明

関数 imsl_random_seed_setは、IMSL 乱数生成器に使用されるシードを初期

化するために使用されます。 この発生器の形は、以下のように表されます。

xi ≡ cxi-1 mod (231 − 1)

x 0 の値がシードです。シードが imsl_random_seed_set を呼び出す事に

よって、乱数生成器のいずれかのルーチンの呼び出しの前に初期化されなかった場合は、シードはシステム時計を使用して初期化されます。シードは seed を0にセットした imsl_random_seed_set を呼び出すことによってシステ

ム時計依存値に再度初期化することができます。

imsl_random_seed_set の効果は、乱数生成器によって使用される大域的

な値にセットすることです。

imsl_random_seed_set の通常の使用法は、imsl_random_seed_get と組み

合わせてシミュレーションをリスタートします。

例題

関数 imsl_random_seed_get を参照してください。

random_option一様 (0,1) 乗算合同法疑似乱数生成器を選択します。

概要

#include <imsl.h>

void imsl_random_option (int generator_option)

必要な引数

int generator_option ( 入力 )乱数生成器の指示子。この乱数生成器はモジュロ 2 31 − 1 を持つ乗算

合同生成器です。引数 generator_option は乗算子とシャッフルが

行われるかどうかを選択するために使用されます。

発生器オプション 発生器1 乗算子 16807 が使用される

Page 624: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

IMSL 一様疑似乱数生成器はシャッフリングが有る、無しの乗算合同法を使用

します。乗算子の値とシャッフリングを使用するかどうかは、 imsl_random_option によって決定されます。 関数 imsl_f_random_uniform の説明はこの生成器の形の選択で幾つかの指針を提供します。 選択が、明確に

されない場合,生成器はシャッフリング無しの乗算子 16807 を使用します。こ

の形の生成器は長い間使用されています (Lewis その他 1969 年 ) 。

例題

C 文

imsl_random_option(1)

乗算子 16807 の単純乗算合同法生成器を使用します。これはデフォルトと同じ

ですので、異なる生成器を選択するために、imsl_random_option が同じ

プログラムの中で以前に呼ばれていない限り、この文は、なにも影響を与えません。

random_uniform一様 (0,1) 分布から疑似乱数を生成します。

概要

#include <imsl.h>

float *imsl_f_random_uniform (int n_random, …, 0)double 型関数は、 imsl_d_random_uniformです。

必要な引数

int n_random ( 入力 )生成する乱数の数。

戻り値

長さ n_random のベクトルのポインターで、無作為な一様 (0, 1) 偏差値を含

みます。

オプション引数の概要

#include <imsl.h> float *imsl_f_random_uniform (int n_random,

IMSL_RETURN_USER, float r[],0)

オプション引数

IMSL_RETURN_USER, float r[] ( 出力 )指定された場合、長さ n_random の無作為の一様 (0, 1) 偏差値を含ん

だ配列が、ユーザ提供の配列 r に返されます。

説明

関数 imsl_f_random_uniform は乗算合同法を使用して、一様 (0, 1) 分布から

疑似乱数を生成します。この生成器の形は、以下のようになります。

2 シャッフリングと共に乗算子 16807 が使用される

3 乗算子 397204094 が使用される4 シャッフリングと共に乗算子

397204094 が使用される5 乗算子 950706376 が使用される6 シャッフリングと共に乗算子

950706376 が使用される

Page 625: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

xi ≡ cxi-1 mod (231 − 1)

各 x i は単位区間 (0,1) に尺度化されます。生成器に於ける c の可能な値は、

16807、397204094 と 950706376 です。この選択は関数 imsl_random_option オプションによって行われます。 imsl_random_option.16807 の選択は、最高速の実行時間になります。選択が

明確にされなければ、この関数は乗算子 16807 を使用します。

関数 imsl_random_seed_set は乱数生成器のシードを初期化するために使用

されます。関数 imsl_random_option は乱数生成器の形を選択するために使

用できます。

ユーザはこれらの乱数生成器のシャッフル版を選択する事ができます。この枠組みの中で、単純乗算合同法生成器から得られた最初の 128 の 一様 (0, 1) 乱数

でテーブルが埋められます。それから、この単純生成器からの各 x I に対して、

x i の低次ビットは 1 から 128 までの乱数英数 j を選択するために使用されま

す。このテーブルの j 番目の入力値はそれから乱数として発行され、 単位区間

に尺度化された後の、x i はこのテーブルの j 番目の位置に挿入されます。

imsl_f_random_uniform によって返された値は、正で、1.0 より小さくな

ります。しかし、返される値は、最小の相対間隔よりも小さくなる場合があります。それで、ある値、例えば r[i] は 1.0 − r[i] = 1.0 のようになるかも知れ

ません。

区間 (a, b) で一様な密度を持つ分布からの偏差値は、imsl_f_random_uniform からの出力を尺度化して得ることができます。次の文は(単精度)、(a, b) 分布

から無作為偏差値を生じます。

float *r;r = imsl_f_random_uniform (n_random, 0);for (i=0; i<n_random; i++) r[i]*(b-a) + a;

例題

この例題では imsl_f_random_uniform を 5 つの一様疑似乱数を生成する

ために使用します。 imsl_random_option が呼ばれないので、使用される発

生器は 16807 の乗算子を持つ単純乗算合同発生器です。

#include <imsl.h>#include <stdio.h>

#define N_RANDOM 5

void main(){ float *r;

imsl_random_seed_set(123457);

r = imsl_f_random_uniform(N_RANDOM, 0);

printf("Uniform random deviates: %8.4f%8.4f%8.4f%8.4f%8.4f\n", r[0], r[1], r[2], r[3], r[4]);}

出力結果

Uniform random deviates: 0.9662 0.2607 0.7663 0.5693 0.8448

random_normal逆 CDF 法を使用して標準正規分布から擬似乱数を生成します。

概要

#include <imsl.h>

Page 626: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float *imsl_f_random_normal (int n_random, …, 0)double 型関数は、 imsl_d_random_normalです。

必要な引数

int n_random ( 入力 )発生する乱数の数。

戻り値

無作為標準正規偏差量を含む、長さ n_random のベクトルのポインター。こ

の記憶域を解放するために、free を使用します。

オプション引数の概要

#include <imsl.h>float *imsl_f_random_normal (int n_random,

IMSL_RETURN_USER, float r[],0)

オプション引数

IMSL_RETURN_USER, float r[] ( 出力 )生成された無作為標準正規偏差量を含む、長さ n_random のベクト

ルのポインター。

説明

関数 imsl_f_random_normal は逆 CDF 技法を使用して、標準正規(ガウス)

分布から擬似乱数を生成します。この方法で、一様 (0, 1) 無作為偏差量が発生

されます。それから、正規分布関数の逆関数が、関数 imsl_f_normal_inverse_cdf を使用し、この点で計算されます。

平均 mean と標準偏差 std_dev を持つ正規分布からの偏差量が imsl_f_random_normal からの出力を換算することによって得ることができ

ます。次の文(単精度)は正規 (mean, std_dev2 ) 分布から無作為偏差量を生

じます。

float *r; r = imsl_f_random_normal (n_random, 0); for (i=0; i<n_random; i++) r[i] = r[i]*std_dev + mean;

例題

この例題で imsl_f_random_normal が標準正規分布から 5 つの擬似乱数偏

差量を生成するために使用されます。

#include <imsl.h>

#define N_RANDOM 5

void main(){ int seed = 123457; int n_random = N_RANDOM; float *r;

imsl_random_seed_set (seed); r = imsl_f_random_normal(n_random, 0); printf("%s: %8.4f%8.4f%8.4f%8.4f%8.4f\n", "Standard normal random deviates", r[0], r[1], r[2], r[3], r[4]);}

出力結果

Standard normal random deviates: 1.8279 -0.6412 0.7266 0.1747 1.0145

Page 627: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

注意

関数 imsl_random_seed_set は乱数生成器のシードを初期化するために使用

することが可能です。関数 imsl_random_option は生成器の形態を選択する

ために使用することができます。

random_poissonポアソン分布から擬似乱数を生成します。

概要

#include <imsl.h>

int *imsl_random_poisson (int n_random, float theta, …, 0)

必要な引数

int n_random ( 入力 )生成する乱数の数。

float theta ( 入力 )ポアソン分布の平均。引数 theta は、正でなければなりません。

戻り値

オプション引数が使用されない場合、 imsl_random_poisson は、無作為のポア

ソン偏差を含む長さ n_random のベクトルへのポインターを返します。空間を開

放するためには、freeを使用します。

オプション引数の概要

#include <imsl.h>int *imsl_random_poisson (int n_random, float theta,

IMSL_RETURN_USER, int r[],0)

オプション引数

IMSL_RETURN_USER, int r[] ( 出力 )指定されると、長さ n_randomの無作為のポアソン偏差のベクトルがユー

ザ提供の配列 rに返されます。

説明

関数 imsl_random_poisson は、正の平均 thetaを持つポワソン分布から擬似

乱数を発生させます。確率関数( θ = thetaを持つ ) は、次の通りです。

f(x) = (e-θθx)/x!, for x = 0, 1,2, …

theta が 15 未満の場合、imsl_random_poisson は、逆 CDF 法を使います。そ

れ以外は、 Schmeiser と Kachitvichyanukul (1981 年 ) (Schmeiser 1983 年も参照 )の PTPE 法が使われます。 PTPE 法は、三角形、平行四辺形、2 つの負の指数関

数の 4 つの領域の構成を使用します。三角形以外のそれぞれの領域内で、採択

/ 棄却が使用されます。この手法の実行時間は、基本的にポアソンの平均に対

して敏感ではありません。

関数 imsl_random_seed_set は、乱数発生器のシードを初期化するために使

用することができます。 関数 imsl_random_option は、乱数発生器の形式を選

択するのに利用可能です。

例題

この例題では、 imsl_random_poisson を使って、平均が 0.5 に等しくなるポワ

ソン分布から 5 つの擬似乱数偏差を生成します。

#include <imsl.h>

#define N_RANDOM 5

Page 628: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

void main(){ int *r; int seed = 123457; float theta = 0.5;

imsl_random_seed_set (seed); r = imsl_random_poisson (N_RANDOM, theta, 0); imsl_i_write_matrix ("Poisson(0.5) random deviates", 1, 5, r, 0);}

出力結果

Poisson(0.5) random deviates 1 2 3 4 5 2 0 1 0 1

random_gamma標準ガンマ分布から擬似乱数を生成します。

概要

#include <imsl.h>

float *imsl_f_random_gamma (int n_random, float a, …, 0)double procedure is imsl_d_random_gamma.

必要な引数

int n_random ( 入力 )生成する乱数の数。

float a ( 入力 )ガンマ分布の形状パラメータ。このパラメータは、正でなければなりません。

戻り値

オプション引数が使用されない場合、 imsl_f_random_gamma は、無作為の標準

ガンマ偏差を含む長さ n_random のベクトルへのポインターを返します。空間を

開放するためには、freeを使用します。

オプション引数の概要

#include <imsl.h>float *imsl_f_random_gamma (int n_random, float a,

IMSL_RETURN_USER, float r[],0)

オプション引数

IMSL_RETURN_USER, float r[] ( 出力 )指定されると、長さ n_randomの無作為の標準ガンマ偏差のベクトルが

ユーザ提供の配列 rに返されます。

説明

関数 imsl_f_random_gamma は、形状パラメータ a と単位尺度パラメータを持

つガンマ分布から擬似乱数を生成します。確率密度関数は次の様になります。

形状パラメータ a の値により、様々な計算アルゴリズムが使われます。.For the special case of a = 0.5 の特殊なケースの場合、二乗され、半分にされた標準偏差

が使用されます。a = 1.0 の場合、指数偏差が生成されます。それ以外は、a が

( ) ( )11 for 0a xf x x e x

a− −= ≥

Γ

Page 629: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1.0 未満の場合、Ahrens と Dieter (1974) で説明されている Ahrens により採択棄

却法が使われます。a が 1.0 より大きい場合、Schmeiser と Lal (1980) によって

開発された ten-region rejection 手順が使用されます。

形状パラメータ a と尺度パラメータ b を持つガンマ分布からの乱数は、

imsl_f_random_gamma を使用し、 r のそれぞれの項目を b と掛けることで生成

することができます。次のコード ( 単精度の場合 ) は、gamma (a, b) 分布から

乱数を生成します。

float *r;r = imsl_f_random_gamma(n_random, a, 0);for (i=0; i<n_random; i++) *(r+i) *= b;

Erlang 分布は、正の整数と等しい値の形状パラメータをもつ標準的なガンマ分

布です。従って、imsl_f_random_gamma は、 Erlang 分布からも修正することな

く擬似乱数を生成します。

関数 imsl_random_seed_set は、乱数生成器のシードを初期化するために使

うことができます。 関数 imsl_random_option は、乱数発生器の形状を選択す

るために使用可能です。

例題

この例題では、 imsl_f_random_gamma を使って、形状パラメータが 3.0 に等し

いガンマ (Erlang) 分布から 5 つの擬似乱数を生成します。

#include <imsl.h>

void main(){ int seed = 123457; int n_random = 5; float a = 3.0; float *r;

imsl_random_seed_set(seed); r = imsl_f_random_gamma(n_random, a, 0); imsl_f_write_matrix("Gamma(3) random deviates", 1, n_random, r, 0);}

出力結果

Gamma(3) random deviates 1 2 3 4 56.843 3.445 1.853 3.999 0.779

random_betaベータ分布から擬似乱数を生成します。

概要

#include <imsl.h>

float *imsl_f_random_beta (float n_random, float pin, float qin, …, 0)double 型関数は、 imsl_d_random_betaです。

必要な引数

int n_random ( 入力 )生成する乱数の数。

float pin ( 入力 )最初のベータ分布パラメータ。引数 pin は、正でなければなりませ

ん。

Page 630: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float qin ( 入力 )2 番目のベータ分布パラメータ。引数 qin は、正でなければなりませ

ん。

戻り値

オプション引数が使用されない場合、 imsl_f_random_beta は、無作為の標準

ベータ偏差を含む長さ n_random のベクトルへのポインターを返します。空間を

開放するためには、freeを使用します。

オプション引数の概要

#include <imsl.h>float *imsl_f_random_beta (float n_random, float pin, float qin,

IMSL_RETURN_USER, float r[],0)

オプション引数

IMSL_RETURN_USER, float r[] ( 出力 )指定されると、長さ n_randomの無作為の標準ベータ偏差のベクトルが

ユーザ提供の配列 rに返されます。

説明

関数 imsl_f_random_beta は、正の値を持つ 2 つのパラメータ pin と qinを

使ってベータ分布から擬似乱数を生成します。p = pin と q = qinでは、確率密度関

数は、次の様になります。

Γ(⋅) は、ガンマ関数です。

使用されるアルゴリズムは、 p と q の値によります。逆 CDF 法が使用される

p = 1 もしくは q = 1 のケースを除くと、全ての手法は採択棄却法を使用しま

す。 p と q が両方とも 1 未満の場合、Johnk (1964 年 ) の方法が使用されます。 p 又は q のどちらかが 1 未満で、もう一方が 1 より大きい場合、Atkinson の手法 (1979) が用いられます。 p と q が 1 より大きい場合で n_random が 4 未満の場

合、設定時間が非常に短い Cheng のアルゴリズム BB (1978) が用いられます。 n_random が 4 以上の場合、Schmeiser と Babu (1980) のアルゴリズム B4PE が用

いられます。 Note that for p と q 両方共に both greater than 1 より大きい場合、そ

れぞれの呼び出しで 4 変量未満にするようなループ内での

imsl_f_random_beta 呼び出しによって得られる偏差のセットと、 imsl_f_random_beta が一回呼ばれ、一度に全ての偏差を取得する時の偏差の

セットは同じにはならないことに注意してください。

r に返される値は 1.0 未満で、 ε より大きくなります。ここで、 ε は 1.0 − ε が 1.0未満になるような最小の正の数です。

関数 imsl_random_seed_set は、乱数発生器のシードを初期化するために使

うことができます。 関数 imsl_random_option は、乱数発生器の形状を選択す

るために使用可能です。

例題

この例題では、 imsl_f_random_beta を使って、5 つの擬似乱数 beta (3, 2) を生

成します。

#include <imsl.h>

main(){

int n_random = 5; int seed = 123457; float pin = 3.0;

( ) ( )( ) ( ) ( ) 11 1 for 0 1qpp q

f x x x xp q

−−Γ += − ≤ ≤

Γ Γ

Page 631: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float qin = 2.0; float *r;

imsl_random_seed_set (seed); r = imsl_f_random_beta (n_random, pin, qin, 0); imsl_f_write_matrix("Beta (3,2) random deviates", 1, n_random, r, 0);}

出力結果

Beta (3,2) random deviates 1 2 3 4 50.2814 0.9483 0.3984 0.3103 0.8296

random_exponential標準指数分布から擬似乱数を生成します。

概要

#include <imsl.h>

float *imsl_f_random_exponential (int n_random, …, 0)double 型関数は、 imsl_d_random_exponentialです。

必要な引数

int n_random ( 入力 )生成する乱数の数。

戻り値

無作為な標準指数偏差を含む長さ n_random の配列へのポインター。

オプション引数の概要

#include <imsl.h>

float *imsl_f_random_exponential (int n_random,IMSL_RETURN_USER, float r[],0)

オプション引数

IMSL_RETURN_USER, float r[] ( 出力 )指定されると、長さ n_randomの無作為の標準指数偏差のベクトルがユー

ザ提供の配列 rに返されます。

説明

関数 imsl_f_random_exponential は、標準指数分布から擬似乱数を生成しま

す。確率密度関数は、 f(x) = e-x, for x > 0 です。関数 imsl_random_exponential は、 antithetic 逆 CDF 技術を使用します。つまり、一様乱数 U が生成され、指

数累積分布関数が、指数偏差を生成するために 1.0 − U で計算されます。

平均 θ を持つ指数分布からの偏差は、 imsl_random_exponential を使用し、 r のそれぞれの項目を θ と掛けることで生成することができます。

例題

この例題では、 imsl_f_random_exponential を使って、標準指数分布から 5つの擬似乱数を生成します。

#include <imsl.h>

#define N_RANDOM 5

main()

{ int seed = 123457;

Page 632: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int n_random = N_RANDOM; float *r;

imsl_random_seed_set(seed); r = imsl_f_random_exponential(n_random, 0); printf("%s: %8.4f%8.4f%8.4f%8.4f%8.4f\n", "Exponential random deviates", r[0], r[1], r[2], r[3], r[4]);}

出力結果

Exponential random deviates: 0.0344 1.3443 0.2662 0.5633 0.1686

faure_next_pointシャッフルされた Faure 数列を計算します。

概要

#include <imsl.h>

Imsl_faure* imsl_faure_sequence_init (int ndim, …, 0)

float* imsl_f_faure_next_point (Imsl_faure *state, …, 0)

void imsl_faure_sequence_free (Imsl_faure *state)double 型関数は、imsl_d_faure_next_pointです。 関数 imsls_faure_sequence_init と imsls_faure_sequence_free は精

度に無関係です。

imsl_faure_sequence_initに必要な引数

int ndim ( 入力 )超幾何空間のディメンジョン。

imsl_faure_sequence_initの戻り値

数列に関する情報を含んだ構造体を返します。この構造体はそれが必要でなくなった後で imsls_faure_sequence_free を使用して解放する必要があり

ます。

imsl_faure_next_pointに必要な引数

Imsl_faure *state ( 入力 / 出力 )imsls_faure_sequence_init の呼び出しによって作成された構造

体。

imsl_faure_next_pointの戻り値

シャッフルされた Faure 数列の次の点を返します。この空間を開放するために free を使用します。

imsl_faure_sequence_freeに必要な引数

Imsl_faure *state ( 入力 / 出力 )imsls_faure_sequence_init の呼び出しによって作成された構造

体。

オプション引数の概要

#include <imsl.h>

float *imsl_faure_sequence_init (int ndim,IMSL_BASE, int base,IMSL_SKIP, int skip,0)

float* imsl_f_faure_next_point (Imsl_faure *state,IMSL_RETURN_USER, float *user,

Page 633: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_RETURN_SKIP, int *skip,0)

オプション引数

IMSL_BASE, int base ( 入力 )Faure 数列のベース。

デフォルト: ndim 以上の大きさの最小の素数。

IMSL_SKIP, int *skip ( 入力 )Faure 数列の始まりでスキップされる点数。

デフォルト: ここで、 で、 B は最大の

表現可能な整数です。

IMSL_RETURN_USER, float *user ( 出力 )数列の現在の点を含む、長さ ndim のユーザ提供の配列。

IMSL_RETURN_SKIP, int *skip ( 出力 )数列中の現在の点。IMSLS_SKIP のこの値と ndim と同じディメン

ジョンを使用して、この数列は新しい数列を初期化してリスタートすることができます。

説明

食い違い量は点集合の一様性からの偏差を測定します。

点集合 の食い違い量は、以下のように表されます。

ここで上限(supremum)は次の形式の [0, 1] d の全ての部分集合にある

λ は ルベーグ(Lebesgue)測度で、 は E に含まれる xj の数です。

点 [0,1]d の数列 x1、x2、… は次式のように d だけに依存する定数 c(d) が存在す

るならば低食い違い量列(low-discrepancy 数列)です。

n>1

一般化された Faure 数列はいずれの素数ベースの b≥d に対しても定義すること

ができます。食い違い量の最低の境界は、最小の素数 b≥d に対して得られ、オ

プションの引数 IMSLS_BASE は、そのディメンジョン以上の大きさの最小の

素数がデフォルトにされます。

一般化された Faure 系列 x1、x2、… は次のようにして計算されます。

その b 関連展開で正の整数 n を表す。

ここで ai(n) は整数 .

/ 2 1m − base log /logBm = base

[ ]1, , 0,1 , 1dnx x d∈ ≥K

( ) ( ) ( );

sup ,E

A E ndD En nλ= −

) )10, 0, , 0 1, 1

d jE t t t j d= × × ≤ ≤ ≤ ≤ L

( );A E n

( ) ( ) ( )log dndD c dn n≤

0

( ) ii

i

n a n b∞

=

= ∑

( )0 ia n b≤ <

Page 634: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

xn の j 番目の座標は、

です。

系列の生成器行列、 は次式で定義され、

そしてこの ckd はパスカル行列の要素です。

Faure 数列そのものを計算するよりはシャッフルされた Faure 数列を計算する

方がより高速です。このシャッフリングは低食い違い量(low-discrepancy)特性を保持することが示されます。

使用されるシャッフリングは b 関連 Gray コードです。関数 G(n) は正の整数 n をその b 関連展開によって与えられる整数にマップします。

この関数によって計算される系列は x(G(n)) で、この x が一般化された Faure 数列です。

例題

この例題では Faure 数列の 5 点が計算されます。この点群は 3 次元単位立方体

の中にあります。

imsl_faure_sequence_init がこの数列の状態を保持する構造体を作成する

ために使用されることに注意してください。imsl_f_faure_next_pointの毎

回の呼び出しはこの数列の次の点を返し、Imsl_faure 構造体を更新します。最

終の imsl_faure_sequence_free 呼び出しは、imsl_faure_sequence_init によって割り当てられた構造体に格納されたデータ項目を解放します。

#include "stdio.h"#include "imsl.h"

void main(){Imsl_faure*state;float *x;int ndim = 3;int k;

state = imsl_faure_sequence_init(ndim, 0);

for (k = 0; k < 5; k++) {x = imsl_f_faure_next_point(state, 0);printf("%10.3f %10.3f %10.3f\n", x[0], x[1], x[2]);

free(x);}

imsl_faure_sequence_free(state);}

出力結果

0.334 0.493 0.064

( ) ( ) 1

0 0

( ) , 1j j kn kd d

k d

x c a n b j d∞ ∞

− −

= =

= ≤ ≤∑∑

)( jkdc

( )j d kk d k dc j c−=

( )!

! !0

k d

d k dc d cc

k d

≤ −= >

Page 635: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

0.667 0.826 0.397 0.778 0.270 0.175 0.111 0.604 0.509 0.445 0.937 0.842

Page 636: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに
Page 637: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

第 11章:プリント関数

ルーチン行列、又はベクトルをプリント . . . . . . . . . . . write_matrix 637ページの幅と高さを設定 . . . . . . . . . . . . . . . . . .page 642プリントオプションの設定 . . . . . . . . . . . . . write_options 643

write_matrix隣接する記憶域に格納された長方形行列(又は、ベクトル)をプリントします。

概要

#include <imsl.h>

void imsl_f_write_matrix (char *title, int nra, int nca, float a[], …, 0)For int a[], use imsl_i_write_matrix.

For double a[], use imsl_d_write_matrix.

For f_complex a[], use imsl_c_write_matrix.

For d_complex a[], use imsl_z_write_matrix.

必要な引数

char *title ( 入力 )行列の表題。改行するためには、表題の中で \n を使用します。 長い表

題は自動的に折り返されます。

int nra ( 入力 )行列の行数。

int nca ( 入力 )行列の列数。

float a[] ( 入力 )プリントされる行列を含んだサイズ nra × nca の配列。

オプション引数の概要

#include <imsl.h>void imsl_f_write_matrix (char *title, int nra, int nca, float a[],

IMSL_TRANSPOSE,IMSL_A_COL_DIM, int a_col_dim,IMSL_PRINT_ALL,IMSL_PRINT_LOWER,IMSL_PRINT_UPPER,IMSL_PRINT_LOWER_NO_DIAG,IMSL_PRINT_UPPER_NO_DIAG,IMSL_WRITE_FORMAT, char *fmt,IMSL_ROW_LABELS, char *rlabel[],IMSL_NO_ROW_LABELS,IMSL_ROW_NUMBER,IMSL_ROW_NUMBER_ZERO,IMSL_COL_LABELS, char *clabel[],IMSL_NO_COL_LABELS,IMSL_COL_NUMBER,IMSL_COL_NUMBER_ZERO,

Page 638: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_RETURN_STRING, char **string,IMSL_WRITE_TO_CONSOLE,0)

オプション引数

IMSL_TRANSPOSE

aT をプリントします。

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 a の列ディメンジョン。

デフォルト: a_col_dim = nca

IMSL_PRINT_ALL, orIMSL_PRINT_LOWER, orIMSL_PRINT_UPPER, orIMSL_PRINT_LOWER_NO_DIAG, orIMSL_PRINT_UPPER_NO_DIAG

これらのオプション引数の 1 つは、行列の三角部分、或いは、行列全

体がプリントされるかどうかを正確に指定することができます。 これ

が省略されると行列全体がプリントされます。

IMSL_WRITE_FORMAT, char *fmt ( 入力 )行列をプリントするときに使用される C 変換仕様 ( フォーマット ) のリストを含んだ文字列。データタイプに適切な、C 変換仕様のどのよ

うなリストでも与えることができます。例えば fmt = “%10.3f“ は、

行列全体のために変換文字 f を指定します。( 変換文字 f に対して

は、行列はタイプ float、double、f_complex、d_complex でなければなり

ません )。代わりに fmt = "%10.3e%10.3e%10.3f%10.3f%10.3f" は列

1 と 2 に変換文字 e を、列 3 と 4 と 5 に変換文字 fを指定します。( complex 行列に対しては、行列の各列に 2 つの変換仕様が必要になりま

すが、それは変換文字 e が列 1 に使用されるからです。変換文字 fは

列 2 と、列 3 の実数部分に使用されます。) もしも fmt の終わりに来

て、行列の幾つかの列が残る場合、フォーマット制御は fmt の最初の

変換仕様に継続します。

最初からフォーマットをリスタートする事を除き、通常の C フォー

マット方法のその他の例外は以下の通りです。

1.変換仕様に関連しない文字は許可されません。例えば、フォーマッ

ト fmt = "1%d2%d" であれば文字 1 と 2 は許可されませんので、エ

ラーになります。

キーワード 作用IMSL_PRINT_ALL 行列全体がプリントされる(デフォルト)IMSL_PRINT_LOWER 対角項を含んだ行列の下三角部分がプリン

トされるIMSL_PRINT_UPPER 対角項を含んだ行列の上三角部分がプリン

トされるIMSL_PRINT_LOWER_NO_DIAG 対角項を含まない行列の下三角部分がプリ

ントされるIMSL_PRINT_UPPER_NO_DIAG 対角項を含まない行列の上三角部分がプリ

ントされる

Page 639: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

2.変換文字 d は浮動小数点値(タイプ float、double、 f_complex、又は d_complex)に使用されます。浮動小数点値の整数部分がプリン

トされます。

3.印刷番号の大きさが分からない時は、変換文字 g が有用です。しか

し番号の列をプリントするとき、通常、小数点は揃いません。変換文字 w ( 又は W) は、変換仕様を選択するためにこの関数で使

用されている特殊変換文字なので、小数点は 揃えらます。w で終わる変換仕様は "%n.dw" として指定されます。ここで n は欄

幅で、d は一般的にプリントされる有効桁数です。n の正当な

値は 3, 4, …,40 です。d の正当な値は 1, 2, …, n-2 です。fmt が w で終わる 1 つの変換仕様で指定される場合、a の全ての要素は

プリントの 1 つの変換仕様を決定するために調べられます。fmt が 1 つ以上の変換仕様を指定するならば、別々の変換仕様が w で終わる各変換仕様に対して生成されます。欄幅 10 で4つの有効

桁数を持つ自動的に選択される変換仕様が必要な場合 fmt = "10.4w" とセットします。

IMSL_NO_ROW_LABELS、又は

IMSL_ROW_NUMBER、又は

IMSL_ROW_NUMBER_ZERO、又は

IMSL_ROW_LABELS, char *rlabel[] ( 入力 )IMSL_ROW_LABELS が指定されると、rlabel は行ラベルを含んだ文

字列のポインターを含む、長さ nra のベクトルです。ここで、nra はプリントされる行列の行数です。改行するためには、ラベルの内部に \n を使用します。長いラベルは自動的に折り返されます。行ラベル

が必要でなければ、IMSL_NO_ROW_LABELS オプション引数を使用しま

す。番号 1, 2, …, nra を望む場合、IMSL_ROW_NUMBER オプション引

数を使用します。番号 1, 2, …, nra− 1 を望む場合、 IMSL_ROW_NUMBER_ZERO オプション引数を使用します。これらのオプ

ション引数が使用されなければ、いかなる時でも nra > 1 であるデ

フォルトによって、番号 1, 2, 3, …, nra が行ラベルのために使用され

ます。 nra = 1 であれば、デフォルトは行ラベルを持ちません。

IMSL_NO_COL_LABELS、又は

IMSL_COL_NUMBER、又は

IMSL_COL_NUMBER_ZERO、又は

IMSL_COL_LABELS, char *clabel[] ( 入力 )IMSL_COL_LABELS が指定されると、 clabel は列表題を含んだ文字

列のポインターを含む長さ nca+1 のベクトルです。列ラベルの表題は clabel[0] で、そして clabel[i]、i = 1, …, nca は i- 番目列の表

題です。改行するためにはラベルの内部に \n を使用します。長いラ

ベルは自動的に折り返されます。列ラベルが必要でない場合,IMSL_NO_COL_LABELS オプション引数を使用します。 番号 1, 2, …, ca を望む場合は、 IMSL_COL_NUMBER オプション引数を使用しま

す。 番号 0, 1, …, nca − 1 を望む場合、 IMSL_COL_NUMBER_ZERO オプ

ション引数を使用します。これらのオプション引数が使用されなければ、いかなる時でも nca > 1 であるデフォルトによって番号 1, 2, 3, …, nca が列ラベルのために使用されます。nca = 1 であれば、デフォル

トは列ラベルを持ちません。

IMSL_RETURN_STRING, char **string ( 出力 )プリントされる行列を含んだ NULL- 終了文字のポインターのアドレ

ス。各行は分離された改行で、最後の行は後ろの改行文字を持ちません。通常、char *string が宣言されて、&string が引数として使

用されます。

IMSL_WRITE_TO_CONSOLEこの行列はコンソールウインドウにプリントされます。コンソールウインドウが割り当てられられない場合、デフォルトコンソールウイン

Page 640: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ドウ (80 × 24、黒い画面に白、スクロール・バーがない ) が作成され

ます。

説明

関数 imsl_write_matrix はオプションの行ラベルと列ラベル ( a 又は aT がプリントされるかは別として、それぞれは rlabel と clabel によって指定

される ) と共に実数矩形行列 ( a に格納される ) をプリントします。オプショ

ンのフォーマット、fmt は行列の各列の変換仕様を指定するために使用されま

す。

加えて、この行列書き込み関数は IMSL_TRIANGLE オプションを使用して、

行列の上三角、又は、下三角の要素をプリントすることに制限することが可能です。一般的に、IMSL_TRIANGLE オプションは対称行列に使用されますが、

これは必要ではありません。ベクトルは、1 の行、又は、列ディメンジョンを

指定することによってプリントすることができます。

出力は関数 imsl_output_file 、第 12 章「ユーティリティ」によって指定

されるファイルに書かれます。デフォルトの出力ファイル ( ポインター stdout に対応する )は標準ファイルです。

ページ幅には 78 文字が使用されます。ページ幅とページ長さは関数 imsl_page を呼び出すことによってリセットすることができます。

水平中心揃え、大きい行列をプリントする方法、ページ付け、NaN (Not a Number) をプリントする方法、各ページに表題をプリントするかどうかは、関

数 imsl_write_options を呼び出すことによって選択することが可能です。

例題

例題 1

この例題は、オプション引数が与えられていない、最も基本的な使用例です。

#include <imsl.h>

#define NRA 3#define NCA 4

main(){ int i, j; f_complex a[NRA][NCA];

for (i = 0; i < NRA; i++) { for (j = 0; j < NCA; j++) { a[i][j].re = (i+1+(j+1)*0.1); a[i][j].im = -a[i][j].re+100; } } /* 行列を書く */ imsl_c_write_matrix ("matrix\na", NRA, NCA, (f_complex *)a, 0);}

出力結果

matrix a 1 2 31 ( 1.1, 98.9) ( 1.2, 98.8) ( 1.3, 98.7)2 ( 2.1, 97.9) ( 2.2, 97.8) ( 2.3, 97.7)3 ( 3.1, 96.9) ( 3.2, 96.8) ( 3.3, 96.7) 41 ( 1.4, 98.6)2 ( 2.4, 97.6)3 ( 3.4, 96.6)

Page 641: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題 2

この例題では、write_matrix 関数に利用されるオプション引数の幾つか

を、説明しています。

#include <imsl.h>

#define NRA 3#define NCA 4

main(){ int i, j; float a[NRA][NCA]; char *fmt = "%10.6W"; char *rlabel[] = {"row 1", "row 2", "row 3"}; char *clabel[] = { "", "col 1", "col 2", "col 3", "col 4"};

for (i = 0; i < NRA; i++) { for (j = 0; j < NCA; j++) { a[i][j] = (i+1+(j+1)*0.1); } } /* 行列を書く */ imsl_f_write_matrix ("matrix\na", NRA, NCA, (float *)a, IMSL_WRITE_FORMAT, fmt, IMSL_ROW_LABELS, rlabel, IMSL_COL_LABELS, clabel, IMSL_PRINT_UPPER_NO_DIAG, 0);}

出力結果

matrix a col 2 col 3 col 4 row 1 1.2 1.3 1.4 row 2 2.3 2.4 row 3 3.4

例題 3

この例題では、長さ 4 の行ベクトルがプリントされます。

#include <imsl.h>

#define NRA 1#define NCA 4

main(){ int i; float a[NCA]; char *clabel[] = {"", "col 1", "col 2", "col 3", "col 4"};

for (i = 0; i < NCA; i++) { a[i] = i + 1; } /* Write matrix */ imsl_f_write_matrix ("matrix\na", NRA, NCA, a, IMSL_COL_LABELS, clabel, 0);}

出力結果 matrix a col 1 col 2 col 3 col 4 1 2 3 4

Page 642: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

pageページの幅や長さを設定、もしくは取得します。

概要

#include <imsl.h>

void imsl_page (Imsl_page_options option, int *page_attribute)

必要な引数

Imsl_page_options option ( 入力 )ページ属性を設定するか、取得するかを選択するオプション。その可能な値は、以下の通りです。

int *page_attribute ( 属性を設定する場合は入力、その他は出力 )ページ属性の値は設定されるか検索されます。ページ幅は出力の行当たりの文字数であり ( デフォルト 78 )、ページ長さはページ当たりの

出力の行数です ( デフォルト 60 )。行当たり 10 又はそれ以上の文字、

ページ当たり 10 又はそれ以上の行が必要になります。

例題

次の例題は、ページ幅に 40 文字を設定するために imsl_page の使用法を説

明します。 IMSL 関数 imsl_f_write_matrix がそれから 3 × 4 行列 A をプ

リントするために使用されます。 a ij = i + j / 10 です。

#include <imsl.h>

#define NRA 3#define NCA 4

main(){ int i, j, page_attribute; float a[NRA][NCA];

for (i = 0; i < NRA; i++) { for (j = 0; j < NCA; j++) { a[i][j] = (i+1) + (j+1)/10.0; } } page_attribute = 40; imsl_page(IMSL_SET_PAGE_WIDTH, &page_attribute); imsl_f_write_matrix("a", NRA, NCA, (float *)a, 0);}

出力結果

a 1 2 31 1.1 1.2 1.32 2.1 2.2 2.33 3.1 3.2 3.3 41 1.4

オプション 説明IMSL_SET_PAGE_WIDTH ページ幅を設定IMSL_GET_PAGE_WIDTH ページ幅を取得IMSL_SET_PAGE_LENGTH ページ長を設定IMSL_GET_PAGE_LENGTH ページ長を取得

Page 643: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

2 2.43 3.4

write_options行列をプリントするためのオプションを設定、又は、取得します。

概要

#include <imsl.h>

void imsl_write_options (Imsl_write_options option, int* option_value)

必要な引数

Imsl_write_options option ( 入力 )印刷属性の設定、取得するのオプション。

int *option_value ( オプションが設定される場合は入力、その他は出力 )Option によって選択されるオプション属性の値。属性が設定される

とき、使用される値は、説明節のテーブルに記述されます。

説明

関数 imsl_write_options はユーザが行列をプリントするオプションを設

定、又は、取得することができます。imsl_write_options によって制御

されるオプションは、水平中心揃え、大きい行列をプリントする方法、ページ代え、NaN (not a number) をプリントする方法、タイトルを表示する方法、実

数と複素数のデフォルト書式です。(NaN は関数 imsl_f_machine と imsl_d_machine、第 12 章「Utilities.」で取得することができます。)

属性のために使用される値は以下の通りです。

設定用オプション 取得用オプション 属性の説明IMSL_SET_DEFAULTS 全てのパラメータにデ

フォルト設定を使用IMSL_SET_CENTERING IMSL_GET_CENTERING 水平中心揃えIMSL_SET_ROW_WRAP IMSL_GET_ROW_WRAP 行の折り返しIMSL_SET_PAGING IMSL_GET_PAGING ページ代えIMSL_SET_NAN_CHAR IMSL_GET_NAN_CHAR NaN (not a number) 印刷

方法IMSL_SET_TITLE_PAGE IMSL_GET_TITLE_PAGE 各ページのタイトルの

表示、非表示IMSL_SET_FORMAT IMSL_GET_FORMAT 実数と複素数のデフォ

ルト書式

オプション 値 意味CENTERING 0

1行列は左揃え。

行列は中心揃え。ROW_WRAP 0

m

次の行が印刷される前に全体行が印刷される。必要であれば、折り返しが使用される。

ここで m は正の整数である。n1 を列 1 で始まる変換

仕様の幅によって決定されるようなページに当てはまる最大列数とする。最初に、列1から n1 が行 1 か

ら m に対してプリントされる。

n2 を列 n1 +1から始まるページに当てはまる最大列

数とする。2 番目に、列 n1 + 1から n1 +n2 が行 1 か

ら m に対してプリントされる。プリントはこの方法で次ぎの m 行に対して続けられる、等々。

Page 644: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

FORMAT オプションで使用される w 変換文字は、特殊変換文字で、e、f、又

は d のいずれかで終わる C 変換仕様を自動的に選択するために使用されます。

w で終わる変換文字は "%n.dw" として指定されます。ここで、n は欄幅、d は一般的にプリントされる有効桁数です。

関数 imsl_write_options は行列をプリントする write_matrix 関数を

使用する前に繰り返して使用することができます。行列印刷関数は、プリントオプションを決定するために imsl_write_options によって設定された値

を検索します。プリントオプションのデフォルト値が望まれる場合、imsl_write_options の呼び出しは必要ではありません。このデフォルト

値は次の通りです。

例題

次の例題は IMSL 関数 imsl_f_write_matrix で 3 × 4 実数行列 A をプリ

ントするとき imsl_write_options の効果を説明するものす。ここでは a ij = i + j/10 です。imsl_write_options の最初の呼び出しは、行列がページ

上に水平に中心揃えでプリントされるように水平中心揃えを設定します。imsl_f_write_matrix の次の呼び出しは行列がプリントされるとき、左揃

えになるように、関数 imsl_write_options を使用して左揃えオプション

が設定されています。

#include <imsl.h>

#define NRA 4#define NCA 3

PAGING −2−1

0

k

ページ操作は起こらない。

ページ操作がオンになる。imsl_f_write_matrix 関数の全ての呼び出しは

新しいページで始まり、ページ操作は必要であれば、各呼び出しの内部で起こる。

ページ操作はオンになる。imsl_f_write_matrix 関数の最初の呼び出しは

新しいページで始まり、続くページ操作は必要によって起こる。ページ操作は imsl_f_write_matrix 関数の 2 番目と全ての続

く呼び出しによって、必要なときだけに起こる。

ページ操作をオンにして、現在ページに k 行を印刷する行数を設定する。k がページ長さよりも、大きいか等しければ、最初の imsl_f_write_matrix 関数の呼び出しは新しいページで始まる。どのような場合にも、続くページ操作は必要に応じて起こる。

NAN_CHAR 01

. . . . . . . . . . が NaN に対してプリントされる。

空欄が NaN に対してプリントされる。TITLE_PAGE 0

1タイトルは最初のページだけに表示される。

タイトルは最初のページと全ての継続ページに表示される。

FORMAT 012

書式は、 "%10.4x"書式は、 "%12.6w"書式は、 "%22.5e"

オプション デフォルト値CENTERING 0 左揃えROW_WRAP 1000 折り返し前の行数PAGING −2 ページ操作なしNAN_CHAR 0 . . . . . . . . . . . . . .TITLE_PAGE 0 最初のページのみタイトル表示FORMAT 0 %10.4w

Page 645: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

main(){ int i, j, option_value; float a[NRA][NCA];

for (i = 0; i < NRA; i++) { for (j = 0; j < NCA; j++) { a[i][j] = (i+1) + (j+1)/10.0; } } /* 中心揃えオプションを設定 */ option_value = 1; imsl_write_options (IMSL_SET_CENTERING, &option_value); /* 行列の表示 */ imsl_f_write_matrix ("a", NRA, NCA, (float*) a, 0); /* 左揃えオプションの設定 */ option_value = 0; imsl_write_options (IMSL_SET_CENTERING, &option_value); imsl_f_write_matrix ("a", NRA, NCA, (float*) a, 0);}

出力結果

a 1 2 3 1 1.1 1.2 1.3 2 2.1 2.2 2.3 3 3.1 3.2 3.3 4 4.1 4.2 4.3 a 1 2 31 1.1 1.2 1.32 2.1 2.2 2.33 3.1 3.2 3.34 4.1 4.2 4.3

Page 646: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに
Page 647: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

第 12章:ユーティリティー

ルーチン

出力ファイルの設定出力ファイルの設定 . . . . . . . . . . . . . . . . . output_file 648ライブラリのバージョンとライセンス番号の取得 . . . . . .version 651

時間と日付使用した CPU 時間 . . . . . . . . . . . . . . . . . . . . ctime 651 今世紀初めからある日付までの日数 . . . . . . . . . date_to_days 652今世紀初めからの日数から日付に変換 . . . . . . . days_to_date 653

エラーハンドリングエラーメッセージオプション . . . . . . . . . . . . error_options 654エラーコードの取得 . . . . . . . . . . . . . . . . . error_code 659

定数自然定数と数学定数 . . . . . . . . . . . . . . . . . . constant 660整数のマシン定数 . . . . . . . . . . . . . . . machine (整数 ) 663浮動小数点数のマシン定数 . . . . . . . . .machine (浮動小数点 ) 665

ソート浮動小数点数ベクトルのソート . . . . . . . . . . . . . . . sort 667 整数ベクトルのソート . . . . . . . . . . . . . . . .sort (整数 ) 668

ベクトルノルムの計算様々なノルムの計算 . . . . . . . . . . . . . . . . vector_norm 670

線形代数サポート

ベクトル - ベクトル、 行列 - ベクトル、行列 - 行列の乗算実行列 . . . . . . . . . . . . . . . . . . . . . .mat_mul_rect 672 複素行列 . . . . . . . . . . . . . . . . mat_mul_rect (複素数 ) 675実数帯行列 . . . . . . . . . . . . . . . . . mat_mul_rect_band 678 複素数帯行列 . . . . . . . . . . . mat_mul_rect_band (複素数 ) 681実数座標行列 . . . . . . . . . . . . . mat_mul_rect_coordinate 685複素数座標行列 . . . . . . . . mat_mul_rect_coordinate (複素数 ) 688

ベクトル - ベクトル、行列 - ベクトル、行列 - 行列の加算実数帯行列 . . . . . . . . . . . . . . . . . . . mat_add_band 692複素数帯行列 . . . . . . . . . . . . . .mat_add_band (複素数 ) 695実数座標行列 . . . . . . . . . . . . . . . .mat_add_coordinate 698複素数座標行列 . . . . . . . . . . mat_add_coordinate (複素数 ) 700

行列ノルム実行列 . . . . . . . . . . . . . . . . . . . . . . matrix_norm 703 実数帯行列 . . . . . . . . . . . . . . . . . matrix_norm_band 705実数座標行列 . . . . . . . . . . . . . . matrix_norm_coordinate 707

クラスの検定行列実行列 . . . . . . . . . . . . . . . . . . . generate_test_band 709複素行列 . . . . . . . . . . . . . generate_test_band (複素数 ) 711実行列 . . . . . . . . . . . . . . . . generate_test_coordinate 712複素数 . . . . . . . . . . . . generate_test_coordinate (複素数 ) 715

Page 648: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

output_file出力ファイル、又は、エラーメッセージ出力ファイルを設定します。

オプション引数の概要

#include <imsl.h>

void imsl_output_file ( IMSL_SET_OUTPUT_FILE, FILE *ofile,IMSL_GET_OUTPUT_FILE, FILE **pofile,IMSL_SET_ERROR_FILE, FILE *efile,IMSL_GET_ERROR_FILE, FILE **pefile,0)

オプション引数

IMSL_SET_OUTPUT_FILE, FILE *ofile ( 入力 )出力ファイルを ofile に設定します。

デフォルト: ofile = stdout

IMSL_GET_OUTPUT_FILE, FILE **pfile ( 出力 )現在の出力ファイルに pfile によって指される FILE ファイルをセッ

トします。

IMSL_SET_ERROR_FILE, FILE *efile ( 入力 )エラーメッセージ出力ファイルに efile をセットします。

デフォルト: efile = stderr

IMSL_GET_ERROR_FILE, FILE **pefile ( 出力 )エラーメッセージ出力ファイルに pefile によって指される FILE をセットします。

説明

この関数で IMSL ルーチンによってプリントされるファイルを変更することが

できます。

マルチスレッドが使用される場合、デフォルト設定に対して各スレッドは正当です。スレッドを使用するときには各スレッドの内部から imsl_output_file

を呼ぶことによって各スレッドのために異なる出力ファイルを設定することが可能になります。詳細は例題 2 を参照してください。

例題

例題 1

この例題はファイル myfile をオープンして、この新規ファイルに出力ファ

イルを変更します。その後,関数 imsl_f_write_matrix は、このファイルに

書き出します。

#include <stdio.h>#include <imsl.h>

main(){ FILE *ofile; float x[] = {3.0, 2.0, 1.0};

imsl_f_write_matrix ("x (default file)", 1, 3, x, 0);

ofile = fopen("myfile", "w"); imsl_output_file(IMSL_SET_OUTPUT_FILE, ofile, 0); imsl_f_write_matrix ("x (myfile)", 1, 3, x, 0);}

Page 649: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

x (default file)1 2 33 2 1

File myfilex (myfile)1 2 33 2 1

例題 2

続く例題は別個のスレッドで実行する IMSL ルーチンから異なるファイルに出

力を指示する方法を説明します。最初に 2 つのスレッドが作られて、それぞれ

が異なる IMSL 関数を呼び出します。それから、その結果が各スレッドの内部

から imsl_f_write_matrix を呼び出してプリントされます。

imsl_output_file はデフォルト出力ファイルを変更するために各スレッ

ドの内部から呼ばれることに注意してください。

#include <pthread.h>

#include <stdio.h>

#include "imsl.h"

void *ex1(void* arg);

void *ex2(void* arg);

void main()

{

pthread_t thread1;

pthread_t thread2;

/* IMSL signal trapping(信号割り込み)を不能にする */

imsl_error_options(IMSL_SET_SIGNAL_TRAPPING, 0, 0);

/* 2 つのスレッドを作成 */

if (pthread_create(&thread1, NULL ,ex1, (void *)NULL) != 0)

perror("pthread_create"), exit(1);

if (pthread_create(&thread2, NULL ,ex2, (void *)NULL) != 0)

perror("pthread_create"), exit(1);

/* スレッドの終了を待機 */

if (pthread_join(thread1, NULL) != 0)

perror("pthread_join"),exit(1);

if (pthread_join(thread2, NULL) != 0)

perror("pthread_join"),exit(1);

}

void *ex1(void* arg)

{

float *rand_nums = NULL;

FILE *file_ptr;

/* 結果を書き込むためのファイルをオープン */

file_ptr = fopen("ex1.out", "w");

Page 650: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* このスレッドのための出力ファイルを設定 */

imsl_output_file(IMSL_SET_OUTPUT_FILE, file_ptr, 0);

/* 5 つの乱数を計算 */

imsl_random_seed_set(12345);

rand_nums = imsl_f_random_uniform(5, 0);

/* 乱数を出力 */

imsl_f_write_matrix("Random Numbers", 5, 1, rand_nums, 0);

if (rand_nums) free(rand_nums);

fclose(file_ptr);

}

void *ex2(void* arg)

{

int n =3;

float *x;

float a[] = {1.0, 3.0, 3.0,

1.0, 3.0, 4.0,

1.0, 4.0, 3.0};

float b[] = {1.0, 4.0, -1.0};

FILE *file_ptr;

/* 結果を書き込むためにファイルをオープン */

file_ptr = fopen("ex2.out", "w");

/* このスレッドのために出力ファイルを設定 */

imsl_output_file(IMSL_SET_OUTPUT_FILE, file_ptr, 0);

/* xのために Ax = b を解く */

x = imsl_f_lin_sol_gen (n, a, b, 0);

/* x をプリント */

imsl_f_write_matrix ("Solution, x, of Ax = b", 1, 3, x, 0);

if (x) free(x);

fclose(file_ptr);

}

出力結果

ex1.out Random Numbers 1 0.0966 2 0.8340 3 0.9477 4 0.0359 5 0.0115

ex2.out Solution, x, of Ax = b 1 2 3 -2 -2 3

Page 651: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

versionこのライブラリのバージョン、シリアル番号、オペレーティング・システム、コンパイラを記述する情報を返します。

概要

#include <imsl.h>

char* imsl_version (Imsl_keyword code)

必要な引数

Imsl_keyword code ( 入力 )どの値が返されるかを示す指標。それは次のものでなくてはなりません。 IMSL_LIBRARY_VERSION、 IMSL_OS_VERSION、 IMSL_COMPILER_VERSION、または IMSL_LICENSE_NUMBER。

戻り値

要求された値が返されます。code が範囲外であれば NULL が返されます。

返される文字列の空間を解放するために、free を使用します。

説明

関数 imsl_version が返す情報は、このライブラリのバージョン、使用され

たコンパイラーと、それがコンパイルされたオペレーティング・システムのバージョン、IMSL のライセンス番号です。

例題

この例題は、特別なマシン上の imsl_version によって返されるすべての値

をプリントします。その結果はシステムに依存しますので、出力は省略します。

#include <imsl.h>

main(){ char *library_version, *os_version; char *compiler_version, *license_number;

library_version = imsl_version(IMSL_LIBRARY_VERSION); os_version = imsl_version(IMSL_OS_VERSION); compiler_version = imsl_version(IMSL_COMPILER_VERSION); license_number = imsl_version(IMSL_LICENSE_NUMBER);

printf("Library version = %s\n", library_version); printf("OS version = %s\n", os_version); printf("Compiler version = %s\n", compiler_version); printf("Serial number = %s\n", license_number);}

ctime消費された CPU 秒数を返します。

概要

#include <imsl.h>

double imsl_ctime ( )

戻り値

このプログラムによってこれまでに消費された CPU 秒数を返します。

例題

計算に必要な CPU 時間

Page 652: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

が、得られて、プリントされます。勿論、必要な時間はマシンに依存します。必要な CPU 時間は、同一マシンに於いても実行毎に少し変化します。

#include <imsl.h>

main(){ int k; double sum, time; /* Sum 1 million values */ for (sum=0, k=1; k<=1000000; k++) sum += k; /* Get amount of CPU time used */ time = imsl_ctime(); printf("sum = %f\n", sum); printf("time = %f\n", time);}

出力結果

sum = 500000500000.000000time = 2.260000

date_to_days1900 年 1 月 1 日から任意の日付までの日数を計算します。

概要

#include <imsl.h>

int imsl_date_to_days (int day, int month, int year)

必要な引数

int day ( 入力 )入力日付の日。

int month ( 入力 )入力日付の月。

int year ( 入力 )入力日付の年。 1950 年は、1950 A.D. 年に対応し、50 年は 50 A.D. 年に

対応します。

戻り値

1900 年 1 月 1 日から任意の日付までの日数。もし負であれば、それは 1900 年 1月 1 日以前の日数を示します。

説明

関数 imsl_date_to_days は、1900 年 1 月 1 日から任意の日付までの日数

を返します。関数 imsl_date_to_days は、1900 年 1 月1日以前の負の日

数を返します。負の year は、B.C を指定するために使用する事ができます。入

力日付が 0 年、並びに、1582 年 10 月 5 日から、1582 年 10 月 14 日の間は、存

在しません。従ってこれらの場合には imsl_date_to_days は終了エラーを

出します。

グレゴリオ歴の始まりは、1582 年 10 月 4 日の後で、後に 1582 年 10 月 14 日に

なりました。これ以前にはユリウス歴が使用されていました。

1,000,000

0kk

=∑

Page 653: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題

次の例題は、imsl_date_to_days を使用して 1986 年 1 月 15 日から 1986 年 1 月 28 日までの日数を計算します。

#include <imsl.h>

main(){ int day0, day1;

day0 = imsl_date_to_days(15, 1, 1986); day1 = imsl_date_to_days(28, 2, 1986); printf("Number of days = %d\n", day1 - day0);}

出力結果

Number of days = 44

days_to_date1900 年 1 月 1 日以来の日数に対応する日付を返します。

概要

#include <imsl.h>void imsl_days_to_date (int days, int *day, int *month, int *year)

必要な引数

int days ( 入力 )1900 年 1 月 1 日以来の日数

int *day ( 出力 )出力する日付の日。

int *month ( 出力 )出力する日付の月。

int *year ( 出力 )出力する日付の年。1950 年は、1950 A.D. に対応し 50 年は 50 A.D. に対応しています。

説明

関数 imsl_days_to_date は、1900 年 1 月 1 日以来の日数に対応する日付を計

算します。daysの値が負の場合、計算される日付は 1900 年 1 月 1 日以前にな

ります。この関数は、関数 imsl_date_to_days の逆になります。

グレゴリオ暦の初日は、1582 年 10 月 15 日になる 1582 年 10 月 4 日の次の日

です。それ以前は、ユリウス暦が使用されていました。

例題

次の例題では、 imsl_days_to_date を使って 1986 年の 100 日目の日付を計算し

ます。まず最初に、 IMSL 関数 imsl_date_to_days を使って 1985 年 12 月 31 日

の「日数」を取得します。

#include <imsl.h>

main(){ int day0, day, month, year;

day0 = imsl_date_to_days(31, 12, 1985); imsl_days_to_date(day0+100, &day, &month, &year); printf("Day 100 of 1986 is (day-month-year) %d-%d-%d\n",

Page 654: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

day, month, year);}

出力結果

Day 100 of 1986 is (day-month-year) 10-4-1986

error_options種々のエラーハンドリングオプションを設定します。

オプション引数の概要

#include <imsl.h>

void imsl_error_options (IMSL_SET_PRINT, Imsl_error type, int setting, IMSL_SET_STOP, Imsl_error type, int setting, IMSL_SET_TRACEBACK, Imsl_error type, int setting, IMSL_FULL_TRACEBACK, int setting, IMSL_GET_PRINT, Imsl_error type, int *psetting, IMSL_GET_STOP, Imsl_error type, int *psetting, IMSL_GET_TRACEBACK, Imsl_error type, int *psetting, IMSL_SET_ERROR_FILE, FILE *file,IMSL_GET_ERROR_FILE, FILE **pfile,IMSL_ERROR_MSG_PATH, char *path,IMSL_ERROR_MSG_NAME, char *name,IMSL_ERROR_PRINT_PROC, Imsl_error_print_proc print_proc,IMSL_SET_SIGNAL_TRAPPING, int setting, 0)

オプション引数

IMSL_SET_PRINT, Imsl_error type, int setting ( 入力 )setting が 0 であれば、type 型エラーメッセージのプリントは、

オフ、その他はオンに設定されます。

デフォルト: プリントのオンは IMSL_WARNING, IMSL_FATAL、IMSL_TERMINAL、IMSL_FATAL_IMMEDIATE、IMSL_WARNING_IMMEDIATE メッセージに対して設定されます。

IMSL_SET_STOP, Imsl_error type, int setting ( 入力 )type 型エラーメッセージでの停止は setting が 0 であればオフ、

その他は停止がオンに設定されます。 デフォルト: 停止のオンは IMSL_FATAL, IMSL_TERMINAL、IMSL_FATAL_IMMEDIATEメッセージに対して設定されます。

IMSL_SET_TRACEBACK, Imsl_error type, int setting ( 入力 )type 型エラーメッセージでのトレースバックのプリントは、

setting が 0 であればオフ、その他はトレースバックのプリントが

オンに設定されます。 デフォルト: トレースバックは全てのメッセージに対してオフに設定

されます。

IMSL_FULL_TRACEBACK, int setting ( 入力 )setting が 0 であれば、文書化された関数だけが トレースバックで

リストされます。その他は、内部関数名がリストされます。

デフォルト: 完全なトレースバックはオフに設定されます。

IMSL_GET_PRINT, Imsl_error type, int *psetting ( 出力 )type 型エラーメッセージのプリントの現在の設定に psetting によって指される整数を設定します。

IMSL_GET_STOP, Imsl_error type, int *psetting ( 出力 )type 型エラーメッセージの停止の現在の設定に psetting によっ

て指される整数を設定します。

Page 655: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_GET_TRACEBACK, Imsl_error type, int *psetting ( 出力 ) type 型エラーメッセージのトレースバックのプリントの現在の設定

に psetting によって指される整数をセットします。

IMSL_SET_ERROR_FILE, FILE *file ( 入力 )エラー出力ファイルをセットします。デフォルト: file = stderr

IMSL_GET_ERROR_FILE, FILE **pfile ( 出力 )エラー出力ファイルに pfile によって指される FILE * をセットしま

す。

IMSL_ERROR_MSG_PATH, char *path ( 入力 )エラーメッセージファイルパスをセットします。UNIX システムでは、

これはエラーメッセージを含んだファイルに対して、検索されるディレクトリのコロンで分離されたリストになります。デフォルト: システムに依存します。

IMSL_ERROR_MSG_NAME, char *name ( 入力 )エラーメッセージを含んだファイルの名前をセットします。

デフォルト: file = “imslerr.bin”

IMSL_ERROR_PRINT_PROC, Imsl_error_print_proc print_proc ( 入力 )エラー出力関数をセットします。プロシージャ print_proc は、以

下の形式です。 void print_proc (Imsl_error type, long code, char *function_name, char *message).この場合には type はエラーメッセージタイプ番号 (IMSL_FATAL など )、code はエラーメッセージコード番号 (IMSL_MAJOR_VIOLATION など )、function_name はエラーをセットする関数の名前で、

message はプリントされるエラーメッセージになります。

print_proc が NULL であればデフォルトのエラー出力関数が使用

されます。

IMSL_SET_SIGNAL_TRAPPING, int setting ( 入力 )Setting が1であれば、C/Math/ライブラリは自分自身の信号ハン

ドラーを使用します。そうでなければ、C/Math/ライブラリ信号ハン

ドラーは使用されません。C/Math/ライブラリがマルチスレッドのア

プリケーションから呼ばれる場合、信号ハンドラーはオフにする必要があります。詳細は例題 3 を参照してください。

デフォルト: setting = 1

戻り値

この関数の戻り値は void です。

説明

この関数でエラーハンドリングシステムをカスタマイズすることができます。

マルチスレッドを使用する場合、デフォルト設定は各スレッドに対して正当であるが個々のスレッドに対して変更することができます。スレッドを使用するときには各スレッドの内部から imsl_error_options を呼ぶことで、各ス

レッドのためにオプション(IMSL_SET_SIGNAL_TRAPPING を除く)を設定す

る必要があります。

IMSL 信号割り込み機構は、マルチスレッドが使用されるときには使用不可に

しなければなりません。IMSL 信号割り込み機構はスレッドが作成される以前

に次の呼び出しをすることによって使用不可にすることができます。

imsl_error_options(IMSL_SET_SIGNAL_TRAPPING, 0, 0);

マルチスレッドの例題は、例題 3 と例題 4 を参照してください。

注意: C/Math ライブラリが呼び出されるとき、信号ハンドラーがインストー

ルされます。そして、C/Math ライブラリから戻る前に、アンインストールさ

れます。 エラーハンドリングに関するざまざまな処理を行うために関数

Page 656: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

imsl_error_options を利用することができます。オプション引数

IMSL_SET_SIGNAL_TRAPPINGを使って信号ハンドラーを利用不可にして呼び出

しても、最初の呼び出しで、信号ハンドラーはインストールされます。しかし、C/Math ライブラリによる信号ハンドラーのインストールをまったく行い

たくない場合があります。そのような場合、以下の関数を呼び出します。

#include <imsl.h>

void imsl_skip_signal_handler();

例題

例題 1

この例題については IMSL_TERMINAL プリント設定が取得されます。次には、

IMSL_TERMINAL エラーでの停止がオフにされ、標準出力の出力がリダイレク

トされて、間違った値を持つ imsl_error_options の呼び出しにより、エ

ラーが故意に発生させられます。

#include <imsl.h>#include <stdio.h>

main(){ int setting; /* IMSL_TERMINAL エラーメッセージの停止を */ /* オフにして、エラーメッセージを */ /* 標準出力に書き込む */ imsl_error_options(IMSL_SET_STOP, IMSL_TERMINAL, 0, IMSL_SET_ERROR_FILE, stdout, 0); /* 間違った値で imsl_error_options() */ /* を呼び出す */ imsl_error_options(-1); /* IMSL_TERMINAL の setting を得る */ imsl_error_options(IMSL_GET_PRINT, IMSL_TERMINAL, &setting, 0); printf("IMSL_TERMINAL error print setting = %d\n", setting);}

出力結果

*** TERMINAL Error from imsl_error_options. There is an error with*** argument number 1. This may be caused by an incorrect number of*** values following a previous optional argument name.

IMSL_TERMINAL error print setting = 1

例題 2

この例題では IMSL 自身のエラープリント関数が標準関数に置き換えられま

す。最初の4行だけが下にプリントされます。

#include <imsl.h>#include <stdio.h>

void print_proc(Imsl_error, long, char*, char*);

main(){ /* IMSL_TERMINAL エラーメッセージの */ /* トレースバックをオフにして */ /* カスタム印刷関数を使用する */ imsl_error_options(IMSL_ERROR_PRINT_PROC, print_proc, 0);

Page 657: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* 間違った値で imsl_error_options() */ /* を呼び出す */ imsl_error_options(-1);}

void print_proc(Imsl_error type, long code, char *function_name, char *message){ printf("Error message type %d\n", type); printf("Error code %d\n", code); printf("From function %s\n", function_name); printf("%s\n", message);}

出力結果 Error message type 5Error code 103From function imsl_error_optionsThere is an error with argument number 1. This may be caused by an incorrect number of values following a previous optional argument name.

例題 3

この例題では、2 つのスレッドが作成されて、それぞれのスレッドごとに異な

るエラーハンドリングオプションを設定するために各スレッドの内部でエラーオプションが呼ばれます。各スレッドの中で停止エラーが発生するので、各スレッドのために停止エラーの停止をオフにしなければならなりません。そして又、 IMSL 信号割り込み機構を使用不可にするためにメインプログラムから

imsl_error_options が呼ばれることに注意してください。WIN32 スレッ

ドを使用する同様な例題は例題 4 を参照してください。マルチスレッドが実行

されているのでエラー出力の順番はシステムによって異なることに注意してください。

#include <pthread.h>#include <stdio.h>#include "imsl.h"

void *ex1(void* arg);void *ex2(void* arg);

void main(){ pthread_t thread1; pthread_t thread2;

/* IMSL 信号割り込みを不能にする */ imsl_error_options(IMSL_SET_SIGNAL_TRAPPING, 0, 0);

/* 2つのスレッドを作成 */ if (pthread_create(&thread1, NULL ,ex1, (void *)NULL) != 0) perror("pthread_create"), exit(1); if (pthread_create(&thread2, NULL ,ex2, (void *)NULL) != 0) perror("pthread_create"), exit(1); /* 終了するためにスレッドを待機 */ if (pthread_join(thread1, NULL) != 0) perror("pthread_join"),exit(1); if (pthread_join(thread2, NULL) != 0) perror("pthread_join"),exit(1); }

void *ex1(void* arg){ float res; /*

Page 658: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

* このスレッドのエラーハンドリングオプションを設定するために * imsl_error_options を呼び出す。 * エラープリント関数はこのスレッドだけのためにユーザ定義になる */ imsl_error_options(IMSL_SET_STOP, IMSL_TERMINAL, 0, 0);

res = imsl_f_beta(-1.0, .5);}

void *ex2(void* arg){ float res; /* * スレッドのエラーハンドリングオプションを設定するために * imsl_error_options を呼び出す。 */ imsl_error_options(IMSL_SET_STOP, IMSL_TERMINAL, 0,

IMSL_SET_TRACEBACK, IMSL_TERMINAL, 1, 0);

res = imsl_f_gamma(-1.0);}

出力結果

*** TERMINAL Error from imsl_f_beta. Both "x" = -1.000000e+00 and "y" =*** 5.000000e-01 must be greater than zero.

*** TERMINAL Error from imsl_f_gamma. The argument for the function can not*** be a negative integer. Argument "x" = -1.000000e+00.

Here is a traceback of the calls in reverse order. Error Type Error Code Routine ---------- ---------- ------- IMSL_TERMINAL IMSL_NEGATIVE_INTEGER imsl_f_gamma USER

例題 4

この例題では、例題 3 で示された同じ機能性を説明するために WIN32 API が使用されています。マルチスレッドが実行されているのでエラー出力の順番はシステムにより異なることに注意してください。

#include <windows.h>#include <stdio.h>#include "imsl.h"

DWORD WINAPI ex1(void *arg); DWORD WINAPI ex2(void *arg); int main(int argc, char* argv[]) {HANDLE thread[2];

imsl_error_options(IMSL_SET_SIGNAL_TRAPPING, 0, 0);

thread[0] = CreateThread(NULL, 0, ex1, NULL, 0, NULL);thread[1] = CreateThread(NULL, 0, ex2, NULL, 0, NULL);

WaitForMultipleObjects(2, thread, TRUE, INFINITE); }DWORD WINAPI ex1(void *arg) { float res;

Page 659: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* * このスレッドのエラーハンドリングオプションを設定するために * imsl_error_options を呼び出す。 */ imsl_error_options(IMSL_SET_STOP, IMSL_TERMINAL, 0, 0); res = imsl_f_beta(-1.0, .5); return(0);} DWORD WINAPI ex2(void *arg) { float res; /* * このスレッドのエラーハンドリングオプションを設定するために * imsl_error_options を呼び出す。トレースバックは

* IMSL_TERMINAL エラーのためにオンにされる

*/ imsl_error_options(IMSL_SET_STOP, IMSL_TERMINAL, 0,

IMSL_SET_TRACEBACK, IMSL_TERMINAL, 1, 0);

res = imsl_f_gamma(-1.0); return(0);}

出力結果

*** TERMINAL Error from imsl_f_gamma. The argument for the function can not*** be a negative integer. Argument "x" = -1.000000e+00.

Here is a traceback of the calls in reverse order. Error Type Error Code Routine ---------- ---------- ------- IMSL_TERMINAL IMSL_NEGATIVE_INTEGER imsl_f_gamma USER

*** TERMINAL Error from imsl_f_beta. Both "x" = -1.000000e+00 and "y" =*** 5.000000e-01 must be greater than zero.

error_code最後に呼び出された関数からのエラーメッセージに対応するコードを取得します。

概要

#include <imsl.h>

long imsl_error_code ( )

戻り値

この関数は、最後に呼び出された IMSL 関数からエラーメッセージコードを返

します。

インクルードファイル imsl.h は各エラーコードの名前を定義します。

例題

この例題は IMSL_TERMINALエラーメッセージの停止をオフにして、

IMSL_SET_PRINT のための間違った値を持つ、imsl_error_options を呼び出

すことによりエラーを発生させます。エラーメッセージコード番号が、引き出されて、プリントされます。imsl.h の中では、

IMSL_INTEGER_OUT_OF_RANGE は 132 であるように定義されます。

#include <imsl.h>#include <stdio.h>

main()

Page 660: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{ long code; /* IMSL_TERMINAL メッセージの停止を */ /* オフにして、エラーメッセージを */ /* 標準出力にプリント */ imsl_error_options(IMSL_SET_STOP, IMSL_TERMINAL, 0, IMSL_SET_ERROR_FILE, stdout, 0); /* 間違った値で imsl_error_options() */ /* を呼び出す */ imsl_error_options(IMSL_SET_PRINT, 100, 0, 0); /* エラーメッセージコードを取得 */ code = imsl_error_code(); printf("error code = %d\n", code);}

出力結果

*** TERMINAL Error from imsl_error_options."type" must be between 1 and 5,*** but "type" = 100.

error code = 132

constant種々の数学定数と物理定数の値を返します。

概要

#include <imsl.h>

float imsl_f_constant (char name, char unit)

double 型関数は、 imsl_d_constantです。

必要な引数

char *name ( 入力 )目的の定数の名前を含む文字列。文字列 name の大文字、小文字の区

別は問いません。名前「PI」、 「Pi」、「pI」、「pi」は同等に扱われま

す。空白とアンダースコアーは使用可能ですが、無視されます。

char *unit ( 入力 )必要な定数の単位を含む文字列。NULL であれば、システム国際単位

の (SI) 単位が想定されます。文字列 unit の大文字、小文字の区別

は問いません。「METER」、「Meter」、「meter」は同等に扱われます。

unit は形状 U1*U2*... *Um/V1/.../Vn を持ち、ここに Ui と Vi は基本単位も名称、又は、べき乗にされた基本単位の名称です。

基本単位は、* 又は / で分離されなければなりません。べき乗は、m2 に対して「m^2」として、^ として示されます。 例えば、

「METER*KILOGRAM/SECOND」、「M*KG/S」、「METER」 又は「M/KG^2」です。

戻り値

デフォルトでは、 imsl_f_constant は望ましい単位を返します。値が何も

計算できない場合,NaN が返されます。

説明

使用可能な名称は、次の表にリストされています。記号 ‡ で標識された値は、

正確(マシン精度に対して)です。右列の参照はコード番号で表されています。 [1] Cohen と Taylor (1986 年 )、 [2] Liepman (1964 年 )、そして [3] 再計算され

た数学定数。

Page 661: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

名前 説明 値 参照Amu 原子質量単位 1.6605655 × 10-27 kg 1ATM 標準気圧 1.01325 × 105 N/m2 ‡ 2AU 天文単位 1.496 × 1011 mAvogadro アボガドロ数、 N 6.022045 × 1023 1/mole 1Boltzman ボルツマン定数、k 1.380662 × 10-23 J/K 1C 光速、c 2.997924580 × 108 m/s 1Catalan カタラン定数 0.915965… ‡ 3E 自然対数の基底、 e 2.718… ‡ 3ElectronCharge 電荷、 e 1.6021892 × 10-19 C 1ElectronMass 電子質量、 me 9.109534 × 10-31 kg 1ElectronVoltEuler

電子ボルト、 evオイラー定数、 γ

1.6021892 x10 -19J0.577… ‡

13

Faraday ファラデー定数、F 9.648456 × 104 C/mole 1FineStructure 微細構造、 α 7.2973506 × 10-3 1Gamma オイラー定数、 γ 0.577… ‡ 3Gas ガス定数、R0 8.31441 J/mole/K 1Gravity 重力定数、 G 6.6720 × 10-11 N m2/kg2 1Hbar プランク定数 /2π 1.0545887 × 10-34 J s 1PerfectGasVolume 標準容積理想気体 2.241383 × 10-2 m3/mole 1Pi 円周率(Pi)、 π 3.141… ‡ 3Planck プランクの定数、 h 6.626176 × 10-34 J s 1ProtonMass プロトンの容積、 Mp 1.6726485 × 10-27 kg 1Rydberg リュードベルの定数、 Rµ 1.097373177 × 107/m 1Speedlight 光速、 c 2.997924580 × 108 m/s 1StandardGravity 標準重力、 g 9.80665 m/s2 ‡ 2StandardPressure 標準気圧 1.01325 × 105 N/m2 ‡ 2StefanBoltzman ステファン - ボルツマン、 σ 5.67032 × 10-8W/K4/m2 1WaterTriple 水の三重点 2.7316 × 102 K 2

Page 662: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

利用可能な単位は次の通りです。

次のメートル法の前置辞が上述の単位を共に使用されます。1 つ、又は、2 文

字の前置辞だけが 1 文字単位省略形と共に使用されます。

m が milliを意味するので、 myria 又は mega の1文字単位省略形は存在しません。

例題

例題 1

この例題では、オイラーの定数 γ が得られてプリントされます。オイラーの定

数は次式で定義されます。この例題では、

#include <stdio.h>#include <imsl.h>

main(){ float gamma; /* Get gamma */ gamma = imsl_f_constant("gamma", 0); /* Print gamma */ printf("gamma = %f\n", gamma);}

出力結果

gamma = 0.577216

単位 説明時間 day, hour = hr, min, minute, s = sec = second, year周波数 Hertz = Hz質量 AMU, g = gram, lb = pound, ounce = oz, slug距離 Angstrom, AU, feet = foot, in = inch, m = meter = metre, micron, mile, mill,

parsec, yard面積 acre体積 1 = liter=litre力 dyne, N = Newton力 BTU, Erg, J = Joule仕事量 W = watt圧力 ATM = atmosphere, bar温度 degC = Celsius, degF = Fahrenheit, degK = Kelvin粘度 poise, stoke電荷 Abcoulomb, C = Coulomb, statcoulomb電流 A = ampere, abampere, statampere電圧 Abvolt, V = volt電磁誘導 T = Telsa, Wb = Weberその他の単位 I, farad, mole, Gauss, Henry, Maxwell, Ohm

a atto 10-18 d deci 10-1

f femto 10-15 dk deca 102

p pico 10-12 k kilo 103

n nano 10-9 myria 104

u micro 10-6 mega 106m milli 10-3 g giga 109

c centi 10-2 t tera 1012

1

1

1lim lnn

n kn

→∞=

= − ∑

Page 663: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題 2

この例題では、光速を異なる単位を使って取得します。

#include <stdio.h>#include <imsl.h>

main(){ float speed_light; /* メートル /秒で光速を取得 */ speed_light = imsl_f_constant("Speed Light", "meter/second"); printf("speed of light = %g meter/second\n", speed_light); /* マイル /秒で光速を取得 */ speed_light = imsl_f_constant("Speed Light", "mile/second"); printf("speed of light = %g mile/second\n", speed_light); /* センチメートル /ナノ秒で光速を取得 */ speed_light = imsl_f_constant("Speed Light", "cm/ns"); printf("speed of light = %g cm/ns\n", speed_light);}

出力結果

speed of light = 2.99792e+08 meter/secondspeed of light = 186282 mile/secondspeed of light = 29.9793 cm/ns

警告エラー

IMSL_MASS_TO_FORCE 質量単位から力の単位への変換は、一貫性が要求

されます。

machine (整数 )そのコンピュータの演算を説明する整数情報を返します。

概要

#include <imsl.h>

int imsl_i_machine (int n)

必要な引数

int n ( 入力 )どの値が返されるかを示す識別子。それは 0 と 12 の間の数でなければ

なりません。

戻り値

要求された値が返されます。 n が範囲外であれば NaN が返されます。

説明

関数 imsl_i_machine はコンピュータの演算を説明する整数情報を返します。

これはプログラムをマシン独立にするために使用されます。

imsl_1_machine(0) = バイトあたりのビット数

次のように、整数は M 桁、基底 -A として形成されるものと想定します。

ここで、σ は符号で、for k = 0,..., M に対して 0 ≤ x k < A です。

n 定義

0

M kkk

x Aσ=∑

Page 664: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

次のように、浮動小数点数は N 桁、基底 B として形成されるものと想定しま

す。

ここで、σ は符号で、k = 0,..., N に対して 0 ≤ x k < B そして E min ≤ E ≤ E maxです。

例題

この例題は IEEE (Institute for Electrical and Electronics Engineer) 演算のマシン上

で imsl_i_machine によって返される全ての値をプリントします。

#include <imsl.h>

main(){ int n, ans;

for (n = 0; n <= 12; n++) { ans = imsl_i_machine(n); printf("imsl_i_machine(%d) = %d\n", n, ans); }}

出力結果

imsl_i_machine(0) = 8imsl_i_machine(1) = 2imsl_i_machine(2) = 15imsl_i_machine(3) = 32767imsl_i_machine(4) = 31imsl_i_machine(5) = 2147483647imsl_i_machine(6) = 2imsl_i_machine(7) = 24imsl_i_machine(8) = -125imsl_i_machine(9) = 128imsl_i_machine(10) = 53imsl_i_machine(11) = -1021imsl_i_machine(12) = 1024

0 C、文字あたりのビット数1 A、基底2 Ms、short int での基底 -A 桁の数

3、最大の short int

4 Ml、 long int での基底 -A 桁の数 5 、最大の long int

n 定義6 B、基底7 Nf、 float での基底 B 桁の数

8 、最小の float 指数

9 、最大の float 指数

10 Nd、double での基底 B 桁の数

11 、最小の double 指数

12 、最大の double 指数

AMs

1–

AM1 1–

1

NE kkk

B x Bσ −=∑

Eminf

Emaxf

Emind

Emaxd

Page 665: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

machine (浮動小数点 )そのコンピュータの浮動小数点演算を説明する情報を返します。

概要

#include <imsl.h>

float imsl_f_machine (int n)

double 型関数は、 imsl_d_machineです。

必要な引数

int n ( 入力 )どの値が返されるかを示す識別子。 それは 0 から 8 の間の数でなけれ

ばなりません。

戻り値

要求された値が返されます。 n が範囲外であれば NaN が返されます。

説明

関数 imsl_f_machine はコンピュータの浮動小数点演算を説明する情報を返

します。これはプログラムをマシン独立にするために使用されます。更に、いくつかの機能は、欠落値を設定するために重要になります。

次のように、浮動小数点数は N f 桁、基底 B として表され、次のように形成さ

れるものと仮定します。

ここで、σ は符号で、k = 0,..., N f- に対して 0 ≤ x k < B そして

です。

B = imsl_i_machine(6)、 N f = imsl_i_machine(7) であることに注意してく

ださい。

そして

二進法演算の ANSI/IEEE Std 754-1985 標準は、0/0 の計算のような種々の例外

反則操作の結果として、NaN (not a number) を使用します。NaN をサポートし

ないコンピュータでは、imsl_d_machine(2) より大きい値が imsl_f_machine(6) に対して返されます。無限大に対して

imsl_f_machine(2) は imsl_f_machine(7) と同じ値を返します。

imsl_f_machine は次の表によって定義されます。

n 定義1

、最小の正の数

2、最大数

3 、最小相対間隔

4 、最大相対間隔

1fNE k

kkB x Bσ −

=∑

min maxf fE E E≤ ≤

min imsl_i_machine(8)f

E =

max imsl_i_machine(9)f

E =

BEmin

f1–

BEmaxf 1 B Nf––( )

B Nf–

B1 Nf–

Page 666: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

関数 imsl_d_machine はコンピュータの倍精度演算を定義するマシン定数

を取得します。double に対して、B = imsl_i_machine(6)、N f = imsl_i_machine(10) であることに注意してください。

そして

IMSL 関数の欠落値は、常に NaN (Not a Number) によって示されます。これは、

単精度における imsl_f_machine(6) そして、倍精度における imsl_d_machine(6) です。整数に対しては、欠落値指標は存在しません。

ユーザは、ほとんどの場合には、その欠落値指標を NaN に変換しなければな

りません。

例題

この例題は、IEEE 演算のマシン上の imsl_f_machine と imsl_d_machine によって返される 8 つの全ての値をプリントします。

#include <imsl.h>

main(){ int n; float fans; double dans;

for (n = 1; n <= 8; n++) { fans = imsl_f_machine(n); printf("imsl_f_machine(%d) = %g\n", n, fans); }

for (n = 1; n <= 8; n++) { dans = imsl_d_machine(n); printf("imsl_d_machine(%d) = %g\n", n, dans); }}

出力結果

imsl_f_machine(1) = 1.17549e-38imsl_f_machine(2) = 3.40282e+38imsl_f_machine(3) = 5.96046e-08imsl_f_machine(4) = 1.19209e-07imsl_f_machine(5) = 0.30103imsl_f_machine(6) = NaNimsl_f_machine(7) = Infimsl_f_machine(8) = -Infimsl_d_machine(1) = 2.22507e-308imsl_d_machine(2) = 1.79769e+308imsl_d_machine(3) = 1.11022e-16imsl_d_machine(4) = 2.22045e-16imsl_d_machine(5) = 0.30103imsl_d_machine(6) = NaNimsl_d_machine(7) = Infimsl_d_machine(8) = -Inf

5 log10(B)6 NaN (not a number)7 正のマシン無限大8 負のマシン無限大

min imsl_i_machine(11)f

E =

max imsl_i_machine(12)f

E =

Page 667: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

sort代数値によってベクトルをソートします。オプションにより、ベクトルは絶対値でソートすることができ、ソートの置換を返すことができます。

概要

#include <imsl.h>

float *imsl_f_sort (int n, float *x, …, 0)

double 型関数は、 imsl_d_sortです。

必要な引数

int n ( 入力 )入力ベクトルの長さ。

float *x ( 入力 )ソートされる入力ベクトルの長さ。

戻り値

昇順にソートされる入力ベクトル x の値を含んだ長さ n のベクトル。エラー

が起こると NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_sort (int n, float *x,IMSL_ABSOLUTE,IMSL_PERMUTATION, int **perm,IMSL_PERMUTATION_USER, int perm_user[],IMSL_RETURN_USER, float y[],0)

オプション引数

IMSL_ABSOLUTE

絶対値によって x をソートします。

IMSL_PERMUTATION, int **perm ( 出力 )ソート置換のポインターを返します。

IMSL_PERMUTATION_USER, int perm_user[] ( 出力 )ユーザ提供の空間にソート置換を返します。

IMSL_RETURN_USER, float y[] ( 出力 )ユーザ提供の空間にソートされたデータを返します。

説明

デフォルトでは、 imsl_f_sort は x の要素を代数値によって昇順にソートし

ます。ベクトルは、ベクトルの中心要素 T を選ぶことによって 2 つの部分に

分割されます。x の最初と最後の要素が T と比較されて、3 つの値が昇順にベ

クトルの中に現れるまで交換されます。ベクトルの要素は、中心要素よりも大きいか、等しい全ての要素がベクトルの 2 番目の部分に現れて、中心要素より

も小さいか、等しい全ての要素が最初の部分に現れるまで再配置されます。区分の上と下の指標が保存されて、このプロセスはその他の区分上に反復的に継続されます。1 つの区分のソートが終わったときに、このプロセスは再びベク

トルのソートされない他の部分の指標を取得することによって始められます。終了したときは、j < i に対して、x j ≤ xi です。オプション IMSL_ABSOLUTE が選択されると、x の要素は絶対値によって昇順にソートされます。y によって

戻りベクトルを示すとすると、終了したときは、j < i に対して |yj | ≤ |yi | になり

ます。

Page 668: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション IMSL_PERMUTATION が選択されると、配列 x の置換の記録が返さ

れます。これは、permi = i の後で、perm の要素は x の要素がされたように

移動されます。

例題

例題 1

この例題では、入力ベクトルが代数的にソートされます。

#include <stdio.h>#include <imsl.h>

main(){ float x[] = {1.0, 3.0, -2.0, 4.0}; float *sorted_result; int n;

n = 4; sorted_result = imsl_f_sort (n, x, 0);

imsl_f_write_matrix("Sorted vector", 1, 4, sorted_result, 0);}

出力結果

Sorted vector 1 2 3 4-2 1 3 4

例題 2

この例題は入力ベクトルが絶対値でソートされて、ユーザ提供の空間に保存された結果がプリントされます。

#include <stdio.h>#include <imsl.h>

main(){ float x[] = {1.0, 3.0, -2.0, 4.0}; float sorted_result[4]; int n;

n = 4; imsl_f_sort (n, x, IMSL_ABSOLUTE, IMSL_RETURN_USER, sorted_result, 0);

imsl_f_write_matrix("Sorted vector", 1, 4, sorted_result, 0);}

出力結果

Sorted vector1 2 3 41 -2 3 4

sort (整数 )代数値によって整数ベクトルをソートします。オプションにより、ベクトルは絶対値でソートすることができ、ソートの置換を返すことができます。

概要

#include <imsl.h>

Page 669: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int *imsl_i_sort (int n, int *x, …, 0)

必要な引数

int n ( 入力 )入力ベクトルの長さ。

int *x ( 入力 )ソートされる入力ベクトルの長さ。

戻り値

昇順にソートされる入力ベクトル x の値を含んだ長さ n のベクトル。エラー

が起こると NULL が返されます。

オプション引数の概要

#include <imsl.h>

int *imsl_i_sort (int, n int *x,IMSL_ABSOLUTE,IMSL_PERMUTATION, int **perm,IMSL_PERMUTATION_USER, int perm_user[],IMSL_RETURN_USER, int y[],0)

オプション引数

IMSL_ABSOLUTE絶対値によって x をソートします。

IMSL_PERMUTAION, int **perm ( 出力 )ソート置換のポインターを返します。

IMSL_PERMUTATION_USER, int perm_user[] ( 出力 )ユーザ提供の空間にソート置換を返します。

IMSL_RETURN_USER, int y[] ( 出力 )ユーザ提供の空間にソートされたデータを返します。

説明

デフォルトでは、 imsl_i_sort は x の要素を代数値によって昇順にソートし

ます。ベクトルは、ベクトルの中心要素 T を選ぶことによって 2 つの部分に

分割されます。x の最初と最後の要素が T と比較されて、3 つの値が昇順にベ

クトルの中に現れるまで交換されます。ベクトルの要素は、中心要素よりも大きいか、等しい全ての要素がベクトルの 2 番目の部分に現れて、中心要素より

も小さいか、等しい全ての要素が最初の部分に現れるまで再配置されます。区分の上と下の指標が保存されて、このプロセスはその他の区分上に反復的に継続されます。1 つの区分のソートが終わったときに、このプロセスは再びベク

トルのソートされない他の部分の指標を取得することによって始められます。終了したときは、j < i に対して、x j ≤ xi です。オプション IMSL_ABSOLUTE が選択されると、x の要素は絶対値によって昇順にソートされます。y によって

戻りベクトルを示すとすると、終了したときは、j < i に対して |yj | ≤ |yi | になり

ます。

オプション IMSL_PERMUTATION が選択されると、配列 x の置換の記録が返さ

れます。これは、permi = i の後で、perm の要素は x の要素がされたように

移動されます。

例題

例題 1

この例題では、入力ベクトルが代数的にソートされます。

#include <stdio.h>#include <imsl.h>

main()

Page 670: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

{ int x[] = {1, 3, -2, 4}; int*sorted_result; int n;

n = 4; sorted_result = imsl_i_sort (n, x, 0);

imsl_i_write_matrix("Sorted vector", 1, 4, sorted_result, 0);}

出力結果

Sorted vector 1 2 3 4-2 1 3 4

例題 2

この例題は、絶対値によって入力ベクトルをソートして、ユーザ割り当ての空間に保存された結果をプリントします。

#include <stdio.h>#include <imsl.h>

main(){ int x[] = {1, 3, -2, 4}; intsorted_result[4]; intn;

n = 4; imsl_i_sort (n, x, IMSL_ABSOLUTE, IMSL_RETURN_USER, sorted_result, 0);

imsl_i_write_matrix("Sorted vector", 1, 4, sorted_result, 0);}

出力結果

Sorted vector 1 2 3 4 1 -2 3 4

vector_normベクトルの様々なノルム、又は、2 つのベクトルの差を計算します。

概要

#include <imsl.h>

float imsl_f_vector_norm (int n, float *x, …., 0)

double 型関数は、 imsl_d_vector_normです。

必要な引数

int n ( 入力 )入力ベクトルの長さ。

float *x ( 入力 )ノルムが計算される入力ベクトル。

戻り値

入力ベクトルの要求されるノルム。 ノルムが計算できない場合、NaN が返され

ます。

Page 671: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数の概要

#include <imsl.h>

float imsl_f_vector_norm (int n, float *x,IMSL_ONE_NORM,IMSL_INF_NORM,IMSL_SECOND_VECTOR, float *y,0)

説明

デフォルトで、imsl_f_vector_norm は次のユークリッドノルムを計算しま

す。

オプション IMSL_ONE_NORM が選択されると 1 ‐ノルム

が返されます。オプション IMSL_INF_NORM が選択されると、無限ノルム

max |xi|

が返されます。 無限ノルムの場合には、このプログラムは、最大絶対値の要素

の指標も返します。IMSL_SECOND_VECTOR が選択されると、x − y のノルム

が計算されます。

例題

例題 1

この例題では、入力ベクトルのユークリッドノルムを計算します。

#include <stdio.h>#include "imsl.h"

main(){ float x[] = {1.0, 3.0, -2.0, 4.0}; float norm; int n;

n = sizeof(x)/sizeof(*x); norm = imsl_f_vector_norm (n, x, 0);

printf("Euclidean norm of x = %f\n", norm);}

出力結果

Euclidean norm of x = 5.477226

例題 2

この例題は max | xi − yi | を計算して、ノルムと指標をプリントします。

#include <stdio.h>#include "imsl.h"

main(){ float x[] = {1.0, 3.0, -2.0, 4.0}; float y[] = {4.0, 2.0, -1.0, -5.0}; float norm;

11 2

2

0

n

ii

x−

=

1

0

n

ii

x−

=∑

Page 672: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int index; int n;

n = sizeof(x)/sizeof(*x); norm = imsl_f_vector_norm (n, x, IMSL_SECOND_VECTOR, y, IMSL_INF_NORM, &index, 0);

printf("Infinity norm of x-y = %f ", norm); printf("at location %d\n", index);}

出力結果

Infinity norm of x-y = 9.000000 at location 3

mat_mul_rect行列の転置、行列 - ベクトル積、行列 - 行列積、双一次形、又は、三重積を計

算します。

概要

#include <imsl.h>

float *imsl_f_mat_mul_rect (char *string, …, 0)

double 型関数は、imsl_d_mat_mul_rectです。

必要な引数

char *string ( 入力 )実行される行列乗積を示す文字列。

戻り値

乗積の結果。 これはその結果が単一数であったとしても、常に float へのポイン

ターです。この空間を解放するために、free を使用します。答えが計算できな

い場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>

float *imsl_f_mat_mul_rect (char *string,IMSL_A_MATRIX, int nrowa, int ncola, float a[],IMSL_A_COL_DIM, int a_col_dim,IMSL_B_MATRIX, int nrowb, int ncolb, float b[],IMSL_B_COL_DIM, int b_col_dim,IMSL_X_VECTOR, int nx, float *x,IMSL_Y_VECTOR, int ny, float *y,IMSL_RETURN_USER, float ans[],IMSL_RETURN_COL_DIM, int return_col_dim,0)

オプション引数

IMSL_A_MATRIX, int nrowa, int ncola, float a[] ( 入力 )nrowa × ncola 行列 A 。

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 A の列ディメンジョン。

デフォルト: a_col_dim = ncola

IMSL_B_MATRIX, int nrowb, int ncolb, float b[] ( 入力 )nrowb × ncolb 行列 A 。

Page 673: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_B_COL_DIM, int b_col_dim ( 入力 )B の列ディメンジョン。 デフォルト: b_col_dim = ncolb

IMSL_X_VECTOR, int nx, float *x ( 入力 )サイズ nx のベクトル x。

IMSL_Y_VECTOR, int ny, float *y ( 入力 )サイズ ny のベクトル y 。

IMSL_RETURN_USER, float ans[] ( 出力 )結果を含む、ユーザ割り当ての配列。

IMSL_RETURN_COL_DIM, int return_col_dim ( 入力 )答えの列ディメンジョン。 デフォルト: return_col_dim = 解答の列数。

説明

この関数は、string によって与えられる仕様に従って行列 - ベクトル積、行

列 - 行列積、行列の双一次形、又は、三重積を計算します。例えば、“A*x” が与えられると Ax が計算されます。 String の中で、行列 A と B そしてベクト

ル x と y を使用することができます。いずれの 4 つの名前は、転置を示す trans と共に使用することができます。ベクトル x と y は、n × 1 行列をして

扱われます。

String が、“x” 又は “trans(A)” などの1項目だけを含む場合、配列、或い

は、その転置のコピーが返されます。string が、“A*x” 又は “B*A” などの

1つの乗積を含むならば、示されたその積が返されます。string の幾つか

の規定値は “trans(y)*A”、 “A*trans(B)”、“x*trans(y)” 又は “trans(x)*y” です。

文字列の中で参照される行列やベクトルはオプションの引数として与えられなければなりません。string が “B*x” であれば、IMSL_B_MATRIX と IMSL_X_VECTOR が与えられなければなりません。

例題

配列 A T、Ax、x TA T、AB、B TA T、x Ty、xy T、x TAy を計算し、プリントしま

す。

#include <imsl.h>

main(){ float A[] = {1, 2, 9, 5, 4, 7}; float B[] = {3, 2, 7, 4, 9, 1}; float x[] = {7, 2, 1}; float y[] = {3, 4, 2}; float *ans;

ans = imsl_f_mat_mul_rect("trans(A)", IMSL_A_MATRIX, 2, 3, A, 0); imsl_f_write_matrix("trans(A)", 3, 2, ans, 0);

ans = imsl_f_mat_mul_rect("A*x", IMSL_A_MATRIX, 2, 3, A,

3 2 7 31 2 9

7 4 2 45 4 7

9 1 1 2A B x y

= = = =

Page 674: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_X_VECTOR, 3, x, 0); imsl_f_write_matrix("A*x", 1, 2, ans, 0);

ans = imsl_f_mat_mul_rect("trans(x)*trans(A)", IMSL_A_MATRIX, 2, 3, A, IMSL_X_VECTOR, 3, x, 0); imsl_f_write_matrix("trans(x)*trans(A)", 1, 2, ans, 0);

ans = imsl_f_mat_mul_rect("A*B", IMSL_A_MATRIX, 2, 3, A, IMSL_B_MATRIX, 3, 2, B, 0); imsl_f_write_matrix("A*B", 2, 2, ans, 0);

ans = imsl_f_mat_mul_rect("trans(B)*trans(A)", IMSL_A_MATRIX, 2, 3, A, IMSL_B_MATRIX, 3, 2, B, 0); imsl_f_write_matrix("trans(B)*trans(A)", 2, 2, ans, 0);

ans = imsl_f_mat_mul_rect("trans(x)*y", IMSL_X_VECTOR, 3, x, IMSL_Y_VECTOR, 3, y, 0); imsl_f_write_matrix("trans(x)*y", 1, 1, ans, 0);

ans = imsl_f_mat_mul_rect("x*trans(y)", IMSL_X_VECTOR, 3, x, IMSL_Y_VECTOR, 3, y, 0); imsl_f_write_matrix("x*trans(y)", 3, 3, ans, 0);

ans = imsl_f_mat_mul_rect("trans(x)*A*y", IMSL_A_MATRIX, 2, 3, A, /* use only the first 2 components of x */ IMSL_X_VECTOR, 2, x, IMSL_Y_VECTOR, 3, y, 0); imsl_f_write_matrix("trans(x)*A*y", 1, 1, ans, 0);}

出力結果

trans(A) 1 21 1 52 2 43 9 7 A*x 1 2 20 50 trans(x)*trans(A) 1 2 20 50

A*B 1 21 98 192 106 33 trans(B)*trans(A) 1 21 98 106

Page 675: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

2 19 33 trans(x)*y 31 x*trans(y) 1 2 31 21 28 14

2 6 8 43 3 4 2 trans(x)*A*y 293

mat_mul_rect (複素数 )行列の転置、行列の共役転置、行列 - ベクトル積、行列 - 行列積、双一次形、

又は三重積を計算します。

概要

#include <imsl.h>

f_complex *imsl_c_mat_mul_rect (char *string, …, 0)

d_complex 型関数は、 imsl_z_mat_mul_rectです。

必要な引数

char *string ( 入力 )実行される行列乗積を示す文字列。

戻り値

乗算の結果。 この結果が単一数であっても、常に f_complex, のポインターです。

この空間を解放するために、free を使用します。答えが計算できない場合、

NULL が返されます。

オプション引数の概要

#include <imsl.h>

f_complex *imsl_c_mat_mul_rect (char *string,IMSL_A_MATRIX, int nrowa, int ncola, f_complex *a,IMSL_A_COL_DIM, int a_col_dim,IMSL_B_MATRIX, int nrowb, int ncolb, f_complex *b,IMSL_B_COL_DIM, int b_col_dim,IMSL_X_VECTOR, int nx, f_complex *x,IMSL_Y_VECTOR, int ny, f_complex *y,IMSL_RETURN_USER, f_complex ans[],IMSL_RETURN_COL_DIM, int return_col_dim,0)

オプション引数

IMSL_A_MATRIX, int nrowa, int ncola, f_complex *a ( 入力 )nrowa × ncola 行列 A。

IMSL_A_COL_DIM, int a_col_dim ( 入力 )配列 A の列ディメンジョン。

デフォルト: a_col_dim = ncola

IMSL_B_MATRIX, int nrowb, int ncolb, f_complex *b ( 入力 )nrowb × ncolb 行列 B。

Page 676: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_B_COL_DIM, int b_col_dim ( 入力 )B の列ディメンジョン。

デフォルト: b_col_dim = ncolb

IMSL_X_VECTOR, int nx, f_complex *x ( 入力 )サイズ nx のベクトル x。

IMSL_Y_VECTOR, int ny, f_complex *y ( 入力 )サイズ ny のベクトル y 。

IMSL_RETURN_USER, f_complex ans[] ( 出力 )結果を含む、ユーザ割り当ての配列。

IMSL_RETURN_COL_DIM, int return_col_dim ( 入力 )解答の列ディメンジョン。 デフォルト: return_col_dim = 解答内の解の列数

説明

この関数は string によって与えられた指定に従い、行列 - ベクトル積、行

列 - 行列積、行列の双一次形、又は三重積を計算します。例えば、“A*x” が与

えられると Ax が計算されます。 string の中で、行列 A と B そしてベクトル x と y を使用することができます。. これらの4つのいずれの名称は、転置を示

す trans 、共役(又はエルミート)転置を示す ctrans と共に使用すること

ができます。ベクトル x と y は、n × 1 行列として扱われます。

もし string が “x” 或いは “trans(A)” のように1項目だけを含む場合、配

列、或いは、その転置のコピーが返されます。string が “A*x” 又は “B*A” のように1つの乗積を含めば、示された積が返されます。string のその他

の正規の値は “trans(y)*A”、“A*ctrans(B)”、“x*trans(y)” 又は “ctrans(x)*y” です。

string の中で参照される行列やベクトルはオプションの引数として与えら

れなければなりません。string が “B*x” であれば、IMSL_B_MATRIX と IMSL_X_VECTOR が与えられなければなりません。

例題

配列 A H、Ax、x TA T、AB、B HA T、x Ty、xy H が計算されてプリントされま

す。

#include <imsl.h>

main(){ f_complex A[] = {{1,4}, {2, 3}, {9,6}, {5,2}, {4,-3}, {7,1}};

f_complex B[] = {{3,-6}, {2, 4}, {7, 3}, {4,-5}, {9, 2}, {1, 3}};

f_complex x[] = {{7,4}, {2, 2}, {1,-5}}; f_complex y[] = {{3,4}, {4,-2}, {2, 3}}; f_complex *ans;

ans = imsl_c_mat_mul_rect("ctrans(A)",

3 6 2 41 4 2 3 9 6

7 3 4 55 2 4 3 7

9 2 1 3

7 4 3 42 2 4 21 5 2 3

i ii i i

A B i ii i i

i i

i ix i y i

i i

− + + + + = = + − + − + + +

+ + = + = − − +

Page 677: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_A_MATRIX, 2, 3, A, 0); imsl_c_write_matrix("ctrans(A)", 3, 2, ans, 0);

ans = imsl_c_mat_mul_rect("A*x", IMSL_A_MATRIX, 2, 3, A, IMSL_X_VECTOR, 3, x, 0); imsl_c_write_matrix("A*x", 1, 2, ans, 0);

ans = imsl_c_mat_mul_rect("trans(x)*trans(A)", IMSL_A_MATRIX, 2, 3, A, IMSL_X_VECTOR, 3, x, 0); imsl_c_write_matrix("trans(x)*trans(A)", 1, 2, ans, 0);

ans = imsl_c_mat_mul_rect("A*B", IMSL_A_MATRIX, 2, 3, A, IMSL_B_MATRIX, 3, 2, B, 0); imsl_c_write_matrix("A*B", 2, 2, ans, 0);

ans = imsl_c_mat_mul_rect("ctrans(B)*trans(A)", IMSL_A_MATRIX, 2, 3, A, IMSL_B_MATRIX, 3, 2, B, 0); imsl_c_write_matrix("ctrans(B)*trans(A)", 2, 2, ans, 0);

ans = imsl_c_mat_mul_rect("trans(x)*y", IMSL_X_VECTOR, 3, x, IMSL_Y_VECTOR, 3, y, 0); imsl_c_write_matrix("trans(x)*y", 1, 1, ans, 0);

ans = imsl_c_mat_mul_rect("x*ctrans(y)", IMSL_X_VECTOR, 3, x, IMSL_Y_VECTOR, 3, y, 0); imsl_c_write_matrix("x*ctrans(y)", 3, 3, ans, 0);}

出力結果

ctrans(A) 1 21 ( 1, -4) ( 5, -2)2 ( 2, -3) ( 4, 3)3 ( 9, -6) ( 7, -1) A*x 1 2( 28, 3) ( 53, 2) trans(x)*trans(A) 1 2( 28, 3) ( 53, 2) A*B 1 21 ( 101, 105) ( 0, 47)2 ( 125, -10) ( 7, 14) ctrans(B)*trans(A) 1 21 ( 95, 69) ( 87, -2)2 ( 38, 5) ( 59, -28)

Page 678: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

trans(x)*y( 34, 37)

x*ctrans(y) 1 2 31 ( 37, -16) ( 20, 30) ( 26, -13)2 ( 14, -2) ( 4, 12) ( 10, -2)3 ( -17, -19) ( 14, -18) ( -13, -13)

mat_mul_rect_band全ての行列が帯形で保存された、行列の転置、行列 - ベクトル積、行列 - 行列

積を計算します。

概要

#include <imsl.h>

float *imsl_f_mat_mul_rect_band (char *string, ..., 0)

同様の double 型関数は、 imsl_d_mat_mul_rect_bandです。

必要な引数

char *string ( 入力 )実行される行列乗積を示す文字列。

戻り値

乗算の結果が返されます。この空間を解放するために、free を使用します。

オプション引数の概要

#include <imsl.h>

void *imsl_f_mat_mul_rect_band (char *string,IMSL_A_MATRIX, int nrowa, int ncola, int nlca, int nuca, float *a,IMSL_B_MATRIX, int nrowb, int ncolb, int nlcb, int nucb, float *b,IMSL_X_VECTOR, int nx, float *x,IMSL_RETURN_MATRIX_CODIAGONALS, int *nlc_result, int *nuc_result,IMSL_RETURN_USER_VECTOR, float vector_user[],0)

オプション引数

IMSL_A_MATRIX, int nrowa, int ncola, int nlca, int nuca, float *a ( 入力 )疎行列

IMSL_B_MATRIX, int nrowb, int ncolb, int nlcb, int nucb, float *b ( 入力 )疎行列

IMSL_X_VECTOR, int nx, float *x, ( 入力 )長さ nx のベクトル x。

IMSL_RETURN_MATRIX_CODIAGONALS, int *nlc_result, int *nuc_result, ( 出力 )関数 imsl_f_mat_mul_rect_band が帯行列のデータを返す場合、

このオプションを使用して返された行列の下と上の共対角項の数を取

得します。

nrowa ncolaA ×∈ℜ

nrowb xnolbB ×∈ ℜ

Page 679: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_RETURN_USER_VECTOR, float vector_user[], ( 出力 )計算の結果がベクトルであれば、その答はユーザ提供の疎の vector_user の中に返されます。

説明

関数 imsl_f_mat_mul_rect_band はその行列が帯形式で指定された、行

列 - 行列積、又は、行列 - ベクトル積を計算します。実行される処理は string で指定されます。例えば、“A*x” が与えられると Ax が計算されます。

String の中で行列 A と B 、そしてベクトル x を使用することができます。こ

れらの名称のいずれでも転置を示す trans を共に使用することができます。

ベクトル x は、密な n × 1 行列として扱われます。string が “x” 又は “trans(A)” などの1項目だけを含む場合、配列、又は、その転置のコピーが

返されます。

string の中で参照される行列やベクトルはオプション引数として与えられな

ければなりません。そのために string が “A*x” であれば、

IMSL_A_MATRIX と IMSL_X_VECTOR が与えられる必要があります。

例題

例題 1

次の行列を考えます。

A を帯形式で保管した後で、A と x = (1, 2, 3, 4)T を掛けて、結果をプリントし

ます。

#include <imsl.h>main(){ float a[] = {0.0, -1.0, -2.0, 2.0, 2.0, 1.0, -1.0, 1.0, -3.0, 0.0, 2.0, 0.0};

float x[] = {1.0, 2.0, 3.0, 4.0}; int n = 4; int nuca = 1; int nlca = 1; float *b; /* b = A*x を設定 */

b = imsl_f_mat_mul_rect_band ("A*x", IMSL_A_MATRIX, n, n, nlca, nuca, a, IMSL_X_VECTOR, n, x, 0); imsl_f_write_matrix ("Product, Ax", 1, n, b, 0);}

出力結果 Product, Ax 1 2 3 4 0 -7 5 10

例題 2

この例題は E(100, 10) の主要固有ベクトルを決定するためにべき乗法を使用し

ます。同じ計算が imsl_f_eig_sym を使用して実行されます。第 2 章:固

2 1 0 03 1 2 0

0 0 1 20 0 2 1

A

− − − = −

Page 680: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

有方程式解析を参照してください。反復は、imsl_f_eig_sym によって見つ

けられた主要固有ベクトルの間の要素並びの絶対偏差と、現在の反復の固有ベクトルが、マシン単位の丸め誤差の平方根より小さければ停止します。

#include <imsl.h>#include <math.h>

void main(){ int i; int j; int k; int n; int c; int nz; int index; int start; int stop; float *a; float *z; float *q; float *dense_a; float *dense_evec; float *dense_eval; float norm; float *evec; float error; float tolerance;

n = 100; c = 10; tolerance = sqrt(imsl_f_machine(4)); error = 1.0; evec = (float*) malloc (n*sizeof(*evec)); z = (float*) malloc (n*sizeof(*z)); q = (float*) malloc (n*sizeof(*q)); dense_a = (float*) calloc (n*n, sizeof(*dense_a)); a = imsl_f_generate_test_band (n, c, 0);

/* 上三角から出発して

密形式に変換 */

start = c; for (i=0; i<c; i++, start--) for (k=0, j=start; j<n; j++, k++) dense_a[k*n + j] = a[i*n + j];

/* 対角項を変換 */

for (j=0; j<n; j++) dense_a[j*n + j] = a[c*n + j];

/* 下三角を変換 */ stop = n-1; for (i=c+1; i<2*c+1; i++, stop--) for (k=i-c, j=0; j<stop; j++, k++) dense_a[k*n + j] = a[i*n + j];

/* 稠密法によって主要固有ベクトルを決定 */

dense_eval = imsl_f_eig_sym (n, dense_a, IMSL_VECTORS, &dense_evec, 0); for (i=0; i<n; i++) evec[i] = dense_evec[n*i];

Page 681: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* 正規化 */

norm = imsl_f_vector_norm (n, evec, 0); for (i=0; i<n; i++) evec[i] /= norm;

for (i=0; i<n; i++) q[i] = 1.0/sqrt((float) n); /* べき乗法を実行 */

while (error > tolerance) { imsl_f_mat_mul_rect_band ("A*x", IMSL_A_MATRIX, n, n, c, c, a, IMSL_X_VECTOR, n, q, IMSL_RETURN_USER_VECTOR, z, 0);

/* 正規化 */

norm = imsl_f_vector_norm (n, z, 0); for (i=0; i<n; i++) q[i] = z[i]/norm;

/* どの 2要素間の最大絶対誤差を計算 */

error = imsl_f_vector_norm (n, q, IMSL_SECOND_VECTOR, evec, IMSL_INF_NORM, &index, 0); } printf ("Maximum absolute error = %e\n", error);}

出力結果

Maximum absolute error = 3.367960e-04

mat_mul_rect_band (複素数 )全ての行列が複素タイプの帯形で保存された、行列の転置、行列 - ベクトル

積、行列 - 行列積を計算します。

概要

#include <imsl.h>f_complex *imsl_c_mat_mul_rect_band (char *string, ..., 0)

同様の d_complex 型関数は、 imsl_z_mat_mul_rect_bandです。

必要な引数

char *string ( 入力 )実行される行列乗積を示す文字列。

戻り値

乗算の結果が返されます。この空間を解放するために、free を使用します。

オプション引数の概要

#include <imsl.h>

void *imsl_c_mat_mul_rect_band (char *string,IMSL_A_MATRIX, int nrowa, int ncola, int nlca, int nuca, f_complex *a,IMSL_B_MATRIX, int nrowb, int ncolb, int nlcb, int nucb, f_complex *b,IMSL_X_VECTOR, int nx, f_complex *x,IMSL_RETURN_MATRIX_CODIAGONALS, int *nlc_result,

Page 682: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int *nuc_result,IMSL_RETURN_USER_VECTOR, f_complex vector_user[],0)

オプション引数

IMSL_A_MATRIX, int nrowa, int ncola, int nlca, int nuca, f_complex *a ( 入力 )疎行列

IMSL_B_MATRIX, int nrowb, int ncolb, int nlcb, int nucb, f_complex *b ( 入力 )疎行列

IMSL_X_VECTOR, int nx, f_complex *x, ( 入力 )長さ nx のベクトル x。

IMSL_RETURN_MATRIX_CODIAGONALS, int *nlc_result, int *nuc_result, ( 出力 )関数 imsl_c_mat_mul_rect_band が帯行列のデータを返す場合、

返された行列の下と上の共対角項の数を取得します。

IMSL_RETURN_USER_VECTOR, f_complex vector_user[], ( 出力 )計算の結果がベクトルであれば、その答はユーザ提供の疎の vector_user の中に返されます。

説明

関数 imsl_c_mat_mul_rect_band はその行列が帯形式で指定された、行列 -行列積、又は、行列 - ベクトル積を計算します。実行される処理は string で指定されます。例えば、“A*x” が与えられると Ax が計算されます。String の中で行列 A と B 、そしてベクトル x を使用することができます。これらの名

称は、転置を示す trans を共に使用することができます。ベクトル x は、密

な n × 1 行列として扱われます。string が “x” 又は “trans(A)” などの1

項目だけを含む場合、配列、又は、その転置のコピーが返されます。

string の中で参照される行列とかベクトルはオプション引数として与えられ

なければなりません。そのために string が “A*x” であれば、

IMSL_A_MATRIX と IMSL_X_VECTOR が与えられる必要があります。

例題

例題 1

以下のような A と x があります。

nrowa ncolaA ×∈ ℜ

nrowb xnolbB ×∈ℜ

2 4 0 06 0.5 3 2 2 0

0 1 3 3 40 0 2 1

i i iA

i i ii i

− + − + − + = + − − −

313

1

ix

i

− + = − +

Page 683: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

この例題は積 Ax を計算します。

#include <imsl.h>

main(){ int n = 4; int nlca = 1; int nuca = 1; f_complex *b;

/* a は帯格納様式であることに注意 */

f_complex a[] = {{0.0, 0.0}, {4.0, 0.0}, {-2.0, 2.0}, {-4.0, -1.0}, {-2.0, -3.0}, {-0.5, 3.0}, {3.0, -3.0}, {1.0, -1.0}, {6.0, 1.0}, {1.0, 1.0}, {0.0, 2.0}, {0.0, 0.0}};

f_complex x[] = {{3.0, 0.0}, {-1.0, 1.0}, {3.0, 0.0}, {-1.0, 1.0}}; /* b = A*xを設定 */

b = imsl_c_mat_mul_rect_band ("A*x", IMSL_A_MATRIX, n, n, nlca, nuca, a, IMSL_X_VECTOR, n, x, 0); imsl_c_write_matrix ("Product, Ax", 1, n, b, 0);}

出力結果

Product, Ax 1 2 3( -10.0, -5.0) ( 9.5, 5.5) ( 12.0, -12.0) 4( 0.0, 8.0)

例題 2

前の例題で与えられたものと同じ行列 A とベクトル x を使用して、積 Ax、 A Tx、 A Hx と AA H を計算します。

#include <imsl.h>

#include <stdlib.h>main(){ int n = 4; int nlca = 1; int nuca = 1; f_complex *b; f_complex *z; int nlca_z; int nuca_z;

/* a は帯格納様式であることに注意 */

f_complex a[] = {{0.0, 0.0}, {4.0, 0.0}, {-2.0, 2.0}, {-4.0, -1.0}, {-2.0, -3.0}, {-0.5, 3.0}, {3.0, -3.0}, {1.0, -1.0}, {6.0, 1.0}, {1.0, 1.0}, {0.0, 2.0}, {0.0, 0.0}};

f_complex x[] = {{3.0, 0.0}, {-1.0, 1.0}, {3.0, 0.0}, {-1.0, 1.0}}; /* b = A*xを設定 */

Page 684: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

b = imsl_c_mat_mul_rect_band ("A*x", IMSL_A_MATRIX, n, n, nlca, nuca, a, IMSL_X_VECTOR, n, x, 0); imsl_c_write_matrix ("Ax", 1, n, b, 0); free(b);

/* b = trans(A)*xを設定 */

b = imsl_c_mat_mul_rect_band ("trans(A)*x", IMSL_A_MATRIX, n, n, nlca, nuca, a, IMSL_X_VECTOR, n, x, 0); imsl_c_write_matrix ("\n\ntrans(A)x", 1, n, b, 0); free(b);

/* b = ctrans(A)*xを設定 */

b = imsl_c_mat_mul_rect_band ("ctrans(A)*x", IMSL_A_MATRIX, n, n, nlca, nuca, a, IMSL_X_VECTOR, n, x, 0); imsl_c_write_matrix ("\n\nctrans(A)x", 1, n, b, 0); free(b);

/* z = A*ctrans(A)を設定 */

z = imsl_c_mat_mul_rect_band ("A*ctrans(A)", IMSL_A_MATRIX, n, n, nlca, nuca, a, IMSL_X_VECTOR, n, x, IMSL_RETURN_MATRIX_CODIAGONALS, &nlca_z, &nuca_z, 0); imsl_c_write_matrix("A*ctrans(A)", nlca_z+nuca_z+1, n, z, 0);}

出力結果 Ax 1 2 3( -10.0, -5.0) ( 9.5, 5.5) ( 12.0, -12.0) 4( 0.0, 8.0) trans(A)x 1 2 3( -13.0, -4.0) ( 12.5, -0.5) ( 7.0, -15.0) 4( -12.0, -1.0) ctrans(A)x 1 2 3( -11.0, 16.0) ( 18.5, -0.5) ( 15.0, 11.0) 4( -14.0, 3.0)

A*ctrans(A) 1 2 31 ( 0.00, 0.00) ( 0.00, 0.00) ( 4.00, -4.00)

Page 685: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

2 ( 0.00, 0.00) ( -17.00, -28.00) ( -9.50, 3.50)3 ( 29.00, 0.00) ( 54.25, 0.00) ( 37.00, 0.00)4 ( -17.00, 28.00) ( -9.50, -3.50) ( -9.00, 11.00)5 ( 4.00, 4.00) ( 4.00, -4.00) ( 0.00, 0.00) 41 ( 4.00, 4.00)2 ( -9.00, -11.00)3 ( 6.00, 0.00)4 ( 0.00, 0.00)5 ( 0.00, 0.00)

mat_mul_rect_coordinate疎の座標形式で保存された全ての行列のための、行列の転置、行列 - ベクトル

積、行列 - 行列積を計算します。

概要

#include <imsl.h>void *imsl_f_mat_mul_rect_coordinate (char *string, ..., 0)

同様の double 型関数は、 imsl_d_mat_mul_rect_coordinateです。

必要な引数

char *string ( 入力 )実行される行列乗積を示す文字列。

戻り値

乗算の結果が返されます。 結果がベクトルであるならば、返されるタイプは float へのポインターです。乗算の結果が疎行列の場合、返されるタイプは Imsl_f_sparse_elem へのポインターになります。この空間を解放するために、

free を使用します。

オプション引数の概要

#include <imsl.h>

void *imsl_f_mat_mul_rect_coordinate (char *string,IMSL_A_MATRIX, int nrowa, int ncola, int nza, Imsl_f_sparse_elem *a,IMSL_B_MATRIX, int nrowb, int ncolb, int nzb, Imsl_f_sparse_elem *b,IMSL_X_VECTOR, int nx, float *x,IMSL_RETURN_MATRIX_SIZE, int *size,IMSL_RETURN_USER_VECTOR, float vector_user[],0)

オプション引数

IMSL_A_MATRIX, int nrowa, int ncola, int nza, Imsl_f_sparse_elem *a ( 入力 )nza 非ゼロ要素を持つ疎行列

IMSL_B_MATRIX, int nrowb, int ncolb, int nzb, Imsl_f_sparse_elem *b ( 入力 )nzb 非ゼロ要素を持つ疎行列

IMSL_X_VECTOR, int nx, float *x, ( 入力 )長さ nx のベクトル x。

nrowa ncolaA ×∈ ℜ

nrowb xnolbB ×∈ℜ

Page 686: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_RETURN_MATRIX_SIZE, int *size, ( 出力 )関数 imsl_f_mat_mul_rect_coordinate が Imsl_f_sparse_elem 型のベ

クトルを返す場合、このオプションを使用して返されたベクトルの長さ、即ち、要求された計算によって生成された疎行列の中の非ゼロ要素の数を検索します。

IMSL_RETURN_USER_VECTOR, float vector_user[], ( 出力 )計算の結果がベクトルであれば、その答はユーザ提供の疎の vector_user の中に返されます。それのサイズは計算に依存します。

説明

関数 imsl_f_mat_mul_rect_coordinate はその行列が座標表現で指定され

た、行列 - 行列積、又は、行列 - ベクトル積を計算します。実行される処理は string で指定されます。例えば、“A*x” が与えられると Ax が計算されます。

String の中で行列 A と B 、そしてベクトル x を使用することができます。こ

れらの名称のいずれでも転置を示す trans を共に使用することができます。

ベクトル x は、密な n × 1 行列として扱われます。

string が “x” 又は “trans(A)” などの 1 項目だけを含む場合、配列、又は、

その転置のコピーが返されます。“A*ctrans(A)” “trans(x)*B” などの、

ある乗算は結果として対応形式の疎行列を生成します。“B*x” のようなその

他の積は結果のベクトルを含む浮動小数点タイプへのポインターを生成します。

string の中で参照される行列やベクトルはオプション引数として与えられ

なければならなりません。そのために string が “A*x”であれば、

IMSL_A_MATRIX と IMSL_X_VECTOR が与えられなければなりません。

例題

例題 1

この例題では、座標形式の疎行列がベクトルの掛けられます。

#include <imsl.h>main(){ Imsl_f_sparse_elem a[] = {0, 0, 10.0, 1, 1, 10.0, 1, 2, -3.0, 1, 3, -1.0, 2, 2, 15.0, 3, 0, -2.0, 3, 3, 10.0, 3, 4, -1.0, 4, 0, -1.0, 4, 3, -5.0, 4, 4, 1.0, 4, 5, -3.0, 5, 0, -1.0, 5, 1, -2.0, 5, 5, 6.0};

float b[] = {10.0, 7.0, 45.0, 33.0, -34.0, 31.0}; int n = 6; int nz = 15; float *x; /* x = A*bを設定 */

x = imsl_f_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, b, 0); imsl_f_write_matrix ("Product Ab", 1, n, x, 0);}

Page 687: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

出力結果

Product Ab 1 2 3 4 5 6 100 -98 675 344 -302 162

例題 2

この例題は、E(100,10) の主要固有ベクトルを決定するためにべき乗法を使用

します。同じ計算が imsl_f_eig_sym を使用して実行されます。この反復

は、imsl_f_eig_sym によって見つけられる主要固有ベクトルと、現在の反

復における固有ベクトルの間の要素並びの絶対偏差が、マシン単位の丸め誤差の平方根より小さければ停止します。

#include <imsl.h>#include <math.h>

void main(){ int i; int n; int c; int nz; int index; Imsl_f_sparse_elem *a; float *z; float *q; float *dense_a; float *dense_evec; float *dense_eval; float norm; float *evec; float error; float tolerance;

n = 100; c = 10; tolerance = sqrt(imsl_f_machine(4)); error = 1.0; evec = (float*) malloc (n*sizeof(*evec)); z = (float*) malloc (n*sizeof(*z)); q = (float*) malloc (n*sizeof(*q)); dense_a = (float*) calloc (n*n, sizeof(*dense_a)); a = imsl_f_generate_test_coordinate (n, c, &nz, 0);

/* 密形式に変換 */

for (i=0; i<nz; i++) dense_a[a[i].col + n*a[i].row] = a[i].val; /* 密形式法によって、主要固有ベクトルを決定 */

dense_eval = imsl_f_eig_sym (n, dense_a, IMSL_VECTORS, &dense_evec, 0); for (i=0; i<n; i++) evec[i] = dense_evec[n*i];

/* 正規化 */

norm = imsl_f_vector_norm (n, evec, 0); for (i=0; i<n; i++) evec[i] /= norm;

for (i=0; i<n; i++) q[i] = 1.0/sqrt((float) n); /* べき乗法を実行 */

while (error > tolerance) {

Page 688: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

imsl_f_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, q, IMSL_RETURN_USER_VECTOR, z, 0);

/* 正規化 */

norm = imsl_f_vector_norm (n, z, 0); for (i=0; i<n; i++) q[i] = z[i]/norm;

/* 2 つの要素間の細大絶対誤差を計算 */ error = imsl_f_vector_norm (n, q, IMSL_SECOND_VECTOR, evec, IMSL_INF_NORM, &index, 0); } printf ("Maximum absolute error = %e\n", error);}

出力結果

Maximum absolute error = 3.368035e-04

mat_mul_rect_coordinate (複素数 )疎の座標形式で保存された全ての行列のための、行列の転置、行列 - ベクトル

積、行列 - 行列積を計算します。

概要

#include <imsl.h>void *imsl_c_mat_mul_rect_coordinate (char *string, ..., 0)

同様の double 型関数は、 imsl_d_mat_mul_rect_coordinateです。

必要な引数

char *string ( 入力 )実行される行列乗積を示す文字列。

戻り値

乗算の結果が返されます。結果がベクトルであれば、返されるタイプは f_complex へのポインターです。乗算の結果が疎行列であれば、返されるタイ

プは Imsl_c_sparse_elem へのポインターです。

オプション引数の概要

#include <imsl.h>

void *imsl_c_mat_mul_rect_coordinate (char *string,IMSL_A_MATRIX, int nrowa, int ncola, int nza, Imsl_c_sparse_elem *a,IMSL_B_MATRIX, int nrowb, int ncolb, int nzb, Imsl_c_sparse_elem *b,IMSL_X_VECTOR, int nx, f_complex *x,IMSL_RETURN_MATRIX_SIZE, int *size,IMSL_RETURN_USER_VECTOR, f_complex vector_user[],0)

オプション引数

IMSL_A_MATRIX, int nrowa, int ncola, int nza, Imsl_c_sparse_elem *a ( 入力 )nza 非ゼロ要素を持つ疎行列

nrowa ncolaA C ×∈

Page 689: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_B_MATRIX, int nrowb, int ncolb, int nzb, Imsl_c_sparse_elem *b ( 入力 )nzb 非ゼロ要素を持つ疎行列

IMSL_X_VECTOR, int nx, f_complex *x, ( 入力 )長さ nx のベクトル x。

IMSL_RETURN_MATRIX_SIZE, int *size, ( 出力 )関数 imsl_c_mat_mul_rect_coordinate が Imsl_c_sparse_elem 型の

ベクトルを返す場合、このオプションを使用して返されたベクトルの長さ、即ち、要求された計算によって生成された疎行列の中の非ゼロ要素の数を検索します。

IMSL_RETURN_USER_VECTOR, f_complex vector_user[], ( 出力 )計算の結果がベクトルであれば、その答はユーザ提供の疎の vector_user の中に返されます。それのサイズは計算に依存します。

説明

関数 imsl_c_mat_mul_rect_coordinate はその行列が対応表現で指定され

た、行列 - 行列積、又は、行列 - ベクトル積を計算します。実行される処理は string で指定されます。例えば、“A*x” が与えられると Ax が計算されます。

String の中で行列 A と B 、そしてベクトル x を使用することができます。こ

れらの名称のいずれでも転置を示す trans を共に使用することができます。

ベクトル x は、密な n × 1 行列として扱われます。

string が “x” 又は “trans(A)” などの 1 項目だけを含む場合、配列、又は、

その転置のコピーが返されます。“A*ctrans(A)” 又は “trans(x)*B” など

の、ある乗算は結果として対応形式の疎行列を生成します。“B*x” のようなそ

の他の積は結果のベクトルを含む浮動小数点タイプへのポインターを生成します。

string の中で参照される行列やベクトルはオプション引数として与えられな

ければなりません。そのために string が “A*x” であれば、

IMSL_A_MATRIX と IMSL_X_VECTOR が与えられる必要があります。

この空間を解放するために、free を使用します。

例題

例題 1

xT = (1 + i, 2 +2i, 3 + 3i, 4 + 4i, 5 +5i, 6 + 6i)

この例題は Ax を計算します。

#include <imsl.h>

main(){ Imsl_c_sparse_elem a[] = {0, 0, {10.0, 7.0}, 1, 1, {3.0, 2.0}, 1, 2, {-3.0, 0.0}, 1, 3, {-1.0, 2.0}, 2, 2, {4.0, 2.0}, 3, 0, {-2.0, -4.0},

nrowb xnolbB C ×∈

10 7 0 0 0 0 00 3 2 3 1 2 0 00 0 4 2 0 0 0

2 4 0 0 1 6 1 3 05 4 0 0 5 12 2 7 71 12 2 8 0 0 0 3 7

ii i

iA

i i ii i ii i i

+ + − − + +

= − − + − +

− + − + − + − + − + +

Page 690: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

3, 3, {1.0, 6.0}, 3, 4, {-1.0, 3.0}, 4, 0, {-5.0, 4.0}, 4, 3, {-5.0, 0.0}, 4, 4, {12.0, 2.0}, 4, 5, {-7.0, 7.0}, 5, 0, {-1.0, 12.0}, 5, 1, {-2.0, 8.0}, 5, 5, {3.0, 7.0}}; f_complex b[] = {{1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}, {5.0, 5.0}, {6.0, 6.0}};

int n = 6; int nz = 15; f_complex *x; /* x = A*bを設定 */

x = imsl_c_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, nz, a, IMSL_X_VECTOR, n, b, 0); imsl_c_write_matrix ("Product Ab", 1, n, x, 0);}

出力結果

Product Ab 1 2 3( 3, 17) ( -19, 5) ( 6, 18) 4 5 6( -38, 32) ( -63, 49) ( -57, 83)

例題 2

前の例題で与えられたものと同じ行列 A とベクトル x を使用して Ax、A Tx、A Hx と AA H を計算します。

#include <imsl.h>

main(){ Imsl_c_sparse_elem *z; Imsl_c_sparse_elem a[] = {0, 0, {10.0, 7.0}, 1, 1, {3.0, 2.0}, 1, 2, {-3.0, 0.0}, 1, 3, {-1.0, 2.0}, 2, 2, {4.0, 2.0}, 3, 0, {-2.0, -4.0}, 3, 3, {1.0, 6.0}, 3, 4, {-1.0, 3.0}, 4, 0, {-5.0, 4.0}, 4, 3, {-5.0, 0.0}, 4, 4, {12.0, 2.0}, 4, 5, {-7.0, 7.0}, 5, 0, {-1.0, 12.0}, 5, 1, {-2.0, 8.0}, 5, 5, {3.0, 7.0}}; f_complex x[] = {{1.0, 1.0}, {2.0, 2.0}, {3.0, 3.0}, {4.0, 4.0}, {5.0, 5.0}, {6.0, 6.0}};

int n = 6; int nz = 15; int nz_z; int i; f_complex *b;

Page 691: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

/* b = A*xを設定 */

b = imsl_c_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, nz, a, IMSL_X_VECTOR, n, x, 0); imsl_c_write_matrix ("Ax", 1, n, b, 0); free(b);

/* b = trans(A)*xを設定 */

b = imsl_c_mat_mul_rect_coordinate ("trans(A)*x", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, x, 0); imsl_c_write_matrix ("\n\ntrans(A)x", 1, n, b, 0); free(b);

/* b = ctrans(A)*xを設定 */

b = imsl_c_mat_mul_rect_coordinate ("ctrans(A)*x", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, x, 0); imsl_c_write_matrix ("\n\nctrans(A)x", 1, n, b, 0); free(b);

/* z = A*ctrans(A)を設定 */

z = imsl_c_mat_mul_rect_coordinate ("A*ctrans(A)", IMSL_A_MATRIX, n, n, nz, a, IMSL_X_VECTOR, n, x, IMSL_RETURN_MATRIX_SIZE, &nz_z, 0); printf("\n\n\t\t\t z = A*ctrans(A)\n\n");

for (i=0; i<nz_z; i++) printf ("\t\t\tz(%1d,%1d) = (%6.1f, %6.1f)\n", z[i].row, z[i].col, z[i].val.re, z[i].val.im);}

出力結果

Ax 1 2 3( 3, 17) ( -19, 5) ( 6, 18) 4 5 6( -38, 32) ( -63, 49) ( -57, 83) trans(A)x 1 2 3( -112, 54) ( -58, 46) ( 0, 12) 4 5 6( -51, 5) ( 34, 78) ( -94, 60) ctrans(A)x

Page 692: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1 2 3( 54, -112) ( 46, -58) ( 12, 0) 4 5 6( 5, -51) ( 78, 34) ( 60, -94)

z = A*ctrans(A)

z(0,0) = ( 149.0, 0.0) z(0,3) = ( -48.0, 26.0) z(0,4) = ( -22.0, -75.0) z(0,5) = ( 74.0, -127.0) z(1,1) = ( 27.0, 0.0) z(1,2) = ( -12.0, 6.0) z(1,3) = ( 11.0, 8.0) z(1,4) = ( 5.0, -10.0) z(1,5) = ( 10.0, -28.0) z(2,1) = ( -12.0, -6.0) z(2,2) = ( 20.0, 0.0) z(3,0) = ( -48.0, -26.0) z(3,1) = ( 11.0, -8.0) z(3,3) = ( 67.0, 0.0) z(3,4) = ( -17.0, 36.0) z(3,5) = ( -46.0, 28.0) z(4,0) = ( -22.0, 75.0) z(4,1) = ( 5.0, 10.0) z(4,3) = ( -17.0, -36.0) z(4,4) = ( 312.0, 0.0) z(4,5) = ( 81.0, 126.0) z(5,0) = ( 74.0, 127.0) z(5,1) = ( 10.0, 28.0) z(5,3) = ( -46.0, -28.0) z(5,4) = ( 81.0, -126.0) z(5,5) = ( 271.0, 0.0)

mat_add_band2 つの帯行列を加えます。帯行列は、両方とも帯格納モード、C ← αA + βB で

す。

概要

#include <imsl.h>

float *imsl_f_mat_add_band (int n, int nlca, int nuca, float alpha, float a[], int nlcb, int nucb, float beta, float b[], int *nlcc, int *nucc, ..., 0)

double 型関数は、 imsl_d_mat_add_bandです。

必要な引数

int n ( 入力 )行列 A と B の次数。

int nlca ( 入力 )A の下共対角項数。

int nuca ( 入力 )A の上共対角項数。

float alpha ( 入力 )A のスカラー乗数。

float a[] ( 入力 )ディメンジョン (nlca + nuca + 1) × n を持つ帯モードで格納された、

nlca 下共対角項と nuca 上共対角項の n × n 帯行列。

Page 693: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int nlcb ( 入力 )B の下共対角項数。

int nucb ( 入力 )B の上共対角項数。

float beta ( 入力 )B のスカラー乗数。

float b[] ( 入力 )ディメンジョン (nlcb + nucb + 1) × n を持つ帯モードで格納された、

nlcb 下共対角項と nucb 上共対角項の n × n 帯行列。

int *nlcc ( 出力 )C の下共対角項数。

int *nucc ( 出力 )C の上共対角項数。Number of upper codiagonals of C.

戻り値

計算された合計を含む、float 型の配列のポインター。NULL が返されるのは、

エラーが発生する、或いは、返された行列が非ゼロ要素を持たないときです。

オプション引数の概要

#include <imsl.h>

float *imsl_f_mat_add_band (int n, int nlca, int nuca, float alpha, float a[], int nlcb, int nucb, float beta, float b[], int *nlcc, int *nucc, IMSL_A_TRANSPOSE,IMSL_B_TRANSPOSE,IMSL_SYMMETRIC,0)

オプション引数

IMSL_A_TRANSPOSE, 式 αA + βB の中で A と A T を置き換えます。

IMSL_B_TRANSPOSE, 式 αA + βB の中で B と B T を置き換えます。

IMSL_SYMMETRIC,A、B と C は帯対称格納モードで格納されます。

説明

関数 imsl_f_mat_add_band は、スカラー α と β 、そして帯形式で行列 A と B が与えられて、合計 αA + βB を形成します。A や B の転置もオプション引数が

指定されると、計算の間に使用することができます。オプション引数が指定されると、対称格納モードも使用することができます。

IMSL_SYMMETRIC が指定されると、下共対角項数の戻り値 nlcc は 0 に等しく

なります。

返された行列が NULL に等しければ、下共対角項数の戻り値 nlcc は -1 に等し

くなり、上共対角項数の戻り値 nucc は 0 に等しくなります。I

例題

例題 1

帯モードで格納された次数 4 の 2 つの実行列を加えます。行列 A は 1 つの上共

対角項と 1 つの下共対角項を持ちます。行列 B は上共対角項がなくて、2 つの

下共対角項を持ちます。

#include <imsl.h>

void main(){

Page 694: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

float a[] = {0.0, 2.0, 3.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 3.0, 4.0, 0.0}; float b[] = {3.0, 3.0, 3.0, 3.0, 1.0, -2.0, 1.0, 0.0, -1.0, 2.0, 0.0, 0.0}; int nucb = 0, nlcb = 2; int nuca = 1, nlca = 1; int nucc, nlcc; int n = 4, m; float alpha = 1.0, beta = 1.0; float *c;

c = imsl_f_mat_add_band(n, nlca, nuca, alpha, a, nlcb, nucb, beta, b, &nlcc, &nucc, 0);

m = nlcc + nucc + 1; imsl_f_write_matrix("C = A + B", m, n, c, 0); free(c);} C = A + B 1 2 3 41 0 2 3 -12 4 4 4 43 1 1 5 04 -1 2 0 0

例題 2

次のような配列の時、 4*A + 2*B を計算します。

#include <imsl.h>

void main(){ float a[] = {0.0, 4.0, 3.0, 1.0, 3.0, 2.0, 1.0, 2.0}; float b[] = {0.0, 2.0, 3.0, 1.0, 5.0, 1.0, 2.0, 2.0}; int nuca = 1, nlca = 1; int nucb = 1, nlcb = 1; int n = 4, m, nlcc, nucc; float alpha = 4.0, beta = 2.0; float *c;

c = imsl_f_mat_add_band(n, nlca, nuca, alpha, a, nlcb, nucb, beta, b, &nlcc, &nucc, IMSL_SYMMETRIC, 0);

m = nucc + nlcc + 1; imsl_f_write_matrix("C = 4*A + 2*B\n", m, n, c, 0); free(c);}

出力結果

C = 4*A + 2*B

3 4 0 0 5 2 0 04 2 3 0 2 1 3 0

and 0 3 1 1 0 3 2 10 0 1 2 0 0 1 2

A B

= =

Page 695: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1 2 3 41 0 20 18 62 22 10 8 12

mat_add_band (複素数 )2 つの帯行列を加えます。帯行列は、両方とも帯格納モード、C ← αA + βB で

す。

概要

#include <imsl.h>

f_complex *imsl_c_mat_add_band (int n, int nlca, int nuca, f_complex alpha, f_complex a[], int nlcb, int nucb, f_complex beta, f_complex b[], int *nlcc, int *nucc, ..., 0)

double 型関数は、 imsl_z_mat_add_bandです。

必要な引数

int n ( 入力 )行列 A と B の次数。

int nlca ( 入力 )A の下共対角項数。

int nuca ( 入力 )A の上共対角項数。

f_complex alpha ( 入力 )A のスカラー乗数。

f_complex a[] ( 入力 )ディメンジョン (nlca + nuca + 1) × n を持つ帯モードで格納された、

nlca 下共対角項と nuca 上共対角項の n × n 帯行列。

int nlcb ( 入力 )B の下共対角項数。

int nucb ( 入力 )B の上共対角項数。

f_complex beta ( 入力 )B のスカラー乗数。

f_complex b[] ( 入力 )ディメンジョン (nlcb + nucb + 1) × n を持つ帯モードで格納された、

nlcb 下共対角項と nucb 上共対角項の n × n 帯行列。

int *nlcc ( 出力 )C の下共対角項数。

int *nucc ( 出力 )C の上共対角項数。

戻り値

計算された合計を含む、 f_complex 型の配列のポインター。NULL が返されるの

は、エラーが発生するか、或いは、返された行列が非ゼロ要素を持たないときです。

オプション引数の概要

#include <imsl.h>

f_complex *imsl_c_mat_add_band (int n, int nlca, int nuca, f_complex alpha, f_complex a[], int nlcb, int nucb, f_complex beta, f_complex

Page 696: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

b[], int *nlcc, int *nucc,IMSL_A_TRANSPOSE,IMSL_B_TRANSPOSE,IMSL_A_CONJUGATE_TRANSPOSE,IMSL_B_CONJUGATE_TRANSPOSE,IMSL_SYMMETRIC,0)

オプション引数

IMSL_A_TRANSPOSE,式 αA + βB の中の A を A T に置き換えます。

IMSL_B_TRANSPOSE,式 αA + β B の中の B を B T に置き換えます。

IMSL_A_CONJUGATE_TRANSPOSE, 式 α A + β B の中の A を A H に置き換えます。

IMSL_B_CONJUGATE_TRANSPOSE,式 α A + β B の中の B を B H に置き換えます。

IMSL_SYMMETRIC,行列 A、B、そして C は帯対称格納モードで格納されます。

説明

関数 imsl_c_mat_add_band は、スカラー α と β 、そして帯形式で行列 A と B が与えられて、合計 α A + β B を形成します。A や B の転置、又は、共役転置

もオプション引数が指定されると、計算の間に使用することができます。対称格納モードもオプション引数が指定されると、使用することができます。

IMSL_SYMMETRIC が指定されると、下共対角項数の戻り値 nlcc は 0 に等しく

なります。

返された行列が NULL に等しければ、下共対角項数の戻り値 nlcc は - 1 に等

しくなり、上共対角項数の戻り値 nucc は 0 に等しくなります。

例題

例題 1

帯モードで格納された次数 4 の 2 つの実行列を加えます。行列 A は 1 つの上共

対角項と 1 つの下共対角項を持ちます。行列 B は上共対角項がなくて、2 つの

下共対角項を持ちます。

#include <imsl.h>

void main(){ f_complex a[] = {{0.0, 0.0}, {2.0, 1.0}, {3.0, 3.0}, {-1.0, 0.0}, {1.0, 1.0}, {1.0, 3.0}, {1.0, -2.0}, {1.0, 5.0}, {0.0, 0.0}, {3.0, -2.0}, {4.0, 0.0}, {0.0, 0.0}}; f_complex b[] = {{3.0, 1.0}, {3.0, 5.0}, {3.0, -1.0}, {3.0, 1.0}, {1.0, -3.0}, {-2.0, 0.0}, {1.0, 2.0}, {0.0, 0.0}, {-1.0, 4.0}, {2.0, 1.0}, {0.0, 0.0}, {0.0, 0.0}}; int nucb = 0, nlcb = 2; int nuca = 1, nlca = 1; int nucc, nlcc; int n = 4, m; f_complex *c; f_complex alpha = {1.0, 0.0}; f_complex beta = {1.0, 0.0};

c = imsl_c_mat_add_band(n, nlca, nuca, alpha, a, nlcb, nucb, beta, b, &nlcc, &nucc, 0);

Page 697: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

m = nlcc + nucc + 1; imsl_c_write_matrix("C = A + B", m, n, c, 0); free(c);}

出力結果

C = A + B 1 2 31 ( 0, 0) ( 2, 1) ( 3, 3)2 ( 4, 2) ( 4, 8) ( 4, -3)3 ( 1, -3) ( 1, -2) ( 5, 2)4 ( -1, 4) ( 2, 1) ( 0, 0) 41 ( -1, 0)2 ( 4, 6)3 ( 0, 0)4 ( 0, 0)

例題 2(3 + 2i)AH + (4 + i) BH

を計算します。配列は以下のように表されます。

#include <imsl.h>

void main(){ f_complex a[] = {{0.0, 0.0}, {1.0, 3.0}, {3.0, 1.0}, {2.0, 5.0}, {2.0, 3.0}, {6.0, 2.0}, {4.0, 1.0}, {1.0, 2.0}}; f_complex b[] = {{0.0, 0.0}, {5.0, 1.0}, {2.0, 3.0}, {4.0, 2.0}, {1.0, 2.0}, {1.0, 3.0}, {3.0, 2.0}, {1.0, 4.0}, {4.0, 1.0}, {2.0, 3.0}, {2.0, 6.0}, {0.0, 0.0}}; int nuca = 1, nlca = 0; int nucb = 1, nlcb = 1; int n = 4, m, nlcc, nucc; f_complex *c; f_complex alpha = {3.0, 2.0}; f_complex beta = {4.0, 1.0}; c = imsl_c_mat_add_band(n, nlca, nuca, alpha, a, nlcb, nucb, beta, b, &nlcc, &nucc, IMSL_A_CONJUGATE_TRANSPOSE, IMSL_B_CONJUGATE_TRANSPOSE, 0);

m = nlcc + nucc + 1; imsl_c_write_matrix("C = (3+2i)*ctrans(A) + (4+i)*ctrans(B)\n", m, n, c, 0); free(c);}

出力結果

C = (3+2i)*ctrans(A) + (4+i)*ctrans(B)

1 2 31 ( 0, 0) ( 17, 0) ( 11, -10)2 ( 18, -12) ( 29, -5) ( 28, 0)3 ( 30, -6) ( 22, -7) ( 34, -15)

2 3 1 3 0 0 1 2 5 0 00 6 2 3 0 4 1 3 2 3 0

and 0 0 4 2 5 0 2 3 3 2 4 20 0 0 1 2 0 0 2 6 1 4

i i i ii i i i i

A Bi i i i i

i i i

+ + + + + + + + + = = + + + + +

+ + +

Page 698: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

41 ( 14, -22)2 ( 15, -19)3 ( 0, 0)

mat_add_coordinate座標形式で格納された 2 つの実行列の要素毎加算 C ← αA + βB を実行します。

概要

#include <imsl.h>

Imsl_f_sparse_elem *imsl_f_mat_add_coordinate (int n, int nz_a, float alpha, Imsl_f_sparse_elem a[], int nz_b, float beta, Imsl_f_sparse_elem b[], int *nz_c, ..., 0)

double 型関数は、 imsl_d_mat_add_coordinateです。

必要な引数

int n ( 入力 )行列 A と B の次数。

int nz_a ( 入力 )行列 A の非ゼロ要素数。

float alpha ( 入力 )A のスカラー乗数。

Imsl_f_sparse_elem a[] ( 入力 )行列 A の中の各非ゼロ入力の位置と値を含んだ、長さ nz_a のベク

トル。

int nz_b ( 入力 )行列 B の非ゼロ要素数。

float beta ( 入力 )B のスカラー乗数。

Imsl_f_sparse_elem b[] ( 入力 )行列 B の中の各非ゼロ入力の位置と値を含んだ、長さ nz_b のベク

トル。

int *nz_c ( 出力 )合計 αA + βB の非ゼロの要素数。

戻り値

計算された合計を含む、Imsl_f_sparse_elem 型の配列のポインター。エラー、

或いは返された行列が非ゼロ要素を持たない時には、NULL が返されます。

オプション引数の概要

#include <imsl.h>

Imsl_f_sparse_elem *imsl_f_mat_add_coordinate (int n, int nz_a, float alpha, Imsl_f_sparse_elem a[], int nz_b, float beta, Imsl_f_sparse_elem b[], int *nz_c,IMSL_A_TRANSPOSE,IMSL_B_TRANSPOSE,0)

Page 699: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション引数

IMSL_A_TRANSPOSE, 式 αA + βB の中の A を A T と置き換えます。

IMSL_B_TRANSPOSE, 式 αA + βB の中の B を B T と置き換えます。

説明

関数 imsl_f_mat_add_coordinate はスカラー α と β、そして行列 A と B が座標形式で与えられて、合計 αA + βB を形成します。A や B の転置は、オプ

ション引数が指定されると、計算の間に使用されます。この方法は、リンクされたリストデータ構造体に A を格納することから始めて、α の掛け算を実行

します。次に行列 B のデータが移動されて、非ゼロ要素の座標が A の非ゼロ

要素の形式に対応する場合、そのリンクされたリストの入力値は更新されます。そうでなければ、リンクされたリストの中に新しいノードが作成されます。β による乗算は、この時に起こります。最後に、C を表すリンクされたリ

ストは、取り消しを通してゼロになる要素を取り除く座標表現に変換されます。

例題

例題 1

座標形式で格納された次数 4 の 2 つの実行列を加算します。行列 A は 5 つの非

ゼロ要素を持ちます。行列 B は 7 つの非ゼロ要素を持ちます。

#include <imsl.h>

void main (){ Imsl_f_sparse_elem a[] = {0, 0, 3, 0, 3, -1, 1, 2, 5, 2, 0, 1, 3, 1, 3}; Imsl_f_sparse_elem b[] = {0, 1, -2, 0, 3, 1, 1, 0, 3, 2, 2, 5, 2, 3, 1, 3, 0, 4, 3, 1, 3}; int nz_a = 5, nz_b = 7, nz_c; int n = 4, i; float alpha = 1.0, beta = 1.0; Imsl_f_sparse_elem *c;

c = imsl_f_mat_add_coordinate(n, nz_a, alpha, a, nz_b, beta, b, &nz_c, 0);

printf(" row column value\n"); for (i = 0; i < nz_c; i++) printf("%3d %5d %8.2f\n", c[i].row, c[i].col, c[i].val);

free(c);}

出力結果

row column value 0 0 3.00 0 1 -2.00 1 0 3.00 1 2 5.00 2 0 1.00 2 2 5.00 2 3 1.00 3 0 4.00

Page 700: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

3 1 6.00

例題 2

2*A T + 2*B T を計算します。ここで A と B は、以下のように表されます。

#include <imsl.h>

void main (){ Imsl_f_sparse_elem a[] = {0, 0, 3, 0, 3, -1, 1, 2, 5, 2, 0, 1, 3, 1, 3}; Imsl_f_sparse_elem b[] = {0, 1, -2, 0, 3, 1, 1, 0, 3, 2, 2, 5, 2, 3, 1, 3, 0, 4, 3, 1, 3}; int nz_a = 5, nz_b = 7, nz_c; int n = 4, i; float alpha = 2.0, beta = 2.0; Imsl_f_sparse_elem *c;

c = imsl_f_mat_add_coordinate(n, nz_a, alpha, a, nz_b, beta, b, &nz_c, IMSL_A_TRANSPOSE, IMSL_B_TRANSPOSE, 0);

printf(" row column value\n"); for (i = 0; i < nz_c; i++) printf("%3d %5d %8.2f\n", c[i].row, c[i].col, c[i].val);

free(c);}

出力結果

row column value 0 0 6.00 0 1 6.00 0 2 2.00 0 3 8.00 1 0 -4.00 1 3 12.00 2 1 10.00 2 2 10.00 3 2 2.00

mat_add_coordinate (複素数 )座標形式で格納された 2 つの複素行列の要素毎加算 C ← αA + βB を実行しま

す。

3 0 0 1 0 2 0 10 0 5 0 3 0 0 0

and 1 0 0 0 0 0 5 10 3 0 0 4 3 0 0

A B

− − = =

Page 701: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

概要

#include <imsl.h>

Imsl_c_sparse_elem *imsl_c_mat_add_coordinate (int n, int nz_a, f_complex alpha, Imsl_c_sparse_elem a[], int nz_b, f_complex beta, Imsl_c_sparse_elem b[], int *nz_c, ..., 0)

double 型関数は、 imsl_z_mat_add_coordinateです。

必要な引数

int n ( 入力 )行列 A と B の次数。

int nz_a ( 入力 )行列 A の非ゼロ要素数。

f_complex alpha ( 入力 )A のスカラー乗数。

Imsl_c_sparse_elem a[] ( 入力 )行列 A の中の各非ゼロ入力の位置と値を含んだ、長さ nz_a のベクト

ル。

int nz_b ( 入力 )行列 B の非ゼロ要素数。

f_complex beta ( 入力 )B のスカラー乗数。

Imsl_c_sparse_elem b[] ( 入力 )行列 B の中の各非ゼロ入力の位置と値を含んだ、長さ nz_b のベクト

ル。

int *nz_c ( 出力 )合計 αA + βB の非ゼロの要素数。The number of nonzeros in the sum αA + βB.

戻り値

計算された合計を含む Imsl_c_sparse_elem 型の配列のポインター。エラー或い

は返された行列が非ゼロ要素を持たない時には、NULL が返されます。

オプション引数の概要

#include <imsl.h>

Imsl_c_sparse_elem *imsl_c_mat_add_coordinate (int n, int nz_a, f_complex alpha, Imsl_c_sparse_elem a[], int nz_b, f_complex beta, Imsl_c_sparse_elem b[], int *nz_c,IMSL_A_TRANSPOSE,IMSL_B_TRANSPOSE,IMSL_A_CONJUGATE_TRANSPOSE,IMSL_B_CONJUGATE_TRANSPOSE,0)

オプション引数

IMSL_A_TRANSPOSE,式 αA + βB の中の A を A T と置き換えます。

IMSL_B_TRANSPOSE,式 αA + βB の中の B を B T と置き換えます。

IMSL_A_CONJUGATE_TRANSPOSE,式 αA + βB の中の A を A H と置き換えます。

IMSL_B_CONJUGATE_TRANSPOSE,式 αA + βB の中の B を B H と置き換えます。

Page 702: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

関数 imsl_c_mat_add_coordinate はスカラー α と β、そして行列 A と B が座標形式で与えられて、合計 αA + βB を形成します。A や B の転置は、オプ

ション引数が指定されると、計算の間に使用されます。この方法は、リンクされたリストデータ構造体に A を格納することから始めて、α の掛け算を実行

します。次に行列 B のデータが移動されて、非ゼロ要素の座標が A の非ゼロ

要素の形式に対応する場合、そのリンクされたリストの入力値は更新されます。そうでなければ、リンクされたリストの中に新しいノードが作成されます。β による乗算は、この時に起こります。最後に、C のリンクされたリスト

表現は、取り消しを通してゼロになる要素を取り除く対応表現に変換されます。

例題

例題 1

対応形式で格納された次数 4 の 2 つの実行列を加算します。行列 A は 5 つの非

ゼロ要素を持ちます。行列 B は 7 つの非ゼロ要素を持ちます。

#include <imsl.h>

void main (){ Imsl_c_sparse_elem a[] = {0, 0, 3, 4, 0, 3, -1, 2, 1, 2, 5, -1, 2, 0, 1, 2, 3, 1, 3, 0}; Imsl_c_sparse_elem b[] = {0, 1, -2, 1, 0, 3, 1, -2, 1, 0, 3, 0, 2, 2, 5, 2, 2, 3, 1, 4, 3, 0, 4, 0, 3, 1, 3, -2}; int nz_a = 5, nz_b = 7, nz_c; int n = 4, i; f_complex alpha = {1.0, 0.0}, beta = {1.0, 0.0}; Imsl_c_sparse_elem *c;

c = imsl_c_mat_add_coordinate(n, nz_a, alpha, a, nz_b, beta, b, &nz_c, 0);

printf(" row column value\n"); for (i = 0; i < nz_c; i++) printf("%3d %5d %8.2f %8.2f\n", c[i].row, c[i].col, c[i].val.re, c[i].val.im);

free(c);}

出力結果

row column value 0 0 3.00 4.00 0 1 -2.00 1.00 1 0 3.00 0.00 1 2 5.00 -1.00 2 0 1.00 2.00 2 2 5.00 2.00 2 3 1.00 4.00 3 0 4.00 0.00 3 1 6.00 -2.00

例題 2

2+3i*A T + 2 - i*B T を計算します。ここで A と B は、以下のように表されます。

Page 703: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

#include <imsl.h>

void main (){ Imsl_c_sparse_elem a[] = {0, 0, 3, 4, 0, 3, -1, 2, 1, 2, 5, -1, 2, 0, 1, 2, 3, 1, 3, 0}; Imsl_c_sparse_elem b[] = {0, 1, -2, 1, 0, 3, 1, -2, 1, 0, 3, 0, 2, 2, 5, 2, 2, 3, 1, 4, 3, 0, 4, 0, 3, 1, 3, -2}; int nz_a = 5, nz_b = 7, nz_c; int n = 4, i; f_complex alpha = {2.0, 3.0}, beta = {2.0, -1.0}; Imsl_c_sparse_elem *c;

c = imsl_c_mat_add_coordinate(n, nz_a, alpha, a, nz_b, beta, b, &nz_c, IMSL_A_TRANSPOSE, IMSL_B_TRANSPOSE, 0);

printf(" row column value\n"); for (i = 0; i < nz_c; i++) printf("%3d %5d %8.2f %8.2f\n", c[i].row, c[i].col, c[i].val.re, c[i].val.im);

free(c);}

出力結果

row column value 0 0 -6.00 17.00 0 1 6.00 -3.00 0 2 -4.00 7.00 0 3 8.00 -4.00 1 0 -3.00 4.00 1 3 10.00 2.00 2 1 13.00 13.00 2 2 12.00 -1.00 3 0 -8.00 -4.00 3 2 6.00 7.00

matrix_norm矩形行列の種々のノルムを計算します。

概要

#include <imsl.h>

float imsl_f_matrix_norm (int m, int n, float a[], ..., 0)

double 型関数は、 imsl_d_matrix_normです。

3 4 0 0 1 2 0 2 0 1 20 0 5 0 3 0 0 0 0

and 1 2 0 0 0 0 0 5 2 1 4

0 3 0 0 0 4 0 3 2 0 0

i i i ii i

A Bi i i

i i i

+ − + − + − − + = = + + +

+ + −

Page 704: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

int m ( 入力 )行列 A の行数。

int n ( 入力 )行列 A の列数。

float a[] ( 入力 )ノルムが計算される行列。

戻り値

入力行列の要求されるノルム。ノルムが計算できない場合、NaN が返されま

す。

オプション引数の概要

#include <imsl.h>

float imsl_f_matrix_norm (int m, int n, float a[],IMSL_ONE_NORM,IMSL_INF_NORM,0)

説明

デフォルトでは、 imsl_f_matrix_norm は Frobenius ノルムを計算します。

オプション IMSL_ONE_NORM が選択されると、1- ノルムが返されます。

オプション IMSL_INF_NORM が選択されると無限大ノルムが返されます。

例題

行列 A の Frobenius ノルム、無限大ノルム、1 - ノルムを計算します。

#include <imsl.h> void main(){ float a[] = {1.0, 2.0, -2.0, 3.0, -2.0, 1.0, 3.0, 0.0, 0.0, 3.0, 1.0, -7.0, 5.0, -2.0, 7.0, 6.0, 4.0, 3.0, 4.0, 0.0}; int m = 5, n = 4; float frobenius_norm, inf_norm, one_norm; frobenius_norm = imsl_f_matrix_norm(m, n, a, 0); inf_norm = imsl_f_matrix_norm(m, n, a, IMSL_INF_NORM, 0); one_norm = imsl_f_matrix_norm(m, n, a, IMSL_ONE_NORM, 0); printf("Frobenius norm = %f\n", frobenius_norm); printf("Infinity norm = %f\n", inf_norm);

11 1 2

22

0 0

m n

iji j

A A− −

= =

=

∑∑

1

1 0 1 0max

m

ijj n iA A

≤ ≤ − =

= ∑

1

0 1 0max

n

iji m jA A

∞ ≤ ≤ − =

= ∑

Page 705: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

printf("One norm = %f\n", one_norm);}

出力結果Frobenius norm = 15.684387Infinity norm = 20.000000One norm = 17.000000

matrix_norm_band帯格納モードで保存された行列の種々のノルムを計算します。

概要

#include <imsl.h>

float imsl_f_matrix_norm_band (int n, float a[], int nlc, int nuc, ..., 0)double 型関数は、 imsl_d_matrix_norm_band です。

必要な引数

int n ( 入力 )行列 A の次数。

float a[] ( 入力 )ノルムが計算される行列。

int nlc ( 入力 )A の下共対角項数。

int nuc ( 入力 )A の上共対角項数。

戻り値

入力行列の要求されるノルムで、デフォルトでは Frobenius ノルム。 ノルムが

計算できない場合、NaN が返されます。

オプション引数の概要

#include <imsl.h>

float imsl_f_matrix_norm_band (int n, float a[], int nlc, int nuc,IMSL_ONE_NORM,IMSL_INF_NORM,IMSL_SYMMETRIC,0)

オプション引数

IMSL_ONE_NORM, 行列 A の 1 – ノルムを計算します。

IMSL_INF_NORM, 行列 A の無限大ノルムを計算します。

IMSL_SYMMETRIC,行列 A は帯対称格納モードで保存されます。

説明

デフォルトで imsl_f_matrix_norm_band は Frobenius ノルムを計算します。

オプション IMSL_ONE_NORM が選択されると、1- ノルムが返されます。

11 1 2

22

0 0

m n

iji j

A A− −

= =

=

∑∑

Page 706: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

オプション IMSL_INF_NORM が選択されると無限大ノルムが返されます。

例題

例題 1

行列 A の Frobenius ノルム、無限大ノルム、1- ノルムを計算します。行列 A. は帯格納モードで格納されます。

#include <imsl.h>

void main(){ float a[] = {0.0, 2.0, 3.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 3.0, 4.0, 0.0}; int nlc = 1, nuc = 1; int n = 4; float frobenius_norm, inf_norm, one_norm;

frobenius_norm = imsl_f_matrix_norm_band(n, a, nlc, nuc, 0);

inf_norm = imsl_f_matrix_norm_band(n, a, nlc, nuc, IMSL_INF_NORM, 0);

one_norm = imsl_f_matrix_norm_band(n, a, nlc, nuc, IMSL_ONE_NORM, 0);

printf("Frobenius norm = %f\n", frobenius_norm); printf("Infinity norm = %f\n", inf_norm); printf("One norm = %f\n", one_norm);}

出力結果

Frobenius norm = 6.557438Infinity norm = 5.000000One norm = 8.000000

例題 2

行列 A の Frobenius ノルム、無限大ノルム、1- ノルムを計算します。行列 A は帯対称格納モードで格納される。

#include <imsl.h> void main(){ float a[] = {0.0, 0.0, 7.0, 3.0, 1.0, 4.0, 0.0, 5.0, 1.0, 2.0, 1.0, 2.0, 1.0, 2.0, 4.0, 6.0, 3.0, 1.0}; int nlc = 2, nuc = 2; int n = 6; float frobenius_norm, inf_norm, one_norm; frobenius_norm = imsl_f_matrix_norm_band(n, a, nlc, nuc, IMSL_SYMMETRIC, 0); inf_norm = imsl_f_matrix_norm_band(n, a, nlc, nuc, IMSL_INF_NORM,

1

1 0 1 0max

m

ijj n iA A

≤ ≤ − =

= ∑

1

0 1 0max

n

iji m jA A

∞ ≤ ≤ − =

= ∑

Page 707: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

IMSL_SYMMETRIC, 0); one_norm = imsl_f_matrix_norm_band(n, a, nlc, nuc, IMSL_ONE_NORM, IMSL_SYMMETRIC, 0); printf("Frobenius norm = %f\n", frobenius_norm); printf("Infinity norm = %f\n", inf_norm); printf("One norm = %f\n", one_norm);}

出力結果Frobenius norm = 16.941074Infinity norm = 16.000000One norm = 16.000000

matrix_norm_coordinate座標形式で保存された行列の種々のノルムを計算します。

概要

#include <imsl.h>

float imsl_f_matrix_norm_coordinate (int m, int n, int nz, Imsl_f_sparse_elem a[], ..., 0)

double 型関数は、 imsl_d_matrix_norm_coordinateです。

必要な引数

int m ( 入力 )行列 A の行数。

int n ( 入力 )行列 A の列数。

int nz ( 入力 )行列 A の非ゼロ要素数。

Imsl_f_sparse_elem a[] ( 入力 )ノルムが計算される行列。

戻り値

入力行列の要求されるノルムで、デフォルトでは Frobenius ノルム。 ノルムが

計算できない場合、NaN が返されます。

オプション引数の概要

#include <imsl.h>

float imsl_f_matrix_norm_coordinate (int m, int n, int nz, Imsl_f_sparse_elem a[],IMSL_ONE_NORM,IMSL_INF_NORM,IMSL_SYMMETRIC,0)

オプション引数

IMSL_ONE_NORM,行列 A の 1- ノルムの計算。

IMSL_INF_NORM,行列 A の無限大ノルムの計算。

IMSL_SYMMETRIC,行列 A は対称対応形式で保存されます。

Page 708: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

説明

デフォルトでは、 imsl_f_matrix_norm_coordinate は Frobenius ノルムを計

算します。

オプション IMSL_ONE_NORM が選択されると、1- ノルムが返されます。

オプション IMSL_INF_NORM が選択されると無限大ノルムが返されます。

例題

例題 1

行列 A の Frobenius ノルム、無限大ノルム、1- ノルムを計算します。行列 A. は座標形式で格納されます。

#include <imsl.h>

void main(){ Imsl_f_sparse_elem a[] = {0, 0, 10.0, 1, 1, 10.0, 1, 2, -3.0, 1, 3, -1.0, 2, 2, 15.0, 3, 0, -2.0, 3, 3, 10.0, 3, 4, -1.0, 4, 0, -1.0, 4, 3, -5.0, 4, 4, 1.0, 4, 5, -3.0, 5, 0, -1.0, 5, 1, -2.0, 5, 5, 6.0}; int m = 6, n = 6; int nz = 15; float frobenius_norm, inf_norm, one_norm;

frobenius_norm = imsl_f_matrix_norm_coordinate (m, n, nz, a, 0);

inf_norm = imsl_f_matrix_norm_coordinate(m, n, nz, a, IMSL_INF_NORM, 0);

one_norm = imsl_f_matrix_norm_coordinate(m, n, nz, a, IMSL_ONE_NORM, 0);

printf("Frobenius norm = %f\n", frobenius_norm); printf("Infinity norm = %f\n", inf_norm); printf("One norm = %f\n", one_norm);}

出力結果

Frobenius norm = 24.839485

11 1 2

22

0 0

m n

iji j

A A− −

= =

=

∑∑

1

1 0 1 0max

m

ijj n iA A

≤ ≤ − =

= ∑

1

0 1 0max

n

iji m jA A

∞ ≤ ≤ − =

= ∑

Page 709: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Infinity norm = 15.000000One norm = 18.000000

例題 2

行列 A の Frobenius ノルム、無限大ノルム、1- ノルムを計算します。行列 A は対称座標形式で格納されます。

#include <imsl.h>

void main(){ Imsl_f_sparse_elem a[] = {0, 0, 10.0, 0, 2, -1.0, 0, 5, 5.0, 1, 3, 2.0, 1, 4, 3.0, 2, 2, 3.0, 2, 5, 4.0, 4, 4, -1.0, 4, 5, 4.0}; int m = 6, n = 6; int nz = 9; float frobenius_norm, inf_norm, one_norm;

frobenius_norm = imsl_f_matrix_norm_coordinate (m, n, nz, a, IMSL_SYMMETRIC, 0);

inf_norm = imsl_f_matrix_norm_coordinate(m, n, nz, a, IMSL_INF_NORM, IMSL_SYMMETRIC, 0);

one_norm = imsl_f_matrix_norm_coordinate(m, n, nz, a, IMSL_ONE_NORM, IMSL_SYMMETRIC, 0);

printf("Frobenius norm = %f\n", frobenius_norm); printf("Infinity norm = %f\n", inf_norm); printf("One norm = %f\n", one_norm);}

出力結果

Frobenius norm = 15.874508Infinity norm = 16.000000One norm = 16.000000

generate_test_bandクラス E (n , c) の検定行列を生成します。帯、又は、帯対称形式で返します。

概要

#include <imsl.h>

float *imsl_f_generate_test_band (int n, int c, ..., 0)

関数 imsl_d_generate_test_band は、倍精度(double )です。

必要な引数

int n ( 入力 )行列の行数

int c ( 入力 )構造体を変更するために使用されるパラメータで、上 / 下の共対角項

の数。

Page 710: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

戻り値

タイプ float のベクトルのポインター。この空間を解放するためには free を使用します。検定が生成できない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>

void *imsl_f_generate_sparse_test (int n, int c,IMSL_SYMMETRIC_STORAGE,0)

オプション引数

IMSL_SYMMETRIC_STORAGE,帯対称形式で格納された行列を返します。

説明

Østerby と Zlatev (1982 年 ) と同じ述語が使用されます。一般的に E- 行列と引用

されているクラス E (n , c) の検定行列は、対称で対角項に 4 を持ち、上対角項

と下対角項に - 1 を持つ、次数 n の正定値行列 です。これに加えて、対角項

から距離 c に- 1 の二本の帯があります。更に正確には、n ≥ 3 と 2 ≤ c ≤ n-1 に

対して、以下のようになります。

E 行列は楕円偏微分方程式の打ち切りにおいて 5 点公式から得られたものに似

ています。

デフォルトで imsl_f_generate_test_band は帯格納モードで E 行列を返

します。オプション IMSL_SYMMETRIC_STORAGE は、帯対称格納モードの行

列を返します。

例題

この例題は次の行列を生成して結果をプリントします。

#include <imsl.h>

main(){ int n = 5; int c = 3; float *a;

a = imsl_f_generate_test_band (n, c, 0);

imsl_f_write_matrix ("E(5,3) in band storage", 2*c + 1, n, a, 0);}

出力結果

E(5,3) in band storage 1 2 3 4 5

ai,i = 4 0 ≤ i < nai,i+1 = −1 0 ≤ i < n − 1ai+1,1 = −1 0 ≤ i < n − 1ai,i+c = −1 0 ≤ i < n − cai+c,I = −1 0 ≤ i < n − c

( )

4 1 0 1 01 4 1 0 1

5,3 0 1 4 1 01 0 1 4 1

0 1 0 1 4

E

− − − − − = − − − − −

− −

Page 711: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1 0 0 0 -1 -12 0 0 0 0 03 0 -1 -1 -1 -14 4 4 4 4 45 -1 -1 -1 -1 06 0 0 0 0 07 -1 -1 0 0 0

generate_test_band (複素数 )クラス Ec (n , c) の検定行列を生成します。帯、又は帯対称形式で返します。

概要

#include <imsl.h>f_complex *imsl_c_generate_test_band (int n, int c, ..., 0)

関数 imsl_z_generate_test_band は、倍精度(double)です。

必要な引数

int n ( 入力 )行列の行数

int c ( 入力 )構造体を変更するために使用されるパラメータで、上 / 下の共対角項

の数。

戻り値

f_complex 型のベクトルのポインター。この空間を解放するために free を使

用します。 検定が生成できない場合、NULL が返されます。

オプション引数の概要

#include <imsl.h>

void *imsl_c_generate_sparse_test (int n, int c,IMSL_SYMMETRIC_STORAGE,0)

オプション引数

IMSL_SYMMETRIC_STORAGE,帯対称形式で格納された行列を返します。

説明

Østerby と Zlatev (1982 年 ) のものと同じ述語が使用されます。一般的に E 行列

と引用されているクラス E (n , c) の検定行列は、対称で対角項に (6.0,0.0)を持ち、上対角項に (-1.0,1.0)下対角項に (-1.0,-1.0)を持つ、次数 n の正定値行列 です。これに加えて、対角項から距離 c に上対角項に (-1.0,1.0) 下対角項に (-1.0,-1.0) の二本の帯がある。更に正確には、n ≥ 3 と 2 ≤ c ≤ n − 1 に対して、以下のようになります。

E- 行列は楕円偏微分方程式の打ち切りにおいて 5 点公式から得られたものに似

ています。

デフォルトで imsl_c_generate_test_band は帯格納モードで E 行列を返

します。オプション IMSL_SYMMETRIC_STORAGE は、帯対称格納モードの行

列を返します。

ai,i = 6 0 ≤ i < nai,i+1 = −1 − i 0 ≤ i < n − 1ai+1,1 = −1 − i 0 ≤ i < n − 1ai,i+c = −1 + i 0 ≤ i < n − cai+c,i = −1 + i 0 ≤ i < n − c

Page 712: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

例題この例題は次の行列を生成して結果をプリントします。

#include <imsl.h>

main(){ int i; int n = 5; int c = 3; f_complex *a;

a = imsl_c_generate_test_band (n, c, 0);

imsl_c_write_matrix ("E(5,3) in band storage", 2*c + 1, n, a, 0);}

出力結果 E(5,3) in band storage 1 2 31 ( 0, 0) ( 0, 0) ( 0, 0)2 ( 0, 0) ( 0, 0) ( 0, 0)3 ( 0, 0) ( -1, 1) ( -1, 1)4 ( 6, 0) ( 6, 0) ( 6, 0)5 ( -1, -1) ( -1, -1) ( -1, -1)6 ( 0, 0) ( 0, 0) ( 0, 0)7 ( -1, -1) ( -1, -1) ( 0, 0) 4 51 ( -1, 1) ( -1, 1)2 ( 0, 0) ( 0, 0)3 ( -1, 1) ( -1, 1)4 ( 6, 0) ( 6, 0)5 ( -1, -1) ( 0, 0)6 ( 0, 0) ( 0, 0)7 ( 0, 0) ( 0, 0)

generate_test_coordinateクラス D(n, c) と E(n, c) の検定行列を生成します。どちらも対応形式で返し

ます。

概要

#include <imsl.h>

Imsl_f_sparse_elem *imsl_f_generate_test_coordinate (int n, int c, int *nz, ..., 0)

関数 imsl_d_generate_test_coordinate は、倍精度( double )です。

必要な引数

int n ( 入力 )行列の行数

int c ( 入力 )構造を変えるために使用されるパラメータ。

( )

6 1 0 1 01 6 1 0 1

5,3 0 1 6 1 01 0 1 6 10 1 0 1 6

c

i ii i i

E i ii i i

i i

− − − + − − − + − + = − − − + − − − − − +

− − − −

Page 713: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

int *nz ( 出力 )戻りベクトルの長さ。

戻り値

タイプ Imsl_f_sparse_elem の長さ nz のベクトルのポインター。この空間を解

放するために free を使用します。 検定が生成できない場合、NULL が返され

ます。

オプション引数の概要

#include <imsl.h>

void *imsl_f_generate_test_coordinate (int n, int c, int *nz,IMSL_D_MATRIX,IMSL_SYMMETRIC_STORAGE,0)

オプション引数

IMSL_D_MATRIX

クラス D(n, c) の行列を返します。

デフォルト: クラス E(n, c) の行列を返します。

IMSL_SYMMETRIC_STORAGE,対応表現のために、対角項と下三角項の値だけを返します。 IMSL_D_MATRIX が指定されると、このオプションは使えません。

説明

Østerby と Zlatev (1982 年 ) と同じ述語が使用されます。一般的に E 行列と

引用されているクラス E(n, c) の検定行列は、対称で対角項に 4 を持ち、

上対角項と 下対角項に -1 を持つ、次数 n の正定値行列 です。これに加

えて、対角項から距離 c に -1 の二本の帯がある。更に正確には、n ≥ 3 と 2 ≤ c ≤ n − 1 に対して、以下のようになります。

E 行列は楕円偏微分方程式の打ち切りにおいて 5 点公式から得られたものに似

ています。

クラス D(n, c) の検定行列は、次数 n の正方形行列で、完全な対角項、対角項

の上の距離 c と対角項の下に周期的に再現する三本の帯、そして右上隅に要

素の 10 × 10 の三角を持ちます。 更に正確には、n ≥ 14 と 1 ≤ c ≤ n − 13 に対し

て、以下のようになります。

ai,i = 4 0 ≤ i < nai,i+1 = −1 0 ≤ i < n − 1ai+1,1 = −1 0 ≤ i < n − 1ai,i+c = −1 0 ≤ i < n − cai+c,i = −1 0 ≤ i < n − c

ai,i = 1 0 ≤ i < nai,i+c = i + 2 0 ≤ i < n − cai,i-n+c = i + 2 n − c ≤ i < nai,i+c+1 = −(i + 1) 0 ≤ i < n − c − 1ai,i-n+c+1 = −(i + 1) n − c − 1 ≤ i < nai,i+c+2 = 16 0 ≤ i < n − c − 2ai,i-n+c+2 = 16 n − c − 2 ≤ i < nai,n-11+i+j = 100j 1 ≤ i< 11 − j, 0 ≤ j < 10

Page 714: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで D(20, 5) の疎のパターンを示します。

デフォルトで imsl_f_generate_test_coordinate は対応表現で E 行列

を返します。IMSL_SYMMETRIC_STORAGE オプションを指定する事によっ

て、対角項と下三角項だけが返されます。スカラー nz はこの表現の非ゼロ要

素の数を含んでいます。

オプション IMSL_D_MATRIX はクラス D(n, c) の行列を返します。D 行列は

対称ではないので、IMSL_SYMMETRIC_STORAGE オプションは使えません。

例題

例題 1

この例題は、次の行列を生成して、結果をプリントします。

#include "imsl.h"

main(){ int i; int n = 5; int c = 3; int nz; Imsl_f_sparse_elem *a;

a = imsl_f_generate_test_coordinate (n, c, &nz, 0);

printf ("row col val\n"); for (i=0; i<nz; i++) printf (" %d %d %5.1f\n", a[i].row, a[i].col, a[i].val);}

出力結果

row col val 0 0 4.0 1 1 4.0

x x x x x x x x x x x x x xx x x x x x x x x x x x x

x x x x x x x x x x x xx x x x x x x x x x x

x x x x x x x x x xx x x x x x x x x

x x x x x x x xx x x x x x x

x x x x x xx x x x x

x x x xx x x x

x x x xx x x xx x x xx x x x

x x x xx x x x

x x x xx x x x

( )

4 1 0 1 01 4 1 0 1

5,3 0 1 4 1 01 0 1 4 1

0 1 0 1 4

E

− − − − − = − − − − −

− −

Page 715: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

2 2 4.0 3 3 4.0 4 4 4.0 1 0 -1.0 2 1 -1.0 3 2 -1.0 4 3 -1.0 0 1 -1.0 1 2 -1.0 2 3 -1.0 3 4 -1.0 3 0 -1.0 4 1 -1.0 0 3 -1.0 1 4 -1.0

例題 2

この例題では、行列 E(5, 3) を対称格納モードで返し、プリントします。

#include <imsl.h>

main(){ int i; int n = 5; int c = 3; int nz; Imsl_f_sparse_elem *a;

a = imsl_f_generate_test_coordinate (n, c, &nz, IMSL_SYMMETRIC_STORAGE, 0);

printf ("row col val\n"); for (i=0; i<nz; i++) printf (" %d %d %5.1f\n", a[i].row, a[i].col, a[i].val);}

出力結果

row col val 0 0 4.0 1 1 4.0 2 2 4.0 3 3 4.0 4 4 4.0 1 0 -1.0 2 1 -1.0 3 2 -1.0 4 3 -1.0 3 0 -1.0 4 1 -1.0

generate_test_coordinate (複素数 )クラス D(n, c) と E(n, c) の検定行列を生成します。対応形式、又は、可能であ

れば帯格納モード形式で返します。

概要

#include <imsl.h>

void *imsl_c_generate_test_coordinate (int n, int c, int *nz, ..., 0)

関数 is imsl_z_generate_test_coordinate は、倍精度( double )です。

Page 716: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

必要な引数

int n ( 入力 )行列の行数

int c ( 入力 )構造を変えるために使用されるパラメータ。

int *nz ( 出力 )戻りベクトルの長さ。

戻り値

imsl_c_sparse_elem 型で長さ nz のベクトルのポインター。この空間を解放す

るために free を使用します。検定が生成できない場合,NULL が返されま

す。

オプション引数の概要

#include <imsl.h>

void *imsl_c_generate_test_coordinate (int n, int c, int *nz,IMSL_D_MATRIX,IMSL_SYMMETRIC_STORAGE,0)

オプション引数

IMSL_D_MATRIX

クラス D(n, c) の行列を返します。

デフォルト: クラス E(n, c) の行列を返します。

IMSL_SYMMETRIC_STORAGE,対応表現のために、対角項と下三角項の値だけを返します。 IMSL_D_MATRIX が指定されるとこのオプションは使えません。

説明

Østerby と Zlatev (1982 年 ) と同じ述語が使用されます。一般的に E- 行列と

引用されているクラス E(n, c) の検定行列は、対称で対角項に (6.0,0.0) を持ち、上対角項に (-1.0,1.0) 下対角項に (-1.0,-1.0) を持つ、次数 n の正定値行列 です。これに加えて、対角項から距

離 c に上対角項に (-1.0,1.0) 下対角項に (-1.0,-1.0) の二本の帯

があります。更に正確には、n ≥ 3 と 2 ≤ c ≤ n − 1 に対して、以下のように

なります。

クラス D(n, c) の検定行列は、次数 n の正方形行列で、完全な対角項、

対角項の上の距離 c と対角項の下に周期的に再現する三本の帯、そして

右上隅に要素の 10 × 10 の三角を持ちます。 更に正確には、n ≥ 14 と 1 ≤ c ≤ n − 13 に対して、以下のようになります。

ai,i = 6 0 ≤ i < nai,i+1 = −1 − i 0 ≤ i < n − 1ai+1,1 = −1 − i 0 ≤ i < n − 1ai,i+c = −1 + i 0 ≤ i < n − cai+c,i = −1 + i 0 ≤ i < n − c

ai,i = 1 0 ≤ i < nai,i+c = i + 2 0 ≤ i < n − cai,i-n+c = i + 2 n − c ≤ i < nai,i+c+1 = −(i + 1) 0 ≤ i < n − c − 1ai,i+c+1 = −(i + 1) n − c − 1≤ i < nai,i+c+2 = 16 0 ≤ i < n − c − 2ai,i-n+c+2 = 16 n − c − 2≤ i < nai,n-11+i+j = 100j 1 ≤ i< 11 − j, 0 ≤ j < 10

Page 717: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

ここで D(20, 5) の疎のパターンを示します。

デフォルトで imsl_c_generate_test_coordinate は対応表現で E 行列

を返します。IMSL_SYMMETRIC_STORAGE オプションを指定する事によっ

て、対角項と下三角項だけが返されます。スカラー nz はこの表現の非ゼロ要

素の数を含みます。

オプション IMSL_D_MATRIX はクラス D(n, c) の行列を返します。D 行列は対

称ではないので、IMSL_SYMMETRIC_STORAGE オプションは使えません。

例題

例題 1

この例題は、次の行列を生成して、結果をプリントします。

#include "imsl.h"

main(){ int i; int n = 5; int c = 3; int nz; Imsl_c_sparse_elem *a;

a = imsl_c_generate_test_coordinate (n, c, &nz, 0);

printf ("row col val\n"); for (i=0; i<nz; i++) printf (" %d %d (%5.1f, %5.1f)\n", a[i].row, a[i].col, a[i].val.re, a[i].val.im);}

出力結果

row col val 0 0 ( 6.0, 0.0)

x x x x x x x x x x x x x xx x x x x x x x x x x x x

x x x x x x x x x x x xx x x x x x x x x x x

x x x x x x x x x xx x x x x x x x x

x x x x x x x xx x x x x x x

x x x x x xx x x x x

x x x xx x x x

x x x xx x x xx x x xx x x x

x x x xx x x x

x x x xx x x x

( )

6 1 0 1 01 6 1 0 1

5,3 0 1 6 1 01 0 1 6 10 1 0 1 6

c

i ii i i

E i ii i i

i i

− − − + − − − − − + = − − − − − − − − − +

− − − −

Page 718: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

1 1 ( 6.0, 0.0) 2 2 ( 6.0, 0.0) 3 3 ( 6.0, 0.0) 4 4 ( 6.0, 0.0) 1 0 ( -1.0, -1.0) 2 1 ( -1.0, -1.0) 3 2 ( -1.0, -1.0) 4 3 ( -1.0, -1.0) 0 1 ( -1.0, 1.0) 1 2 ( -1.0, 1.0) 2 3 ( -1.0, 1.0) 3 4 ( -1.0, 1.0) 3 0 ( -1.0, -1.0) 4 1 ( -1.0, -1.0) 0 3 ( -1.0, 1.0) 1 4 ( -1.0, 1.0)

例題 2

この例題では、行列 E(5, 3) を対称格納ノードで返し、プリントします。

#include <imsl.h>

main(){ int i; int n = 5; int c = 3; int nz; Imsl_c_sparse_elem *a;

a = imsl_c_generate_test_coordinate (n, c, &nz, IMSL_SYMMETRIC_STORAGE, 0);

printf ("row col val\n"); for (i=0; i<nz; i++) printf (" %d %d (%5.1f, %5.1f)\n", a[i].row, a[i].col, a[i].val.re, a[i].val.im);}

出力結果

row col val 0 0 ( 6.0, 0.0) 1 1 ( 6.0, 0.0) 2 2 ( 6.0, 0.0) 3 3 ( 6.0, 0.0) 4 4 ( 6.0, 0.0) 1 0 ( -1.0, -1.0) 2 1 ( -1.0, -1.0) 3 2 ( -1.0, -1.0) 4 3 ( -1.0, -1.0) 3 0 ( -1.0, -1.0) 4 1 ( -1.0, -1.0)

Page 719: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

参照資料

ユーザエラーIMSL の関数はユーザエラーの検出を行い、出来る限り多くの情報をユーザに

提供します。そのためにエラーの様々なレベル重要度のを認識し、又その関数の目的の脈絡によってエラーの範囲を考慮します。ある状態での軽微なエラーが他の状態では重大な場合もあります。関数は、検出できる限りの多くのエラーの報告を試みます。複数のエラーはエラー検出に困難です。それは最初のエラーが検出された後で、入力が不確かな脈絡で解釈されるからです。

エラー重要度をどのように決定するか

ユーザの入力は数学的には正しいにもかかわらず、コンピュータ演算や使用されるアルゴリズムの制限により、正確に解答を計算することが出来ない場合があります。この場合には、評価された精度の等級がエラーの重要度を決定します。その関数が、いくらかの出力量を計算する場合において、いくつかは計算できないが、大部分は計算できる場合、エラーの条件が存在します。その重要度はエラーの全体に与える影響の評価によります。

エラーの種類とデフォルト操作

IMSL C/Math/ ライブラリでは、エラーの重要度は、5 つのレベルで 定義されて

います。各レベルは関連する PRINT 属性と STOP 属性を持っています。これ

らの属性は、デフォルト設定 (YES 又は NO) がありますが、ユーザ自身で設定

する事も可能です。複数のエラータイプを持つ理由は、重要度の異なるレベルのエラーに対して、独立した操作の制御方法を提供することです。 IMSL 関数

から戻る時、必ず 1 つのエラー状態が存在します。( コード 0 「エラー」 はエ

ラー無し )。 もし 2 つ以上の情報エラーが起きたとしても、(PRINT 属性が YES の場合 )1 つだけのメッセージがプリントされます。(重要度の PRINT 属性が

YES の場合)呼び出しプログラムの修正が適切ではない、又は、必要ではな

い複数のエラーは、複数のメッセージをプリントします。IMSL_TERMINAL を除くいずれの重要度のエラーは、情報エラーの可能さエイがあります。インクルードファイル imsl.h では Imsl_error のデータタイプとして、 IMSL_NOTE、IMSL_ALERT、IMSL_WARNING、IMSL_FATAL、IMSL_TERMINAL、IMSL_WARNING_IMMEDIATE、IMSL_FATAL_IMMEDIATE を定義しています。

IMSL_NOTE note は、軽微なエラーの可能性を示す、又は、単に計算に関する

情報を提供するために発行されます。

デフォルト属性: PRINT=NO, STOP=NO.

IMSL_ALERT alert は、アンダーフローによって関数値が 0 にセットされたこと

を 示します。

デフォルト属性: PRINT=NO, STOP=NO.

IMSL_WARNING warning は、 ユーザか呼び出しルーチンによって修正作業を必

要とする状態が存在することをが示します。警告エラーが出されるのは、結果が数桁だけ正確、出力のあるものは間違いの可能性があるが、出力の大部分は正確、又は解析技術の根底にあるいくつかの仮定が違反しているなどです。通常、修正作業は必要ではなく、その状態は無視されます。

デフォルト属性: PRINT=YES, STOP=NO.

IMSL_FATAL fatalエラーは重大かもしれない状態が存在する事を示します。 ほとんどの場合には、ユーザ、もしくは呼び出しルーチンで修正作業を行う必要があります。

Page 720: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

デフォルト属性: PRINT=YES, STOP=YES.

IMSL_TERMINAL terminal エラーは重大です。通常それは、方程式の数として

負の数を指定するような不正確な指定の結果です。これらのエラーは、また C 言語において正確に診断することが不可能な、種々のプログラ

ミングエラーが原因となっています。この結果生じるエラーメッセージは、ユーザが当惑する場合があります。このような場合に、ユーザには、この関数に渡される実際の引数と、この文書に与えられるダミー引数の説明とを、注意深く比較する必要があります。引数の順序とデータ型のチェックに特別な注意をしなければなりません。

TERMINAL エラーは、そのプログラムの訂正作業が一般的に妥当では

ないので、情報を与えるエラーとはなりません。通常の使用法では、TERMINAL エラーが起きたときに実行は直ちに停止します。2 つ以上

の TERMINAL エラーに関連するメッセージがプリントされます。

デフォルト属性: PRINT=YES, STOP=YES.

IMSL_WARNING_IMMEDIATE  immediate warning エラーは、その情報が直ちにプ

リントされることを除いて警告エラーと同じです。

デフォルト属性: PRINT=YES, STOP=NO.

IMSL_FATAL_IMMEDIATE immediate fatal エラーは、それが直ちにプリントされ

ることを除いて FATAL エラーと同じです。

デフォルト属性: PRINT=YES, STOP=YES.

ユーザは、第 12 章:ユーティリティーに記載されている imsl_error_options を呼び出して、PRINT と STOP 属性を変更することができます。

低レベル関数のエラー

ユーザのプログラムは、低レベル関数のネストを交互に呼び出す IMSL C/Mathライブラリ関数を呼び出す可能性があります。このような関数のネストの中で低レベル関数のエラーが起こった場合や、この低レベル関数が元のユーザ呼び出し関数まで情報を渡すことが出来なかった場合、関数のトレースバックが出力されます。これが生じる唯一の状況は、IMSL C/Math ライブラリの関数が他

の IMSL C/Math ライブラリ 関数を呼び出すユーザ提供のルーチンを呼んでい

るときです。

エラーハンドリングの関数

ユーザがエラーハンドリングを行う方法は次の 2 つがあります。

(1) デフォルト作業を変更する。(2) 修正作業を行うような情報エラーのコード

を決定する。 使用する関数は、imsl_error_options と imsl_error_code です。関数 imsl_error_options はエラーが発生したときに行われる作業を指

定します。関数 imsl_error_code は情報エラーの整数コードを返します。詳

細は、第 12 章:ユーティリティーの関数 imsl_error_options と imsl_error_codeを参照してください。

スレッドとエラーハンドリング

マルチスレッドが使用されている場合、各スレッドに対してデフォルト設定が有効でも、各個々のスレッドは変更することが可能です。スレッドを使用するときにオプションを設定するためには、各スレッド内から imsl_error_options を呼んで imsl_error_options(IMSL_SET_SIGNAL_TRAPPINGを除く ) を使用する必要

があります。

マルチスレッドが使用される際、IMSL信号トラッピング メカニズムは、無効

にしなければなりません。IMSL信号トラッピング メカニズムはスレッドが作

成される前に次の呼び出しを行って無効にすることができます。

imsl_error_options(IMSL_SET_SIGNAL_TRAPPING, 0, 0);

マルチスレッドの例題は imsl_error_options の例題 3 と 4 を参照してくだ

さい。

Page 721: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

情報エラーを使用してプログラム作業を決定

次のプログラムの一部分で、行列のコレスキー分解が実行されなければならない。行列が非負定値ではない ( そしてこれは、すぐには明白ではない ) ことが

決定されると、このプログラムは異なる分岐を取らなければなりません。

x = imsl_f_lin_sol_nonnegdef (n, a, b, 0);if (imsl_error_code() == IMSL_NOT_NONNEG_DEFINITE) {

/* Handle matrix that is not nonnegative definite */

}

追加の例題

他の例題は、第 12 章:ユーティリティー内の関数 imsl_error_options と imsl_error_code を参照してください。

複素データタイプと関数ユーザは、前もって定義されたデータタイプを使用して複素演算で計算を実行する事が可能です。これらのタイプは 2 つの浮動小数点精度で利用できます。

• f_complex z は単精度複素値

• d_complex w は倍精度複素値

各複素値は、複素数の実数部と虚数部である実数の組で構成される C 言語 構造体 です。 単精度複素数 z の実数部を呼び出すためには従属式 z.re を使

用し、虚数部には、従属式 z.imを使用します。倍精度複素数 w の実数部と

虚数部のためには、従属式 w.re と w.im を使用します。imsl.h で宣言さ

れる構造体は以下の通りです。

typedef struct{float re; float im;

} f_complex;

幾つかの標準の演算と関数を、自分のプログラムの中に複素数で計算を実行するためにユーザが使用することができます。この演算は、単精度と倍精度の両方のタイプに対して提供されます。 “+”、“-”、“*”、“/” の通常の数値演算さ

えも、適切な関数を使用して、実行されなければならないことに注意してください。

一様な前置名が演算と関数の名前の部分として使用されます。前置名 imsl_c_ は f_complex データのために使用されます。 前置名 imsl_z_ は d_complex データのために使用されます。

単精度複素数演算と関数

a x と y は、同じ実部と虚部を持つ有効な数字の場合、a 結果は値1を持ちます。双でない場合は、結果は、値 0 にな

ります。

演算 関数名 関数結果 関数引数z = –x z = imsl_c_neg(x) f_complex f_complexz = x + y z = imsl_c_add(x,y) f_complex f_complex ( 両方 )z = x – y z = imsl_c_sub(x,y) f_complex f_complex ( 両方 )z = x * y z = imsl_c_mul(x,y) f_complex f_complex ( 両方 )z = x / y z = imsl_c_div(x,y) f_complex f_complex ( 両方 )x= =ya z = imsl_c_eq(x,y) Int f_complex ( 両方 )z = x精度落下

z = imsl_cz_convert(x) f_complex d_complex

Page 722: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

倍精度複素数演算と関数

b x と y は、同じ実部と虚部を持つ有効な数字の場合、a 結果は値1を持ちます。双でない場合は、結果は、値 0 にな

ります。

演算 関数名 関数結果 関数引数z = a + ibデータ昇格

z = imsl_cf_convert(a,b) f_complex float ( 両方 )

z = z = imsl_c_conjg(x) f_complex f_complex

a = |z| a = imsl_c_abs(z) float f_complex

a = arg (z)–π < a ≤ π

a = imsl_c_arg(z) float f_complex

z =z = imsl_c_sqrt(z) f_complex f_complex

z = cos (x) z = imsl_c_cos(z) f_complex f_complexz = sin (x) z = imsl_c_sin(z) f_complex f_complexz = exp (x) z = imsl_c_exp(z) f_complex f_complexz = log (x) z = imsl_c_log(z) f_complex f_complex

z = xa z = imsl_cf_power(x,a) f_complex f_complex, float

z = xy z = imsl_cc_power(x,y) f_complex f_complex (both)

c = ak c = imsl_fi_power(a,k) float float, int

c = ab c = imsl_ff_power(a,b) float float (both)

m = jk m = imsl_ii_power(j,k) Int int (both)

演算 関数名 関数結果 関数引数z = –x z = imsl_z_neg(x) d_complex d_complexz = x + y z = imsl_z_add(x,y) d_complex d_complex ( 両方 )z = x – y z = imsl_z_sub(x,y) d_complex d_complex ( 両方 )z = x * y z = imsl_z_mul(x,y) d_complex d_complex ( 両方 )z = x / y z = imsl_z_div(x,y) d_complex d_complex ( 両方 )x==yb z = imsl_z_eq(x,y) Int d_complex ( 両方 )z = x精度落下

z = imsl_zc_convert(x) d_complex f_complex

z = a + ibデータ昇格

z = imsl_zd_convert(a,b) d_complex double ( 両方 )

演算 関数名 関数結果 関数引数z = x z = imsl_z_conjg(x) d_complex d_complex

a = |z| a = imsl_z_abs(z) Double d_complex

a = arg (z)–π < a ≤ π

a = imsl_z_arg(z) Double d_complex

z =z = imsl_z_sqrt(z) d_complex d_complex

z = cos (x) z = imsl_z_cos(z) d_complex d_complexz = sin (x) z = imsl_z_sin(z) d_complex d_complexz = exp (x) z = imsl_z_exp(z) d_complex d_complexz = log (x) z = imsl_z_log(z) d_complex d_complex

z = xa z = imsl_zd_power(x,a) d_complex d_complex, double

z = xy z = imsl_zz_power(x,y) d_complex d_complex (both)

c = ak c = imsl_di_power(a,k) Double double, int

c = ab c = imsl_dd_power(a,b) Double double (both)

m = jk m = imsl_ii_power(j,k) Int int (both)

x

x

x

Page 723: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

次のサンプルコードは、複素数に関連する幾つかの数量を計算してプリントします。次の数量

は、それに関連する丸め誤差を持つことに注意してください。 また、商 z = (1 + 2i) / (3 + 4i) も丸め誤差を持ちます。この結果は、相対誤差 |w –(2 + 2i)|/ |w| と |z * (3 + 4i) – (1 + 2i)|/ |(1 + 2i)| が近似的にマシン精度の大きさであるから受け入

れられます。

#include <imsl.h>

main(){

f_complex x = {1,2};f_complex y = {3,4};f_complex z;f_complex w;int isame;float eps = imsl_f_machine(4);

/* Echo inputs x and y */printf("Data: x = (%g, %g)\n y = (%g, %g)\n\n",

x.re, x.im, y.re, y.im);/* Add inputs */

z = imsl_c_add(x,y);printf("Sum: z = x + y = (%g, %g)\n\n", z.re, z.im);

/* Compute square root of y */w = imsl_c_sqrt(y);printf("Square Root: w = sqrt(y) = (%g, %g)\n", w.re, w.im);

/* Check results */z = imsl_c_mul(w,w);printf("Check: w*w = (%g, %g)\n", z.re, z.im);isame = imsl_c_eq(y,z);printf(" y == w*w = %d\n", isame);z = imsl_c_sub(z,y);printf("Difference: w*w - y = (%g, %g) = (%g, %g) * eps\n\n",

z.re, z.im, z.re/eps, z.im/eps);/* Divide inputs */

z = imsl_c_div(x,y);printf("Quotient: z = x/y = (%g, %g)\n", z.re, z.im);

/* Check results */w = imsl_c_sub(x, imsl_c_mul(z, y));printf("Check: w = x - z*y = (%g, %g) = (%g, %g) * eps\n",

w.re, w.im, w.re/eps, w.im/eps);}

出力結果Data: x = (1, 2)

y = (3, 4)

Sum: z = x + y = (4, 6)

Square Root: w = sqrt(y) = (2, 1)Check: w*w = (3, 4)

y == w*w = 0Difference: w*w - y = (-2.38419e-07, 4.76837e-07) = (-2, 4) * eps

Quotient: z = x/y = (0.44, 0.08)Check: w = x - z*y = (5.96046e-08, 0) = (0.5, 0) * eps

3 4w i= +

Page 724: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに
Page 725: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

製品サポート

Visual Numerics 社製品技術サポートへのお問い合わせ保守契約にご加入のお客様は、当社エンジニアに IMSL C 数値計算ライブラリ

の使用法に関してお問い合わせいただくことが可能です。 当社エンジニアは次

の項目についての質問にお答えいたします。

• ドキュメンテーションに関する説明

• 弊社の提供するプログラミングに関する問題

• 特定の問題のための IMSL ライブラリ関数、またはプロシージャの選択

数学・統計に関する質問およびお客様のプログラムのデバッグについては、質問項目に含まれません。

技術的な質問のお問い合わせフォーム

• http://www.vnij.com/forms/tech_sprt_request.html

技術的なご質問は、上記 URL よりお問い合わせください。もし、フォームが

正しく送信できない場合は、お問い合わせの内容に加え下記の情報を弊社サポート宛([email protected])までメールにてお送りください。

1. ライセンス番号

2. 製品名とバージョン : IMSL C Numerical Library Version 6.0

3. コンパイラ、OS とそのバージョン

4. 問題がある具体的な関数名など

Page 726: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに
Page 727: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

付録 A: 参考文献

Abramowitz and Stegun

Abramowitz, Milton, and Irene A. Stegun (editors) (1964), Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables, National Bureau of Standards, Washington.

Ahrens and Dieter

Ahrens, J.H., and U. Dieter (1974), Computer methods for sampling from gamma, beta, Poisson, and binomial distributions, Computing, 12, 223–246.

Akima

Akima, H. (1970), A new method of interpolation and smooth curve fitting based on local procedures, Journal of the ACM, 17, 589–602.

Akima, H. (1978), A method of bivariate interpolation and smooth surface fitting for irregularly distributed data points, ACM Transactions on Mathematical Software, 4, 148–159.

Ashcraft

Ashcraft, C. (1987), A vector implementation of the multifrontal method for large sparse symmetric positive definite systems, Technical Report ETA-TR-51, Engineering Technology Applications Division, Boeing Computer Services, Seattle, Washington.

Ashcraft et al.

Ashcraft, C., R. Grimes, J. Lewis, B. Peyton, and H. Simon (1987), Progress in sparse matrix methods for large linear systems on vector supercomputers. Intern. J. Supercomputer Applic., 1(4), 10–29.

Atkinson (1979)

Atkinson, A.C. (1979), A family of switching algorithms for the computer generation of beta random variates, Biometrika, 66, 141–145.

Atkinson (1978)

Atkinson, Ken (1978), An Introduction to Numerical Analysis, John Wiley & Sons, New York.

Barnett

Barnett, A.R. (1981), An algorithm for regular and irregular Coulomb and Bessel functions of real order to machine accuracy, Computer Physics Communication, 21, 297–314.

Barrett and Healy

Barrett, J.C., and M. J.R. Healy (1978), A remark on Algorithm AS 6: Triangular decomposition of a symmetric matrix, Applied Statistics, 27, 379–380.

Bays and Durham

Bays, Carter, and S.D. Durham (1976), Improving a poor random number generator, ACM Transactions on Mathematical Software, 2, 59–64.

Page 728: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Blom

Blom, Gunnar (1958), Statistical Estimates and Transformed Beta-Variables, John Wiley & Sons, New York.

Blom and Zegeling

Blom, JG, and Zegeling, PA (1994), A Moving-grid Interface for Systems of One-dimensional Time-dependent Partial Differential Equations, ACM Transactions on Mathematical Software, Vol 20, No.2, 194-214.

Boisvert

Boisvert, Ronald (1984), A fourth order accurate fast direct method of the Helmholtz equation, Elliptic Problem solvers II, (edited by G. Birkhoff and A. Schoenstadt), Academic Press, Orlando, Florida, 35–44.

Bosten and Battiste

Bosten, Nancy E., and E.L. Battiste (1974), Incomplete beta ratio, Communications of the ACM, 17, 156–157.

Brenan, Campbell, and Petzold

Brenan, K.E., S.L. Campbell, L.R. Petzold (1989), Numerical Solution of Initial-Value Problems in Differential-Algebraic Equations, Elsevier Science Publ. Co.

Brent

Brent, Richard P. (1973), Algorithms for Minimization without Derivatives, Prentice-Hall, Inc., Englewood Cliffs, New Jersey.

Brigham

Brigham, E. Oran (1974), The Fast Fourier Transform, Prentice-Hall, Englewood Cliffs, New Jersey.

Burgoyne

Burgoyne, F.D. (1963), Approximations to Kelvin functions, Mathematics of Computation, 83, 295-298.

Carlson

Carlson, B.C. (1979), Computing elliptic integrals by duplication, Numerische Mathematik, 33, 1–16.

Carlson and Notis

Carlson, B.C., and E.M. Notis (1981), Algorithms for incomplete elliptic integrals, ACM Transactions on Mathematical Software, 7, 398–403.

Carlson and Foley

Carlson, R.E., and T.A. Foley (1991),The parameter R2 in multiquadric interpolation, Computer Mathematical Applications, 21, 29–42.

Cheng

Cheng, R.C.H. (1978), Generating beta variates with nonintegral shape parameters, Communications of the ACM, 21, 317–322.

Cohen and Taylor

Cohen, E. Richard, and Barry N. Taylor (1986), The 1986 Adjustment of the Fundamental Physical Constants, Codata Bulletin, Pergamon Press, New York.

Page 729: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Cooley and Tukey

Cooley, J.W., and J.W. Tukey (1965), An algorithm for the machine computation of complex Fourier series, Mathematics of Computation, 19, 297–301.

Cooper

Cooper, B.E. (1968), Algorithm AS4, An auxiliary function for distribution integrals, Applied Statistics, 17, 190–192.

Courant and Hilbert

Courant, R., and D. Hilbert (1962), Methods of Mathematical Physics, Volume II, John Wiley & Sons, New York, NY.

Craven and Wahba

Craven, Peter, and Grace Wahba (1979), Smoothing noisy data with spline functions, Numerische Mathematik, 31, 377–403.

Crowe et al.

Crowe, Keith, Yuan-An Fan, Jing Li, Dale Neaderhouser, and Phil Smith (1990), A direct sparse linear equation solver using linked list storage, IMSL Technical Report 9006, IMSL, Houston.

Davis and Rabinowitz

Davis, Philip F., and Philip Rabinowitz (1984), Methods of Numerical Integration, Academic Press, Orlando, Florida.

de Boor

de Boor, Carl (1978), A Practical Guide to Splines, Springer-Verlag, New York.

Dennis and Schnabel

Dennis, J.E., Jr., and Robert B. Schnabel (1983), Numerical Methods for Unconstrained Optimization and Nonlinear Equations, Prentice-Hall, Englewood Cliffs, New Jersey.

Dongarra et al.

Dongarra, J.J., J.R. Bunch, C.B. Moler, and G.W. Stewart (1979), LINPACK User’s Guide, SIAM, Philadelphia.

Draper and Smith

Draper, N.R., and H. Smith (1981), Applied Regression Analysis, 2nd. ed., John Wiley & Sons, New York.

DuCroz et al.

Du Croz, Jeremy, P. Mayes, and G. Radicati (1990), Factorization of band matrices using Level-3 BLAS, Proceedings of CONPAR 90-VAPP IV, Lecture Notes in Computer Science, Springer, Berlin, 222.

Duff et al.

Duff, I. S., A. M. Erisman, and J. K. Reid (1986), Direct Methods for Sparse Matrices, Clarendon Press, Oxford.

Duff and Reid

Duff, I.S., and J.K. Reid (1983), The multifrontal solution of indefinite sparse symmetric linear equations. ACM Transactions on Mathematical Software, 9, 302–325.

Duff, I.S., and J.K. Reid (1984), The multifrontal solution of unsymmetric sets of linear equations. SIAM Journal on Scientific and Statistical Computing, 5, 633–641.

Page 730: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Enright and Pryce

Enright, W.H., and J.D. Pryce (1987), Two FORTRAN packages for assessing initial value methods, ACM Transactions on Mathematical Software, 13, 1–22.

Farebrother and Berry

Farebrother, R.W., and G. Berry (1974), A remark on Algorithm AS 6: Triangular decomposition of a symmetric matrix, Applied Statistics, 23, 477.

Fisher

Fisher, R.A. (1936), The use of multiple measurements in taxonomic problems, Annals of Eugenics, 7, 179– 188.

Fishman and Moore

Fishman, George S. and Louis R. Moore (1982), A statistical evaluation of multiplicative congruential random number generators with modulus 231 – 1, Journal of the American Statistical Association, 77, 129–136.

Forsythe

Forsythe, G.E. (1957), Generation and use of orthogonal polynomials for fitting data with a digital computer, SIAM Journal on Applied Mathematics, 5, 74–88.

Franke

Franke, R. (1982), Scattered data interpolation: Tests of some methods, Mathematics of Computation, 38, 181–200.

Garbow et al.

Garbow, B.S., J.M. Boyle, K.J. Dongarra, and C.B. Moler (1977), Matrix Eigensystem Routines - EISPACK Guide Extension, Springer–Verlag, New York.

Garbow, B.S., G. Giunta, J.N. Lyness, and A. Murli (1988), Software for an implementation of Weeks’ method for the inverse Laplace transform problem, ACM Transactions on Mathematical Software, 14, 163–170.

Gautschi

Gautschi, Walter (1968), Construction of Gauss-Christoffel quadrature formulas, Mathematics of Computation, 22, 251–270.

Gautschi, Walter (1969), Complex error function, Communications of the ACM, 12, 635. Gautschi, Walter (1970), Efficient computation of the complex error function, SIAM Journal on Mathematical Analysis, 7, 187−198.

Gear

Gear, C.W. (1971), Numerical Initial Value Problems in Ordinary Differential Equations, Prentice-Hall, Englewood Cliffs, New Jersey.

Gear and Petzold

Gear, C.W. and Petzold, Linda R. (1984), ODE methods for the solutions of differential/algebraic equations. SIAM Journal Numerical Analyisis, 21, #4, 716.

Gentleman

Gentleman, W. Morven (1974), Basic procedures for large, sparse or weighted linear least squares problems, Applied Statistics, 23, 448–454.

George and Liu

George, A., and J.W.H. Liu (1981), Computer Solution of Large Sparse Positive Definite Systems, Prentice-Hall, Englewood Cliffs, New Jersey.

Page 731: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Gill and Murray

Gill, Philip E., and Walter Murray (1976), Minimization subject to bounds on the variables, NPL Report NAC 92, National Physical Laboratory, England.

Gill et al.

Gill, P.E., W. Murray, M.A. Saunders, and M.H. Wright (1985), Model building and practical aspects of nonlinear programming, in Computational Mathematical Programming, (edited by K. Schittkowski), NATO ASI Series, 15, Springer-Verlag, Berlin, Germany.

Goldfarb and Idnani

Goldfarb, D., and A. Idnani (1983), A numerically stable dual method for solving strictly convex quadratic programs, Mathematical Programming, 27, 1–33.

Golub

Golub, G.H. (1973), Some modified matrix eigenvalue problems, SIAM Review, 15, 318–334.

Golub and Van Loan

Golub, G.H., and C.F. Van Loan (1989), Matrix Computations, Second Edition, The Johns Hopkins University Press, Baltimore, Maryland.

Golub, Gene H., and Charles F. Van Loan (1983), Matrix Computations, Johns Hopkins University Press, Baltimore, Maryland.

Golub and Welsch

Golub, G.H., and J.H. Welsch (1969), Calculation of Gaussian quadrature rules, Mathematics of Computation, 23, 221–230.

Gregory and Karney

Gregory, Robert, and David Karney (1969), A Collection of Matrices for Testing Computational Algorithms, Wiley-Interscience, John Wiley & Sons, New York.

Griffin and Redfish

Griffin, R., and K A. Redish (1970), Remark on Algorithm 347: An efficient algorithm for sorting with minimal storage, Communications of the ACM, 13, 54.

Grosse

Grosse, Eric (1980), Tensor spline approximation, Linear Algebra and its Applications, 34, 29–41.

Guerra and Tapia

Guerra, V., and R. A. Tapia (1974), A local procedure for error detection and data smoothing, MRC Technical Summary Report 1452, Mathematics Research Center, University of Wisconsin, Madison.

Hageman and Young

Hageman, Louis A., and David M. Young (1981), Applied Iterative Methods, Academic Press, New York.

Hanson

Hanson, Richard J. (1986), Least squares with bounds and linear constraints, SIAM Journal Sci. Stat. Computing, 7, #3.

Page 732: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Hardy

Hardy, R.L. (1971), Multiquadric equations of topography and other irregular surfaces, Journal of Geophysical Research, 76, 1905–1915.

Hart et al.

Hart, John F., E.W. Cheney, Charles L. Lawson, Hans J.Maehly, Charles K. Mesztenyi, John R. Rice, Henry G. Thacher, Jr., and Christoph Witzgall (1968), Computer Approximations, John Wiley & Sons, New York.

Healy

Healy, M.J.R. (1968), Algorithm AS 6: Triangular decomposition of a symmetric matrix, Applied Statistics, 17, 195–197.

Herraman

Herraman, C. (1968), Sums of squares and products matrix, Applied Statistics, 17, 289–292.

Higham

Higham, Nicholas J. (1988), FORTRAN Codes for estimating the one-norm of a real or complex matrix, with applications to condition estimation, ACM Transactions on Mathematical Software, 14, 381-396.

Hill

Hill, G.W. (1970), Student’s t-distribution, Communications of the ACM, 13, 617–619.

Hindmarsh

Hindmarsh, A.C. (1974), GEAR: Ordinary Differential Equation System Solver, Lawrence Livermore National Laboratory Report UCID-30001, Revision 3, Lawrence Livermore National Laboratory, Livermore, Calif.

Hinkley

Hinkley, David (1977), On quick choice of power transformation, Applied Statistics, 26, 67–69.

Huber

Huber, Peter J. (1981), Robust Statistics, John Wiley & Sons, New York.

Hull et al.

Hull, T.E., W.H. Enright, and K.R. Jackson (1976), User’s guide for DVERK — A subroutine for solving nonstiff ODEs, Department of Computer Science Technical Report 100, University of Toronto.

Irvine et al.

Irvine, Larry D., Samuel P. Marin, and Philip W. Smith (1986), Constrained interpolation and smoothing, Constructive Approximation, 2, 129–151.

Jackson et al.

Jackson, K.R., W.H. Enright, and T.E. Hull (1978), A theoretical criterion for comparing Runge-Kutta formulas, SIAM Journal of Numerical Analysis, 15, 618–641.

Jenkins

Jenkins, M.A. (1975), Algorithm 493: Zeros of a real polynomial, ACM Transactions on Mathematical Software, 1, 178–189.

Page 733: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Jenkins and Traub

Jenkins, M.A., and J.F. Traub (1970), A three-stage algorithm for real polynomials using quadratic iteration, SIAM Journal on Numerical Analysis, 7, 545–566.

Jenkins, M.A., and J.F. Traub (1970), A three-stage variable-shift iteration for polynomial zeros and its relation to generalized Rayleigh iteration, Numerishe Mathematik, 14, 252–263.

Jenkins, M.A., and J.F. Traub (1972), Zeros of a complex polynomial, Communications of the ACM, 15, 97– 99.

Johnk

Jöhnk, M.D. (1964), Erzeugung von Betaverteilten und Gammaverteilten Zufalls-zahlen, Metrika, 8, 5–15.

Kendall and Stuart

Kendall, Maurice G., and Alan Stuart (1973), The Advanced Theory of Statistics, Volume II, Inference and Relationship, Third Edition, Charles Griffin & Company, London, Chapter 30.

Kennedy and Gentle

Kennedy, William J., Jr., and James E. Gentle (1980), Statistical Computing, Marcel Dekker, New York.

Kernighan and Richtie

Kernighan, Brian W., and Richtie, Dennis M. 1988, "The C Programming Language" Second Edition, 241.

Kinnucan and Kuki

Kinnucan, P., and Kuki, H., (1968), A single precision inverse error function subroutine, Computation Center, University of Chicago.

Knuth

Knuth, Donald E. (1981), The Art of Computer Programming, Volume II: Seminumerical Algorithms, 2nd. ed., Addison-Wesley, Reading, Mass.

Krogh

Krogh, Fred, T. (2005), An Algorithm for Linear Programming, http://mathalacarte.com/fkrogh/pub/lp.pdf , Tujunga, CA.

Learmonth and Lewis

Learmonth, G.P., and P.A.W. Lewis (1973), Naval Postgraduate School Random Number Generator Package LLRANDOM, NPS55LW73061A, Naval Postgraduate School, Monterey, California.

Lehmann

Lehmann, E.L. (1975), Nonparametrics: Statistical Methods Based on Ranks, Holden-Day, San Francisco.

Levenberg

Levenberg, K. (1944), A method for the solution of certain problems in least squares, Quarterly of Applied Mathematics, 2, 164–168.

Leavenworth

Leavenworth, B. (1960), Algorithm 25: Real zeros of an arbitrary function, Communications of the ACM, 3, 602.

Page 734: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Lentini and Pereyra

Pereyra, Victor (1978), PASVA3: An adaptive finite-difference FORTRAN program for first order nonlinear boundary value problems, in Lecture Notes in Computer Science, 76, Springer-Verlag, Berlin, 67−88.

Lewis et al.

Lewis, P.A.W., A.S. Goodman, and J.M. Miller (1969), A pseudorandom number generator for the System/ 360, IBM Systems Journal, 8, 136–146.

Liepman

Liepman, David S. (1964), Mathematical constants, in Handbook of Mathematical Functions, Dover Publications, New York.

Liu

Liu, J.W.H. (1987), A collection of routines for an implementation of the multifrontal method, Technical Report CS-87-10, Department of Computer Science, York University, North York, Ontario, Canada.

Liu, J.W.H. (1989), The multifrontal method and paging in sparse Cholesky factorization. ACM Transactions on Mathematical Software, 15, 310-325.

Liu, J.W.H. (1990), The multifrontal method for sparse matrix solution: theory and practice, Technical Report CS-90-04, Department of Computer Science, York University, North York, Ontario, Canada.

Liu, J.W.H. (1986), On the storage requirement in the out-of-core multifrontal method for sparse factorization. ACM Transactions on Mathematical Software, 12, 249-264.

Lyness and Giunta

Lyness, J.N. and G. Giunta (1986), A modification of the Weeks Method for numerical inversion of the Laplace transform, Mathematics of Computation, 47, 313–322.

Madsen and Sincovec

Madsen, N.K., and R.F. Sincovec (1979), Algorithm 540: PDECOL, General collocation software for partial differential equations, ACM Transactions on Mathematical Software, 5, #3, 326–351.

Maindonald

Maindonald, J.H. (1984), Statistical Computation, John Wiley & Sons, New York.

Marquardt

Marquardt, D. (1963), An algorithm for least-squares estimation of nonlinear parameters, SIAM Journal on Applied Mathematics, 11, 431–441.

Martin and Wilkinson

Martin, R.S., and J.H. Wilkinson (1971), Reduction of the Symmetric Eigenproblem Ax = λBx and Related Problems to Standard Form, Volume II, Linear Algebra Handbook, Springer, New York.

Martin, R.S., and J.H. Wilkinson (1971), The Modified LR Algorithm for Complex Hessenberg Matrices, Handbook, Volume II, Linear Algebra, Springer, New York.

Mayle

Mayle, Jan, (1993), Fixed Income Securities Formulas for Price, Yield, and Accrued Interest, SIA Standard Securities Calculation Methods, Volume I, Third Edition, pages 17-35.

Page 735: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Michelli

Micchelli, C.A. (1986), Interpolation of scattered data: Distance matrices and conditionally positive definite functions, Constructive Approximation, 2, 11–22.

Michelli et al.

Micchelli, C.A., T.J. Rivlin, and S. Winograd (1976), The optimal recovery of smooth functions, Numerische Mathematik, 26, 279–285.

Micchelli, C.A., Philip W. Smith, John Swetits, and Joseph D. Ward (1985), Constrained Lp approximation, Constructive Approximation, 1, 93–102.

Moler and Stewart

Moler, C., and G.W. Stewart (1973), An algorithm for generalized matrix eigenvalue problems, SIAM Journal on Numerical Analysis, 10, 241-256.

Moré et al.

Moré, Jorge, Burton Garbow, and Kenneth Hillstrom (1980), User Guide for MINPACK-1, Argonne National Laboratory Report ANL-80-74, Argonne, Illinois.

Müller

Müller, D.E. (1956), A method for solving algebraic equations using an automatic computer, Mathematical Tables and Aids to Computation, 10, 208–215.

Murtagh

Murtagh, Bruce A. (1981), Advanced Linear Programming: Computation and Practice, McGraw-Hill, New York.

Murty

Murty, Katta G. (1983), Linear Programming, John Wiley and Sons, New York.

Neter and Wasserman

Neter, John, and William Wasserman (1974), Applied Linear Statistical Models, Richard D. Irwin, Homewood, Illinois.

Neter et al.

Neter, John, William Wasserman, and Michael H. Kutner (1983), Applied Linear Regression Models, Richard D. Irwin, Homewood, Illinois.

Østerby and Zlatev

Østerby, Ole, and Zahari Zlatev (1982), Direct Methods for Sparse Matrices, Lecture Notes in Computer Science, 157, Springer-Verlag, New York.

Owen

Owen, D.B. (1962), Handbook of Statistical Tables, Addison-Wesley Publishing Company, Reading, Mass.

Owen, D.B. (1965), A special case of the bivariate non-central t distribution, Biometrika, 52, 437–446.

Parlett

Parlett, B.N. (1980), The Symmetric Eigenvalue Problem, Prentice-Hall, Inc., Englewood Cliffs, New Jersey.

Pennington and Berzins

Pennington, S. V., and Berzins, M., (1994), “New NAG Library Software for First Order Partial Differential Equations.” ACM-Trans, Math. Soft., 20, 1, pages 63-99.

Page 736: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Petro

Petro, R. (1970), Remark on Algorithm 347: An efficient algorithm for sorting with minimal storage, Communications of the ACM, 13, 624.

Petzold

Petzold, L.R. (1982), A description of DASSL: A differential/ algebraic system solver, Proceedings of the IMACS World Congress, Montreal, Canada.

Piessens et al.

Piessens, R., E. deDoncker-Kapenga, C.W. Überhuber, and D.K. Kahaner (1983), QUADPACK, Springer-Verlag, New York.

Powell

Powell, M.J.D. (1978), A fast algorithm for nonlinearly constrained optimization calculations, Numerical Analysis Proceedings, Dundee 1977, Lecture Notes in Mathematics, (edited by G. A. Watson), 630, Springer-Verlag, Berlin, Germany, 144–157.

Powell, M.J.D. (1985), On the quadratic programming algorithm of Goldfarb and Idnani, Mathematical Programming Study, 25, 46–61.

Powell, M.J.D. (1988), A tolerant algorithm for linearly constrained optimizations calculations, DAMTP Report NA17, University of Cambridge, England.

Powell, M.J.D. (1989), TOLMIN: A fortran package for linearly constrained optimizations calculations, DAMTP Report NA2, University of Cambridge, England.

Powell, M.J.D. (1983), ZQPCVX a FORTRAN subroutine for convex quadratic programming, DAMTP Report 1983/NA17, University of Cambridge, Cambridge, England.

Reinsch

Reinsch, Christian H. (1967), Smoothing by spline functions, Numerische Mathematik, 10, 177–183.

Rice

Rice, J.R. (1983), Numerical Methods, Software, and Analysis, McGraw-Hill, New York.

Saad and Schultz

Saad, Y., and M. H. Schultz (1986), GMRES: A generalized minimum residual algorithm for solving nonsymmetric linear systems, SIAM Journal of Scientific and Statistical Computing, 7, 856-869.

Sallas and Lionti

Sallas, William M., and Abby M. Lionti (1988), Some useful computing formulas for the nonfull rank linear model with linear equality restrictions, IMSL Technical Report 8805, IMSL, Houston.

Savage

Savage, I. Richard (1956), Contributions to the theory of rank order statistics—the two-sample case, Annals of Mathematical Statistics, 27, 590–615.

Schmeiser

Schmeiser, Bruce (1983), Recent advances in generating observations from discrete random variates, in Computer Science and Statistics: Proceedings of the Fifteenth Symposium on the Interface, (edited by James E. Gentle), North-Holland Publishing Company, Amsterdam, 154–160.

Page 737: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Schmeiser and Babu

Schmeiser, Bruce W., and A.J.G. Babu (1980), Beta variate generation via exponential majorizing functions, Operations Research, 28, 917–926.

Schmeiser and Kachitvichyanukul

Schmeiser, Bruce, and Voratas Kachitvichyanukul (1981), Poisson Random Variate Generation, Research Memorandum 81–4, School of Industrial Engineering, Purdue University, West Lafayette, Indiana.

Schmeiser and Lal

Schmeiser, Bruce W., and Ram Lal (1980), Squeeze methods for generating gamma variates, Journal of the American Statistical Association, 75, 679–682.

Seidler and Carmichael

Seidler, Lee J. and Carmichael, D.R., (editors) (1980), Accountants' Handbook, Volume I, Sixth Edition, The Ronald Press Company, New York.

Shampine

Shampine, L.F. (1975), Discrete least squares polynomial fits, Communications of the ACM, 18, 179–180.

Shampine and Gear

Shampine, L.F. and C.W. Gear (1979), A user’s view of solving stiff ordinary differential equations, SIAM Review, 21, 1–17.

Sincovec and Madsen

Sincovec, R.F., and N.K. Madsen (1975), Software for nonlinear partial differential equations, ACM Transactions on Mathematical Software, 1, #3, 232–260.

Singleton

Singleton, T.C. (1969), Algorithm 347: An efficient algorithm for sorting with minimal storage, Communications of the ACM, 12, 185–187.

Smith et al.

Smith, B.T., J.M. Boyle, J.J. Dongarra, B.S. Garbow, Y. Ikebe, V.C. Klema, and C.B. Moler (1976), Matrix Eigensystem Routines — EISPACK Guide, Springer-Verlag, New York.

Smith

Smith, P.W. (1990), On knots and nodes for spline interpolation, Algorithms for Approximation II, J.C. Mason and M.G. Cox, Eds., Chapman and Hall, New York.

Spellucci, PeterSpellucci, P. (1998), An SQP method for general nonlinear programs using only equality constrained subproblems, Math. Prog., 82, 413-448, Physica Verlag, Heidelberg, Germany

Spellucci, P. (1998), A new technique for inconsistent problems in the SQP method. Math. Meth. of Oper. Res.,47, 355-500, Physica Verlag, Heidelberg, Germany.

Stewart

Stewart, G.W. (1973), Introduction to Matrix Computations, Academic Press, New York.

Strecok

Strecok, Anthony J. (1968), On the calculation of the inverse of the error function, Mathematics of Computation, 22, 144–158.

Page 738: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Stroud and Secrest

Stroud, A.H., and D.H. Secrest (1963), Gaussian Quadrature Formulae, Prentice-Hall, Englewood Cliffs, New Jersey.

Temme

Temme, N.M (1975), On the numerical evaluation of the modified Bessel Function of the third kind, Journal of Computational Physics, 19, 324–337.

Tezuka

Tezuka, S. (1995), Uniform Random Numbers: Theory and Practice. Academic Publishers, Boston.

Thompson and Barnett

Thompson, I.J. and A.R. Barnett (1987), Modified Bessel functions Iν(z) and Kν(z) of real order and complex argument, Computer Physics Communication, 47, 245–257.

Tukey

Tukey, John W. (1962), The future of data analysis, Annals of Mathematical Statistics, 33, 1–67.

Velleman and Hoaglin

Velleman, Paul F., and David C. Hoaglin (1981), Applications, Basics, and Computing of Exploratory Data Analysis, Duxbury Press, Boston

Verwer et al

Verwer, J. G., Blom, J. G., Furzeland, R. M., and Zegeling, P. A. (1989), A moving-grid method for one-dimensional PDEs Based on the Method of Lines, Adaptive Methods for Partial Differential Equations, Eds., J. E. Flaherty, P. J. Paslow, M. S. Shephard, and J. D. Vasiilakis, SIAM Publications, Philadelphia, PA (USA) pp. 160-175.

Walker

Walker, H.F. (1988), Implementation of the GMRES method using Householder transformations, SIAM Journal of Scientific and Statistical Computing, 9, 152-163.

Watkins

Watkins, David S., L. Elsner (1991), Convergence of algorithm of decomposition type for the eigenvalue problem, Linear Algebra Applications, 143, pp. 29–47.

Weeks

Weeks, W.T. (1966), Numerical inversion of Laplace transforms using Laguerre functions, J. ACM, 13, 419–429.

Wilmott et al

Wilmott, P., Howison, and S., Dewynne, J., (1996), The Mathematics of Financial Derivatives (A Student Introduction), Cambridge Univ. Press, New York, NY.317 pages.

Page 739: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

付録 B: Alphabetical Summary of Routines

ルーチン

関数名 / ページ 概要

A

B

accr_interest_maturity 549 ページ

満期時に利息を支払う債券の累積利息を計算します。

accr_interest_periodic 551 ページ

定期的に利息を支払う債券の累積利息を計算します。

airy_Ai 495 ページ エアリー関数を計算します。airy_Ai_derivative 497ペー

エアリー関数の導関数を計算します。

airy_Bi 496 ページ 第 2 種のエアリー関数を計算します。airy_Bi_derivative 498 ページ

第 2 種のエアリー関数の導関数を計算します。

bessel_exp_I0 479 ページ 第 1 種 0 次の指数関数的にスケーリングされた修正ベッセル関数を計算します。

bessel_exp_I1 481 ページ 第 1 種 1 次の指数関数的にスケーリングされた修正ベッセル関数を計算します。

bessel_exp_K0 484 ページ 第 2 種 0 次の指数関数的にスケーリングされた修正ベッセル関数を計算します。

bessel_exp_K1 486 ページ 第 2 種 0 次の指数関数的にスケーリングされた修正ベッセル関数を計算します。

bessel_I0 478 ページ 第 1 種 0 次実数修正ベッセル関数 I0(x) を計算しま

す。bessel_I1 480 ページ 第 1 種 1 次実数修正ベッセル関数 I1(x) を計算しま

す。bessel_Ix 482 実数の次数と複素数の引数を持つ第 1 種修正ベッセ

ル関数の数列を計算します。bessel_J0 470 ページ 第 1 種 0 次実数ベッセル関数 J 0 (x) を計算します。bessel_J1 472 ページ 第 1 種 1 次実数ベッセル関数 J1(x) を計算します。bessel_Jx 473 ページ 実数の次数と複素数の引数を持つ第 1 種ベッセル関

数の数列を計算します。bessel_K0 483 ページ 第 2 種 0 次実数修正ベッセル関数 K0(x) を計算しま

す。bessel_K1 485 ページ 第 2 種 1 次実数修正ベッセル関数 K1(x) を計算しま

す。bessel_Kx 487 ページ 実数の次数と複素数の引数を持つ第 2 種修正ベッセ

ル関数の数列を計算します。bessel_Y0 474 ページ 第 2 種 0 次実数ベッセル関数 Y0(x) を計算します。bessel_Y1 475 ページ 第 2 種 1 次実数ベッセル関数 Y1(x) を計算します。bessel_Yx 476 ページ 実数の次数と複素数の引数を持つベッセル関数の数

列を計算します。beta 464 ページ 実数ベータ関数 β(x, y) を計算します。

Page 740: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

C

D

beta_cdf 518 ページ ベータ確率分布関数を計算します。beta_incomplete 466 ページ 不完全ベータ関数 Ix = βx(a,b)/β(a,b) を

計算します。beta_inverse_cdf 520 ページ ベータ分布関数の逆を計算します。binomial_cdf 515 ページ 2 項分布関数を計算します。bivariate_normal_cdf 521 ページ

二変量正規分布関数を計算します。

bond_equivalent_yield 552 ページ

米国財務省短期債券の債券換算の利回りを計算します。

bounded_least_squares 440 ページ

修正 Levenberg-Marquardt アルゴリズムを使用して変数の境界に従う非線形最小二乗問題を解きます。

bvp_finite_difference 270 ページ

2 点の境界条件を持つ微分方程式のシステムを、可変次数、可変ステップサイズの繰り延べ修正を持つ有限差分法を使って解きます。

chi_squared_cdf 507 ページ カイ二乗分布関数を計算します。chi_squared_inverse_cdf 508 ページ

カイ二乗分布関数の逆を計算します。

chi_squared_test 593 ページ カイ二乗適合度検定を実行します。constant 660 ページ 種々の数学定数と物理定数の値を返します。constrained_nlp 446 ページ 逐次等号制約二次計画法を使用して一般非線形計画

問題を解きます。convexity 553 ページ 債券のコンベクシティを計算します。convolution (complex) 372 ページ

たたみ込みとオプションで 2 つの複素数ベクトルの相関を計算します。

convolution 367 ページ たたみ込みとオプションで 2 つの実数ベクトルの相関を計算します。

coupon_days 555 ページ 決済日を含むクーポン期間の日数を計算します。coupon_number 556 ページ 決済日と満期日の間の支払われるクーポン数を計算

します。covariances 600 ページ 標本の分散共分散行列、又は相関行列を計算します。ctime 651 ページ 消費された CPU 秒数を返します。cub_spline_integral 152 ページ

3 次スプラインの積分を計算します。

cub_spline_interp_e_cnd 140 ページ

種々の端点条件を指定して、3 次スプライン関数を計算します。

cub_spline_interp_shape 146 ページ

形状を保存する 3 次スプラインを計算します。

cub_spline_smooth 189 ページ 平滑化パラメータの推定に交差検定(cross-validation)を使う、もしくは直接、平滑化パラメータを選択することにより、ノイズを含むデータに対する平滑化 3 次スプライン近似を計算します。

cub_spline_value 149 ページ 3 次スプラインの値、或いは、導関数の値を計算します。

cumulative_interest 522 ページ

2 期間の間に支払われる累積利息を計算します。

cumulative_principal 523 ページ

2 期間の間に支払われた累積元金を計算します。

date_to_days 652 ページ 1900 年1月1日から任意の日付までの日数を計算します。

days_before_settlement 557 ページ

クーポン期間の最初の日から決済日までの日数を計算します。

days_to_date 653 ページ 1900 年 1 月 1 日以来の日数に対応する日付を計算します。

days_to_next_coupon 558 ページ

決済日から次のクーポン期日までの日数を計算します。

Page 741: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

E

F

dea_petzold_gear 279 ページ Petzold−Gear BDF BDF(後退微分公式)法を使用し

て、1階微分代数連立方式 g(t, y, y′) = 0 を解きます。depreciation_amordegrc 560 ページ

各会計期間の減価償却を計算します。 depreciation_amorlincと同様です。

depreciation_amorlinc 561 ページ

各会計期間の減価償却を計算します。 depreciation_amordegrcと同様です。

depreciation_db 524 ページ 定率法を使用した資産の減価償却を計算します。depreciation_ddb 526 ページ 倍率法を使用して資産の減価償却額を計算します。depreciation_sln 527 ページ 定額法を使用して資産の減価償却額を計算します。depreciation_syd 528 ページ 算術級数法を使用して資産の減価償却費を計算しま

す。depreciation_vdb 529 ページ 倍率逓減法により指定した期間の資産の減価償却額

を計算します。discount_price 562 ページ 割引債の額面 $100 に対する価格を計算します。discount_rate 564 ページ 債券の割引率を計算します。discount_yield 565 ページ 割引債の年利回りを計算します。dollar_decimal 530 ページ 分数表記の金額を小数表記に変換します。dollar_fraction 531 ページ 小数表記の金額を分数表記に変換します。duration 566 ページ 定期的に利息が支払われる債券の 1 年のデュレー

ションを計算します。

effective_rate 532 ページ 実効年利率を計算します。eig_gen (complex) 119 ページ 複素行列 A の固有展開を計算します。eig_gen 117 ページ 実数行列 A の固有展開を計算します。eig_herm (complex) 123 ペー

ジ複素エルミート行列 A の固有展開を計算します。

eig_sym 121 ページ 実数対称行列 A の固有展開を計算します。eig_symgen 126 ページ 連立方程式 Ax = λBx の一般化された固有展開を計算

します。行列 A と B は実数対称で、B は正定値です。elliptic_integral_E 489 ページ

第 2 種の完全楕円積分 E(x) を計算します。

elliptic_integral_K 488 ページ

第 1 種の完全楕円積分 K(x) を計算します。

elliptic_integral_RC 493 ページ

逆円関数、対数と逆双曲線関数が計算される初期積分を計算します。

elliptic_integral_RD 491 ページ

第 2 種の Carlson の楕円積分 RD(x, y, z) を計算しま

す。elliptic_integral_RF 490 ページ

第 1 種の Carlson の楕円積分 RF(x, y, z) を計算します。

elliptic_integral_RJ 492 ページ

第 3 種の Carlson の楕円積分 RJ (x, y, z, ρ) を計算しま

す。erf 457 ページ 実数誤差関数 erf(x) を計算します。erf_inverse 461 ページ 逆誤差関数 erf-1 (x) を計算します。erfc 458 ページ 実数相補誤差関数 erfc(x) を計算します。erfc_inverse 462 ページ 実数逆相補誤差関数 erfc-1 (x) を計算します。erfce 459 ページ 指数関数的にスケーリングされた相補誤差関数を計

算します。erfe 460 ページ erfc(z) に関連したスケーリングされた関数を計算し

ます。error_code 659 ページ 最後に呼び出された関数からのエラーメッセージに

対応するコードを取得します。error_options 654 ページ 種々のエラーハンドリングオプションを設定します。

f_cdf 509 ページ F 分布関数を計算します。f_inverse_cdf 510 ページ F 分布関数の逆を計算します。

Page 742: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

G

H

I

fast_poisson_2d 341 ページ 一様メッシュ上の HODIE 有限差分スキームを基にした高速ポアソンソルバーを使用して二次元矩形上のポアソン、又は、ヘルムホルツ方程式を解きます。

faure_next_point 632 ページ シャッフルされた Faure 数列を計算します。fcn_derivative 253 ページ ユーザ提供の関数の 1 次、2 次、3 次導関数を計算し

ます。fft_2d_complex 363 ページ 複素 2 次元配列の複素離散 2 次元フーリエ変換を計

算します。fft_complex 353 ページ 複素数列の複素離散フーリエ変換を計算します。fft_complex_init 355 ページ imsl_c_fft_complexのパラメータを計算します。fft_cosine 357 ページ 偶数級数の離散フーリエ余弦変換を計算します。fft_cosine_init 358 ページ imsl_f_fft_cosineで必要とされるパラメータを計

算します。fft_real 348 ページ 実数列の実離散フーリエ変換を計算します。fft_real_init 352 ページ imsl_f_fft_realのパラメータを計算します。fft_sine 360 ページ 奇数級数の離散フーリエ正弦変換を計算します。fft_sine_init 361 ページ imsl_f_fft_sineで必要とされるパラメータを計算

します。fresnel_integral_C 494 ペー

ジ余弦フレネル積分を計算します。

fresnel_integral_S 494 ペー

ジ正弦フレネル積分を計算します。

future_value 533 ページ 投資の将来価値を計算します。future_value_schedule 534 ページ

初期元金の将来価値を、複利利率の表を考慮して計算します。

gamma 466 ページ 実数ガンマ関数 γ(x) を計算します。gamma_cdf 514 ページ ガンマ分布関数を計算します。gamma_incomplete 469 ページ 不完全ガンマ関数 γ(a, x) を計算します。gauss_quad_rule 249 ページ 種々の古典的加重関数で Gauss、Gauss-Radau、又は

Gauss-Lobatto 求積法を計算します。geneig (complex) 131 ページ A と B が複素数である、連立方程式 Ax = λBx の一般

化された固有展開を計算します。geneig 128 ページ A と B が実数である連立方程式 Ax = λBx の一般化さ

れた固有展開を計算します。generate_test_band (complex) 711 ページ

クラス Ec (n , c) の検定行列を生成します。帯、又は

帯対称形式で返します。generate_test_band 709 ペー

ジクラス E (n , c) の検定行列を生成します。帯、又は、帯対称形式で返します。

generate_test_coordinate (complex) 715 ページ

クラス D(n, c) と E(n, c) の検定行列を生成します。

generate_test_coordinate 712 ページ

クラス D(n, c) と E(n, c) の検定行列を生成します。

hypergeometric_cdf 516 ペー

ジ超幾何分布関数を計算します。

int_fcn 218 ページ Gauss-Kronrod 規則に基づく全体適応枠組みを使用して、関数を積分します。

int_fcn_2d 242 ページ 2 次元累次積分を計算します。

Page 743: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

J

K

L

int_fcn_alg_log 224 ページ 代数的、対数的特異点を持つ関数を積分します。int_fcn_cauchy 236 ページ コーシーの主値を用いて次式の積分を計算します。

int_fcn_fourier 233 ページ フーリエ正弦変換又は、フーリエ余弦変換を計算し

ます。int_fcn_hyper_rect 245 ペー

ジ超矩形上の関数を積分します。

int_fcn_inf 227 ページ 無限区間、或いは、半無限区間の関数を積分します。int_fcn_qmc 247 ページ 準モンテカルロ法を使用して超幾何空間上の関数を

積分します。int_fcn_sing 215 ページ Gauss-Kronrod 規則に基づく全体適応枠組みを使用し

て、端点特異性を持つ関数を積分します。int_fcn_sing_pts 221 ページ 与えられた特異点を持つ関数を積分します。int_fcn_smooth 239 ページ 非適応則を使って平滑化関数を積分します。int_fcn_trig 230 ページ 正弦、または余弦の要素を含む関数を積分します。interest_payment 535 ページ 任意の期間の投資の利息支払いを計算します。interest_rate_annuity 536 ページ

年金の期間あたりの利率を計算します。

interest_rate_security 568 ページ

全額投資された債券の利率を計算します。

internal_rate_of_return 538 ページ

キャッシュフロー表の内部収益率を計算します。

internal_rate_schedule 539 ページ

キャッシュフロー表の内部収益率を計算します。キャッシュフローが周期的である必要はありません。

inverse_laplace 377 ページ 複素関数の逆ラプラス変換を計算します。

kelvin_bei0 499 ページ 次数ゼロの第 1 種ケルビン関数 bei を計算します。kelvin_bei0_derivative 502 ページ

次数ゼロの第 1 種ケルビン関数 bei の導関数を計算します。

kelvin_ber0 498 ページ 次数ゼロの第 1 種ケルビン関数 ber を計算します。kelvin_ber0_derivative 501 ページ

次数ゼロの第 1 種ケルビン関数 ber の導関数を計算します。

kelvin_kei0 501 ページ 次数ゼロの第 2 種ケルビン関数 kei を計算します。kelvin_kei0_derivative 504 ページ

次数ゼロの第 2 種ケルビン関数 kei の導関数を計算します。

kelvin_ker0 500 ページ 次数ゼロの第 2 種ケルビン関数 ker を計算します。kelvin_ker0_derivative 503 ページ

次数ゼロの第 2 種ケルビン関数 ker の導関数を計算します。

linear_programming 423 ペー

ジ線形計画問題を解きます。

lin_least_squares_gen 92 ページ

線形最小二乗問題 Ax = b を解きます。

lin_lsq_lin_constraints 98 ページ

線形制約付き最小二乗問題を解きます。

lin_prog 428 ページ 改訂シンプレックス法を使用して線形計画問題を解きます。

lin_sol_def_cg 87 ページ 共役勾配法を用いて実対称正定値連立方程式を解きます。

lin_sol_gen (complex) 33 ページ

複素数一般線形連立方程式 Ax = b を解きます。

lin_sol_gen 27 ページ 実数一般線形連立方程式 Ax = b を解きます。

( )b

a

f xdx

x c−∫

Page 744: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

M

lin_sol_gen_band (complex) 49 ページ

複素数一般線形帯連立方程式 Ax = b を解きます。

lin_sol_gen_band 45 ページ 実数一般線形帯連立方程式 Ax = b を解きます。lin_sol_gen_coordinate (complex) 68 ページ

疎の複素数係数行列 A で線形連立方程式 Ax = b を解きます。

lin_sol_gen_coordinate 59 ページ

疎の線形連立方程式 Ax = b を解きます。

lin_sol_gen_min_residual 83 ページ

再開された一般化最小残差法 (GMRES) を使用して線形連立方程式 Ax = b を解きます。

lin_sol_nonnegdef 110 ページ 実対称非負定値線形連立方程式 Ax = b を解きます。lin_sol_posdef (complex) 41 ページ

複素エルミート正定値連立方程式 Ax = b を解きます。

lin_sol_posdef 37 ページ 実対称正定値連立方程式 Ax = b を解きます。lin_sol_posdef_band (complex) 56 ページ

帯対称格納モードの複素エルミート正定値線形連立方程式、Ax = b を解きます。

lin_sol_posdef_band 52 ペー

ジ帯対称格納様式の実対称正定値線形連立方程式、Ax = b を解きます。

lin_sol_posdef_coordinate (complex) 78 ページ

疎のエルミート正定値の線形連立方程式 Ax = b を解きます。

lin_sol_posdef_coordinate 74 ページ

疎実対称正定値の線形連立方程式 Ax = b を解きます。

lin_svd_gen (complex) 105 ページ

複素数矩形行列 A の SVD(特異値分解)A = USVH を計算します。

lin_svd_gen 101 ページ実数矩形行列 A の SVD(特異値分解)A = USVT を計算します。

log_beta 465 ページ 実数ベータ関数 の対数 ln β(x, y) を計算します。log_gamma 468 ページ ガンマ関数の絶対値の対数 log |Γ(x)| を計算します。

machine (float) 665 ページ そのコンピュータの浮動小数点演算を説明する情報を返します。

machine (integer) 663 ページ そのコンピュータの演算を説明する整数情報を返します。

mat_add_band (complex) 695 ページ

2 つの帯行列を加えます。帯行列は、両方とも帯格納

モード、C ← αA + βB です。mat_add_band 692 ページ 2 つの帯行列を加えます。帯行列は、両方とも帯格納

モード、C ← αA + βB です。mat_add_coordinate (complex) 700 ページ

座標形式で格納された2つの複素行列の要素毎加算 C ← αA + βB を実行します。

mat_add_coordinate 698 ペー

ジ座標形式で格納された 2 つの実行列の要素毎加算 C ← αA + βB を実行します。

mat_mul_rect (complex) 675 ページ

行列の転置、行列の共役転置、行列 - ベクトル積、行列 - 行列積、双一次形、又は三重積を計算します。

mat_mul_rect 672 ページ 行列の転置、行列 - ベクトル積、行列 - 行列積、双一次形、又は、三重積を計算します。

mat_mul_rect_band (complex) 681 ページ

全ての行列が複素タイプの帯形で保存された、行列の転置、行列 - ベクトル積、行列 - 行列積を計算します。

mat_mul_rect_band 678 ページ 全ての行列が帯形で保存された、行列の転置、行列 -ベクトル積、行列 - 行列積を計算します。

mat_mul_rect_coordinate (complex) 688 ページ

疎の座標形式で保存された全ての行列のための、行列の転置、行列 - ベクトル積、行列 - 行列積を計算します。

mat_mul_rect_coordinate 685 ページ

疎の座標形式で保存された全ての行列のための、行列の転置、行列 - ベクトル積、行列 - 行列積を計算します。

matrix_norm 703 ページ 矩形行列の種々のノルムを計算します。matrix_norm_band 705 ページ 帯格納モードで保存された行列の種々のノルムを計

算します。matrix_norm_coordinate 707 ページ

座標形式で保存された行列の種々のノルムを計算します。

Page 745: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

N

O

P

min_con_gen_lin 435 ページ 線形等号 / 不等号制約をうける一般目的関数を最小化します。

min_uncon 396 ページ 関数計算だけを使用して、単一変数の平滑関数 f(x) の最小点を見つけます。

min_uncon_deriv 399 ページ 関数と 1 次微係数計算の両方を使用して、1 変数の平滑関数 f(x) の最小点を見つけます。

min_uncon_multivar 403 ペー

ジ擬似 Newton 法を使って n 変数の関数 f(x) を最小化します。

modified_duration 569 ページ 債券の修正マコーレー(Macauley)デュレーションを計算します。

modified_internal_rate 540 ページ

定期的なキャッシュフロー表の修正内部収益率を計算します。

net_present_value 542 ページ 一連の均等でない定期的キャッシュフローの純現在価値を計算します。

next_coupon_date 571 ページ 決済日後の最初のクーポン期日を計算します。nominal_rate 543 ページ 名目年利率を計算します。nonlin_least_squares 408 ページ

修正 Levenberg-Marquardt アルゴリズムを使用して非線形最小二乗問題を解きます。

normal_cdf 504 ページ 標準正規 ( ガウス ) 分布関数を計算します。normal_inverse_cdf 506 ペー

ジ標準正規 ( ガウス ) 分布関数の逆を計算します。

number_of_periods 543 ページ 定期的な定額の支払いかつ利率が一定である投資の期間数を計算します。

ode_adams_gear 264 ページ Adams-Gear 法を使用して常微分方程式の硬い初期値問題を解きます。

ode_runge_kutta 259 ページ ルンゲ - クッタ - ヴァーナー 5 次と 6 次法を使用して常微分方程式の初期値問題を解きます。

output_file 648 ページ 出力ファイル、又は、エラーメッセージ出力ファイルを設定します。

page 642 ページ ページの幅や長さを設定、もしくは取得します。payment 545 ページ 投資の定期的な支払い額を計算します。pde_1d_mg 296 ページ 移動グリッドインターフェースを使用する 1 次元時

間依存偏微分方程式のシステムを解きます。 pde_method_of_lines 326 ページ

直線法を使用して、形式 ut = f(x, t, u, ux, uxx) の偏微分

連立方程式を解きます。poisson_cdf 517 ページ ポワソン分布関数を計算します。poly_regression 611 ページ 多項式の最小二乗回帰を実行します。present_value 546 ページ 透視の現在価値を計算します。present_value_schedule 547 ページ

キャッシュフロー表の現在価値を計算します。キャッシュフローが定期的である必要はありません。

previous_coupon_date 572 ページ

決済日直前のクーポン期日を計算します。

price 573 ページ 定期的に利息を支払う債券の額面価格 100 ドルあたりの価格を計算します。

price_maturity 574 ページ 満期日に利息を支払う債券の額面価格 100 ドルあたりの価格を計算します。

principal_payment 548 ページ 指定した期間の元金の支払い額を計算します。

Page 746: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

Q

R

S

quadratic_prog 432 ページ 線形等号制約、又は不等号制約を受ける二次計画問題を解きます。

radial_evaluate 211 ページ 動径基底当てはめを計算します。radial_scattered_fit 205 ページ

動径基底関数を使用して n ≥ 1 の Rn における離散データの近似を計算します。

random_beta 629 ページ ベータ分布から擬似乱数を生成します。random_exponential 631 ペー

ジ標準指数分布から擬似乱数を生成します。

random_gamma 628 ページ 標準ガンマ分布から擬似乱数を生成します。Xrandom_normal 625 ページ 逆 CDF 法を使用して標準正規分布から擬似乱数を

生成します。random_option 623 ページ 一様 (0,1) 乗算合同法疑似乱数生成器を選択します。random_poisson 627 ページ ポアソン分布から擬似乱数を生成します。random_seed_get 622 ページ IMSL 乱数生成器で使用されるシードの現在値を取

得します。random_seed_set 623 ページ IMSL 乱数生成器で使用するための乱数シードを初

期化します。random_uniform 624 ページ 一様 (0,1) 分布から疑似乱数を生成します。ranks 616 ページ 観測のベクトルに対する順位、標準得点、又は指数

得点を計算します。read_mps 416 ページ 線形計画問題や二次計画問題を含む MPS ファイルを

読み込みます。received_maturity 576 ページ 全額投資した債券が満期日を迎えた時の受取額を計

算します。regression 604 ページ 最小二乗法を使用して多重線形回帰モデルを当ては

めます。

scattered_2d_interp 202 ページ

局所的に 2 変数の 5 次の多項式である離散データの2 変量補間関数を計算します。

simple_statistics 586 ページ 基本単変量統計量を計算します。smooth_1d_data 198 ページ エラー検出による1次元データの平滑化を行います。sort (integer) 668 ページ 代数値によって整数ベクトルをソートします。オプ

ションにより、ベクトルは絶対値でソートすることができ、ソートの置換を返すことができます。

sort 667 ページ 代数値によってベクトルをソートします。オプションにより、ベクトルは絶対値でソートすることができ、ソートの置換を返すことができます。

spline_2d_integral 173 ペー

ジ矩形領域でのテンソル積スプラインの積分を計算します。

spline_2d_interp 161 ページ 2 次元のテンソル積データから 2 次元、テンソル積スプライン補間を計算します。

spline_2d_least_squares 184 ページ

最小二乗法を使って2次元のテンソル積スプライン近似を計算します。

spline_2d_value 170 ページ テンソル積スプラインの値、もしくはその偏微係数の値を計算します。

spline_integral 168 ページ スプラインの積分を計算します。spline_interp 153 ページ スプライン補間関数を計算します。spline_knots 158 ページ スプライン補間関数のためのノットを計算します。spline_least_squares 179 ページ

最小二乗スプライン近似を計算します。

Page 747: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

T

U

V

W

X

Y

Z

spline_lsq_constrained 192 ページ

最小二乗制約付きスプライン近似を計算します。

spline_value 166 ページ スプラインの値、又は、その微係数の値を計算します。

t_cdf 511 ページ スチューデントの t 分布関数を計算します。t_inverse_cdf 513 ページ スチューデントの t 分布関数の逆を計算します。table_oneway 590 ページ 観測値を一元度数分布表内に集計します。treasury_bill_price 577 ページ

米国財務省短期債券の額面 100 ドルあたりの価格を計算します。

treasury_bill_yield 578 ページ

米国財務省短期債券の利回りを計算します。

user_fcn_least_squares 175 ページ

ユーザ提供の関数を使用して最小二乗当てはめを計算します。

vector_norm 670 ページ ベクトルの様々なノルム、又は、2 つのベクトルの差を計算します。

version 651 ページ このライブラリのバージョン、シリアル番号、オペレーティング・システム、コンパイラを記述する情報を返します。

write_matrix 637 ページ 隣接する記憶域に格納された長方形行列(又は、ベクトル)をプリントします。

write_options 643 ページ 行列をプリントするためのオプションを設定、又は、取得します。

year_fraction 580 ページ 2つの日付の間の日数を1年に対する割合で表します。yield_maturity 581 ページ 満期日に利息を支払う債券の年利回りを計算します。yield_periodic 582 ページ 定期的に利息を支払う債券の利回りを計算します。

Page 748: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

zeros_fcn 387 ページ Müller の方法を使用して実関数の実ゼロ点を見つけます。

zeros_poly (complex) 385 ページ

Jenkins-Traub の3段階アルゴリズムを使用して、複素係数の多項式のゼロ点を見つけます。

zeros_poly 383 ページ Jenkins-Traub の3段階アルゴリズムを使用して、実係数の多項式のゼロ点を見つけます。

zeros_sys_eqn 391 ページ 修正 Powell ハイブリッドアルゴリズムを使用して、n 個の非線形連立方程式 f(x) = 0 を解きます。

Page 749: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

索引

A

active set 396, 450active set strategy 424Adams-Gear method 264Airy functions 495, 497, 498algebraic-logarithmic singularities 224ANSI C 11approximation 205

B

backward differentiation formulas 267band storage mode 705Bauer and Fike theorem 115Bessel functions 470, 472, 473, 474, 475, 478, 480, 483, 485beta distributions 629beta functions 464, 465, 466, 518binomial functions 515bivariate functions 521Blom scores 616bond functions 549, 551, 552, 553, 555, 556, 557, 558, 560, 561, 562, 564, 565, 566, 568, 569, 571, 572, 573, 574,

576, 577, 578, 580, 581, 582bvp_finite_difference 270

C

Cauchy principal 236chi-squared functions 507, 508chi-squared goodness-of-fit test 593Cholesky factorization 41, 52, 56complex arithmetic 22complex general band system 49complex Hermitian positive definite system 56computerís arithmetic 663condition numbers 115conjugate gradient method 87constrained quadratic programming 446coordinate format 707correlation matrix 600cosine factor 230cosine Fresnel integrals 494CPU time 651cubic splines 140, 146, 149, 152, 189current value of the seed 622

D

dates and days 652, 653dea_petzold_gear 279decay rates 258derivatives 253differential algebraic equations 259discrete Fourier cosine transformation 358discrete Fourier sine transformation 361distribution functions 504, 506, 507, 508, 509, 510, 511, 513, 514, 515, 516, 517, 518, 520, 521

E

eigenvalues 115, 116, 117, 119, 121, 123, 126, 128, 131

Page 750: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

eigenvectors 115, 116, 117, 119, 121, 123, 126, 128, 131equality/inequality constraints 435error detection 198error functions 457, 458, 461, 462error handling 21, 654, 659error messages 648errors 719evaluation 149even sequence 357expected normal scores 616

F

factorization 26fast Fourier transforms 347, 348, 352, 353, 355, 363fast_poisson_2d 341Faure sequence 632financial functions 522, 523, 524, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 538, 539, 540, 542, 543,

545, 546, 547, 548Fourier transform 233

G

gamma distributions 628gamma functions 466, 468, 469, 514Gauss quadrature 249Gaussian functions 504, 506Gauss-Kronrod rules 215, 218GMRES method 83

H

Hermitian matrices 123Householderí s method 107hypergeometric functions 516hyper-rectangle 245, 247, 632

I

infinite interval 227initialize random seed 623integration 168, 173, 215, 218, 221, 224, 227, 230, 233, 236, 239, 242, 245, 247, 249interpolation 138, 140, 146, 153, 158, 161, 202inverse matrix 41inversions 27

J

Jenkins-Traub algorithm 383, 385

L

lack-of-fit test 611least squares 138least-squares approximation 192least-squares fit 175, 179, 184, 198, 408, 611least-squares solutions 26Levenberg-Marquardt algorithm 408linear constraints 98linear equations 45, 49, 52, 59, 68, 74, 78linear least squares 26linear least-squares problem 98linear programmingactive set strategy 424linear system solution 25, 27LU factorization 27, 45, 49, 59, 68

Page 751: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

M

mathematical constants 660matrices 26, 27, 41, 110, 637general 13multiplying 672rectangular 13symmetric 14matrix multiply 675matrix transpose 678, 681, 685, 688matrix-vector products 672, 675memory allocation 19minimization 395, 396, 399, 403, 408, 423, 428, 432, 435Müller’s method 387

N

non-ANSI C 11nonlinear least squares 408numerical ranking 616

O

odd sequence 360ode_adams_gear 264one-way frequency table 590order statistics 616ordinary differential equations 257, 264output files 648overflow 21

P

page size 642Partial Differential EquationsA Flame Propagation Model 303A Model in Cylindrical Coordinates 302A ëHot Spotí Model 303Black Scholes 304Electrodynamics Model 300Inviscid Flow on a Plate 301Population Dynamics 302Traveling Waves 303partial differential equations 258pde_1d_mg 294pde_method_of_lines 326PetzoldGear BDF method 279Poisson distributions 627Poisson functions 517Poisson solver 341polynomial functions 383polynomials 136Powell hybrid algorithm 391printing 637, 642, 643

Q

QR factorizations 26, 92quadratic programming 432quadrature 213, 214quasi-Newton method 403

R

radial-basis fit 211radial-basis functions 205random number generation 585, 586random numbers 622, 623, 624, 625, 627, 628, 629

Page 752: IMSL C 数値計算ライブラリ - XLsoftjp.xlsoft.com/documents/vni/Cmath_JPN.pdfTable of Contents イントロダクション 11 IMSL C Math ライブラリ..... 11 初めに

real general band system 45real symmetric definite linear system 87real symmetric positive definite system 52regression 604, 611restarted generalized minimum residual method 83Runge-Kutta-Verner method 259

S

Savage scores 616scattered data 202, 205select random number generator 623semi-infinite interval 227simplex algorithm 423, 428sine factor 230sine Fresnel integrals 494singular value decomposition 27smoothing 189sort 667, 668sparse Hermitian positive definite system 78sparse real symmetric positive definite system 74sparse system 59spline interpolant 153, 158, 161splines 136, 137, 138, 152, 166, 168, 170, 173, 179, 184, 192standard exponential distributions 631statistics 586, 600, 604, 616symbolic factorizations 74, 78

T

Thread Safe 12, 13threads and error handling 720time constants 258Tukey scores 616

U

underflow 21uniform mesh 341univariate 224univariate statistics 586

V

Van der Waerden scores 616vectors 637version 651

Z

zero of a system 391zeros of a function 387