Reputation: 41
I have code which generates many N sequences and stores them. If I make runs
large then the loop can get stuck on the while N[j] > 0:
section of the code. What is the best way to include something to skip a step in the while loop, say if time exceeds a few seconds in that step in the loop and move to the next?
runs = 20
Lloc = 1
n0 = 1
#Empty list to store N series
N_array = []
#Empty list to store z series
z_array = []
for r in range(0,runs):
#Set initial z series values to be zero
z = [0]
#Set initial jump process values to be n0
N = [n0]
#Set iteration to be zero
j = 0
#While
while N[j] > 0:
z.append(z[j] + np.random.exponential(Lloc/(2*N[j]**2)))
#Pick jump at position j+1 to be N[j] -1 or +1 with prob 1/2
N.append(N[j] + np.random.choice([-1,1]))
#Update iteration
j = j+1
#Store N,z realisation if sum dz < 10 say
if sum(np.diff(z)) < 10:
N_array.append(N)
z_array.append(z)
#Completion
print((r+1)/runs*100,'%')
Upvotes: 1
Views: 313
Reputation: 7128
You can just measure time by yourself!
from time import perf_counter
#While
start = perf_counter()
while N[j] > 0:
z.append(z[j] + np.random.exponential(Lloc/(2*N[j]**2)))
#Pick jump at position j+1 to be N[j] -1 or +1 with prob 1/2
N.append(N[j] + np.random.choice([-1,1]))
#Update iteration
j = j+1
if perf_counter() - start > TIMEOUT:
break
Or even use Context for that:
class Timer:
def __enter__(self):
self.start = perf_counter()
return self
@property
def elapsed(self):
return perf_counter() - self.start
def __exit__(self, exc_type, exc_value, exc_traceback):
pass
with Timer() as t:
while True:
if t.elapsed > TIMEOUT:
break
As image357 pointed It's not ideal, as we still need to wait until one loop cycle finish what can last very long, but in your case it should be work as expected.
Upvotes: 2
Reputation: 471
I would use something like this:
import time
import multiprocessing as mp
def loop_body(i):
print(f"sleeping for {i} seconds")
time.sleep(i)
print(f"sleep of {i} seconds done")
max_wait_time = 2.1
i = 1
while i < 4:
proc = mp.Process(target=loop_body, args=(i,))
proc.start()
proc.join(max_wait_time)
proc.terminate()
i += 1
The idea is to spawn a separate process and wait for a certain amount of time. If the process isn't finished you can terminate it and move on to the next step.
Upvotes: 2