示例#1
0
def inverse_iteration(a: Dmatrix, a_qr: Dmatrix, eps: float) -> Dmatrix:
    mu = 0.0

    y = Dvector(1, N)
    a_ii = a_qr.copy()

    for i in range(1, N + 1):
        lambda_ = a_ii[i][i]  # 近似固有値の代入
        y[i] = 1.0  # 初期値設定

        # 行列の作成およびLU分解
        lu = a.copy()
        for k in range(1, N + 1):
            lu[k][k] -= lambda_
        lu, p = lu_decomp(lu, N)  # LU分解

        # 逆反復法
        while True:
            muo = mu
            v = y.copy()
            v = lu_solve(lu, v, p, N)  # 固有ベクトルの計算
            mu = inner_product(v, y)  # 補正
            v2s = sqrt(inner_product(v, v))
            for j in range(1, N + 1):
                y[j] = v[j] / v2s

            if abs((mu - muo) / mu) < eps:
                break

        # 結果の代入(固有ベクトルはaのi列に)
        for j in range(1, N + 1):
            a_ii[j][i] = y[j]

    return a_ii
示例#2
0
def qr(a: Dmatrix, eps: float, n: int) -> Dmatrix:
    # 領域の確保
    q    = Dmatrix(1, n, 1, n)
    work = Dvector(1, n)
    a_qr = a.copy()
    m = n
    while m > 1:
        # 収束判定
        if abs(a_qr[m][m-1]) < eps:
            m = m - 1
            continue

        # 原点移動
        s = a_qr[n][n]
        if m == n:  # m=n のときは原点移動なし
            s = 0.0
        for i in range(1, m+1):
            a_qr[i][i] -= s
        
        # QR法
        for i in range(1, m+1):
            for j in range(1, m+1):
                q[i][j] = 0.0      # Q を m x m 単位行列で初期化
            q[i][i] = 1.0
        
        # R と Q の計算
        for i in range(1, m):
            r = sqrt( a_qr[i][i]*a_qr[i][i] + a_qr[i+1][i]*a_qr[i+1][i] )
            if r == 0.0:
                sint = 0.0
                cost = 0.0
            else:
                sint = a_qr[i+1][i] / r
                cost = a_qr[i][i] / r
            for j in range(i+1, m+1):
                tmp = a_qr[i][j]*cost + a_qr[i+1][j]*sint
                a_qr[i+1][j] = -a_qr[i][j]*sint + a_qr[i+1][j]*cost
                a_qr[i][j] = tmp
            a_qr[i+1][i] = 0.0
            a_qr[i][i] = r
            for j in range(1, m+1):        # Q は P の転置
                tmp = q[j][i]*cost + q[j][i+1]*sint
                q[j][i+1] = -q[j][i]*sint + q[j][i+1]*cost
                q[j][i] = tmp
            
        # RQ の計算
        for i in range(1, m+1):
            for j in range(i, m+1):
                work[j] = a_qr[i][j]
            for j in range(1, m+1):
                a_qr[i][j] = sum( ( work[k] * q[k][j] for k in range(i, m+1) ) )
            
        # 原点移動後の処理
        for i in range(1, m+1):
            a_qr[i][i] += s

    return a_qr
示例#3
0
def least_square(x: Dvector, y: Dvector, fout):
    global M, N
    p = Dmatrix(1, N + 1, 1, N + 1)  # p[1...N+1][1...N+1]
    a = Dvector(1, N + 1)  # a[1...N-1]

    # 右辺ベクトルの作成
    for i in range(1, N + 2):
        a[i] = 0.0
        for j in range(1, M + 1):
            a[i] += y[j] * (x[j]**(i - 1))

    # 係数行列の作成
    for i in range(1, N + 2):
        for j in range(1, i + 1):
            p[i][j] = 0.0
            for k in range(1, M + 1):
                p[i][j] += x[k]**(i + j - 2)
            p[j][i] = p[i][j]

    # 連立一次方程式を解く. 結果は a に上書き
    a = gauss2(p, a, N + 1)

    # 結果の出力
    fout.write("最小2乗近似式は y=\n")
    for i in range(N + 1, 0, -1):
        fout.write("+ {:5.2f} x^{} ".format(a[i], i - 1))
    fout.write("\n")
示例#4
0
def lu_decomp(a: Dmatrix, N: int=N) -> Tuple[Dmatrix, List[int]]:
    eps = 2.0 ** -50.0 # eps = 2^{-50}とする
    p = [0] * (a.row_last_idx - a.row_head_idx + 1) # p[1...N-1] を利用, p[0] は未使用
    a_lu = a.copy() # 値渡し

    for k in range(1, N):
        # ピボットの選択
        amax = abs(a_lu[k][k])
        ip = k
        for i in range(k+1, N+1):
            if abs(a_lu[i][k]) > amax:
                amax = abs(a_lu[i][k])
                ip = i

        # 正則性の判定
        if amax < eps:
            print("入力した行列は正則ではない!!")
        # ipを配列pに保存
        p[k] = ip
        # 行交換
        if ip != k:
            for j in range(k, N+1):
                a_lu[k][j], a_lu[ip][j] = a_lu[ip][j], a_lu[k][j]

        # 前進消去
        for i in range(k+1, N+1):
            alpha = - a_lu[i][k] / a_lu[k][k]
            a_lu[i][k] = alpha
            for j in range(k+1, N+1):
                a_lu[i][j] += alpha * a_lu[k][j]

    return (a_lu, p)
示例#5
0
def produce_matrix(nr1: int, nr2: int, nl1: int, nl2: int):
    a = Dmatrix(nr1, nr2, nl1, nl2)
    seed()  # シードを与える
    for i in range(nr1, nr2 + 1):
        for j in range(nl1, nl2 + 1):
            a[i][j] = rand() / RAND_MAX
    return a
示例#6
0
def bvp(b: Dvector, a1: float, a2: float, u0: float,
    un: float, n: float, f) -> Dvector:
    h = (a2 - a1) / n # 刻み幅
    h2 = h * h
    a = Dmatrix(1, n-1, 1, n-1) # 係数行列

    # 行列の作成
    for i in range(2, n-1):
        a[i][i]   = 2.0
        a[i][i+1] = -1.0
        a[i][i-1] = -1.0
    
    for j in range(3, n):
        a[1][j] = 0.0
    a[1][1] = 2.0
    a[1][2] = -1.0
    for j in range(1, n-2):
        a[n-1][j] = 0.0
    a[n-1][n-2] = -1.0
    a[n-1][n-1] = 2.0

    # 右辺ベクトルの作成
    for i in range(1, n):
        b[i] = h2 * func( a1 + h*i )
    b[1] += u0
    b[n-1] += un

    # 修正コレスキー分解
    a_cd = cholesky_decomp(a, n-1)
    # 修正コレスキー分解を利用して連立一次方程式を解く
    b_cs = cholesky_solve( a_cd, b, n-1)

    return b_cs
示例#7
0
def main():
    global N
    a = Dmatrix(1, N, 1, N)  # 行列 a[1...N][1...N]
    b = Dvector(1, N)  # b[1...N]
    with open("input.dat", "r") as fin:
        with open("output.dat", "w") as fout:
            input_matrix(a, 'A', fin, fout)
            input_vector(b, 'b', fin, fout)
示例#8
0
def cholesky_decomp(a: Dmatrix, N: int = N):
    a_cd = a.copy()
    for i in range(2, N + 1):
        for j in range(1, i):
            a_cd[i][j] = (a_cd[i][j] - sum(
                (a_cd[i][k] * a_cd[k][k] * a_cd[j][k]
                 for k in range(1, j)))) / a_cd[j][j]
        a_cd[i][i] -= sum(
            (a_cd[i][k] * a_cd[i][k] * a_cd[k][k] for k in range(1, j + 1)))
    return a_cd
示例#9
0
def matrix_sum(a: Dmatrix, b: Dmatrix):
    m1, m2 = a.row_head_idx, a.row_last_idx
    n1, n2 = a.col_head_idx, a.col_last_idx
    c = Dmatrix(m1, m2, n1, n2)

    for i in range(m1, m2 + 1):
        for j in range(n1, n2 + 1):
            c[i][j] = a[i][j] + b[i][j]

    return c
示例#10
0
def main():
    a = Dmatrix(1, N, 1, N) # 行列領域の確保
    x = Dvector(1, N)       # ベクトル領域の確保

    # ファイルのオープン
    with open("input_eigen.dat", "r") as fin:
        with open("result_eigen.dat", "w") as fout:
            input_matrix( a, 'A', fin, fout ) # 行列 A の入出力
            input_vector( x, 'x', fin, fout ) # ベクトル x の入出力
            power_method( a, x, fout )        # べき乗法
示例#11
0
def main():
    global ROW, COLUMN
    a = Dmatrix(1, ROW, 1, COLUMN)  # 行列 a[1...ROW][1...COLUMN]
    b = Dmatrix(1, ROW, 1, COLUMN)  # 行列 b[1...ROW][1...COLUMN]

    # 行列の定義
    for i in range(1, ROW + 1):
        for j in range(1, COLUMN + 1):
            a[i][j] = 2.0 * (i + j)
            b[i][j] = 3.0 * (i + j)

    # 行列の和の計算
    c = matrix_sum(a, b)

    # 結果の表示
    print("行列 A と行列 B の和は次の通りです")
    for i in range(1, ROW + 1):
        for j in range(1, COLUMN + 1):
            print(c[i][j], end="  ")
        print()
示例#12
0
def householder(a: Dmatrix, n: int) -> Dmatrix:
    u = Dvector(1, n)
    f = Dvector(1, n)
    g = Dvector(1, n)

    a_hh = a.copy()

    for k in range(1, n - 1):
        # v の計算
        for i in range(1, k + 1):
            u[i] = 0.0
        for i in range(k + 1, n + 1):
            u[i] = a_hh[i][k]

        # s の計算
        ss = 0.0
        for i in range(k + 2, n + 1):
            ss += u[i] * u[i]
        if abs(ss) <= 0.0:  # 消去が必要ない場合の処理
            continue
        s = sqrt(ss + u[k + 1] * u[k + 1])
        if u[k + 1] > 0.0:
            s = -s

        # uの計算
        u[k + 1] -= s
        uu = sqrt(ss + u[k + 1] * u[k + 1])
        for i in range(k + 1, n + 1):
            u[i] /= uu

        # f, gの計算
        for i in range(1, n + 1):
            f[i], g[i] = 0.0, 0.0
            for j in range(k + 1, n + 1):
                f[i] += a_hh[i][j] * u[j]
                g[i] += a_hh[j][i] * u[j]

        # gammaの計算
        gamma = 0.0
        for j in range(1, n + 1):
            gamma += u[j] * g[j]

        # f, gの計算
        for i in range(1, n + 1):
            f[i] -= gamma * u[i]
            g[i] -= gamma * u[i]

        # A の計算
        for i in range(1, n + 1):
            for j in range(1, n + 1):
                a_hh[i][j] -= 2.0 * u[i] * g[j] + 2.0 * f[i] * u[j]

    return a_hh
示例#13
0
def matrix_product(a: Dmatrix, b: Dmatrix) -> Dmatrix:
    l1, l2 = a.row_head_idx, a.row_last_idx
    m1, m2 = a.col_head_idx, a.col_last_idx
    n1, n2 = b.col_head_idx, b.col_last_idx
    c = Dmatrix(l1, l2, n1, n2)

    for i in range(l1, l2 + 1):  # 行の添字
        for j in range(n1, n2 + 1):
            c[i][j] = 0.0  # 変数の初期化
            for k in range(m1, m2 + 1):  # 列の添字
                c[i][j] += a[i][k] * b[k][j]

    return c
示例#14
0
def main():
    global ROW, COLUMN

    a = Dmatrix(1, ROW, 1, COLUMN)  # 行列 a[1...ROW][1...COLUMN]
    # 行列の定義
    print("A=")
    for i in range(1, ROW + 1):
        for j in range(1, COLUMN + 1):
            a[i][j] = 2.0 * (i + j) * (-1.0)**j
            print(a[i][j], end="\t")
        print()

    print(f"Aの1ノルムは{matrix_norm1(a)}")
    print(f"Aの最大値ノルムは{matrix_norm_max(a)}")
示例#15
0
def main():
    a = Dmatrix(1, N, 1, N)

    # ファイルのオープン
    with open("input_eigen.dat", "r") as fin:
        with open("result_eigen.dat", "w") as fout:
            input_matrix(a, 'A', fin, fout)  # 行列 A の入出力
            a_hh = householder(a, N)  # ハウスホルダー法

            # 結果の出力
            print("Hessenberg 行列は")
            for i in range(1, N + 1):
                for j in range(1, N + 1):
                    print("{:10.7f}\t".format(a_hh[i][j]), end="")
                print()
示例#16
0
def main():
    global L, M, N

    a = Dmatrix(1, L, 1, M)  # 行列 a[1...L][1...M]
    b = Dmatrix(1, M, 1, N)  # 行列 b[1...M][1...N]

    # 行列 A の定義
    for i in range(1, L + 1):
        for j in range(1, M + 1):
            a[i][j] = 2.0 * (i + j)

    # 行列 B の定義
    for i in range(1, M + 1):
        for j in range(1, N + 1):
            b[i][j] = 2.0 * (i + j)

    # 行列の積の計算
    c = matrix_product(a, b)
    # 結果の表示
    print("A x B の結果は次の通りです")
    for i in range(1, L + 1):
        for j in range(1, N + 1):
            print(c[i][j], end="  ")
        print()
示例#17
0
def main():
    global N
    a = Dmatrix(1, N, 1, N) # 行列 a[1...N][1...N]
    b = Dvector(1, N) # b[1...N]

    # ファイルのオープン
    with open("input.dat", "r") as fin:
        with open("output.dat", "w") as fout:
            input_matrix( a, 'A', fin, fout ) # 行列 A の入出力
            input_vector( b, 'b', fin, fout ) # ベクトル b の入出力
            b = simple_gauss( a, b )          # ガウス消去法

            # 結果の出力
            fout.write("Ax=b の解は次の通りです\n")
            for i in range(1, N+1):
                fout.write("{:.6f}\n".format(b[i]))
示例#18
0
def main():
    global N

    a = Dmatrix(1, N, 1, N)
    b = Dvector(1, N)

    # ファイルのオープン
    with open("input.dat", "r") as fin:
        with open("output.dat", "w") as fout:
            input_matrix(a, 'A', fin, fout)  # 行列 A の入出力
            input_vector(b, 'b', fin, fout)  # ベクトル b の入出力
            b = gauss(a, b)  # ガウス消去法

            # 結果の出力
            fout.write("Ax=b の解は次の通りです\n")
            for i in range(1, N + 1):
                fout.write(f"{b[i]}\n")
示例#19
0
def main():
    a = Dmatrix(1, N, 1, N)  # 行列 a[1...N][1...N]
    b = Dvector(1, N)  # b[1...N]
    x0 = Dvector(1, N)  # x[1...N]

    # ファイルのオープン
    with open("input_sp.dat", "r") as fin:
        with open("output_sp.dat", "w") as fout:
            input_matrix(a, 'A', fin, fout)  # 行列 A の入出力
            input_vector(b, 'b', fin, fout)  # ベクトル b の入出力
            input_vector(x0, 'x0', fin, fout)  # 初期ベクトル x0 の入出力
            x = gauss_seidel(a, b, x0)  # ガウス・ザイデル法

            # 結果の出力
            fout.write("Ax=b の解は次の通りです\n")
            for i in range(1, N + 1):
                fout.write("{:.6f}\n".format(x[i]))
示例#20
0
def main():
    a = Dmatrix(1, N, 1, N) # 行列 a[1...N][1...N]
    b = Dvector(1, N)       # b[1...N]
    x = Dvector(1, N)       # x[1...N]

    # ファイルのオープン
    with open("input_sp.dat", "r") as fin:
        with open("output_sp.dat", "w") as fout:
            input_matrix( a, 'A', fin, fout ) # 行列 A の入出力
            input_vector( b, 'b', fin, fout ) # ベクトル b の入出力
            input_vector( x, 'x', fin, fout ) # 初期ベクトル x0 の入出力
            x = jacobi_lin( a, b, x )         # ヤコビ法

            # 結果の出力
            fout.write("Ax=b の解は次の通りです\n")
            for i in range(1, N+1):
                fout.write("{:.6f}\n".format(x[i]))
示例#21
0
def main():
    global N

    a = Dmatrix(1, N, 1, N)  # 行列 a[1...N][1...N]
    b = Dvector(1, N)  # b[1...N]

    # ファイルのオープン
    with open("input_cho.dat", "r") as fin:
        with open("output_cho.dat", "w") as fout:
            input_matrix(a, 'A', fin, fout)  # 行列 A の入出力
            input_vector(b, 'b', fin, fout)  # ベクトル b の入出力
            a_cd = cholesky_decomp(a)  # 修正コレスキー分解
            b_cs = cholesky_solve(a_cd, b)  # 前進代入・後退代入

            # 結果の出力
            fout.write("Ax=bの解は次の通りです\n")
            for i in range(1, N + 1):
                fout.write("{:.6f}\t\n".format(b_cs[i]))
示例#22
0
def main():
    global N

    a = Dmatrix(1, N, 1, N) # 行列 a[1...N][1...N]
    b = Dvector(1,N) # b[1...N]

    # ファイルのオープン
    with open("input_lu.dat", "r") as fin:
        with open("output_lu.dat", "w") as fout:
            input_matrix( a, 'A', fin, fout ) # 行列 A の入力
            input_vector( b, 'B', fin, fout ) # ベクトル b の入出力
            a_lu, p = lu_decomp( a )          # LU分解
            b_lu = lu_solve( a_lu, b, p )     # 前進代入・後退代入

            # 結果の出力
            fout.write("Ax=b の解は次の通りです\n")
            for i in b_lu:
                fout.write(f"{i}\n")
示例#23
0
def newton_ip(x: Dvector, y: Dvector, n: int, xi: float) -> float:
    pn = 0.0

    a = Dmatrix(0, n, 0, n)

    for i in range(n+1):
        a[i][0] = y[i]

    # 差商の計算
    for j in range(1, n+1):
        for i in range(n-j+1):
            a[i][j] = ( a[i+1][j-1] - a[i][j-1] ) / ( x[i+j] - x[i] )

    # 補間の計算
    pn, li = y[0], 1.0
    for j in range(1, n+1):
        li *= ( xi - x[j-1] )
        pn += a[0][j] * li

    return pn
示例#24
0
def newton2(x: float, y: float, z: float):
    global N
    k = 0
    d = Dvector(1, N)  # d[1...N]
    xk = Dvector(1, N)  # xk[1...N]
    J = Dmatrix(1, N, 1, N)  # 行列 J[1...N][1...N]

    xk[1] = x
    xk[2] = y
    xk[3] = z

    while True:
        # 右辺ベクトルの作成
        d[1] = -f(xk[1], xk[2], xk[3])
        d[2] = -g(xk[1], xk[2], xk[3])
        d[3] = -h(xk[1], xk[2], xk[3])

        # ヤコビ行列の作成
        J[1][1] = f_x(xk[1], xk[2], xk[3])
        J[1][2] = f_y(xk[1], xk[2], xk[3])
        J[1][3] = f_z(xk[1], xk[2], xk[3])
        J[2][1] = g_x(xk[1], xk[2], xk[3])
        J[2][2] = g_y(xk[1], xk[2], xk[3])
        J[2][3] = g_z(xk[1], xk[2], xk[3])
        J[3][1] = h_x(xk[1], xk[2], xk[3])
        J[3][2] = h_y(xk[1], xk[2], xk[3])
        J[3][3] = h_z(xk[1], xk[2], xk[3])
        d = gauss(J, d, N)  # 連立一次方程式を解く
        for i in range(1, N + 1):
            xk[i] += d[i]
        k += 1

        if vector_norm1(d) <= EPS or k >= KMAX:
            break

    if k == KMAX:
        print("答えが見つかりませんでした")
    else:
        print(f"答えは x={xk[1]}, y={xk[2]}, z={xk[3]} です")
示例#25
0
def main():
    eps = 10.0 ** -8.0

    a = Dmatrix(1, N, 1, N) # 行列領域の確保

    # ファイルのオープン
    with open("input_eigen.dat", "r") as fin:
        with open("result_eigen.dat", "w") as fout:
            input_matrix( a, 'A', fin, fout ) # 行列 A の入出力
            a_hh = householder( a, N )               # ハウスホルダー法
            a_qr = qr( a_hh, eps, N )                   # QR法

            # 結果の出力
            print("QR法の結果は")
            for i in range(1, N+1):
                for j in range(1, N+1):
                    print("{:10.7f}\t".format(a_qr[i][j]), end="")
                print()

            print("固有値は")
            for i in range(1, N+1):
                print("{:10.7f}\t".format(a_qr[i][i]), end="")
            print()
示例#26
0
def main():
    eps = 10.0**-8.0

    a = Dmatrix(1, N, 1, N)  # 行列領域の確保

    with open("input_eigen.dat", "r") as fin:
        with open("result_eigen.dat", "w") as fout:
            input_matrix(a, 'A', fin, fout)  # 行列Aの入出力

            a_hh = householder(a, N)  # ハウスホルダー法

            a_qr = qr(a_hh, eps, N)  # QR 法
            print("固有値は")
            for i in range(1, N + 1):
                print("{:10.7f}".format(a_qr[i][i]), end="\t")
            print()

            a_ii = inverse_iteration(a, a_qr, eps)  # 逆反復法
            print("固有ベクトルは")
            for i in range(1, N + 1):
                print("[", end="")
                for j in range(1, N + 1):
                    print("{:10.7f}".format(a_ii[j][i]), end="\t")
                print("]")