Sekantmetoden

Fra testwiki
Version fra 11. nov. 2023, 09:19 af imported>Steenthbot imported>Steenthbot (bot: indsæt Skabelon:Flere problemer omkring relevante skabeloner; kosmetiske ændringer)
(forskel) ← Ældre version | Nuværende version (forskel) | Nyere version → (forskel)
Spring til navigation Spring til søgning

Skabelon:Flere problemer 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

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

f(x)=0

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

Illustration af metoden:

Animation zeigt mehrere Iterationsschritte des Sekantenverfahrens

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:

[y=f(x),x0,x1]

y0=f(x0)

y1=f(x1)

Den lige linje der går gennem (x0,y0) og (x1,y1) kaldes en sekantlinje, og vi kan nemt finde forskriften som:

yy1=y1y0x1x0(xx1)

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

x=x1(x1x0)(y1y0)y1

Hvis f(x) er meget tæt på at ligne en lige linje mellem x0 og x1, 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:

ϵ=f(x)

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

xi+1=xi(xixi1)(yiyi1)yi,While[f(xi)>tolerancen]

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

Skabelon:Reflist Skabelon:Ingen kilder