Как найти Коэффициент более чем одной переменной желаемой мощности в Python - PullRequest
2 голосов
/ 04 марта 2020

Если бы у меня было уравнение с более чем одной переменной, скажем, x**2+x*y+y**2, я мог бы найти Коэффициенты с CoefficientList от Mathematica. Он вывел бы желаемую матрицу как 3x3.

В Python я нашел sympy.coeff(x, n), но я не могу вернуть коэффициент для более чем одной переменной.

Есть ли способ, которым вы знаете

Ответы [ 2 ]

2 голосов
/ 04 марта 2020

Для случая квадратичного c следующее соответствует выводу Mathematica:

def CoefficientList(p, v):
    """
    >>> CoefficientList(x**2+2*x*y+3*y**2+4*x+5*y+6,(x,y))
    Matrix([
    [6, 5, 3],
    [4, 2, 0],
    [1, 0, 0]])
    """
    assert len(v) == 2
    n = len(v)
    t = [prod(i) for i in subsets([S.One] + list(v), n, repetition=n)]
    p = p.expand()
    m = zeros(n + 1)
    r = n + 1
    while t:
        if r > n:
            n -= 1
            r = 0
            c = n
        x = t.pop()
        if x == 1:
            d = p
        else:
            p, d = p.as_independent(x, as_Add=True)
        co = d.as_coeff_Mul()[0]
        m[r, c] = co
        r += 1
        c -= 1
    return m

Но метод мономов является хорошим для использования. Чтобы получить все коэффициенты всех мономов, я бы порекомендовал хранить их в defaultdict со значением по умолчанию, равным 0. Затем вы можете получить коэффициенты, когда вы будете sh:

def coeflist(p, v):
    """
    >>> coeflist(x**2+2*x*y+3*y**2+4*x+5*y+6, [x])
    defaultdict(<class 'int'>, {x**2: 1, x: 2*y + 4, 1: 3*y**2 + 5*y + 6})
    >>> coeflist(x**2+2*x*y+3*y**2+4*x+5*y+6, [x, y])
    defaultdict(<class 'int'>, {x**2: 1, x*y: 2, x: 4, y**2: 3, y: 5, 1: 6})
    >>> _[y**2]
    3
    """
    from collections import defaultdict
    p = Poly(p, *v)
    rv = defaultdict(int)
    for i in p.monoms():
        rv[prod(i**j for i,j in zip(p.gens, i))] = p.coeff_monomial(i)
    return rv
1 голос
/ 04 марта 2020

Вот способ найти каждый из коэффициентов квадратичной формы c и представить их в виде матрицы:

import sympy as sy
from sympy.abc import x, y

def quadratic_form_matrix(expr, x, y):
    a00, axx, ayy, ax, ay, axy = sy.symbols('a00 axx ayy ax ay axy')
    quad_coeffs = sy.solve([sy.Eq(expr.subs({x: 0, y: 0}), a00),
                            sy.Eq(expr.diff(x).subs({x: 0, y: 0}), 2 * ax),
                            sy.Eq(expr.diff(x, 2).subs({y: 0}), 2 * axx),
                            sy.Eq(expr.diff(y).subs({x: 0, y: 0}), 2 * ay),
                            sy.Eq(expr.diff(y, 2).subs({x: 0}), 2 * ayy),
                            sy.Eq(expr.diff(x).diff(y), 2 * axy)],
                           (a00, axx, ayy, ax, ay, axy))
    return sy.Matrix([[axx, axy, ax], [axy, ayy, ay], [ax, ay, a00]]).subs(quad_coeffs)

expr = x**2 + 2*x*y + 3*y**2 + 7
M = quadratic_form_matrix(expr, x, y)
print(M)

XY1 = sy.Matrix([x, y, 1])
quadatric_form = (XY1.T * M * XY1)[0]
print(quadatric_form.expand())

PS: применение преобразования к многомерному многоугольнику в соответствии с предложением @Marcus ' ссылка , а затем преобразование в матрицу приведет к следующему коду. Обратите внимание, что для получения постоянного члена, 1 может быть передано в coeff_monomial(1). Недиагональные элементы матрицы симметрии c для квадратичной формы c должны составлять половину соответствующих коэффициентов.

import sympy as sy
from sympy.abc import x, y

def quadratic_form_matrix_using_poly(expr, x, y):
    p = sy.poly(expr)
    axx = p.coeff_monomial(x * x)
    ayy = p.coeff_monomial(y * y)
    a00 = p.coeff_monomial(1)
    ax = p.coeff_monomial(x) / 2
    ay = p.coeff_monomial(y) / 2
    axy = p.coeff_monomial(x * y) / 2
    return sy.Matrix([[axx, axy, ax], [axy, ayy, ay], [ax, ay, a00]])

expr = x**2 + 2*x*y + 3*y**2 + 7 + 11*x + 23*y

M = quadratic_form_matrix(expr, x, y)
print(M)

XY1 = sy.Matrix([x, y, 1])
quadatric_form = (XY1.T * M * XY1)[0]
print(quadatric_form.expand())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...