<commit_before>"""
Finite difference weight generating method (finite_diff_weights)
and convencience method for estimating a derivative (or interpolate)
directly from a series of points (apply_finite_diff)

References
==========
Generation of Finite Difference Formulas on Arbitrarily Spaced Grids, <NAME>
Mathematics of compuation, 51, 184, 1988, 699-706 doi:10.1090/S0025-5718-1988-0935077-0

"""

from sympy import S

def finite_diff_weights(order, x_list, x0):
    """
    Calculates the finite difference weights for an arbitrarily
    spaced one-dimensional grid (x_list) for derivatives at 'x0'
    of order 0, 1, ..., up to 'order' using a recursion formula.

    Parameters
    ==========
    order : int
        Up to what derivative order weights should be calculated.
        0 corresponds to interpolation.
    x_list: sequence
        Strictly monotonically increasing sequence of values for
        the independent variable.
    x0: Number or Symbol
        At what value of the independent variable the finite difference
        weights should be generated.

    Returns
    =======
    list
        A list of sublists, each corresponding to coefficients for
        increasing derivative order, and each containing lists of
        coefficients for increasing accuracy.

    Examples
    ========

    >>> from sympy import S
    >>> from sympy.series import finite_diff_weights
    >>> finite_diff_weights(1, [-S(1)/2, S(1)/2, S(3)/2, S(5)/2], 0)
    [[[1, 0, 0, 0],
      [1/2, 1/2, 0, 0],
      [3/8, 3/4, -1/8, 0],
      [5/16, 15/16, -5/16, 1/16]],
     [[0, 0, 0, 0], [-1, 1, 0, 0], [-1, 1, 0, 0], [-23/24, 7/8, 1/8, -1/24]]]

    the result is two subslists, the first is for the 0:th derivative
    (interpolation) and the second for the first derivative (we gave
    1 as the parameter of order so this is why we get no list for
    a higher order derivative). Each sublist contains the most accurate
    formula in the end (all points used).

    Beware of the offset in the lower accuracy formulae when looking at a centered
    difference:

    >>> from sympy import S
    >>> from sympy.series import finite_diff_weights
    >>> finite_diff_weights(1, [-S(5)/2, -S(3)/2, -S(1)/2, S(1)/2, S(3)/2, S(5)/2], 0)
    [[[1, 0, 0, 0, 0, 0],
      [-3/2, 5/2, 0, 0, 0, 0],
      [3/8, -5/4, 15/8, 0, 0, 0],
      [1/16, -5/16, 15/16, 5/16, 0, 0],
      [3/128, -5/32, 45/64, 15/32, -5/128, 0],
      [3/256, -25/256, 75/128, 75/128, -25/256, 3/256]],
     [[0, 0, 0, 0, 0, 0],
      [-1, 1, 0, 0, 0, 0],
      [1, -3, 2, 0, 0, 0],
      [1/24, -1/8, -7/8, 23/24, 0, 0],
      [0, 1/24, -9/8, 9/8, -1/24, 0],
      [-3/640, 25/384, -75/64, 75/64, -25/384, 3/640]]]


    The capability to generate weights at arbitrary points can be
    used e.g. to minimize Runge's phenomenon by using Chebyshev nodes:

    >>> from sympy import cos, symbols, pi, simplify
    >>> from sympy.series import finite_diff_weights
    >>> N, (h, x) = 4, symbols('h x')
    >>> x_list = [x+h*cos(i*pi/(N)) for i in range(N,-1,-1)] # chebyshev nodes
    >>> print(x_list)
    [-h + x, -sqrt(2)*h/2 + x, x, sqrt(2)*h/2 + x, h + x]
    >>> mycoeffs = finite_diff_weights(1, x_list, 0)[1][4]
    >>> [simplify(c) for c in  mycoeffs]
    [(h**3 + 2*h**2*x - 6*h*x**2 - 8*x**3)/(2*h**4),
     (-sqrt(2) - 4*x/h + 3*sqrt(2)*x**2/h**2 + 8*x**3/h**3)/h,
     6*x/h**2 - 8*x**3/h**4,
     (sqrt(2) - 4*x/h - 3*sqrt(2)*x**2/h**2 + 8*x**3/h**3)/h,
     (-h**3 + 2*h**2*x + 6*h*x**2 - 8*x**3)/(2*h**4)]


    Notes
    -----
    If weights for a finite difference approximation
    of the 3rd order derivative is wanted, weights for 0th, 1st
    and 2nd order are calculated "for free", so are formulae using
    fewer and fewer of the paramters. This is somehting one can
    take advantage of to save computational cost.

    See also
    ========
    sympy.series.finite_diff.apply_finite_diff


    References
    ==========

    .. [1] Generation of Finite Difference Formulas on Arbitrarily Spaced Grids,
               <NAME>; Mathematics of compuation; 51; 184; (1988);
               699-706; doi:10.1090/S0025-5718-1988-0935077-0
<commit_msg>Fixed docstring.<commit_after>"""
Finite difference weight generating method (finite_diff_weights)
and convencience method for estimating a derivative (or interpolate)
directly from a series of points (apply_finite_diff)

References
==========
Generation of Finite Difference Formulas on Arbitrarily Spaced Grids, <NAME>
Mathematics of compuation, 51, 184, 1988, 699-706 doi:10.1090/S0025-5718-1988-0935077-0

"""

from sympy import S

def finite_diff_weights(order, x_list, x0):
    """
    Calculates the finite difference weights for an arbitrarily
    spaced one-dimensional grid (x_list) for derivatives at 'x0'
    of order 0, 1, ..., up to 'order' using a recursion formula.

    Parameters
    ==========
    order : int
        Up to what derivative order weights should be calculated.
        0 corresponds to interpolation.
    x_list: sequence
        Strictly monotonically increasing sequence of values for
        the independent variable.
    x0: Number or Symbol
        At what value of the independent variable the finite difference
        weights should be generated.

    Returns
    =======
    list
        A list of sublists, each corresponding to coefficients for
        increasing derivative order, and each containing lists of
        coefficients for increasing accuracy.

    Examples
    ========

    >>> from sympy import S
    >>> from sympy.series import finite_diff_weights
    >>> finite_diff_weights(1, [-S(1)/2, S(1)/2, S(3)/2, S(5)/2], 0)
    [[[1, 0, 0, 0],
      [1/2, 1/2, 0, 0],
      [3/8, 3/4, -1/8, 0],
      [5/16, 15/16, -5/16, 1/16]],
     [[0, 0, 0, 0], [-1, 1, 0, 0], [-1, 1, 0, 0], [-23/24, 7/8, 1/8, -1/24]]]

    the result is two subslists, the first is for the 0:th derivative
    (interpolation) and the second for the first derivative (we gave
    1 as the parameter of order so this is why we get no list for
    a higher order derivative). Each sublist contains the most accurate
    formula in the end (all points used).

    Beware of the offset in the lower accuracy formulae when looking at a centered
    difference:

    >>> from sympy import S
    >>> from sympy.series import finite_diff_weights
    >>> finite_diff_weights(1, [-S(5)/2, -S(3)/2, -S(1)/2, S(1)/2, S(3)/2, S(5)/2], 0)
    [[[1, 0, 0, 0, 0, 0],
      [-3/2, 5/2, 0, 0, 0, 0],
      [3/8, -5/4, 15/8, 0, 0, 0],
      [1/16, -5/16, 15/16, 5/16, 0, 0],
      [3/128, -5/32, 45/64, 15/32, -5/128, 0],
      [3/256, -25/256, 75/128, 75/128, -25/256, 3/256]],
     [[0, 0, 0, 0, 0, 0],
      [-1, 1, 0, 0, 0, 0],
      [1, -3, 2, 0, 0, 0],
      [1/24, -1/8, -7/8, 23/24, 0, 0],
      [0, 1/24, -9/8, 9/8, -1/24, 0],
      [-3/640, 25/384, -75/64, 75/64, -25/384, 3/640]]]


    The capability to generate weights at arbitrary points can be
    used e.g. to minimize Runge's phenomenon by using Chebyshev nodes:

    >>> from sympy import cos, symbols, pi, simplify
    >>> from sympy.series import finite_diff_weights
    >>> N, (h, x) = 4, symbols('h x')
    >>> x_list = [x+h*cos(i*pi/(N)) for i in range(N,-1,-1)] # chebyshev nodes
    >>> print(x_list)
    [-h + x, -sqrt(2)*h/2 + x, x, sqrt(2)*h/2 + x, h + x]
    >>> mycoeffs = finite_diff_weights(1, x_list, 0)[1][4]
    >>> [simplify(c) for c in  mycoeffs]
    [(h**3/2 + h**2*x - 3*h*x**2 - 4*x**3)/h**4, (-sqrt(2)*h**3 - 4*h**2*x + 3*sqrt(2)*h*x**2 + 8*x**3)/h**4, 6*x/h**2 - 8*x**3/h**4, (sqrt(2)*h**3 - 4*h**2*x - 3*sqrt(2)*h*x**2 + 8*x**3)/h**4, (-h**3/2 + h**2*x + 3*h*x**2 - 4*x**3)/h**4]

    Notes
    -----
    If weights for a finite difference approximation
    of the 3rd order derivative is wanted, weights for 0th, 1st
    and 2nd order are calculated "for free", so are formulae using
    fewer and fewer of the paramters. This is somehting one can
    take advantage of to save computational cost.

    See also
    ========
    sympy.series.finite_diff.apply_finite_diff


    References
    ==========

    .. [1] Generation of Finite Difference Formulas on Arbitrarily Spaced Grids,
               <NAME>; Mathematics of compuation; 51; 184; (1988);
               699-706; doi:10.1090/S0025-5718-1988-0935077-0

{'fraction_non_alphanumeric': 0.162145798014047, 'fraction_numerical': 0.09203196899975781, 'mean_word_length': 2.6383259911894275, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 85, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7432315', 'n_tokens_mistral': 3465, 'n_tokens_neox': 2956, 'n_words': 1007}