def get_matrix_and_derivatives(self, x): """Produces the circuit matrix and partials for this gate.""" alpha, l = self.partition_input(x) l = utils.softmax(l, 10) Hv = [] stride = self.working_sigmav.shape[1] for i in range(self.working_sigmav.shape[0]): Hv.append( utils.dot_product(alpha[i * stride:(i + 1) * stride], self.working_sigmav[i])) H = utils.dot_product(l, Hv) # Partials of H with respect to function variables alpha_der = np.array([ l[i] * self.working_sigmav[i] for i in range(self.get_location_count()) ]) alpha_der = alpha_der.reshape( (-1, alpha_der.shape[-2], alpha_der.shape[-1])) # Partials of H with respect to location variables L = np.tile(l, (self.working_sigmav.shape[0], 1)) L = np.identity(self.working_sigmav.shape[0]) - L L = 10 * (np.diag(l) @ L) l_der = np.array([utils.dot_product(Lr, Hv) for Lr in L]) _, dav = utils.dexpmv(H, alpha_der) _, dlv = utils.dexpmv(H, l_der) return sp.linalg.expm(H), np.concatenate([dav, dlv])
def get_matrix ( self, x ): """Produces the circuit matrix for this gate.""" alpha, l = self.partition_input( x ) l = utils.softmax( l, 10 ) H = utils.dot_product( alpha, self.sigmav ) U = sp.linalg.expm( H ) P = utils.dot_product( l, self.working_perms ) return P @ np.kron( U, self.I ) @ P.T
def get_matrix(self, x): """Produces the circuit matrix for this gate.""" alpha, l = self.partition_input(x) l = utils.softmax(l, 10) Hv = [] stride = self.working_sigmav.shape[1] for i in range(self.working_sigmav.shape[0]): Hv.append( utils.dot_product(alpha[i * stride:(i + 1) * stride], self.working_sigmav[i])) H = utils.dot_product(l, Hv) return sp.linalg.expm(H)
def get_fixed_matrix(self, x): """Returns the fixed-location version of this gate's matrix.""" alpha, l = self.partition_input(x) fixed_location = np.argmax(l) H = utils.dot_product(self.get_function_values(x, True), self.working_sigmav[fixed_location]) return sp.linalg.expm(H)
def get_gate_matrix(self, x): """Produces the matrix for this gate on its own.""" sigma = pauli.get_norder_paulis(self.gate_size) sigma = self.Hcoef * sigma alpha = self.get_function_values(x, True) H = utils.dot_product(alpha, sigma) return sp.linalg.expm(H)
def test_is_unitary1(self): paulis = get_norder_paulis(3) for i in range(10): alpha = np.random.random(4**3) U = sp.linalg.expm(1j * dot_product(alpha, paulis)) self.assertTrue(is_unitary(U, tol=1e-14))
def get_fixed_matrix ( self, x ): """Returns the fixed-location version of this gate's matrix.""" alpha, l = self.partition_input( x ) fixed_location = np.argmax( l ) H = utils.dot_product( alpha, self.sigmav ) U = sp.linalg.expm( H ) P = self.working_perms[ fixed_location ] return P @ np.kron( U, self.I ) @ P.T
def get_matrix_and_derivatives ( self, x ): """Produces the circuit matrix and partials for this gate.""" alpha, l = self.partition_input( x ) l = utils.softmax( l, 10 ) H = utils.dot_product( alpha, self.sigmav ) P = utils.dot_product( l, self.working_perms ) U = np.kron( sp.linalg.expm( H ), self.I ) PU = P @ U UP = U @ P.T PUP = PU @ P.T _, dav = utils.dexpmv( H, self.sigmav ) dav = np.kron( dav, self.I ) dav = P @ dav @ P.T dlv = self.working_perms @ UP + PU @ self.working_perms.transpose( ( 0, 2, 1 ) ) - 2*PUP dlv = np.array( [ x*y for x, y in zip( 10*l, dlv ) ] ) return PUP, np.concatenate( [ dav, dlv ] )
def test_dexpmv_single(self): n = 2 paulis = get_norder_paulis(n) H = dot_product(np.random.random(4**n), paulis) for p in paulis: F0, dF0 = dexpm_exact(H, p) F1, dF1 = dexpmv(H, p) self.assertTrue(np.allclose(F0, F1)) self.assertTrue(np.allclose(dF0, dF1))
def get_matrix_and_derivatives ( self, x ): """Produces the circuit matrix and partials for this gate.""" H = utils.dot_product( x, self.sigmav ) P = self.perm_matrix U = np.kron( sp.linalg.expm( H ), self.I ) PUP = P @ U @ P.T _, dav = utils.dexpmv( H, self.sigmav ) dav = np.kron( dav, self.I ) dav = P @ dav @ P.T return PUP, dav
def test_dexpmv_vector(self): n = 2 paulis = get_norder_paulis(n) H = dot_product(np.random.random(4**n), paulis) dFs0 = [] for p in paulis: _, dF = dexpm_exact(H, p) dFs0.append(dF) dFs0 = np.array(dFs0) _, dFs1 = dexpmv(H, paulis) self.assertTrue(np.allclose(dFs0, dFs1))
def test_is_hermitian ( self ): paulis = get_norder_paulis( 3 ) for i in range( 10 ): alpha = np.random.random( 4 ** 3 ) self.assertTrue( is_hermitian( dot_product( alpha, paulis ) ) )
def get_matrix_and_derivatives ( self, x ): """Produces the circuit matrix and partials for this gate.""" H = utils.dot_product( x, self.sigmav ) return utils.dexpmv( H, self.sigmav )
def get_matrix ( self, x ): """Produces the circuit matrix for this gate.""" H = utils.dot_product( x, self.sigmav ) return sp.linalg.expm( H )
def test_dot_product_valid1(self): sigma = np.array([[[0, 1], [1, 0]], [[1, 0], [0, 1]]]) alpha = [1, 1] expected = np.array([[1, 1], [1, 1]]) self.assertTrue(np.allclose(dot_product(alpha, sigma), expected))
def get_matrix ( self, x ): """Produces the circuit matrix for this gate.""" H = utils.dot_product( x, self.sigmav ) U = sp.linalg.expm( H ) P = self.perm_matrix return P @ np.kron( U, self.I ) @ P.T
def test_is_square_matrix1(self): paulis = get_norder_paulis(3) for i in range(10): alpha = np.random.random(4**3) self.assertTrue(is_square_matrix(dot_product(alpha, paulis)))
def get_gate_matrix ( self, x ): """Produces the matrix for this gate on its own.""" sigma = pauli.get_norder_paulis( self.gate_size ) sigma = self.Hcoef * sigma H = utils.dot_product( x, sigma ) return sp.linalg.expm( H )