Numba fails to parallelize a loop - python

The following code runs but the loop with prange fails to be parallelized, although it it clearly paralellizable:
import numpy as np
from numba import njit, prange
#njit(parallel=True)
def f1(money, u, v, cost_u, cost_v):
# task: find index of u iu_opt and index of v iv_opt
# such that u[iu_opt] + v[iv_opt] is maximal subject
# to cost_u[iu_opt] + cost_v[iv_opt] < money
na = money.size
ncu = cost_u.size
ncv = cost_v.size
iu_opt = np.empty((na,),dtype=np.int16)
iv_opt = np.empty((na,),dtype=np.int16)
for ia in prange(na):
money_i = money[ia]
ivbest = 0 # initially pick iv = 0
# find max iu corresponding to iv = 0
for iu in range(ncu-1,-1,-1):
if cost_u[iu] + cost_v[0] < money_i: break
iubest = iu
# compute initial score
score_best = u[iu] + v[0]
# then try to increase iv
for iv in range(1,ncv):
# it not enough money for u_0
if cost_v[iv] + cost_u[0] > money_i: break
while cost_v[iv] + cost_u[iu] > money_i:
iu -= 1
assert iu >= 0
score_now = u[iu] + v[iv]
if score_now > score_best:
ivbest = iv
iubest = iu
score_best = score_now
iu_opt[ia] = iubest
iv_opt[ia] = ivbest
return iu_opt, iv_opt
na = 50
ncu = 204
ncv = 205
money = np.arange(na)/(na)
cost_u = np.arange(ncu)/ncu
u = np.cumsum(np.random.random_sample(ncu))
cost_v = np.arange(ncv)/ncv
v = np.cumsum(np.random.random_sample(ncv))
iu, iv = f1(money, u, v, cost_u, cost_v)
f1.parallel_diagnostics(level=4)
If this helps, the setup of the problem is the following: value of u[i] costs cost_u[i] and value of v[j] costs cost_v[j] (all these sequences are strictly increasing), for each value money[ia] we want to find i and j maximizing u[i] + v[j] given that cost_u[i] + cost_v[j] cannot exceed money[ia].

In case someone ever has a similar problem, I finally made it work by splitting insides of the big loop into another njit function. Here is the code:
import numpy as np
from numba import njit, prange
#njit(parallel=True)
def f1(money, u, v, cost_u, cost_v):
# task: find index of u iu_opt and index of v iv_opt
# such that u[iu_opt] + v[iv_opt] is maximal subject
# to cost_u[iu_opt] + cost_v[iv_opt] < money
na = money.size
iu_opt = np.empty((na,),dtype=np.int16)
iv_opt = np.empty((na,),dtype=np.int16)
for ia in prange(na):
money_i = money[ia]
iubest, ivbest = f1_int(money_i,u,v,cost_u,cost_v)
iu_opt[ia] = iubest
iv_opt[ia] = ivbest
return iu_opt, iv_opt
#njit
def f1_int(money_i,u,v,cost_u,cost_v):
ivbest = 0 # initially pick iv = 0
ncu = cost_u.size
ncv = cost_v.size
# find max iu corresponding to iv = 0
for iu in range(ncu-1,-1,-1):
if cost_u[iu] + cost_v[0] < money_i: break
iubest = iu
# compute initial score
score_best = u[iu] + v[0]
# then try to increase iv
for iv in range(1,ncv):
# it not enough money for u_0
if cost_v[iv] + cost_u[0] > money_i: break
while cost_v[iv] + cost_u[iu] > money_i:
iu -= 1
assert iu >= 0
score_now = u[iu] + v[iv]
if score_now > score_best:
ivbest = iv
iubest = iu
score_best = score_now
return iubest, ivbest
na = 50
ncu = 204
ncv = 205
money = np.arange(na)/(na)
cost_u = np.arange(ncu)/ncu
u = np.cumsum(np.random.random_sample(ncu))
cost_v = np.arange(ncv)/ncv
v = np.cumsum(np.random.random_sample(ncv))
iu, iv = f1(money, u, v, cost_u, cost_v)
f1.parallel_diagnostics(level=4)
This does not really answer the question why the problem happens, but works somehow.

Related

Setting limits. I want QH = 1 if QH > 1 but I don't know how to do it or where to put it

The code is solving an integral using the trapezium rule. I need to set limits for QH so if QH > 1 then QH = 1. I cant seem to get what I've done below to work properly.
## Solve ODE
QH = odeint(model, QH0, z, atol = 1.0e-8, rtol = 1.0e-8)
QHe = odeint(model1, QHe0, z, atol = 1.0e-8, rtol = 1.8e-8)
if QH > 1:
QH == 1
if QHe > 1:
QHe == 1
#Solving Thomson Optical Depth Integral for Hydrogen
def f_hydrogen(z_in):
Hz = H0*math.sqrt(OMEGAm*((1+z_in)**3)+OMEGAlam)
flatQH = QH.flatten()
QH_int = np.interp(z_in, z[::-1], flatQH[::-1])
return QH_int*(((1+z_in)**2)/Hz)
a = 0
z1 = 7
n = 1000
hei = (z1-a)/n
k = 0
#sum = 0
sum = np.zeros(n+1)
while (k<n):
x_in = a + (k*hei)
if k < n-1 :
sum[k + 1] = sum[k] + f_hydrogen(x_in)
k = k + 1
int_a = (hei/2)*((f_hydrogen(a) + f_hydrogen(z1)) + (2*sum))
tH = (c)*(sigma)*(nbarH)*(1+(y/(4*x)))*(int_a)
for index, val in enumerate(tH):
print("Thomson Optical Depth - Hydrogen = ", index, val)

Solve waterhammer PDE in numpy/scipy

I’ve been trying to solve the water hammer PDE’s from the Maple example linked below in python (numpy/scipy). I’m getting very unstable results. Can anyone see my mistake? Guessing something is wrong with the boundary conditions.
https://www.maplesoft.com/support/help/view.aspx?path=applications/WaterHammer
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
## Parameters
Dia = 0.1
V = 14.19058741 # Stead state
p = 1000 # Liquid density
u = 0.001 # Viscosity
L = 25
e = 0.0001 # Roughness
Psource = 0.510E6
thick = 0.001
E= 7010*10**9
K=20010E6
Vsteady= 14.19058741
Ks = 1/((1/K)+(Dia/E*thick))
# Darcy-Weisbach
def Friction(V):
Rey = ((Dia*V*p)/u)
fL = 64/Rey
fT = 1/((1.8*np.log10((6.9/Rey) + (e/(3.7*Dia))**1.11))**2)
if Rey >= 0 and Rey < 2000:
return fL
if Rey >= 2000 and Rey<4000:
return fL + ((fT-fL)*(Rey-2000))/(4000-2000)
if Rey >= 4000:
return fT
return 0
def model(D, t):
V = D[:N]
P = D[N:]
dVdt = np.zeros(N)
for i in range(1, len(dVdt)-1):
dVdt[i] = -(1/p)*((P[i+1]-P[i-1])/2*dx)-((Friction(np.abs(V[i]))*(np.abs(V[i])**2))/(2*Dia))
dPdt = np.zeros(N)
for i in range(1, len(dPdt)-1):
dPdt[i] = -((V[i+1]-V[i-1])/(2*dx))*Ks
if t < 2:
dVdt[29] = 0
else:
dVdt[29] = -1
dPdt[29] = 0
dVdt[0] = dVdt[1]
return np.append(dVdt,dPdt)
N = 30
x = np.linspace(0, L, N)
dx = x[1] - x[0]
## Initial conditions
Vi_0 = np.ones(N)*Vsteady
Pi_0 = np.arange(N)
for i in Pi_0:
Pi_0[i] = Psource - (i*dx/L)*Psource
# initial condition
y0 = np.append(Vi_0, Pi_0)
# time points
t = np.linspace(0,3,10000)
# solve ODE
y = odeint(model,y0,t)
Vr = y[:,0:N]
Pr = y[:,N:]
plt.plot(t,Pr[:,5])

How to find Average directional movement for stocks using Pandas?

I have a dataframe of OHLCV data. I would like to know if anyone knows any tutorial or any way of finding ADX(Average directional movement ) using pandas?
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt
import datetime as dt
import numpy as nm
start=dt.datetime.today()-dt.timedelta(59)
end=dt.datetime.today()
df=pd.DataFrame(yf.download("MSFT", start=start, end=end))
The average directional index, or ADX, is the primary technical indicator among the five indicators that make up a technical trading system developed by J. Welles Wilder, Jr. and is calculated using the other indicators that make up the trading system. The ADX is primarily used as an indicator of momentum, or trend strength, but the total ADX system is also used as a directional indicator.
Directional movement is calculated by comparing the difference between two consecutive lows with the difference between their respective highs.
For the excel calculation of ADX this is a really good video:
https://www.youtube.com/watch?v=LKDJQLrXedg&t=387s
I was playing with this a little bit and found something that can help you with the issue:
def ADX(data: pd.DataFrame, period: int):
"""
Computes the ADX indicator.
"""
df = data.copy()
alpha = 1/period
# TR
df['H-L'] = df['High'] - df['Low']
df['H-C'] = np.abs(df['High'] - df['Close'].shift(1))
df['L-C'] = np.abs(df['Low'] - df['Close'].shift(1))
df['TR'] = df[['H-L', 'H-C', 'L-C']].max(axis=1)
del df['H-L'], df['H-C'], df['L-C']
# ATR
df['ATR'] = df['TR'].ewm(alpha=alpha, adjust=False).mean()
# +-DX
df['H-pH'] = df['High'] - df['High'].shift(1)
df['pL-L'] = df['Low'].shift(1) - df['Low']
df['+DX'] = np.where(
(df['H-pH'] > df['pL-L']) & (df['H-pH']>0),
df['H-pH'],
0.0
)
df['-DX'] = np.where(
(df['H-pH'] < df['pL-L']) & (df['pL-L']>0),
df['pL-L'],
0.0
)
del df['H-pH'], df['pL-L']
# +- DMI
df['S+DM'] = df['+DX'].ewm(alpha=alpha, adjust=False).mean()
df['S-DM'] = df['-DX'].ewm(alpha=alpha, adjust=False).mean()
df['+DMI'] = (df['S+DM']/df['ATR'])*100
df['-DMI'] = (df['S-DM']/df['ATR'])*100
del df['S+DM'], df['S-DM']
# ADX
df['DX'] = (np.abs(df['+DMI'] - df['-DMI'])/(df['+DMI'] + df['-DMI']))*100
df['ADX'] = df['DX'].ewm(alpha=alpha, adjust=False).mean()
del df['DX'], df['ATR'], df['TR'], df['-DX'], df['+DX'], df['+DMI'], df['-DMI']
return df
At the beginning the values aren't correct (as always with the EWM approach) but after several computations it converges to the correct value.
Math was taken from here.
def ADX(df):
def getCDM(df):
dmpos = df["High"][-1] - df["High"][-2]
dmneg = df["Low"][-2] - df["Low"][-1]
if dmpos > dmneg:
return dmpos
else:
return dmneg
def getDMnTR(df):
DMpos = []
DMneg = []
TRarr = []
n = round(len(df)/14)
idx = n
while n <= (len(df)):
dmpos = df["High"][n-1] - df["High"][n-2]
dmneg = df["Low"][n-2] - df["Low"][n-1]
DMpos.append(dmpos)
DMneg.append(dmneg)
a1 = df["High"][n-1] - df["High"][n-2]
a2 = df["High"][n-1] - df["Close"][n-2]
a3 = df["Low"][n-1] - df["Close"][n-2]
TRarr.append(max(a1,a2,a3))
n = idx + n
return DMpos, DMneg, TRarr
def getDI(df):
DMpos, DMneg, TR = getDMnTR(df)
CDM = getCDM(df)
POSsmooth = (sum(DMpos) - sum(DMpos)/len(DMpos) + CDM)
NEGsmooth = (sum(DMneg) - sum(DMneg)/len(DMneg) + CDM)
DIpos = (POSsmooth / (sum(TR)/len(TR))) *100
DIneg = (NEGsmooth / (sum(TR)/len(TR))) *100
return DIpos, DIneg
def getADX(df):
DIpos, DIneg = getDI(df)
dx = (abs(DIpos- DIneg) / abs(DIpos + DIneg)) * 100
ADX = dx/14
return ADX
return(getADX(df))
print(ADX(df))
This gives you the exact numbers as Tradingview and Thinkorswim.
import numpy as np
def ema(arr, periods=14, weight=1, init=None):
leading_na = np.where(~np.isnan(arr))[0][0]
arr = arr[leading_na:]
alpha = weight / (periods + (weight-1))
alpha_rev = 1 - alpha
n = arr.shape[0]
pows = alpha_rev**(np.arange(n+1))
out1 = np.array([])
if 0 in pows:
out1 = ema(arr[:int(len(arr)/2)], periods)
arr = arr[int(len(arr)/2) - 1:]
init = out1[-1]
n = arr.shape[0]
pows = alpha_rev**(np.arange(n+1))
scale_arr = 1/pows[:-1]
if init:
offset = init * pows[1:]
else:
offset = arr[0]*pows[1:]
pw0 = alpha*alpha_rev**(n-1)
mult = arr*pw0*scale_arr
cumsums = mult.cumsum()
out = offset + cumsums*scale_arr[::-1]
out = out[1:] if len(out1) > 0 else out
out = np.concatenate([out1, out])
out[:periods] = np.nan
out = np.concatenate(([np.nan]*leading_na, out))
return out
def atr(highs, lows, closes, periods=14, ema_weight=1):
hi = np.array(highs)
lo = np.array(lows)
c = np.array(closes)
tr = np.vstack([np.abs(hi[1:]-c[:-1]),
np.abs(lo[1:]-c[:-1]),
(hi-lo)[1:]]).max(axis=0)
atr = ema(tr, periods=periods, weight=ema_weight)
atr = np.concatenate([[np.nan], atr])
return atr
def adx(highs, lows, closes, periods=14):
highs = np.array(highs)
lows = np.array(lows)
closes = np.array(closes)
up = highs[1:] - highs[:-1]
down = lows[:-1] - lows[1:]
up_idx = up > down
down_idx = down > up
updm = np.zeros(len(up))
updm[up_idx] = up[up_idx]
updm[updm < 0] = 0
downdm = np.zeros(len(down))
downdm[down_idx] = down[down_idx]
downdm[downdm < 0] = 0
_atr = atr(highs, lows, closes, periods)[1:]
updi = 100 * ema(updm, periods) / _atr
downdi = 100 * ema(downdm, periods) / _atr
zeros = (updi + downdi == 0)
downdi[zeros] = .0000001
adx = 100 * np.abs(updi - downdi) / (updi + downdi)
adx = ema(np.concatenate([[np.nan], adx]), periods)
return adx

Using matplotlib.pyplot to make the animation of the 1D wave equation

I have been using matplotlib from python to show the animation of 1D wave equation.But I got a problem of making the animation.I want the image of the wave to change with time.It means that I may need a loop to form many different pictures of the wave equation.But it seems that the time cannot be put into the wave functions ,so the images do not change at all.Please help me with the mistake that I made.
Here are the codes that I wrote:(Part of the codes comes from the book "Python Scripting for Computational Science")
from numpy import zeros,linspace,sin,pi
import matplotlib.pyplot as mpl
def I(x):
return sin(2*x*pi/L)
def f(x,t):
return sin(x*t)
def solver0(I,f,c,L,n,dt,tstop):
# f is a function of x and t, I is a function of x
x = linspace(0,L,n+1)
dx = L/float(n)
if dt <= 0:
dt = dx/float(c)
C2 = (c*dt/dx)**2
dt2 = dt*dt
up = zeros(n+1)
u = up.copy()
um = up.copy()
t = 0.0
for i in range(0,n):
u[i] = I(x[i])
for i in range(1,n-1):
um[i] = u[i]+0.5*C2*(u[i-1] - 2*u[i] + u[i+1]) + dt2*f(x[i],t)
um[0] = 0
um[n] = 0
while t <= tstop:
t_old = t
t += dt
#update all inner points:
for i in range(1,n-1):
up[i] = -um[i] + 2*u[i] + C2*(u[i-1] - 2*u[i] + u[i+1]) + dt2*f(x[i],t_old)
#insert boundary conditions:
up[0] = 0
up[n] = 0
#update data structures for next step
um = u.copy()
u = up.copy()
return u
c = 3.0 #given by myself
L = 10
n = 100
dt = 0
tstart = 0
tstop = 6
x = linspace(0,L,n+1)
t_values = linspace(tstart,tstop,31)
mpl.ion()
y = solver0(I, f, c, L, n, dt, tstop)
lines = mpl.plot(x,y)
mpl.axis([x[0], x[-1], -1.0, 1.0])
mpl.xlabel('x')
mpl.ylabel('y')
counter = 0
for t in t_values:
y = solver0(I,f,c,L,n,dt,tstop)
lines[0].set_ydata(y)
mpl.draw()
mpl.legend(['t=%4.1f' % t])
mpl.savefig('sea_%04d.png' %counter)
counter += 1
Maybe that's what you need?
y = solver0(I,f,c,L,n,dt,t)

how to calculate std dev in file

i have input file like this
#a
CTCTCTTTAGAACAATCATCACATACCCCTGGTT
+
1>1A>FDF3113B11BB1BAED1D11BAEE0ABG
#b
CAATGCAGCGAACAATGTTCTGGTGGTTGAATTT
+
111>1#11C?1AE?BFDGGGGGBGCCGGGGHHHH
....
i calculated the avg quality scores in this file but need help in calculating the standard
deviation of that score
here what i did
import sys,csv
import numpy as np
import math
r = open(sys.argv[1],"r")
length =200
a = np.zeros(length)
b = np.zeros(length)
av = np.zeros(length)
while True:
id = reads.readline().rstrip()
if id == "":
break
seq= r.readline().rstrip()
p = r.readline().rstrip()
qua = r.readline().rstrip()
l= len(qua)
q = [ord(character) - 33 for character in qua]
for i in range(l):
a[i] += q[i]
b[i] += 1
for j in range(length):
av[j] = float(a[j]) / b[j]
s2 = sum((x - av[j])**2 for x in q[i])/b[j] # error in this
standard_deviation = s2**0.5
print standard_deviation
How about this?
import sys,csv
import numpy as np
import math
r = open(sys.argv[1],"r")
while True:
id = reads.readline().rstrip()
if id == "":
break
seq= r.readline().rstrip()
p = r.readline().rstrip()
qua = r.readline().rstrip()
q = [ord(character) - 33 for character in qua]
mean = np.mean(q)
standard_deviation = np.std(q)

Categories

Resources