• 検索結果がありません。

IMSL_CSC_FORMAT, int *col_ptr, int *row_ind, float *values, IMSL_MEMORY_BLOCK_SIZE, int block_size,

0)

プ ン引数

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 分解が 標対応形式 lu_coordinate 長さ nz 配列に返さ ます こ

Imsl_f_sparse_lu プ 化さ た内部表現よ 簡潔 す こ 利 点

SOLVE_ONLY 呼び出し 間 因子 内部表現が再構成さ け いこ す

し し こ 因子がプログ 終了 後 格納さ 再度 後 実行時にロー さ あ IMSL_RETURN_LU_IN_COORD IMSL_SUPPLY_LU_IN_COORD 組 合わ せ 格納 込 が単純 形式 最良 選択に ます

IMSL_SUPPLY_SPARSE_LU_IN_COORD, int nzlu, 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 条件数 推定し 変数 condition に返します IMSL_PIVOTING_STRATEGY, Imsl_pivot method 。入力)

ッ 選択 次 選びます:

IMSL_ROW_MARKOWITZ, IMSL_COLUMN_MARKOWITZ, 又 IMSL_SYMMETRIC_MARKOWITZ

フ : IMSL_SYMMETRIC_MARKOWITZ

IMSL_NUMBER_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_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 分解 行うこ に

よ いわゆ one-off (一回限 ) 問題 解 ます 因子 L 陽的に 保存さ ませ こ 行

交換に加え 消去演算 に行 わ saxpy 演算が右辺にも拡張さ た す 従 式 Ly

= b

陰的に解 ます 因子 U Ux = yx 計算す 角解法に渡さ ます

A 複数 方程式 Ax = b 解く場合 分解 一回 け計算し 種々 右辺に対し 何回も 前進

後退解法 す こ が効率的 す こ 場合 因子 L 陽的に保存さ 全 列 行 交換が記録さ

ます そ 角方程式 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 ようにします 分解 一回 呼び出し

Ax = b ATx = b 両方 解 ます

プ ン IMSL_CONDITION A L1 条件数 推定す に使用さ ます こ ア

Higham に基 ます IMSL_CONDITION 指定す 場合 one-off (一回限 ) 問題が解 にし

も 完全 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 減 すこ が 許容値 設定す た に使用 ま す こ 指定した ロップ許容値よ も小さい大 さ 新しい 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

例 し 次 行列 考えます













6 0 0 0 2 1

3 1 5 0 0 1

0 1 10 0 0 2

0 0 1 3 10 0

0 0 0 0 0 10 A

xT = (1, 2, 3, 4, 5, 6) し Ax = (10, 7, 45, 33, 34, 31)T ます A 非 ロ 数 nz = 15 す

#include <imsl.h>

int 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 = imsl_f_lin_sol_gen_coordinate (n, nz, a, b, 0);

imsl_f_write_matrix ("solution", 1, n, x, 0);

imsl_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パー ン あ こ 示します こ 比率 係数行列 元数 初 非 ロ 数 特に消去 際に生成さ fill-in 量によ 非常に変 化します 時間測定 結果 ンに強く依存す こ に注意し く さい

#include <imsl.h>

#include <stdio.h>

#include <stdlib.h>

int 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;

/* Get the coefficient matrix */

a = imsl_f_generate_test_coordinate (n, c, &nz, 0);

/* Set two different predetermined solutions */

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);

mod_ten[i] = (float) (i % 10);

}

/* Choose b so that x will approximate mod_five */

b = (float *) imsl_f_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a,

IMSL_X_VECTOR, n, mod_five, 0);

/* Time the factor/solve */

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;

/* Compute max absolute error */

error_factor_solve = imsl_f_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_five,

IMSL_INF_NORM, &index, 0);

free (mod_five);

imsl_free (b);

imsl_free (x);

/* Get new right hand side -- b = A * mod_ten */

b = (float *) imsl_f_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a,

IMSL_X_VECTOR, n, mod_ten, 0);

/* Use the previously computed factorization to solve 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);

imsl_free (b);

imsl_free (x);

/* Print errors and ratio of execution times */

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-05 absolute error (solve) = 2.160072e-04 time_solve/time_factor_solve = 0.093750

例題 3

こ 例題 A = E (500, 50) 線形方程式 Ax = b ます 方程式

ップ許容値 使用し 解 ます 最後に 計算した 分解 使用し 同 線形方程式 反 復改良法 解 ます 測定時間結果 ンに強く依存す こ に注意し く さい

#include <imsl.h>

#include <stdio.h>

#include <stdlib.h>

int 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;

/* Get the coefficient matrix */

a = imsl_f_generate_test_coordinate (n, c, &nz, 0);

for (i=0; i<nz; i++) a[i].val *= 0.05;

/* Set a predetermined solution */

mod_five = (float*) malloc (n*sizeof(*mod_five));

for (i=0; i<n; i++)

mod_five[i] = (float) (i % 5);

/* Choose b so that x will approximate mod_five */

b = imsl_f_mat_mul_rect_coordinate ("A*x", IMSL_A_MATRIX, n, n, nz, a,

IMSL_X_VECTOR, n, mod_five, 0);

/* Time the factor/solve */

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;

/* Compute max abolute error */

error_zero_drop_tol = imsl_f_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_five,

IMSL_INF_NORM, &index, 0);

imsl_free (x);

/* Solve the same problem, with drop tolerance = 0.005 */

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;

/* Compute max abolute error */

error_nonzero_drop_tol = imsl_f_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_five,

IMSL_INF_NORM, &index, 0);

imsl_free (x);

/* Solve the same problem with IR, use last factorization */

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;

/* Compute max abolute error */

error_nonzero_drop_tol_IR = imsl_f_vector_norm (n, x, IMSL_SECOND_VECTOR, mod_five,

IMSL_INF_NORM, &index, 0);

imsl_free (x);

imsl_free (b);

/* Print errors and ratio of execution times */

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) absolute error = 1.907349e-06 fillin = 8656

time_nonzero_drop_tol/time_zero_drop_tol = 1.086957 time_nonzero_drop_tol_IR/time_zero_drop_tol = 0.840580

反復改良法(IR)が使用さ い 絶対誤差に注目し く さい また 反復改良法 極 時 間が こ に注意し く さい こ 場合に IR 解 大体 分解 同 い時間が ます

こ 問題 大 い ロップ許容値 反復改良法 使用 フ 2倍にあた 時間 fill-in 10パー ン 減少す こ が ました 容量が厳しい状況下 こ よう ー

フが適 場合があ ます ロップ許容値 大 く選ぶ LU に大 い誤差 持 込 反 復改良 束 妨 こ に注意し く さい