codex/tetrahedral-chiral-achiral-rotation-test.py

tetrahedral-chiral-achiral-rotation-test.py
"""Proper-rotation mirror test. Run from _media.

Tested: Python 3.14, matplotlib 3.10.7, numpy 2.3.5.
Enumerates all label-respecting matchings and fits proper orthogonal rotations.
"""
from itertools import permutations
from pathlib import Path
import json
import matplotlib.pyplot as plt
import numpy as np

V = np.array([[1, 1, 1], [1, -1, -1], [-1, 1, -1], [-1, -1, 1]], float)
S = np.diag([-1., 1., 1.])
Q = np.array([[-1, 0, 0], [0, 0, 1], [0, 1, 0]], float)
COLORS = {'A': '#bb4a24', 'B': '#08699b', 'C': '#6e4096',
          'D': '#237e43', 'H': '#686868'}


def best_rotation_error(labels):
    """Minimum Frobenius residual over legal matchings and SO(3) rotations."""
    source = V @ S.T
    errors = []
    for order in permutations(range(4)):
        if any(labels[j] != labels[order[j]] for j in range(4)):
            continue
        target = V[list(order)]
        u, _, vt = np.linalg.svd(source.T @ target)
        correction = np.diag([1., 1., np.linalg.det(u @ vt)])
        rotation_row = u @ correction @ vt
        assert np.isclose(np.linalg.det(rotation_row), 1.)
        errors.append(np.linalg.norm(source @ rotation_row - target))
    return min(errors), len(errors)


def draw(ax, points, labels, title, targets=False):
    ax.set_proj_type('ortho')
    ax.view_init(elev=22, azim=-90)
    for i, p in enumerate(points):
        ax.plot([0, p[0]], [0, p[1]], [0, p[2]], color='#777777',
                lw=2, ls='--' if p[1] > 0 else '-')
        ax.scatter(*p, s=390, color=COLORS[labels[i]], edgecolors='white',
                   linewidths=1.4, depthshade=False)
        ax.text(*p, labels[i], ha='center', va='center',
                fontsize=14, color='white', fontweight='bold', zorder=100)
    if targets:
        for i, p in enumerate(V):
            ax.scatter(*p, s=720, facecolors='none', edgecolors=COLORS[labels[i]],
                       linewidths=2, depthshade=False)
    ax.scatter(0, 0, 0, s=130, color='#444444', depthshade=False)
    ax.set(xlim=(-1.65, 1.65), ylim=(-1.65, 1.65), zlim=(-1.65, 1.65))
    ax.set_box_aspect((1, 1, 1))
    ax.set_axis_off()
    ax.set_title(title, fontsize=12, pad=-8)


def main():
    assert np.allclose(Q.T @ Q, np.eye(3)) and np.isclose(np.linalg.det(Q), 1.)
    assert np.allclose(Q @ np.array([0., 1., 1.]), [0., 1., 1.])
    mirror = V @ S.T
    turned = mirror @ Q.T
    assert np.allclose(turned, V[[0, 1, 3, 2]])
    chiral_error, chiral_matchings = best_rotation_error('ABCD')
    achiral_error, achiral_matchings = best_rotation_error('ABHH')
    assert chiral_error > 1 and achiral_error < 1e-12
    fig = plt.figure(figsize=(9, 6), facecolor='white')
    for row, labels in enumerate(['ABCD', 'ABHH']):
        titles = ['Original', 'Mirror: x → −x',
                  'Half-turn: C/D mismatch' if row == 0 else 'Half-turn: exact match']
        for col, points in enumerate([V, mirror, turned]):
            draw(fig.add_subplot(2, 3, 3 * row + col + 1, projection='3d'),
                 points, labels, titles[col], targets=col == 2)
    fig.subplots_adjust(left=.09, right=.99, bottom=.14, top=.87, hspace=.22, wspace=.03)
    fig.suptitle('Identical groups change the superposition test', fontsize=18, y=.96)
    fig.text(.025, .67, 'CHIRAL', rotation=90, va='center', fontsize=13, fontweight='bold')
    fig.text(.025, .32, 'ACHIRAL', rotation=90, va='center', fontsize=13, fontweight='bold')
    fig.text(.5, .08, 'Actual 180° spatial rotation about (0, 1, 1); det Q = +1',
             ha='center', fontsize=12)
    fig.text(.5, .04, 'Outlines = original target groups • distinct C/D cannot exchange • identical H/H can',
             ha='center', fontsize=10, color='#555555')
    fig.savefig(Path(__file__).stem + '.png', dpi=120, facecolor='white')
    plt.close(fig)
    print(json.dumps({'proper_rotation_det': float(np.linalg.det(Q)),
                      'axis': [0, 1, 1], 'label_mapping': [0, 1, 3, 2],
                      'minimum_proper_rotation_residual_ABCD': chiral_error,
                      'minimum_proper_rotation_residual_ABHH': achiral_error,
                      'legal_matchings': [chiral_matchings, achiral_matchings],
                      'dimensions': [1080, 720]}))


if __name__ == '__main__':
    main()