Numerical Python - how to make this ufunc?

new for NumPy and may not be looking correctly, so I will take pieces if this is a general question ...

I am working on a problem when I need to compute log (n!) For relatively large numbers - i.e. to big, to calculate the factorial first, so I wrote the following function:

def log_fact(n):
    x = 0
    for i in range(1,n+1):
        x += log(i)
    return x

Now the problem is that I want to use this as part of the function passed to curve_fit:

def logfactfunc(x, a, b, c):
    return a*log_fact(x) + b*x + c

from scipy.optimize import curve_fit

curve_fit(logfactfunc, x, y)

However, this results in the following error:

File "./fit2.py", line 16, in log_fact
    for i in range(1,n+1):
TypeError: only length-1 arrays can be converted to Python scalars

A small search suggested numpy.frompyfunc () to convert this to ufunc

curve_fit(np.frompyfunc(logfactfunc, 1, 1), data[k].step, data[k].sieve)

TypeError: <ufunc 'logfactfunc (vectorized)'> is not a Python function

Tried this too:

def logfactfunc(x, a, b, c):
    return a*np.frompyfunc(log_fact, 1, 1)(x) + b*x + c

File "./fit2.py", line 30, in logfactfunc
    return a*np.frompyfunc(log_fact, 1, 1)(x) + b*x + c
TypeError: unsupported operand type(s) for +: 'numpy.ndarray' and 'numpy.float64

Any ideas on how I can get my log_fact () function to be used in curve_fit () function

Thanks!

+4
source share
5 answers

n (, 10 ), , . . .

, , log_fact(n) ,

def log_fact(n) :
    return np.sum(np.log(np.arange(1,n+1)))

. @Isaac np.vectorize(), , . , , Python.

, !

+2

log_fact gammaln, ufunc scipy.special. , log_fact(n) == scipy.special.gammaln(n+1). n :

In [15]: %timeit log_fact(19)
10000 loops, best of 3: 24.4 us per loop
In [16]: %timeit scipy.special.gammaln(20)
1000000 loops, best of 3: 1.13 us per loop

, gammaln n, log_fact.

+6

log_fact , . :

def log_fact(n):
    n = np.asarray(n)
    m = np.max(n)
    return np.take(np.cumsum(np.log(np.arange(1, m+1))), n-1)

:

>>> log_fact(3)
1.791759469228055
>>> log_fact([10, 15, 23])
array([ 15.10441257,  27.89927138,  51.60667557])
>>> log_fact([[10, 15, 23], [14, 15, 8]])
array([[ 15.10441257,  27.89927138,  51.60667557],
       [ 25.19122118,  27.89927138,  10.6046029 ]])

, , , . n , , , . , , .

+3

, ufunc , c. . ufuncs.

, ndarray s. :

def logfact_arr(a):
  return np.array([log_fact(x) for x in a.flat]).reshape(a.shape)
0

. , .. log_fact, np.vectorize:

vlog_fact=np.vectorize(log_fact)
def vlogfactfunc(x, a, b, c):
    return a*vlog_fact(x) + b*x + c

curve_fit(vlogfactfunc, np.array([1,2,3]), np.array([ -1. , 4.465 , 11.958]))

, np.frompyfunc, , , python, curve_fit :

TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'

, float:

ulog_fact = np.frompyfunc(log_fact, 1,1) 
def ulogfactfunc(x, a, b, c):
    return a*ulog_fact(x).astype(np.float) + b*x + c

, curve_fit ulogfactfunc , !

0

All Articles