1use scirs2_core::Complex64;
2use scirs2_core::parallel_ops::*;
3use std::sync::Mutex;
4
5use quantrs2_circuit::builder::{Circuit, Simulator};
6use quantrs2_core::{
7 error::{QuantRS2Error, QuantRS2Result},
8 gate::{multi, single, GateOp},
9 qubit::QubitId,
10 register::Register,
11};
12
13use crate::diagnostics::SimulationDiagnostics;
14use crate::optimized_simd;
15use crate::scirs2_integration::{SciRS2Backend, SciRS2Matrix, SciRS2Vector, BLAS};
16use crate::utils::{flip_bit, gate_vec_to_array2};
17
18#[derive(Debug)]
23pub struct StateVectorSimulator {
24 pub parallel: bool,
26
27 pub noise_model: Option<crate::noise::NoiseModel>,
29
30 pub advanced_noise_model: Option<crate::noise_advanced::AdvancedNoiseModel>,
32
33 buffer_pool: Mutex<BufferPool>,
35
36 pub use_simd: bool,
38
39 pub use_gate_fusion: bool,
41
42 pub diagnostics: Option<SimulationDiagnostics>,
44
45 scirs2_backend: SciRS2Backend,
47}
48
49impl Clone for StateVectorSimulator {
50 fn clone(&self) -> Self {
51 Self {
52 parallel: self.parallel,
53 noise_model: self.noise_model.clone(),
54 advanced_noise_model: self.advanced_noise_model.clone(),
55 buffer_pool: Mutex::new(BufferPool::new(4, 1024)), use_simd: self.use_simd,
57 use_gate_fusion: self.use_gate_fusion,
58 diagnostics: self
59 .diagnostics
60 .as_ref()
61 .map(|_| SimulationDiagnostics::new()),
62 scirs2_backend: SciRS2Backend::new(),
63 }
64 }
65}
66
67#[derive(Debug, Clone)]
69pub struct BufferPool {
70 working_buffers: std::collections::VecDeque<Vec<Complex64>>,
72 max_buffers: usize,
74 target_size: usize,
76}
77
78impl BufferPool {
79 pub fn new(max_buffers: usize, target_size: usize) -> Self {
81 Self {
82 working_buffers: std::collections::VecDeque::with_capacity(max_buffers),
83 max_buffers,
84 target_size,
85 }
86 }
87
88 pub fn get_buffer(&mut self, size: usize) -> Vec<Complex64> {
90 if let Some(mut buffer) = self.working_buffers.pop_front() {
92 if buffer.capacity() >= size {
93 buffer.clear();
94 buffer.resize(size, Complex64::new(0.0, 0.0));
95 return buffer;
96 }
97 }
98
99 let capacity = size.max(self.target_size);
101 let mut buffer = Vec::with_capacity(capacity);
102 buffer.resize(size, Complex64::new(0.0, 0.0));
103 buffer
104 }
105
106 pub fn return_buffer(&mut self, buffer: Vec<Complex64>) {
108 if self.working_buffers.len() < self.max_buffers
109 && buffer.capacity() >= self.target_size / 2
110 {
111 self.working_buffers.push_back(buffer);
112 }
113 }
115
116 pub fn clear(&mut self) {
118 self.working_buffers.clear();
119 }
120}
121
122impl StateVectorSimulator {
123 pub fn new() -> Self {
125 Self {
126 parallel: true,
127 noise_model: None,
128 advanced_noise_model: None,
129 buffer_pool: Mutex::new(BufferPool::new(4, 1024)), use_simd: true,
131 use_gate_fusion: true,
132 diagnostics: None,
133 scirs2_backend: SciRS2Backend::new(),
134 }
135 }
136
137 pub fn sequential() -> Self {
139 Self {
140 parallel: false,
141 noise_model: None,
142 advanced_noise_model: None,
143 buffer_pool: Mutex::new(BufferPool::new(2, 512)), use_simd: true,
145 use_gate_fusion: true,
146 diagnostics: None,
147 scirs2_backend: SciRS2Backend::new(),
148 }
149 }
150
151 pub fn with_noise(noise_model: crate::noise::NoiseModel) -> Self {
153 Self {
154 parallel: true,
155 noise_model: Some(noise_model),
156 advanced_noise_model: None,
157 buffer_pool: Mutex::new(BufferPool::new(4, 1024)),
158 use_simd: true,
159 use_gate_fusion: true,
160 diagnostics: None,
161 scirs2_backend: SciRS2Backend::new(),
162 }
163 }
164
165 pub fn with_advanced_noise(
167 advanced_noise_model: crate::noise_advanced::AdvancedNoiseModel,
168 ) -> Self {
169 Self {
170 parallel: true,
171 noise_model: None,
172 advanced_noise_model: Some(advanced_noise_model),
173 buffer_pool: Mutex::new(BufferPool::new(4, 1024)),
174 use_simd: true,
175 use_gate_fusion: true,
176 diagnostics: None,
177 scirs2_backend: SciRS2Backend::new(),
178 }
179 }
180
181 pub fn with_buffer_pool(parallel: bool, max_buffers: usize, target_size: usize) -> Self {
183 Self {
184 parallel,
185 noise_model: None,
186 advanced_noise_model: None,
187 buffer_pool: Mutex::new(BufferPool::new(max_buffers, target_size)),
188 use_simd: true,
189 use_gate_fusion: true,
190 diagnostics: None,
191 scirs2_backend: SciRS2Backend::new(),
192 }
193 }
194
195 pub fn set_noise_model(&mut self, noise_model: crate::noise::NoiseModel) -> &mut Self {
197 self.noise_model = Some(noise_model);
198 self.advanced_noise_model = None; self
200 }
201
202 pub fn set_advanced_noise_model(
204 &mut self,
205 advanced_noise_model: crate::noise_advanced::AdvancedNoiseModel,
206 ) -> &mut Self {
207 self.advanced_noise_model = Some(advanced_noise_model);
208 self.noise_model = None; self
210 }
211
212 pub fn remove_noise_model(&mut self) -> &mut Self {
214 self.noise_model = None;
215 self.advanced_noise_model = None;
216 self
217 }
218
219 pub fn set_simd_enabled(&mut self, enabled: bool) -> &mut Self {
221 self.use_simd = enabled;
222 self
223 }
224
225 pub fn set_gate_fusion_enabled(&mut self, enabled: bool) -> &mut Self {
227 self.use_gate_fusion = enabled;
228 self
229 }
230
231 pub fn get_buffer_pool(&self) -> &Mutex<BufferPool> {
233 &self.buffer_pool
234 }
235
236 pub fn enable_diagnostics(&mut self) -> &mut Self {
238 self.diagnostics = Some(SimulationDiagnostics::new());
239 self
240 }
241
242 pub fn disable_diagnostics(&mut self) -> &mut Self {
244 self.diagnostics = None;
245 self
246 }
247
248 pub fn get_diagnostics_report(&self) -> Option<crate::diagnostics::DiagnosticReport> {
250 self.diagnostics.as_ref().map(|d| d.generate_report())
251 }
252
253 pub fn high_performance() -> Self {
255 Self {
256 parallel: true,
257 noise_model: None,
258 advanced_noise_model: None,
259 buffer_pool: Mutex::new(BufferPool::new(8, 2048)), use_simd: true,
261 use_gate_fusion: true,
262 diagnostics: Some(SimulationDiagnostics::new()),
263 scirs2_backend: SciRS2Backend::new(),
264 }
265 }
266
267 #[cfg(feature = "advanced_math")]
269 fn apply_dense_matrix_vector(
270 &mut self,
271 matrix: &[Complex64],
272 vector: &[Complex64],
273 result: &mut [Complex64],
274 ) -> QuantRS2Result<()> {
275 if self.scirs2_backend.is_available() && matrix.len() >= 64 && vector.len() >= 8 {
276 use scirs2_core::ndarray::{Array1, Array2};
278
279 let rows = result.len();
280 let cols = vector.len();
281
282 if matrix.len() != rows * cols {
283 return Err(QuantRS2Error::InvalidInput(
284 "Dimension mismatch in matrix application".to_string(),
285 ));
286 }
287
288 let matrix_2d =
290 Array2::from_shape_vec((rows, cols), matrix.to_vec()).map_err(|_| {
291 QuantRS2Error::InvalidInput("Matrix shape conversion failed".to_string())
292 })?;
293 let vector_1d = Array1::from_vec(vector.to_vec());
294
295 let scirs2_matrix = SciRS2Matrix::from_array2(matrix_2d);
297 let scirs2_vector = SciRS2Vector::from_array1(vector_1d);
298
299 let scirs2_result = self
301 .scirs2_backend
302 .matrix_vector_multiply(&scirs2_matrix, &scirs2_vector)
303 .map_err(|_| {
304 QuantRS2Error::ComputationError(
305 "Matrix-vector multiplication failed".to_string(),
306 )
307 })?;
308
309 let result_array = scirs2_result.to_array1().map_err(|_| {
311 QuantRS2Error::ComputationError("Result conversion to array failed".to_string())
312 })?;
313 result.copy_from_slice(result_array.as_slice().unwrap());
314
315 Ok(())
316 } else {
317 for i in 0..result.len() {
319 result[i] = Complex64::new(0.0, 0.0);
320 for j in 0..vector.len() {
321 result[i] += matrix[i * vector.len() + j] * vector[j];
322 }
323 }
324 Ok(())
325 }
326 }
327
328 #[cfg(not(feature = "advanced_math"))]
330 fn apply_dense_matrix_vector(
331 &mut self,
332 matrix: &[Complex64],
333 vector: &[Complex64],
334 result: &mut [Complex64],
335 ) -> QuantRS2Result<()> {
336 for i in 0..result.len() {
338 result[i] = Complex64::new(0.0, 0.0);
339 for j in 0..vector.len() {
340 result[i] += matrix[i * vector.len() + j] * vector[j];
341 }
342 }
343 Ok(())
344 }
345
346 fn apply_single_qubit_gate<const N: usize>(
348 &self,
349 state: &mut [Complex64],
350 gate_matrix: &[Complex64],
351 target: QubitId,
352 ) -> QuantRS2Result<()> {
353 let target_idx = target.id() as usize;
354 if target_idx >= N {
355 return Err(QuantRS2Error::InvalidQubitId(target.id()));
356 }
357
358 if self.use_simd && state.len() >= 8 {
360 return self.apply_single_qubit_gate_simd::<N>(state, gate_matrix, target_idx);
361 }
362
363 let m00 = gate_matrix[0];
366 let m01 = gate_matrix[1];
367 let m10 = gate_matrix[2];
368 let m11 = gate_matrix[3];
369
370 if self.parallel {
372 let mut state_copy = self.buffer_pool.lock().unwrap().get_buffer(state.len());
374 state_copy.copy_from_slice(state);
375
376 state.par_iter_mut().enumerate().for_each(|(idx, amp)| {
377 let bit_val = (idx >> target_idx) & 1;
378 let paired_idx = if bit_val == 0 {
379 idx | (1 << target_idx)
380 } else {
381 idx & !(1 << target_idx)
382 };
383
384 let idx0 = if bit_val == 0 { idx } else { paired_idx };
385 let idx1 = if bit_val == 0 { paired_idx } else { idx };
386
387 let val0 = state_copy[idx0];
388 let val1 = state_copy[idx1];
389
390 *amp = if idx == idx0 {
392 m00 * val0 + m01 * val1
393 } else {
394 m10 * val0 + m11 * val1
395 };
396 });
397
398 self.buffer_pool.lock().unwrap().return_buffer(state_copy);
400 } else {
401 let dim = state.len();
403 let mut new_state = self.buffer_pool.lock().unwrap().get_buffer(dim);
404
405 for i in 0..dim {
406 let bit_val = (i >> target_idx) & 1;
407 let paired_idx = flip_bit(i, target_idx);
408
409 if bit_val == 0 {
410 new_state[i] = m00 * state[i] + m01 * state[paired_idx];
411 new_state[paired_idx] = m10 * state[i] + m11 * state[paired_idx];
412 }
413 }
414
415 state.copy_from_slice(&new_state);
416 self.buffer_pool.lock().unwrap().return_buffer(new_state);
418 }
419
420 Ok(())
421 }
422
423 fn apply_single_qubit_gate_simd<const N: usize>(
425 &self,
426 state: &mut [Complex64],
427 gate_matrix: &[Complex64],
428 target_idx: usize,
429 ) -> QuantRS2Result<()> {
430 let dim = state.len();
431 let pairs_per_block = 1 << target_idx;
432 let total_pairs = dim / 2;
433
434 let mut pool = self.buffer_pool.lock().unwrap();
436 let mut in_amps0 = pool.get_buffer(total_pairs);
437 let mut in_amps1 = pool.get_buffer(total_pairs);
438 let mut out_amps0 = pool.get_buffer(total_pairs);
439 let mut out_amps1 = pool.get_buffer(total_pairs);
440
441 let mut pair_idx = 0;
443 for block in 0..(dim / (pairs_per_block * 2)) {
444 let block_start = block * pairs_per_block * 2;
445
446 for offset in 0..pairs_per_block {
447 let idx0 = block_start + offset;
448 let idx1 = block_start + pairs_per_block + offset;
449
450 in_amps0[pair_idx] = state[idx0];
451 in_amps1[pair_idx] = state[idx1];
452 pair_idx += 1;
453 }
454 }
455
456 let gate_matrix_array: [Complex64; 4] = [
458 gate_matrix[0],
459 gate_matrix[1],
460 gate_matrix[2],
461 gate_matrix[3],
462 ];
463
464 optimized_simd::apply_single_qubit_gate_optimized(
466 &gate_matrix_array,
467 &in_amps0,
468 &in_amps1,
469 &mut out_amps0,
470 &mut out_amps1,
471 );
472
473 pair_idx = 0;
475 for block in 0..(dim / (pairs_per_block * 2)) {
476 let block_start = block * pairs_per_block * 2;
477
478 for offset in 0..pairs_per_block {
479 let idx0 = block_start + offset;
480 let idx1 = block_start + pairs_per_block + offset;
481
482 state[idx0] = out_amps0[pair_idx];
483 state[idx1] = out_amps1[pair_idx];
484 pair_idx += 1;
485 }
486 }
487
488 pool.return_buffer(in_amps0);
490 pool.return_buffer(in_amps1);
491 pool.return_buffer(out_amps0);
492 pool.return_buffer(out_amps1);
493
494 Ok(())
495 }
496
497 fn apply_two_qubit_gate<const N: usize>(
499 &self,
500 state: &mut [Complex64],
501 gate_matrix: &[Complex64],
502 control: QubitId,
503 target: QubitId,
504 ) -> QuantRS2Result<()> {
505 let control_idx = control.id() as usize;
506 let target_idx = target.id() as usize;
507
508 if control_idx >= N || target_idx >= N {
509 return Err(QuantRS2Error::InvalidQubitId(if control_idx >= N {
510 control.id()
511 } else {
512 target.id()
513 }));
514 }
515
516 if control_idx == target_idx {
517 return Err(QuantRS2Error::CircuitValidationFailed(
518 "Control and target qubits must be different".into(),
519 ));
520 }
521
522 let m = gate_matrix; if self.parallel {
527 let mut state_copy = self.buffer_pool.lock().unwrap().get_buffer(state.len());
529 state_copy.copy_from_slice(state);
530
531 state.par_iter_mut().enumerate().for_each(|(idx, amp)| {
532 let idx00 = idx & !(1 << control_idx) & !(1 << target_idx);
533 let idx01 = idx00 | (1 << target_idx);
534 let idx10 = idx00 | (1 << control_idx);
535 let idx11 = idx00 | (1 << control_idx) | (1 << target_idx);
536
537 let val00 = state_copy[idx00];
538 let val01 = state_copy[idx01];
539 let val10 = state_copy[idx10];
540 let val11 = state_copy[idx11];
541
542 *amp = match idx {
544 i if i == idx00 => m[0] * val00 + m[1] * val01 + m[2] * val10 + m[3] * val11,
545 i if i == idx01 => m[4] * val00 + m[5] * val01 + m[6] * val10 + m[7] * val11,
546 i if i == idx10 => m[8] * val00 + m[9] * val01 + m[10] * val10 + m[11] * val11,
547 i if i == idx11 => {
548 m[12] * val00 + m[13] * val01 + m[14] * val10 + m[15] * val11
549 }
550 _ => unreachable!(),
551 };
552 });
553
554 self.buffer_pool.lock().unwrap().return_buffer(state_copy);
556 } else {
557 let dim = state.len();
559 let mut new_state = self.buffer_pool.lock().unwrap().get_buffer(dim);
560
561 #[allow(clippy::needless_range_loop)]
562 for i in 0..dim {
563 let control_bit = (i >> control_idx) & 1;
564 let target_bit = (i >> target_idx) & 1;
565
566 let i00 = i & !(1 << control_idx) & !(1 << target_idx);
568 let i01 = i00 | (1 << target_idx);
569 let i10 = i00 | (1 << control_idx);
570 let i11 = i10 | (1 << target_idx);
571
572 let basis_idx = (control_bit << 1) | target_bit;
573
574 let row_offset = basis_idx * 4;
576 new_state[i] = m[row_offset] * state[i00]
577 + m[row_offset + 1] * state[i01]
578 + m[row_offset + 2] * state[i10]
579 + m[row_offset + 3] * state[i11];
580 }
581
582 state.copy_from_slice(&new_state);
583 self.buffer_pool.lock().unwrap().return_buffer(new_state);
585 }
586
587 Ok(())
588 }
589
590 fn apply_cnot<const N: usize>(
592 &self,
593 state: &mut [Complex64],
594 control: QubitId,
595 target: QubitId,
596 ) -> QuantRS2Result<()> {
597 let control_idx = control.id() as usize;
598 let target_idx = target.id() as usize;
599
600 if control_idx >= N || target_idx >= N {
601 return Err(QuantRS2Error::InvalidQubitId(if control_idx >= N {
602 control.id()
603 } else {
604 target.id()
605 }));
606 }
607
608 if control_idx == target_idx {
609 return Err(QuantRS2Error::CircuitValidationFailed(
610 "Control and target qubits must be different".into(),
611 ));
612 }
613
614 if self.parallel {
616 let mut state_copy = self.buffer_pool.lock().unwrap().get_buffer(state.len());
617 state_copy.copy_from_slice(state);
618
619 state.par_iter_mut().enumerate().for_each(|(i, amp)| {
620 if (i >> control_idx) & 1 == 1 {
621 let flipped = flip_bit(i, target_idx);
622 *amp = state_copy[flipped];
623 }
624 });
625
626 self.buffer_pool.lock().unwrap().return_buffer(state_copy);
627 } else {
628 let dim = state.len();
629 let mut new_state = self.buffer_pool.lock().unwrap().get_buffer(dim);
630
631 for i in 0..dim {
632 if (i >> control_idx) & 1 == 1 {
633 let flipped = flip_bit(i, target_idx);
634 new_state[flipped] = state[i];
635 new_state[i] = state[flipped];
636 } else {
637 new_state[i] = state[i];
638 }
639 }
640
641 state.copy_from_slice(&new_state);
642 self.buffer_pool.lock().unwrap().return_buffer(new_state);
643 }
644
645 Ok(())
646 }
647
648 fn apply_swap<const N: usize>(
650 &self,
651 state: &mut [Complex64],
652 qubit1: QubitId,
653 qubit2: QubitId,
654 ) -> QuantRS2Result<()> {
655 let q1_idx = qubit1.id() as usize;
656 let q2_idx = qubit2.id() as usize;
657
658 if q1_idx >= N || q2_idx >= N {
659 return Err(QuantRS2Error::InvalidQubitId(if q1_idx >= N {
660 qubit1.id()
661 } else {
662 qubit2.id()
663 }));
664 }
665
666 if q1_idx == q2_idx {
667 return Err(QuantRS2Error::CircuitValidationFailed(
668 "Qubits must be different for SWAP gate".into(),
669 ));
670 }
671
672 if self.parallel {
674 let mut state_copy = self.buffer_pool.lock().unwrap().get_buffer(state.len());
675 state_copy.copy_from_slice(state);
676
677 state.par_iter_mut().enumerate().for_each(|(i, amp)| {
678 let bit1 = (i >> q1_idx) & 1;
679 let bit2 = (i >> q2_idx) & 1;
680
681 if bit1 != bit2 {
682 let swapped = flip_bit(flip_bit(i, q1_idx), q2_idx);
683 *amp = state_copy[swapped];
684 }
685 });
686
687 self.buffer_pool.lock().unwrap().return_buffer(state_copy);
688 } else {
689 let dim = state.len();
690 let mut new_state = self.buffer_pool.lock().unwrap().get_buffer(dim);
691
692 for i in 0..dim {
693 let bit1 = (i >> q1_idx) & 1;
694 let bit2 = (i >> q2_idx) & 1;
695
696 if bit1 != bit2 {
697 let swapped = flip_bit(flip_bit(i, q1_idx), q2_idx);
698 new_state[swapped] = state[i];
699 new_state[i] = state[swapped];
700 } else {
701 new_state[i] = state[i];
702 }
703 }
704
705 state.copy_from_slice(&new_state);
706 self.buffer_pool.lock().unwrap().return_buffer(new_state);
707 }
708
709 Ok(())
710 }
711}
712
713impl Default for StateVectorSimulator {
714 fn default() -> Self {
715 Self::new()
716 }
717}
718
719impl<const N: usize> Simulator<N> for StateVectorSimulator {
720 fn run(&self, circuit: &Circuit<N>) -> QuantRS2Result<Register<N>> {
721 let dim = 1 << N;
723 let mut state = vec![Complex64::new(0.0, 0.0); dim];
724 state[0] = Complex64::new(1.0, 0.0);
725
726 for gate in circuit.gates() {
728 match gate.name() {
729 "H" => {
731 if let Some(g) = gate.as_any().downcast_ref::<single::Hadamard>() {
732 let matrix = g.matrix()?;
733 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
734 }
735 }
736 "X" => {
737 if let Some(g) = gate.as_any().downcast_ref::<single::PauliX>() {
738 let matrix = g.matrix()?;
739 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
740 }
741 }
742 "Y" => {
743 if let Some(g) = gate.as_any().downcast_ref::<single::PauliY>() {
744 let matrix = g.matrix()?;
745 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
746 }
747 }
748 "Z" => {
749 if let Some(g) = gate.as_any().downcast_ref::<single::PauliZ>() {
750 let matrix = g.matrix()?;
751 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
752 }
753 }
754 "RX" => {
755 if let Some(g) = gate.as_any().downcast_ref::<single::RotationX>() {
756 let matrix = g.matrix()?;
757 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
758 }
759 }
760 "RY" => {
761 if let Some(g) = gate.as_any().downcast_ref::<single::RotationY>() {
762 let matrix = g.matrix()?;
763 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
764 }
765 }
766 "RZ" => {
767 if let Some(g) = gate.as_any().downcast_ref::<single::RotationZ>() {
768 let matrix = g.matrix()?;
769 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
770 }
771 }
772 "S" => {
773 if let Some(g) = gate.as_any().downcast_ref::<single::Phase>() {
774 let matrix = g.matrix()?;
775 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
776 }
777 }
778 "T" => {
779 if let Some(g) = gate.as_any().downcast_ref::<single::T>() {
780 let matrix = g.matrix()?;
781 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
782 }
783 }
784 "S†" => {
785 if let Some(g) = gate.as_any().downcast_ref::<single::PhaseDagger>() {
786 let matrix = g.matrix()?;
787 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
788 }
789 }
790 "T†" => {
791 if let Some(g) = gate.as_any().downcast_ref::<single::TDagger>() {
792 let matrix = g.matrix()?;
793 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
794 }
795 }
796 "√X" => {
797 if let Some(g) = gate.as_any().downcast_ref::<single::SqrtX>() {
798 let matrix = g.matrix()?;
799 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
800 }
801 }
802 "√X†" => {
803 if let Some(g) = gate.as_any().downcast_ref::<single::SqrtXDagger>() {
804 let matrix = g.matrix()?;
805 self.apply_single_qubit_gate::<N>(&mut state, &matrix, g.target)?;
806 }
807 }
808
809 "CNOT" => {
811 if let Some(g) = gate.as_any().downcast_ref::<multi::CNOT>() {
812 self.apply_cnot::<N>(&mut state, g.control, g.target)?;
814 }
815 }
816 "CZ" => {
817 if let Some(g) = gate.as_any().downcast_ref::<multi::CZ>() {
818 let matrix = g.matrix()?;
819 self.apply_two_qubit_gate::<N>(&mut state, &matrix, g.control, g.target)?;
820 }
821 }
822 "SWAP" => {
823 if let Some(g) = gate.as_any().downcast_ref::<multi::SWAP>() {
824 self.apply_swap::<N>(&mut state, g.qubit1, g.qubit2)?;
826 }
827 }
828 "CY" => {
829 if let Some(g) = gate.as_any().downcast_ref::<multi::CY>() {
830 let matrix = g.matrix()?;
831 self.apply_two_qubit_gate::<N>(&mut state, &matrix, g.control, g.target)?;
832 }
833 }
834 "CH" => {
835 if let Some(g) = gate.as_any().downcast_ref::<multi::CH>() {
836 let matrix = g.matrix()?;
837 self.apply_two_qubit_gate::<N>(&mut state, &matrix, g.control, g.target)?;
838 }
839 }
840 "CS" => {
841 if let Some(g) = gate.as_any().downcast_ref::<multi::CS>() {
842 let matrix = g.matrix()?;
843 self.apply_two_qubit_gate::<N>(&mut state, &matrix, g.control, g.target)?;
844 }
845 }
846 "CRX" => {
847 if let Some(g) = gate.as_any().downcast_ref::<multi::CRX>() {
848 let matrix = g.matrix()?;
849 self.apply_two_qubit_gate::<N>(&mut state, &matrix, g.control, g.target)?;
850 }
851 }
852 "CRY" => {
853 if let Some(g) = gate.as_any().downcast_ref::<multi::CRY>() {
854 let matrix = g.matrix()?;
855 self.apply_two_qubit_gate::<N>(&mut state, &matrix, g.control, g.target)?;
856 }
857 }
858 "CRZ" => {
859 if let Some(g) = gate.as_any().downcast_ref::<multi::CRZ>() {
860 let matrix = g.matrix()?;
861 self.apply_two_qubit_gate::<N>(&mut state, &matrix, g.control, g.target)?;
862 }
863 }
864
865 "Toffoli" => {
867 if let Some(toffoli_gate) = gate.as_any().downcast_ref::<multi::Toffoli>() {
868 let control1 = toffoli_gate.control1;
869 let control2 = toffoli_gate.control2;
870 let target = toffoli_gate.target;
871 self.apply_toffoli_to_state::<N>(&mut state, control1, control2, target)?;
872 }
873 }
874 "Fredkin" => {
875 if let Some(fredkin_gate) = gate.as_any().downcast_ref::<multi::Fredkin>() {
876 let control = fredkin_gate.control;
877 let target1 = fredkin_gate.target1;
878 let target2 = fredkin_gate.target2;
879 self.apply_fredkin_to_state::<N>(&mut state, control, target1, target2)?;
880 }
881 }
882
883 _ => {
884 return Err(QuantRS2Error::UnsupportedOperation(format!(
885 "Gate {} not supported",
886 gate.name()
887 )));
888 }
889 }
890
891 if let Some(ref noise_model) = self.noise_model {
893 if noise_model.per_gate {
894 noise_model.apply_to_statevector(&mut state)?;
895 }
896 }
897
898 if let Some(ref advanced_noise_model) = self.advanced_noise_model {
900 if advanced_noise_model.per_gate {
901 advanced_noise_model.apply_to_statevector(&mut state)?;
902 }
903 }
904 }
905
906 if let Some(ref noise_model) = self.noise_model {
908 if !noise_model.per_gate {
909 noise_model.apply_to_statevector(&mut state)?;
910 }
911 }
912
913 if let Some(ref advanced_noise_model) = self.advanced_noise_model {
915 if !advanced_noise_model.per_gate {
916 advanced_noise_model.apply_to_statevector(&mut state)?;
917 }
918 }
919
920 Register::<N>::with_amplitudes(state)
922 }
923}
924
925impl StateVectorSimulator {
926 pub fn initialize_state(&mut self, num_qubits: usize) -> QuantRS2Result<()> {
928 Ok(())
930 }
931
932 pub fn get_state(&self) -> Vec<Complex64> {
934 vec![Complex64::new(1.0, 0.0)]
936 }
937
938 pub fn get_state_mut(&mut self) -> Vec<Complex64> {
940 vec![Complex64::new(1.0, 0.0)]
942 }
943
944 pub fn set_state(&mut self, _state: Vec<Complex64>) -> QuantRS2Result<()> {
946 Ok(())
948 }
949
950 pub fn apply_interface_circuit(
952 &mut self,
953 _circuit: &crate::circuit_interfaces::InterfaceCircuit,
954 ) -> QuantRS2Result<()> {
955 Ok(())
957 }
958
959 pub fn apply_h(&mut self, _qubit: usize) -> QuantRS2Result<()> {
961 Ok(())
963 }
964
965 pub fn apply_x(&mut self, _qubit: usize) -> QuantRS2Result<()> {
967 Ok(())
969 }
970
971 pub fn apply_z_public(&mut self, _qubit: usize) -> QuantRS2Result<()> {
973 Ok(())
975 }
976
977 pub fn apply_cnot_public(&mut self, _control: usize, _target: usize) -> QuantRS2Result<()> {
979 Ok(())
981 }
982
983 fn apply_toffoli_to_state<const N: usize>(
985 &self,
986 state: &mut [Complex64],
987 control1: QubitId,
988 control2: QubitId,
989 target: QubitId,
990 ) -> QuantRS2Result<()> {
991 let control1_idx = control1.id() as usize;
992 let control2_idx = control2.id() as usize;
993 let target_idx = target.id() as usize;
994
995 if control1_idx >= N || control2_idx >= N || target_idx >= N {
996 return Err(QuantRS2Error::InvalidQubitId(if control1_idx >= N {
997 control1.id()
998 } else if control2_idx >= N {
999 control2.id()
1000 } else {
1001 target.id()
1002 }));
1003 }
1004
1005 if self.parallel {
1007 let mut state_copy = self.buffer_pool.lock().unwrap().get_buffer(state.len());
1008 state_copy.copy_from_slice(state);
1009
1010 state.par_iter_mut().enumerate().for_each(|(i, amp)| {
1011 let control1_bit = (i >> control1_idx) & 1;
1012 let control2_bit = (i >> control2_idx) & 1;
1013
1014 if control1_bit == 1 && control2_bit == 1 {
1015 let flipped = flip_bit(i, target_idx);
1016 *amp = state_copy[flipped];
1017 }
1018 });
1019
1020 self.buffer_pool.lock().unwrap().return_buffer(state_copy);
1021 } else {
1022 let mut new_state = self.buffer_pool.lock().unwrap().get_buffer(state.len());
1023 new_state.copy_from_slice(state);
1024
1025 for i in 0..state.len() {
1026 let control1_bit = (i >> control1_idx) & 1;
1027 let control2_bit = (i >> control2_idx) & 1;
1028
1029 if control1_bit == 1 && control2_bit == 1 {
1030 let flipped = flip_bit(i, target_idx);
1031 new_state[flipped] = state[i];
1032 new_state[i] = state[flipped];
1033 }
1034 }
1035
1036 state.copy_from_slice(&new_state);
1037 self.buffer_pool.lock().unwrap().return_buffer(new_state);
1038 }
1039
1040 Ok(())
1041 }
1042
1043 fn apply_fredkin_to_state<const N: usize>(
1045 &self,
1046 state: &mut [Complex64],
1047 control: QubitId,
1048 target1: QubitId,
1049 target2: QubitId,
1050 ) -> QuantRS2Result<()> {
1051 let control_idx = control.id() as usize;
1052 let target1_idx = target1.id() as usize;
1053 let target2_idx = target2.id() as usize;
1054
1055 if control_idx >= N || target1_idx >= N || target2_idx >= N {
1056 return Err(QuantRS2Error::InvalidQubitId(if control_idx >= N {
1057 control.id()
1058 } else if target1_idx >= N {
1059 target1.id()
1060 } else {
1061 target2.id()
1062 }));
1063 }
1064
1065 if self.parallel {
1067 let mut state_copy = self.buffer_pool.lock().unwrap().get_buffer(state.len());
1068 state_copy.copy_from_slice(state);
1069
1070 state.par_iter_mut().enumerate().for_each(|(i, amp)| {
1071 let control_bit = (i >> control_idx) & 1;
1072 let target1_bit = (i >> target1_idx) & 1;
1073 let target2_bit = (i >> target2_idx) & 1;
1074
1075 if control_bit == 1 && target1_bit != target2_bit {
1076 let swapped = flip_bit(flip_bit(i, target1_idx), target2_idx);
1077 *amp = state_copy[swapped];
1078 }
1079 });
1080
1081 self.buffer_pool.lock().unwrap().return_buffer(state_copy);
1082 } else {
1083 let mut new_state = self.buffer_pool.lock().unwrap().get_buffer(state.len());
1084 new_state.copy_from_slice(state);
1085
1086 for i in 0..state.len() {
1087 let control_bit = (i >> control_idx) & 1;
1088 let target1_bit = (i >> target1_idx) & 1;
1089 let target2_bit = (i >> target2_idx) & 1;
1090
1091 if control_bit == 1 && target1_bit != target2_bit {
1092 let swapped = flip_bit(flip_bit(i, target1_idx), target2_idx);
1093 new_state[swapped] = state[i];
1094 new_state[i] = state[swapped];
1095 }
1096 }
1097
1098 state.copy_from_slice(&new_state);
1099 self.buffer_pool.lock().unwrap().return_buffer(new_state);
1100 }
1101
1102 Ok(())
1103 }
1104
1105 pub fn apply_toffoli(
1107 &mut self,
1108 control1: QubitId,
1109 control2: QubitId,
1110 target: QubitId,
1111 ) -> QuantRS2Result<()> {
1112 Ok(())
1114 }
1115
1116 pub fn apply_fredkin(
1118 &mut self,
1119 control: QubitId,
1120 target1: QubitId,
1121 target2: QubitId,
1122 ) -> QuantRS2Result<()> {
1123 Ok(())
1125 }
1126}