1use num_complex::Complex64;
2use std::any::Any;
3use std::f64::consts::PI;
4use std::fmt::Debug;
5
6use crate::error::QuantRS2Result;
7use crate::qubit::QubitId;
8
9macro_rules! impl_clone_gate {
11 () => {
12 fn clone_gate(&self) -> Box<dyn GateOp> {
13 Box::new(self.clone())
14 }
15 };
16}
17
18pub trait GateOp: Debug + Send + Sync {
20 fn name(&self) -> &'static str;
22
23 fn qubits(&self) -> Vec<QubitId>;
25
26 fn num_qubits(&self) -> usize {
28 self.qubits().len()
29 }
30
31 fn is_parameterized(&self) -> bool {
33 false
34 }
35
36 fn matrix(&self) -> QuantRS2Result<Vec<Complex64>>;
38
39 fn as_any(&self) -> &dyn Any;
41
42 fn clone_gate(&self) -> Box<dyn GateOp>;
44}
45
46impl Clone for Box<dyn GateOp> {
48 fn clone(&self) -> Box<dyn GateOp> {
49 self.clone_gate()
50 }
51}
52
53pub mod single {
55 use super::*;
56 use std::any::Any;
57
58 #[derive(Debug, Clone, Copy)]
60 pub struct Hadamard {
61 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 #[derive(Debug, Clone, Copy)]
93 pub struct PauliX {
94 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 #[derive(Debug, Clone, Copy)]
125 pub struct PauliY {
126 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 #[derive(Debug, Clone, Copy)]
157 pub struct PauliZ {
158 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 #[derive(Debug, Clone, Copy)]
189 pub struct RotationX {
190 pub target: QubitId,
192
193 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 #[derive(Debug, Clone, Copy)]
230 pub struct RotationY {
231 pub target: QubitId,
233
234 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 #[derive(Debug, Clone, Copy)]
271 pub struct RotationZ {
272 pub target: QubitId,
274
275 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 #[derive(Debug, Clone, Copy)]
312 pub struct Phase {
313 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 #[derive(Debug, Clone, Copy)]
344 pub struct T {
345 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 #[derive(Debug, Clone, Copy)]
377 pub struct TDagger {
378 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 #[derive(Debug, Clone, Copy)]
410 pub struct PhaseDagger {
411 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 #[derive(Debug, Clone, Copy)]
442 pub struct SqrtX {
443 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 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 #[derive(Debug, Clone, Copy)]
478 pub struct SqrtXDagger {
479 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 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
513pub mod multi {
515 use super::*;
516 use std::any::Any;
517
518 #[derive(Debug, Clone, Copy)]
520 pub struct CNOT {
521 pub control: QubitId,
523
524 pub target: QubitId,
526 }
527
528 impl GateOp for CNOT {
529 fn name(&self) -> &'static str {
530 "CNOT"
531 }
532
533 fn qubits(&self) -> Vec<QubitId> {
534 vec![self.control, self.target]
535 }
536
537 fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
538 Ok(vec![
540 Complex64::new(1.0, 0.0),
541 Complex64::new(0.0, 0.0),
542 Complex64::new(0.0, 0.0),
543 Complex64::new(0.0, 0.0),
544 Complex64::new(0.0, 0.0),
545 Complex64::new(1.0, 0.0),
546 Complex64::new(0.0, 0.0),
547 Complex64::new(0.0, 0.0),
548 Complex64::new(0.0, 0.0),
549 Complex64::new(0.0, 0.0),
550 Complex64::new(0.0, 0.0),
551 Complex64::new(1.0, 0.0),
552 Complex64::new(0.0, 0.0),
553 Complex64::new(0.0, 0.0),
554 Complex64::new(1.0, 0.0),
555 Complex64::new(0.0, 0.0),
556 ])
557 }
558
559 fn as_any(&self) -> &dyn Any {
560 self
561 }
562
563 impl_clone_gate!();
564 }
565
566 #[derive(Debug, Clone, Copy)]
568 pub struct CZ {
569 pub control: QubitId,
571
572 pub target: QubitId,
574 }
575
576 impl GateOp for CZ {
577 fn name(&self) -> &'static str {
578 "CZ"
579 }
580
581 fn qubits(&self) -> Vec<QubitId> {
582 vec![self.control, self.target]
583 }
584
585 fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
586 Ok(vec![
588 Complex64::new(1.0, 0.0),
589 Complex64::new(0.0, 0.0),
590 Complex64::new(0.0, 0.0),
591 Complex64::new(0.0, 0.0),
592 Complex64::new(0.0, 0.0),
593 Complex64::new(1.0, 0.0),
594 Complex64::new(0.0, 0.0),
595 Complex64::new(0.0, 0.0),
596 Complex64::new(0.0, 0.0),
597 Complex64::new(0.0, 0.0),
598 Complex64::new(1.0, 0.0),
599 Complex64::new(0.0, 0.0),
600 Complex64::new(0.0, 0.0),
601 Complex64::new(0.0, 0.0),
602 Complex64::new(0.0, 0.0),
603 Complex64::new(-1.0, 0.0),
604 ])
605 }
606
607 fn as_any(&self) -> &dyn Any {
608 self
609 }
610
611 impl_clone_gate!();
612 }
613
614 #[derive(Debug, Clone, Copy)]
616 pub struct SWAP {
617 pub qubit1: QubitId,
619
620 pub qubit2: QubitId,
622 }
623
624 impl GateOp for SWAP {
625 fn name(&self) -> &'static str {
626 "SWAP"
627 }
628
629 fn qubits(&self) -> Vec<QubitId> {
630 vec![self.qubit1, self.qubit2]
631 }
632
633 fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
634 Ok(vec![
636 Complex64::new(1.0, 0.0),
637 Complex64::new(0.0, 0.0),
638 Complex64::new(0.0, 0.0),
639 Complex64::new(0.0, 0.0),
640 Complex64::new(0.0, 0.0),
641 Complex64::new(0.0, 0.0),
642 Complex64::new(1.0, 0.0),
643 Complex64::new(0.0, 0.0),
644 Complex64::new(0.0, 0.0),
645 Complex64::new(1.0, 0.0),
646 Complex64::new(0.0, 0.0),
647 Complex64::new(0.0, 0.0),
648 Complex64::new(0.0, 0.0),
649 Complex64::new(0.0, 0.0),
650 Complex64::new(0.0, 0.0),
651 Complex64::new(1.0, 0.0),
652 ])
653 }
654
655 fn as_any(&self) -> &dyn Any {
656 self
657 }
658
659 impl_clone_gate!();
660 }
661
662 #[derive(Debug, Clone, Copy)]
664 pub struct CY {
665 pub control: QubitId,
667
668 pub target: QubitId,
670 }
671
672 impl GateOp for CY {
673 fn name(&self) -> &'static str {
674 "CY"
675 }
676
677 fn qubits(&self) -> Vec<QubitId> {
678 vec![self.control, self.target]
679 }
680
681 fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
682 Ok(vec![
688 Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, -1.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 1.0), Complex64::new(0.0, 0.0), ])
705 }
706
707 fn as_any(&self) -> &dyn Any {
708 self
709 }
710
711 impl_clone_gate!();
712 }
713
714 #[derive(Debug, Clone, Copy)]
716 pub struct CH {
717 pub control: QubitId,
719
720 pub target: QubitId,
722 }
723
724 impl GateOp for CH {
725 fn name(&self) -> &'static str {
726 "CH"
727 }
728
729 fn qubits(&self) -> Vec<QubitId> {
730 vec![self.control, self.target]
731 }
732
733 fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
734 let sqrt2_inv = 1.0 / 2.0_f64.sqrt();
740
741 Ok(vec![
742 Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(sqrt2_inv, 0.0), Complex64::new(sqrt2_inv, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(sqrt2_inv, 0.0), Complex64::new(-sqrt2_inv, 0.0), ])
759 }
760
761 fn as_any(&self) -> &dyn Any {
762 self
763 }
764
765 impl_clone_gate!();
766 }
767
768 #[derive(Debug, Clone, Copy)]
770 pub struct CS {
771 pub control: QubitId,
773
774 pub target: QubitId,
776 }
777
778 impl GateOp for CS {
779 fn name(&self) -> &'static str {
780 "CS"
781 }
782
783 fn qubits(&self) -> Vec<QubitId> {
784 vec![self.control, self.target]
785 }
786
787 fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
788 Ok(vec![
794 Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 1.0), ])
811 }
812
813 fn as_any(&self) -> &dyn Any {
814 self
815 }
816
817 impl_clone_gate!();
818 }
819
820 #[derive(Debug, Clone, Copy)]
822 pub struct Toffoli {
823 pub control1: QubitId,
825
826 pub control2: QubitId,
828
829 pub target: QubitId,
831 }
832
833 impl GateOp for Toffoli {
834 fn name(&self) -> &'static str {
835 "Toffoli"
836 }
837
838 fn qubits(&self) -> Vec<QubitId> {
839 vec![self.control1, self.control2, self.target]
840 }
841
842 fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
843 Err(crate::error::QuantRS2Error::UnsupportedOperation(
847 "Direct matrix representation of Toffoli gate not supported. \
848 Use gate decomposition."
849 .into(),
850 ))
851 }
852
853 fn as_any(&self) -> &dyn Any {
854 self
855 }
856
857 impl_clone_gate!();
858 }
859
860 #[derive(Debug, Clone, Copy)]
862 pub struct Fredkin {
863 pub control: QubitId,
865
866 pub target1: QubitId,
868
869 pub target2: QubitId,
871 }
872
873 impl GateOp for Fredkin {
874 fn name(&self) -> &'static str {
875 "Fredkin"
876 }
877
878 fn qubits(&self) -> Vec<QubitId> {
879 vec![self.control, self.target1, self.target2]
880 }
881
882 fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
883 Err(crate::error::QuantRS2Error::UnsupportedOperation(
887 "Direct matrix representation of Fredkin gate not supported. \
888 Use gate decomposition."
889 .into(),
890 ))
891 }
892
893 fn as_any(&self) -> &dyn Any {
894 self
895 }
896
897 impl_clone_gate!();
898 }
899
900 #[derive(Debug, Clone, Copy)]
902 pub struct CRX {
903 pub control: QubitId,
905
906 pub target: QubitId,
908
909 pub theta: f64,
911 }
912
913 impl GateOp for CRX {
914 fn name(&self) -> &'static str {
915 "CRX"
916 }
917
918 fn qubits(&self) -> Vec<QubitId> {
919 vec![self.control, self.target]
920 }
921
922 fn is_parameterized(&self) -> bool {
923 true
924 }
925
926 fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
927 let cos = (self.theta / 2.0).cos();
933 let sin = (self.theta / 2.0).sin();
934
935 Ok(vec![
936 Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(cos, 0.0), Complex64::new(0.0, -sin), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, -sin), Complex64::new(cos, 0.0), ])
953 }
954
955 fn as_any(&self) -> &dyn Any {
956 self
957 }
958
959 impl_clone_gate!();
960 }
961
962 #[derive(Debug, Clone, Copy)]
964 pub struct CRY {
965 pub control: QubitId,
967
968 pub target: QubitId,
970
971 pub theta: f64,
973 }
974
975 impl GateOp for CRY {
976 fn name(&self) -> &'static str {
977 "CRY"
978 }
979
980 fn qubits(&self) -> Vec<QubitId> {
981 vec![self.control, self.target]
982 }
983
984 fn is_parameterized(&self) -> bool {
985 true
986 }
987
988 fn matrix(&self) -> QuantRS2Result<Vec<Complex64>> {
989 let cos = (self.theta / 2.0).cos();
995 let sin = (self.theta / 2.0).sin();
996
997 Ok(vec![
998 Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(cos, 0.0), Complex64::new(-sin, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(sin, 0.0), Complex64::new(cos, 0.0), ])
1015 }
1016
1017 fn as_any(&self) -> &dyn Any {
1018 self
1019 }
1020
1021 impl_clone_gate!();
1022 }
1023
1024 #[derive(Debug, Clone, Copy)]
1026 pub struct CRZ {
1027 pub control: QubitId,
1029
1030 pub target: QubitId,
1032
1033 pub theta: f64,
1035 }
1036
1037 impl GateOp for CRZ {
1038 fn name(&self) -> &'static str {
1039 "CRZ"
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 let phase = Complex64::new(0.0, -self.theta / 2.0).exp();
1057 let phase_conj = Complex64::new(0.0, self.theta / 2.0).exp();
1058
1059 Ok(vec![
1060 Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(1.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), phase_conj, Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), Complex64::new(0.0, 0.0), phase, ])
1077 }
1078
1079 fn as_any(&self) -> &dyn Any {
1080 self
1081 }
1082
1083 impl_clone_gate!();
1084 }
1085}