use crate::{
algorithms::time_evolution::{
trotter_evolve_state, first_order_trotter_step, second_order_trotter_step, TrotterOrder,
},
components::{
operator::Pauli,
pauli_string::{PauliString, SumOp},
state::State,
},
};
use num_complex::Complex;
#[test]
fn test_first_order_trotter_step_success() {
let ps1: PauliString = PauliString::new(1.0.into()).with_op(0, Pauli::X);
let ps2: PauliString = PauliString::new(1.0.into()).with_op(1, Pauli::Y);
let hamiltonian: SumOp = SumOp::new(vec![
ps1.clone(),
ps2.clone(),
]);
let initial_state = State::new_basis_n(2, 2).unwrap();
let dt = 0.1;
let result = first_order_trotter_step(&hamiltonian, &initial_state, dt).unwrap();
let mut expected_state = State::new_basis_n(2, 2).unwrap();
expected_state = ps1.apply_exp_factor(&expected_state, Complex::new(0.0, -dt)).unwrap();
expected_state = ps2.apply_exp_factor(&expected_state, Complex::new(0.0, -dt)).unwrap();
assert_eq!(result, expected_state, "First-order Trotter step failed");
}
#[test]
fn test_first_order_trotter_step_empty_hamiltonian_error() {
let hamiltonian: SumOp = SumOp::new(vec![]);
let initial_state = State::new_basis_n(2, 0).unwrap();
let dt = 0.1;
let result = first_order_trotter_step(&hamiltonian, &initial_state, dt);
assert!(result.is_err(), "Expected error for empty Hamiltonian");
}
#[test]
fn test_first_order_trotter_invalid_indices_error() {
let ps1: PauliString = PauliString::new(1.0.into()).with_op(0, Pauli::X);
let ps2: PauliString = PauliString::new(1.0.into()).with_op(2, Pauli::Y);
let hamiltonian: SumOp = SumOp::new(vec![ps1, ps2]);
let initial_state = State::new_basis_n(2, 2).unwrap();
let dt = 0.1;
let result = first_order_trotter_step(&hamiltonian, &initial_state, dt);
assert!(result.is_err(), "Expected error for invalid indices in Hamiltonian");
}
#[test]
fn test_second_order_trotter_step_success() {
let ps1: PauliString = PauliString::new(1.0.into()).with_op(0, Pauli::X);
let ps2: PauliString = PauliString::new(1.0.into()).with_op(1, Pauli::Y);
let hamiltonian: SumOp = SumOp::new(vec![
ps1.clone(),
ps2.clone(),
]);
let initial_state = State::new_basis_n(2, 2).unwrap();
let dt = 0.1;
let result = second_order_trotter_step(&hamiltonian, &initial_state, dt).unwrap();
let mut expected_state = State::new_basis_n(2, 2).unwrap();
expected_state = ps1.apply_exp_factor(&expected_state, Complex::new(0.0, -dt / 2.0)).unwrap();
expected_state = ps2.apply_exp_factor(&expected_state, Complex::new(0.0, -dt)).unwrap();
expected_state = ps1.apply_exp_factor(&expected_state, Complex::new(0.0, -dt / 2.0)).unwrap();
assert_eq!(result, expected_state, "Second-order Trotter step failed");
}
#[test]
fn test_second_order_trotter_step_empty_hamiltonian_error() {
let hamiltonian: SumOp = SumOp::new(vec![]);
let initial_state = State::new_basis_n(2, 0).unwrap();
let dt = 0.1;
let result = second_order_trotter_step(&hamiltonian, &initial_state, dt);
assert!(result.is_err(), "Expected error for empty Hamiltonian");
}
#[test]
fn test_second_order_trotter_invalid_indices_error() {
let ps1: PauliString = PauliString::new(1.0.into()).with_op(0, Pauli::X);
let ps2: PauliString = PauliString::new(1.0.into()).with_op(2, Pauli::Y);
let hamiltonian: SumOp = SumOp::new(vec![ps1, ps2]);
let initial_state = State::new_basis_n(2, 2).unwrap();
let dt = 0.1;
let result = second_order_trotter_step(&hamiltonian, &initial_state, dt);
assert!(result.is_err(), "Expected error for invalid indices in Hamiltonian");
}
#[test]
fn test_trotter_evolve_state_first_order_success() {
let ps1: PauliString = PauliString::new(1.0.into()).with_op(0, Pauli::X);
let ps2: PauliString = PauliString::new(1.0.into()).with_op(1, Pauli::Y);
let hamiltonian: SumOp = SumOp::new(vec![
ps1.clone(),
ps2.clone(),
]);
let initial_state = State::new_basis_n(2, 2).unwrap();
let dt = 0.1;
let result = trotter_evolve_state(&hamiltonian, &initial_state, dt, 3, TrotterOrder::First).unwrap();
let mut expected_state = State::new_basis_n(2, 2).unwrap();
for _ in 0..3 {
expected_state = ps1.apply_exp_factor(&expected_state, Complex::new(0.0, -dt)).unwrap();
expected_state = ps2.apply_exp_factor(&expected_state, Complex::new(0.0, -dt)).unwrap();
}
assert_eq!(result, expected_state, "Trotter evolution failed for first order");
}
#[test]
fn test_trotter_evolve_state_second_order_success() {
let ps1: PauliString = PauliString::new(1.0.into()).with_op(0, Pauli::X);
let ps2: PauliString = PauliString::new(1.0.into()).with_op(1, Pauli::Y);
let hamiltonian: SumOp = SumOp::new(vec![
ps1.clone(),
ps2.clone(),
]);
let initial_state = State::new_basis_n(2, 2).unwrap();
let dt = 0.1;
let result = trotter_evolve_state(&hamiltonian, &initial_state, dt, 3, TrotterOrder::Second).unwrap();
let mut expected_state = State::new_basis_n(2, 2).unwrap();
for _ in 0..3 {
expected_state = ps1.apply_exp_factor(&expected_state, Complex::new(0.0, -dt / 2.0)).unwrap();
expected_state = ps2.apply_exp_factor(&expected_state, Complex::new(0.0, -dt)).unwrap();
expected_state = ps1.apply_exp_factor(&expected_state, Complex::new(0.0, -dt / 2.0)).unwrap();
}
assert_eq!(result, expected_state, "Trotter evolution failed for second order");
}
#[test]
fn test_trotter_evolve_state_empty_hamiltonian_error() {
let hamiltonian: SumOp = SumOp::new(vec![]);
let initial_state = State::new_basis_n(2, 0).unwrap();
let dt = 0.1;
let result = trotter_evolve_state(&hamiltonian, &initial_state, dt, 3, TrotterOrder::First);
assert!(result.is_err(), "Expected error for empty Hamiltonian in Trotter evolution");
}
#[test]
fn test_trotter_evolve_state_invalid_indices_error() {
let ps1: PauliString = PauliString::new(1.0.into()).with_op(0, Pauli::X);
let ps2: PauliString = PauliString::new(1.0.into()).with_op(2, Pauli::Y);
let hamiltonian: SumOp = SumOp::new(vec![ps1, ps2]);
let initial_state = State::new_basis_n(2, 2).unwrap();
let dt = 0.1;
let result = trotter_evolve_state(&hamiltonian, &initial_state, dt, 3, TrotterOrder::First);
assert!(result.is_err(), "Expected error for invalid indices in Hamiltonian during Trotter evolution");
}