-
Notifications
You must be signed in to change notification settings - Fork 0
Symplectic moments #43
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
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests.
🚀 New features to boost your workflow:
|
| monte_carlo_integral = sum( | ||
| prod( | ||
| cse[i-1, j-1] | ||
| for i, j in zip(seq_i, seq_j) | ||
| ) | ||
| for cse in cse_gen | ||
| ) / sample_size | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would preferable to precalculate the values on separate notebook and harccode the answers here. I would suggest to not do Montecarlo inside the test.
haarpy/tests/test_symplectic.py
Outdated
| def generate_random_usp(d): | ||
| """Generate a Haar-random USp(2d) matrix of size (2d x 2d).""" | ||
| # Step 1: Random quaternionic d x d matrix with i.i.d. N(0,1) components | ||
| A = np.random.normal(size=(d, d)) | ||
| B = np.random.normal(size=(d, d)) | ||
| C = np.random.normal(size=(d, d)) | ||
| D = np.random.normal(size=(d, d)) | ||
| # Prepare list to store orthonormal quaternion columns (each as 4 real component arrays) | ||
| basis = [] | ||
| # Step 2: Quaternionic Gram-Schmidt | ||
| for j in range(d): | ||
| # j-th column as quaternion vector components | ||
| v0, v1, v2, v3 = A[:, j].copy(), B[:, j].copy(), C[:, j].copy(), D[:, j].copy() | ||
| # Make orthogonal to previous basis vectors | ||
| for (u0, u1, u2, u3) in basis: | ||
| # Compute quaternion inner product: q = <u, v> = sum_i conj(u_i)*v_i (a quaternion) | ||
| p0, p1, p2, p3 = u0, -u1, -u2, -u3 # components of conj(u) | ||
| q0 = p0 @ v0 - p1 @ v1 - p2 @ v2 - p3 @ v3 # (conj(u)·v)_real | ||
| q1 = p0 @ v1 + p1 @ v0 + p2 @ v3 - p3 @ v2 # (conj(u)·v)_i | ||
| q2 = p0 @ v2 - p1 @ v3 + p2 @ v0 + p3 @ v1 # (conj(u)·v)_j | ||
| q3 = p0 @ v3 + p1 @ v2 - p2 @ v1 + p3 @ v0 # (conj(u)·v)_k | ||
| # Subtract projection: v := v - u * q | ||
| t0 = u0 * q0 - u1 * q1 - u2 * q2 - u3 * q3 | ||
| t1 = u0 * q1 + u1 * q0 + u2 * q3 - u3 * q2 | ||
| t2 = u0 * q2 - u1 * q3 + u2 * q0 + u3 * q1 | ||
| t3 = u0 * q3 + u1 * q2 - u2 * q1 + u3 * q0 | ||
| v0 -= t0; v1 -= t1; v2 -= t2; v3 -= t3 | ||
| # Normalize v (so that <v,v> = 1) | ||
| norm = np.sqrt(v0@v0 + v1@v1 + v2@v2 + v3@v3) | ||
| v0 /= norm; v1 /= norm; v2 /= norm; v3 /= norm | ||
| # Step 3: Multiply by a random unit quaternion (random phase) | ||
| q0, q1, q2, q3 = random_unit_quaternion() | ||
| t0 = v0*q0 - v1*q1 - v2*q2 - v3*q3 | ||
| t1 = v0*q1 + v1*q0 + v2*q3 - v3*q2 | ||
| t2 = v0*q2 - v1*q3 + v2*q0 + v3*q1 | ||
| t3 = v0*q3 + v1*q2 - v2*q1 + v3*q0 | ||
| v0, v1, v2, v3 = t0, t1, t2, t3 | ||
| basis.append((v0, v1, v2, v3)) | ||
| # Step 4: Assemble the complex 2d x 2d matrix from quaternion basis | ||
| d2 = 2 * d | ||
| U = np.zeros((d2, d2), dtype=np.complex128) | ||
| # Fill block entries for each quaternion column | ||
| for j, (u0, u1, u2, u3) in enumerate(basis): | ||
| U[:d, j] = u0 + 1j*u1 # top-left block | ||
| U[:d, j+d] = u2 + 1j*u3 # top-right block | ||
| U[d:, j] = -u2 + 1j*u3 # bottom-left block | ||
| U[d:, j+d] = u0 - 1j*u1 # bottom-right block | ||
| return U | ||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the code to generate symplectics should not be here. Instead we should separately Montecarlo teh answer and the just hardcode them here.
More symplectic tests
No description provided.