load("../framework/instance_gen.sage")

verbosity = 0
report_every = None

"""  Example
Uncomment the following to get the detailed computation
"""
# verbosity = 2
# report_every = 20

# FRODOKEM parameters
n = 976
m = 976
q = 2**16
t = q / 16
D_s = {- 10: 1.52587890625e-05, - 9: 9.1552734375e-05, - 8: 0.0004425048828125,
       - 7: 0.001800537109375, - 6: 0.00604248046875, - 5: 0.0167999267578125,
       - 4: 0.0388336181640625, - 3: 0.074493408203125, - 2: 0.118621826171875,
       - 1: 0.1568145751953125, 0: 0.172088623046875, 1: 0.1568145751953125,
       2: 0.118621826171875, 3: 0.074493408203125, 4: 0.0388336181640625,
       5: 0.0167999267578125, 6: 0.00604248046875, 7: 0.001800537109375,
       8: 0.0004425048828125, 9: 9.1552734375e-05, 10: 1.52587890625e-05}
D_e = D_s
_, var = average_variance(D_s)
d = n + m
ell = RR(sqrt(d * var))

# nu2 = RR(var * ell**4 / (t**2))
# for k in [0, 1, 2, 4, 8, 16, 32, 64, 128, 256]:
#     xx = 1 / (1 / var + k / nu2)
#     print(k, RR(xx / var))

covh = RR(var * ell**4 / (t**2)) * identity_matrix(d)

_, _, inst = initialize_from_LWE_instance(DBDD_predict_diag, n, q,
                                          m, D_e, D_s, verbosity=verbosity)

print("# failures, relative variance, bit-security (1 bit = 0.265 bikz) ")
for i in range(0, 256):
    if report_every is not None:
        inst.integrate_q_vectors(q, indices=range(d),
                                 report_every=report_every)
    else:
        inst.integrate_q_vectors(q, indices=range(d))
    print(i, ",\t \t \t", inst.S[0] / var, ",\t \t \t", inst.beta * .265)
    inst.integrate_approx_hint_fulldim(None, covh)