如何在python中使用矢量化方法?

时间:2016-03-08 22:39:32

标签: python numpy

我写了以下两个函数:

def iterate_list(f, x0, n_iterations):

    # initialise the list consisting of iterates of f
    list = [x0]

    # initialise x
    x = x0

    # iterate using for loop
    for n in xrange(n_iterations):
        x = f(x)
        list.append(x)

    # return the list consisting of iterates of f
    return list

def lyapunov_exponent(f, df, x0, n_iterations):

    from iterate_list import iterate_list
    import numpy as np

    # vectorise the list of iterates x0 to xn of f
    vec = np.array(iterate_list(f, x0, n_iterations))

    # calculate the sum of all the values of df for x0 to xn
    s = sum(np.log(abs(df(vec))))

    # calculate the mean as an estimate of the lyapunov exponent
    return s / (n_iterations + 1)

f = k * x * (1-x)
df = k * (1 - 2*x)

但是现在我想在两个函数中改变k的值并设置k = np.linspace(3.0, 4.0, 11)。如何修改函数,以便为每个k值返回一个Lyapunov指数列表?我现在遇到的困难是我想使用矢量化方法而不是循环。

1 个答案:

答案 0 :(得分:0)

您的功能,在此上下文中运行:

f = lambda x,k: k * x * (1-x)
df = lambda x,k: k * (1 - 2*x)

# test k iteratively
for k in [1,2]:
    print(iterate_list(f, .25, k, 5))
    print(lyapunov_exponent(f, df, .25, k, 5))

# test k as array; x0 is matching size
k = np.array([1,2])
x0  = np.array([.25,.25])
ll = iterate_list(f, x0, k, 5)
print(ll)
la = np.array(ll)   # turn list array as done in lyapunov
print(la.shape)
print(la[:,0])
print(la[:,1])
print(lyapunov_exponent(f, df, x0, k, 5))

产生

2243:~/mypy$ python2.7 stack35879467.py 
[0.25, 0.1875, 0.15234375, 0.1291351318359375, 0.11245924956165254, 0.09981216674968249]
-0.383796035676
[0.25, 0.375, 0.46875, 0.498046875, 0.49999237060546875, 0.4999999998835847]
-6.58489821532
[array([ 0.25,  0.25]), array([ 0.1875,  0.375 ]), array([ 0.15234375,  0.46875   ]), array([ 0.12913513,  0.49804688]), array([ 0.11245925,  0.49999237]), array([ 0.09981217,  0.5       ])]
(6, 2)
[ 0.25        0.1875      0.15234375  0.12913513  0.11245925  0.09981217]
[ 0.25        0.375       0.46875     0.49804688  0.49999237  0.5       ]
[-0.38379604 -6.58489822]

因此,使用向量k运行问题(并匹配x0)会产生与迭代执行相同的结果。事实上kx0几乎可以有任何维度(0d,1d,2d等),只要它们具有相同的形状。

可以清理一下,但是你的功能在k中“矢量化”就好了。

摆脱iterate_list中的迭代将会更棘手,因为每个阶段的值取决于前一个值。可以写f(x,k)来使用cumprod

以下是我运行的脚本中的函数:

def iterate_list(f, x0, k, n_iterations):

    # initialise the list consisting of iterates of f
    alist = [x0]

    # initialise x
    x = x0

    # iterate using for loop
    for n in xrange(n_iterations):
        x = f(x,k)
        alist.append(x)

    # return the list consisting of iterates of f
    return alist

def lyapunov_exponent(f, df, x0, k, n_iterations):

    # vectorise the list of iterates x0 to xn of f
    vec = np.array(iterate_list(f, x0, k, n_iterations))

    # calculate the sum of all the values of df for x0 to xn
    s = sum(np.log(abs(df(vec,k))))

    # calculate the mean as an estimate of the lyapunov exponent
    return s / (n_iterations + 1)