OpenMythosのサンプルプログラムを動かしました

1.概要 前回、OpenMythosの環境構築まで実現したので、GitHubにあるサンプルプログラム(Usage)を動かしてみました。一部エラーが発生しましたが、結果出力部分なので修正をしました。その内容を記述します。 2.詳細 Usageに記載されているPythonプログラムをopenmythos_usage.pyとして作成します。 $ source ~/mypy/bin/activate (mypy) $ pythoh3 openmythos_usage.py 下記エラーとなります [MLA] Parameters: 1,538,626 [MLA] Logits shape: torch.Size([2, 16, 1000]) [MLA] Generated shape: torch.Size([2, 24]) Traceback (most recent call last):   File "/home/nakasima/openmythos/openmythos_usage.py", line 48, in <module>     rho = torch.linalg.eigvals(A).abs().max().item()           ^^^^^^^^^^^^^^^^^^^^^^^ RuntimeError: linalg.eig: The input tensor A must have at least 2 dimensions. コードの下記部分を修正します #rho = torch.linalg.eigvals(A).abs().max().item() rho = A.abs().max().item() $ source ~/mypy/bin/activate (mypy) $ pythoh3 openmythos_usage.py [MLA] Parameters: 1,538,626 [MLA] Logits shape: torch.Size([2, 16, 1000]) [MLA] Generated shape: torch.Size([2, 24]) [MLA] Spectral radius ρ(A) = 0.3679 (mus...

テスト駆動開発を利用したfibonacciのコード作成 性能向上編

 1.概要

前回、再帰呼出しを利用することで、fibonacci関数をTDDで作成しました。再帰呼出しは非常に便利な手法ですが、計算量により実用に適しない場合があります。その内容を説明した上で、TDD手法でfibonacci関数を再帰呼出しを利用しない方式へ修正することを説明します。

2.詳細

fibonacci数列は、0,1,1,2,3,5,8,13,.....と継続する数列で、先行する2つの数値を足した値が、次の数値になる無限に続く数列です。初期値と次の値は、0と1になっています。前回作成したtestcode(Testfibonacci.py)とcode(fibonacci.py)を利用して修正します。

(1) testcode(TestFibonacci.py)を修正
50番目の項目の試験を記述します。
48番目と49番目の項目を加えると、50番目の項目になります。
この試験項目を追加します。

import unittest
from fibonacci import Fibonacci

class TestFibonacci(unittest.TestCase):

    def setUp(self):
        self.obj = Fibonacci()
    def tearDown(self):
        del self.obj
    def testFibonacci01(self):
        assert(self.obj.fibonacci(0) == 0)
        assert(self.obj.fibonacci(1) == 1)
        assert(self.obj.fibonacci(2) == \
                self.obj.fibonacci(0) + self.obj.fibonacci(1))
        assert(self.obj.fibonacci(10) == \
                self.obj.fibonacci(8) + self.obj.fibonacci(9))
        assert(self.obj.fibonacci(50) == \
                self.obj.fibonacci(48) + self.obj.fibonacci(49))

if __name__ == '__main__':
    unittest.main()

(2) testcode(TestFibonacci.py)を実行
python3 TestFibonacci.py

実行すると処理が終わりません。しばらく経過しても何も変わりません。
そこで、Ctrl-Cで終了します。
理由は以下の通りです。

fibonacci(50) = fibonacci(48) + fibonacci(49)

この式は以下の計算が必要です
fibonacci(48) = fibonacci(46) + fibonacci(47)
fibonacci(49) = fibonacci(47) + fibonacci(48)

更にこの式は以下の計算が必要です
fibonacci(46) = fibonacci(44) + fibonacci(45)
fibonacci(47) = fibonacci(45) + fibonacci(46)
fibonacci(47) = fibonacci(45) + fibonacci(46)
fibonacci(48) = fibonacci(46) + fibonacci(47)

この計算をfibonacci(0), fibonacci(1)になるまで実施する必要があり、計算量が非常に多くなります。つまり、再帰呼出しがボトルネックです。

そこで、fibonacci(N)に対して、fibolist = [0,1,1,2,3,......]とN個のlistを作成するように変えます

(3) code(finonacci.py)を修正
初期値と次の項目を処理するコードに変更します。

class Fibonacci:
    def fibonacci(self, number):
        fibolist = [0,1]
        return fibolist[number]

if __name__ == '__main__':
    obj = Fibonacci()

(4) testcode(TestFibonacci.py)を実行
python3 TestFibonacci.py

fibonacci(2)でエラーになります。

RROR: testFibonacci01 (__main__.TestFibonacci)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "TestFibonacci.py", line 15, in testFibonacci01
    assert(self.obj.fibonacci(2) == \
  File "/home/nakasima/mycode/fibotest/fibonacci.py", line 11, in fibonacci
    return fibolist[number]
IndexError: list index out of range

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (errors=1)

(5) code(finonacci.py)を修正
3番目以降をfibolistに追加するロジックを追加します。

class Fibonacci:
    def fibonacci(self, number):
        fibolist = [0,1]
        for i in range(2, number+1):
            fibolist.append(fibolist[i-2] + fibolist[i-1])
        return fibolist[number]

if __name__ == '__main__':
    obj = Fibonacci()

(6) testcode(TestFibonacci.py)を実行
python3 TestFibonacci.py
エラーがなくなります

Ran 1 test in 0.000s
OK

これで、fibonacci関数プログラムを再帰呼出しを利用せずにfibonacci.pyが完成しました。

参考

テスト駆動開発入門 ケント・ベック著

コメント

このブログの人気の投稿

miniPCのBMAXでWindows11のsecure boot設定漏れでトラブル発生

LinuxMint-22.3にWine 11.6をサクッと入れてみました

LinuxMint 21.3にWinBoat導入を試してみました