ket/
util.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// SPDX-FileCopyrightText: 2024 Evandro Chagas Ribeiro da Rosa <evandro@quantuloop.com>
//
// SPDX-License-Identifier: Apache-2.0

use env_logger::Builder;
use log::LevelFilter;

use crate::{error::Result, ir::qubit::LogicalQubit, process::Process};

#[cfg(feature = "plot")]
use crate::process::{DumpData, Sample};
#[cfg(feature = "plot")]
use plotly::Plot;

pub fn ajd<F>(process: &mut Process, mut f: F) -> Result<()>
where
    F: FnMut(&mut Process) -> Result<()>,
{
    process.adj_begin()?;
    f(process)?;
    process.adj_end()
}

pub fn ctrl<F>(process: &mut Process, control: &[LogicalQubit], mut f: F) -> Result<()>
where
    F: FnMut(&mut Process) -> Result<()>,
{
    process.ctrl_push(control)?;
    f(process)?;
    process.ctrl_pop()
}

pub fn around<O, I>(process: &mut Process, mut outer: O, mut inner: I) -> Result<()>
where
    I: FnMut(&mut Process) -> Result<()>,
    O: FnMut(&mut Process) -> Result<()>,
{
    outer(process)?;
    inner(process)?;
    ajd(process, outer)
}

pub fn set_log_level(level: u32) {
    let level = match level {
        0 => LevelFilter::Off,
        1 => LevelFilter::Error,
        2 => LevelFilter::Warn,
        3 => LevelFilter::Info,
        4 => LevelFilter::Debug,
        5 => LevelFilter::Trace,
        _ => LevelFilter::max(),
    };

    Builder::new().filter_level(level).init();
}

#[cfg(feature = "plot")]
pub fn plot_sample(data: &Sample) -> Plot {
    use plotly::{layout::Axis, Bar, Layout};

    let trace = Bar::new(data.0.clone(), data.1.clone());
    let layout = Layout::new()
        .x_axis(Axis::new().title("Measurement Results"))
        .y_axis(Axis::new().title("Measurement Count"));
    let mut plot = Plot::new();
    plot.add_trace(trace);
    plot.set_layout(layout);

    plot
}

#[cfg(feature = "plot")]
pub fn plot_dump(data: &DumpData) -> Plot {
    use plotly::{common::Marker, layout::Axis, Bar, Layout};
    use std::f64::consts::PI;

    use crate::ir::gate::Cf64;

    let amp: Vec<_> = data
        .amplitudes_real
        .iter()
        .zip(data.amplitudes_imag.iter())
        .map(|(re, im)| Cf64::new(*re, *im))
        .collect();

    let prob: Vec<_> = amp.iter().map(|x| x.norm_sqr()).collect();
    let phase: Vec<_> = amp.iter().map(|x| x.arg()).collect();
    let base: Vec<_> = data.basis_states.iter().map(|x| x[0]).collect();

    let trace = Bar::new(base, prob).marker(
        Marker::new()
            .color_array(phase)
            .cmin(-PI)
            .cmax(PI)
            .show_scale(true),
    );

    let layout = Layout::new()
        .x_axis(Axis::new().title("Basis State"))
        .y_axis(
            Axis::new()
                .title("Measurement Probability (%)")
                .range(vec![0.0, 1.0]),
        );

    let mut plot = Plot::new();
    plot.add_trace(trace);
    plot.set_layout(layout);

    plot
}