Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simplify tree_rows helper by only counting bits #3

Merged
merged 1 commit into from
Oct 28, 2022

Conversation

theStack
Copy link
Contributor

This helper basically calculates the number of trailing zeros of the next power of two of the input number, which can be simply achieved by counting the number of bits after the input number is reduced by 1 (to take perfect powers of two into account). Tests still pass, additionally the following script was used to verify this for n from zero up to one billion:

#!/usr/bin/env python3
import math


def next_power_of_2(x: int) -> int:
    return 1 if x == 0 else 2**(x - 1).bit_length()


def tree_rows_old(n: int) -> int:
    return int(math.log2(next_power_of_2(n)))


def tree_rows_new(n: int) -> int:
    return (n - 1).bit_length()


for n in range(1, 1_000_000_000):
    assert tree_rows_old(n) == tree_rows_new(n)

This helper basically calculates the number of trailing zeros of the
next power of two of the input number, which can be simply achieved by
counting the number of bits after the input number is reduced by 1 (to
take perfect powers of two into account).
@kcalvinalvin
Copy link
Contributor

I took a few days thinking/testing this and this is really nifty. It should always work since only the numbers that's 2^n should decrement in the bits it's using.

Tested the script, tested with the go library at https://github.com/utreexo/utreexo
ACK 8446862

This is just a straight up better implementation of treeRows. This change should go into all the other implementations as well :)

@kcalvinalvin kcalvinalvin merged commit 072c6ed into utreexo:main Oct 28, 2022
@theStack theStack deleted the simplify_tree_rows branch October 28, 2022 07:09
kcalvinalvin added a commit to kcalvinalvin/utreexo-utreexo that referenced this pull request Oct 30, 2022
treeRows() is changed to a much simpler algorithm that only depends on
counting the number of bits used to represent the number of leaves.

Since only numLeaves of 2^n should decrement in the number of bits used,
the function should return the correct amount of total rows except 0
(which is handled separately).

This changed is based off of utreexo/pytreexo#3
kcalvinalvin added a commit to kcalvinalvin/rustreexo-1 that referenced this pull request Nov 16, 2022
tree_rows() is simplified based on the algorithm by theStack on PR mit-dci#3
utreexo/pytreexo#3 on github. next_pow doesn't
need to be calculated anymore with this change.
kcalvinalvin added a commit to kcalvinalvin/rustreexo-1 that referenced this pull request Nov 24, 2022
tree_rows() is simplified based on the algorithm by theStack on PR mit-dci#3
utreexo/pytreexo#3 on github. next_pow doesn't
need to be calculated anymore with this change.
theStack added a commit to theStack/libutreexo that referenced this pull request Apr 12, 2023
This simplification was first proposed for pytreexo, and then also adapted for
the go and rust implementations, see
    - utreexo/pytreexo#3
    - utreexo/utreexo#72
    - mit-dci/rustreexo#18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants