[Python] polynomial evaluation Decimal precision [closed]

Discussão em 'Python' iniciado por Stack, Junho 7, 2025.

  1. Stack

    Stack Membro Participativo

    I'm struggling to implement two functions that need to pass specific pytest cases I can't modify. The first evaluates a polynomial with precision requirements, and the second solves a system of equations with Decimal arithmetic.

    Problem 1: Polynomial Evaluation (code1.py) The test requires:

    Exact float evaluation (y_e)

    Term-by-term evaluation with truncation (y_p)

    Nested (Horner) evaluation (y_a) All with Decimal precision (3 digits) and ROUND_FLOOR rounding.

    Test Cases(code 1):

    ,,, import code1 as q import numpy from decimal import * import pytest

    @pytest.mark.timeout(5)
    def pytest_code1():
    getcontext().prec = 3
    getcontext().rounding = ROUND_FLOOR

    # Test case 1
    y_e, y_p, y_a = q.eval_poly(numpy.array([1, -7, 8, 0.35], dtype=numpy.float64),
    numpy.float64(1.37))
    assert y_e == pytest.approx(0.743053)
    assert y_p == Decimal('0.549')
    assert y_a == Decimal('0.732')

    # Test case 2
    y_e, y_p, y_a = q.eval_poly(numpy.array([1, -6.1, 3.2, 1.5], dtype=numpy.float64),
    numpy.float64(4.71))
    assert y_e == pytest.approx(-14.263899)
    assert y_p == Decimal('-15.5')
    assert y_a == Decimal('-14.6')

    # Type checks
    with pytest.raises(TypeError):
    q.eval_poly([1, -6.1, 3.2, 1.5], 4.71)
    with pytest.raises(TypeError):
    q.eval_poly(numpy.array([1, -6.1, 3.2, 1.5], dtype=numpy.float64), 4.71)


    ,,, my attempt (code1); ,,, import numpy as np from decimal import Decimal, getcontext, ROUND_FLOOR, localcontext

    def trunc(x, sig=3):
    """Truncate x to sig significant figures using Decimal."""
    if x == 0:
    return Decimal('0')

    x = Decimal(str(x))
    exponent = x.adjusted()
    shift = sig - exponent - 1

    if shift < 0:
    shift = 0

    with localcontext() as ctx:
    ctx.prec = sig
    ctx.rounding = ROUND_FLOOR
    truncated = (x.scaleb(shift).to_integral_value()).scaleb(-shift)
    return truncated

    def eval_poly(a: np.ndarray, x0: float):
    if not isinstance(a, np.ndarray) or not isinstance(x0, float):
    raise TypeError("Invalid input types")

    # Exact evaluation
    y_e = a[0] * x0**3 + a[1] * x0**2 + a[2] * x0 + a[3]

    # Decimal conversions
    x0_d = Decimal(str(x0))
    a_d = [Decimal(str(coef)) for coef in a]

    # Partial evaluation
    def calculate_yp():
    with localcontext() as ctx:
    ctx.prec = 3
    ctx.rounding = ROUND_FLOOR
    terms = [
    trunc(a_d[0] * x0_d**3),
    trunc(a_d[1] * x0_d**2),
    trunc(a_d[2] * x0_d),
    trunc(a_d[3])
    ]
    yield trunc(sum(terms))

    # Horner's method
    def calculate_ya():
    with localcontext() as ctx:
    ctx.prec = 3
    ctx.rounding = ROUND_FLOOR
    h = trunc(a_d[0])
    h = trunc(h * x0_d + a_d[1])
    h = trunc(h * x0_d + a_d[2])
    yield trunc(h * x0_d + a_d[3])

    return (y_e, next(calculate_yp()), next(calculate_ya()))


    ,,, Test Cases(code 2):

    ,,, import code2 as q from decimal import * import pytest

    @pytest.mark.timeout(5)
    def pytest_code2():
    getcontext().prec = 4
    # Test case 1
    a, b, e = 1.130, -6.990, 14.20
    c, d, f = 1.013, -6.099, 14.22
    x, y = q.two_eq_system(a, b, c, d, e, f)
    assert (float(x), float(y)) == (float(Decimal('68.15')), float(Decimal('8.987')))

    # Test case 2
    a, b, e = 8.110, 12.20, -0.1370
    c, d, f = -18.11, 112.2, -0.1376
    x, y = q.two_eq_system(a, b, c, d, e, f)
    assert (float(x), float(y)) == (float(Decimal('-0.01211')),
    float(Decimal('-0.003183')))


    ,,,

    my attempt (code2); ,,, from decimal import Decimal, getcontext, ROUND_FLOOR

    def two_eq_system(a, b, e, c, d, f): getcontext().prec = 6 getcontext().rounding = ROUND_FLOOR

    a_d = Decimal(str(a))
    b_d = Decimal(str(b))
    e_d = Decimal(str(e))
    c_d = Decimal(str(c))
    d_d = Decimal(str(d))
    f_d = Decimal(str(f))

    det = (a_d * d_d - b_d * c_d).quantize(Decimal('1.0000'))
    x = (e_d * d_d - b_d * f_d) / det
    y = (a_d * f_d - e_d * c_d) / det

    return (
    x.quantize(Decimal('1.00') if abs(x) > 1 else Decimal('1.0000')),
    y.quantize(Decimal('1.000') if abs(y) > 1 else Decimal('1.0000'))
    )


    ,,,

    Continue reading...

Compartilhe esta Página