Skip to content

feat: pretty-print (draw) for Statevec and DensityMatrix#542

Open
kish-00 wants to merge 1 commit into
TeamGraphix:masterfrom
kish-00:feat/pretty-print
Open

feat: pretty-print (draw) for Statevec and DensityMatrix#542
kish-00 wants to merge 1 commit into
TeamGraphix:masterfrom
kish-00:feat/pretty-print

Conversation

@kish-00

@kish-00 kish-00 commented Jun 14, 2026

Copy link
Copy Markdown

Description

Adds draw() methods to Statevec and DensityMatrix for human-readable pretty-printing of quantum states and density matrices, supporting three output formats (Unicode, ASCII, LaTeX).

New public API

  • complex_to_str(z, output) — pretty-print a complex number, detecting:
    • Zero, integers, simple fractions (1/2, 3/4)
    • Square roots (1/√2, √3/2)
    • Pure exponentials (e^(iπ/3), e^(iπ/4))
    • Pure real/imaginary and general a±bi
  • statevec_to_str(state_dict, output) — format a statevector dict as ∑ c_i|b_i⟩
  • densitymatrix_to_str(rho, nqubit, output) — format density matrix as ∑ w_{ij}|i⟩⟨j|
  • Statevec.draw(encoding, output, ...) — prints the statevector
  • DensityMatrix.draw(output, ...) — prints the density matrix

Breaking changes

None.

Checklist

  • Implemented complex_to_str() with fraction, sqrt, exponential detection
  • Implemented statevec_to_str() and densitymatrix_to_str()
  • Added Statevec.draw() and DensityMatrix.draw() methods
  • Updated exports in __init__.py
  • 16 new test cases across 5 test classes
  • All 98 pretty-print tests pass (165 including statevec/density_matrix)
  • Ruff linting clean (all rules)
  • Mypy type-checking clean
  • Output verified manually

Closes #501

Add pretty-print support via draw() methods with three output formats
(Unicode, ASCII, LaTeX).

- complex_to_str(): detects zero, integers, fractions (1/2), square roots
  (1/\u221a2, \u221a3/2), exponentials (e^(i\u03c0/3)), pure real/imaginary,
  and general a\u00b1bi
- statevec_to_str(): formats Statevec amplitudes with ket notation
- densitymatrix_to_str(): formats rho elements with Dirac |i\u27e9\u27e8j| notation
- Statevec.draw() and DensityMatrix.draw() public methods
- 16 new test cases across 5 test classes

Closes TeamGraphix#501
@thierry-martinez

thierry-martinez commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Thank you for your contribution. As you may have noticed, there is an other pull request #524 that already addresses the same issue.

Could you clarify how your contribution differs from, or improves upon, the previous works? Specifically, please explain why you consider your approach to be better.

@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.96721% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.68%. Comparing base (6edaaef) to head (12e9bcb).

Files with missing lines Patch % Lines
graphix/pretty_print.py 81.14% 33 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #542      +/-   ##
==========================================
- Coverage   88.85%   88.68%   -0.18%     
==========================================
  Files          49       49              
  Lines        7135     7317     +182     
==========================================
+ Hits         6340     6489     +149     
- Misses        795      828      +33     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kish-00

kish-00 commented Jun 15, 2026

Copy link
Copy Markdown
Author

Thanks for the review and the pointer to #524. I had not seen that PR — we were apparently working on this independently.

The core approach is the same (square-then-rationalize for sqrt detection), but there are differences:

My approach is lighter: I lean on Fraction.limit_denominator() (stdlib) instead of implementing custom _squarefree_decomposition. For the common amplitudes seen in graphix statevectors — ±1, ±1/2, ±√2/2, ±√3/2, e^{±iπ/n} — both approaches produce identical output.

PR #524 is more thorough: the explicit _squarefree_decomposition handles cases like √12 → 2√3 properly, while my approach would render √(12). That said, such cases are unlikely from Clifford+T statevectors where amplitudes are almost always in the set {0, ±1, ±1/2, ±√2/2, ±√3/2}.

Other minor differences:

  • My densitymatrix_to_str formats as a sum of Dirac projectors rather than a grid — I found this more natural for sparse density matrices common in MBQC.
  • LaTeX output: I use \mathrm{e}^{...} for exponentials rather than the raw e^{...}.

Happy to either:
a) Close this PR in favor of #524 if the more robust sqrt detection is preferred
b) Merge relevant parts if any of my formatting choices are useful independently

I defer to your judgment on which approach fits the project better.

@kish-00

kish-00 commented Jun 15, 2026

Copy link
Copy Markdown
Author

Thanks for the review @thierry-martinez! I see PR #524 by @Vinny010 also addresses #501. Here is how the two approaches differ:

Architecture:

Rendering:

Size:

Testing:

I am happy to adapt my PR in either direction — merge with #524, rebase on top of it, or close mine if #524 is preferred. Let me know what works best for the project.

@Vinny010

Copy link
Copy Markdown

Thanks for the detailed comparison, @kish-00 ? generous write-up, and I appreciate the offer to coordinate.

A couple of notes on the technical points:

  • State-class size. Fair design choice on your end. #524's precision/atol/rtol live on the draw methods themselves, which is what drove the extra lines on Statevec/DensityMatrix. If a leaner state-class footprint is preferred, those parameters could equally sit on free functions with thin draw wrappers ? happy to refactor #524 that way.
  • Rendering. The uniform-magnitude factoring in #524 is one branch of the statevec path; the per-term form (closer to your approach) is still the fallback for non-uniform/Cartesian amplitudes. So the two styles compose, and I'm happy to wire per-term as an option if useful.

Glad to incorporate any pieces from #542, or step aside if that's the cleaner call ? leaving the merge decision to @thierry-martinez.

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.

Pretty-print for Statevec and DensityMatrix

3 participants