From f90768c5326ee6809abb61b477c7d460ffce3592 Mon Sep 17 00:00:00 2001 From: Andrew Barlow Date: Tue, 23 Jan 2024 13:37:39 +0000 Subject: [PATCH 1/6] Edit docs and bump copyright number The documentation has been review and checked for spelling and grammer. In particular, the changelog has had it's previous breaking change edited. The copyright number in the examples and tesrt folders have been bumped up. Signed-off-by: Andrew Barlow --- CHANGELOG.md | 29 +++++++++++++++++---- QUICK_START.md | 32 ++++++++++-------------- README.md | 6 ++--- examples/custom_gate.rs | 2 +- examples/generalised_control_not_gate.rs | 2 +- examples/grovers.rs | 2 +- examples/qft.rs | 2 +- tests/grovers.rs | 2 +- tests/qft.rs | 2 +- 9 files changed, 46 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb3b812..60fc10a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,20 @@ This file logs the versions of quantr. ## 0.5.0 - Finalising Interface -Following this update, interfacing with quantr can now be done safely, -as to not allow the user to destroy any assumptions made from building -the circuit. In this update, that meant making the final public fields -private for the `Circuit` struct. +Following this update, interfacing with quantr can now be done safely. +All assumptions that are needed for the safe simulation of the circuit +can now be upheld, no matter how the user interfaces with this library. +Of course, any incorrect interfacing should result in an error. In this +update, that meant making the final public fields private for the +`Circuit` struct. + +Some functions have promoted to constant functions. Although this was +not a breaking change in itself, it meant that removing such constraints +constitutes as a breaking change. Moreover, I had not fully understood +it's use in Rust. So, this will be removed for some functions, if not +all. This will be most likely removed in the next major update. Of +course, it is the developers wishes to minimise these breaking changes. +- A. Barlow Breaking changes: @@ -32,6 +42,15 @@ Breaking changes: - `states::SuperPosition::new_with_amplitudes` - `states::ProductState::new` +Constant functions: + +The following functions have been made constant. + + - `Circuit::new` + - `Circuit::get_superposition` + - `Circuit::get_num_qubits` + - `SuperPosition::get_num_qubits` + Internal improvements: - Added `QuantrErrorConst` that consumes a `&str`. This can be used for @@ -129,7 +148,7 @@ Examples: - The `.unwrap()` on measurements have been removed, in favour of explicitly showing the `Result` return type of `Circuit::repeated_measurement` and `Circuit::get_superposition`. -- Added examples for implementing a controlled not gate with arbitary +- Added examples for implementing a controlled not gate with arbitrary number of control nodes. This uses generic constants. This can be found in `examples/generalised_control_not_gate.rs`. diff --git a/QUICK_START.md b/QUICK_START.md index 3040e84..edffdd9 100644 --- a/QUICK_START.md +++ b/QUICK_START.md @@ -1,7 +1,7 @@ # Quick Start Guide This guide walks through an implementation of Grover's algorithm using -[quantr](https://crates.io/crates/quantr). It's aimed at beginners in +[quantr](https://crates.io/crates/quantr) 0.5.0. It's aimed at beginners in Rust and requires a little knowledge of the console. Moreover, it's assumed that [Rust and Cargo are installed](https://doc.rust-lang.org/stable/book/ch01-00-getting-started.html). @@ -29,7 +29,7 @@ This will create a new directory called `grovers_example` containing the necessary files for a Rust project. Enter this directory. Add the latest version of quantr as a dependency by running `cargo add -quantr` on the console. This should add quantr below `[d ependecies]` in +quantr` on the console. This should add quantr below `[dependecies]` in you `Cargo.toml` file. Then, run `cargo build`. This will download the quantr crate from [crates.io](https://crates.io/) and make it accessible for your project. @@ -128,7 +128,7 @@ be prepared and measured multiple times to collect a bin count of observed states. This bin count can be found and printed with ```rust,ignore -if let Measurement::Observable(bin_count) = circuit.repeat_measurement(500).unwrap() { +if let Ok(Measurement::Observable(bin_count)) = circuit.repeat_measurement(500) { // bin_count is a HashMap for (state, count) in bin_count { println!("{} : {}", state.to_string(), count); @@ -147,7 +147,7 @@ In nature, this cannot be directly observed. However, it can still be useful to view this "theoretical" superposition: ```rust,ignore -if let Measurement::NonObservable(output_super_position) = circuit.get_superposition().unwrap() +if let Ok(Measurement::NonObservable(output_super_position)) = circuit.get_superposition() { for (state, amplitude) in super_position.into_iter() { println!("{} : {}", state.to_string(), amplitude); @@ -167,9 +167,9 @@ so: ```rust,ignore ... -use quantr::QuantrError; +use std::error::Error; -fn main() -> Result<(), QuantrError> { +fn main() -> Result<(), Box> { ...; Ok(()) } @@ -177,17 +177,11 @@ fn main() -> Result<(), QuantrError> { A `Ok(())` is returned on the last line; signalling that the program has exited without errors. Then, effectively all unwrap methods called after -appending gates can be replaced with a `?`. However, an argument for -leaving the unwraps explicit is that if a function has appended a gate -resulting in an error, such as adding a gate out width the circuit's -size, then at runtime the program will panic and return a compiler -message explicitly directing the user to the line in question. Even -though the many unwraps may be unpleasant, it can be beneficial for -debugging while creating the circuit. - -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. +appending gates can be replaced with a `?`. This can be seen explicitly +in the `example/grovers.rs` folder. + +The following is the completed code. This can be ran with `cargo run +--example grovers` from the root directory. ```rust use quantr::{Circuit, Gate, Measurement, Printer}; @@ -232,7 +226,7 @@ fn main() { // Displays bin count of the resulting 500 repeat measurements of // superpositions. bin_count is a HashMap. - if let Measurement::Observable(bin_count) = circuit.repeat_measurement(500).unwrap() { + if let Ok(Measurement::Observable(bin_count)) = circuit.repeat_measurement(500) { println!("\n[Observable] Bin count of observed states."); for (state, count) in bin_count { println!("|{}> observed {} times", state.to_string(), count); @@ -240,7 +234,7 @@ fn main() { } // Returns the superpsoition that cannot be directly observed. - if let Measurement::NonObservable(output_super_position) = circuit.get_superposition().unwrap() + if let Ok(Measurement::NonObservable(output_super_position)) = circuit.get_superposition() { println!("\n[Non-Observable] The amplitudes of each state in the final superposition."); for (state, amplitude) in output_super_position.into_iter() { diff --git a/README.md b/README.md index e27f289..9567e82 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ implementation of Grover's algorithm. - Aimed to be accessible for beginners in Rust. - The distinction between physical observables and non-physical - observables is made clear; but the latter is still made possible to - retrieve. + observables that can be extracted from the circuit is made clear, + where the latter is still possible to retrieve. - Prints the circuit diagram to the terminal, or saves it to a text file, as a UTF-8 string. - Custom gates can be implemented easily by giving their explicit linear @@ -79,7 +79,7 @@ fn main() { quantum_circuit.simulate(); - // Below prints the number of times that each state was observered + // Below prints the number of times that each state was observed // over 500 measurements of superpositions. if let Ok(Observable(bin_count)) = quantum_circuit.repeat_measurement(500) { diff --git a/examples/custom_gate.rs b/examples/custom_gate.rs index c43fd16..de4048f 100644 --- a/examples/custom_gate.rs +++ b/examples/custom_gate.rs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Andrew Rowan Barlow. Licensed under the EUPL-1.2 +* Copyright (c) 2024 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 diff --git a/examples/generalised_control_not_gate.rs b/examples/generalised_control_not_gate.rs index eb668e4..bc1eb78 100644 --- a/examples/generalised_control_not_gate.rs +++ b/examples/generalised_control_not_gate.rs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Andrew Rowan Barlow. Licensed under the EUPL-1.2 +* Copyright (c) 2024 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 diff --git a/examples/grovers.rs b/examples/grovers.rs index 0b6fa33..b542f84 100644 --- a/examples/grovers.rs +++ b/examples/grovers.rs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Andrew Rowan Barlow. Licensed under the EUPL-1.2 +* Copyright (c) 2024 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 diff --git a/examples/qft.rs b/examples/qft.rs index 0fba49e..ba5fec2 100644 --- a/examples/qft.rs +++ b/examples/qft.rs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Andrew Rowan Barlow. Licensed under the EUPL-1.2 +* Copyright (c) 2024 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 diff --git a/tests/grovers.rs b/tests/grovers.rs index b8de73b..c27db9b 100644 --- a/tests/grovers.rs +++ b/tests/grovers.rs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Andrew Rowan Barlow. Licensed under the EUPL-1.2 +* Copyright (c) 2024 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 diff --git a/tests/qft.rs b/tests/qft.rs index ee30585..76208ef 100644 --- a/tests/qft.rs +++ b/tests/qft.rs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Andrew Rowan Barlow. Licensed under the EUPL-1.2 +* Copyright (c) 2024 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 From d702fc2e60a34323a672711e044d8b3c6da87ada Mon Sep 17 00:00:00 2001 From: Andrew Barlow Date: Tue, 23 Jan 2024 13:42:43 +0000 Subject: [PATCH 2/6] Update changelog Signed-off-by: Andrew Barlow --- CHANGELOG.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60fc10a..9e7a4ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,17 @@ This file logs the versions of quantr. -## 0.5.0 - Finalising Interface +## 0.5.1 - Review of docs and deprecated const functions + +See the previous update, 0.5.0, for why some functions were promoted to +a const (TL;DR it was a mistake). These have been marked `deprecate` so +the rust compiler warns users to not use them in a const context. + +The quick start guide has been updated to for 0.5.0 use of quantr, where +the errors that functions return have now been made private, forcing the +user to handle them through their `std::error::Error` trait. + +## 0.5.0 - Finalising interface Following this update, interfacing with quantr can now be done safely. All assumptions that are needed for the safe simulation of the circuit From 93f92dfb25b32600c486cf3e1f373142c00f8a9c Mon Sep 17 00:00:00 2001 From: Andrew Barlow Date: Wed, 24 Jan 2024 15:47:06 +0000 Subject: [PATCH 3/6] Add deprecated warning messages about const A deprecated message has been added to all functions that are constant, as in the next major update the const feature will be removed. This will jopefully minimise breaking changes, as the warning states to not use the functions in a constant setting. Signed-off-by: Andrew Barlow --- src/circuit.rs | 12 ++++++++++++ src/circuit/printer.rs | 3 +++ src/circuit/states/super_positions.rs | 3 +++ 3 files changed, 18 insertions(+) diff --git a/src/circuit.rs b/src/circuit.rs index 6cc0ae6..d537a9a 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -50,6 +50,10 @@ pub struct Circuit<'a> { } impl<'a> Circuit<'a> { + + #[deprecated(note= + "In the next major update, const will be removed from this function. Therefore, please do not use this function in constant settings." + )] /// Initialises a new circuit. /// /// The lifetime is due to the slices of control qubits for [Gate::Custom]. That is, the slice @@ -79,6 +83,9 @@ impl<'a> Circuit<'a> { }) } + #[deprecated(note= + "In the next major update, const will be removed from this function. Therefore, please do not use this function in constant settings." + )] /// Returns the number of qubits in the circuit. /// /// # Example @@ -422,6 +429,9 @@ impl<'a> Circuit<'a> { self.output_state = Some(register); } + #[deprecated(note= + "In the next major update, const will be removed from this function. Therefore, please do not use this function in constant settings." + )] /// Returns the resulting superposition after the circuit has been simulated using /// [Circuit::simulate]. /// @@ -588,6 +598,8 @@ impl<'a> Circuit<'a> { #[rustfmt::skip] #[cfg(test)] mod tests { + #![allow(deprecated)] + use crate::{complex_im, complex_re, complex_re_array, complex, COMPLEX_ZERO, Gate, Complex, Circuit}; use crate::states::{SuperPosition, Qubit, ProductState}; use super::HashMap; diff --git a/src/circuit/printer.rs b/src/circuit/printer.rs index 79ed303..c1cda00 100644 --- a/src/circuit/printer.rs +++ b/src/circuit/printer.rs @@ -371,6 +371,9 @@ impl Printer<'_> { #[rustfmt::skip] #[cfg(test)] mod tests { + + #![allow(deprecated)] + use crate::{ Printer, Circuit, Gate, states::{Qubit, ProductState, SuperPosition}, }; diff --git a/src/circuit/states/super_positions.rs b/src/circuit/states/super_positions.rs index 8f655e6..316b809 100644 --- a/src/circuit/states/super_positions.rs +++ b/src/circuit/states/super_positions.rs @@ -140,6 +140,9 @@ impl SuperPosition { self.amplitudes.get(pos).cloned() } + #[deprecated(note= + "In the next major update, const will be removed from this function. Therefore, please do not use this function in constant settings." + )] /// Returns the number of qubits that each product state in the super position is composed of by using the Kronecker product. /// /// # Example From 5b02d2adea3290c425c919549fa4f6ca1c274088 Mon Sep 17 00:00:00 2001 From: Andrew Barlow Date: Sat, 3 Feb 2024 10:12:15 +0000 Subject: [PATCH 4/6] Edit README A reference to the custom enum not checking for unitary mappings was added, and removing an unnecersary `.to_string` call in the example code. Signed-off-by: Andrew Barlow --- CHANGELOG.md | 2 +- README.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e7a4ce..cfc3f31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ See the previous update, 0.5.0, for why some functions were promoted to a const (TL;DR it was a mistake). These have been marked `deprecate` so the rust compiler warns users to not use them in a const context. -The quick start guide has been updated to for 0.5.0 use of quantr, where +The quick start guide has been updated for 0.5.0 use of quantr, where the errors that functions return have now been made private, forcing the user to handle them through their `std::error::Error` trait. diff --git a/README.md b/README.md index 9567e82..3d7d7a2 100644 --- a/README.md +++ b/README.md @@ -81,11 +81,10 @@ fn main() { // Below prints the number of times that each state was observed // over 500 measurements of superpositions. - if let Ok(Observable(bin_count)) = quantum_circuit.repeat_measurement(500) { println!("[Observable] Bin count of observed states."); for (state, count) in bin_count { - println!("|{}> observed {} times", state.to_string(), count); + println!("|{}> observed {} times", state, count); } } @@ -118,8 +117,9 @@ When defining a custom function that depends on the position of control nodes to define gates (such as the CNot and Toffoli gates), it must be defined so that the most far right state of the product state, is assumed to be the gate that is 'activated'. In general, it is better to -assume that the custom function doesn't define control nodes, but rather -it extends the dimension of the function's domain. +assume that the custom function doesn't define control nodes, but rather +it extends the dimension of the function's domain. Lastly, the custom +enum does not check if the mapping is unitary. ### Documentation From d9f711a89d9d26057ad677e33a681aa46c241b15 Mon Sep 17 00:00:00 2001 From: Andrew Barlow Date: Sun, 4 Feb 2024 15:55:28 +0000 Subject: [PATCH 5/6] Format deprecated notes Signed-off-by: Andrew Barlow --- src/circuit.rs | 13 ++++++------- src/circuit/states/super_positions.rs | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/circuit.rs b/src/circuit.rs index d537a9a..a5f8d39 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -50,9 +50,8 @@ pub struct Circuit<'a> { } impl<'a> Circuit<'a> { - - #[deprecated(note= - "In the next major update, const will be removed from this function. Therefore, please do not use this function in constant settings." + #[deprecated( + note = "In the next major update, const will be removed from this function. Therefore, please do not use this function in constant settings." )] /// Initialises a new circuit. /// @@ -83,8 +82,8 @@ impl<'a> Circuit<'a> { }) } - #[deprecated(note= - "In the next major update, const will be removed from this function. Therefore, please do not use this function in constant settings." + #[deprecated( + note = "In the next major update, const will be removed from this function. Therefore, please do not use this function in constant settings." )] /// Returns the number of qubits in the circuit. /// @@ -429,8 +428,8 @@ impl<'a> Circuit<'a> { self.output_state = Some(register); } - #[deprecated(note= - "In the next major update, const will be removed from this function. Therefore, please do not use this function in constant settings." + #[deprecated( + note = "In the next major update, const will be removed from this function. Therefore, please do not use this function in constant settings." )] /// Returns the resulting superposition after the circuit has been simulated using /// [Circuit::simulate]. diff --git a/src/circuit/states/super_positions.rs b/src/circuit/states/super_positions.rs index 316b809..d2b3709 100644 --- a/src/circuit/states/super_positions.rs +++ b/src/circuit/states/super_positions.rs @@ -140,8 +140,8 @@ impl SuperPosition { self.amplitudes.get(pos).cloned() } - #[deprecated(note= - "In the next major update, const will be removed from this function. Therefore, please do not use this function in constant settings." + #[deprecated( + note = "In the next major update, const will be removed from this function. Therefore, please do not use this function in constant settings." )] /// Returns the number of qubits that each product state in the super position is composed of by using the Kronecker product. /// From 7bed981ffa5cb803fba0f30cab7e08b122470202 Mon Sep 17 00:00:00 2001 From: Andrew Barlow Date: Sun, 4 Feb 2024 16:05:09 +0000 Subject: [PATCH 6/6] Bump version to 0.5.1 Bump version and prepare code for cargo publish. Signed-off-by: Andrew Barlow --- Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ef283e9..190c081 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "quantr" -version = "0.5.0" +version = "0.5.1" edition = "2021" license = "EUPL-1.2" readme = "README.md" @@ -10,7 +10,6 @@ authors = ["Andrew Barlow "] repository = "https://github.com/a-barlow/quantr" homepage = "https://a-barlow.github.io/quantr-book" description = "Readily create, simulate and print quantum circuits." -publish = false [dependencies] fastrand = "^2.0.1"