'''
Skrevet av: Vegard G. Jervell
Hensikt: Hjelpe folk med å lære alt de ikke lærte i ITGK
Spesifikt: SciPy
'''
import scipy.optimize as opt
import scipy.integrate as si
import numpy as np

#Nå skal vi løse litt likninger og integrere numerisk!

#en enkel funksjon
def f(x):
    return np.exp(np.sin(x**2))

xf0 = opt.fsolve(f, 1) #løser likningen f(x) = 0 med startgjetning x = 1, NB: returnerer en liste med ett element!
print('xf0 =', xf0)
print('f(xf0) =', f(xf0[0]))

#en litt mer avansert funksjon
def g(x, a, b):
    return np.cos(a * x) + b * x

xg0 = opt.fsolve(g, 2, args=(2, 5)) #løser likningen g(x, 2, 5) = 0 med startgjetning x = 2
print()
print('xg0 =', xg0)
print('g(xg0, 2, 5) =', g(xg0[0], 2, 5))

#En funksjon som er vanskelig å integrere
def h(x):
    return np.sin(np.exp(x**2))

integral_1_10 = si.quad(h, 0, 1) #integrerer h(x) fra 0 til 1
#NB: integral_1_10 = [resultat, feilestimat] er en liste med to elementer, det første er resultatet, det andre er et feilestimat
print()
print('integral_1_10 =', integral_1_10)


#enda en funskjon som er vanskelig å integrere
def l(x, a, b):
    return np.sin(a * np.cos(b*x))

integral_2_6 = si.quad(l, 2, 6, args=(8, 3)) # integrerer l(x, 8, 3) fra 2 til 6
print('integral_2_6 =', integral_2_6)

#En skikkelig komplisert funksjon
def avanserte_greier(t):
    return si.quad(h, 0, t)[0] - 0.5*t #returnerer integralet av h(x) fra 0 til t, minus 0.5*t

t0 = opt.fsolve(avanserte_greier, 1) #løser likningen avanserte_greier(t) = 0
print()
print('t0 :', t0)
print('avanserte_greier(t0) :', avanserte_greier(t0))
