def METHOD_NAME(
    N,
    corners,
    conv_iters,
    max_iters,
    warmup,
    conv_threshold,
    perform_check,
    timing,
    verbose,
):
    # A, b = generate_random(N)
    A, b = generate_2D(N, corners)
    print("Solving system...")
    x = np.zeros(A.shape[1])
    r = b - A.dot(x)
    p = r
    rsold = r.dot(r)
    converged = -1
    # Should always converge in fewer iterations than this
    max_iters = (
        min(max_iters, b.shape[0]) if max_iters is not None else b.shape[0]
    )
    timer.start()
    for i in range(-warmup, max_iters):
        if i == 0:
            timer.start()
        Ap = A.dot(p)
        alpha = rsold / (p.dot(Ap))
        x = x + alpha * p
        r = r - alpha * Ap
        rsnew = r.dot(r)
        # We only do the convergence test every conv_iters or on the last
        # iteration
        if (
            i >= 0
            and (i % conv_iters == 0 or i == (max_iters - 1))
            and np.sqrt(rsnew) < conv_threshold
        ):
            converged = i
            break
        if verbose:
            print("Residual: " + str(rsnew))
        beta = rsnew / rsold
        p = r + beta * p
        rsold = rsnew
    total = timer.stop()
    if converged < 0:
        print("Convergence FAILURE!")
    else:
        print("Converged in %d iterations" % (converged))
    if perform_check:
        check(A, x, b)
    if timing:
        print(f"Elapsed Time: {total} ms")
    return total