Keyword: ヘッセンベルグ, シュール分解
概要
本サンプルは一般化上ヘッセンベルグ形の固有値の算出、または一般化シュール分解を行うC言語によるサンプルプログラムです。 本サンプルは以下に示される行列のペアに対して一般化上ヘッセンベルグ形の固有値を求めて出力します。
※本サンプルはnAG Cライブラリに含まれる関数 nag_dhgeqz() のExampleコードです。本サンプル及び関数の詳細情報は nag_dhgeqz のマニュアルページをご参照ください。
ご相談やお問い合わせはこちらまで
入力データ
(本関数の詳細はnag_dhgeqz のマニュアルページを参照)| このデータをダウンロード |
nag_dhgeqz (f08xec) Example Program Data 5 :Value of N 1.00 1.00 1.00 1.00 1.00 2.00 4.00 8.00 16.00 32.00 3.00 9.00 27.00 81.00 243.00 4.00 16.00 64.00 256.00 1024.00 5.00 25.00 125.00 625.00 3125.00 :End of matrix A 1.00 2.00 3.00 4.00 5.00 1.00 4.00 9.00 16.00 25.00 1.00 8.00 27.00 64.00 125.00 1.00 16.00 81.00 256.00 625.00 1.00 32.00 243.00 1024.00 3125.00 :End of matrix B
- 1行目はタイトル行で読み飛ばされます。
- 2行目に行列A、B、Q、Zの次数(n)を指定しています。
- 3〜7行目に行列Aの要素を指定しています。
- 8〜12行目に行列Bの要素を指定しています。
出力結果
(本関数の詳細はnag_dhgeqz のマニュアルページを参照)| この出力例をダウンロード |
nag_dhgeqz (f08xec) Example Program Results
Matrix A after balancing
1 2 3 4 5
1 1.0000 1.0000 0.1000 0.1000 0.1000
2 2.0000 4.0000 0.8000 1.6000 3.2000
3 0.3000 0.9000 0.2700 0.8100 2.4300
4 0.4000 1.6000 0.6400 2.5600 10.2400
5 0.5000 2.5000 1.2500 6.2500 31.2500
Matrix B after balancing
1 2 3 4 5
1 1.0000 2.0000 0.3000 0.4000 0.5000
2 1.0000 4.0000 0.9000 1.6000 2.5000
3 0.1000 0.8000 0.2700 0.6400 1.2500
4 0.1000 1.6000 0.8100 2.5600 6.2500
5 0.1000 3.2000 2.4300 10.2400 31.2500
Matrix A in Hessenberg form
1 2 3 4 5
1 -2.1898 -0.3181 2.0547 4.7371 -4.6249
2 -0.8395 -0.0426 1.7132 7.5194 -17.1850
3 0.0000 -0.2846 -1.0101 -7.5927 26.4499
4 0.0000 0.0000 0.0376 1.4070 -3.3643
5 0.0000 0.0000 0.0000 0.3813 -0.9937
Matrix B is triangular
1 2 3 4 5
1 -1.4248 -0.3476 2.1175 5.5813 -3.9269
2 0.0000 -0.0782 0.1189 8.0940 -15.2928
3 0.0000 0.0000 1.0021 -10.9356 26.5971
4 0.0000 0.0000 0.0000 0.5820 -0.0730
5 0.0000 0.0000 0.0000 0.0000 0.5321
Generalized eigenvalues
1 ( -2.437, 0.000)
2 ( 0.607, 0.795)
3 ( 0.607, -0.795)
4 ( 1.000, 0.000)
5 ( -0.410, 0.000)
- 5〜10行目にバランス化された後の行列Aが出力されています。
- 14〜196行目にバランス化された後の行列Bが出力されています。
- 23〜28行目にヘッセンベルグ形の行列Aが出力されています。
- 32〜37行目に三角行列Bが出力されています。
- 40〜44行目に一般化固有値が出力されています。
ソースコード
(本関数の詳細はnag_dhgeqz のマニュアルページを参照)
※本サンプルソースコードはnAG数値計算ライブラリ(Windows, Linux, MAC等に対応)の関数を呼び出します。
サンプルのコンパイル及び実行方法
| このソースコードをダウンロード |
/* nag_dhgeqz (f08xec) Example Program.
*
* CLL6I261D/CLL6I261DL Version.
*
* Copyright 2017 Numerical Algorithms Group.
*
* Mark 26.1, 2017.
*/
#include <stdio.h>
#include <nag.h>
#include <nag_stdlib.h>
#include <nagf08.h>
#include <nagx04.h>
int main(void)
{
/* Scalars */
Integer i, ihi, ilo, irows, j, n, pda, pdb;
Integer alpha_len, beta_len, scale_len, tau_len;
Integer exit_status = 0;
NagError fail;
Nag_OrderType order;
/* Arrays */
double *a = 0, *alphai = 0, *alphar = 0, *b = 0, *beta = 0;
double *lscale = 0, *q = 0, *rscale = 0, *tau = 0, *z = 0;
#ifdef nAG_COLUMN_MAJOR
#define A(I, J) a[(J-1)*pda + I - 1]
#define B(I, J) b[(J-1)*pdb + I - 1]
order = Nag_ColMajor;
#else
#define A(I, J) a[(I-1)*pda + J - 1]
#define B(I, J) b[(I-1)*pdb + J - 1]
order = Nag_RowMajor;
#endif
INIT_FAIL(fail);
printf("nag_dhgeqz (f08xec) Example Program Results\n\n");
/* Skip heading in data file */
scanf("%*[^\n] ");
scanf("%ld%*[^\n] ", &n);
pda = n;
pdb = n;
alpha_len = n;
beta_len = n;
scale_len = n;
tau_len = n;
/* Allocate memory */
if (!(a = nAG_ALLOC(n * n, double)) ||
!(alphai = nAG_ALLOC(alpha_len, double)) ||
!(alphar = nAG_ALLOC(alpha_len, double)) ||
!(b = nAG_ALLOC(n * n, double)) ||
!(beta = nAG_ALLOC(beta_len, double)) ||
!(lscale = nAG_ALLOC(scale_len, double)) ||
!(q = nAG_ALLOC(1 * 1, double)) ||
!(rscale = nAG_ALLOC(scale_len, double)) ||
!(tau = nAG_ALLOC(tau_len, double)) || !(z = nAG_ALLOC(1 * 1, double)))
{
printf("Allocation failure\n");
exit_status = -1;
goto END;
}
/* READ matrix A from data file */
for (i = 1; i <= n; ++i) {
for (j = 1; j <= n; ++j)
scanf("%lf", &A(i, j));
}
scanf("%*[^\n] ");
/* READ matrix B from data file */
for (i = 1; i <= n; ++i) {
for (j = 1; j <= n; ++j)
scanf("%lf", &B(i, j));
}
scanf("%*[^\n] ");
/* Balance matrix pair (A,B) */
/* nag_dggbal (f08whc).
* Balance a pair of real general matrices
*/
nag_dggbal(order, Nag_DoBoth, n, a, pda, b, pdb, &ilo, &ihi, lscale,
rscale, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_dggbal (f08whc).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
/* Matrix A after balancing */
/* nag_gen_real_mat_print (x04cac).
* Print real general matrix (easy-to-use)
*/
fflush(stdout);
nag_gen_real_mat_print(order, Nag_GeneralMatrix, Nag_NonUnitDiag, n, n, a,
pda, "Matrix A after balancing", 0, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_gen_real_mat_print (x04cac).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
printf("\n");
/* Matrix B after balancing */
/* nag_gen_real_mat_print (x04cac), see above. */
fflush(stdout);
nag_gen_real_mat_print(order, Nag_GeneralMatrix, Nag_NonUnitDiag, n, n, b,
pdb, "Matrix B after balancing", 0, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_gen_real_mat_print (x04cac).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
printf("\n");
/* Reduce B to triangular form using QR */
irows = ihi + 1 - ilo;
/* nag_dgeqrf (f08aec).
* QR factorization of real general rectangular matrix
*/
nag_dgeqrf(order, irows, irows, &B(ilo, ilo), pdb, tau, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_dgeqrf (f08aec).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
/* Apply the orthogonal transformation to matrix A */
/* nag_dormqr (f08agc).
* Apply orthogonal transformation determined by nag_dgeqrf
* (f08aec) or nag_dgeqpf (f08bec)
*/
nag_dormqr(order, Nag_LeftSide, Nag_Trans, irows, irows, irows,
&B(ilo, ilo), pdb, tau, &A(ilo, ilo), pda, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_dormqr (f08agc).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
/* Compute the generalized Hessenberg form of (A,B) */
/* nag_dgghd3 (f08wfc).
* Orthogonal reduction of a pair of real general matrices
* to generalized upper Hessenberg form
*/
nag_dgghd3(order, Nag_NotQ, Nag_NotZ, irows, 1, irows, &A(ilo, ilo), pda,
&B(ilo, ilo), pdb, q, 1, z, 1, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_dgghd3 (f08wfc).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
/* Matrix A in generalized Hessenberg form */
/* nag_gen_real_mat_print (x04cac), see above. */
fflush(stdout);
nag_gen_real_mat_print(order, Nag_GeneralMatrix, Nag_NonUnitDiag, n, n, a,
pda, "Matrix A in Hessenberg form", 0, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_gen_real_mat_print (x04cac).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
printf("\n");
/* Matrix B in generalized Hessenberg form */
/* nag_gen_real_mat_print (x04cac), see above. */
fflush(stdout);
nag_gen_real_mat_print(order, Nag_GeneralMatrix, Nag_NonUnitDiag, n, n, b,
pdb, "Matrix B is triangular", 0, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_gen_real_mat_print (x04cac).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
/* Compute the generalized Schur form */
/* nag_dhgeqz (f08xec).
* Eigenvalues and generalized Schur factorization of real
* generalized upper Hessenberg form reduced from a pair of
* real general matrices
*/
nag_dhgeqz(order, Nag_EigVals, Nag_NotQ, Nag_NotZ, n, ilo, ihi, a, pda,
b, pdb, alphar, alphai, beta, q, 1, z, 1, &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_dhgeqz (f08xec).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
/* Print the generalized eigenvalues */
printf("\n Generalized eigenvalues\n");
for (i = 1; i <= n; ++i) {
if (beta[i - 1] != 0.0) {
printf(" %4ld (%7.3f,%7.3f)\n", i,
alphar[i - 1] / beta[i - 1], alphai[i - 1] / beta[i - 1]);
}
else
printf(" %4ldEigenvalue is infinite\n", i);
}
END:
nAG_FREE(a);
nAG_FREE(alphai);
nAG_FREE(alphar);
nAG_FREE(b);
nAG_FREE(beta);
nAG_FREE(lscale);
nAG_FREE(q);
nAG_FREE(rscale);
nAG_FREE(tau);
nAG_FREE(z);
return exit_status;
}
