26
26
from .simplify import _split_two_qubit_gate
27
27
from .utils import arg_alias
28
28
29
+
29
30
Gate = gates .Gate
30
31
Tensor = Any
31
32
@@ -613,6 +614,9 @@ def sample_expectation_ps(
613
614
random_generator : Optional [Any ] = None ,
614
615
status : Optional [Tensor ] = None ,
615
616
readout_error : Optional [Sequence [Any ]] = None ,
617
+ noise_conf : Optional [Any ] = None ,
618
+ nmc : int = 1000 ,
619
+ statusc : Optional [Tensor ] = None ,
616
620
** kws : Any ,
617
621
) -> Tensor :
618
622
"""
@@ -630,6 +634,22 @@ def sample_expectation_ps(
630
634
>>> readout_error.append([0.4,0.7])
631
635
>>> c.sample_expectation_ps(x=[0], y=[1],readout_error = readout_error)
632
636
637
+ >>> c = tc.Circuit(2)
638
+ >>> c.cnot(0, 1)
639
+ >>> c.rx(0, theta=0.4)
640
+ >>> c.rx(1, theta=0.8)
641
+ >>> c.h(0)
642
+ >>> c.h(1)
643
+ >>> error1 = tc.channels.generaldepolarizingchannel(0.1, 1)
644
+ >>> error2 = tc.channels.generaldepolarizingchannel(0.06, 2)
645
+ >>> readout_error = [[0.9, 0.75],[0.4, 0.7]]
646
+ >>> noise_conf = NoiseConf()
647
+ >>> noise_conf.add_noise("rx", error1)
648
+ >>> noise_conf.add_noise("cnot", [error2], [[0, 1]])
649
+ >>> noise_conf.add_noise("readout", readout_error)
650
+ >>> c.sample_expectation_ps(x=[0], noise_conf=noise_conf, nmc=10000)
651
+ 0.44766843
652
+
633
653
:param x: index for Pauli X, defaults to None
634
654
:type x: Optional[Sequence[int]], optional
635
655
:param y: index for Pauli Y, defaults to None
@@ -645,62 +665,85 @@ def sample_expectation_ps(
645
665
:type status: Optional[Tensor]
646
666
:param readout_error: readout_error, defaults to None
647
667
:type readout_error: Optional[Sequence[Any]]. Tensor, List, Tuple
668
+ :param noise_conf: Noise Configuration, defaults to None
669
+ :type noise_conf: Optional[NoiseConf], optional
670
+ :param nmc: repetition time for Monte Carlo sampling for noisfy calculation, defaults to 1000
671
+ :type nmc: int, optional
672
+ :param statusc: external randomness given by tensor uniformly from [0, 1], defaults to None,
673
+ used for noisfy circuit sampling
674
+ :type statusc: Optional[Tensor], optional
648
675
:return: [description]
649
676
:rtype: Tensor
650
677
"""
651
- inputs_nodes , _ = self ._copy_state_tensor ()
652
- inputs = inputs_nodes [0 ].tensor
653
- if self .is_dm is False :
654
- c = type (self )(self ._nqubits , inputs = inputs ) # type: ignore
655
- else :
656
- c = type (self )(self ._nqubits , dminputs = inputs ) # type: ignore
657
- if x is None :
658
- x = []
659
- if y is None :
660
- y = []
661
- if z is None :
662
- z = []
663
- for i in x :
664
- c .H (i ) # type: ignore
665
- for i in y :
666
- c .rx (i , theta = np .pi / 2 ) # type: ignore
667
- s = c .state () # type: ignore
668
- if self .is_dm is False :
669
- p = backend .abs (s ) ** 2
670
- else :
671
- p = backend .abs (backend .diagonal (s ))
672
-
673
- # readout error
674
- if readout_error is not None :
675
- p = self .readouterror_bs (readout_error , p )
676
-
677
- x = list (x )
678
- y = list (y )
679
- z = list (z )
680
- if shots is None :
681
- mc = measurement_counts (
682
- p ,
683
- counts = shots ,
684
- format = "count_vector" ,
685
- random_generator = random_generator ,
686
- status = status ,
687
- jittable = True ,
688
- is_prob = True ,
689
- )
690
- r = correlation_from_counts (x + y + z , mc )
678
+ from .noisemodel import sample_expectation_ps_noisfy
679
+
680
+ if noise_conf is None :
681
+ inputs_nodes , _ = self ._copy_state_tensor ()
682
+ inputs = inputs_nodes [0 ].tensor
683
+ if self .is_dm is False :
684
+ c = type (self )(self ._nqubits , inputs = inputs ) # type: ignore
685
+ else :
686
+ c = type (self )(self ._nqubits , dminputs = inputs ) # type: ignore
687
+ if x is None :
688
+ x = []
689
+ if y is None :
690
+ y = []
691
+ if z is None :
692
+ z = []
693
+ for i in x :
694
+ c .H (i ) # type: ignore
695
+ for i in y :
696
+ c .rx (i , theta = np .pi / 2 ) # type: ignore
697
+ s = c .state () # type: ignore
698
+ if self .is_dm is False :
699
+ p = backend .abs (s ) ** 2
700
+ else :
701
+ p = backend .abs (backend .diagonal (s ))
702
+
703
+ # readout error
704
+ if readout_error is not None :
705
+ p = self .readouterror_bs (readout_error , p )
706
+
707
+ x = list (x )
708
+ y = list (y )
709
+ z = list (z )
710
+ if shots is None :
711
+ mc = measurement_counts (
712
+ p ,
713
+ counts = shots ,
714
+ format = "count_vector" ,
715
+ random_generator = random_generator ,
716
+ status = status ,
717
+ jittable = True ,
718
+ is_prob = True ,
719
+ )
720
+ r = correlation_from_counts (x + y + z , mc )
721
+ else :
722
+ mc = measurement_counts (
723
+ p ,
724
+ counts = shots ,
725
+ format = "sample_bin" ,
726
+ random_generator = random_generator ,
727
+ status = status ,
728
+ jittable = True ,
729
+ is_prob = True ,
730
+ )
731
+ r = correlation_from_samples (x + y + z , mc , self ._nqubits )
732
+ # TODO(@refraction-ray): analytical standard deviation
733
+ return r
691
734
else :
692
- mc = measurement_counts (
693
- p ,
694
- counts = shots ,
695
- format = "sample_bin" ,
696
- random_generator = random_generator ,
735
+ return sample_expectation_ps_noisfy (
736
+ c = self ,
737
+ x = x ,
738
+ y = y ,
739
+ z = z ,
740
+ noise_conf = noise_conf ,
741
+ nmc = nmc ,
742
+ shots = shots ,
743
+ statusc = statusc ,
697
744
status = status ,
698
- jittable = True ,
699
- is_prob = True ,
745
+ ** kws ,
700
746
)
701
- r = correlation_from_samples (x + y + z , mc , self ._nqubits )
702
- # TODO(@refraction-ray): analytical standard deviation
703
- return r
704
747
705
748
sexpps = sample_expectation_ps
706
749
0 commit comments