Skip to content

Add Smith Normal Form, Jacobian group, and Picard group#31

Open
Copilot wants to merge 3 commits into
mainfrom
copilot/add-smith-normal-form-algo
Open

Add Smith Normal Form, Jacobian group, and Picard group#31
Copilot wants to merge 3 commits into
mainfrom
copilot/add-smith-normal-form-algo

Conversation

Copilot AI commented Apr 21, 2026

Copy link
Copy Markdown

Implements the three follow-up items from the issue: a Smith Normal Form (SNF) routine, the Jacobian/critical group, the Picard group, and an SNF-based path through linear_equivalence.

Changes

  • CFSmithNormalForm.pysmith_normal_form(A) -> (D, U, V) with U @ A @ V == D, U/V unimodular. Pure-integer arithmetic via NumPy object dtype (no float / no new deps). Plus elementary_divisors(A) helper.
  • CFPicardJacobian.pyJacobianGroup(graph) and PicardGroup(graph), both built from the SNF of the graph Laplacian.
    • JacobianGroup: order (= number of spanning trees), invariant_factors, structure(), contains(divisor).
    • PicardGroup: free_rank, torsion_order, invariant_factors, structure(), equivalent(d1, d2).
    • free_rank reflects connected-component count; JacobianGroup.order raises on disconnected graphs.
  • algo.linear_equivalence — new method kwarg: "ewd" (default, unchanged) or "smith", the latter dispatching to PicardGroup.equivalent for a purely algebraic check. Docstring notes that callers running many checks on one graph should reuse a PicardGroup to avoid repeated SNF computation.
  • Exports added in chipfiring/__init__.py.
  • Tests (tests/test_picard_jacobian.py, 31 cases) cover SNF invariants (U A V = D, unimodularity, divisibility chain), known group structures (K₃ → Z/3Z, K₄ → (Z/4Z)², trees → trivial, C₄ → Z/4Z), contains/equivalent membership, disconnected-graph handling, and EWD-vs-SNF agreement on K₄.

Example

from chipfiring import CFGraph, CFDivisor, JacobianGroup, PicardGroup, linear_equivalence

g = CFGraph({"a", "b", "c"}, [("a", "b", 1), ("b", "c", 1), ("a", "c", 1)])

JacobianGroup(g)            # JacobianGroup(order=3, structure='Z/3Z')
PicardGroup(g).structure()  # 'Z (+) Z/3Z'

d1 = CFDivisor(g, [("a", 3), ("b", 1), ("c", 0)])
d2 = CFDivisor(g, [("a", 1), ("b", 2), ("c", 1)])  # d1 with vertex a fired
linear_equivalence(d1, d2, method="smith")  # True

Copilot AI and others added 2 commits April 21, 2026 03:33
…near equivalence

Agent-Logs-Url: https://github.com/DhyeyMavani2003/chipfiring/sessions/6d06702b-f457-44dc-b70b-9ceb014dccf7

Co-authored-by: DhyeyMavani2003 <82772894+DhyeyMavani2003@users.noreply.github.com>
Copilot AI changed the title [WIP] Add Smith Normal Form algorithm for linear equivalence Add Smith Normal Form, Jacobian group, and Picard group Apr 21, 2026
Copilot AI requested a review from DhyeyMavani2003 April 21, 2026 03:35
@DhyeyMavani2003 DhyeyMavani2003 marked this pull request as ready for review April 21, 2026 03:44
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.

[Later on Optimization] Smith Normal Form for chipfiring.algo.linear_equivalence + Picard Group + Jacobian Group

2 participants