def vec_commutator(A: Array): r"""Linear algebraic vectorization of the linear map X -> [A, X] in column-stacking convention. In column-stacking convention we have .. math:: vec(ABC) = C^T \otimes A vec(B), so for the commutator we have .. math:: [A, \cdot] = A \cdot - \cdot A \mapsto id \otimes A - A^T \otimes id Note: this function is also "vectorized" in the programming sense. Args: A: Either a 2d array representing the matrix A described above, or a 3d array representing a list of matrices. Returns: Array: vectorized version of the map. """ iden = Array(np.eye(A.shape[-1])) axes = list(range(A.ndim)) axes[-1] = axes[-2] axes[-2] += 1 return np.kron(iden, A) - np.kron(A.transpose(axes), iden)
def test_operators_into_frame_basis_with_cutoff(self): """Test function for construction of operators with cutoff.""" # cutoff test frame_op = -1j * np.pi * Array([1.0, -1.0]) operators = Array([self.X.data, self.Y.data, self.Z.data]) carrier_freqs = Array([1.0, 2.0, 3.0]) cutoff_freq = 3.0 frame = Frame(frame_op) cutoff_mat = Array([[[1, 1], [1, 1]], [[1, 0], [1, 1]], [[0, 0], [1, 0]]]) ops_w_cutoff, ops_w_conj_cutoff = frame.operators_into_frame_basis_with_cutoff( operators, cutoff_freq=cutoff_freq, carrier_freqs=carrier_freqs) ops_w_cutoff_expect = cutoff_mat * operators ops_w_conj_cutoff_expect = cutoff_mat.transpose([0, 2, 1]) * operators self.assertAllClose(ops_w_cutoff, ops_w_cutoff_expect) self.assertAllClose(ops_w_conj_cutoff, ops_w_conj_cutoff_expect) # same test with lower cutoff cutoff_freq = 2.0 cutoff_mat = Array([[[1, 0], [1, 1]], [[0, 0], [1, 0]], [[0, 0], [0, 0]]]) ops_w_cutoff, ops_w_conj_cutoff = frame.operators_into_frame_basis_with_cutoff( operators, cutoff_freq=cutoff_freq, carrier_freqs=carrier_freqs) ops_w_cutoff_expect = cutoff_mat * operators ops_w_conj_cutoff_expect = cutoff_mat.transpose([0, 2, 1]) * operators self.assertAllClose(ops_w_cutoff, ops_w_cutoff_expect) self.assertAllClose(ops_w_conj_cutoff, ops_w_conj_cutoff_expect)
def test_lindblad_lmult_pseudorandom(self): """Test lmult of Lindblad OperatorModel with structureless pseudorandom model parameters. """ rng = np.random.default_rng(9848) dim = 10 num_ham = 4 num_diss = 3 b = 1.0 # bound on size of random terms # generate random hamiltonian randoperators = rng.uniform(low=-b, high=b, size=( num_ham, dim, dim)) + 1j * rng.uniform(low=-b, high=b, size=(num_ham, dim, dim)) rand_ham_ops = Array(randoperators + randoperators.conj().transpose([0, 2, 1])) # generate random hamiltonian coefficients rand_ham_coeffs = rng.uniform(low=-b, high=b, size=( num_ham)) + 1j * rng.uniform(low=-b, high=b, size=(num_ham)) rand_ham_carriers = Array(rng.uniform(low=-b, high=b, size=(num_ham))) rand_ham_phases = Array(rng.uniform(low=-b, high=b, size=(num_ham))) ham_sigs = VectorSignal(lambda t: rand_ham_coeffs, rand_ham_carriers, rand_ham_phases) # generate random dissipators rand_diss = Array( rng.uniform(low=-b, high=b, size=(num_diss, dim, dim)) + 1j * rng.uniform(low=-b, high=b, size=(num_diss, dim, dim))) # random dissipator coefficients rand_diss_coeffs = rng.uniform(low=-b, high=b, size=( num_diss)) + 1j * rng.uniform(low=-b, high=b, size=(num_diss)) rand_diss_carriers = Array(rng.uniform(low=-b, high=b, size=(num_diss))) rand_diss_phases = Array(rng.uniform(low=-b, high=b, size=(num_diss))) diss_sigs = VectorSignal(lambda t: rand_diss_coeffs, rand_diss_carriers, rand_diss_phases) # random anti-hermitian frame operator rand_op = rng.uniform(low=-b, high=b, size=( dim, dim)) + 1j * rng.uniform(low=-b, high=b, size=(dim, dim)) frame_op = Array(rand_op - rand_op.conj().transpose()) lindblad_frame_op = np.kron(Array(np.eye(dim)), frame_op) - np.kron( frame_op.transpose(), Array(np.eye(dim))) # construct model hamiltonian = HamiltonianModel(operators=rand_ham_ops, signals=ham_sigs) lindblad_model = LindbladModel.from_hamiltonian( hamiltonian=hamiltonian, noise_operators=rand_diss, noise_signals=diss_sigs) lindblad_model.frame = lindblad_frame_op A = Array( rng.uniform(low=-b, high=b, size=(dim, dim)) + 1j * rng.uniform(low=-b, high=b, size=(dim, dim))) t = rng.uniform(low=-b, high=b) value = lindblad_model.lmult(t, A.flatten(order="F")) ham_coeffs = np.real(rand_ham_coeffs * np.exp(1j * 2 * np.pi * rand_ham_carriers * t + 1j * rand_ham_phases)) ham = np.tensordot(ham_coeffs, rand_ham_ops, axes=1) diss_coeffs = np.real(rand_diss_coeffs * np.exp(1j * 2 * np.pi * rand_diss_carriers * t + 1j * rand_diss_phases)) expected = self._evaluate_lindblad_rhs(A, ham, rand_diss, diss_coeffs, frame_op, t) self.assertAllClose(expected, value.reshape(dim, dim, order="F"))