🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

5231閲覧

pythonを用いてフラクタル次元解析[ボックスカウンティング法]の高速化を実現したい。

grintea

総合スコア15

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/01/21 08:23

前提・実現したいこと

ボックスカウンティング法のプログラムを自作で作成したのですが、あまりにも処理が遅いため改善したいと考えております。
プログラムは二次元のグラフに対しての処理で、100データを50データずらしながらボックスカウンティング法を用いることを検討しています。現状総データ3000に対して3388秒かかってしまいます。

該当のソースコード

df:データ[x値、y値]
x: xの値における最大値
y: yの絶対値における最大値
b: ボックスの大きさ

def count(df, x, y, b): i = 0 j = 0 c = 0 x = math.ceil(x/b) * b y = math.ceil(y/b) * b flag1 = False flag2 = False while i <= x and j <= y: flag1 = False flag2 = False if i + b <= x and j + b <= y: for m, n in df: if (i <= abs(m) < i+b) and (j <= abs(n) < j+b): if (np.sign(n) == 1) and (flag1 == 0): c += 1 flag1 = True elif (np.sign(n) == -1) and (flag2 == 0): c += 1 flag2 = True if (flag1 == 1) and (flag2 == 1): break i += b if i >= x: i = 0 j += b return c

試したこと

higich法やマルチフラクタル解析について調べてみたのですがよく理解できませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tiitoi

2021/01/21 08:57

こういうループが沢山あるコードは Python はかなり遅いです。 Python で利用するにしても、このアルゴリズム部分だけ CかC++で書き直して、Python から呼び出すようにしたらどうでしょうか。 ロジックがまったく同じコードでも C++ で書き直すだけで300倍ぐらい早くなります。
A_kirisaki

2021/01/21 09:11

いまなら C++ よりちょっと遅いけどメモリ安全な Rust もアルヨ!
grintea

2021/01/22 06:33

ありがとうございます! ほかの言語については詳しくないのですがやってみます!
ppaul

2021/01/22 07:27

フラクタル次元を推定したいのなら、bを6個ぐらいとって収束の様子を調べればいいですね。 pythonでやるにしても、C/C++でやるにしても、局所的にコードをいじるのではなく全体のアルゴリズムを見直せばo(nlog(n))にできるので、まずそれを考えてみたほうが良いと思います。
guest

回答1

0

ベストアンサー

grinteaさんのコードと端の余りの処理がちょっと違うかもしれませんが、cvを使って高速化してみました。

python

1import cv2 2 3def boxcount(image, b): 4 x, y = image.shape 5 xrepeat = x // b 6 yrepeat = y // b 7 x = xrepeat * b 8 y = yrepeat * b 9 _, img = cv2.threshold(cv2.bitwise_not(image[:x, :y]), 1, 255, cv2.THRESH_BINARY) 10 _, img_b = cv2.threshold(cv2.resize(img, (xrepeat,yrepeat)), 1, 255, cv2.THRESH_BINARY) 11 return img_b.sum()//255 12 13if __name__ == '__main__': 14 import sys 15 import time 16 imagefile = sys.argv[1] 17 image = cv2.imread(imagefile, cv2.IMREAD_GRAYSCALE) 18 print(f'ImageFile: {imagefile} Size: ({image.shape[0]}, {image.shape[1]})') 19 start = time.time() 20 print('BoxCount:', boxcount(image, 2)) 21 elapsed_time = time.time() - start 22 print (f"elapsed_time:{elapsed_time}sec")

実行結果は以下です。

shell

1> python boxcount.py koch.png 2ImageFile: koch.png Size: (16384, 16384) 3BoxCount: 64876 4elapsed_time:8.804325342178345sec

16384 × 16384 の画像を処理して9秒弱でした。
cvの関数はたぶんC/C++で書いてあるので、それほど遅くはないと思います。

投稿2021/01/23 11:46

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

grintea

2021/01/23 12:10

たくさんのご意見ありがとうございます! 是非参考にしていただきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問