1
0

More than 1 year has passed since last update.

乱数を用いた正方行列の生成プログラム(Python)

Last updated at Posted at 2023-01-08

プログラムについて

乱数で生成した正方行列をCSV形式で出力するプログラムです.
以下の行列が生成できます.

  • 非対称行列
    • 密行列
    • 疎行列
  • 対称行列
    • 密行列
    • 疎行列

環境

  • MacBook Air(M1, 2020)
  • Docker(Ubuntu 20.04.5 LTS)
  • Python 3.8.10

プログラム

クラスファイル

Matrix.py
import numpy as np
import random

class Matrix:
    def __init__(self, matrix, N, coefficient, correction, NonZeroList):
        self.matrix = matrix
        self.N = N
        self.coefficient = coefficient
        self.correction = correction
        self.NonZeroList = NonZeroList
# 対称行列を生成する
    def SparseSymmetricMatrix(self):
        for i in range(self.N):
            for j in range(self.N):
                if j > i:
                    break
                elif i == j:
                    self.matrix[i][j] = random.random() + self.correction
                else:
                    tmp = random.random()
                    self.matrix[i][j] = tmp
                    self.matrix[j][i] = tmp
                    if random.random()  > self.coefficient:
                        self.matrix[i][j] = 0
                        self.matrix[j][i] = 0
                        self.NonZeroList[i] = self.NonZeroList[i] + 1
                        self.NonZeroList[j] = self.NonZeroList[j] + 1                   
        return self.matrix, self.NonZeroList
# 非対称行列を生成する   
    def SparseNonsymmetricMatrix(self):
        self.matrix = np.random.rand(self.N, self.N)
        for i in range(self.N):
            k = 0
            for j in range(self.N):
                if random.random()  > self.coefficient:
                    self.matrix[i][j] = 0
                    k = k + 1
                if i == j:
                    if self.matrix[i][j] == 0:
                        self.matrix[i][j] = random.random() + self.correction
                        k = k - 1
            self.NonZeroList[i] = k

        return self.matrix, self.NonZeroList

メインプログラム

MakeMatrix.py
import numpy as np
import sys
import random
import Matrix
import datetime

#現在時刻の取得
dt_now = datetime.datetime.now()
#出力ファイル名
filename = sys.argv[1] + "_" + sys.argv[1] + "matrix" + dt_now.strftime('%Y%m%d%H%M%S') + ".csv"

# 行列の大きさを取得
N =int(sys.argv[1])

# 行列の要素を0で埋める
matrix = np.zeros((N,N))

# 行列における非零要素の割合 (0 ~ 1)
# 1であれば行列の全ての要素を乱数によって埋める
coefficient = float(sys.argv[2])

# 行列の対角成分が0とならないための補正値
correction = 0.00001

# 生成する行列が非対称行列か対称行列かを決める
# 0:非対称行列
# 1:対称行列
flag = int(sys.argv[3])

# 各行における0要素の数を格納するためのリスト
NonZeroList = [0] * N

data1 = Matrix.Matrix(matrix, N, coefficient, correction, NonZeroList)

if flag == 0:
# 非対称行列の生成
    matrix, NonZeroList = data1.SparseNonsymmetricMatrix()
else:
# 対称行列の生成
    matrix, NonZeroList = data1.SparseSymmetricMatrix()

print(matrix)
print(NonZeroList)
# 行列式の表示
print("det A = " + str(np.linalg.det(matrix)))

# ファイルに以下の情報を出力する
# 行列の大きさ,行における非零要素数の最大値,行列における0要素の数
matrix_info = str(N)+ ',' + str(N - min(NonZeroList)) + ',' + str(sum(NonZeroList))
# 行列をファイルに出力する
np.savetxt(filename, matrix, delimiter=",", header = matrix_info)

# 非零要素の数を表示
#print(sum(NonZeroList))

# 行における最大非零要素数を表示
#print(N - min(NonZeroList))

実行方法

python3 MakeMatrix.py N coefficient flag
  • N: 行列の大きさ(int)

  • coefficient: 行列における非零要素の割合
    値の範囲: 0 ~ 1のfloat

  • flag: 生成する行列が対称行列か非対称行列かを決める
    0:非対称行列
    1:対称行列

実行例
python3 MakeMatrix.py 4 0.4 0

実行結果

ターミナルでは以下の結果を出力しています

  • 生成した行列
  • 各行における0要素の数
  • 行列式

出力ファイルでは1行目に以下の内容を記録しています

  • 行列の大きさ
  • 行における非零要素数の最大値
  • 行列における0要素の数
ターミナルでの出力(非対称行列)
$ python3 MakeMatrix.py 4 0.4 0
[[0.65066897 0.         0.         0.        ]
 [0.         0.26324103 0.95347185 0.        ]
 [0.         0.         0.57528549 0.        ]
 [0.         0.77893017 0.27670035 0.06987914]]
[3, 2, 3, 1]
det A = 0.006885645312935573

$ cat 4_4matrix20230109025801.csv 
# 4,3,9
6.506689652550904368e-01,0.000000000000000000e+00,0.000000000000000000e+00,0.000000000000000000e+00
0.000000000000000000e+00,2.632410346860651895e-01,9.534718467392574448e-01,0.000000000000000000e+00
0.000000000000000000e+00,0.000000000000000000e+00,5.752854908460579564e-01,0.000000000000000000e+00
0.000000000000000000e+00,7.789301673589617003e-01,2.767003451180947149e-01,6.987913896584962981e-02

ターミナルでの出力(対称行列)
$ python3 MakeMatrix.py 4 0.4 1
[[0.91577758 0.         0.         0.        ]
 [0.         0.62715689 0.         0.27769902]
 [0.         0.         0.50224569 0.17688978]
 [0.         0.27769902 0.17688978 0.96498479]]
[3, 2, 2, 1]
det A = 0.22491701267021577

$ cat 4_4matrix20230109025922.csv 
# 4,3,8
9.157775837042154699e-01,0.000000000000000000e+00,0.000000000000000000e+00,0.000000000000000000e+00
0.000000000000000000e+00,6.271568857682054965e-01,0.000000000000000000e+00,2.776990216306892689e-01
0.000000000000000000e+00,0.000000000000000000e+00,5.022456936930083105e-01,1.768897789438276247e-01
0.000000000000000000e+00,2.776990216306892689e-01,1.768897789438276247e-01,9.649847898813963543e-01
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0