Skip to content

Commit

Permalink
Merge pull request #23 from a-barlow/release-0.2.4
Browse files Browse the repository at this point in the history
Release 0.2.4
  • Loading branch information
a-barlow committed Oct 27, 2023
2 parents efd285b + 3dc9308 commit d49388d
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 12 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Expand Up @@ -2,7 +2,7 @@

This file logs the versions of quantr.

## 0.2.3 - S and T gates, and extra functionality for `ProductState`.
## 0.2.4 - S and T gates, and extra functionality for `ProductState`.

Features:

Expand Down Expand Up @@ -45,6 +45,11 @@ Tests:
using `ProductStates::invert_digit`.
- Add unit test of `Product::to_super_position`.

## 0.2.3 - !! YANKED VERSION !!

There was a problem in implementing the Gitflow strategy, resulting in
some commits not appearing in the master branch.

## 0.2.2 - Fixing the `Printer` and pushing of custom functions

Features:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "quantr"
version = "0.2.3"
version = "0.2.4"
edition = "2021"
license = "EUPL-1.2"
readme = "README.md"
Expand Down
9 changes: 5 additions & 4 deletions QUICK_START.md
Expand Up @@ -13,7 +13,8 @@ offers a good explanation of Grover's. This guide does not attempt to
explain either of these subjects in detail.

The complete code that is built from following this guide is available
at the end.
at the end. Or, the code can be found in `examples/grovers.rs`, and ran
from the root directory with `cargo run --example grovers`.

---

Expand Down Expand Up @@ -158,9 +159,9 @@ This completes the construction and measurement of a three qubit
Grover's circuit. Other functions (which include examples in their
documentation) can add gates in other ways.

The following is the completed code. This can be copied directly to your
`main.rs` and ran with `cargo run`. Make sure that quantr is added as a
dependency.
The following is the completed code. This can also be found in
`examples/grovers.rs`, and ran with `cargo run --example grovers` from
the root directory.

```rust,ignore
use quantr::circuit::{printer::Printer, Circuit, Measurement, StandardGate};
Expand Down
10 changes: 10 additions & 0 deletions examples/grovers.rs
@@ -1,3 +1,13 @@
/*
* Copyright (c) 2023 Andrew Rowan Barlow. Licensed under the EUPL-1.2
* or later. You may obtain a copy of the licence at
* https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12. A copy
* of the EUPL-1.2 licence in English is given in LICENCE.txt which is
* found in the root directory of this repository.
*
* Author: Andrew Rowan Barlow <a.barlow.dev@gmail.com>
*/

use quantr::circuit::{printer::Printer, Circuit, Measurement, StandardGate};

fn main() {
Expand Down
57 changes: 52 additions & 5 deletions src/circuit.rs
Expand Up @@ -51,6 +51,9 @@ pub enum Measurement<T> {

/// Gates that can be added to a [Circuit] struct.
///
/// Matrix representations of these gates can be found at
/// [https://www.quantum-inspire.com/kbase/cqasm-qubit-gate-operations/].
///
/// Currently, this enum has the `#[non_exhaustive]` as it's
/// yet undecided what will be included as a standard gate. This will
/// lessen the impact of breaking changes in the future.
Expand All @@ -61,7 +64,15 @@ pub enum StandardGate<'a> {
Id,
/// Hadamard.
H,
/// Pauli-X
/// Phase.
S,
/// Phase dagger.
Sdag,
/// T.
T,
/// T dagger.
Tdag,
/// Pauli-X.
X,
/// Pauli-Y.
Y,
Expand Down Expand Up @@ -118,6 +129,10 @@ impl<'a> StandardGate<'a> {
match self {
StandardGate::Id
| StandardGate::H
| StandardGate::S
| StandardGate::Sdag
| StandardGate::T
| StandardGate::Tdag
| StandardGate::X
| StandardGate::Y
| StandardGate::Z => None,
Expand Down Expand Up @@ -635,6 +650,10 @@ impl<'a> Circuit<'a> {
match gate {
StandardGate::Id
| StandardGate::H
| StandardGate::S
| StandardGate::Sdag
| StandardGate::T
| StandardGate::Tdag
| StandardGate::X
| StandardGate::Y
| StandardGate::Z => GateSize::Single,
Expand Down Expand Up @@ -696,6 +715,10 @@ impl<'a> Circuit<'a> {
let operator: fn(Qubit) -> SuperPosition = match single_gate.name {
StandardGate::Id => standard_gate_ops::identity,
StandardGate::H => standard_gate_ops::hadamard,
StandardGate::S => standard_gate_ops::phase,
StandardGate::Sdag => standard_gate_ops::phasedag,
StandardGate::T => standard_gate_ops::tgate,
StandardGate::Tdag => standard_gate_ops::tgatedag,
StandardGate::X => standard_gate_ops::pauli_x,
StandardGate::Y => standard_gate_ops::pauli_y,
StandardGate::Z => standard_gate_ops::pauli_z,
Expand Down Expand Up @@ -838,7 +861,7 @@ impl<'a> Circuit<'a> {
#[rustfmt::skip]
#[cfg(test)]
mod tests {
use crate::{complex_Im, complex_Re, complex_Re_array, complex_zero};
use crate::{complex_Im, complex_Re, complex_Re_array, complex_zero, complex};
use std::f64::consts::FRAC_1_SQRT_2;
use crate::circuit::Measurement::NonObservable;
use super::*;
Expand Down Expand Up @@ -872,7 +895,6 @@ mod tests {
}).unwrap()
}


// No expected panic message as the eample_cnot function is an address in memory, that will
// change everytime.
#[test]
Expand Down Expand Up @@ -946,6 +968,33 @@ mod tests {
//
// All circuit tests were calculated by hand.
//

#[test]
fn swap_and_conjugate_gates() {
let mut circuit = Circuit::new(2).unwrap();
circuit.add_gates(vec!(StandardGate::H, StandardGate::H)).unwrap();
circuit.add_gates(vec!(StandardGate::S, StandardGate::Sdag)).unwrap();
circuit.simulate();

let correct_register: [Complex<f64>; 4] = [
complex_Re!(0.5f64), complex_Im!(-0.5f64),
complex_Im!(0.5f64), complex_Re!(0.5f64)];
compare_circuit(circuit, &correct_register);
}

#[test]
fn t_and_conjugate_gates() {
let mut circuit = Circuit::new(2).unwrap();
circuit.add_gates(vec!(StandardGate::H, StandardGate::H)).unwrap();
circuit.add_gates(vec!(StandardGate::T, StandardGate::Tdag)).unwrap();
circuit.simulate();

let correct_register: [Complex<f64>; 4] = [
complex_Re!(0.5f64), complex!(0.5f64*FRAC_1_SQRT_2, -0.5f64*FRAC_1_SQRT_2),
complex!(0.5f64*FRAC_1_SQRT_2, 0.5f64*FRAC_1_SQRT_2), complex_Re!(0.5f64)];
compare_circuit(circuit, &correct_register);
}


#[test]
fn custom_gates() {
Expand Down Expand Up @@ -1005,8 +1054,6 @@ mod tests {
.iter().all(|item| quantum_circuit.circuit_gates.contains(item)));
}



#[test]
fn runs_three_pauli_gates_with_hadamard() {
let mut circuit = Circuit::new(4).unwrap();
Expand Down
4 changes: 4 additions & 0 deletions src/circuit/printer.rs
Expand Up @@ -252,6 +252,10 @@ impl Printer<'_> {
match gate {
StandardGate::X => "X".to_string(),
StandardGate::H => "H".to_string(),
StandardGate::S => "S".to_string(),
StandardGate::Sdag => "S†".to_string(),
StandardGate::T => "T".to_string(),
StandardGate::Tdag => "T†".to_string(),
StandardGate::Y => "Y".to_string(),
StandardGate::Z => "Z".to_string(),
StandardGate::Swap(_) => "Sw".to_string(),
Expand Down
34 changes: 33 additions & 1 deletion src/circuit/standard_gate_ops.rs
Expand Up @@ -15,7 +15,7 @@

use crate::circuit::states::{ProductState, Qubit, SuperPosition};
use crate::complex::Complex;
use crate::{complex_Im, complex_Im_array, complex_Re, complex_Re_array, complex_zero};
use crate::{complex, complex_Im, complex_Im_array, complex_Re, complex_Re_array, complex_zero};
use std::f64::consts::FRAC_1_SQRT_2;

// The following gates (inlcuding triple and custom) are mapping qubits via the
Expand Down Expand Up @@ -48,6 +48,38 @@ pub fn hadamard(register: Qubit) -> SuperPosition {
}).unwrap()
}

#[rustfmt::skip]
pub fn tgate(register: Qubit) -> SuperPosition {
SuperPosition::new(1).set_amplitudes(match register {
Qubit::Zero => &[complex_Re!(1f64), complex_zero!()],
Qubit::One => &[complex_zero!(), complex!(FRAC_1_SQRT_2, FRAC_1_SQRT_2)],
}).unwrap()
}

#[rustfmt::skip]
pub fn tgatedag(register: Qubit) -> SuperPosition {
SuperPosition::new(1).set_amplitudes(match register {
Qubit::Zero => &[complex_Re!(1f64), complex_zero!()],
Qubit::One => &[complex_zero!(), complex!(FRAC_1_SQRT_2, -FRAC_1_SQRT_2)],
}).unwrap()
}

#[rustfmt::skip]
pub fn phase(register: Qubit) -> SuperPosition {
SuperPosition::new(1).set_amplitudes(match register {
Qubit::Zero => &[complex_Re!(1f64), complex_zero!()],
Qubit::One => &[complex_zero!(), complex_Im!(1f64)],
}).unwrap()
}

#[rustfmt::skip]
pub fn phasedag(register: Qubit) -> SuperPosition {
SuperPosition::new(1).set_amplitudes(match register {
Qubit::Zero => &[complex_Re!(1f64), complex_zero!()],
Qubit::One => &[complex_zero!(), complex_Im!(-1f64)],
}).unwrap()
}

#[rustfmt::skip]
pub fn pauli_x(register: Qubit) -> SuperPosition {
SuperPosition::new(1).set_amplitudes(match register {
Expand Down

0 comments on commit d49388d

Please sign in to comment.