def get_regression_count(rows, ignoreFlappingTimeouts): # for options.dump_counts

    def status_is(run_result, status):
        # startswith is used because status can be "TIMEOUT (TRUE)" etc., which count as "TIMEOUT"
        return run_result.status and run_result.status.startswith(status)

    def any_status_is(run_results, status):
        for run_result in run_results:
            if status_is(run_result, status):
                return True
        return False

    regressions = 0
    for row in rows:
        if len(row.results) < 2:
            return 0 # no regressions at all with only one run

        # "new" and "old" are the latest two results
        new = row.results[-1]
        old = row.results[-2]

        if new.category == result.CATEGORY_CORRECT:
            continue # no regression if result is correct

        if new.status == old.status:
            continue # no regression if result is the same as before
        if status_is(new, 'TIMEOUT') and status_is(old, 'TIMEOUT'):
            continue # no regression if both are some form of timeout
        if status_is(new, 'OUT OF MEMORY') and status_is(old, 'OUT OF MEMORY'):
            continue # same for OOM

        if (ignoreFlappingTimeouts and
                status_is(new, 'TIMEOUT') and any_status_is(row.results[:-2], 'TIMEOUT')):
            continue # flapping timeout because any of the older results is also a timeout

        regressions += 1

    return regressions
Orthonormalizes the "list" of functions using the Gram-Schmidt process.
dataset/ETHPy150Open sosy-lab/benchexec/benchexec/tablegenerator/__init__.py/get_regression_count--crossover with--dataset/ETHPy150Open sympy/sympy/examples/advanced/gibbs_phenomenon.py/l2_gram_schmidt