Skip to content

Commit 9ef8495

Browse files
authored
Constant energy bug (#107)
1 parent b5c2e43 commit 9ef8495

File tree

7 files changed

+66
-20
lines changed

7 files changed

+66
-20
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,13 @@ For more details, see the [interop documentation](https://ferrmion.readthedocs.i
5151

5252

5353
## Hamiltonians
54-
Functions to produce Hamiltonian templates and enumerated encodings are available in `ferrmion.hamiltonians`
54+
Arbitrary fermionic Hamiltonians can be built with the `FermionHamiltonian` class in `ferrmion.hamiltonians`. Additionally there are named functions for:
5555

5656
- Molecular Hamiltonian (Born-Oppenheimer Approximation)
5757
- Hubbard Hamiltonian (3D Square lattice)
5858

59+
See the [example notebook](https://ferrmion.readthedocs.io/en/latest/notebooks/encoding_hamiltonians.html#) for more information.
60+
5961
## Development
6062
For information on development, check out the project [documentation](https://ferrmion.readthedocs.io/en/latest/development.html).
6163

python/ferrmion/core.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def encode_standard(
7878
n_qubits: int,
7979
signatures: list[str],
8080
coeffs: list[np.ndarray],
81-
constant_energy:float,
81+
constant_energy: float,
8282
) -> dict: ...
8383
def encode(
8484
ipowers: npt.NDArray[np.uint8],

python/tests/test_hamiltonians.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def test_encode_standard_water_eigvals_equal_expected(encoding, water_data):
3434
e_nuc = water_data["constant_energy"]
3535

3636
qham = encode_standard(encoding, 14,14, ["+-","++--"], [ones, twos], e_nuc)
37+
assert np.isclose(qham["I"*14], -46.465600781952176)
3738

3839
ofop = QubitOperator()
3940
for k, v in qham.items():

python/tests/test_ternary_tree.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from ferrmion import FermionHamiltonian
12
import numpy as np
23
import pytest
34
import scipy as sp
@@ -17,6 +18,7 @@
1718
from openfermion.transforms import jordan_wigner
1819
from ferrmion.hamiltonians import molecular_hamiltonian
1920
from ferrmion.core import standard_symplectic_matrix
21+
from scipy.sparse.linalg import eigsh
2022

2123

2224
@pytest.fixture
@@ -573,3 +575,50 @@ def test_core_standard_encodings(n_modes,encoding,name):
573575
ci, cs = standard_symplectic_matrix(name,20)
574576
assert np.all(i==ci)
575577
assert np.all(s==cs)
578+
579+
@pytest.mark.parametrize("encoding", [JW, BK, ParityEncoding, JKMN])
580+
def test_encode_standard_water_eigvals_equal_expected(encoding, water_data):
581+
ones = water_data["ones"]
582+
twos = water_data["twos"]
583+
e_nuc = water_data["constant_energy"]
584+
585+
fham = FermionHamiltonian(terms = {"+-":ones,"++--":twos}, constant_energy=e_nuc)
586+
qham = encoding(fham.n_modes).encode(fham)
587+
assert np.isclose(qham["I"*14], -46.465600781952176)
588+
589+
ofop = QubitOperator()
590+
for k, v in qham.items():
591+
string = " ".join(
592+
[
593+
f"{char.upper()}{pos}" if char != "I" else ""
594+
for pos, char in enumerate(k)
595+
]
596+
)
597+
ofop+= QubitOperator(term=string, coefficient=v)
598+
print(expected:=water_data["eigvals"])
599+
diag, _ = eigsh(get_sparse_operator(ofop), k=2, which="SA")
600+
print(diag)
601+
assert np.allclose(np.sort(diag), np.sort(expected)[:2])
602+
603+
@pytest.mark.parametrize("encoding", [JW, BK, ParityEncoding, JKMN])
604+
def test_encode_standard_h2_eigvals_equal_expected(encoding, h2_mol_data_sets):
605+
ones = h2_mol_data_sets["ones"]
606+
twos = h2_mol_data_sets["twos"]
607+
e_nuc = h2_mol_data_sets["constant_energy"]
608+
n_modes = ones.shape[0]
609+
fham = FermionHamiltonian(terms = {"+-":ones,"++--":twos}, constant_energy=e_nuc)
610+
qham = encoding(n_modes).encode(fham)
611+
612+
ofop = QubitOperator()
613+
for k, v in qham.items():
614+
string = " ".join(
615+
[
616+
f"{char.upper()}{pos}" if char != "I" else ""
617+
for pos, char in enumerate(k)
618+
]
619+
)
620+
ofop+= QubitOperator(term=string, coefficient=v)
621+
print(expected:=h2_mol_data_sets["eigvals"])
622+
diag, _ = eigsh(get_sparse_operator(ofop), k=2*n_modes, which="SA")
623+
print(diag)
624+
assert np.allclose(np.sort(diag), np.sort(h2_mol_data_sets["eigvals"]))

src/encoding.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ impl Encode<&MajoranaSparse> for MajoranaEncoding {
269269
)
270270
.or_insert(c64(0., 0.)) += input.constant;
271271
// qham.into_iter().filter(|(_, v)| v.abs() > 1e-12).collect()
272-
qham.into_iter().filter(|(k, v)| v.norm() > 1e-16).collect()
272+
qham.into_iter().filter(|(_, v)| v.norm() > 1e-16).collect()
273273
}
274274
}
275275

src/lib.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use ::core::panic;
22
use log::{debug, info};
33
use numpy::{
4-
Complex64, IntoPyArray, PyArray1, PyArray2, PyArray3, PyReadonlyArray1, PyReadonlyArray2, PyReadonlyArrayDyn,
4+
Complex64, IntoPyArray, PyArray1, PyArray2, PyArray3, PyReadonlyArray1, PyReadonlyArray2,
5+
PyReadonlyArrayDyn,
56
};
67
use pyo3::types::{IntoPyDict, PyComplex, PyDict, PyInt, PyString};
78
use pyo3::{prelude::*, pymodule, Bound};
@@ -362,7 +363,8 @@ fn core(m: &Bound<'_, PyModule>) -> PyResult<()> {
362363
"Must have at least as many qubits as modes."
363364
);
364365

365-
let hamiltonian: MajoranaSparse = build_majorana_sparse(signatures, coeffs, constant_energy);
366+
let hamiltonian: MajoranaSparse =
367+
build_majorana_sparse(signatures, coeffs, constant_energy);
366368

367369
debug!("Got MSparse");
368370
debug!("Got Hamiltonian");
@@ -379,7 +381,7 @@ fn core(m: &Bound<'_, PyModule>) -> PyResult<()> {
379381
let encoding = tree.build_encoding(n_qubits).unwrap();
380382
debug!("Got encoding {:?}", encoding);
381383
debug!("Got encoding {:?}", encoding);
382-
384+
383385
let qham: QubitHamiltonian = encoding.encode(&hamiltonian);
384386

385387
debug!("Got qham");
@@ -453,7 +455,7 @@ fn core(m: &Bound<'_, PyModule>) -> PyResult<()> {
453455
debug!("Starting TOPPHATT");
454456
// let flatpack: TTFlatPack = node_map.extract::<TTFlatPack>()?;
455457
let hamiltonian: MajoranaSparse = build_majorana_sparse(signatures, coeffs, 0.);
456-
458+
457459
debug!("Got MSparse");
458460
debug!("Got Hamiltonian");
459461
let mut tree: TernaryTree = match encoding.as_str() {

src/operators.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
use crate::ternarytree::Edge;
22
use ndarray::Dimension;
3-
use tinyvec::{ArrayVec};
3+
use tinyvec::ArrayVec;
44
/*
55
Shared Types.
66
*/
77
use itertools::Itertools;
88
use log::debug;
99
use num_complex::{c64, ComplexFloat};
10-
use numpy::ndarray::{
11-
arr1, arr2, Array1, Array2, ArrayD, ArrayView1, Axis, IntoDimension, Zip,
12-
};
10+
use numpy::ndarray::{arr1, arr2, Array1, Array2, ArrayD, ArrayView1, Axis, IntoDimension, Zip};
1311
use numpy::Complex64;
1412
use std::collections::BTreeMap;
15-
use std::iter::{repeat_n};
13+
use std::iter::repeat_n;
1614
use std::{result::Result, str::FromStr};
1715

1816
const MAX_MAJORANAS: usize = 4;
@@ -598,23 +596,17 @@ impl MajoranaSparse {
598596
if coefficients.len() != indices.len() {
599597
return Err(MajoranaSparseError);
600598
};
601-
let identity_terms_constant: Complex64 = indices
602-
.iter()
603-
.zip(&coefficients)
604-
.filter(|&(ind, _)| ind == &ArrayVec::new())
605-
.map(|(_, coeff)| coeff)
606-
.sum();
607599

608600
let (i, c) = indices
609601
.iter()
610602
.zip(&coefficients)
611-
.filter(|&(&inds, &coeff)| (coeff != Complex64::ZERO) && (inds != ArrayVec::new()))
603+
.filter(|&(_, &coeff)| (coeff != Complex64::ZERO))
612604
.unzip();
613605

614606
Ok(Self {
615607
indices: i,
616608
coefficients: c,
617-
constant: constant + identity_terms_constant.norm(),
609+
constant: constant,
618610
})
619611
}
620612
}

0 commit comments

Comments
 (0)