Как найти полином для заданных корней с sympy / python - PullRequest
0 голосов
/ 03 февраля 2019

Предположим, у меня есть многочлен третьей степени с корнями в -2, 1 и 3, как мне найти его уравнение?Это разрешимо с sympy или, может быть, есть и другие способы с питоном в целом?

Функция может понравиться, и я хочу решить a, b, c, d.

f = lambda x: a*x**3+b*x**2+c*x+d

А что, если полином пятой степени?

Обновление:

Спасибо за ответы.Кажется, использование формулы Виеты упростило вопрос.Но иногда число корней для многочлена N-й степени не равно N. Например, многочлен пятой степени может быть выражен следующим образом:

(x-a)**2*(x-b)**2(x-c)

Если это так, это все еще разрешимо??

Пожалуйста, посмотрите мое решение ниже для этого обновления

Ответы [ 5 ]

0 голосов
/ 04 февраля 2019

Спасибо за все ответы.После игры со своими решениями.Для моего Обновления с повторяющимися корнями я нашел следующее решение:

def find_all_polys(degree, roots):
    '''find all formats of polynomials with given degree and roots

    Args:
        degree (int): the degree of the polynomial
        roots (list): the list contains all given roots

    Returns:
        All simplified formats of polynomials with a given degree

    Notes:
        1. The degree of a polynomial determines its maximum number of
           all possible real roots.
        2. Each combination of roots for a given degree polynomial
           determines a simplified format of the polynomial (i.e., the
           coefficient of the highest-degree term is 1)
        3. The number of all possible formats for a n-th degree
           polynomial with m roots is defined as:
                            H(m, n-m)=C(m, n-m+m-1)
           Since the given roots will always be contained in the roots
           combination, the number of format variations depends on the
           combination of duplicated roots, which can be considered as
           a combination with repetition problem as defined above.

    '''

    from math import factorial
    from sympy import Symbol

    # counting number of all possible roots combinations
    nHr = lambda n,r: factorial(n+r-1)/(factorial(r)*factorial(n-1))
    n_all_roots = nHr(len(roots), degree-len(roots))

    # getting all roots combinations
    if len(np.unique(roots)) == len(roots):
        n_dups = degree-len(roots)
        roots_all_dups = []
        while True:
            # randomly select from the given roots
            roots_dups = np.random.choice(roots, n_dups).tolist()
            roots_dups.sort()

            # testing if the combination already exists
            if roots_dups not in roots_all_dups:
               roots_all_dups.append(roots_dups)
            else:
                if len(roots_all_dups) == n_all_roots:
                    break

        # adding duplicated roots to all given roots list
        for dups in roots_all_dups:
            dups.extend(roots)
        all_roots_combs = roots_all_dups

        # finding all possible formats of polynomials
        for counter, roots_combs in enumerate(all_roots_combs):
            x = Symbol('x'); term = 1
            for root in all_roots_combs[counter]:
                term *= (x-root)
            print(f'f(x) = {term.expand()}')

    else:
        raise ValueError('The root list should not contain duplicated roots')

Например:

roots = [-2, 1, 3]
find_all_polys(degree=6, roots=roots)

вернет:

f(x) = x**6 - 4*x**5 - 6*x**4 + 32*x**3 + x**2 - 60*x + 36
f(x) = x**6 - 6*x**5 + 50*x**3 - 45*x**2 - 108*x + 108
f(x) = x**6 - 9*x**5 + 24*x**4 + 2*x**3 - 99*x**2 + 135*x - 54
f(x) = x**6 - x**5 - 15*x**4 + 5*x**3 + 70*x**2 + 12*x - 72
f(x) = x**6 + 4*x**5 - 5*x**4 - 40*x**3 - 40*x**2 + 32*x + 48
f(x) = x**6 + x**5 - 11*x**4 - 13*x**3 + 26*x**2 + 20*x - 24
f(x) = x**6 - 2*x**5 - 8*x**4 + 14*x**3 + 11*x**2 - 28*x + 12
f(x) = x**6 - 11*x**5 + 40*x**4 - 30*x**3 - 135*x**2 + 297*x - 162
f(x) = x**6 - 5*x**5 + 4*x**4 + 14*x**3 - 31*x**2 + 23*x - 6
f(x) = x**6 - 7*x**5 + 12*x**4 + 14*x**3 - 59*x**2 + 57*x - 18
0 голосов
/ 03 февраля 2019

Это должно сделать трюк для полинома в любой степени.Символ звездочки допускает любое количество аргументов.

def c_find(*roots):
    from sympy import Symbol
    x = Symbol('x')
    whole =1
    for root in roots:
        whole *=(x-root)
    print('f(x) =',whole.expand())

вызов c_find(3,4,5) возврат f(x) = x**3 - 12*x**2 + 47*x - 60

0 голосов
/ 03 февраля 2019
def f(x): return (x - (-2)) * (x - 1) * (x - 2)

Для оценки полинома в точке x это должно быть так же хорошо, как умножение коэффициентов на символы.Чтобы сделать несколько полиномиальных функций, определенных корнями, используйте фабрику функций.

def poly3(r1, r2, r3):
    def _poly3(x):
        return (x - r1) * (x - r2) * (x - r3)
    return _poly3

f2 = poly3(-2, 1, 2)

for i in range(-10, 11):
    assert f(i) == f2(i)
# no AssertionError means all tests pass

Следующее обобщение дает n корней.

def polyn(*roots):
    def _polyn(x):
        val = 1
        for r in roots:
            val *= x - r
        return val
    return _polyn

f3 = polyn(-2, 1, 2)

for i in range(-10, 11):
    assert f(i) == f3(i)
# Above code passed on Win 10, 3.7.2
0 голосов
/ 03 февраля 2019

В numpy имеется базовый poly набор функций:

In [44]: f = np.poly([-2,1,3])
In [45]: f
Out[45]: array([ 1., -2., -5.,  6.])
In [46]: np.roots(f)
Out[46]: array([-2.,  3.,  1.])
In [49]: np.polyval(f, np.arange(-3,5))
Out[49]: array([-24.,   0.,   8.,   6.,   0.,  -4.,   0.,  18.])

Значения в диапазоне значений также можно оценить с помощью:

In [53]: np.dot(np.arange(-3,5)[:,None]**np.array([3,2,1,0]), f)
Out[53]: array([-24.,   0.,   8.,   6.,   0.,  -4.,   0.,  18.])
0 голосов
/ 03 февраля 2019

Используйте sympy, чтобы построить многочлен из корней, а затем получить коэффициенты:

from sympy import Symbol, poly

x = Symbol('x')

roots = [-1, 1]
expr = 1

# polynomial in format (x-a)(x-b)(x-c)...
for i in roots:
  expr *= (x - i)

p = poly(expr, x)
print(p)
print(p.all_coeffs())

Вывод:

Poly(x**2 - 1, x, domain='ZZ')
[1, 0, -1]

Обратите внимание, что это будет работать для произвольно длинного спискакорней.

Например, если корни [-1, 1, 2, 3, 4, 5, 6]

Вывод:

Poly(x**7 - 20*x**6 + 154*x**5 - 560*x**4 + 889*x**3 - 140*x**2 - 1044*x + 720, x, domain='ZZ')
[1, -20, 154, -560, 889, -140, -1044, 720]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...