quantrs2_core/
gate.rs

1use scirs2_core::Complex64;
2use std::any::Any;
3use std::f64::consts::PI;
4use std::fmt::Debug;
5
6use crate::error::QuantRS2Result;
7use crate::qubit::QubitId;
8
9/// Macro to implement clone_gate method for gate types
10macro_rules! impl_clone_gate {
11    () => {
12        fn clone_gate(&self) -> Box<dyn GateOp> {
13            Box::new(self.clone())
14        }
15    };
16}
17
18/// Trait for quantum gate operations
19pub trait GateOp: Debug + Send + Sync {
20    /// Returns the name of the gate
21    fn name(&self) -> &'static str;
22
23    /// Returns the qubits that this gate acts on
24    fn qubits(&self) -> Vec<QubitId>;
25
26    /// Returns the number of qubits this gate acts on
27    fn num_qubits(&self) -> usize {
28        self.qubits().len()
29    }
30
31    /// Returns true if this gate is parameterized
32    fn is_parameterized(&self) -> bool {
33        false
34    }
35
36    /// Returns the matrix representation of this gate
37    fn matrix(&self) -> QuantRS2Result<Vec<Complex64>>;
38
39    /// Downcast to concrete gate type
40    fn as_any(&self) -> &dyn Any;
41
42    /// Clone the gate into a new boxed instance
43    fn clone_gate(&self) -> Box<dyn GateOp>;
44}
45
46/// Implement Clone for `Box<dyn GateOp>`
47impl Clone for Box<dyn GateOp> {
48    fn clone(&self) -> Self {
49        self.clone_gate()
50    }
51}
52
53/// Single-qubit gate operations
54pub mod single {
55    use super::*;
56    use std::any::Any;
57
58    /// Hadamard gate
59    #[derive(Debug, Clone, Copy)]
60    pub struct Hadamard {
61        /// Target qubit
62        pub target: QubitId,
63    }
64
65    impl GateOp for Hadamard {
66        fn name(&self) -> &'static str {
67            "H"
68        }
69
70        fn qubits(&self) -> Vec<QubitId> {
71            vec![self.target]
72        }
73
74        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
75            let sqrt2_inv = 1.0 / 2.0_f64.sqrt();
76            Ok(vec![
77                Complex64::new(sqrt2_inv, 0.0),
78                Complex64::new(sqrt2_inv, 0.0),
79                Complex64::new(sqrt2_inv, 0.0),
80                Complex64::new(-sqrt2_inv, 0.0),
81            ])
82        }
83
84        fn as_any(&self) -> &dyn Any {
85            self
86        }
87
88        impl_clone_gate!();
89    }
90
91    /// Pauli-X gate
92    #[derive(Debug, Clone, Copy)]
93    pub struct PauliX {
94        /// Target qubit
95        pub target: QubitId,
96    }
97
98    impl GateOp for PauliX {
99        fn name(&self) -> &'static str {
100            "X"
101        }
102
103        fn qubits(&self) -> Vec<QubitId> {
104            vec![self.target]
105        }
106
107        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
108            Ok(vec![
109                Complex64::new(0.0, 0.0),
110                Complex64::new(1.0, 0.0),
111                Complex64::new(1.0, 0.0),
112                Complex64::new(0.0, 0.0),
113            ])
114        }
115
116        fn as_any(&self) -> &dyn Any {
117            self
118        }
119
120        impl_clone_gate!();
121    }
122
123    /// Pauli-Y gate
124    #[derive(Debug, Clone, Copy)]
125    pub struct PauliY {
126        /// Target qubit
127        pub target: QubitId,
128    }
129
130    impl GateOp for PauliY {
131        fn name(&self) -> &'static str {
132            "Y"
133        }
134
135        fn qubits(&self) -> Vec<QubitId> {
136            vec![self.target]
137        }
138
139        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
140            Ok(vec![
141                Complex64::new(0.0, 0.0),
142                Complex64::new(0.0, -1.0),
143                Complex64::new(0.0, 1.0),
144                Complex64::new(0.0, 0.0),
145            ])
146        }
147
148        fn as_any(&self) -> &dyn Any {
149            self
150        }
151
152        impl_clone_gate!();
153    }
154
155    /// Pauli-Z gate
156    #[derive(Debug, Clone, Copy)]
157    pub struct PauliZ {
158        /// Target qubit
159        pub target: QubitId,
160    }
161
162    impl GateOp for PauliZ {
163        fn name(&self) -> &'static str {
164            "Z"
165        }
166
167        fn qubits(&self) -> Vec<QubitId> {
168            vec![self.target]
169        }
170
171        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
172            Ok(vec![
173                Complex64::new(1.0, 0.0),
174                Complex64::new(0.0, 0.0),
175                Complex64::new(0.0, 0.0),
176                Complex64::new(-1.0, 0.0),
177            ])
178        }
179
180        fn as_any(&self) -> &dyn Any {
181            self
182        }
183
184        impl_clone_gate!();
185    }
186
187    /// Rotation around X-axis
188    #[derive(Debug, Clone, Copy)]
189    pub struct RotationX {
190        /// Target qubit
191        pub target: QubitId,
192
193        /// Rotation angle (in radians)
194        pub theta: f64,
195    }
196
197    impl GateOp for RotationX {
198        fn name(&self) -> &'static str {
199            "RX"
200        }
201
202        fn qubits(&self) -> Vec<QubitId> {
203            vec![self.target]
204        }
205
206        fn is_parameterized(&self) -> bool {
207            true
208        }
209
210        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
211            let cos = (self.theta / 2.0).cos();
212            let sin = (self.theta / 2.0).sin();
213            Ok(vec![
214                Complex64::new(cos, 0.0),
215                Complex64::new(0.0, -sin),
216                Complex64::new(0.0, -sin),
217                Complex64::new(cos, 0.0),
218            ])
219        }
220
221        fn as_any(&self) -> &dyn Any {
222            self
223        }
224
225        impl_clone_gate!();
226    }
227
228    /// Rotation around Y-axis
229    #[derive(Debug, Clone, Copy)]
230    pub struct RotationY {
231        /// Target qubit
232        pub target: QubitId,
233
234        /// Rotation angle (in radians)
235        pub theta: f64,
236    }
237
238    impl GateOp for RotationY {
239        fn name(&self) -> &'static str {
240            "RY"
241        }
242
243        fn qubits(&self) -> Vec<QubitId> {
244            vec![self.target]
245        }
246
247        fn is_parameterized(&self) -> bool {
248            true
249        }
250
251        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
252            let cos = (self.theta / 2.0).cos();
253            let sin = (self.theta / 2.0).sin();
254            Ok(vec![
255                Complex64::new(cos, 0.0),
256                Complex64::new(-sin, 0.0),
257                Complex64::new(sin, 0.0),
258                Complex64::new(cos, 0.0),
259            ])
260        }
261
262        fn as_any(&self) -> &dyn Any {
263            self
264        }
265
266        impl_clone_gate!();
267    }
268
269    /// Rotation around Z-axis
270    #[derive(Debug, Clone, Copy)]
271    pub struct RotationZ {
272        /// Target qubit
273        pub target: QubitId,
274
275        /// Rotation angle (in radians)
276        pub theta: f64,
277    }
278
279    impl GateOp for RotationZ {
280        fn name(&self) -> &'static str {
281            "RZ"
282        }
283
284        fn qubits(&self) -> Vec<QubitId> {
285            vec![self.target]
286        }
287
288        fn is_parameterized(&self) -> bool {
289            true
290        }
291
292        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
293            let phase = Complex64::new(0.0, -self.theta / 2.0).exp();
294            let phase_conj = Complex64::new(0.0, self.theta / 2.0).exp();
295            Ok(vec![
296                phase_conj,
297                Complex64::new(0.0, 0.0),
298                Complex64::new(0.0, 0.0),
299                phase,
300            ])
301        }
302
303        fn as_any(&self) -> &dyn Any {
304            self
305        }
306
307        impl_clone_gate!();
308    }
309
310    /// Phase gate (S gate)
311    #[derive(Debug, Clone, Copy)]
312    pub struct Phase {
313        /// Target qubit
314        pub target: QubitId,
315    }
316
317    impl GateOp for Phase {
318        fn name(&self) -> &'static str {
319            "S"
320        }
321
322        fn qubits(&self) -> Vec<QubitId> {
323            vec![self.target]
324        }
325
326        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
327            Ok(vec![
328                Complex64::new(1.0, 0.0),
329                Complex64::new(0.0, 0.0),
330                Complex64::new(0.0, 0.0),
331                Complex64::new(0.0, 1.0),
332            ])
333        }
334
335        fn as_any(&self) -> &dyn Any {
336            self
337        }
338
339        impl_clone_gate!();
340    }
341
342    /// T gate
343    #[derive(Debug, Clone, Copy)]
344    pub struct T {
345        /// Target qubit
346        pub target: QubitId,
347    }
348
349    impl GateOp for T {
350        fn name(&self) -> &'static str {
351            "T"
352        }
353
354        fn qubits(&self) -> Vec<QubitId> {
355            vec![self.target]
356        }
357
358        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
359            let phase = Complex64::new((PI / 4.0).cos(), (PI / 4.0).sin());
360            Ok(vec![
361                Complex64::new(1.0, 0.0),
362                Complex64::new(0.0, 0.0),
363                Complex64::new(0.0, 0.0),
364                phase,
365            ])
366        }
367
368        fn as_any(&self) -> &dyn Any {
369            self
370        }
371
372        impl_clone_gate!();
373    }
374
375    /// T-dagger gate (Conjugate of T gate)
376    #[derive(Debug, Clone, Copy)]
377    pub struct TDagger {
378        /// Target qubit
379        pub target: QubitId,
380    }
381
382    impl GateOp for TDagger {
383        fn name(&self) -> &'static str {
384            "T†"
385        }
386
387        fn qubits(&self) -> Vec<QubitId> {
388            vec![self.target]
389        }
390
391        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
392            let phase = Complex64::new((PI / 4.0).cos(), -(PI / 4.0).sin());
393            Ok(vec![
394                Complex64::new(1.0, 0.0),
395                Complex64::new(0.0, 0.0),
396                Complex64::new(0.0, 0.0),
397                phase,
398            ])
399        }
400
401        fn as_any(&self) -> &dyn Any {
402            self
403        }
404
405        impl_clone_gate!();
406    }
407
408    /// S-dagger gate (Conjugate of Phase/S gate)
409    #[derive(Debug, Clone, Copy)]
410    pub struct PhaseDagger {
411        /// Target qubit
412        pub target: QubitId,
413    }
414
415    impl GateOp for PhaseDagger {
416        fn name(&self) -> &'static str {
417            "S†"
418        }
419
420        fn qubits(&self) -> Vec<QubitId> {
421            vec![self.target]
422        }
423
424        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
425            Ok(vec![
426                Complex64::new(1.0, 0.0),
427                Complex64::new(0.0, 0.0),
428                Complex64::new(0.0, 0.0),
429                Complex64::new(0.0, -1.0),
430            ])
431        }
432
433        fn as_any(&self) -> &dyn Any {
434            self
435        }
436
437        impl_clone_gate!();
438    }
439
440    /// Square Root of X (√X) gate
441    #[derive(Debug, Clone, Copy)]
442    pub struct SqrtX {
443        /// Target qubit
444        pub target: QubitId,
445    }
446
447    impl GateOp for SqrtX {
448        fn name(&self) -> &'static str {
449            "√X"
450        }
451
452        fn qubits(&self) -> Vec<QubitId> {
453            vec![self.target]
454        }
455
456        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
457            // √X = [[0.5+0.5i, 0.5-0.5i], [0.5-0.5i, 0.5+0.5i]]
458            let half_plus_i_half = Complex64::new(0.5, 0.5);
459            let half_minus_i_half = Complex64::new(0.5, -0.5);
460
461            Ok(vec![
462                half_plus_i_half,
463                half_minus_i_half,
464                half_minus_i_half,
465                half_plus_i_half,
466            ])
467        }
468
469        fn as_any(&self) -> &dyn Any {
470            self
471        }
472
473        impl_clone_gate!();
474    }
475
476    /// Square Root of X Dagger (√X†) gate
477    #[derive(Debug, Clone, Copy)]
478    pub struct SqrtXDagger {
479        /// Target qubit
480        pub target: QubitId,
481    }
482
483    impl GateOp for SqrtXDagger {
484        fn name(&self) -> &'static str {
485            "√X†"
486        }
487
488        fn qubits(&self) -> Vec<QubitId> {
489            vec![self.target]
490        }
491
492        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
493            // √X† = [[0.5-0.5i, 0.5+0.5i], [0.5+0.5i, 0.5-0.5i]]
494            let half_minus_i_half = Complex64::new(0.5, -0.5);
495            let half_plus_i_half = Complex64::new(0.5, 0.5);
496
497            Ok(vec![
498                half_minus_i_half,
499                half_plus_i_half,
500                half_plus_i_half,
501                half_minus_i_half,
502            ])
503        }
504
505        fn as_any(&self) -> &dyn Any {
506            self
507        }
508
509        impl_clone_gate!();
510    }
511
512    /// U gate - General single-qubit rotation (Qiskit compatible)
513    ///
514    /// U(θ, φ, λ) = [[cos(θ/2), -e^(iλ)·sin(θ/2)],
515    ///              [e^(iφ)·sin(θ/2), e^(i(φ+λ))·cos(θ/2)]]
516    #[derive(Debug, Clone, Copy)]
517    pub struct UGate {
518        /// Target qubit
519        pub target: QubitId,
520        /// Rotation angle theta
521        pub theta: f64,
522        /// Phase angle phi
523        pub phi: f64,
524        /// Phase angle lambda
525        pub lambda: f64,
526    }
527
528    impl GateOp for UGate {
529        fn name(&self) -> &'static str {
530            "U"
531        }
532
533        fn qubits(&self) -> Vec<QubitId> {
534            vec![self.target]
535        }
536
537        fn is_parameterized(&self) -> bool {
538            true
539        }
540
541        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
542            let cos = (self.theta / 2.0).cos();
543            let sin = (self.theta / 2.0).sin();
544            let exp_i_lambda = Complex64::new(0.0, self.lambda).exp();
545            let exp_i_phi = Complex64::new(0.0, self.phi).exp();
546            let exp_i_phi_lambda = Complex64::new(0.0, self.phi + self.lambda).exp();
547
548            Ok(vec![
549                Complex64::new(cos, 0.0),
550                -exp_i_lambda * sin,
551                exp_i_phi * sin,
552                exp_i_phi_lambda * cos,
553            ])
554        }
555
556        fn as_any(&self) -> &dyn Any {
557            self
558        }
559
560        impl_clone_gate!();
561    }
562
563    /// P gate - Phase gate with parameter (equivalent to RZ up to global phase)
564    ///
565    /// P(λ) = [[1, 0], [0, e^(iλ)]]
566    #[derive(Debug, Clone, Copy)]
567    pub struct PGate {
568        /// Target qubit
569        pub target: QubitId,
570        /// Phase angle lambda
571        pub lambda: f64,
572    }
573
574    impl GateOp for PGate {
575        fn name(&self) -> &'static str {
576            "P"
577        }
578
579        fn qubits(&self) -> Vec<QubitId> {
580            vec![self.target]
581        }
582
583        fn is_parameterized(&self) -> bool {
584            true
585        }
586
587        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
588            let exp_i_lambda = Complex64::new(0.0, self.lambda).exp();
589            Ok(vec![
590                Complex64::new(1.0, 0.0),
591                Complex64::new(0.0, 0.0),
592                Complex64::new(0.0, 0.0),
593                exp_i_lambda,
594            ])
595        }
596
597        fn as_any(&self) -> &dyn Any {
598            self
599        }
600
601        impl_clone_gate!();
602    }
603
604    /// Identity gate
605    #[derive(Debug, Clone, Copy)]
606    pub struct Identity {
607        /// Target qubit
608        pub target: QubitId,
609    }
610
611    impl GateOp for Identity {
612        fn name(&self) -> &'static str {
613            "I"
614        }
615
616        fn qubits(&self) -> Vec<QubitId> {
617            vec![self.target]
618        }
619
620        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
621            Ok(vec![
622                Complex64::new(1.0, 0.0),
623                Complex64::new(0.0, 0.0),
624                Complex64::new(0.0, 0.0),
625                Complex64::new(1.0, 0.0),
626            ])
627        }
628
629        fn as_any(&self) -> &dyn Any {
630            self
631        }
632
633        impl_clone_gate!();
634    }
635}
636
637/// Multi-qubit gate operations
638pub mod multi {
639    use super::*;
640    use std::any::Any;
641
642    /// Controlled-NOT gate
643    #[derive(Debug, Clone, Copy)]
644    pub struct CNOT {
645        /// Control qubit
646        pub control: QubitId,
647
648        /// Target qubit
649        pub target: QubitId,
650    }
651
652    impl GateOp for CNOT {
653        fn name(&self) -> &'static str {
654            "CNOT"
655        }
656
657        fn qubits(&self) -> Vec<QubitId> {
658            vec![self.control, self.target]
659        }
660
661        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
662            // For a 2-qubit gate, we return a 4x4 matrix in row-major order
663            Ok(vec![
664                Complex64::new(1.0, 0.0),
665                Complex64::new(0.0, 0.0),
666                Complex64::new(0.0, 0.0),
667                Complex64::new(0.0, 0.0),
668                Complex64::new(0.0, 0.0),
669                Complex64::new(1.0, 0.0),
670                Complex64::new(0.0, 0.0),
671                Complex64::new(0.0, 0.0),
672                Complex64::new(0.0, 0.0),
673                Complex64::new(0.0, 0.0),
674                Complex64::new(0.0, 0.0),
675                Complex64::new(1.0, 0.0),
676                Complex64::new(0.0, 0.0),
677                Complex64::new(0.0, 0.0),
678                Complex64::new(1.0, 0.0),
679                Complex64::new(0.0, 0.0),
680            ])
681        }
682
683        fn as_any(&self) -> &dyn Any {
684            self
685        }
686
687        impl_clone_gate!();
688    }
689
690    /// Controlled-Z gate
691    #[derive(Debug, Clone, Copy)]
692    pub struct CZ {
693        /// Control qubit
694        pub control: QubitId,
695
696        /// Target qubit
697        pub target: QubitId,
698    }
699
700    impl GateOp for CZ {
701        fn name(&self) -> &'static str {
702            "CZ"
703        }
704
705        fn qubits(&self) -> Vec<QubitId> {
706            vec![self.control, self.target]
707        }
708
709        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
710            // For a 2-qubit gate, we return a 4x4 matrix in row-major order
711            Ok(vec![
712                Complex64::new(1.0, 0.0),
713                Complex64::new(0.0, 0.0),
714                Complex64::new(0.0, 0.0),
715                Complex64::new(0.0, 0.0),
716                Complex64::new(0.0, 0.0),
717                Complex64::new(1.0, 0.0),
718                Complex64::new(0.0, 0.0),
719                Complex64::new(0.0, 0.0),
720                Complex64::new(0.0, 0.0),
721                Complex64::new(0.0, 0.0),
722                Complex64::new(1.0, 0.0),
723                Complex64::new(0.0, 0.0),
724                Complex64::new(0.0, 0.0),
725                Complex64::new(0.0, 0.0),
726                Complex64::new(0.0, 0.0),
727                Complex64::new(-1.0, 0.0),
728            ])
729        }
730
731        fn as_any(&self) -> &dyn Any {
732            self
733        }
734
735        impl_clone_gate!();
736    }
737
738    /// SWAP gate
739    #[derive(Debug, Clone, Copy)]
740    pub struct SWAP {
741        /// First qubit
742        pub qubit1: QubitId,
743
744        /// Second qubit
745        pub qubit2: QubitId,
746    }
747
748    impl GateOp for SWAP {
749        fn name(&self) -> &'static str {
750            "SWAP"
751        }
752
753        fn qubits(&self) -> Vec<QubitId> {
754            vec![self.qubit1, self.qubit2]
755        }
756
757        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
758            // For a 2-qubit gate, we return a 4x4 matrix in row-major order
759            Ok(vec![
760                Complex64::new(1.0, 0.0),
761                Complex64::new(0.0, 0.0),
762                Complex64::new(0.0, 0.0),
763                Complex64::new(0.0, 0.0),
764                Complex64::new(0.0, 0.0),
765                Complex64::new(0.0, 0.0),
766                Complex64::new(1.0, 0.0),
767                Complex64::new(0.0, 0.0),
768                Complex64::new(0.0, 0.0),
769                Complex64::new(1.0, 0.0),
770                Complex64::new(0.0, 0.0),
771                Complex64::new(0.0, 0.0),
772                Complex64::new(0.0, 0.0),
773                Complex64::new(0.0, 0.0),
774                Complex64::new(0.0, 0.0),
775                Complex64::new(1.0, 0.0),
776            ])
777        }
778
779        fn as_any(&self) -> &dyn Any {
780            self
781        }
782
783        impl_clone_gate!();
784    }
785
786    /// Controlled-Y (CY) gate
787    #[derive(Debug, Clone, Copy)]
788    pub struct CY {
789        /// Control qubit
790        pub control: QubitId,
791
792        /// Target qubit
793        pub target: QubitId,
794    }
795
796    impl GateOp for CY {
797        fn name(&self) -> &'static str {
798            "CY"
799        }
800
801        fn qubits(&self) -> Vec<QubitId> {
802            vec![self.control, self.target]
803        }
804
805        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
806            // Matrix for CY:
807            // [[1, 0, 0, 0],
808            //  [0, 1, 0, 0],
809            //  [0, 0, 0, -i],
810            //  [0, 0, i, 0]]
811            Ok(vec![
812                Complex64::new(1.0, 0.0),  // (0,0)
813                Complex64::new(0.0, 0.0),  // (0,1)
814                Complex64::new(0.0, 0.0),  // (0,2)
815                Complex64::new(0.0, 0.0),  // (0,3)
816                Complex64::new(0.0, 0.0),  // (1,0)
817                Complex64::new(1.0, 0.0),  // (1,1)
818                Complex64::new(0.0, 0.0),  // (1,2)
819                Complex64::new(0.0, 0.0),  // (1,3)
820                Complex64::new(0.0, 0.0),  // (2,0)
821                Complex64::new(0.0, 0.0),  // (2,1)
822                Complex64::new(0.0, 0.0),  // (2,2)
823                Complex64::new(0.0, -1.0), // (2,3)
824                Complex64::new(0.0, 0.0),  // (3,0)
825                Complex64::new(0.0, 0.0),  // (3,1)
826                Complex64::new(0.0, 1.0),  // (3,2)
827                Complex64::new(0.0, 0.0),  // (3,3)
828            ])
829        }
830
831        fn as_any(&self) -> &dyn Any {
832            self
833        }
834
835        impl_clone_gate!();
836    }
837
838    /// Controlled-H (CH) gate
839    #[derive(Debug, Clone, Copy)]
840    pub struct CH {
841        /// Control qubit
842        pub control: QubitId,
843
844        /// Target qubit
845        pub target: QubitId,
846    }
847
848    impl GateOp for CH {
849        fn name(&self) -> &'static str {
850            "CH"
851        }
852
853        fn qubits(&self) -> Vec<QubitId> {
854            vec![self.control, self.target]
855        }
856
857        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
858            // For a controlled-H gate, the matrix is:
859            // [[1, 0, 0, 0],
860            //  [0, 1, 0, 0],
861            //  [0, 0, 1/√2, 1/√2],
862            //  [0, 0, 1/√2, -1/√2]]
863            let sqrt2_inv = 1.0 / 2.0_f64.sqrt();
864
865            Ok(vec![
866                Complex64::new(1.0, 0.0),        // (0,0)
867                Complex64::new(0.0, 0.0),        // (0,1)
868                Complex64::new(0.0, 0.0),        // (0,2)
869                Complex64::new(0.0, 0.0),        // (0,3)
870                Complex64::new(0.0, 0.0),        // (1,0)
871                Complex64::new(1.0, 0.0),        // (1,1)
872                Complex64::new(0.0, 0.0),        // (1,2)
873                Complex64::new(0.0, 0.0),        // (1,3)
874                Complex64::new(0.0, 0.0),        // (2,0)
875                Complex64::new(0.0, 0.0),        // (2,1)
876                Complex64::new(sqrt2_inv, 0.0),  // (2,2)
877                Complex64::new(sqrt2_inv, 0.0),  // (2,3)
878                Complex64::new(0.0, 0.0),        // (3,0)
879                Complex64::new(0.0, 0.0),        // (3,1)
880                Complex64::new(sqrt2_inv, 0.0),  // (3,2)
881                Complex64::new(-sqrt2_inv, 0.0), // (3,3)
882            ])
883        }
884
885        fn as_any(&self) -> &dyn Any {
886            self
887        }
888
889        impl_clone_gate!();
890    }
891
892    /// Controlled-Phase (CS) gate
893    #[derive(Debug, Clone, Copy)]
894    pub struct CS {
895        /// Control qubit
896        pub control: QubitId,
897
898        /// Target qubit
899        pub target: QubitId,
900    }
901
902    impl GateOp for CS {
903        fn name(&self) -> &'static str {
904            "CS"
905        }
906
907        fn qubits(&self) -> Vec<QubitId> {
908            vec![self.control, self.target]
909        }
910
911        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
912            // For a controlled-S gate, the matrix is:
913            // [[1, 0, 0, 0],
914            //  [0, 1, 0, 0],
915            //  [0, 0, 1, 0],
916            //  [0, 0, 0, i]]
917            Ok(vec![
918                Complex64::new(1.0, 0.0), // (0,0)
919                Complex64::new(0.0, 0.0), // (0,1)
920                Complex64::new(0.0, 0.0), // (0,2)
921                Complex64::new(0.0, 0.0), // (0,3)
922                Complex64::new(0.0, 0.0), // (1,0)
923                Complex64::new(1.0, 0.0), // (1,1)
924                Complex64::new(0.0, 0.0), // (1,2)
925                Complex64::new(0.0, 0.0), // (1,3)
926                Complex64::new(0.0, 0.0), // (2,0)
927                Complex64::new(0.0, 0.0), // (2,1)
928                Complex64::new(1.0, 0.0), // (2,2)
929                Complex64::new(0.0, 0.0), // (2,3)
930                Complex64::new(0.0, 0.0), // (3,0)
931                Complex64::new(0.0, 0.0), // (3,1)
932                Complex64::new(0.0, 0.0), // (3,2)
933                Complex64::new(0.0, 1.0), // (3,3)
934            ])
935        }
936
937        fn as_any(&self) -> &dyn Any {
938            self
939        }
940
941        impl_clone_gate!();
942    }
943
944    /// Toffoli (CCNOT) gate
945    #[derive(Debug, Clone, Copy)]
946    pub struct Toffoli {
947        /// First control qubit
948        pub control1: QubitId,
949
950        /// Second control qubit
951        pub control2: QubitId,
952
953        /// Target qubit
954        pub target: QubitId,
955    }
956
957    impl GateOp for Toffoli {
958        fn name(&self) -> &'static str {
959            "Toffoli"
960        }
961
962        fn qubits(&self) -> Vec<QubitId> {
963            vec![self.control1, self.control2, self.target]
964        }
965
966        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
967            // For a 3-qubit gate, we return an 8x8 matrix
968            // This would be very large to write out fully, so for now we return
969            // an error indicating it should be expanded into its constituent gates
970            Err(crate::error::QuantRS2Error::UnsupportedOperation(
971                "Direct matrix representation of Toffoli gate not supported. \
972                 Use gate decomposition."
973                    .into(),
974            ))
975        }
976
977        fn as_any(&self) -> &dyn Any {
978            self
979        }
980
981        impl_clone_gate!();
982    }
983
984    /// Fredkin (CSWAP) gate
985    #[derive(Debug, Clone, Copy)]
986    pub struct Fredkin {
987        /// Control qubit
988        pub control: QubitId,
989
990        /// First target qubit
991        pub target1: QubitId,
992
993        /// Second target qubit
994        pub target2: QubitId,
995    }
996
997    impl GateOp for Fredkin {
998        fn name(&self) -> &'static str {
999            "Fredkin"
1000        }
1001
1002        fn qubits(&self) -> Vec<QubitId> {
1003            vec![self.control, self.target1, self.target2]
1004        }
1005
1006        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1007            // For a 3-qubit gate, we return an 8x8 matrix
1008            // This would be very large to write out fully, so for now we return
1009            // an error indicating it should be expanded into its constituent gates
1010            Err(crate::error::QuantRS2Error::UnsupportedOperation(
1011                "Direct matrix representation of Fredkin gate not supported. \
1012                 Use gate decomposition."
1013                    .into(),
1014            ))
1015        }
1016
1017        fn as_any(&self) -> &dyn Any {
1018            self
1019        }
1020
1021        impl_clone_gate!();
1022    }
1023
1024    /// Controlled Rotation-X gate (CRX)
1025    #[derive(Debug, Clone, Copy)]
1026    pub struct CRX {
1027        /// Control qubit
1028        pub control: QubitId,
1029
1030        /// Target qubit
1031        pub target: QubitId,
1032
1033        /// Rotation angle (in radians)
1034        pub theta: f64,
1035    }
1036
1037    impl GateOp for CRX {
1038        fn name(&self) -> &'static str {
1039            "CRX"
1040        }
1041
1042        fn qubits(&self) -> Vec<QubitId> {
1043            vec![self.control, self.target]
1044        }
1045
1046        fn is_parameterized(&self) -> bool {
1047            true
1048        }
1049
1050        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1051            // For a controlled-RX gate, the matrix is:
1052            // [[1, 0, 0, 0],
1053            //  [0, 1, 0, 0],
1054            //  [0, 0, cos(θ/2), -i·sin(θ/2)],
1055            //  [0, 0, -i·sin(θ/2), cos(θ/2)]]
1056            let cos = (self.theta / 2.0).cos();
1057            let sin = (self.theta / 2.0).sin();
1058
1059            Ok(vec![
1060                Complex64::new(1.0, 0.0),  // (0,0)
1061                Complex64::new(0.0, 0.0),  // (0,1)
1062                Complex64::new(0.0, 0.0),  // (0,2)
1063                Complex64::new(0.0, 0.0),  // (0,3)
1064                Complex64::new(0.0, 0.0),  // (1,0)
1065                Complex64::new(1.0, 0.0),  // (1,1)
1066                Complex64::new(0.0, 0.0),  // (1,2)
1067                Complex64::new(0.0, 0.0),  // (1,3)
1068                Complex64::new(0.0, 0.0),  // (2,0)
1069                Complex64::new(0.0, 0.0),  // (2,1)
1070                Complex64::new(cos, 0.0),  // (2,2)
1071                Complex64::new(0.0, -sin), // (2,3)
1072                Complex64::new(0.0, 0.0),  // (3,0)
1073                Complex64::new(0.0, 0.0),  // (3,1)
1074                Complex64::new(0.0, -sin), // (3,2)
1075                Complex64::new(cos, 0.0),  // (3,3)
1076            ])
1077        }
1078
1079        fn as_any(&self) -> &dyn Any {
1080            self
1081        }
1082
1083        impl_clone_gate!();
1084    }
1085
1086    /// Controlled Rotation-Y gate (CRY)
1087    #[derive(Debug, Clone, Copy)]
1088    pub struct CRY {
1089        /// Control qubit
1090        pub control: QubitId,
1091
1092        /// Target qubit
1093        pub target: QubitId,
1094
1095        /// Rotation angle (in radians)
1096        pub theta: f64,
1097    }
1098
1099    impl GateOp for CRY {
1100        fn name(&self) -> &'static str {
1101            "CRY"
1102        }
1103
1104        fn qubits(&self) -> Vec<QubitId> {
1105            vec![self.control, self.target]
1106        }
1107
1108        fn is_parameterized(&self) -> bool {
1109            true
1110        }
1111
1112        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1113            // For a controlled-RY gate, the matrix is:
1114            // [[1, 0, 0, 0],
1115            //  [0, 1, 0, 0],
1116            //  [0, 0, cos(θ/2), -sin(θ/2)],
1117            //  [0, 0, sin(θ/2), cos(θ/2)]]
1118            let cos = (self.theta / 2.0).cos();
1119            let sin = (self.theta / 2.0).sin();
1120
1121            Ok(vec![
1122                Complex64::new(1.0, 0.0),  // (0,0)
1123                Complex64::new(0.0, 0.0),  // (0,1)
1124                Complex64::new(0.0, 0.0),  // (0,2)
1125                Complex64::new(0.0, 0.0),  // (0,3)
1126                Complex64::new(0.0, 0.0),  // (1,0)
1127                Complex64::new(1.0, 0.0),  // (1,1)
1128                Complex64::new(0.0, 0.0),  // (1,2)
1129                Complex64::new(0.0, 0.0),  // (1,3)
1130                Complex64::new(0.0, 0.0),  // (2,0)
1131                Complex64::new(0.0, 0.0),  // (2,1)
1132                Complex64::new(cos, 0.0),  // (2,2)
1133                Complex64::new(-sin, 0.0), // (2,3)
1134                Complex64::new(0.0, 0.0),  // (3,0)
1135                Complex64::new(0.0, 0.0),  // (3,1)
1136                Complex64::new(sin, 0.0),  // (3,2)
1137                Complex64::new(cos, 0.0),  // (3,3)
1138            ])
1139        }
1140
1141        fn as_any(&self) -> &dyn Any {
1142            self
1143        }
1144
1145        impl_clone_gate!();
1146    }
1147
1148    /// Controlled Rotation-Z gate (CRZ)
1149    #[derive(Debug, Clone, Copy)]
1150    pub struct CRZ {
1151        /// Control qubit
1152        pub control: QubitId,
1153
1154        /// Target qubit
1155        pub target: QubitId,
1156
1157        /// Rotation angle (in radians)
1158        pub theta: f64,
1159    }
1160
1161    impl GateOp for CRZ {
1162        fn name(&self) -> &'static str {
1163            "CRZ"
1164        }
1165
1166        fn qubits(&self) -> Vec<QubitId> {
1167            vec![self.control, self.target]
1168        }
1169
1170        fn is_parameterized(&self) -> bool {
1171            true
1172        }
1173
1174        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1175            // For a controlled-RZ gate, the matrix is:
1176            // [[1, 0, 0, 0],
1177            //  [0, 1, 0, 0],
1178            //  [0, 0, e^(-iθ/2), 0],
1179            //  [0, 0, 0, e^(iθ/2)]]
1180            let phase = Complex64::new(0.0, -self.theta / 2.0).exp();
1181            let phase_conj = Complex64::new(0.0, self.theta / 2.0).exp();
1182
1183            Ok(vec![
1184                Complex64::new(1.0, 0.0), // (0,0)
1185                Complex64::new(0.0, 0.0), // (0,1)
1186                Complex64::new(0.0, 0.0), // (0,2)
1187                Complex64::new(0.0, 0.0), // (0,3)
1188                Complex64::new(0.0, 0.0), // (1,0)
1189                Complex64::new(1.0, 0.0), // (1,1)
1190                Complex64::new(0.0, 0.0), // (1,2)
1191                Complex64::new(0.0, 0.0), // (1,3)
1192                Complex64::new(0.0, 0.0), // (2,0)
1193                Complex64::new(0.0, 0.0), // (2,1)
1194                phase_conj,               // (2,2)
1195                Complex64::new(0.0, 0.0), // (2,3)
1196                Complex64::new(0.0, 0.0), // (3,0)
1197                Complex64::new(0.0, 0.0), // (3,1)
1198                Complex64::new(0.0, 0.0), // (3,2)
1199                phase,                    // (3,3)
1200            ])
1201        }
1202
1203        fn as_any(&self) -> &dyn Any {
1204            self
1205        }
1206
1207        impl_clone_gate!();
1208    }
1209
1210    /// iSWAP gate - swaps two qubits and phases |01⟩ and |10⟩ by i
1211    ///
1212    /// iSWAP = [[1, 0, 0, 0],
1213    ///          [0, 0, i, 0],
1214    ///          [0, i, 0, 0],
1215    ///          [0, 0, 0, 1]]
1216    #[derive(Debug, Clone, Copy)]
1217    pub struct ISwap {
1218        /// First qubit
1219        pub qubit1: QubitId,
1220        /// Second qubit
1221        pub qubit2: QubitId,
1222    }
1223
1224    impl GateOp for ISwap {
1225        fn name(&self) -> &'static str {
1226            "iSWAP"
1227        }
1228
1229        fn qubits(&self) -> Vec<QubitId> {
1230            vec![self.qubit1, self.qubit2]
1231        }
1232
1233        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1234            Ok(vec![
1235                Complex64::new(1.0, 0.0), // (0,0)
1236                Complex64::new(0.0, 0.0), // (0,1)
1237                Complex64::new(0.0, 0.0), // (0,2)
1238                Complex64::new(0.0, 0.0), // (0,3)
1239                Complex64::new(0.0, 0.0), // (1,0)
1240                Complex64::new(0.0, 0.0), // (1,1)
1241                Complex64::new(0.0, 1.0), // (1,2) = i
1242                Complex64::new(0.0, 0.0), // (1,3)
1243                Complex64::new(0.0, 0.0), // (2,0)
1244                Complex64::new(0.0, 1.0), // (2,1) = i
1245                Complex64::new(0.0, 0.0), // (2,2)
1246                Complex64::new(0.0, 0.0), // (2,3)
1247                Complex64::new(0.0, 0.0), // (3,0)
1248                Complex64::new(0.0, 0.0), // (3,1)
1249                Complex64::new(0.0, 0.0), // (3,2)
1250                Complex64::new(1.0, 0.0), // (3,3)
1251            ])
1252        }
1253
1254        fn as_any(&self) -> &dyn Any {
1255            self
1256        }
1257
1258        impl_clone_gate!();
1259    }
1260
1261    /// ECR gate - Echoed Cross-Resonance gate (IBM native two-qubit gate)
1262    ///
1263    /// ECR = (1/√2) * [[0, 1, 0, i],
1264    ///                  [1, 0, -i, 0],
1265    ///                  [0, i, 0, 1],
1266    ///                  [-i, 0, 1, 0]]
1267    #[derive(Debug, Clone, Copy)]
1268    pub struct ECR {
1269        /// Control qubit
1270        pub control: QubitId,
1271        /// Target qubit
1272        pub target: QubitId,
1273    }
1274
1275    impl GateOp for ECR {
1276        fn name(&self) -> &'static str {
1277            "ECR"
1278        }
1279
1280        fn qubits(&self) -> Vec<QubitId> {
1281            vec![self.control, self.target]
1282        }
1283
1284        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1285            let sqrt2_inv = 1.0 / 2.0_f64.sqrt();
1286            Ok(vec![
1287                Complex64::new(0.0, 0.0),        // (0,0)
1288                Complex64::new(sqrt2_inv, 0.0),  // (0,1)
1289                Complex64::new(0.0, 0.0),        // (0,2)
1290                Complex64::new(0.0, sqrt2_inv),  // (0,3) = i/√2
1291                Complex64::new(sqrt2_inv, 0.0),  // (1,0)
1292                Complex64::new(0.0, 0.0),        // (1,1)
1293                Complex64::new(0.0, -sqrt2_inv), // (1,2) = -i/√2
1294                Complex64::new(0.0, 0.0),        // (1,3)
1295                Complex64::new(0.0, 0.0),        // (2,0)
1296                Complex64::new(0.0, sqrt2_inv),  // (2,1) = i/√2
1297                Complex64::new(0.0, 0.0),        // (2,2)
1298                Complex64::new(sqrt2_inv, 0.0),  // (2,3)
1299                Complex64::new(0.0, -sqrt2_inv), // (3,0) = -i/√2
1300                Complex64::new(0.0, 0.0),        // (3,1)
1301                Complex64::new(sqrt2_inv, 0.0),  // (3,2)
1302                Complex64::new(0.0, 0.0),        // (3,3)
1303            ])
1304        }
1305
1306        fn as_any(&self) -> &dyn Any {
1307            self
1308        }
1309
1310        impl_clone_gate!();
1311    }
1312
1313    /// RXX gate - Two-qubit XX rotation
1314    ///
1315    /// RXX(θ) = exp(-i * θ/2 * X⊗X)
1316    #[derive(Debug, Clone, Copy)]
1317    pub struct RXX {
1318        /// First qubit
1319        pub qubit1: QubitId,
1320        /// Second qubit
1321        pub qubit2: QubitId,
1322        /// Rotation angle
1323        pub theta: f64,
1324    }
1325
1326    impl GateOp for RXX {
1327        fn name(&self) -> &'static str {
1328            "RXX"
1329        }
1330
1331        fn qubits(&self) -> Vec<QubitId> {
1332            vec![self.qubit1, self.qubit2]
1333        }
1334
1335        fn is_parameterized(&self) -> bool {
1336            true
1337        }
1338
1339        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1340            let cos = (self.theta / 2.0).cos();
1341            let sin = (self.theta / 2.0).sin();
1342            let mi_sin = Complex64::new(0.0, -sin);
1343
1344            Ok(vec![
1345                Complex64::new(cos, 0.0), // (0,0)
1346                Complex64::new(0.0, 0.0), // (0,1)
1347                Complex64::new(0.0, 0.0), // (0,2)
1348                mi_sin,                   // (0,3)
1349                Complex64::new(0.0, 0.0), // (1,0)
1350                Complex64::new(cos, 0.0), // (1,1)
1351                mi_sin,                   // (1,2)
1352                Complex64::new(0.0, 0.0), // (1,3)
1353                Complex64::new(0.0, 0.0), // (2,0)
1354                mi_sin,                   // (2,1)
1355                Complex64::new(cos, 0.0), // (2,2)
1356                Complex64::new(0.0, 0.0), // (2,3)
1357                mi_sin,                   // (3,0)
1358                Complex64::new(0.0, 0.0), // (3,1)
1359                Complex64::new(0.0, 0.0), // (3,2)
1360                Complex64::new(cos, 0.0), // (3,3)
1361            ])
1362        }
1363
1364        fn as_any(&self) -> &dyn Any {
1365            self
1366        }
1367
1368        impl_clone_gate!();
1369    }
1370
1371    /// RYY gate - Two-qubit YY rotation
1372    ///
1373    /// RYY(θ) = exp(-i * θ/2 * Y⊗Y)
1374    #[derive(Debug, Clone, Copy)]
1375    pub struct RYY {
1376        /// First qubit
1377        pub qubit1: QubitId,
1378        /// Second qubit
1379        pub qubit2: QubitId,
1380        /// Rotation angle
1381        pub theta: f64,
1382    }
1383
1384    impl GateOp for RYY {
1385        fn name(&self) -> &'static str {
1386            "RYY"
1387        }
1388
1389        fn qubits(&self) -> Vec<QubitId> {
1390            vec![self.qubit1, self.qubit2]
1391        }
1392
1393        fn is_parameterized(&self) -> bool {
1394            true
1395        }
1396
1397        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1398            let cos = (self.theta / 2.0).cos();
1399            let sin = (self.theta / 2.0).sin();
1400            let i_sin = Complex64::new(0.0, sin);
1401            let mi_sin = Complex64::new(0.0, -sin);
1402
1403            Ok(vec![
1404                Complex64::new(cos, 0.0), // (0,0)
1405                Complex64::new(0.0, 0.0), // (0,1)
1406                Complex64::new(0.0, 0.0), // (0,2)
1407                i_sin,                    // (0,3)
1408                Complex64::new(0.0, 0.0), // (1,0)
1409                Complex64::new(cos, 0.0), // (1,1)
1410                mi_sin,                   // (1,2)
1411                Complex64::new(0.0, 0.0), // (1,3)
1412                Complex64::new(0.0, 0.0), // (2,0)
1413                mi_sin,                   // (2,1)
1414                Complex64::new(cos, 0.0), // (2,2)
1415                Complex64::new(0.0, 0.0), // (2,3)
1416                i_sin,                    // (3,0)
1417                Complex64::new(0.0, 0.0), // (3,1)
1418                Complex64::new(0.0, 0.0), // (3,2)
1419                Complex64::new(cos, 0.0), // (3,3)
1420            ])
1421        }
1422
1423        fn as_any(&self) -> &dyn Any {
1424            self
1425        }
1426
1427        impl_clone_gate!();
1428    }
1429
1430    /// RZZ gate - Two-qubit ZZ rotation
1431    ///
1432    /// RZZ(θ) = exp(-i * θ/2 * Z⊗Z)
1433    #[derive(Debug, Clone, Copy)]
1434    pub struct RZZ {
1435        /// First qubit
1436        pub qubit1: QubitId,
1437        /// Second qubit
1438        pub qubit2: QubitId,
1439        /// Rotation angle
1440        pub theta: f64,
1441    }
1442
1443    impl GateOp for RZZ {
1444        fn name(&self) -> &'static str {
1445            "RZZ"
1446        }
1447
1448        fn qubits(&self) -> Vec<QubitId> {
1449            vec![self.qubit1, self.qubit2]
1450        }
1451
1452        fn is_parameterized(&self) -> bool {
1453            true
1454        }
1455
1456        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1457            let phase_neg = Complex64::new(0.0, -self.theta / 2.0).exp();
1458            let phase_pos = Complex64::new(0.0, self.theta / 2.0).exp();
1459
1460            Ok(vec![
1461                phase_neg,                // (0,0) = e^(-iθ/2)
1462                Complex64::new(0.0, 0.0), // (0,1)
1463                Complex64::new(0.0, 0.0), // (0,2)
1464                Complex64::new(0.0, 0.0), // (0,3)
1465                Complex64::new(0.0, 0.0), // (1,0)
1466                phase_pos,                // (1,1) = e^(iθ/2)
1467                Complex64::new(0.0, 0.0), // (1,2)
1468                Complex64::new(0.0, 0.0), // (1,3)
1469                Complex64::new(0.0, 0.0), // (2,0)
1470                Complex64::new(0.0, 0.0), // (2,1)
1471                phase_pos,                // (2,2) = e^(iθ/2)
1472                Complex64::new(0.0, 0.0), // (2,3)
1473                Complex64::new(0.0, 0.0), // (3,0)
1474                Complex64::new(0.0, 0.0), // (3,1)
1475                Complex64::new(0.0, 0.0), // (3,2)
1476                phase_neg,                // (3,3) = e^(-iθ/2)
1477            ])
1478        }
1479
1480        fn as_any(&self) -> &dyn Any {
1481            self
1482        }
1483
1484        impl_clone_gate!();
1485    }
1486
1487    /// RZX gate - Two-qubit ZX rotation (Cross-resonance gate)
1488    ///
1489    /// RZX(θ) = exp(-i * θ/2 * Z⊗X)
1490    #[derive(Debug, Clone, Copy)]
1491    pub struct RZX {
1492        /// Control qubit (Z)
1493        pub control: QubitId,
1494        /// Target qubit (X)
1495        pub target: QubitId,
1496        /// Rotation angle
1497        pub theta: f64,
1498    }
1499
1500    impl GateOp for RZX {
1501        fn name(&self) -> &'static str {
1502            "RZX"
1503        }
1504
1505        fn qubits(&self) -> Vec<QubitId> {
1506            vec![self.control, self.target]
1507        }
1508
1509        fn is_parameterized(&self) -> bool {
1510            true
1511        }
1512
1513        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1514            let cos = (self.theta / 2.0).cos();
1515            let sin = (self.theta / 2.0).sin();
1516            let mi_sin = Complex64::new(0.0, -sin);
1517            let i_sin = Complex64::new(0.0, sin);
1518
1519            Ok(vec![
1520                Complex64::new(cos, 0.0), // (0,0)
1521                mi_sin,                   // (0,1)
1522                Complex64::new(0.0, 0.0), // (0,2)
1523                Complex64::new(0.0, 0.0), // (0,3)
1524                mi_sin,                   // (1,0)
1525                Complex64::new(cos, 0.0), // (1,1)
1526                Complex64::new(0.0, 0.0), // (1,2)
1527                Complex64::new(0.0, 0.0), // (1,3)
1528                Complex64::new(0.0, 0.0), // (2,0)
1529                Complex64::new(0.0, 0.0), // (2,1)
1530                Complex64::new(cos, 0.0), // (2,2)
1531                i_sin,                    // (2,3)
1532                Complex64::new(0.0, 0.0), // (3,0)
1533                Complex64::new(0.0, 0.0), // (3,1)
1534                i_sin,                    // (3,2)
1535                Complex64::new(cos, 0.0), // (3,3)
1536            ])
1537        }
1538
1539        fn as_any(&self) -> &dyn Any {
1540            self
1541        }
1542
1543        impl_clone_gate!();
1544    }
1545
1546    /// DCX gate - Double CNOT gate
1547    ///
1548    /// DCX = CNOT(0,1) @ CNOT(1,0)
1549    #[derive(Debug, Clone, Copy)]
1550    pub struct DCX {
1551        /// First qubit
1552        pub qubit1: QubitId,
1553        /// Second qubit
1554        pub qubit2: QubitId,
1555    }
1556
1557    impl GateOp for DCX {
1558        fn name(&self) -> &'static str {
1559            "DCX"
1560        }
1561
1562        fn qubits(&self) -> Vec<QubitId> {
1563            vec![self.qubit1, self.qubit2]
1564        }
1565
1566        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1567            // DCX = [[1, 0, 0, 0],
1568            //        [0, 0, 0, 1],
1569            //        [0, 1, 0, 0],
1570            //        [0, 0, 1, 0]]
1571            Ok(vec![
1572                Complex64::new(1.0, 0.0), // (0,0)
1573                Complex64::new(0.0, 0.0), // (0,1)
1574                Complex64::new(0.0, 0.0), // (0,2)
1575                Complex64::new(0.0, 0.0), // (0,3)
1576                Complex64::new(0.0, 0.0), // (1,0)
1577                Complex64::new(0.0, 0.0), // (1,1)
1578                Complex64::new(0.0, 0.0), // (1,2)
1579                Complex64::new(1.0, 0.0), // (1,3)
1580                Complex64::new(0.0, 0.0), // (2,0)
1581                Complex64::new(1.0, 0.0), // (2,1)
1582                Complex64::new(0.0, 0.0), // (2,2)
1583                Complex64::new(0.0, 0.0), // (2,3)
1584                Complex64::new(0.0, 0.0), // (3,0)
1585                Complex64::new(0.0, 0.0), // (3,1)
1586                Complex64::new(1.0, 0.0), // (3,2)
1587                Complex64::new(0.0, 0.0), // (3,3)
1588            ])
1589        }
1590
1591        fn as_any(&self) -> &dyn Any {
1592            self
1593        }
1594
1595        impl_clone_gate!();
1596    }
1597
1598    /// XXPlusYY gate - Two-qubit XX+YY interaction (XY gate)
1599    ///
1600    /// Induces a coherent rotation between |01⟩ and |10⟩
1601    #[derive(Debug, Clone, Copy)]
1602    pub struct XXPlusYY {
1603        /// First qubit
1604        pub qubit1: QubitId,
1605        /// Second qubit
1606        pub qubit2: QubitId,
1607        /// Rotation angle theta
1608        pub theta: f64,
1609        /// Phase angle beta
1610        pub beta: f64,
1611    }
1612
1613    impl GateOp for XXPlusYY {
1614        fn name(&self) -> &'static str {
1615            "XXPlusYY"
1616        }
1617
1618        fn qubits(&self) -> Vec<QubitId> {
1619            vec![self.qubit1, self.qubit2]
1620        }
1621
1622        fn is_parameterized(&self) -> bool {
1623            true
1624        }
1625
1626        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1627            let cos = (self.theta / 2.0).cos();
1628            let sin = (self.theta / 2.0).sin();
1629            let exp_neg_i_beta = Complex64::new(0.0, -self.beta).exp();
1630            let exp_i_beta = Complex64::new(0.0, self.beta).exp();
1631            let mi_sin_neg = Complex64::new(0.0, -sin) * exp_neg_i_beta;
1632            let mi_sin_pos = Complex64::new(0.0, -sin) * exp_i_beta;
1633
1634            Ok(vec![
1635                Complex64::new(1.0, 0.0), // (0,0)
1636                Complex64::new(0.0, 0.0), // (0,1)
1637                Complex64::new(0.0, 0.0), // (0,2)
1638                Complex64::new(0.0, 0.0), // (0,3)
1639                Complex64::new(0.0, 0.0), // (1,0)
1640                Complex64::new(cos, 0.0), // (1,1)
1641                mi_sin_neg,               // (1,2)
1642                Complex64::new(0.0, 0.0), // (1,3)
1643                Complex64::new(0.0, 0.0), // (2,0)
1644                mi_sin_pos,               // (2,1)
1645                Complex64::new(cos, 0.0), // (2,2)
1646                Complex64::new(0.0, 0.0), // (2,3)
1647                Complex64::new(0.0, 0.0), // (3,0)
1648                Complex64::new(0.0, 0.0), // (3,1)
1649                Complex64::new(0.0, 0.0), // (3,2)
1650                Complex64::new(1.0, 0.0), // (3,3)
1651            ])
1652        }
1653
1654        fn as_any(&self) -> &dyn Any {
1655            self
1656        }
1657
1658        impl_clone_gate!();
1659    }
1660
1661    /// XXMinusYY gate - Two-qubit XX-YY interaction
1662    ///
1663    /// Induces a coherent rotation between |00⟩ and |11⟩
1664    #[derive(Debug, Clone, Copy)]
1665    pub struct XXMinusYY {
1666        /// First qubit
1667        pub qubit1: QubitId,
1668        /// Second qubit
1669        pub qubit2: QubitId,
1670        /// Rotation angle theta
1671        pub theta: f64,
1672        /// Phase angle beta
1673        pub beta: f64,
1674    }
1675
1676    impl GateOp for XXMinusYY {
1677        fn name(&self) -> &'static str {
1678            "XXMinusYY"
1679        }
1680
1681        fn qubits(&self) -> Vec<QubitId> {
1682            vec![self.qubit1, self.qubit2]
1683        }
1684
1685        fn is_parameterized(&self) -> bool {
1686            true
1687        }
1688
1689        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1690            let cos = (self.theta / 2.0).cos();
1691            let sin = (self.theta / 2.0).sin();
1692            let exp_neg_i_beta = Complex64::new(0.0, -self.beta).exp();
1693            let exp_i_beta = Complex64::new(0.0, self.beta).exp();
1694            let mi_sin_neg = Complex64::new(0.0, -sin) * exp_neg_i_beta;
1695            let mi_sin_pos = Complex64::new(0.0, -sin) * exp_i_beta;
1696
1697            Ok(vec![
1698                Complex64::new(cos, 0.0), // (0,0)
1699                Complex64::new(0.0, 0.0), // (0,1)
1700                Complex64::new(0.0, 0.0), // (0,2)
1701                mi_sin_pos,               // (0,3)
1702                Complex64::new(0.0, 0.0), // (1,0)
1703                Complex64::new(1.0, 0.0), // (1,1)
1704                Complex64::new(0.0, 0.0), // (1,2)
1705                Complex64::new(0.0, 0.0), // (1,3)
1706                Complex64::new(0.0, 0.0), // (2,0)
1707                Complex64::new(0.0, 0.0), // (2,1)
1708                Complex64::new(1.0, 0.0), // (2,2)
1709                Complex64::new(0.0, 0.0), // (2,3)
1710                mi_sin_neg,               // (3,0)
1711                Complex64::new(0.0, 0.0), // (3,1)
1712                Complex64::new(0.0, 0.0), // (3,2)
1713                Complex64::new(cos, 0.0), // (3,3)
1714            ])
1715        }
1716
1717        fn as_any(&self) -> &dyn Any {
1718            self
1719        }
1720
1721        impl_clone_gate!();
1722    }
1723
1724    /// CSX gate - Controlled-√X gate
1725    #[derive(Debug, Clone, Copy)]
1726    pub struct CSX {
1727        /// Control qubit
1728        pub control: QubitId,
1729        /// Target qubit
1730        pub target: QubitId,
1731    }
1732
1733    impl GateOp for CSX {
1734        fn name(&self) -> &'static str {
1735            "CSX"
1736        }
1737
1738        fn qubits(&self) -> Vec<QubitId> {
1739            vec![self.control, self.target]
1740        }
1741
1742        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1743            let half_plus_i_half = Complex64::new(0.5, 0.5);
1744            let half_minus_i_half = Complex64::new(0.5, -0.5);
1745
1746            Ok(vec![
1747                Complex64::new(1.0, 0.0), // (0,0)
1748                Complex64::new(0.0, 0.0), // (0,1)
1749                Complex64::new(0.0, 0.0), // (0,2)
1750                Complex64::new(0.0, 0.0), // (0,3)
1751                Complex64::new(0.0, 0.0), // (1,0)
1752                Complex64::new(1.0, 0.0), // (1,1)
1753                Complex64::new(0.0, 0.0), // (1,2)
1754                Complex64::new(0.0, 0.0), // (1,3)
1755                Complex64::new(0.0, 0.0), // (2,0)
1756                Complex64::new(0.0, 0.0), // (2,1)
1757                half_plus_i_half,         // (2,2)
1758                half_minus_i_half,        // (2,3)
1759                Complex64::new(0.0, 0.0), // (3,0)
1760                Complex64::new(0.0, 0.0), // (3,1)
1761                half_minus_i_half,        // (3,2)
1762                half_plus_i_half,         // (3,3)
1763            ])
1764        }
1765
1766        fn as_any(&self) -> &dyn Any {
1767            self
1768        }
1769
1770        impl_clone_gate!();
1771    }
1772}
1773
1774/// Global phase and other zero-qubit gates
1775pub mod global {
1776    use super::*;
1777    use std::any::Any;
1778
1779    /// Global Phase gate - applies a global phase to the quantum state
1780    ///
1781    /// GlobalPhase(θ) = e^(iθ) * I
1782    #[derive(Debug, Clone, Copy)]
1783    pub struct GlobalPhase {
1784        /// Phase angle
1785        pub phase: f64,
1786    }
1787
1788    impl GateOp for GlobalPhase {
1789        fn name(&self) -> &'static str {
1790            "GlobalPhase"
1791        }
1792
1793        fn qubits(&self) -> Vec<QubitId> {
1794            vec![] // Global phase doesn't act on specific qubits
1795        }
1796
1797        fn is_parameterized(&self) -> bool {
1798            true
1799        }
1800
1801        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1802            let phase = Complex64::new(0.0, self.phase).exp();
1803            Ok(vec![phase])
1804        }
1805
1806        fn as_any(&self) -> &dyn Any {
1807            self
1808        }
1809
1810        impl_clone_gate!();
1811    }
1812
1813    /// R gate - Rotation around axis in X-Y plane
1814    ///
1815    /// R(θ, φ) = exp(-i * θ/2 * (cos(φ)X + sin(φ)Y))
1816    #[derive(Debug, Clone, Copy)]
1817    pub struct RGate {
1818        /// Target qubit
1819        pub target: QubitId,
1820        /// Rotation angle theta
1821        pub theta: f64,
1822        /// Axis angle phi
1823        pub phi: f64,
1824    }
1825
1826    impl GateOp for RGate {
1827        fn name(&self) -> &'static str {
1828            "R"
1829        }
1830
1831        fn qubits(&self) -> Vec<QubitId> {
1832            vec![self.target]
1833        }
1834
1835        fn is_parameterized(&self) -> bool {
1836            true
1837        }
1838
1839        fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
1840            let cos = (self.theta / 2.0).cos();
1841            let sin = (self.theta / 2.0).sin();
1842            let exp_neg_i_phi = Complex64::new(0.0, -self.phi).exp();
1843            let exp_i_phi = Complex64::new(0.0, self.phi).exp();
1844
1845            Ok(vec![
1846                Complex64::new(cos, 0.0),
1847                Complex64::new(0.0, -sin) * exp_neg_i_phi,
1848                Complex64::new(0.0, -sin) * exp_i_phi,
1849                Complex64::new(cos, 0.0),
1850            ])
1851        }
1852
1853        fn as_any(&self) -> &dyn Any {
1854            self
1855        }
1856
1857        impl_clone_gate!();
1858    }
1859}