import numpy as np
import sympy as sp
import matplotlib.pyplot as plt

t = sp.symbols('t')
T = 4  # Perioda funkce
to = 1/2
omega = 2 * sp.pi / T

f = 1 + sp.exp(-t)

def fc(x):
    return 1 + sp.exp(-x)

def get_tabulka():
    print(f"a_0 = {a_0: .2f}")
    print(f"c_0 = {((1 / T) * sp.integrate(f, (t, 0, to))):.2f}")
    print(f"A_0 = {(a_0 / 2):.2f}")

    pa_coeffs = [((2 / T) * sp.integrate(f * sp.cos(n * omega * t), (t, 0, to)).evalf(), n) for n in range(1, n_max + 1)]
    pb_coeffs = [((2 / T) * sp.integrate(f * sp.sin(n * omega * t), (t, 0, to)).evalf(), n) for n in range(1, n_max + 1)]
    pc_coeffs = [((1 / T) * sp.integrate(f * sp.exp(1j * n * omega * t), (t, 0, to)).evalf(), n) for n in range(1, n_max + 1)]
    for a, b, c in zip(pa_coeffs, pb_coeffs, pc_coeffs):
        print(f"n= {a[1]}")
        print(f"a= {a[0]:.2f}")
        print(f"b= {b[0]:.2f}")
        print(f"A= {(a[0]**2+b[0]**2)**(1/2):.2f}")
        print(f"c_n= {np.absolute(c[0]):.2f}")
        print(f"phi= {np.angle(float(a[0])+float(b[0])*1j, deg=True):.2f}")

def calculate_coefficients(n_max):
    a_0 = (2 / T) * sp.integrate(f, (t, 0, to))
    a_coeffs = [((2 / T) * sp.integrate(f * sp.cos(n * omega * t), (t, 0, to)), n) for n in range(1, n_max + 1)]
    b_coeffs = [((2 / T) * sp.integrate(f * sp.sin(n * omega * t), (t, 0, to)), n) for n in range(1, n_max + 1)]
    return a_0, a_coeffs, b_coeffs

def cosinus_series(x, a_0, a_coeffs):
    cosinus = a_0 / 2
    for a_n, n in a_coeffs:
        cosinus += a_n * sp.cos(omega * n * x)
    return cosinus

def sinus_series(x, b_coeffs):
    sinus = 0
    for b_n, n in b_coeffs:
        sinus += b_n * sp.sin(omega * n * x)
    return sinus

# Předpočítat koeficienty
n_maxs = [5, 10, 20, 30]

for n_max in n_maxs:
    a_0, a_coeffs, b_coeffs = calculate_coefficients(n_max)

    # Definujte interval pro vykreslení
    t_values = np.linspace(-4, 6, 200)

    cosinus = [cosinus_series(x, a_0, a_coeffs) for x in t_values]
    cosinus_scaled = [2 * y for y in cosinus]
    original = [fc(-x % (2*2)) if (-x % (2*2)) < to else fc(x % (2*2)) if (x % (2*2)) < to else 0 for x in t_values]
    plt.plot(t_values, original, label="f(t)")
    plt.plot(t_values, cosinus_scaled, label="CŘ")
    plt.title(f"n={n_max}")
    plt.legend()
    plt.xlabel("t")
    plt.ylabel("f(t)")
    plt.show()

    sinus = [sinus_series(x, b_coeffs) for x in t_values]
    sinus_scaled = [2 * y for y in sinus]
    original = [-fc(-x % (2*2)) if (-x % (2*2)) < to else fc(x % (2*2)) if (x % (2*2)) < to else 0 for x in t_values]
    plt.plot(t_values, original, label="f(t)")
    plt.plot(t_values, sinus_scaled, label="SŘ")
    plt.title(f"n={n_max}")
    plt.legend()
    plt.xlabel("t")
    plt.ylabel("f(t)")
    plt.show()
