Как я могу построить полиномиальную лямбда-функцию из списка коэффициентов? - PullRequest
3 голосов
/ 01 февраля 2011

У меня есть список коэффициентов, которые соответствуют полиномиальному выражению, то есть: [1,2,0] соответствует x^2 + 2x + 0. Я хотел бы поместить массив произвольной длины этих коэффициентов в лямбда-функцию.

В частности, я использую mpmath и у меня есть список, используемый для поливального модуля , то есть:

polyval(ctx, coeffs, x, derivative=False)

Учитывая коэффициенты и число, polyval() оценивает полином.

И мне нужно использовать модуль findroot которая принимает одномерную функцию, то есть:

findroot(lambda x: x**3 + 2*x + 1, 2)

Как я могу построить лямбда-функцию из списка коэффициентов?

Ответы [ 4 ]

7 голосов
/ 01 февраля 2011

Вам действительно нужна функция лямбда ?Использовать «обычную» функцию должно быть проще:

def poly(coeffs):
   def calc(x):
      result = 0
      for c in coeffs:
         result = result*x + c
      return result
   return calc

findroot(poly([1,2,0]))

А с помощью упомянутой вами функции polyval() должно работать что-то вроде этого:

findroot(lambda x: polyval(ctx, [1,2,0], x))

(Для соответствующего ctx значение)

1 голос
/ 01 февраля 2011

Если вы действительно хотите лямбда-выражение, я могу придумать, как просто можно использовать reduce():

coeffs = [1, 2, 0]
f = lambda x: reduce(lambda y, a: x*y + a, coeffs, 0.0)
findroot(f, 2)

Поскольку это также помечено numpy, вы также можете использовать numpy.poly1d:

coeffs = [1, 2, 0]
f = numpy.poly1d(coeffs)
findroot(f, 2)
1 голос
/ 01 февраля 2011
Подход, основанный на

sth polyval(), выглядит как лучший ответ (поскольку у вас уже есть доступ к этой функции), но если вы хотите реализовать свой собственный эквивалент, функция будет выглядеть примерно так:

def poly(coeffs):
  def calc(x)
    result = 0
    for i,c in enumerate(reversed(coeffs)):
      result += c*(x**i)
    return result
  return calc

findroot(poly([1,2,0]))
0 голосов
/ 01 февраля 2011

Лямбда-выражение возможно благодаря великолепным базовым функциям Python! Первое - получить пары (коэф, экспоненты) с помощью мощной функции zip:

>>> l = [3, 0, 4, -9]
>>> range(len(l) - 1, -1, -1)
[3, 2, 1, 0]
>>> zip(l, range(len(l) - 1, -1, -1))
[(3, 3), (0, 2), (4, 1), (-9, 0)]

Я использую перевернутый range, так как большие показатели находятся в начале списка. Теперь полином - это сумма ... вычисленная благодаря функции sum!

>>> f = lambda x: sum([coef*x**exp for (coef, exp) in zip(l, range(len(l) - 1, -1, -1))])
>>> f(3)
84

и действительно 3*3^3 + 0*3^2 + 4*3^1 - 9*3^0 = 3*27 + 0 + 4*3 - 9*1 = 81 + 12 - 9 = 84. Это выражение f является правильным для всего списка значений l независимо от его длины, благодаря использованию len(l).

...