Keyword: スパース, 不完全コレスキー分解
概要
本サンプルは実スパース対称行列の不完全コレスキー分解を行うC言語によるサンプルプログラムです。 本サンプルは実スパース対称行列Aを読み込み、不完全コレスキー分解を計算し、行列Aと以下に示される下三角行列Cの非ゼロ要素を出力します。
※本サンプルはnAG Cライブラリに含まれる関数 nag_sparse_sym_chol_fac() のExampleコードです。本サンプル及び関数の詳細情報は nag_sparse_sym_chol_fac のマニュアルページをご参照ください。
ご相談やお問い合わせはこちらまで
入力データ
(本関数の詳細はnag_sparse_sym_chol_fac のマニュアルページを参照)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
このデータをダウンロード |
nag_sparse_sym_chol_fac (f11jac) Example Program Data 7 n 16 nnz 0 0.0 lfill, dtol Nag_SparseSym_UnModFact 0.0 mic, dscale Nag_SparseSym_MarkPiv pstrat 4. 1 1 1. 2 1 5. 2 2 2. 3 3 2. 4 2 3. 4 4 -1. 5 1 1. 5 4 4. 5 5 1. 6 2 -2. 6 5 3. 6 6 2. 7 1 -1. 7 2 -2. 7 3 5. 7 7 a[i-1], irow[i-1], icol[i-1], i=1,...,nnz
- 1行目はタイトル行で読み飛ばされます。
- 2行目に行列Aの次数(n)を指定しています。
- 3行目に行列Aの下三角部分の非ゼロ要素の数(nnz)を指定しています。
- 4行目の1番目のパラメータ(lfill)は値が0以上の場合、コレスキー分解で許されたフィル(fill)の最大レベルを指定しています。2番目のパラメータ(dtol)は、1番目のパラメータの値が負の値の場合、フィルイン(fill-in)を制御するためのドロップ許容値を指定しています。1番目のパラメータの値が0以上の場合は2番目のパラメータの値は参照されません。
- 5行目には行の合計を保持するためにコレスキー分解が修正されるかどうかを示すフラグ(mic)と対角スケーリング引数(dscale)を指定しています。 "Nag_SparseSym_UnModFact"はコレスキー分解が修正されないことを意味します。
- 6行目にピボット法(pstrat)を指定しています。"Nag_SparseSym_MarkPiv"はMarkowitz法を用いて対角ピボットが実行されることを意味します。
- 7~22行目に行列Aの非ゼロ要素(a)、行列Aの非ゼロ要素の行インデックス(irow)、列インデックス(icol)を指定しています。
出力結果
(本関数の詳細はnag_sparse_sym_chol_fac のマニュアルページを参照)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
この出力例をダウンロード |
nag_sparse_sym_chol_fac (f11jac) Example Program Results Original Matrix n = 7 nnz = 16 1 4.0000e+00 1 1 2 1.0000e+00 2 1 3 5.0000e+00 2 2 4 2.0000e+00 3 3 5 2.0000e+00 4 2 6 3.0000e+00 4 4 7 -1.0000e+00 5 1 8 1.0000e+00 5 4 9 4.0000e+00 5 5 10 1.0000e+00 6 2 11 -2.0000e+00 6 5 12 3.0000e+00 6 6 13 2.0000e+00 7 1 14 -1.0000e+00 7 2 15 -2.0000e+00 7 3 16 5.0000e+00 7 7 Factorization n = 7 nnz = 16 npivm = 0 17 5.0000e-01 1 1 18 3.3333e-01 2 2 19 3.3333e-01 3 2 20 2.7273e-01 3 3 21 -5.4545e-01 4 3 22 5.2381e-01 4 4 23 -2.7273e-01 5 3 24 2.6829e-01 5 5 25 6.6667e-01 6 2 26 5.2381e-01 6 4 27 2.6829e-01 6 5 28 3.4788e-01 6 6 29 -1.0000e+00 7 1 30 5.3659e-01 7 5 31 -5.3455e-01 7 6 32 9.0461e-01 7 7 i ipiv(i) 1 3 2 4 3 5 4 6 5 1 6 2 7 7
- 3~22行目には元の行列の情報が出力されています。
- 4行目に行列Aの次数が出力されています。
- 5行目に行列Aの非ゼロ要素の数が出力されています。
- 7~22行目に行列Aの要素の値、行インデックスと列インデックスが出力されています。
- 24~44行目にはコレスキー分解して得られた行列の情報が出力されています。
- 25行目にコレスキー分解して得られた行列の次数が出力されています。
- 26行目にコレスキー分解して得られた行列の非ゼロ要素の数が出力されています。
- 27行目にコレスキー分解で修正されたピボットの数が出力されています。
- 29~44行目にコレスキー分解して得られた下三角行列Cの要素の値、行インデックスと列インデックスが出力されています。
- 47~53行目にピボットインデックスが出力されています。
ソースコード
(本関数の詳細はnag_sparse_sym_chol_fac のマニュアルページを参照)
※本サンプルソースコードはnAG数値計算ライブラリ(Windows, Linux, MAC等に対応)の関数を呼び出します。
サンプルのコンパイル及び実行方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
このソースコードをダウンロード |
/* nag_sparse_sym_chol_fac (f11jac) Example Program. * * CLL6I261D/CLL6I261DL Version. * * Copyright 2017 Numerical Algorithms Group. * * Mark 26.1, 2017. * */ #include <nag.h> #include <stdio.h> #include <nag_stdlib.h> #include <nag_string.h> #include <nagf11.h> int main(void) { double dtol; double *a; double dscale; Integer *irow, *icol; Integer *ipiv, nnzc, *istr; Integer exit_status = 0, i, n, lfill, npivm; Integer nnz; Integer num; char nag_enum_arg[40]; Nag_SparseSym_Piv pstrat; Nag_SparseSym_Fact mic; Nag_Sparse_Comm comm; NagError fail; INIT_FAIL(fail); printf("nag_sparse_sym_chol_fac (f11jac) Example Program Results\n\n"); /* Skip heading in data file */ scanf("%*[^\n]"); /* Read algorithmic parameters */ scanf("%ld", &n); scanf("%*[^\n]"); scanf("%ld%*[^\n]", &nnz); scanf("%ld%lf%*[^\n]", &lfill, &dtol); scanf("%39s%lf%*[^\n]", nag_enum_arg, &dscale); /* nag_enum_name_to_value (x04nac). * Converts nAG enum member name to value */ mic = (Nag_SparseSym_Fact) nag_enum_name_to_value(nag_enum_arg); scanf("%39s%*[^\n]", nag_enum_arg); pstrat = (Nag_SparseSym_Piv) nag_enum_name_to_value(nag_enum_arg); /* Allocate memory */ num = 2 * nnz; ipiv = nAG_ALLOC(n, Integer); istr = nAG_ALLOC(n + 1, Integer); irow = nAG_ALLOC(num, Integer); icol = nAG_ALLOC(num, Integer); a = nAG_ALLOC(num, double); if (!ipiv || !istr || !irow || !icol || !a) { printf("Allocation failure\n"); exit_status = -1; goto END; } /* Read the matrix a */ for (i = 1; i <= nnz; ++i) scanf("%lf%ld%ld%*[^\n]", &a[i - 1], &irow[i - 1], &icol[i - 1]); /* Calculate incomplete Cholesky factorization */ /* nag_sparse_sym_chol_fac (f11jac). * Incomplete Cholesky factorization (symmetric) */ nag_sparse_sym_chol_fac(n, nnz, &a, &num, &irow, &icol, lfill, dtol, mic, dscale, pstrat, ipiv, istr, &nnzc, &npivm, &comm, &fail); if (fail.code != NE_NOERROR) { printf("Error from nag_sparse_sym_chol_fac (f11jac).\n%s\n", fail.message); exit_status = 1; goto END; } /* Output original matrix */ printf(" Original Matrix \n"); printf(" n = %6ld\n", n); printf(" nnz = %6ld\n\n", nnz); for (i = 1; i <= nnz; ++i) printf(" %8ld%16.4e%8ld%8ld\n", i, a[i - 1], irow[i - 1], icol[i - 1]); printf("\n"); /* Output details of the factorization */ printf(" Factorization\n n = %6ld \n nnz = %6ld\n", n, nnzc); printf(" npivm = %6ld\n\n", npivm); for (i = nnz + 1; i <= nnz + nnzc; ++i) printf(" %8ld%16.4e%8ld%8ld\n", i, a[i - 1], irow[i - 1], icol[i - 1]); printf("\n i ipiv(i) \n"); for (i = 1; i <= n; ++i) printf(" %8ld%8ld\n", i, ipiv[i - 1]); END: nAG_FREE(irow); nAG_FREE(icol); nAG_FREE(a); nAG_FREE(istr); nAG_FREE(ipiv); return exit_status; }