Number of CRF polychora

Discussion of known convex regular-faced polytopes, including the Johnson solids in 3D, and higher dimensions; and the discovery of new ones.

Re: Number of CRF polychora

Postby mr_e_man » Mon Sep 19, 2022 4:22 pm

Now I've added more functions to my program, with short explanations and examples. It still uses bit operations, though.

Code: Select all
n1,n2 = 10,10

disallow_pyramids1 = True
disallow_magbicups1 = False
disallow_adjacents1 = False

disallow_pyramids2 = True
disallow_magbicups2 = False
disallow_adjacents2 = False

disallow_simultaneous1and2 = False

# Keep in mind the operator precedence:
# arithmetic operations (+ - * //) are evaluated first, then
# bit shifts (<< >>), then other bitwise operations (& | ^).

# no augment = 00, pyramid augment = 01,
# ortho augment = 10, gyro augment = 11 (binary)

m = max(n1, n2)
all_bits = (1 << 2*m) - 1   # 1111...1111
even_bits = all_bits // 3   # 0101...0101
odd_bits = even_bits << 1   # 1010...1010
limit1 = 1 << 2*n1
limit2 = 1 << 2*n2

def pyramids(x):
    """Keep the '01' bit-pairs in x, and set '10' and '11' to '00'.

    >>> pyramids(0b00101101) == 0b00000001
    return x & even_bits & ~(x & odd_bits)>>1

def magbicups(x):
    """Keep the '10' and '11' bit-pairs in x, and set '01' to '00'.

    >>> magbicups(0b00101101) == 0b00101100
    return (x & odd_bits) | (x & even_bits & (x & odd_bits)>>1)

def gyrate(x):
    """Keep the '01' bit-pairs in x, and swap '10' and '11'.

    >>> gyrate(0b00101101) == 0b00111001
    return (x & odd_bits) | ((x & even_bits) ^ (x & odd_bits)>>1)

def rotate(x, num_places, total_places):
    """Shift bit-pairs in x right num_places; carry the remainder left.

    It's assumed that x has total_places many bit-pairs, and that
    num_places is between 0 and total_places (inclusive).

    >>> rotate(0b00101101, 1, 4) == 0b01001011
    return x >> 2*num_places | (
        (x & ((1<<2*num_places)-1)) << 2*(total_places - num_places))

def reverse(x, total_places):
    """Reverse the order of bit-pairs in x.

    This doesn't completely reverse the order of bits; '01' gets moved,
    but not flipped to '10'.

    It's assumed that x has total_places many bit-pairs.

    >>> reverse(0b00101101, 4) == 0b01111000
    y = 0
    for i in range(total_places):
        y |= (x>>2*i & 3) << 2*(total_places - 1 - i)
    return y

def adjacents(x, total_places):
    """Keep each bit-pair in x with a non-zero bit-pair to its left.

    This is cyclic; the leftmost bit-pair is kept if the rightmost
    bit-pair is non-zero.

    It's assumed that x has total_places many bit-pairs.

    >>> adjacents(0b00101101, 4) == 0b00001101
    x_left = rotate(x, 1, total_places)
    # The bit-pair in x_left at the kth place is the bit-pair in x to
    # the left of the kth place.  It moved from left to right.
    x_left_nonzero = (x_left & even_bits) | (x_left & odd_bits)>>1
    # Multiply by 3 to replace each '01' with '11'.
    return x & x_left_nonzero*3

count = 0
for ring1 in range(limit1):
    if (disallow_pyramids1 and pyramids(ring1)
            or disallow_magbicups1 and magbicups(ring1)
            or disallow_adjacents1 and adjacents(ring1, n1)):
    for ring2 in range(limit2):
        if (disallow_pyramids2 and pyramids(ring2)
                or disallow_magbicups2 and magbicups(ring2)
                or disallow_adjacents2 and adjacents(ring2, n2)
                or disallow_simultaneous1and2 and ring1 and ring2):

        rings1and2 = ring1 << 2*n2 | ring2
        is_least = True
        i = 0
        while i < 2 and is_least:
            ring1_i = reverse(ring1, n1) if i else ring1
            ring2_i = gyrate(ring2) if i else ring2
            j = 0
            while j < 2 and is_least:
                ring2_ij = reverse(ring2_i, n2) if j else ring2_i
                ring1_ij = gyrate(ring1_i) if j else ring1_i
                k = 0
                while k < n1 and is_least:
                    ring1_ijk = rotate(ring1_ij, k, n1)
                    ring2_ijk = gyrate(ring2_ij) if k & 1 else ring2_ij
                    l = 0
                    while l < n2 and is_least:
                        ring2_ijkl = rotate(ring2_ijk, l, n2)
                        ring1_ijkl = gyrate(ring1_ijk) if l & 1 else ring1_ijk
                        new_rings1and2 = ring1_ijkl << 2*n2 | ring2_ijkl
                        new_rings2and1 = ring2_ijkl << 2*n1 | ring1_ijkl
                        is_least &= rings1and2 <= new_rings1and2
                        is_least &= n1 != n2 or rings1and2 <= new_rings2and1
                        l += 1
                    k += 1
                j += 1
            i += 1
        count += is_least


(And I have other chunks of code to more efficiently handle special cases, such as when both rings can't be augmented at the same time, or when only pyramid augments are possible.)

Using this (with the first few lines changed), I got mostly the same results as in quickfur's list. The only exceptions had both rings augmentable at the same time, and at least one ring gyratably augmentable:

4,8-duoprism: 152 augmentations
5,6-duoprism: 66 augmentations
5,8-duoprism: 162 augmentations
5,10-duoprism: 2702 augmentations
8,8-duoprism: 429 augmentations (possibly wrong, because of relation to tesseract)
10,10-duoprism: 4924629 augmentations (took about 9 hours with the code in this post, vs. 4 hours with the previous version)

Again, these counts include the un-augmented duoprisms.

If only one ring is augmentable at a time, then quickfur's operation of reversing both rings has the same effect as reversing one and gyrating the other. (Reversing no augments is the same as gyrating no augments.) So the false symmetry happens to be equivalent to the true symmetry, and the count is correct, in this case.

If both rings are augmentable at the same time, but only with pyramids (so both have size at most 5), then reversing both has the same effect as reversing and gyrating both. This is a true symmetry of the duoprism, but still the reflection is missing. It turns out that the augmentations of a ring with size 3, 4, or 5 all have reflection symmetry anyway; i.e. reversing it has the same effect as rotating it. So the reflection symmetry doesn't need to be included explicitly, and the count is correct, in this case.
Last edited by mr_e_man on Tue Sep 20, 2022 4:29 pm, edited 2 times in total.
ΓΔΘΛΞΠΣΦΨΩ αβγδεζηθϑικλμνξοπρϱσςτυϕφχψωϖ °±∓½⅓⅔¼¾×÷†‡• ⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎
ℕℤℚℝℂ∂¬∀∃∅∆∇∈∉∋∌∏∑ ∗∘∙√∛∜∝∞∧∨∩∪∫≅≈≟≠≡≤≥⊂⊃⊆⊇ ⊕⊖⊗⊘⊙⌈⌉⌊⌋⌜⌝⌞⌟〈〉⟨⟩
Posts: 378
Joined: Tue Sep 18, 2018 4:10 am

Re: Number of CRF polychora

Postby mr_e_man » Mon Sep 19, 2022 4:44 pm

There are other possible augments that we haven't considered.

One is the digonal magnabicupolic ring, i.e. cube || line segment. Instead of ortho and gyro, it actually has three orientations, corresponding to the three axes of the cube. But in the third orientation, it can be considered as a square pyramid prism, and grouped with other n-gon pyramid prisms.

Then there are n-gon cupola prisms, as well.

And a duoprism could even be augmented with another duoprism. But it seems that the only possibility is 3,4 being augmented with another 3,4, producing two gyrobifastigia.

...Never mind; they have been considered. viewtopic.php?f=32&t=1947&start=30#p24865
I agree that these won't contribute significantly to the number of duoprism augmentations.
quickfur wrote:If we include other augment shapes such as n-pyramid prisms, the counts will have to be adjusted accordingly. Though I doubt it will add significantly more augmentations to the total, because the 90° dichoral angles of the n-pyramid prisms would mean that only 3,n-duoprisms and 4,n-duoprisms are augmentable with them, so they would not experience the same kind of combinatorial explosion the augmented 10,10-duoprism and 20,20-duoprism exhibits.
ΓΔΘΛΞΠΣΦΨΩ αβγδεζηθϑικλμνξοπρϱσςτυϕφχψωϖ °±∓½⅓⅔¼¾×÷†‡• ⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎
ℕℤℚℝℂ∂¬∀∃∅∆∇∈∉∋∌∏∑ ∗∘∙√∛∜∝∞∧∨∩∪∫≅≈≟≠≡≤≥⊂⊃⊆⊇ ⊕⊖⊗⊘⊙⌈⌉⌊⌋⌜⌝⌞⌟〈〉⟨⟩
Posts: 378
Joined: Tue Sep 18, 2018 4:10 am


Return to CRF Polytopes

Who is online

Users browsing this forum: No registered users and 1 guest