2011-02-01 1 views
2

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

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

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

С учетом коэффициентов и число, polyval() оценивает многочлен.

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

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

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

+0

Что делать вы имеете в виду «положить произвольный массив длин этих коэффициентов в лямбда-функцию»? – Phil

+2

Я не понимаю, почему важно, чтобы это была лямбда-функция. Конечно, вы можете просто определить регулярную функцию. – senderle

ответ

7

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

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 значения)

+0

Это принципиально верно. Только две настройки: (1) «ctx» просто скрывается (поливал - это метод), и его не нужно передавать; и (2) findroot нуждается в интервале или отправной точке. Итак, findroot (lambda x: polyval ([1,2,0], x), [-3, -1]) возвращает mpf ('- 2.0'), как и следовало ожидать. – DSM

1

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

Lambda выражение возможно, благодаря отличным функциям базы 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).

+0

Я думаю, что суммарный вариант ответа ncoghlan проще: def f (cfs, x): return sum (c * x ** i для i, c в перечислении (обратный (cfs))) – DSM

+0

Действительно, перечислите правила! – Emmanuel

1

Если вы действительно хотите, лямбда-выражения, то easiset я могу думать использует 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) 
+0

Красивое использование функции 'reduce'! – Emmanuel

Смежные вопросы