<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run_symmetrized_readout(self, program: Program, trials: int) -> np.ndarray: """ 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. """

        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