예제 #1
0
    def test_model_with_lgst_circuit_estimates(self):
        model = directx.model_with_lgst_circuit_estimates(self.strs,
                                                          self.ds,
                                                          self.prepStrs,
                                                          self.effectStrs,
                                                          self.tgt,
                                                          svd_truncate_to=4,
                                                          verbosity=10)
        # TODO assert correctness

        model = directx.model_with_lgst_circuit_estimates(
            self.strs,
            self.ds,
            self.prepStrs,
            self.effectStrs,
            self.tgt,
            include_target_ops=False,
            svd_truncate_to=4,
            verbosity=10)
        # TODO assert correctness

        circuit_labels = [L('G0'), L('G1'), L('G2'), L('G3'), L('G4'), L('G5')]
        # circuit_labels = [L('G0'), L('G1'), L('G2'), L('G3')]
        model = directx.model_with_lgst_circuit_estimates(
            self.strs,
            self.ds,
            self.prepStrs,
            self.effectStrs,
            self.tgt,
            circuit_labels=circuit_labels,
            include_target_ops=False,
            svd_truncate_to=4,
            verbosity=10)
        self.assertEqual(set(model.operations.keys()), set(circuit_labels))
예제 #2
0
    def test_random_circuit(self):

        n_qubits = 4
        qubit_labels = ['Q0', 'Q1', 'Q2', 'Q3']
        gate_names = ['Gxpi2', 'Gxmpi2', 'Gypi2', 'Gympi2', 'Gcphase']
        availability = {
            'Gcphase': [('Q0', 'Q1'), ('Q1', 'Q2'), ('Q2', 'Q3'), ('Q3', 'Q0')]
        }
        pspec = QPS(n_qubits,
                    gate_names,
                    availability=availability,
                    qubit_labels=qubit_labels)
        depth = 10
        circuit = _rc.create_random_circuit(pspec,
                                            depth,
                                            sampler='Qelimination',
                                            samplerargs=[0.5])
        circuit = _rc.create_random_circuit(pspec,
                                            depth,
                                            sampler='edgegrab',
                                            samplerargs=[0.25])

        C2QGs1 = [
        ]  #  A list containing no 2-qubit gates is an acceptable set of compatible 2-qubit gates.
        C2QGs2 = [
            L('Gcphase', ('Q0', 'Q1')),
        ]
        C2QGs3 = [
            L('Gcphase', ('Q1', 'Q2')),
        ]
        C2QGs4 = [
            L('Gcphase', ('Q2', 'Q3')),
        ]
        C2QGs5 = [
            L('Gcphase', ('Q3', 'Q0')),
        ]
        C2QGs6 = [
            L('Gcphase', ('Q0', 'Q1')),
            L('Gcphase', ('Q2', 'Q3')),
        ]
        C2QGs7 = [
            L('Gcphase', ('Q1', 'Q2')),
            L('Gcphase', ('Q3', 'Q0')),
        ]

        co2Qgates = [C2QGs1, C2QGs2, C2QGs3, C2QGs4, C2QGs5, C2QGs6, C2QGs7]
        co2Qgatesprob = [0.5, 0.125, 0.125, 0.125, 0.125, 0, 0]
        twoQprob = 1

        samplerargs = [co2Qgates, co2Qgatesprob, twoQprob]
        circuit = _rc.create_random_circuit(pspec,
                                            depth,
                                            sampler='co2Qgates',
                                            samplerargs=samplerargs)

        co2Qgates = [C2QGs1, [C2QGs2, C2QGs3, C2QGs4, C2QGs5]]
        co2Qgatesprob = [0.5, 0.5]
        twoQprob = 1
        samplerargs = [
            co2Qgates,
        ]
        circuit = _rc.create_random_circuit(pspec,
                                            depth,
                                            sampler='co2Qgates',
                                            samplerargs=samplerargs)
예제 #3
0
    def test_confidenceRegion(self):

        edesign = proto.CircuitListsDesign([pygsti.circuits.CircuitList(circuit_struct)
                                            for circuit_struct in self.gss])
        data = proto.ProtocolData(edesign, self.ds)
        res = proto.ModelEstimateResults(data, proto.StandardGST(modes="TP"))

        #Add estimate for hessian-based CI --------------------------------------------------
        builder = pygsti.objectivefns.PoissonPicDeltaLogLFunction.builder()
        res.add_estimate(
            proto.estimate.Estimate.create_gst_estimate(
                res, stdxyi.target_model(), stdxyi.target_model(),
                [self.model] * len(self.maxLengthList), parameters={'final_objfn_builder': builder}),
            estimate_key="default"
        )

        est = res.estimates['default']
        est.add_confidence_region_factory('final iteration estimate', 'final')
        self.assertWarns(est.add_confidence_region_factory, 'final iteration estimate','final') #overwrites former
        self.assertTrue( est.has_confidence_region_factory('final iteration estimate', 'final'))

        cfctry = est.create_confidence_region_factory('final iteration estimate', 'final')
        self.assertFalse( cfctry.can_construct_views() ) # b/c no hessian or LR enabled yet...
        cfctry.compute_hessian(approximate=True)
        cfctry.compute_hessian()
        self.assertTrue( cfctry.has_hessian )
        self.assertFalse( cfctry.can_construct_views() ) # b/c hessian isn't projected yet...

        mdl_dummy = cfctry.model # test method
        s = pickle.dumps(cfctry) # test pickle
        pickle.loads(s)

        cfctry.project_hessian('std')
        cfctry.project_hessian('none')
        cfctry.project_hessian('optimal gate CIs')
        cfctry.project_hessian('intrinsic error')
        with self.assertRaises(ValueError):
            cfctry.project_hessian(95.0, 'normal', 'FooBar') #bad hessianProjection

        self.assertTrue( cfctry.can_construct_views() )

        ci_std = cfctry.view( 95.0, 'normal', 'std')
        ci_noproj = cfctry.view( 95.0, 'normal', 'none')
        ci_intrinsic = cfctry.view( 95.0, 'normal', 'intrinsic error')
        ci_opt = cfctry.view( 95.0, 'normal', 'optimal gate CIs')

        with self.assertRaises(ValueError):
            cfctry.view(95.0, 'foobar') #bad region type

        self.assertWarns(cfctry.view, 0.95, 'normal', 'none') # percentage < 1.0


        #Add estimate for linresponse-based CI --------------------------------------------------
        res.add_estimate(
            proto.estimate.Estimate.create_gst_estimate(
                res, stdxyi.target_model(), stdxyi.target_model(),
                [self.model]*len(self.maxLengthList), parameters={'final_objfn_builder': builder}),
            estimate_key="linresponse"
        )

        estLR = res.estimates['linresponse']

        #estLR.add_confidence_region_factory('final iteration estimate', 'final') #Could do this, but use alt. method for more coverage
        with self.assertRaises(KeyError):
            estLR.create_confidence_region_factory('final iteration estimate', 'final') #won't create by default
        cfctryLR = estLR.create_confidence_region_factory('final iteration estimate', 'final', create_if_needed=True) #now it will
        self.assertTrue( estLR.has_confidence_region_factory('final iteration estimate', 'final'))

        #cfctryLR = estLR.create_confidence_region_factory('final iteration estimate', 'final') #done by 'get' call above
        self.assertFalse( cfctryLR.can_construct_views() ) # b/c no hessian or LR enabled yet...
        cfctryLR.enable_linear_response_errorbars() #parent results object is used to automatically populate params

        #self.assertTrue( cfctryLR.can_construct_views() )
        ci_linresponse = cfctryLR.view( 95.0, 'normal', None)

        mdl_dummy = cfctryLR.model # test method
        s = pickle.dumps(cfctryLR) # test pickle
        pickle.loads(s)


        #Add estimate for with bad objective ---------------------------------------------------------
        class FooBar:
            def __init__(self):
                self.cls_to_build = list  # an invalid objective class
                self.regularization = {}
                self.penalties = {}
        
        res.add_estimate(
            proto.estimate.Estimate.create_gst_estimate(
                res, stdxyi.target_model(), stdxyi.target_model(),
                [self.model]*len(self.maxLengthList), parameters={'final_objfn_builder': FooBar()}),
            estimate_key="foo"
        )

        est = res.estimates['foo']
        est.add_confidence_region_factory('final iteration estimate', 'final')
        with self.assertRaises(ValueError): # bad objective
            est.create_confidence_region_factory('final iteration estimate', 'final').compute_hessian()



        # Now test each of the views we created above ------------------------------------------------
        for ci_cur in (ci_std, ci_noproj, ci_opt, ci_intrinsic, ci_linresponse):

            s = pickle.dumps(ci_cur) # test pickle
            pickle.loads(s)

            #linear response CI doesn't support profile likelihood intervals
            if ci_cur is not ci_linresponse: # (profile likelihoods not implemented in this case)
                ar_of_intervals_Gx = ci_cur.retrieve_profile_likelihood_confidence_intervals(L("Gx"))
                ar_of_intervals_rho0 = ci_cur.retrieve_profile_likelihood_confidence_intervals(L("rho0"))
                ar_of_intervals_M0 = ci_cur.retrieve_profile_likelihood_confidence_intervals(L("Mdefault"))
                ar_of_intervals = ci_cur.retrieve_profile_likelihood_confidence_intervals()

                with self.assertRaises(ValueError):
                    ci_cur.retrieve_profile_likelihood_confidence_intervals("foobar") #invalid label

            def fnOfGate_float(mx,b):
                return float(mx[0,0])
            def fnOfGate_complex(mx,b):
                return complex(mx[0,0] + 1.0j)
            def fnOfGate_0D(mx,b):
                return np.array( float(mx[0,0]) )
            def fnOfGate_1D(mx,b):
                return mx[0,:]
            def fnOfGate_2D(mx,b):
                return mx[:,:]
            def fnOfGate_2D_complex(mx,b):
                return np.array(mx[:,:] + 1j*mx[:,:],'complex')
            def fnOfGate_3D(mx,b):
                return np.zeros( (2,2,2), 'd') #just to test for error

            fns = (fnOfGate_float, fnOfGate_0D, fnOfGate_1D,
                   fnOfGate_2D, fnOfGate_3D)
            if ci_cur is not ci_linresponse: # complex functions not supported by linresponse CIs
                fns += (fnOfGate_complex, fnOfGate_2D_complex)

            for fnOfOp in fns:
                FnClass = gsf.opfn_factory(fnOfOp)
                FnObj = FnClass(self.model, 'Gx')
                if fnOfOp is fnOfGate_3D:
                    with self.assertRaises(ValueError):
                        df = ci_cur.compute_confidence_interval(FnObj, verbosity=0)
                else:
                    df = ci_cur.compute_confidence_interval(FnObj, verbosity=0)
                    df, f0 = self.runSilent(ci_cur.compute_confidence_interval,
                                            FnObj, return_fn_val=True, verbosity=4)

            ##SHORT-CIRCUIT linear reponse here to reduce run time
            if ci_cur is ci_linresponse: continue

            def fnOfVec_float(v,b):
                return float(v[0])
            def fnOfVec_0D(v,b):
                return np.array( float(v[0]) )
            def fnOfVec_1D(v,b):
                return np.array(v[:])
            def fnOfVec_2D(v,b):
                return np.dot(v.T,v)
            def fnOfVec_3D(v,b):
                return np.zeros( (2,2,2), 'd') #just to test for error

            for fnOfVec in (fnOfVec_float, fnOfVec_0D, fnOfVec_1D, fnOfVec_2D, fnOfVec_3D):
                FnClass = gsf.vecfn_factory(fnOfVec)
                FnObj = FnClass(self.model, 'rho0', 'prep')
                if fnOfVec is fnOfVec_3D:
                    with self.assertRaises(ValueError):
                        df = ci_cur.compute_confidence_interval(FnObj, verbosity=0)
                else:
                    df = ci_cur.compute_confidence_interval(FnObj, verbosity=0)
                    df, f0 = self.runSilent(ci_cur.compute_confidence_interval,
                                            FnObj, return_fn_val=True, verbosity=4)

            for fnOfVec in (fnOfVec_float, fnOfVec_0D, fnOfVec_1D, fnOfVec_2D, fnOfVec_3D):
                FnClass = gsf.vecfn_factory(fnOfVec)
                FnObj = FnClass(self.model, 'Mdefault:0', 'effect')
                if fnOfVec is fnOfVec_3D:
                    with self.assertRaises(ValueError):
                        df = ci_cur.compute_confidence_interval(FnObj, verbosity=0)
                else:
                    df = ci_cur.compute_confidence_interval(FnObj, verbosity=0)
                    df, f0 = self.runSilent(ci_cur.compute_confidence_interval,
                                            FnObj, return_fn_val=True, verbosity=4)


            def fnOfSpam_float(rhoVecs, povms):
                lbls = list(povms[0].keys())
                return float( np.dot( rhoVecs[0].T, povms[0][lbls[0]] ) )
            def fnOfSpam_0D(rhoVecs, povms):
                lbls = list(povms[0].keys())
                return np.array( float( np.dot( rhoVecs[0].T, povms[0][lbls[0]] ) ) )
            def fnOfSpam_1D(rhoVecs, povms):
                lbls = list(povms[0].keys())
                return np.array( [ np.dot( rhoVecs[0].T, povms[0][lbls[0]] ), 0] )
            def fnOfSpam_2D(rhoVecs, povms):
                lbls = list(povms[0].keys())
                return np.array( [[ np.dot( rhoVecs[0].T, povms[0][lbls[0]] ), 0],[0,0]] )
            def fnOfSpam_3D(rhoVecs, povms):
                return np.zeros( (2,2,2), 'd') #just to test for error

            for fnOfSpam in (fnOfSpam_float, fnOfSpam_0D, fnOfSpam_1D, fnOfSpam_2D, fnOfSpam_3D):
                FnClass = gsf.spamfn_factory(fnOfSpam)
                FnObj = FnClass(self.model)
                if fnOfSpam is fnOfSpam_3D:
                    with self.assertRaises(ValueError):
                        df = ci_cur.compute_confidence_interval(FnObj, verbosity=0)
                else:
                    df = ci_cur.compute_confidence_interval(FnObj, verbosity=0)
                    df, f0 = self.runSilent(ci_cur.compute_confidence_interval,
                                            FnObj, return_fn_val=True, verbosity=4)


            def fnOfGateSet_float(mdl):
                return float( mdl.operations['Gx'][0,0] )
            def fnOfGateSet_0D(mdl):
                return np.array( mdl.operations['Gx'][0,0]  )
            def fnOfGateSet_1D(mdl):
                return np.array( mdl.operations['Gx'][0,:] )
            def fnOfGateSet_2D(mdl):
                return np.array( mdl.operations['Gx'] )
            def fnOfGateSet_3D(mdl):
                return np.zeros( (2,2,2), 'd') #just to test for error

            for fnOfGateSet in (fnOfGateSet_float, fnOfGateSet_0D, fnOfGateSet_1D, fnOfGateSet_2D, fnOfGateSet_3D):
                FnClass = gsf.modelfn_factory(fnOfGateSet)
                FnObj = FnClass(self.model)
                if fnOfGateSet is fnOfGateSet_3D:
                    with self.assertRaises(ValueError):
                        df = ci_cur.compute_confidence_interval(FnObj, verbosity=0)
                else:
                    df = ci_cur.compute_confidence_interval(FnObj, verbosity=0)
                    df, f0 = self.runSilent(ci_cur.compute_confidence_interval,
                                            FnObj, return_fn_val=True, verbosity=4)
예제 #4
0
    def test_3Q(self):

        ##only test when reps are fast (b/c otherwise this test is slow!)
        #try: from pygsti.objects.replib import fastreplib
        #except ImportError:
        #    warnings.warn("Skipping test_3Q b/c no fastreps!")
        #    return

        nQubits = 3
        print("Constructing Target LinearOperator Set")
        target_model = build_XYCNOT_cloudnoise_model(nQubits,
                                                     geometry="line",
                                                     maxIdleWeight=1,
                                                     maxhops=1,
                                                     extraWeight1Hops=0,
                                                     extraGateWeight=1,
                                                     simulator="map",
                                                     verbosity=1)
        #print("nElements test = ",target_model.num_elements)
        #print("nParams test = ",target_model.num_params)
        #print("nNonGaugeParams test = ",target_model.num_nongauge_params)

        print("Constructing Datagen LinearOperator Set")
        mdl_datagen = build_XYCNOT_cloudnoise_model(nQubits,
                                                    geometry="line",
                                                    maxIdleWeight=1,
                                                    maxhops=1,
                                                    extraWeight1Hops=0,
                                                    extraGateWeight=1,
                                                    verbosity=1,
                                                    roughNoise=(1234, 0.1),
                                                    simulator="map")

        mdl_test = mdl_datagen
        print(
            "Constructed model with %d op-blks, dim=%d, and nParams=%d.  Norm(paramvec) = %g"
            % (len(mdl_test.operation_blks), mdl_test.dim, mdl_test.num_params,
               np.linalg.norm(mdl_test.to_vector())))

        op_labels = target_model.primitive_op_labels
        line_labels = tuple(range(nQubits))
        fids1Q = std1Q_XY.fiducials
        fiducials = []
        for i in range(nQubits):
            fiducials.extend(
                pygsti.circuits.manipulate_circuits(fids1Q, [((L('Gx'), ),
                                                              (L('Gx', i), )),
                                                             ((L('Gy'), ),
                                                              (L('Gy', i), ))],
                                                    line_labels=line_labels))
        print(len(fiducials), "Fiducials")
        prep_fiducials = meas_fiducials = fiducials
        #TODO: add fiducials for 2Q pairs (edges on graph)

        germs = pygsti.circuits.to_circuits([(gl, ) for gl in op_labels],
                                            line_labels=line_labels)
        maxLs = [1]
        expList = pygsti.circuits.create_lsgst_circuits(
            mdl_datagen, prep_fiducials, meas_fiducials, germs, maxLs)
        self.assertTrue(Circuit((), line_labels) in expList)

        ds = pygsti.data.simulate_data(mdl_datagen,
                                       expList,
                                       1000,
                                       "multinomial",
                                       seed=1234)
        print("Created Dataset with %d strings" % len(ds))

        logL = pygsti.tools.logl(mdl_datagen, ds, expList)
        max_logL = pygsti.tools.logl_max(mdl_datagen, ds, expList)
        twoDeltaLogL = 2 * (max_logL - logL)
        chi2 = pygsti.tools.chi2(mdl_datagen, ds, expList)

        dof = ds.degrees_of_freedom()
        nParams = mdl_datagen.num_params
        print("Datagen 2DeltaLogL = 2(%g-%g) = %g" %
              (logL, max_logL, twoDeltaLogL))
        print("Datagen chi2 = ", chi2)
        print("Datagen expected DOF = ", dof)
        print("nParams = ", nParams)
        print("Expected 2DeltaLogL or chi2 ~= %g-%g =%g" %
              (dof, nParams, dof - nParams))
        #print("EXIT"); exit()
        return

        results = pygsti.run_long_sequence_gst(
            ds,
            target_model,
            prep_fiducials,
            meas_fiducials,
            germs,
            maxLs,
            verbosity=5,
            advanced_options={
                'max_iterations': 2
            })  #keep this short; don't care if it doesn't converge.
        print("DONE!")
예제 #5
0
    def setUpClass(cls):
        """
        Handle all once-per-class (slow) computation and loading,
         to avoid calling it for each test (like setUp).  Store
         results in class variable for use within setUp.
        """
        super(CalcMethods1QTestCase, cls).setUpClass()

        #Change to test_packages directory (since setUp hasn't been called yet...)
        origDir = os.getcwd()
        os.chdir(os.path.abspath(os.path.dirname(__file__)))
        os.chdir('..')  # The test_packages directory

        #Standard GST dataset
        cls.maxLengths = [1, 2, 4]
        cls.mdl_datagen = std.target_model().depolarize(op_noise=0.03,
                                                        spam_noise=0.001)
        cls.listOfExperiments = pygsti.circuits.create_lsgst_circuits(
            std.target_model(), std.prep_fiducials(), std.meas_fiducials(),
            std.germs(), cls.maxLengths)

        #RUN BELOW FOR DATAGEN (SAVE)
        if regenerate_references():
            ds = pygsti.data.simulate_data(cls.mdl_datagen,
                                           cls.listOfExperiments,
                                           num_samples=1000,
                                           sample_error="multinomial",
                                           seed=1234)
            ds.save(compare_files + "/calcMethods1Q.dataset")

        #DEBUG TEST- was to make sure data files have same info -- seemed ultimately unnecessary
        #ds_swp = pygsti.objects.DataSet(file_to_load_from=compare_files + "/calcMethods1Q.datasetv3") # run in Python3
        #pygsti.io.write_dataset(temp_files + "/dataset.3to2.txt", ds_swp) # run in Python3
        #ds_swp = pygsti.io.read_dataset(temp_files + "/dataset.3to2.txt") # run in Python2
        #ds_swp.save(compare_files + "/calcMethods1Q.dataset") # run in Python2
        #assert(False),"STOP"

        cls.ds = pygsti.data.DataSet(file_to_load_from=compare_files +
                                     "/calcMethods1Q.dataset")

        #Reduced model GST dataset
        cls.nQubits = 1  # can't just change this now - see op_labels below
        cls.mdl_redmod_datagen = build_XYCNOT_cloudnoise_model(
            cls.nQubits,
            geometry="line",
            maxIdleWeight=1,
            maxhops=1,
            extraWeight1Hops=0,
            extraGateWeight=1,
            simulator="matrix",
            verbosity=1,
            roughNoise=(1234, 0.01))

        #Create a reduced set of fiducials and germs
        op_labels = [L('Gx', 0), L('Gy', 0)]  # 1Q gate labels
        fids1Q = std1Q_XY.fiducials[
            1:2]  # for speed, just take 1 non-empty fiducial
        cls.redmod_fiducials = [
            Circuit([], line_labels=(0, ))
        ]  # special case for empty fiducial (need to change line label)
        for i in range(cls.nQubits):
            cls.redmod_fiducials.extend(
                pygsti.circuits.manipulate_circuits(fids1Q,
                                                    [((L('Gx'), ),
                                                      (L('Gx', i), )),
                                                     ((L('Gy'), ),
                                                      (L('Gy', i), ))]))
        #print(redmod_fiducials, "Fiducials")

        cls.redmod_germs = pygsti.circuits.to_circuits([(gl, )
                                                        for gl in op_labels])
        cls.redmod_maxLs = [1]
        expList = pygsti.circuits.create_lsgst_circuits(
            op_labels, cls.redmod_fiducials, cls.redmod_fiducials,
            cls.redmod_germs, cls.redmod_maxLs)

        #RUN BELOW FOR DATAGEN (SAVE)
        if regenerate_references():
            redmod_ds = pygsti.data.simulate_data(cls.mdl_redmod_datagen,
                                                  expList,
                                                  1000,
                                                  "round",
                                                  seed=1234)
            redmod_ds.save(compare_files + "/calcMethods1Q_redmod.dataset")

        cls.redmod_ds = pygsti.data.DataSet(file_to_load_from=compare_files +
                                            "/calcMethods1Q_redmod.dataset")

        #print(len(expList)," reduced model sequences")

        #Random starting points - little kick so we don't get hung up at start
        np.random.seed(1234)
        cls.rand_start18 = np.random.random(18) * 1e-6
        cls.rand_start25 = np.random.random(30) * 1e-6  # TODO: rename?
        cls.rand_start36 = np.random.random(30) * 1e-6  # TODO: rename?

        #Circuit Simulation circuits
        cls.csim_nQubits = 3
        cls.circuit1 = pygsti.circuits.Circuit((('Gxpi2', 0), ('Gypi2', 0)))
        # now Circuit adds qubit labels... pygsti.circuits.Circuit(layer_labels=('Gx','Gy'), num_lines=1) # 1-qubit circuit
        cls.circuit3 = pygsti.circuits.Circuit(layer_labels=[('Gxpi', 0),
                                                             ('Gypi', 1),
                                                             ('Gcnot', 1, 2)],
                                               num_lines=3)  # 3-qubit circuit

        os.chdir(origDir)  # return to original directory
예제 #6
0
 def test_hoperation(self):
     hg = self.fwdsim._hoperation(L('Gx'), flat=False)
     hgflat = self.fwdsim._hoperation(L('Gx'), flat=True)
예제 #7
0
def Ls(*args):
    """ Convert args to a tuple to Labels """
    return tuple([L(x) for x in args])
예제 #8
0
 def test_doperation(self):
     dg = self.fwdsim._doperation(L('Gx'), flat=False)
     dgflat = self.fwdsim._doperation(L('Gx'), flat=True)