L oop код с: {x_ (n + 1) = x_n * r * (1-x_n)} - PullRequest
1 голос
/ 16 апреля 2020

Немного нового, и любая помощь будет принята с благодарностью.

Я уже некоторое время разбираюсь с этим кодом и, похоже, не могу обернуть его вокруг. Я довольно новичок в python, поэтому я пока не знаю и не помню все уловки / умения.

Итак, под рукой вопрос:

Уравнение: {x_ (n + 1) ) = x_n * r * (1-x_n)}

С x_n между (0,1) и r между (0,4).

Цель состоит в том, чтобы сделать функцию al oop, которая будет собирать значение для 'x_n' и 'r' и выплевывать итерацию 'n' и текущий 'x_n + 1'; то есть напечатайте (n, x_n + 1), на каждом шаге 'n', проверяя, находится ли новое значение в пределах 0,0000001 от старого значения.

Если оно устанавливается в фиксированной точке в пределах 20 000 (0,0000001) , напечатайте окончательное сообщение 'n' +. Если нет, то перейдите к 20 000, а затем напечатайте еще одно сообщение.

Все, что у меня есть, это:

import math

x_o=float(input("Enter a 'seed' value: "))
r=float(input("Enter an 'r' value: "))
x_a=((x_o + 0) * r * (1-(x_o + 0)))

while x_a != (0.0000001, x_o , 0.0000001):
  for n in range(0,99):
    x_a=((x_o + n) * r * (1-(x_o + n)))
    print(n , x_a)

Я почти уверен, что это не так близко, поэтому любая помощь будет огромной ; если вам нужна дополнительная информация, дайте мне знать.

Очень ценю, Геносфера

Ответы [ 3 ]

2 голосов
/ 16 апреля 2020

Вы можете написать функцию генератора и использовать ее непосредственно в вашем для l oop. Если вам нужно отслеживать ранг промежуточных значений, вы можете использовать перечисление в генераторе.

def fnIter(fn,x,delta=0.000001):
    while True:
        yield x
        prev,x = x,fn(x)
        if abs(x-prev)<delta:break

output:

r    = 2
seed = 0.1
for i,Xn in enumerate(fnIter(lambda x:x*r*(1-x),seed)):
    print(i,Xn)

0 0.1
1 0.18000000000000002
2 0.2952
3 0.41611392
4 0.4859262511644672
5 0.49960385918742867
6 0.49999968614491325
7 0.49999999999980305

Для реализации проверки максимальной итерации вы можете добавить условный разрыв в l oop или используйте zip с диапазоном:

maxCount = 20000
n,Xn = max(zip(range(maxCount+1),fnIter(lambda x:x*r*(1-x),seed)))

if n < maxCount:
    print(n,Xn)
else:
    print(Xn,"not converging")
1 голос
/ 16 апреля 2020

Это экспоненциально-взвешенное скользящее среднее. Pandas имеет функцию для этого: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.ewm.html

0 голосов
/ 16 апреля 2020

Пока у вас хорошее начало. Вы можете переосмыслить это.

Следующий подход просто пытается сгенерировать эту последовательность для 20 000 терминов. Каждый раз он проверяет, находится ли новое значение в пределах 0,0000001 от предыдущего значения. Если это так, он вырывается из l oop и печатает это. Если нет, то для вывода другого значения используется конструкция python for / else. Обратите внимание на различные уровни отступа .

x_0 = float(input("enter a 'seed' value: "))
r = float(input("enter an 'r' value: "))

x_m = x_0  # placeholder for 'previous value'
delta = 0.0000001

# Try to calculate 20 thousand terms of this sequence
# We will break out of the loop early if our x_n converges
for _ in range(20000):  
    x_n = x_m * r * (1 - x_m)
    if abs(x_n - x_m) < delta:
        print("Settled on value for x_n: ", x_n)
        break
    else:
        x_m = x_n  # move forward to the next value
else:
  print("x_n did not converge in 20000 terms")
...