0

I am adapting Schorsch's answer in While loop inside for loop in Matlab to use in Python 3.5 for my problem.

I want to iterate over values in my t array. For each value, if the result of my calculation z converges (or doesn't converge after a maximum no. of iterations) I copy this to an array. Then I plot the results.

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()

I get an error: VisibleDeprecationWarning: using a non-integer number instead of an integer will result in an error in the future lines = """

Does this mean I have to change how I index the while or for loops, and if so how should I do this?

5
  • It probably means that you are indexing arrays using x[ii], and ii is not an integer. Something is wrong with your t array (the one you use in the to iterate the for loop). If it is suppose to be integer array, but somehow is float, you can do something like for ii in np.asarray(t, np.int32). Commented Dec 16, 2016 at 10:55
  • 2
    Your question title is misleading. Commented Dec 16, 2016 at 11:03
  • 1
    Why are you indexing with float values? I would suggest setting x and cvec to an empty list before the loops then just append the values as needed i.e. x.append(z). Or, you could use a counter to index x and cvec then increment it everytime you set an element. If you need to store the time as well just set something like timestamps = [] and append to that as well. Commented Dec 16, 2016 at 11:03
  • @pbreach If I have a t array with 1000 elements say, would it be more efficient to use the append function or start with an array of zeros as in my MWE? Commented Dec 16, 2016 at 11:09
  • 1
    Actually now that I think about it the easiest way would be to just use for idx, ii in enumerate(t): and then just do the indexing with idx no need for a counter or to switch to lists :). Before I didn't realize you were storing the values for x in the case of non-convergence. See here for enumerate function. Commented Dec 16, 2016 at 11:14

1 Answer 1

1

The issue is related with the lines x[ii] = and cvec[ii]. As you are trying to access non-integers indexes. Those indexes were generated on the following line:

(...)
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]
(...)

To solve the issue, there are several ways to do it, but the easiest is simply to access the same index the value from the t variable is on.

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()

Using the while loop to iterate the maximum times a value, while it doesn't converge

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()
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks @AdrianoMartins. I think there should be a while-loop counter(tutorialspoint.com/python/python_while_loop.htm). For the line elif abs(z-z_old) >= 0.01 and ii < maxiter: # no convergence but loop again, we change ii to counter using the example notation in the link.
Updated the answer. If I managed to understand correctly, that new code should do what you're expecting
OK thanks - is the break command in the second code block meant to be not indented?
Sorry about it. I had misunderstood the issue - and made some typos. Fixed it. Now it should loop until converge or give up if the max iterations are reached.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.