2016-12-16 18 views
0

私はSchorschの答えをWhile loop inside for loop in Matlabに適応させています。問題はPython 3.5で使用します。whileループとforループのPythonインデックス問題

t配列の値を繰り返し処理したいと思います。それぞれの値について、私の計算結果がzならば収束します(または最大反復回数の後に収束しません)。これを配列にコピーします。次に、結果をプロットします。

import numpy as np 
import matplotlib.pyplot as plt 

maxiter = 100 # max no. iterations in convergence loop 
t = 0.05*np.arange(10) 
z = 0.1 # initial guess 
x = np.zeros(len(t)) # array for results 
cvec = np.zeros(len(t)) # does loop converge? 

for ii in t: 

    print(ii) 

    convergence = 0 

    while convergence == 0: 

     z_old = z 
     z = ii*np.random.rand() # perform calculations 

     # check convergence 

     if abs(z-z_old) < 0.01: # convergence 
      # store result 
      convergence = 1 
      x[ii] = z 
      cvec[ii] = convergence 

     elif abs(z-z_old) >= 0.01 and ii < maxiter: # no convergence but loop again 
      convergence = 0 
     else: # no convergence, move on to next value in t array 
      convergence = 0 
      x[ii] = 1e3 
      cvec[ii] = convergence 
      break 

# plot result 
plt.figure() 
plt.plot(t[cvec==1],x[cvec==1],'x') 
plt.xlabel('t') 
plt.ylabel('x') 
plt.show() 

私はエラーを取得する:VisibleDeprecationWarning: using a non-integer number instead of an integer will result in an error in the future lines = """

は、この平均は私がどのようにIインデックスwhileforループを変更する必要がない、そしてもしそうなら、私はこれをどのようにしたらよいでしょうか?

+0

を収束していない間、それはおそらく、 '[II]は、' xを使って、配列のインデックスを作成していることを意味し、最大倍の値を反復するwhileループを使用して、 「ii」は整数ではない。あなたの 't'配列(forループを反復するために使う配列)に何か問題があります。もし整数配列であると思われていてfloatであれば、 'for ii in np.asarray(t、np.int32)'のようにすることができます。 –

+2

あなたの質問のタイトルは誤解を招くようなものです。 – Psytho

+1

なぜ浮動小数点値でインデックスを作成していますか?ループの前に空のリストに 'x'と' cvec'を設定して、必要に応じて値を追加する、つまり 'x.append(z)'を追加することをお勧めします。あるいは、あなたは 'x'と' cvec'にインデックスを付けるためにカウンタを使い、要素を設定するたびにインクリメントすることができます。時間を保存する必要がある場合は、 'timestamps = []'のようなものを設定し、それにも追加してください。 – pbreach

答えて

1

問題は、x[ii] =cvec[ii]という行に関連しています。非整数インデックスにアクセスしようとしています。 これらのインデックスは次の行に生成された:問題を解決するために

(...) 
t = 0.05*np.arange(10) #[ 0. , 0.05, 0.1 , 0.15, 0.2 , 0.25, 0.3 , 0.35, 0.4 , 0.45] 
(...) 

、そこにそれを行うには、いくつかの方法がありますが、最も簡単ではt変数から値がオンになっている同じインデックスにアクセスするだけです。

import numpy as np 
import matplotlib.pyplot as plt 

maxiter = 100 # max no. iterations in convergence loop 
t = 0.05*np.arange(10) 
z = 0.1 # initial guess 
x = np.zeros(len(t)) # array for results 
cvec = np.zeros(len(t)) # does loop converge? 

for idx, ii in enumerate(t): 

    print(ii) 

    convergence = 0 

    while convergence == 0: 

     z_old = z 
     z = ii*np.random.rand() # perform calculations 

     # check convergence 

     if abs(z-z_old) < 0.01: # convergence 
      # store result 
      convergence = 1 
      x[idx] = z 
      cvec[idx] = convergence 

     elif abs(z-z_old) >= 0.01 and ii < maxiter: # no convergence but loop again 
      convergence = 0 
     else: # no convergence, move on to next value in t array 
      convergence = 0 
      x[idx] = 1e3 
      cvec[idx] = convergence 
      break 

# plot result 
plt.figure() 
plt.plot(t[cvec==1],x[cvec==1],'x') 
plt.xlabel('t') 
plt.ylabel('x') 
plt.show() 

それは

import numpy as np 
import matplotlib.pyplot as plt 

maxiter = 100 # max no. iterations in convergence loop 
t = 0.05*np.arange(10) 
z = 0.1 # initial guess 
x = np.zeros(len(t)) # array for results 
cvec = np.zeros(len(t)) # does loop converge? 

for idx, ii in enumerate(t): 

    print(ii) 

    # Assume it wont converge 
    # So if we loop through all the max iterations and still no convergence, it is already marked 
    x[idx] = 1e3 
    cvec[idx] = 0 

    while iter in range(maxiter): 

     z_old = z 
     z = ii*np.random.rand() # perform calculations 

     if abs(z-z_old) < 0.01: # converge, therefore stop looping 
      x[idx] = z 
      cvec[idx] = 1 
      break 

# plot result 
plt.figure() 
plt.plot(t[cvec==1],x[cvec==1],'x') 
plt.xlabel('t') 
plt.ylabel('x') 
plt.show() 
+0

ありがとう@AdrianoMartins。私はwhileループカウンタ(https://www.tutorialspoint.com/python/python_while_loop.htm)があるはずだと思います。 'elif abs(z-z_old)> = 0.01かつii

+0

答えを更新しました。私が正しく理解できれば、その新しいコードはあなたが期待していることを達成するはずです –

+0

OK - 2番目のコードブロックの 'break'コマンドはインデントされていないことを意味しますか? –