Расчет производной очков в python - PullRequest
3 голосов
/ 31 января 2020

Я хочу вычислить производную баллов, для нескольких постов типа inte rnet предлагается использовать функцию np.diff. Однако я попытался использовать np.diff для вычисленных вручную результатов (выбрал случайное полиномиальное уравнение и дифференцировал его), чтобы проверить, получу ли я в результате те же результаты. Я использовал следующее выражение: Y = (X ^ 3) + (X ^ 2) + 7, и результаты, с которыми я закончил, были другими. Есть идеи почему? Есть ли какой-либо другой метод для вычисления разницы.

В задаче, которую я пытаюсь решить, я получил точки данных с подогнанной функцией сплайна (не исходные данные, которые должны быть подогнаны сплайном, но точки уже установленного сплайна). Значения x находятся через равные интервалы. У меня есть только точки и нет уравнения, что мне нужно для расчета, первая, вторая и третья производные. т.е. dy / dx, d2y / dx2, d3y / dx3. Есть идеи, как это сделать?. Заранее спасибо.

xval = [1,2,3,4,5]
yval = []
yval_dashList = []

#selected a polynomial equation
def calc_Y(X):
      Y = (X**3) + (X**2) + 7
      return(Y)

#calculate y values using equatuion 
for i in xval:
    yval.append(calc_Y(i))

#output: yval = [9,19,43,87,157]

#manually differentiated the equation or use sympy library (sym.diff(x**3 + x**2 + 7))
def calc_diffY(X):
   yval_dash = 3*(X**2) + 2**X

#store differentiated y-values in a list
for i in xval:
    yval_dashList.append(yval_dash(i))

#output: yval_dashList = [5,16,35,64,107]

#use numpy diff method on the y values(yval)
numpyDiff = np.diff(yval)
#output: [10,24,44,60]

Значения numpy diff метода [10,24,44,60] отличаются от yval_dashList = [5,16,35,64,107]

Ответы [ 2 ]

5 голосов
/ 31 января 2020

Идея того, что вы пытаетесь сделать, правильная, но есть пара моментов, чтобы заставить ее работать как задумано:

  1. В calc_diffY (X), производной от производной, есть опечатка X ** 2 равно 2 * X, а не 2 ** X:
  def calc_diffY(X):    
      yval_dash = 3*(X**2) + 2*X

При этом вы не получите намного лучших результатов:

yval_dash = [5, 16, 33, 56, 85]
numpyDiff = [10. 24. 44. 70.]
Чтобы вычислить числовую производную, вы должны сделать «Коэффициент разности», который является приближением производной
numpyDiff = np.diff(yval)/np.diff(xval)

Приближение становится все лучше и лучше, если значения точек более плотные , Разница между вашими точками на оси x равна 1, поэтому вы попадаете в эту ситуацию (синим цветом - аналитическая производная, красным - цифра):

enter image description here

Если вы уменьшите разницу в своих точках х до 0,1, вы получите это, что гораздо лучше:

enter image description here

Просто добавьте что-то к взгляните на это изображение, показывающее эффект уменьшения расстояния между точками, по которым производная численно рассчитывается, взято из Wikipedia :

enter image description here

4 голосов
/ 31 января 2020

Мне нравится ответ @ lgsp. Я добавлю, что вы можете напрямую оценить производную, не беспокоясь о том, сколько места между значениями. Это просто использует формулу симметрии c для расчета конечных разностей, описанную в на этой странице википедии .

Обратите внимание, что указан способ delta. Я обнаружил, что когда он слишком мал, оценки более высокого порядка терпят неудачу. Вероятно, нет 100% общего значения c, которое всегда будет работать хорошо!

Кроме того, я упростил ваш код, воспользовавшись преимуществом numpy широковещательной передачи по массивам для исключения циклов.

import numpy as np

# selecte a polynomial equation
def f(x):
    y = x**3 + x**2 + 7
    return y

# manually differentiate the equation
def f_prime(x):
    return 3*x**2 + 2*x

# numerically estimate the first three derivatives
def d1(f, x, delta=1e-10):
    return (f(x + delta) - f(x - delta)) / (2 * delta)

def d2(f, x, delta=1e-5):
    return (d1(f, x + delta, delta) - d1(f, x - delta, delta)) / (2 * delta)

def d3(f, x, delta=1e-2):
    return (d2(f, x + delta, delta) - d2(f, x - delta, delta)) / (2 * delta)

# demo output
# note that functions operate in parallel on numpy arrays -- no for loops!
xval = np.array([1,2,3,4,5])

print('y  = ', f(xval))
print('y\' = ', f_prime(xval))
print('d1 = ', d1(f, xval))
print('d2 = ', d2(f, xval))
print('d3 = ', d3(f, xval))

И выходы:

y  =  [  9  19  43  87 157]
y' =  [ 5 16 33 56 85]
d1 =  [ 5.00000041 16.00000132 33.00002049 56.00000463 84.99995374]
d2 =  [ 8.0000051  14.00000116 20.00000165 25.99996662 32.00000265]
d3 =  [6.         6.         6.         6.         5.99999999]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...