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

疎 実対称正定値 線形方程式 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) void imsl_free_symbolic_factor (Imsl_symbolic_factor *sym_factor)

void imsl_f_free_numeric_factor (Imsl_f_numeric_factor *num_factor) double型 関数 imsl_d_lin_sol_posdef_coordinate

imsl_d_free_numeric_factor

必須 引数

int n 。入力) 行列 行数

int nz 。入力)

行列 下 角にあ 非 ロ 数

Imsl_f_sparse_elem *a 。入力)

行列 下 角にあ 非 ロ入力値 位置 値 含 長さ nz ベク float *b 。入力)

右辺 含 長さn ベク

戻 値

疎対称正定値線形方程式 Ax = b x へ インタ こ 領域 解放す に imsl_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,

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_symbolic_factor 構造体 詳細 次 通

パ ータ ータ型 説明

nzsub int ** Cholesky因子 非 ロ 非対角要素に対す

縮行指標 含 配列へ インタ

xnzsub int ** *nzsub に対す イン ック 含 長さ

n + 1 配列へ インタ Cholesky因子 列 j にあ 非 ロ 要素に対す 行指標 (*nzsub)[(*xnzsub)[j]]) 始ま 連 続領域に格納さ

maxsub int 指標 し 使わ 配列 *nzsub 要素

数 *nzsub 大 さ maxsub よ 大 いこ もあ こ に注意

xlnz int ** 長さ n + 1 配列へ インタ こ 配

列 *alnz 非 ロ 非対角要素 抽出

す に使わ 始 終わ イン ック

含 alnz に い プ ン引

数 IMSL_RETURN_NUMERIC_FACTOR 説 明 参照 因子行列 列 j に対し *alnz

始 終わ イン ック そ

(*xlnz)[j] (*xlnz)[j + 1] に格納 さ

maxlnz int Cholesky 因子 非 ロ非対角要素 数

perm int ** 置換ベク 含 長さ n 配列へ イ

ンタ

invp int ** 逆置換ベク 含 長さ n 配列へ

インタ

multifrontal_space int フロンタ 行列 タック た に必要 作

業用領域 大 さ チフロンタ 因子分 解が用い い場合 こ 値 ロに ッ さ

こ 構造体内 アロ ー さ た 解放す に 関数 imsl_free_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_RETURN_SYMBOLIC_FACTOR プ ン引数に説 明があ ます こ 構造体内 アロ ー さ た 解放す に 関数

imsl_free_symbolic_factor 使うこ IMSL_SYMBOLIC_FACTOR_ONLY,

入力行列 ン ック分解 計算し 戻 ます 引数 b 無視さ ます IMSL_RETURN_NUMERIC_FACTOR, Imsl_f_numeric_factor *num_factor 。出力)

戻 入力行列 数値的分解 含 Imsl_f_numeric_factor型 構造体へ インタ Imsl_f_numeric_factor構造体 詳細 次 通

パ ータ ータ型 説明

nzsub int ** Cholesky因子 非 ロ 非対角要素に対す 行指標

含 配列へ インタ こ 配列 長さ nz 割 当 が 配列 全 要素 使うこ い

xnzsub int ** nzsub に対す 指標 含 長さ n + 1 配列へ

インタ Cholesky因子 列 j にあ 非 ロ 要

素に対す 行指標 nzsub[xnzsub[j]]

連続領域に格納さ

xlnz int ** 長さ n + 1 配列へ インタ こ 配列

alnz 非 ロ 非対角要素 抽出す に使

わ 始 終わ 指標 含 因子行列 列 j

に対し alnz 始 終わ 指標 そ

xlnz[j] xlnz[j + 1] に格納さ

alnz float ** Cholesky因子 非 ロ 非対角要素 含

perm int ** 置換ベク 含 長さ n 配列へ インタ

diag float ** Cholesky因子 対角要素 含 長さ n 配列へ インタ

L A コ キー因子 し num_nonzeros L 非 ロ 数 します に述べた構

造体 L 対角要素 diag に格納さ ます L 非 ロ 非対角要素 alnzに格納さ

ます 列 j に対し alnz L 非 ロ要素 抽出す に使わ 始 終わ

指標 そ xlnz[j] xlnz[j+1] に格納さ ます L 非 ロ 要素 列イン

ック nzsub に含ま ます xnzsub[i] 列 i に対し L 行イン ック 抽出

す 始 nzsub イン ック 含 ます こ 次 コー 説明さ ます ここ

構造体 成分 因子行列L 下 角 再構築す や 方 示します:

Imsl_f_numeric_factor numfctr;

. . .

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

L[i][i] = (*numfctr.diag)[i];

if ((*numfctr.xlnz)[i] > (num_nonzeros-n)) continue;

start = (*numfctr.xlnz)[i]-1;

stop = (*numfctr.xlnz)[i+1]-1;

k = (*numfctr.xnzsub)[i]-1;

for (j = start; j < stop; j++){

L[(*numfctr.nzsub)[k]-1][i] = (*numfctr.alnz)[j];

k++;

} }

こ 構造体内 アロ ー さ た 解放す に 関数 imsl_f_free_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_RETURN_NUMERIC_FACTOR 説明さ

います

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 呼び出し 計算さ 場合

有効 す

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に ン 値 生成します:

PAP T = LL T ここ P 最小次数 並び えによ 決定さ 置換行列 す

数値的分解 2 方法 い 実行す こ が ます フ 疎 縮格納方式に基

い 標準 分解 行 います こ 方法 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 次によ 得 ます:

L y1

= Pb

LT y2

= y

1

x = PT y2

置換情報 P 数値因子構造体に保持さ ます

例題 1

例 し 次 5 × 5 係数行列 考えます













50 5 0 3 2

5 40 4 0 0

0 4 30 0 1

3 0 0 20 0

2 0 1 0 10 a

Ax = (55, 83, 103, 97, 82)T に ように xT = (5, 4, 3, 2, 1) します A 下 角 非 ロ 数 nz

= 10 す 下 角 疎 標対応形式 次 ように ます:

行 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

#include <imsl.h>

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

imsl_free (x);

}

出力

solution

1 2 3 4 5

5 4 3 2 1

例題 2

こ 例題 A A = E(2500, 50) します 方程式 Ax = b1 解 そこ 数値的分解 返しま

す 計算さ たこ 数値的分解 使用し 方程式 Ax = b2 解 ます また 実行時間 比率がプ ン さ ます こ 時間 測定結果 ンに強く依存す こ に注意し 下さい

#include <imsl.h>

#include <stdio.h>

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

/* Generate two right hand sides */

b_1 = imsl_f_random_uniform (n*sizeof(*b_1), 0);

b_2 = imsl_f_random_uniform (n*sizeof(*b_2), 0);

/* Build coefficient matrix a */

a = imsl_f_generate_test_coordinate (n, ic, &nz, IMSL_SYMMETRIC_STORAGE,

0);

/* Now solve Ax_1 = b_1 and return the numeric factorization */

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;

/* Now solve Ax_2 = b_2 given the numeric factorization */

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