示例#1
0
    def _control_circuit(self, psi, action):
        """
        Args:
            psi (Tensor([batch_size,N], c64)): batch of states
            action (dict, 'alpha' : Tensor([batch_size,2], tf.float32),
                          'beta'  : Tensor([batch_size,2], tf.float32),
                          'phi'   : Tensor([batch_size,1], tf.float32),
                          'theta' : Tensor([batch_size,1], tf.float32))

        Returns: see parent class docs

        """
        # extract parameters
        alpha = hf.vec_to_complex(action['alpha'])
        beta = hf.vec_to_complex(action['beta'])
        phi = action['phi']
        Rotation = self.rotate(action['theta'])

        Kraus = {}
        T = {'a': self.translate(alpha), 'b': self.translate(beta / 2.0)}
        Kraus[0] = 1 / 2 * (tf.linalg.adjoint(T['b']) +
                            self.phase(phi) * T['b'])
        Kraus[1] = 1 / 2 * (tf.linalg.adjoint(T['b']) -
                            self.phase(phi) * T['b'])

        psi = self.simulate(psi, self.t_feedback)
        psi = batch_dot(T['a'], psi)
        psi_cached = batch_dot(Rotation, psi)
        psi = self.simulate(psi_cached, self.t_round + self.t_idle)
        psi_final, msmt = measurement(psi, Kraus)

        return psi_final, psi_cached, msmt
    def _control_circuit(self, psi, action):
        """
        Args:
            psi (Tensor([batch_size,N], c64)): batch of states
            action (dict, 'alpha'   : Tensor([batch_size,2], tf.float32),
                          'beta'    : Tensor([batch_size,2], tf.float32),
                          'epsilon' : Tensor([batch_size,2], tf.float32))

        Returns: see parent class docs

        """
        # extract parameters
        alpha = hf.vec_to_complex(action['alpha'])
        beta = hf.vec_to_complex(action['beta'])
        epsilon = hf.vec_to_complex(action['epsilon'])

        # Construct gates
        Hadamard = tf.stack([self.hadamard] * self.batch_size)
        sx = tf.stack([self.sx] * self.batch_size)
        I = tf.stack([self.I] * self.batch_size)
        Rxp = tf.stack([self.rxp] * self.batch_size)
        Rxm = tf.stack([self.rxm] * self.batch_size)
        T, CT = {}, {}
        T['a'] = self.translate(alpha)
        T['b'] = self.translate(beta / 4.0)
        T['e'] = self.translate(epsilon / 2.0)
        CT['b'] = self.ctrl(tf.linalg.adjoint(T['b']), T['b'])
        CT['e'] = self.ctrl(tf.linalg.adjoint(T['e']), T['e'])

        # Feedback translation
        psi_cached = batch_dot(T['a'], psi)
        # Between-round wait time
        psi = self.simulate(psi_cached, self.t_idle)
        # Qubit gates
        psi = batch_dot(Hadamard, psi)
        # Conditional translation
        psi = batch_dot(CT['b'], psi)
        psi = self.simulate(psi, self.t_gate)
        psi = batch_dot(CT['b'], psi)
        # Qubit rotation
        psi = batch_dot(Rxp, psi)
        # Conditional translation
        psi = batch_dot(CT['e'], psi)
        # Qubit rotation
        psi = batch_dot(Rxm, psi)
        # Readout of finite duration
        psi = self.simulate(psi, self.t_read)
        psi, msmt = measurement(psi, self.P)
        psi = self.simulate(psi, self.t_read)
        # Feedback delay
        psi = self.simulate(psi, self.t_feedback)
        # Flip qubit conditioned on the measurement
        psi_final = psi * tf.cast((msmt == 1), c64)
        psi_final += batch_dot(sx, psi) * tf.cast((msmt == -1), c64)

        return psi_final, psi_cached, msmt
    def _control_circuit(self, psi, action):
        """
        Args:
            psi (Tensor([batch_size,N], c64)): batch of states
            action (dict, 'beta'    : Tensor([batch_size,2], tf.float32),
                          'epsilon' : Tensor([batch_size,2], tf.float32,
                          'phi'     : Tensor([batch_size,1])))

        Returns: see parent class docs

        """
        # extract parameters
        beta = hf.vec_to_complex(action['beta'])
        epsilon = hf.vec_to_complex(action['epsilon'])
        phi = tf.squeeze(action['phi'])

        # Construct gates
        Phase = self.rotate_qb_z(phi)
        T, CT = {}, {}
        T['b'] = self.translate(beta / 4.0)  # 4 because it will be troterized
        T['e'] = self.translate(epsilon / 2.0)
        CT['b'] = self.ctrl(tf.linalg.adjoint(T['b']), T['b'])
        CT['e'] = self.ctrl(tf.linalg.adjoint(T['e']), T['e'])

        # Between-round wait time
        psi = self.simulate(psi, self.t_idle)
        # Rotate qubit to |+> state
        psi = tf.linalg.matvec(self.hadamard, psi)
        # Troterized conditional translation
        psi = tf.linalg.matvec(CT['b'], psi)
        psi = self.simulate(psi, self.t_gate)
        psi = tf.linalg.matvec(CT['b'], psi)
        # Qubit rotation
        psi = tf.linalg.matvec(self.rxp, psi)
        # Conditional translation
        psi = tf.linalg.matvec(CT['e'], psi)
        # Qubit rotation
        psi = tf.linalg.matvec(self.rxm, psi)
        # Troterized conditional translation
        psi = tf.linalg.matvec(CT['b'], psi)
        psi = self.simulate(psi, self.t_gate)
        psi = tf.linalg.matvec(CT['b'], psi)
        # Qubit gates
        psi = tf.linalg.matvec(Phase, psi)
        psi = tf.linalg.matvec(self.hadamard, psi)
        # Readout of finite duration
        psi = self.simulate(psi, self.t_read)
        psi, msmt = measurement(psi, self.P)
        psi = self.simulate(psi, self.t_read)
        # Feedback delay
        psi = self.simulate(psi, self.t_feedback)
        # Flip qubit conditioned on the measurement
        psi_final = tf.where(msmt == 1, psi, tf.linalg.matvec(self.sx, psi))

        return psi_final, psi_final, msmt
示例#4
0
    def _control_circuit(self, psi, action):
        """
        Args:
            psi (Tensor([batch_size,N], c64)): batch of states
            action (dict, 'alpha' : Tensor([batch_size,2], tf.float32),
                          'theta' : Tensor([batch_size,7], tf.float32),
                          'phi' : Tensor([batch_size,7], tf.float32))

        Returns: see parent class docs

        """
        # Extract parameters
        alpha = hf.vec_to_complex(action['alpha'])
        theta = action['theta']
        phi = action['phi']

        # Build gates
        displace = self.displace(alpha)
        snap = self.SNAP_miscalibrated(theta, dangle=phi)

        # Apply gates
        psi = tf.linalg.matvec(displace, psi)
        psi = tf.linalg.matvec(snap, psi)
        psi = tf.linalg.matvec(tf.linalg.adjoint(displace), psi)

        # Readout with feedback to flip the qubit
        # psi, msmt = measurement(psi, self.P)
        # psi = tf.where(msmt==1, psi, tf.linalg.matvec(self.sx, psi))

        return psi, psi, tf.ones((self.batch_size, 1))
示例#5
0
def fill_buffer_v2(target_state, buffer=[], target_vals=[], samples=1000):
    # Distributions for rejection sampling
    L = window_size / 2
    P = tfp.distributions.Uniform(low=[[-L, -L]] * samples,
                                  high=[[L, L]] * samples)
    P_v = tfp.distributions.Uniform(low=[0.0] * samples, high=[1.0] * samples)

    # batch rejection sampling of phase space points
    cond = True
    accepted = tf.zeros([samples], tf.bool)
    accepted_points = tf.zeros([samples], tf.complex64)
    accepted_targets = tf.zeros([samples], tf.float32)
    while cond:
        points = tf.squeeze(hf.vec_to_complex(P.sample()))
        target_state_translated = tf.linalg.matvec(T(-points), target_state)
        W_target = expectation(target_state_translated,
                               parity,
                               reduce_batch=False)
        W_target = tf.math.real(tf.squeeze(W_target))
        reject = P_v.sample() > tf.math.abs(W_target)**2
        mask = tf.logical_and(tf.logical_not(reject), tf.logical_not(accepted))
        accepted = tf.logical_or(mask, accepted)
        accepted_points = tf.where(mask, points, accepted_points)
        accepted_targets = tf.where(mask, W_target, accepted_targets)
        cond = not tf.reduce_all(accepted)

    buffer += list(accepted_points)
    target_vals += list(accepted_targets)
    return buffer, target_vals
示例#6
0
    def _control_circuit(self, psi, action):
        """
        Args:
            psi (Tensor([batch_size,N], c64)): batch of states
            action (dict, 'beta'  : Tensor([batch_size,2], tf.float32),
                          'phi'   : Tensor([batch_size,2], tf.float32))

        Returns: see parent class docs

        """
        # Extract parameters
        beta = hf.vec_to_complex(action['beta'])
        phase, angle = action['phi'][:, 0], action['phi'][:, 1]

        # Construct gates
        D = self.displace(beta / 2.0)
        CD = self.ctrl(D, tf.linalg.adjoint(D))
        R = self.rotate_qb_xy(angle, phase)
        flip = self.rotate_qb_xy(tf.constant(pi), tf.constant(0))

        # Apply gates
        psi = tf.linalg.matvec(R, psi)
        psi = tf.linalg.matvec(CD, psi)
        if self._elapsed_steps < self.T - 1:
            psi = tf.linalg.matvec(flip, psi)

        m = tf.ones((self.batch_size, 1))
        # if self._elapsed_steps == self.T-1:
        #     psi, m = measurement(psi, self.P, sample=True)

        return psi, psi, m
    def _control_circuit(self, psi, action):
        """
        Args:
            psi (Tensor([batch_size,N], c64)): batch of states
            action (dict, 'beta'    : Tensor([batch_size,2], tf.float32),
                          'epsilon' : Tensor([batch_size,2], tf.float32,
                          'phi'     : Tensor([batch_size,1])))

        Returns: see parent class docs

        """
        # extract parameters
        beta = hf.vec_to_complex(action['beta'])
        epsilon = hf.vec_to_complex(action['epsilon'])
        phi = action['phi']

        Kraus = {}
        T = {}
        T['+b'] = self.translate(beta / 2.0)
        T['-b'] = tf.linalg.adjoint(T['+b'])
        T['+e'] = self.translate(epsilon / 2.0)
        T['-e'] = tf.linalg.adjoint(T['+e'])


        chunk1 = 1j*batch_dot(T['-b'], batch_dot(T['+e'], T['+b'])) \
                - 1j*batch_dot(T['-b'], batch_dot(T['-e'], T['+b'])) \
                + batch_dot(T['-b'], batch_dot(T['-e'], T['-b'])) \
                + batch_dot(T['-b'], batch_dot(T['+e'], T['-b']))

        chunk2 = 1j*batch_dot(T['+b'], batch_dot(T['-e'], T['-b'])) \
                - 1j*batch_dot(T['+b'], batch_dot(T['+e'], T['-b'])) \
                + batch_dot(T['+b'], batch_dot(T['-e'], T['+b'])) \
                + batch_dot(T['+b'], batch_dot(T['+e'], T['+b']))

        Kraus[0] = 1 / 4 * (chunk1 + self.phase(phi) * chunk2)
        Kraus[1] = 1 / 4 * (chunk1 - self.phase(phi) * chunk2)

        psi = self.simulate(psi, self.t_round + self.t_idle)
        psi_final, msmt = measurement(normalize(psi), Kraus)

        return psi_final, psi_final, msmt
    def _control_circuit(self, psi, action):
        """
        Args:
            psi (Tensor([batch_size,N], c64)): batch of states
            action (dict, 'alpha'   : Tensor([batch_size,2], tf.float32),
                          'beta'    : Tensor([batch_size,2], tf.float32),
                          'epsilon' : Tensor([batch_size,2], tf.float32))

        Returns: see parent class docs

        """
        # extract parameters
        alpha = hf.vec_to_complex(action['alpha'])
        beta = hf.vec_to_complex(action['beta'])
        epsilon = hf.vec_to_complex(action['epsilon'])

        Kraus = {}
        T = {}
        T['a'] = self.translate(alpha)
        T['+b'] = self.translate(beta / 2.0)
        T['-b'] = tf.linalg.adjoint(T['+b'])
        T['+e'] = self.translate(epsilon / 2.0)
        T['-e'] = tf.linalg.adjoint(T['+e'])

        chunk1 = batch_dot(T['-e'], T['-b']) - 1j * batch_dot(T['-e'], T['+b'])
        chunk2 = batch_dot(T['+e'], T['-b']) + 1j * batch_dot(T['+e'], T['+b'])

        Kraus[0] = 1 / 2 / sqrt(2) * (chunk1 + chunk2)
        Kraus[1] = 1 / 2 / sqrt(2) * (chunk1 - chunk2)

        psi = self.simulate(psi, self.t_feedback)
        psi_cached = batch_dot(T['a'], psi)
        psi = self.simulate(psi_cached, self.t_round + self.t_idle)
        psi_final, msmt = measurement(psi, Kraus)

        return psi_final, psi_cached, msmt
示例#9
0
def fill_buffer(target_state, buffer=[], target_vals=[], samples=1000):
    # Distributions for rejection sampling
    L = window_size / 2
    P = tfp.distributions.Uniform(low=[[-L, -L]], high=[[L, L]])
    P_v = tfp.distributions.Uniform(low=0.0, high=1.0)

    # rejection sampling of phase space points
    for i in range(samples):
        cond = True
        while cond:
            point = tf.squeeze(hf.vec_to_complex(P.sample()))
            target_state_translated = tf.linalg.matvec(T(-point), target_state)
            W_target = expectation(target_state_translated, parity)
            W_target = tf.math.real(tf.squeeze(W_target))
            cond = P_v.sample() > tf.math.abs(W_target)**2
        buffer.append(point)
        target_vals.append(W_target)
    return buffer, target_vals
    def _control_circuit(self, psi, action):
        """
        Args:
            psi (Tensor([batch_size,N], c64)): batch of states
            action (dict, 'alpha' : Tensor([batch_size,2], tf.float32),
                          'theta' : Tensor([batch_size,10], tf.float32))

        Returns: see parent class docs

        """
        # Extract parameters
        alpha = hf.vec_to_complex(action['alpha'])
        theta = action['theta']

        # Build gates
        displace = self.displace(alpha)
        snap = self.SNAP_miscalibrated(theta)

        # Apply gates
        psi = tf.linalg.matvec(displace, psi)
        psi = tf.linalg.matvec(snap, psi)
        psi = tf.linalg.matvec(tf.linalg.adjoint(displace), psi)

        # Either implement a measurement with a random qubit projection, or
        # project on the specified 'self.bit_string' sequence of qubit states.
        if self.bit_string is not None:
            s = int(self.bit_string[self._elapsed_steps])
            psi = tf.linalg.matvec(self.P[s], psi)
            if s == 1: psi = tf.linalg.matvec(self.sx, psi)
            psi, norm = normalize(psi)
            self.norms.append(norm)
            msmt = tf.ones((self.batch_size, 1)) * (1 if s == 0 else -1)
        else:  # Readout with feedback to flip the qubit
            psi, msmt = measurement(psi, self.P)
            psi = tf.where(msmt == 1, psi, tf.linalg.matvec(self.sx, psi))

        return psi, psi, msmt
    def _control_circuit(self, psi, action):
        """
        Args:
            psi (Tensor([batch_size,N], c64)): batch of states
            action (dict, 'alpha' : Tensor([batch_size,2], tf.float32),
                          'theta' : Tensor([batch_size,7], tf.float32))

        Returns: see parent class docs

        """
        # Extract parameters
        alpha = hf.vec_to_complex(action['alpha'])
        theta = action['theta']

        # Build gates
        displace = self.displace(alpha)
        snap = self.SNAP(theta)

        # Apply gates
        psi = tf.linalg.matvec(displace, psi)
        psi = tf.linalg.matvec(snap, psi)
        psi = tf.linalg.matvec(tf.linalg.adjoint(displace), psi)

        return psi, psi, tf.ones((self.batch_size, 1))