Trying to simply apple numba #njit (No Python mode) for speed in numba but running into errors I do not understand.
Want to declare an array of size n =100, and in the loop want to set each array member with index i in range (0,100) equal to r**2+5
Why the big stack of errors from numba ?
# -*- coding: utf-8 -*-
"""
Spyder Editor
This is a temporary script file.
"""
import numpy as np
from numba import njit
n=100
r=.5
Values=np.zeros(n, dtype=np.float64)
#njit
def func(n):
for i in range(0,n):
Values[i]=r**2+5
return(Values)
print(func(n))
You could do it with a bit of modification your code as follows:
import numpy as np
from numba import njit
#njit
def func(n):
r = .5
Values = np.zeros(n, dtype=np.float64)
for i in range(0, n):
Values[i] = r ** 2 + 5
return (Values)
Or you could do it with much cleaner and pythonic way of list comprehensions. i.e bulk assigning as you called it.
#njit
def func1(n):
vals = np.array([(0.5**2 + 5) for r in range(n)])
return vals
Related
UPDATE:
I went around the problem with a DataFrame:
import pandas as pd
import numpy as np
dict = {'x0':[1,1,1,1,1],'x1':[2,3,5,7,8],'x2':[1,5,3,6,7], 'y':[3,2,4,5,8]}
df = pd.DataFrame(dict)
# y = β(0) + β1x1 + β2x2
X = df[['x0','x1','x2']].to_numpy()
Y = df[['y']].to_numpy()
X_transpose = (X.transpose())
beta_hats = np.linalg.inv(X_transpose.dot(X)).dot(X_transpose.dot(Y))
print(beta_hats)
df = pd.DataFrame(beta_hats)
df.rename(columns = {0:'Beta_Hats'}, inplace = True)
print(df)
I wrote the following program to find the beta coefficients from a set of matrices via NumPy. When I converted the array to a list, I ran into problems: some of the decimal points were off :
Array output:
[[ 0.5 ]
[ 1. ]
[-0.25]]
list output: [[0.49999999999999784], [1.0000000000000022], [-0.2500000000000009]]
I am aware Python has some limitations with calculations, but I was wondering if anyone has figured a way around this. Any help would be much appreciated! I haven't been coding for too long (since May) so sorry if this may seem a bit simple to some of you:
import pandas as pd
import numpy as np
dict = {'x0':[1,1,1,1,1],'x1':[2,3,5,7,8],'x2':[1,5,3,6,7], 'y':[3,2,4,5,8]}
df = pd.DataFrame(dict)
X = df[['x0','x1','x2']].to_numpy()
Y = df[['y']].to_numpy()
X_transpose = (X.transpose())
beta_hats = np.linalg.inv(X_transpose.dot(X)).dot(X_transpose.dot(Y))
print(beta_hats)
list = beta_hats.tolist()
print(list)
I have this code and my aim to calculate the sin of my raster in the power of 0.8.
import os
os.chdir('D:/NOA/Soil_Erosion/test_Project/Workspace/Input_Data_LS_Factor')
import rasterio
import math
data = rasterio.open('Slope_degrees_clipped.tif')
band = data.read(1) # array of float32 with size (3297,2537)
w = band.shape[0]
print(w)
h = band.shape[1]
print(h)
dtypes =data.dtypes[0]
band_calc = math.sin(band)**0.8 # the formula I would like to calculate
However, the following error pops up:
only size-1 arrays can be converted to Python scalars / Rasterio
May you know how I should fix this?
P.S. I tried to vectorize it (np.vectorize()) but it does not work as it needs a real number.
When I use the np.ndarray.flatten(band) the same error occurs.
I found the solution on Geographic Information Systems:
import os
os.chdir('D:/NOA/Soil_Erosion/test_Project/Workspace/Input_Data_LS_Factor')
import rasterio
import math
data = rasterio.open('Slope_degrees_clipped.tif')
from rasterio.plot import show
show(data)
band = data.read(1) # array of float32 with size (3297,2537)
w = band.shape[0]
print(w)
h = band.shape[1]
print(h)
dtypes =data.dtypes[0]
Calculate the sine of the raster in the power of 0.8
import numpy as np
band_calc2 = np.sin(band)**0.8 # the formula I would like to calculate
"""
another way to do it
band_calc = [ [] for i in range(len(band)) ]
for i,row in enumerate(band):
for element in row:
band_calc[i].append(math.sin(element*math.pi/180)**0.8)
"""
Many code examples of calculating the logistic map function
use arrays. For example
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
def logistic(r, x):
return r * x * (1 - x)
n = 1000
r = np.linspace(2.5, 4., n)
iterations = 1000
last = 900
x = 1e-5 * np.ones(n)
fig, ax1 = plt.subplots(figsize=(8, 8))
for i in range(iterations):
x = logistic(r, x)
if i >= (iterations - last):
ax1.plot(r, x, ',k', alpha=.25)
ax1.set_xlim(2.5, 4)
ax1.set_title("Bifurcation diagram")
This is the result:
However, I am trying to make real time plot of the function. My attempt results in many values being omitted.
import ipywidgets as widgets
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
def logistic(r, s):
return r * s * (1 - s)
fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion()
fig.show()
fig.canvas.draw()
#j goes from 2.5 to 4
for j in [float(j) / 100 for j in range(250, 400, 1)]:
x=0.2
# for a given value of j, iterate the logistic function 1000x
for i in range(1000):
y=logistic(j, x)
x=y
#plot the iterated logistic function for a given value of j
ax.plot(j,y,'ko',markersize=1)
fig.canvas.draw()
It looks really bad.
It seems half the data is missing and the data points for larger values of r appear sparse. How can I iterate the logistic function to obtain all the values for a given r?
I figured it out. Basically, the logistic map 'explodes' and becomes chaotic only after it is iterated a few times. So, I have to iterate a few times 'silently' (to allow the function to converge if it will) and then to print out the next few iterated values like so.
import ipywidgets as widgets
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
import time
def logistic(r, s):
return r * s * (1 - s)
fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion()
fig.show()
fig.canvas.draw()
#j goes from 2.5 to 4
j=2.5
#for j in [float(j) / 500 for j in range(1250, 2000, 1)]:
while j<4:
x=0.2
# for a given value of j, iterate the logistic function 1000x
for i in range(30):
y=logistic(j, x)
x=y
for i in range(50):
y=logistic(j, x)
ax.plot(j,y,'ko',markersize=.2)
x=y
#plot the iterated logistic function for a given value of j
fig.canvas.draw()
j=j+.01
which gives
I was just solving a problem using python, and my codes are:
from math import sin,pi
import numpy
import numpy as np
import pylab
N=20
x = np.linspace(0,1, N)
def v(x):
return 100*sin(pi*x)
#set up initial condition
u0 = [0.0] # Boundary conditions at t= 0
for i in range(1,N):
u0[i] = v(x[i])
And I would want to plot the results by updating v(x) in range(0, N) after. it looks simple but perhaps you guys could help since it gives me an error, like
Traceback (most recent call last):
File "/home/universe/Desktop/Python/sample.py", line 13, in <module>
u0[i] = v(x[i])
IndexError: list assignment index out of range
You could change u0[i] = v(x[i]) to u0.append(v(x[i])). But you should write more elegantly as
u0 = [v(xi) for xi in x]
Indices i are bug magnets.
Since you are using numpy, I'd suggest using np.vectorize. That way you can pass the array x directly to the function and the function will return an array of the same size with the function applied on each element of the input array.
from math import sin,pi
import numpy
import numpy as np
import pylab
N=20
x = np.linspace(0,1, N)
def v(x):
return 100*sin(pi*x)
vectorized_v = np.vectorize(v) #so that the function takes an array of x's and returns an array again
u0 = vectorized_v(x)
Out:
array([ 0.00000000e+00, 1.64594590e+01, 3.24699469e+01,
4.75947393e+01, 6.14212713e+01, 7.35723911e+01,
8.37166478e+01, 9.15773327e+01, 9.69400266e+01,
9.96584493e+01, 9.96584493e+01, 9.69400266e+01,
9.15773327e+01, 8.37166478e+01, 7.35723911e+01,
6.14212713e+01, 4.75947393e+01, 3.24699469e+01,
1.64594590e+01, 1.22464680e-14])
u is a list with one element, so you can't assign values to indices that don't exist. Instead make u a dictionary
u = {}
u[0] = 0.0
for i in range(1,N):
u[i] = v(x[i])
I'm trying to setup a buffer protocol in cython. I declare a new class in which I setup the two necessary methods __getbuffer__ and __releasebuffer__
FYI I'm using Cython0.19 and Python2.7 and here is the cython code:
cimport numpy as CNY
# Cython buffer protocol implementation for my array class
cdef class P_NpArray:
cdef CNY.ndarray npy_ar
def __cinit__(self, inpy_ar):
self.npy_ar=inpy_ar
def __getbuffer__(self, Py_buffer *buffer, int flags):
cdef Py_ssize_t ashape[2]
ashape[0]=self.npy_ar.shape[0]
ashape[1]=self.npy_ar.shape[1]
cdef Py_ssize_t astrides[2]
astrides[0]=self.npy_ar.strides[0]
astrides[1]=self.npy_ar.strides[1]
buffer.buf = <void *> self.npy_ar.data
buffer.format = 'f'
buffer.internal = NULL
buffer.itemsize = self.npy_ar.itemsize
buffer.len = self.npy_ar.size*self.npy_ar.itemsize
buffer.ndim = self.npy_ar.ndim
buffer.obj = self
buffer.readonly = 0
buffer.shape = ashape
buffer.strides = astrides
buffer.suboffsets = NULL
def __releasebuffer__(self, Py_buffer *buffer):
pass
This code compiles fine. But I can't retrieve the buffer data properly.
See the following test where:
I create a numpy array
load it with my buffer protocoled class
try to retrieve it as numpy array (Just to showcase my problem):
>>> import myarray
>>> import numpy as np
>>> ar=np.ones((2,4)) # create a numpy array
>>> ns=myarray.P_NpArray(ar) # declare numpy array as a new numpy-style array
>>> print ns
<myarray.P_NpArray object at 0x7f30f2791c58>
>>> nsa = np.asarray(ns) # Convert back to numpy array. Buffer protocol called here.
/home/tools/local/x86z/lib/python2.7/site-packages/numpy/core/numeric.py:235: RuntimeWarning: Item size computed from the PEP 3118 buffer format string does not match the actual item size.
return array(a, dtype, copy=False, order=order)
>>> print type(nsa) # Output array has the correct type
<type 'numpy.ndarray'>
>>> print "nsa=",nsa
nsa= <myarray.P_NpArray object at 0x7f30f2791c58>
>>> print "nsa.data=", nsa.data
nsa.data= Xy�0
>>> print "nsa.itemsize=",nsa.itemsize
nsa.itemsize= 8
>>> print "nsa.size=",nsa.size # Output array has a WRONG size
nsa.size= 1
>>> print "nsa.shape=",nsa.shape # Output array has a WRONG shape
nsa.shape= ()
>>> np.frombuffer(nsa.data, np.float64) # I can't get a proper read of the data buffer
[ 6.90941928e-310]
I looked around for the RuntimeWarning and found out that it probably was not relevant see PEP 3118 warning when using ctypes array as numpy array http://bugs.python.org/issue10746 and http://bugs.python.org/issue10744. What do you think ?
Obviously the buffer shape and size are not properly transmitted. So. What am I missing ? Is my buffer protocol correctly defined ?
Thanks