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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Python

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

Q&A

解決済

1回答

1851閲覧

ガウス関数の不定積分を表す方法はあるのか?

python_wakaran

総合スコア13

Python

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

0グッド

0クリップ

投稿2021/11/04 14:43

pythonでガウス関数の不定積分を行いたいと考えています。
一度不定積分を求めた後で、積分範囲を代入することでいちいち積分する手間を省いて、実行速度を速めたい目的があります。

一般的に不定積分を求めてい場合はsympyモジュールでintegrateを活用することによって可能となると理解しています。

python

1import sympy as sp 2x = sp.symbols('x') 3f1 = x**2 + 1 4 5sp.integrate(f1, x) 6>>> x**3/3 + x

しかし、ガウス関数の不定積分を実行しようとエラーが発生してしまいます。

Python

1def f2(x): 2 return np.exp(-(x**2/2)) 3 4sp.integrate(f2, x) 5>>> 6SympifyError: Sympify of expression 'could not parse '<function f at 0x0000026BF27FD558>'' failed, because of exception being raised: 7SyntaxError: invalid syntax (<string>, line 1)

これはガウス関数の不定積分は初等関数では表せないことによるものなのかなと考えました。(このエラーで調べてもあまり情報がなかったので。。。)

ガウス関数の不定積分を表す方法があれば、教えていただきたく思います。
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

Google Colaboratory で、標準正規分布の確率密度関数の積分、出来ましたよ。以下、参考まで。

イメージ説明

追記

コメントに対する回答です。コメントいただいてから調べましたが、lambdify というのを使うと、不定積分の結果を、pythonの関数(というか、callableオブジェクト)として取り出せるようです。

python

1from sympy import * 2 3x = Symbol('x') 4f = (1/sqrt(2*pi)) * exp(-(x**2 / 2)) # 標準正規分布の確率密度関数 5 6F = integrate(f, x) # f の不定積分を求める 7print(F) # => erf(sqrt(2)*x/2)/2 8print() 9 10F1 = lambdify(x, F) # Fをpythonの関数化したものを取得 11 12# 検算のため、erf(sqrt(2)*x/2)/2 を scipy.erf と math.sqrt から求める関数を作る 13from scipy.special import erf 14import math 15 16def F2(x): 17 u = (math.sqrt(2) / 2) * x 18 return erf(u) / 2 19 20 21# F1(x) と F2(x) とが同じ結果を返すことの確認 22print(F1(0), '/', F2(0)) 23print(F1(1), '/', F2(1)) 24print(F1(2), '/', F2(2)) 25 26# x=5 あたりから 0.5 に漸近する。 27print(F1(5), '/', F2(5)) 28print(F1(6), '/', F2(6)) 29print(F1(7), '/', F2(7)) 30print(F1(8), '/', F2(8)) 31print(F1(9), '/', F2(9)) 32print(F1(10), '/', F2(10)) 33print(F1(100), '/', F2(100)) 34 35# F は奇関数なので、xの符号を変えると、結果もマイナスになる。 36print(F1(-100), '/', F2(-100))

erf(sqrt(2)*x/2)/2

0.0 / 0.0

0.3413447460685429 / 0.3413447460685429
0.4772498680518208 / 0.4772498680518208
0.49999971334842813 / 0.49999971334842813
0.49999999901341236 / 0.49999999901341236
0.4999999999987202 / 0.4999999999987202
0.4999999999999994 / 0.4999999999999994
0.5 / 0.5
0.5 / 0.5
0.5 / 0.5
-0.5 / -0.5

上記の結果は、標準正規分布の確率密度関数を-∞から+∞まで定積分(もとい、広義積分)した値は、確率密度関数の性質上、1 ですが、この1は、上記のコードで求めた、F1(x) によって、a を十分大きな正の数(といっても、上記の結果から、a=9 程度のことですが。)として、

F1(a) - F1(-a) = 0.5 - (-0.5) = 1

と算出される結果に合致しています。

投稿2021/11/04 15:46

編集2021/11/05 22:44
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

python_wakaran

2021/11/05 13:47

回答ありがとうございます。以上のようにしたところ実行できました。 ここで質問なのですがこの不定積分を関数のように扱い、xに入る変数をあとから指定して積分値を求める方法はありますのでしょうか? kilesaさんの実行結果[2]のようにすればある範囲での積分を出すことはできるのですが、私の場合この積分を何度も行う必要があるプログラムを作成しているので、何度も積分する手間を省いて、一度不定積分を出力したうえでそこに数値を代入できれば楽になると考えているのですが。。
退会済みユーザー

退会済みユーザー

2021/11/05 16:11 編集

コメントありがとうございます。回答のほうに追記しました。
python_wakaran

2021/11/06 09:29

以上のようになること確認できました。 とても勉強になりました、ありがとうございます!
退会済みユーザー

退会済みユーザー

2021/11/06 13:59

解決したようでよかったです!私も調べながらの回答だったので勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問