2012-01-30

Przybliżenie wartości pochodnej

Dla niektórych metod poszukiwania miejsc zerowych potrzebujemy wartości pochodnych, z reguły 1, 2 i 3 rzędu. Samą badaną funkcję nie zawsze mamy daną wzorem analitycznym by te pochodne policzyć, czasami jest to zbyt kłopotliwe. Wtedy nie pozostaje nam nic innego jak przybliżyć wartość pochodnej korzystając z wzoru:

$f'(x_{0}) = \displaystyle \lim _{h\to 0}\frac{f(x_{0}+h) - f(x_{0})}{h}$

Wartość drugiej otrzymamy poprzez podstawienie do podanego wzoru wartości pierwszej pochodnej.

Możemy wyróżnić trzy metody doboru przedziału. Centralnie wokół punktu x, na prawo od punktu x i na lewo od punktu x:

$\delta_h[f](x) = f(x+\tfrac12h)-f(x-\tfrac12h)$

$\nabla_h[f](x) = f(x) - f(x-h)$

$\delta_h[f](x) = f(x+\tfrac12h)-f(x-\tfrac12h)$

Ja skorzystałem z metody pierwszej. Kod na pierwszą i drugą pochodną jest następujący:

public class CentralDifferenceMethod
{
    private double m_h;
    private Func<double, double> m_func;

    public CentralDifferenceMethod()
        : base()
    {
    }
        
    public CentralDifferenceMethod(Func<double, double> a_func, 
        double a_h = Constants.DOUBLE_PRECISION * 2)
    {
        m_h = a_h;
        m_func = a_func;
    }

    public double Derive1(double a_x)
    {
        return (m_func(a_x + m_h) - m_func(a_x - m_h)) / (2 * m_h);
    }

    public double Derive2(double a_x)
    {
        return (m_func(a_x + m_h) - 2 * m_func(a_x) + 
            m_func(a_x - m_h)) / (m_h * m_h);
    }

    public static  Func<double, double> Derive1(
        Func<double, double> a_func, double a_h)
    {
        CentralDifferenceMethod cdm = 
            new CentralDifferenceMethod(a_func, a_h);

        return (x) =>
        {
            return cdm.Derive1(x);
        };
    }

    public static Func<double, double> Derive2(
        Func<double, double> a_func, double a_h)
    {
        CentralDifferenceMethod cdm = 
            new CentralDifferenceMethod(a_func, a_h);

        return (x) =>
        {
            return cdm.Derive2(x);
        };
    }

    public static Func<double, double> Derive2(
        Func<double, double> a_func, 
        Func<double, double> a_d1, double a_h)
    {
        CentralDifferenceMethod cdm = 
            new CentralDifferenceMethod(a_d1, a_h);

        return (x) =>
        {
            return cdm.Derive1(x);
        };
    }
}

Zauważmy, że pierwsza pochodna wymaga dwóch punktów, druga trzech, itd.

Brak komentarzy:

Prześlij komentarz