20TD02U Programmering av nullpunkt med halveringsmetoden_v3 - itnett/FTD02H-N GitHub Wiki

Forklaring av Forbedret Kode

Input Validering:

Funksjonen get_valid_input sørger for at brukeren gir gyldige inndata ved å sjekke om a er mindre enn b og at f(a) og f(b) har motsatte fortegn. Hvis ikke, blir brukeren bedt om å prøve igjen.

Hovedprogram:

Inputene blir samlet ved hjelp av get_valid_input, og deretter blir bisection_method kalt med de validerte verdiene.

Unntakshåndtering:

Hvis det oppstår en feil i bisection_method, vil feilmeldingen bli fanget og skrevet ut.

Dette sikrer at brukeren ikke kan skrive inn verdier som bryter forutsetningene for halveringsmetoden, og gir en mer robust og brukervennlig opplevelse.

Gyldige Verdier som Vil Gi Resultater

Intervall med motsatte fortegn:

$a = 0$, $b = 2$

$$ f(0) = -1 $$ $$ f(2) = rac{1}{3} \cdot 2^3 + rac{1}{2} \cdot 2^2 - 2 - 1 = 2.6667 + 2 - 2 - 1 = 1.6667 $$ Siden $f(0)$ og $f(2)$ har motsatte fortegn, vil dette intervallet gi et resultat.

Intervall med røtter innenfor området:

$a = -2$, $b = 0$

$$ f(-2) = rac{1}{3} \cdot (-2)^3 + rac{1}{2} \cdot (-2)^2 - (-2) - 1 = -2.6667 + 2 + 2 - 1 = 0.3333 $$ $$ f(0) = -1 $$ Siden $f(-2)$ og $f(0)$ har motsatte fortegn, vil dette intervallet gi et resultat.

Intervall med høyere nøyaktighet:

$a = 1$, $b = 2$, $tol = 0.00001$

$$ f(1) = rac{1}{3} \cdot 1^3 + rac{1}{2} \cdot 1^2 - 1 - 1 = 0.8333 - 1 - 1 = -1.1667 $$ $$ f(2) = 1.6667 $$ Siden $f(1)$ og $f(2)$ har motsatte fortegn, vil dette intervallet gi et resultat, men med høyere nøyaktighet.

Ugyldige Verdier som Ikke Vil Gi Resultater

Intervall uten motsatte fortegn:

$a = 0$, $b = 1$

$$ f(0) = -1 $$ $$ f(1) = rac{1}{3} \cdot 1^3 + rac{1}{2} \cdot 1^2 - 1 - 1 = 0.8333 - 1 - 1 = -1.1667 $$ Siden både $f(0)$ og $f(1)$ har negative verdier, vil dette intervallet ikke gi et resultat.

Intervall med samme fortegn:

$a = -1$, $b = 1$

$$ f(-1) = rac{1}{3} \cdot (-1)^3 + rac{1}{2} \cdot (-1)^2 - (-1) - 1 = -0.3333 + 0.5 + 1 - 1 = 0.1667 $$ $$ f(1) = -1.1667 $$ Selv om $f(-1)$ er positiv og $f(1)$ er negativ, vil dette intervallet kunne være gyldig. Men hvis vi endrer $b$ til 0, vil $f(-1)$ og $f(0)$ ikke ha motsatte fortegn, og intervallet vil ikke gi et resultat.

Feil rekkefølge på grensene:

$a = 3$, $b = 2$

Grensene er i feil rekkefølge, $a$ må være mindre enn $b$. Dette vil ikke gi et resultat uansett funksjonsverdier.

Kode for å teste ulike intervaller

Dette gir en klar og visuell fremstilling av hvilke intervaller som fungerer og hvilke som ikke gjør det, samt hvorfor de ikke fungerer. Ved å kjøre koden kan du se hvordan funksjonen reagerer på ulike inputverdier.

import matplotlib.pyplot as plt
import numpy as np

def f(x):
    return (1/3)*x**3 + (1/2)*x**2 - x - 1

def bisection_method(f, a, b, tol=0.0001):
    if f(a) * f(b) >= 0:
        raise ValueError("f(a) and f(b) must have opposite signs")
    
    midpoints = []
    while (b - a) / 2 > tol:
        midpoint = (a + b) / 2
        midpoints.append(midpoint)
        
        if f(midpoint) == 0:
            return midpoint, midpoints
        elif f(a) * f(midpoint) < 0:
            b = midpoint
        else:
            a = midpoint
    
    return (a + b) / 2, midpoints

def plot_function_and_root(f, a, b, root, midpoints):
    x = np.linspace(a, b, 400)
    y = f(x)
    
    plt.figure(figsize=(10, 6))
    plt.plot(x, y, label='f(x) = (1/3)*x^3 + (1/2)*x^2 - x - 1')
    plt.axhline(0, color='black', linewidth=0.5)
    plt.axvline(0, color='black', linewidth=0.5)
    plt.plot(root, f(root), 'ro', label=f'Root ≈ {root:.4f}')
    
    for i, m in enumerate(midpoints):
        plt.plot([a, b], [f(a), f(b)], 'g:')
        plt.plot([m, m], [0, f(m)], 'b:')
        plt.text(m, f(m) + 0.1, f'm{i+1}', ha='center')
    
    plt.title('Bisection Method')
    plt.xlabel('x')
    plt.ylabel('f(x)')
    plt.legend()
    plt.grid(True)
    plt.show()

def test_intervals():
    test_cases = [
        (0, 2),      # Gyldig
        (-2, 0),     # Gyldig
        (1, 2),      # Gyldig, høyere nøyaktighet
        (0, 1),      # Ugyldig, samme fortegn
        (-1, 0),     # Ugyldig, samme fortegn
        (3, 2)       # Ugyldig, feil rekkefølge
    ]
    
    for a, b in test_cases:
        try:
            print(f"Testing interval ({a}, {b})")
            root, midpoints = bisection_method(f, a, b)
            print(f"Nullpunktet er x ≈ {root:.4f}
")
        except ValueError as e:
            print(f"Feil for intervallet ({a}, {b}): {e}
")

test_intervals()

Denne formatert markdown-blokken kan nå kopieres og limes inn direkte for å beholde all formatering korrekt.