Unpacking error within numerical integration in python - python

Here is my code snippet to draw an integral function by NumPy, SciPy and MatPlotLib libraries:
import numpy as np
from scipy.integrate import quad
import matplotlib.pyplot as plt
sigma = 1
def integrand(x,n):
return (n/(2*sigma*np.sqrt(np.pi)))*np.exp(-(n**2*x**2)/(4*sigma**2))
tt = np.linspace(0, 20, 0.01)
nn = np.linspace(1, 100, 1)
T = np.zeros_like([len(tt), len(nn)])
for i,t in enumerate(tt):
for j,n in enumerate(nn):
T[i,j] = quad(integrand, -oo, t, args = (x))
plt.pcolormesh(tt,nn,T)
But there is a ValueError as below about a unpacking-related issue:
Traceback (most recent call last):
File "C:\Program Files\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Python Tools for Visual Studio\2.1\visualstudio_py_util.py", line 106, in exec_file exec_code(code, file, global_variables)
File "C:\Program Files\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Python Tools for Visual Studio\2.1\visualstudio_py_util.py", line 82, in exec_code exec(code_obj, global_variables)
File "C:\Users\Matinking\documents\visual studio 2013\Projects\NeuroSimulation\NeuroSimulation\XSundry\test2.py", line 63, in <module>
plt.pcolormesh(tt,nn,T)
File "C:\Python34\lib\site-packages\matplotlib\pyplot.py", line 2946, in pcolormesh
ret = ax.pcolormesh(*args, **kwargs)
File "C:\Python34\lib\site-packages\matplotlib\axes.py", line 7747, in pcolormesh
X, Y, C = self._pcolorargs('pcolormesh', *args, allmatch=allmatch)
File "C:\Python34\lib\site-packages\matplotlib\axes.py", line 7357, in _pcolorargs
numRows, numCols = C.shape
ValueError: need more than 1 value to unpack
Press any key to continue . . .
The issue is seemingly related to the last line of the code, but I can'y figure any solution out for that...
Could you please enlightening me upon this case?
Kind regards

import numpy as np
from scipy.integrate import quad
import matplotlib.pyplot as plt
sigma = 1
def integrand(x, n):
return (n/(2*sigma*np.sqrt(np.pi)))*np.exp(-(n**2*x**2)/(4*sigma**2))
tt = np.linspace(0, 19, 20) # divides range 0 to 19 into 20 equal size portions. Thus, tt = [0, 1, 2, ..., 19]
nn = np.linspace(1, 100, 100) # nn = [1, 2, ..., 100]
T = np.zeros([len(tt), len(nn)])
for i,t in enumerate(tt):
for j,n in enumerate(nn):
T[i, j], _ = quad(integrand, -np.inf, t, args=(n,)) # evaluate integral from -infinity to t, with value of n in the function set to n passed in from here.
x, y = np.mgrid[0:20:1, 1:101:1] # create a mesh/grid for plotting.
plt.pcolormesh(x, y, T) #plot
plt.show()

Related

Plotting sympy.Max yields TypeError

I am trying to generate a 3-dimensional plot for a function involving sympy.Max, but I am getting a type-error.
Minimum example:
import sympy
u, v = sympy.symbols("u v", positive=True)
f = sympy.Max(0, u*v - 0.5)
my_plot = sympy.plotting.plot3d(f, (u, 0, 1), (v, 0, 1), show=False, legend=True)
my_plot.show()
The code runs fine if I remove the -0.5 for example, so it really seems to be about taking the maximum. Any ideas how to fix this?
Full stack trace:
Traceback (most recent call last):
File "/Users/marcusrockel/Documents/projects/copulas_in_systemic_risk/venv/lib/python3.9/site-packages/sympy/plotting/experimental_lambdify.py", line 131, in __call__
results = self.vector_func(*temp_args)
File "/Users/marcusrockel/Documents/projects/copulas_in_systemic_risk/venv/lib/python3.9/site-packages/sympy/plotting/experimental_lambdify.py", line 272, in __call__
return self.lambda_func(*args, **kwargs)
File "<string>", line 1, in <lambda>
File "<__array_function__ internals>", line 180, in amax
File "/Users/marcusrockel/Documents/projects/copulas_in_systemic_risk/venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 2793, in amax
return _wrapreduction(a, np.maximum, 'max', axis, None, out,
File "/Users/marcusrockel/Documents/projects/copulas_in_systemic_risk/venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 86, in _wrapreduction
return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
TypeError: only integer scalar arrays can be converted to a scalar index
I am using Python 3.9 and sympy 1.11.1.
That's unfortunate: it is a limitation of the current plotting module, which is using experimental_lambdify which is quite old.
Two solutions:
you lambdify your expression, and manually plot it with matplotlib.
from sympy import *
import numpy as np
import matplotlib.pyplot as plt
u, v = symbols("u v", positive=True)
expr = Max(0, u*v - 0.5)
f = np.vectorize(lambdify([u, v], expr))
uu, vv = np.mgrid[0:1:50j, 0:1:50j]
zz = f(uu, vv)
fig = plt.figure()
ax = fig.add_subplot(projection="3d")
ax.plot_surface(uu, vv, zz)
ax.set_xlabel("u")
ax.set_ylabel("v")
plt.show()
take a look at this plotting module, which uses lambdify and it is able to plot it:
from sympy import *
from spb import *
u, v = symbols("u v", positive=True)
expr = Max(0, u*v - 0.5)
plot3d(expr, (u, 0, 1), (v, 0, 1))

matplotlib triplot and tricontourf

I'm attempting to plot a 2D dataset having unstructured coordinates in matplotlib using tricontourf. I'm able to generate a plot of the 'mesh' with triplot, however when I use the same Triangulation object for tricontourf, I get an error (see below). What am I missing? Example:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
def lower(x):
return 2 + 1*x
def upper(x):
return 60 + 4*x
ni = 10
nj = 12
x = np.linspace(1,15,ni)
## make a trapezoid
xy = np.zeros((ni,nj,2),dtype=np.float32)
for i in range(len(x)):
y = np.linspace(lower(x[i]),upper(x[i]),nj)
xy[i,:,0] = x[i]
xy[i,:,1] = y
## add noise
xy += -0.1 + 0.2*np.random.rand(ni,nj,2)
## make tris 'indices list'
xi, yi = np.meshgrid(range(ni), range(nj), indexing='xy')
inds_list = np.stack((xi,yi), axis=2)
inds_list = np.reshape(inds_list, (ni*nj,2), order='C')
inds_list = np.ravel_multi_index((inds_list[:,0],inds_list[:,1]), (ni,nj), order='C')
inds_list = np.reshape(inds_list, (ni,nj), order='F')
tris = np.zeros((2*(ni-1)*(nj-1),3), dtype=np.int64)
ci=0
for i in range(ni-1):
for j in range(nj-1):
tris[ci,0] = inds_list[i+1, j+1]
tris[ci,1] = inds_list[i, j+1]
tris[ci,2] = inds_list[i, j ]
ci+=1
tris[ci,0] = inds_list[i, j ]
tris[ci,1] = inds_list[i+1, j ]
tris[ci,2] = inds_list[i+1, j+1]
ci+=1
triangulation = mpl.tri.Triangulation(x=xy[:,:,0].ravel(), y=xy[:,:,1].ravel(), triangles=tris)
fig1 = plt.figure(figsize=(4, 4/(16/9)), dpi=300)
ax1 = plt.gca()
ax1.triplot(triangulation, lw=0.5)
#ax1.tricontourf(triangulation)
fig1.tight_layout(pad=0.25)
plt.show()
...produces
however, uncommenting the line with ax1.tricontourf
throws the error:
Traceback (most recent call last):
File "test.py", line 54, in <module>
ax1.tricontourf(triangulation)
File "C:\Users\steve\AppData\Roaming\Python\Python38\site-packages\matplotlib\tri\tricontour.py", line 307, in tricontourf
return TriContourSet(ax, *args, **kwargs)
File "C:\Users\steve\AppData\Roaming\Python\Python38\site-packages\matplotlib\tri\tricontour.py", line 29, in __init__
super().__init__(ax, *args, **kwargs)
File "C:\Users\steve\AppData\Roaming\Python\Python38\site-packages\matplotlib\contour.py", line 812, in __init__
kwargs = self._process_args(*args, **kwargs)
File "C:\Users\steve\AppData\Roaming\Python\Python38\site-packages\matplotlib\tri\tricontour.py", line 45, in _process_args
tri, z = self._contour_args(args, kwargs)
File "C:\Users\steve\AppData\Roaming\Python\Python38\site-packages\matplotlib\tri\tricontour.py", line 60, in _contour_args
z = np.ma.asarray(args[0])
IndexError: list index out of range
I am using:
Python version: 3.8.9
matplotlib version: 3.5.1
I would say you need to provide the array of values to contour, e.g.:
x= xy[:,:,0].ravel()
z= np.random.rand(x.shape[0])
ax1.tricontourf(triangulation, z)

strange error python code for definite integral of a matrix

I am trying to compute a definite integral of a 2*10 matrix. I need to compute its definite integral from zero to t as we know the results must coincide to the sinus table.
Here is the code before reaching the goal gives error. The error probably is for the last lines.
I would be so thankful if you guide me please.
import numpy as np
import math
import matplotlib.pyplot as plt
from scipy import integrate
from scipy.integrate import quad
from numpy import linalg as LA
from numpy.linalg import matrix_power
from scipy import linalg
from sympy import *
import scipy.integrate as it
from numpy import vectorize
############
from numba import vectorize, float64
##############################
# Constants
tmax = 20
t = np.arange(0.0, tmax, 1)
t0=0
m=len(t)
#print(t)
etest=np.matrix([[np.sqrt(0),np.sqrt(1),np.sqrt(2) ,np.sqrt(3),np.sqrt(4),np.sqrt(5),np.sqrt(6),np.sqrt(7),np.sqrt(8),np.sqrt(9)],
[np.sqrt(10),np.sqrt(11),np.sqrt(12), np.sqrt(13),np.sqrt(14),np.sqrt(15),np.sqrt(16),np.sqrt(17),np.sqrt(18),np.sqrt (19)]])
pow = np.power( etest, 2 )
pow0=pow[0]
pow1=pow[1]
def norm2etest(xx):
sum= pow0+pow1
return sum
ans2=norm2etest(etest)
print(ans2)
def outerfun(norm2etest):
return np.cos(norm2etest)
def integrandtest(xx):
return outerfun(norm2etest(xx))
ttt=outerfun(norm2etest(etest))
#print(ttt)
for tnow in np.arange(0.0, tmax, 1):
numnow=1*tnow
num=np.array(numnow,dtype=int)
#np.vectorize
def integratetest(i):
def integrandtest(t):
return outerfun(norm2etest(t))[i]
I, ff = quad(integrandtest, t0,tnow)
return I
###########################
INTERVALtest=np.arange(0,10)
ANS1=integratetest(INTERVALtest)
print(INTERVALtest)
#print(ANS1.size)
gives this error
Traceback (most recent call last):
File "C:\Users\user\OneDrive\Desktop\44integral.py", line 58, in <module>
ANS1=integratetest(INTERVALtest)
File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\numpy\lib\function_base.py", line 2163, in __call__
return self._vectorize_call(func=func, args=vargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\numpy\lib\function_base.py", line 2241, in _vectorize_call
ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\numpy\lib\function_base.py", line 2201, in _get_ufunc_and_otypes
outputs = func(*inputs)
File "C:\Users\user\OneDrive\Desktop\44integral.py", line 54, in integratetest
I, ff = quad(integrandtest, t0,tnow)
File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\scipy\integrate\quadpack.py", line 352, in quad
points)
File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\scipy\integrate\quadpack.py", line 463, in _quad
return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
TypeError: only size-1 arrays can be converted to Python scalars

Only size-1 arrays can be converted to Python scalars: Integrate.quad Vs Integrate.quadrature

I'm trying to calculate an integral. When I use the function scipy.integrate.quad the code works perfectly. However, when I use scipy.integrate.quadrature (I need to use this or the fixed.quad methods) it returns "only size-1 arrays can be converted to Python scalars" error. What should I do?
My code
import cmath as c
import math as m
import numpy as np
import scipy as sp
import os
import csv
import time
import scipy.integrate as integrate
from scipy import special
k = 0.1
def solnum(x, chi, y):
Bk = ((2*abs(k))**(3/2))*((1+(1.5*abs(k))))*(m.gamma((1/(2*abs(k)))+(3/4))/m.gamma((1/(2*abs(k)))-(3/4)))
C = (chi/(2*m.sqrt(m.pi)))
R1 = (1/(1+(y**2)))
R2 = (((k**2)*(-((chi**2)*((x-y)**2))/4))-(m.sqrt(1+((k**2)*(-((chi**2)*((x-y)**2))/4)**2))))/(k**2 - 1)
R3 = ((((m.sqrt(1+((k**2)*(-((chi**2)*((x-y)**2))/4)**2)))) + ((k*(-((chi**2)*((x-y)**2))/4))))**(1/k))
sn = (C*Bk*R1*R2*R3)
return sn
def g(x, chi):
f1 = lambda y: solnum(x, chi, y)
f2 = integrate.quadrature(f1,-200,200)
return f2[0]
print(g(0.,0.05)) #for instance
The error message:
Traceback (most recent call last):
File "c:/Users/pwadmin/Google Drive/Pós-Doc/Py2/Completão/cacete de agulha.py", line 34, in <module>
print(g(0.,0.05))
File "c:/Users/pwadmin/Google Drive/Pós-Doc/Py2/Completão/cacete de agulha.py", line 32, in g
f2 = integrate.quadrature(f1,-200,200)
File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\integrate\_quadrature.py", line 238, in quadrature
newval = fixed_quad(vfunc, a, b, (), n)[0]
File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\integrate\_quadrature.py", line 119, in fixed_quad
return (b-a)/2.0 * np.sum(w*func(y, *args), axis=-1), None
File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\integrate\_quadrature.py", line 149, in vfunc
return func(x, *args)
File "c:/Users/pwadmin/Google Drive/Pós-Doc/Py2/Completão/cacete de agulha.py", line 31, in <lambda>
f1 = lambda y: solnum(y, x, chi)
File "c:/Users/pwadmin/Google Drive/Pós-Doc/Py2/Completão/cacete de agulha.py", line 22, in solnum
R2 = (((k**2)*(-((chi**2)*((x-y)**2))/4))-(m.sqrt(1+((k**2)*(-((chi**2)*((x-y)**2))/4)**2))))/(k**2 - 1)
TypeError: only size-1 arrays can be converted to Python scalars

TypeError: fun() missing 1 required positional argument: 'a'

I know there are plenty of subject on this error and I've been on many of them trying to understand what is going on with sush a simple system. Here is my code, solving a very simple equation to test the efficiency of solve_ivp vs odeint.
import numpy as np
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
def fun(t,x,a) :
return -x/a
t = np.linspace(0,10,1000)
tspan = [t[0], t[-1]]
x0 = [10]
sol = solve_ivp(fun, tspan, x0, t_eval = t, args = 1)
plt.plot(t,sol.y.T)
plt.show()
And this is the full error report :
/home/anthony/.local/lib/python3.8/site-packages/scipy/integrate/_ivp/common.py:40:
/home/anthony/.local/lib/python3.8/site-packages/scipy/integrate/_ivp/common.py:40:
UserWarning: The following arguments have no effect for a chosen solver: `args`.
warn("The following arguments have no effect for a chosen solver: {}."
Traceback (most recent call last):
File "test.py", line 25, in <module>
sol = solve_ivp(fun, tspan, x0, t_eval = t, args = 1)
File "/home/anthony/.local/lib/python3.8/site-packages/scipy/integrate/_ivp/ivp.py", line
477, in solve_ivp
solver = method(fun, t0, y0, tf, vectorized=vectorized, **options)
File "/home/anthony/.local/lib/python3.8/site-packages/scipy/integrate/_ivp/rk.py", line
100, in __init__
self.f = self.fun(self.t, self.y)
File "/home/anthony/.local/lib/python3.8/site-packages/scipy/integrate/_ivp/base.py", line
139, in fun
return self.fun_single(t, y)
File "/home/anthony/.local/lib/python3.8/site-packages/scipy/integrate/_ivp/base.py", line
21, in fun_wrapped
return np.asarray(fun(t, y), dtype=dtype)
TypeError: fun() missing 1 required positional argument: 'a'
To me, the error is pretty clear but it is also very obvious that I put in the right place my argument according to the documentation of this solver doc scipy.integrate.solve_ivp
I also upgraded to the latest my scipy version, any advices would be very helful.
args is supposed to be a tuple
In [281]: sol = solve_ivp(fun, tspan, x0, t_eval = t, args = (1,))
In [282]: sol
Out[282]:
message: 'The solver successfully reached the end of the integration interval.'
nfev: 80
njev: 0
nlu: 0
sol: None
status: 0
success: True
....
Messing up the args is one of the most common scipy.integrate (and optimize) SO errors.

Categories