Having a list and trying to make a polynomial in Python (symbolic calculation)

那年仲夏 提交于 2020-03-26 05:18:02

问题


Suppose I have the following list:

f=[1, 3, 4, 5, 3, 4, 5, 6, 6, 3, 3, 1, 1, 4, 2]

I can count how many of each integers exists in the list using two methods.

First:

from collections import Counter
Counter(f)
#Counter({1: 3, 2: 1, 3: 4, 4: 3, 5: 2, 6: 2})

or second:

[[x,f.count(x)] for x in set(f)]
#[[1, 3], [2, 1], [3, 4], [4, 3], [5, 2], [6, 2]]

the second method is preferable as it throws me with a list. Now I want to turn the output into polynomial where the first element of sublists would be power of x and the second element of sublists would be the coefficients and finally sum them to form a polynomial, such that I get:

3 x + x^2 + 4 x^3 + 3 x^4 + 2 x^5 + 2 x^6

To make this polynomial I used Sympy as follow:

from sympy import Array, tensorproduct
from sympy.abc import x
from sympy import transpose
A = Array([x])
B = Array([x[1] for x in [[x,f.count(x)] for x in set(f)]])
tensorproduct(A, B)
#[[3*x, x, 4*x, 3*x, 2*x, 2*x]]

now I am not sure how to raise for the correct power of x ? Also is there a better solution for this?


回答1:


this should work for you:

from sympy import poly, var
from collections import Counter

x = var("x")
f = [1, 3, 4, 5, 3, 4, 5, 6, 6, 3, 3, 1, 1, 4, 2]
count = Counter(f)
p = sum(coeff * x ** exp for exp, coeff in count.items())
# 2*x**6 + 2*x**5 + 3*x**4 + 4*x**3 + x**2 + 3*x

where ** is used for exponentiation.




回答2:


Did you want to actually evaluate the polynomial, or just get a pretty string?

from collections import Counter
superscript_digits = "⁰¹²³⁴⁵⁶⁷⁸⁹"

f=[1, 3, 4, 5, 3, 4, 5, 6, 6, 3, 3, 1, 1, 4, 2]
coeffs_by_exp = Counter(f)
print(' + '.join("{}x{}".format(coeff, superscript_digits[exp])
                     for exp, coeff in coeffs_by_exp.items()))

Gives:

3x¹ + 1x² + 4x³ + 3x⁴ + 2x⁵ + 2x⁶

Special handling of omitting 1 coeffecients and 0 and 1 exponents left as an exercise for the OP.




回答3:


You can also take a look at this which is working well but maybe too complex compared with what you want to achieve (you can compute the derivative, ...).

More particularly, this piece of code can help you:

import numpy as np
import matplotlib.pyplot as plt
class Polynomial:

def __init__(self, *coefficients):
    """ input: coefficients are in the form a_n, ...a_1, a_0 
    """
    # for reasons of efficiency we save the coefficients in reverse order,
    # i.e. a_0, a_1, ... a_n
    self.coefficients = coefficients[::-1] # tuple is also turned into list

def __repr__(self):
    """
    method to return the canonical string representation 
    of a polynomial.

    """
    # The internal representation is in reverse order,
    # so we have to reverse the list
    return "Polynomial" + str(self.coefficients[::-1])

def __call__(self, x):    
    res = 0
    for index, coeff in enumerate(self.coefficients):
        res += coeff * x** index
    return res 

def degree(self):
    return len(self.coefficients)

@staticmethod
def zip_longest(iter1, iter2, fillchar=None):    
    for i in range(max(len(iter1), len(iter2))):
        if i >= len(iter1):
            yield (fillchar, iter2[i])
        elif i >= len(iter2):
            yield (iter1[i], fillchar)
        else:
            yield (iter1[i], iter2[i])
        i += 1   

def __add__(self, other):
    c1 = self.coefficients
    c2 = other.coefficients
    res = [sum(t) for t in Polynomial.zip_longest(c1, c2, 0)]
    return Polynomial(*res[::-1])

def __sub__(self, other):
    c1 = self.coefficients
    c2 = other.coefficients
    res = [t1-t2 for t1, t2 in Polynomial.zip_longest(c1, c2, 0)]
    return Polynomial(*res[::-1])

def derivative(self):
    derived_coeffs = []
    exponent = 1
    for i in range(1, len(self.coefficients)):
        derived_coeffs.append(self.coefficients[i] * exponent)
        exponent += 1
    return Polynomial(*derived_coeffs[::-1])

def __str__(self):
    res = ""
    for i in range(len(self.coefficients)-1, -1, -1):
        res +=  str(self.coefficients[i]) + "x^" + str(i) + " + "
    if res.endswith(" + "):
        res = res[:-3]
    return res

Then you can use:

 p = Polynomial(-0.8, 2.3, 0.5, 1, 0.2)

To get:

Hope this can help you!




回答4:


Poly can instantiate from a list of coefficients. A defaultdict can be used to fill in for the missing powers:

>>> d = defaultdict(int, multiset(f))
>>> Poly.from_list([d[i] for i in range(max(d), -1, -1)], x)
Poly(2*x**6 + 2*x**5 + 3*x**4 + 4*x**3 + x**2 + 3*x, x, domain='ZZ')
>>> _.as_expr()
2*x**6 + 2*x**5 + 3*x**4 + 4*x**3 + x**2 + 3*x


来源:https://stackoverflow.com/questions/57460956/having-a-list-and-trying-to-make-a-polynomial-in-python-symbolic-calculation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!