Пример #1
0
def form_size(expr: Expr) -> typing.Tuple[Size, typing.Optional[Symbol]]:
    """Form a size object from a SymPy expression."""

    symbs = expr.atoms(Symbol)
    n_symbs = len(symbs)

    if n_symbs == 0:
        symb = None
        coeff_exprs = [expr]
    elif n_symbs == 1:
        symb = symbs.pop()
        coeff_exprs = Poly(expr, symb).all_coeffs()
        coeff_exprs.reverse()
    else:
        raise ValueError(
            'Invalid expression', expr,
            'expecting single variate polynomial (or number)'
        )

    if all(i.is_integer for i in coeff_exprs):
        dtype = int
    else:
        dtype = float

    if len(coeff_exprs) > 1:
        coeffs = np.array(coeff_exprs, dtype=dtype)
        cost = SVPoly(coeffs)
    elif len(coeff_exprs) == 1:
        cost = dtype(coeff_exprs[0])
    else:
        assert False

    return cost, symb
Пример #2
0
def get_reduced_fraction(numerator_coefs, denominator_coefs, result_deg):
    """
    Reduce polynomial division by common factors. So (1+k)/(1+2k+k**2) will be reduced to 1/(1+k)
    Items in the coefs list start from the lowest degree ([a, b, c] = a + b*x +c*x**2)

    """
    k = var('k')
    numerator = sum([coef * k**i for i, coef in enumerate(numerator_coefs)])
    denominator = sum(
        [coef * k**i for i, coef in enumerate(denominator_coefs)])

    reduced_num, reduced_denom = (numerator /
                                  denominator).simplify().as_numer_denom()
    reduced_num_coefs, reduced_denom_coefs = Poly(
        reduced_num, k).all_coeffs(), Poly(reduced_denom, k).all_coeffs()
    reduced_num_coefs.reverse()
    reduced_denom_coefs.reverse()

    # If the higher degrees are missing from the expression, then the list will have a smaller size then needed.
    # Adding zeros as padding to the end.
    reduced_num_coefs += [0] * (result_deg + 1 - len(reduced_num_coefs))
    reduced_denom_coefs += [0] * (result_deg + 1 - len(reduced_denom_coefs))

    return reduced_num_coefs, reduced_denom_coefs