예제 #1
0
def simulate_output_data(func, xvals, param_dict, **metadata):
    """Generate arbitrary fit data."""
    __shots = 100000

    expected_probs = func(xvals, **param_dict)
    counts = np.asarray(expected_probs * __shots, dtype=int)

    data = [{
        "counts": {
            "0": __shots - count,
            "1": count
        },
        "metadata":
        dict(xval=xi,
             qubits=(0, ),
             experiment_type="fake_experiment",
             **metadata),
    } for xi, count in zip(xvals, counts)]

    expdata = ExperimentData(experiment=FakeExperiment())
    for datum in data:
        expdata.add_data(datum)

    expdata.metadata["job_metadata"] = [{
        "run_options": {
            "meas_level": MeasLevel.CLASSIFIED
        }
    }]

    return expdata
예제 #2
0
    def test_t1_analysis(self):
        """
        Test T1Analysis
        """

        data = ExperimentData()
        numbers = [
            750, 1800, 2750, 3550, 4250, 4850, 5450, 5900, 6400, 6800, 7000,
            7350, 7700
        ]

        for i, count0 in enumerate(numbers):
            data.add_data({
                "counts": {
                    "0": count0,
                    "1": 10000 - count0
                },
                "metadata": {
                    "xval": 3 * i + 1,
                    "experiment_type": "T1",
                    "qubit": 0,
                    "unit": "ns",
                    "dt_factor_in_sec": None,
                },
            })

        res = T1Analysis()._run_analysis(data)[0][0]
        self.assertEqual(res.quality, "good")
        self.assertAlmostEqual(res.value.value, 25e-9, delta=3)
예제 #3
0
    def test_qv_failure_insufficient_confidence(self):
        """
        Test that the quantum volume is unsuccessful when:
            there are more than 100 trials, the heavy output probability mean is more than 2/3
            but the confidence is not high enough
        """
        dir_name = os.path.dirname(os.path.abspath(__file__))
        insufficient_confidence_json = "qv_data_moderate_noise_100_trials.json"
        with open(os.path.join(dir_name, insufficient_confidence_json),
                  "r") as json_file:
            insufficient_confidence_data = json.load(json_file,
                                                     cls=ExperimentDecoder)

        num_of_qubits = 4
        backend = Aer.get_backend("aer_simulator")

        qv_exp = QuantumVolume(num_of_qubits, seed=SEED)
        exp_data = ExperimentData(experiment=qv_exp, backend=backend)
        exp_data.add_data(insufficient_confidence_data)

        qv_exp.run_analysis(exp_data)
        qv_result = exp_data.analysis_results(1)
        self.assertTrue(
            qv_result.extra["success"] is False and qv_result.value == 1,
            "quantum volume is successful with insufficient confidence",
        )
예제 #4
0
    def test_t1_low_quality(self):
        """
        A test where the fit's quality will be low
        """

        data = ExperimentData()
        data._metadata = {
            "job_metadata": [
                {
                    "run_options": {
                        "meas_level": 2
                    },
                },
            ]
        }

        for i in range(10):
            data.add_data({
                "counts": {
                    "0": 10,
                    "1": 10
                },
                "metadata": {
                    "xval": i * 1e-9,
                    "experiment_type": "T1",
                    "qubit": 0,
                    "unit": "s",
                },
            })

        res, _ = T1Analysis()._run_analysis(data)
        result = res[1]
        self.assertEqual(result.quality, "bad")
예제 #5
0
    def test_composite_single_kerneled_memory_marginalization(self):
        """Test the marginalization of level 1 data."""
        test_data = ExperimentData()

        datum = {
            "memory": [
                # qubit 0,   qubit 1,    qubit 2
                [[0.0, 0.0], [1.0, 1.0], [2.0, 2.0]],  # shot 1
                [[0.1, 0.1], [1.1, 1.1], [2.1, 2.1]],  # shot 2
                [[0.2, 0.2], [1.2, 1.2], [2.2, 2.2]],  # shot 3
                [[0.3, 0.3], [1.3, 1.3], [2.3, 2.3]],  # shot 4
                [[0.4, 0.4], [1.4, 1.4], [2.4, 2.4]],  # shot 5
            ],
            "metadata": {
                "experiment_type":
                "ParallelExperiment",
                "composite_index": [0, 1, 2],
                "composite_metadata": [
                    {
                        "experiment_type": "FineXAmplitude",
                        "qubits": [0]
                    },
                    {
                        "experiment_type": "FineXAmplitude",
                        "qubits": [1]
                    },
                    {
                        "experiment_type": "FineXAmplitude",
                        "qubits": [2]
                    },
                ],
                "composite_qubits": [[0], [1], [2]],
                "composite_clbits": [[0], [1], [2]],
            },
            "shots":
            5,
            "meas_level":
            1,
        }

        test_data.add_data(datum)

        all_sub_data = CompositeAnalysis([])._marginalized_component_data(
            test_data.data())
        for idx, sub_data in enumerate(all_sub_data):
            expected = {
                "metadata": {
                    "experiment_type": "FineXAmplitude",
                    "qubits": [idx]
                },
                "memory": [
                    [[idx + 0.0, idx + 0.0]],
                    [[idx + 0.1, idx + 0.1]],
                    [[idx + 0.2, idx + 0.2]],
                    [[idx + 0.3, idx + 0.3]],
                    [[idx + 0.4, idx + 0.4]],
                ],
            }

            self.assertEqual(expected, sub_data[0])
예제 #6
0
    def test_local_analysis(self):
        """Tests local mitigator generation from experimental data"""
        qubits = [0, 1, 2]
        run_data = [
            {
                "counts": {"000": 986, "010": 10, "100": 16, "001": 12},
                "metadata": {"label": "000"},
                "shots": 1024,
            },
            {
                "counts": {"111": 930, "110": 39, "011": 24, "101": 29, "010": 1, "100": 1},
                "metadata": {"label": "111"},
                "shots": 1024,
            },
        ]
        expected_assignment_matrices = [
            np.array([[0.98828125, 0.04003906], [0.01171875, 0.95996094]]),
            np.array([[0.99023438, 0.02929688], [0.00976562, 0.97070312]]),
            np.array([[0.984375, 0.02441406], [0.015625, 0.97558594]]),
        ]
        run_meta = {"physical_qubits": qubits}
        expdata = ExperimentData()
        expdata.add_data(run_data)
        expdata._metadata = run_meta
        exp = ReadoutMitigationExperiment(qubits)
        result = exp.analysis.run(expdata)
        mitigator = result.analysis_results(0).value

        self.assertEqual(len(qubits), mitigator._num_qubits)
        self.assertEqual(qubits, mitigator._qubits)
        self.assertTrue(matrix_equal(expected_assignment_matrices, mitigator._assignment_mats))
예제 #7
0
    def test_qv_failure_insufficient_trials(self):
        """
        Test that the quantum volume is unsuccessful when:
            there is less than 100 trials
        """
        dir_name = os.path.dirname(os.path.abspath(__file__))
        insufficient_trials_json_file = "qv_data_70_trials.json"
        with open(os.path.join(dir_name, insufficient_trials_json_file),
                  "r") as json_file:
            insufficient_trials_data = json.load(json_file,
                                                 cls=ExperimentDecoder)

        num_of_qubits = 3
        backend = Aer.get_backend("aer_simulator")

        qv_exp = QuantumVolume(num_of_qubits, seed=SEED)
        exp_data = ExperimentData(experiment=qv_exp, backend=backend)
        exp_data.add_data(insufficient_trials_data)

        qv_exp.run_analysis(exp_data)
        qv_result = exp_data.analysis_results(1)
        self.assertTrue(
            qv_result.extra["success"] is False and qv_result.value == 1,
            "quantum volume is successful with less than 100 trials",
        )
예제 #8
0
    def test_t1_analysis(self):
        """
        Test T1Analysis
        """

        data = ExperimentData()
        data._metadata = {"meas_level": 2}

        numbers = [
            750, 1800, 2750, 3550, 4250, 4850, 5450, 5900, 6400, 6800, 7000,
            7350, 7700
        ]

        for i, count0 in enumerate(numbers):
            data.add_data({
                "counts": {
                    "0": count0,
                    "1": 10000 - count0
                },
                "metadata": {
                    "xval": (3 * i + 1) * 1e-9,
                    "experiment_type": "T1",
                    "qubit": 0,
                    "unit": "s",
                },
            })

        res, _ = T1Analysis()._run_analysis(data)
        result = res[1]
        self.assertEqual(result.quality, "good")
        self.assertAlmostEqual(result.value.nominal_value, 25e-9, delta=3)
예제 #9
0
    def _load_json_data(self, rb_exp_data_file_name: str):
        """
        loader for the experiment data and configuration setup.
        Args:
            rb_exp_data_file_name(str): The file name that contain the experiment data.
        Returns:
            list: containing dict of the experiment setup configuration and list of dictionaries
                containing the experiment results.
            ExperimentData:  ExperimentData object that was creates by the analysis function.
        """
        expdata1 = ExperimentData()
        self.assertTrue(
            os.path.isfile(rb_exp_data_file_name),
            "The file containing the experiment data doesn't exist."
            " Please run the data generator.",
        )
        with open(rb_exp_data_file_name, "r") as json_file:
            data = json.load(json_file)
            # The experiment attributes added
            exp_attributes = data[0]
            # pylint: disable=protected-access, invalid-name
            expdata1._metadata = data[0]
            # The experiment data located in index [1] as it is a list of dicts
            expdata1.add_data(data[1])

        return data, exp_attributes, expdata1
예제 #10
0
    def test_to_real(self):
        """Test scaling and conversion to real part."""
        processor = DataProcessor("memory", [ToReal(scale=1e-3)])

        exp_data = ExperimentData(FakeExperiment())
        exp_data.add_data(self.result_lvl1)

        # Test to real on a single datum
        new_data = processor(exp_data.data(0))

        expected_old = {
            "memory": [
                [[1103260.0, -11378508.0], [2959012.0, -16488753.0]],
                [[442170.0, -19283206.0], [-5279410.0, -15339630.0]],
                [[3016514.0, -14548009.0], [-3404756.0, -16743348.0]],
            ],
            "metadata": {"experiment_type": "fake_test_experiment"},
            "job_id": "job-123",
            "meas_level": 1,
            "shots": 3,
        }

        expected_new = np.array([[1103.26, 2959.012], [442.17, -5279.41], [3016.514, -3404.7560]])

        self.assertEqual(exp_data.data(0), expected_old)
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            expected_new,
        )
        self.assertTrue(np.isnan(unp.std_devs(new_data)).all())

        # Test that we can call with history.
        new_data, history = processor.call_with_history(exp_data.data(0))

        self.assertEqual(exp_data.data(0), expected_old)
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            expected_new,
        )

        self.assertEqual(history[0][0], "ToReal")
        np.testing.assert_array_almost_equal(
            unp.nominal_values(history[0][1]),
            expected_new,
        )

        # Test to real on more than one datum
        new_data = processor(exp_data.data())

        expected_new = np.array(
            [
                [[1103.26, 2959.012], [442.17, -5279.41], [3016.514, -3404.7560]],
                [[5131.962, 4438.87], [3415.985, 2942.458], [5199.964, 4030.843]],
            ]
        )
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            expected_new,
        )
    def test_to_imag(self):
        """Test that we can average the data."""
        processor = DataProcessor("memory")
        processor.append(ToImag(scale=1e-3))

        exp_data = ExperimentData(FakeExperiment())
        exp_data.add_data(self.result_lvl1)

        new_data, error = processor(exp_data.data(0))

        expected_old = {
            "memory": [
                [[1103260.0, -11378508.0], [2959012.0, -16488753.0]],
                [[442170.0, -19283206.0], [-5279410.0, -15339630.0]],
                [[3016514.0, -14548009.0], [-3404756.0, -16743348.0]],
            ],
            "metadata": {
                "experiment_type": "fake_test_experiment"
            },
            "job_id":
            "job-123",
            "meas_level":
            1,
            "shots":
            3,
        }

        expected_new = np.array([
            [-11378.508, -16488.753],
            [-19283.206000000002, -15339.630000000001],
            [-14548.009, -16743.348],
        ])

        self.assertEqual(exp_data.data(0), expected_old)
        self.assertTrue(np.allclose(new_data, expected_new))
        self.assertIsNone(error)

        # Test that we can call with history.
        new_data, error, history = processor.call_with_history(
            exp_data.data(0))
        self.assertEqual(exp_data.data(0), expected_old)
        self.assertTrue(np.allclose(new_data, expected_new))

        self.assertEqual(history[0][0], "ToImag")
        self.assertTrue(np.allclose(history[0][1], expected_new))

        # Test to imaginary on more than one datum
        new_data, error = processor(exp_data.data())

        expected_new = np.array([
            [[-11378.508, -16488.753], [-19283.206, -15339.630],
             [-14548.009, -16743.348]],
            [[-16630.257, -13752.518], [-16031.913, -15840.465],
             [-14955.998, -14538.923]],
        ])

        self.assertTrue(np.allclose(new_data, expected_new))
예제 #12
0
    def test_qv_success(self):
        """
        Test a successful run of quantum volume.
        Compare the results to a pre-run experiment
        """
        dir_name = os.path.dirname(os.path.abspath(__file__))
        successful_json_file = "qv_data_moderate_noise_300_trials.json"
        with open(os.path.join(dir_name, successful_json_file),
                  "r") as json_file:
            successful_data = json.load(json_file, cls=ExperimentDecoder)

        num_of_qubits = 4
        backend = Aer.get_backend("aer_simulator")

        qv_exp = QuantumVolume(range(num_of_qubits), seed=SEED)
        exp_data = ExperimentData(experiment=qv_exp, backend=backend)
        exp_data.add_data(successful_data)

        qv_exp.analysis.run(exp_data)
        results_json_file = "qv_result_moderate_noise_300_trials.json"
        with open(os.path.join(dir_name, results_json_file), "r") as json_file:
            successful_results = json.load(json_file, cls=ExperimentDecoder)

        results = exp_data.analysis_results()
        for result, reference in zip(results, successful_results):
            if isinstance(result.value, UFloat):
                # ufloat is distinguished by object id. so usually not identical to cache.
                self.assertTupleEqual(
                    (result.value.n, result.value.s),
                    (reference["value"].n, reference["value"].s),
                    "result value is not the same as precalculated analysis",
                )
            else:
                self.assertEqual(
                    result.value,
                    reference["value"],
                    "result value is not the same as precalculated analysis",
                )
            self.assertEqual(
                result.name,
                reference["name"],
                "result name is not the same as precalculated analysis",
            )
            for key, value in reference["extra"].items():
                if isinstance(value, float):
                    self.assertAlmostEqual(
                        result.extra[key],
                        value,
                        msg="result " + str(key) + " is not the same as the "
                        "pre-calculated analysis",
                    )
                else:
                    self.assertTrue(
                        result.extra[key] == value,
                        "result " + str(key) + " is not the same as the "
                        "pre-calculated analysis",
                    )
class BaseDataProcessorTest(QiskitExperimentsTestCase):
    """Define some basic setup functionality for data processor tests."""

    def setUp(self):
        """Define variables needed for most tests."""
        super().setUp()

        self.base_result_args = dict(
            backend_name="test_backend",
            backend_version="1.0.0",
            qobj_id="id-123",
            job_id="job-123",
            success=True,
        )

        self.header = QobjExperimentHeader(
            memory_slots=2,
            metadata={"experiment_type": "fake_test_experiment"},
        )

    def create_experiment_data(self, iq_data: List[Any], single_shot: bool = False):
        """Populate avg_iq_data to use it for testing.

        Args:
            iq_data: A List of IQ data.
            single_shot: Indicates if the data is single-shot or not.
        """
        results = []
        if not single_shot:
            for circ_data in iq_data:
                res = ExperimentResult(
                    success=True,
                    meas_level=1,
                    meas_return="avg",
                    data=ExperimentResultData(memory=circ_data),
                    header=self.header,
                    shots=1024,
                )
                results.append(res)
        else:
            for circ_data in iq_data:
                res = ExperimentResult(
                    success=True,
                    meas_level=1,
                    meas_return="single",
                    data=ExperimentResultData(memory=circ_data),
                    header=self.header,
                    shots=1024,
                )
                results.append(res)

        # pylint: disable=attribute-defined-outside-init
        self.iq_experiment = ExperimentData(FakeExperiment())
        self.iq_experiment.add_data(Result(results=results, **self.base_result_args))
예제 #14
0
    def test_composite_avg_kerneled_memory_marginalization(self):
        """The the marginalization of level 1 averaged data."""
        test_data = ExperimentData()

        datum = {
            "memory": [
                [0.0, 0.1],  # qubit 0
                [1.0, 1.1],  # qubit 1
                [2.0, 2.1],  # qubit 2
            ],
            "metadata": {
                "experiment_type":
                "ParallelExperiment",
                "composite_index": [0, 1, 2],
                "composite_metadata": [
                    {
                        "experiment_type": "FineXAmplitude",
                        "qubits": [0]
                    },
                    {
                        "experiment_type": "FineXAmplitude",
                        "qubits": [1]
                    },
                    {
                        "experiment_type": "FineXAmplitude",
                        "qubits": [2]
                    },
                ],
                "composite_qubits": [[0], [1], [2]],
                "composite_clbits": [[0], [1], [2]],
            },
            "shots": 5,
            "meas_level": 1,
        }

        test_data.add_data(datum)

        all_sub_data = CompositeAnalysis([])._marginalized_component_data(
            test_data.data())
        for idx, sub_data in enumerate(all_sub_data):
            expected = {
                "metadata": {
                    "experiment_type": "FineXAmplitude",
                    "qubits": [idx]
                },
                "memory": [[idx + 0.0, idx + 0.1]],
            }

            self.assertEqual(expected, sub_data[0])
예제 #15
0
    def test_bad_analysis(self):
        """Test the Rabi analysis."""
        experiment_data = ExperimentData()

        thetas = np.linspace(0.0, np.pi / 4, 31)
        amplitudes = np.linspace(0.0, 0.95, 31)

        experiment_data.add_data(
            self.simulate_experiment_data(thetas, amplitudes, shots=200))

        data_processor = DataProcessor("counts", [Probability(outcome="1")])

        experiment_data = OscillationAnalysis().run(
            experiment_data, data_processor=data_processor, plot=False)
        result = experiment_data.analysis_results()

        self.assertEqual(result[0].quality, "bad")
예제 #16
0
    def test_good_analysis(self):
        """Test the Rabi analysis."""
        experiment_data = ExperimentData()

        thetas = np.linspace(-np.pi, np.pi, 31)
        amplitudes = np.linspace(-0.25, 0.25, 31)
        expected_rate, test_tol = 2.0, 0.2

        experiment_data.add_data(
            self.simulate_experiment_data(thetas, amplitudes, shots=400))

        data_processor = DataProcessor("counts", [Probability(outcome="1")])

        experiment_data = OscillationAnalysis().run(
            experiment_data, data_processor=data_processor, plot=False)
        result = experiment_data.analysis_results(0)
        self.assertEqual(result.quality, "good")
        self.assertAlmostEqual(result.value[1], expected_rate, delta=test_tol)
    def create_data(xvals, d_theta, shots=1000, noise_seed=123):
        """Create experiment data for testing."""
        np.random.seed(noise_seed)
        noise = np.random.normal(0, 0.03, len(xvals))
        yvals = 0.5 * np.cos(
            (d_theta + np.pi) * xvals - np.pi / 2) + 0.5 + noise

        results = []
        for x, y in zip(xvals, yvals):
            n1 = int(shots * y)
            results.append({
                "counts": {
                    "0": shots - n1,
                    "1": n1
                },
                "metadata": {
                    "xval": x
                }
            })

        expdata = ExperimentData()
        expdata.add_data(results)

        return expdata
예제 #18
0
    def test_qv_failure_insufficient_hop(self):
        """
        Test that the quantum volume is unsuccessful when:
            there are more than 100 trials, but the heavy output probability mean is less than 2/3
        """
        dir_name = os.path.dirname(os.path.abspath(__file__))
        insufficient_hop_json_file = "qv_data_high_noise.json"
        with open(os.path.join(dir_name, insufficient_hop_json_file),
                  "r") as json_file:
            insufficient_hop_data = json.load(json_file, cls=ExperimentDecoder)

        num_of_qubits = 4
        backend = Aer.get_backend("aer_simulator")

        qv_exp = QuantumVolume(range(num_of_qubits), seed=SEED)
        exp_data = ExperimentData(experiment=qv_exp, backend=backend)
        exp_data.add_data(insufficient_hop_data)

        qv_exp.analysis.run(exp_data)
        qv_result = exp_data.analysis_results(1)
        self.assertTrue(
            qv_result.extra["success"] is False and qv_result.value == 1,
            "quantum volume is successful with heavy output probability less than 2/3",
        )
예제 #19
0
    def test_t1_low_quality(self):
        """
        A test where the fit's quality will be low
        """

        data = ExperimentData()

        for i in range(10):
            data.add_data({
                "counts": {
                    "0": 10,
                    "1": 10
                },
                "metadata": {
                    "xval": i,
                    "experiment_type": "T1",
                    "qubit": 0,
                    "unit": "ns",
                    "dt_factor_in_sec": None,
                },
            })

        res = T1Analysis()._run_analysis(data)[0][0]
        self.assertEqual(res.quality, "bad")
예제 #20
0
class TestAveragingAndSVD(BaseDataProcessorTest):
    """Test the averaging of single-shot IQ data followed by a SVD."""
    def setUp(self):
        """Here, single-shots average to points at plus/minus 1.

        The setting corresponds to four single-shots done on two qubits.
        """
        super().setUp()

        circ_es = ExperimentResultData(memory=[
            [[1.1, 0.9], [-0.8, 1.0]],
            [[1.2, 1.1], [-0.9, 1.0]],
            [[0.8, 1.1], [-1.2, 1.0]],
            [[0.9, 0.9], [-1.1, 1.0]],
        ])
        self._sig_gs = np.array([1.0, -1.0]) / np.sqrt(2.0)

        circ_gs = ExperimentResultData(memory=[
            [[-1.1, -0.9], [0.8, -1.0]],
            [[-1.2, -1.1], [0.9, -1.0]],
            [[-0.8, -1.1], [1.2, -1.0]],
            [[-0.9, -0.9], [1.1, -1.0]],
        ])
        self._sig_es = np.array([-1.0, 1.0]) / np.sqrt(2.0)

        circ_x90p = ExperimentResultData(memory=[
            [[-1.0, -1.0], [1.0, -1.0]],
            [[-1.0, -1.0], [1.0, -1.0]],
            [[1.0, 1.0], [-1.0, 1.0]],
            [[1.0, 1.0], [-1.0, 1.0]],
        ])
        self._sig_x90 = np.array([0, 0])

        circ_x45p = ExperimentResultData(memory=[
            [[-1.0, -1.0], [1.0, -1.0]],
            [[-1.0, -1.0], [1.0, -1.0]],
            [[-1.0, -1.0], [1.0, -1.0]],
            [[1.0, 1.0], [-1.0, 1.0]],
        ])
        self._sig_x45 = np.array([0.5, -0.5]) / np.sqrt(2.0)

        res_es = ExperimentResult(
            shots=4,
            success=True,
            meas_level=1,
            meas_return="single",
            data=circ_es,
            header=self.header,
        )

        res_gs = ExperimentResult(
            shots=4,
            success=True,
            meas_level=1,
            meas_return="single",
            data=circ_gs,
            header=self.header,
        )

        res_x90p = ExperimentResult(
            shots=4,
            success=True,
            meas_level=1,
            meas_return="single",
            data=circ_x90p,
            header=self.header,
        )

        res_x45p = ExperimentResult(
            shots=4,
            success=True,
            meas_level=1,
            meas_return="single",
            data=circ_x45p,
            header=self.header,
        )

        self.data = ExperimentData(FakeExperiment())
        self.data.add_data(
            Result(results=[res_es, res_gs, res_x90p, res_x45p],
                   **self.base_result_args))

    def test_averaging(self):
        """Test that averaging of the datums produces the expected IQ points."""

        processor = DataProcessor("memory", [AverageData(axis=1)])

        # Test that we get the expected outcome for the excited state
        processed = processor(self.data.data(0))

        np.testing.assert_array_almost_equal(
            unp.nominal_values(processed),
            np.array([[1.0, 1.0], [-1.0, 1.0]]),
        )
        np.testing.assert_array_almost_equal(
            unp.std_devs(processed),
            np.array([[0.15811388300841894, 0.1], [0.15811388300841894, 0.0]])
            / 2.0,
        )

        # Test that we get the expected outcome for the ground state
        processed = processor(self.data.data(1))

        np.testing.assert_array_almost_equal(
            unp.nominal_values(processed),
            np.array([[-1.0, -1.0], [1.0, -1.0]]),
        )
        np.testing.assert_array_almost_equal(
            unp.std_devs(processed),
            np.array([[0.15811388300841894, 0.1], [0.15811388300841894, 0.0]])
            / 2.0,
        )

    def test_averaging_and_svd(self):
        """Test averaging followed by a SVD."""

        processor = DataProcessor("memory", [AverageData(axis=1), SVD()])

        # Test training using the calibration points
        self.assertFalse(processor.is_trained)
        processor.train([self.data.data(idx) for idx in [0, 1]])
        self.assertTrue(processor.is_trained)

        # Test the excited state
        processed = processor(self.data.data(0))
        np.testing.assert_array_almost_equal(
            unp.nominal_values(processed),
            self._sig_es,
        )

        # Test the ground state
        processed = processor(self.data.data(1))
        np.testing.assert_array_almost_equal(
            unp.nominal_values(processed),
            self._sig_gs,
        )

        # Test the x90p rotation
        processed = processor(self.data.data(2))
        np.testing.assert_array_almost_equal(
            unp.nominal_values(processed),
            self._sig_x90,
        )
        np.testing.assert_array_almost_equal(
            unp.std_devs(processed),
            np.array([0.25, 0.25]),
        )

        # Test the x45p rotation
        processed = processor(self.data.data(3))
        np.testing.assert_array_almost_equal(
            unp.nominal_values(processed),
            self._sig_x45,
        )
        np.testing.assert_array_almost_equal(
            unp.std_devs(processed),
            np.array([np.std([1, 1, 1, -1]) / np.sqrt(4.0) / 2] * 2),
        )

    def test_process_all_data(self):
        """Test that we can process all data at once."""

        processor = DataProcessor("memory", [AverageData(axis=1), SVD()])

        # Test training using the calibration points
        self.assertFalse(processor.is_trained)
        processor.train([self.data.data(idx) for idx in [0, 1]])
        self.assertTrue(processor.is_trained)

        all_expected = np.vstack((
            self._sig_es.reshape(1, 2),
            self._sig_gs.reshape(1, 2),
            self._sig_x90.reshape(1, 2),
            self._sig_x45.reshape(1, 2),
        ))

        # Test processing of all data
        processed = processor(self.data.data())
        np.testing.assert_array_almost_equal(
            unp.nominal_values(processed),
            all_expected,
        )

        # Test processing of each datum individually
        for idx, expected in enumerate(
            [self._sig_es, self._sig_gs, self._sig_x90, self._sig_x45]):
            processed = processor(self.data.data(idx))
            np.testing.assert_array_almost_equal(
                unp.nominal_values(processed),
                expected,
            )

    def test_normalize(self):
        """Test that by adding a normalization node we get a signal between 1 and 1."""

        processor = DataProcessor(
            "memory", [AverageData(axis=1),
                       SVD(), MinMaxNormalize()])

        self.assertFalse(processor.is_trained)
        processor.train([self.data.data(idx) for idx in [0, 1]])
        self.assertTrue(processor.is_trained)

        # Test processing of all data
        processed = processor(self.data.data())
        np.testing.assert_array_almost_equal(
            unp.nominal_values(processed),
            np.array([[0.0, 1.0], [1.0, 0.0], [0.5, 0.5], [0.75, 0.25]]),
        )

    def test_distorted_iq_data(self):
        """Test if uncertainty can consider correlation.

        SVD projects IQ data onto I-axis, and input different data sets that
        have the same mean and same variance but squeezed along different axis.
        """
        svd_node = SVD()
        svd_node._scales = [1.0]
        svd_node._main_axes = [np.array([1, 0])]
        svd_node._means = [(0.0, 0.0)]

        processor = DataProcessor("memory", [AverageData(axis=1), svd_node])

        dist_i_axis = {
            "memory": [[[-1, 0]], [[-0.5, 0]], [[0.0, 0]], [[0.5, 0]], [[1,
                                                                         0]]]
        }
        dist_q_axis = {
            "memory": [[[0, -1]], [[0, -0.5]], [[0, 0.0]], [[0, 0.5]], [[0,
                                                                         1]]]
        }

        out_i = processor(dist_i_axis)
        self.assertAlmostEqual(out_i[0].nominal_value, 0.0)
        self.assertAlmostEqual(out_i[0].std_dev, 0.31622776601683794)

        out_q = processor(dist_q_axis)
        self.assertAlmostEqual(out_q[0].nominal_value, 0.0)
        self.assertAlmostEqual(out_q[0].std_dev, 0.0)
예제 #21
0
    def test_get_subset(self):
        """Test that get subset data from full data array."""
        # data to analyze
        fake_data = [
            {
                "data": 1,
                "metadata": {
                    "xval": 1,
                    "type": 1,
                    "valid": True
                }
            },
            {
                "data": 2,
                "metadata": {
                    "xval": 2,
                    "type": 2,
                    "valid": True
                }
            },
            {
                "data": 3,
                "metadata": {
                    "xval": 3,
                    "type": 1,
                    "valid": True
                }
            },
            {
                "data": 4,
                "metadata": {
                    "xval": 4,
                    "type": 3,
                    "valid": True
                }
            },
            {
                "data": 5,
                "metadata": {
                    "xval": 5,
                    "type": 3,
                    "valid": True
                }
            },
            {
                "data": 6,
                "metadata": {
                    "xval": 6,
                    "type": 4,
                    "valid": True
                }
            },  # this if fake
        ]
        expdata = ExperimentData(experiment=FakeExperiment())
        for datum in fake_data:
            expdata.add_data(datum)

        def _processor(datum):
            return datum["data"], datum["data"] * 2

        self.analysis.set_options(x_key="xval")
        self.analysis._extract_curves(expdata, data_processor=_processor)

        filt_data = self.analysis._data(series_name="curve1")
        np.testing.assert_array_equal(filt_data.x,
                                      np.asarray([1, 3], dtype=float))
        np.testing.assert_array_equal(filt_data.y,
                                      np.asarray([1, 3], dtype=float))
        np.testing.assert_array_equal(filt_data.y_err,
                                      np.asarray([2, 6], dtype=float))

        filt_data = self.analysis._data(series_name="curve2")
        np.testing.assert_array_equal(filt_data.x, np.asarray([2],
                                                              dtype=float))
        np.testing.assert_array_equal(filt_data.y, np.asarray([2],
                                                              dtype=float))
        np.testing.assert_array_equal(filt_data.y_err,
                                      np.asarray([4], dtype=float))

        filt_data = self.analysis._data(series_name="curve3")
        np.testing.assert_array_equal(filt_data.x,
                                      np.asarray([4, 5], dtype=float))
        np.testing.assert_array_equal(filt_data.y,
                                      np.asarray([4, 5], dtype=float))
        np.testing.assert_array_equal(filt_data.y_err,
                                      np.asarray([8, 10], dtype=float))
class TestAveragingAndSVD(BaseDataProcessorTest):
    """Test the averaging of single-shot IQ data followed by a SVD."""
    def setUp(self):
        """Here, single-shots average to points at plus/minus 1.

        The setting corresponds to four single-shots done on two qubits.
        """
        super().setUp()

        circ_es = ExperimentResultData(memory=[
            [[1.1, 0.9], [-0.8, 1.0]],
            [[1.2, 1.1], [-0.9, 1.0]],
            [[0.8, 1.1], [-1.2, 1.0]],
            [[0.9, 0.9], [-1.1, 1.0]],
        ])
        self._sig_gs = np.array([[1.0], [-1.0]]) / np.sqrt(2.0)

        circ_gs = ExperimentResultData(memory=[
            [[-1.1, -0.9], [0.8, -1.0]],
            [[-1.2, -1.1], [0.9, -1.0]],
            [[-0.8, -1.1], [1.2, -1.0]],
            [[-0.9, -0.9], [1.1, -1.0]],
        ])
        self._sig_es = np.array([[-1.0], [1.0]]) / np.sqrt(2.0)

        circ_x90p = ExperimentResultData(memory=[
            [[-1.0, -1.0], [1.0, -1.0]],
            [[-1.0, -1.0], [1.0, -1.0]],
            [[1.0, 1.0], [-1.0, 1.0]],
            [[1.0, 1.0], [-1.0, 1.0]],
        ])
        self._sig_x90 = np.array([[0], [0]])

        circ_x45p = ExperimentResultData(memory=[
            [[-1.0, -1.0], [1.0, -1.0]],
            [[-1.0, -1.0], [1.0, -1.0]],
            [[-1.0, -1.0], [1.0, -1.0]],
            [[1.0, 1.0], [-1.0, 1.0]],
        ])
        self._sig_x45 = np.array([[0.5], [-0.5]]) / np.sqrt(2.0)

        res_es = ExperimentResult(
            shots=4,
            success=True,
            meas_level=1,
            meas_return="single",
            data=circ_es,
            header=self.header,
        )

        res_gs = ExperimentResult(
            shots=4,
            success=True,
            meas_level=1,
            meas_return="single",
            data=circ_gs,
            header=self.header,
        )

        res_x90p = ExperimentResult(
            shots=4,
            success=True,
            meas_level=1,
            meas_return="single",
            data=circ_x90p,
            header=self.header,
        )

        res_x45p = ExperimentResult(
            shots=4,
            success=True,
            meas_level=1,
            meas_return="single",
            data=circ_x45p,
            header=self.header,
        )

        self.data = ExperimentData(FakeExperiment())
        self.data.add_data(
            Result(results=[res_es, res_gs, res_x90p, res_x45p],
                   **self.base_result_args))

    def test_averaging(self):
        """Test that averaging of the datums produces the expected IQ points."""

        processor = DataProcessor("memory", [AverageData(axis=1)])

        # Test that we get the expected outcome for the excited state
        processed, error = processor(self.data.data(0))
        expected_avg = np.array([[1.0, 1.0], [-1.0, 1.0]])
        expected_std = np.array([[0.15811388300841894, 0.1],
                                 [0.15811388300841894, 0.0]]) / 2.0
        self.assertTrue(np.allclose(processed, expected_avg))
        self.assertTrue(np.allclose(error, expected_std))

        # Test that we get the expected outcome for the ground state
        processed, error = processor(self.data.data(1))
        expected_avg = np.array([[-1.0, -1.0], [1.0, -1.0]])
        expected_std = np.array([[0.15811388300841894, 0.1],
                                 [0.15811388300841894, 0.0]]) / 2.0
        self.assertTrue(np.allclose(processed, expected_avg))
        self.assertTrue(np.allclose(error, expected_std))

    def test_averaging_and_svd(self):
        """Test averaging followed by a SVD."""

        processor = DataProcessor("memory", [AverageData(axis=1), SVD()])

        # Test training using the calibration points
        self.assertFalse(processor.is_trained)
        processor.train([self.data.data(idx) for idx in [0, 1]])
        self.assertTrue(processor.is_trained)

        # Test the excited state
        processed, error = processor(self.data.data(0))
        self.assertTrue(np.allclose(processed, self._sig_es))

        # Test the ground state
        processed, error = processor(self.data.data(1))
        self.assertTrue(np.allclose(processed, self._sig_gs))

        # Test the x90p rotation
        processed, error = processor(self.data.data(2))
        self.assertTrue(np.allclose(processed, self._sig_x90))
        self.assertTrue(np.allclose(error, np.array([0.25, 0.25])))

        # Test the x45p rotation
        processed, error = processor(self.data.data(3))
        expected_std = np.array([np.std([1, 1, 1, -1]) / np.sqrt(4.0) / 2] * 2)
        self.assertTrue(np.allclose(processed, self._sig_x45))
        self.assertTrue(np.allclose(error, expected_std))

    def test_process_all_data(self):
        """Test that we can process all data at once."""

        processor = DataProcessor("memory", [AverageData(axis=1), SVD()])

        # Test training using the calibration points
        self.assertFalse(processor.is_trained)
        processor.train([self.data.data(idx) for idx in [0, 1]])
        self.assertTrue(processor.is_trained)

        all_expected = np.vstack((
            self._sig_es.reshape(1, 2),
            self._sig_gs.reshape(1, 2),
            self._sig_x90.reshape(1, 2),
            self._sig_x45.reshape(1, 2),
        )).T

        # Test processing of all data
        processed = processor(self.data.data())[0]
        self.assertTrue(np.allclose(processed, all_expected))

        # Test processing of each datum individually
        for idx, expected in enumerate(
            [self._sig_es, self._sig_gs, self._sig_x90, self._sig_x45]):
            processed = processor(self.data.data(idx))[0]
            self.assertTrue(np.allclose(processed, expected))

    def test_normalize(self):
        """Test that by adding a normalization node we get a signal between 1 and 1."""

        processor = DataProcessor(
            "memory", [AverageData(axis=1),
                       SVD(), MinMaxNormalize()])

        self.assertFalse(processor.is_trained)
        processor.train([self.data.data(idx) for idx in [0, 1]])
        self.assertTrue(processor.is_trained)

        all_expected = np.array([[0.0, 1.0, 0.5, 0.75], [1.0, 0.0, 0.5, 0.25]])

        # Test processing of all data
        processed = processor(self.data.data())[0]
        self.assertTrue(np.allclose(processed, all_expected))
class DataProcessorTest(BaseDataProcessorTest):
    """Class to test DataProcessor."""
    def setUp(self):
        """Setup variables used for testing."""
        super().setUp()

        mem1 = ExperimentResultData(memory=[
            [[1103260.0, -11378508.0], [2959012.0, -16488753.0]],
            [[442170.0, -19283206.0], [-5279410.0, -15339630.0]],
            [[3016514.0, -14548009.0], [-3404756.0, -16743348.0]],
        ])

        mem2 = ExperimentResultData(memory=[
            [[5131962.0, -16630257.0], [4438870.0, -13752518.0]],
            [[3415985.0, -16031913.0], [2942458.0, -15840465.0]],
            [[5199964.0, -14955998.0], [4030843.0, -14538923.0]],
        ])

        res1 = ExperimentResult(shots=3,
                                success=True,
                                meas_level=1,
                                data=mem1,
                                header=self.header)
        res2 = ExperimentResult(shots=3,
                                success=True,
                                meas_level=1,
                                data=mem2,
                                header=self.header)

        self.result_lvl1 = Result(results=[res1, res2],
                                  **self.base_result_args)

        raw_counts1 = {"0x0": 4, "0x2": 6}
        raw_counts2 = {"0x0": 2, "0x2": 8}
        data1 = ExperimentResultData(counts=dict(**raw_counts1))
        data2 = ExperimentResultData(counts=dict(**raw_counts2))
        res1 = ExperimentResult(shots=9,
                                success=True,
                                meas_level=2,
                                data=data1,
                                header=self.header)
        res2 = ExperimentResult(shots=9,
                                success=True,
                                meas_level=2,
                                data=data2,
                                header=self.header)
        self.exp_data_lvl2 = ExperimentData(FakeExperiment())
        self.exp_data_lvl2.add_data(
            Result(results=[res1, res2], **self.base_result_args))

    def test_empty_processor(self):
        """Check that a DataProcessor without steps does nothing."""
        data_processor = DataProcessor("counts")

        datum, error = data_processor(self.exp_data_lvl2.data(0))
        self.assertEqual(datum, [{"00": 4, "10": 6}])
        self.assertIsNone(error)

        datum, error, history = data_processor.call_with_history(
            self.exp_data_lvl2.data(0))
        self.assertEqual(datum, [{"00": 4, "10": 6}])
        self.assertEqual(history, [])

    def test_to_real(self):
        """Test scaling and conversion to real part."""
        processor = DataProcessor("memory", [ToReal(scale=1e-3)])

        exp_data = ExperimentData(FakeExperiment())
        exp_data.add_data(self.result_lvl1)

        # Test to real on a single datum
        new_data, error = processor(exp_data.data(0))

        expected_old = {
            "memory": [
                [[1103260.0, -11378508.0], [2959012.0, -16488753.0]],
                [[442170.0, -19283206.0], [-5279410.0, -15339630.0]],
                [[3016514.0, -14548009.0], [-3404756.0, -16743348.0]],
            ],
            "metadata": {
                "experiment_type": "fake_test_experiment"
            },
            "job_id":
            "job-123",
            "meas_level":
            1,
            "shots":
            3,
        }

        expected_new = np.array([[1103.26, 2959.012], [442.17, -5279.41],
                                 [3016.514, -3404.7560]])

        self.assertEqual(exp_data.data(0), expected_old)
        self.assertTrue(np.allclose(new_data, expected_new))
        self.assertIsNone(error)

        # Test that we can call with history.
        new_data, error, history = processor.call_with_history(
            exp_data.data(0))

        self.assertEqual(exp_data.data(0), expected_old)
        self.assertTrue(np.allclose(new_data, expected_new))

        self.assertEqual(history[0][0], "ToReal")
        self.assertTrue(np.allclose(history[0][1], expected_new))

        # Test to real on more than one datum
        new_data, error = processor(exp_data.data())

        expected_new = np.array([
            [[1103.26, 2959.012], [442.17, -5279.41], [3016.514, -3404.7560]],
            [[5131.962, 4438.87], [3415.985, 2942.458], [5199.964, 4030.843]],
        ])

        self.assertTrue(np.allclose(new_data, expected_new))

    def test_to_imag(self):
        """Test that we can average the data."""
        processor = DataProcessor("memory")
        processor.append(ToImag(scale=1e-3))

        exp_data = ExperimentData(FakeExperiment())
        exp_data.add_data(self.result_lvl1)

        new_data, error = processor(exp_data.data(0))

        expected_old = {
            "memory": [
                [[1103260.0, -11378508.0], [2959012.0, -16488753.0]],
                [[442170.0, -19283206.0], [-5279410.0, -15339630.0]],
                [[3016514.0, -14548009.0], [-3404756.0, -16743348.0]],
            ],
            "metadata": {
                "experiment_type": "fake_test_experiment"
            },
            "job_id":
            "job-123",
            "meas_level":
            1,
            "shots":
            3,
        }

        expected_new = np.array([
            [-11378.508, -16488.753],
            [-19283.206000000002, -15339.630000000001],
            [-14548.009, -16743.348],
        ])

        self.assertEqual(exp_data.data(0), expected_old)
        self.assertTrue(np.allclose(new_data, expected_new))
        self.assertIsNone(error)

        # Test that we can call with history.
        new_data, error, history = processor.call_with_history(
            exp_data.data(0))
        self.assertEqual(exp_data.data(0), expected_old)
        self.assertTrue(np.allclose(new_data, expected_new))

        self.assertEqual(history[0][0], "ToImag")
        self.assertTrue(np.allclose(history[0][1], expected_new))

        # Test to imaginary on more than one datum
        new_data, error = processor(exp_data.data())

        expected_new = np.array([
            [[-11378.508, -16488.753], [-19283.206, -15339.630],
             [-14548.009, -16743.348]],
            [[-16630.257, -13752.518], [-16031.913, -15840.465],
             [-14955.998, -14538.923]],
        ])

        self.assertTrue(np.allclose(new_data, expected_new))

    def test_populations(self):
        """Test that counts are properly converted to a population."""

        processor = DataProcessor("counts")
        processor.append(Probability("00"))

        # Test on a single datum.
        new_data, error = processor(self.exp_data_lvl2.data(0))

        self.assertEqual(new_data, 0.4)
        self.assertEqual(error, np.sqrt(0.4 * (1 - 0.4) / 10))

        # Test on all the data
        new_data, error = processor(self.exp_data_lvl2.data())
        self.assertTrue(np.allclose(new_data, np.array([0.4, 0.2])))

    def test_validation(self):
        """Test the validation mechanism."""

        for validate, error in [(False, AttributeError),
                                (True, DataProcessorError)]:
            processor = DataProcessor("counts")
            processor.append(Probability("00", validate=validate))

            with self.assertRaises(error):
                processor({"counts": [0, 1, 2]})
예제 #24
0
class DataProcessorTest(BaseDataProcessorTest):
    """Class to test DataProcessor."""
    def setUp(self):
        """Setup variables used for testing."""
        super().setUp()

        mem1 = ExperimentResultData(memory=[
            [[1103260.0, -11378508.0], [2959012.0, -16488753.0]],
            [[442170.0, -19283206.0], [-5279410.0, -15339630.0]],
            [[3016514.0, -14548009.0], [-3404756.0, -16743348.0]],
        ])

        mem2 = ExperimentResultData(memory=[
            [[5131962.0, -16630257.0], [4438870.0, -13752518.0]],
            [[3415985.0, -16031913.0], [2942458.0, -15840465.0]],
            [[5199964.0, -14955998.0], [4030843.0, -14538923.0]],
        ])

        res1 = ExperimentResult(shots=3,
                                success=True,
                                meas_level=1,
                                data=mem1,
                                header=self.header)
        res2 = ExperimentResult(shots=3,
                                success=True,
                                meas_level=1,
                                data=mem2,
                                header=self.header)

        self.result_lvl1 = Result(results=[res1, res2],
                                  **self.base_result_args)

        raw_counts1 = {"0x0": 4, "0x2": 6}
        raw_counts2 = {"0x0": 2, "0x2": 8}
        data1 = ExperimentResultData(counts=dict(**raw_counts1))
        data2 = ExperimentResultData(counts=dict(**raw_counts2))
        res1 = ExperimentResult(shots=10,
                                success=True,
                                meas_level=2,
                                data=data1,
                                header=self.header)
        res2 = ExperimentResult(shots=10,
                                success=True,
                                meas_level=2,
                                data=data2,
                                header=self.header)
        self.exp_data_lvl2 = ExperimentData(FakeExperiment())
        self.exp_data_lvl2.add_data(
            Result(results=[res1, res2], **self.base_result_args))

    def test_data_prep_level1_memory_single(self):
        """Format meas_level=1 meas_return=single."""
        # slots = 3, shots = 2, circuits = 2
        data_raw = [
            {
                "memory": [
                    [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]],
                    [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]],
                ],
            },
            {
                "memory": [
                    [[0.7, 0.8], [0.9, 1.0], [1.1, 1.2]],
                    [[0.7, 0.8], [0.9, 1.0], [1.1, 1.2]],
                ],
            },
        ]
        formatted_data = DataProcessor("memory", [])._data_extraction(data_raw)

        ref_data = np.array([
            [
                [
                    [ufloat(0.1, np.nan),
                     ufloat(0.2, np.nan)],
                    [ufloat(0.3, np.nan),
                     ufloat(0.4, np.nan)],
                    [ufloat(0.5, np.nan),
                     ufloat(0.6, np.nan)],
                ],
                [
                    [ufloat(0.1, np.nan),
                     ufloat(0.2, np.nan)],
                    [ufloat(0.3, np.nan),
                     ufloat(0.4, np.nan)],
                    [ufloat(0.5, np.nan),
                     ufloat(0.6, np.nan)],
                ],
            ],
            [
                [
                    [ufloat(0.7, np.nan),
                     ufloat(0.8, np.nan)],
                    [ufloat(0.9, np.nan),
                     ufloat(1.0, np.nan)],
                    [ufloat(1.1, np.nan),
                     ufloat(1.2, np.nan)],
                ],
                [
                    [ufloat(0.7, np.nan),
                     ufloat(0.8, np.nan)],
                    [ufloat(0.9, np.nan),
                     ufloat(1.0, np.nan)],
                    [ufloat(1.1, np.nan),
                     ufloat(1.2, np.nan)],
                ],
            ],
        ])

        self.assertTupleEqual(formatted_data.shape, ref_data.shape)
        np.testing.assert_array_equal(unp.nominal_values(formatted_data),
                                      unp.nominal_values(ref_data))
        # note that np.nan cannot be evaluated by "=="
        self.assertTrue(np.isnan(unp.std_devs(formatted_data)).all())

    def test_data_prep_level1_memory_average(self):
        """Format meas_level=1 meas_return=avg."""
        # slots = 3, circuits = 2
        data_raw = [
            {
                "memory": [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]],
            },
            {
                "memory": [[0.7, 0.8], [0.9, 1.0], [1.1, 1.2]],
            },
        ]
        formatted_data = DataProcessor("memory", [])._data_extraction(data_raw)

        ref_data = np.array([
            [
                [ufloat(0.1, np.nan), ufloat(0.2, np.nan)],
                [ufloat(0.3, np.nan), ufloat(0.4, np.nan)],
                [ufloat(0.5, np.nan), ufloat(0.6, np.nan)],
            ],
            [
                [ufloat(0.7, np.nan), ufloat(0.8, np.nan)],
                [ufloat(0.9, np.nan), ufloat(1.0, np.nan)],
                [ufloat(1.1, np.nan), ufloat(1.2, np.nan)],
            ],
        ])

        self.assertTupleEqual(formatted_data.shape, ref_data.shape)
        np.testing.assert_array_equal(unp.nominal_values(formatted_data),
                                      unp.nominal_values(ref_data))
        # note that np.nan cannot be evaluated by "=="
        self.assertTrue(np.isnan(unp.std_devs(formatted_data)).all())

    def test_data_prep_level2_counts(self):
        """Format meas_level=2."""
        # slots = 2, shots=10, circuits = 2
        data_raw = [
            {
                "counts": {
                    "00": 2,
                    "01": 3,
                    "10": 1,
                    "11": 4
                },
            },
            {
                "counts": {
                    "00": 3,
                    "01": 3,
                    "10": 2,
                    "11": 2
                },
            },
        ]
        formatted_data = DataProcessor("counts", [])._data_extraction(data_raw)

        ref_data = np.array(
            [
                {
                    "00": 2,
                    "01": 3,
                    "10": 1,
                    "11": 4
                },
                {
                    "00": 3,
                    "01": 3,
                    "10": 2,
                    "11": 2
                },
            ],
            dtype=object,
        )

        np.testing.assert_array_equal(formatted_data, ref_data)

    def test_data_prep_level2_counts_memory(self):
        """Format meas_level=2 with having memory set."""
        # slots = 2, shots=10, circuits = 2
        data_raw = [
            {
                "counts": {
                    "00": 2,
                    "01": 3,
                    "10": 1,
                    "11": 4
                },
                "memory":
                ["00", "01", "01", "10", "11", "11", "00", "01", "11", "11"],
            },
            {
                "counts": {
                    "00": 3,
                    "01": 3,
                    "10": 2,
                    "11": 2
                },
                "memory":
                ["00", "00", "01", "00", "10", "01", "01", "11", "10", "11"],
            },
        ]
        formatted_data = DataProcessor("memory", [])._data_extraction(data_raw)

        ref_data = np.array(
            [
                ["00", "01", "01", "10", "11", "11", "00", "01", "11", "11"],
                ["00", "00", "01", "00", "10", "01", "01", "11", "10", "11"],
            ],
            dtype=object,
        )

        np.testing.assert_array_equal(formatted_data, ref_data)

    def test_empty_processor(self):
        """Check that a DataProcessor without steps does nothing."""
        data_processor = DataProcessor("counts")

        datum = data_processor(self.exp_data_lvl2.data(0))
        self.assertEqual(datum, {"00": 4, "10": 6})

        datum, history = data_processor.call_with_history(
            self.exp_data_lvl2.data(0))
        self.assertEqual(datum, {"00": 4, "10": 6})
        self.assertEqual(history, [])

    def test_to_real(self):
        """Test scaling and conversion to real part."""
        processor = DataProcessor("memory", [ToReal(scale=1e-3)])

        exp_data = ExperimentData(FakeExperiment())
        exp_data.add_data(self.result_lvl1)

        # Test to real on a single datum
        new_data = processor(exp_data.data(0))

        expected_old = {
            "memory": [
                [[1103260.0, -11378508.0], [2959012.0, -16488753.0]],
                [[442170.0, -19283206.0], [-5279410.0, -15339630.0]],
                [[3016514.0, -14548009.0], [-3404756.0, -16743348.0]],
            ],
            "metadata": {
                "experiment_type": "fake_test_experiment"
            },
            "job_id":
            "job-123",
            "meas_level":
            1,
            "shots":
            3,
        }

        expected_new = np.array([[1103.26, 2959.012], [442.17, -5279.41],
                                 [3016.514, -3404.7560]])

        self.assertEqual(exp_data.data(0), expected_old)
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            expected_new,
        )
        self.assertTrue(np.isnan(unp.std_devs(new_data)).all())

        # Test that we can call with history.
        new_data, history = processor.call_with_history(exp_data.data(0))

        self.assertEqual(exp_data.data(0), expected_old)
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            expected_new,
        )

        self.assertEqual(history[0][0], "ToReal")
        np.testing.assert_array_almost_equal(
            unp.nominal_values(history[0][1]),
            expected_new,
        )

        # Test to real on more than one datum
        new_data = processor(exp_data.data())

        expected_new = np.array([
            [[1103.26, 2959.012], [442.17, -5279.41], [3016.514, -3404.7560]],
            [[5131.962, 4438.87], [3415.985, 2942.458], [5199.964, 4030.843]],
        ])
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            expected_new,
        )

    def test_to_imag(self):
        """Test that we can average the data."""
        processor = DataProcessor("memory")
        processor.append(ToImag(scale=1e-3))

        exp_data = ExperimentData(FakeExperiment())
        exp_data.add_data(self.result_lvl1)

        new_data = processor(exp_data.data(0))

        expected_old = {
            "memory": [
                [[1103260.0, -11378508.0], [2959012.0, -16488753.0]],
                [[442170.0, -19283206.0], [-5279410.0, -15339630.0]],
                [[3016514.0, -14548009.0], [-3404756.0, -16743348.0]],
            ],
            "metadata": {
                "experiment_type": "fake_test_experiment"
            },
            "job_id":
            "job-123",
            "meas_level":
            1,
            "shots":
            3,
        }

        expected_new = np.array([
            [-11378.508, -16488.753],
            [-19283.206000000002, -15339.630000000001],
            [-14548.009, -16743.348],
        ])

        self.assertEqual(exp_data.data(0), expected_old)
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            expected_new,
        )
        self.assertTrue(np.isnan(unp.std_devs(new_data)).all())

        # Test that we can call with history.
        new_data, history = processor.call_with_history(exp_data.data(0))
        self.assertEqual(exp_data.data(0), expected_old)
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            expected_new,
        )

        self.assertEqual(history[0][0], "ToImag")
        np.testing.assert_array_almost_equal(
            unp.nominal_values(history[0][1]),
            expected_new,
        )

        # Test to imaginary on more than one datum
        new_data = processor(exp_data.data())

        expected_new = np.array([
            [[-11378.508, -16488.753], [-19283.206, -15339.630],
             [-14548.009, -16743.348]],
            [[-16630.257, -13752.518], [-16031.913, -15840.465],
             [-14955.998, -14538.923]],
        ])

        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            expected_new,
        )

    def test_populations(self):
        """Test that counts are properly converted to a population."""

        processor = DataProcessor("counts")
        processor.append(Probability("00", alpha_prior=1.0))

        # Test on a single datum.
        new_data = processor(self.exp_data_lvl2.data(0))

        self.assertAlmostEqual(float(unp.nominal_values(new_data)), 0.41666667)
        self.assertAlmostEqual(float(unp.std_devs(new_data)),
                               0.13673544235706114)

        # Test on all the data
        new_data = processor(self.exp_data_lvl2.data())
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            np.array([0.41666667, 0.25]),
        )

    def test_validation(self):
        """Test the validation mechanism."""

        for validate, error in [(False, AttributeError),
                                (True, DataProcessorError)]:
            processor = DataProcessor("counts")
            processor.append(Probability("00", validate=validate))

            with self.assertRaises(error):
                processor({"counts": [0, 1, 2]})
예제 #25
0
class TestIQSingleAvg(BaseDataProcessorTest):
    """Test the IQ data processing nodes single and average."""
    def setUp(self):
        """Setup some IQ data."""
        super().setUp()

        mem_avg = ExperimentResultData(
            memory=[[-539698.0, -153030784.0], [5541283.0, -160369600.0]])
        mem_single = ExperimentResultData(memory=[
            [[-56470872.0, -136691568.0], [-53407256.0, -176278624.0]],
            [[-34623272.0, -151247824.0], [-36650644.0, -170559312.0]],
            [[42658720.0, -153054640.0], [29689970.0, -174671824.0]],
            [[-47387248.0, -177826640.0], [-62149124.0, -165909728.0]],
            [[-51465408.0, -148338000.0], [23157112.0, -165826736.0]],
            [[51426688.0, -142703104.0], [34330920.0, -185572592.0]],
        ])

        res_single = ExperimentResult(
            shots=3,
            success=True,
            meas_level=1,
            meas_return="single",
            data=mem_single,
            header=self.header,
        )
        res_avg = ExperimentResult(shots=6,
                                   success=True,
                                   meas_level=1,
                                   meas_return="avg",
                                   data=mem_avg,
                                   header=self.header)

        # result_single = Result(results=[res_single], **self.base_result_args)
        # result_avg = Result(results=[res_avg], **self.base_result_args)

        self.exp_data_single = ExperimentData(FakeExperiment())
        self.exp_data_single.add_data(
            Result(results=[res_single], **self.base_result_args))

        self.exp_data_avg = ExperimentData(FakeExperiment())
        self.exp_data_avg.add_data(
            Result(results=[res_avg], **self.base_result_args))

    def test_avg_and_single(self):
        """Test that the different nodes process the data correctly."""

        to_real = DataProcessor("memory", [ToReal(scale=1)])
        to_imag = DataProcessor("memory", [ToImag(scale=1)])

        # Test the real single shot node
        new_data = to_real(self.exp_data_single.data(0))
        expected = np.array([
            [-56470872.0, -53407256.0],
            [-34623272.0, -36650644.0],
            [42658720.0, 29689970.0],
            [-47387248.0, -62149124.0],
            [-51465408.0, 23157112.0],
            [51426688.0, 34330920.0],
        ])
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            expected,
        )
        self.assertTrue(np.isnan(unp.std_devs(new_data)).all())

        # Test the imaginary single shot node
        new_data = to_imag(self.exp_data_single.data(0))
        expected = np.array([
            [-136691568.0, -176278624.0],
            [-151247824.0, -170559312.0],
            [-153054640.0, -174671824.0],
            [-177826640.0, -165909728.0],
            [-148338000.0, -165826736.0],
            [-142703104.0, -185572592.0],
        ])
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            expected,
        )

        # Test the real average node
        new_data = to_real(self.exp_data_avg.data(0))
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            np.array([-539698.0, 5541283.0]),
        )

        # Test the imaginary average node
        new_data = to_imag(self.exp_data_avg.data(0))
        np.testing.assert_array_almost_equal(
            unp.nominal_values(new_data),
            np.array([-153030784.0, -160369600.0]),
        )
예제 #26
0
    def test_composite_count_memory_marginalization(self, memory):
        """Test the marginalization of level two memory."""
        test_data = ExperimentData()

        # Simplified experimental data
        datum = {
            "counts": {
                "0 0": 4,
                "0 1": 1,
                "1 0": 2,
                "1 1": 3
            },
            "memory": memory,
            "metadata": {
                "experiment_type":
                "ParallelExperiment",
                "composite_index": [0, 1],
                "composite_metadata": [
                    {
                        "experiment_type": "FineXAmplitude",
                        "qubits": [0]
                    },
                    {
                        "experiment_type": "FineXAmplitude",
                        "qubits": [1]
                    },
                ],
                "composite_qubits": [[0], [1]],
                "composite_clbits": [[0], [1]],
            },
            "shots": 10,
            "meas_level": 2,
        }

        test_data.add_data(datum)

        sub_data = CompositeAnalysis([])._marginalized_component_data(
            test_data.data())
        expected = [
            [{
                "metadata": {
                    "experiment_type": "FineXAmplitude",
                    "qubits": [0]
                },
                "counts": {
                    "0": 6,
                    "1": 4
                },
                "memory": ["0", "0", "1", "0", "0", "1", "1", "0", "0", "1"],
            }],
            [{
                "metadata": {
                    "experiment_type": "FineXAmplitude",
                    "qubits": [1]
                },
                "counts": {
                    "0": 5,
                    "1": 5
                },
                "memory": ["0", "1", "1", "0", "0", "0", "1", "0", "1", "1"],
            }],
        ]

        self.assertListEqual(sub_data, expected)
예제 #27
0
class TestAvgDataAndSVD(BaseDataProcessorTest):
    """Test the SVD and normalization on averaged IQ data."""
    def setUp(self):
        """Here, single-shots average to points at plus/minus 1.

        The setting corresponds to four single-shots done on two qubits.
        """
        super().setUp()

        circ_es = ExperimentResultData(memory=[[1.0, 1.0], [-1.0, 1.0]])
        self._sig_gs = np.array([1.0, -1.0]) / np.sqrt(2.0)

        circ_gs = ExperimentResultData(memory=[[-1.0, -1.0], [1.0, -1.0]])
        self._sig_es = np.array([-1.0, 1.0]) / np.sqrt(2.0)

        circ_x90p = ExperimentResultData(memory=[[0.0, 0.0], [0.0, 0.0]])
        self._sig_x90 = np.array([0, 0])

        circ_x45p = ExperimentResultData(memory=[[-0.5, -0.5], [0.5, -0.5]])
        self._sig_x45 = np.array([0.5, -0.5]) / np.sqrt(2.0)

        res_es = ExperimentResult(
            shots=4,
            success=True,
            meas_level=1,
            meas_return="avg",
            data=circ_es,
            header=self.header,
        )

        res_gs = ExperimentResult(
            shots=4,
            success=True,
            meas_level=1,
            meas_return="avg",
            data=circ_gs,
            header=self.header,
        )

        res_x90p = ExperimentResult(
            shots=4,
            success=True,
            meas_level=1,
            meas_return="avg",
            data=circ_x90p,
            header=self.header,
        )

        res_x45p = ExperimentResult(
            shots=4,
            success=True,
            meas_level=1,
            meas_return="avg",
            data=circ_x45p,
            header=self.header,
        )

        self.data = ExperimentData(FakeExperiment())
        self.data.add_data(
            Result(results=[res_es, res_gs, res_x90p, res_x45p],
                   **self.base_result_args))

    def test_normalize(self):
        """Test that by adding a normalization node we get a signal between 1 and 1."""

        processor = DataProcessor("memory", [SVD(), MinMaxNormalize()])

        self.assertFalse(processor.is_trained)
        processor.train([self.data.data(idx) for idx in [0, 1]])
        self.assertTrue(processor.is_trained)

        # Test processing of all data
        processed = processor(self.data.data())
        np.testing.assert_array_almost_equal(
            unp.nominal_values(processed),
            np.array([[0.0, 1.0], [1.0, 0.0], [0.5, 0.5], [0.75, 0.25]]),
        )
예제 #28
0
    def test_correlated_analysis(self):
        """Tests correlated mitigator generation from experimental data"""
        qubits = [0, 2, 3]
        run_data = [
            {
                "counts": {
                    "000": 989,
                    "010": 12,
                    "100": 7,
                    "001": 15,
                    "101": 1
                },
                "metadata": {
                    "state_label": "000"
                },
                "shots": 1024,
            },
            {
                "counts": {
                    "001": 971,
                    "101": 15,
                    "000": 36,
                    "011": 2
                },
                "metadata": {
                    "state_label": "001"
                },
                "shots": 1024,
            },
            {
                "counts": {
                    "000": 30,
                    "010": 965,
                    "110": 15,
                    "011": 11,
                    "001": 2,
                    "100": 1
                },
                "metadata": {
                    "state_label": "010"
                },
                "shots": 1024,
            },
            {
                "counts": {
                    "011": 955,
                    "111": 15,
                    "010": 26,
                    "001": 27,
                    "110": 1
                },
                "metadata": {
                    "state_label": "011"
                },
                "shots": 1024,
            },
            {
                "counts": {
                    "100": 983,
                    "101": 8,
                    "110": 13,
                    "000": 20
                },
                "metadata": {
                    "state_label": "100"
                },
                "shots": 1024,
            },
            {
                "counts": {
                    "101": 947,
                    "001": 34,
                    "100": 32,
                    "111": 11
                },
                "metadata": {
                    "state_label": "101"
                },
                "shots": 1024,
            },
            {
                "counts": {
                    "100": 26,
                    "110": 965,
                    "010": 21,
                    "111": 11,
                    "000": 1
                },
                "metadata": {
                    "state_label": "110"
                },
                "shots": 1024,
            },
            {
                "counts": {
                    "111": 938,
                    "011": 23,
                    "110": 35,
                    "101": 27,
                    "100": 1
                },
                "metadata": {
                    "state_label": "111"
                },
                "shots": 1024,
            },
        ]

        expected_assignment_matrix = np.array([
            [
                0.96582031, 0.03515625, 0.02929688, 0.0, 0.01953125, 0.0,
                0.00097656, 0.0
            ],
            [
                0.01464844, 0.94824219, 0.00195312, 0.02636719, 0.0,
                0.03320312, 0.0, 0.0
            ],
            [
                0.01171875, 0.0, 0.94238281, 0.02539062, 0.0, 0.0, 0.02050781,
                0.0
            ],
            [
                0.0, 0.00195312, 0.01074219, 0.93261719, 0.0, 0.0, 0.0,
                0.02246094
            ],
            [
                0.00683594, 0.0, 0.00097656, 0.0, 0.95996094, 0.03125,
                0.02539062, 0.00097656
            ],
            [
                0.00097656, 0.01464844, 0.0, 0.0, 0.0078125, 0.92480469, 0.0,
                0.02636719
            ],
            [
                0.0, 0.0, 0.01464844, 0.00097656, 0.01269531, 0.0, 0.94238281,
                0.03417969
            ],
            [
                0.0, 0.0, 0.0, 0.01464844, 0.0, 0.01074219, 0.01074219,
                0.91601562
            ],
        ])
        run_meta = {"physical_qubits": qubits}
        expdata = ExperimentData()
        expdata.add_data(run_data)
        expdata._metadata = run_meta
        exp = CorrelatedReadoutError(qubits)
        result = exp.analysis.run(expdata)
        mitigator = result.analysis_results(0).value

        self.assertEqual(len(qubits), mitigator._num_qubits)
        self.assertEqual(qubits, mitigator._qubits)
        self.assertTrue(
            matrix_equal(expected_assignment_matrix,
                         mitigator.assignment_matrix()))