@@ -96,6 +96,19 @@ pub mod graphsim {
9696 ZF ,
9797 }
9898
99+ impl Vop {
100+ pub fn get_state_str ( & self ) -> & ' static str {
101+ match self {
102+ Vop :: IA | Vop :: XA | Vop :: YD | Vop :: ZD => "+" ,
103+ Vop :: YA | Vop :: ZA | Vop :: ID | Vop :: XD => "-" ,
104+ Vop :: IB | Vop :: XB | Vop :: YE | Vop :: ZE => "+i" ,
105+ Vop :: YB | Vop :: ZB | Vop :: IE | Vop :: XE => "-i" ,
106+ Vop :: IC | Vop :: XC | Vop :: YF | Vop :: ZF => "1" ,
107+ Vop :: YC | Vop :: ZC | Vop :: IF | Vop :: XF => "0" ,
108+ }
109+ }
110+ }
111+
99112 #[ pyclass( eq, eq_int) ]
100113 #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
101114 pub ( crate ) enum Axis {
@@ -223,7 +236,7 @@ pub mod graphsim {
223236 /// Simulator for graph states over a fixed number of qubits.
224237 ///
225238 /// Use this class from Python to apply gates and perform measurements.
226- #[ derive( Clone ) ]
239+ #[ derive( Clone , Debug ) ]
227240 #[ pyclass]
228241 pub struct GraphSim {
229242 vop : Vec < Vop > ,
@@ -672,4 +685,148 @@ pub mod graphsim {
672685 ( true , false ) | ( false , true ) => Zeta :: Zero ,
673686 }
674687 }
688+
689+ #[ cfg( test) ]
690+ mod tests {
691+ use super :: * ;
692+ #[ test]
693+ fn test_single_qubit_gates ( ) {
694+ let mut qec = GraphSim :: new ( 1 ) ;
695+ assert_eq ! ( qec. vop[ 0 ] , Vop :: YC ) ;
696+ qec. h ( 0 ) ;
697+ assert_eq ! ( qec. vop[ 0 ] , Vop :: IA ) ;
698+ qec. s ( 0 ) ;
699+ assert_eq ! ( qec. vop[ 0 ] , Vop :: YB ) ;
700+ qec. s ( 0 ) ;
701+ assert_eq ! ( qec. vop[ 0 ] , Vop :: ZA ) ;
702+ qec. z ( 0 ) ;
703+ assert_eq ! ( qec. vop[ 0 ] , Vop :: IA ) ;
704+ qec. sdag ( 0 ) ;
705+ assert_eq ! ( qec. vop[ 0 ] , Vop :: XB ) ;
706+ qec. z ( 0 ) ;
707+ assert_eq ! ( qec. vop[ 0 ] , Vop :: YB ) ;
708+ }
709+
710+ #[ test]
711+ fn test_measure_single_z_det ( ) {
712+ let mut qec = GraphSim :: new ( 1 ) ;
713+
714+ let ( outcome, det) = qec. measure ( 0 , Axis :: Z ) ;
715+ assert_eq ! ( outcome, MeasurementResult :: PlusOne ) ;
716+ assert_eq ! ( det, true ) ;
717+
718+ qec. s ( 0 ) ;
719+ let ( outcome, det) = qec. measure ( 0 , Axis :: Z ) ;
720+ assert_eq ! ( outcome, MeasurementResult :: PlusOne ) ;
721+ assert_eq ! ( det, true ) ;
722+
723+ qec. s ( 0 ) ;
724+ let ( outcome, det) = qec. measure ( 0 , Axis :: Z ) ;
725+ assert_eq ! ( outcome, MeasurementResult :: PlusOne ) ;
726+ assert_eq ! ( det, true ) ;
727+
728+ qec. s ( 0 ) ;
729+ let ( outcome, det) = qec. measure ( 0 , Axis :: Z ) ;
730+ assert_eq ! ( outcome, MeasurementResult :: PlusOne ) ;
731+ assert_eq ! ( det, true ) ;
732+
733+ qec. x ( 0 ) ;
734+ let ( outcome, det) = qec. measure ( 0 , Axis :: Z ) ;
735+ assert_eq ! ( outcome, MeasurementResult :: MinusOne ) ;
736+ assert_eq ! ( det, true ) ;
737+
738+ qec. s ( 0 ) ;
739+ let ( outcome, det) = qec. measure ( 0 , Axis :: Z ) ;
740+ assert_eq ! ( outcome, MeasurementResult :: MinusOne ) ;
741+ assert_eq ! ( det, true ) ;
742+
743+ qec. s ( 0 ) ;
744+ let ( outcome, det) = qec. measure ( 0 , Axis :: Z ) ;
745+ assert_eq ! ( outcome, MeasurementResult :: MinusOne ) ;
746+ assert_eq ! ( det, true ) ;
747+
748+ qec. s ( 0 ) ;
749+ let ( outcome, det) = qec. measure ( 0 , Axis :: Z ) ;
750+ assert_eq ! ( outcome, MeasurementResult :: MinusOne ) ;
751+ assert_eq ! ( det, true ) ;
752+ }
753+
754+ #[ test]
755+ fn test_cnot_measure_x ( ) {
756+ let mut qec = GraphSim :: new ( 2 ) ;
757+
758+ qec. h ( 0 ) ;
759+ qec. cx ( 0 , 1 ) ;
760+
761+ println ! ( "state is {:#?} before meas" , qec) ;
762+ let ( outcome_1, det_1) = qec. measure ( 0 , Axis :: X ) ;
763+ println ! (
764+ "state is {:#?} between meas, outcome was {:?}" ,
765+ qec, outcome_1
766+ ) ;
767+ let ( outcome_2, det_2) = qec. measure ( 1 , Axis :: X ) ;
768+ println ! (
769+ "state is {:#?} after meas, outcome was {:?}" ,
770+ qec, outcome_2
771+ ) ;
772+
773+ assert_eq ! ( det_1, false ) ;
774+ assert_eq ! ( det_2, true ) ;
775+
776+ assert_eq ! ( qec. vop[ 0 ] . get_state_str( ) , qec. vop[ 1 ] . get_state_str( ) ) ;
777+ assert_eq ! ( outcome_1, outcome_2) ;
778+ }
779+
780+ #[ test]
781+ fn test_cnot_measure_y ( ) {
782+ let mut qec = GraphSim :: new ( 2 ) ;
783+
784+ qec. h ( 0 ) ;
785+ qec. cx ( 0 , 1 ) ;
786+
787+ println ! ( "state is {:#?} before meas" , qec) ;
788+ let ( outcome_1, det_1) = qec. measure ( 0 , Axis :: Y ) ;
789+ println ! (
790+ "state is {:#?} between meas, outcome was {:?}" ,
791+ qec, outcome_1
792+ ) ;
793+ let ( outcome_2, det_2) = qec. measure ( 1 , Axis :: Y ) ;
794+ println ! (
795+ "state is {:#?} after meas, outcome was {:?}" ,
796+ qec, outcome_2
797+ ) ;
798+
799+ assert_eq ! ( det_1, false ) ;
800+ assert_eq ! ( det_2, true ) ;
801+
802+ assert_ne ! ( qec. vop[ 0 ] . get_state_str( ) , qec. vop[ 1 ] . get_state_str( ) ) ;
803+ assert_ne ! ( outcome_1, outcome_2) ;
804+ }
805+
806+ #[ test]
807+ fn test_cnot_measure_z ( ) {
808+ let mut qec = GraphSim :: new ( 2 ) ;
809+
810+ qec. h ( 0 ) ;
811+ qec. cx ( 0 , 1 ) ;
812+
813+ println ! ( "state is {:#?} before meas" , qec) ;
814+ let ( outcome_1, det_1) = qec. measure ( 0 , Axis :: Z ) ;
815+ println ! (
816+ "state is {:#?} between meas, outcome was {:?}" ,
817+ qec, outcome_1
818+ ) ;
819+ let ( outcome_2, det_2) = qec. measure ( 1 , Axis :: Z ) ;
820+ println ! (
821+ "state is {:#?} after meas, outcome was {:?}" ,
822+ qec, outcome_2
823+ ) ;
824+
825+ assert_eq ! ( det_1, false ) ;
826+ assert_eq ! ( det_2, true ) ;
827+
828+ assert_eq ! ( qec. vop[ 0 ] . get_state_str( ) , qec. vop[ 1 ] . get_state_str( ) ) ;
829+ assert_eq ! ( outcome_1, outcome_2) ;
830+ }
831+ }
675832}
0 commit comments