#!/usr/bin/env python3
"""Recompute the four-row finite-size error decomposition table."""
from __future__ import annotations

import csv
import math
from common import (
    DATA, load_compact_counts, partition_numbers, saddle_parameter,
    boltzmann_zero_xor, two_level,
)

MILESTONES = [10000, 12000, 19584, 20000]


def main() -> None:
    counts = load_compact_counts()
    partitions = partition_numbers(max(MILESTONES))
    (DATA / 'tables').mkdir(parents=True, exist_ok=True)
    out = DATA / 'tables' / 'table_02_error_decomposition.tsv'
    with out.open('w', newline='') as fh:
        w = csv.writer(fh, delimiter='\t', lineterminator='\n')
        w.writerow([
            'total_size_N', 'exact_density', 'first_order_density',
            'exact_boltzmann_fixed_size_2R', 'two_level_fixed_size_approximation',
            'one_block_gc_error_percent', 'two_level_gc_error_percent',
            'fixed_size_error_percent', 'two_level_total_error_percent'
        ])
        for n in MILESTONES:
            t = saddle_parameter(n)
            L = math.log(1.0 / t) / t
            J = 2 ** math.floor(math.log2(L) + 0.5)
            Lambda = math.exp(-t * J) / t
            first = (1.0 + math.exp(-2.0 * Lambda)) / J
            R = boltzmann_zero_xor(t)
            twoR = 2.0 * R
            h2 = 2.0 * two_level(t, J)
            exact = counts[n] / partitions[n]
            w.writerow([
                n, f'{exact:.17g}', f'{first:.17g}', f'{twoR:.17g}', f'{h2:.17g}',
                f'{100.0 * (first / twoR - 1.0):.15g}',
                f'{100.0 * (h2 / twoR - 1.0):.15g}',
                f'{100.0 * (twoR / exact - 1.0):.15g}',
                f'{100.0 * (h2 / exact - 1.0):.15g}'
            ])
    print(out)


if __name__ == '__main__':
    main()
