-
Notifications
You must be signed in to change notification settings - Fork 10
feat: Implement LaTeX generation #145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
hiyaryan
wants to merge
127
commits into
rigetti:main
Choose a base branch
from
hiyaryan:to-latex
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 117 commits
Commits
Show all changes
127 commits
Select commit
Hold shift + click to select a range
7be2094
Initial ToLaTeX commit.
479974d
Add X and Y gate tests with helper function.
8fb30e5
Move gate tests to tests submodule gates.
cb02ef8
Add TikZ operators.
5cb096d
Add latex dependency as feature.
029d337
Rename TikzOperators to TikzOperator and CamelCase variant names.
c9fc7e9
Move latex.rs and snapshots into latex directory.
a25abb4
Initial commit for LaTeX abstract factory model.
1d418a4
Revert "Initial commit for LaTeX abstract factory model."
3f217f4
Remove new snapshot of failed X gate unit test.
ed1f8a0
Remove latex dependency and rename feature to-latex to latex.
e00633e
Add comments and update names wrt Quantikz docs.
b7642bc
Update snapshot test names.
865f495
Add document template and unit tests.
dc5b563
Add gate command and update command variant data types.
6486920
Add test for single qubit with two gates X and Y.
5cbfb4d
Build a Diagram from a vector of Circuits.
f3ea53b
Remove extraneous gate from snapshot test.
2a97404
Add LaTeX gen for single qubit gate instructions.
f39f1d8
Add multi-line n-qubit single qubit gates.
1a3d66c
Update doc string example for get_command.
6a4894d
Preserve order of wires by indexing circuit keys in vector.
04a1723
Add initial CNOT LaTeX gen for variable qubits.
458e750
Merge branch 'main' into to-latex
568fcdf
Add CNOT gate.
4a8cf9b
Add combined single and multi qubit gate tests.
e615f2c
Add settings test module with snapshot test.
8494931
Add impute missing qubits setting.
2048ccd
Debug CNOT with two TDD tests of complex Programs.
5094048
Optimize ctrl/targ programs with only one call to set_ctrl_targ.
dad6ac4
Allow CNOT for a single qubit.
423a7ec
Revert "Allow CNOT for a single qubit."
e36623a
Handle CNOT without target.
b2b1f1a
Working draft of CCNOT and CONTROLLED.
298075f
Revert "Allow CNOT for a single qubit."
9fc3c62
Merge with to-latex.
39f8f46
Add CONTROLLED and CCNOT.
b6a9e20
Update doc and remove unused variables.
6e1dfba
Reformat doc.
9062255
Reformat file.
6f3c0c3
Propagate LatexGenError instead of panic.
d40808e
Add PHASE, CZ, and CPHASE.
0cfb8d2
Initial docs.
6a20a52
Add DAGGER modifier.
5655d7e
Add texify numerical constants setting.
370c3cc
Fix get_symbol doctest.
5d9c138
Initial good modifiers test.
e49e7d7
Merge branch 'main' into to-latex
f0591fb
Merge branch 'to-latex' into good-tests
a068411
Add multiple controlled modifiers to single qubit gates.
86a280e
Add good defgate and modifiers tests.
2338b2e
Refactor to_latex with initial circuit of used qubits.
d31b231
Move to_latex code blocks to new functions and remove outdated TODOs.
6cd43dc
Test five good programs from quilc good-test-files.
5dfafec
Add error handling for unsupported programs.
772c2ad
Merge branch 'to-latex' into to-latex-docs
37dbb7f
Update docs including supported programs.
645b787
Tighten visibility of crate.
5d7940c
Fix docs and remove deadcode.
11cd5c5
Replace explicit Clone impl for Parameter with derived trait.
5dbaaad
Refactor get_symbol into ToString for Symbol and Parameter.
0b9213d
Apply docs suggestions from code review.
hiyaryan 10fe4f3
Fix Quantikz link in documentation.
025f7fa
Add clippy fixes.
af07939
Apply clippy fixes, doc fixes, rename Settings to RenderSettings.
63e13ea
Add manual clippy fixes and Clone or Copy to structs and make more id…
3677651
Remove supported program checking.
6a2fd9e
Use write! in Diagram fmt, reduce/reformat docs.
6ec15be
Merge branch 'rigetti:main' into to-latex
hiyaryan 28f16e7
Decompose gates to canonical form.
7ab4b5a
Fill circuit using instruction in canonical form.
e37d83e
Debug PHASE, multiline, and CNOT 0 0 tests.
61f990a
Handle unsupported instructions and gates.
1af1a9f
Update docs and readability.
029f05b
Refactor gate setting from parse_gate into separate method set_gate.
421e7eb
Rename feature to ToLatex, set_qw to set_empty, make enums more idiom…
cab0caf
Update doctest examples.
571c497
Rename err variant FoundCNOTWithNoTarget to FoundTargetWithNoControl.
0af2769
Refactor impute_missing_qubits and set_empty to use built-ins from std.
hiyaryan 712a24c
Add missing semicolon and fix format.
c353c3f
Organize code by restructuring design.
1ecc789
Make ToLatex a method of Program.
4e4ca5a
Add derive_more, change From<String> to FromStr, generify with From<S>.
46c024f
Apply suggestions to extend derived traits and shorten/simplify code.
30169aa
Update GateDefinition Instruction block in to_latex.
0b58d76
Change insert_gate to apply_gate and simplify using to_canonical.
8b74dbe
Refactor Wire.gate value type to String and remove CONTROLLED collect…
9b782fa
Rename set_modifiers to extract_daggers, Wire.modifiers to Wire.dagge…
2e4a67b
Show Display path from fmt module.
hiyaryan 7a6f513
Move FromStr for Symbol into Symbol enum block using strum.
hiyaryan 392e7af
Remove unused CompositeGate variant None.
hiyaryan f85ddbf
Make empty string with new instead of from.
hiyaryan 935875a
Initial file restructuring.
90c3cb1
Move settings to latex crate.
ee42a06
Organize latex module into submodules and update docs.
6833a9b
Correct docs to m is row, n is column, for m x n matrix.
041b969
Move set_empty into gate block in to_latex.
f2d2733
Pull column from Wire methods, set as field, refactor set_empty to ap…
1464300
Refactor column from int to usize, track in wire, set total in diagram.
09d7fac
Refactor Diagram fmt to use enumerate and iters and expand comments.
3010fe8
Remove enumeration in Diagram fmt.
6808837
Add inner String type to Gate and Phase variants, and implement dagge…
07b6184
Remove verticals from Diagram, add Display for Wire, refactor Display…
f7e0409
Iterate over circuit instead of keys in Diagram fmt and update docs.
08a6013
Move unwrap for last item in collections to outside of loop.
68cc16e
Use regex for canonical gate decomposition and handle unimplemented X…
4f9cae4
Merge targ and ctrl fields into single generic gates field.
755883d
Use the generic gate and counted modifiers, and catch unsupported gat…
8cf0073
Change parameters values from vector to single parameter.
11191e0
Change Lstick to LeftWireLabel.
05334d1
Update docs for Diagram circuit.
hiyaryan 9487249
Apply review suggestions.
436ac86
Add QuantikzGate struct, unnest apply_gate
MarquessV 41c2538
apply parameters inside of main apply_gate loop
MarquessV e835c61
Couple parameter with a specific cell in Column struct in a Wire of C…
04c2abf
Make enum-as-inner an optional dependency for latex feature.
b19f0aa
Use enum-as-inner to extract fixed qubits, reorganize code, update docs.
9e6d4bc
Revert "Make enum-as-inner an optional dependency for latex feature."
3aacde2
Remove wordy QuantikzGate doc, refactor if-let for instruction to match.
ea8cd05
Refactor using new data model WIP.
b07ff0f
Fix doc tests, remove dev notes.
12b5ee3
Fix doc tests, remove dev notes and template snapshot test.
69087b7
Merge branch 'to-latex' of https://github.com/hiyaryan/quil-rs into t…
b504fec
Add error handling, clean up code and comments, remove sorting with B…
c400135
Apply suggestions from code review.
hiyaryan a837cf4
Amend previous commit.
1a44a3a
Merge branch 'main' into to-latex
hiyaryan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,158 @@ | ||
| use std::{ | ||
| collections::{BTreeMap, HashSet}, | ||
| fmt, | ||
| }; | ||
|
|
||
| use crate::instruction::{Gate, Qubit}; | ||
|
|
||
| use self::wire::{QuantikzColumn, Wire}; | ||
| use super::{LatexGenError, Parameter, RenderCommand, RenderSettings}; | ||
|
|
||
| pub(crate) mod wire; | ||
|
|
||
| /// A Diagram represents a collection of wires in a Circuit. The size of the | ||
| /// Diagram can be measured by multiplying the number of Instructions in a | ||
| /// Program with the length of the Circuit. This is an [m x n] matrix where n, | ||
| /// is the number of Quil instructions (or columns), and m, is the number of | ||
| /// wires (or rows). Each individual element of the matrix represents an item | ||
| /// that is serializable into LaTeX using the ``Quantikz`` RenderCommands. | ||
| #[derive(Clone, Debug, Default)] | ||
| pub(super) struct Diagram { | ||
| /// customizes how the diagram renders the circuit | ||
| pub(crate) settings: RenderSettings, | ||
| /// Wires (diagram rows) keyed by qubit index | ||
| pub(crate) circuit: BTreeMap<u64, Box<Wire>>, | ||
| } | ||
|
|
||
| impl Diagram { | ||
| /// Compares qubits from a single instruction associated with a column on | ||
| /// the circuit to all of the qubits used in the quil program. If a qubit | ||
| /// from the quil program is not found in the qubits in the single | ||
| /// instruction line, then an empty slot is added to that column on the | ||
| /// qubit wire of the circuit indicating a "do nothing" at that column. | ||
| /// | ||
| /// # Arguments | ||
| /// `qubits` - the qubits from the Quil program. | ||
| /// `gate` - the Gate of the Instruction from `to_latex`. | ||
| pub(crate) fn apply_empty(&mut self, qubits: &HashSet<Qubit>, gate: &Gate) { | ||
| qubits | ||
| .difference(&gate.qubits.iter().cloned().collect()) | ||
| .filter_map(|q| q.as_fixed()) | ||
| .for_each(|index| { | ||
| if let Some(wire) = self.circuit.get_mut(index) { | ||
| wire.set_empty() | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| /// Applies a gate from an instruction to the associated wires in the | ||
| /// circuit of this diagram. | ||
| /// | ||
| /// # Arguments | ||
| /// `gate` - the Gate of the Instruction from `to_latex`. | ||
| pub(crate) fn apply_gate(&mut self, gate: &Gate) -> Result<(), LatexGenError> { | ||
| // circuit needed immutably but also used mutably | ||
| let circuit = self.circuit.clone(); | ||
|
|
||
| // Quantum Gates operate on at least one qubit | ||
| let last_qubit = gate.qubits[gate.qubits.len() - 1] | ||
| .clone() | ||
| .into_fixed() | ||
| .map_err(|_| LatexGenError::UnsupportedQubit)?; | ||
|
|
||
| // set gate for each qubit in the instruction | ||
| for qubit in gate.qubits.iter() { | ||
| let mut column = QuantikzColumn::default(); | ||
|
|
||
| let instruction_qubit = qubit | ||
| .clone() | ||
| .into_fixed() | ||
| .map_err(|_| LatexGenError::UnsupportedQubit)?; | ||
|
|
||
| let wire = self | ||
| .circuit | ||
| .get_mut(&instruction_qubit) | ||
| .ok_or(LatexGenError::QubitNotFound(instruction_qubit))?; | ||
|
|
||
| // set the parameters for each qubit in the instruction | ||
| for expression in &gate.parameters { | ||
| column.set_param(expression, self.settings.texify_numerical_constants); | ||
| } | ||
|
|
||
| let quantikz_gate = wire::QuantikzGate::try_from(gate.clone())?; | ||
|
|
||
| if gate.qubits.len() - quantikz_gate.ctrl_count > 1 { | ||
| return Err(LatexGenError::UnsupportedGate { | ||
| gate: gate.name.to_string(), | ||
| }); | ||
| } | ||
|
|
||
| // if the instruction qubit a control qubit | ||
| if quantikz_gate.ctrl_count > 0 && instruction_qubit != last_qubit { | ||
| // get the distance between the instruction qubit and the target qubit | ||
| let distance = if instruction_qubit < last_qubit { | ||
| circuit.range(instruction_qubit..last_qubit).count() as i64 | ||
| } else { | ||
| -(circuit.range(last_qubit..instruction_qubit).count() as i64) | ||
| }; | ||
| column.cell = wire::QuantikzCellType::Ctrl(distance); | ||
|
|
||
| // otherwise, the instruction qubit is the target qubit or a single qubit gate | ||
| } else { | ||
| column.cell = wire::QuantikzCellType::Gate(quantikz_gate); | ||
| } | ||
|
|
||
| // parameterized non-PHASE gates are unsupported | ||
| if column.parameter != Parameter::None && !gate.name.contains("PHASE") { | ||
| // parameterized single qubit gates are unsupported | ||
| return Err(LatexGenError::UnsupportedGate { | ||
| gate: gate.name.clone(), | ||
| }); | ||
| } | ||
|
|
||
| // push the gate to the wire | ||
| wire.columns.push(column); | ||
| } | ||
|
|
||
| Ok(()) | ||
| } | ||
| } | ||
|
|
||
| impl fmt::Display for Diagram { | ||
| /// Returns a result containing the body of the Document. | ||
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
| // write a newline between the body and the Document header | ||
| writeln!(f)?; | ||
|
|
||
| // write the LaTeX string for each wire in the circuit | ||
| let last = self.circuit.keys().last().unwrap_or(&0); | ||
| for (qubit, wire) in &self.circuit { | ||
| // are labels on in settings? | ||
| if self.settings.label_qubit_lines { | ||
| // write the label to the left side of wire | ||
| write!(f, "{}", RenderCommand::LeftWireLabel(*qubit))?; | ||
| } else { | ||
| // write an empty column buffer as the first column | ||
| write!(f, "{}", RenderCommand::Qw)?; | ||
| } | ||
|
|
||
| // write the LaTeX string for the wire | ||
| write!(f, "{wire}")?; | ||
|
|
||
| // chain an empty column to the end of the line | ||
| write!(f, "{}{}", &RenderCommand::Separate, &RenderCommand::Qw)?; | ||
|
|
||
| // omit a new row if this is the last qubit wire | ||
| if *qubit != *last { | ||
| // otherwise, write a new row to the end of the line | ||
| write!(f, " ")?; | ||
| write!(f, "{}", &RenderCommand::Nr)?; | ||
| } | ||
|
|
||
| // write a newline between each row and or the body and the document footer | ||
| writeln!(f)?; | ||
| } | ||
|
|
||
| Ok(()) | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.