def check_gramian()

in src/evaluator.py [0:0]


def check_gramian(env, src, tgt, hyp):
    # Read src
    try:
        degree, pos = env.parse_int(src)
        nx = src[
            pos:
        ]  # retourne src sans le degree et le séparateur qui va avec si j'ai bien suivi
        system = []
        while len(nx) > 0:
            b, nx = env.prefix_to_infix(nx[1:])
            # convertit en sympy, on en aura besoin de toutes facons
            s = sp.S(b)
            system.append(s)

        # get expected shape of solution (from tgt)
        nr_lines = tgt.count(env.line_separator)
        nr_cols = tgt.count(env.list_separator)
        if nr_cols % nr_lines != 0 or nr_cols // nr_lines != degree:
            logger.error("Incorrect target gramian in check_gramian")
            return False
        nr_cols = nr_cols // nr_lines

        for i in range(degree):
            valA, valB = env.compute_gradient_control(
                system[i], env.eval_point, degree, nr_lines
            )
            if i == 0:
                A = valA
                B = valB
            else:
                A = np.vstack((A, valA))
                B = np.vstack((B, valB))

        A = A / np.linalg.norm(A)
        B = B / np.linalg.norm(A)

        # read hyp, check correct shape
        h = hyp
        K0 = np.zeros((nr_lines, nr_cols))
        for i in range(nr_lines):
            for j in range(nr_cols):
                val, pos = env.parse_float(h)
                if np.isnan(val):
                    return False
                if len(h) <= pos or h[pos] != env.list_separator:
                    return False
                K0[i][j] = val
                h = h[pos + 1 :]
            if len(h) == 0 or h[0] != env.line_separator:
                return False
            h = h[1:]

        V = A + B @ K0
        return max(np.linalg.eigvals(V).real) < 0

    except TimeoutError:
        return False
    except Exception as e:
        logger.info(f"{e} in check_gramian")
        return False