Aufgabe 1


In [1]:
fn(x) = sin(x) + 0.02*x^2 - 1/pi


Out[1]:
fn (generic function with 1 method)

Aufgabe 1a)


In [2]:
# f: Zu untersuchende Funktion ; dx: delta x ; x: x Startwert ; h: Intervallänge
function find_intervals(f, dx, x, h)
    result = Float64[]
    for i in x:dx:(x+h-dx)
        if(f(i)*f(i+dx) < 0)
            push!(result, i)
        end
    end
    return result
end


Out[2]:
find_intervals (generic function with 1 method)

In [3]:
# f: Zu untersuchende Funktion ; x: x Startwert ; h: Intervallänge ; n: Anzahl der Iterationen
function bisection_method(f, x, h, n)
    for i in 1:n
        if(f(x)*f(x + h/2) > 0) # Wenn der Vorzeichenwechsel nicht im ersten Intervall passiert ..
            x += h/2 # .. im nächsten durchlauf den zweiten betrachten
        end
        h /= 2 # Intervall halbiert sich in jedem Fall
    end
    return x + h/2
end


Out[3]:
bisection_method (generic function with 1 method)

In [4]:
delta = 0.02
for x in find_intervals(fn, delta, -10, 20)
    println("Nullstelle bei ", bisection_method(fn, x, delta, 10))
end


Nullstelle bei -8.055986328125
Nullstelle bei -7.009990234375
Nullstelle bei -3.248994140625
Nullstelle bei 0.321767578125
Nullstelle bei 3.003232421875
Nullstelle bei 5.896552734375

In [5]:
# f: Zu untersuchende Funktion ; x: x Startwert ; h: Intervallänge ; n: Anzahl der Iterationen
function random_bisection_method(f, x, h, n)
    for i in 1:n
        dx = h * rand(1)[1]
        if(f(x)*f(x + dx) > 0) # Wenn der Vorzeichenwechsel nicht im ersten Intervall passiert ..
            x += dx # .. im nächsten durchlauf den zweiten betrachten
            h = h - dx
        else
            h = dx
        end
    end
    return x + h/2
end


Out[5]:
random_bisection_method (generic function with 1 method)

In [6]:
delta = 0.02
for x in find_intervals(fn, delta, -10, 20)
    println("Nullstelle bei ", random_bisection_method(fn, x, delta, 10))
end


Nullstelle bei -8.055973344760366
Nullstelle bei -7.0100092067847
Nullstelle bei -3.248980532639321
Nullstelle bei 0.321731249321681
Nullstelle bei 3.003226595854533
Nullstelle bei 5.896537125752543

Aufgabe 1c)


In [7]:
function convergence_of_bisection(f, x, h, n)
    result = Float64[]
    for i in 1:n
        if(f(x)*f(x + h/2) > 0) # Wenn der Vorzeichenwechsel nicht im ersten Intervall passiert ..
            x += h/2 # .. im nächsten durchlauf den zweiten betrachten
        end
        h /= 2 # Intervall halbiert sich in jedem Fall
        push!(result, log(h))
    end
    return result
end


Out[7]:
convergence_of_bisection (generic function with 1 method)

In [8]:
function convergence_of_random_bisection(f, x, h, n)
    result = Float64[]
    for i in 1:n
        dx = h * rand(1)[1]
        if(f(x)*f(x + dx) > 0) # Wenn der Vorzeichenwechsel nicht im ersten Intervall passiert ..
            x += dx # .. im nächsten durchlauf den zweiten betrachten
            h = h - dx
        else
            h = dx
        end
        push!(result, log(h))
    end
    return result
end


Out[8]:
convergence_of_random_bisection (generic function with 1 method)

In [9]:
using Plots

db = convergence_of_bisection(fn, 0, 1, 100)
drb = convergence_of_random_bisection(fn, 0, 1, 100)

plot([db, drb])


Out[9]:

Aufgabe 2


In [10]:
fn(x) = sin(x)-0.3+0.5*x


WARNING: Method definition fn(Any) in module Main at In[1]:1 overwritten at In[10]:1.
Out[10]:
fn (generic function with 1 method)

Aufgabe 2a)


In [11]:
# f: Zu untersuchende Funktion ; x: x Startwert ; n: Anzahl der Iterationen
function newton_method(f, x, n)
    h = fn(x)
    for i in 1:n
        x = x - (f(x)/((f(x+h)+f(x))/h)) # nächste Näherung berechnen
        h = f(x) # h sollte proportional zu der Abweichung von f(xn) zu 0 sein, damit die Näherung immer besser wird
    end
    return x
end


Out[11]:
newton_method (generic function with 1 method)

In [12]:
println("Nullstelle nach 100 Iterationen Newton-Verfahren bei ", newton_method(fn, 0.2, 100))


Nullstelle nach 100 Iterationen Newton-Verfahren bei 0.20089911470635702

Aufgabe 2b)


In [13]:
result = bisection_method(fn, -10, 20, 10)
result = newton_method(fn, result, 100)

println("Ergebnis nach 10 Iterationen Bisektion und 100 Iterationen Newton-Verfahren: ", result)


Ergebnis nach 10 Iterationen Bisektion und 100 Iterationen Newton-Verfahren: 0.20089911470635705