def apply_measurement(self, op, input_register, moutputs): # Find the operator of the measurement instance we're running measurement = self.find_measurement(op['operator_id']) # Using the same principle as in apply_gate, obtain a matrix we can # run on all lines before = op['lines'][0] after = self.register_size - op['lines'][-1] - 1 matrix = TensorProduct(eye(2**before), measurement.matrix, eye(2**after)) # To contain the possible states the system could fall into after the # measurement states = [] # For each triple in the eigensystem # Eigenvalue, duplicity (not needed here), eigenvectors for val, dup, vecs in matrix.eigenvects(): # For each vector in the eigenvector basis for vec in vecs: # Obtain a projection operator P = x*x^T p = vec * vec.H # Probability of this outcome Pr = |phi>^T * P * |phi> # [0] because we want the value of a 1x1 matrix probability = (input_register.H * p * input_register)[0] # Don't need to consider this outcome anymore if it # won't happen if probability == 0: continue # Calculate the new register |phi'> = P*|phi> / sqrt(Pr) register = p * input_register / sqrt(probability) # Copy the measurement outputs as we're branching so don't # want to affect other branches moutputs = dict(moutputs) # Store the outcome that's just happened in the measurement # outputs moutputs[op['oid']] = val # Add the state tuple into states state = (register, probability, moutputs) states.append(state) return states
Omega_T_d = (pi / ((pi / (2 * omega))**2)) * F * T_d * F.adjoint() # %% Omega_T_d # %% Hs = I * hbar * omega * Matrix([[0, 1], [-1, 0]]) # %% J = TensorProduct(hbar * Omega_T_d, eye(2)) + TensorProduct(eye(2), Hs) # %% J # %% J.eigenvects() # %% [markdown] # ## Ordinary quantum theory # %% t = Symbol('t') t0 = Symbol('t_0') # %% exp(-I * Hs * (t - t0) / hbar) # %% exp(-I * Hs * (t - t0) / hbar) * Matrix([0, -I]) # %%