# pmm_tools.models.kitaev_chain

*module*

Isolated quadratic Kitaev chains in Fock and real Majorana representations.

Physical convention (matching chain_matrix_dict at phi=0):

```
H = sum mu_j c_j^dagger c_j
    + sum [t_j c_j^dagger c_(j+1)
           + Delta_j c_j^dagger c_(j+1)^dagger + h.c.]
```

We use a_j = -i(c_j-c_j^dagger), b_j = -(c_j+c_j^dagger).
Then H = Tr(B)/2 + i a^T B b/2, where B has diagonal mu,
superdiagonal t+Delta and subdiagonal t-Delta. These axes are a local
rotation of the common (c+c^dagger, -i(c-c^dagger)) convention; using that
common convention instead transposes B. No physical pairing phase changes.

For gamma=(a_1,...,a_N,b_1,...,b_N), H=Tr(B)/2+i gamma^T A gamma/4,
with A=\[[0,B],[-B^T,0]\]. Singular values of B are excitation energies.
The signed gap is always E_even-E_odd, with physical occupation parity:
-sign(det B) times the smallest singular value. The even/odd low Hamiltonian
after subtracting its midpoint is diag(+gap/2,-gap/2), so epsilon=gap/2.

Fock-space constructors retain the superconducting pairing phase. Majorana
spectra assume an isolated, real, noninteracting chain. No bridge, noise law,
or projection onto an assumed edge state is built in. Absolute accuracy is
floating-point limited: exponentially small gaps may not have reliable
relative accuracy.

## pmm_tools.models.kitaev_chain.ChainMajoranas

*class* · *dataclass*

```python
class ChainMajoranas
```

Lowest singular pair plus gap=E_even-E_odd and diagnostics.

a and b have shape (..., N), each with unit Euclidean norm. They define
gamma_a=sum a_j\*a_site_j and gamma_b=sum b_j\*b_site_j, with
B\*b=E\*a and B.T\*a=E\*b for E=energies[...,0]>=0.
This positive-SVD convention does NOT encode the signed parity gap in
gamma_a/gamma_b: use gap separately when labeling even and odd states.

At t=Delta>0, mu=0, a is on the right and b on the left. Away from this
regime they need not be edge-localized. Interface probabilities are
a[...,j]\*\*2 and b[...,j]\*\*2, not the combined BdG quasiparticle density.

energies are sorted ascending. isolated flags separation from the next
singular value at the requested tolerance, NOT good edge localization.
gap_resolved flags a gap above an estimated floating-point scale; it is
only a diagnostic, not a rigorous error bound. At an exact sweet spot
gap_resolved is false even though the isolated zero-mode pair is valid.

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L309-L335)

### pmm_tools.models.kitaev_chain.ChainMajoranas.a

*attribute* · *instance attribute*

```python
a: np.ndarray
```

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L332-L332)

### pmm_tools.models.kitaev_chain.ChainMajoranas.b

*attribute* · *instance attribute*

```python
b: np.ndarray
```

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L333-L333)

### pmm_tools.models.kitaev_chain.ChainMajoranas.energies

*attribute* · *instance attribute*

```python
energies: np.ndarray
```

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L331-L331)

### pmm_tools.models.kitaev_chain.ChainMajoranas.gap

*attribute* · *instance attribute*

```python
gap: np.ndarray
```

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L330-L330)

### pmm_tools.models.kitaev_chain.ChainMajoranas.gap_resolved

*attribute* · *instance attribute*

```python
gap_resolved: np.ndarray
```

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L335-L335)

### pmm_tools.models.kitaev_chain.ChainMajoranas.isolated

*attribute* · *instance attribute*

```python
isolated: np.ndarray
```

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L334-L334)

## pmm_tools.models.kitaev_chain.chain_basis_indices

*function*

```python
def chain_basis_indices(n_sites: int, parity: str) -> np.ndarray
```

Return isolated-chain Fock-basis indices of one parity.

**Parameters**

- `n_sites` (`int`) — Number of sites in the chain.
- `parity` (`str`) — Fermion-parity sector, `"even"` or `"odd"`.

**Returns**

- (`np.ndarray`) — Indices into the full chain occupation basis.

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L205-L222)

## pmm_tools.models.kitaev_chain.chain_ground_state

*function*

```python
def chain_ground_state(n_sites, parameters, parity)
```

Return an isolated-chain parity ground state in the full Fock basis.

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L225-L233)

## pmm_tools.models.kitaev_chain.chain_matrix_dict

*function* · *cached*

```python
def chain_matrix_dict(n_sites: int, parity: str | None = 'even')
```

Sparse isolated-chain terms with one-index mu_j,t_j,Delta_j and phase phi.

Pair creation has coefficient Delta_j\*exp(i\*phi). Select "even", "odd", or
None for the full occupation basis. No low-energy projection is made.

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L154-L179)

## pmm_tools.models.kitaev_chain.chain_operators

*function*

```python
def chain_operators(n_sites, *, phi=0.0)
```

Return full isolated-chain coefficient matrices and physical +/-1 parity.

Controls are named mu_1,...,mu_N,t_1,...,Delta_1,... and the phase is fixed.

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L197-L202)

## pmm_tools.models.kitaev_chain.chain_parameter_names

*function*

```python
def chain_parameter_names(n_sites: int) -> tuple[str, ...]
```

Return the parameter names for one isolated Kitaev chain.

**Parameters**

- `n_sites` (`int`) — Number of sites in the chain.

**Returns**

- (`tuple of str`) — Names of the onsite, hopping, pairing, and phase parameters.

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L81-L100)

## pmm_tools.models.kitaev_chain.low_energy_majoranas

*function*

```python
def low_energy_majoranas(block, *, rtol=1e-10, atol=0.0)
```

Return the lowest a/b Majoranas and gap=E_even-E_odd, using one SVD.

Fix the arbitrary common sign by making the largest-magnitude component
of a positive (first index wins ties); flip b by the same sign. This is
reproducible locally, not a continuous gauge along parameter sweeps.
At zero singular value the two vector signs are independently arbitrary.
Squared interface weights are unaffected by these gauge choices.

Warn when the lowest pair is not isolated: individual vectors then depend
on the chosen basis in the degenerate subspace, and a one-mode projection
is not justified. A single exact zero mode is allowed. For N=1 there is
no next mode. rtol/atol affect diagnostics only, never energies or vectors.

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L338-L380)

## pmm_tools.models.kitaev_chain.majorana_block

*function*

```python
def majorana_block(mu, hopping, pairing)
```

Build B with shape (..., N, N), accepting batches of chains.

mu has shape (..., N), N>=1. Real hopping/pairing broadcast to
(..., N-1); scalars specify uniform bonds. All energies use the same
caller-chosen unit. No assumption t=Delta or uniform gap is imposed.

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L245-L269)

## pmm_tools.models.kitaev_chain.majorana_matrix

*function*

```python
def majorana_matrix(block)
```

Expand B to the real antisymmetric 2N-by-2N matrix A.

Grouped ordering is (a_1,...,a_N,b_1,...,b_N), not interleaved sites.
Eigenvalues of i\*A are +/- excitation energies. Gap/mode calculations
can use B directly and need not allocate this larger matrix.

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L279-L291)

## pmm_tools.models.kitaev_chain.parity_gap

*function*

```python
def parity_gap(block)
```

Return E_even-E_odd without computing singular vectors.

The determinant sign is calibrated to the empty, even vacuum for positive
diagonal B, where the returned gap is negative. It includes the parity
of all modes, not just the lowest mode.
A singular B has zero gap. No tolerance clips small nonzero splittings.
Inputs may be batched. Near numerical singularity the sign and relative
gap accuracy are not certified; low_energy_majoranas provides a diagnostic.

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L294-L306)

## pmm_tools.models.kitaev_chain.symbolic_chain

*function*

```python
def symbolic_chain(n_sites)
```

Return (Hamiltonian, fermions, symbols) for a complex-phase Kitaev chain.

Ordered modes are c_0,...,c\_(N-1), with +mu_j\*n_j and real hopping t_j.
Pair creation has coefficient Delta_j\*exp(i\*phi_j), with real signed Delta_j.
Energies use any common unit; phases are radians. No projection is made.

[View source](https://gitlab.kwant-project.org/qt/pmm_tools/-/blob/e412d66507a554f455ef935b755fc39f28ab4e05/pmm_tools/models/kitaev_chain.py#L53-L78)
