1use std::fmt;
28use std::ops;
29
30#[derive(PartialEq, Debug, Clone, Copy)]
68pub struct Comp(pub f64, pub f64);
69
70pub mod mod_funcs;
73
74impl Comp {
75 pub fn new(re: f64, im: f64) -> Self {
76 return Comp(re, im);
77 }
78
79 pub fn abs_square(&self) -> f64 {
80 return self.0 * self.0 + self.1 * self.1;
81 }
82
83 pub fn zero() -> Self {
84 return Comp(0.0, 0.0);
85 }
86}
87
88impl fmt::Display for Comp {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 write!(
91 f,
92 "{:+.3} {:+.3}i",
93 (self.0 * 1000.0).round() / 1000.0,
94 (self.1 * 1000.0).round() / 1000.0
95 )
96 }
97}
98
99impl ops::Add<Comp> for Comp {
100 type Output = Comp;
101 fn add(self, _rhs: Comp) -> Comp {
102 return Comp(self.0 + _rhs.0, self.1 + _rhs.1);
103 }
104}
105
106impl ops::Add<f64> for Comp {
107 type Output = Comp;
108 fn add(self, rhs: f64) -> Comp {
109 return Comp(self.0 + rhs, self.1);
110 }
111}
112
113impl ops::Sub<Comp> for Comp {
114 type Output = Comp;
115 fn sub(self, _rhs: Comp) -> Comp {
116 return Comp(self.0 - _rhs.0, self.1 - _rhs.1);
117 }
118}
119
120impl ops::Sub<f64> for Comp {
121 type Output = Comp;
122 fn sub(self, rhs: f64) -> Comp {
123 return Comp(self.0 - rhs, self.1);
124 }
125}
126
127impl ops::Mul<Comp> for Comp {
128 type Output = Comp;
129 fn mul(self, _rhs: Comp) -> Comp {
130 return Comp(
131 self.0 * _rhs.0 - self.1 * _rhs.1,
132 self.0 * _rhs.1 + self.1 * _rhs.0,
133 );
134 }
135}
136
137impl ops::Mul<f64> for Comp {
138 type Output = Comp;
139 fn mul(self, rhs: f64) -> Comp {
140 return Comp(self.0 * rhs, self.1 * rhs);
141 }
142}
143
144#[derive(Clone)]
174pub struct Qubits {
175 pub size: usize,
176 pub bits: Vec<Comp>,
177}
178
179impl Qubits {
180 pub fn from_num(size: usize, number: usize) -> Self {
186 assert!((1 << size) > number);
187 let mut bits = vec![Comp::zero(); 1 << size];
188 bits[number] = Comp(1.0, 0.0);
189 return Qubits {
190 size: size,
191 bits: bits,
192 };
193 }
194
195 pub fn from_comp(size: usize, number: usize, comp: Comp) -> Self {
196 assert!((1 << size) > number);
197 assert!(comp.abs_square() == 1.0);
198 let mut bits = vec![Comp::zero(); 1 << size];
199 bits[number] = comp;
200 return Qubits {
201 size: size,
202 bits: bits,
203 };
204 }
205
206 pub fn from_bits(size: usize, bits: Vec<Comp>) -> Self {
207 assert_eq!(1 << size, bits.len());
208 return Qubits {
209 size: size,
210 bits: bits,
211 };
212 }
213
214 pub fn zeros(size: usize) -> Self {
218 let mut bits = vec![Comp::zero(); 1 << size];
219 bits[0] = Comp(1.0, 0.0);
220 return Qubits {
221 size: size,
222 bits: bits,
223 };
224 }
225
226 pub fn print_probs(&self) {
230 for index in 0..(1 << self.size) {
231 println!(
232 "|{index:0>size$b}⟩ : {prob:>3}%",
233 index = index,
234 size = self.size,
235 prob = (self.bits[index].abs_square() * 100.0).round()
236 );
237 }
238 }
239
240 pub fn print_cmps(&self) {
244 for index in 0..(1 << self.size) {
245 println!(
246 "|{index:0>size$b}⟩ : {cmp}",
247 index = index,
248 size = self.size,
249 cmp = self.bits[index]
250 );
251 }
252 }
253
254 pub fn probs(&self) -> Vec<f64> {
255 let mut prob = vec![0.0; (1 << self.size)];
256 for index in 0..(1 << self.size) {
257 prob[index] = self.bits[index].abs_square();
258 }
259 return prob;
260 }
261
262 pub fn pop_most_plausible(&self) -> usize {
266 let mut max_prob = 0.0;
267 let mut max_idx = 0;
268 for i in 0..(1 << self.size) {
269 let prob = self.bits[i].abs_square();
270 if max_prob < prob {
271 max_prob = prob;
272 max_idx = i;
273 }
274 }
275 return max_idx;
276 }
277
278 pub fn _measure(&self, tar: &[usize]) -> Vec<f64> {
282 let mut probs: Vec<f64> = Vec::new();
283 for _ in 0..(1 << tar.len()) {
284 probs.push(0.0);
285 }
286 for i in 0..(1 << self.size) {
287 let mut tar_idx = 0;
288 for j in 0..tar.len() {
289 tar_idx |= (1 & (i >> tar[j])) << j;
290 }
291 probs[tar_idx] += self.bits[i].abs_square();
292 }
293
294 return probs;
295 }
296
297 pub fn _print_measure(&self, tar: &[usize]) {
298 let mut probs: Vec<f64> = Vec::new();
299 for _ in 0..(1 << tar.len()) {
300 probs.push(0.0);
301 }
302 for i in 0..(1 << self.size) {
303 let mut tar_idx = 0;
304 for j in 0..tar.len() {
305 tar_idx |= (1 & (i >> tar[j])) << j;
306 }
307 probs[tar_idx] += self.bits[i].abs_square();
308 }
309
310 for index in 0..(1 << tar.len()) {
311 println!(
312 "|{index:0>size$b}⟩ : {prob:>3.2}%",
313 index = index,
314 size = tar.len(),
315 prob = (probs[index] * 10000.0).round() / 100.0
316 );
317 }
318 }
319}
320
321pub trait Applicable {
325 fn apply(&self, qubits: Qubits) -> Qubits {
326 let it = BitSlideIndex::new(1 << qubits.size, 0);
327 return self.apply_iter(qubits, &it);
328 }
329 fn name(&self) -> String;
330 fn apply_iter(&self, qubits: Qubits, iter: &BitSlideIndex) -> Qubits;
331}
332
333pub struct BitSlideIndex {
337 idx: usize,
338 pub mask: usize,
339 to: usize,
340}
341
342impl BitSlideIndex {
343 pub fn new(to: usize, mask: usize) -> Self {
344 return BitSlideIndex {
345 idx: 0,
346 mask: mask,
347 to: to,
348 };
349 }
350
351 pub fn merge(&self, other: usize) -> Self {
352 if self.mask & other > 0 {
353 println!("self.mask:{:b}, other_mask:{:b}", self.mask, other);
354 panic!("invalid mask was input.");
355 }
356 return BitSlideIndex {
357 idx: 0,
358 mask: self.mask | other,
359 to: self.to,
360 };
361 }
362
363 pub fn init(&mut self) {
364 self.idx = 0;
365 }
366}
367
368impl Iterator for BitSlideIndex {
369 type Item = usize;
370
371 fn next(&mut self) -> Option<Self::Item> {
372 let idx = self.idx;
373 if (idx & self.mask) != self.mask {
374 let idx = idx | self.mask;
375 self.idx = idx + 1;
376 if idx < self.to {
377 return Some(idx);
378 }
379 } else {
380 self.idx = idx + 1;
381 if idx < self.to {
382 return Some(idx);
383 }
384 }
385 return None;
386 }
387}
388
389pub trait Inversible {
393 fn inverse(&mut self) {}
394}
395
396pub trait Operator: Applicable + Inversible {}
400
401pub fn pop_from_probs(probs: &[f64], size: usize) -> usize {
405 use rand::prelude::*;
406
407 loop {
408 let mut r: f64 = rand::thread_rng().gen();
409 for i in 0..(1 << size) {
410 r -= probs[i];
411 if r < 0.0 {
412 return i;
413 }
414 }
415 }
416}