| 情報学部 | 菅沼ホーム | 目次 | 索引 |
/****************************************/
/* 最大固有値と固有ベクトル(べき乗法) */
/* coded by Y.Suganuma */
/****************************************/
#include <stdio.h>
int power(int, int, int, int, double, double **, double **, double **,
double *, double **, double *, double *, double *);
int main()
{
double **A, **B, **C, *r, **v, *v0, *v1, *v2, eps;
int i1, i2, ind, ct, m, n;
// データの設定
ct = 200;
eps = 1.0e-10;
n = 3;
m = 15;
A = new double * [n];
B = new double * [n];
C = new double * [n];
v = new double * [n];
for (i1 = 0; i1 < n; i1++) {
A[i1] = new double [n];
B[i1] = new double [n];
C[i1] = new double [n];
v[i1] = new double [n];
}
r = new double [n];
v0 = new double [n];
v1 = new double [n];
v2 = new double [n];
A[0][0] = 11.0;
A[0][1] = 6.0;
A[0][2] = -2.0;
A[1][0] = -2.0;
A[1][1] = 18.0;
A[1][2] = 1.0;
A[2][0] = -12.0;
A[2][1] = 24.0;
A[2][2] = 13.0;
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < n; i2++)
B[i1][i2] = 0.0;
B[i1][i1] = 1.0;
v0[i1] = 1.0;
}
// 計算
ind = power(0, n, m, ct, eps, A, B, C, r, v, v0, v1, v2);
// 出力
if (ind == 0)
printf("固有値が求まりませんでした!\n");
else {
for (i1 = 0; i1 < ind; i1++) {
printf("固有値 %f", r[i1]);
printf(" 固有ベクトル ");
for (i2 = 0; i2 < n; i2++)
printf(" %f", v[i1][i2]);
printf("\n");
}
}
for (i1 = 0; i1 < n; i1++) {
delete [] A[i1];
delete [] B[i1];
delete [] C[i1];
delete [] v[i1];
}
delete [] A;
delete [] B;
delete [] C;
delete [] v;
delete [] r;
delete [] v0;
delete [] v1;
delete [] v2;
return 0;
}
/****************************************/
/* 最大固有値と固有ベクトル(べき乗法) */
/* i : 何番目の固有値かを示す */
/* n : 次数 */
/* m : 丸め誤差の修正回数 */
/* ct : 最大繰り返し回数 */
/* eps : 収束判定条件 */
/* A : 対象とする行列 */
/* B : nxnの行列,最初は,単位行列 */
/* C : 作業域,nxnの行列 */
/* r : 固有値 */
/* v : 各行が固有ベクトル(nxn) */
/* v0 : 固有ベクトルの初期値 */
/* v1,v2 : 作業域(n次元ベクトル) */
/* return : 求まった固有値の数 */
/* coded by Y.Suganuma */
/****************************************/
#include <math.h>
int power(int i, int n, int m, int ct, double eps, double **A, double **B,
double **C, double *r, double **v, double *v0, double *v1, double *v2)
{
double l1, l2, x;
int i1, i2, i3, ind, k, k1;
// 初期設定
ind = i;
k = 0;
l1 = 0.0;
for (i1 = 0; i1 < n; i1++) {
l1 += v0[i1] * v0[i1];
v1[i1] = v0[i1];
}
l1 = sqrt(l1);
// 繰り返し計算
while (k < ct) {
// 丸め誤差の修正
if (k%m == 0) {
l2 = 0.0;
for (i1 = 0; i1 < n; i1++) {
v2[i1] = 0.0;
for (i2 = 0; i2 < n; i2++)
v2[i1] += B[i1][i2] * v1[i2];
l2 += v2[i1] * v2[i1];
}
l2 = sqrt(l2);
for (i1 = 0; i1 < n; i1++)
v1[i1] = v2[i1] / l2;
}
// 次の近似
l2 = 0.0;
for (i1 = 0; i1 < n; i1++) {
v2[i1] = 0.0;
for (i2 = 0; i2 < n; i2++)
v2[i1] += A[i1][i2] * v1[i2];
l2 += v2[i1] * v2[i1];
}
l2 = sqrt(l2);
for (i1 = 0; i1 < n; i1++)
v2[i1] /= l2;
// 収束判定
// 収束した場合
if (fabs((l2-l1)/l1) < eps) {
k1 = -1;
for (i1 = 0; i1 < n && k1 < 0; i1++) {
if (fabs(v2[i1]) > 0.001) {
k1 = i1;
if (v2[k1]*v1[k1] < 0.0)
l2 = -l2;
}
}
k = ct;
r[i] = l2;
for (i1 = 0; i1 < n; i1++)
v[i][i1] = v2[i1];
if (i == n-1)
ind = i + 1;
else {
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < n; i2++) {
C[i1][i2] = 0.0;
for (i3 = 0; i3 < n; i3++) {
x = (i1 == i3) ? A[i1][i3] - l2 : A[i1][i3];
C[i1][i2] += x * B[i3][i2];
}
}
}
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < n; i2++)
B[i1][i2] = C[i1][i2];
}
for (i1 = 0; i1 < n; i1++) {
v1[i1] = 0.0;
for (i2 = 0; i2 < n; i2++)
v1[i1] += B[i1][i2] * v0[i2];
}
for (i1 = 0; i1 < n; i1++)
v0[i1] = v1[i1];
ind = power(i+1, n, m, ct, eps, A, B, C, r, v, v0, v1, v2);
}
}
// 収束しない場合
else {
for (i1 = 0; i1 < n; i1++)
v1[i1] = v2[i1];
l1 = l2;
k++;
}
}
return ind;
}
/****************************************/
/* 最大固有値と固有ベクトル(べき乗法) */
/* coded by Y.Suganuma */
/****************************************/
import java.io.*;
public class Test {
public static void main(String args[]) throws IOException
{
double A[][], B[][], C[][], r[], v[][], v0[], v1[], v2[], eps;
int i1, i2, ind, ct, m, n;
// データの設定
ct = 200;
eps = 1.0e-10;
n = 3;
m = 15;
A = new double [n][n];
B = new double [n][n];
C = new double [n][n];
v = new double [n][n];
r = new double [n];
v0 = new double [n];
v1 = new double [n];
v2 = new double [n];
A[0][0] = 11.0;
A[0][1] = 6.0;
A[0][2] = -2.0;
A[1][0] = -2.0;
A[1][1] = 18.0;
A[1][2] = 1.0;
A[2][0] = -12.0;
A[2][1] = 24.0;
A[2][2] = 13.0;
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < n; i2++)
B[i1][i2] = 0.0;
B[i1][i1] = 1.0;
v0[i1] = 1.0;
}
// 計算
ind = power(0, n, m, ct, eps, A, B, C, r, v, v0, v1, v2);
// 出力
if (ind == 0)
System.out.println("固有値が求まりませんでした!");
else {
for (i1 = 0; i1 < ind; i1++) {
System.out.print("固有値 " + r[i1]);
System.out.print(" 固有ベクトル ");
for (i2 = 0; i2 < n; i2++)
System.out.print(" " + v[i1][i2]);
System.out.println();
}
}
}
/****************************************/
/* 最大固有値と固有ベクトル(べき乗法) */
/* i : 何番目の固有値かを示す */
/* n : 次数 */
/* m : 丸め誤差の修正回数 */
/* ct : 最大繰り返し回数 */
/* eps : 収束判定条件 */
/* A : 対象とする行列 */
/* B : nxnの行列,最初は,単位行列 */
/* C : 作業域,nxnの行列 */
/* r : 固有値 */
/* v : 各行が固有ベクトル(nxn) */
/* v0 : 固有ベクトルの初期値 */
/* v1,v2 : 作業域(n次元ベクトル) */
/* return : 求まった固有値の数 */
/* coded by Y.Suganuma */
/****************************************/
static int power(int i, int n, int m, int ct, double eps, double A[][], double B[][],
double C[][], double r[], double v[][], double v0[], double v1[], double v2[])
{
double l1, l2, x;
int i1, i2, i3, ind, k, k1;
// 初期設定
ind = i;
k = 0;
l1 = 0.0;
for (i1 = 0; i1 < n; i1++) {
l1 += v0[i1] * v0[i1];
v1[i1] = v0[i1];
}
l1 = Math.sqrt(l1);
// 繰り返し計算
while (k < ct) {
// 丸め誤差の修正
if (k%m == 0) {
l2 = 0.0;
for (i1 = 0; i1 < n; i1++) {
v2[i1] = 0.0;
for (i2 = 0; i2 < n; i2++)
v2[i1] += B[i1][i2] * v1[i2];
l2 += v2[i1] * v2[i1];
}
l2 = Math.sqrt(l2);
for (i1 = 0; i1 < n; i1++)
v1[i1] = v2[i1] / l2;
}
// 次の近似
l2 = 0.0;
for (i1 = 0; i1 < n; i1++) {
v2[i1] = 0.0;
for (i2 = 0; i2 < n; i2++)
v2[i1] += A[i1][i2] * v1[i2];
l2 += v2[i1] * v2[i1];
}
l2 = Math.sqrt(l2);
for (i1 = 0; i1 < n; i1++)
v2[i1] /= l2;
// 収束判定
// 収束した場合
if (Math.abs((l2-l1)/l1) < eps) {
k1 = -1;
for (i1 = 0; i1 < n && k1 < 0; i1++) {
if (Math.abs(v2[i1]) > 0.001) {
k1 = i1;
if (v2[k1]*v1[k1] < 0.0)
l2 = -l2;
}
}
k = ct;
r[i] = l2;
for (i1 = 0; i1 < n; i1++)
v[i][i1] = v2[i1];
if (i == n-1)
ind = i + 1;
else {
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < n; i2++) {
C[i1][i2] = 0.0;
for (i3 = 0; i3 < n; i3++) {
x = (i1 == i3) ? A[i1][i3] - l2 : A[i1][i3];
C[i1][i2] += x * B[i3][i2];
}
}
}
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < n; i2++)
B[i1][i2] = C[i1][i2];
}
for (i1 = 0; i1 < n; i1++) {
v1[i1] = 0.0;
for (i2 = 0; i2 < n; i2++)
v1[i1] += B[i1][i2] * v0[i2];
}
for (i1 = 0; i1 < n; i1++)
v0[i1] = v1[i1];
ind = power(i+1, n, m, ct, eps, A, B, C, r, v, v0, v1, v2);
}
}
// 収束しない場合
else {
for (i1 = 0; i1 < n; i1++)
v1[i1] = v2[i1];
l1 = l2;
k++;
}
}
return ind;
}
}
<!DOCTYPE HTML>
<HTML>
<HEAD>
<TITLE>最大固有値と固有ベクトル(べき乗法)</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<SCRIPT TYPE="text/javascript">
function main()
{
// データの設定
let eps = 1.0e-10;
let ct = parseInt(document.getElementById("trial").value);
let n = parseInt(document.getElementById("order").value);
let m = parseInt(document.getElementById("mod").value);
let A = new Array();
for (let i1 = 0; i1 < n; i1++)
A[i1] = new Array();
let s = (document.getElementById("ar").value).split(/ {1,}|\n{1,}/);
let k = 0;
for (let i1 = 0; i1 < n; i1++) {
for (let i2 = 0; i2 < n; i2++) {
A[i1][i2] = parseFloat(s[k]);
k++;
}
}
let B = new Array();
for (let i1 = 0; i1 < n; i1++) {
B[i1] = new Array();
for (let i2 = 0; i2 < n; i2++)
B[i1][i2] = 0.0;
B[i1][i1] = 1.0;
}
let C = new Array();
for (let i1 = 0; i1 < n; i1++)
C[i1] = new Array();
let v = new Array();
for (let i1 = 0; i1 < n; i1++)
v[i1] = new Array();
let r = new Array();
let v0 = (document.getElementById("init").value).split(/ {1,}/);
let v1 = new Array();
let v2 = new Array();
ind = power(0, n, m, ct, eps, A, B, C, r, v, v0, v1, v2);
// 出力
if (ind == 0)
document.getElementById("ans").value = "解を求めることができません!";
else {
let str = "";
for (let i1 = 0; i1 < ind; i1++) {
str = str + "固有値: " + r[i1] + "\n";
str = str + " 固有ベクトル:";
for (let i2 = 0; i2 < n; i2++) {
if (i2 == n-1)
str = str + v[i1][i2] + "\n";
else
str = str + v[i1][i2] + " ";
}
}
document.getElementById("ans").value = str;
}
}
/****************************************/
/* 最大固有値と固有ベクトル(べき乗法) */
/* i : 何番目の固有値かを示す */
/* n : 次数 */
/* m : 丸め誤差の修正回数 */
/* ct : 最大繰り返し回数 */
/* eps : 収束判定条件 */
/* A : 対象とする行列 */
/* B : nxnの行列,最初は,単位行列 */
/* C : 作業域,nxnの行列 */
/* r : 固有値 */
/* v : 各行が固有ベクトル(nxn) */
/* v0 : 固有ベクトルの初期値 */
/* v1,v2 : 作業域(n次元ベクトル) */
/* return : 求まった固有値の数 */
/* coded by Y.Suganuma */
/****************************************/
function power(i, n, m, ct, eps, A, B, C, r, v, v0, v1, v2)
{
let l1 = 0.0;
let l2;
let x;
let i1;
let i2;
let i3;
let ind = i;
let k = 0;
let k1;
// 初期設定
for (i1 = 0; i1 < n; i1++) {
l1 += v0[i1] * v0[i1];
v1[i1] = v0[i1];
}
l1 = Math.sqrt(l1);
// 繰り返し計算
while (k < ct) {
// 丸め誤差の修正
if (k%m == 0) {
l2 = 0.0;
for (i1 = 0; i1 < n; i1++) {
v2[i1] = 0.0;
for (i2 = 0; i2 < n; i2++)
v2[i1] += B[i1][i2] * v1[i2];
l2 += v2[i1] * v2[i1];
}
l2 = Math.sqrt(l2);
for (i1 = 0; i1 < n; i1++)
v1[i1] = v2[i1] / l2;
}
// 次の近似
l2 = 0.0;
for (i1 = 0; i1 < n; i1++) {
v2[i1] = 0.0;
for (i2 = 0; i2 < n; i2++)
v2[i1] += A[i1][i2] * v1[i2];
l2 += v2[i1] * v2[i1];
}
l2 = Math.sqrt(l2);
for (i1 = 0; i1 < n; i1++)
v2[i1] /= l2;
// 収束判定
// 収束した場合
if (Math.abs((l2-l1)/l1) < eps) {
k1 = -1;
for (i1 = 0; i1 < n && k1 < 0; i1++) {
if (Math.abs(v2[i1]) > 0.001) {
k1 = i1;
if (v2[k1]*v1[k1] < 0.0)
l2 = -l2;
}
}
k = ct;
r[i] = l2;
for (i1 = 0; i1 < n; i1++)
v[i][i1] = v2[i1];
if (i == n-1)
ind = i + 1;
else {
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < n; i2++) {
C[i1][i2] = 0.0;
for (i3 = 0; i3 < n; i3++) {
x = (i1 == i3) ? A[i1][i3] - l2 : A[i1][i3];
C[i1][i2] += x * B[i3][i2];
}
}
}
for (i1 = 0; i1 < n; i1++) {
for (i2 = 0; i2 < n; i2++)
B[i1][i2] = C[i1][i2];
}
for (i1 = 0; i1 < n; i1++) {
v1[i1] = 0.0;
for (i2 = 0; i2 < n; i2++)
v1[i1] += B[i1][i2] * v0[i2];
}
for (i1 = 0; i1 < n; i1++)
v0[i1] = v1[i1];
ind = power(i+1, n, m, ct, eps, A, B, C, r, v, v0, v1, v2);
}
}
// 収束しない場合
else {
for (i1 = 0; i1 < n; i1++)
v1[i1] = v2[i1];
l1 = l2;
k++;
}
}
return ind;
}
</SCRIPT>
</HEAD>
<BODY STYLE="font-size: 130%; background-color: #eeffee;">
<H2 STYLE="text-align:center"><B>最大固有値と固有ベクトル(べき乗法)</B></H2>
<DL>
<DT> テキストフィールドおよびテキストエリアには,例として,以下に示す行列の固有値及び固有ベクトル(固有ベクトルは,正規化されて表示)を求める場合に対する値が設定されています.他の問題を実行する場合は,それらを適切に修正してください.
<P STYLE="text-align:center"><IMG SRC="power.gif"></P>
</DL>
<DIV STYLE="text-align:center">
次数:<INPUT ID="order" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="3">
修正:<INPUT ID="mod" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="15">
最大繰り返し:<INPUT ID="trial" STYLE="font-size: 100%;" TYPE="text" SIZE="4" VALUE="200">
初期値:<INPUT ID="init" STYLE="font-size: 100%;" TYPE="text" SIZE="20" VALUE="1 1 1">
<BUTTON STYLE="font-size: 100%; background-color: pink" onClick="main()">OK</BUTTON><BR><BR>
<TEXTAREA ID="ar" COLS="50" ROWS="15" STYLE="font-size: 100%">11 6 -2
-2 18 1
-12 24 13</TEXTAREA><BR><BR>
<TEXTAREA ID="ans" COLS="80" ROWS="15" STYLE="font-size: 100%"></TEXTAREA>
</DIV>
</BODY>
</HTML>
<?php
/****************************************/
/* 最大固有値と固有ベクトル(べき乗法) */
/* coded by Y.Suganuma */
/****************************************/
// データの設定
$ct = 200;
$eps = 1.0e-10;
$n = 3;
$m = 15;
$A = array($n);
$B = array($n);
$C = array($n);
$v = array($n);
for ($i1 = 0; $i1 < $n; $i1++) {
$A[$i1] = array($n);
$B[$i1] = array($n);
$C[$i1] = array($n);
$v[$i1] = array($n);
}
$r = array($n);
$v0 = array($n);
$v1 = array($n);
$v2 = array($n);
$A[0][0] = 11.0;
$A[0][1] = 6.0;
$A[0][2] = -2.0;
$A[1][0] = -2.0;
$A[1][1] = 18.0;
$A[1][2] = 1.0;
$A[2][0] = -12.0;
$A[2][1] = 24.0;
$A[2][2] = 13.0;
for ($i1 = 0; $i1 < $n; $i1++) {
for ($i2 = 0; $i2 < $n; $i2++)
$B[$i1][$i2] = 0.0;
$B[$i1][$i1] = 1.0;
$v0[$i1] = 1.0;
}
// 計算
$ind = power(0, $n, $m, $ct, $eps, $A, $B, $C, $r, $v, $v0, $v1, $v2);
// 出力
if ($ind == 0)
printf("固有値が求まりませんでした!\n");
else {
for ($i1 = 0; $i1 < $ind; $i1++) {
printf("固有値 %f", $r[$i1]);
printf(" 固有ベクトル ");
for ($i2 = 0; $i2 < $n; $i2++)
printf(" %f", $v[$i1][$i2]);
printf("\n");
}
}
/****************************************/
/* 最大固有値と固有ベクトル(べき乗法) */
/* i : 何番目の固有値かを示す */
/* n : 次数 */
/* m : 丸め誤差の修正回数 */
/* ct : 最大繰り返し回数 */
/* eps : 収束判定条件 */
/* A : 対象とする行列 */
/* B : nxnの行列,最初は,単位行列 */
/* C : 作業域,nxnの行列 */
/* r : 固有値 */
/* v : 各行が固有ベクトル(nxn) */
/* v0 : 固有ベクトルの初期値 */
/* v1,v2 : 作業域(n次元ベクトル) */
/* return : 求まった固有値の数 */
/* coded by Y.Suganuma */
/****************************************/
function power($i, $n, $m, $ct, $eps, $A, $B, $C, &$r, &$v, $v0, $v1, $v2)
{
// 初期設定
$ind = $i;
$k = 0;
$l1 = 0.0;
for ($i1 = 0; $i1 < $n; $i1++) {
$l1 += $v0[$i1] * $v0[$i1];
$v1[$i1] = $v0[$i1];
}
$l1 = sqrt($l1);
// 繰り返し計算
while ($k < $ct) {
// 丸め誤差の修正
if ($k%$m == 0) {
$l2 = 0.0;
for ($i1 = 0; $i1 < $n; $i1++) {
$v2[$i1] = 0.0;
for ($i2 = 0; $i2 < $n; $i2++)
$v2[$i1] += $B[$i1][$i2] * $v1[$i2];
$l2 += $v2[$i1] * $v2[$i1];
}
$l2 = sqrt($l2);
for ($i1 = 0; $i1 < $n; $i1++)
$v1[$i1] = $v2[$i1] / $l2;
}
// 次の近似
$l2 = 0.0;
for ($i1 = 0; $i1 < $n; $i1++) {
$v2[$i1] = 0.0;
for ($i2 = 0; $i2 < $n; $i2++)
$v2[$i1] += $A[$i1][$i2] * $v1[$i2];
$l2 += $v2[$i1] * $v2[$i1];
}
$l2 = sqrt($l2);
for ($i1 = 0; $i1 < $n; $i1++)
$v2[$i1] /= $l2;
// 収束判定
// 収束した場合
if (abs(($l2-$l1)/$l1) < $eps) {
$k1 = -1;
for ($i1 = 0; $i1 < $n && $k1 < 0; $i1++) {
if (abs($v2[$i1]) > 0.001) {
$k1 = $i1;
if ($v2[$k1]*$v1[$k1] < 0.0)
$l2 = -$l2;
}
}
$k = $ct;
$r[$i] = $l2;
for ($i1 = 0; $i1 < $n; $i1++)
$v[$i][$i1] = $v2[$i1];
if ($i == $n-1)
$ind = $i + 1;
else {
for ($i1 = 0; $i1 < $n; $i1++) {
for ($i2 = 0; $i2 < $n; $i2++) {
$C[$i1][$i2] = 0.0;
for ($i3 = 0; $i3 < $n; $i3++) {
$x = ($i1 == $i3) ? $A[$i1][$i3] - $l2 : $A[$i1][$i3];
$C[$i1][$i2] += $x * $B[$i3][$i2];
}
}
}
for ($i1 = 0; $i1 < $n; $i1++) {
for ($i2 = 0; $i2 < $n; $i2++)
$B[$i1][$i2] = $C[$i1][$i2];
}
for ($i1 = 0; $i1 < $n; $i1++) {
$v1[$i1] = 0.0;
for ($i2 = 0; $i2 < $n; $i2++)
$v1[$i1] += $B[$i1][$i2] * $v0[$i2];
}
for ($i1 = 0; $i1 < $n; $i1++)
$v0[$i1] = $v1[$i1];
$ind = power($i+1, $n, $m, $ct, $eps, $A, $B, $C, $r, $v, $v0, $v1, $v2);
}
}
// 収束しない場合
else {
for ($i1 = 0; $i1 < $n; $i1++)
$v1[$i1] = $v2[$i1];
$l1 = $l2;
$k++;
}
}
return $ind;
}
?>
#***************************************/
# 最大固有値と固有ベクトル(べき乗法) */
# coded by Y.Suganuma */
#***************************************/
#***************************************/
# 最大固有値と固有ベクトル(べき乗法) */
# i : 何番目の固有値かを示す */
# n : 次数 */
# m : 丸め誤差の修正回数 */
# ct : 最大繰り返し回数 */
# eps : 収束判定条件 */
# a : 対象とする行列 */
# b : nxnの行列,最初は,単位行列 */
# c : 作業域,nxnの行列 */
# r : 固有値 */
# v : 各行が固有ベクトル(nxn) */
# v0 : 固有ベクトルの初期値 */
# v1,v2 : 作業域(n次元ベクトル) */
# return : 求まった固有値の数 */
# coded by Y.Suganuma */
#***************************************/
def power(i, n, m, ct, eps, a, b, c, r, v, v0, v1, v2)
# 初期設定
ind = i
k = 0
l1 = 0.0
for i1 in 0 ... n
l1 += v0[i1] * v0[i1]
v1[i1] = v0[i1]
end
l1 = Math.sqrt(l1)
# 繰り返し計算
while k < ct
# 丸め誤差の修正
if k%m == 0
l2 = 0.0
for i1 in 0 ... n
v2[i1] = 0.0
for i2 in 0 ... n
v2[i1] += b[i1][i2] * v1[i2]
end
l2 += v2[i1] * v2[i1]
end
l2 = Math.sqrt(l2)
for i1 in 0 ... n
v1[i1] = v2[i1] / l2
end
end
# 次の近似
l2 = 0.0
for i1 in 0 ... n
v2[i1] = 0.0
for i2 in 0 ... n
v2[i1] += a[i1][i2] * v1[i2]
end
l2 += v2[i1] * v2[i1]
end
l2 = Math.sqrt(l2)
for i1 in 0 ... n
v2[i1] /= l2
end
# 収束判定
# 収束した場合
if ((l2-l1)/l1).abs() < eps
k1 = -1
for i1 in 0 ... n
if v2[i1].abs() > 0.001
k1 = i1
if v2[k1]*v1[k1] < 0.0
l2 = -l2
end
end
if k1 >= 0
break
end
end
k = ct
r[i] = l2
for i1 in 0 ... n
v[i][i1] = v2[i1]
end
if i == n-1
ind = i + 1
else
for i1 in 0 ... n
for i2 in 0 ... n
c[i1][i2] = 0.0
for i3 in 0 ... n
x = (i1 == i3) ? a[i1][i3] - l2 : a[i1][i3]
c[i1][i2] += x * b[i3][i2]
end
end
end
for i1 in 0 ... n
for i2 in 0 ... n
b[i1][i2] = c[i1][i2]
end
end
for i1 in 0 ... n
v1[i1] = 0.0
for i2 in 0 ... n
v1[i1] += b[i1][i2] * v0[i2]
end
end
for i1 in 0 ... n
v0[i1] = v1[i1]
end
ind = power(i+1, n, m, ct, eps, a, b, c, r, v, v0, v1, v2)
end
# 収束しない場合
else
for i1 in 0 ... n
v1[i1] = v2[i1]
end
l1 = l2
k += 1
end
end
return ind
end
# データの設定
ct = 200
eps = 1.0e-10
n = 3
m = 15
a = Array.new(n)
b = Array.new(n)
c = Array.new(n)
v = Array.new(n)
for i1 in 0 ... n
a[i1] = Array.new(n)
b[i1] = Array.new(n)
c[i1] = Array.new(n)
v[i1] = Array.new(n)
end
r = Array.new(n)
v0 = Array.new(n)
v1 = Array.new(n)
v2 = Array.new(n)
a[0][0] = 11.0
a[0][1] = 6.0
a[0][2] = -2.0
a[1][0] = -2.0
a[1][1] = 18.0
a[1][2] = 1.0
a[2][0] = -12.0
a[2][1] = 24.0
a[2][2] = 13.0
for i1 in 0 ... n
for i2 in 0 ... n
b[i1][i2] = 0.0
end
b[i1][i1] = 1.0
v0[i1] = 1.0
end
# 計算
ind = power(0, n, m, ct, eps, a, b, c, r, v, v0, v1, v2)
# 出力
if ind == 0
printf("固有値が求まりませんでした!\n")
else
for i1 in 0 ... ind
printf("固有値 %f", r[i1])
printf(" 固有ベクトル ")
for i2 in 0 ... n
printf(" %f", v[i1][i2])
end
printf("\n")
end
end
# -*- coding: UTF-8 -*-
import numpy as np
from math import *
############################################
# 最大固有値と固有ベクトル(べき乗法)
# i : 何番目の固有値かを示す
# n : 次数
# m : 丸め誤差の修正回数
# ct : 最大繰り返し回数
# eps : 収束判定条件
# A : 対象とする行列
# B : nxnの行列,最初は,単位行列
# C : 作業域,nxnの行列
# r : 固有値
# v : 各行が固有ベクトル(nxn)
# v0 : 固有ベクトルの初期値
# v1,v2 : 作業域(n次元ベクトル)
# return : 求まった固有値の数
# coded by Y.Suganuma
############################################
def power(i, n, m, ct, eps, A, B, C, r, v, v0, v1, v2) :
# 初期設定
ind = i
k = 0
l1 = 0.0
for i1 in range(0, n) :
l1 += v0[i1] * v0[i1]
v1[i1] = v0[i1]
l1 = sqrt(l1)
# 繰り返し計算
while k < ct :
# 丸め誤差の修正
if k%m == 0 :
l2 = 0.0
for i1 in range(0, n) :
v2[i1] = 0.0
for i2 in range(0, n) :
v2[i1] += B[i1][i2] * v1[i2]
l2 += v2[i1] * v2[i1]
l2 = sqrt(l2)
for i1 in range(0, n) :
v1[i1] = v2[i1] / l2
# 次の近似
l2 = 0.0
for i1 in range(0, n) :
v2[i1] = 0.0
for i2 in range(0, n) :
v2[i1] += A[i1][i2] * v1[i2]
l2 += v2[i1] * v2[i1]
l2 = sqrt(l2)
for i1 in range(0, n) :
v2[i1] /= l2
# 収束判定
# 収束した場合
if abs((l2-l1)/l1) < eps :
k1 = -1
for i1 in range(0, n) :
if abs(v2[i1]) > 0.001 :
k1 = i1
if v2[k1]*v1[k1] < 0.0 :
l2 = -l2
break
k = ct
r[i] = l2
for i1 in range(0, n) :
v[i][i1] = v2[i1]
if i == n-1 :
ind = i + 1
else :
for i1 in range(0, n) :
for i2 in range(0, n) :
C[i1][i2] = 0.0
for i3 in range(0, n) :
if i1 == i3 :
x = A[i1][i3] - l2
else :
x = A[i1][i3]
C[i1][i2] += x * B[i3][i2]
for i1 in range(0, n) :
for i2 in range(0, n) :
B[i1][i2] = C[i1][i2]
for i1 in range(0, n) :
v1[i1] = 0.0
for i2 in range(0, n) :
v1[i1] += B[i1][i2] * v0[i2]
for i1 in range(0, n) :
v0[i1] = v1[i1]
ind = power(i+1, n, m, ct, eps, A, B, C, r, v, v0, v1, v2)
# 収束しない場合
else :
for i1 in range(0, n) :
v1[i1] = v2[i1]
l1 = l2
k += 1
return ind
############################################
# 最大固有値と固有ベクトル(べき乗法)
# coded by Y.Suganuma
############################################
# データの設定
ct = 200
eps = 1.0e-10
n = 3
m = 15
A = np.array([[11, 6, -2],[-2, 18, 1],[-12, 24, 13]], np.float)
B = np.array([[1, 0, 0],[0, 1, 0],[0, 0, 1]], np.float)
C = np.empty((n, n), np.float)
v = np.empty((n, n), np.float)
r = np.empty(n, np.float)
v0 = np.array([1, 1, 1], np.float)
v1 = np.empty(n, np.float)
v2 = np.empty(n, np.float)
# 計算
ind = power(0, n, m, ct, eps, A, B, C, r, v, v0, v1, v2)
# 出力
if ind == 0 :
print("固有値が求まりませんでした!")
else :
for i1 in range(0, ind) :
print("固有値 " + str(r[i1]), end="")
print(" 固有ベクトル ", end="")
for i2 in range(0, n) :
print(" " + str(v[i1][i2]), end="")
print()
/****************************************/
/* 最大固有値と固有ベクトル(べき乗法) */
/* coded by Y.Suganuma */
/****************************************/
using System;
class Program
{
static void Main()
{
Test1 ts = new Test1();
}
}
class Test1
{
public Test1()
{
// データの設定
int ct = 200;
int n = 3;
int m = 15;
double eps = 1.0e-10;
double[][] A = new double [][] {
new double[] {11.0, 6.0, -2.0},
new double[] {-2.0, 18.0, 1.0},
new double[] {-12.0, 24.0, 13.0}
};
double[][] B = new double [n][];
B[0] = new double[] {1.0, 0.0, 0.0};
B[1] = new double[] {0.0, 1.0, 0.0};
B[2] = new double[] {0.0, 0.0, 1.0};
double[][] C = new double [n][];
double[][] v = new double [n][];
for (int i1 = 0; i1 < n; i1++) {
C[i1] = new double [n];
v[i1] = new double [n];
}
double[] v0 = {1.0, 1.0, 1.0};
double[] v1 = new double [n];
double[] v2 = new double [n];
double[] r = new double [n];
// 計算
int ind = power(0, n, m, ct, eps, A, B, C, r, v, v0, v1, v2);
// 出力
if (ind == 0)
Console.WriteLine("固有値が求まりませんでした!");
else {
for (int i1 = 0; i1 < ind; i1++) {
Console.WriteLine("固有値 " + r[i1]);
Console.Write(" 固有ベクトル ");
for (int i2 = 0; i2 < n; i2++)
Console.Write(" " + v[i1][i2]);
Console.WriteLine();
}
}
}
/****************************************/
/* 最大固有値と固有ベクトル(べき乗法) */
/* i : 何番目の固有値かを示す */
/* n : 次数 */
/* m : 丸め誤差の修正回数 */
/* ct : 最大繰り返し回数 */
/* eps : 収束判定条件 */
/* A : 対象とする行列 */
/* B : nxnの行列,最初は,単位行列 */
/* C : 作業域,nxnの行列 */
/* r : 固有値 */
/* v : 各行が固有ベクトル(nxn) */
/* v0 : 固有ベクトルの初期値 */
/* v1,v2 : 作業域(n次元ベクトル) */
/* return : 求まった固有値の数 */
/* coded by Y.Suganuma */
/****************************************/
static int power(int i, int n, int m, int ct, double eps, double[][] A,
double[][] B, double[][] C, double[] r, double[][] v,
double[] v0, double[] v1, double[] v2)
{
// 初期設定
int ind = i;
int k = 0;
double l1 = 0.0;
for (int i1 = 0; i1 < n; i1++) {
l1 += v0[i1] * v0[i1];
v1[i1] = v0[i1];
}
l1 = Math.Sqrt(l1);
// 繰り返し計算
while (k < ct) {
// 丸め誤差の修正
double l2;
if (k%m == 0) {
l2 = 0.0;
for (int i1 = 0; i1 < n; i1++) {
v2[i1] = 0.0;
for (int i2 = 0; i2 < n; i2++)
v2[i1] += B[i1][i2] * v1[i2];
l2 += v2[i1] * v2[i1];
}
l2 = Math.Sqrt(l2);
for (int i1 = 0; i1 < n; i1++)
v1[i1] = v2[i1] / l2;
}
// 次の近似
l2 = 0.0;
for (int i1 = 0; i1 < n; i1++) {
v2[i1] = 0.0;
for (int i2 = 0; i2 < n; i2++)
v2[i1] += A[i1][i2] * v1[i2];
l2 += v2[i1] * v2[i1];
}
l2 = Math.Sqrt(l2);
for (int i1 = 0; i1 < n; i1++)
v2[i1] /= l2;
// 収束判定
// 収束した場合
if (Math.Abs((l2-l1)/l1) < eps) {
int k1 = -1;
for (int i1 = 0; i1 < n && k1 < 0; i1++) {
if (Math.Abs(v2[i1]) > 0.001) {
k1 = i1;
if (v2[k1]*v1[k1] < 0.0)
l2 = -l2;
}
}
k = ct;
r[i] = l2;
for (int i1 = 0; i1 < n; i1++)
v[i][i1] = v2[i1];
if (i == n-1)
ind = i + 1;
else {
for (int i1 = 0; i1 < n; i1++) {
for (int i2 = 0; i2 < n; i2++) {
C[i1][i2] = 0.0;
for (int i3 = 0; i3 < n; i3++) {
double x = (i1 == i3) ? A[i1][i3] - l2 : A[i1][i3];
C[i1][i2] += x * B[i3][i2];
}
}
}
for (int i1 = 0; i1 < n; i1++) {
for (int i2 = 0; i2 < n; i2++)
B[i1][i2] = C[i1][i2];
}
for (int i1 = 0; i1 < n; i1++) {
v1[i1] = 0.0;
for (int i2 = 0; i2 < n; i2++)
v1[i1] += B[i1][i2] * v0[i2];
}
for (int i1 = 0; i1 < n; i1++)
v0[i1] = v1[i1];
ind = power(i+1, n, m, ct, eps, A, B, C, r, v, v0, v1, v2);
}
}
// 収束しない場合
else {
for (int i1 = 0; i1 < n; i1++)
v1[i1] = v2[i1];
l1 = l2;
k++;
}
}
return ind;
}
}
''''''''''''''''''''''''''''''''''''''''
' 最大固有値と固有ベクトル(べき乗法) '
' coded by Y.Suganuma '
''''''''''''''''''''''''''''''''''''''''
Module Test
Sub Main()
' データの設定
Dim ct As Integer = 200
Dim n As Integer = 3
Dim m As Integer = 15
Dim eps As Double = 1.0e-10
Dim A(,) As Double = {{11.0, 6.0, -2.0}, {-2.0, 18.0, 1.0}, {-12.0, 24.0, 13.0}}
Dim B(,) As Double = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}}
Dim C(n,n) As Double
Dim v(n,n) As Double
Dim v0() As Double = {1.0, 1.0, 1.0}
Dim v1(n) As Double
Dim v2(n) As Double
Dim r(n) As Double
' 計算
Dim ind As Integer = power(0, n, m, ct, eps, A, B, C, r, v, v0, v1, v2)
' 出力
If ind = 0
Console.WriteLine("固有値が求まりませんでした!")
Else
For i1 As Integer = 0 To ind-1
Console.WriteLine("固有値 " & r(i1))
Console.Write(" 固有ベクトル ")
For i2 As Integer = 0 To n-1
Console.Write(" " & v(i1,i2))
Next
Console.WriteLine()
Next
End If
End Sub
''''''''''''''''''''''''''''''''''''''''
' 最大固有値と固有ベクトル(べき乗法) '
' i : 何番目の固有値かを示す '
' n : 次数 '
' m : 丸め誤差の修正回数 '
' ct : 最大繰り返し回数 '
' eps : 収束判定条件 '
' A : 対象とする行列 '
' B : nxnの行列,最初は,単位行列 '
' C : 作業域,nxnの行列 '
' r : 固有値 '
' v : 各行が固有ベクトル(nxn) '
' v0 : 固有ベクトルの初期値 '
' v1,v2 : 作業域(n次元ベクトル) '
' return : 求まった固有値の数 '
' coded by Y.Suganuma '
''''''''''''''''''''''''''''''''''''''''
Function power(i As Integer, n As Integer, m As Integer, ct As Integer,
eps As Double, A(,) As Double, B(,) As Double, C(,) As Double,
r() As Double, v(,) As Double, v0() As Double, v1() As Double,
v2() As Double)
' 初期設定
Dim ind As Integer = i
Dim k As Integer = 0
Dim l1 As Double = 0.0
For i1 As Integer = 0 To n-1
l1 += v0(i1) * v0(i1)
v1(i1) = v0(i1)
Next
l1 = Math.Sqrt(l1)
' 繰り返し計算
Do While k < ct
' 丸め誤差の修正
Dim l2 As Double
If (k Mod m) = 0
l2 = 0.0
For i1 As Integer = 0 To n-1
v2(i1) = 0.0
For i2 As Integer = 0 To n-1
v2(i1) += B(i1,i2) * v1(i2)
Next
l2 += v2(i1) * v2(i1)
Next
l2 = Math.Sqrt(l2)
For i1 As Integer = 0 To n-1
v1(i1) = v2(i1) / l2
Next
End If
' 次の近似
l2 = 0.0
For i1 As Integer = 0 To n-1
v2(i1) = 0.0
For i2 As Integer = 0 To n-1
v2(i1) += A(i1,i2) * v1(i2)
Next
l2 += v2(i1) * v2(i1)
Next
l2 = Math.Sqrt(l2)
For i1 As Integer = 0 To n-1
v2(i1) /= l2
Next
' 収束判定
' 収束した場合
If Math.Abs((l2-l1)/l1) < eps
Dim k1 As Integer = -1
Dim ii As Integer = 0
Do While ii < n and k1 < 0
If Math.Abs(v2(ii)) > 0.001
k1 = ii
If v2(k1)*v1(k1) < 0.0
l2 = -l2
End If
End If
ii += 1
Loop
k = ct
r(i) = l2
For i1 As Integer = 0 To n-1
v(i,i1) = v2(i1)
Next
If i = n-1
ind = i + 1
Else
For i1 As Integer = 0 To n-1
For i2 As Integer = 0 To n-1
C(i1,i2) = 0.0
For i3 As Integer = 0 To n-1
Dim x As Double = A(i1,i3) - l2
If i1 <> i3
x = A(i1,i3)
End If
C(i1,i2) += x * B(i3,i2)
Next
Next
Next
For i1 As Integer = 0 To n-1
For i2 As Integer = 0 To n-1
B(i1,i2) = C(i1,i2)
Next
Next
For i1 As Integer = 0 To n-1
v1(i1) = 0.0
For i2 As Integer = 0 To n-1
v1(i1) += B(i1,i2) * v0(i2)
Next
Next
For i1 As Integer = 0 To n-1
v0(i1) = v1(i1)
Next
ind = power(i+1, n, m, ct, eps, A, B, C, r, v, v0, v1, v2)
End If
' 収束しない場合
Else
For i1 As Integer = 0 To n-1
v1(i1) = v2(i1)
Next
l1 = l2
k += 1
End If
Loop
Return ind
End Function
End Module
| 情報学部 | 菅沼ホーム | 目次 | 索引 |