Pythonic从线性差异生成序列的方法

问题描述 投票:0回答:2

我有一个序列定义

xn + 1 = f(xn,xn-1)

其中xn是在时间tn评估的x。序列中的任何值都由前两个值的某个函数(以及时间步长,但现在是常量)定义。我希望在此序列中生成前N个值,给定x0和x1。

什么是最pythonic的方式来做到这一点?

我目前的做法只是循环。我创建一个正确大小的numpy.ones数组,然后通过索引循环它。如果index = 01,那么我将值从1分别更改为x0 / x1。对于更大的凹凸,我查找数组中的先前值并应用该函数。

但我觉得这似乎没有使用numpy数组方法,所以我想知道是否有更好的方法?

Code

在我的代码中,我有一个createSequence函数,它接受xn + 1的定义以及边界条件和时间步长,并输出遵循这些规则的序列。 NB,我是Python的新手,所以任何一般建议也将不胜感激!

import numpy as np

def x_next(x_current,x_previous,dt):
    """Function to return the next value in the sequence
       x_current and x_previous are the values at tn and tn-1 respectively
       dt is the time step
    """
    return (x_current - x_previous)/dt #as an example

def createSequence(x_next,x0,x1,start,stop,dt):
    """ Function to create sequence based on x_next function, and boundary conditions"""
    num = (stop-start)/dt
    x_array = np.ones(int(num))
    x_array[0] = x0
    x_array[1] = x1
    for index in range(len(x_array)):
        if index == 0:
            x_array[index] = x0
        elif index == 1:
            x_array[index] = x1
        else:
            x_current = x_array[index - 1]
            x_previous = x_array[index - 2]
            x_array[index] = x_next(x_current,x_previous,dt)
    return x_array

print(createSequence(x_next=x_next,x0=0.1,x1=0.2,start=0,stop=20,dt=0.1))
python arrays python-3.x numpy sequence
2个回答
0
投票

我建议使用发电机,因为

  • 它允许您生成任意长度的序列而不浪费内存
  • 有人可能认为它是“pythonic”。

在下文中,我将使用Fibonacci sequence作为示例,因为它采用与您的问题类似的形式。

def fibonacci(a=0, b=1, length=None):
    # Generate a finite or infinite sequence
    num = 0
    while length is None or num < length:
        # Evaluate the next Fibonacci number
        c = a + b
        yield c
        # Advance to the next item in the sequence
        a, b = c, a
        num += 1

请注意,a对应于您的x_nb对应于x_{n-1},而c对应于x_{n+1}。还有一个简单的例子:

>>> list(fibonacci(length=10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

如果你想让序列变成一个numpy数组

>>> np.fromiter(fibonacci(length=10), int)
array([ 1,  1,  2,  3,  5,  8, 13, 21, 34, 55])

0
投票

我想你想要最初的术语集合。但是,如果你或者读过这个问题的任何人都想要个别条款,那么sympy库会派上用场。这里到水平线的所有东西都来自Solve a recurrence relation

>>> from sympy import *
>>> var('y')
y
>>> var('n', integer=True)
n
>>> f = Function('f')
>>> f = y(n)-2*y(n-1)-5*y(n-2)
>>> r = rsolve(f, y(n), [1, 4])

一旦你有r,你可以在同情设施内评估它的各种n值......

>>> N(r.subs(n,1))
4.00000000000000
>>> N(r.subs(n,2))
13.0000000000000
>>> N(r.subs(n,10))
265333.000000000

或者您可以“解除”r中的代码并将其重新用于您自己的例程。

>>> r
(1/2 + sqrt(6)/4)*(1 + sqrt(6))**n + (-sqrt(6) + 1)**n*(-sqrt(6)/4 + 1/2)
© www.soinside.com 2019 - 2024. All rights reserved.