I have a MATLAB function :
Bits=30
NBits= ceil(fzero(#(x)2^(x) - x -1 - Bits, max(log2(Bits),1)))
I want to convert it to python, I wrote something like this so far:
from numpy import log, log2
from scipy.optimize import root_scalar
def func(x,Bits):
return ((x)2^(x)-x-1-Bits, max(log2(Bits)))
However it says that it need to be (x)*2^
Does anybody know first, if the conversion from Matlab to python is correct? and second if * has to be added?
Upon suggestion I wrote this lambda function:
lambda x: (2^(x) -x -1 -Bits) , max(log2(Bits))
but I get this error:
TypeError: 'numpy.float64' object is not iterable
I don't have numpy or scipy on this computer so here is my best attempt at an answer.
def YourFunc(Bits):
return math.ceil(root_scalar(lambda x: (2**x)-x-1-Bits, x0 = max(log2(Bits),1)))
Bits = 30
NBits = YourFunc(30)
print(NBits)
I used this function for log2 rather than the one from numpy. Try it
def log2(x):
return math.log(x,2)
Related
I am trying to write a code which reads this file and gives the inverse of square root of each term in a matrix. This is the file I am using:
1.659999999999999963e-04
3.970000000000000005e-04
-8.014499999999999402e-02
-2.274299999999999933e-02
-7.559999999999999880e-03
-3.156229999999999869e-01
5.650100000000000261e-02
2.350100000000000106e-02
-4.383999999999999876e-03
-4.878299999999999997e-02
1.207599999999999993e-02
-5.254199999999999843e-02
1.123500000000000019e-02
1.614240000000000119e-01
1.954900000000000040e-02
-2.614100000000000104e-02
1.534899999999999980e-02
5.446000000000000320e-03
-6.210299999999999848e-02
-9.615000000000000283e-03
1.687800000000000064e-02
6.460999999999999729e-03
-9.490999999999999437e-03
1.676700000000000065e-02
-2.308000000000000156e-03
-1.412399999999999940e-02
8.978899999999999382e-02
1.848960000000000048e-01
5.956000000000000356e-03
-5.592300000000000049e-02
1.114599999999999966e-02
-5.689600000000000213e-02
-6.731000000000000004e-03
2.572999999999999940e-02
1.512000000000000106e-03
-3.237999999999999993e-03
-4.068999999999999700e-03
-1.234000000000000071e-03
2.378109999999999946e-01
-1.128000000000000096e-03
-3.534999999999999948e-03
-4.550000000000000008e-04
1.479999999999999925e-04
5.220000000000000031e-04
3.718099999999999877e-02
1.104580000000000006e-01
1.965000000000000167e-03
4.266999999999999960e-03
-5.140999999999999737e-03
1.648640000000000105e-01
1.776220000000000021e-01
1.922000000000000097e-03
3.250600000000000017e-02
4.402899999999999869e-02
-8.430999999999999259e-03
4.409999999999999858e-04
1.389999999999999905e-04
1.374209999999999876e-01
-2.431860000000000133e-01
-1.727000000000000019e-03
-2.280000000000000126e-04
8.100000000000000375e-05
-7.480999999999999803e-03
8.000000000000000654e-05
-3.939999999999999817e-04
1.441000000000000007e-03
-7.290000000000000473e-04
-3.663000000000000284e-02
-1.657999999999999969e-03
-8.369999999999999619e-04
-6.904999999999999680e-03
1.593100000000000072e-02
-3.393000000000000183e-03
1.495999999999999934e-03
-7.368999999999999682e-03
1.436199999999999977e-02
-1.319700000000000040e-02
-4.557000000000000287e-03
8.123700000000000365e-02
2.447399999999999923e-02
-1.295199999999999997e-02
-8.722100000000000686e-02
-5.232999999999999804e-03
-1.255940000000000112e-01
1.291999999999999963e-03
-1.382999999999999898e-03
4.989999999999999644e-03
1.508000000000000009e-03
2.304399999999999851e-02
2.819400000000000031e-02
3.119999999999999944e-04
-8.781999999999999876e-03
6.794500000000000539e-02
6.198999999999999649e-03
-2.058879999999999877e-01
9.219999999999999680e-04
-1.618800000000000100e-02
-3.415860000000000007e-01
-1.660999999999999933e-03
-4.889999999999999599e-04
1.759999999999999954e-04
-3.763999999999999985e-03
-6.566600000000000215e-02
-7.680000000000000195e-04
-1.231799999999999978e-01
7.047999999999999578e-03
1.425000000000000051e-02
-2.900799999999999906e-02
1.187499999999999944e-01
-1.449199999999999933e-01
-1.106999999999999911e-03
-1.557999999999999923e-03
-2.236999999999999839e-03
-7.270699999999999386e-02
-5.140000000000000254e-04
2.246999999999999865e-03
-1.778949999999999976e-01
1.669599999999999904e-02
-1.277799999999999943e-02
-2.379040000000000044e-01
-2.207999999999999893e-03
1.925000000000000062e-03
7.750100000000000044e-02
-5.004100000000000215e-02
1.704999999999999918e-03
3.272400000000000309e-02
1.957499999999999865e-02
-1.514620000000000133e-01
-3.288999999999999823e-03
-3.605699999999999877e-02
3.648999999999999900e-03
3.459799999999999681e-02
-1.859999999999999945e-04
3.300000000000000253e-05
3.000000000000000076e-06
9.999999999999999547e-07
4.800000000000000122e-05
1.361999999999999929e-03
-6.057300000000000184e-02
5.689999999999999529e-04
-5.000000000000000409e-06
2.984699999999999853e-02
6.999999999999999387e-05
4.600000000000000004e-05
-1.294499999999999991e-02
-2.318000000000000182e-03
-0.000000000000000000e+00
1.858200000000000129e-01
-5.969959999999999711e-01
6.000000000000000152e-06
The code I have tried to write is this:
from ast import Num
from cmath import sqrt
import math
import numpy as np
from numpy import append
f1= open('diagonal.txt', 'r')
k=f1.readlines()
#def mkstr(s):
# str1=" "
# return (str1.join(s))
#print(float(mkstr(k)))
#for j in f1:
#inverse_root(j)
#def mkstr2():
# f1=open("diagonal.txt", "r")
# k=f1.readlines()
# fl=[float(item) for item in k]
# inverse_root(fl)
#for j in mkstr2():
#inverse_root(j)
f=[float(x) for x in k]
sa=np.array(f)
ca=sa.astype(np.float)
def inverse_root(j):
return [1/(sqrt(j))]
j=[inverse_root(ca)]
I am getting the output like this:
DeprecationWarning: `np.float` is a deprecated alias for the builtin `float`. To silence this warning, use `float` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.float64` here.
Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
ca=sa.astype(np.float)
Traceback (most recent call last):
File "/home/gian-2018/prateek/python/read_file/27/5/rmwpd.py", line 34, in <module>
j=[inverse_root(ca)]
File "/home/gian-2018/prateek/python/read_file/27/5/rmwpd.py", line 33, in inverse_root
return [1/(sqrt(j))]
TypeError: only length-1 arrays can be converted to Python scalars
So to get inverse of sqrt for each term from the matrix file: I tried to convert the list of these strings into float list, but even after I get error for trying to get list of these numbers into the formula of inverse sqrt instead of using a real number.
Now I am trying to create the inverse formula suitable for an array which means creating a new array which converts each term in the previous matrix into their inverse sqrt and saves the value into the new array.
By any way possible please either tell me how to convert this list into real numbers or convert each term of this matrix into its inverse sqrt and save it into new matrix.
Or just tell me how to implement this task in any way possible if you have understood it.
I'm trying out numba, the python package that is said to make my nparray super fast. I want to run my function in nonpython mode. What it essentially does is that it takes in an 20x20 array, assigns random numbers to each of its elements, calculate its inverse matrix, then return it.
But here's the problem, when I initialize the array result with np.zeros(), my script crashes and gives me an error message 'overload of function zeros'.
Could someone kindly tell me what is going on? Much appreciated.
from numba import njit
import time
import numpy as np
import random
arr = np.zeros((20,20),dtype = float)
#njit
def aFunctionWithNumba (incomingArray):
result = np.zeros(np.shape(incomingArray), dtype = float)
for i in range(len(incomingArray[0])):
for j in range(len(incomingArray[1])):
incomingArray[i,j] = random.randrange(105150,1541586)
result = np.linalg.inv(incomingArray)
return result
t0 = time.time()
fastArray = aFunctionWithNumba(arr)
t1 = time.time()
s1 = t1 - t0
Here's the full error message:
Exception has occurred: TypingError Failed in nopython mode pipeline (step: nopython frontend) No implementation of function Function(<built-in function zeros>) found for signature:
>>> zeros(UniTuple(int64 x 2), dtype=Function(<class 'float'>)) There are 2 candidate implementations:
- Of which 2 did not match due to: Overload of function 'zeros': File: numba\core\typing\npydecl.py: Line 511.
With argument(s): '(UniTuple(int64 x 2), dtype=Function(<class 'float'>))': No match.
During: resolving callee type: Function(<built-in function zeros>) During: typing of call at c:\Users\Eric\Desktop\testNumba.py (9)
File "testNumba.py", line 9: def aFunctionWithNumba (incomingArray):
result = np.zeros(np.shape(incomingArray), dtype = float)
^ File "C:\Users\Eric\Desktop\testNumba.py", line 25, in <module>
fastArray = aFunctionWithNumba(arr)
The error
You should use Numpy or Numba types inside JITted functions.
Changing the following line your code works:
result = np.zeros(np.shape(incomingArray), dtype=np.float64)
But your code will be more generic using:
result = np.zeros(incomingArray.shape, dtype=incomingArray.dtype)
Or, even better:
result = np.zeros_like(incomingArray)
The timing
The first time you call a JITted function it will take some time to compile it, much longer than the time it will take to execute it. So you should call the function with the same parameter types once before you make any timings.
Additional optimization
If you are interested in comparing the execution time of nested loops with or without Numba, your code is fine. Otherwise you can replace the loops with something like:
incomingArray[:] = np.random.random(incomingArray.shape) * (1541586 - 105150) + 105150
I found that when the index of a numpy array will go out of bound inside a while-loop in a njit decorated function, the way the function handles the while loop can quite weird, and I am not sure why it happens.
from numba import njit
import numpy as np
def func1(v):
i= 0
K= v[-1]+1
while v[i] < K:
i+=1
return i
#njit
def func2(v):
i= 0
K= v[-1]+1
while v[i] < K:
i+=1
return i
x= np.arange(2)
result2 = func2(x)
result1 = func1(x)
Here is a short summary of the results:
1) func2 won't raise IndexError
2) func2 returns different results(like sometimes it is 4; sometimes 5,9,12, etc, basically unstable output) every time we run the file in the console (I am using ipython version 7.8.0)
I am not sure why and how this happens(could be due to numba or spyder or ipython issues or it could be that my cpu is broken beyond repair) which is why I am asking for help here.
Note: I am using:
Anaconda's distribution of python, python version 3.7.4,
spyder version 3.3.6,
ipython version 7.8.0,
numba version 0.45.1
OS windows 10 64-bit
Numba does not do bounds checking on Numpy arrays for performance reasons. There is currently work to turn it on optionally (https://github.com/numba/numba/pull/4432). When you go outside of the bounds of the array you will get whatever is in memory at the location or possibly seg fault.
I've heard of Numba before, but never used it myself.
Here are the results of some messing around with it (version 0.45.1) just now.
from numba import njit
import numpy as np
x = np.arange(2)
#njit
def func2(v):
i = 0
k = v[-1]+1
while v[i] < k:
i += 1
return i
#njit
def func3(x):
return x[2]
func2(x) # returns 2, but no error raised
func3(x) # returns 32, no error raised
func3(np.array([0])) # returns 32, no error raised
func2([0, 1]) # IndexError raised
func3([0, 1]) # IndexError raised
So to me, the bug looks to be the result of some sort of interaction between Numba's jit and Numpy arrays, since normal Python lists behave as expected.
I am calling from matlab (R2015b) a python module that I created. Now I've noticed that, we can only send to python a 1xN vector.
So I fixed this in Matlab
Matlab Code:
a = ones(3, 3);
a = a(:).';
Then I sent a as parameter to python function.
m = py.computeCoreset.computecoreset(a, obj.coresetSize);
Now my problem that python doesn't return Matlab matrix
I noticed that I am returning an ndarray while debugging.
This is my python code:
import numpy as np
def computecoreset(mat, coresetSize):
return np.random.choice(mat, coresetSize)
I guess I need to make the ndarray a matrix once again
But how do I convert it ?
Thanks in advance!
https://www.mathworks.com/matlabcentral/answers/157347-convert-python-numpy-array-to-double
The accepted answer suggests py.array.array function:
data = double(py.array.array('d',py.numpy.nditer(x)));
Which is also listed on
https://www.mathworks.com/help/matlab/matlab_external/handling-data-returned-from-python.html
This is a shot in the dark, because I don't have Matlab to test it, but I suspect you'll have to return a python array object, not a numpy array.
So something like this:
import numpy as np
import array
def computecoreset(mat, coresetSize):
c = np.random.choice(mat, coresetSize)
return array.array('d', c)
Just for completeness, the other way goes like this:
rnd = rand(5);
py.numpy.asarray(rnd)
Python ndarray:
0.3112 0.6541 0.2290 0.9961 0.0046
0.5285 0.6892 0.9133 0.0782 0.7749
0.1656 0.7482 0.1524 0.4427 0.8173
0.6020 0.4505 0.8258 0.1067 0.8687
0.2630 0.0838 0.5383 0.9619 0.0844
Use details function to view the properties of the Python object.
Use double function to convert to a MATLAB array.
How can I import factorial function from numpy and scipy separately in order to see which one is faster?
I already imported factorial from python itself by import math. But, it does not work for numpy and scipy.
You can import them like this:
In [7]: import scipy, numpy, math
In [8]: scipy.math.factorial, numpy.math.factorial, math.factorial
Out[8]:
(<function math.factorial>,
<function math.factorial>,
<function math.factorial>)
scipy.math.factorial and numpy.math.factorial seem to simply be aliases/references for/to math.factorial, that is scipy.math.factorial is math.factorial and numpy.math.factorial is math.factorial should both give True.
The answer for Ashwini is great, in pointing out that scipy.math.factorial, numpy.math.factorial, math.factorial are the same functions. However, I'd recommend use the one that Janne mentioned, that scipy.special.factorial is different. The one from scipy can take np.ndarray as an input, while the others can't.
In [12]: import scipy.special
In [13]: temp = np.arange(10) # temp is an np.ndarray
In [14]: math.factorial(temp) # This won't work
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-14-039ec0734458> in <module>()
----> 1 math.factorial(temp)
TypeError: only length-1 arrays can be converted to Python scalars
In [15]: scipy.special.factorial(temp) # This works!
Out[15]:
array([ 1.00000000e+00, 1.00000000e+00, 2.00000000e+00,
6.00000000e+00, 2.40000000e+01, 1.20000000e+02,
7.20000000e+02, 5.04000000e+03, 4.03200000e+04,
3.62880000e+05])
So, if you are doing factorial to a np.ndarray, the one from scipy will be easier to code and faster than doing the for-loops.
SciPy has the function scipy.special.factorial (formerly scipy.misc.factorial)
>>> import math
>>> import scipy.special
>>> math.factorial(6)
720
>>> scipy.special.factorial(6)
array(720.0)
from numpy import prod
def factorial(n):
print prod(range(1,n+1))
or with mul from operator:
from operator import mul
def factorial(n):
print reduce(mul,range(1,n+1))
or completely without help:
def factorial(n):
print reduce((lambda x,y: x*y),range(1,n+1))
after running different aforementioned functions for factorial, by different people, turns out that math.factorial is the fastest to calculate the factorial.
find running times for different functions in the attached image
You can save some homemade factorial functions on a separate module, utils.py, and then import them and compare the performance with the predefinite one, in scipy, numpy and math using timeit.
In this case I used as external method the last proposed by Stefan Gruenwald:
import numpy as np
def factorial(n):
return reduce((lambda x,y: x*y),range(1,n+1))
Main code (I used a framework proposed by JoshAdel in another post, look for how-can-i-get-an-array-of-alternating-values-in-python):
from timeit import Timer
from utils import factorial
import scipy
n = 100
# test the time for the factorial function obtained in different ways:
if __name__ == '__main__':
setupstr="""
import scipy, numpy, math
from utils import factorial
n = 100
"""
method1="""
factorial(n)
"""
method2="""
scipy.math.factorial(n) # same algo as numpy.math.factorial, math.factorial
"""
nl = 1000
t1 = Timer(method1, setupstr).timeit(nl)
t2 = Timer(method2, setupstr).timeit(nl)
print 'method1', t1
print 'method2', t2
print factorial(n)
print scipy.math.factorial(n)
Which provides:
method1 0.0195569992065
method2 0.00638914108276
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Process finished with exit code 0