import numpy as np, matplotlib.pyplot as plt
import time

def oppg2(x_0=1, eps=1e-15):
    print()
    print('Oppgave 2:')
    new_x = np.cos(x_0)
    iter_count = 1

    while abs(new_x - x_0) >= eps:
        x_0 = new_x
        new_x = np.cos(x_0)
        iter_count += 1

    print('x =', new_x, ' ' * (30 - len(str(new_x))), 'Iterasjoner :', iter_count, ' ' * (5 - len(str(iter_count))),
          'x_' + str(iter_count), '- x_' + str(iter_count - 1), '=', new_x - x_0)

def oppg3(x_0=1, eps=1e-15):
    print()
    print('Oppgave 3:')
    new_x = x_0 - (np.cos(x_0)-x_0)/(-np.sin(x_0)-1)
    iter_count = 1

    while abs(new_x - x_0) >= eps:
        x_0 = new_x
        new_x = x_0 - (np.cos(x_0)-x_0)/(-np.sin(x_0)-1)
        iter_count += 1

    print('x =', new_x, ' '*(30-len(str(new_x))), 'Iterasjoner :', iter_count, ' '*(5-len(str(iter_count))),
          'x_' + str(iter_count), '- x_' + str(iter_count - 1), '=', new_x - x_0)

######## funksjonene i oppg 4 ######
def f(x_0):
    x,y = x_0
    return (x**2) + (y**2) - 4

def f_x(x_0):
    x,y = x_0
    return 2*x

def f_y(x_0):
    x,y = x_0
    return 2*y

def g(x_0):
    x,y = x_0
    return (x*y) -1

def g_x(x_0):
    x,y = x_0
    return y

def g_y(x_0):
    x,y = x_0
    return x

def oppg4(x_0 = np.array([2,0]) , eps = 1e-15):
    #print()
    #print('Oppgave 4:')
    ##### evaluerer funksjoner ######
    f_val = f(x_0)
    fx_val = f_x(x_0)
    fy_val = f_y(x_0)

    g_val = g(x_0)
    gx_val = g_x(x_0)
    gy_val = g_y(x_0)

    det = ((fx_val * gy_val) - (gx_val * fy_val)) #determinanten
    matrise = (1 / det) * np.array([[gy_val, -fy_val],
                                    [-gx_val, fx_val]]) # inverse matrisen
    vektor = np.array([f_val, g_val]) #forrige funksjonsverdier

    new_x = x_0 - np.dot(matrise, vektor) #neste punkt

    iter_count = 1

    ##### Finner avstand mellom forrige punkt og nye punkt ######
    diff_vektor = x_0 - new_x
    diff = sum([x**2 for x in diff_vektor])

    while diff >= eps:
        x_0 = new_x

        f_val = f(x_0)
        fx_val = f_x(x_0)
        fy_val = f_y(x_0)

        g_val = g(x_0)
        gx_val = g_x(x_0)
        gy_val = g_y(x_0)

        det = ((fx_val * gy_val) - (gx_val * fy_val))
        matrise = (1 / det) * np.array([[gy_val, -fy_val],
                                        [-gx_val, fx_val]])
        vektor = np.array([f_val, g_val])

        new_x = x_0 - np.dot(matrise, vektor)
        iter_count += 1

        diff_vektor = x_0 - new_x
        diff = sum([x ** 2 for x in diff_vektor])


    print('x =', new_x, ' '*(30-len(str(new_x))), 'Iterasjoner :', iter_count, ' '*(5-len(str(iter_count))),
          '|x_' + str(iter_count)+ ' - x_' + str(iter_count - 1)+'| =', diff)

def oppg5(x_0 = 1, eps = 1e-15):
    print()
    print('Oppgave 5:')
    # f(x) = x^3 - 7 løses av 7^(1/3)
    # f'(x) = 3x^2
    new_x = x_0 - (((x_0**3) - 7)/(3*(x_0**2)))
    iter_count = 1
    diff = new_x - x_0

    while abs(diff) > eps:
        x_0 = new_x
        new_x = x_0 - (((x_0**3) - 7)/(3*(x_0**2)))

        iter_count += 1
        diff = new_x - x_0

    print('x =', new_x, ' '*(30-len(str(new_x))), 'Iterasjoner :', iter_count, ' '*(5-len(str(iter_count))),
          'x_' + str(iter_count), '- x_' + str(iter_count - 1), '=', new_x - x_0)

t0 = time.process_time()
oppg4()
print(time.process_time()-t0)
