use crate::{
components::{
operator::Pauli,
pauli_string::{PauliString, SumOp},
state::State,
},
errors::Error,
models::ising::{ising_1d, ising_1d_uniform, ising_2d, ising_2d_uniform},
};
use num_complex::Complex;
#[test]
fn test_ising_1d_success() {
let h: [f64; 3] = [1.0, 2.0, 3.0];
let j: [f64; 3] = [0.5, 1.0, 1.5];
let m: f64 = 0.1;
let result: SumOp = ising_1d(h, j, m).unwrap();
assert_eq!(result.terms.len(), 6);
let expected_terms: Vec<PauliString> = vec![
m * h[0] * PauliString::new(Complex::new(-1.0, 0.0)).with_op(0, Pauli::Z),
m * h[1] * PauliString::new(Complex::new(-1.0, 0.0)).with_op(1, Pauli::Z),
m * h[2] * PauliString::new(Complex::new(-1.0, 0.0)).with_op(2, Pauli::Z),
j[0] * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(0, Pauli::Z)
.with_op(1, Pauli::Z),
j[1] * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(1, Pauli::Z)
.with_op(2, Pauli::Z),
j[2] * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(2, Pauli::Z)
.with_op(0, Pauli::Z),
];
let state: State = State::new_basis_n(3, 6).unwrap();
let result_state: State = result.apply(&state).unwrap();
let expected_state: State = SumOp::new(expected_terms).apply(&state).unwrap();
assert_eq!(result_state, expected_state);
}
#[test]
fn test_ising_1d_error() {
let h: [f64; 1] = [1.0];
let j: [f64; 1] = [0.5];
let m: f64 = 0.1;
let result: Result<SumOp, Error> = ising_1d(h, j, m);
assert_eq!(result.unwrap_err(), Error::InvalidNumberOfInputs(1, 2));
}
#[test]
fn test_ising_1d_uniform_success() {
let h: f64 = 1.0;
let j: f64 = 2.0;
let m: f64 = 0.1;
let result: SumOp = ising_1d_uniform(3, h, j, m).unwrap();
assert_eq!(result.terms.len(), 6);
let expected_terms: Vec<PauliString> = vec![
m * h * PauliString::new(Complex::new(-1.0, 0.0)).with_op(0, Pauli::Z),
m * h * PauliString::new(Complex::new(-1.0, 0.0)).with_op(1, Pauli::Z),
m * h * PauliString::new(Complex::new(-1.0, 0.0)).with_op(2, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(0, Pauli::Z)
.with_op(1, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(1, Pauli::Z)
.with_op(2, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(2, Pauli::Z)
.with_op(0, Pauli::Z),
];
let state: State = State::new_basis_n(3, 6).unwrap();
let result_state: State = result.apply(&state).unwrap();
let expected_state: State = SumOp::new(expected_terms).apply(&state).unwrap();
assert_eq!(result_state, expected_state);
}
#[test]
fn test_ising_1d_uniform_error() {
let h: f64 = 1.0;
let j: f64 = 2.0;
let m: f64 = 0.1;
let result: Result<SumOp, Error> = ising_1d_uniform(1, h, j, m);
assert_eq!(result.unwrap_err(), Error::InvalidNumberOfInputs(1, 2));
}
#[test]
fn test_ising_2d_success() {
let h: [[f64; 3]; 3] = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]];
let j: [[[f64; 2]; 3]; 3] = [
[[0.5, 1.0], [1.5, 2.0], [2.5, 3.0]],
[[3.5, 4.0], [4.5, 5.0], [5.5, 6.0]],
[[6.5, 7.0], [7.5, 8.0], [8.5, 9.0]],
];
let m: f64 = 0.1;
let result: SumOp = ising_2d(h, j, m).unwrap();
assert_eq!(result.terms.len(), 27);
let expected_terms: Vec<PauliString> = vec![
PauliString::new(Complex::new(-0.1 * 1.0, 0.0)).with_op(0, Pauli::Z), PauliString::new(Complex::new(-0.5, 0.0))
.with_op(0, Pauli::Z)
.with_op(3, Pauli::Z), PauliString::new(Complex::new(-1.0, 0.0))
.with_op(0, Pauli::Z)
.with_op(1, Pauli::Z), PauliString::new(Complex::new(-0.1 * 2.0, 0.0)).with_op(1, Pauli::Z), PauliString::new(Complex::new(-1.5, 0.0))
.with_op(1, Pauli::Z)
.with_op(4, Pauli::Z), PauliString::new(Complex::new(-2.0, 0.0))
.with_op(1, Pauli::Z)
.with_op(2, Pauli::Z), PauliString::new(Complex::new(-0.1 * 3.0, 0.0)).with_op(2, Pauli::Z), PauliString::new(Complex::new(-2.5, 0.0))
.with_op(2, Pauli::Z)
.with_op(5, Pauli::Z), PauliString::new(Complex::new(-3.0, 0.0))
.with_op(2, Pauli::Z)
.with_op(0, Pauli::Z), PauliString::new(Complex::new(-0.1 * 4.0, 0.0)).with_op(3, Pauli::Z), PauliString::new(Complex::new(-3.5, 0.0))
.with_op(3, Pauli::Z)
.with_op(6, Pauli::Z), PauliString::new(Complex::new(-4.0, 0.0))
.with_op(3, Pauli::Z)
.with_op(4, Pauli::Z), PauliString::new(Complex::new(-0.1 * 5.0, 0.0)).with_op(4, Pauli::Z), PauliString::new(Complex::new(-4.5, 0.0))
.with_op(4, Pauli::Z)
.with_op(7, Pauli::Z), PauliString::new(Complex::new(-5.0, 0.0))
.with_op(4, Pauli::Z)
.with_op(5, Pauli::Z), PauliString::new(Complex::new(-0.1 * 6.0, 0.0)).with_op(5, Pauli::Z), PauliString::new(Complex::new(-5.5, 0.0))
.with_op(5, Pauli::Z)
.with_op(8, Pauli::Z), PauliString::new(Complex::new(-6.0, 0.0))
.with_op(5, Pauli::Z)
.with_op(3, Pauli::Z), PauliString::new(Complex::new(-0.1 * 7.0, 0.0)).with_op(6, Pauli::Z), PauliString::new(Complex::new(-6.5, 0.0))
.with_op(6, Pauli::Z)
.with_op(0, Pauli::Z), PauliString::new(Complex::new(-7.0, 0.0))
.with_op(6, Pauli::Z)
.with_op(7, Pauli::Z), PauliString::new(Complex::new(-0.1 * 8.0, 0.0)).with_op(7, Pauli::Z), PauliString::new(Complex::new(-7.5, 0.0))
.with_op(7, Pauli::Z)
.with_op(1, Pauli::Z), PauliString::new(Complex::new(-8.0, 0.0))
.with_op(7, Pauli::Z)
.with_op(8, Pauli::Z), PauliString::new(Complex::new(-0.1 * 9.0, 0.0)).with_op(8, Pauli::Z), PauliString::new(Complex::new(-8.5, 0.0))
.with_op(8, Pauli::Z)
.with_op(2, Pauli::Z), PauliString::new(Complex::new(-9.0, 0.0))
.with_op(8, Pauli::Z)
.with_op(6, Pauli::Z), ];
let state: State = State::new_basis_n(9, 511).unwrap();
let result_state: State = result.apply(&state).unwrap();
let expected_state: State = SumOp::new(expected_terms).apply(&state).unwrap();
assert_eq!(result_state, expected_state);
}
#[test]
fn test_ising_2d_error() {
let h: [[f64; 1]; 1] = [[1.0]];
let j: [[[f64; 2]; 1]; 1] = [[[0.5, 1.0]]];
let m: f64 = 0.1;
let result: Result<SumOp, Error> = ising_2d(h, j, m);
assert_eq!(result.unwrap_err(), Error::InvalidNumberOfInputs(1, 2));
}
#[test]
fn test_ising_2d_uniform_success() {
let h: f64 = 1.0;
let j: f64 = 2.0;
let m: f64 = 0.1;
let result: SumOp = ising_2d_uniform(3, 3, h, j, m).unwrap();
assert_eq!(result.terms.len(), 27);
let expected_terms: Vec<PauliString> = vec![
m * h * PauliString::new(Complex::new(-1.0, 0.0)).with_op(0, Pauli::Z),
m * h * PauliString::new(Complex::new(-1.0, 0.0)).with_op(1, Pauli::Z),
m * h * PauliString::new(Complex::new(-1.0, 0.0)).with_op(2, Pauli::Z),
m * h * PauliString::new(Complex::new(-1.0, 0.0)).with_op(3, Pauli::Z),
m * h * PauliString::new(Complex::new(-1.0, 0.0)).with_op(4, Pauli::Z),
m * h * PauliString::new(Complex::new(-1.0, 0.0)).with_op(5, Pauli::Z),
m * h * PauliString::new(Complex::new(-1.0, 0.0)).with_op(6, Pauli::Z),
m * h * PauliString::new(Complex::new(-1.0, 0.0)).with_op(7, Pauli::Z),
m * h * PauliString::new(Complex::new(-1.0, 0.0)).with_op(8, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(0, Pauli::Z)
.with_op(3, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(1, Pauli::Z)
.with_op(4, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(2, Pauli::Z)
.with_op(5, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(3, Pauli::Z)
.with_op(6, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(4, Pauli::Z)
.with_op(7, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(5, Pauli::Z)
.with_op(8, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(6, Pauli::Z)
.with_op(0, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(7, Pauli::Z)
.with_op(1, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(8, Pauli::Z)
.with_op(2, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(0, Pauli::Z)
.with_op(1, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(1, Pauli::Z)
.with_op(2, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(2, Pauli::Z)
.with_op(0, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(3, Pauli::Z)
.with_op(4, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(4, Pauli::Z)
.with_op(5, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(5, Pauli::Z)
.with_op(3, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(6, Pauli::Z)
.with_op(7, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(7, Pauli::Z)
.with_op(8, Pauli::Z),
j * PauliString::new(Complex::new(-1.0, 0.0))
.with_op(8, Pauli::Z)
.with_op(6, Pauli::Z),
];
let state: State = State::new_basis_n(9, 255).unwrap();
let result_state: Vec<f64> = result
.apply(&state)
.unwrap()
.state_vector
.iter()
.map(|c| f64::round(c.re * 10000.0) / 10000.0)
.collect();
let expected_state: Vec<f64> = SumOp::new(expected_terms)
.apply(&state)
.unwrap()
.state_vector
.iter()
.map(|c| f64::round(c.re * 10000.0) / 10000.0)
.collect();
assert_eq!(result_state, expected_state);
}
#[test]
fn test_ising_2d_uniform_error() {
let h: f64 = 1.0;
let j: f64 = 2.0;
let m: f64 = 0.1;
let result: Result<SumOp, Error> = ising_2d_uniform(1, 1, h, j, m);
assert_eq!(result.unwrap_err(), Error::InvalidNumberOfInputs(1, 2));
}