use crate::{
components::{
operator::Pauli,
pauli_string::{PauliString, SumOp},
state::State,
},
errors::Error,
models::heisenberg::{heisenberg_1d, heisenberg_2d},
};
use num_complex::Complex;
#[test]
fn test_heisenberg_1d_success() {
let n = 4;
let jx = 1.0;
let jy = 2.0;
let jz = 3.0;
let h = 4.0;
let mu = 5.0;
let result = heisenberg_1d(n, jx, jy, jz, h, mu);
assert!(result.is_ok());
let result = result.unwrap();
assert_eq!(result.terms.len(), 16);
let expected_terms = vec![
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(0, Pauli::Z),
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(1, Pauli::Z),
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(2, Pauli::Z),
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(3, Pauli::Z),
-0.5 * jx
* PauliString::new(Complex::new(1.0, 0.0))
.with_op(0, Pauli::X)
.with_op(1, Pauli::X),
-0.5 * jx
* PauliString::new(Complex::new(1.0, 0.0))
.with_op(1, Pauli::X)
.with_op(2, Pauli::X),
-0.5 * jx
* PauliString::new(Complex::new(1.0, 0.0))
.with_op(2, Pauli::X)
.with_op(3, Pauli::X),
-0.5 * jx
* PauliString::new(Complex::new(1.0, 0.0))
.with_op(3, Pauli::X)
.with_op(0, Pauli::X),
-0.5 * jy
* PauliString::new(Complex::new(1.0, 0.0))
.with_op(0, Pauli::Y)
.with_op(1, Pauli::Y),
-0.5 * jy
* PauliString::new(Complex::new(1.0, 0.0))
.with_op(1, Pauli::Y)
.with_op(2, Pauli::Y),
-0.5 * jy
* PauliString::new(Complex::new(1.0, 0.0))
.with_op(2, Pauli::Y)
.with_op(3, Pauli::Y),
-0.5 * jy
* PauliString::new(Complex::new(1.0, 0.0))
.with_op(3, Pauli::Y)
.with_op(0, Pauli::Y),
-0.5 * jz
* PauliString::new(Complex::new(1.0, 0.0))
.with_op(0, Pauli::Z)
.with_op(1, Pauli::Z),
-0.5 * jz
* PauliString::new(Complex::new(1.0, 0.0))
.with_op(1, Pauli::Z)
.with_op(2, Pauli::Z),
-0.5 * jz
* PauliString::new(Complex::new(1.0, 0.0))
.with_op(2, Pauli::Z)
.with_op(3, Pauli::Z),
-0.5 * jz
* PauliString::new(Complex::new(1.0, 0.0))
.with_op(3, Pauli::Z)
.with_op(0, Pauli::Z),
];
let state = State::new_basis_n(4, 6).unwrap();
let result_state = result.apply(&state).unwrap();
let expected_state = SumOp::new(expected_terms).apply(&state).unwrap();
assert_eq!(result_state, expected_state);
}
#[test]
fn test_heisenberg_1d_error() {
let n = 1; let jx = 1.0;
let jy = 2.0;
let jz = 3.0;
let h = 4.0;
let mu = 5.0;
let result = heisenberg_1d(n, jx, jy, jz, h, mu);
assert_eq!(result.unwrap_err(), Error::InvalidNumberOfInputs(1, 2));
}
#[test]
fn test_heisenberg_2d_success() {
let n = 3;
let m = 3;
let jx = 1.0;
let jy = 2.0;
let jz = 3.0;
let h = 4.0;
let mu = 5.0;
let result: Result<SumOp, Error> = heisenberg_2d(n, m, jx, jy, jz, h, mu);
assert!(result.is_ok());
let result = result.unwrap();
assert_eq!(result.terms.len(), 63);
let expected_terms = vec![
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(0, Pauli::Z),
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(1, Pauli::Z),
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(2, Pauli::Z),
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(3, Pauli::Z),
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(4, Pauli::Z),
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(5, Pauli::Z),
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(6, Pauli::Z),
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(7, Pauli::Z),
-0.5 * h * mu * PauliString::new(Complex::new(1.0, 0.0)).with_op(8, Pauli::Z),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(0, Pauli::X).with_op(1, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(1, Pauli::X).with_op(2, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(2, Pauli::X).with_op(0, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(3, Pauli::X).with_op(4, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(4, Pauli::X).with_op(5, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(5, Pauli::X).with_op(3, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(6, Pauli::X).with_op(7, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(7, Pauli::X).with_op(8, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(8, Pauli::X).with_op(6, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(0, Pauli::X).with_op(3, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(3, Pauli::X).with_op(6, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(6, Pauli::X).with_op(0, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(1, Pauli::X).with_op(4, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(4, Pauli::X).with_op(7, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(7, Pauli::X).with_op(1, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(2, Pauli::X).with_op(5, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(5, Pauli::X).with_op(8, Pauli::X),
-0.5 * jx * PauliString::new(Complex::new(1.0, 0.0)).with_op(8, Pauli::X).with_op(2, Pauli::X),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(0, Pauli::Y).with_op(1, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(1, Pauli::Y).with_op(2, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(2, Pauli::Y).with_op(0, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(3, Pauli::Y).with_op(4, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(4, Pauli::Y).with_op(5, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(5, Pauli::Y).with_op(3, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(6, Pauli::Y).with_op(7, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(7, Pauli::Y).with_op(8, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(8, Pauli::Y).with_op(6, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(0, Pauli::Y).with_op(3, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(3, Pauli::Y).with_op(6, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(6, Pauli::Y).with_op(0, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(1, Pauli::Y).with_op(4, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(4, Pauli::Y).with_op(7, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(7, Pauli::Y).with_op(1, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(2, Pauli::Y).with_op(5, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(5, Pauli::Y).with_op(8, Pauli::Y),
-0.5 * jy * PauliString::new(Complex::new(1.0, 0.0)).with_op(8, Pauli::Y).with_op(2, Pauli::Y),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(0, Pauli::Z).with_op(1, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(1, Pauli::Z).with_op(2, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(2, Pauli::Z).with_op(0, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(3, Pauli::Z).with_op(4, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(4, Pauli::Z).with_op(5, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(5, Pauli::Z).with_op(3, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(6, Pauli::Z).with_op(7, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(7, Pauli::Z).with_op(8, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(8, Pauli::Z).with_op(6, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(0, Pauli::Z).with_op(3, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(3, Pauli::Z).with_op(6, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(6, Pauli::Z).with_op(0, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(1, Pauli::Z).with_op(4, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(4, Pauli::Z).with_op(7, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(7, Pauli::Z).with_op(1, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(2, Pauli::Z).with_op(5, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(5, Pauli::Z).with_op(8, Pauli::Z),
-0.5 * jz * PauliString::new(Complex::new(1.0, 0.0)).with_op(8, Pauli::Z).with_op(2, Pauli::Z),
];
let state = State::new_basis_n(9, 255).unwrap();
let result_state = result.apply(&state).unwrap();
let expected_state = SumOp::new(expected_terms).apply(&state).unwrap();
assert_eq!(result_state, expected_state);
}
#[test]
fn test_heisenberg_2d_error() {
let n = 1; let m = 2;
let jx = 1.0;
let jy = 2.0;
let jz = 3.0;
let h = 4.0;
let mu = 5.0;
let result: Result<SumOp, Error> = heisenberg_2d(n, m, jx, jy, jz, h, mu);
assert_eq!(result.unwrap_err(), Error::InvalidNumberOfInputs(1, 2));
let new_n = 2;
let new_m = 1; let result2: Result<SumOp, Error> = heisenberg_2d(new_n, new_m, jx, jy, jz, h, mu);
assert_eq!(result2.unwrap_err(), Error::InvalidNumberOfInputs(1, 2));
}