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

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

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

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

解決済

2回答

410閲覧

エラーの解決、条件によって中身が変化する関数を作りたい ValueError:

higasi

総合スコア3

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

0グッド

1クリップ

投稿2023/11/10 03:00

編集2023/11/10 03:39

実現したいこと

計算処理を行いたい、が初心者なのでエラーをどう解決するべきなのかがわからない

前提

x=v/v_c の値で条件によりA(v/v_c)の関数が(F、G、H)変更するようにしたいけど配列をそのまま渡してしまうからany(),all()って聞かれてしまう。
A(x)=(G,G,G,G,F,F,F,F,F,H,H,H,H)みたく条件で変化する関数を作りたい

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

--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-51-903ba0a3dfc3> in <module> 60 def P2(v): 61 return P(v)*ndgdb ---> 62 np.savetxt("{}/P_{}_{}_g^-{}B^-{}_g10^0-4_B10^0-4.txt".format(date,j,k,p,q),P2(v)) 63 <ipython-input-51-903ba0a3dfc3> in P2(v) 59 y[l]=P(v[l]) 60 def P2(v): ---> 61 return P(v)*ndgdb 62 np.savetxt("{}/P_{}_{}_g^-{}B^-{}_g10^0-4_B10^0-4.txt".format(date,j,k,p,q),P2(v)) 63 <ipython-input-51-903ba0a3dfc3> in P(v) 54 v_c=3*g**2*Q*B*sin_pa/(2*m*c*(2*np.pi)) 55 def P(v): ---> 56 return (np.sqrt(3)*Q**3*B*sin_pa/(m*c**2))*A(v/v_c) 57 y=np.zeros(N) 58 for l in range(N): <ipython-input-51-903ba0a3dfc3> in A(x) 35 36 def A(x): ---> 37 if x <= 5.0*1e-3: 38 return G(x) 39 elif 5.0*1e-3 < x < 30: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

該当のソースコード

python

1from scipy.special import kv 2import matplotlib.pyplot as plt 3from scipy.integrate import quad 4import numpy as np 5import math 6from math import gamma 7from sympy import * 8import os 9from matplotlib import rc 10from decimal import Decimal , ROUND_HALF_UP 11from scipy.optimize import curve_fit 12import seaborn as sns 13 14import itertools 15 16date="20231102A" 17 18m=9.1093837015e-31 * 1000 19c=299792458 * 100 20Q=4.803204673e-10 21pa=np.pi/2 22sin_pa=np.sin(pa) 23a = gamma(1/3) 24 25xs=np.logspace(-5, 3, 10000) 26 27f = lambda z: kv(5/3,z) 28 29def F(x): 30 return quad(f,x,np.inf)[0]*x 31def G(x): 32 return (4*np.pi/np.sqrt(3)/a)*(x/2)**(1/3) 33def H(x): 34 return ((np.pi/2)**(1/2))*(x**(1/2))*(np.exp(-x)) 35 36def A(x): 37 if x <= 5.0*1e-3: 38 return G(x) 39 elif 5.0*1e-3 < x < 30: 40 return F(x) 41 else: 42 return H(x) 43 44p=2 45q=3 46N=(15-0)*10 47v=np.logspace(0,15,N) 48s = 0 49for j in range(0,41): 50 for k in range(0,41): 51 g=10**(0.1*j) 52 B=10**(0.1*k) 53 ndgdb=(g**(-p))*(B**(-q))*((10**(0.1*(j+1)))-(10**(0.1*j)))*((10**(0.1*(k+1)))-(10**(0.1*k))) 54 v_c=3*g**2*Q*B*sin_pa/(2*m*c*(2*np.pi)) 55 def P(v): 56 return (np.sqrt(3)*Q**3*B*sin_pa/(m*c**2))*A(v/v_c) 57 y=np.zeros(N) 58 for l in range(N): 59 y[l]=P(v[l]) 60 def P2(v): 61 return P(v)*ndgdb 62 np.savetxt("{}/P_{}_{}_g^-{}B^-{}_g10^0-4_B10^0-4.txt".format(date,j,k,p,q),P2(v)) 63

試したこと

調べて、模索中
for文で逐次処理対応させられたら大丈夫かと思ったが同じようにエラーが出てしまう

import itertools #### j k l ### p=2 q=3 N=(15-0)*10 v=np.logspace(0,15,N) s = 0 for j in range(0,4): for k in range(0,4): g=10**(0.1*j) B=10**(0.1*k) ndgdb=(g**(-p))*(B**(-q))*((10**(0.1*(j+1)))-(10**(0.1*j)))*((10**(0.1*(k+1)))-(10**(0.1*k))) v_c=3*g**2*Q*B*sin_pa/(2*m*c*(2*np.pi)) CC=v/v_c Z=np.zeros(N) for mm in range(N): Z[mm]=A(CC[mm]) np.savetxt("{}/A_C_{}_{}_g^-{}B^-{}_g10^0-4_B10^0-4.txt".format(date,j,k,p,q),A(CC))
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-48-4af7f2999ddc> in <module> 17 for mm in range(N): 18 Z[mm]=A(CC[mm]) ---> 19 np.savetxt("{}/A_C_{}_{}_g^-{}B^-{}_g10^0-4_B10^0-4.txt".format(date,j,k,p,q),A(CC)) 20 21 <ipython-input-36-a26b605d64ec> in A(x) 1 def A(x): ----> 2 if x <= 5.0*1e-3: 3 return G(x) 4 elif 5.0*1e-3 < x < 30: 5 return F(x) ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

解決後の後学勉強のため
np.vectorizeを使ってみる (np.vectorize(A)(v/v_c)だとうまく計算された)(np.vectorize(A(v/v_c))だとエラーになる

return (np.sqrt(3)*Q**3*B*sin_pa/(m*c**2))*np.vectorize(A(v/v_c))
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-56-8cbe0f1e7b70> in <module> 57 y=np.zeros(N) 58 for l in range(N): ---> 59 y[l]=P(v[l]) 60 def P2(v): 61 return P(v)*ndgdb <ipython-input-56-8cbe0f1e7b70> in P(v) 54 v_c=3*g**2*Q*B*sin_pa/(2*m*c*(2*np.pi)) 55 def P(v): ---> 56 return (np.sqrt(3)*Q**3*B*sin_pa/(m*c**2))*np.vectorize(A(v/v_c)) 57 y=np.zeros(N) 58 for l in range(N): TypeError: unsupported operand type(s) for *: 'float' and 'vectorize'

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

windows 11
jupyter notebook

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

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

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

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

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

guest

回答2

0

横入りですみません。 気になったので。

解決後の後学勉強のため
np.vectorizeを使ってみる (np.vectorize(A)(v/v_c)だとうまく計算された)(np.vectorize(A(v/v_c))だとエラーになる

この疑問が出るのは関数呼び出しについての理解があいまいなためだと思います。

pythonで関数some_funcを呼び出すときには以下のように書きます。

python

1sum_func(arg1, arg2)

このときの sum_funcとは何なのか考えたことありますか? これは関数の名前ではありますが、実はただの変数名なのです。
pythonでは、変数名の後に「()」を付けると、それは変数に代入されている関数の呼び出しだと解釈されます。

変数の後に何か付けて解釈させるというしくみはリストや辞書でも同様です。

python

1person['name'] 2person_list[10]

変数名の後に「[]」を付けるとそれは、リストや辞書からの要素の取り出しと解釈され、対応するインデックスやキーに対応する値が取り出されます。
また、この書式は連続で作用させることもできます。

python

1p = person_list[10] 2p['name] 3 4person_list[10]['name']

上の2行と下の一行は同じ操作になります。 person_listのインデックス10の値(=辞書である想定)が取り出され、続けてその name キーの値を取り出しています。

pythoでは関数でも同様のことができます。ただし、そう書くには、上記のリストの要素が辞書であったように、関数を返す関数である必要があります。

python

1def make_adder(n): 2 def add_fun(x): 3 return x + n 4 return add_fun 5 6add2 = make_adder(2) 7add10 = make_adder(10) 8 9print(add2(5)) 10# 7が表示される。 11 12print(add10(5)) 13# 15が表示される。

make_adder()は関数を返す関数です。 引数で与えた数だけ増やした値を返す関数を作って返します。作った関数はadd2 や add10 のような変数に代入するこおtで、defで定義したときと同じように使うことができます。
また、make_adderが返した関数をそのまま使うこともできます。

python

1print(make_adder(8)(10) 2# 18が表示される。

ここでは まず、 make_adder(8) が実行され、 **「8を足す関数」**が返されます。 その返った関数を10を引数にして呼び出しているので、 結果として18が返り、 printで表示されます。

質問の記述を見てみます。
まず、np.vectorize()関数ですが、これは関数を受け取り、その関数の引数にベクトルを使えるようにした関数を返す関数です。

質問の、np.vectorize(A(v/v_c) ですが、 これは、 np.vectorize()の引数に、 A(v/v_c)が指定されています。これは関数A()の呼び出しです。 関数Aは定義を見ると何らかの値を返す関数のようです。 そして、返った値が np.vector()に渡されます。 np.vectorizeは関数を引数に取るものですから、間違えた使いかたのように見えます。

次にnp.vectorize(A)(v/v_c) ですが、これは先に説明した 関数を2回呼び出す形です。 左側は np.vectorize(A) は、関数Aをベクトルに対応したものが返されます。 想定通りの使いかたです。 そしてその関数を v/v_c を引数にして呼び出しています。 これがベクトルであれば、想定通りの動作をすることになります。

投稿2023/11/10 06:21

TakaiY

総合スコア14298

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

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

higasi

2023/11/10 07:40

丁寧な解説とても助かります。ありがとうございます。 調べながら試行錯誤していく形で進めているので、こういった詳しい解説はとてもありがたいです。 pythonという世界の広さの片鱗を味わった気がします。頑張って勉強します。 ありがとうございました。
guest

0

ベストアンサー

python

1def P(v): 2 return (np.sqrt(3)*Q**3*B*sin_pa/(m*c**2))*np.vectorize(A)(v/v_c)

投稿2023/11/10 03:18

PondVillege

総合スコア1581

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

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

higasi

2023/11/10 03:31

ありがとうございます。無事に進むことができました。本当にありがとうございます。 恐縮なのですが np.vectorize(A)(v/v_c)では 問題がなくて、 np.vectorize(A(v/v_c))では TypeError: unsupported operand type(s) for *: 'float' and 'vectorize' になるというのが心残りで...、後学のために、教えていただくことは可能でしょうか。もしくは、詳しく書かれてるサイトでも構いませんのでお願いします。
PondVillege

2023/11/10 04:35 編集

これは,関数Aを,n階のnumpyオブジェクトで操作できるようにvectorizeするものです.したがって,np.vectorize(A)はCallableを返します. 関数Aが,numpy.float32と,numpy.ndarrayの2つを受け取るような実装であったため,従来の記法ではif文の動作に互換がなくエラーになっています.numpy.float32で受け取ろうが,numpy.ndarrayで受け取ろうが,各要素に対する条件分岐として動作するようにしたまでのことです. 愚直に分岐を書くなら,if isinstance(v, numpy.float32)みたいな書き方で従来の関数に値を渡し,forで書いてみたと追記いただいたものは,elseの項に書くかちゃんとelif isinstance(v, numpy.ndarray):で分岐させて関数に値を渡すみたいなことになります.めんどいのでnp.vectorizeがいいですね.
higasi

2023/11/10 05:14

親切丁寧にありがとうございます。 少しずつ動かすのに慣れていけるよう、しっかりと勉強していきたいと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問