import numpy as np
import numpy.linalg as la
import matplotlib.pyplot as plt

from blatt05 import *

def gauss(n):
    ns = 1 + np.arange(n)
    c = ns / np.sqrt(4 * ns**2 - 1)
    P = np.diag(c, 1) + np.diag(c, -1)

    xs, vects = la.eig(P)
    coeffs = 2 * vects[0,:]**2
    return xs, coeffs

def transformQuad(f, t, quad):
    xs, coeffs = quad
    expansion = (t[1] - t[0]) / (f[1] - f[0])
    return t[0] + (xs - f[0]) * expansion, expansion * coeffs

if __name__ == "__main__":
    f, a, b = np.exp, -3, 3
    noKnots, noIter = np.arange(6), 1 + (4 * np.arange(10))

    exactValue = np.exp(3) - np.exp(-3)
    data = [[np.abs(exactValue - chainedQuad(transformQuad((-1, 1), (0, 1), gauss(n)), a, b, k, f))
        for k in noIter] for n in noKnots]

    plt.figure(figsize=(16, 9))
    # Reason for the transpose: Unintuitively matplotlib plots *columnwise*.
    plt.semilogy(noIter, np.array(data).T, label=["{} Knoten".format(n+1) for n in noKnots])

    plt.xlabel("Anzahl der Iterationen der Quadraturformel")
    plt.ylabel("Fehler")
    plt.legend()

    plt.savefig("image.png")
