from pylab import *
no_steps = 10000
number = random()
position = zeros(no_steps)
position[0] = 0
time = zeros(no_steps)
time[0] = 0
for i in range(1, no_steps):
time[i] = time[i-1] + 1
if number >= 0.5:
position[i] = position[i-1] + 1
number = random()
else:
position[i] = position[i-1] - 1
number = random()
plot(time, position)
number2 = random()
position2 = zeros(no_steps)
position2[0] = 0
time2 = zeros(no_steps)
time2[0] = 0
for t2 in range(1, no_steps):
time2[t2] = time[t2-1] + 1
if number2 >= 0.5:
position2[t2] = position2[t2-1] + 1
number2 = random()
else:
position2[t2] = position[t2-1] - 1
number2 = random()
plot(time2,position2)
This is supposed to generate random walks by generating a random number each time and checking the conditions. Therefore I assumed that if it works for one walk I can just add more of the same and put them all on the same graph at the end. However, apparently that's not how this works and the graphs that do end up being plotted are extremely similar with the difference in the positions being one of -2 for some reason. The code if I run the blocks separately from their own program will generate two completely different walks, it's just when I put them together that it stops working as intended. What exactly am I missing?
You've accidentally reused variables from the first plot:
for t2 in range(1, no_steps):
time2[t2] = time[t2-1] + 1
^^^^^ ^^^^
if number2 >= 0.5:
position2[t2] = position2[t2-1] + 1
number2 = random()
else:
position2[t2] = position[t2-1] - 1
^^^^^^^^^ ^^^^^^^^
number2 = random()
plot(time2,position2)
I would generate the random walk with a function so you don't have to worry about renaming variables like this:
import numpy
from pylab import *
no_steps = 10000
def random_walk(no_steps):
# 2 * [0, 1] - 1 -> [0, 2] - 1 -> [-1, 1]
directions = 2 * numpy.random.randint(0, 2, size=(1, no_steps)) - 1
positions = numpy.cumsum(directions)
positions -= positions[0] # To make it start from zero
return positions
time1 = numpy.arange(0, no_steps)
plot(time1, random_walk(no_steps))
savefig('1.png')
clf()
time2 = numpy.arange(0, no_steps)
plot(time2, random_walk(no_steps))
savefig('2.png')
Related
Here are two codes, which handles the same data and returns the essentially the same result.
1.
for j in range(np.shape(I)[0]):
if (j%int(np.shape(I)[0]/10) ==0):
print(str(j/np.shape(I)[0]*100)+'% ........... is done')
for k in range(np.shape(I)[1]):
for i in range(np.shape(I)[1]):
if (abs(time_resc_array[j,k]-time_tar[i]) < t_toler):
I_pp[i] = I_pp[i]+ I[j,k]
count[i]=count[i]+1
norm[i]=norm[i]+1
break
here I and time_resc_array are the 290*10000 numpy arrays, and count, I_pp, and time_tar are the 290 numpy arrays.
2.
trial = int(n_rep * N/10)
freq11 = freq1 * 10**6
average = 100*10**6
tau = np.zeros(trial)
pp_seq = int(n_rep2*(t_unit2 * 10 **-9) * 10 * average )
Narray = np.arange(0,pp_seq)
pp_tk = Narray * 1/(10*average) # divide 1 period of average freq by 10
pp_data = np.zeros(pp_seq)
pp_cnt = np.zeros(pp_seq)
Narray = np.arange(1, n_rep2+1)
oper_tk = Narray * (t_unit2 * 10 **-9)
for i in range(0,A):
if (i%int(trial)==0):
print(str(i/trial*100)+'.......... % is done')
ptr = i%n_rep2
tau[i] = oper_tk[ptr] * freq11[i//n_rep2][i%n_rep2] / average
for j in range(0, pp_seq):
if ptr == 0:
break
elif tau[i] < pp_tk[j]:
pp_data[j] += I[i//n_rep2][i%n_rep2]
pp_cnt[j] += 1
break
where freq1 and I are the 290*10000 array. The first code is approximately 4-5 times slower than the second one, which I don't grasp the reason. Could somebody please help me understand what I am doing wrong with the first one?
p.s. the second code is not of mine, so it can be deleted sooner or later.
import math
import random
import time
stress_base = 3
stress_report = 0
i = 0
while True:
start = time.time()
a = random.randrange(0,9)
stress_base = stress_base + a
stress_report = stress_report + 1
if stress_report % 10000000 == 0:
time.sleep(.0001)
end = time.time()
print((end - start) -.0001,'=',i)
i = i + 1
this code is a simple benchmark on a system. (I know that even if I fix it won't be useful, its an exercise) the result is how long it takes to add up a million random numbers from 0-9, and the timer for some reason seems completely off, am I missing something?
here are some results
0.0018946098327636718 = 0
0.0018938945770263671 = 1
0.002891914749145508 = 2
0.0018953250885009765 = 3
0.0018936561584472656 = 4
0.0018948482513427734 = 5
0.012865679168701172 = 6
0.0008999275207519531 = 7
0.001895086669921875 = 8
0.0018958019256591796 = 9
the time between each one is roughly half a second. when I increase the number of equations these times don't increase.
Your start variable should be outside of the loop, because currently the value is to add the last random number rather than adding all the random numbers. Also, your modulo was set to check for 10,000,000 when it should be 1,000,000. Correcting this, the variability is between 1.3-1.6 seconds. I also changed the value of i to represent how many million numbers have been added. Here is the code:
import math
import random
import time
stress_base = 3
stress_report = 0
i = 1
while True:
start = time.time()
while True:
a = random.randrange(0,9)
stress_base = stress_base + a
stress_report = stress_report + 1
if stress_report % 1000000 == 0:
time.sleep(.0001)
break
end = time.time()
print((end - start) -.0001,'=',i)
i = i + 1
Here is a part of the output:
1.6038764881134033 = 1
1.5193711685180664 = 2
1.4884077476501465 = 3
1.4721638130187988 = 4
1.5818635391235352 = 5
1.4038864540100098 = 6
1.4031793045043945 = 7
1.3717972206115723 = 8
1.472563164138794 = 9
I am trying to sum the values in the 'Callpayoff' list however am unable to do so, print(Callpayoff) returns a vertical list:
0
4.081687878300656
1.6000410648454846
0.5024316862043037
0
so I wonder if it's a special sublist ? sum(Callpayoff) does not work unfortunately. Any help would be greatly appreciated.
def Generate_asset_price(S,v,r,dt):
return (1 + r * dt + v * sqrt(dt) * np.random.normal(0,1))
def Call_Poff(S,T):
return max(stream[-1] - S,0)
# initial values
S = 100
v = 0.2
r = 0.05
T = 1
N = 2 # number of steps
dt = 0.00396825
simulations = 5
for x in range(simulations):
stream = [100]
Callpayoffs = []
t = 0
for n in range(N):
s = stream[t] * Generate_asset_price(S,v,r,dt)
stream.append(s)
t += 1
Callpayoff = Call_Poff(S,T)
print(Callpayoff)
plt.plot(stream)
Right now you're not appending values to a list, you're just replacing the value of Callpayoff at each iteration and printing it. At each iteration, it's printed on a new line so it looks like a "vertical list".
What you need to do is use Callpayoffs.append(Call_Poff(S,T)) instead of Callpayoff = Call_Poff(S,T).
Now a new element will be added to Callpayoffs at every iteration of the for loop.
Then you can print the list with print(Callpayoffs) or the sum with print(sum(Callpayoffs))
All in all the for loop should look like this:
for x in range(simulations):
stream = [100]
Callpayoffs = []
t = 0
for n in range(N):
s = stream[t] * Generate_asset_price(S,v,r,dt)
stream.append(s)
t += 1
Callpayoffs.append(Call_Poff(S,T))
print(Callpayoffs,"sum:",sum(Callpayoffs))
Output:
[2.125034975231003, 0] sum: 2.125034975231003
[0, 0] sum: 0
[0, 0] sum: 0
[0, 0] sum: 0
[3.2142923036024342, 4.1390018820809615] sum: 7.353294185683396
I'm running a population model, and the wrong numbers always come out because I'm setting the variables to new values, but then when I want to use the old variables, the loop automatically updates itself and uses the new ones.
juvenile_population = 10
adult_population = 10
senile_population = 1
juvenile_survival = 1
adult_survival = 1
senile_survival = 0
birth_rate = 2
generations = 5
counter = 0
while counter < generations:
juvenile_population = adult_population * birth_rate
adult_population = juvenile_population * juvenile_survival
senile_population = (adult_population * adult_survival) (senile_population * senile_survival)
total_population = juvenile_population + adult_population + senile_population
print("Juvenile: ",juvenile_population)
print("Adult: ",adult_population)
print("Senile: ",senile_population)
print("Total: ",total_population)
counter += 1
A friend said to set new named variables, but then after one loop, won't you get the same problem again? I want the variables to update, but only after they've been printed, if that makes sense.
Any suggestions?
You are overwriting the existing values with new values. With Python you can merge all four lines into one like this:
juvenile_population, adult_population, senile_population, total_population = adult_population * birth_rate, juvenile_population * juvenile_survival, (adult_population * adult_survival) (senile_population * senile_survival), juvenile_population + adult_population + senile_population
This will assign all the values at once, without overwriting them first.
Per #Selcuk, you could use variable unpacking directly, but even with nicer formatting it looks unwieldly:
juvenile_population, adult_population, senile_population, total_population = (adult_population * birth_rate,
juvenile_population * juvenile_survival,
(adult_population * adult_survival) (senile_population * senile_survival),
juvenile_population + adult_population + senile_population)
My suggestion would be to either write a helper function, and keep "like" values in a dictionary like so:
populations = {'juvenile': 10,
'adult': 10,
'senile': 1
}
survivals = {'juvenile': 1,
'adult': 1,
'senile': 0}
birth_rate = 2
generations = 5
def update_population(pops):
juvie = pops['adult'] * birth_rate
adults = pops['juvenile'] * survivals['juvenile']
seniles = pops['adult'] * survivals['adult'] + (pops['senile'] * survivals['senile'])
return {k:v for k,v in zip(['juvenile','adult','senile'],[juvie,adults,seniles])}
counter = 0
while counter < generations:
populations = update_population(populations.copy())
total_population = sum(populations.values())
print("Juvenile: ",populations['juvenile'])
print("Adult: ",populations['adult'])
print("Senile: ",populations['senile'])
print("Total: ",total_population)
counter += 1
(Python) Given two numbers A and B. I need to find all nested "groups" of numbers:
range(2169800, 2171194)
leading numbers: 21698XX, 21699XX, 2170XX, 21710XX, 217110X, 217111X,
217112X, 217113X, 217114X, 217115X, 217116X, 217117X, 217118X, 2171190X,
2171191X, 2171192X, 2171193X, 2171194X
or like this:
range(1000, 1452)
leading numbers: 10XX, 11XX, 12XX, 13XX, 140X, 141X, 142X, 143X,
144X, 1450, 1451, 1452
Harder than it first looked - pretty sure this is solid and will handle most boundary conditions. :) (There are few!!)
def leading(a, b):
# generate digit pairs a=123, b=456 -> [(1, 4), (2, 5), (3, 6)]
zip_digits = zip(str(a), str(b))
zip_digits = map(lambda (x,y):(int(x), int(y)), zip_digits)
# this ignores problems where the last matching digits are 0 and 9
# leading (12000, 12999) is same as leading(12, 12)
while(zip_digits[-1] == (0,9)):
zip_digits.pop()
# start recursion
return compute_leading(zip_digits)
def compute_leading(zip_digits):
if(len(zip_digits) == 1): # 1 digit case is simple!! :)
(a,b) = zip_digits.pop()
return range(a, b+1)
#now we partition the problem
# given leading(123,456) we decompose this into 3 problems
# lows -> leading(123,129)
# middle -> leading(130,449) which we can recurse to leading(13,44)
# highs -> leading(450,456)
last_digits = zip_digits.pop()
low_prefix = reduce(lambda x, y : 10 * x + y, [tup[0] for tup in zip_digits]) * 10 # base for lows e.g. 120
high_prefix = reduce(lambda x, y : 10 * x + y, [tup[1] for tup in zip_digits]) * 10 # base for highs e.g. 450
lows = range(low_prefix + last_digits[0], low_prefix + 10)
highs = range(high_prefix + 0, high_prefix + last_digits[1] + 1)
#check for boundary cases where lows or highs have all ten digits
(a,b) = zip_digits.pop() # pop last digits of middle so they can be adjusted
if len(lows) == 10:
lows = []
else:
a = a + 1
if len(highs) == 10:
highs = []
else:
b = b - 1
zip_digits.append((a,b)) # push back last digits of middle after adjustments
return lows + compute_leading(zip_digits) + highs # and recurse - woohoo!!
print leading(199,411)
print leading(2169800, 2171194)
print leading(1000, 1452)
def foo(start, end):
index = 0
is_lower = False
while index < len(start):
if is_lower and start[index] == '0':
break
if not is_lower and start[index] < end[index]:
first_lower = index
is_lower = True
index += 1
return index-1, first_lower
start = '2169800'
end = '2171194'
result = []
while int(start) < int(end):
index, first_lower = foo(start, end)
range_end = index > first_lower and 10 or int(end[first_lower])
for x in range(int(start[index]), range_end):
result.append(start[:index] + str(x) + 'X'*(len(start)-index-1))
if range_end == 10:
start = str(int(start[:index])+1)+'0'+start[index+1:]
else:
start = start[:index] + str(range_end) + start[index+1:]
result.append(end)
print "Leading numbers:"
print result
I test the examples you've given, it is right. Hope this will help you
This should give you a good starting point :
def leading(start, end):
leading = []
hundreds = start // 100
while (end - hundreds * 100) > 100:
i = hundreds * 100
leading.append(range(i,i+100))
hundreds += 1
c = hundreds * 100
tens = 1
while (end - c - tens * 10) > 10:
i = c + tens * 10
leading.append(range(i, i + 10))
tens += 1
c += tens * 10
ones = 1
while (end - c - ones) > 0:
i = c + ones
leading.append(i)
ones += 1
leading.append(end)
return leading
Ok, the whole could be one loop-level deeper. But I thought it might be clearer this way. Hope, this helps you...
Update :
Now I see what you want. Furthermore, maria's code doesn't seem to be working for me. (Sorry...)
So please consider the following code :
def leading(start, end):
depth = 2
while 10 ** depth > end : depth -=1
leading = []
const = 0
coeff = start // 10 ** depth
while depth >= 0:
while (end - const - coeff * 10 ** depth) >= 10 ** depth:
leading.append(str(const / 10 ** depth + coeff) + "X" * depth)
coeff += 1
const += coeff * 10 ** depth
coeff = 0
depth -= 1
leading.append(end)
return leading
print leading(199,411)
print leading(2169800, 2171194)
print leading(1000, 1453)
print leading(1,12)
Now, let me try to explain the approach here.
The algorithm will try to find "end" starting from value "start" and check whether "end" is in the next 10^2 (which is 100 in this case). If it fails, it will make a leap of 10^2 until it succeeds. When it succeeds it will go one depth level lower. That is, it will make leaps one order of magnitude smaller. And loop that way until the depth is equal to zero (= leaps of 10^0 = 1). The algorithm stops when it reaches the "end" value.
You may also notice that I have the implemented the wrapping loop I mentioned so it is now possible to define the starting depth (or leap size) in a variable.
The first while loop makes sure the first leap does not overshoot the "end" value.
If you have any questions, just feel free to ask.