OverflowError: math range error in Python - python

I'm new to Python and I'm having trouble with this:
import cmath as cm
import numpy as np
from scipy import special
from scipy.misc import derivative
def T(X, Y):
s0 = np.sign(X)
s1 = np.sign(X - 15)
s3 = np.sign(X + 15)
k0 = cm.sqrt( X**2 -(10*Y)**2 )/10
k1 = cm.sqrt( ((X - 15)**2) - (10*Y)**2 )/10
k3 = cm.sqrt( ((X + 15)**2) - (10*Y)**2 )/10
def z(k):
return complex(k, -Y)/cm.sqrt(k**2 + Y**2)
def w(k, s, x):
return np.array([[cm.exp(complex(0, 1)*k*x), cm.exp(-complex(0, 1)*k*x)], [s*z(k)*cm.exp(complex(0, 1)*k*x), -s*cm.exp(-complex(0, 1)*z(k)*x)/z(k)]])
I15 = np.linalg.inv(w(k1, s1, 5))
I05 = np.linalg.inv(w(k0, s0, 5))
I310 = np.linalg.inv(w(k3, s3, 10))
Omega = w(k1, s1, 0).dot(I15).dot(w(k0, s0, 5)).dot(I05).dot(w(k3, s3, 5)).dot(I310)
Omegan = special.eval_chebyu(19, np.trace(Omega)/2)*Omega - special.eval_chebyu(18, np.trace(Omega)/2)*np.identity(2)
I00 = np.linalg.inv(w(k0, s0, 0))
tt = I00.dot(Omegan).dot(w(k0, s0, 200))
t = 1/tt[0][0]
return cm.log(t)
def V(X):
Y0 = X*np.sin(np.deg2rad(2))/10
result = derivative(func=T, x0=Y0, args=(X,))*X/(20*np.pi)
return -result.imag
V = np.vectorize(V)
X = np.linspace(0.01, 10, 1000)
VX = V(X)
I'm getting an OverflowError: math range error, when trying to run this code.
Is there a way to avoid this error? Any help is appreciated. Thanks!

How to debug:
Change your function w like this:
def w(k, s, x):
try:
return np.array([[cm.exp(complex(0, 1)*k*x), cm.exp(-complex(0, 1)*k*x)], [s*z(k)*cm.exp(complex(0, 1)*k*x), -s*cm.exp(-complex(0, 1)*z(k)*x)/z(k)]])
except OverflowError:
import pdb
pdb.set_trace()
Run your program:
#> python myprog.py
--Return--
> /Users/xxx/tmp/myprog.py(19)w()->None
-> pdb.set_trace()
(Pdb)
Debug by testing all your expressions:
(Pdb) locals()
{'k': 3.5499997838094535j, 's': 1.0, 'x': 200, 'z': <function T.<locals>.z at 0x124770c10>, '__return__': None}
(Pdb) cm.exp(complex(0, 1)*k*x)
(4.47647977601281e-309+0j)
(Pdb) cm.exp(-complex(0, 1)*k*x) # The problem is here x=200, x=199 works
*** OverflowError: math range error

Related

converting the 1D np array to 2D np array

The nPhotonDesity is 1 D <class 'numpy.ndarray'> , How can I convert it to 2D <class 'numpy.ndarray'> ?
#######################################################
def getPhotonDensity( pulseWidth, PhotonsTotalNumber, pulseShapeName, xPosition=0):
z = []
if pulseShapeName == ePulseShape.RECT:
Io = PhotonsTotalNumber/len(x);
z = getTransmitedPulse(ePulseShape.RECT.name, T, Io, 0, pulseWidth)(t)
elif pulseShapeName == ePulseShape.GAUSSIAN:
Io = PhotonsTotalNumber;
z = getTransmitedPulse(ePulseShape.GAUSSIAN.name, T, Io, 0, pulseWidth)(t)
return z;
def getTransmitedPulse(name, T, Io, mu=0, pulseWidth = 0, rolloff=None ):
def rc(t, beta):
import warnings
with warnings.catch_warnings():
warnings.simplefilter("ignore")
return np.sinc(t)*np.cos(np.pi*beta*t)/(1-(2*beta*t)**2)
def rrc(t, beta):
return (np.sin(np.pi*t*(1-beta))+4*beta*t*np.cos(np.pi*t*(1+beta)))/(np.pi*t*(1-(4*beta*t)**2))
# rolloff is ignored for triang and rect
if name == ePulseShape.RECT.name:
return lambda t: Io*(abs(t/T) < pulseWidth).astype(int)
elif name == 'triang':
return lambda t: (1-abs(t/T)) * (abs(t/T) < pulseWidth ).astype(float)
elif name == 'rc':
return lambda t: rc(t/T, rolloff)
elif name == 'rrc':
return lambda t: rrc(t/T, rolloff)
elif name == ePulseShape.GAUSSIAN.name:
return lambda t: Io/(pulseWidth * np.sqrt(2 * np.pi)) * np.exp( - (t/T - mu)**2 / (2 * pulseWidth**2) )
nPhotonDesity = getPhotonDensity(pulseWidth, PhotonsTotalNumber, pulseShapeName)

ImportError: cannot import name 'ODE_Solver' odesolver implementation and call error

I try to implement ODE Solver contain deifferent numerical schemes for solve ODE 5-th order:
For example consider the Forward Euler scheme code implementation:
# ES.py
from abc import ABC
from ODS import ODE_Solver
class FE(ODE_Solver, ABC):
"""
Attribute:
x: array of x coords
u: solution array y(x)
k: number of steps
f: right hand side ODE equation: du/dx = f(u, x)
"""
#classmethod
def solver_st(self):
u, f, k, x = self.u, self.f, self.k, self.x
dx = x[k+1] - x[k]
u_new = u[k] + dx*f(u[k], x[k])
return u_new
This method code by class and contain one method and based on superclass ODE_Solver:
#ODS.py
import numpy as np
class ODE_Solver(object):
"""
Supercalss sover ODE-s
Attribute:
x: array of x coords
u: solution array y(x)
k: number of steps
f: right hand side ODE equation: du/dx = f(u, x)
"""
def __init__(self, f):
if not callable(f):
# check correct function f(u, x)
raise TypeError('f is %s, not function' % type(f))
self.f = lambda u, x: np.asarray(f(u, x), float)
def solver_st(self):
"""Implement numerical scheme"""
raise NotImplementedError
def set_initial_condition(self, u0):
if isinstance(u0, (float, int)): # ODE 1-th order
self.neq = 1
u0 = float(u0)
else: # ODE high order or system of ODE-s
u0 = np.asarray(u0) # (initial conds)
self.neq = u0.size
self.u0 = u0
# check correct lenght of vector f
try:
f0 = self.f(self.u0, 0)
except IndexError:
raise IndexError(
'index out of bounds f(u,x). right index %s' % (str(range(self.neq))))
if f0.size != self.neq:
raise ValueError('f(u,x) return %d elems, u has %d elems' % (f0.size, self.neq))
def solve(self, coord_points, terminate=None):
"""
Solve equations. Default False
"""
if terminate is None:
terminate = lambda u, x, step_no: False
if isinstance(coord_points, (float, int)):
raise TypeError('solve: array lists not iterable')
self.x = np.asarray(coord_points)
if self.x.size <= 1:
raise ValueError('ODESolver.solve requre coords x array')
n = self.x.size
if self.neq == 1: # ODE
self.u = np.zeros(n)
else:
self.u = np.zeros((n, self.neq))
# Assume self.x[0] corresponds to self.u0
self.u[0] = self.u0
# looping for x coords
for k in range(n - 1):
self.k = k
self.u[k + 1] = self.solver_st()
if terminate(self.u, self.x, self.k + 1):
break
return self.u[:k + 2], self.x[:k + 2]
And now I try to testing my code:
# test.py
import matplotlib.pyplot as plt
import numpy as np
from ODS import ODE_Solver
def f(u, x):
return (u[1],
u[2],
u[3],
u[4],
- 15 * u[4] - 90 * u[3] -
270 * u[2] - 405 * u[1] - 243 * u[0])
y0 = [0, 3, -9, -8, 0]
solver = FE(f)
solver.set_initial_condition(y0)
x_points = np.linspace(0, 5, 150)
u, x = solver.solve(x_points)
plt.plot(x, u)
So I consider the reccomendation in commentary I succes to call solver methods, but I get type error:
File "C:\Fin_Proj_ODE\test1.py", line 19, in <module>
u, x = solver.solve(x_points)
File "C:\Fin_Proj_ODE\ODS.py", line 71, in solve
self.u[k + 1] = self.solver_st()
File "C:\Fin_Proj_ODE\ES.py", line 18, in solver_st
u, f, k, x = self.u, self.f, self.k, self.x
AttributeError: type object 'FE' has no attribute 'u'
This post not help me to decide this troubleshooting
And I have 2 questions:
1) How to fix this error of call methods of required class? Any idea?
How to rewrite class for calling methods in test file from EF class?
ImportError: cannot import name 'ODE_Solver' - this bug related with wrong call methods of class EF:
solver = ODE_Solver.solver_st(f)
solver.set_initial_condition(y0)
x_points = np.linspace(0, 5, 150)
u, x = solver.solve(x_points)
For fixing 2-nd problem should remove #classmethod in numerical scheme class implementation:
class FE(ODE_Solver, ABC):
def solver_st(self):
u, f, k, x = self.u, self.f, self.k, self.x
dx = x[k+1] - x[k]
u_new = u[k] + dx*f(u[k], x[k])
return u_new

Code wont work unless I *repeat* functions, which seems unnecessary

Here is the whole code, and a description of my problem below
import matplotlib.pyplot as plt
import math
import numpy as np
import time
import timeit
import cProfile
import scipy.constants as cons
from astropy import units as u
def main():
# For timing purposes
start = time.time()
pr = cProfile.Profile()
pr.enable()
# Exercise 6.14
# Preliminary values
w = 1e-9 # in nanometers
V = 20 # in electronVolts
m = cons.m_e # in kilograms
c_e = cons.elementary_charge # 1 eV = 1 Joule
hbar = cons.hbar # in J*s
# multiplying w^2*m by c_e allows to get a tangent graph and not funky
# lines like before
c = c_e*((w ** 2) * m) / (2 * hbar ** 2)
# First function
def y1(e):
return np.tan(np.sqrt(c * e))
# Second function
def y2(e):
return np.sqrt((V - e) / e)
# Third function
def y3(e):
return -np.sqrt(e / (V - e))
# For the different values of E
E = np.linspace(.05, 19.95, 100)
y1 = y1(E)
y2 = y2(E)
y3 = y3(E)
# Plot the values of E
plt.plot(E,y1, '-', label='tangent')
plt.plot(E, y2, '-', label='positive values')
plt.plot(E, y3, '-', label='negative values')
plt.legend()
plt.xlabel('E in electronVolts')
plt.show()
accuracy = 1e-3 # in Ev
def roots(f, x1, x2, acc):
def midpoint(x, y):
return (x + y) / 2
def have_same_sign(x, y):
if x < 0 and y < 0 or x > 0 and y > 0:
return True
else:
return False
while abs(x1 - x2) > acc:
x = midpoint(x1, x2)
if have_same_sign(f(x1), f(x)):
x1 = x
elif have_same_sign(f(x), f(x2)):
x2 = x
elif abs(x) < acc:
return x
return midpoint(x1, x2)
# For bisection purposes
# First function
def y1(e):
return np.tan(np.sqrt(c * e))
# Second function
def y2(e):
return np.sqrt((V - e) / e)
# Third function
def y3(e):
return -np.sqrt(e / (V - e))
def f1(x):
return y1(x) - y2(x)
def f2(x):
return y1(x) - y3(x)
# Finding the first 6 values for energy levels
print('E0 = ', roots(f1, 0.02, 0.75, accuracy))
print('E1 = ', roots(f2, 1, 1.5, accuracy))
print('E2 = ', roots(f1, 2.5, 4.5, accuracy))
print('E3 = ', roots(f2, 5, 6, accuracy))
print('E4 = ', roots(f1, 7.5, 9, accuracy))
print('E5 = ', roots(f2, 10, 12, accuracy))
pr.disable()
# pr.print_stats(sort='time')
end = time.time()
print(f"Program took :{end - start} seconds to run")
if __name__ == '__main__':
main()
The problem:
I have to duplicate this section, which can be seen at the top and near the middle of the code
# First function
def y1(e):
return np.tan(np.sqrt(c * e))
# Second function
def y2(e):
return np.sqrt((V - e) / e)
# Third function
def y3(e):
return -np.sqrt(e / (V - e))
Trying to organize the functions so that I don't have to repeat them gives me call errors.
I am at a loss here, anyone care to help / point where is my mistake?
Sorry for pasting such large chunk of code, but if I don't show it entirely then it just looks like I am yelling "wolf" to the town hall.
You have a problem between using function and variables for storing numbers (integers, floats, etc). You cannot have the same name for both of them.
# For the different values of E
E = np.linspace(.05, 19.95, 100)
y1 = y1(E) # this
y2 = y2(E) # this
y3 = y3(E) # this
Here is your mistake. You can use another name for variables such as _y1, so that the Python interpreter does as you expect.
# For the different values of E
E = np.linspace(.05, 19.95, 100)
_y1 = y1(E)
_y2 = y2(E)
_y3 = y3(E)
# Plot the values of E
plt.plot(E, _y1, '-', label='tangent')
plt.plot(E, _y2, '-', label='positive values')
plt.plot(E, _y3, '-', label='negative values')

How can I use numba's jit in my program which contains only Numpy arrays?

My program evaluates error in solving a linear differential equation. It uses only numpy arrays. When I try to use numba's jit decorator for the functions I define, I just get errors. Can you please help me use it properly?
My code:
import numpy as np
from numba import jit
def rk4(t_prev, x_prev, derivs, dt):
k1 = dt * derivs(t_prev, x_prev)
k2 = dt * derivs(t_prev + 1/2*dt, x_prev + 1/2*k1)
k3 = dt * derivs(t_prev + 1/2*dt, x_prev + 1/2*k2)
k4 = dt * derivs(t_prev + dt, x_prev + k3)
x_next = x_prev + 1/6*k1 + 1/3*k2 + 1/3*k3 + 1/6*k4
return x_next
global k, x_0, v_0, t_0, t_f
k = 1
x_0 = 0
v_0 = np.sqrt(k)
t_0 = 0
t_f = 10
dtList = np.logspace(0, -5, 1000)
def derivs(t, X):
deriv = np.zeros([2])
deriv[0] = X[1]
deriv[1] = -k * X[0]
return deriv
def err(dt):
tList = np.arange(t_0, t_f + dt, dt)
N = tList.shape[0]
XList = np.zeros([N,2])
XList[0][0], XList[0][1] = x_0, v_0
for i in range(N-1):
XList[i+1] = rk4(tList[i], XList[i], derivs, dt)
error = np.abs(XList[-1][0] - np.sin(10))
return error
print(err(.001))
The following works for me:
import numpy as np
from numba import jit
#jit(nopython=True)
def rk4(t_prev, x_prev, derivs, dt):
k1 = dt * derivs(t_prev, x_prev)
k2 = dt * derivs(t_prev + 1/2*dt, x_prev + 1/2*k1)
k3 = dt * derivs(t_prev + 1/2*dt, x_prev + 1/2*k2)
k4 = dt * derivs(t_prev + dt, x_prev + k3)
x_next = x_prev + 1/6*k1 + 1/3*k2 + 1/3*k3 + 1/6*k4
return x_next
global k, x_0, v_0, t_0, t_f
k = 1
x_0 = 0
v_0 = np.sqrt(k)
t_0 = 0
t_f = 10
dtList = np.logspace(0, -5, 1000)
#jit(nopython=True)
def derivs(t, X):
deriv = np.zeros(2)
deriv[0] = X[1]
deriv[1] = -k * X[0]
return deriv
#jit(nopython=True)
def err(dt):
tList = np.arange(t_0, t_f + dt, dt)
N = tList.shape[0]
XList = np.zeros((N,2))
XList[0][0], XList[0][1] = x_0, v_0
for i in range(N-1):
XList[i+1] = rk4(tList[i], XList[i], derivs, dt)
error = np.abs(XList[-1][0] - np.sin(10))
return error
print(err(.001))
Note, the only two changes I made to your code was to replace the calls to np.zeros that passed in lists to either a tuple in the 2d case, or just the bare integer in the 1d case. See the following issue for an explanation of why this is:
https://github.com/numba/numba/issues/3993

Accelerate or decelerate a movie clip

I am trying to accelerate and/or decelerate a movie clip with the help of Python's moviepy module, but I can't seem to work it out properly. The script runs quite smoothly, and without any errors, but I do not see any effects. Might be my script is wrong and I can't detect the problem. Looking for help/tips from you. I do not need a complete solution, any hints will be of great help. I have been working on this solution for sometime and I think I should post my problem here. Any help, tips, guidance will be greatly appreciated. Thank you.
from moviepy.editor import *
from moviepy.video.tools.drawing import color_split
import os
dir = os.path.split(os.path.realpath(__file__))[0]
img = os.path.join('tmp', 'stock.jpg')
folder = 'tmp'
def f_accel_decel(t, old_d, new_d, abruptness=1, soonness=1.0):
"""
abruptness
negative abruptness (>-1): speed up down up
zero abruptness : no effect
positive abruptness: speed down up down
soonness
for positive abruptness, determines how soon the
speedup occurs (0<soonness < inf)
"""
a = 1.0+abruptness
def _f(t):
f1 = lambda t: (0.5)**(1-a)*(t**a)
f2 = lambda t: (1-f1(1-t))
return (t<.5)*f1(t) + (t>=.5)*f2(t)
return old_d*_f((t/new_d)**soonness)
def accel_decel(clip, new_duration=None, abruptness=1.0, soonness=1.0):
"""
new_duration
If None, will be that of the current clip.
abruptness
negative abruptness (>-1): speed up down up
zero abruptness : no effect
positive abruptness: speed down up down
soonness
for positive abruptness, determines how soon the
speedup occurs (0<soonness < inf)
"""
if new_duration is None:
new_duration = clip.duration
fl = lambda t : f_accel_decel(t, clip.duration, new_duration,
abruptness, soonness)
return clip.fl_time(fl).set_duration(new_duration)
duration = 30
main_clip = ImageClip(img, duration=30)
W,H = main_clip.size
print W,H
clip1 = (main_clip
.subclip(0,duration)
.set_pos(lambda t:(max((0), (int(W-0.5*W*t))), "center"))
)
modifiedClip1 = accel_decel(clip1, abruptness=5, soonness=1.3)
cc = CompositeVideoClip([modifiedClip1], size=(1920,1080), bg_color=(232,54,18)).resize(0.5)
cc.preview(fps=24)
#cc.write_videofile("mask.avi", fps=25, codec="libx264", bitrate="1000K", threads=3)
I think the best way of accelerating and decelerating clip objects is using easing functions.
Some reference sites:
http://easings.net
http://www.gizma.com/easing/
http://gsgd.co.uk/sandbox/jquery/easing/
Here's part of a script I made when trying to understand these functions.
Maybe you can use some of this concepts to solve your issue.
from __future__ import division
from moviepy.editor import TextClip, CompositeVideoClip
import math
def efunc(x0, x1, dur, func='linear', **kwargs):
# Return an easing function.
# It will control a single dimention of the clip movement.
# http://www.gizma.com/easing/
def linear(t):
return c*t/d + b
def out_quad(t):
t = t/d
return -c * t*(t-2) + b
def in_out_sine(t):
return -c/2 * (math.cos(math.pi*t/d) - 1) + b
def in_quint(t):
t = t/d
return c*t*t*t*t*t + b
def in_out_circ(t):
t /= d/2;
if t < 1:
return -c/2 * (math.sqrt(1 - t*t) - 1) + b
t -= 2;
return c/2 * (math.sqrt(1 - t*t) + 1) + b;
def out_bounce(t):
# http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js
t = t/d
if t < 1/2.75:
return c*(7.5625*t*t) + b
elif t < 2/2.75:
t -= 1.5/2.75
return c*(7.5625*t*t + .75) + b
elif t < 2.5/2.75:
t -= 2.25/2.75
return c*(7.5625*t*t + .9375) + b
else:
t -= 2.625/2.75
return c*(7.5625*t*t + .984375) + b
# Kept the (t, b, c, d) notation found everywhere.
b = x0
c = x1 - x0
d = dur
return locals()[func]
def particle(x0, x1, y0, y1, d, func='linear', color='black', **kwargs):
# Dummy clip for testing.
def pos(t):
return efunc(x0, x1, d, func=func)(t), efunc(y0, y1, d, func=func)(t)
return (
TextClip('*', fontsize=80, color=color)
.set_position(pos)
.set_duration(d)
)
# Make a gif to visualize the behaviour of the functions:
easing_functions = [
('linear', 'red'),
('in_out_sine', 'green'),
('in_out_circ', 'violet'),
('out_quad', 'blue'),
('out_bounce', 'brown'),
('in_quint', 'black'),
]
d = 4
x0, x1 = 0, 370
clips = []
for i, (func, c) in enumerate(easing_functions):
y = 40*i
clips.append(particle(x0, x1, y, y, d=d, func=func, color=c))
clips.append(particle(x1, x0, y, y, d=d, func=func, color=c).set_start(d))
clip = CompositeVideoClip(clips, size=(400,250), bg_color=(255,255,255))
clip.write_gif('easing.gif', fps=12)
The output of the script:

Categories

Resources