Keyword: 実一般行列, 特異値主要項
概要
本サンプルは実一般行列の特異値主要項を求めるC言語によるサンプルプログラムです。 本サンプルは2次元カーネルが以下の式で示される場合の有限差分の離散化から得られる100x500の実行列の最大特異値4つを求めて出力します。
※本サンプルはnAG Cライブラリに含まれる関数 nag_real_partial_svd() のExampleコードです。本サンプル及び関数の詳細情報は nag_real_partial_svd のマニュアルページをご参照ください。
ご相談やお問い合わせはこちらまで
入力データ
(本関数の詳細はnag_real_partial_svd のマニュアルページを参照)このデータをダウンロード |
nag_real_partial_svd (f02wgc) Example Program Data 100 500 4 10 : Values for m n nev and ncv
- 1行目はタイトル行で読み飛ばされます。
- 2行目に行列Aの行数(m)、列数(n)、特異値の数(nev)、特異値と残差の配列の次数(ncv)を指定しています。
出力結果
(本関数の詳細はnag_real_partial_svd のマニュアルページを参照)この出力例をダウンロード |
nag_real_partial_svd (f02wgc) Example Program Results (User-supplied callback av, first invocation.) Singular Value Residual 0.00830 3.6e-18 0.01223 8.2e-18 0.02381 4.7e-18 0.11274 2.5e-17
- 4〜7行目に特異値と残差が出力されています。
ソースコード
(本関数の詳細はnag_real_partial_svd のマニュアルページを参照)
※本サンプルソースコードはnAG数値計算ライブラリ(Windows, Linux, MAC等に対応)の関数を呼び出します。
サンプルのコンパイル及び実行方法
このソースコードをダウンロード |
/* nag_real_partial_svd (f02wgc) Example Program. * * CLL6I261D/CLL6I261DL Version. * * Copyright 2017 Numerical Algorithms Group. * * Mark 26.1, 2017. */ /* Pre-processor includes */ #include <stdio.h> #include <math.h> #include <nag.h> #include <nag_stdlib.h> #include <nagf02.h> #ifdef __cplusplus extern "C" { #endif static void nAG_CALL av(Integer *iflag, Integer m, Integer n, const double x[], double ax[], Nag_Comm *comm); #ifdef __cplusplus } #endif int main(void) { /*Integer scalar and array declarations */ Integer exit_status = 0; Integer i, m, n, nconv, ncv, nev; Integer pdu, pdv; Nag_Comm comm; NagError fail; /*Double scalar and array declarations */ static double ruser[1] = { -1.0 }; double *resid = 0, *sigma = 0, *u = 0, *v = 0; Nag_OrderType order; INIT_FAIL(fail); printf("nag_real_partial_svd (f02wgc) Example Program Results\n\n"); /* For communication with user-supplied functions: */ comm.user = ruser; /* Skip heading in data file */ scanf("%*[^\n] "); scanf("%ld%ld%ld%ld%*[^\n]", &m, &n, &nev, &ncv); #ifdef nAG_COLUMN_MAJOR order = Nag_ColMajor; pdu = m; pdv = n; #else order = Nag_RowMajor; pdu = ncv; pdv = ncv; #endif if (!(resid = nAG_ALLOC(m, double)) || !(sigma = nAG_ALLOC(ncv, double)) || !(u = nAG_ALLOC(m * ncv, double)) || !(v = nAG_ALLOC(n * ncv, double))) { printf("Allocation failure\n"); exit_status = -1; goto END; } /* * nag_real_partial_svd (f02wgc) * Computes leading terms in the singular value decomposition of * a real general matrix; also computes corresponding left and right * singular vectors. */ nag_real_partial_svd(order, m, n, nev, ncv, av, &nconv, sigma, u, pdu, v, pdv, resid, &comm, &fail); if (fail.code != NE_NOERROR) { printf("Error from nag_real_partial_svd (f02wgc).\n%s\n", fail.message); exit_status = 1; goto END; } /* Print computed residuals */ printf("%s\n", " Singular Value Residual"); for (i = 0; i < nconv; i++) printf("%10.5f %16.2g\n", sigma[i], resid[i]); printf("\n"); END: nAG_FREE(resid); nAG_FREE(sigma); nAG_FREE(u); nAG_FREE(v); return exit_status; } static void nAG_CALL av(Integer *iflag, Integer m, Integer n, const double x[], double ax[], Nag_Comm *comm) { Integer i, j; double one = 1.0, zero = 0.0; double h, k, s, t; /* Matrix vector multiply: w <- A*x or w <- Trans(A)*x. */ if (comm->user[0] == -1.0) { printf("(User-supplied callback av, first invocation.)\n"); comm->user[0] = 0.0; } h = one / (double) (m + 1); k = one / (double) (n + 1); if (*iflag == 1) { for (i = 0; i < m; i++) ax[i] = zero; t = zero; for (j = 0; j < n; j++) { t = t + k; s = zero; for (i = 0; i < MIN(j + 1, m); i++) { s = s + h; ax[i] = ax[i] + k * s * (t - one) * x[j]; } for (i = j + 1; i < m; i++) { s = s + h; ax[i] = ax[i] + k * t * (s - one) * x[j]; } } } else { for (i = 0; i < n; i++) ax[i] = zero; t = zero; for (j = 0; j < n; j++) { t = t + k; s = zero; for (i = 0; i < MIN(j + 1, m); i++) { s = s + h; ax[j] = ax[j] + k * s * (t - one) * x[i]; } for (i = j + 1; i < m; i++) { s = s + h; ax[j] = ax[j] + k * t * (s - one) * x[i]; } } } return; }