Ejemplo n.º 1
0
def test_weighted_quad_degree():
    """
    check weighted quadrature degree
    we compare n-th moment of weight function calculated in two ways:
        - by moments()
        - numerically by quad()
    """
    x0, x1 = 1, 3
    alpha = 0.14
    beta = 0.88

    max_degree = 7
    for deg in range(1, max_degree):
        p = Monome(deg)
        xs = np.linspace(x0, x1, 6)[1:-1]  # 4 points => accuracy degree is 3

        res = quad(p, x0, x1, xs, a=x0, alpha=alpha)
        ans = moments(deg, x0, x1, a=x0, alpha=alpha)[-1]
        d = abs(res - ans)
        print(f'{deg:2}-a: {res:8.3f} vs {ans:8.3f}, delta = {d:e}')
        if deg < len(xs):
            assert d < 1e-6

        res = quad(p, x0, x1, xs, b=x1, beta=beta)
        ans = moments(deg, x0, x1, b=x1, beta=beta)[-1]
        d = abs(res - ans)
        print(f'{deg:2}-b: {res:8.3f} vs {ans:8.3f}, delta = {d:e}')
        if deg < len(xs):
            assert d < 1e-6
Ejemplo n.º 2
0
def test_weighted_quad_degree():
    """
    Проверяем АСТ для ИКФ с весами
    Посчитаем n-ый момент весовой функции двумя способами:
        - через moments()
        - численно через quad()
    """
    x0, x1 = 1, 3
    alpha = 0.14
    beta = 0.88

    max_degree = 7
    for deg in range(1, max_degree):
        p = Monome(deg)
        xs = np.linspace(x0, x1, 6)[1:-1]  # 4 points => accuracy degree is 3

        res = quad(p, x0, x1, xs, a=x0, alpha=alpha)
        ans = moments(deg, x0, x1, a=x0, alpha=alpha)[-1]
        d = abs(res - ans)
        print(f'{deg:2}-a: {res:8.3f} vs {ans:8.3f}, delta = {d:e}')
        if deg < len(xs):
            assert d < 1e-6

        res = quad(p, x0, x1, xs, b=x1, beta=beta)
        ans = moments(deg, x0, x1, b=x1, beta=beta)[-1]
        d = abs(res - ans)
        print(f'{deg:2}-b: {res:8.3f} vs {ans:8.3f}, delta = {d:e}')
        if deg < len(xs):
            assert d < 1e-6
Ejemplo n.º 3
0
def test_weighted_quad_degree():
    """
    check weighed quadrature degree
    """
    x0, x1 = 1, 3
    alpha = 0.14
    beta = 0.88

    max_degree = 7
    for deg in range(1, max_degree):
        p = Monome(deg)
        xs = np.linspace(x0, x1, 6)[1:-1]  # 4 points => accuracy degree is 3

        res = quad(p, x0, x1, xs, alpha=alpha)
        ans = weight(deg, x0, x1, alpha=alpha)
        d = abs(res - ans)
        print(f'{deg:2}-a: {res:8.3f} vs {ans:8.3f}, delta = {d:e}')
        if deg < len(xs):
            assert d < 1e-6

        res = quad(p, x0, x1, xs, beta=beta)
        ans = weight(deg, x0, x1, beta=beta)
        d = abs(res - ans)
        print(f'{deg:2}-b: {res:8.3f} vs {ans:8.3f}, delta = {d:e}')
        if deg < len(xs):
            assert d < 1e-6
Ejemplo n.º 4
0
def test_quad_degree():
    """
    Проверяем АСТ для ИКФ
    Q: почему в  некоторых случаях x^n интегрируется почти без ошибок при n узлах ИКФ?
    """
    x0, x1 = 0, 1

    max_degree = 7
    max_nodes = 7

    for deg in range(max_degree):
        p = Monome(deg)
        y0 = p[x0, x1]

        node_counts = range(1, max_nodes+1)

        Y = [quad(p, x0, x1, np.linspace(x0, x1, node_count)) for node_count in node_counts]
        # Y = [quad(p, x0, x1, x0 + (x1-x0) * np.random.random(node_count)) for node_count in max_node_count]
        accuracy = get_accuracy(Y, y0 * np.ones_like(Y))

        # Проверяем точность
        for node_count, acc in zip(node_counts, accuracy):
            if node_count >= deg + 1:
                assert acc > 6

        plt.plot(node_counts, accuracy, '.:', label=f'x^{deg}')

    plt.legend()
    plt.ylabel('accuracy')
    plt.xlabel('node_count')
    plt.suptitle(f'test quad')
    plt.show()
Ejemplo n.º 5
0
def test_interpolation(func):
    """
    Проверяем, что значит буква "И" в названии ИКФ
    Интегрируем интерполяционный многочлен, затем сравниваем результат с quad()
    """
    x0, x1 = 0, 1
    n_nodes = 5

    xs = np.linspace(x0, x1, n_nodes)
    ys = func(xs)

    # numpy
    poly = np.polyfit(xs, ys, deg=n_nodes - 1)
    polyint = np.polyint(poly)
    int_v = np.polyval(polyint, x1) - np.polyval(polyint, x0)

    # our
    num_v = quad(func, x0, x1, xs)

    delta = np.abs(int_v - num_v)
    assert delta < 1e-6

    print(
        f'interpolate+integrate: {int_v:8.3f}, quad: {num_v:8.3f}, delta: {delta:e}'
    )
Ejemplo n.º 6
0
def test_quad_vs_cq():
    """
    Проверяем, как работают ИКФ и СКФ при одинакомом количестве обращений к функции
    """
    x0, x1 = 0, np.pi/2

    p = Harmonic(0, 1)
    y0 = p[x0, x1]

    n_nodes = 2
    ys_nt_ct = []
    ys_gauss = []
    ys_cquad = []

    n_intervals = 2 ** np.arange(8)
    for n in n_intervals:
        n_evals = n * n_nodes
        ys_nt_ct.append(quad(p, x0, x1, np.linspace(0, 1, n_evals) * (x1-x0) + x0))
        ys_gauss.append(quad_gauss(p, x0, x1, n_evals))
        ys_cquad.append(composite_quad(p, x0, x1, n, n_nodes))

    for ys, label in zip((ys_nt_ct, ys_gauss, ys_cquad),
                         (f'newton-cotes', f'gauss', f'{n_nodes}-node CQ')):
        acc = get_accuracy(ys, y0 * np.ones_like(ys))
        acc[acc > 17] = 17

        plt.plot(np.log10(n_intervals), acc, '.:', label=label)

    plt.legend()
    plt.ylabel('accuracy')
    plt.xlabel('log10(n_evals)')
    plt.suptitle(f'test quad vs composite quad')
    plt.show()
Ejemplo n.º 7
0
def tes_quad_degree():
    """
    check quadrature degree
    Q: why in some cases x^n integrated perfectly with only n nodes?
    """
    x0, x1 = 0, 1

    max_degree = 7

    for deg in range(1, max_degree):
        p = Monome(deg)
        y0 = p[x0, x1]

        max_node_count = range(1, max_degree + 1)

        Y = [
            quad(p, x0, x1, np.linspace(x0, x1, node_count))
            for node_count in max_node_count
        ]
        # Y = [quad(p, x0, x1, x0 + (x1-x0) * np.random.random(node_count)) for node_count in max_node_count]
        accuracy = get_log_error(Y, y0 * np.ones_like(Y))
        accuracy[np.isinf(accuracy)] = 17

        # check accuracy is good enough
        for node_count, acc in zip(max_node_count, accuracy):
            if node_count >= deg + 1:
                assert acc > 6

        plt.plot(max_node_count, accuracy, '.:', label=f'x^{deg}')

    plt.legend()
    plt.ylabel('accuracy')
    plt.xlabel('node_count')
    plt.suptitle(f'test quad')
    plt.show()