code: def run_symmetrized_readout(self, program: Program, trials: int) -> np.ndarray:
          
          flipped_program = _get_flipped_protoquil_program(program)
          if trials % 2 != 0:
              raise ValueError("Using symmetrized measurement functionality requires that you "
                               "take an even number of trials.")
          half_trials = trials // 2
          flipped_program = flipped_program.wrap_in_numshots_loop(shots=half_trials)
          flipped_executable = self.compile(flipped_program)
  
          executable = self.compile(program.wrap_in_numshots_loop(half_trials))
          samples = self.run(executable)
          flipped_samples = self.run(flipped_executable)
          double_flipped_samples = np.logical_not(flipped_samples).astype(int)
          results = np.concatenate((samples, double_flipped_samples), axis=0)
          np.random.shuffle(results)
          return results
docs: Run a quil program in such a way that the readout error is made collectively symmetric
  
          This means the probability of a bitstring ``b`` being mistaken for a bitstring ``c`` is
          the same as the probability of ``not(b)`` being mistaken for ``not(c)``
  
          A more general symmetrization would guarantee that the probability of ``b`` being
          mistaken for ``c`` depends only on which bit of ``c`` are different from ``b``. This
          would require choosing random subsets of bits to flip.
  
          In a noisy device, the probability of accurately reading the 0 state might be higher
          than that of the 1 state. This makes correcting for readout more difficult. This
          function runs the program normally ``(trials//2)`` times. The other half of the time,
          it will insert an ``X`` gate prior to any ``MEASURE`` instruction and then flip the
          measured classical bit back.
  
          See :py:func:`run` for this function's parameter descriptions.