Sekantmetoden

numerisk metode til bestemmelse af funktioners rod

Sekantmetoden er en matematisk metode til at søge efter en rod. Hvor en rod er den værdi, for hvilken en funktion antager værdien 0.

Problemet redigér

Så vi leder altså efter den værdi af x, som løser

 

Hvis sekantmetoden skal kunne finde løsningen, skal funktionen opføre sig "pænt" glat omkring roden ellers kan de foreslåede løsninger springe frem og tilbage og muligvis vil metoden ikke konvergere og derfor aldrig finder en rod.

Beskrivelse af metoden redigér

Illustration af metoden:

 

Sekantmetoden kræver, at man har funktionsforskriften og to forskellige x-værdier, hvor man kan starte metoden fra. Herefter gentages metoden, indtil roden er fundet med en passende nøjagtighed, så som det første kan vi finde y-værdierne til de kendte x-værdier:

 

 

 

Den lige linje der går gennem   og   kaldes en sekantlinje, og vi kan nemt finde forskriften som:

 

og når vi isolerer x, og løser den med hensyn til y=0, finder vi x-værdien i sekantlinjens rod.

 

Hvis f(x) er meget tæt på at ligne en lige linje mellem   og  , er sekantlinjens rod meget tæt på f(x)'s rod. Vi kan finde forskellen ved at evaluere f(x), så bliver forskellen mellem f(x) og nul til fejlen:

 

hvis fejlen er større end vi tillader, kan vi gentage processen, og her siger sekantmetoden, at hvis vi genbruger  , som  , og   som  , bør fejlen blive mindre næste gang. Generelt kan det udtrykkes sådan:

 

hvilket kan kodes som:

public static double Secant(double x0, double x1, Func<double, double>f, double tolerance = 0.0001, int maxSteps = 100)
{
    double dX = x1 - x0;
    if (dX == 0)
        throw new DivideByZeroException("the two points provided for the secant method, are so similar, that I cannot determine a slope, or the slope is vertical");
    
    double y0 = f(x0);
    double y1 = f(x1);
    
    if(y0 <= tolerance)
        return x0;

    if(y1 <= tolerance)
        return x1;
    
    double x2 = x1 - ( (x1 - x0) / (y1 - y0) ) * y1
    
    for(int i = 0; i < maxSteps, i++)
    {
        x0 = x1;
        y0 = y1;
        
        x1 = x2;
        y1 = f(x2);
        
        if(y1 <= tolerance)
            return x1;
            
        x2 = x1 - ( (x1 - x0) / (y1 - y0) ) * y1
    }
    throw new Exception("Did not produce a number within tolerance, before I ran out of allowed steps. Possible divergens issues?")
}

Referencer redigér