from typing import Dict, Any
import sympy as sp
from Stochastisches_Modell import StochastischesModell

def iterative_ausgleichung(
    A: sp.Matrix,
    dl: sp.Matrix,
    modell: StochastischesModell,
) -> Dict[str, Any]:

    ergebnisse_iter = []                                #Liste für Zwischenergebnisse

    for it in range(max_iter):
        Q_ll, P = modell.berechne_Qll_P()               #Stochastisches Modell: Qll und P berechnen

        N = A.T * P * A                                 #Normalgleichungsmatrix N
        Q_xx = N.inv()                                  #Kofaktormatrix der Unbekannten Qxx
        n = A.T * P * dl                                 #Absolutgliedvektor n

        dx = N.LUsolve(n)                               #Zuschlagsvektor dx

        v = dl - A * dx                                  #Residuenvektor v

        Q_vv = modell.berechne_Qvv(A, P, Q_xx)          #Kofaktormatrix der Verbesserungen Qvv
        R = modell.berechne_R(Q_vv, P)                  #Redundanzmatrix R
        r = modell.berechne_r(R)                        #Redundanzanteile als Vektor r

        ergebnisse_iter.append({                        #Zwischenergebnisse speichern in Liste
            "iter": it + 1,
            "Q_ll": Q_ll,
            "P": P,
            "N": N,
            "Q_xx": Q_xx,
            "dx": dx,
            "v": v,
            "Q_vv": Q_vv,
            "R": R,
            "r": r,
            "sigma_hat": sigma_hat,
            "sigma0_groups": dict(modell.sigma0_groups),
        })

    return {
        "dx": dx,
        "v": v,
        "Q_ll": Q_ll,
        "P": P,
        "N": N,
        "Q_xx": Q_xx,
        "Q_vv": Q_vv,
        "R": R,
        "r": r,
        "sigma_hat": sigma_hat,
        "sigma0_groups": dict(modell.sigma0_groups),
        "history": ergebnisse_iter,
    }