microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
cd67b36992d2ea20ba330acb56e2e9ac04c11938

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_eval/src/output.rs

122lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use std::io::{Cursor, Write};
5
6use num_bigint::BigUint;
7use num_complex::{Complex, Complex64};
8
9#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
10pub struct Error;
11
12#[must_use]
13pub fn format_state_id(id: &BigUint, qubit_count: usize) -> String {
14 format!("|{}⟩", fmt_basis_state_label(id, qubit_count))
15}
16
17#[must_use]
18pub fn get_phase(c: &Complex<f64>) -> f64 {
19 f64::atan2(c.im, c.re)
20}
21
22#[must_use]
23pub fn fmt_complex(c: &Complex<f64>) -> String {
24 // Format -0 as 0
25 // Also using Unicode Minus Sign instead of ASCII Hyphen-Minus
26 // and Unicode Mathematical Italic Small I instead of ASCII i.
27 format!(
28 "{}{:.4}{}{:.4}𝑖",
29 if c.re <= -0.00005 { "−" } else { "" },
30 c.re.abs(),
31 if c.im <= -0.00005 { "−" } else { "+" },
32 c.im.abs()
33 )
34}
35
36#[must_use]
37pub fn fmt_basis_state_label(id: &BigUint, qubit_count: usize) -> String {
38 // This will generate a bit string that shows the qubits in the order
39 // of allocation, left to right.
40 format!("{:0>qubit_count$}", id.to_str_radix(2))
41}
42
43pub trait Receiver {
44 /// Receive state output
45 /// # Errors
46 /// This will return an error if handling the output fails.
47 fn state(&mut self, state: Vec<(BigUint, Complex64)>, qubit_count: usize) -> Result<(), Error>;
48
49 /// Receive generic message output
50 /// # Errors
51 /// This will return an error if handling the output fails.
52 fn message(&mut self, msg: &str) -> Result<(), Error>;
53}
54
55pub struct GenericReceiver<'a> {
56 writer: &'a mut dyn Write,
57}
58
59impl<'a> GenericReceiver<'a> {
60 pub fn new(writer: &'a mut impl Write) -> Self {
61 Self { writer }
62 }
63}
64
65impl<'a> Receiver for GenericReceiver<'a> {
66 fn state(&mut self, state: Vec<(BigUint, Complex64)>, qubit_count: usize) -> Result<(), Error> {
67 writeln!(self.writer, "STATE:").map_err(|_| Error)?;
68 for (id, state) in state {
69 writeln!(
70 self.writer,
71 "{}: {}",
72 format_state_id(&id, qubit_count),
73 state
74 )
75 .map_err(|_| Error)?;
76 }
77 Ok(())
78 }
79
80 fn message(&mut self, msg: &str) -> Result<(), Error> {
81 writeln!(self.writer, "{msg}").map_err(|_| Error)
82 }
83}
84
85pub struct CursorReceiver<'a> {
86 cursor: &'a mut Cursor<Vec<u8>>,
87}
88
89impl<'a> CursorReceiver<'a> {
90 pub fn new(cursor: &'a mut Cursor<Vec<u8>>) -> Self {
91 Self { cursor }
92 }
93 pub fn dump(&mut self) -> String {
94 let v = self.cursor.get_mut();
95 let s = match std::str::from_utf8(v) {
96 Ok(v) => v.to_owned(),
97 Err(e) => format!("Invalid UTF-8 sequence: {e}"),
98 };
99 v.clear();
100 s.trim().to_string()
101 }
102}
103
104impl<'a> Receiver for CursorReceiver<'a> {
105 fn state(&mut self, state: Vec<(BigUint, Complex64)>, qubit_count: usize) -> Result<(), Error> {
106 writeln!(self.cursor, "STATE:").map_err(|_| Error)?;
107 for (id, state) in state {
108 writeln!(
109 self.cursor,
110 "{}: {}",
111 format_state_id(&id, qubit_count),
112 state
113 )
114 .map_err(|_| Error)?;
115 }
116 Ok(())
117 }
118
119 fn message(&mut self, msg: &str) -> Result<(), Error> {
120 writeln!(self.cursor, "{msg}").map_err(|_| Error)
121 }
122}
123