Skip to content

Commit d198154

Browse files
add some docstrs
1 parent 12e43bf commit d198154

File tree

2 files changed

+96
-16
lines changed

2 files changed

+96
-16
lines changed

tensorcircuit/experimental.py

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ def adaptive_vmap(
2020
static_argnums: Optional[Union[int, Sequence[int]]] = None,
2121
chunk_size: Optional[int] = None,
2222
) -> Callable[..., Any]:
23+
"""
24+
Vectorized map with adaptive chunking for memory efficiency.
25+
26+
:param f: Function to be vectorized
27+
:param vectorized_argnums: Arguments to be vectorized over
28+
:param static_argnums: Arguments that remain static during vectorization
29+
:param chunk_size: Size of chunks for batch processing, None means no chunking
30+
(naive vmap)
31+
:return: Vectorized function
32+
"""
2333
if chunk_size is None:
2434
return backend.vmap(f, vectorized_argnums) # type: ignore
2535

@@ -94,6 +104,29 @@ def qng(
94104
postprocess: Optional[str] = "qng",
95105
mode: str = "fwd",
96106
) -> Callable[..., Tensor]:
107+
"""
108+
Compute quantum natural gradient for quantum circuit optimization.
109+
110+
:param f: Function that takes parameters and returns quantum state
111+
:param kernel: Type of kernel to use ("qng" or "dynamics"), the former has the second term
112+
:param postprocess: Post-processing method ("qng" or None)
113+
:param mode: Mode of differentiation ("fwd" or "rev")
114+
:return: Function computing QNG matrix
115+
116+
:Example:
117+
118+
>>> import tensorcircuit as tc
119+
>>> def ansatz(params):
120+
... c = tc.Circuit(2)
121+
... c.rx(0, theta=params[0])
122+
... c.ry(1, theta=params[1])
123+
... return c.state()
124+
>>> qng_fn = tc.experimental.qng(ansatz)
125+
>>> params = tc.array_to_tensor([0.5, 0.8])
126+
>>> qng_matrix = qng_fn(params)
127+
>>> print(qng_matrix.shape) # (2, 2)
128+
"""
129+
97130
# for both qng and qng2 calculation, we highly recommended complex-dtype but real valued inputs
98131
def wrapper(params: Tensor, **kws: Any) -> Tensor:
99132
params = backend.cast(params, dtype=dtypestr) # R->C protection
@@ -406,19 +439,46 @@ def hamiltonian_evol(
406439
callback: Optional[Callable[..., Any]] = None,
407440
) -> Tensor:
408441
"""
409-
Fast implementation of static full Hamiltonian evolution
410-
(default as imaginary time)
442+
Fast implementation of time independent Hamiltonian evolution using eigendecomposition.
443+
By default, performs imaginary time evolution.
411444
412-
:param tlist: _description_
445+
:param tlist: Time points for evolution
413446
:type tlist: Tensor
414-
:param h: _description_
447+
:param h: Time-independent Hamiltonian matrix
415448
:type h: Tensor
416-
:param psi0: _description_
449+
:param psi0: Initial state vector
417450
:type psi0: Tensor
418-
:param callback: _description_, defaults to None
451+
:param callback: Optional function to process state at each time point
419452
:type callback: Optional[Callable[..., Any]], optional
420-
:return: Tensor
421-
:rtype: result dynamics on ``tlist``
453+
:return: Evolution results at each time point. If callback is None, returns state vectors;
454+
otherwise returns callback results
455+
:rtype: Tensor
456+
457+
:Example:
458+
459+
>>> import tensorcircuit as tc
460+
>>> import numpy as np
461+
>>> # Define a simple 2-qubit Hamiltonian
462+
>>> h = tc.array_to_tensor([
463+
... [1.0, 0.0, 0.0, 0.0],
464+
... [0.0, -1.0, 2.0, 0.0],
465+
... [0.0, 2.0, -1.0, 0.0],
466+
... [0.0, 0.0, 0.0, 1.0]
467+
... ])
468+
>>> # Initial state |00⟩
469+
>>> psi0 = tc.array_to_tensor([1.0, 0.0, 0.0, 0.0])
470+
>>> # Evolution times
471+
>>> times = tc.array_to_tensor([0.0, 0.5, 1.0])
472+
>>> # Evolve and get states
473+
>>> states = tc.experimental.hamiltonian_evol(times, h, psi0)
474+
>>> print(states.shape) # (3, 4)
475+
476+
477+
Note:
478+
1. The Hamiltonian must be time-independent
479+
2. For time-dependent Hamiltonians, use ``evol_local`` or ``evol_global`` instead
480+
3. The evolution is performed in imaginary time by default (factor -t in exponential)
481+
4. The state is automatically normalized at each time point
422482
"""
423483
es, u = backend.eigh(h)
424484
utpsi0 = backend.reshape(

tensorcircuit/fgs.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,34 @@ def onehot_matrix(i: int, j: int, N: int) -> Tensor:
3434

3535
class FGSSimulator:
3636
r"""
37-
main refs: https://arxiv.org/pdf/2306.16595.pdf,
38-
https://arxiv.org/abs/2209.06945,
39-
https://scipost.org/SciPostPhysLectNotes.54/pdf
40-
41-
convention:
42-
for Hamiltonian (c^dagger, c)H(c, c^\dagger)
43-
for correlation <(c, c^\dagger)(c^\dagger, c)>
44-
c' = \alpha^\dagger (c, c^\dagger)
37+
Fermion Gaussian State (FGS) simulator for efficient simulation of non-interacting fermionic systems.
38+
39+
This simulator implements methods for:
40+
1. State initialization and evolution
41+
2. Correlation matrix calculations
42+
3. Entanglement measures
43+
4. Out-of-time-ordered correlators (OTOC)
44+
5. Post-selection and measurements
45+
46+
Main references:
47+
- Gaussian formalism: https://arxiv.org/pdf/2306.16595.pdf
48+
- Quantum circuits: https://arxiv.org/abs/2209.06945
49+
- Theory background: https://scipost.org/SciPostPhysLectNotes.54/pdf
50+
51+
Conventions:
52+
- Hamiltonian form: (c^dagger, c)H(c, c^\dagger)
53+
- Correlation form: <(c, c^\dagger)(c^\dagger, c)>
54+
- Bogoliubov transformation: c' = \alpha^\dagger (c, c^\dagger)
55+
56+
:Example:
57+
58+
>>> import tensorcircuit as tc
59+
>>> # Initialize a 4-site system with sites 0 and 2 occupied
60+
>>> sim = tc.FGSSimulator(L=4, filled=[0, 2])
61+
>>> # Apply hopping between sites 0 and 1
62+
>>> sim.evol_hp(i=0, j=1, chi=1.0)
63+
>>> # Calculate entanglement entropy for first two sites
64+
>>> entropy = sim.entropy([2, 3])
4565
"""
4666

4767
def __init__(

0 commit comments

Comments
 (0)