質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

91.25%

  • Python

    4225questions

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

  • VBA

    1180questions

    VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

グラフPythonでDFT(離散フーリエ変換)

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 88

asoaso

score 37

VBAのプログラムを元に、PythonでDFTを実行したいと考えています。

def dft (x, N):
    X = [0.0] * N
    sr, si = 0,0
    fr, fi = [],[]
    for i in range(N):
        for k in range(N):
            wr = np.cos(2 * np.pi * k * i / N)
            wi = - np.sin(2 * np.pi * k * i / N)
            sr = sr + x[k] * wr
            si = si + x[k] * wi

        fr = sr.real
        fi = si.imag

        X[i] = np.math.sqrt(fr*fr+fi*fi)
    return X

このようなプログラムを以下のVBAのプログラムを参考に作成しました。

Dim inr(16384)
Dim fr(16384), fi(16384)
z = Cells(1, "b") 'sample time
n = Cells(2, "b") 'DATA size
'Data Read
For i = 0 To n - 1
inr(i) = Cells(i + 3, 2)
Next i
Pi = 3.14159265358979
'DFT
For i = 0 To n - 1
sr = 0
si = 0
For k = 0 To n - 1
wr = Cos(2 * Pi * k * i / n)
wi = -Sin(2 * Pi * k * i / n)
sr = sr + inr(k) * wr
si = si + inr(k) * wi
Next k
fr(i) = sr 'Re
fi(i) = si 'Im
Next i
'Data Out
For i = 0 To n - 1
Cells(i + 2, 4) = i / z / n
Cells(i + 2, 5) = Sqr(fr(i) * fr(i) + fi(i) * fi(i)) / n
Next i

自作のpythonのグラフは、
イメージ説明

VBAは、
イメージ説明

自分で考えたPythonのプログラムが同じように実行できません。
どこで違ってきているのでしょうか。

また、

fr(i) = sr 'Re
fi(i) = si 'Im


これをPyhtonでどのように表現したら良いかがわかっていません

よろしくお願いいたいます。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

離散フーリエ変換は以下のものになります。
もとのVBAのコードでは更に絶対値を取っているように見えます。
そこが振幅が異なる理由だと思われます。

そして横軸ですが、これは別に計算する必要があります。
横軸がずれている理由はそこにあると思われます。

import numpy as np
from scipy import linalg
from pprint import pprint

def dft(x, N):
    X = np.zeros((N,), dtype=np.complex)
    for i in range(N):
        sr, si = 0,0
        for k in range(N):
            wr = np.cos(2 * np.pi * k * i / N)
            wi = - np.sin(2 * np.pi * k * i / N)
            sr = sr + x[k] * wr
            si = si + x[k] * wi
        X[i] = sr + si*1.j
    return X

x = np.linspace(0., np.pi, 100)
y = np.sin(x)
Y = dft(y, len(y))
pprint(Y)
pprint(np.abs(Y))

t = linalg.dft(len(y))
Y = t.dot(y)
pprint(Y)
pprint(np.abs(Y))

勘違いしてました。 また考え直してきます。

X = [0.0] * Nなので全ての要素が同じポインタをシェアしている気がします。 つまりXの要素は中身としては同じもので、1つ書き換えようとしたら、みんな同じように書き換わってしまいます。 X = [0.0 for i in range(N)]とすると一歩前進するかもしれません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

VBAはほんのちょっと齧ったくらいの知識ですが... かなり違いません?
ちゃんとVBAにもインデントを付けてPython-likeに書くと見比べやすいですよ。

  • srとsiが0に初期化されるタイミングが異なる
  • frへの代入が異なっている (VBAは添え字アクセスしている)

scipy.linalg.dftという関数があるようです。
使い方を調査するのは面倒ですが、既にあるものを使った方がいいですよ。
手間と言うより、単純に実行速度の恩恵が大きいです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

ただいまの回答率

91.25%

関連した質問

  • 解決済

    [VBA]マクロをコンパクトに短くまとめたい

    質問内容が大きく変わったので修正です。 C列には都道府県名、I列にはURLが記入されています。 以下のコードは、 「C列に"東京"とあるがI列のURLには"tokyo"と

  • 解決済

    VAB 結合セルとループ

    前提・実現したいこと | 2013 | 1 | 山田 |      | 2 | 田中 |      | 3 | 佐藤 | 2014 | 1 | 山田 | 2015 | 1

  • 解決済

    VBA オブジェクトとfor each~next

    お疲れ様です。 データーを高速に処理するプログラムに改良するため、 セルをループで人る一つ見るのではなく、オブジェクト変数を使った方が高速に処理できるとのことで、オブジェク

  • 解決済

    VBA 配列

    お世話になっております。 配列について学習を進めておりますが、イマイチどのようにデーターが格納されているくな分からず、意図した処理ができない状態です。 D列に"No"が合っ

  • 解決済

    エクセル VBA 1つのセルの値を分けて、逆並びで列に配置

    教えてください。 F列2行目から例えば、 43x43x5(×は大文字のx(エックス)で代用してます。) というサイズ「縦x横x高さ」が入力されています。 これを数値ごと

  • 解決済

    【VBA】ドメインのリスト一覧から配列に含まれるドメインのみを着色したい

    下記のような感じで、大量のドメインが記載されているExcelシートから、特定のドメインのみを着色するマクロを書きたいです。 Excelシートの例   A B C

  • 解決済

    EXCEL VBAで縦列の数字をグルーピングしたい

    VBAでA列に縦に数値が並んでいます。 |A  |B|C| |0  |1|1| |0.4|1|2| |0  |2|1| |0.4|2|2| |0.5|2|3| ………

  • 解決済

    三次元グラフ同時に表示できるようにしたい

    前提・実現したいこと 同時に2枚(またはそれ以上)表示されるようにしたい 発生している問題・エラーメッセージ 2枚表示はされるが完全に重なった位置に表示されてしまうため、

同じタグがついた質問を見る

  • Python

    4225questions

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

  • VBA

    1180questions

    VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。