#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Mar  6 08:06:39 2020

@author: suwako
"""
import matplotlib.pyplot as plt
import numpy as np
def newton(f, df, u, xtol=1e-12, Nmax=100):
    n = 1
    v = u - f(u) / df(u)
    while abs(u - v) >= xtol:
        u, v = v, v - f(v) / df(v)
        n += 1
        if n > Nmax:
            return None
    return v, n

def secante(f, u, v, xtol=1e-12, Nmax=100):
    n = 1
    while abs(u - v) >= xtol:
        u, v = v, (u * f(v) - v * f(u)) / (f(v) - f(u))
        n += 1
        if n > Nmax:
            return None
    return v, n

def f(x): return x**3 - 2 * x - 5
def df(x): return 3 * x * x - 2
plt.figure(0)
X = np.linspace(-3, 3, 256)
Y = [f(x) for x in X]
plt.plot(X,Y)
plt.grid()
plt.show()

for u in range(-3, 4):
    x, n = newton(f, df, u)
    print(f"Pour u0 = {u} on obtient {x} au bout de {n} itérations'")

nmax = 0
for u in range(-3, 4):
    for v in range(-3, 4):
        if u != v:
            x, n = secante(f, u, v)
            if n > nmax:
                nmax = n
                (a, b) = (u, v)
print(f"pour u0 = {a} et u1 = {b}, {nmax} itérations sont nécéssaires")

print(secante(df, 0, 1)[0])
print(newton(f, df, secante(df, 0, 1)[0], Nmax=200))

def f(x): return 3 * np.sin(4*x)+x*x - 2
def df(x): return 12*np.cos(4*x)+2*x
plt.figure(1)
X = np.linspace(-3, 3, 256)
Y = [f(x) for x in X]
plt.plot(X,Y)
plt.grid()
plt.show()

def zeros(f, df, a, b, n=100):
    zer = []
    for k in range(n):
        u = a + np.random.random() * (b - a)
        x = newton(f, df, u)
        if x is not None and round(x[0], 12) not in zer:
            zer.append(round(x[0], 12))
    return zer
from scipy.integrate import quad

def f(x): 
    return quad(lambda t : np.sqrt(1-t*t)*np.cos(x*t),-1,1)[0]
def df(x):
    return quad(lambda t : -t*np.sqrt(1-t*t)*np.sin(x*t),-1,1)[0]
plt.figure(2)
X = np.linspace(0, 16, 256)
Y = [f(x) for x in X]
plt.plot(X,Y)
plt.grid()
plt.show()

def derivee(f,x,h):
    return (f(x+h)-f(x-h)/(2*h))
def delta(p):
    return abs(np.cos(1)-derivee(np.sin,1,10**(-p)))
plt.figure(3)
P= np.arange(4,8,.1)
D=[delta(p) for p in P]
print(D)
plt.plot(P,D)
plt.show()