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

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

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

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

Q&A

解決済

1回答

3260閲覧

Pythonでの積分について、integrate.quadを用いて-π/2からπ/2の範囲での積分をしたい

mag0123

総合スコア3

Python

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

0グッド

0クリップ

投稿2021/07/15 04:47

編集2021/07/15 10:02

実現したいこと

Pythonでの積分について、integrate.quadを用いて-π/2からπ/2の範囲での積分をしたい

発生している問題・エラーメッセージ

●RuntimeWarning: invalid value encountered in double_scalars
y_in = lambda phi: np.sin(phi)/(phi*(delta_in+Do*(1-np.cos(phi))))

●IntegrationWarning: The occurrence of roundoff error is detected, which prevents
the requested tolerance from being achieved. The error may be
underestimated.
integ_in = integrate.quad(y_in, (-1/2)*np.pi, (1/2)*np.pi)

●RuntimeWarning: invalid value encountered in double_scalars
y_out = lambda phi: np.sin(phi)/(phi*(delta_out+Do*(1-np.cos(phi))))

●IntegrationWarning: The occurrence of roundoff error is detected, which prevents
the requested tolerance from being achieved. The error may be
underestimated.
integ_out = integrate.quad(y_out, (-1/2)*np.pi, (1/2)*np.pi)

該当のソースコード

Python

1import numpy as np 2from scipy import integrate 3 4# 変数を定義 5delta_in = 0.15E-3 6delta_out = 1.00E-3 7delta_tc = 0.6E-3 8Do = 1.03E-3 9Di = 1.00E-3 10eps_0 = 8.854187E-12 11eps_r = 4.0 12h_core = 12.3E-3 13dia_in_core = 17.6E-3 14dia_out_core = 32.8E-3 15 16r_in = (dia_in_core/2) - delta_tc - Do/2 17r_out = (dia_out_core/2) + delta_tc + Do/2 18 19 20# 積分1 21y_in = lambda phi: np.sin(phi)/(phi*(delta_in+Do*(1-np.cos(phi)))) 22y_out = lambda phi: np.sin(phi)/(phi*(delta_out+Do*(1-np.cos(phi)))) 23integ_in = integrate.quad(y_in, (-1/2)*np.pi, (1/2)*np.pi) 24integ_out = integrate.quad(y_out, (-1/2)*np.pi, (1/2)*np.pi) 25 26L_T_in = h_core + delta_tc + Do 27L_T_out = L_T_in 28L_T = h_core*2+ (dia_out_core-dia_in_core) + Do 29 30 31 32C_tt_air_in = (Do/2.0)*eps_0*L_T_in * integ_in[0] 33C_tt_air_out = (Do/2.0)*eps_0*L_T_out * integ_out[0] 34 35 36 37# 積分2 38f = lambda phi, r: np.sin(phi)/(phi*( ((delta_out-delta_in)/(r_out-r_in))*(r-r_in + delta_in + Do*(1-np.cos(phi))))) 39val, err = integrate.dblquad(f, r_in, r_out, lambda phi: (-1/2)*np.pi, lambda phi: (1/2)*np.pi) 40 41C_tt_air_l = (Do/2.0)*eps_0 * val 42print("C_tt_air_l", C_tt_air_l) 43 44C_tt_ins = (np.pi*eps_0*eps_r*L_T)/(2*np.log(Do/Di)) 45print("C_tt_ins", C_tt_ins) 46 47C_tt_in = (C_tt_ins*C_tt_air_in)/(C_tt_ins+C_tt_air_in) 48C_tt_out = (C_tt_ins*C_tt_air_out)/(C_tt_ins + C_tt_air_out) 49C_tt_l = (C_tt_ins*C_tt_air_l)/(C_tt_ins + C_tt_air_l) 50 51C_tt = C_tt_in + C_tt_out + 2*C_tt_l

試したこと

積分範囲を、0からnp.pi、(-1/2)*np.piから0などにすると積分できましたが、
(-1/2)*np.piから(1/2)*np.piに関しては上記のようなエラーが出ます。

補足情報(FW/ツールのバージョンなど)

コードを全文掲載しました。

コード中の式は、工学系論文の式を引用しています。
引用した論文では、最終的にC_ttの値は、上記の変数の時におよそ1.124E-12の結果となるようです。

イメージ説明

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

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

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

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

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

jeanbiego

2021/07/15 05:13

<code>機能を使って、コードを囲ってください。読みやすくなります。 また、気になる部分の抜粋ではなくて、コピペだけでテストできるように、なるべく全体を記載したほうが有用な回答がつきやすいと思います。
mag0123

2021/07/15 06:38

jeanbiego様 修正依頼ありがとうございました。コードの掲載について修正しました。
guest

回答1

0

ベストアンサー

pythonの計算精度の問題で、途中で計算しきれなくなっているようです。(参考:15. 浮動小数点演算、その問題と制限)sin(φ)/φをsinc(φ/π)と置き換え(参考:numpy.sinc)て計算を省力化したところ、最後まで回るようになりました。(最初のコードでは、integ_inなどが計算できずにNaNになっていました)
しかし結果は、1.6141283310668653e-12ということで、まだ目標とは50%くらいずれていますね。途中の誤差の積み重ねでしょうか。精度を上げるには、途中の式を手でほぐして簡単な計算に置き換えていくのが王道かと思います。

python3

1import numpy as np 2from scipy import integrate 3 4# 変数を定義 5delta_in = 0.15E-3 6delta_out = 1.00E-3 7delta_tc = 0.6E-3 8Do = 1.03E-3 9Di = 1.00E-3 10eps_0 = 8.854187E-12 11eps_r = 4.0 12h_core = 12.3E-3 13dia_in_core = 17.6E-3 14dia_out_core = 32.8E-3 15 16r_in = (dia_in_core/2) - delta_tc - Do/2 17r_out = (dia_out_core/2) + delta_tc + Do/2 18# r_in: 0.007685000000000001 19# r_out: 0.017515000000000003 20 21# 積分1 22y_in = lambda phi: np.sinc(phi/np.pi)/(delta_in+Do*(1-np.cos(phi))) 23y_out = lambda phi: np.sinc(phi/np.pi)/(delta_out+Do*(1-np.cos(phi))) 24 25integ_in = integrate.quad(y_in, (-1/2)*np.pi, (1/2)*np.pi) 26integ_out = integrate.quad(y_out, (-1/2)*np.pi, (1/2)*np.pi) 27# integ_in: (8546.321590461577, 9.466839635601456e-05) 28# integ_out: (2154.5245517896133, 2.3920027417134726e-11) 29 30 31L_T_in = h_core + delta_tc + Do 32L_T_out = L_T_in 33L_T = h_core*2+ (dia_out_core-dia_in_core) + Do 34# L_T_in: 0.01393 35# L_T_out: 0.01393 36 37C_tt_air_in = (Do/2.0)*eps_0*L_T_in * integ_in[0] 38C_tt_air_out = (Do/2.0)*eps_0*L_T_out * integ_out[0] 39# C_tt_air_in: 5.428580300693041e-13 40# C_tt_air_out: 1.3685431112559984e-13 41 42# 積分2 43f = lambda phi, r: np.sinc(phi/np.pi)/( ((delta_out-delta_in)/(r_out-r_in))*(r-r_in + delta_in + Do*(1-np.cos(phi)))) 44val, err = integrate.dblquad(f, r_in, r_out, lambda phi: (-1/2)*np.pi, lambda phi: (1/2)*np.pi) 45 46C_tt_air_l = (Do/2.0)*eps_0 * val 47print("C_tt_air_l", C_tt_air_l) 48# C_tt_air_l 4.721164453460405e-13 49 50C_tt_ins = (np.pi*eps_0*eps_r*L_T)/(2*np.log(Do/Di)) 51print("C_tt_ins", C_tt_ins) 52# C_tt_ins 7.684597167088852e-11 53 54C_tt_in = (C_tt_ins*C_tt_air_in)/(C_tt_ins+C_tt_air_in) 55C_tt_out = (C_tt_ins*C_tt_air_out)/(C_tt_ins + C_tt_air_out) 56C_tt_l = (C_tt_ins*C_tt_air_l)/(C_tt_ins + C_tt_air_l) 57 58C_tt = C_tt_in + C_tt_out + 2*C_tt_l 59print(C_tt) 60# 1.6141283310668653e-12

追記

python3

1import sympy as sym 2sym.var("phi delta_out delta_in r_out r_in r Do") 3f = sym.sin(phi)/(phi*( ((delta_out-delta_in)/(r_out-r_in))*(r-r_in + delta_in + Do*(1-sym.cos(phi))))) 4display(f)

f

投稿2021/07/15 07:50

編集2021/07/15 23:22
jeanbiego

総合スコア3966

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

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

mag0123

2021/07/15 10:08

jeanbiego様 ご回答いただき誠にありがとうございます。 修正していただいたコードをこちらでも試したところ、同様の結果を得ました。 コード中の式は論文の式を参考にしていますが、一部は自分が式を設定しているものもあったりしますので一度式の部分を見直してみようと思います。 もう1点気になるところなのですが、積分2の重積分は正しく記述できていますでしょうか。 積分2で実現したい式の画像を補足情報に追加しています。 お忙しいところ恐縮ですが、ご回答いただければ幸いです。
jeanbiego

2021/07/15 23:35 編集

sympyを使ってfを表示してみましたが(回答欄に追記)、r-r_inの括弧位置がおかしいせいで、実現したい式とは異なっていますね。 あと、画像の重積分のところですが、rとφの積分範囲が逆ではないですか?
mag0123

2021/07/15 23:59

jeanbiego様 ご回答いただき誠にありがとうございます。 ご指摘していただいた式を修正したところ、計算結果が1.0206928711387264e-12で、1.124E-12との誤差が約-9.3%とだいぶ近づきました。 見落としていたところをご指摘いただきとても助かりました。 画像の積分範囲も逆になっていました。正しい積分の順序はφ→rの順だと思います。 コード中ではこれが実現できていますでしょうか。 お忙しいところ再々の質問申し訳ございません。
jeanbiego

2021/07/16 01:21

コード中では重積分の範囲等は問題ないように見えます。
mag0123

2021/07/16 04:05 編集

jeanbiego様 ご回答いただき誠にありがとうございます。 重積分の範囲の確認ありがとうございます。 この度は問題の解決にご協力いただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問