Beispiel #1
0
    def test_composite_basis(self):
        comp = Basis([('std', 2,), ('std', 1)])

        a = Basis([('std', 2), ('std', 2)])
        b = Basis('std', [2,2])
        self.assertEqual(len(a), len(b))
        self.assertArraysAlmostEqual(np.array(a._matrices), np.array(b._matrices))
Beispiel #2
0
    def test_errgen_construction(self):
        from pygsti.models.gaugegroup import UnitaryGaugeGroupElement

        mx_basis = Basis.cast('pp', 4)
        basis = Basis.cast('pp', 4)
        X = basis['X']
        Y = basis['Y']
        Z = basis['Z']

        # Build known combination to project back to
        errgen = (0.1 * lt.create_elementary_errorgen('H', Z) -
                  0.01 * lt.create_elementary_errorgen('H', X) +
                  0.2 * lt.create_elementary_errorgen('S', X) +
                  0.25 * lt.create_elementary_errorgen('S', Y) +
                  0.05 * lt.create_elementary_errorgen('C', X, Y) -
                  0.01 * lt.create_elementary_errorgen('A', X, Y))
        errgen = bt.change_basis(errgen, 'std', mx_basis)

        eg = op.LindbladErrorgen.from_error_generator(errgen,
                                                      "CPTP",
                                                      'pp',
                                                      truncate=False,
                                                      mx_basis="pp",
                                                      evotype='default')
        self.assertTrue(np.allclose(eg.to_dense(), errgen))

        errgen_copy = eg.copy()

        T = UnitaryGaugeGroupElement(np.identity(4, 'd'))
        errgen_copy.transform_inplace(T)
        self.assertTrue(np.allclose(errgen_copy.to_dense(), eg.to_dense()))
Beispiel #3
0
    def test_expand_contract(self):
        # matrix that operates on 2x2 density matrices, but only on the 0-th and 3-rd
        # elements which correspond to the diagonals of the 2x2 density matrix.
        mxInStdBasis = np.array([[1,0,0,2],
                                 [0,0,0,0],
                                 [0,0,0,0],
                                 [3,0,0,4]],'d')

        # Reduce to a matrix operating on a density matrix space with 2 1x1 blocks (hence [1,1])
        begin = Basis('std', [1,1])
        end   = Basis('std', 2)
        
        mxInReducedBasis = bt.resize_std_mx(mxInStdBasis, 'contract', end, begin)
        #mxInReducedBasis = bt.change_basis(mxInStdBasis, begin, end)
        notReallyContracted = bt.change_basis(mxInStdBasis, 'std', 'std', 4)
        correctAnswer = np.array([[ 1.0,  2.0],
                                  [ 3.0,  4.0]])
        #self.assertArraysAlmostEqual( mxInReducedBasis, correctAnswer )
        self.assertArraysAlmostEqual( notReallyContracted, mxInStdBasis )

        expandedMx = bt.resize_std_mx(mxInReducedBasis, 'expand', begin, end)
        #expandedMx = bt.change_basis(mxInReducedBasis, end, begin)
        expandedMxAgain = bt.change_basis(expandedMx, 'std', 'std', 4)
        self.assertArraysAlmostEqual( expandedMx, mxInStdBasis )
        self.assertArraysAlmostEqual( expandedMxAgain, mxInStdBasis )
Beispiel #4
0
    def setUp(self):
        #Set Model objects to "strict" mode for testing
        ExplicitOpModel._strict = True

        # density matrix == 3x3 block diagonal matrix: a 2x2 block followed by a 1x1 block
        self.stateSpaceDims = [(4, ), (1, )]
        self.stateSpaceUDims = [(2, ), (1, )]
        self.std = Basis.cast('std', 9)
        self.gm = Basis.cast('gm', 9)
        self.stdSmall = Basis.cast('std', [4, 1])
        self.gmSmall = Basis.cast('gm', [4, 1])

        #labels which give a tensor product interp. for the states within each density matrix block
        self.stateSpaceLabels = [('Qhappy', ), ('Lsad', )]

        # Adjust for deprecation of _create_operation
        self.sslbls = statespace.ExplicitStateSpace(self.stateSpaceLabels,
                                                    self.stateSpaceUDims)

        #Build a test gate   -- old # X(pi,Qhappy)*LX(pi,0,2)
        self.testGate = create_operation("LX(pi,0,2)", self.sslbls,
                                         self.stdSmall)
        self.testGateGM_mx = bt.change_basis(self.testGate, self.stdSmall,
                                             self.gmSmall)
        self.expTestGate_mx = bt.flexible_change_basis(self.testGate,
                                                       self.stdSmall, self.std)
        self.expTestGateGM_mx = bt.change_basis(self.expTestGate_mx, self.std,
                                                self.gm)
Beispiel #5
0
 def test_auto_expand(self):
     comp = Basis(matrices=[('std', 2,), ('std', 1)])
     std  = Basis('std', 3)
     mxStd = np.identity(5)
     test   = bt.resize_std_mx(mxStd, 'expand', comp, std)
     test2  = bt.resize_std_mx(test, 'contract', std, comp)
     self.assertArraysAlmostEqual(test2, mxStd)
Beispiel #6
0
 def test_change_between_composites(self):
     a = Basis('std', [2, 1])
     b = Basis('gm',  [2, 1])
     mxStd = np.identity(5)
     test = bt.change_basis(mxStd, a, b)
     self.assertEqual(test.shape, mxStd.shape)
     test2 = bt.change_basis(test, b, a)
     self.assertArraysAlmostEqual(test2, mxStd)
Beispiel #7
0
 def test_flexible_change_basis(self):
     comp  = Basis(matrices=[('gm', 2,), ('gm', 1)])
     std   = Basis('std', 3)
     mx    = np.identity(5)
     test  = bt.flexible_change_basis(mx, comp, std)
     self.assertEqual(test.shape[0], sum(comp.dim.blockDims) ** 2)
     test2 = bt.flexible_change_basis(test, std, comp)
     self.assertArraysAlmostEqual(test2, mx)
Beispiel #8
0
    def setUp(self):
        self.gm = Basis.cast('gm', 4)
        self.pp = Basis.cast('pp', 4)
        self.std = Basis.cast('std', 4)
        self.mxGM = np.array(
            [[1, 0, 0, 0], [0, 0, 1, 0], [0, -1, 0, 0], [0, 0, 0, 1]],
            'complex')

        self.mxStd = bt.change_basis(self.mxGM, self.gm, self.std)
        self.mxPP = bt.change_basis(self.mxGM, self.gm, self.pp)
Beispiel #9
0
    def test_basis_object(self):
        #test a few aspects of a Basis object that other tests miss...
        b = Basis("pp",2)
        beq = b.expanded_equivalent()
        longnm = bt.basis_longname(b)
        lbls = bt.basis_element_labels(b)

        raw_mxs = bt.basis_matrices("pp",2)
        with self.assertRaises(NotImplementedError):
            bt.basis_matrices("foobar",2) #invalid basis name

        print("Dim = ", repr(b.dim) ) # calls Dim.__repr__
Beispiel #10
0
    def __init__(self, errormap, povm=None, mx_basis=None):
        """
        Creates a new LindbladPOVM object.

        Parameters
        ----------
        errormap : MapOperator
            The error generator action and parameterization, encapsulated in
            a gate object.  Usually a :class:`LindbladOp`
            or :class:`ComposedOp` object.  (This argument is *not* copied,
            to allow ComposedPOVMEffects to share error generator
            parameters with other gates and spam vectors.)

        povm : POVM, optional
            A sub-POVM which supplies the set of "reference" effect vectors
            that `errormap` acts on to produce the final effect vectors of
            this LindbladPOVM.  This POVM must be *static*
            (have zero parameters) and its evolution type must match that of
            `errormap`.  If None, then a :class:`ComputationalBasisPOVM` is
            used on the number of qubits appropriate to `errormap`'s dimension.

        mx_basis : {'std', 'gm', 'pp', 'qt'} or Basis object
            The basis for this spam vector. Allowed values are Matrix-unit (std),
            Gell-Mann (gm), Pauli-product (pp), and Qutrit (qt) (or a custom
            basis object).  If None, then this is extracted (if possible) from
            `errormap`.
        """
        self.error_map = errormap
        state_space = self.error_map.state_space

        if mx_basis is None:
            if isinstance(errormap, _op.ExpErrorgenOp) and isinstance(
                    errormap.errorgen, _op.LindbladErrorgen):
                mx_basis = errormap.errorgen.matrix_basis
            else:
                raise ValueError(
                    "Cannot extract a matrix-basis from `errormap` (type %s)" %
                    str(type(errormap)))

        self.matrix_basis = _Basis.cast(mx_basis, state_space)
        evotype = self.error_map._evotype

        if povm is None:
            assert(state_space.num_qubits >= 0), \
                ("A default computational-basis POVM can only be used with an"
                 " integral number of qubits!")
            povm = _ComputationalBasisPOVM(state_space.num_qubits, evotype)
        else:
            assert(povm.evotype == evotype), \
                ("Evolution type of `povm` (%s) must match that of "
                 "`errormap` (%s)!") % (povm.evotype, evotype)
            assert(povm.num_params == 0), \
                "Given `povm` must be static (have 0 parameters)!"
        self.base_povm = povm

        items = []  # init as empty (lazy creation of members)
        _POVM.__init__(self, state_space, evotype, items)
        self.init_gpindices(
        )  # initialize gpindices and subm_rpindices from sub-members
Beispiel #11
0
    def test_build_gatesets(self):
        SQ2 = 1 / np.sqrt(2)
        for defParamType in ("full", "full TP", "static"):
            gateset_simple = pygsti.models.ExplicitOpModel(['Q0'], 'pp',
                                                           defParamType)
            gateset_simple['rho0'] = [SQ2, 0, 0, SQ2]
            gateset_simple[
                'Mdefault'] = pygsti.modelmembers.povms.UnconstrainedPOVM(
                    [('0', [SQ2, 0, 0, -SQ2])], evotype='default')
            gateset_simple['Gi'] = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0],
                                    [0, 0, 0, 1]]

            with self.assertRaises(TypeError):
                gateset_simple['rho0'] = 3.0
            with self.assertRaises(ValueError):
                gateset_simple['rho0'] = [3.0]
            with self.assertRaises(ValueError):
                gateset_simple['Gx'] = [1, 2, 3, 4]
            with self.assertRaises(ValueError):
                gateset_simple['Gx'] = [[1, 2, 3, 4], [5, 6, 7]]

        gateset_badDefParam = pygsti.models.ExplicitOpModel(['Q0'], "pp",
                                                            "full")
        gateset_badDefParam.preps.default_param = "foobar"
        gateset_badDefParam.operations.default_param = "foobar"
        with self.assertRaises(ValueError):
            gateset_badDefParam['rho0'] = [1, 0, 0, 0]
        with self.assertRaises(ValueError):
            gateset_badDefParam['Gi'] = np.identity(4, 'd')

        stateSpace = [(4, )]  # density matrix is a 2x2 matrix
        spaceLabels = [
            ('Q0', )
        ]  # interpret the 2x2 density matrix as a single qubit named 'Q0'

        with self.assertRaises(AssertionError):
            modelconstruction.create_identity_vec(
                Basis.cast("foobar", stateSpace))

        gateset_povm_first = pygsti.models.ExplicitOpModel(
            ['Q0'])  #set effect vector first
        gateset_povm_first['Mdefault'] = pygsti.modelmembers.povms.TPPOVM(
            [('0', modelconstruction.create_spam_vector("0", stateSpace,
                                                        "gm")),
             ('1', modelconstruction.create_spam_vector("1", stateSpace, "gm"))
             ],
            evotype='default')

        with self.assertRaises(ValueError):
            gateset_povm_first['rhoBad'] = np.array([1, 2, 3],
                                                    'd')  #wrong dimension
        with self.assertRaises(ValueError):
            gateset_povm_first[
                'Mdefault'] = pygsti.modelmembers.povms.UnconstrainedPOVM(
                    [('0', np.array([1, 2, 3], 'd'))],
                    evotype='default',
                    state_space=pygsti.baseobjs.StateSpace.cast([
                        ('L0', ), ('L1', ), ('L2', )
                    ]))  #wrong dimension
Beispiel #12
0
    def test_elementary_errorgen_bases(self):

        bases = [Basis.cast('gm', 4), Basis.cast('pp', 4), Basis.cast('PP', 4)]

        for basis in bases:
            print(basis)

            primals = []
            duals = []
            lbls = []
            for lbl, bel in zip(basis.labels[1:], basis.elements[1:]):
                lbls.append("H_%s" % lbl)
                primals.append(lt.create_elementary_errorgen('H', bel))
                duals.append(lt.create_elementary_errorgen_dual('H', bel))
            for lbl, bel in zip(basis.labels[1:], basis.elements[1:]):
                lbls.append("S_%s" % lbl)
                primals.append(lt.create_elementary_errorgen('S', bel))
                duals.append(lt.create_elementary_errorgen_dual('S', bel))
            for i, (lbl,
                    bel) in enumerate(zip(basis.labels[1:],
                                          basis.elements[1:])):
                for lbl2, bel2 in zip(basis.labels[1 + i + 1:],
                                      basis.elements[1 + i + 1:]):
                    lbls.append("C_%s_%s" % (lbl, lbl2))
                    primals.append(
                        lt.create_elementary_errorgen('C', bel, bel2))
                    duals.append(
                        lt.create_elementary_errorgen_dual('C', bel, bel2))
            for i, (lbl,
                    bel) in enumerate(zip(basis.labels[1:],
                                          basis.elements[1:])):
                for lbl2, bel2 in zip(basis.labels[1 + i + 1:],
                                      basis.elements[1 + i + 1:]):
                    lbls.append("A_%s_%s" % (lbl, lbl2))
                    primals.append(
                        lt.create_elementary_errorgen('A', bel, bel2))
                    duals.append(
                        lt.create_elementary_errorgen_dual('A', bel, bel2))

            dot_mx = np.empty((len(duals), len(primals)), complex)
            for i, dual in enumerate(duals):
                for j, primal in enumerate(primals):
                    dot_mx[i, j] = np.vdot(dual.flatten(), primal.flatten())

            self.assertTrue(np.allclose(dot_mx, np.identity(len(lbls), 'd')))
Beispiel #13
0
 def build_gate():
     mx = np.identity(4, 'd')
     ppBasis = Basis.cast("pp", 4)
     return op.LindbladErrorgen.from_operation_matrix(mx,
                                                      "GLND",
                                                      ppBasis,
                                                      truncate=False,
                                                      mx_basis="pp",
                                                      evotype='default')
Beispiel #14
0
    def test_instance(self):
        state_space = statespace.default_space_for_dim(4)
        sop = op.StochasticNoiseOp(state_space)

        sop.from_vector(np.array([0.1, 0.0, 0.0]))
        self.assertArraysAlmostEqual(sop.to_vector(), np.array([0.1, 0., 0.]))

        expected_mx = np.identity(4)
        expected_mx[2, 2] = expected_mx[3, 3] = 0.98  # = 2*(0.1^2)
        self.assertArraysAlmostEqual(sop.to_dense(), expected_mx)

        rho = create_spam_vector("0", "Q0", Basis.cast("pp", [4]))
        self.assertAlmostEqual(
            float(np.dot(rho.T, np.dot(sop.to_dense(), rho))),
            0.99)  # b/c X dephasing w/rate is 0.1^2 = 0.01
Beispiel #15
0
    def __init__(self, state_space, labels, basis1q=None):
        # TODO: docstring - labels must be of form (sslbls, elementary_errorgen_lbl)
        self._labels = tuple(labels) if not isinstance(labels,
                                                       tuple) else labels
        self._label_indices = _collections.OrderedDict([
            (lbl, i) for i, lbl in enumerate(self._labels)
        ])
        self.basis_1q = basis1q if (basis1q is not None) else _Basis.cast(
            'pp', 4)

        self.state_space = state_space
        assert (self.state_space.is_entirely_qubits
                ), "FOGI only works for models containing just qubits (so far)"
        sslbls = self.state_space.tensor_product_block_labels(
            0)  # all the model's state space labels
        self.sslbls = sslbls  # the "support" of this space - the qubit labels
        self._cached_elements = None
Beispiel #16
0
    def __init__(self, vec, basis="pp", evotype="default", state_space=None):
        vector = _State._to_vector(vec)
        if basis is not None:
            if not isinstance(basis, _Basis):
                basis = _Basis.cast(basis, len(
                    vector))  # don't perform this cast if we're given a basis
            firstEl = basis.elsize**-0.25  # not dim, as the dimension of the vector space may be less
            if not _np.isclose(vector[0], firstEl):
                raise ValueError(
                    "Cannot create TPState: first element must equal %g!" %
                    firstEl)
        # if basis is None, don't check first element (hackfor de-serialization, so we don't need to store basis)

        _DenseState.__init__(self, vector, evotype, state_space)
        assert (isinstance(self.columnvec, _ProtectedArray))
        self._paramlbls = _np.array(
            ["VecElement %d" % i for i in range(1, self.dim)], dtype=object)
Beispiel #17
0
    def test_depol_noise_op(self):
        state_space = statespace.default_space_for_dim(4)
        dop = op.DepolarizeOp(state_space)

        dop.from_vector(np.array([0.1]))
        self.assertArraysAlmostEqual(dop.to_vector(), np.array([0.1]))

        expected_mx = np.identity(4)
        expected_mx[1,
                    1] = expected_mx[2,
                                     2] = expected_mx[3,
                                                      3] = 0.96  # = 4*(0.1^2)
        self.assertArraysAlmostEqual(dop.to_dense(), expected_mx)

        rho = create_spam_vector("0", "Q0", Basis.cast("pp", [4]))
        # b/c both X and Y dephasing rates => 0.01 reduction
        self.assertAlmostEqual(
            float(np.dot(rho.T, np.dot(dop.to_dense(), rho))), 0.98)
Beispiel #18
0
    def test_jamiolkowski_ops(self):
        gm = Basis('gm', 2)
        pp = Basis('pp', 2)
        std = Basis('std', 2)
        mxGM = np.array(
            [[1, 0, 0, 0], [0, 0, 1, 0], [0, -1, 0, 0], [0, 0, 0, 1]],
            'complex')

        mxStd = bt.change_basis(mxGM, gm, std)
        mxPP = bt.change_basis(mxGM, gm, pp)

        choiStd = pygsti.jamiolkowski_iso(mxStd, std, std)
        choiStd2 = pygsti.jamiolkowski_iso(mxGM, gm, std)
        choiStd3 = pygsti.jamiolkowski_iso(mxPP, pp, std)
        fastChoiStd = pygsti.fast_jamiolkowski_iso_std(mxStd, std)
        fastChoiStd2 = pygsti.fast_jamiolkowski_iso_std(mxGM, gm)
        fastChoiStd3 = pygsti.fast_jamiolkowski_iso_std(mxPP, pp)

        choiGM = pygsti.jamiolkowski_iso(mxStd, std, gm)
        choiGM2 = pygsti.jamiolkowski_iso(mxGM, gm, gm)
        choiGM3 = pygsti.jamiolkowski_iso(mxPP, pp, gm)

        choiPP = pygsti.jamiolkowski_iso(mxStd, std, pp)
        choiPP2 = pygsti.jamiolkowski_iso(mxGM, gm, pp)
        choiPP3 = pygsti.jamiolkowski_iso(mxPP, pp, pp)

        self.assertArraysAlmostEqual(choiStd, choiStd2)
        self.assertArraysAlmostEqual(choiStd, choiStd3)
        self.assertArraysAlmostEqual(choiStd, fastChoiStd)
        self.assertArraysAlmostEqual(choiStd, fastChoiStd2)
        self.assertArraysAlmostEqual(choiStd, fastChoiStd3)
        self.assertArraysAlmostEqual(choiGM, choiGM2)
        self.assertArraysAlmostEqual(choiGM, choiGM3)
        self.assertArraysAlmostEqual(choiPP, choiPP2)
        self.assertArraysAlmostEqual(choiPP, choiPP3)

        gateStd = pygsti.jamiolkowski_iso_inv(choiStd, std, std)
        gateStd2 = pygsti.jamiolkowski_iso_inv(choiGM, gm, std)
        gateStd3 = pygsti.jamiolkowski_iso_inv(choiPP, pp, std)

        gateGM = pygsti.jamiolkowski_iso_inv(choiStd, std, gm)
        gateGM2 = pygsti.jamiolkowski_iso_inv(choiGM, gm, gm)
        gateGM3 = pygsti.jamiolkowski_iso_inv(choiPP, pp, gm)

        gatePP = pygsti.jamiolkowski_iso_inv(choiStd, std, pp)
        gatePP2 = pygsti.jamiolkowski_iso_inv(choiGM, gm, pp)
        gatePP3 = pygsti.jamiolkowski_iso_inv(choiPP, pp, pp)

        fastGateStd = pygsti.fast_jamiolkowski_iso_std_inv(choiStd, std)
        fastGateGM = pygsti.fast_jamiolkowski_iso_std_inv(choiStd, gm)
        fastGatePP = pygsti.fast_jamiolkowski_iso_std_inv(choiStd, pp)

        self.assertArraysAlmostEqual(gateStd, mxStd)
        self.assertArraysAlmostEqual(gateStd2, mxStd)
        self.assertArraysAlmostEqual(gateStd3, mxStd)
        self.assertArraysAlmostEqual(fastGateStd, mxStd)

        self.assertArraysAlmostEqual(gateGM, mxGM)
        self.assertArraysAlmostEqual(gateGM2, mxGM)
        self.assertArraysAlmostEqual(gateGM3, mxGM)
        self.assertArraysAlmostEqual(fastGateGM, mxGM)

        self.assertArraysAlmostEqual(gatePP, mxPP)
        self.assertArraysAlmostEqual(gatePP2, mxPP)
        self.assertArraysAlmostEqual(gatePP3, mxPP)
        self.assertArraysAlmostEqual(fastGatePP, mxPP)
        '''
        with self.assertRaises(NotImplementedError):
            pygsti.jamiolkowski_iso(mxStd, "foobar", gm) #invalid gate basis
        with self.assertRaises(NotImplementedError):
            pygsti.jamiolkowski_iso(mxStd, std, "foobar") #invalid choi basis
        with self.assertRaises(NotImplementedError):
            pygsti.jamiolkowski_iso_inv(choiStd, "foobar", gm) #invalid choi basis
        with self.assertRaises(NotImplementedError):
            pygsti.jamiolkowski_iso_inv(choiStd, std, "foobar") #invalid gate basis
        '''

        sumOfNeg = pygsti.sum_of_negative_choi_evals(std1Q.gs_target)
        sumOfNegWt = pygsti.sum_of_negative_choi_evals(std1Q.gs_target, {
            'Gx': 1.0,
            'Gy': 0.5
        })
        sumsOfNeg = pygsti.sums_of_negative_choi_evals(std1Q.gs_target)
        magsOfNeg = pygsti.mags_of_negative_choi_evals(std1Q.gs_target)
        self.assertAlmostEqual(sumOfNeg, 0.0)
        self.assertArraysAlmostEqual(sumsOfNeg,
                                     np.zeros(3,
                                              'd'))  # 3 gates in std.gs_target
        self.assertArraysAlmostEqual(magsOfNeg, np.zeros(
            12, 'd'))  # 3 gates * 4 evals each = 12
Beispiel #19
0
 def test_gm_basis(self):
     cmb = Basis('gm', sum(self.stateSpaceDims))
     self.checkBasis(cmb)
Beispiel #20
0
 def test_std_basis(self):
     cmb = Basis('std', sum(self.stateSpaceDims))
     self.checkBasis(cmb)
Beispiel #21
0
 def test_raises_on_invalid_conversion_type(self):
     basis = Basis.cast("pp", 4)
     with self.assertRaises(ValueError):
         states.convert(self.vec, "foobar", basis)
Beispiel #22
0
 def test_gm_basis(self):
     #mx_dim = sum([ int(np.sqrt(d)) for d in self.stateSpaceDims])
     cmb = Basis.cast('gm', self.stateSpaceDims)
     self.checkBasis(cmb)
Beispiel #23
0
 def test_convert(self):
     basis = Basis.cast("pp", 4)
     conv = states.convert(self.vec, "static", basis)
Beispiel #24
0
 def _from_memoized_dict(cls, mm_dict, serial_memo):
     errormap = serial_memo[mm_dict['submembers'][0]]
     base_povm = serial_memo[mm_dict['submembers'][1]] if len(
         mm_dict['submembers']) > 1 else None
     mx_basis = _Basis.from_nice_serialization(mm_dict['matrix_basis'])
     return cls(errormap, base_povm, mx_basis)
Beispiel #25
0
    def test_sparse_basis(self):
        sparsePP = Basis("pp",2,sparse=True)
        sparsePP2 = Basis("pp",2,sparse=True)
        sparseBlockPP = Basis("pp",[2,2],sparse=True)
        sparsePP_2Q = Basis("pp",4,sparse=True)
        sparseGM_2Q = Basis("gm",2,sparse=True) #different sparsity structure than PP 2Q
        denseGM = Basis("gm",2,sparse=False)
        
        mxs = sparsePP.get_composite_matrices()
        block_mxs = sparseBlockPP.get_composite_matrices()

        expeq = sparsePP.expanded_equivalent()
        block_expeq = sparseBlockPP.expanded_equivalent()

        raw_mxs = bt.basis_matrices("pp",2,sparse=True)
        
        #test equality of bases with other bases and matrices
        self.assertEqual(sparsePP, sparsePP2)
        self.assertEqual(sparsePP, raw_mxs)
        self.assertNotEqual(sparsePP, sparsePP_2Q)
        self.assertNotEqual(sparsePP_2Q, sparseGM_2Q)

        #sparse transform matrix
        trans = sparsePP.transform_matrix(sparsePP2)
        self.assertArraysAlmostEqual(trans, np.identity(4,'d'))
        trans2 = sparsePP.transform_matrix(denseGM)

        #test equality for large bases, which is too expensive so it always returns false
        large_sparsePP = Basis("pp",16,sparse=True)
        large_sparsePP2 = Basis("pp",16,sparse=True)
        self.assertNotEqual(large_sparsePP, large_sparsePP2)
Beispiel #26
0
    def test_general(self):
        Basis('pp', 2)
        Basis('std', [2, 1])
        Basis([('std', 2), ('gm', 2)])

        std  = Basis('std', 2)
        std4  = Basis('std', 4)
        std2x2 = Basis([('std', 2), ('std', 2)])
        gm   = Basis('gm', 2)
        ungm = Basis('gm_unnormalized', 2)
        empty = Basis([]) #special "empty" basis
        self.assertEqual(empty.name, "*Empty*")

        from_basis,to_basis = pygsti.tools.build_basis_pair(np.identity(4,'d'),"std","gm")
        from_basis,to_basis = pygsti.tools.build_basis_pair(np.identity(4,'d'),std,"gm")
        from_basis,to_basis = pygsti.tools.build_basis_pair(np.identity(4,'d'),"std",gm)

        gm_mxs = gm.get_composite_matrices()
        unnorm = Basis(matrices=[ gm_mxs[0], 2*gm_mxs[1] ])

        std[0]
        std.get_sub_basis_matrices(0)

        print(gm.get_composite_matrices())
        self.assertTrue(gm.is_normalized())
        self.assertFalse(ungm.is_normalized())
        self.assertFalse(unnorm.is_normalized())

        transMx = bt.transform_matrix(std, gm)

        composite = Basis([std, gm])

        comp = Basis(matrices=[std, gm], name='comp', longname='CustomComposite')

        comp.labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
        comp = Basis(matrices=[std, gm], name='comp', longname='CustomComposite', labels=[
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'
            ])

        std2x2Matrices = np.array([
            [[1, 0],
             [0, 0]],
            
            [[0, 1],
             [0, 0]],
            
            [[0, 0],
             [1, 0]],
            
            [[0, 0],
             [0, 1]]
        ],'complex')

        empty = Basis(matrices=[])
        alt_standard = Basis(matrices=std2x2Matrices)
        print("MXS = \n",alt_standard._matrices)
        alt_standard = Basis(matrices=std2x2Matrices,
                             name='std',
                             longname='Standard'
                            )
        self.assertEqual(alt_standard, std2x2Matrices)

        mx = np.array([
                [1, 0, 0, 1],
                [0, 1, 2, 0],
                [0, 2, 1, 0],
                [1, 0, 0, 1]
            ])

        bt.change_basis(mx, 'std', 'gm') # shortname lookup
        bt.change_basis(mx, std, gm) # object
        bt.change_basis(mx, std, 'gm') # combination
        bt.flexible_change_basis(mx, std, gm) #same dimension
        I2x2 = np.identity(8,'d')
        I4 = bt.flexible_change_basis(I2x2, std2x2, std4)
        self.assertArraysAlmostEqual(bt.flexible_change_basis(I4, std4, std2x2), I2x2)
        
        with self.assertRaises(ValueError):
            bt.change_basis(mx, std, std4) # basis size mismatch
        
        
        mxInStdBasis = np.array([[1,0,0,2],
                                 [0,0,0,0],
                                 [0,0,0,0],
                                 [3,0,0,4]],'d')

        begin = Basis('std', [1,1])
        end   = Basis('std', 2)
        mxInReducedBasis = bt.resize_std_mx(mxInStdBasis, 'contract', end, begin)
        original         = bt.resize_std_mx(mxInReducedBasis, 'expand', begin, end)
Beispiel #27
0
 def test_qt(self):
     qt = Basis('qt', 3)
     qt = Basis('qt', [3])
Beispiel #28
0
def create_qutrit_model(error_scale, x_angle=_np.pi / 2, y_angle=_np.pi / 2,
                        ms_global=_np.pi / 2, ms_local=0,
                        similarity=False, seed=None, basis='qt', evotype='default'):
    """
    Constructs a standard qutrit :class:`Model`.

    This model contains the identity, XX, YY, and Molmer-Sorenson gates.

    Parameters
    ----------
    error_scale : float
        Magnitude of random rotations to apply to the returned model.  If
        zero, then perfect "ideal" gates are constructed.

    x_angle : float, optional
        The rotation angle of each X in the XX gate.

    y_angle : float, optional
        The rotation angle of each Y in the YY gate.

    ms_global : float, optional
        The global Molmer-Sorenson angle (theta)

    ms_local : float, optional
        The local Molmer-Sorenson angle (theta)

    similarity : bool, optional
        If true, then apply the random rotations (whose strengths are given
        by `error_scale`) as similarity transformations rather than just as
        post-multiplications to the ideal operation matrices.

    seed : int, optional
        The seed used to generate random rotations.

    basis : str, optional
        The string abbreviation of the basis of the returned vector.  Allowed
        values are Matrix-unit (std), Gell-Mann (gm) and Qutrit (qt).  A `Basis`
        object may also be used.

    evotype : Evotype or str, optional
        The evolution type.  The special value `"default"` is equivalent
        to specifying the value of `pygsti.evotypes.Evotype.default_evotype`.

    Returns
    -------
    Model
    """
    arrType = _np.array  # Are we casting gates as matrices or arrays?

    rho0 = arrType(([[1, 0, 0],
                     [0, 0, 0],
                     [0, 0, 0]]))

    identity3 = arrType(_np.identity(3))

    E0 = arrType(_np.diag([1, 0, 0]))
    E1 = arrType(_np.diag([0, 1, 0]))
    E2 = arrType(_np.diag([0, 0, 1]))

    #Define gates as unitary ops on Hilbert space
    gateImx = arrType(identity3)
    gateXmx = arrType(_xx_qutrit(x_angle))
    gateYmx = arrType(_yy_qutrit(y_angle))
    gateMmx = arrType(_ms_qutrit(ms_global, ms_local))

    #Now introduce unitary noise.
    scale = error_scale
    rndm = _np.random.RandomState(seed)
    Xrand = _random_rot(scale, rndm)
    Yrand = _random_rot(scale, rndm)
    Mrand = _random_rot(scale, rndm)
    Irand = _random_rot(scale, rndm)

    if similarity:  # Change basis for each gate; this preserves rotation angles, and should map identity to identity
        gateXmx = _np.dot(_np.dot(_np.conj(Xrand).T, gateXmx), Xrand)
        gateYmx = _np.dot(_np.dot(_np.conj(Yrand).T, gateYmx), Yrand)
        gateMmx = _np.dot(_np.dot(_np.conj(Mrand).T, gateMmx), Mrand)
        gateImx = _np.dot(_np.dot(_np.conj(Irand).T, gateImx), Irand)

    else:
        gateXmx = _np.dot(gateXmx, Xrand)
        gateYmx = _np.dot(gateYmx, Yrand)
        gateMmx = _np.dot(gateMmx, Mrand)
        gateImx = _np.dot(gateImx, Irand)

    #Change gate representation to superoperator in Gell-Mann basis
    gateISOfinal = unitary_to_superop(gateImx, basis)
    gateXSOfinal = unitary_to_superop(gateXmx, basis)
    gateYSOfinal = unitary_to_superop(gateYmx, basis)
    gateMSOfinal = unitary_to_superop(gateMmx, basis)

    rho0final = change_basis(_np.reshape(rho0, (9, 1)), "std", basis)
    E0final = change_basis(_np.reshape(E0, (9, 1)), "std", basis)
    E1final = change_basis(_np.reshape(E1, (9, 1)), "std", basis)
    E2final = change_basis(_np.reshape(E2, (9, 1)), "std", basis)

    state_space = _statespace.ExplicitStateSpace(['QT'], [3])
    qutritMDL = _ExplicitOpModel(state_space, _Basis.cast(basis, 9), evotype=evotype)
    qutritMDL.preps['rho0'] = rho0final
    qutritMDL.povms['Mdefault'] = _UnconstrainedPOVM([('0bright', E0final),
                                                      ('1bright', E1final),
                                                      ('2bright', E2final)], evotype=evotype)
    qutritMDL.operations['Gi'] = _FullArbitraryOp(arrType(gateISOfinal), evotype, state_space)
    qutritMDL.operations['Gx'] = _FullArbitraryOp(arrType(gateXSOfinal), evotype, state_space)
    qutritMDL.operations['Gy'] = _FullArbitraryOp(arrType(gateYSOfinal), evotype, state_space)
    qutritMDL.operations['Gm'] = _FullArbitraryOp(arrType(gateMSOfinal), evotype, state_space)
    qutritMDL.default_gauge_group = _FullGaugeGroup(state_space, evotype)

    return qutritMDL