summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNorbert Preining <preining@logic.at>2021-04-03 23:54:49 +0000
committerNorbert Preining <preining@logic.at>2021-04-03 23:54:49 +0000
commit32f9a397a899dfac82a4f4d80670f48b675da246 (patch)
tree4d4429493606d826f06de7ae1401bf3a3b667bcc
parent8687c318c8de471be301f160ad143242f1a88e68 (diff)
yquant (4apr21)
git-svn-id: svn://tug.org/texlive/trunk@58712 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/latex/yquant/yquant-doc.pdfbin606568 -> 679110 bytes
-rw-r--r--Master/texmf-dist/doc/latex/yquant/yquant-doc.tex1883
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquant-circuit.tex248
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquant-config.tex395
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquant-draw.tex1016
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquant-env.tex449
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquant-lang.tex859
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquant-langhelper.tex89
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex883
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquant-registers.tex356
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquant-shapes.tex356
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquant-tools.tex100
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquant.sty19
-rw-r--r--Master/texmf-dist/tex/latex/yquant/yquantlanguage-qasm.sty151
14 files changed, 4311 insertions, 2493 deletions
diff --git a/Master/texmf-dist/doc/latex/yquant/yquant-doc.pdf b/Master/texmf-dist/doc/latex/yquant/yquant-doc.pdf
index b7233fbebc3..203ef161c98 100644
--- a/Master/texmf-dist/doc/latex/yquant/yquant-doc.pdf
+++ b/Master/texmf-dist/doc/latex/yquant/yquant-doc.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/yquant/yquant-doc.tex b/Master/texmf-dist/doc/latex/yquant/yquant-doc.tex
index 735f98eb577..8a9ebc886dd 100644
--- a/Master/texmf-dist/doc/latex/yquant/yquant-doc.tex
+++ b/Master/texmf-dist/doc/latex/yquant/yquant-doc.tex
@@ -14,7 +14,8 @@
\definecolor{darkblue}{RGB}{5, 10, 122}
\usepackage[english]{babel}
\usepackage[colorlinks, linkcolor=darkblue, bookmarksdepth=paragraph]{hyperref}
-\usepackage{yquant,braket,hyphenat,microtype,hologo,minted,import}
+\usepackage[compat=newest]{yquant}
+\usepackage{braket,hyphenat,microtype,hologo,minted,import,ragged2e}
\usetikzlibrary{quotes,fit,shapes.symbols,backgrounds,quantikz}
\useyquantlanguage{qasm}
\usepackage{amsmath,adjustbox,cleveref}
@@ -23,6 +24,8 @@
\makeatletter
+\long\def\compat#1{\texorpdfstring{\leavevmode\makenote{#1}\penalty10000 }{}}
+
% BEGIN_FOLD Minted configuration
\begingroup
\catcode`\&=11
@@ -53,17 +56,17 @@
\endgroup\vskip-\parskip%
\noindent\ignorespaces%
}
-\newenvironment{option*}[2]{\vskip5mm%
+\newenvironment{option*}[3][]{\vskip5mm%
\noindent\begin{minipage}[t]{\linewidth}%
\begingroup%
\let\minted@inline@iii=\patched@minted@inline@iii%
\raggedleft%
\hspace*{-1cm}%
- \phantomsection\label{style:/#1/#2}%
- \texttt{\textcolor{gray}{/#1/}\textcolor{mintgreen}{#2}}\hfill default: %
+ \phantomsection\label{style:/#2/#3}%
+ \texttt{\ifstrempty{#1}\relax{\compat{#1}}\textcolor{gray}{/#2/}\textcolor{mintgreen}{#3}}\hfill default: %
\tex}{%
\end{minipage}}
-\newenvironment{option}{\csname option*\endcsname{yquant}}{\csname endoption*\endcsname}
+\newenvironment{option}[1][]{\csname option*\endcsname[{#1}]{yquant}}{\csname endoption*\endcsname}
\newsavebox\codeexamplebox
\newenvironment{codeexample}{%
@@ -112,21 +115,26 @@
}
\def\bd@boxextra#1{%
- \node[anchor=north west] at (current bounding box.north east) {\hskip7pt#1};%
+ \node[anchor=north east, overlay] at (current bounding box.north west) {#1\hskip7pt};%
}
\newcommand*\bd@boxintro[5]{%
\begingroup%
\setlength{\parskip}{0pt}%
\setlength{\parindent}{0pt}%
- \ifstrempty{#5}{%
+ \edef\tmp{#5}%
+ \ifx\tmp\empty%
+ \expandafter\@firstoftwo%
+ \else%
+ \expandafter\@secondoftwo%
+ \fi{%
\begin{mdframed}[style=bdBox, backgroundcolor=#4, linecolor=#2,
firstextra=\bd@boxextra{#1}, singleextra=\bd@boxextra{#1}]%
}{%
\begin{mdframed}[style=bdBox, backgroundcolor=#4,
frametitlefont=\bfseries\sffamily\color{#3},
frametitlebackgroundcolor=#2,
- frametitle={\strut#5}, linecolor=#2,
+ frametitle={\strut\tmp}, linecolor=#2,
firstextra=\bd@boxextra{#1}, singleextra=\bd@boxextra{#1}]%
}%
\ignorespaces%
@@ -154,18 +162,22 @@
}
\newenvironment*{warning}[1][]{%
\bd@boxintro{\raisebox{\baselineskip-\height-6.5pt}{\includegraphics[width=1cm]{Warning.pdf}}}%
- {boxRedHead}{white}{boxRedBody}{#1}%
+ {boxRedHead}{white}{boxRedBody}{\unexpanded{#1}}%
\ignorespaces%
}{%
\bd@boxoutro%
}
-\newenvironment*{example}[1][]{%
- \bd@boxintro{\raisebox{\baselineskip-\height-6.5pt}{\includegraphics[width=1cm]{Bulb.png}}}%
- {boxBlueHead}{white}{boxBlueBody}{#1}%
+\def\example{\@ifnextchar<\example@i{\example@i<>}}
+\def\example@i<#1>{\@ifnextchar[{\example@ii<{#1}>}{\example@ii<{#1}>[]}}
+\long\def\example@ii<#1>[#2]{%
+ \bd@boxintro{\ifstrempty{#1}{}{\ifstrempty{#2}{\compat{#1}}{}}%
+ \raisebox{\baselineskip-\height-6.5pt}{%
+ \includegraphics[width=1cm]{Bulb.png}%
+ }}{boxBlueHead}{white}{boxBlueBody}%
+ {\ifstrempty{#1}{}{\ifstrempty{#2}{}{\unexpanded{\compat{#1}}}}\unexpanded{#2}}%
\ignorespaces%
-}{%
- \bd@boxoutro%
}
+\let\endexample=\bd@boxoutro
% END_FOLD
\def\TikZ{\textcolor{brown}{Ti\textit kZ}}
@@ -178,10 +190,16 @@
\def\ketbra#1#2{\ket{#1}\!\bra{#2}}
\frenchspacing
-\RequirePackage{scrlayer-scrpage}
+\RequirePackage{scrlayer-scrpage,scrlayer-notecolumn}
\setcounter{tocdepth}{\subsectiontocdepth}
\KOMAoptions{DIV=8}
-\addtokomafont{section}{\clearpage}
+\newcommand*{\the@orig@section}{}
+\let\the@orig@section=\section
+\renewcommand*{\section}{%
+ \clearpage%
+ \the@orig@section%
+}
+\addtokomafont{notecolumn.marginpar}{\footnotesize\RaggedRight}
\recalctypearea
\begin{document}
@@ -190,18 +208,18 @@
\noindent This manual introduces \Yquant, a \LaTeX\hyp only package that outputs quantum circuits.
They are entered using a human\hyp readable language that, even from the source code, allows for a fluent understanding of the logic that underlies the circuit.
\Yquant{} internally builds on \TikZ{} and can be easily combined with arbitrary \LaTeX{} code.
- More than forty pages of examples complement the formal manual.
+ More than fifty pages of examples complement the formal manual.
\end{abstract}
\tableofcontents
-
- \clearpage
+
\section{Introduction}
This document outlines the scope and usage of the \Yquant{} package.
It contains both a reference and a huge number of examples.
\Yquant{} is a package that makes typesetting quantum circuits easy; the package is available on CTAN.
- This alpha version~0.3.3 \emph{should} be stable and interfaces are not very likely to change in an incompatible way in the future.
- Please do report all issues and desirable additions.
-
+ This beta version~0.4 \emph{should} be stable and interfaces are not very likely to change in an incompatible way in the future.
+ \compat{New in 0.4}Sometimes, backwards\hyp incompatible changes are required or advisable, in which case a compatibility setting will allow to revert back to the old behavior (rather, to maximize compatibility, this is an opt\hyp in setting: unless you choose the new behavior, you will get the old one).
+ Please do report all issues and desirable additions on \href{https://github.com/projekter/yquant/issues}{GitHub}.
+
\subsection{How to read the manual}
The probably fastest way to start using \Yquant{} is by just scanning through the examples in \cref{sec:examples}.
A more formal description of the \Yquant{} grammar and its fundamental concepts can be found in \cref{sec:grammar}.
@@ -209,13 +227,16 @@
The full list of all available gates is provided in \cref{sec:gates}.
Finally, you may find that \Yquant{} \emph{almost} does what you want, but there is some final tweak that you cannot achieve\dots.
Then, have a look at \cref{sec:tikz} (or \cref{sec:alt}).
-
+
\subsection{Installation}
The recommended way of installation is through CTAN.
- A direct installation from this Git repository to obtain the latest additions and features is be possible by just cloning it to a path visible to your \TeX{} compiler.
+ A direct installation from the Git repository to obtain the latest additions and features is be possible by just cloning it to a path visible to your \TeX{} compiler.
+ For example, you may put the source files in the same directory as your document (if you just want to give a try), or you may extract them to \texttt{tex/latex/yquant} in your local \texttt{texmf} (followed by an update of the file name database).
While the repository may contain new additions, they are not thoroughly tested until they end up on CTAN; features that are not documented in this manual are entirely unreliable.
- For example, you may put them in the same directory as your document (if you just want to give a try), or you may extract them to \texttt{tex/latex/yquant} in your local \texttt{texmf} (followed by an update of the file name database).
-
+
+ \compat{New in 0.4}The CTAN repository reflects the most current version tag on Git; the \href{https://github.com/projekter/yquant/releases}{Releases} section on GitHub additionally provides a single\hyp file version of the main package, which can for example conveniently be included in arXiv submissions.
+ Note that the arXiv currently provides \Yquant{}~0.3.2 out\hyp of\hyp the\hyp box.
+
\subsection{Purpose of \Yquant, alternatives}\label{sec:alt}
\Yquant{} is the acronym for ``yet another quantum circuit package.''
This highlights the fact that nothing that this package provides cannot be achieved by other means.
@@ -232,9 +253,9 @@
Consequently, the user is restricted to the set of features that \pkg{qasm} directly offers (which is small).
Changes to the output, while possible, will be overwritten if \texttt{qasm2circ} is run again.
\pkg{qasm} output often looks sub\hyp optimal do to the fact that, e.g., rectangles are made up of four lines that do not properly connect and give a crumbly general feeling.
-
+
Note that since version~0.3, \Yquant{} understands \pkg{qasm} syntax, see \cref{sec:foreign:qasm}.
-
+
Maintenance status: last update of \pkg{qasm} in 2005. Also, \pkg{xy} was last updated in 2013, and the script is not compatible out\hyp of\hyp the\hyp box with Python~3, though an automatic conversion should work.
\item \pkg{qcircuit} is probably the most\hyp widely used package.
It provides commands that make it much easier to create quantum circuits using the \pkg{xy} package.
@@ -242,13 +263,13 @@
This is particularly true for multi\hyp qubit gates.
Additionally, the \tex!\xymatrix! syntax is also somewhat cryptic.
\pkg{qcircuit} provides some flexibility within the limits of \pkg{xy} as to configuring the output.
-
+
Maintenance status: last update in 2018; and remember this is \pkg{xy} based, with last update in 2013.
\item \pkg{quantikz} is a relatively recent package that, following the same grid\hyp based approach as \pkg{qcircuit}, instead builds on \TikZ{} as a backend.
As a consequence, it provides the full flexibility of customization that \TikZ{} offers, where hardly anything cannot be done.
It also reduces burdens of the \pkg{xy} syntax.
However, the disadvantages of the grid\hyp based syntax still remain.
-
+
Maintenance status: last update in 2020; the underlying \TikZ{} is actively maintained again by now.
\item \pkg{qpic} follows the approach of \pkg{qasm}: It makes use of an external Python program that reads the quantum circuits in an own language and converts them into \TikZ{} commands.
The language \pkg{qpic} follows is much more powerful than \pkg{qasm}'s.
@@ -256,11 +277,11 @@
Being an external program, \pkg{qpic}'s intrinsic set of features (including, e.g., vertically set circuits) are huge.
However, the language \pkg{qpic} uses cannot be understood without a detailed study of the manual, it appears to have been designed with the aim to minimize the length of command names.
A disadvantage of external programs is that the amount of space gates need is not accessible by the script; hence, manual intervention may be required.
-
- Maintenance status: last update in 2016; the underlying \TikZ{} is actively maintained, and the script is compatible with Python~3.
+
+ Maintenance status: last update in 2020; the underlying \TikZ{} is actively maintained, and the script is compatible with Python~3.
\end{itemize}
\end{itemize}
-
+
\subsection{License}
This work may be distributed and/or modified under the conditions of the \LaTeX{} Project Public License, either version~1.3c of this license or (at your option) any later version.
The latest version of this license is in
@@ -268,20 +289,20 @@
\url{http://www.latex-project.org/lppl.txt}
\end{center}
and version~1.3c or later is part of all distributions of LaTeX version 2005/12/01 or later.
-
+
\section{Basic elements of \Yquant}\label{sec:grammar}
\Yquant, as some of the aforementioned packages, builds on \TikZ.
Its basic syntax is similar to \pkg{pgfplots}: Start a \tex!tikzpicture! environment (perhaps passing some options); inside, start a \tex!yquant! environment.
-
+
Inside the \tex!yquant! environment, \TeX{} will now understand the \Yquant{} language---so \Yquant{} falls into the same category as \pkg{qasm} and \pkg{qpic}, providing a human\hyp readable language for the specification of the circuit that is not fixed to the actual layout.
-
+
However, \Yquant{} is a \TeX\hyp only package (actually, \hologo{LaTeX2e}, but not \hologo{LaTeX3}) that requires no external script to run---so it also falls into the same category as \pkg{qcircuit} and \pkg{quantikz}.
-
+
Since it runs entirely within \TeX, you can at any time interject \Yquant{} code with arbitrary \TeX{} or \TikZ{} code (though if it is ``too arbitrary,'' you may need to restart the \Yquant{} interpreter).
-
+
\subsection{General usage}
- \begin{minted}{tex}
-% preamble: \usepackage{yquant}
+ \begin{minted}[escapeinside=||]{tex}
+% preamble: |\compat{Changed in 0.4}|\usepackage[compat=<version>]{yquant}
\begin{tikzpicture}% tikz options possible
% tikz commands go here
\begin{yquant}% yquant options possible. Watch the newlines!
@@ -290,10 +311,10 @@
% tikz commands go here
\end{tikzpicture}
\end{minted}
-
- Note that \Yquant{} depends on \pkg{etoolbox}, \TikZ, and \pkg{trimspaces}.
- Additionally, it requires a moderately recent version of \hologo{LaTeX2e}, using either \hologo{LuaLaTeX}, or (untested), \hologo{pdfLaTeX} or \hologo{XeLaTeX}.
-
+
+ Note that \Yquant{} depends on \pkg{etoolbox}, \TikZ, \pkg{trimspaces}, and \compat{Changed in 0.4}\pkg{xkeyval}.
+ Additionally, it requires a moderately recent version of \hologo{LaTeX2e}, using either \hologo{LuaLaTeX}; or (untested) \hologo{pdfLaTeX} or \hologo{XeLaTeX}.
+
\begin{warning}[Optional arguments]
The optional arguments for the \tex!yquant! environment have to appear \emph{on the same line} as the environment itself.
If you want to put the arguments into a new line, it is crucial to mask the line break by putting a comment symbol after the environment: \tex!\begin{yquant}%!.
@@ -301,23 +322,46 @@
Finally note that in (non\hyp fragile) \pkg{beamer} frames, this discrimination between spaces and new lines does not work; the optional arguments will always be counted for the environment, not for the gate.
In this case, you can either declare the frame as fragile or (recommended) introduce a blank line between the environment and the options for the first gate.
\end{warning}
-
+
+ \begin{warning}[\compat{New in 0.4}Compatibility mode]
+ Sometimes, continued development shows that certain choices of interfaces, configuration, or behavior are less ideal than originally thought.
+ In other cases, bugs are detected and fixed.
+ Both may lead to a change in the look of circuits developed with a previous version of \Yquant{} or even---though this should rarely, if ever, happen, and should be filed as a bug---prevent compilation in the new version.
+
+ For this reason, \Yquant{} offers a compatibility key that is highly recommended to be specified as a package option.
+ This allows certain features that are expected to break old layout or functionality to revert to their previous behavior.
+ Every feature affected by the \texttt{compat} key is documented in this manual.
+ Once a compatibility version is selected in a document, it cannot be changed any more.
+ Compatibility versions will include the major and minor, but not the patch level version number.
+ Bugs that clearly violated behavior described in this manual will be fixed without a possibility to revert back.
+ Changes that are not supposed to result in a (more than marginally) different result will not be included in the compatibility layer.
+ If you find this to be wrong in a particular case, please file a bug report.
+
+ When starting a new document, it is recommended to leave out the compatibility key at first compilation.
+ \Yquant{} will then issue a warning from which you can infer the recommended setting, corresponding to the current version.
+ You should then pass the appropriate version to the \tex!\usepackage! command.
+ For example, this manual corresponds to \tex!\usepackage[compat=0.4]{yquant}!.
+
+ Allowed values for \texttt{compat} are \texttt{newest} (discouraged), which equals \texttt{0.4}, and \texttt{0.3} (default).
+ \end{warning}
+
\subsection{Starred vs. unstarred environment}
You may choose to use either the \tex!yquant! or the \tex!yquant*! environment.
The former one requires you to define all your registers before you use them (though you may decide to define a register after some operations on \emph{different} registers, but before its first usage).
-
+
The starred form additionally supports the use of undeclared registers: it basically declares a registers upon its first usage.
- This will always be a \texttt{qubit} register; but if you use the corresponding option and the first usage is an \gate{init} command, you may overwrite this.
- Subcircuits always use the unstarred form.
-
- Additionally, if you refer to the index $i$ of a vector register of length $L < i$, this register will automatically be enlarged to $i \coloneq L$.
+ This will always be a \texttt{qubit} register; but if you use the corresponding attribute and the first usage is an \gate{init} command, you may overwrite this.
+
+ \compat{New in 0.2}Subcircuits always use the unstarred form.
+
+ \compat{New in 0.1.1}Additionally, if you refer to the index $i$ of a vector register of length $L < i$, this register will automatically be enlarged to $i \coloneq L$.
It is also possible to convert a scalar register into a vector register in this manner.
To enlarge a register in the unstarred environment, you must precede the number of registers to be added in the second declaration by a plus sign.
Note that in this manner, you may even create discontiguous vectors.
-
+
\emph{This might be a good point to proceed to the examples \cref{sec:examples}.}
-
- \subsection{Formal syntax}
+
+ \subsection[Formal syntax]{\compat{Enhanced in 0.1.2, 0.1.1}Formal syntax}
Every \Yquant{} command has the same structure (described here in EBNF syntax):
\begin{minted}{ebnf}
Command = { Arguments }, ?command?, [ Value ], [ RegisterList ], Controls, ";";
@@ -345,7 +389,7 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
Virtually every comma in the EBNF notation may consist of an arbitrary (including zero) number of whitespaces.
Not all combinations that can be constructed by this grammar are actually allowed semantically; but it would make the grammar too verbose to spell this out in detail.
Deviations are noted in this manual.
-
+
Valid values for
\begin{BVerbatim}[commandchars=\\\{\}]
\PYG{n+ni}{?command?}
@@ -370,7 +414,7 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
\PYG{l+s+s2}{\PYGZdq{}+\PYGZdq{}}
\end{BVerbatim}
).
-
+
\subsection{Registers}\label{sec:registers}
Every quantum circuit is structured by means of \emph{registers}.
A register has a \emph{type} that specifies how its wire is drawn, and that may even change during its lifetime.
@@ -389,62 +433,63 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
However, it can also be directly declared, which on rare occasions might be necessary (its type can then be changed by means of an \gate{init} or \gate{setwire} pseudo\hyp gate).
If you want to declare a register only at a certain horizontal position in the circuit, consider using the \texttt{after} argument instead.
\end{enumerate}
-
+
Registers must be declared before they can be used (though in the \tex!yquant*! environment, this declaration may be implicit, creating a \gate{qubit} register).
-
+
Registers can have a vector character, i.e., not only a \emph{name}, but also an \emph{index} (or, in the declaration, a \emph{length}).
The index (zero\hyp based) or length is specified in square brackets following the name, which closely mimics the OpenQASM language.
-
- Since version 0.1.1, vector registers may be non\hyp contiguous: Whenever you create a bunch of registers, it is put at the bottom of the circuit.
+
+ \compat{New in 0.1.1}Vector registers may be non\hyp contiguous: Whenever you create a bunch of registers, it is put at the bottom of the circuit.
If you later on again create registers of the same name---either implicitly in the \tex!yquant*! environment, or explicitly by preceding the length of the vectors entries to be added by a plus, as in \yquant!qubit a[+3];!---they will be put to what is \emph{now} the bottom of the circuit, even if some other registers are interspersed.
-
+
Registers are referenced---i.e., used in operations---by their name and index.
If the latter is omitted, all indices of the register are targeted.
Multiple registers can be referenced by joining their names in a comma\hyp separated list, or by means of a range specifier: give the name of the first (topmost), a dash, and the last (bottom\hyp most) register.
Both are inclusive.
In a range specifier, omitting the start name means that the range begins at the first known register; omitting the end name means that the range ends at the last known (at the moment of its use) register.
Omitting both indicates a range over all known registers.
-
- Since version 0.1.1, it is also possible to use comma\hyp separated lists and ranges within the indices themselves, so that, e.g., \yquant!a[0, 2, 5-], b[-2]! will target the zeroth and second index of \yquant!a!; the remaining indices of \yquant!a! starting from five; and the first three indices of \yquant!b!.
+
+ \compat{New in 0.1.1}It is also possible to use comma\hyp separated lists and ranges within the indices themselves, so that, e.g., \yquant!a[0, 2, 5-], b[-2]! will target the zeroth and second index of \yquant!a!; the remaining indices of \yquant!a! starting from five; and the first three indices of \yquant!b!.
However, if you use an \emph{outer} range (i.e., a range between indices of registers with different names), the initial and final register of the range must be unique, i.e., either you omit the index (targeting the first or last register with the given name) or specify a single one.
-
+
\begin{warning}[Ranges and discontiguous registers]
Assume a configuration in which the vector register \yquant!a! begins with one qubit, then the single register \yquant!b! follows, and after that \yquant!a! is continued with another qubit.
-
+
The range \yquant!a-b! will target \yquant!a[0]! and \yquant!b[0]!, but not \yquant!a[1]!.
As \yquant!a! is used as the initial register in the range without an explicit index specification, \Yquant{} automatically translates this into \yquant!a[0]!, while \yquant!b!, being used as the final register, is automatically translated into the last register of name \yquant!b! (which here happens to be \yquant!b[0]!).
Ranges between different register names (outer ranges) are \emph{visual} ranges, i.e., they refer to the top\hyp to\hyp bottom order that is visible.
Consequently, the register \yquant!a[1]! is left out since it is visually below the others.
-
+
Likewise, the range \yquant!b-a! will target \yquant!b[0]! and \yquant!a[1]!.
-
+
Ranges within indices are \emph{logical} ranges.
Hence, \yquant!a!, \yquant!a[-]!, \yquant!a[0-]!, \yquant!a[-1]!, and \yquant!a[0-1]! are all equivalent: they all refer to the registers \yquant!a[0]! and \yquant!a[1]!, but never to \yquant!b!, regardless of any visual position.
\end{warning}
-
+
All that was said so far refers to the operation being carried out on each of the registers \emph{individually}, i.e., producing several copies of the operation.
- This is different from using the operation multiple times on the individual single registers only with regard to the vertical positioning: if specified as a register list with one operation, all copies of the operation will be aligned at the same vertical position (as if an \gate{align} command had been carried out before).
+ This is different from using the operation multiple times on the individual single registers only with regard to the horizontal positioning: if specified as a register list with one operation, all copies of the operation will be aligned at the same horizontal middle axis (for gates with the same width on each register, this is the same as issuing an \gate{align} command before performing the operations individually).
\begin{warning}
- It is forbidden (in the sense of ``not useful,'' but \Yquant{} does not check for this) to list the same register multiple times (explicitly or via ranges) in one operation.
+ It is forbidden (in the sense of ``not useful and giving unexpected output,'' but \Yquant{} does not check for this) to list the same register multiple times (explicitly or via ranges) in one operation.
\end{warning}
-
+
Instead of copies of single\hyp register operations, one might want to carry out a multi\hyp register operation.
In this case, the desired list of registers (comma separated, range, or both) must be surrounded by parentheses.
It is possible to mix single- and multi\hyp register operations arbitrarily.
In an index list, you may also choose to surround only certain indices with parenthesis, provided the whole register is not already a multi\hyp register.
\begin{warning}
Note that some gates, such as the \gate{swap} gate, always require (semantically, not grammatically) multi\hyp register operations.
- Since version 0.1.2, the number of constituents is no longer fixed; while a \gate{swap} gate with more than two targets is no longer well\hyp defined, other registers such as \gate{zz} may still be useful.
+ \compat{Changed in 0.1.2}The number of constituents is not stipulated; while a \gate{swap} gate with more than two targets is no longer well\hyp defined, other registers such as \gate{zz} may still be useful.
\Yquant{} will prevent you from using a gate in a multi\hyp qubit setting when it may only be used for single registers.
\end{warning}
Typically, multi\hyp register operations should only be carried out on adjacent registers---but sometimes, one might want to carry out a multi\hyp qubit operation on a visually discontiguous set of registers (which, due to a particular quantum computer topology, might even be physically feasible).
- Since version 0.1.2, \Yquant{} supports these discontiguous operations explicitly (before, a single gate was drawn with all intermediate non\hyp affected register lines laying on top).
+ \compat{New in 0.1.2}\Yquant{} supports these discontiguous operations explicitly.
It will draw a \emph{main} part of the gate at the first contiguous slice of registers in the target list---you may select another register for this part by preceding the name or index with a star (which, contrary to the simplified grammar, may only occur \emph{once} in a target specification).
All other contiguous slices of target registers will be drawn in a \emph{subordinate style} for this gate.
Finally, all slices will be connected by a single vertical line with the style \style{/yquant/every multi line}.
- Subcircuits, supported as of version~0.2, will always span the full region from the first to the last register specified in a multi\hyp qubit gate.
- This is due to the fact that they may contain arbitrary ancilla registers which may be positioned somewhere in between the parts that actually constitute the subcircuit---so this whole region must not have wires of other registers crossing.
- \begin{warning}[Discontiguous targets and control lines]
+ \compat{New in 0.2}Subcircuits will always span the full region from the first to the last register specified in a multi\hyp qubit gate.
+ This is due to the fact that they may contain arbitrary ancilla registers which may be positioned somewhere in between the parts that actually constitute the subcircuit---surrounding this with a scattered set of connected boxes would look quite unpleasant.
+ \clearpage
+ \begin{warning}[\compat{Improved in 0.1.2}Discontiguous targets and control lines]
A control line extends from the very first to the very last affected register in an operation.
A sub\hyp gate line that is used for discontiguous registers will only span the range of a multi\hyp register.
This distinction becomes crucial if you want to carry out a \emph{controlled} operation on more than one multi\hyp register, where at least one is discontiguous.
@@ -456,44 +501,43 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
\begin{warning}
There is no established style for discontiguous gates.
Note that at the moment, main and subordinate style coincide for all gates except for the \gate{measure} gate with a value.
- In order to still make it possible to visually distinguish discontiguous multi\hyp register gates operating on slices of a single register from just a bunch of single\hyp register gates that are executed in a parallel manner, if controls are present, \Yquant's default vertical line style for the former case is a wavy line instead of a straight one.
+ In order to still make it possible to visually distinguish discontiguous multi\hyp register gates operating on slices of a single register from just a bunch of single\hyp register gates that are executed in a parallel manner if controls are present, \Yquant's default vertical line style for the former case is a wavy line instead of a straight one.
Still, the meaning of this should probably be explained.
Please feel free to submit issues or pull requests with propositions of how default styles or alternative subordinate gate shapes may additionally help to mitigate the problem.
\end{warning}
-
+
\subsection{Arguments}
Every command may take one or multiple arguments.
Those are specified in square brackets that precede the command itself.
The content of those square brackets is essentially fed to a \tex!\pgfkeys!-like macro.
- The default path is set appropriately such that the arguments of the command can be accessed without and path specifiers.
+ The default path is set appropriately such that the arguments of the command can be accessed without path specifiers.
If the key is not a valid argument for the command or a global argument and it is not given by an absolute path, it is searched for in the \texttt{/yquant} namespace.
If it cannot be found there, it is passed to \style{/yquant/operator style}.
-
+
Note that commands may have required arguments.
If a required argument is missing, an error will be issued.
-
+
The \texttt{value} attribute can alternatively be given inside curly brackets after the command name and before the register specification.
This has the advantage that special characters such as a closing square bracket need not be escaped.
If both alternatives are present, the value inside curly brackets takes precedence and a warning is issued.
-
+
\subsection{Controls}
Lots of gates may have controls, i.e., they are only to be executed if some other gate is set or unset.
The former case is called a \emph{positive control}, the latter one a \emph{negative control}.
Those are indicated by filled and empty circles on the control registers and a vertical line that joins the registers that belong together.
-
+
The gate specification is followed by the list of target registers.
By then writing a pipe (``\yquant!|!''), the list of positive controls is introduced; this mimics the mathematical syntax ``conditioned on'' for probabilities or ``given'' for sets.
If there are no positive controls, the list may be empty or, together with the pipe, omitted.
Preceded by a tilde (``\yquant!~!''), the list of negative controls then follows; this mimics the syntax of many programming languages that denote logical negation by a tilde.
- If there are no negative controls, the list may be empty or, together with the pipe, omitted.
-
- \clearpage
- \subsection{Importing circuits from files}\label{sec:import}
- Since version~0.2, \Yquant{} provides a simple way to import circuits that are stored in external files.
+ If there are no negative controls, the list may be empty or, together with the tilde, omitted.
+
+ \subsection[Importing circuit from files]{\compat{New in 0.2}Importing circuits from files}\label{sec:import}
+ \Yquant{} provides a simple way to import circuits that are stored in external files.
The macro \tex!\yquantimport! can be used in three different contexts:
\begin{itemize}
\item Outside of a \TikZ{} picture environment. \\
- In this case, \tex!\yquantimport[<options>]{<filename>}! will be equivalent to
+ Here, \tex!\yquantimport[<options>]{<filename>}! will be equivalent to
\begin{minted}{tex}
\begin{tikzpicture}
\begin{yquant}[<options>]
@@ -513,30 +557,31 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
\end{itemize}
Note that \Yquant{} internally uses plain \TeX's \tex!\import! command (i.e., \tex!\@@import! in \LaTeX).
However, when the \pkg{import} package is loaded, it uses \\ \tex!\subimport{\yquantimportpath}{<filename>}!, where \tex!\yquantimportpath! defaults to \texttt{./}---so by changing this, files from other folders may be imported which by themselves again include other files, and the relative path resolution will work.
-
+
Note that you may in particular import the content of a \gate{subcircuit}.
-
+
\subsection{Defining own gates}
\begin{warning}[Scope]
All gate declarations are always global.
\end{warning}
-
- Since version~0.2.1, if you want to define a gate that corresponds to a single \gate{box} gate with a certain pre\hyp defined content, you may use the macro\\
+
+ \compat{New in 0.2.1}If you want to define a gate that corresponds to a single \gate{box} gate with a certain pre\hyp defined content, you may use the macro\\
\tex!\yquantdefinebox{<name>}[<style>]{<content>}!, which is far more efficient than the much more general \tex!\yquantdefinegate! introduced below.
- It works in the following way:
+ It only allows for single\hyp register usage; use \compat{New in 0.4}\tex!\yquantdefinemultibox! with the same arguments if you want to allow the gate to be used in a multi\hyp register gate fashion.
+ The macros work in the following way:
\begin{itemize}
- \item It creates a new gate with name \texttt{<name>} that can be accessed as all the other build\hyp in gates.
+ \item They create a new gate with name \texttt{<name>} that can be accessed as all the other build\hyp in gates.
Note that \texttt{<name>} is case\hyp insensitive and may not contain spaces.
Special characters are allowed if \TeX{} can cope with them (i.e., no comment signs, no unbalanced braces, no backslashes...).
- \item It creates a style \style{/yquant/operators/every <name>} and assigns the optional \texttt{<style>} to it.
+ \item They create a style \style{/yquant/operators/every <name>} and assign the optional \texttt{<style>} to it.
If no style is provided, the default style will inherit from \style{/yquant/operators/every box}.
- \item It defines \texttt{<content>} to be the value that is written into the box.
+ \item They define \texttt{<content>} to be the value that is written into the box.
This \texttt{<content>} is expanded in a protected manner at the time of gate declaration.
You may need to prefix fragile macros by \tex!\protect!.
\end{itemize}
-
- Sometimes, you may wish to define gates that are more than just a single box---perhaps a succession of multiple gates or even multi\hyp register gates with individual operations on the input registers. \\
- Since version~0.2, \Yquant{} provides a simple macro that allows this.
+
+ \compat{New in 0.2}Sometimes, you may wish to define gates that are more than just a single box---perhaps a succession of multiple gates or even multi\hyp register gates with individual operations on the input registers.
+ \Yquant{} provides a simple macro that allows this.
The macro \tex!\yquantdefinegate{<name>}[<style>]{<content>}! works in the following way:
\begin{itemize}
\item It creates a new gate with name \texttt{<name>} that can be accessed as all the other built\hyp in gates.
@@ -558,310 +603,394 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
\end{enumerate}
Gates defined in this way can only make use of the default gates or other custom gates.
They do not accept custom arguments, and it is not possible to declare own, custom shapes in this way (though other predefined shapes may be used).
- If they are used in a multi\hyp qubit manner, they will never be split into contiguous slices (but their content will be, so if you use the default style that turns off the box, the only way to notice this is that intermediate unaffected gates will not be allowed to place gates within the custom gate).
-
+ If they are used in a multi\hyp qubit manner, they will never be split into contiguous slices (but their content will be, so if you use the default style that turns off the box, the only way to notice this is that intermediate unaffected registers will not be allowed to have gates visually within the rectangle that would bound the custom gate).
+
\begin{warning}[Redefining existing gates]
The above macros will issue an error if the gate already exists.
- You can use \tex!\yquantredefinebox! or \tex!\yquantredefinegate! to overwrite existing gate definitions.
+ You can use \tex!\yquantredefinebox!, \tex!\yquantredefinemultibox! (use the appropriate command for the \emph{new} definition), or \tex!\yquantredefinegate! to overwrite existing gate definitions.
Note that this will overwrite \emph{any} gate, even the built\hyp in ones.
-
+
Generally, it is discouraged to make use of this possibility.
For custom gates, if you redefine a gate as a box which was previously a general subcircuit\hyp based gate, the macro that contains the subcircuit will still be held in memory.
Overwriting built\hyp in gates will not clear the attributes associated to this gate (though required attributes will no longer be required afterwards).
Again, this is not a problem but prevents \Yquant{} from issuing potentially helpful error message if such a---now meaningless---attribute is used.
-
+
Finally, once a built\hyp in gate is overwritten, it cannot be restored.
In particular, the register creation pseudo\hyp gates \gate{qubit}, \gate{cbit}, \gate{qubits}, and \gate{nobit} perform some magic that cannot be mimicked with custom gates.
\end{warning}
-
+
More advanced declaration of custom gates requires the use of backend macros.
Refer to \texttt{yquant-lang.tex} for this.
+ Note that the backend interface changed in version~0.4.
For the declaration of custom shapes, see \texttt{yquant-shapes.tex} for examples.
-
+
\section{Configuration}\label{sec:config}
\Yquant{} uses \pkg{pgfkeys} to control its options, which are located in the path \texttt{/yquant}.
The following list contains all options and styles that are recognized, apart from gate arguments.
Those are listed together with their operations.
-
+
\subsection{Circuit layout}\unskipOpt
- \begin{option}{register/minimum height}!3mm!
- \Yquant{} automatically determines the total height of a register as the height of the largest operation.
+ \begin{option}[Changed in 0.4]{register/minimum height}!1.5mm!
+ \Yquant{} automatically determines the height (extent from wire to top boundary) of a register as the height of the largest operation.
This might be too small for two reasons:
\begin{itemize}
\item if the register is used only with small gates (e.g., only as a control, or as a swap), and it does not have a label (or one containing only x\hyp height letters).
- \item if the register is used only with multi\hyp qubit gates.
- For those, \Yquant{} cannot decide where to put the height---and it is easy to see that an equal distribution over all affected registers is not necessarily a good solution.
- Hence, multi\hyp qubit gates are ignored in the height calculation.
- Usually, this is not a problem since those operations are large enough as they take the height of all involved registers and separations.
+ \item if you manually turned off height calculation or multi\hyp extent calculation for a large gate.
+ \Yquant{} will then not consider the vertical extent of this gate, which might consequently lead to undesirable overlaps.
\end{itemize}
This key provides an easy alleviation of the problem by requiring a minimal height for every register.
+ As the value of this key is relevant at the time of register declaration, it can also be changed for each register individually.
+
+ Note that this key is affected by the \texttt{compat} setting.
+ Before version \texttt{0.4}, there was no \style{/yquant/register/minimum depth} key.
+ In this compatibility setting, passing the value $x$ to this key will set both height and depth to $\frac x2$.
+ The default for $x$ is then \texttt{3mm}.
\end{option}
-
+
+ \begin{option}[New in 0.4]{register/minimum depth}!1.5mm!
+ \emph{see} \style{/yquant/register/minimum height}
+
+ This key allows to specify a minimum depth (extent from wire to bottom boundary) for a register.
+
+ Note that this key is affected by the \texttt{compat} setting.
+ Before version \texttt{0.4}, this key will not be available.
+ \end{option}
+
\begin{option}{register/separation}!1mm!
This key controls the amount of vertical space that is inserted between two successive registers.
Half of this value is also the length that multi\hyp\gate{init} or multi\hyp\gate{output} braces extend beyond the mid position of the register.
\end{option}
-
+
\begin{option}{operator/minimum width}!3mm!
\Yquant{} automatically determines the width of an operator according to its content.
However, single\hyp letter boxes are among the most common operators, and giving them slightly different widths would result in a very uneven spacing, as \Yquant{} does not use a grid layout but stacks the operators horizontally one after each other.
Hence, this key provides a minimum width that will be set for every operator.
This does not imply that the \emph{visual} appearance (i.e., the \texttt{x radius} key) is enlarged, but that operators of a smaller actual width will be centered in a virtual box of the minimum width.
\end{option}
-
+
\begin{option}{operator/separation}!1mm!
- This key controls the amount of horizontal space that is inserted between two successive operators.
+ This key controls the amount of horizontal space that is inserted between two successive operators and at the beginning and end of a circuit.
\end{option}
-
- \begin{option}{operator/multi warning}!true!
- If this key is \texttt{true}, a warning is displayed whenever more than a single multi\hyp register gate, where at least one is discontiguous, are employed together with controls.
+
+ \begin{option}[New in 0.1.2]{operator/multi warning}!true!
+ If this key is \texttt{true}, a warning is displayed whenever more than a single multi\hyp register gate, where at least one is discontiguous, is employed together with controls.
Even if a visual distinction between control and multi\hyp qubit line may be possible (depending on the style in use), they will overlap and produce unaesthetic output.
You may disable this warning globally, on a per\hyp circuit, or even on a per\hyp gate basis.
\end{option}
-
+
\subsection{Register creation}\unskipOpt
\begin{option}{register/default name}!\regidx!
The printed name that is used by default if a new register is created explicitly (\gate{qubit}, \gate{cbit}, \gate{qubits}; not used for \gate{nobit} or for implicit declarations) and no value is specified.
The following macros are available:
\begin{itemize}
- \item \tex!\reg! contains the internal name that is used to identify this register.
+ \item \tex!\reg! contains your name to identify this register.
\item \tex!\idx! contains the index (zero\hyp based) of the current register within a vector register.
\item \tex!\regidx! expands to \tex!\reg! if the register is of length one, and to \tex!\reg[\idx]! else.
\item \tex!\len! contains the length of the current register vector.
\end{itemize}
\end{option}
-
- \begin{option}{every label}!shape=yquant-text, anchor=center, align=right!
+
+ \begin{option}[Changed in 0.4]{every label}!shape=yquant-init, anchor=center, align=right, outer xsep=2pt, /yquant/operator/if multi={draw, decoration={gapped brace, mirror, raise=2pt}, decorate}!
This style is installed for every single register name label (i.e., upon creation and when used with the \gate{init} gate).
The default style allows to use line breaks in the labels.
+ The node shape, \texttt{yquant-init}, will generate a path at its right side, which is replaced by the \texttt{gapped brace} decoration if the gate is used in a multi\hyp register fashion.
+ The decoration is similar to \TikZ's \texttt{brace} decoration, but additionally allows specify the regions in which a line should be drawn by using the \texttt{/tikz/decoration/from to} key, which expects a comma\hyp separated list of dimension ranges, and which is automatically populated by \Yquant.
+
+ Note that if the \texttt{compat} key is below \texttt{0.3}, the multi options are instead read from \style{/yquant/every multi label}.
\end{option}
-
+
\begin{option}{every initial label}!anchor=east!
This style is installed for every single register name label at the left border of the circuit.
- Hence, it is only used for the \gate{init} gate if in the \tex!yquant*! environment, the gate occurs for a new register (which allows to override the default register type).
+ \compat{Changed in 0.4}It is therefore used if a label is specified upon declaration and also for the \gate{init} gate if it happens to be the first gate on an unlabelled register (use a zero\hyp width \gate{hspace} gate before if you want to suppress this).
\end{option}
-
+
\begin{option}{every qubit label}!!
This style is installed for every single register name label of a register of type \gate{qubit}.
\end{option}
-
+
\begin{option}{every cbit label}!!
This style is installed for every single register name label of a register of type \gate{cbit}.
\end{option}
-
+
\begin{option}{every qubits label}!!
This style is installed for every single register name label of a register of type \gate{qubits}.
\end{option}
-
- \begin{option}{every multi label}!shift={(-.075, 0)}, draw, decoration={gapped brace, mirror}, decorate, /yquant/gapped brace/apply shift, every node/.append style={shape=yquant-text, anchor=east, align=right, shift={(-.05, 0)}, pos=-1}!
+
+ \begin{option}[Removed in 0.4\\Changed in 0.1.2]{every multi label}!draw, decoration={gapped brace, mirror, raise=2pt}, decorate!
This style is installed for every register name label that is attached to a multi\hyp qubit register by means of the \gate{init} gate.
- \Yquant{} additionally inserts a straight line that connects the topmost and the bottom\hyp most register at their left ends.
- The default style turns this line into a brace and places the description at the appropriate position.
- The decoration \texttt{gapped brace} allows to additionally specify the regions in which a line should be drawn by using the \texttt{/tikz/decoration/from to} key, which expects a comma\hyp separated list of dimension ranges, and which is automatically populated by \Yquant.
- Since it may happen that the arch of the brace needs to be shifted from the value specified in \texttt{/tikz/decoration/aspect} (else, it would be drawn into a gap), the special key \texttt{/yquant/gapped brace/apply shift} is installed, which transforms the \texttt{pos=-1} specification into a position that corresponds to the actual \texttt{aspect} value.
+
+ Note that this key is only available if the \texttt{compat} setting is smaller than \texttt{0.4}.
+ In newer versions, this is incorporated in \style{/yquant/every label}.
\end{option}
-
- \begin{option}{every input label}!!
+
+ \begin{option}[Removed in 0.4\\New in 0.2]{every input label}!!
This style is installed for every register name label in a \gate{subcircuit} when the register is an input (or input and output) register.
+
+ Note that this key is only available if the \texttt{compat} setting is smaller than \texttt{0.4}; and in this case, it behaves inconsistently, as it is only applied for labels directly specified during creation, but not for initial \gate{init} gates.
\end{option}
-
+
\subsection{Register outputs}\unskipOpt
- \begin{option}{every output}!shape=yquant-text, anchor=west, align=left!
+ \begin{option}[Changed in 0.4]{every output}!shape=yquant-output, anchor=west, align=left, outer xsep=2pt, /yquant/operator/if multi={draw, decoration={gapped brace, raise=2pt}, decorate}!
This style is installed for every \gate{output} label at the end of the circuit.
The default style allows to use line breaks in the labels.
+
+ The node shape, \texttt{yquant-output}, will generate a path at its left side, which is replaced by the \texttt{gapped brace} decoration in the case of multi\hyp register usage.
+ See \style{/yquant/every label} for a more detailed explanation.
\end{option}
-
+
\begin{option}{every qubit output}!!
This style is installed for every \gate{output} label of a register of type \gate{qubit}.
\end{option}
-
+
\begin{option}{every cbit output}!!
This style is installed for every \gate{output} label of a register of type \gate{cbit}.
\end{option}
-
+
\begin{option}{every qubits output}!!
This style is installed for every \gate{output} label of a register of type \gate{qubits}.
\end{option}
-
- \begin{option}{every multi output}!shift={(.075, 0)}, draw, decoration={gapped brace}, decorate, /yquant/gapped brace/apply shift, every node/.append style={shape=yquant-text, anchor=west, align=left, shift={(.05, 0)}, pos=-1}!
+
+ \begin{option}[Removed in 0.4\\Changed in 0.1.2]{every multi output}!draw, decoration={gapped brace, raise=2pt}, decorate!
This style is installed for every \gate{output} label that is attached to a multi\hyp qubit register.
- \Yquant{} additionally inserts a straight line that connects the topmost and the bottom\hyp most register at their right ends.
- The default style turns this line into a brace and places the description at the appropriate position.
- See \style{/yquant/every multi label} for a more detailed explanation.
+
+ Note that this key is only available if the \texttt{compat} setting is smaller than \texttt{0.4}.
+ In newer versions, this is incorporated into \style{/yquant/every output}.
\end{option}
-
+
\subsection{General styling}\unskipOpt
- \begin{option}{every circuit}!every node/.prefix style={transform shape}, every label/.prefix style={transform shape=false}!
+ \begin{option}[Changed in 0.4, 0.1.2]{every circuit}!every node/.prefix style={transform shape}!
Style that is installed for every \tex!yquant! and \tex!yquant*! environment, as if it had been given as an option.
- Since version 0.1.2, the style's default path is, as with all other styles, \texttt{/tikz}.
+ The style's default path is, as with all other styles, \texttt{/tikz}.
+ The style is re\hyp applied for every subcircuit.
The default style will make all nodes (which in particular means, all gates) respect outer canvas transformations.
- Due to \TikZ{} bug \href{https://github.com/pgf-tikz/pgf/issues/843}{\#843}, this must be undone for \texttt{label}s.
- % TODO Note that unless you use a very recent version of \TikZ{} in which bug \href{https://github.com/pgf-tikz/pgf/issues/843}{\#843} was fixed, you might need to add \tex!every label/.prefix style={transform shape=false}! to this style, which undoes the effect for \texttt{label}s.
+
+ If your \TikZ{} version is before 3.1.6a, this style will additionally contain \tex!every label/.prefix style={transform shape=false}!, which undoes the effect for \texttt{label}s (see \TikZ{} bug \href{https://github.com/pgf-tikz/pgf/issues/843}{\#843}).
+ An update is recommended.
\end{option}
-
+
\begin{option}{every wire}!draw!
This style is installed whenever a wire is drawn.
\end{option}
-
+
\begin{option}{every qubit wire}!!
This style is installed whenever a wire for a register of type \gate{qubit} is drawn.
\end{option}
-
+
\begin{option}{every cbit wire}!!
This style is installed whenever a wire for a register of type \gate{cbit} is drawn.
\end{option}
-
+
\begin{option}{every qubits wire}!!
This style is installed whenever a wire for a register of type \gate{qubits} is drawn.
\end{option}
-
+
\begin{option}{every control line}!draw!
This style is used to draw the vertical control line that connects controlled operations and their controls.
\end{option}
-
+
\begin{option}{every control}!shape=yquant-circle, anchor=center, radius=.5mm!
This style is used to draw the node for a control, both positive and negative.
\end{option}
-
+
\begin{option}{every positive control}!fill=black!
This style is installed for every positive control (i.e., one that conditions on the register being in state $\ket1$ or $1$).
\end{option}
-
+
\begin{option}{every negative control}!draw!
This style is installed for every negative control (i.e., one that conditions on the register being in state $\ket0$ or $0$).
\end{option}
-
+
\begin{option}{every operator}!anchor=center!
This style is installed for every gate (and also pseudo\hyp gates such as the \gate{slash} operator) that acts on one or multiple registers.
\end{option}
-
- \begin{option}{every multi line}!draw, decoration={snake, amplitude=.25mm, segment length=5pt}, decorate!
+
+ \begin{option}[New in 0.1.2]{every multi line}!draw, decoration={snake, amplitude=.25mm, segment length=5pt}, decorate!
This style is used to draw the vertical line that connects discontiguous slices of sub\hyp gates.
\end{option}
-
+
\begin{option}{this operator}!!
This style is appended to the current style installed for an operator; it should be used only locally to overwrite any global configuration effect.
\end{option}
-
+
\begin{option}{this control}!!
This style is appended to the current style installed for a control; it should be used only locally to overwrite any global configuration effect.
\end{option}
-
+
\begin{option}{operator style}!/yquant/this operator/.append style={#1}!
This is a shorthand that can be used to modify the appearance of the current operator.
\end{option}
-
+
\begin{option}{control style}!/yquant/every control line/.append style={#1}, /yquant/this control/.append style={#1}!
This is a shorthand that can be used to modify the appearance of the current control and its associated line.
\end{option}
-
+
\begin{option}{style}!/yquant/operator style={#1}, /yquant/control style={#1}!
This is a shorthand that modifies the appearance of both the current operator and any controls or control lines.
\end{option}
-
- \begin{option}{operator/multi as single}!/yquant/every multi line/.style=/yquant/every control line!
- This option is automatically set for certain gates such as the \gate{swap} or the \gate{zz} gate.
+
+ \begin{option}[New in 0.1.2]{operator/multi as single}!/yquant/every multi line/.style=/yquant/every control line!
+ This style is automatically set for certain gates such as the \gate{swap} or the \gate{zz} gate.
For those gates, neighboring registers will be treated as discontiguous; and this style will enforce their connecting line to have the style used by control lines.
-
+
The default \style{/yquant/every multi line} is a wavy line; this allows to distinguish discontiguous multi\hyp qubit gates from multiple single\hyp qubit gates when using controls.
Still, some gates have such an established appearance that---despite being logically misleading---we rather use the same style as for a control line.
\end{option}
-
+
+ \begin{option}[New in 0.4]{operator/if multi}!!
+ This style can be invoked by other styles with an arguments that contains styles to be executed only if the current gate is used in a multi\hyp register fashion.
+ See \style{/yquant/every label} for an example.
+ \end{option}
+
+ \begin{option}[New in 0.4]{circuit/seamless}!false!
+ The value of this setting determines whether circuits drawn in a \Yquant{} environment in the current group will be drawn in a ``seamless'' state (hence, this style must be set \emph{before} the \Yquant{} environment is started).
+ The key \style{/yquant/operator/separation} will control the amount of padding with which a wire starts or ends before the first or after the last gate.
+ By turning on the seamless state, this padding is suppressed.
+ Using outputs or giving an initial value at the register declaration brings the corresponding padding back.
+ Usually, this setting is intended only for subcircuits.
+ Direct access is discouraged, as it will persist in subcircuits.
+ Only access it via \style{/yquant/operators/subcircuit/seamless}.
+ \end{option}
+
+ \begin{option}[New in 0.4]{every post measurement control}!indirect!
+ This style determines the default arrangement of measurements that are followed by positive controls.
+
+ The default option \texttt{indirect} will draw the measurement at the position where it is specified.
+ Any later use of a control will be at the position of the controlled gate.
+
+ The option \texttt{direct} will defer the measurement.
+ If later on, a controlled operation is used where the positive controls contain all of the targets of this measurement \emph{and} no other gate was executed meanwhile on any of the targets of this measurement, then the measurement gate will replace the corresponding positive control knobs (and might inherit \TikZ{} options of the embedding gate); otherwise, it will behave as if the \texttt{indirect} option had been specified.
+
+ Some care must be taken when gates are named that are affected by this option.
+ If the embedding gate is named, the positive controls that will be replaced by measurements are no longer available with the ``\texttt{p}''~suffix (but other positive controls will still be numbered as if all were).
+ Attach the name to the measurement in order to access it as if it were an ordinary gate; however, note that the name only becomes available after the later embedding gate was called.
+
+ Note that this setting affects all measurements that have a compatible shape; currently, this is only \gate{measure}.
+ While there is no technical difficulty in implementing the same behavior for \gate{dmeter}, its particular shape does not really suggest this use.
+ However, if you desire to do so, please file a feature request.
+ \end{option}
+
\subsection{Styles for operators}\unskipOpt
- \begin{option}{operators/every barrier}!shape=yquant-line, dashed, draw!
+ \begin{option}[Changed in 0.4]{operators/every barrier}!shape=yquant-line, dashed, draw, shorten <= -1mm, shorten >= -1mm!
This style is installed for every \gate{barrier} pseudo\hyp gate, i.e., the one that is used to explicitly denote a separation between ``before'' and ``after'' within the circuit.
+
+ Note that the \texttt{shorten} keys are only present in the default style if you specify at least the compatibility version \texttt{0.4}.
\end{option}
-
+
\begin{option}{operators/every box}!shape=yquant-rectangle, draw, align=center, inner xsep=1mm, x radius=2mm, y radius=2.47mm!
This style is installed for every \gate{box} operator.
\end{option}
-
- \begin{option}{operators/every custom gate}!/yquant/operators/this subcircuit box/.append style={draw=none, inner sep=0pt}, /yquant/register/default name=!
- This style is by default installed for every user\hyp defined gate (since version~0.2).
+
+ \begin{option}[Changed in 0.4\\New in 0.2]{operators/every custom gate}!/yquant/operators/subcircuit/seamless!
+ This style is by default installed for every user\hyp defined gate.
User\hyp defined gates are implemented via subcircuits; this style suppresses the box that surrounds the subcircuit and by default suppresses all register names.
This allows a seamless integration of the gate/subcircuit into the main circuit, without putting particular emphasis to the fact that what was defined as the custom gate indeed belongs together.
+ Note that with the \texttt{compat} key set before \texttt{0.4}, this style instead defaults to \tex!/yquant/operators/subcircuit/frameless, /yquant/register/default name=!.
\end{option}
-
+
\begin{option}{operators/every dmeter}!shape=yquant-dmeter, x radius=2mm, y radius=2mm, fill=white, draw!
This style is installed for every \gate{dmeter} gate.
The \texttt{yquant-dmeter} shape consists of a rectangle whose right side is replaced by a circle, resembling the letter ``D.''
\end{option}
-
+
\begin{option}{operators/every h}!/yquant/operators/every box!
This style is installed for every \gate{h} (Hadamard) operator.
\end{option}
-
+
+ \begin{option}{operators/every inspect}!shape=yquant-output, align=left, outer xsep=.3333em, y radius=2.47mm, /yquant/operator/if multi={draw, decoration={gapped brace, raise=2pt}, decorate}!
+ This style is installed for every \gate{inspect} gate.
+ It does not have any shape on its own, apart from multi\hyp register uses, in which it will contain a brace on its left.
+ \end{option}
+
\begin{option}{operators/every measure}!shape=yquant-measure, x radius=4mm, y radius=2.5mm, draw!
This style is installed for every \gate{measure} gate.
The \texttt{yquant-measure} shape is a rectangle that contains a ``meter'' symbol.
It allows for a text to be put inside (e.g., a basis), which then shifts the meter symbol accordingly.
\end{option}
-
+
\begin{option}{operators/every measure meter}!draw, -{Latex[length=2.5pt]}!
This style is applied to the path that resembles the ``meter'' symbol that is drawn by the \texttt{yquant-measure} shape.
Due to the default style, the \TikZ{} library \pkg{arrows.meta} is automatically loaded with \Yquant.
\end{option}
-
+
\begin{option}{operators/every not}!shape=yquant-oplus, radius=1.3mm, draw!
This style is installed for every \gate{not} or \gate{cnot} gate (which are synonyms, and actually do the same as the Pauli~$\sigma_x$ gate).
The \texttt{yquant-oplus} shape resembles the addition\hyp modulo\hyp two symbol $\oplus$.
\end{option}
-
+
\begin{option}{operators/every pauli}!/yquant/operators/every box!
This style is installed for every Pauli operator, i.e., \gate{x}, \gate{y}, and \gate{z}.
\end{option}
-
+
\begin{option}{operators/every phase}!shape=yquant-circle, radius=.5mm, fill!
This style is installed for every \gate{phase} gate $\ketbra00 + \ee^{\ii\phi} \ketbra11$.
\end{option}
-
+
\begin{option}{operators/every slash}!shape=yquant-slash, x radius=.5mm, y radius=.7mm, draw!
This style is installed for every \gate{slash} pseudo\hyp gate, i.e., the one that is used to indicate that a single register line actually denotes multiple registers.
\end{option}
-
- \begin{option}{operators/every subcircuit}!!
+
+ \begin{option}[New in 0.2]{operators/every subcircuit}!!
This style is installed for every \gate{subcircuit}.
+ Note that all styles given here will also apply to every element in the subcircuit; in a way, this is an addition to \style{/yquant/every circuit} (which is also again put into effect at the beginning of a subcircuit).
\end{option}
-
- \begin{option}{operators/every subcircuit box}!/yquant/operators/every box!
+
+ \begin{option}[New in 0.2]{operators/every subcircuit box}!/yquant/operators/every box!
This style is installed for every \gate{subcircuit}.
Note that in contrast to all other styles such as \style{/yquant/operators/every subcircuit} or \style{/yquant/this operator}, this style is only applied to the ``container'' node of the subcircuit, but not to the elements in the subcircuit themselves.
+ Also note that the box style by default contains an \texttt{inner xsep} that will be added as an inside padding.
+ This makes sense if your wires have labels so that these labels don't move too closely to the border of the box.
+ However, if you do not labelled wires but still want to have a box around the subcircuit, you should consider removing the separation---as it will be added to the initial wire padding given by \style{/yquant/operator/separation}.
\end{option}
-
- \begin{option}{subcircuit box style}!/yquant/operators/every subcircuit box/.append style={#1}!
- This is a shorthand to apply styles to the subcircuit box only.
+
+ \begin{option}[New in 0.2]{subcircuit box style}!/yquant/operators/every subcircuit box/.append style={#1}!
+ This is a shorthand to append styles to the subcircuit box only.
\end{option}
-
- \begin{option}{operators/this subcircuit box}!!
+
+ \begin{option}[New in 0.2]{operators/this subcircuit box}!!
This style is appended to the current style installed for the \gate{subcircuit}, but will not apply to its contents.
Additionally, this style will be reset to an empty style at the beginning of each subcircuit, so that it really only applies to exactly the subcircuit box it is explicitly specified on, not to nested subcircuit boxes.
\end{option}
-
- \begin{option}{this subcircuit box style}!/yquant/operators/this subcircuit box/.append style={#1}!
- This is a shorthand to apply styles to the current subcircuit box only.
+
+ \begin{option}[New in 0.2]{this subcircuit box style}!/yquant/operators/this subcircuit box/.append style={#1}!
+ This is a shorthand to append styles to the current subcircuit box only.
+ \end{option}
+
+ \begin{option}[New in 0.4]{operators/subcircuit/frameless}!/yquant/operators/this subcircuit box/.append style={draw=none, inner sep=0pt}!
+ This is a shorthand style that removes the frame and additional inner separation for the current subcircuit.
+ Note that still, the wire padding given by \style{/yquant/operator/separation} is present within the---now invisible---outer box that contains the subcircuit (use \style{/yquant/operators/subcircuit/seamless} to suppress it).
+ Hence, the most prominent application of this key is if the wires before and after the subcircuit are \gate{nobit}s, which provides a clean way to build up circuit equations with perfectly aligned wires (examples can be found in \cref{sec:examples}).
+ \end{option}
+
+ \begin{option}[New in 0.4]{operators/subcircuit/seamless}!/yquant/operators/subcircuit/frameless, /yquant/register/default name=, /yquant/circuit/seamless!
+ This option carries out multiple actions that are responsible to let the current subcircuit appear in a ``seamless'' state:
+ \begin{itemize}
+ \item It calls \style{/yquant/operators/subcircuit/frameless}.
+ \item It sets \style{/yquant/circuit/seamless} to \texttt{true}.
+ \item It ensures that \style{/yquant/circuit/seamless} is reset within the subcircuit, so that it does not propagate to nested subcircuits.
+ \end{itemize}
\end{option}
-
+
\begin{option}{operators/every swap}!shape=yquant-swap, radius=.75mm, draw!
This style is installed for every \gate{swap} gate that interchanges two qubits.
The \texttt{yquant-swap} shape consists of a single cross.
\end{option}
-
- \begin{option}{operators/every wave}!shape=yquant-circle, radius=.5mm, fill!
+
+ \begin{option}[New in 0.1.2]{operators/every wave}!shape=yquant-circle, radius=.5mm, fill!
This style is installed for every \gate{correlate} gate.
\end{option}
-
+
\begin{option}{operators/every x}!/yquant/operators/every pauli!
This style is installed for every Pauli operator $\sigma_x$, i.e., \gate{x}.
\end{option}
-
+
\begin{option}{operators/every xx}!shape=yquant-rectangle, radius=.75mm, draw!
This style is installed for every \gate{xx} gate in symmetrized notation ($\ketbra{++}{++} + \ketbra{+-}{+-} + \ketbra{-+}{-+} - \ketbra{--}{--}$).
\end{option}
-
+
\begin{option}{operators/every y}!/yquant/operators/every pauli!
This style is installed for every Pauli operator $\sigma_y$, i.e., \gate{y}.
\end{option}
-
+
\begin{option}{operators/every z}!/yquant/operators/every pauli!
This style is installed for every Pauli operator $\sigma_z$, i.e., \gate{z}.
\end{option}
@@ -869,139 +998,183 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
\begin{option}{operators/every zz}!shape=yquant-circle, radius=.5mm, fill!
This style is installed for every \gate{zz} gate (aka \textsc{CPhase}) in symmetrized notation ($\ketbra{00}{00} + \ketbra{01}{01} + \ketbra{10}{10} - \ketbra{11}{11}$).
\end{option}
-
+
\section{Doing the impossible}\label{sec:tikz}
\Yquant{} will almost certainly never be able to do everything an author has in mind.
Sometimes, there is the need to draw something non\hyp standard, and this cannot be implemented in the \Yquant{} language.
However, since \Yquant{} is a layer on top of \TikZ, it should be very hard to find something (meaningful) that cannot be done by combining the power of both packages.
-
- Before or after any gate, you may interrupt the \Yquant{} instructions to perform arbitrary \TikZ{} path operations.
- After every such operation, \Yquant{} will automatically restart its parser so that you can fluently jump between \Yquant{} and \TikZ{} code.
- You can even interject arbitrary \TeX{} code (or, say, low\hyp level \pkg{pgf} commands); however, then, \Yquant{} is not able to restart its parser.
- For this reason, after the last command in a block of \TeX{} commands, you must issue \tex!\yquant!, which then re\hyp enables the \Yquant{} language.
-
- The feature to perform arbitrary \TikZ{} operations is powerful in itself, but would be of limited use were there no way to access the elements in the quantum circuit.
- \Yquant{} provides a global attribute \texttt{name} that can be assigned to every gate.
- All quantum operations are in fact \TikZ{} nodes, and the name you give to them then becomes a \TikZ{} name, which you can easily reference to get the coordinates of a particular operator.
- Note that the name you specify is only available if a single register is targeted.
- The name is suffixed by \tex!-\idx!, where \tex!\idx! refers to the (zero\hyp based) index of the operation ordered from top to bottom (i.e., if an operator acts on two qubits and should be named \texttt{op}, the topmost operator will be available as \texttt{op-0} and the second as \texttt{op-1}).
- Multiple slices in a discontiguous multi\hyp register are additionally suffixed by \texttt{-s\textit{<slice index>}}.
- All controls are also named, suffixed by \tex!-p\idx! or \tex!-n\idx! for positive and negative controls (i.e., the topmost positive control of the previous operator will be available as \texttt{op-p0}).
- Counters for target registers, positive, and negative controls are all independent.
- Finally, you can even access names within a subcircuit, provided you give a name to the subcircuit.
- All nodes in the subcircuit will then have the name \texttt{\textit{<subcircuit name>}-\textit{<name specified in the subcircuits>}}.
- For nested subcircuits, you will get multiple prefixes.
-
- All \Yquant{} shapes have the anchors available you would typically expect from a \TikZ{} shape of the given outline.
- Before version~0.1.2, \Yquant{} shapes needed to provide a \texttt{circuit} anchor and projection anchors.
- These were removed in version~0.1.2 in favor of the common \texttt{center} anchor and clipping paths.
- The latter is a \Yquant{} extension to \TikZ{} shapes: it is an additional path that must be declared for a given shape.
- This path has to provide the ``clipping outline,'' i.e., anything that should not contain register or control lines.
- There may be a difference between horizontal and vertical clipping outlines.
- To understand clipping paths, \Yquant's drawing pipeline needs to be explained.
- \begin{itemize}
- \item In a first run---this is what happens directly at the position where you type the gate command---\Yquant{} will ``virtually'' draw the gates in order to determine their dimensions and calculate register heights.
- The actual drawing commands are written to a macro (this is the cause that some macros must be preceded by \tex!\protect! if used in a gate \texttt{value}).
- \item When \tex!\end{yquant}! is encountered, the actual drawing commands are executed.
- \item Unless the operation changes the wire type or style, do the following (first two items for every register at which an operator node has to be created).
- \begin{itemize}
- \item Create the operator node at the appropriate position.
- \item Call \tex!\pgfshapeclippath! on the newly created node.
- This will first determine whether the node was stroked; if not, \tex!\pgflinewidth! is set to zero.
- Then, it will call the horizontal clipping path, which is supposed to create some soft path commands.
- Those soft path commands are collected in a macro on a per\hyp register basis and the soft path is cleared.
- The same happens for the vertical clipping path, which is collected in a macro on a per\hyp operation basis.
- \item If control lines or multi lines are to be drawn, the vertical clipping path commands are now executed and installed as an inverted\footnote{Inverting the clipping has two consequences: First, the region of inversion in vertical direction is given by the width of the operators. The line cannot be wider than the operator. Second, if you specify a register multiple times, whether as target, control, or mixed, funny effects can be expected, as the clipping region is inverted multiple times. Note that using a register more than once is always an error, but \Yquant{} does not check for it due to the high overhead.} clipping path.
- \item Control lines and multi lines are drawn (in this order) from one to the next \texttt{center} anchor.
- Due to the clipping commands, this will create a perfect connection with the shape of the gate, but even transparent gates are possible without the lines being visible.
- \end{itemize}
- \item If the operation changes the wire type or style, or if there is no operation left on this register, the following is done.
- \begin{itemize}
- \item Load the clipping paths accumulated for all the gates acting on this register and install the inverted clipping.
- \item Draw the wire as one continuous line from where the last wire ended (or the beginning of the circuit) to the center of the last gate, or to the common end position for all wires of the circuit.
- \item Remove the clipping paths stored so far on this register, apart from the clipping on the last gate (which will be needed again if this was not the end of the circuit).
- \end{itemize}
- \end{itemize}
-
+
+ \subsection{Mixing \texorpdfstring{\Yquant}{yquant} and \texorpdfstring{\TikZ}{TikZ} code}
+ Before or after any gate, you may interrupt the \Yquant{} instructions to perform arbitrary \TikZ{} path operations.
+ After every such operation, \Yquant{} will automatically restart its parser so that you can fluently jump between \Yquant{} and \TikZ{} code.
+ You can even interject arbitrary \TeX{} code (or, say, low\hyp level \pkg{pgf} commands); however, then, \Yquant{} is not able to restart its parser.
+ For this reason, after the last command in a block of \TeX{} commands, you must issue \tex!\yquant!, which then re\hyp enables the \Yquant{} language.
+
+ \subsection{Accessing gates in \texorpdfstring{\TikZ}{TikZ}}
+ The feature to perform arbitrary \TikZ{} operations is powerful in itself, but would be of limited use were there no way to access the elements in the quantum circuit.
+ \Yquant{} provides a global attribute \texttt{name} that can be assigned to every gate.
+ All quantum operations are in fact \TikZ{} nodes, and the name you give to them then becomes a \TikZ{} name, which you can easily reference to get the coordinates of a particular operator.
+ Note that the name you specify is only available if a single register is targeted.
+ The name is suffixed by \tex!-\idx!, where \tex!\idx! refers to the (zero\hyp based) index of the operation ordered from top to bottom (i.e., if an operator acts on two qubits and should be named \texttt{op}, the topmost operator will be available as \texttt{op-0} and the second as \texttt{op-1}).
+ Multiple slices in a discontiguous multi\hyp register are additionally suffixed by \texttt{-s\textit{<slice index>}}.
+ All controls are also named, suffixed by \tex!-p\idx! or \tex!-n\idx! for positive and negative controls (i.e., the topmost positive control of the previous operator will be available as \texttt{op-p0}).
+ Counters for target registers, positive, and negative controls are all independent.
+ Finally, you can even access names within a subcircuit, provided you give a name to the subcircuit.
+ All nodes in the subcircuit will then have the name \texttt{\textit{<subcircuit name>}-\textit{<name specified in the subcircuits>}}.
+ For nested subcircuits, you will get multiple prefixes.
+
+ \subsection{Shapes and the drawing pipeline}
+ All \Yquant{} shapes have the anchors available you would typically expect from a \TikZ{} shape of the given outline.
+ The \texttt{center} anchor will be aligned to the wire.
+ \compat{Changed in 0.1.2}In addition to the normal paths implemented by \TikZ{} shapes, those fit for \Yquant{} must additionally implement clipping paths, a \Yquant{} addition to \TikZ{} shapes.
+ Such a path has to provide the ``clipping outline,'' i.e., anything that should not contain register or control lines.
+ There may be a difference between horizontal and vertical clipping outlines.
+ To understand clipping paths, \Yquant's drawing pipeline needs to be explained.
+ \begin{itemize}
+ \item In a first run---this is what happens directly at the position where you type the gate command---\Yquant{} will ``virtually'' draw the gates in order to determine their dimensions and calculate register heights.
+ The actual drawing commands are written to a macro (this is the cause that some macros must be preceded by \tex!\protect! if used in a gate \texttt{value}---in fact, if multiple registers are targeted in one gate, the style and values required for this gate are only stored once, so that for example \tex!\idx! is a \tex!\protected! macro until the very end).
+ \item \compat{New in 0.4}Deferred gates (measurements that may replace future control knobs) are stored temporarily and queried when the next gate is executed or at the end of the circuit.
+ The corresponding commands---either re\hyp inserting if they must appear at their original position or substituting the controls---are inserted appropriately.
+ \item When \tex!\end{yquant}! is encountered, the vertical positions are determined and the actual drawing commands are executed.
+ \item Unless the operation changes the wire type or style, do the following (first two items for every register at which an operator node has to be created).
+ \begin{itemize}
+ \item Create the operator node at the appropriate position.
+ \item Call \tex!\pgfshapeclippath! on the newly created node.
+ This will first determine whether the node was stroked; if not, \tex!\pgflinewidth! is set to zero.
+ Then, it will call the horizontal clipping path, which is supposed to create some soft path commands.
+ Those soft path commands are collected in a macro on a per\hyp register basis and the soft path is cleared.
+ The same happens for the vertical clipping path, which is collected in a macro on a per\hyp operation basis.
+ \item If control lines or multi lines are to be drawn, the vertical clipping path commands are now executed and installed as an inverted\footnote{Inverting the clipping means that instead of drawing only \emph{within} the clipping path (which corresponds to the gates), we only draw \emph{outside}. However, as there is no direct support for this, we invert by exploiting the even\hyp odd rule. If you specify a register multiple times, whether as target, control, or mixed, funny effects can be expected, as the clipping region is inverted multiple times. Note that using a register more than once is always an error, but \Yquant{} does not check for it due to the high overhead.} clipping.
+ \item Control lines and multi lines are drawn (in this order) from one to the next \texttt{center} anchor.
+ Due to the clipping commands, this will create a perfect connection with the shape of the gate, but even transparent gates are possible without the lines being visible.
+ \end{itemize}
+ \item If the operation changes the wire type or style, or if there is no operation left on this register, the following is done.
+ \begin{itemize}
+ \item Load the clipping paths accumulated for all the gates acting on this register and install the inverted clipping.
+ \item Draw the wire as one continuous line from where the last wire ended (or the beginning of the circuit) to the center of the last gate, or to the common end position for all wires of the circuit.
+ \item Remove the clipping paths stored so far on this register, apart from the clipping on the last gate (which will be needed again if this was not the end of the circuit).
+ \end{itemize}
+ \end{itemize}
+
+ \subsection{Overwriting the height and depth calculation}
+ \Yquant{} automatically takes care of calculating the height and depth of all registers, so that their final vertical positions are chosen without overlap.
+ This is almost always advisable, but it has some weaknesses:
+ \begin{itemize}
+ \item If you specify a multi\hyp register gate, say, extending for three registers and this requires a certain height and depth, where should this be accounted for?
+ \compat{New in 0.4}\Yquant{} is able to handle these situations by first determining all heights and depths that can safely be attributed to individual registers.
+ After that, it checks for all multi\hyp register gates: Is the space from the top of the first to the bottom of the last register enough to hold the multi\hyp qubit gate?
+ If not, it evenly distributes the additional required space to all registers that are visually within the range of this multi\hyp register.
+
+ This will fail to produce good results (hopefully) only in two cases:
+ \begin{itemize}
+ \item If you place \texttt{label}s on the gate, those are outside of the gate---and typically, either below or above.
+ Hence, the additional extent stemming from them should \emph{not} be equally distributed among all registers, but either to the height of the first or the depth of the last one.
+ Currently, \Yquant{} is unable to detect this (and, considering the fact that you can place \texttt{label}s at any angle, this is not an easy problem to solve except for special cases).
+ \item If you make use of a discontiguous \gate{init} gate with a large vertical extent, \Yquant{} will correctly allocate space as if the gate's content were placed in the vertical center.
+ However, if there is no way to put the arch of the brace at the middle, as the register at this position is excluded from the gate, the content will be shifted---but only after calculating the extent.
+ Hence, the automatically calculated vertical positions will be unsuitable.
+ \end{itemize}
+ \item Sometimes, there is more space available than \Yquant{} thinks because you already discarded some wire.
+ \Yquant{} does not keep track of whether the wires below or above a gate are actually visible at this position---which is not even be known at the time the gate command is issued, as horizontal positions are determined only in the drawing stage.
+ Hence, you may choose to draw ``within'' the other, invisible wire.
+ \end{itemize}
+
+ \compat{New in 0.4}In these certain special cases, you may want to turn off the automatic calculation for one particular gate.
+ Note that you may then, depending on the situation, obtain results with overlapping gates.
+ You can use the keys \style{/yquant/register/minimum height} and \style{/yquant/register/minimum depth} when declaring the relevant register to manually specify a larger desired value, but you have to experiment with regard to what this value is.
+
+ The global attribute \texttt{overlay} (conveniently overshadowing \TikZ's \texttt{overlay} key, which should not be used for gates) can take the values
+ \begin{itemize}
+ \item \texttt{true} (default if no value given, combines \texttt{multi}, \texttt{height}, and \texttt{depth}),
+ \item \texttt{multi} (short \texttt{m}),
+ \item \texttt{height} (short \texttt{ht}, \texttt{h}),
+ \item \texttt{depth} (short \texttt{dp}, \texttt{d}),
+ \item \texttt{single} (short \texttt{s}, combines \texttt{height} and \texttt{depth}), and
+ \item \texttt{false} (useless, default if attribute not given).
+ \end{itemize}
+ It disables the calculation of the selected vertical extent for this particular gate.
+ (In fact, \texttt{multi}, \texttt{height}, \texttt{depth}, and \texttt{single} are subkeys that accept boolean values.)
+
\section{Reference: Gates and operations}\label{sec:gates}
This section lists all operations \Yquant{} currently understands.
- It also details all arguments that can be given to customize the operation, apart from \texttt{name}, which is always available.
+ It also details all arguments that can be given to customize the operation, apart from \texttt{name} and \compat{New in 0.4}\texttt{overlay}, which are always available.
Note that the \tex![value=<value>]! attribute can (and should) alternatively be given as a braced expression that follows the name of the register.
-
- \subsection{\texorpdfstring{\yquant!addstyle!}{addstyle}}\label{gate:addstyle}
+
+ \subsection[\texorpdfstring{\yquant!addstyle!}{addstyle}]{\compat{New in 0.1.2}\yquant!addstyle!}\label{gate:addstyle}
Syntax: \yquant!setstyle <target>;! \\
This is an invisible pseudo\hyp gate that immediately changes the \TikZ{} style with which the register lines of all target registers are drawn.
It adds to the styles that are already installed.
Use \gate{setstyle} to replace styles.
It may not span multiple registers and does not allow for controls.
-
+
\emph{Possible attributes:}
\begin{itemize}
\item \yquant![value=<styles>]! (required) \\
Denotes the new styles; this should be a string that could be passed to \tex!\tikzset!.
\end{itemize}
-
+
\subsection{\texorpdfstring{\yquant!align!}{align}}\label{gate:align}
Syntax: \yquant!align <target>;! \\
This is an invisible pseudo\hyp gate that enforces all affected registers to share a common horizontal position for their next gate, which is determined by the largest position of all gates involved.
It may not span multiple registers and does not allow for controls.
-
+ \compat{Changed in 0.4}The gate now always aligns the wires, i.e., if they are discarded directly after this gate, they will still discarded all at the same position.
+
\emph{Possible attributes:} none
-
+
\subsection{\texorpdfstring{\yquant!barrier!}{barrier}}\label{gate:barrier}
Syntax: \yquant!barrier <target>;! \\
This is a pseudo\hyp gate that denotes some physical barrier that ensures execution with a specific timing; it is basically a visible version of the \hyperref[gate:align]{\yquant!align!} gate, denoted by a vertical line.
It may span multiple registers, but does not allow for controls.
The style \style{/yquant/operators/every barrier} is installed.
-
+
\emph{Possible attributes:} none
-
+
\subsection{\texorpdfstring{\yquant!box!}{box}}\label{gate:box}
Syntax: \yquant!box <target> | <pcontrol> ~ <ncontrol>;! \\
This is a generic register of a rectangular shape that can be filled with arbitrary content.
It may span multiple registers and allows for controls.
The style \style{/yquant/operators/every box} is installed.
-
+
\emph{Possible attributes:}
\begin{itemize}
\item \yquant![value=<value>]! \\
Denotes the content of the box.
\end{itemize}
-
+
\subsection{\texorpdfstring{\yquant!cbit!}{cbit}}\label{gate:cbit}
Syntax: \yquant!cbit <name>[<len>];! \\
Declares a register of type \texttt{cbit}.
-
+
\emph{see \hyperref[gate:qubit]{\yquant!qubit!}}
-
- \subsection{\texorpdfstring{\yquant!correlate!}{correlate}}\label{gate:correlate}
+
+ \subsection[\texorpdfstring{\yquant!correlate!}{correlate}]{\compat{New in 0.1.2}\yquant!correlate!}\label{gate:correlate}
Syntax: \yquant!correlate <target>;! \\
This is a pseudo\hyp gate that indicates a correlation (usually a Bell\hyp state) present between the multi\hyp registers involved.
This gate should span multiple registers and does not allow for controls.
-
+
\emph{Possible attributes:} none
-
+
\subsection{\texorpdfstring{\yquant!cnot!}{cnot}}\label{gate:cnot}
Syntax: \yquant!cnot <target> | <pcontrol> ~ <ncontrol>;! \\
This is a synonym for the \gate{not} gate.
Note that despite its name, controls are not mandatory and also here, the style \style{/yquant/operators/every not} is installed.
-
+
\subsection{\texorpdfstring{\yquant!discard!}{discard}}\label{gate:discard}
Syntax: \yquant!discard <target>;! \\
This is an invisible pseudo\hyp gate that changes the type of all target registers to \gate{nobit}, i.e., no line will be drawn for them.
- This has effect already for the outgoing line of the last visible gate on the target registers.
+ This has effect already for the outgoing line of the last gate on the target registers.
The gate may not span multiple registers and does not allow for controls.
- To change into a register type on\hyp the\hyp fly into something different from \gate{nobit}, use the \gate{settype} pseudo\hyp gate.
-
+ To change a register type on\hyp the\hyp fly into something different from \gate{nobit}, use the \compat{Changed in 0.1.2}\gate{settype} pseudo\hyp gate.
+
\emph{Possible attributes:} none
-
+
\subsection{\texorpdfstring{\yquant!dmeter!}{dmeter}}\label{gate:dmeter}
Syntax: \yquant!dmeter <target>;! \\
This is a measurement gate, denoted by a ``D'' shape.
It changes the type of all targets involved.
It may span multiple registers, but does not allow for controls.
The style \style{/yquant/operators/every dmeter} is installed.
-
+
\emph{Possible attributes:}
\begin{itemize}
\item \yquant![value=<value>]! \\
@@ -1011,35 +1184,35 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
Allows to specify the type into which the affected targets are converted.
Default is \gate{cbit}.
\end{itemize}
-
+
\subsection{\texorpdfstring{\yquant!h!}{h}}\label{gate:h}
Syntax: \yquant!h <target> | <pcontrol> ~ <ncontrol>;! \\
- This is a Hadamard gate, $\frac{1}{\sqrt2} \bigl( \ketbra00 + \ketbra01 + \ketbra10 - \ketbra11 \bigr)$, denoted by a rectangle that contains the letter $H$.
+ This is a Hadamard gate, $\bigl( \ketbra00 + \ketbra01 + \ketbra10 - \ketbra11 \bigr) \fracslash \sqrt2$, denoted by a rectangle that contains the letter $H$.
It may not span multiple registers, but allows for controls. \\
The style \style{/yquant/operators/every h} is installed.
-
+
\emph{Possible attributes:} none
-
+
\subsection{\texorpdfstring{\yquant!hspace!}{hspace}}\label{gate:hspace}
Syntax: \yquant!hspace <target>;! \\
This is an invisible pseudo\hyp gate that inserts a certain amount of white space into all target registers.
It may not span multiple registers and does not allow for controls.
-
+ \compat{Changed in 0.4}The gate now always has an effect, e.g., if the wire is discarded after this gate, it will still be extended by the given amount first.
+
\emph{Possible attributes}:
\begin{itemize}
\item \yquant![value=<dim>]! (required) \\
- Gives the amount of white space that is to be inserted. Must be a valid \TeX{} dimension.
+ Gives the amount of white space that is to be inserted. Must be a valid (nonnegative) \TeX{} dimension.
\end{itemize}
-
- \subsection{\texorpdfstring{\yquant!init!}{init}}\label{gate:init}
+
+ \subsection[\texorpdfstring{\yquant!init!}{init}]{\compat{Changed in 0.4}\yquant!init!}\label{gate:init}
Syntax: \yquant!init <target>;! \\
This is a pseudo\hyp gate that (re)initializes a registers to a given state.
It may span multiple registers, but does not allow for controls.
The style \style{/yquant/every label} is installed.
- Note that this pseudo\hyp gate, unlike all others, behaves differently if it the first operation acting on a register: in this case, it does not increment the horizontal position, but uses the space available to the left.
- If it is the first operation, the style \style{/yquant/every initial label} is installed additionally.
- For multiple registers, the style \style{/yquant/every multi label} is installed at the end, and a path is constructed that extends from the left end of the first to the left end of the last register in the multi\hyp register compound.
-
+ Note that this pseudo\hyp gate, unlike all others, behaves differently if it is the first operation acting on a register: in this case, it does not increment the horizontal position, but uses the space available to the left; and the style \style{/yquant/every initial label} is installed additionally.
+ Internally, creating a new register with some printed name is translated into the creation of an unnamed register, followed by application of this gate with the desired text.
+
\emph{Possible attributes:}
\begin{itemize}
\item \yquant![type=<qubit|cbit|qubits>]! \\
@@ -1048,17 +1221,32 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
The style \texttt{/yquant/every <type> label} is installed additionally.
\item \yquant![value=<value>]! (required) \\
Denotes the label that is printed to the left of the wire.
-
+
+ Inside the value, \tex!\idx! expands to the current index within the register list.
+ \end{itemize}
+
+ \subsection[\texorpdfstring{\yquant!inspect!}{inspect}]{\compat{New in 0.4}\yquant!inspect!}\label{gate:inspect}
+ Syntax: \yquant!inspect <target>;! \\
+ This is a pseudo\hyp gate that allows to print the current state of one or multiple registers within a circuit.
+ It may span multiple registers, but does not allow for controls.
+ The style \style{/yquant/every inspect} is installed.
+ Essentially, it is the same as an \gate{output} gate that will be drawn immediately at the current position and not deferred until the end.
+
+ \emph{Possible attributes:}
+ \begin{itemize}
+ \item \yquant![value=<value>]! (required) \\
+ Denotes the text that is to be printed.
Inside the value, \tex!\idx! expands to the current index within the register list.
\end{itemize}
-
- \subsection{\texorpdfstring{\yquant!measure!}{measure}}\label{gate:measure}
+
+ \subsection[\texorpdfstring{\yquant!measure!}{measure}]{\compat{Changed in 0.4}\yquant!measure!}\label{gate:measure}
Syntax: \yquant!measure <target>;! \\
This is a measurement gate, denoted by a rectangle with a meter symbol.
It changes the type of all targets involved.
It may span multiple registers, but does not allow for controls.
The style \style{/yquant/operators/every measure} is installed.
-
+ It may be deferred to be used instead of a control knob for a later gate using the \style{/yquant/every post measurement control} style or the suitable attributes; see the documentation for this style.
+
\emph{Possible attributes:}
\begin{itemize}
\item \yquant![type=<qubit|cbit|qubits>]! \\
@@ -1067,52 +1255,54 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
\item \yquant![value=<value>]! \\
Allows to specify a text that will be included at the bottom of the rectangle (which will shift the meter symbol upwards accordingly).
For outside texts, use \TikZ{} \texttt{label}s instead.
+ \item \yquant![direct control]! \\
+ Temporarily sets \style{/yquant/every post measurement control}\tex!=direct! for this particular gate.
+ \item \yquant![indirect control]! \\
+ Temporarily sets \style{/yquant/every post measurement control}\tex!=indirect! for this particular gate.
\end{itemize}
-
+
\subsection{\texorpdfstring{\yquant!nobit!}{nobit}}\label{gate:nobit}
Syntax: \yquant!nobit <name>[<len>];! \\
Declares a register of type \gate{nobit}.
- The \texttt{<name>} must be a self\hyp chosen name for the register which was not previously used as a register name in this \tex!yquant! environment.
+ The \texttt{<name>} must be a self\hyp chosen name for the register which was not previously used as a register name in this circuit (but names can be re\hyp used in subcircuits).
Names are case\hyp insensitive.
The register can be made into a vector register by specifying \texttt{<len>} (default \tex!1!).
-
- \clearpage
+
\emph{Possible attributes:}
\begin{itemize}
- \item \yquant![out]! or \yquant![ancilla]! (required in subcircuits) \\
+ \item \compat{New in 0.2}\yquant![out]! or \yquant![ancilla]! (required in subcircuits) \\
\emph{see \gate{qubit}}
\end{itemize}
-
+
\subsection{\texorpdfstring{\yquant!not!}{not}}\label{gate:not}
Syntax: \yquant!not <target> | <pcontrol> ~ <ncontrol>;! \\
This is a \textsc{not} gate, $\ketbra01 + \ketbra10$, denoted by the $\oplus$ symbol.
It may not span multiple registers, but allows for controls.
Due to its common usage, the synonymous gate \hyperref[gate:cnot]{\yquant!cnot!} is provided.
The style \style{/yquant/operators/every not} is installed.
-
+
\emph{Possible attributes:} none
-
- \subsection{\texorpdfstring{\yquant!output!}{output}}\label{gate:output}
+
+ \subsection[\texorpdfstring{\yquant!output!}{output}]{\compat{Changed in 0.4}\yquant!output!}\label{gate:output}
Syntax: \yquant!output <target>;! \\
This is a pseudo\hyp gate that allows to write some text at the very end of the register line.
It may only be specified once per register.
It may span multiple registers, but does not allow for controls.
The style \style{/yquant/every output} is installed, and also the style \texttt{/yquant/every <type> output}, where \texttt{<type>} is the type of the affected register (at the time of printout).
- For outputs on multiple registers, the style \style{/yquant/every multi output} is installed instead of the two previously mentioned ones; and additionally, a path is constructed that extends from the first to the last register in the multi\hyp register compound.
-
+
\emph{Possible attributes:}
\begin{itemize}
\item \yquant![value=<value>]! (required) \\
Denotes the text that is to be printed.
Inside the value, \tex!\idx! expands to the current index within the register list.
\end{itemize}
-
+
\subsection{\texorpdfstring{\yquant!phase!}{phase}}\label{gate:phase}
Syntax: \yquant!phase <name> | <pcontrol> ~ <ncontrol>;! \\
This is a phase gate, $\ketbra00 + \ee^{\ii\phi} \ketbra11$, denoted by a filled circle.
- It may not span multiple registers, but allows for controls (and should have them, to make any sense).
+ It may not span multiple registers, but allows for controls.
The style \style{/yquant/operators/every phase} is installed.
-
+
\emph{Possible attributes:}
\begin{itemize}
\item \yquant![value=<value>]! (required) \\
@@ -1120,98 +1310,104 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
Position and appearance can be influenced by setting the position of \TikZ{} labels, as this is internally used.
Note that at the moment, it is not possible to change any label options on a gate\hyp type basis, only locally or fully globally (\TikZ{} feature request \href{https://github.com/pgf-tikz/pgf/issues/811}{\#811}).
\end{itemize}
-
+
\subsection{\texorpdfstring{\yquant!qubit!}{qubit}}\label{gate:qubit}
Syntax: \yquant!qubit <name>[<len>];! \\
Declares a register of type \texttt{qubit}.
- The \texttt{<name>} must be a self\hyp chosen name for the register which was not previously used as a register name in this \tex!yquant! environment.
+ The \texttt{<name>} must be a self\hyp chosen name for the register which was not previously used as a register name in this circuit (but names can be re\hyp used in subcircuits).
Names are case\hyp insensitive.
The register can be made into a vector register by specifying \texttt{<len>} (default \tex!1!).
-
+
\emph{Possible attributes:}
\begin{itemize}
\item \yquant![after=<regname>]! \\
If given, the register will start not at the left of the circuit but instead at the position at which the last gate in the register \texttt{<regname>} ended.
-
+
This attribute may not be given in combination with \yquant![in]! or \yquant![inout]!.
- \item \yquant![in]!, \yquant![out]!, \yquant![inout]!, or \yquant![ancilla]! \\
+ \item \compat{New in 0.2}\yquant![in]!, \yquant![out]!, \yquant![inout]!, or \yquant![ancilla]! \\
Default: \yquant![ancilla]! for top\hyp level circuits (do not change there); \yquant![inout]! for subcircuits.
-
+
Determines how a subcircuit interacts with its parent circuit.
-
+
Registers declared with the \yquant![ancilla]! attribute are available only to the subcircuit; they cannot be connected to an outside wire.
-
+
Registers declared with the \yquant![in]! or \yquant![inout]! attribute will expect an outer wire of the same type to be present and will then be identical with this outer wire.
Any changes applied to the wire within the subcircuit automatically also happen on the associated outer wire.
If the attribute is \yquant![in]!, the wire will automatically be discarded at the end of the subcircuit (and hence also in the outer circuit, where it may be re\hyp initialized).
This is different from applying the \gate{discard} gate in that the wire will still extend until the end of the subcircuit and may thus receive proper \gate{output}s.
-
+
Registers declared with the \yquant![out]! attribute will expect a discarded outer wire to be present, which will be initialized to a \texttt{qubit} at the beginning of the subcircuit, and from then on be identical with the outer wire.
\item \yquant![value=<value>]! \\
Denotes the label that is printed to the left of the wire.
If the value is omitted, the default is used (\style{/yquant/register/default name}, preinitialized to \tex!\regidx!).
-
+
Inside the value, \tex!\reg! expands to \texttt{<name>}, \tex!\len! expands to \texttt{<len>}, \tex!\idx! expands to the current index within the vector register ($0 \leq \text{\tex!\idx!} < \text{\texttt{<len>}}$), and \tex!\regidx! expands to \tex!\reg! if \texttt{<len>} is one, or to \tex!\reg[\idx]! else.
\end{itemize}
-
+
\subsection{\texorpdfstring{\yquant!qubits!}{qubits}}\label{gate:qubits}
Syntax: \yquant!qubits <name>[<len>];! \\
Declares a register of type \texttt{qubits}.
-
+
\emph{see \hyperref[gate:qubit]{\yquant!qubit!}}
-
- \subsection{\texorpdfstring{\yquant!setstyle!}{setstyle}}\label{gate:setstyle}
+
+ \subsection[\texorpdfstring{\yquant!setstyle!}{setstyle}]{\compat{New in 0.1.2}\yquant!setstyle!}\label{gate:setstyle}
Syntax: \yquant!setstyle <target>;! \\
This is an invisible pseudo\hyp gate that immediately changes the \TikZ{} style with which the register lines of all target registers are drawn.
It replaces all previous styles.
Use \gate{addstyle} to accumulate styles.
It may not span multiple registers and does not allow for controls.
-
+
\emph{Possible attributes:}
\begin{itemize}
\item \yquant![value=<styles>]! (required) \\
Denotes the new styles; this should be a string that could be passed to \tex!\tikzset!.
\end{itemize}
-
- \subsection{\texorpdfstring{\yquant!settype!}{settype}}\label{gate:settype}
+
+ \subsection[\texorpdfstring{\yquant!settype!}{settype}]{\compat{New in 0.1.2}\yquant!settype!}\label{gate:settype}
Syntax: \yquant!settype <target>;! \\
This is an invisible pseudo\hyp gate that immediately changes the type of the targets registers, taking effect with the output line extending from the last drawn gate.
It may not span multiple registers and does not allow for controls.
-
+
\emph{Possible attributes:}
\begin{itemize}
\item \yquant![value=<qubit|cbit|qubits>]! (required) \\
Denotes the new type that is assigned to all registers.
To change the type to \gate{nobit}, use the \hyperref[gate:discard]{\yquant!discard!} pseudo\hyp gate instead.
\end{itemize}
-
- \subsection{\texorpdfstring{\yquant!setwire!}{setwire}}\label{gate:setwire}
- \emph{Deprecated as of version~0.1.2. Use \gate{settype} instead.}
-
+
+ \subsection[\texorpdfstring{\yquant!setwire!}{setwire}]{\compat{Removed in 0.4\\Deprecated in 0.1.2}\yquant!setwire!}\label{gate:setwire}
+ \emph{Use \gate{settype} instead.}
+
+ This gate is only available if a compatibility version before \texttt{0.4} is chosen.
+
\subsection{\texorpdfstring{\yquant!slash!}{slash}}\label{gate:slash}
Syntax: \yquant!slash <target>;! \\
This is a pseudo\hyp gate used to denote that a single line actually represents multiple registers.
It is drawn as a short slash through the line of the register.
Note that this gate, in contrast to all others, is positioned on the line extending from the last gate or the initialization line of the registers and does not advance the register's horizontal position.
The style \style{/yquant/operators/every slash} is installed.
-
+
\emph{Possible attributes:} none
-
- \subsection{\texorpdfstring{\yquant!subcircuit!}{subcircuit}}\label{gate:subcircuit}
+
+ \subsection[\texorpdfstring{\yquant!subcircuit!}{subcircuit}]{\compat{New in 0.2}\yquant!subcircuit!}\label{gate:subcircuit}
Syntax: \yquant!subcircuit <target>;! \\
This is a subcircuit gate which inserts independent quantum circuits at the current position within the circuit.
It may span multiple registers, but is never split into contiguous slices.
It allows for controls and may change the type of any target involved, depending on the particular subcircuit.
The style \style{/yquant/operators/every subcircuit} is installed.
-
+
\emph{Possible attributes:}
\begin{itemize}
+ \item \compat{New in 0.4}\yquant!frameless! \\
+ This \style{/yquant/operators/subcircuit/frameless} style is activated with this shorthand.
+ \item \compat{New in 0.4}\yquant!seamless! \\
+ The \style{/yquant/operators/subcircuit/seamless} style is activated with this shorthand (implies \yquant!frameless!).
\item \yquant!value=<subcircuit>! (required) \\
Denotes the content of the subcircuit.
It is specified in the usual syntax of \Yquant.
Note that, regardless of the outer environment, a subcircuit always implicitly uses the unstarred form, i.e., you must declare every register explicitly before its first usage.
This is to make sure that the interface of the circuit, i.e., which registers are taken as input and/or output parameters and in which order, is not accidentally mistaken.
-
+
The mapping between input and output registers is trivial for single\hyp qubit uses.
For multi\hyp qubit uses, it works in the following way---in short, it matches in visual order.
You declare input and output registers by using the appropriate attributes on the \gate{qubit}, \gate{cbit}, \gate{qubits} (or even \gate{nobit}) gates.
@@ -1220,13 +1416,13 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
Also within the multi\hyp qubit target, we sort all registers from the topmost to the bottom\hyp most (in the order as they visually appear, not the order in which they are entered).
Those two lists of equal length are then mapped $1:1$ to each other.
Intermixing with ancillas is possible at every position and will lead to a vertical shift of the wires, until all registers, inner and outer, can be displayed flawlessly.
-
+
As subcircuits follow the same rules as ordinary circuits, it is possible to mix them with arbitrary \TeX{} code, and also to access named gates within the subcircuit---but note that named gates in the outer circuit cannot be accessed (at least unless you play with the \texttt{name prefix} key in \TikZ).
In order to access inner nodes from the outer circuit, the subcircuit itself must be named; the inner nodes are then prefixed by the name of the subcircuit and a dash.
-
+
It is possible to nest subcircuits arbitrarily.
\end{itemize}
-
+
\subsection{\texorpdfstring{\yquant!swap!}{swap}}\label{gate:swap}
Syntax: \yquant!swap <targets> | <pcontrol> ~ <ncontrol>;! \\
This is the two\hyp qubit \textsc{swap} gate $\ketbra{00}{00} + \ketbra{01}{10} + \ketbra{10}{01} + \ketbra{11}{11}$ that exchanges two qubits.
@@ -1236,59 +1432,59 @@ IndexSingle = ?number? | ( [ ?number? ], "-", [ ?number? ] );
The control line will extend from the first to the last of all registers involved in the operation, so that it is impossible to discern visually which registers should actually be swapped.
Using multiple swaps without controls in one operation is fine, as well as a single controlled swap.
The style \style{/yquant/operators/every swap} is installed.
-
+
\emph{Possible attributes:} none
-
+
\subsection{\texorpdfstring{\yquant!x!}{x}}\label{gate:x}
Syntax: \yquant!x <target> | <pcontrol> ~ <ncontrol>;! \\
This is a Pauli $\sigma_{\symup x}$ gate $\ketbra01 + \ketbra10$, denoted by a rectangle that contains the letter $X$.
It may not span multiple registers, but allows for controls. \\
The style \style{/yquant/operators/every x} is installed.
-
+
\emph{Possible attributes:} none
-
+
\subsection{\texorpdfstring{\yquant!xx!}{xx}}\label{gate:xx}
Syntax: \yquant!xx <targets>;! \\
This is a symmetric flip gate, denoted by joined open squares.
It should span multiple registers and it allows for controls.
The same warnings as for the \gate{swap} gate apply.
The style \style{/yquant/operators/every xx} is installed.
-
+
\emph{Possible attributes:} none
-
+
\subsection{\texorpdfstring{\yquant!y!}{y}}\label{gate:y}
Syntax: \yquant!y <target> | <pcontrol> ~ <ncontrol>;! \\
This is a Pauli $\sigma_{\symup y}$ gate $-\ii\ketbra01 + \ii\ketbra10$, denoted by a rectangle that contains the letter $Y$.
It may not span multiple registers, but allows for controls. \\
The style \style{/yquant/operators/every y} is installed.
-
+
\emph{Possible attributes:} none
-
+
\subsection{\texorpdfstring{\yquant!z!}{z}}\label{gate:z}
Syntax: \yquant!z <target> | <pcontrol> ~ <ncontrol>;! \\
This is a Pauli $\sigma_{\symup z}$ gate $\ketbra00 - \ketbra11$, denoted by a rectangle that contains the letter $Z$.
It may not span multiple registers, but allows for controls. \\
The style \style{/yquant/operators/every z} is installed.
-
+
\emph{Possible attributes:} none
-
+
\subsection{\texorpdfstring{\yquant!zz!}{zz}}\label{gate:zz}
Syntax: \yquant!zz <targets>;! \\
This is a symmetric phase gate, denoted by joined filled circles.
It should span multiple registers, but does not allow for controls.
The same warnings as for the \gate{swap} gate apply.
The style \style{/yquant/operators/every zz} is installed.
-
+
\emph{Possible attributes:} none
-
-
+
+
\section{Examples}\label{sec:examples}
This section will contain lots of examples.
On the left\hyp hand side, the output is given, while the code to construct the example is on the right.
All examples that are provided originate from the examples supplied with \pkg{qasm}, \pkg{qcircuit}, and \pkg{quantikz}.
We will essentially follow their manuals example\hyp by\hyp example, which gives a nice comparison in how to achieve the given feature using these packages and \Yquant{} instead.
- All examples of course require inclusion of the \Yquant{} package in the preamble, and some also require \pkg{braket}.
-
+ All examples of course require inclusion of the \Yquant{} package with newest compatibility in the preamble, and some also require \pkg{braket}.
+
\subsection{\pkg{qasm} documentation}
\begingroup%
\yquantset{register/default name=$\ket{\reg_{\idx}}$}%
@@ -1302,48 +1498,48 @@ qubit {$\ket{<name>_{\idx}}$} <name>[<len>];
\yquantset{register/default name=$\ket{\reg_{\idx}}$}
\end{minted}
in the preamble, as is done here.
-
- Note that since version~0.3, \Yquant{} supports the \pkg{qasm} syntax, see \cref{sec:foreign:qasm}
-
+
+ \compat{New in 0.3}Note that \Yquant{} also directly supports the \pkg{qasm} syntax, see \cref{sec:foreign:qasm}.
+
\begin{example}[test1 (create an EPR pair)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit q[2];
-
+
h q[0];
cnot q[1] | q[0];
\end{yquant}
\end{tikzpicture}
\end{codeexample}
\end{example}
-
+
\clearpage
- \begin{example}[test2 (simple teleportation circuit)]
+ \begin{example}<Updated in 0.1.1>[test2 (simple teleportation circuit)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit q[3];
-
+
h q[1];
cnot q[2] | q[1];
cnot q[1] | q[0];
h q[0];
measure q[0-1];
-
+
z q[2] | q[1];
x q[2] | q[0];
\end{yquant}
\end{tikzpicture}
\end{codeexample}
\end{example}
-
+
\begin{example}[test3 (swap circuit)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit q[2];
-
+
cnot q[1] | q[0];
cnot q[0] | q[1];
cnot q[1] | q[0];
@@ -1351,14 +1547,14 @@ qubit {$\ket{<name>_{\idx}}$} <name>[<len>];
\end{tikzpicture}
\end{codeexample}
\end{example}
-
+
\clearpage
- \begin{example}[test4 (quantum fourier transform on three qubits)]
+ \begin{example}<Updated in 0.1.1>[test4 (quantum fourier transform on three qubits)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit j[3];
-
+
h j[0];
box {$S$} j[0] | j[1];
box {$T$} j[0] | j[2];
@@ -1370,14 +1566,14 @@ qubit {$\ket{<name>_{\idx}}$} <name>[<len>];
\end{tikzpicture}
\end{codeexample}
\end{example}
-
+
\begin{example}[test5 (demonstrate arbitrary qubit matrix ops)]
\begin{codeexample}
% \usepackage{amsmath}
\begin{tikzpicture}
\begin{yquant}
qubit j[2];
-
+
box {$\begin{bmatrix}
e^{i \alpha} & 0 \\
0 & e^{-i \alpha}
@@ -1390,14 +1586,14 @@ qubit {$\ket{<name>_{\idx}}$} <name>[<len>];
\end{tikzpicture}
\end{codeexample}
\end{example}
-
+
\clearpage
- \begin{example}[test6 (demonstrate multiple-qubit controlled single-q-gates)]
+ \begin{example}<Updated in 0.1.1>[test6 (demonstrate multiple-qubit controlled single-q-gates)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit j[4];
-
+
cnot j[2] | j[0, 1];
x j[0];
box {$U$} j[1] | j[0, 2-3];
@@ -1407,13 +1603,13 @@ qubit {$\ket{<name>_{\idx}}$} <name>[<len>];
\end{tikzpicture}
\end{codeexample}
\end{example}
-
- \begin{example}[test7 (measurement of operator with correction)]
+
+ \begin{example}<Updated in 0.1.1>[test7 (measurement of operator with correction)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit q[2];
-
+
h q[0];
box {$U$} q[1] | q[0];
h q[0];
@@ -1423,15 +1619,15 @@ qubit {$\ket{<name>_{\idx}}$} <name>[<len>];
\end{tikzpicture}
\end{codeexample}
\end{example}
-
+
\clearpage
- \begin{example}[test8 (stage in simplification of quantum teleportation)]
+ \begin{example}<Updated in 0.4>[test8 (stage in simplification of quantum teleportation)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit {$\ket{q_0} = \ket\psi$} q[1];
qubit {$\ket{q_{\idx}} = \ket0$} q[+2];
-
+
h q[1];
cnot q[1] | q[0];
cnot q[2] | q[1];
@@ -1443,19 +1639,24 @@ qubit {$\ket{<name>_{\idx}}$} <name>[<len>];
\end{tikzpicture}
\end{codeexample}
Note that we left out two Hadamards at the end.
-
- Before version 0.1.1, the recommended approach (which of course still works) to define a vector qubit register with various texts was to use case discrimination on \tex!\idx!, for example in the following manner:
+
+ Another way to provide various initial values in a single command is by performing case discrimination on \tex!\idx!, for example in the following manner:
+
\begin{minted}{tex}
-qubit {$\ket{q_{\idx}} = \ifcase\idx\relax \ket\psi \else \ket0 \fi$} q[3];
+qubit {$\ket{q_{\idx}} = \Ifcase\idx\relax \ket\psi \Else \ket0 \Fi$} q[3];
\end{minted}
+ In principle, all \TeX{} conditionals that check against \tex!\idx! need to be prefixed by \tex!\protect!.
+ If the \texttt{compat} key is at least \texttt{0.4}, \Yquant{} will make the commands \tex!\Ifnum!, \tex!\Ifcase!, \tex!\Or!, \tex!\Else!, \tex!\Fi!, \tex!\Unless! and \tex!\The! available for use within gates; they correspond in a certain way to auto\hyp\tex!\protect!ed versions of the corresponding \TeX{} primitives.
+ Most likely, you will never need them inside values if not in the exact combination with \tex!\idx!.
\end{example}
-
+
+ \clearpage
\begin{example}[test9 (two-qubit gate circuit implementation of Toffoli)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit q[3];
-
+
box {$\sqrt X$} q[2] | q[1];
cnot q[1] | q[0];
box {$\sqrt X^\dagger$} q[2] | q[1];
@@ -1465,16 +1666,15 @@ qubit {$\ket{q_{\idx}} = \ifcase\idx\relax \ket\psi \else \ket0 \fi$} q[3];
\end{tikzpicture}
\end{codeexample}
\end{example}
-
- \clearpage
- \begin{example}[test10 (multi-qubit gates also demonstrates use of classical bits)]
+
+ \begin{example}<Alternative in 0.1.2\\Updated in 0.1.1>[test10 (multi-qubit gates also demonstrates use of classical bits)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit {$\ket{q_0}$} q;
cbit {$c_1$} c;
qubit {$\ket{q_2}$} q[+1];
-
+
h q[0];
box {$U$} (q[0], c);
box {$S$} q[1];
@@ -1482,17 +1682,18 @@ qubit {$\ket{q_{\idx}} = \ifcase\idx\relax \ket\psi \else \ket0 \fi$} q[3];
\end{yquant}
\end{tikzpicture}
\end{codeexample}
- Instead of a discontigous vector register, we could also have used three scalar registers.
+ Instead of a discontiguous vector register, we could also have used three scalar registers.
The labels chosen for \pkg{qasm} do not fit well to the indices \Yquant{} assigns.
We might also have used a three\hyp register vector and used the \gate{settype} pseudo\hyp gate to immediately change the second register into a classical one, which would give indices matching the labels---but still, the registers would have a common name, which would make this a very unnatural approach.
\end{example}
-
- \begin{example}[test11 (user-defined multi-qubit ops)]
+
+ \clearpage
+ \begin{example}<Updated in 0.1.1>[test11 (user-defined multi-qubit ops)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit q[3];
-
+
h q[0];
box {$U_{f(x)}$} (q[0, 1]);
h q[1];
@@ -1503,14 +1704,13 @@ qubit {$\ket{q_{\idx}} = \ifcase\idx\relax \ket\psi \else \ket0 \fi$} q[3];
Here we used the fact that a vector register can also be addressed as a whole.
Instead of \tex!(q)!, we could have also written, e.g., \tex!(q[0]-q[2])! or \tex!(q[0-2])!, or enumerated all sub\hyp registers in a comma\hyp separated list.
\end{example}
-
- \clearpage
- \begin{example}[test12 (multi-qubit controlled multi-qubit operations)]
+
+ \begin{example}<Updated in 0.1.1>[test12 (multi-qubit controlled multi-qubit operations)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit q[3];
-
+
h q[0];
box {$U$} (q[1-2]) | q[0];
h q[0];
@@ -1519,14 +1719,15 @@ qubit {$\ket{q_{\idx}} = \ifcase\idx\relax \ket\psi \else \ket0 \fi$} q[3];
\end{tikzpicture}
\end{codeexample}
\end{example}
-
+
+ \clearpage
\begin{example}[test13 (three-qubit phase estimation circuit with QFT and controlled-U)]
\begin{codeexample*}
\begin{tikzpicture}
\begin{yquant}
qubit {$\ket{j_{\idx}} = \ket0$} j[3];
qubit s[2];
-
+
h j;
box {$U^4$} (s) | j[0];
box {$U^2$} (s) | j[1];
@@ -1542,7 +1743,7 @@ qubit {$\ket{q_{\idx}} = \ifcase\idx\relax \ket\psi \else \ket0 \fi$} q[3];
\end{tikzpicture}
\end{codeexample*}
\end{example}
-
+
\begingroup%
\mdfapptodefinestyle{bdBox}{%
leftmargin=-.12\linewidth,
@@ -1555,7 +1756,7 @@ qubit {$\ket{q_{\idx}} = \ifcase\idx\relax \ket\psi \else \ket0 \fi$} q[3];
qubit q[3];
qubit {$\ket{s_{\idx}} = \ket0$} s[2];
cbit {$c_{\idx} = 0$} c[2];
-
+
h s[0];
cnot s[1] | s[0];
cnot s[0] | q[0];
@@ -1566,7 +1767,7 @@ qubit {$\ket{q_{\idx}} = \ifcase\idx\relax \ket\psi \else \ket0 \fi$} q[3];
cnot c[0] | s[0];
cnot c[1] | s[1];
discard s; % to suppress wires extending until re-initialization
-
+
init {$\ket0$} s;
h s[0];
cnot s[1] | s[0];
@@ -1575,7 +1776,7 @@ qubit {$\ket{q_{\idx}} = \ifcase\idx\relax \ket\psi \else \ket0 \fi$} q[3];
cnot s[1] | s[0];
h s[0];
measure s;
-
+
box {Process\\Syndrome} (s, c);
box {$\symcal R$} (q) | s, c;
\end{yquant}
@@ -1583,35 +1784,38 @@ qubit {$\ket{q_{\idx}} = \ifcase\idx\relax \ket\psi \else \ket0 \fi$} q[3];
\end{codeexample*}
\end{example}
\endgroup%
-
+
\clearpage
- \begin{example}[test15 (``D-type'' measurement)]
+ \begin{example}<Updated in 0.1.1>[test15 (``D-type'' measurement)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit {$\ket{q_0} = \ket\psi$} q;
qubit {$\ket{q_1} = \ket+$} q[+1];
-
+
zz (q);
dmeter {$H Z_\theta$} q[0];
\end{yquant}
\end{tikzpicture}
\end{codeexample}
\end{example}
-
- \begin{example}[test16 (example from Nielsen paper on cluster states)]
+
+ \begin{example}<Updated in 0.4, 0.1.2, 0.1.1>[test16 (example from Nielsen paper on cluster states)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit {$\ket{q_{\idx}} = \ket\psi$} q[2];
qubit {$\ket{q_2} = \ket\phi$} q[+1];
qubit {$\ket{q_3} = \ket0$} q[+1];
-
+
zz (q[1], q[2]);
align q;
cnot q[3] | q[2];
slash q[0];
dmeter q[3];
+ align q;
+ [solid]
+ barrier q[2];
discard q[2];
\end{yquant}
\end{tikzpicture}
@@ -1620,18 +1824,17 @@ qubit {$\ket{q_{\idx}} = \ifcase\idx\relax \ket\psi \else \ket0 \fi$} q[3];
Usually, this would be sufficient to put the \gate{cnot} and the \gate{slash} gate directly under each other, as it is in the \pkg{qasm} example.
However, the \gate{slash} gate is special in that it does not need horizontal space and is put with only half of the usual operator separation into the circuit (for this reason, it can be put at the beginning of a wire without creating weird shifts with respect to the ``unslashed'' registers---it is put in the initial line that every wire even without an operation has).
Hence, you should normally only use the \gate{slash} gate as the very first gate in a circuit.
- It is not possible to construct the exact same appearance as in the \pkg{qasm} example.
- Note that \gate{discard} currently just drops the wire directly after the last operation.
+ To get the vertical stopper mark, we abuse a \gate{barrier} on just a single wire and turn it from dashed to solid before \gate{discard}ing.
\end{example}
-
- \begin{example}[test17 (example from Nielsen paper on cluster states)]
+
+ \begin{example}<Updated in 0.1.1>[test17 (example from Nielsen paper on cluster states)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit {$\ket{q_0} = \ket\psi$} q;
qubit {$\ket{q_{\idx}} = \ket+$} q[+2];
qubit {$\ket{q_3} = \ket\phi$} q[+1];
-
+
zz q[(0-1), (2-3)];
zz (q[1-2]);
dmeter {$H$} q[1-2];
@@ -1640,86 +1843,147 @@ qubit {$\ket{q_{\idx}} = \ifcase\idx\relax \ket\psi \else \ket0 \fi$} q[3];
\end{codeexample}
This example shows how the multi\hyp qubit delimiter (the parenthesis) can even be used within indices.
\end{example}
-
- \begin{example}[test18 (multiple-control bullet op)]
+
+ \begin{example}<Updated in 0.1.2>[test18 (multiple-control bullet op)]
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
- qubit {$\ket{q_{\idx}} = \ket{\ifcase\idx\relax \psi \or + \or + \or \phi \fi}$} q[4];
-
+ qubit {$\ket{q_{\idx}} = \ket{\Ifcase\idx\relax \psi \Or + \Or + \Or \phi \Fi}$} q[4];
+
zz (q);
dmeter {$H$} q[1, 2];
\end{yquant}
\end{tikzpicture}
\end{codeexample}
This gate is probably a generalization of \gate{zz}, $\symbb1 - 2 \ketbra{1\dotsm1}{1\dotsm1}$, and indeed since version~0.1.2, we can use \gate{zz} for this purpose.
- This time, we also used the common way to initialize a gate with various identifiers as was done before version~0.1.1, using case distinctions.
+ This time, we used the case distinction method in the initialization, as already alluded to before.
\end{example}
\endgroup
-
+
\clearpage
\subsection{\pkg{qcircuit} documentation}
\begingroup%
- \yquantset{operator/separation=3mm}
+ \yquantset{operator/separation=2mm}
For a better orientation, we use the same section headings as the \pkg{qcircuit} manual.
The manual uses unnamed registers a lot; often, we will use the \tex!yquant*! environment to make things more concise.
- As \pkg{qcircuit} uses a much large separation between the operators than \Yquant's default, we globally say\\*\tex!\yquantset{operator/separation=3mm}!.
-
+ As the \pkg{qcircuit} manual uses a bit larger separation between the operators than \Yquant's default, we globally say\\*\tex!\yquantset{operator/separation=1em}!.
+
\subsubsection{I. Introduction}
- \begin{example}
+ \begin{example}<Updated in 0.4, 0.1.1>%
\begin{codeexample*}
-\begin{tikzpicture}[baseline=(current bounding box.center)]
- \begin{yquant*}
- box {$U$} q[2] | q[0, 1];
- \end{yquant*}
-\end{tikzpicture}
-$=$
-\begin{tikzpicture}[baseline=(current bounding box.center)]
- \begin{yquant*}
- box {$V$} q[2] | q[1];
- cnot q[1] | q[0];
- box {$V^\dagger$} q[2] | q[1];
- cnot q[1] | q[0];
- box {$V$} q[2] | q[0];
- \end{yquant*}
+\begin{tikzpicture}
+ \begin{yquant}[operators/subcircuit/frameless]
+ nobit q[3];
+
+ subcircuit {
+ [out]
+ qubit {} q[3];
+ box {$U$} q[2] | q[0, 1];
+ } (q);
+ discard -;
+
+ [draw=none]
+ box {$=$} (-);
+
+ subcircuit {
+ [out]
+ qubit {} q[3];
+ box {$V$} q[2] | q[1];
+ cnot q[1] | q[0];
+ box {$V^\dagger$} q[2] | q[1];
+ cnot q[1] | q[0];
+ box {$V$} q[2] | q[0];
+ } (q);
+ discard -;
+ \end{yquant}
\end{tikzpicture}
\end{codeexample*}
- Here, we chose to realize the equality using two \tex!tikzpicture!s with appropriately set baselines.
-
- If mangling with the baselines becomes problematic, a different approach would be to use an outer \tex!tikzpicture! with three nodes (left circuit, equals, right circuit); but the circuits themselves are \tex!tikzpictures! again, and nesting those is dangerous (but may work).
- Instead they could have been put into \tex!\savebox!es and just used.
-
- Finally, using nested \tex!tikzpictures! for the outer nodes is not really necessary.
- Not using nodes but putting the two \tex!yquant*! environments in a \TikZ{} \tex!scope! with \texttt{shift} transformation would have also worked.
+ The best way to realize circuit equalities is with the help of \texttt{frameless} subcircuits.
+ The \texttt{[frameless]} attribute can either be specified on each subcircuit individually or, as done here, globally via the corresponding style.
+ In this way, we can specify all subcircuits individually.
+ All wires that are identical in the circuits must be outer wires; but in fact, we do not want them to be visible outside of the subcircuits.
+ Consequently, we initialize them in the outer circuit as \gate{nobit}s, declare them with the \texttt{[out]} attribute, and discard them right after the subcircuit.
+ It is important not to discard them within the subcircuit, as the wires would then not extend to the same horizontal final position.
+ The equality sign is realized very easily by means of a \gate{box} gate that spans all registers and from which we remove the border.
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.4>
\begin{codeexample*}
\begin{tikzpicture}
\begin{yquant}
qubit {$\ket\psi$} a;
qubit {$\ket0$} b[2];
-
+
h b[1];
cnot b[0] | b[1];
- cnot b[1] | a;
+ cnot b[0] | a;
h a;
align a, b;
measure a;
+ [direct control]
measure b[0];
-
+
x b[1] | b[0];
z b[1] | a;
-
+
discard a;
discard b[0];
output {$\ket\psi$} b[1];
\end{yquant}
\end{tikzpicture}
\end{codeexample*}
+ Here, we see how to use a measurement as a direct output for the next controlled operation.
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.4>
+ \begin{codeexample*}
+% \usetikzlibrary{quotes}
+\begin{tikzpicture}
+ \begin{yquant}
+ qubit {} msg[3];
+ nobit syndrome[3];
+
+ [this subcircuit box style={dashed, "Syndrome Measurement"}]
+ subcircuit {
+ qubit {} msg[3];
+ [out]
+ qubit {$\ket0$} syndrome[3];
+
+ cnot syndrome[0] | msg[0];
+ cnot syndrome[0] | msg[1];
+ cnot syndrome[1] | msg[1];
+ cnot syndrome[1] | msg[2];
+ cnot syndrome[2] | msg[0];
+ cnot syndrome[2] | msg[2];
+
+ dmeter {$M_{\symbol{\numexpr`a+\idx}}$} syndrome;
+ } (msg[-2], syndrome[-2]);
+
+ ["Recovery"]
+ box {$\mathcal R$} (msg) | syndrome;
+ discard syndrome;
+ \end{yquant}
+\end{tikzpicture}
+ \end{codeexample*}
+ The example demonstrates how to put a description next to a gate.
+ In general, those descriptions should be realized using the \TikZ{} feature \texttt{label}.
+ Using the \TikZ{} library \texttt{quotes}, the label is most easily specified.
+ Since the label is not part of the valid arguments and also cannot be found in the \texttt{/yquant} path, it is automatically passed to \style{/yquant/operator style}.
+
+ To enclose a part of the circuit by a rectangle, we use a subcircuit.
+ We define the incoming \gate{qubit}s in the outer circuit, they will have the default attribute \texttt{[inout]}; the syndrome registers, which are created only in the subcircuit enter as \gate{nobit}s and consequently have the \texttt{[out]} attribute.
+ It is important to note that both the \texttt{dashed} style as well as the \texttt{label} (here with quoted syntax) are specified only inside \style{/yquant/this subcircuit box style}.
+ This ensures that they are not also attached to every single gate in the subcircuit.
+
+ Then we see how to apply an operation to multiple registers in parallel while using the \tex!\idx! macro to still give them a different text.
+ Since \tex!\idx! gives a numerical index (zero\hyp based), we exploit the ASCII code (actually, this document is compiled in Unicode mode...) to turn this into a letter.
+
+ Note that it could have become necessary to pass the \texttt{overlay} attribute to the recovery gate, as it is a multi\hyp register gate with a \texttt{label}, meaning that \Yquant{} cannot reliably distribute its total vertical extent over its constituent registers.
+ However, as the $\symcal R$ together with the label in total were not higher than the three\hyp qubit gate would have been anyway, this was not necessary here.
+ In generally, don't use \texttt{overlay} unless necessary; maybe a future version will even be able to handle the more difficult cases better.
+
+ Finally, we will give a similar circuit by using the \TikZ{} interface instead of subcircuits, this time also showing how we can change the shape of the measurement gate to one as in the \pkg{qcircuit} manual:
+
\begin{codeexample*}
% \usetikzlibrary{fit, quotes}
\begin{tikzpicture}
@@ -1727,7 +1991,7 @@ $=$
qubit {} msg[3];
[name=inits]
qubit {$\ket0$} syndrome[3];
-
+
[name=scnot0]
cnot syndrome[0] | msg[0];
cnot syndrome[0] | msg[1];
@@ -1735,7 +1999,7 @@ $=$
cnot syndrome[1] | msg[2];
cnot syndrome[2] | msg[0];
cnot syndrome[2] | msg[2];
- [name=smeas]
+ [name=smeas, shape=yquant-rectangle, rounded corners=.45em]
dmeter {$M_{\symbol{\numexpr`a+\idx}}$} syndrome;
["Recovery"]
box {$\symcal R$} (msg) | syndrome;
@@ -1744,22 +2008,10 @@ $=$
\node[draw, dashed, fit=(inits-2) (scnot0-p0) (smeas-2), "Syndrome Measurement"] {};
\end{tikzpicture}
\end{codeexample*}
- In this case, an implicit register declaration would not have worked: we would have needed to define the first part of the syndrome register \emph{before} the second part of the message register.
- But this would then have mixed data with syndrome registers in the vertical ordering.
-
- This also is a first demonstration of how to access \Yquant{} objects from within \TikZ.
We name several elements that visually form the enclosing rectangle; then, we use the \TikZ{} library \texttt{fit} to put a node around them all.
-
- Then we see how to apply an operation to multiple registers in parallel while using the \tex!\idx! macro to still give them a different text.
- Since \tex!\idx! gives a numerical index (zero\hyp based), we exploit the ASCII code (actually, this document is compiled in Unicode mode...) to turn this into a letter.
-
- The example also demonstrates how to put a description next to a gate.
- In general, those descriptions should be realized using the \TikZ{} feature \texttt{label}.
- Using the \TikZ{} library \texttt{quotes}, the label is most easily specified.
- Since the label is not part of the valid arguments and also cannot be found in the \texttt{/yquant} path, it is automatically passed to \style{/yquant/operator style}.
+ Any gate can be given a custom shape; here, we use a \texttt{yquant-rectangle}, which is the analogue to \TikZ's \texttt{rectangle} and thus supports the standard \texttt{rounded corners} style.
\end{example}
-
- \clearpage
+
\subsubsection{IV. Simple Quantum Circuits}
\begin{example}
\begin{codeexample}
@@ -1770,7 +2022,8 @@ $=$
\end{tikzpicture}
\end{codeexample}
\end{example}
-
+
+ \clearpage
\paragraph{A. Wires and gates}\leavevmode
\begin{example}
\begin{codeexample}
@@ -1785,8 +2038,8 @@ $=$
\end{tikzpicture}
\end{codeexample}
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.1.2>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -1796,12 +2049,12 @@ $=$
\end{yquant*}
\end{tikzpicture}
\end{codeexample}
- Since version~0.1.2, \Yquant{} allows to change wire styles by means of the \gate{setstyle} and \gate{addstyle} pseudo\hyp gates.
+ \Yquant{} allows to change wire styles by means of the \gate{setstyle} and \gate{addstyle} pseudo\hyp gates.
Here, we use the gate on all wires in order to set an arrow style.
Note that arrowheads are actually very special in two respects:
\begin{itemize}
\item \Yquant{} draws continuous wires for as long as possible.
- In this example, the wire path extends from the very left to the end of the circuit; since version 0.1.2, \Yquant{} does not draw a wire \emph{to} the gate and then a separate one \emph{from} the gate to the next or the end.
+ In this example, the wire path extends from the very left to the end of the circuit; \compat{Changed in 0.1.2}\Yquant{} does not draw a wire \emph{to} the gate and then a separate one \emph{from} the gate to the next or the end.
The only way to force \Yquant{} to draw multiple wires is to change the wire style or type mid\hyp circuit.
For example, by saying \yquant!addstyle {} -;!, all wire paths will be separated at the current position, which \emph{in theory} allows to draw arrowsheads on intermediate wires.
\item \emph{In practice}, this will not work due to the clipping commands that \Yquant{} installs.
@@ -1812,7 +2065,7 @@ $=$
If you really need to do this (say, for only a single gate), you may experiment with the \TikZ{} \texttt{shorten} keys, which allow you to manually reduce the length of the wire, but the amount of reduction must be hand\hyp computed for every gate.
If you need this more often, consider filing a feature request.
\end{example}
-
+
\paragraph{B. CNOT and other controlled single qubits gates}\leavevmode
\begin{example}
\begin{codeexample}
@@ -1824,8 +2077,8 @@ $=$
\end{tikzpicture}
\end{codeexample}
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -1836,14 +2089,13 @@ $=$
\end{tikzpicture}
\end{codeexample}
\end{example}
-
- \clearpage
+
\paragraph{C. Vertical wires}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.4, 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
- box {$U_{\protect\the\numexpr\idx+1}$} q[0, 2] | q[1];
+ box {$U_{\The\numexpr\idx+1}$} q[0, 2] | q[1];
\end{yquant*}
\end{tikzpicture}
\end{codeexample}
@@ -1851,12 +2103,10 @@ $=$
This macro follows the same rules as the name suffix, i.e., it assigns indices (zero\hyp based) to the target registers in top\hyp to\hyp bottom order, regardless of which order was specified in the target list.
Since we instead want a one\hyp based subscript, we need to add one.
Note that if you want to output \tex!\idx! directly or within an unexpandable expression, you don't need to take any action.
- However, here, \tex!\the! is expandable; and since \Yquant{} needs to process all its output twice (first in order to determine the vertical spacing, second to actually typeset), you must manually take care that the command is \emph{not} expanded prematurely by inserting \tex!\protect!.
- Had you not done this, the subscript would have been ``$1$'' for both operators.
- Note this is not the case if this macro is used upon creation of a register (as is evident by the fact that the previous examples that used \tex!\ifcase! within the value did not need to say \tex!\protect\ifcase ... \protect\or ... \protect\fi!).
- Probably we can avoid the need for protection in a future release\dots.
+ However, here, \tex!\the! is expandable; and since \Yquant{} needs to process all its output twice (first in order to determine the vertical spacing, second to actually typeset), you must manually take care that the command is \emph{not} expanded prematurely by saying \tex!\protect\the! instead, for which \Yquant{}, with a \texttt{compat} setting of at least \texttt{0.4}, provides the shorthand \tex!\The!.
+ Had we used the plain \TeX{} \tex!\the! instead, the subscript would have been ``$1$'' for both operators.
\end{example}
-
+
\paragraph{D. Labeling input and output states}\leavevmode
\begin{example}
\begin{codeexample}
@@ -1869,19 +2119,20 @@ $=$
\end{tikzpicture}
\end{codeexample}
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.4, 0.1.1>
\begin{codeexample}
+% \usetikzlibrary{calc}
\begin{tikzpicture}
\begin{yquant*}
{
- \yquantset{every multi label/.append style={decorate=false, draw=none}}
+ \yquantset{every multi label/.style={every node/.style={anchor=east, midway}}}
init {$\ket{0^k}$} (a[-1]);
}
init {$\ket\psi$} (b[-1]);
- qubit {\ifcase\idx\relax$A$\or$B$\fi} c[2];
- [every multi label/.append style={decorate=false, draw=none, every node/.append style={shift={(-.3, 0)}}}]
- init {$\ket\psi$} (c);
+ [name=cinit]
+ qubit {\Ifcase\idx\relax$A$\Or$B$\Fi} c[2];
+ \node[anchor=east] at ($(cinit-0.west)!.5!(cinit-1.west)$) {$\ket\psi$};
\end{yquant*}
\end{tikzpicture}
\end{codeexample}
@@ -1889,13 +2140,12 @@ $=$
The second one (using a curly brace) corresponds to the default.
It is overwritten for the first qubit, and to make this modification local, this is done in a group.
The third qubit pair uses an overall label and additionally individual labels on the lines.
- This is achieved by some trickery: the individual labels are given as initialization labels on the register; the global label is given as an \gate{init} multi\hyp qubit gate.
+ The recommended way to do this starting from version~0.4 is to add the ``special'' label by means of a \TikZ{} command.
\end{example}
-
- \clearpage
+
\subsubsection{V. More Complicated Circuits: Multiple Qubit gates and Beyond}
\paragraph{A. Multiple qubit gates}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -1904,30 +2154,32 @@ $=$
\end{tikzpicture}
\end{codeexample}
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.4, 0.1.1>
\begin{codeexample}
+\yquantdefinebox{dots}[inner sep=0pt]{$\dots$}
\begin{tikzpicture}
\begin{yquant}
qubit {} a;
cbit {} b;
+ [register/minimum height=0pt, register/minimum depth=0pt]
nobit ellipsis;
qubit {} c;
-
- [draw=none]
- box {$\dots$} ellipsis;
+
+ dots ellipsis;
box {$U$} (a, b, ellipsis, c);
- [draw=none]
- box {$\dots$} ellipsis;
+ dots ellipsis;
\end{yquant}
\end{tikzpicture}
\end{codeexample}
- This demonstrates how a register of type \gate{nobit} might even be useful if the register is never used.
- We use \gate{box} registers with disabled border to put the ellipsis dots in place.
+ This demonstrates how a register of type \gate{nobit} might even be useful if the register is never used and no subcircuits are involved.
+ Note how we overwrite the default minimum height and depth setting for this register only.
+ Additionally, we for the first time define our own gate, which we call \texttt{dots}.
+ As we define our own style, it does not inherit from \style{/yquant/operators/every box}; hence, we only need to overwrite the \texttt{inner sep} coming from \TikZ's defaults.
\end{example}
-
+
\clearpage
- \begin{example}
+ \begin{example}<Updated in 0.1.2, 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -1936,10 +2188,10 @@ $=$
\end{yquant*}
\end{tikzpicture}
\end{codeexample}
- This demonstrates \Yquant's capabilities of discontiguous multi\hyp qubit gates that was added in version~0.1.2.
+ This demonstrates \Yquant's capabilities of discontiguous multi\hyp qubit gates.
\Yquant{} automatically splits multi\hyp qubit gates into slices of directly adjacent wires (which, for the $\symcal G$ case, are the single wires \yquant!a[0]! and as second slice \yquant!a[2]!).
\end{example}
-
+
\paragraph{B. Measurements and classical bits}\leavevmode
\begin{example}
\begin{codeexample}
@@ -1955,13 +2207,13 @@ $=$
Extracting a meter symbol on its own will not be supported.
If you are interested in the code, have a look at \texttt{yquant-shapes.tex} and search for the \texttt{yquant-measure} shape.
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.4, 0.1.2>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
- [rounded corners]
- box {Codebit} a;
+ [shape=yquant-rectangle, rounded corners=.45em, direct control]
+ measure {Codebit} a;
box {$\chi$} b | a;
discard a;
measure b;
@@ -1970,21 +2222,21 @@ $=$
\end{codeexample}
Rectangles with rounded corners are not a specific style, but since the \texttt{yquant-rectangle} shape internally uses \tex!\pgfpathrectangle!, the ordinary \TikZ{} option can be used (also, an inset specification can control how much the corner is rounded).
\end{example}
-
+
\clearpage
\begin{example}
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
qubit {$\ket\psi$} q;
-
+
measure {$\ket{\xi_\pm}$} q;
\end{yquant}
\end{tikzpicture}
\end{codeexample}
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -1994,8 +2246,8 @@ $=$
\end{tikzpicture}
\end{codeexample}
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.1.2, 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -2003,11 +2255,11 @@ $=$
\end{yquant*}
\end{tikzpicture}
\end{codeexample}
- Multi\hyp qubit gates (including measurements) on non\hyp adjacent registers are properly supported since version~0.1.2.
- As explained in \cref{sec:registers}, there is one main and multiple subordinate gate in such a discontiguous multi\hyp qubit operation (though at the moment, the \gate{measure} gate with text is the only gate that makes this distinction).
+ Multi\hyp qubit gates (including measurements) on non\hyp adjacent registers are properly supported.
+ As explained in \cref{sec:registers}, there is one main and multiple subordinate gate in such a discontiguous multi\hyp qubit operation (though at the moment, the \gate{measure} gates with text is the only gate that makes this distinction).
In our case, the main part contains the measurement symbol and the text, while the subordinate gates only contain the text.
By default, \Yquant{} uses the first slice as main part, but you may influence this by preceding what you want to be ``main'' by a star:
-
+
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -2016,10 +2268,10 @@ $=$
\end{tikzpicture}
\end{codeexample}
\end{example}
-
+
\clearpage
\paragraph{C. Non-gate inserts, forcing space, and swap}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -2036,7 +2288,7 @@ $=$
Here, the intermediate text was inserted by using a \gate{box} without drawing.
Another way would be to use an \gate{init} command, although this is semantically wrong (probably).
\end{example}
-
+
\begin{example}
\begin{codeexample}
\begin{tikzpicture}
@@ -2044,7 +2296,7 @@ $=$
qubit {} a;
[name=ypos]
qubit {} b[3];
-
+
cnot a | b[0];
[name=left]
cnot a | b[1];
@@ -2058,10 +2310,10 @@ $=$
Note how the register range \texttt{-} was used to denote all registers.
We positioned the dots by first naming the relevant registers, so that the vertical position is at the coordinates \texttt{ypos-0} and \texttt{ypos-1}; and then, we also named the \gate{cnot} gates, so that we are able to discern the horizontal position.
\end{example}
-
+
\clearpage
\paragraph{D. Barriers}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -2072,10 +2324,10 @@ $=$
\end{codeexample}
\end{example}
Now the \pkg{qcircuit} manual lists three circuits with barriers at different positions.
- They cannot be drawn with \Yquant; however, since neither of them is a valid circuit, this is of no concern.
-
+ They cannot be drawn with \Yquant; however, since neither of them is a valid circuit (no indication whether the control is positive or negative), this is of no concern.
+
\paragraph{E. How to control anything}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -2094,13 +2346,12 @@ $=$
If there is need for this, please file a feature request.
But note the relatively common (though unsupported by \Yquant{} at the moment) use of control lines that directly go from the measurement operator to the controlled operation; in this case, the opposite direction would be meant by using the same notation.
\end{example}
-
+
\subsubsection{VI. Bells and Whistles: Tweaking Your Diagram to Perfection}
For options how to configure the circuits, refer to \cref{sec:config}.
-
- \clearpage
+
\paragraph{A. Spacing}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -2111,31 +2362,38 @@ $=$
\end{tikzpicture}
\end{codeexample}
\end{example}
-
+
\paragraph{B. Labeling}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.4>
\begin{codeexample}
\begin{tikzpicture}
- \begin{yquant}[every initial label/.style={anchor=south east}]
+ \begin{yquant}[every initial label/.style={anchor=south east, yshift=1mm}, every post measurement control=direct, operators/every box/.append style={draw=none}]
qubit {\rlap{\hskip2mm $a$}} a;
qubit {\rlap{\hskip2mm $b$}} b;
+ nobit out;
hspace {5mm} -;
-
+
measure b;
- align -;
+ box {$B$} out | b;
measure a;
- output {$A$} a;
- output {$B$} b;
+ box {$A$} out | a;
+ discard -;
\end{yquant}
\end{tikzpicture}
\end{codeexample}
- Measurement with vertical output are not supported (yet).
+ We support measurements with vertical outputs, but only if they replace the positive control of some action.
+ Here, we fake this behavior by introducing an invisible register at the bottom, which will contain the outputs.
+ In order to disable the line around the \gate{box}es, we used the \style{/yquant/operators/every box} style, which here was most convenient, as the only \gate{box}es in use are those without an outline.
+ However, if we instead want to say \texttt{[draw=none]} as an attribute to the \gate{box}es, this will also remove the outline of the measurements.
+ The reason for this is that giving this as an attribute will in fact populate \style{/yquant/operator style}; and internally, the measurement will be nested within the same scope that draws the \gate{box}---so the options given to the \gate{box} will be inherited by the \gate{measure}ment.
+ As an operator style overwrites default styles, this will also apply to the measurements.
+ Hence, to circumvent this, we would have to additionally say \texttt{[draw]} as an attribute to the \gate{measure}ments, although this is already included in their native style.
+
Repositioning the initial labels needs some care and manual fine\hyp tuning.
\end{example}
-
- \clearpage
+
\paragraph{C. Grouping}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.4, 0.1.1>
\begin{codeexample*}
% \usetikzlibrary{fit}
\begin{tikzpicture}
@@ -2150,36 +2408,37 @@ $=$
h a[0];
[name=rightbot]
h a[1] | a[2];
-
+
hspace {2mm} -;
\end{yquant*}
\node[draw, dashed, fit=(left-0) (left-1) (righttop) (rightbot-0)] {};
\end{tikzpicture}
\end{codeexample*}
Note that \tex!\begin{yquant*}! must not be followed by a line break (unless masked by \tex!%!) if options follow.
+ Also note that here, we cannot make use of a subcircuit due to the very last control, which would then control an inner gate of said subcircuit---but they are not exposed.
\end{example}
\endgroup
-
+
\clearpage
\subsection{\pkg{quantikz} documentation}
\begingroup
\yquantset{operator/separation=4mm}%
Again, our section headings will be the same as in the \pkg{quantikz} manual.
And since \pkg{quantikz} also has even more space between the gates, we globally say \tex!\yquantset{operator/separation=4mm}!.
-
+
\subsubsection{II. A single wire}
\begin{example}
\begin{codeexample*}
\begin{tikzpicture}[label position=north east, every label/.style={inner sep=1pt}]
\begin{yquant}
qubit {$\ket0$} a;
-
+
phase {$\alpha$} a;
h a;
phase {$\beta$} a;
h a;
phase {$\gamma$} a;
-
+
[every output/.append style={align=center}]
output {Arbitrary\\pure state} a;
\end{yquant}
@@ -2188,7 +2447,7 @@ $=$
The captions of \gate{phase} commands are internally implemented using \TikZ{} \texttt{label}s.
At the moment, it is not possible to change any label options on a gate-type basis, only locally or fully globally (\TikZ{} feature request \href{https://github.com/pgf-tikz/pgf/issues/811}{\#811}).
\end{example}
-
+
\clearpage
\paragraph{A. Measurements}\leavevmode
\begin{example}
@@ -2199,7 +2458,7 @@ $=$
["$0$"]
measure a;
discard a;
-
+
init {} a;
dmeter {$1$} a;
discard a;
@@ -2208,21 +2467,21 @@ $=$
\end{codeexample}
Other measurement shapes are not supported at the moment.
\end{example}
-
+
\paragraph{B. Wires and arrows}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.1.2>
\begin{codeexample*}
% \usetikzlibrary{quotes}
\begin{tikzpicture}
\begin{yquant}[operator/separation=1cm, every label/.append style={align=center}]
qubit {$\ket0$\\initial state} a;
-
+
[draw=none]
box {$X$} a;
-
+
["$0$/$1$", type=qubit]
measure a;
-
+
addstyle {->} a;
output {$\ket1$} a;
\yquantset{operator/separation=5mm}
@@ -2230,16 +2489,32 @@ $=$
\end{tikzpicture}
\end{codeexample*}
This example demonstrates how to instruct the \gate{measure} gate to use a different output type than the standard \gate{cbit}.
-
+
In general, any macros that are used within a \TikZ{} path or a \Yquant{} operation must not be fragile, or must be preceded with \tex!\protect!.
In this example, \tex!\\! is a robust command (at least in newer kernels), so protection is not required.
Since it may occur quite frequently that \Yquant{} is used within a \tex!center! environment or in \tex!\centering! mode (in which \tex!\\! is still fragile), \Yquant{} takes care of this (it actually robustifies \tex!\@centercr!, which is the meaning of \tex!\\! in these surroundings).
-
- In order to change the style of an individual wire, we use \gate{addstyle} as of version~0.1.2.
- To make the final line smaller, we change the operator separation by issuing \tex!\yquantset! at the end.
+
+ In order to change the style of an individual wire, we use \gate{addstyle}.
+ To make the final line shorter, we change the operator separation by issuing \tex!\yquantset! at the end.
\end{example}
-
- \begin{example}
+
+ \begin{example}<New in 0.4>
+ \begin{codeexample}
+\begin{tikzpicture}
+ \begin{yquant}
+ qubit {$\ket0$} q;
+ [name=h]
+ h q;
+ discard q;
+ \path[/yquant/every wire, /yquant/every qubit wire, -Stealth] (h) -| ++(1cm, -.5cm) node[below] {trash};
+ \end{yquant}
+\end{tikzpicture}
+ \end{codeexample}
+ Here, we use an ordinary \tex!\path! command to reproduce the ``trash'' line.
+ This time, we chose to use the appropriate styles as \Yquant{} itself would do it instead of just saying \tex!\draw! without the options, which would also have worked.
+ \end{example}
+
+ \begin{example}<Updated in 0.4>
\begin{codeexample}
% \usetikzlibrary{quotes}
\begin{tikzpicture}
@@ -2247,14 +2522,13 @@ $=$
qubit {$\ket0^{\otimes n}$} a;
["north east:3" {font=\protect\footnotesize, inner sep=0pt}]
slash a;
- hspace {2mm} a;
h a;
\end{yquant*}
\end{tikzpicture}
\end{codeexample}
Again, you see an example of how some commands need to be \tex!\protect!ed when used in \Yquant{} options, and that you can indeed exploit all features of the \texttt{quotes} library.
\end{example}
-
+
\begin{example}
\begin{codeexample}
\begin{tikzpicture}
@@ -2265,8 +2539,7 @@ $=$
\end{tikzpicture}
\end{codeexample}
\end{example}
-
- \clearpage
+
\subsubsection{III. Multiple Qubits}
\begin{example}
\begin{codeexample*}
@@ -2274,47 +2547,46 @@ $=$
\begin{yquant}
qubit {$\ket0$} a;
qubit {$\ket0$} b;
-
+
h a, b;
cnot b | a;
box {$U$} a ~ b;
zz (a, b);
-
+
[after=a]
qubit {} c;
-
+
swap (a, c);
box {$U$} c | a ~ b;
\end{yquant}
\end{tikzpicture}
\end{codeexample*}
This example demonstrates the use of the \texttt{after} argument that instructs the register creation to begin the register only after the current position of another register that already exists.
+ Note that this argument will always make the wire begin \emph{at the right end} of the last gate of the referenced register; however, if---as is the case here---this gate is shorter than \style{/yquant/operator/minimum width}, this might not coincide with the visual right end.
\end{example}
-
+
\clearpage
- \begin{example}
+ \begin{example}<Updated in 0.4, 0.1.2, 0.1.1>
\begin{codeexample*}
\begin{tikzpicture}
\begin{yquant*}
[name=c]
cnot a[0, 2] | a[1];
- [name=m]
+ [name=m, direct control]
measure a[1];
discard a[2];
- \path[/yquant/every wire, /yquant/every qubit wire] (c-1) -- (m.center |- c-1);
box {$U$} a[0] | a[1];
+ \path[/yquant/every wire, /yquant/every qubit wire] (c-1) -- (m.center |- c-1);
discard a[1];
\end{yquant*}
\end{tikzpicture}
\end{codeexample*}
- It is not possible for the double control line to directly exit the measurement gate.
- Also, if you discard a gate, this will prevent it from exiting from its last gate.
- \Yquant{} will not allow you (apart from manual drawing) to extend the wire to some arbitrary position, then drop it.
- But of course, as done here, you can always resort to the full power of \TikZ.
- Still, this is inferior to a wire drawn by \Yquant, as it does not use clippings: the connection with the \gate{cnot} gate may not be accurate; in particular, if the wire is of a different color or if you need to draw classical or bundle wires, the connection will become unpleasant.
+ Here, we manually extended the wire on the last register.
+ We could instead have performed an \gate{align} gate before the discarding process, then, the wire line would have been extended by \Yquant{}; but since \gate{align} aligns at the \emph{right end} as opposed to the center of the gate, the wire line would have been a bit longer.
+ Still, this \TikZ{} wire is inferior to a wire drawn by \Yquant, as it does not use clippings: the connection with the \gate{cnot} gate may not be accurate; in particular, if the wire is of a different color or if you need to draw classical or bundle wires, the connection will become unpleasant.
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -2327,15 +2599,17 @@ $=$
\end{tikzpicture}
\end{codeexample}
\end{example}
-
+
+ \Yquant{} doesn't offer anything comparable to the new \tex!\ctrlbundle! command; and as the bundle lines are spaced much more tightly in \Yquant, this would not really make sense.
+
\clearpage
\subsubsection{IV. Operating on many Qubits}
- \begin{example}
+ \begin{example}<Updated in 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
init {$\ket0^{\otimes3}$} (a[-2]);
-
+
box {$U$} (a[1-2]) | a[0];
measure a[0];
discard a[0];
@@ -2346,11 +2620,11 @@ $=$
Multi\hyp qubits inputs are possible using the \gate{init} command.
The text assigned to a register declaration is always for an individual register.
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.4>
\begin{codeexample}
\begin{tikzpicture}
- \begin{yquant*}
+ \begin{yquant*}[register/minimum height=6mm, register/minimum depth=6mm]
hspace {7.5mm} a;
h a;
hspace {7.5mm} a;
@@ -2366,34 +2640,49 @@ $=$
Therefore, there is no automatic centering of a column, though it could be emulated using hand-crafted \gate{hspace} commands, as was done here (the Hadamard gate uses the \style{/yquant/operator/minimum width}, which is \tex!5mm!, while the large box has a width of \tex!2cm!, so that we need two \tex!7.5mm! spacings at the end, as the \gate{hspace} pseudo\hyp gate only inserts exactly the space you give, but not additional [twice] \style{/yquant/operator/separation}, as would be the case for a hypothetical zero\hyp width gate).
In fact, we don't even need the second \gate{hspace}, since the two\hyp qubit \gate{cnot} will automatically enforce correct alignment.
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.4>
\begin{codeexample*}
-\begin{tikzpicture}[braced/.style={decoration={brace, #1, pre=moveto, pre length=-1pt, post=moveto, post length=-1mm}, decorate}, inner/.style={font=\footnotesize}]
- \begin{yquant}[register/separation=3mm]
- [name=a]
+\begin{tikzpicture}
+ \begin{yquant}[register/separation=3mm, every nobit output/.style={}]
qubit {} a[4];
- [x radius=1cm, name=u]
- box {$U$} (a[1-3]) | a[0];
+ [every inspect/.append style={outer xsep=0pt}, operator/minimum width=0pt, font=\footnotesize, name=sub]
+ subcircuit {
+ \yquantset{operator/separation=0pt}
+ qubit {} x[2];
+ qubit {} y;
+ discard -;
+
+ inspect {$x$} (x);
+ [inner xsep=0pt]
+ inspect {$y\vphantom f$} y;
+
+ [shape=yquant-init, decoration={mirror}]
+ inspect {\hskip4mm $x$} (x);
+ [shape=yquant-init, inner xsep=0pt]
+ inspect {$y \oplus f(x)$} y;
+ } (a[1-3]) | a[0];
+ \node at (sub) {$U$};
+ settype {qubit} a;
\end{yquant}
- \draw[braced]
- ([xshift=2pt] a-1 -| u.west) -- ([xshift=2pt] a-2 -| u.west)
- node[inner, anchor=west, xshift=1pt, pos=.55] {$x$};
- \draw[braced=mirror]
- ([xshift=-2pt] a-1 -| u.east) -- ([xshift=-2pt] a-2 -| u.east)
- node[inner, anchor=east, xshift=-1pt, pos=.55] {$x$};
- \node[inner, anchor=west] at (a-3 -| u.west) {\smash{$y$}};
- \node[inner, anchor=east] at (a-3 -| u.east) {\smash{$y \oplus f(x)$}};
\end{tikzpicture}
\end{codeexample*}
- There is no simple way to draw \emph{within} a gate, unless this gate is a proper quantum circuit itself.
- Instead, here the intricate parts were reproduced using \TikZ: first, we make sure we assign a name to every relevant coordinate.
- Then we use some \TikZ{} styles to draw the braces and nodes at the intersection of these coordinates.
- Here, we also make use of the \texttt{moveto} decoration transformation that comes with \Yquant{} and that allows to enlarge the braces slightly for a good overall appearance.
- Finally, as $y$ has a much smaller height than $y \oplus f(x)$, we make sure this does not affect the vertical positioning; and also, as $x$ has no ascender, we need to slightly position it off\hyp mid for a good look.
+ We use quite some tricks to achieve such a layout.
+ We use a subcircuit as a container and \gate{inspect} gates to indicate the inputs and output states accurately.
+ As those are ordinary gates, we reset \style{/yquant/operator/minimum width}, so that the ``$y$'' indication is not too long.
+ Additionally, they are usually meant to be used within a circuit, i.e., they have an additional margin denoted by the \texttt{outer xsep}, which we also remove.
+ Then, within the subcircuit, we reset the \style{/yquant/operator/separation}, which would insert additional whitespace at the beginning.
+ It is important to do this within the subcircuit and not as an attribute; else, we would also remove the outer lines going into the subcircuit.
+
+ Initial or final \gate{inspect} gates without a brace do not really need the separation between brace tip and text (\texttt{inner xsep}), so we also remove it.
+ The output gates should have their braces and separations at the other side, which corresponds to changing their shape from \texttt{yquant-output} to \texttt{yquant-init} and mirroring the decoration (as in \style{/yquant/every label}).
+ To get the desired right\hyp alignment, we hand\hyp tailor an \tex!\hskip! that enlarges the upper output label---automatic alignments would not work here: putting the two \gate{inspect}s together with a case distinction on \tex!\idx! would center them; using \gate{output}s would left\hyp align them.
+
+ Finally, we have to deal with the caption of the gate, which should be absolutely centered with respect to the subcircuit and not have any influence on the spacing---so we just insert it retrospectively as an ordinary \TikZ{} node.
+
+ Also note the use of \gate{discard} and \gate{settype} since we needed wires before and after the subcircuit, which must match the inner wires in type, but we actually do not want to have inner wires.
\end{example}
-
- \clearpage
+
\begin{example}
\begin{codeexample}
\begin{tikzpicture}
@@ -2407,8 +2696,8 @@ $=$
\end{codeexample}
This time, we did not artificially discard the lines.
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.4, 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}
@@ -2418,8 +2707,13 @@ $=$
\end{yquant}
\end{tikzpicture}
\end{codeexample}
+ Notice here that the vertical spacing is uneven.
+ \Yquant{} realizes that the minimal vertical spacing will not be enough to account for the multi\hyp qubit boxes.
+ However, when it tries to adjust positions accordingly so that the last gate fits, this will of course not change anything for the first wire, which is not contained in the gate.
+ After having increased the spacing, \Yquant{} realizes that this already was enough to accomodate for the first gate, so no further action is taken.
+ In order to get a more even spacing, just increase \style{/yquant/register/minimum height} and \style{/yquant/register/minimum depth}.
\end{example}
-
+
\paragraph{A. Different connections}\leavevmode
\begin{example}
\begin{codeexample}
@@ -2435,10 +2729,9 @@ $=$
\end{yquant}
\end{tikzpicture}
\end{codeexample}
- This example for the first time demonstrates the declaration of a non\hyp existing register and the \gate{settype} pseudo\hyp gate that acts as a zero\hyp width, no\hyp content \gate{init} gate.
+ This example demonstrates the declaration of a non\hyp existing register and the \gate{settype} pseudo\hyp gate that acts as a zero\hyp width, no\hyp content \gate{init} gate.
\end{example}
-
- \clearpage
+
\subsubsection{V. Slicing}
\begin{example}
\begin{codeexample}
@@ -2460,7 +2753,7 @@ $=$
Changing the style of slice captions simply means providing label options.
This time, we used the \texttt{label} key instead of the shorter syntax provided by the \texttt{quotes} library, which is of course also possible.
\end{example}
-
+
\begin{example}
\begin{codeexample*}
% \usetikzlibrary{quotes}
@@ -2483,23 +2776,23 @@ $=$
\end{tikzpicture}
\end{codeexample*}
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.4>
\begin{codeexample*}
% \usetikzlibrary{quotes}
\begin{tikzpicture}[label distance=4mm]
- \begin{yquant}[operators/every barrier/.append style={red, thick, shorten <= -2mm, shorten >= -2mm}]
+ \begin{yquant}[operators/every barrier/.append style={red, thick, shorten <= -4mm, shorten >= -4mm}]
qubit {$\ket0$} a;
h a;
["1"]
- barrier (a);
+ barrier a;
phase {[label distance=0pt]$\varphi$} a;
["2"]
- barrier (a);
+ barrier a;
h a;
["3"]
- barrier (a);
- output {$\cos\frac\varphi2 \ket0 - i\sin\frac\varphi2 \ket1$};
+ barrier a;
+ output {$\cos\frac\varphi2 \ket0 - i\sin\frac\varphi2 \ket1$} a;
\end{yquant}
\end{tikzpicture}
\end{codeexample*}
@@ -2526,21 +2819,21 @@ $=$
Only \tex!\yquantset! will be properly captured and re\hyp issued at the correct position when the content is actually typeset.
Had we written \tex!\tikzset{label distance=0pt} \yquant!, no effect at all would have been visible, since this command would only have taken effect in the first (invisible) round when \Yquant{} determines heights.
\end{example}
-
+
\Yquant{} does not provide a mechanism for vertical labels, but you may of course just insert line breaks at appropriate positions (and set the \texttt{align} property of the labels).
-
+
\clearpage
\subsubsection{VI. Spacing}
\paragraph{A. Local adjustment}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.4>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant}[register/default name=]
- [register/minimum height=2cm]
+ [register/minimum depth=2cm]
qubit a;
- qubit {\vbox to 1cm{}} b;
+ qubit b;
qubit c;
-
+
h a;
x b-;
hspace {2cm} -;
@@ -2551,13 +2844,12 @@ $=$
\end{yquant}
\end{tikzpicture}
\end{codeexample}
- At the moment, the distance between registers is calculated by \Yquant{} automatically.
- We show various possibilities to intervene in this example.
- The first is to locally, upon creation of the register, reset \style{/yquant/register/minimum height} to a different value.
- The second is to artificially enlarge the label that the qubit initializer takes.
- However, both approaches enlarge the \emph{height} of the registers, i.e., add half of the specified amount to the top and the bottom.
+ The vertical distance between registers is calculated by \Yquant{} automatically based on the height and depth that \Yquant{} find for this particular register---i.e., how much space is required above and below the wire line for all the gates.
+ In order to enlarge these values, reset \style{/yquant/register/minimum height} or \style{/yquant/register/minimum depth} to a different value.
+ It is not possible to artificially \emph{reduce} the calculated heights and depths, as this would result in overlapping gates.
+ However, sometimes it might be required to exclude a certain gate from the calculation; then, use the \texttt{overlay} attribute.
\end{example}
-
+
\begin{example}
\begin{codeexample*}
\begin{tikzpicture}
@@ -2577,7 +2869,7 @@ $=$
Note that in the first case, the \emph{radius} is specified, i.e., the half\hyp width, while in the second case, it is the \emph{total} width (both times modulo the inner separation).
Also note that the \style{/yquant/operator/minimum width} style is unsuitable for the given task: it would not change the visual width, only what \Yquant{} assumes its width to be.
\end{example}
-
+
\paragraph{B. Global Adjustment}\leavevmode
\begin{example}
\begin{codeexample*}
@@ -2590,11 +2882,11 @@ $=$
\end{tikzpicture}
\end{codeexample*}
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.4, 0.1.1>
\begin{codeexample}
\begin{tikzpicture}
- \begin{yquant*}[register/minimum height=0pt]
+ \begin{yquant*}[register/minimum height=0pt, register/minimum depth=0pt]
x a[0, 2];
zz (a[0, 1]);
x a[0];
@@ -2602,13 +2894,13 @@ $=$
\end{yquant*}
\end{tikzpicture}
\end{codeexample}
- By default, \Yquant{} will use the height that is required by the individual gates, but at least \style{/yquant/register/minimum height} (which defaults to \tex!3mm!).
+ By default, \Yquant{} will use the height and depth that is required by the individual gates, but at least \style{/yquant/register/minimum height} or, respectively, \style{/yquant/register/minimum depth} (which default to \tex!1.5mm!).
Only manually reducing the default height will produce the cramped spacing displayed here.
\end{example}
-
+
\clearpage
\paragraph{C. Alignment}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.4>
\begin{codeexample}
\begin{tikzpicture}
\begin{yquant*}
@@ -2625,80 +2917,128 @@ $=$
\end{tikzpicture}
\end{codeexample}
Not specifying anything for the vertical alignment will lead to the common \TikZ{} problem: the baseline will be at the bottom, which is particularly bad in this case due to the missing $X$ gate.
- The \style{/yquant/register/minimum height} key does not help here, since it only affects \Yquant's internal handling, but not the bounding box calculated by \TikZ.
- In the first example of the \pkg{qcircuit} documentation, we demonstrated how the desired task can easily be achieved in terms of \texttt{baseline}s.
- We will now do the same with scopes instead.\vskip2mm
- \begin{codeexample*}
-\begin{tikzpicture}[/yquant/register/minimum height=5mm]
- \begin{yquant*}
- x a[0];
- cnot a[1] | a[0];
- \end{yquant*}
- \path (current bounding box.east |- 0, 0) ++(1, 0) coordinate (shift);
- \begin{scope}[shift=(shift)]
- \begin{yquant*}
- cnot a[1] | a[0];
- x a;
- \end{yquant*}
- \end{scope}
- \node at (current bounding box) {$=$};
-\end{tikzpicture}
- \end{codeexample*}
- Here, we increased the minimum height so that in the left circuit despite the absence of the $X$ gate, the second register has the same separation.
- We used the meta\hyp node \texttt{current bounding box} to avoid the need to manually specify hard\hyp coded positions.
- \end{example}
-
- \subparagraph{1. Perfecting Vertical Alignment}\leavevmode
- \begin{example}
- \begin{codeexample*}
-\begin{tikzpicture}[baseline=(W)]
+ The keys for minimal register sizes do not help here, since they only affect \Yquant's internal handling, but not the bounding box calculated by \TikZ.
+ The recommended way to draw circuit equations is always with \texttt{frameless} \gate{subcircuit}s; only this will guarantee perfect wire alignment in all cases.
+
+ \begin{codeexample}
+\begin{tikzpicture}
\begin{yquant}
- qubit {$\ket0$} anc;
- [name=W]
- qubit {} x;
- h x;
- cnot x | anc;
+ nobit q[2];
+
+ [frameless]
+ subcircuit {
+ [out]
+ qubit {} q[2];
+ x q[0];
+ cnot q[1] | q[0];
+ } (q);
+ discard -;
+
+ [draw=none]
+ box {$=$} (q);
+
+ [frameless]
+ subcircuit {
+ [out]
+ qubit {} q[2];
+ cnot q[1] | q[0];
+ x q;
+ } (q);
+ discard -;
\end{yquant}
-\end{tikzpicture} $\equiv$ \begin{tikzpicture}[baseline=(W)]
+\end{tikzpicture}
+ \end{codeexample}
+ \end{example}
+
+ \begin{example}<New in 0.4>
+ \begin{codeexample*}
+\begin{tikzpicture}
\begin{yquant}
- [name=W]
- qubit {} x;
- h x;
- x x;
+ qubit {$\ket x$} q;
+ qubit {$\ket y$} q[+1];
+
+ [seamless]
+ subcircuit {
+ [in]
+ qubit {} q[2];
+
+ h q[0];
+ cnot q[1] | q[0];
+ output {\quad$\mapsto$} (-);
+ } (q);
+
+ [draw=none, inner sep=0pt]
+ box {$\ket{\psi_{x, y}}$} (q);
+
+ [seamless]
+ subcircuit {
+ [out]
+ qubit {} q[2];
+
+ init {$\mapsto$\quad} (q);
+ cnot q[1] | q[0];
+ h q[0];
+ } (q);
+
+ output {$\ket x$} q[0];
+ output {$\ket y$} q[1];
\end{yquant}
\end{tikzpicture}
- \end{codeexample*}
- While here, we opted for the most logical choice to name the declaration of the register, a name put to any operation on the desired register would also serve the purpose (as long as this operation is vertically symmetrical, which subcircuits may not be).
- \end{example}
-
- \clearpage
- \begin{example}
+ \end{codeexample*}
+ Here, we do not have a circuit equation (i.e., logical statements involving multiple rather independent circuits), but a circuit progression.
+ We start with some ``outer'' states (note we could again have used the \tex!\symbol! trick to make the declaration a bit shorter), let them enter into the first subcircuit and define an output of this.
+ In the opposite way, we proceed after giving the state.
+ Where to put the actual labels (e.g., the \gate{box} could also have contained $\mapsto \ket{\psi_{x, y}} \mapsto$ and the \gate{output} and \gate{init} gates could have been empty) is up to the user.
+
+ Note that we used \texttt{seamless} instead of \texttt{frameless}, which gives a tighter spacing that is more suitable if initializers or outputs are present.
+ \end{example}
+
+ \clearpage
+ \subparagraph{1. Perfecting Vertical Alignment}\leavevmode
+ \begin{example}<Updated in 0.4>
\begin{codeexample*}
-\begin{tikzpicture}[baseline={([yshift=.2cm]W)}]
- \begin{yquant}
- qubit {$\ket0$} anc;
- [name=W]
- qubit {} x;
- h x;
- cnot x | anc;
- \end{yquant}
-\end{tikzpicture} $\equiv$
-\begin{tikzpicture}[baseline={([yshift=.2cm]new)}]
+\begin{tikzpicture}
\begin{yquant}
- [name=new]
- qubit {} x;
- h x;
- x x;
+ nobit q[2];
+
+ [frameless]
+ subcircuit {
+ [out]
+ qubit {} q;
+ [out]
+ qubit {$\ket0$} q[+1];
+
+ cnot q[0] | q[1];
+ cnot q[1] | q[0];
+ cnot q[0] | q[1];
+ } (q);
+ discard -;
+
+ [draw=none]
+ box {$=$} (q);
+
+ [frameless]
+ subcircuit {
+ [out]
+ qubit {} q;
+ [out]
+ qubit {$\ket0$} q[+1];
+
+ cnot q[1] | q[0];
+ cnot q[0] | q[1];
+ } (q);
+ discard -;
\end{yquant}
\end{tikzpicture}
\end{codeexample*}
- Of course, you may also use the features of the \TikZ{} library \texttt{calc} to achieve the same shift.
+ Using \gate{subcircuit}s here looks like an overkill, but it is the best way both for logical consistency and also to achieve perfect horizontal alignment.
\end{example}
-
+
+ \clearpage
\paragraph{D. Scaling}\leavevmode
\begin{example}
\begin{codeexample*}
-\begin{tikzpicture}[scale=1.5, every label/.append style={scale=1.5}]
+\begin{tikzpicture}[scale=1.5]
\begin{yquant*}
h a;
phase {$\beta$} a;
@@ -2708,10 +3048,10 @@ $=$
\end{codeexample*}
Here, we first scaled the circuit itself.
The default style for \style{/yquant/every circuit} sets the \texttt{transform shape} key for every node (which means any gate), so that those are also scaled.
- This is explicitly undone for \texttt{label}s due to \TikZ{} bug \href{https://github.com/pgf-tikz/pgf/issues/843}{\#843}, so the scaling must be specified explicitly for the \texttt{label}s.
- % TODO Note that unless you use a very recent version of \TikZ{} in which bug \href{https://github.com/pgf-tikz/pgf/issues/843}{\#843} was fixed, you might need to add \tex!every label/.prefix style={transform shape=false}! to this style, which undoes the effect for \texttt{label}s.
+ If your \TikZ{} version is at least 3.1.6a, this is all that needs to be done.
+ In earlier versions, there was a bug that required \Yquant{} to reset the \texttt{transform shape} key for \texttt{label}s, which would then require you to scale those manually.
\end{example}
-
+
\subsubsection{VII. Typesetting}
\paragraph{A. Global Styling}\leavevmode
\begin{example}
@@ -2731,7 +3071,7 @@ $=$
Had we used \style{/yquant/every operator}, then the measurement would also have changed.
Again, due to a \TikZ{} limitation, it is not possible to change the position of labels on a per\hyp style basis, only by using \texttt{label} options or a global setting.
\end{example}
-
+
\begin{example}
\begin{codeexample*}
\begin{tikzpicture}[thick]
@@ -2749,8 +3089,8 @@ $=$
Contrary to \pkg{quantikz}, this also fills the \gate{cnot}s.
If you only want to fill certain operators, you have to selectively target them using their styles.
\end{example}
-
- \begin{example}
+
+ \begin{example}<Updated in 0.1.2, 0.1.1>
\begin{codeexample*}
\begin{tikzpicture}
\begin{yquant}[operators/every box/.append style={fill=white}]
@@ -2761,11 +3101,12 @@ $=$
\end{yquant}
\end{tikzpicture}
\end{codeexample*}
- \Yquant{} properly splits discontiguous multi\hyp qubit operations as of version~0.1.2.
+ \Yquant{} properly splits discontiguous multi\hyp qubit operations.
\end{example}
-
+
+ \clearpage
\paragraph{B. Per-Gate Styling}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.4>
\begin{codeexample}
% \usetikzlibrary{quotes}
\begin{tikzpicture}
@@ -2774,23 +3115,22 @@ $=$
h a;
[green]
phase {[green]$\beta$} a;
- ["$\ket\pm$"]
+ ["$\ket\pm$", blue]
measure a;
discard a;
\end{yquant*}
\end{tikzpicture}
\end{codeexample}
\end{example}
-
- \clearpage
- \begin{example}
+
+ \begin{example}<Updated in 0.4>
\begin{codeexample*}
% \usetikzlibrary{shapes.symbols, fit}
\begin{tikzpicture}
\begin{yquant}
qubit {} data;
qubit {$\ket0$} anc1[2];
-
+
h data;
cnot anc1 | data;
[after=data]
@@ -2800,10 +3140,11 @@ $=$
cnot anc2[0] | data;
cnot anc2 | anc1[0];
cnot anc2[1] | anc1[1];
- measure anc2;
+ measure anc2[0];
+ [blue] measure anc2[1];
\end{yquant}
- \node[starburst, cyan, fill=yellow, draw=red,
- line width=2pt, inner xsep=-4pt, inner ysep=-5pt, fit=(box)] {noise};
+ \node[starburst, cyan, fill=yellow, draw=red, line width=2pt,
+ inner xsep=-4pt, inner ysep=-5pt, fit=(box)] {noise};
\end{tikzpicture}
\end{codeexample*}
\TikZ{} shapes cannot simply be used with \Yquant.
@@ -2813,11 +3154,11 @@ $=$
\Yquant{} draws its elements sequentially; hence, a wire that comes into an operator will be hidden by anything the operator draws on top of it; but outgoing wires will in turn draw on the operator (modulo clipping).
To avoid the issues, we construct an invisible box operator and name it; \emph{outside} of the \tex!yquant! environment, we \texttt{fit} the special \TikZ{} shape on top of it.
\end{example}
-
+
\paragraph{C. Boxing/Highlighting Parts of a Circuit}\leavevmode
- \begin{example}
+ \begin{example}<Updated in 0.2>
\begin{codeexample*}
-% \usetikzlibrary{quotes}
+% \usetikzlibrary{quotes, fit}
\begin{tikzpicture}
\begin{yquant*}
h a;
@@ -2834,14 +3175,14 @@ $=$
draw, inner sep=6pt, "reversed c-\textsc{not}"] {};
\end{tikzpicture}
\end{codeexample*}
- In this case, since version~0.2, a subcircuit may provide a similar experience:
+ As usual, subcircuits provide a similar experience, but respect the separation:
\begin{codeexample*}
% \usetikzlibrary{quotes}
\begin{tikzpicture}
\begin{yquant*}
h a;
cnot b | a;
- [this subcircuit box style={inner sep=6pt, "reversed c-\textsc{not}"}]
+ [this subcircuit box style={inner ysep=6pt, "reversed c-\textsc{not}"}]
subcircuit {
qubit {} x;
qubit {} y;
@@ -2856,15 +3197,15 @@ $=$
\end{codeexample*}
Here, we used the key \style{/yquant/this subcircuit box style} to influence only the style of the subcircuit box itself instead of providing global options that apply to every object in the subcircuit (you wouldn't want the label be assigned to every single gate).
\end{example}
-
+
\clearpage
- \begin{example}
+ \begin{example}<Updated in 0.4>
\begin{codeexample*}
% \usetikzlibrary{quotes}
\begin{tikzpicture}
\begin{yquant*}
h a;
- [this subcircuit box style={draw, dashed, rounded corners, fill=blue!20, inner xsep=6pt, inner ysep=10pt, "\textsc{swap}" below}, register/default name=]
+ [this subcircuit box style={draw, dashed, rounded corners, fill=blue!20, inner ysep=10pt, "\textsc{swap}" below}, register/default name=]
subcircuit {
qubit a;
qubit b;
@@ -2880,24 +3221,24 @@ $=$
Before, this had to be done using named operations and layers.
Note that here we used the style \style{/yquant/this subcircuit box style} to assign a styling that only applies to the box containing the subcircuit, but not to the inner gates---which would have happened had we just given the arguments to the subcircuit directly.
\end{example}
-
+
\Yquant{} does not support the fancy nearest\hyp neighbor swap gate that \pkg{quantikz} has.
It would however not be very difficult to implement this particular shape and make it available.
Maybe even a multi\hyp swap gate using the \texttt{knots} library would be possible.
-
+
\clearpage
\subsubsection{VIII. Otherwise undocumented features}
- \begin{example}
+ \begin{example}<Updated in 0.4>
\begin{codeexample*}
-% \usetikzlibrary{quantikz}
+% \usetikzlibrary{quantikz,fit}
\begin{tikzpicture}
\begin{yquant}[register/default name=]
qubit a;
- [name=wave, register/minimum height=1cm]
+ [name=wave, register/minimum height=5mm, register/minimum depth=5mm]
nobit wave;
qubit b;
qubit c;
-
+
h a, b;
box {$U$} c | a;
[draw=none]
@@ -2913,10 +3254,12 @@ $=$
Since the name assigned to a register without any text actually is of a \texttt{coordinate} shape, we need to enlarge the height of the wave by providing a slightly increased \texttt{inner ysep}.
Additionally, \pkg{quantikz} sets a negative \texttt{inner xsep}, which is probably required for its grid layout; but \Yquant{} positions exactly, so we also need to reset this.
\end{example}
-
+
+ \Yquant{} does not provide a shape corresponding to the ``creating an ebit'' gate.
+
\clearpage
\subsubsection{X. Troubleshooting}
- \begin{example}
+ \begin{example}<Updated in 0.4>
\begin{codeexample*}
\begin{tikzpicture}
\begin{yquant}
@@ -2926,21 +3269,21 @@ $=$
\beta & -\alpha
\end{pmatrix}$} a[0];
cnot a[1] | a[0];
- box {$U_{\protect\the\numexpr\idx+1}$} a;
+ box {$U_{\The\numexpr\idx+1}$} a;
\end{yquant}
\end{tikzpicture}
\end{codeexample*}
\end{example}
\endgroup
-
+
\section{Foreign language support}\label{sec:foreign}
\Yquant{} is built in various modules, so that it is not hard to use the quantum circuit rendering backend, but expose a different language frontend.
- Since version~0.3, \Yquant{} not only understands its own language, but also others.
-
+ \compat{New in 0.3}\Yquant{} not only understands its own language, but also others.
+
\subsection{qasm}\label{sec:foreign:qasm}
By saying \tex!\useyquantlanguage{qasm}! in the preamble after loading \Yquant{} itself, the parser for \pkg{qasm} (not OpenQASM) is loaded.
It provides the environment \tex!qasm! as well as the macro \tex!\qasmimport!, which works similarly to \tex!\yquantimport! (but does not accept additional options).
-
+
\subsubsection{Language specification}
The \pkg{qasm} language is not formally defined, but an overview is provided at \href{https://web.archive.org/web/20050410022847/https://www.media.mit.edu/quanta/qasm2circ/#spec}{the archived website of \texttt{qasm2circ}}.
The \Yquant{} implementation is designed to be compatible with the original parser, with the following exceptions:
@@ -2953,47 +3296,47 @@ $=$
\item The \texttt{space} gate is supposed to produce a horizontal whitespace without a gate.
In \Yquant's implementation, you have to discard the wire if you want to reproduce this behavior; \texttt{space} and \texttt{nop} are equivalent.
\end{itemize}
-
+
The default \pkg{qasm} style defines several macros that can be used in gates.
\Yquant{} makes \tex!\m! (matrix; requires \pkg{amsmath}) and \tex!\txt! (switch to text mode) available within the \pkg{qasm} environment.
-
+
Do not expect \Yquant's output to match the one of \pkg{qasm} exactly.
\Yquant{} is not grid based, so that commands such as \texttt{nop} don't even make sense.
They are implemented for compatibility reasons and will produce a fixed horizontal space of the operator minimum width plus one separation, which might or might not be accurate.
-
+
Note that whatever you write between \tex!\begin{qasm}! and \tex!\end{qasm}! is essentially treated as verbatim; only where the specification says so (in the definition of a new gate and in the optional third command to the register definition), it is interpreted as \TeX{} markup.
- Consequently, in \pkg{beamer}, any frame containing these environments must be given the \texttt{verbatim} option.
-
+ Consequently, in \pkg{beamer}, any frame containing these environments must be given the \texttt{fragile} option.
+
\subsubsection{Configuration}
Loading the \pkg{qasm} language interpreter will define several new configuration keys.
For all the gates, it will use the keys defined in \cref{sec:config}, and it additionally provides the following:
-
+
\begin{option}{operators/every s}!/yquant/operators/every box!
This style is installed for every \texttt{s} operator.
\end{option}
-
+
\begin{option}{operators/every t}!/yquant/operators/every box!
This style is installed for every \texttt{t} operator.
\end{option}
-
+
\begin{option}{operators/every utwo}!/yquant/operators/every box!
This style is installed for every \texttt{Utwo} operator.
\end{option}
-
+
\begin{option*}{qasm}{zero}!\qasm@ket0!
The content of this macro is used as the initialization content whenever the \texttt{zero} gate is invoked.
\end{option*}
-
+
\begin{option*}{qasm}{register/default qubit name}!\qasm@ket{#1}!
This macro is invoked with a single parameter (the name of a qubit register) and gives back what is printed as the name of the register (will be in math mode automatically).
\end{option*}
-
+
\begin{option*}{qasm}{register/default qubit name value}!\qasm@ket{#1} = \qasm@ket{#2}!
This macro is invoked with two parameters (the name of a qubit register and its initial value) and gives back what is printed as the name of the register (will be in math mode automatically).
\end{option*}
-
+
\subsubsection{Examples}
- The unaltered\footnote{Only in \texttt{test14.qasm}, \tex!\cal! was replaced by \tex!\symcal!---and this is only necessary as this manual was set with \pkg{unicode-math}. In traditional mode, even this would not be necessary.} \texttt{.qasm} files provided from \href{https://www.media.mit.edu/quanta/qasm2circ/}{the \texttt{qasm2circ} page} were stored in the subfolder \texttt{qasm} relative to this manual's \TeX{} file.
+ The unaltered \texttt{.qasm} files provided from \href{https://www.media.mit.edu/quanta/qasm2circ/}{the \texttt{qasm2circ} page} were stored in the subfolder \texttt{qasm} relative to this manual's \TeX{} file.
The following command is then used to print all of them:
\begin{minted}{tex}
% preamble:
@@ -3007,7 +3350,7 @@ $=$
\end{center}
}
\end{minted}
-
+
\def\yquantimportpath{qasm/}
\foreach \circuitno in {1, ..., 18} {
\paragraph{Circuit \#\circuitno}\leavevmode\nopagebreak\par\nopagebreak
@@ -3015,7 +3358,7 @@ $=$
\qasmimport{test\circuitno.qasm}
\end{adjustbox}
}
-
+
\section{Wishlist}
This section contains some thoughts on future improvements and features.
\begin{itemize}
@@ -3030,16 +3373,16 @@ $=$
In principle, \Yquant's approach could allow for a simple key switch that changes horizontal to vertical.
Currently, this is largely unsupported by all quantum circuit packages except for \pkg{qpic}.
\end{itemize}
-
+
\section{Changelog}
\subsection*{2020-03-15: Version 0.1}
Initial release
-
+
\subsection*{2020-03-22: Version 0.1.1}
Complete rewrite of the register name parser.
\Yquant{} now understands comma\hyp separated lists and ranges in indices, and also is far more tolerant with respect to whitespaces. \\
\Yquant{} now also supports non\hyp contiguous vector registers and allows to add new registers into an already existing vector that is not the last register, and also in the unstarred mode.
-
+
\subsection*{2020-04-11: Version 0.1.2}
Introduce \gate{setstyle} and \gate{addstyle} pseudo\hyp gates that allow to style individual wires; rename \gate{setwire} to \gate{settype} (the old name is still available and shows a deprecation warning). \\
Complete rewrite of the way \Yquant{} draws wires; projection anchors are removed in favor of clipping paths.
@@ -3047,24 +3390,42 @@ $=$
\Yquant{} now also properly draws non\hyp contiguous multi\hyp qubit operations. \\
New gate: \gate{correlate}.
Various bug fixes.
-
+
\subsection*{2020-06-02: Version 0.2}
Introduce \gate{subcircuit}; required rewriting how \Yquant{} internally positions vertically.
Provide simple macros to load circuits (or parts) from a file and to declare own custom gates.
-
+
\subsection*{2020-06-07: Version 0.2.1}
Introduce a macro to declare a lightweight custom gate, which is only a single box with custom content.
-
+
\subsection*{2020-06-13: Version 0.3}
Introduce support for the \pkg{qasm} language.
-
+
\subsection*{2020-07-11: Version 0.3.1}
Add legacy support for very old \TikZ{} versions such as the one used on the arXiv.
-
+
\subsection*{2020-08-24: Version 0.3.2}
Fix \href{https://github.com/projekter/yquant/issues/5}{\#5}: Can't draw circuits with more than 9 qubits.
-
+
\subsection*{2020-10-27: Version 0.3.3}
Fix \href{https://github.com/projekter/yquant/issues/6}{\#6}: shorten doesn't work for 2-qubit barriers. This fixes a bug in how the \texttt{shorten} keyword worked on \gate{barrier}s, which may require re\hyp assessing your chosen values.
+
+ \subsection*{2021-02-21: Version 0.4a}
+ Lots of internal fixes, most notably vertical alignment with subcircuits. \\
+ Introduce capability to perform vertical alignment with multi\hyp register gates. \\
+ Dramatic changes under the hood regarding horizontal positioning, which is now only determined in the drawing stage; this paves the way for delayed gates, which are planned for 0.4.
+ Also changes in the gate declaration interface. \\
+ Introduce compatibility layer, so that layout\hyp breaking changes will not become effective unless explicitly requested. \\
+ Separate register height into a height and depth key. \\
+ Introduce \texttt{overlay} key to disable height caluclation selectively. \\
+ Change register style declaration, so that this is now always equivalent to creating an unnamed register followed by an \gate{init} gate with the given text.
+ Note: This may be a \textbf{breaking change} that cannot be compatibility\hyp protected---if you used \TeX{} conditionals involving \tex!\idx! for creation labels of registers, you will now need to either \tex!\protect! them all or just capitalize their first letter (which corresponds to auto\hyp\tex!protect!ed versions for \texttt{compat} at least \texttt{0.4}). \\
+ Now use nodes for \gate{init} and \gate{output} gates. \\
+ Change behavior of \gate{hspace} and \gate{align}: Now also extend if the wire is discarded afterwards. \\
+ Introduce the commands \tex!\Ifnum!, \tex!\Ifcase!, \tex!\Or!, \tex!\Else!, \tex!\Fi!, \tex!\Unless! and \tex!\The! available for use within gates that behave like auto\hyp\tex!\protect!ed versions of their plain \TeX{} equivalents.
+
+ \subsection*{2021-03-27: Version 0.4}
+ New gate: \gate{inspect}. Various bug fixes. \\
+ Introduce the \texttt{direct control} feature: \gate{measure} gates can now substitute positive controls of future gates.
%END_FOLD
\end{document} \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-circuit.tex b/Master/texmf-dist/tex/latex/yquant/yquant-circuit.tex
index 2c9e114bdc5..52cb435b2f0 100644
--- a/Master/texmf-dist/tex/latex/yquant/yquant-circuit.tex
+++ b/Master/texmf-dist/tex/latex/yquant/yquant-circuit.tex
@@ -8,35 +8,45 @@
\pgfpointanchor{yquantbox}{#2}%
\edef\wirexpos{\the\pgf@x}%
\fi%
- \yquant@register@get@typeywire{#1}\wiretype\wireypos\wirelast%
- \edef\wirexprevpos{\expandafter\@firstoffour\wirelast}%
- \ifnum\wiretype=\yquant@register@type@none%
- % the clippings of the previous operator will for sure not be needed, but the type might be turned into an active one, so we need the last clipping.
- \yquant@register@set@lastwire{#1}{%
- {\wirexprevpos}{\wirexpos}{}%
- {\unexpanded\expandafter{\pgfshapeclippathhorzresult}}%
- }%
- \else%
- % append the previous `last' clipping to the old list and insert the new one
- \yquant@register@set@lastwire{#1}{%
- {\wirexprevpos}{\wirexpos}%
- {\unexpanded\expandafter\expandafter\expandafter{%
- \expandafter\@thirdandfourthoffour\wirelast%
- }%
+ \ifdim\wirexpos>0pt % may be negative for init gates
+ \yquant@register@get@typeywire{#1}\wiretype\wireypos\wirelast%
+ \edef\wirexprevpos{\expandafter\@firstoffour\wirelast}%
+ \ifnum\wiretype=\yquant@register@type@none%
+ % the clippings of the previous operator will for sure not be needed, but the type might be turned into an active one, so we need the last clipping.
+ \yquant@register@set@lastwire{#1}{%
+ {\wirexprevpos}{\wirexpos}{}%
+ {\unexpanded\expandafter{\pgfshapeclippathhorzresult}}%
}%
- {\unexpanded\expandafter{\pgfshapeclippathhorzresult}}%
- }%
+ \else%
+ % append the previous `last' clipping to the old list and insert the new one
+ \yquant@register@set@lastwire{#1}{%
+ {\wirexprevpos}{\wirexpos}%
+ {\unexpanded\expandafter\expandafter\expandafter{%
+ \expandafter\@thirdandfourthoffour\wirelast%
+ }%
+ }%
+ {\unexpanded\expandafter{\pgfshapeclippathhorzresult}}%
+ }%
+ \fi%
\fi%
\endgroup%
}
-% finishes the wires of all registers until x position #1
-\protected\def\yquant@circuit@endwires#1{%
- \ifcsname\yquant@prefix xshift\endcsname%
- \dimdef\yquant@env@end@xpos{#1+\csname\yquant@prefix xshift\endcsname}%
- \else%
- \def\yquant@env@end@xpos{#1}%
- \fi%
+% finishes the wires of all registers
+\protected\def\yquant@circuit@endwires{%
+ \expandafter\expandafter\expandafter\yquant@register@get@maxxrange%
+ \expandafter\expandafter\expandafter\yquant@circuit@endwires@x%
+ \expandafter\expandafter\expandafter1%
+ \expandafter\expandafter\expandafter{\csname\yquant@prefix registers\endcsname}%
+ % to have a symmetric situation, we extend again one separation at the end, unless this is supposed to be seamless and we don't have outputs (for seamless circuits with outputs, extend - since this extension will be between last register and output)
+ \ifyquant@env@seamless{%
+ \expandafter\unless\expandafter\ifx\csname\yquant@prefix outputs\endcsname\relax%
+ \dimdef\yquant@circuit@endwires@x{\yquant@circuit@endwires@x+\yquant@config@operator@sep}%
+ \fi%
+ }{%
+ \dimdef\yquant@circuit@endwires@x{\yquant@circuit@endwires@x+\yquant@config@operator@sep}%
+ }%
+ \let\yquant@circuit@endwires@finalize=\relax%
\yquant@for \yquant@circuit@endwires@i := 1 to \csname\yquant@prefix registers\endcsname {%
% we only extend the wire if it does not come from the outer circuit - this one would be responsible for the extension.
\ifcsname\yquant@prefix registermap@\yquant@circuit@endwires@i\endcsname%
@@ -45,7 +55,10 @@
\edef\storedleft{\the\pgf@picminx}%
\yquant@draw@wire\yquant@circuit@endwires@i1%
\global\pgf@picminx=\storedleft%
- \yquant@register@set@type\yquant@circuit@endwires@i\yquant@register@type@none%
+ \eappto\yquant@circuit@endwires@finalize{%
+ \yquant@register@set@type%
+ \yquant@circuit@endwires@i\noexpand\yquant@register@type@none%
+ }%
}\relax%
\else%
\yquant@draw@wire\yquant@circuit@endwires@i1%
@@ -55,14 +68,7 @@
% outputs the wire according to its previous instructions and prepares for a change in the wire style
\protected\def\yquant@circuit@flushwire#1{%
- \ifcsname\yquant@prefix registermap@#1\endcsname%
- % make sure drawing the wire does not affect our left bounding box position
- \edef\storedleft{\the\pgf@picminx}%
- \yquant@draw@wire{#1}0%
- \global\pgf@picminx=\storedleft%
- \else%
- \yquant@draw@wire{#1}0%
- \fi%
+ \yquant@draw@wire{#1}0%
\begingroup%
\yquant@register@get@lastwire{#1}\wirelast%
\yquant@register@set@lastwire{#1}{%
@@ -78,13 +84,13 @@
% BEGIN_FOLD Drawing control lines
% populates a drawing macro with the current control line with style #1 at position #2. Assumes a node called yquantbox is set up, and the \pgfshapeclippathvertresult was set up appropriately for this node. At the first call, \yquant@circuit@extendcontrolline@cmd must be \let to \empty and \yquant@circuit@extendcontrolline@prev to \relax.
\protected\def\yquant@circuit@extendcontrolline#1#2{%
+ \eappto\yquant@circuit@extendcontrolline@clip{%
+ \unexpanded\expandafter{\pgfshapeclippathvertresult}%
+ }%
\begingroup%
\tikzset{/yquant/every control line}%
\expandafter%
\endgroup%
- \eappto\yquant@circuit@extendcontrolline@clip{%
- \unexpanded\expandafter{\pgfshapeclippathvertresult}%
- }%
\expandafter\@tempdima\the\pgflinewidth%
\ifcase#1%
% no control (or to a discarded target, which we don't do)
@@ -207,17 +213,35 @@
\yquant@circuit@operator@maxpctrl%
\yquant@circuit@operator@maxnctrl%
\relax%
- % obtain the required minimal x position
- \yquant@register@get@maxxrange%
- \yquant@circuit@operator@x%
- \yquant@circuit@operator@minctrl%
- \yquant@circuit@operator@maxctrl%
- \dimdef\yquant@circuit@operator@x{%
- \yquant@circuit@operator@x+\yquant@config@operator@sep%
- }%
+}
+
+% restores the data captured for an uncontrolled operator and starts preparation
+% #1: \yquant@attrs@remaining
+% #2: \yquant@circuit@operator@targets
+% #3: \yquant@circuit@operator@mintarget
+% #4: \yquant@circuit@operator@maxtarget
+% #5: \yquant@circuit@operator@numtarget
+\protected\def\yquant@circuit@restore#1#2#3#4#5{%
+ \def\yquant@attrs@remaining{#1}%
+ \def\yquant@circuit@operator@targets{#2}%
+ \def\yquant@circuit@operator@mintarget{#3}%
+ \def\yquant@circuit@operator@maxtarget{#4}%
+ \def\yquant@circuit@operator@numtarget{#5}%
+ \yquant@circuit@operator@hasControlsfalse%
+ \let\yquant@circuit@operator@pctrls=\empty%
+ \def\yquant@circuit@operator@minpctrl{2147483647}%
+ \def\yquant@circuit@operator@maxpctrl{0}%
+ \let\yquant@circuit@operator@numpctrl=\yquant@circuit@operator@maxpctrl%
+ \let\yquant@circuit@operator@nctrls=\empty%
+ \let\yquant@circuit@operator@minnctrl=\yquant@circuit@operator@minpctrl%
+ \let\yquant@circuit@operator@maxnctrl=\yquant@circuit@operator@maxpctrl%
+ \let\yquant@circuit@operator@numnctrl=\yquant@circuit@operator@numpctrl%
+ \let\yquant@circuit@operator@minctrl=\yquant@circuit@operator@mintarget%
+ \let\yquant@circuit@operator@maxctrl=\yquant@circuit@operator@maxtarget%
}
% creates a subcircuit. Parameter registers must be filled in \yquant@circuit@subcircuit@params.
+% #1: style
\protected\def\yquant@circuit@subcircuit#1{%
\numdef\yquant@circuit@subcircuit@id{\yquant@env+1}%
\listcsxadd{\yquant@prefix subcircuits}{\yquant@circuit@subcircuit@id}%
@@ -232,46 +256,6 @@
\PackageError{yquant.sty}{Invalid subcircuit parameters count}%
{Too many parameters given.}%
\fi%
- \global\cslet{\yquant@prefix parameters}\yquant@circuit@subcircuit@param%
- \dimen0=\yquant@config@register@sep%
- % the first input must count all its height plus everything that is above it in the subcircuit as the height of the outer wire it is attached to
- \edef\firstinput{%
- \expandafter\expandafter\expandafter%
- \@firstoftwo\csname\yquant@prefix firstinput\endcsname%
- }%
- \edef\outerfirst{%
- \expandafter\expandafter\expandafter%
- \@secondoftwo\csname\yquant@prefix firstinput\endcsname%
- }%
- \dimen2=\yquant@register@get@height\firstinput\relax%
- \ifnum\firstinput>1 %
- \yquant@fordown \i := \the\numexpr\firstinput-1\relax downto 1 {%
- \advance\dimen2 by \dimexpr\yquant@register@get@height\i+%
- \yquant@register@get@depth\i+\dimen0\relax%
- }%
- \fi%
- % the last input must count all its depth plus everything that is below it in the subcircuit as the depth of the outer wire it is attached to
- \edef\lastinput{%
- \expandafter\expandafter\expandafter%
- \@firstoftwo\csname\yquant@prefix lastinput\endcsname%
- }%
- \edef\outerlast{%
- \expandafter\expandafter\expandafter%
- \@secondoftwo\csname\yquant@prefix lastinput\endcsname%
- }%
- \dimen4=\yquant@register@get@depth\lastinput\relax%
- \ifnum\lastinput<\csname\yquant@prefix registers\endcsname%
- \yquant@for \i := \the\numexpr\lastinput+1\relax to \csname\yquant@prefix registers\endcsname {%
- \advance\dimen4 by \dimexpr\yquant@register@get@height\i+%
- \yquant@register@get@depth\i+\dimen0\relax%
- }%
- \fi%
- \begingroup%
- \let\yquant@prefix=\yquant@parent%
- \yquant@register@update@height\outerfirst{\the\dimen2}%
- \yquant@register@update@depth\outerlast{\the\dimen4}%
- \endgroup%
- % we cannot make more precise statements about the inputs in between - for example, if input 1 is mapped to outer wire 1 and input 2 to outer wire 5, how to split the heights/depth appropriately between the outer wires 1-5?
\yquant@env@end%
\endgroup%
}
@@ -279,7 +263,13 @@
% BEGIN_FOLD Helpers for operator callbacks
% turn a wire into a different type
\def\yquant@circuit@settype#1{%
- \yquant@circuit@flushwire{#1}%
+ \unless\if\yquant@register@get@type{#1}\yquant@circuit@settype@to %
+ \yquant@circuit@flushwire{#1}%
+ \yquant@register@set@type{#1}{\yquant@circuit@settype@to}%
+ \fi%
+}
+
+\protected\def\yquant@circuit@settype@prepare#1{%
\yquant@register@set@type{#1}{\yquant@circuit@settype@to}%
}
@@ -296,95 +286,51 @@
% performs an alignment of all registers specified in the argument; that is, the next operation on any of the listed registers will be after the maximum position of all of them
% #1: arbitrary register list
\protected\def\yquant@circuit@align#1{%
- \begingroup%
- \yquant@register@get@maxxlist\x{#1}%
- \def\do##1{%
- \yquant@register@set@x{##1}\x%
- }%
- \dolistloop{#1}%
- \endgroup%
+ \csxappto{\yquant@prefix draw}{%
+ \yquant@draw@hspace{#1}{0pt}%
+ }%
}
% introduces a horizontal skip (= invisible operator of given width) among the registers; that is, those registers are first aligned, then skipped by the given amount.
% #1: arbitrary register list
% #2: skip width
\protected\def\yquant@circuit@hspace#1#2{%
- \begingroup%
- \yquant@register@get@maxxlist\x{#1}%
- \dimdef\x{\x+#2}%
- \def\do##1{%
- \yquant@register@set@x{##1}\x%
- }%
- \dolistloop{#1}%
- \endgroup%
+ \csxappto{\yquant@prefix draw}{%
+ \yquant@draw@hspace{#1}{#2}%
+ }%
}
% applies an action to wires a list of registers and causes them to be redrawn
-% #1: action
-% #2: arbitrary register list
-% #3: parameter(s)
-\protected\def\yquant@circuit@actonwires#1#2#3{%
+% #1: action for prepare
+% #2: action for draw
+% #3: arbitrary register list
+% #4: parameter(s)
+\protected\def\yquant@circuit@actonwires#1#2#3#4{%
\begingroup%
\let\tmp=\empty%
\def\do##1{%
% We do not extend the wire: a register that is discarded somewhere does not make
% sense, only right after some application (which is supposed to already have
% extended the wire appropriately).
- \appto\tmp{#1{##1}#3}%
+ \eappto\tmp{#2{##1}#4}%
+ #1{##1}#4%
}%
- \dolistloop{#2}%
+ \dolistloop{#3}%
\csxappto{\yquant@prefix draw}{\tmp}%
\endgroup%
}
% sets the output of wires
% #1: arbitrary register list
-\protected\def\yquant@circuit@output#1{%
- \csxappto{\yquant@prefix outputs}%
- {\noexpand\yquant@circuit@output@do%
- {\noexpand#1}% there is nothing to expand - except the first token, which might be \yquant@register@multi, and we need to preserve this.
+\protected\def\yquant@circuit@output{%
+ \protected\def\idx{}%
+ \protected@csxappto{\yquant@prefix outputs}%
+ {\yquant@circuit@restore%
{\yquant@attrs@remaining}%
- {\unexpanded\expandafter{\yquant@lang@attr@value}}%
+ {\unexpanded\expandafter{\yquant@circuit@operator@targets}}%
+ {\yquant@circuit@operator@mintarget}{\yquant@circuit@operator@maxtarget}%
+ {\yquant@circuit@operator@numtarget}%
+ \yquant@prepare{\yquant@lang@attr@value}{}%
}%
}
-
-\protected\long\def\yquant@circuit@output@do#1#2#3{%
- % this must only be called at the end of an environment, where \yquant@env@end@xpos is set up properly! It not only has to provide the appropriate drawing commands for later, but also has to measure the actual width of the outputs, which is required for proper subcircuit positioning.
- \def\do##1{%
- \pgfinterruptboundingbox%
- \yquant@env@virtualize@path%
- \ifyquant@firsttoken\yquant@register@multi{##1}{%
- \csxappto{\yquant@prefix draw}%
- {\yquant@draw@output@multi%
- \yquant@circuit@output@do@multi@@extract##1{\unexpanded{#3}}}%
- \yquant@draw@@output@multi{#3}%
- }{%
- \csgappto{\yquant@prefix draw}%
- {\yquant@draw@output@single{##1}{#3}}%
- \yquant@draw@@output@single{##1}{#3}%
- \yquant@register@update@height{##1}{\the\pgf@picmaxy}%
- \yquant@register@update@depth{##1}{\the\dimexpr-\pgf@picminy\relax}%
- }%
- \ifdim\pgf@picmaxx>\csname\yquant@prefix xmax\endcsname%
- \csxdef{\yquant@prefix xmax}{\the\pgf@picmaxx}%
- \fi%
- \endpgfinterruptboundingbox%
- }%
- \yquant@draw@output@group{#2}%
- \csgappto{\yquant@prefix draw}{%
- \yquant@draw@output@group{#2}%
- }%
- % \dolistloop will carry out one \expandafter on the argument; but this expansion step
- % is already done. If #1 starts with \yquant@register@multi, this will be expanded once
- % despite \protected, so insert some expand-to-nothing token first.
- \dolistloop{\empty#1}%
- \csgappto{\yquant@prefix draw}{%
- \yquant@draw@output@endgroup%
- }%
- \yquant@draw@output@endgroup%
-}
-
-\def\yquant@circuit@output@do@multi@@extract#1#2#3#4#5{%
- {#2}{#3}{#5}%
-}
% END_FOLD \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-config.tex b/Master/texmf-dist/tex/latex/yquant/yquant-config.tex
index a6765d14850..d5844480ee0 100644
--- a/Master/texmf-dist/tex/latex/yquant/yquant-config.tex
+++ b/Master/texmf-dist/tex/latex/yquant/yquant-config.tex
@@ -13,21 +13,53 @@
\decoration{\pgfkeysvalueof{/pgf/decoration/post}}%
}%
}
+
+% BEGIN_FOLD Circuit layout
+\ifnum\yquant@compat<2 %
+ \pgfqkeys{/yquant}{%
+ register/minimum height/.code=%
+ {\dimdef\yquant@config@register@minimum@height{.5\dimexpr#1\relax}%
+ \let\yquant@config@register@minimum@depth=\yquant@config@register@minimum@height}%
+ }
+\else%
+ \pgfqkeys{/yquant}{%
+ register/minimum height/.code=%
+ {\dimdef\yquant@config@register@minimum@height{#1}},%
+ register/minimum depth/.code=%
+ {\dimdef\yquant@config@register@minimum@depth{#1}}%
+ }
+\fi
\pgfqkeys{/yquant}{%
- every circuit/.style={%
- every node/.prefix style={transform shape},%
- every label/.prefix style={transform shape=false}% TODO: no, we don't really want this, but pgf bug #843 requires this if we still want to have `label position` available
- },%
- % register settings
- register/default name/.store in=%
- \yquant@config@register@default@name,%
- register/minimum height/.code=%
- {\dimdef\yquant@config@register@minimum@height{#1}},%
register/separation/.code=%
{\dimdef\yquant@config@register@sep{#1}},%
- % register label style
- every label/.style=%
- {shape=yquant-text, anchor=center, align=right},%
+ operator/minimum width/.code=%
+ {\dimdef\yquant@config@operator@minimum@width{#1}},%
+ operator/separation/.code=%
+ {\dimdef\yquant@config@operator@sep{#1}},%
+ operator/multi warning/.is if=%
+ yquant@config@operator@multi@warn%
+}%
+% END_FOLD
+% BEGIN_FOLD Register creation
+\pgfqkeys{/yquant}{%
+ register/default name/.store in=%
+ \yquant@config@register@default@name%
+}
+\ifnum\yquant@compat<2 %
+ \pgfqkeys{/yquant}{%
+ every label/.style=%
+ {shape=yquant-init, anchor=center, align=right, outer xsep=2pt},%
+ every multi label/.style=%
+ {draw, decoration={gapped brace, mirror, raise=2pt}, decorate}%
+ }
+\else
+ \pgfqkeys{/yquant}{%
+ every label/.style=%
+ {shape=yquant-init, anchor=center, align=right, outer xsep=2pt,%
+ /yquant/operator/if multi={draw, decoration={gapped brace, mirror, raise=2pt}, decorate}}%
+ }
+\fi
+\pgfqkeys{/yquant}{
every initial label/.style=%
{anchor=east},%
every qubit label/.style=%
@@ -35,25 +67,51 @@
every cbit label/.style=%
{},%
every qubits label/.style=%
- {},%
- every multi label/.style=%
- {shift={(-.075, 0)}, draw, decoration={gapped brace, mirror}, decorate, /yquant/gapped brace/apply shift,%
- every node/.append style={shape=yquant-text, anchor=east, align=right, shift={(-.05, 0)}, pos=-1}},%
- every input label/.style=%
- {},%
- % output label styles
- every output/.style=%
- {shape=yquant-text, anchor=west, align=left},%
+ {}%
+}
+\ifnum\yquant@compat<2 %
+ \pgfqkeys{/yquant}{%
+ every input label/.style=%
+ {}%
+ }%
+\fi%
+% END_FOLD
+% BEGIN_FOLD Register outputs
+\ifnum\yquant@compat<2 %
+ \pgfqkeys{/yquant}{%
+ every output/.style=%
+ {shape=yquant-output, anchor=west, align=left, outer xsep=2pt},%
+ every multi output/.style=%
+ {draw, decoration={gapped brace, raise=2pt}, decorate}%
+ }
+\else
+ \pgfqkeys{/yquant}{%
+ every output/.style=%
+ {shape=yquant-output, anchor=west, align=left, outer xsep=2pt,%
+ /yquant/operator/if multi={draw, decoration={gapped brace, raise=2pt}, decorate}}%
+ }
+\fi
+\pgfqkeys{/yquant}{%
every qubit output/.style=%
{},%
every cbit output/.style=%
{},%
every qubits output/.style=%
- {},%
- every multi output/.style=%
- {shift={(.075, 0)}, draw, decoration={gapped brace}, decorate, /yquant/gapped brace/apply shift,%
- every node/.append style={shape=yquant-text, anchor=west, align=left, shift={(.05, 0)}, pos=-1}},%
- % wire style
+ {}%
+}
+% END_FOLD
+% BEGIN_FOLD General styling
+\pgfqkeys{/yquant}{%
+ every circuit/.style={%
+ every node/.prefix style={transform shape}
+ }%
+}
+\@ifpackagelater{pgf}{2020/09/31}\relax{
+ \pgfkeys{/yquant/every circuit/.append style={%
+ every label/.prefix style={transform shape=false}%
+ }}
+}
+\pgfqkeys{/yquant}{%
every wire/.style=%
{draw},%
every qubit wire/.style=%
@@ -62,14 +120,6 @@
{},%
every qubits wire/.style=%
{},%
- % operator settings
- operator/separation/.code=%
- {\dimdef\yquant@config@operator@sep{#1}},%
- operator/minimum width/.code=%
- {\dimdef\yquant@config@operator@minimum@width{#1}},%
- operator/multi warning/.is if=%
- yquant@config@operator@multi@warn,%
- % operator style: control
every control line/.style=%
{draw},%
every control/.style=%
@@ -78,16 +128,10 @@
{fill=black},%
every negative control/.style=%
{draw},%
- % operator style: main part
every operator/.style=%
{anchor=center},%
- operator/multi main/.is if=%
- yquant@config@operator@multi@main,%
- operator/multi as single/.style=%
- {/yquant/every multi line/.style=/yquant/every control line},%
every multi line/.style=%
{draw, decoration={snake, amplitude=.25mm, segment length=5pt}, decorate},%
- % overwriting all styles
this operator/.style=%
{},%
this control/.style=%
@@ -101,9 +145,66 @@
{/yquant/this operator/.append style={#1},%
/yquant/every control line/.append style={#1},%
/yquant/this control/.append style={#1}},%
- % different operator appearances
+ operator/multi as single/.style=%
+ {/yquant/every multi line/.style=/yquant/every control line},%
+ operator/if multi/.code=%
+ {\ifyquant@config@operator@multi\pgfkeysalso{#1}\fi},%
+ circuit/seamless/.is if=yquant@config@circuit@seamless,%
+ every post measurement control/.is choice,
+ every post measurement control/indirect/.code={%
+ \undef\yquant@lang@attr@directcontrol%
+ },%
+ every post measurement control/direct/.code={%
+ \let\yquant@lang@attr@directcontrol=\relax%
+ }%
+}
+% END_FOLD
+% BEGIN_FOLD Styles for operators
+\ifnum\yquant@compat<2 %
+ \pgfqkeys{/yquant}{%
+ operators/every barrier/.style=%
+ {shape=yquant-line, dashed, draw}%
+ }
+\else
+ \pgfqkeys{/yquant}{%
+ operators/every barrier/.style=%
+ {shape=yquant-line, dashed, draw, shorten <= -1mm, shorten >= -1mm}
+ }
+\fi
+\pgfqkeys{/yquant}{%
operators/every box/.style=%
{shape=yquant-rectangle, draw, align=center, inner xsep=1mm, x radius=2mm, y radius=2.47mm},%
+}
+\ifnum\yquant@compat<2 %
+ \pgfqkeys{/yquant}{%
+ operators/every custom gate/.style=%
+ {/yquant/operators/subcircuit/frameless, /yquant/register/default name=}%
+ }
+\else
+ \pgfqkeys{/yquant}{%
+ operators/every custom gate/.style=%
+ {/yquant/operators/subcircuit/seamless}%
+ }
+\fi
+\pgfqkeys{/yquant}{%
+ operators/every dmeter/.style=%
+ {shape=yquant-dmeter, x radius=2mm, y radius=2mm, draw},
+ % every h is implicitly defined during gate declaration
+ operators/every inspect/.style=%
+ {shape=yquant-output, align=left, outer xsep=.3333em, y radius=2.47mm,%
+ /yquant/operator/if multi={draw, decoration={gapped brace, raise=2pt}, decorate}},%
+ operators/every measure/.style=%
+ {shape=yquant-measure, x radius=4mm, y radius=2.5mm, draw},%
+ operators/every measure meter/.style=%
+ {draw, -{Latex[length=2.5pt]}},%
+ operators/every not/.style=%
+ {shape=yquant-oplus, radius=1.3mm, draw},%
+ operators/every pauli/.style=%
+ {/yquant/operators/every box},%
+ operators/every phase/.style=%
+ {shape=yquant-circle, radius=.5mm, fill},%
+ operators/every slash/.style=%
+ {shape=yquant-slash, x radius=.5mm, y radius=.7mm, draw},%
operators/every subcircuit/.style=%
{},%
operators/every subcircuit box/.style=%
@@ -114,181 +215,61 @@
{},%
this subcircuit box style/.style=%
{/yquant/operators/this subcircuit box/.append style={#1}},%
- operators/every custom gate/.style=%
- {/yquant/operators/this subcircuit box/.append style={draw=none, inner sep=0pt},%
- /yquant/register/default name=},
- % every h, every x, every y, every z are implicitly defined during gate declaration
- operators/every pauli/.style=%
- {/yquant/operators/every box},%
- operators/every phase/.style=%
- {shape=yquant-circle, radius=.5mm, fill},%
- operators/every zz/.style=%
- {shape=yquant-circle, radius=.5mm, fill},%
- operators/every xx/.style=%
- {shape=yquant-rectangle, radius=.75mm, draw},%
- operators/every slash/.style=%
- {shape=yquant-slash, x radius=.5mm, y radius=.7mm, draw},%
+ operators/subcircuit/frameless/.style=
+ {/yquant/operators/this subcircuit box/.append style={draw=none, inner sep=0pt}},%
+ operators/subcircuit/seamless/.code=%
+ {\pgfkeysalso{/yquant/operators/subcircuit/frameless, /yquant/register/default name=}%
+ \letcs\yquant@prevseamless{\yquant@prefix seamless}%
+ \yquant@config@circuit@seamlesstrue},
operators/every swap/.style=%
{shape=yquant-swap, radius=.75mm, draw},%
- operators/every not/.style=%
- {shape=yquant-oplus, radius=1.3mm, draw},%
- operators/every measure/.style=%
- {shape=yquant-measure, x radius=4mm, y radius=2.5mm, draw},%
- operators/every measure meter/.style=%
- {draw, -{Latex[length=2.5pt]}},%
- operators/every dmeter/.style=%
- {shape=yquant-dmeter, x radius=2mm, y radius=2mm, draw},%
- operators/every barrier/.style=%
- {shape=yquant-line, dashed, draw},%
operators/every wave/.style=%
+ {shape=yquant-circle, radius=.5mm, fill}%
+ % every x is implicitly defined during gate declaration
+ operators/every xx/.style=%
+ {shape=yquant-rectangle, radius=.75mm, draw},%
+ % every y is implicitly defined during gate declaration
+ % every z is implicitly defined during gate declaration
+ operators/every zz/.style=%
{shape=yquant-circle, radius=.5mm, fill},%
- /pgf/decoration/from to/.store in=\pgfdecorationsegmentfromto,%
- gapped brace/apply shift/.code={%
- \let\tikz@timer@line=\yquant@gappedbrace@timer%
- },%
}
+% END_FOLD
+% BEGIN_FOLD Internal styles (undocument, do not use!)
+\pgfqkeys{/yquant}{%
+ internal/move label/.code=%
+ {\yquant@config@operator@position@rightaligntrue},
+ internal/no advance/.code=%
+ {\unless\ifyquantmeasuring% We don't draw subcircuits during measuring time, but we need their advancement
+ \yquant@config@operator@position@advancefalse%
+ \fi},
+ internal/multi main/.is if=%
+ yquant@config@internal@multi@main,%
+}
+\ifnum\yquant@compat<2 %
+ \pgfqkeys{/yquant}{%
+ internal/squeeze slash/.code=%
+ {\dimdef\yquant@config@operator@sep{.5\dimexpr\yquant@config@operator@sep-\pgflinewidth\relax}%
+ \yquant@config@operator@position@advancefalse},%
+ }
+\else%
+ \pgfqkeys{/yquant}{%
+ internal/squeeze slash/.code={}%
+ }
+\fi
+% END_FOLD
\def\yquant@config@register@default@name{\regidx}
-\def\yquant@config@register@minimum@height{3mm}
+\def\yquant@config@register@minimum@height{1.5mm}
+\def\yquant@config@register@minimum@depth{1.5mm}
\def\yquant@config@register@sep{1mm}
\def\yquant@config@operator@sep{1mm}
\def\yquant@config@operator@minimum@width{5mm}
-\newif\ifyquant@config@operator@multi@main%
-\yquant@config@operator@multi@maintrue
+\newif\ifyquant@config@internal@multi@main%
+\yquant@config@internal@multi@maintrue
\newif\ifyquant@config@operator@multi@warn
\yquant@config@operator@multi@warntrue
-\def\pgfdecorationsegmentfromto{0-1}%
-
-\protected\def\yquant@gappedbrace@extract#1-#2\yquant@sep{%
- \dimdef\from{#1\pgfdecoratedremainingdistance}%
- \dimdef\to{#2\pgfdecoratedremainingdistance}%
-}
-% This function is set to replace the transformation that changes the fraction value specified in the node property pos by a computation of the correct value for the gappedbrace decoration. It thus requires \pgfdecorationsegmentfromto to be already set up properly. Only if the special position -1 is given, these transformations are applied; else, the default behavior is reproduced (\tikz@timer@line).
-\protected\def\yquant@gappedbrace@timer{%
- \ifdim\tikz@time pt=-1pt %
- % first set \pgfdecoratedremainingdistance appropriately
- \pgfpointdiff\tikz@timer@start\tikz@timer@end%
- \pgfmathsqrt@{\dimexpr\pgf@x*\pgf@x/65536+\pgf@y*\pgf@y/65536\relax\@gobbletwo}%
- \pgfdecoratedremainingdistance=\pgfmathresult pt %
- % now perform the transformation
- \pgf@xc=\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance%
- \expandafter\forcsvlist\expandafter\yquant@gappedbrace@shiftloop%
- \expandafter{\pgfdecorationsegmentfromto}%
- % and finally let us return the desired position, just ignoring \tikz@time...
- \pgftransformlineattime{\pgfdecorationsegmentaspect}{\tikz@timer@start}{\tikz@timer@end}%
- \else%
- \pgftransformlineattime{\tikz@time}{\tikz@timer@start}{\tikz@timer@end}%
- \fi%
-}
-\def\yquant@gappedbrace@shiftloop#1{%
- \yquant@gappedbrace@extract#1\yquant@sep%
- \unless\ifdim\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance<\from %
- \unless\ifdim\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance>\to %
- % be careful about arch positions at the border
- \ifdim\dimexpr\to-\from\relax<2\pgfdecorationsegmentamplitude %
- % The arch is larger than the segment. We do not draw a line to it or an end line and place it in the mid of the segment, even if it is too short (this issues one extra \pgfpathmoveto command, but catching this rare case is not worth the effort).
- \edef\pgfdecorationsegmentaspect{\pgfmath@tonumber{\dimexpr%
- .5\dimexpr\from+\to\relax*65536/\pgfdecoratedremainingdistance%
- \relax}}%
- \else%
- % The segment is large enough to cover the whole arch. But maybe we are too close at the border?
- \ifdim\dimexpr\pgf@xc-\pgfdecorationsegmentamplitude\relax<\from %
- \pgf@xc=\dimexpr\from+\pgfdecorationsegmentamplitude\relax%
- \fi%
- \ifdim\dimexpr\pgf@xc+\pgfdecorationsegmentamplitude\relax>\to %
- \pgf@xc=\dimexpr\to-\pgfdecorationsegmentamplitude\relax%
- \fi%
- \edef\pgfdecorationsegmentaspect{\pgfmath@tonumber{\dimexpr%
- \dimexpr\pgf@xc*65536/\pgfdecoratedremainingdistance%
- \relax}}%
- \fi%
- \expandafter\expandafter\expandafter\listbreak%
- \fi%
- \fi%
-}
-\def\yquant@gappedbrace@loop#1{%
- \yquant@gappedbrace@extract#1\yquant@sep%
- \unless\ifdim\from=0pt %
- \pgfpathmoveto{%
- \pgfqpoint{\from}{.5\pgfdecorationsegmentamplitude}%
- }%
- \fi%
- \unless\ifdim\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance<\from %
- \unless\ifdim\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance>\to %
- % be careful about arch positions at the border
- \ifdim\dimexpr\to-\from\relax<2\pgfdecorationsegmentamplitude %
- % The arch is larger than the segment. We do not draw a line to it or an end line and place it in the mid of the segment, even if it is too short (this issues one extra \pgfpathmoveto command, but catching this rare case is not worth the effort).
- \pgfpathmoveto{%
- \pgfqpoint{\dimexpr.5\dimexpr\from+\to\relax-\pgfdecorationsegmentamplitude\relax}%
- {.5\pgfdecorationsegmentamplitude}%
- }%
- \edef\to{\the\pgfdecoratedremainingdistance}% to prevent the final line, we do not need "to" any more
- \else%
- % The segment is large enough to cover the whole arch. But maybe we are too close at the border?
- \ifdim\dimexpr\pgf@xc-\pgfdecorationsegmentamplitude\relax<\from %
- \pgf@xc=\dimexpr\from+\pgfdecorationsegmentamplitude\relax%
- \fi%
- \ifdim\dimexpr\pgf@xc+\pgfdecorationsegmentamplitude\relax>\to %
- \pgf@xc=\dimexpr\to-\pgfdecorationsegmentamplitude\relax%
- \fi%
- % Both cases can't occur at the same time in this \else clause.
- \pgfpathlineto{%
- \pgfqpoint{\dimexpr\pgf@xc-\pgfdecorationsegmentamplitude\relax}%
- {.5\pgfdecorationsegmentamplitude}%
- }%
- \fi%
- \pgfpathcurveto{%
- \pgfqpoint{\dimexpr\pgf@xc-.5\pgfdecorationsegmentamplitude\relax}%
- {.5\pgfdecorationsegmentamplitude}%
- }{%
- \pgfqpoint{\dimexpr\pgf@xc-.15\pgfdecorationsegmentamplitude\relax}%
- {.7\pgfdecorationsegmentamplitude}%
- }{%
- \pgfqpoint{\pgf@xc}{\pgfdecorationsegmentamplitude}%
- }%
- \pgfpathcurveto{%
- \pgfqpoint{\dimexpr\pgf@xc+.15\pgfdecorationsegmentamplitude\relax}%
- {.7\pgfdecorationsegmentamplitude}%
- }{%
- \pgfqpoint{\dimexpr\pgf@xc+.5\pgfdecorationsegmentamplitude\relax}%
- {.5\pgfdecorationsegmentamplitude}%
- }{%
- \pgfqpoint{\dimexpr\pgf@xc+\pgfdecorationsegmentamplitude\relax}%
- {.5\pgfdecorationsegmentamplitude}%
- }%
- \fi%
- \fi%
- \unless\ifdim\to=\pgfdecoratedremainingdistance %
- \pgfpathlineto{%
- \pgfqpoint{\to}{.5\pgfdecorationsegmentamplitude}%
- }%
- \fi%
-}
-% This is a variant of the brace in pathreplacing that allows for holes
-\pgfdeclaredecoration{gapped brace}{final}{%
- \state{final}{%
- \pgf@xc=\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance%
- \pgfpathcurveto{%
- \pgfqpoint{.15\pgfdecorationsegmentamplitude}{.3\pgfdecorationsegmentamplitude}%
- }{%
- \pgfqpoint{.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}%
- }{%
- \pgfqpoint{\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}%
- }%
- \expandafter\forcsvlist\expandafter\yquant@gappedbrace@loop%
- \expandafter{\pgfdecorationsegmentfromto}%
- \pgfpathlineto{%
- \pgfqpoint{\dimexpr\pgfdecoratedremainingdistance-\pgfdecorationsegmentamplitude\relax}%
- {.5\pgfdecorationsegmentamplitude}%
- }%
- \pgfpathcurveto{%
- \pgfqpoint{\dimexpr\pgfdecoratedremainingdistance-.5\pgfdecorationsegmentamplitude\relax}%
- {.5\pgfdecorationsegmentamplitude}%
- }{%
- \pgfqpoint{\dimexpr\pgfdecoratedremainingdistance-.15\pgfdecorationsegmentamplitude\relax}%
- {.3\pgfdecorationsegmentamplitude}%
- }{%
- \pgfqpoint{\pgfdecoratedremainingdistance}{0pt}%
- }%
- }%
-}% \ No newline at end of file
+\newif\ifyquant@config@operator@position@rightalign
+\newif\ifyquant@config@operator@position@advance
+\yquant@config@operator@position@advancetrue
+\newif\ifyquant@config@circuit@seamless
+\newif\ifyquant@config@operator@multi \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex b/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex
index a74197192c7..1bf8d3fb19a 100644
--- a/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex
+++ b/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex
@@ -1,31 +1,96 @@
-% BEGIN_FOLD Actual drawing at shipout
\newcount\yquant@draw@@currentcontroltype%
-\protected\def\yquant@draw@group#1#2#3#4#5{%
- \begingroup%
- \ifcsname\yquant@prefix xshift\endcsname%
- \dimdef\yquant@draw@@x{#1+\csname\yquant@prefix xshift\endcsname}%
- \else%
- \def\yquant@draw@@x{#1}%
+\protected\def\yquant@draw@init#1#2{%
+ \ifcsname\yquant@prefix registermap@#1\endcsname%
+ % for connected subcircuit wires, check if this actually changes the type [happens for formerly discarded output wires] and flush the wire if necessary
+ \edef\yquant@draw@init@type{\yquant@register@get@type{#1}}%
+ \unless\if\yquant@draw@init@type#2\relax%
+ \yquant@circuit@flushwire{#1}%
+ \ifx\yquant@draw@init@type\yquant@register@type@none%
+ % in case the wire was discarded before, forget about the lastx position, it should always start with the others
+ \yquant@register@get@lastwire{#1}\wirelast%
+ \expandafter\expandafter\expandafter\ifstrempty\expandafter\expandafter\expandafter{%
+ \expandafter\@thirdoffour\wirelast%
+ }{%
+ \yquant@register@set@lastwire{#1}{%
+ {\yquant@draw@subcircuit@wirestart}{\yquant@draw@subcircuit@wirestart}{}%
+ {\unexpanded\expandafter\expandafter\expandafter{%
+ \expandafter\@fourthoffour\wirelast%
+ }}%
+ }%
+ }\relax
+ \fi%
+ \yquant@register@set@type{#1}{#2}%
\fi%
+ \else%
+ % for new wires, reset the type, and if this a subcircuit, put the appropriate x position in place. It might have changed from its initial value during preparation stage
+ \yquant@register@set@type{#1}{#2}%
+ \ifdefined\yquant@draw@subcircuit@wirestart%
+ \yquant@register@set@x{#1}{\yquant@draw@subcircuit@wirestart}%
+ \yquant@register@set@lastwire{#1}{%
+ {\yquant@draw@subcircuit@wirestart}{\yquant@draw@subcircuit@wirestart}{}{}%
+ }%
+ \fi%
+ \fi%
+}
+
+\def\yquant@draw@subcircuit@leftpos{0pt}% outermost circuit: 0pt
+\protected\long\def\yquant@draw@group#1#2#3#4#5#6{%
+ \begingroup%
+ \yquant@register@get@maxxlist\yquant@draw@@x{#6}%
\ifx F#2%
\yquant@draw@@currentcontroltype=0 %
\else%
- \yquant@draw@@currentcontroltype=\yquant@register@get@type{#2}\relax%
+ \yquant@draw@@currentcontroltype=#2 %
\fi%
\let\yquant@circuit@extendcontrolline@cmd=\empty%
\let\yquant@circuit@extendcontrolline@prev=\relax%
\let\yquant@circuit@extendcontrolline@clip=\empty%
\let\yquant@circuit@extendmultiline@total=\empty%
- \yquant@langhelper@list@attrs%
- % If the quotes library is loaded, activate it. (else, this is by default \relax)
- \tikz@enable@node@quotes%
- \yquant@set{#3}%
+ \def\yquant@draw@@width{#1}%
\def\yquant@draw@@style{#4}%
\def\yquant@draw@@content{#5}%
\def\yquant@draw@@idx@content{0}%
\def\yquant@draw@@idx@pcontrol{0}%
\def\yquant@draw@@idx@ncontrol{0}%
+ % If the quotes library is loaded, activate it. (else, this is by default \relax)
+ \tikz@enable@node@quotes%
+ \yquant@config@operator@position@rightalignfalse%
+ \yquant@config@operator@position@advancetrue%
+ \yquant@set{#3}%
+ % if the operator is right-aligned, we will not advance, as we must assume that the x position is already chosen appropriately
+ \ifyquant@config@operator@position@rightalign%
+ % for rightalign, we instead overwrite the lastx configurations, so that the outgoing wire starts after the operator.
+ \forlistloop\yquant@draw@group@rightadvance{#6}%
+ \else%
+ \ifyquant@env@seamless{%
+ \unless\ifdim\yquant@draw@@x=\yquant@draw@subcircuit@leftpos%
+ \dimdef\yquant@draw@@x{%
+ \yquant@draw@@x+\yquant@config@operator@sep%
+ }%
+ \fi%
+ }{%
+ \dimdef\yquant@draw@@x{%
+ \yquant@draw@@x+\yquant@config@operator@sep%
+ }%
+ }%
+ \ifyquant@config@operator@position@advance%
+ \dimdef\newx{\yquant@draw@@x+#1}%
+ \forlistloop\yquant@draw@group@advance{#6}%
+ \fi%
+ \dimdef\yquant@draw@@x{\yquant@draw@@x+.5\dimexpr#1\relax}%
+ \fi%
+}
+
+\protected\def\yquant@draw@group@advance#1{%
+ \yquant@register@set@x{#1}\newx%
+}
+
+\protected\def\yquant@draw@group@rightadvance#1{%
+ \ifcsname\yquant@prefix registermap@#1\endcsname%
+ % for connected subcircuit wires, make sure to flush the wire until the beginning.
+ \yquant@circuit@flushwire{#1}%
+ \fi%
}
\protected\def\yquant@draw@endgroup#1#2#3{%
@@ -57,8 +122,83 @@
\endgroup%
}
-\protected\long\def\yquant@draw@single#1#2{%
+\protected\def\yquant@draw@injectiongroup#1#2\yquant@draw@endinjectiongroup#3#4#5{%
+ \csdef{yquant@draw@@injection@#1}{%
+ \yquant@draw@begininjection#2\yquant@draw@stopinjection{#3}{#4}{#5}%
+ }%
+}
+
+\protected\long\def\yquant@draw@begininjection#1#2#3#4#5#6{%
+ % this is called within another draw group, so lots of things are already set up
+ \begingroup%
+ \def\yquant@draw@@style{#4}%
+ \def\yquant@draw@@content{#5}%
+ \let\yquant@draw@@idx@content=\yquant@draw@@idx@pcontrol%
+ \yquant@set{#3}% this will accumulate with outer styles from the enclosing draw group, but there is nothing we can do about it
+}
+
+\protected\def\yquant@draw@stopinjection#1#2#3{%
+ \ifcase#3\relax%
+ \or%
+ \yquant@draw@alias@ctrl{#2}n%
+ \or%
+ \yquant@draw@alias@ctrl{#2}p%
+ \or%
+ \yquant@draw@alias@ctrl{#2}p%
+ \yquant@draw@alias@ctrl{#2}n%
+ \or%
+ \yquant@draw@alias{#2}%
+ \or%
+ \yquant@draw@alias{#2}%
+ \yquant@draw@alias@ctrl{#2}n%
+ \or%
+ \yquant@draw@alias{#2}%
+ \yquant@draw@alias@ctrl{#2}p%
+ \or%
+ \yquant@draw@alias{#2}%
+ \yquant@draw@alias@ctrl{#2}p%
+ \yquant@draw@alias@ctrl{#2}n%
+ \fi%
+ \edef\process{%
+ \endgroup%
+ \def\noexpand\yquant@circuit@extendcontrolline@clip{%
+ \unexpanded\expandafter{\yquant@circuit@extendcontrolline@clip}%
+ }%
+ \def\noexpand\yquant@circuit@extendcontrolline@prev{%
+ \unexpanded\expandafter{\yquant@circuit@extendcontrolline@prev}%
+ }%
+ \def\noexpand\yquant@circuit@extendcontrolline@cmd{%
+ \unexpanded\expandafter{\yquant@circuit@extendcontrolline@cmd}%
+ }%
+ \def\noexpand\yquant@circuit@extendmultiline@total{%
+ \unexpanded\expandafter{\yquant@circuit@extendmultiline@total}%
+ }%
+ \def\noexpand\yquant@draw@@idx@pcontrol{\yquant@draw@@idx@content}%
+ }%
+ \process%
+}
+
+\protected\def\yquant@draw@inject#1{%
+ \csname yquant@draw@@injection@#1\endcsname%
+ \csgundef{yquant@draw@@injection@#1}%
+}
+
+\protected\def\yquant@draw@inject@outer#1{%
+ % we thought we wanted to inject #1, however, this was not valid; so now insert it directly.
+ \expandafter\expandafter\expandafter\yquant@draw@inject@outer@helper%
+ \csname yquant@draw@@injection@#1\endcsname%
+ \csgundef{yquant@draw@@injection@#1}%
+}
+
+\def\yquant@draw@inject@outer@helper\yquant@draw@begininjection#1\yquant@draw@stopinjection{%
+ \yquant@draw@group%
+ #1%
+ \yquant@draw@endgroup%
+}
+
+\protected\def\yquant@draw@single#1#2{%
\let\idx=\yquant@draw@@idx@content%
+ \yquant@config@operator@multifalse%
\edef\cmd{%
\noexpand\path (\yquant@draw@@x, \yquant@register@get@y{#1})%
node[/yquant/every operator, \yquant@draw@@style, /yquant/this operator,%
@@ -80,6 +220,7 @@
}
\protected\def\yquant@draw@multi#1#2#3#4#5{%
+ \yquant@config@operator@multitrue%
\let\idx=\yquant@draw@@idx@content%
\edef\yquant@draw@multi@@name{#5}%
\def\yquant@draw@@idx@multipart{0}%
@@ -106,7 +247,7 @@
\yquant@register@get@y{#1}+\yquant@register@get@y{#2}\relax%
\relax)%
node[/yquant/every operator, \yquant@draw@@style, /yquant/this operator,%
- /yquant/operator/multi main=\ifnum#3=1 true\else false\fi\unless\ifnum#1=#2 ,%
+ /yquant/internal/multi main=\ifnum#3=1 true\else false\fi\unless\ifnum#1=#2 ,%
y radius/.expanded=\the\dimexpr.5\dimexpr\yquant@register@get@ydist{#1}{#2}\relax\relax+%
.5*\noexpand\pgfkeysvalueof{/tikz/y radius}\fi,%
name prefix=, name suffix=, name=yquantbox]%
@@ -145,17 +286,28 @@
\let\pgfdecorationsegmentfromto=\empty%
#4%
\edef\pgfdecorationsegmentfromto{\expandafter\@gobble\pgfdecorationsegmentfromto}%
+ \yquant@config@operator@multitrue%
% We need to somehow extract the y radius
\edef\cmd{%
- \noexpand\path[/yquant/every operator, \yquant@draw@@style,%
- /yquant/every multi label, /yquant/this operator]%
- (\yquant@draw@@x, \yquant@draw@multiinit@@min) --%
- (\yquant@draw@@x, \yquant@draw@multiinit@@max)%
- node[name prefix=, name suffix=, name=yquantbox]%
+ \noexpand\path (\yquant@draw@@x, \the\dimexpr.5\dimexpr%
+ \yquant@draw@multiinit@@min+\yquant@draw@multiinit@@max\relax%
+ \relax)%
+ node[/yquant/every operator, \yquant@draw@@style,
+ \ifnum\yquant@compat<2 /yquant/every multi label,\fi%
+ /yquant/this operator,%
+ y radius=\yquant@abs{\the\dimexpr.5\dimexpr\yquant@draw@multiinit@@total\relax\relax},%
+ name prefix=, name suffix=, name=yquantbox]%
{\unexpanded\expandafter{\yquant@draw@@content}};%
+ \pgfshapeclippath{yquantbox}%
+ {/yquant/every operator, \yquant@draw@@style,%
+ \ifnum\yquant@compat<2 /yquant/every multi label,\fi%
+ /yquant/this operator}%
}%
\cmd%
- % no wire extension (we are still at the initial position), no control line (init doesn't allow for those, so just save the no-op), no multi line
+ \yquant@for \i := #1 to #2 {%
+ \yquant@circuit@extendwire\i{center}%
+ }%
+ % no control line (init doesn't allow for those, so just save the no-op), no multi line
% check for empty name parameter
\ifstrempty{#5}\relax{%
\pgfnodealias{\tikz@pp@name{#5}}{yquantbox}%
@@ -201,7 +353,85 @@
\fi%
}
-\newbox\yquant@draw@subcircuit@box
+\protected\long\def\yquant@draw@output@single#1#2{%
+ \let\idx=\yquant@draw@@idx@content%
+ \yquant@config@operator@multifalse%
+ \edef\cmd{%
+ \noexpand\path (\yquant@circuit@endwires@x, \yquant@register@get@y{#1})%
+ node[\ifnum\yquant@compat>1 /yquant/every operator,\fi%
+ /yquant/every output,%
+ /yquant/every \yquant@register@type@tostring{\yquant@register@get@type{#1}} output,%
+ \yquant@draw@@style, /yquant/this operator,%
+ name prefix=, name suffix=, name=yquantbox]%
+ {\unexpanded\expandafter{\yquant@draw@@content}};%
+ \ifdefined\yquant@parent%
+ \pgfshapeclippath{yquantbox}%
+ {\ifnum\yquant@compat>1 /yquant/every operator,\fi%
+ /yquant/every output,%
+ /yquant/every \yquant@register@type@tostring{\yquant@register@get@type{#1}} output,%
+ \yquant@draw@@style,%
+ /yquant/this operator}%
+ \fi%
+ }%
+ \cmd%
+ % only extend for subcircuits
+ \ifdefined\yquant@parent%
+ \yquant@circuit@extendwire{#1}{center}%
+ \fi%
+ % check for empty name parameter
+ \ifstrempty{#2}\relax{%
+ \pgfnodealias{\tikz@pp@name{#2}}{yquantbox}%
+ }%
+ \numdef\yquant@draw@@idx@content{\yquant@draw@@idx@content+1}%
+}
+
+\protected\long\def\yquant@draw@output@multi#1#2#3#4#5{%
+ \let\idx=\yquant@draw@@idx@content%
+ \@tempdima=-.5\dimexpr\yquant@config@register@sep\relax%
+ \dimdef\yquant@draw@multiinit@@min{\yquant@register@get@y{#1}-\@tempdima}%
+ \dimdef\yquant@draw@multiinit@@max{\yquant@register@get@y{#2}+\@tempdima}%
+ \dimdef\yquant@draw@multiinit@@total{%
+ \yquant@draw@multiinit@@max-\yquant@draw@multiinit@@min%
+ }%
+ \def\pgfdecorationsegmentaspect{0}%
+ \let\yquant@register@multi@contiguous=\yquant@draw@multiinit@contiguous%
+ \let\pgfdecorationsegmentfromto=\empty%
+ #4%
+ \edef\pgfdecorationsegmentfromto{\expandafter\@gobble\pgfdecorationsegmentfromto}%
+ \yquant@config@operator@multitrue%
+ % We need to somehow extract the y radius
+ \edef\cmd{%
+ \noexpand\path (\yquant@circuit@endwires@x, \the\dimexpr.5\dimexpr%
+ \yquant@draw@multiinit@@min+\yquant@draw@multiinit@@max\relax%
+ \relax)%
+ node[\ifnum\yquant@compat>1 /yquant/every operator, /yquant/every output,\fi%
+ \yquant@draw@@style,%
+ \ifnum\yquant@compat<2 /yquant/every multi output,\fi%
+ /yquant/this operator,%
+ y radius=\yquant@abs{\the\dimexpr.5\dimexpr\yquant@draw@multiinit@@total\relax\relax},%
+ name prefix=, name suffix=, name=yquantbox]%
+ {\unexpanded\expandafter{\yquant@draw@@content}};%
+ \ifdefined\yquant@parent%
+ \pgfshapeclippath{yquantbox}%
+ {\ifnum\yquant@compat>1 /yquant/every operator, /yquant/every output,\fi%
+ \yquant@draw@@style,
+ \ifnum\yquant@compat<2 /yquant/every multi output,\fi%
+ /yquant/this operator}%
+ \fi%
+ }%
+ \cmd%
+ % only extend for subcircuits
+ \ifdefined\yquant@parent%
+ \yquant@for \i := #1 to #2 {%
+ \yquant@circuit@extendwire\i{center}%
+ }%
+ \fi%
+ % check for empty name parameter
+ \ifstrempty{#5}\relax{%
+ \pgfnodealias{\tikz@pp@name{#5}}{yquantbox}%
+ }%
+ \numdef\yquant@draw@@idx@content{\yquant@draw@@idx@content+1}%
+}
\protected\def\yquant@draw@subcircuit@nodecallback#1{%
\ifstrequal{#1}{yquantbox}\relax{%
@@ -209,65 +439,87 @@
}%
}
-\protected\long\def\yquant@draw@subcircuit@prepare#1#2{%
+% #1: id of subcircuit
+% #2: name
+% #3: {width of subcircuit (excluding outer box)}{including outer box}{left margin}
+% #4: affected wires
+\protected\long\def\yquant@draw@subcircuit@prepare#1#2#3#4{%
\let\idx=\yquant@draw@@idx@content%
- % In order to wrap the inner circuit in a proper box operator and clip outer paths appropriately (which was not possible yet, as we didn't know the exact vertical positions), we first place it within a box. During the setup time, we assumed that the subcircuit be placed at position #3; however, now, this has changed due to the additional box.
+ % In order to wrap the inner circuit in a proper box operator and clip outer paths appropriately (which was not possible yet, as we didn't know the exact vertical positions), we first place it within a box.
% First, we anticipate the macro that is used by our subcircuit to store the node
% names.
\edef\yquant@draw@subcircuit@nodelist{yquant@env#1@draw@subcircuit@nodelist}%
\global\cslet\yquant@draw@subcircuit@nodelist\empty%
- \pgfinterruptboundingbox%
- \let\yquant@parent=\yquant@prefix%
- \def\yquant@prefix{yquant@env#1@}%
- \ifstrempty{#2}{%
- % we make sure there are no conflicts by prefixing any named nodes in any case.
- \pgfkeys{/tikz/name prefix/.expanded={sub\yquant@prefix-}}%
- \let\pgf@nodecallback=\yquant@draw@subcircuit@nodecallback%
- }{%
- \pgfkeys{/tikz/name prefix/.expanded={\pgfkeysvalueof{/tikz/name prefix}#2-}}%
+ % \pgfinterruptboundingbox, but just for y
+ \begingroup%
+ \edef\pgf@interrupt@savemaxy{\the\pgf@picmaxy}%
+ \edef\pgf@interrupt@saveminy{\the\pgf@picminy}%
+ \pgf@picmaxy=-16000pt %
+ \pgf@picminy=16000pt %
+ \pgf@size@hookedfalse%
+ \let\pgf@path@size@hook=\pgfutil@empty%
+ % now we must take care of extending all the wires appropriately until the beginning of the box. #3 contains width of this box, #4 contains registers affected by this box. Note that for subcircuits, x extension by the group is disabled.
+ \dimdef\newx{%
+ \yquant@draw@@x-.5\dimexpr\@secondofthree#3\relax%
}%
- \letcs\xmin{\yquant@prefix xmin}%
- \letcs\xmax{\yquant@prefix xmax}%
- \global\setbox\yquant@draw@subcircuit@box=\hbox to 0pt {{%
- % bypass 'overlay' option
- \pgf@relevantforpicturesizetrue%
- \pgfsys@beginpicture%
- % reset all styles to the expected defaults (similar, but extended to \pgfpicture, see pgf issue #870)
- \pgfsetcolor{.}%
- \pgfsetlinewidth{0.4pt}%
- \pgfsetbuttcap%
- \pgfsetmiterjoin%
- \pgfsetmiterlimit{10}%
- \pgfsetdash{}{0pt}%
- % The left outer position of our box will be \yquant@draw@@x-.5(xmax-xmin).
- % To compensate for, we perform a left shift of all commands that take explicit coordinates from the subcircuit.
- % The y positions, on the other hand, are exactly the ones as they should be integrated in the picture.
- \csdimdef{\yquant@prefix xshift}{\yquant@draw@@x-.5\dimexpr\xmax+\xmin\relax}%
- \csname\yquant@prefix draw\endcsname%
- \ifdim\pgf@picmaxx=-16000pt %
- \global\pgf@picmaxx=0pt %
- \global\pgf@picminx=0pt %
- \global\pgf@picmaxy=0pt %
- \global\pgf@picminy=0pt %
- \fi%
- \ifyquantdebug%
- \pgf@relevantforpicturesizefalse%
- \draw[green] (current bounding box.north east) rectangle (current bounding box.south west);%
- \fi%
- \pgfsys@endpicture%
+ \dimen0=\newx%
+ \let\yquant@draw@subcircuit@leftpos=\newx% seamless subcircuits: do not add another separation if we are there
+ \let\pgfshapeclippathhorzresult=\empty%
+ \forlistloop\yquant@draw@move@loop{#4}%
+ % but the new positions are not at the beginning of the box, but inside (with possible margin)
+ \dimdef\newx{%
+ \yquant@draw@@x-.5\dimexpr\@firstofthree#3\relax-\@thirdofthree#3%
+ }%
+ \forlistloop\yquant@draw@group@advance{#4}%
+ \setbox\yquant@prepare@subcircuit@box=\hbox{{%
+ \let\yquant@draw@subcircuit@wirestart=\newx%
+ \let\yquant@parent=\yquant@prefix%
+ \def\yquant@prefix{yquant@env#1@}%
+ \ifstrempty{#2}{%
+ % we make sure there are no conflicts by prefixing any named nodes in any case.
+ \pgfkeys{/tikz/name prefix/.expanded={sub\yquant@prefix-}}%
+ \let\pgf@nodecallback=\yquant@draw@subcircuit@nodecallback%
+ }{%
+ \pgfkeys{/tikz/name prefix/.expanded={\pgfkeysvalueof{/tikz/name prefix}#2-}}%
+ }%
+ \pgfkeys{/yquant/operators/this subcircuit box/.style={}}%
+ \edef\yquant@draw@subcircuit@style{%
+ /yquant/every operator, \yquant@draw@@style,%
+ /yquant/this operator, /yquant/internal/multi main=true,%
+ }
+ \expandafter\tikzset\expandafter{\yquant@draw@subcircuit@style}%
+ \csname\yquant@prefix draw\endcsname%
+ \dimen0=\yquant@register@get@y1\relax%
+ \ifdim\dimen0>\pgf@picmaxy %
+ \global\pgf@picmaxy=\dimen0 %
+ \fi%
+ \dimen0=\dimexpr\yquant@register@get@y{\csname\yquant@prefix registers\endcsname}\relax%
+ \ifdim\dimen0<\pgf@picminy %
+ \global\pgf@picminy=\dimen0 %
+ \fi%
}}%
- \global\setbox\yquant@draw@subcircuit@box=\hbox to \dimexpr\xmax-\xmin\relax {%
- \hskip-\dimexpr\yquant@draw@@x-.5\dimexpr\xmax-\xmin\relax\relax%
- \lower\pgf@picmaxy%
- \box\yquant@draw@subcircuit@box%
+ \edef\cmd{%
+ \noexpand\path (\yquant@draw@@x, \the\dimexpr.5\pgf@picminy+.5\pgf@picmaxy\relax)%
+ node[/yquant/every operator, \yquant@draw@@style,%
+ /yquant/operators/every subcircuit box, /yquant/this operator,%
+ /yquant/operators/this subcircuit box,%
+ /yquant/internal/multi main=true,%
+ name prefix=, name suffix=, name=yquantbox]%
+ {\vbox to \the\dimexpr\pgf@picmaxy-\pgf@picminy\relax {\hbox to \@firstofthree#3 {}}};%
}%
- \ht\yquant@draw@subcircuit@box=0pt%
- \dp\yquant@draw@subcircuit@box=\dimexpr\pgf@picmaxy-\pgf@picminy\relax%
- \expandafter%
- \endpgfinterruptboundingbox%
- \expandafter\edef\expandafter\yquant@draw@subcircuit@y\expandafter{%
- \the\dimexpr.5\pgf@picminy+.5\pgf@picmaxy\relax%
- }%
+ \cmd%
+ \unhbox\yquant@prepare@subcircuit@box
+ % \endpgfinterruptboundingbox + increase
+ \ifdim\pgf@interrupt@savemaxy>\pgf@picmaxy%
+ \global\pgf@picmaxy=\pgf@interrupt@savemaxy%
+ \fi%
+ \ifdim\pgf@interrupt@saveminy<\pgf@picminy%
+ \global\pgf@picminy=\pgf@interrupt@saveminy%
+ \fi%
+ \endgroup%
+ % Now that the subcircuit is finished, we need advance all the wires
+ \dimdef\newx{\yquant@draw@@x+.5\dimexpr\yquant@draw@@width\relax}%
+ \forlistloop\yquant@draw@group@advance{#4}%
\ifstrempty{#2}{%
% However, if the outer node was not named, no access to the inner nodes is desired, so we delete all nodes again.
\def\do##1{%
@@ -287,25 +539,21 @@
}%
}
-\protected\long\def\yquant@draw@subcircuit@single#1#2#3{%
- \yquant@draw@subcircuit@prepare{#2}{#3}%
+\protected\long\def\yquant@draw@subcircuit@single#1#2#3#4{%
+ \yquant@config@operator@multifalse%
+ \yquant@draw@subcircuit@prepare{#2}{#3}{#4}{#1}%
\edef\cmd{%
- \noexpand\path (\yquant@draw@@x, \yquant@draw@subcircuit@y)%
- node[/yquant/every operator, \yquant@draw@@style,%
- /yquant/operators/every subcircuit box, /yquant/this operator,%
- /yquant/operators/this subcircuit box,%
- name prefix=, name suffix=, name=yquantbox]%
- {\box\yquant@draw@subcircuit@box};%
- \pgfshapeclippath{yquantbox}%
- {/yquant/every operator, \yquant@draw@@style,%
- /yquant/operators/every subcircuit box, /yquant/this operator,%
- /yquant/operators/this subcircuit box}%
+ \pgfshapeclippath{yquantbox}{%
+ /yquant/every operator, \yquant@draw@@style,%
+ /yquant/operators/every subcircuit box, /yquant/this operator,%
+ /yquant/operators/this subcircuit box,%
+ }%
}%
\cmd%
% see comment in draw@subcircuit@multi
\yquant@softpath@extractmaxxat\pgfshapeclippathhorzresult{\yquant@register@get@y{#1}}%
\let\pgfshapeclippathhorzresult=\empty%
- \yquant@circuit@extendwire{#1}{*}%
+ \yquant@circuit@extendwire{#1}*%
\expandafter\yquant@circuit@extendcontrolline\expandafter%
{\the\yquant@draw@@currentcontroltype}\yquant@draw@@x%
% check for empty name parameter
@@ -315,31 +563,25 @@
\numdef\yquant@draw@@idx@content{\yquant@draw@@idx@content+1}%
}
-\protected\long\def\yquant@draw@subcircuit@multi#1#2#3#4#5#6{%
+\protected\long\def\yquant@draw@subcircuit@multi#1#2#3#4#5#6#7{%
+ \yquant@config@operator@multitrue%
% there is no contiguous slicing for subcircuits, as they may have all kinds of wire operations that can extend beyond the individual slices, let alone ancillas
- \yquant@draw@subcircuit@prepare{#5}{#6}%
- % We need to somehow extract the y radius
+ \yquant@draw@subcircuit@prepare{#5}{#6}{#7}{#4}%
\edef\cmd{%
- \noexpand\path (\yquant@draw@@x, \yquant@draw@subcircuit@y)%
- node[/yquant/every operator, \yquant@draw@@style,%
- /yquant/operators/every subcircuit box, /yquant/this operator,%
- /yquant/operators/this subcircuit box,
- /yquant/operator/multi main=true,%
- name prefix=, name suffix=, name=yquantbox]%
- {\box\yquant@draw@subcircuit@box};%
- \pgfshapeclippath{yquantbox}%
- {/yquant/every operator, \yquant@draw@@style,%
- /yquant/operators/every subcircuit box, /yquant/this operator,%
- /yquant/operators/this subcircuit box,%
- /yquant/operator/multi main=true}%
+ \pgfshapeclippath{yquantbox}{%
+ /yquant/every operator, \yquant@draw@@style,%
+ /yquant/operators/every subcircuit box, /yquant/this operator,%
+ /yquant/operators/this subcircuit box,%
+ /yquant/internal/multi main=true,%
+ }%
}%
\cmd%
% install the clippings - but only on wires that are visually between the first and list while not being part of the circuit.
\let\nonaffectedpgfshapeclippathhorzresult=\pgfshapeclippathhorzresult%
\yquant@for \i := #1 to #2 {%
\xifinlist{\i}{#4}{%
- % Usually, we always begin with a wire from the center of the operator shape and clip the inner parts away. This can't be done here, as the wire needs to be drawn _inside_ of the outer box operator here. Instead of clipping against the clip path, we extract its maximum x position at the position of the wire (which is an overkill for simple shapes, but the allows to specify even more complicated ones) and place the wire at this position without clipping.
- % Note: this works very well for lines joining at perpendicular angles; but if the shape of the box is more fancy, while the position will be calculated correctly, the wire has a rectangular (or rounded, depending on the line cap) shape that is drawn on top of thw operator. While \yquant@softpath@extractmaxxat could without much effort determine exactly the segment of the path that corresponds to the rightmost line, we would then have to convert this single line into a closed path that fills the linewidth and clip against it to get proper joiners. Since most likely, no-one will ever need this, we don't do it. But file a feature request if desired.
+ % Usually, we always begin with a wire from the center of the operator shape and clip the inner parts away. This can't be done here, as the wire needs to be drawn _inside_ of the outer box operator here. Instead of clipping against the clip path, we extract its maximum x position at the position of the wire (which is an overkill for simple shapes, but allows to specify even more complicated ones) and place the wire at this position without clipping.
+ % Note: this works very well for lines joining at perpendicular angles; but if the shape of the box is more fancy, while the position will be calculated correctly, the wire has a rectangular (or rounded, depending on the line cap) shape that is drawn on top of the operator. While \yquant@softpath@extractmaxxat could without much effort determine exactly the segment of the path that corresponds to the rightmost line, we would then have to convert this single line into a closed path that fills the linewidth and clip against it to get proper joiners. Since most likely, no-one will ever need this, we don't do it. But file a feature request if desired.
\yquant@softpath@extractmaxxat\nonaffectedpgfshapeclippathhorzresult%
{\yquant@register@get@y\i}%
\let\pgfshapeclippathhorzresult=\empty%
@@ -465,7 +707,7 @@
\ifx0#2%
\edef\wirexpos{\expandafter\@secondoffour\wirelast}%
\else%
- \let\wirexpos=\yquant@env@end@xpos%
+ \let\wirexpos=\yquant@circuit@endwires@x%
\fi%
\ifdim\wirexpos>\wirexprevpos %
\edef\wirestyle{\noexpand\tikzset{%
@@ -483,41 +725,52 @@
}%
}%
\pgfscope%
- % install the clipping
- \pgfsyssoftpath@setcurrentpath\wireclipping%
- % invert the clipping
- \ifyquantdebug%
- \pgfsetfillcolor{orange}%
- \pgfsetfillopacity{.3}%
- \pgfusepathqfill%
- \else%
- % We need to access the current bounding box as well as other positions in the local coordinate frame. For this, transform the bounding box to the current frame (though this is expensive). Does this capture rotations correctly?
- \begingroup%
- \pgftransforminvert%
- \pgfpointtransformednonlinear{\pgfqpoint{\pgf@picminx}{\pgf@picminy}}%
- \global\@tempdima=\pgf@y%
- \pgfpointtransformednonlinear{\pgfqpoint{\pgf@picmaxx}{\pgf@picmaxy}}%
- \global\@tempdimb=\pgf@y%
- \endgroup%
- % To avoid rendering artifacts at all zoom levels with all renderers, we need to make the clipping region large. Let's try the current bounding box first.
- % This may be insufficient if there no or a tiny wire label and only registers of a small height. In this case, take ten times the line width or at least 1cm, but don't let it affect the bounding box.
- \ifdim\dimexpr\@tempdimb-\@tempdima\relax<10\pgflinewidth %
- \@tempdima=\dimexpr\wireypos-5\pgflinewidth\relax%
- \@tempdimb=\dimexpr\wireypos+5\pgflinewidth\relax%
- \fi%
- \ifdim\dimexpr\@tempdimb-\@tempdima\relax<1cm %
- \@tempdima=\dimexpr\wireypos-5mm\relax%
- \@tempdimb=\dimexpr\wireypos+5mm\relax%
+ \unless\ifx\wireclipping\empty% may happen if the style is altered to be invisible, though the type is not none
+ % install the clipping
+ \pgfsyssoftpath@setcurrentpath\wireclipping%
+ % invert the clipping
+ \ifyquantdebug%
+ \pgfsetfillcolor{orange}%
+ \pgfsetfillopacity{.3}%
+ \pgfusepathqfill%
+ \else%
+ % We need to access the current bounding box as well as other positions in the local coordinate frame. For this, transform the bounding box to the current frame (though this is expensive). Does this capture rotations correctly?
+ \begingroup%
+ \ifdim\pgf@picminx>\pgf@picmaxx%
+ % nothing drawn yet (or bounding box reset)
+ \pgf@picminx=0pt %
+ \pgf@picmaxx=0pt %
+ \fi%
+ \ifdim\pgf@picminy>\pgf@picmaxy%
+ \pgf@picminy=0pt %
+ \pgf@picmaxy=0pt %
+ \fi%
+ \pgftransforminvert%
+ \pgfpointtransformednonlinear{\pgfqpoint{\pgf@picminx}{\pgf@picminy}}%
+ \global\@tempdima=\pgf@y%
+ \pgfpointtransformednonlinear{\pgfqpoint{\pgf@picmaxx}{\pgf@picmaxy}}%
+ \global\@tempdimb=\pgf@y%
+ \endgroup%
+ % To avoid rendering artifacts at all zoom levels with all renderers, we need to make the clipping region large. Let's try the current bounding box first.
+ % This may be insufficient if there no or a tiny wire label and only registers of a small height. In this case, take ten times the line width or at least 1cm, but don't let it affect the bounding box.
+ \ifdim\dimexpr\@tempdimb-\@tempdima\relax<10\pgflinewidth %
+ \@tempdima=\dimexpr\wireypos-5\pgflinewidth\relax%
+ \@tempdimb=\dimexpr\wireypos+5\pgflinewidth\relax%
+ \fi%
+ \ifdim\dimexpr\@tempdimb-\@tempdima\relax<1cm %
+ \@tempdima=\dimexpr\wireypos-5mm\relax%
+ \@tempdimb=\dimexpr\wireypos+5mm\relax%
+ \fi%
+ \pgf@relevantforpicturesizefalse%
+ \pgfpathrectanglecorners%
+ {\pgfqpoint{\dimexpr\wirexprevpos-2\pgflinewidth\relax}%
+ {\@tempdima}}%
+ {\pgfqpoint{\dimexpr\wirexpos+2\pgflinewidth\relax}%
+ {\@tempdimb}}%
+ \pgf@relevantforpicturesizetrue%
+ \pgfseteorule% even-odd to properly invert the clipping
+ \pgfusepathqclip%
\fi%
- \pgfinterruptboundingbox%
- \pgfpathrectanglecorners%
- {\pgfqpoint{\dimexpr\wirexprevpos-2\pgflinewidth\relax}%
- {\@tempdima}}%
- {\pgfqpoint{\dimexpr\wirexpos+2\pgflinewidth\relax}%
- {\@tempdimb}}%
- \endpgfinterruptboundingbox%
- \pgfseteorule% even-odd to properly invert the clipping
- \pgfusepathqclip%
\fi%
% the clip inversion is left to the drawing commands (clip two \pgflinewidth more to avoid renderer artifacts)
\csname yquant@draw@wire@\wiretype\endcsname{#1}%
@@ -557,486 +810,17 @@
\cmd%
}
-\protected\long\def\yquant@draw@output@group#1{%
- \begingroup%
- \def\idx{0}%
- \yquant@set{#1}%
-}
-
-\let\yquant@draw@output@endgroup=\endgroup%
-
-\protected\long\def\yquant@draw@output@single#1#2{%
- \path%
- (\yquant@env@end@xpos, \yquant@register@get@y{#1})%
- node[/yquant/every output,%
- /yquant/every \yquant@register@type@tostring{\yquant@register@get@type{#1}} output] {#2};
- \numdef\idx{\idx+1}%
-}
-
-\protected\long\def\yquant@draw@output@multi#1#2#3#4{%
- % extremely similar to \yquant@draw@multiinit
- \@tempdima=-.5\dimexpr\yquant@config@register@sep\relax%
- \dimdef\yquant@draw@multiinit@@min{\yquant@register@get@y{#1}-\@tempdima}%
- \dimdef\yquant@draw@multiinit@@max{\yquant@register@get@y{#2}+\@tempdima}%
- \dimdef\yquant@draw@multiinit@@total{%
- \yquant@draw@multiinit@@max-\yquant@draw@multiinit@@min%
- }%
- \def\pgfdecorationsegmentaspect{0}%
- \let\yquant@register@multi@contiguous=\yquant@draw@multiinit@contiguous%
- \let\pgfdecorationsegmentfromto=\empty%
- #3%
- \edef\pgfdecorationsegmentfromto{\expandafter\@gobble\pgfdecorationsegmentfromto}%
- \path[/yquant/every multi output]%
- (\yquant@env@end@xpos, \yquant@draw@multiinit@@min) --%
- (\yquant@env@end@xpos, \yquant@draw@multiinit@@max)%
- node {#4};%
- \numdef\idx{\idx+1}%
-}
-% END_FOLD
-
-% BEGIN_FOLD Preparation of drawing a generic shape
-% Most drawing operations will be realized through nodes
-\let\yquant@draw@callback@box=\@gobble
-\let\yquant@draw@callback@wire=\@gobble
-
-\def\yquant@draw@sort#1#2{%
- \yquant@draw@sort@aux#1\relax#2\relax%
- \expandafter\@firstoftwo%
- \else%
- \expandafter\@secondoftwo%
- \fi%
-}
-
-\def\yquant@draw@sort@aux#1#2#3\relax#4#5#6\relax{%
- \unless\ifnum#2>#5\relax%
-}
-
-% generic shape of an operator
-% #1: value
-% #2: tikz options that select the correct shape
-% #3: positive controls
-% #4: negative controls
-% #5: targets
-\protected\long\def\yquant@draw#1#2#3#4#5{%
- % setup the required macros
- \yquant@circuit@operator{#3}{#4}{#5}%
- \yquant@draw@{#1}{#2}%
-}
-
-\protected\long\def\yquant@draw@#1#2{%
- \yquant@sort@clear%
- \def\idx{0}%
- \dimen2=\yquant@config@operator@minimum@width%
- % BEGIN_FOLD register
- \def\do##1{%
- \ifx\yquant@lang@attr@name\empty%
- \let\nodename=\empty%
- \else%
- \edef\nodename{\yquant@lang@attr@name-\idx}%
- \fi%
- \ifyquant@firsttoken\yquant@register@multi{##1}{%
- \yquant@draw@@multi{#1}{#2}{##1}%
- }{%
- \yquant@draw@@single{#1}{#2}{##1}%
- }%
- \ifx\yquant@draw@@multi\yquant@draw@@multiinit%
- % if we draw an initialization (whether multi or single), this possibly affects the minimal x position. All other gates will be shifted so that they cannot extend beyond the minimal position.
- \ifdim\pgf@picminx<\csname\yquant@prefix xmin\endcsname%
- \csxdef{\yquant@prefix xmin}{\the\pgf@picminx}%
- \fi%
- \fi%
- \expandafter%
- \endpgfinterruptboundingbox%
- \expandafter\dimen\expandafter0\expandafter=%
- \the\dimexpr\pgf@picmaxx-\pgf@picminx\relax\relax%
- \ifdim\dimen0>\dimen2 %
- \dimen2=\dimen0 %
- \fi%
- \numdef\idx{\idx+1}%
- }%
- \dolistloop\yquant@circuit@operator@targets%
- % END_FOLD
- \yquant@draw@@controls%
- \yquant@draw@@finalize{#1}{#2}%
-}
-
-\protected\def\yquant@draw@@controls@loop#1#2{%
- \ifx\yquant@lang@attr@name\empty%
- \let\nodename=\empty%
- \else%
- \edef\nodename{\yquant@lang@attr@name-#1\idx}%
- \fi%
- \yquant@sort@eadd{%
- \expandafter\noexpand\csname yquant@draw@#1control\endcsname%
- {#2}% register index
- {\nodename}%
- }%
- \unless\ifdefined\yquant@draw@controltype%
- \edef\yquant@draw@controltype{#2}%
- \fi%
- \numdef\idx{\idx+1}%
-}
-
-\protected\def\yquant@draw@@controls{%
- \ifyquant@circuit@operator@hasControls%
- \def\idx{0}%
- \forlistloop{\yquant@draw@@controls@loop p}\yquant@circuit@operator@pctrls%
- \def\idx{0}%
- \forlistloop{\yquant@draw@@controls@loop n}\yquant@circuit@operator@nctrls%
- \unless\ifdefined\yquant@draw@controltype%
- \PackageError{yquant.sty}{Assertion failure}%
- {Internal inconsistency in yquant: Controlled action detected, but no controls were found.}%
- \fi%
- \fi%
-}
-
-\protected\long\def\yquant@draw@@finalize#1#2{%
- % We now know the dimensions of all the registers (though we didn't bother with the height of the control knobs [if present], we just assume they are too small to change this).
- \protected\def\idx{}%
- \protected@edef\yquant@draw@append{%
- \noexpand\yquant@draw@group%
- {\the\dimexpr\yquant@circuit@operator@x+.5\dimen2\relax}% mid x position
- \ifyquant@circuit@operator@hasControls%
- \yquant@draw@controltype%
- \else%
- F%
- \fi% if-switch whether controls are present
- {\yquant@attrs@remaining}% custom style
- {#2}% operator style
- {#1}%
- }%
- \yquant@sort\yquant@draw@sort%
- \advance \dimen2 by \yquant@circuit@operator@x\relax%
- \ifyquant@circuit@operator@hasControls%
- % If we draw a control line, all intermediate registers are affected in their position so that the line is never crossed. If the vertical line is instead caused by a multi register, \yquant@draw@@finalize@ctrl will be responsible for advancing only the affected positions.
- \yquant@for \yquant@i := \yquant@circuit@operator@minctrl to \yquant@circuit@operator@maxctrl {%
- \yquant@register@set@x\yquant@i{\the\dimen2}%
- }%
- \fi%
- \def\do##1{%
- \appto\yquant@draw@append{##1}%
- \yquant@draw@@finalize@ctrl##1%
- }%
- \yquant@sort@dolistloop%
- \csxappto{\yquant@prefix draw}{%
- \unexpanded\expandafter{\yquant@draw@append}%
- \noexpand\yquant@draw@endgroup%
- \ifyquant@circuit@operator@hasControls%
- T%
- \else%
- F%
- \fi%
- \ifx\yquant@lang@attr@name\empty%
- {}0%
- \else%
- {\yquant@lang@attr@name}%
- \ifnum\yquant@circuit@operator@numtarget=1 %
- \ifnum\yquant@circuit@operator@numpctrl=1 %
- \ifnum\yquant@circuit@operator@numnctrl=1 %
- 7%
- \else%
- 6%
- \fi%
- \else%
- \ifnum\yquant@circuit@operator@numnctrl=1 %
- 5%
- \else%
- 4%
- \fi%
- \fi%
- \else%
- \ifnum\yquant@circuit@operator@numpctrl=1 %
- \ifnum\yquant@circuit@operator@numnctrl=1 %
- 3%
- \else%
- 2%
- \fi%
- \else%
- \ifnum\yquant@circuit@operator@numnctrl=1 %
- 1%
- \else%
- 0%
- \fi%
- \fi%
- \fi%
- \fi%
- }%
-}
-
-\protected\def\yquant@draw@@single#1#2#3{%
- \yquant@sort@eadd{%
- \yquant@draw@single%
- {#3}% register index
- {\nodename}%
- }%
- % determine the actual dimensions by a virtual draw command
- \pgfinterruptboundingbox%
- \yquant@env@virtualize@path%
- \path%
- (0pt, 0pt)%
- node[/yquant/every operator, #2, /yquant/this operator,%
- name prefix=, name suffix=, name=] {#1};%
- \yquant@register@update@height{#3}{\the\pgf@picmaxy}%
- \yquant@register@update@depth{#3}{\the\dimexpr-\pgf@picminy\relax}%
-}
-
-\protected\def\yquant@draw@@multi#1#2#3{%
- \yquant@sort@eadd{%
- \yquant@draw@multi%
- #3%
- {\nodename}%
- }%
- % Determining the actual height is a problem - where to store its value? If there are single-register parts, we update the height accordingly; else we just assume that there is always enough space for such a control, since it anyways already spans multiple registers. (TODO?)
- \pgfinterruptboundingbox%
- \yquant@env@virtualize@path%
- \def\yquant@draw@@content{#1}%
- \def\yquant@draw@@style{#2}%
- \let\yquant@register@multi@contiguous=\yquant@draw@@multi@contiguous%
- \@fifthoffive#3%
- \ifdim\pgf@picmaxy=-16000pt %
- % if there was no single contiguous part before, determine the width now
- \path%
- (0pt, 0pt)%
- node[/yquant/every operator, #2, /yquant/this operator,%
- name prefix=, name suffix=, name=] {#1};%
- \fi%
-}
-
-\protected\def\yquant@draw@@multi@contiguous#1#2#3{%
- \ifnum#1=#2 %
- % we only care about single-register parts
- \global\pgf@picmaxy=-16000pt %
- \global\pgf@picminy=16000pt %
- \edef\cmd{%
- \noexpand\path (0pt, 0pt)%
- node[/yquant/every operator, \yquant@draw@@style, /yquant/this operator,%
- /yquant/operator/multi main=\ifnum#3=1 true\else false\fi,%
- name prefix=, name suffix=, name=]%
- {\unexpanded\expandafter{\yquant@draw@@content}};%
- }%
- \cmd%
- \yquant@register@update@height{#1}{\the\pgf@picmaxy}%
- \yquant@register@update@depth{#1}{\the\dimexpr-\pgf@picminy\relax}%
- \fi%
-}
-
-\protected\def\yquant@draw@@multiinit#1#2#3{%
- \yquant@sort@eadd{%
- \yquant@draw@multiinit%
- #3%
- {\nodename}%
- }%
- % Determining the actual height is a problem - where to store its value? We just assume that there is always enough space for such a control, since it anyway already spans multiple registers. (TODO?)
- \pgfinterruptboundingbox%
- \yquant@env@virtualize@path%
- \path%
- (0pt, 0pt)%
- node[/yquant/every operator, #2, /yquant/every multi label,%
- name prefix=, name suffix=, name=] {#1};%
-}
-
-\protected\long\def\yquant@draw@@subcircuit#1{%
- \yquant@sort@clear%
- \def\idx{0}%
- \dimen2=\yquant@config@operator@minimum@width%
- % BEGIN_FOLD register
- \def\do##1{%
- \ifx\yquant@lang@attr@name\empty%
- \let\nodename=\empty%
- \else%
- \edef\nodename{\yquant@lang@attr@name-\idx}%
- \fi%
- \ifyquant@firsttoken\yquant@register@multi{##1}{%
- \yquant@draw@@subcircuit@multi{#1}{##1}%
- }{%
- \yquant@draw@@subcircuit@single{#1}{##1}%
- }%
- \dimen0=\dimexpr%
- \csname yquant@env\yquant@circuit@subcircuit@id @xmax\endcsname-%
- \csname yquant@env\yquant@circuit@subcircuit@id @xmin\endcsname%
- \relax\relax%
- \pgfinterruptboundingbox%
- % There will still be some extra width taken by separations or other things related to the box itself.
- \yquant@env@virtualize@path%
- \path%
- (0pt, 0pt)%
- node[/yquant/every operator, #1,%
- /yquant/operators/every subcircuit box, /yquant/this operator,%
- /yquant/operators/this subcircuit box,%
- name prefix=, name suffix=, name=]%
- {\hbox to \dimen0{}};%
- % We also don't update the height here, as the height of the subcircuit is undetermined as long as we did not match inner and outer wires.
- \expandafter%
- \endpgfinterruptboundingbox%
- \expandafter\dimen\expandafter0\expandafter=%
- \the\dimexpr\pgf@picmaxx-\pgf@picminx\relax\relax%
- \ifdim\dimen0>\dimen2 %
- \dimen2=\dimen0 %
- \fi%
- \numdef\idx{\idx+1}%
- }%
- \dolistloop\yquant@circuit@operator@targets%
- % END_FOLD
- \yquant@draw@@controls%
- \yquant@draw@@finalize{}{#1}%
-}
-
-\protected\def\yquant@draw@@subcircuit@single#1#2{%
- \edef\yquant@circuit@subcircuit@param{#2\yquant@list@delim}%
- \yquant@circuit@subcircuit{#1}%
- \yquant@sort@eadd{%
- \yquant@draw@subcircuit@single%
- {#2}% register index
- {\yquant@circuit@subcircuit@id}%
- {\nodename}%
- }%
-}
-
-\protected\def\yquant@draw@@subcircuit@multi#1#2{%
- \edef\yquant@circuit@subcircuit@param{\@fifthoffive#2}%
- \yquant@sort@list\yquant@circuit@subcircuit@param\yquant@sort@ascending%
- \yquant@circuit@subcircuit{#1}%
- \yquant@sort@eadd{%
- \yquant@draw@subcircuit@multi%
- #2%
- {\yquant@circuit@subcircuit@id}%
- {\nodename}%
- }
-}
-
-\protected\long\def\yquant@draw@@output@single#1#2{%
- \path
- (\yquant@env@end@xpos, 0pt)%
- node[/yquant/every output,%
- /yquant/every \yquant@register@type@tostring{\yquant@register@get@type{#1}} output] {#2};%
- \numdef\idx{\idx+1}%
-}
-
-\protected\long\def\yquant@draw@@output@multi#1{%
- \path[/yquant/every multi output]%
- (\yquant@env@end@xpos, 0pt) -- (\yquant@env@end@xpos, 1cm)%
- node {#1};%
- \numdef\idx{\idx+1}%
-}
-
-\def\yquant@draw@@finalize@ctrl#1{%
- \let\next=\yquant@draw@@finalize@ctrl@single%
- \ifx\yquant@draw@multi#1%
- \let\next=\yquant@draw@@finalize@ctrl@multi%
- \else%
- \ifx\yquant@draw@multiinit#1%
- \let\next=\yquant@draw@@finalize@ctrl@multi%
- \else%
- \ifx\yquant@draw@subcircuit@multi#1%
- \let\next=\yquant@draw@@finalize@ctrl@subcircuit@multi%
- \else%
- \ifx\yquant@draw@subcircuit@single#1%
- \let\next=\yquant@draw@@finalize@ctrl@subcircuit@single%
- \fi%
- \fi%
- \fi%
- \fi%
- \next%
-}
-
-\protected\def\yquant@draw@@finalize@ctrl@single#1#2{%
- \unless\ifyquant@circuit@operator@hasControls%
- \yquant@register@set@x{#1}{\the\dimen2}%
- \fi%
- \eappto\yquant@draw@append{%
- \yquant@draw@callback@wire{#1}%
- }%
-}
-
-\def\yquant@draw@@finalize@ctrl@subcircuit@single#1#2#3{%
- \yquant@draw@@finalize@ctrl@single{#1}{#3}%
-}
-
-\protected\def\yquant@draw@@finalize@ctrl@singleinit#1#2{%
- \eappto\yquant@draw@append{%
- \yquant@draw@callback@wire{#1}%
- }%
-}
-
-\protected\def\yquant@draw@@finalize@ctrl@multi#1#2#3#4#5{%
- \unless\ifyquant@circuit@operator@hasControls{%
- % \yquant@for uses \loop...\repeat and hence redefines \body, which would destroy an outer loop.
- % if we did not draw a control line, the x position has not yet been set. A multi-qubit register might visually extend over multiple registers that are not even part, hence we update them all.
- \yquant@for \yquant@i := #1 to #2 {%
- \yquant@register@set@x\yquant@i{\the\dimen2}%
- }%
- }\fi%
- \let\yquant@register@multi@contiguous=\yquant@draw@@finalize@ctrl@multi@contiguous%
- \ifyquant@circuit@operator@hasControls%
- \ifyquant@config@operator@multi@warn%
- \def\yquant@draw@@finalize@ctrl@multi@contiguous@warn{0}%
- \else%
- \def\yquant@draw@@finalize@ctrl@multi@contiguous@warn{2}%
- \fi%
- \else%
- \def\yquant@draw@@finalize@ctrl@multi@contiguous@warn{2}%
- \fi%
- \cslet{\yquant@prefix finalize@ctrl@draw@appto}\empty%
- #4%
- \eappto\yquant@draw@append{\csname\yquant@prefix finalize@ctrl@draw@appto\endcsname}%
- \csgundef{\yquant@prefix finalize@ctrl@draw@appto}%
-}
-
-\protected\def\yquant@draw@@finalize@ctrl@subcircuit@multi@loop#1{%
+\protected\def\yquant@draw@hspace#1#2{%
\begingroup%
- \edef\tmp{\yquant@draw@callback@wire{#1}}%
- \expandafter%
+ \yquant@register@get@maxxlist\newx{#1}%
+ \dimdef\newx{\newx+#2}%
+ \dimen0=\newx%
+ \let\pgfshapeclippathhorzresult=\empty%
+ \forlistloop\yquant@draw@move@loop{#1}%
\endgroup%
- \expandafter\appto\expandafter\yquant@draw@append\expandafter{\tmp}%
}
-\protected\def\yquant@draw@@finalize@ctrl@subcircuit@multi#1#2#3#4#5#6{%
- % there are no contiguous parts here, don't call the normal @multi
- \unless\ifyquant@circuit@operator@hasControls{%
- % \yquant@for uses \loop...\repeat and hence redefines \body, which would destroy an outer loop.
- % if we did not draw a control line, the x position has not yet been set. A multi-qubit register might visually extend over multiple registers that are not even part, hence we update them all.
- \yquant@for \yquant@i := #1 to #2 {%
- \yquant@register@set@x\yquant@i{\the\dimen2}%
- }%
- }\fi%
- \forlistloop\yquant@draw@@finalize@ctrl@subcircuit@multi@loop{#4}%
-}
-
-\protected\def\yquant@draw@@finalize@ctrl@multiinit#1#2#3#4#5{%
- % this is called from a do loop itself, so preserve \do (but do not enter grouping)
- \let\yquant@register@multi@contiguous=\yquant@draw@@finalize@ctrl@multi@contiguous%
- \ifyquant@circuit@operator@hasControls%
- \ifyquant@config@operator@multi@warn%
- \def\yquant@draw@@finalize@ctrl@multi@contiguous@warn{0}%
- \else%
- \def\yquant@draw@@finalize@ctrl@multi@contiguous@warn{2}%
- \fi%
- \else%
- \def\yquant@draw@@finalize@ctrl@multi@contiguous@warn{2}%
- \fi%
- \cslet{\yquant@prefix finalize@ctrl@draw@appto}\empty%
- #4%
- \eappto\yquant@draw@append{\csname\yquant@prefix finalize@ctrl@draw@appto\endcsname}%
- \csgundef{\yquant@prefix finalize@ctrl@draw@appto}%
-}
-
-\protected\def\yquant@draw@@finalize@ctrl@multi@contiguous#1#2#3{%
- \ifnum\yquant@draw@@finalize@ctrl@multi@contiguous@warn=1 %
- \PackageWarning{yquant.sty}{Ambiguous operation: multiple discontiguous multi-register operations in combination with controls make it hard to visually determine on which registers the gates act on.}%
- % switch the warning off for this group (which is a single operation)
- \yquant@config@operator@multi@warnfalse%
- \def\yquant@draw@@finalize@ctrl@multi@contiguous@warn{2}%
- \else%
- \numdef\yquant@draw@@finalize@ctrl@multi@contiguous@warn{%
- \yquant@draw@@finalize@ctrl@multi@contiguous@warn+1%
- }%
- \fi%
- {% save \body
- \yquant@for \yquant@i := #1 to #2 {{% let inner loop mess up with macros
- \csxappto{\yquant@prefix finalize@ctrl@draw@appto}{%
- \expandafter\yquant@draw@callback@wire\expandafter{\yquant@i}%
- }%
- }}%
- }%
-}
-% END_FOLD \ No newline at end of file
+\protected\def\yquant@draw@move@loop#1{%
+ \yquant@register@set@x{#1}\newx%
+ \yquant@circuit@extendwire{#1}*%
+} \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-env.tex b/Master/texmf-dist/tex/latex/yquant/yquant-env.tex
index a9262b957da..96ea7bbac37 100644
--- a/Master/texmf-dist/tex/latex/yquant/yquant-env.tex
+++ b/Master/texmf-dist/tex/latex/yquant/yquant-env.tex
@@ -1,4 +1,5 @@
\newif\ifyquant@env@lazy
+\newif\ifyquantmeasuring
\protected\def\yquant@envunstar{%
\yquant@env@lazyfalse%
@@ -47,18 +48,17 @@
\yquant@env@begin@generic\yquant%
}
-\long\protected\def\yquant@env@begin@generic#1[#2]{
+\long\protected\def\yquant@env@begin@generic#1[#2]{%
\begingroup%
\let\yquant@parent=\yquant@prefix%
\global\advance\yquant@env by 1 %
\edef\yquant@prefix{yquant@env\the\yquant@env @}%
\ifnum\yquant@env=1 %
+ \yquantmeasuringtrue%
\yquant@env@substikz#1%
- \def\yquant@env@create@x{0pt}%
\global\cslet{\yquant@prefix parameters}\empty%
\else%
\let\yquant@lang@reset@attrs@inputoutput=\yquant@lang@reset@attrs@inputoutput@subcircuit%
- \let\yquant@env@create@x=\yquant@circuit@operator@x%
\global\cslet{\yquant@prefix parameters}\yquant@circuit@subcircuit@param%
\yquant@env@lazyfalse% forbid lazy register creation in subcircuits. We need a proper and in-order declaration of the subcircuit's interface.
\fi%
@@ -67,42 +67,45 @@
\csgdef{\yquant@prefix registers}{0}%
\global\cslet{\yquant@prefix draw}\relax%
\global\cslet{\yquant@prefix outputs}\relax%
- \csdimgdef{\yquant@prefix xmin}{\yquant@env@create@x+\yquant@config@operator@sep}%
\global\cslet{\yquant@prefix subcircuits}\empty%
\global\cslet{\yquant@prefix inonly}\empty%
+ \global\csletcs{\yquant@prefix seamless}{ifyquant@config@circuit@seamless}%
+ \ifdefined\yquant@prevseamless%
+ \cslet{ifyquant@config@circuit@seamless}\yquant@prevseamless%
+ \undef\yquant@prevseamless%
+ \fi%
\csxdef{\yquant@prefix cleanup}{%
\expandafter\noexpand\csname\yquant@prefix registers\endcsname%
\expandafter\noexpand\csname\yquant@prefix draw\endcsname%
\expandafter\noexpand\csname\yquant@prefix outputs\endcsname%
\expandafter\noexpand\csname\yquant@prefix parameters\endcsname%
- \expandafter\noexpand\csname\yquant@prefix xmin\endcsname%
\expandafter\noexpand\csname\yquant@prefix subcircuits\endcsname%
\expandafter\noexpand\csname\yquant@prefix inonly\endcsname%
+ \expandafter\noexpand\csname\yquant@prefix seamless\endcsname%
\expandafter\noexpand\csname\yquant@prefix cleanup\endcsname%
}%
\scope[{/yquant/.cd, #2, /tikz/.cd, /yquant/every circuit}]%
}
\protected\def\yquant@env@end{%
- \letcs\yquant@env@end@registers{\yquant@prefix registers}%
- \ifnum\yquant@env@end@registers>0 %
- % draw all wires
- \yquant@register@get@maxxrange\yquant@env@end@xpos{1}{\yquant@env@end@registers}%
- \ifdim\csname\yquant@prefix xmin\endcsname<%
- \dimexpr\yquant@env@create@x+\yquant@config@operator@sep\relax%
- % to have a symmetric situation, we extend again one separation at the end
- \dimdef\yquant@env@end@xpos{\yquant@env@end@xpos+\yquant@config@operator@sep}%
- \global\cslet{\yquant@prefix xmax}\yquant@env@end@xpos%
- \else%
- % while the outputs need this, the subcircuit doesn't if there are no outputs.
- \global\cslet{\yquant@prefix xmax}\yquant@env@end@xpos%
- \dimdef\yquant@env@end@xpos{\yquant@env@end@xpos+\yquant@config@operator@sep}%
+ \ifnum\csname\yquant@prefix registers\endcsname>0 %
+ \yquant@for \i := 1 to \csname\yquant@prefix registers\endcsname {%
+ \yquant@register@execclear@lastgate{\i}{@end}%
+ }%
+ \csgappto{\yquant@prefix draw}{%
+ \yquant@circuit@endwires%
+ }%
+ \expandafter\unless\expandafter\ifx\csname\yquant@prefix outputs\endcsname\relax%
+ \begingroup%
+ \def\yquant@config@operator@minimum@width{0pt}%
+ \let\yquant@prepare@single=\yquant@prepare@output@single%
+ \let\yquant@prepare@multi=\yquant@prepare@output@multi%
+ \csname\yquant@prefix outputs\endcsname%
+ \endgroup%
\fi%
- \yquant@cleanup@csadd{xmax}%
- \csxappto{\yquant@prefix draw}{%
- \yquant@circuit@endwires{\yquant@env@end@xpos}%
+ \csgappto{\yquant@prefix draw}{%
+ \yquant@circuit@endwires@finalize%
}%
- \csname\yquant@prefix outputs\endcsname%
% also calculate the true y positions
\unless\ifdefined\yquant@parent%
\yquant@env@end@calcypositions%
@@ -139,6 +142,7 @@
\ifyquantdebug%
\csshow{\yquant@prefix draw}%
\fi%
+ \yquantmeasuringfalse%
\csname\yquant@prefix draw\endcsname%
\expandafter\expandafter\expandafter\yquant@cleanup\csname\yquant@prefix cleanup\endcsname|%
\global\yquant@env=0 %
@@ -146,128 +150,342 @@
\endgroup%
}
+\protected\def\ifyquant@env@seamless{%
+ \csname\yquant@prefix seamless\endcsname%
+ \expandafter\@firstoftwo%
+ \else%
+ \expandafter\@secondoftwo%
+ \fi%
+}
+
+\newif\ifyquant@env@end@calcypositions@godeep
\protected\def\yquant@env@end@calcypositions{%
\begingroup%
\dimen4=\yquant@config@register@sep %
- % We know the heights of most gates, but subcircuits are tricky. Since the position of their inner wires depends on the heights of the outer wires, we could not make any assumption about their heights yet. So we now need multiple iterations: First, we fix the positions of our own wires preliminarily. Then, we iterate through all subcircuits at the first level, place their wires appropriately and try to align input and output. In doing so, we recognize when there's not enough space at an outer wire. If this is the case, we enlarge the outer wire's height appropriately and restart alignment from the outmost level. If everything is proper, we start aligning at the next level.
- \yquant@env@end@calcypositions@toplevel1%
+ \yquant@sort@clear%
+ % Setup...
+ \yquant@env@end@calcypositions@setup1%
+ % and go!
+ \let\redolist=\empty%
+ \yquant@env@end@calcypositions@godeeptrue%
+ \yquant@env@end@calcypositions@run1%
+ \yquant@env@end@calcypositions@godeepfalse%
+ \yquant@env@end@calcypositions@redo%
+% % The macros now set up performed all the proper and unambiguous justification. After that, we will also need to take care of the multi gates. We expect that for most of all multi gates, we already have enough space. But sometimes, this may not be the case, so we need to increase overall spacing and re-evaluate all spacing. In order to get a proper balanced layout, we start with the largest enlargement that is required. Every enlargement step will equally distribute the registers in between. Starting with the largest one, this is likely to also solve issues with smaller ones.
+ \yquant@env@end@calcypositions@multi%
% Turn the preliminary positions into true ones at every level.
\yquant@env@end@setypositions1%
\endgroup%
}
-\protected\def\yquant@env@end@calcypositions@loop#1{%
- % \yquant@parent has to be set already
+\protected\def\yquant@env@end@calcypositions@setup#1{%
\def\yquant@prefix{yquant@env#1@}%
- % #1 now holds the id of the subcircuit. Find the first input.
- \edef\firstinput{%
- \expandafter\expandafter\expandafter%
- \@firstoftwo\csname\yquant@prefix firstinput\endcsname%
+ % Our problem is a linear program. To solve it, we proceed iteratively: We define macros for each subcircuit that, based on the current positions, calculate the allowed positions.
+ \letcs\max{\yquant@prefix registers}%
+ % BEGIN_FOLD find out about the first and last register with maps
+ \let\firstinout=\relax%
+ \let\lastinout=\relax%
+ \yquant@for \i := 1 to \max {%
+ \ifcsname\yquant@prefix registermap@\i\endcsname%
+ \ifx\firstinout\relax%
+ \let\firstinout=\i%
+ \fi%
+ \let\lastinout=\i%
+ \fi%
}%
- \edef\lastinput{%
- \expandafter\expandafter\expandafter%
- \@firstoftwo\csname\yquant@prefix lastinput\endcsname%
+ % END_FOLD
+ % BEGIN_FOLD Take care with internal registers before the first inout
+ % We could in principle merge the loop to define \firstinout/\lastinout, but nested for loops are problematic.
+ \ifx\firstinout\relax%
+ \dimen0=\yquant@register@get@height1 %
+ \def\i{1}%
+ \else%
+ \edef\outerlevel{\yquant@register@get@parent{\firstinout}}%
+ \dimen0=\csname yquant@env\expandafter\@firstoftwo\outerlevel @env@endy@\expandafter\@secondoftwo\outerlevel\endcsname\relax%
+ \ifnum\firstinout>1 %
+ % We need to take special care with internal registers if the first one is not a connected one. In this case, the internal registers will grow upwards instead... Since the y position may change in both upward and downward direction, we need to have an additional bookkeeping value that stores the last y position of the first item in this subcircuit.
+ \csedef{\yquant@prefix env@endyprev}{\the\dimen0}%
+ \yquant@fordown \i := \numexpr\firstinout-1\relax downto 1 {%
+ \advance \dimen0 by -\dimexpr%
+ \expandafter\yquant@register@get@height\expandafter{\the\numexpr\i+1\relax}+%
+ \dimen4+%
+ \yquant@register@get@depth\i%
+ \relax%
+ % We know for sure there's none with a parent in this loop
+ \csedef{\yquant@prefix env@endy@\i}{\the\dimen0}%
+ \csedef{yquant@env@end@calcypositions@#1@\i}{%
+ \advance\dimen0 by -\dimexpr%
+ \noexpand\yquant@register@get@height{\the\numexpr\i+1\relax}+%
+ \dimen4+%
+ \noexpand\yquant@register@get@depth{\i}%
+ \relax%
+ % The first connected wire might have been re-aligned, which destroys all our knowledge. \dimen2 will contain the relative shift that we must take into account.
+ % Make sure the current y position is at most the previous y position + previous depth + separation + current height.
+ \noexpand\ifdim\dimexpr\dimen0-\dimen2\relax<\expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname\space%
+ \edef\expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname{\noexpand\the\dimen0}%
+ \ifinlist{#1}\noexpand\redolist\relax{%
+ \listadd\noexpand\redolist{#1}%
+ }%
+ \noexpand\else%
+ \noexpand\ifdim\dimen2=0pt %
+ % No change at all
+ \dimen0=\expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname\space%
+ \noexpand\else%
+ % We must still overwrite the position macro due to the shift
+ \dimen0=\dimexpr\expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname+\dimen2\relax%
+ \edef\expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname{\noexpand\the\dimen0}%
+ \ifinlist{#1}\noexpand\redolist\relax{%
+ \listadd\noexpand\redolist{#1}%
+ }%
+ \noexpand\fi
+ \noexpand\fi%
+ \unless\ifx\i1%
+ \expandafter\noexpand\csname yquant@env@end@calcypositions@#1@\the\numexpr\i-1\relax\endcsname%
+ \fi%
+ }%
+ }%
+ \fi%
+ \let\i=\firstinout%
+ \fi%
+ % END_FOLD
+ % BEGIN_FOLD Define initial macro
+ \csedef{yquant@env@end@calcypositions@#1}{%
+ \def\noexpand\yquant@prefix{\yquant@prefix}%
+ \dimen0=\expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname\relax%
+ \listremove\noexpand\redolist{#1}%
+ \expandafter\noexpand\csname yquant@env@end@calcypositions@#1@\i\endcsname%
+ \expandafter\unless\expandafter\ifx\csname\yquant@prefix subcircuits\endcsname\empty%
+ \ifinlist{#1}\noexpand\redolist{%
+ \noexpand\forlistloop%
+ \yquant@env@end@calcypositions@run%
+ \expandafter\noexpand\csname\yquant@prefix subcircuits\endcsname%
+ }{%
+ \noexpand\ifyquant@env@end@calcypositions@godeep%
+ \noexpand\forlistloop%
+ \yquant@env@end@calcypositions@run%
+ \expandafter\noexpand\csname\yquant@prefix subcircuits\endcsname%
+ \noexpand\fi%
+ }%
+ \fi%
}%
- % we already made sure during in \yquant@circuit@subcircuit that there is enough space above and below the subcircuit. Still, the wires need to be positioned. However, we will first deal with all intermediate wires, which need to be placed by means of shifts - there is no direct correspondence to heights or depths of parent wires any more.
- \ifnum\firstinput<\numexpr\lastinput-1\relax%
- \dimen0=\dimexpr%
- \csname y@\csname\yquant@prefix registermap@\firstinput\endcsname\endcsname+%
- \yquant@register@get@depth\firstinput+\dimen4%
- \relax%
- \yquant@for \i := \numexpr\firstinput+1\relax to \lastinput {%
- \advance\dimen0 by \yquant@register@get@height\i\relax%
+ % END_FOLD
+ % BEGIN_FOLD Set up chain of other macros
+ % We set up a chain of position evaluation macros. We start with the first [external] register in the outermost circuit; it is supposed to call the evaluation macro of its successor. Next, we iterate through all subcircuits (recursively). Whenever we find a register that is mapped to an outer one, we take appropriate measures.
+ \yquant@for \i := \i to \max {%
+ \ifcsname\yquant@prefix registermap@\i\endcsname%
+ % \outery = env@endy macro of parent wire
+ \edef\outerlevel{\yquant@register@get@parent{\i}}%
+ \edef\outery{%
+ \expandafter\noexpand\csname yquant@env\expandafter\@firstoftwo\outerlevel @env@endy@\expandafter\@secondoftwo\outerlevel\endcsname%
+ }%
+ % in this initialization step, we only check in one direction
+ \ifdim\dimen0<\outery\space%
+ \dimen0=\outery\space%
+ \fi%
+ \fi%
+ \csedef{\yquant@prefix env@endy@\i}{\the\dimen0}%
+ \unless\ifx\i\max%
+ \advance \dimen0 by \dimexpr%
+ \yquant@register@get@depth\i+%
+ \dimen4+%
+ \expandafter\yquant@register@get@height\expandafter{\the\numexpr\i+1\relax}%
+ \relax%
+ \fi%
+ \csedef{yquant@env@end@calcypositions@#1@\i}{%
+ % make sure the current y position is at least the previous y position + previous depth + separation + current height
+ \noexpand\ifdim\dimen0>\expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname\space%
+ \edef\expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname{\noexpand\the\dimen0}%
+ \ifinlist{#1}\noexpand\redolist\relax{%
+ \listadd\noexpand\redolist{#1}%
+ }%
+ \noexpand\else%
+ \dimen0=\expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname\space%
+ \noexpand\fi%
+ % now \dimen0 holds the current y position of register \i
+ % BEGIN_FOLD map
\ifcsname\yquant@prefix registermap@\i\endcsname%
- % this is an input: do we have enough space by using the outer position?
- \letcs\outername{\yquant@prefix registermap@\i}%
- \letcs\outery{y@\outername}%
- \ifdim\dimen0>\outery\relax%
- % re-aligning the outer positions is required
- \ifcsname y+@\outername\endcsname%
- \csdimdef{y+@\outername}%
- {\csname y+@\outername\endcsname+\dimen0-\outery}%
+ % if this is an in/out register, put it at the same position as the outer one
+ \noexpand\ifdim\dimen0<\expandafter\noexpand\outery\space%
+ \dimen0=\expandafter\noexpand\outery\space%
+ \let\expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname\expandafter\noexpand\outery%
+ \ifinlist{#1}\noexpand\redolist\relax{%
+ \listadd\noexpand\redolist{#1}%
+ }%
+ \noexpand\fi%
+ \noexpand\ifdim\dimen0>\expandafter\noexpand\outery\space%
+ \let\expandafter\noexpand\outery\expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname%
+ \ifinlist{\expandafter\@firstoftwo\outerlevel}\noexpand\redolist\relax{%
+ \listadd\noexpand\redolist{\expandafter\@firstoftwo\outerlevel}%
+ }%
+ \noexpand\fi%
+ \ifx\i\firstinout%
+ % This is the first in/out register. Find all previous internal registers and make sure the parent has enough height.
+ \ifnum\i>1 %
+ % Here, we must now call the (backwards-running) alignment macros of the previous registers. First fill \dimen2 with the relative shift of this wire's position with respect to the last iteration.
+ \dimen2=\dimexpr\dimen0-\expandafter\noexpand\csname\yquant@prefix env@endyprev\endcsname\relax%
+ % Store \dimen0...
+ \dimen6=\dimen0 %
+ % ...call previous calculations...
+ \expandafter\noexpand\csname yquant@env@end@calcypositions@#1@\the\numexpr\i-1\relax\endcsname%
+ % ...restore...
+ \dimen0=\dimen6 %
+ % ...and backup its value for the next iteration.
+ \edef\expandafter\noexpand\csname\yquant@prefix env@endyprev\endcsname{\noexpand\the\dimen0}%
+ \expandafter\noexpand\csname ifdim\endcsname\noexpand\yquant@register@peek@height\outerlevel<\dimexpr%
+ \noexpand\yquant@register@get@height1+%
+ \expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname-%
+ \expandafter\noexpand\csname\yquant@prefix env@endy@1\endcsname%
+ \relax%
+ \yquant@register@set@height@remote\outerlevel{\noexpand\the\dimexpr%
+ \noexpand\yquant@register@get@height1+%
+ \expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname-%
+ \expandafter\noexpand\csname\yquant@prefix env@endy@1\endcsname%
+ }%
\else%
- \csdimdef{y+@\outername}{\dimen0-\outery}%
+ \expandafter\noexpand\csname ifdim\endcsname\noexpand\yquant@register@peek@height\outerlevel<%
+ \noexpand\yquant@register@get@height1 %
+ \yquant@register@set@height@remote\outerlevel{%
+ \noexpand\yquant@register@get@height1%
+ }%
\fi%
- \let\yquant@env@end@calcypositions@redo=\relax%
+ \ifinlist{\expandafter\@firstoftwo\outerlevel}\noexpand\redolist\relax{%
+ \listadd\noexpand\redolist{\expandafter\@firstoftwo\outerlevel}%
+ }%
+ \expandafter\noexpand\csname fi\endcsname%
+ \fi%
+ \ifx\i\lastinout%
+ % this is the last in/out register. Find all following internal registers and make sure the parent has enough depth.
+ \ifnum\i<\max\space%
+ \expandafter\noexpand\csname ifdim\endcsname\noexpand\yquant@register@peek@depth\outerlevel<\dimexpr%
+ \noexpand\yquant@register@get@depth{\max}+%
+ \expandafter\noexpand\csname\yquant@prefix env@endy@\max\endcsname-%
+ \expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname%
+ \relax%
+ \yquant@register@set@depth@remote\outerlevel{\noexpand\the\dimexpr%
+ \noexpand\yquant@register@get@depth{\max}+%
+ \expandafter\noexpand\csname\yquant@prefix env@endy@\max\endcsname-%
+ \expandafter\noexpand\csname\yquant@prefix env@endy@\i\endcsname%
+ }%
+ \else%
+ \expandafter\noexpand\csname ifdim\endcsname\noexpand\yquant@register@peek@depth\outerlevel<%
+ \noexpand\yquant@register@get@depth{\max} %
+ \yquant@register@set@depth@remote\outerlevel{%
+ \noexpand\yquant@register@get@depth{\max}%
+ }%
+ \fi%
+ \ifinlist{\expandafter\@firstoftwo\outerlevel}\noexpand\redolist\relax{%
+ \listadd\noexpand\redolist{\expandafter\@firstoftwo\outerlevel}%
+ }%
+ \expandafter\noexpand\csname fi\endcsname%
\fi%
- \else%
- \csedef{y@\yquant@prefix register@\i}{\the\dimen0}%
\fi%
- \ifdefined\yquant@env@end@calcypositions@redo%
- \expandafter\yquant@for@break%
- \else%
- \advance\dimen0 by \dimexpr\yquant@register@get@depth\i+\dimen4\relax%
+ % END_FOLD
+ \unless\ifx\i\max%
+ \advance\dimen0 by \dimexpr%
+ \noexpand\yquant@register@get@depth{\i}+%
+ \dimen4+%
+ \noexpand\yquant@register@get@height{\the\numexpr\i+1\relax}%
+ \relax%
+ \expandafter\noexpand\csname yquant@env@end@calcypositions@#1@\the\numexpr\i+1\relax\endcsname%
\fi%
}%
+ % for every multi-register space requirement, install the requirement in the sortlist
+ \edef\multidata{\yquant@register@get@multispace\i}%
+ \forlistloop{\yquant@env@end@calcypositions@setupmulti{#1}}\multidata%
+ }%
+ % END_FOLD
+ \forlistcsloop\yquant@env@end@calcypositions@setup{\yquant@prefix subcircuits}%
+}
+
+\protected\def\yquant@env@end@calcypositions@setupmulti#1#2{%
+ \yquant@sort@eadd{%
+ {#1}%
+ {\i}%
+ {\expandafter\@firstoftwo\yquant@env@end@calcypositions@setupmulti@group#2\yquant@end}%
+ {\expandafter\@secondoftwo\yquant@env@end@calcypositions@setupmulti@group#2\yquant@end}%
+ }%
+}
+
+\def\yquant@env@end@calcypositions@setupmulti@group#1:#2\yquant@end{{#1}{#2}}
+
+\protected\def\yquant@env@end@calcypositions@run#1{%
+ \csname yquant@env@end@calcypositions@#1\endcsname%
+}
+
+\protected\def\yquant@env@end@calcypositions@redo{%
+ \forlistloop\yquant@env@end@calcypositions@run\redolist%
+ \unless\ifx\redolist\empty%
+ \expandafter\yquant@env@end@calcypositions@redo%
\fi%
- \unless\ifdefined\yquant@env@end@calcypositions@redo%
- % sounds good, no readjustments necessary. Now transfer the wires above and below in the appropriate macros.
- \ifnum\firstinput>1 %
- \dimen0=\dimexpr%
- \csname y@\csname\yquant@prefix registermap@\firstinput\endcsname\endcsname-%
- \yquant@register@get@height\firstinput-\dimen4%
- \relax%
- \yquant@fordown \i := \numexpr\firstinput-1\relax downto 1 {%
- \advance\dimen0 by -\yquant@register@get@depth\i\relax%
- \csedef{y@\yquant@prefix register@\i}{\the\dimen0}%
- \advance\dimen0 by -\dimexpr\yquant@register@get@height\i+\dimen4\relax%
- }%
- \fi%
- \ifnum\lastinput<\csname\yquant@prefix registers\endcsname%
- \dimen0=\dimexpr%
- \csname y@\csname\yquant@prefix registermap@\lastinput\endcsname\endcsname+%
- \yquant@register@get@depth\lastinput+\dimen4%
- \relax%
- \yquant@for \i := \numexpr\lastinput+1\relax to \csname\yquant@prefix registers\endcsname {%
- \advance\dimen0 by \yquant@register@get@height\i\relax%
- \csedef{y@\yquant@prefix register@\i}{\the\dimen0}%
- \advance\dimen0 by \dimexpr\yquant@register@get@depth\i+\dimen4\relax%
- }%
- \fi%
- \fi%
- \ifdefined\yquant@env@end@calcypositions@redo%
- % forget every plan about going deeper, restart.
- \expandafter\listbreak%
- \else%
- \expandafter\yquant@env@end@calcypositions@subcircuits%
- \fi%
}
-\protected\def\yquant@env@end@calcypositions@subcircuits{%
- \let\yquant@parent=\yquant@prefix%
- \forlistcsloop\yquant@env@end@calcypositions@loop{\yquant@prefix subcircuits}%
- \ifdefined\yquant@env@end@calcypositions@redo%
- \expandafter\listbreak%
+\def\yquant@env@end@calcypositions@multiheight#1#2#3#4{%
+ \dimexpr%
+ \csname yquant@env#1@env@endy@#3\endcsname-
+ \csname yquant@env#1@env@endy@#2\endcsname+%
+ \yquant@register@peek@height{#1}{#2}+%
+ \yquant@register@peek@depth{#1}{#3}%
+ \relax%
+}
+
+\def\yquant@env@end@calcypositions@sortmulti#1#2{%
+ % sort, in descending order, by the amount of missing space
+ \ifdim\dimexpr\@fourthoffour#2-\yquant@env@end@calcypositions@multiheight#2\relax>%
+ \dimexpr\@fourthoffour#1-\yquant@env@end@calcypositions@multiheight#1\relax%
+ \expandafter\@firstoftwo%
+ \else%
+ \expandafter\@secondoftwo%
\fi%
}
-\protected\def\yquant@env@end@calcypositions@toplevel{%
- \def\yquant@prefix{yquant@env1@}%
- \dimen0=0pt %
- \yquant@for \i := 1 to \yquant@env@end@registers {%
- % we do not care if the wire is present for the y position
- \advance\dimen0 by \yquant@register@get@height\i\relax%
- \ifcsname y+@\yquant@prefix register@\i\endcsname%
- \advance\dimen0 by \csname y+@\yquant@prefix register@\i\endcsname\relax%
+\protected\def\yquant@env@end@calcypositions@multi{%
+ % We will always only operate on the first item in the sortlist, which is determined anew in each iteration - as changes due to this first item will potentially affect all others, including which one is the next...
+ \yquant@sort@findfirst\yquant@env@end@calcypositions@sortmulti\first%
+ \unless\ifx\first\empty%
+ \dimdef\missing{%
+ \expandafter\@fourthoffour\first-%
+ \expandafter\yquant@env@end@calcypositions@multiheight\first%
+ }%
+ % maybe this was already resolved?
+ \ifdim\missing>0pt %
+ \edef\yquant@prefix{yquant@env\expandafter\@firstoffour\first @}%
+ \numdef\divisor{\expandafter\@thirdoffour\first-\expandafter\@secondoffour\first}% not +1, since we will not move the first element
+ \dimdef\add{1sp+\dimexpr\missing-1sp\relax/\divisor}%
+ \let\inc=\add%
+ \edef\max{\expandafter\@thirdoffour\first}%
+ \ifnum\expandafter\@secondoffour\first<\max\relax%
+ \yquant@for \i := \numexpr\expandafter\@secondoffour\first+1\relax to \max {%
+ \csdimdef{\yquant@prefix env@endy@\i}{\csname\yquant@prefix env@endy@\i\endcsname+\add}%
+ \dimdef\add{\add+\inc}%
+ }%
+ \fi%
+ \yquant@env@end@calcypositions@godeeptrue%
+ \csname yquant@env@end@calcypositions@\expandafter\@firstoffour\first\endcsname%
+ \yquant@env@end@calcypositions@godeepfalse%
+ \yquant@env@end@calcypositions@redo%
+ \expandafter\expandafter\expandafter\yquant@env@end@calcypositions@multi%
\fi%
- \csedef{y@\yquant@prefix register@\i}{\the\dimen0}%
- \advance\dimen0 by \dimexpr\yquant@register@get@depth\i+\dimen4\relax%
- }%
- \undef\yquant@env@end@calcypositions@redo%
- \let\yquant@parent=\yquant@prefix%
- \forlistcsloop\yquant@env@end@calcypositions@loop{\yquant@prefix subcircuits}%
- \ifdefined\yquant@env@end@calcypositions@redo%
- \expandafter\yquant@env@end@calcypositions@toplevel%
\fi%
}
\protected\def\yquant@env@end@setypositions#1{%
\def\yquant@prefix{yquant@env#1@}%
- \yquant@for \i := 1 to \csname\yquant@prefix registers\endcsname {%
- \unless\ifcsname\yquant@prefix registermap@\i\endcsname%
- \yquant@register@set@y\i{-\csname y@\yquant@prefix register@\i\endcsname}%
- \fi%
- }%
+ \ifyquantdebug%
+ \yquant@for \i := 1 to \csname\yquant@prefix registers\endcsname {%
+ \ifcsname\yquant@prefix registermap@\i\endcsname%
+ \message{^^J y(#1, \i): external}%
+ \else%
+ \message{^^J y(#1, \i): \csname\yquant@prefix env@endy@\i\endcsname}%
+ \yquant@register@set@y\i{-\csname\yquant@prefix env@endy@\i\endcsname}%
+ \fi%
+ }%
+ \else%
+ \yquant@for \i := 1 to \csname\yquant@prefix registers\endcsname {%
+ \unless\ifcsname\yquant@prefix registermap@\i\endcsname%
+ \yquant@register@set@y\i{-\csname\yquant@prefix env@endy@\i\endcsname}%
+ \fi%
+ }%
+ \fi%
\forlistcsloop\yquant@env@end@setypositions{\yquant@prefix subcircuits}%
}
@@ -303,6 +521,9 @@
\let\path=\tikz@command@path%
\let\tikz@finish=\yquant@env@substikz@finish%
\let\tikz@lib@scope@check=\yquant@env@substikz@scopecheck%
+ % we rely on the origin being the origin
+ \pgf@pt@x=0pt %
+ \pgf@pt@y=0pt %
}
% substitute the tikz commands (defined in \tikz@installcommands) so that they can be arbitrarily interleaved with yquant code. We patch \path, \scope, \endscope, \stopscope, their internal complements, and also patch \yquantset.
diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-lang.tex b/Master/texmf-dist/tex/latex/yquant/yquant-lang.tex
index 2ea08e8b16c..f19ebfcc386 100644
--- a/Master/texmf-dist/tex/latex/yquant/yquant-lang.tex
+++ b/Master/texmf-dist/tex/latex/yquant/yquant-lang.tex
@@ -14,21 +14,66 @@
\let\yquant@lang@attr@input=\relax%
\undef\yquant@lang@attr@output%
},%
- in/.default=\regidx,%
out/.code={%
\undef\yquant@lang@attr@input%
\let\yquant@lang@attr@output=\relax%
},%
- out/.default=\regidx,%
inout/.code={%
\let\yquant@lang@attr@input=\relax%
\let\yquant@lang@attr@output=\relax%
+ },%
+ frameless/.code={%
+ \pgfkeysalso{/yquant/operators/subcircuit/frameless}%
+ \appto\yquant@attrs@remaining{,/yquant/operators/subcircuit/frameless}%
+ },%
+ seamless/.code={%
+ \pgfkeysalso{/yquant/operators/subcircuit/seamless}%
+ \appto\yquant@attrs@remaining{,/yquant/operators/subcircuit/seamless}%
+ },%
+ direct control/.code={%
+ \let\yquant@lang@attr@directcontrol=\relax%
+ },%
+ indirect control/.code={%
+ \undef\yquant@lang@attr@directcontrol%
}%
- inout/.default=\regidx,%
}
\yquant@langhelper@declare@attr@global{%
- name/.store in=\yquant@lang@attr@name%
-}
+ name/.store in=\yquant@lang@attr@name,%
+ overlay/.code={%
+ \ifstrequal{#1}{true}{%
+ \yquant@lang@attr@overlay@multitrue%
+ \yquant@lang@attr@overlay@heighttrue%
+ \yquant@lang@attr@overlay@depthtrue%
+ }{%
+ \ifstrequal{#1}{false}{%
+ % Why??? This is the default and should always be reset automatically!
+ \yquant@lang@attr@overlay@multifalse%
+ \yquant@lang@attr@overlay@heightfalse%
+ \yquant@lang@attr@overlay@depthfalse%
+ }{%
+ \pgfqkeys{/yquant/global attrs/overlay}{#1}%
+ }%
+ }%
+ },%
+ overlay/.default=true,%
+ overlay/multi/.is if=yquant@lang@attr@overlay@multi,%
+ overlay/m/.forward to=/yquant/global attrs/overlay/multi,%
+ overlay/height/.is if=yquant@lang@attr@overlay@height,%
+ overlay/ht/.forward to=/yquant/global attrs/overlay/height,%
+ overlay/h/.forward to=/yquant/global attrs/overlay/height,%
+ overlay/depth/.is if=yquant@lang@attr@overlay@depth,%
+ overlay/dp/.forward to=/yquant/global attrs/overlay/depth,%
+ overlay/d/.forward to=/yquant/global attrs/overlay/depth,%
+ overlay/single/.code={\pgfkeysalso{%
+ /yquant/global attrs/overlay/height={#1},%
+ /yquant/global attrs/overlay/depth={#1}%
+ }},%
+ overlay/single/.default=true,%
+ overlay/s/.forward to=/yquant/global attrs/overlay/single,%
+}
+\newif\ifyquant@lang@attr@overlay@multi%
+\newif\ifyquant@lang@attr@overlay@height%
+\newif\ifyquant@lang@attr@overlay@depth%
\protected\def\yquant@lang@reset@attrs{%
\undef\yquant@lang@attr@value%
@@ -36,6 +81,9 @@
\undef\yquant@lang@attr@type%
\yquant@lang@reset@attrs@inputoutput%
\let\yquant@lang@attr@name=\empty%
+ \yquant@lang@attr@overlay@multifalse%
+ \yquant@lang@attr@overlay@heightfalse%
+ \yquant@lang@attr@overlay@depthfalse%
}
\protected\def\yquant@lang@reset@attrs@inputoutput{%
@@ -50,7 +98,7 @@
% END_FOLD
% BEGIN_FOLD Declaration of registers
-\yquant@langhelper@declare@command@uncontrolled{nobit}\yquant@lang@@nobit
+\yquant@langhelper@declare@command@create{nobit}\yquant@lang@@nobit
\yquant@langhelper@setup@attrs{nobit}{}{ancilla,out}
\def\yquant@lang@@nobit#1{%
\let\yquant@lang@create@type=\yquant@register@type@none%
@@ -64,7 +112,7 @@
\yquant@lang@create@parse@name#1[;%
}
-\yquant@langhelper@declare@command@uncontrolled{qubit}\yquant@lang@@qubit
+\yquant@langhelper@declare@command@create{qubit}\yquant@lang@@qubit
\yquant@langhelper@setup@attrs{qubit}{}{after,value,ancilla,in,out,inout}
\def\yquant@lang@@qubit#1{%
\let\yquant@lang@create@type=\yquant@register@type@q%
@@ -75,18 +123,18 @@
\yquant@lang@create@parse@name#1[;%
}
-\yquant@langhelper@declare@command@uncontrolled{cbit}\yquant@lang@@cbit
+\yquant@langhelper@declare@command@create{cbit}\yquant@lang@@cbit
\yquant@langhelper@setup@attrs{cbit}{}{after,value,ancilla,in,out,inout}
\def\yquant@lang@@cbit#1{%
\let\yquant@lang@create@type=\yquant@register@type@c%
- \def\yquant@lang@create@style{qubit}%
+ \def\yquant@lang@create@style{cbit}%
\unless\ifdefined\yquant@lang@attr@value%
\let\yquant@lang@attr@value=\yquant@config@register@default@name%
\fi%
\yquant@lang@create@parse@name#1[;%
}
-\yquant@langhelper@declare@command@uncontrolled{qubits}\yquant@lang@@qubits
+\yquant@langhelper@declare@command@create{qubits}\yquant@lang@@qubits
\yquant@langhelper@setup@attrs{qubits}{}{after,value,ancilla,in,out,inout}
\def\yquant@lang@@qubits#1{%
\let\yquant@lang@create@type=\yquant@register@type@qs%
@@ -136,193 +184,87 @@
\else%
\def\regidx{\reg[\idx]}%
\fi%
- % determine x position
- \ifdefined\yquant@lang@attr@after%
- \yquant@register@get@maxxlist\yquant@lang@create@x\yquant@lang@attr@after%
- \ifdefined\yquant@lang@attr@input%
- \PackageError{yquant.sty}{An input register cannot be created with `after` attribute}{}%
+ \numdef\yquant@circuit@operator@mintarget{\csname\yquant@prefix registers\endcsname+1}%
+ % create the registers
+ \begingroup%
+ % if we have the after attribute, we start with a discarded wire
+ \ifdefined\yquant@lang@attr@after%
+ \ifdefined\yquant@lang@attr@input%
+ \PackageError{yquant.sty}{An input register cannot be created with `after` attribute}{}%
+ \fi%
+ \let\yquant@lang@create@type=\yquant@register@type@none%
\fi%
+ \yquant@for \idx := \idx to \numexpr \len -1\relax {%
+ \yquant@prepare@create\reg\idx\yquant@lang@create@type%
+ }%
+ \endgroup%
+ % gather details about the created registers
+ \letcs\yquant@circuit@operator@maxtarget{\yquant@prefix registers}%
+ \numdef\yquant@circuit@operator@numtarget{\yquant@circuit@operator@maxtarget-\yquant@circuit@operator@mintarget+1}%
+ \edef\yquant@circuit@operator@targets{%
+ \yquant@list@range%
+ \yquant@circuit@operator@mintarget%
+ \yquant@circuit@operator@maxtarget%
+ }%
+ \let\yquant@circuit@operator@pctrls=\empty%
+ \def\yquant@circuit@operator@minpctrl{2147483647}%
+ \def\yquant@circuit@operator@maxpctrl{0}%
+ \let\yquant@circuit@operator@numpctrl=\yquant@circuit@operator@maxpctrl%
+ \let\yquant@circuit@operator@nctrls=\empty%
+ \let\yquant@circuit@operator@minnctrl=\yquant@circuit@operator@minpctrl%
+ \let\yquant@circuit@operator@maxnctrl=\yquant@circuit@operator@maxpctrl%
+ \let\yquant@circuit@operator@numnctrl=\yquant@circuit@operator@numpctrl%
+ \let\yquant@circuit@operator@minctrl=\yquant@circuit@operator@mintarget%
+ \let\yquant@circuit@operator@maxctrl=\yquant@circuit@operator@maxtarget%
+ % if we have the after attribute, we fake an align gate
+ \ifdefined\yquant@lang@attr@after%
+ \edef\jointindices{\yquant@circuit@operator@targets\yquant@lang@attr@after}%
+ \yquant@circuit@align\jointindices%
+ % and we also need to change the wire after the alignment
+ \let\yquant@circuit@settype@to=\yquant@lang@create@type%
+ \let\yquant@prepare@callback@prepare=\yquant@circuit@settype@prepare%
+ \let\yquant@prepare@callback@draw=\yquant@circuit@settype%
+ \expandafter\@thirdofthree%
\else%
- \let\yquant@lang@create@x=\yquant@env@create@x%
+ \expandafter\@firstofone%
\fi%
- \begingroup%
+ % unless there is no name, no text and no after attribute, we now need an init gate
+ {%
+ \ifx\yquant@lang@attr@value\empty%
+ \expandafter\@firstofone%
+ \else%
+ \expandafter\@secondoftwo%
+ \fi%
+ }%
+ {%
\ifx\yquant@lang@attr@name\empty%
- \let\yquant@lang@create@name=\empty%
+ \expandafter\@gobble%
\else%
- \def\yquant@lang@create@name{\yquant@lang@attr@name-\idx}%
+ \expandafter\@firstofone%
\fi%
- % pre-set y position
- \yquant@for \idx := \idx to \numexpr \len -1\relax {%
- \ifdefined\yquant@lang@attr@input%
- \expandafter\yquant@list@gdequeue\csname \yquant@prefix parameters\endcsname\outermap%
- \ifx\outermap\empty%
- \PackageError{yquant.sty}{Invalid subcircuit parameter count}%
- {No outer register available for input register `\reg[\idx]`.}%
- \fi%
- \csxappto{\yquant@prefix draw}{%
- \yquant@lang@create@check@input{\outermap}{\yquant@lang@create@type}%
- {\reg[\idx]}%
- }%
- \unless\ifdefined\yquant@lang@attr@output%
- \listcsxadd{\yquant@prefix inonly}%
- {\the\numexpr\csname\yquant@prefix registers\endcsname+1\relax}%
- \fi%
- \yquant@register@alias%
- \yquant@lang@create@type%
- \yquant@lang@create@x%
- \reg\idx\outermap%
- \else%
- \ifdefined\yquant@lang@attr@output%
- \expandafter\yquant@list@gdequeue\csname\yquant@prefix parameters\endcsname\outermap%
- \ifx\outermap\empty%
- \PackageError{yquant.sty}{Invalid subcircuit parameter count}%
- {No outer register available for output register `\reg`.}%
- \fi%
- \csxappto{\yquant@prefix draw}{%
- \yquant@lang@create@check@output{\outermap}{\reg[\idx]}%
- }%
- \yquant@register@alias%
- \yquant@lang@create@type%
- \yquant@lang@create@x%
- \reg\idx\outermap%
- \else%
- \yquant@register@define%
- \yquant@lang@create@type%
- \yquant@lang@create@x%
- \reg\idx%
- \fi%
- \fi%
- % First determine the actual height by a virtual draw command
- \protected@edef\trimmedvalue{\trim@spaces{\yquant@lang@attr@value}}%
- \unless\ifx\empty\trimmedvalue%
- \pgfinterruptboundingbox%
- \yquant@env@virtualize@path%
- \edef\cmd{%
- \noexpand\path%
- (\yquant@lang@create@x, 0pt)%
- node[/yquant/every label, /yquant/every initial label,%
- /yquant/every \yquant@lang@create@style\space label%
- \ifdefined\yquant@lang@attr@input, /yquant/every input label\fi]%
- {\unexpanded\expandafter{\trimmedvalue}};%
- }%
- \cmd%
- \ifdim\pgf@picminx<\csname\yquant@prefix xmin\endcsname%
- \csxdef{\yquant@prefix xmin}{\the\pgf@picminx}%
- \fi%
- \expandafter\yquant@register@update@height%
- \csname\yquant@prefix registers\endcsname%
- {\the\pgf@picmaxy}%
- \expandafter\yquant@register@update@depth%
- \csname\yquant@prefix registers\endcsname%
- {\the\dimexpr-\pgf@picminy\relax}%
- \endpgfinterruptboundingbox%
- \fi%
- % Prepare to shipout
- \csxappto{\yquant@prefix draw}{%
- \yquant@lang@create@draw{\csname\yquant@prefix registers\endcsname}%
- {\yquant@lang@create@x}%
- {\yquant@lang@create@style}%
- \ifdefined\yquant@lang@attr@input1\else0\fi%
- {\unexpanded\expandafter{\trimmedvalue}}%
- {\yquant@lang@create@name}%
- \unless\ifdefined\yquant@lang@attr@input%
- \ifdefined\yquant@lang@attr@output%
- \yquant@circuit@flushwire%
- {\csname\yquant@prefix registers\endcsname}%
- \yquant@register@set@type%
- {\csname\yquant@prefix registers\endcsname}%
- \yquant@lang@create@type%
- \fi%
- \fi%
+ }%
+ {%
+ % there are no multi inits in this context
+ \preto\yquant@attrs@remaining{internal/move label,}%
+ \def\yquant@config@operator@minimum@width{0pt}%
+ \unless\ifx\yquant@lang@attr@value\empty%
+ % make sure to immediately remove the "clear" marker again if we have a text
+ \yquant@for \i := \yquant@circuit@operator@mintarget to \yquant@circuit@operator@maxtarget {%
+ \yquant@register@execclear@lastgate{\i}{init}%
}%
- }%
+ \fi%
+ \expandafter\yquant@prepare%
+ \expandafter{\yquant@lang@attr@value}%
+ {/yquant/every label, /yquant/every initial label,%
+ /yquant/every \yquant@lang@create@style\space label,%
+ \ifnum\yquant@compat<2 \ifdefined\yquant@lang@attr@input /yquant/every input label\fi\fi}%
\unless\ifx\yquant@lang@attr@name\empty%
\ifnum\len=1 %
\csxappto{\yquant@prefix draw}%
{\yquant@draw@alias{\yquant@lang@attr@name}}%
\fi%
\fi%
- \endgroup%
-}
-
-\protected\def\yquant@lang@create@check@input#1#2#3{%
- \begingroup%
- \let\yquant@prefix=\yquant@parent%
- \unless\if#2\yquant@register@get@type{#1}%
- \PackageError{yquant.sty}{Subcircuit expects wire of type `\yquant@register@type@tostring{#2}', but got `\yquant@register@type@tostring{\yquant@register@get@type{#1}}'}%
- {Outer and inner wire types must match for input wire `\detokenize{#3}`.}%
- \fi%
- \endgroup%
-}
-
-\protected\def\yquant@lang@create@check@output#1#2{%
- \begingroup%
- \let\yquant@prefix=\yquant@parent%
- \unless\if\yquant@register@type@none\yquant@register@get@type{#1}%
- \PackageError{yquant.sty}%
- {Subcircuit expects discarded wire, got `\yquant@register@type@tostring{\yquant@register@get@type{#1}}'}%
- {Outer wire must be discarded before being acceptable for output-only register `\detokenize{#2}`.}%
- \fi%
- \endgroup%
-}
-
-\protected\def\yquant@lang@create@draw#1#2#3#4#5#6{%
- \begingroup%
- \dimdef\wireypos{\yquant@register@get@y{#1}}%
- \ifcsname\yquant@prefix xshift\endcsname%
- \dimdef\createxpos{#2+\csname\yquant@prefix xshift\endcsname}%
- \else%
- \dimdef\createxpos{#2}%
- \fi%
- \ifstrempty{#5}{%
- % For empty labels, we still put the node at the appropriate position as it may needs to be referenced, but we will not let it effect the bounding box (so that the left end is not shifted), and we don't need an inner separation, so that the label is truely just a coordinate.
- \path[overlay]%
- (\createxpos, \wireypos)%
- coordinate[name prefix=, name suffix=, name=yquantbox];%
- \let\pgfshapeclippathhorzresult=\empty%
- }{%
- \edef\cmd{%
- \noexpand\path%
- (\createxpos, \wireypos)%
- node[/yquant/every label, /yquant/every initial label,%
- /yquant/every #3 label\ifx1#4, /yquant/every input label\fi,%
- name prefix=, name suffix=, name=yquantbox]%
- {\unexpanded{#5}};%
- \ifcsname\yquant@prefix registermap@#1\endcsname%
- \pgfshapeclippath{yquantbox}%
- {/yquant/every label, /yquant/every initial label,%
- /yquant/every #3 label\ifx1#4, /yquant/every input label\fi}%
- \fi%
- }%
- \cmd%
- }%
- \ifcsname\yquant@prefix registermap@#1\endcsname%
- % if this is an alias, the creation is just an extension
- \if\yquant@register@type@none\yquant@register@get@type{#1}%
- \ifstrequal{#3}{initial}{%
- \yquant@circuit@extendwire{#1}{east}%
- }{%
- % however, our inner wire is present, while the outer wire was discarded.
- \tikzset{/yquant/every wire}%
- \pgfpointanchor{yquantbox}{east}%
- \yquant@register@set@lastwire{#1}{%
- {\the\pgf@x}{\the\pgf@x}{}%
- {\unexpanded\expandafter{\pgfshapeclippathhorzresult}}%
- }%
- }%
- \else%
- \yquant@circuit@extendwire{#1}{east}%
- \fi%
- \else%
- % set the wire style to have the correct \pgflinewidth available (we don't allow individual line widths for different types of wires)
- \tikzset{/yquant/every wire}%
- \pgfpointanchor{yquantbox}{east}%
- \yquant@register@set@lastwire{#1}{{\the\pgf@x}{\the\pgf@x}{}{}}%
- \fi%
- \ifstrempty{#6}\relax{%
- \pgfnodealias{\tikz@pp@name{#6}}{yquantbox}%
- }%
- \endgroup%
+ }%
}
% END_FOLD
@@ -348,23 +290,21 @@
\protected\long\def\yquantdefinegate@i#1[#2]#3{%
\pgfkeys{/yquant/operators/every #1/.style={#2}}%
+ \yquant@prepare@ifs@set%
\protected@edef\yquantdefinegate@do{%
\yquant@langhelper@declare@command%
{#1}%
- \expandafter\noexpand\csname yquant@lang@@#1\endcsname%
+ \yquant@register@get@multiaslist%
+ {%
+ \let\noexpand\yquant@lang@attr@value=\expandafter\noexpand\csname yquant@lang@@#1\endcsname%
+ \yquant@prepare@subcircuit{/yquant/operators/every #1}%
+ }%
% This does not clear the attributes for redefines, but makes at least sure nothing is marked as required that should not be.
\yquant@langhelper@setup@attrs{#1}{}{}%
% Now define the gate's content as a macro
- \def\expandafter\noexpand\csname yquant@lang@@@#1\endcsname{%
+ \def\expandafter\noexpand\csname yquant@lang@@#1\endcsname{%
#3%
}%
- % And provide the implementation
- \protected\def\expandafter\noexpand\csname yquant@lang@@#1\endcsname####1####2####3{%
- \yquant@register@get@multiaslist%
- \yquant@circuit@operator{####1}{####2}{####3}%
- \let\noexpand\yquant@lang@attr@value=\expandafter\noexpand\csname yquant@lang@@@#1\endcsname%
- \yquant@draw@@subcircuit{/yquant/operators/every #1}%
- }%
}%
\yquantdefinegate@do%
}
@@ -374,8 +314,15 @@
\PackageError{yquant.sty}{Gate redefined}%
{The gate `#1' already exists. Use \string\yquantredefinebox\space if you really want to redefine it.}%
\fi%
- \@ifnextchar[{\yquantdefinebox@i{#1}}%
- {\yquantdefinebox@i{#1}[/yquant/operators/every box]}%
+ \yquantdefinebox@{#1}{}%
+}
+
+\def\yquantdefinemultibox#1{%
+ \ifcsname yquant@lang@#1\endcsname%
+ \PackageError{yquant.sty}{Gate redefined}%
+ {The gate `#1' already exists. Use \string\yquantredefinemultibox\space if you really want to redefine it.}%
+ \fi%
+ \yquantdefinebox@{#1}\yquant@register@get@allowmultitrue%
}
\def\yquantredefinebox#1{%
@@ -383,38 +330,47 @@
\PackageError{yquant.sty}{Unknown gate redefined}%
{The gate `#1' is unknown and cannot be redefined. Use \string\yquantdefinebox\space to define it.}%
\fi%
- \yquantdefinebox@i{#1}%
- \@ifnextchar[{\yquantdefinebox@i{#1}}%
- {\yquantdefinebox@i{#1}[/yquant/operators/every box]}%
+ \yquantdefinebox@{#1}{}%
}
-\protected\long\def\yquantdefinebox@i#1[#2]#3{%
- \pgfkeys{/yquant/operators/every #1/.style={#2}}%
+\def\yquantredefinemultibox#1{%
+ \unless\ifcsname yquant@lang@#1\endcsname%
+ \PackageError{yquant.sty}{Unknown gate redefined}%
+ {The gate `#1' is unknown and cannot be redefined. Use \string\yquantdefinemultibox\space to define it.}%
+ \fi%
+ \yquantdefinebox@{#1}\yquant@register@get@allowmultitrue%
+}
+
+\def\yquantdefinebox@#1#2{%
+ \@ifnextchar[{\yquantdefinebox@i{#1}{#2}}%
+ {\yquantdefinebox@i{#1}{#2}[/yquant/operators/every box]}%
+}
+
+\protected\long\def\yquantdefinebox@i#1#2[#3]#4{%
+ \pgfkeys{/yquant/operators/every #1/.style={#3}}%
+ \yquant@prepare@ifs@set%
\protected@edef\yquantdefinebox@do{%
\yquant@langhelper@declare@command%
{#1}%
- \expandafter\noexpand\csname yquant@lang@@#1\endcsname%
- \yquant@langhelper@setup@attrs{#1}{}{}%
- \def\expandafter\noexpand\csname yquant@lang@@#1\endcsname{%
- \yquant@draw%
- {#3}%
- {/yquant/operators/every #1}%
- }%
+ {\unexpanded{#2}}%
+ {\yquant@prepare{#4}{/yquant/operators/every #1}}%
}%
\yquantdefinebox@do%
+ \yquant@langhelper@setup@attrs{#1}{}{}%
}
% END_FOLD
% BEGIN_FOLD Box registers
% all-purpose box with arbitrary text
-\yquant@langhelper@declare@command{box}\yquant@lang@@box
-\yquant@langhelper@setup@attrs{box}{value}{}
-\def\yquant@lang@@box{%
+\yquant@langhelper@declare@command%
+ {box}%
\yquant@register@get@allowmultitrue%
- \expandafter\yquant@draw%
- \expandafter{\yquant@lang@attr@value}%
- {/yquant/operators/every box}%
-}
+ {%
+ \expandafter\yquant@prepare%
+ \expandafter{\yquant@lang@attr@value}%
+ {/yquant/operators/every box}%
+ }
+\yquant@langhelper@setup@attrs{box}{value}{}
% Hadamard
\yquantdefinebox{h}{$H$}
@@ -429,183 +385,255 @@
\yquantdefinebox{z}[/yquant/operators/every pauli]{$Z$}
% sub-circuit: This is a nested circuit.
-\yquant@langhelper@declare@command{subcircuit}\yquant@lang@@subcircuit
-\yquant@langhelper@setup@attrs{subcircuit}{value}{}
-\protected\def\yquant@lang@@subcircuit#1#2#3{%
+\yquant@langhelper@declare@command%
+ {subcircuit}%
\yquant@register@get@multiaslist%
- \yquant@circuit@operator{#1}{#2}{#3}%
- \yquant@draw@@subcircuit{/yquant/operators/every subcircuit}%
-}
+ {%
+ \yquant@prepare@subcircuit{/yquant/operators/every subcircuit}%
+ }
+\yquant@langhelper@setup@attrs{subcircuit}{value}{frameless,seamless}
% END_FOLD
% BEGIN_FOLD other geometric shapes
% phase
-\yquant@langhelper@declare@command{phase}\yquant@lang@@phase
+\yquant@langhelper@declare@command%
+ {phase}%
+ {}%
+ {%
+ \edef\cmd{%
+ \yquant@prepare%
+ {}%
+ {/yquant/operators/every phase, label={\unexpanded\expandafter{\yquant@lang@attr@value}}}%
+ }%
+ \cmd%
+ }
\yquant@langhelper@setup@attrs{phase}{value}{}%
-\def\yquant@lang@@phase{%
- \edef\cmd{%
- \noexpand\yquant@draw%
- {}%
- {/yquant/operators/every phase, label={\unexpanded\expandafter{\yquant@lang@attr@value}}}%
- }%
- \cmd%
-}
% two-qubit controlled x (symmetric notation)
-\yquant@langhelper@declare@command{xx}\yquant@lang@@xx
-\yquant@langhelper@setup@attrs{xx}{}{}
-\def\yquant@lang@@xx{%
+\yquant@langhelper@declare@command%
+ {xx}%
\yquant@register@get@multiassingle%
- \yquant@draw%
- {}%
- {/yquant/operators/every xx}%
-}
+ {%
+ \yquant@prepare%
+ {}%
+ {/yquant/operators/every xx}%
+ }
+\yquant@langhelper@setup@attrs{xx}{}{}
% two-qubit controlled phase (symmetric notation)
-\yquant@langhelper@declare@command@uncontrolled{zz}\yquant@lang@@zz
-\yquant@langhelper@setup@attrs{zz}{}{}
-\def\yquant@lang@@zz{%
+\yquant@langhelper@declare@command@uncontrolled%
+ {zz}%
\yquant@register@get@multiassingle%
- \yquant@draw%
- {}%
- {/yquant/operators/every zz}%
- {}{}%
-}
+ {%
+ \yquant@prepare%
+ {}%
+ {/yquant/operators/every zz}%
+ }
+\yquant@langhelper@setup@attrs{zz}{}{}
% slash (pseudo-operator, alternative indication for a bundle)
-\yquant@langhelper@declare@command@uncontrolled{slash}\yquant@lang@@slash
-\yquant@langhelper@setup@attrs{slash}{}{}
-\protected\def\yquant@lang@@slash#1{%
- % temporarily squeeze most into the separation
- \pgfkeys{%
- /yquant/operator/minimum width=0pt,%
- /yquant/operator/separation=.5\dimexpr\yquant@config@operator@sep-\pgflinewidth\relax%
- }%
- \def\yquant@draw@callback@wire##1{%
- \yquant@register@set@x%
- {##1}%
- {\the\dimexpr\yquant@register@get@x{##1}-\yquant@config@operator@sep-\pgflinewidth\relax}%
+\yquant@langhelper@declare@command@uncontrolled%
+ {slash}%
+ {}%
+ {%
+ % temporarily squeeze most into the separation
+ \pgfkeys{%
+ /yquant/operator/minimum width=0pt,%
+ }%
+ \preto\yquant@attrs@remaining{internal/squeeze slash,}%
+ \yquant@prepare%
+ {}%
+ {/yquant/operators/every slash}%
}
- \yquant@draw%
- {}%
- {/yquant/operators/every slash}%
- {}{}{#1}%
-}
+\yquant@langhelper@setup@attrs{slash}{}{}
% swap
-\yquant@langhelper@declare@command{swap}\yquant@lang@@swap
+\yquant@langhelper@declare@command%
+ {swap}%
+ \yquant@register@get@multiassingle
+ {%
+ \yquant@prepare%
+ {}%
+ {/yquant/operators/every swap}%
+ }
\yquant@langhelper@setup@attrs{swap}{}{}
-\def\yquant@lang@@swap{%
- \yquant@register@get@multiassingle%
- \yquant@draw%
- {}%
- {/yquant/operators/every swap}%
-}
% not
-\yquant@langhelper@declare@command{not}\yquant@lang@@not
+\yquant@langhelper@declare@command%
+ {not}%
+ {}%
+ {%
+ \yquant@prepare%
+ {}%
+ {/yquant/operators/every not}%
+ }
\yquant@langhelper@setup@attrs{not}{}{}
-\def\yquant@lang@@not{%
- \yquant@draw%
- {}%
- {/yquant/operators/every not}%
-}
% alias to cnot
-\let\yquant@lang@cnot=\yquant@lang@not
+\yquant@langhelper@declare@command@alias{cnot}{not}
\yquant@langhelper@setup@attrs{cnot}{}{}
% measure
-\yquant@langhelper@declare@command@uncontrolled{measure}\yquant@lang@@measure
-\yquant@langhelper@setup@attrs{measure}{}{value,type}
-\def\yquant@lang@@measure{%
- \ifdefined\yquant@lang@attr@type%
- \yquant@register@type@fromstring\yquant@lang@attr@type\yquant@circuit@settype@to%
- \else%
- \let\yquant@circuit@settype@to=\yquant@register@type@c%
- \fi%
- \let\yquant@draw@callback@wire=\yquant@circuit@settype%
+\yquant@langhelper@declare@command@uncontrolled%
+ {measure}%
\yquant@register@get@allowmultitrue%
- \unless\ifcsname yquant@lang@attr@value\endcsname%
- \let\yquant@lang@attr@value=\empty%
- \fi%
- \expandafter\yquant@draw%
- \expandafter{\yquant@lang@attr@value}%
- {/yquant/operators/every measure}%
- {}{}%
-}
+ {%
+ \ifdefined\yquant@lang@attr@type%
+ \yquant@register@type@fromstring\yquant@lang@attr@type\yquant@circuit@settype@to%
+ \else%
+ \let\yquant@circuit@settype@to=\yquant@register@type@c%
+ \fi%
+ \let\yquant@prepare@callback@prepare=\yquant@circuit@settype@prepare%
+ \let\yquant@prepare@callback@draw=\yquant@circuit@settype%
+ \unless\ifcsname yquant@lang@attr@value\endcsname%
+ \let\yquant@lang@attr@value=\empty%
+ \fi%
+ \ifdefined\yquant@lang@attr@directcontrol%
+ % direct control means that we must defer this operator until the next that has this/these targets as positive controls.
+ \expandafter\yquant@prepare@injection%
+ \expandafter{\yquant@lang@attr@value}%
+ {/yquant/operators/every measure}%
+ \else%
+ \expandafter\yquant@prepare%
+ \expandafter{\yquant@lang@attr@value}%
+ {/yquant/operators/every measure}%
+ \fi%
+ }
+\yquant@langhelper@setup@attrs{measure}{}{value,type,direct control,indirect control}
% measure (dmeter)
-\yquant@langhelper@declare@command@uncontrolled{dmeter}\yquant@lang@@dmeter
-\yquant@langhelper@setup@attrs{dmeter}{}{value,type}
-\def\yquant@lang@@dmeter{%
- \ifdefined\yquant@lang@attr@type%
- \yquant@register@type@fromstring\yquant@lang@attr@type\yquant@circuit@settype@to%
- \else%
- \let\yquant@circuit@settype@to=\yquant@register@type@c%
- \fi%
- \let\yquant@draw@callback@wire=\yquant@circuit@settype%
+\yquant@langhelper@declare@command@uncontrolled%
+ {dmeter}%
\yquant@register@get@allowmultitrue%
- \unless\ifcsname yquant@lang@attr@value\endcsname%
- \let\yquant@lang@attr@value=\empty%
- \fi%
- \expandafter\yquant@draw%
- \expandafter{\yquant@lang@attr@value}%
- {/yquant/operators/every dmeter}%
- {}{}%
-}
+ {%
+ \ifdefined\yquant@lang@attr@type%
+ \yquant@register@type@fromstring\yquant@lang@attr@type\yquant@circuit@settype@to%
+ \else%
+ \let\yquant@circuit@settype@to=\yquant@register@type@c%
+ \fi%
+ \let\yquant@prepare@callback@prepare=\yquant@circuit@settype@prepare%
+ \let\yquant@prepare@callback@draw=\yquant@circuit@settype%
+ \unless\ifcsname yquant@lang@attr@value\endcsname%
+ \let\yquant@lang@attr@value=\empty%
+ \fi%
+ \expandafter\yquant@prepare%
+ \expandafter{\yquant@lang@attr@value}%
+ {/yquant/operators/every dmeter}%
+ }
+\yquant@langhelper@setup@attrs{dmeter}{}{value,type}
% END_FOLD
% BEGIN_FOLD miscellaneous
-\yquant@langhelper@declare@command@uncontrolled{barrier}\yquant@lang@@barrier
-\yquant@langhelper@setup@attrs{barrier}{}{}
-\def\yquant@lang@@barrier{%
+\yquant@langhelper@declare@command@uncontrolled%
+ {barrier}%
\yquant@register@get@allowmultitrue%
- \yquant@draw%
- {}%
- {/yquant/operators/every barrier}%
- {}{}%
-}
+ {%
+ \yquant@prepare%
+ {}%
+ {/yquant/operators/every barrier}%
+ }%
+\yquant@langhelper@setup@attrs{barrier}{}{}
-\yquant@langhelper@declare@command@uncontrolled{correlate}\yquant@lang@@correlate
+\yquant@langhelper@declare@command@uncontrolled%
+ {correlate}%
+ {%
+ % do not call \yquant@register@get@multiassingle, we do not want to install a different multi line style!
+ \yquant@register@get@allowmultitrue%
+ \let\yquant@register@multi@splitparts=\yquant@register@multi@splitparts@sepall%
+ }{%
+ \yquant@prepare%
+ {}%
+ {/yquant/operators/every wave}%
+ }
\yquant@langhelper@setup@attrs{correlate}{}{}
-\def\yquant@lang@@correlate{%
- % do not call \yquant@register@get@multiassingle, we do not want to install a different multi line style!
- \yquant@register@get@allowmultitrue%
- \let\yquant@register@multi@splitparts=\yquant@register@multi@splitparts@sepall%
- \yquant@draw%
- {}%
- {/yquant/operators/every wave}%
- {}{}%
-}
-\yquant@langhelper@declare@command@uncontrolled{align}\yquant@lang@@align
+\yquant@langhelper@declare@command@uncontrolled%
+ {align}%
+ {}%
+ {%
+ \yquant@circuit@align\yquant@circuit@operator@targets%
+ }
\yquant@langhelper@setup@attrs{align}{}{}
-\def\yquant@lang@@align#1{%
- \yquant@register@get@ids{#1}%
- \yquant@circuit@align\yquant@register@get@ids@list%
-}
-\yquant@langhelper@declare@command@uncontrolled{hspace}\yquant@lang@@hspace
+\yquant@langhelper@declare@command@uncontrolled%
+ {hspace}%
+ {%
+ \yquant@langhelper@validate\amount\dimen\yquant@lang@attr@value%
+ }{%
+ \yquant@circuit@hspace\yquant@circuit@operator@targets\amount%
+ }
\yquant@langhelper@setup@attrs{hspace}{value}{}
-\def\yquant@lang@@hspace#1{%
- \yquant@langhelper@validate\amount\dimen\yquant@lang@attr@value%
- \yquant@register@get@ids{#1}%
- \yquant@circuit@hspace\yquant@register@get@ids@list\amount%
-}
-\yquant@langhelper@declare@command@uncontrolled{discard}\yquant@lang@@discard
+\yquant@langhelper@declare@command@uncontrolled%
+ {discard}%
+ {\yquant@langhelper@execclear@lastgatefalse}%
+ {%
+ \let\yquant@circuit@settype@to=\yquant@register@type@none%
+ \yquant@circuit@actonwires%
+ \yquant@circuit@settype@prepare%
+ \yquant@circuit@settype%
+ \yquant@circuit@operator@targets%
+ {}%
+ }
\yquant@langhelper@setup@attrs{discard}{}{}
-\def\yquant@lang@@discard#1{%
- \yquant@register@get@ids{#1}%
- \let\yquant@circuit@settype@to=\yquant@register@type@none%
- \yquant@circuit@actonwires%
- \yquant@circuit@settype%
- \yquant@register@get@ids@list%
- \yquant@register@type@none%
-}
-\yquant@langhelper@declare@command@uncontrolled{init}\yquant@lang@@init
+\yquant@langhelper@declare@command@uncontrolled%
+ {init}%
+ {%
+ \yquant@register@get@allowmultitrue%
+ % we will count how many registers contain the "clean" flag, and only if this is equal to the number of targets, we apply the shift.
+ \count8=0 %
+ }%
+ {%
+ \ifdefined\yquant@lang@attr@type%
+ \yquant@register@type@fromstring\yquant@lang@attr@type\yquant@circuit@settype@to%
+ \else%
+ % We don't know which type is desired. Scan all target registers and use the first wire that is available as a type.
+ \let\yquant@circuit@settype@to=\yquant@register@type@none%
+ \forlistloop\yquant@lang@@init@loop\yquant@circuit@operator@targets%
+ \ifx\yquant@circuit@settype@to\yquant@register@type@none%
+ % now we don't have a clue; assume it's a qubit
+ \let\yquant@circuit@settype@to=\yquant@register@type@q%
+ \fi%
+ \edef\yquant@lang@attr@type{%
+ \yquant@register@type@tostring\yquant@circuit@settype@to%
+ }%
+ \fi%
+ \let\yquant@prepare@callback@prepare=\yquant@circuit@settype@prepare%
+ \let\yquant@prepare@callback@draw=\yquant@circuit@settype%
+ \let\yquant@prepare@multi=\yquant@prepare@multiinit%
+ \ifnum\count8=\numexpr\yquant@circuit@operator@maxctrl-\yquant@circuit@operator@minctrl+1\relax%
+ \def\yquant@config@operator@minimum@width{0pt}%
+ \preto\yquant@attrs@remaining{internal/move label,}%
+ \edef\cmd{%
+ \yquant@prepare%
+ {\unexpanded\expandafter{\yquant@lang@attr@value}}%
+ {/yquant/every label, /yquant/every initial label,%
+ /yquant/every \yquant@lang@attr@type\space label}%
+ }%
+ \else%
+ \edef\cmd{%
+ \yquant@prepare%
+ {\unexpanded\expandafter{\yquant@lang@attr@value}}%
+ {/yquant/every label, /yquant/every \yquant@lang@attr@type\space label}%
+ }%
+ \fi%
+ \cmd%
+ }
\yquant@langhelper@setup@attrs{init}{value}{type}
+
+\protected\def\yquant@lang@@init@loop#1{%
+ \ifyquant@firsttoken\yquant@register@multi{#1}{%
+ \let\yquant@register@multi@contiguous=\yquant@lang@@init@multi@@extract%
+ \@fifthoffive#1%
+ % we should reset multi@contiguous to the original command; but this is really just a placeholder. As long as it is \protected, everything is fine.
+ }{%
+ \edef\yquant@circuit@settype@to{\yquant@register@get@type{#1}}%
+ }%
+ \unless\ifx\yquant@circuit@settype@to\yquant@register@type@none%
+ \expandafter\listbreak%
+ \fi%
+}
+
\protected\def\yquant@lang@@init@multi@@extract#1#2#3{%
\yquant@for \yquant@i := #1 to #2 {%
\edef\yquant@circuit@settype@to{\yquant@register@get@type\yquant@i}%
@@ -615,95 +643,64 @@
}%
}
-\protected\def\yquant@lang@@init#1{%
+\yquant@langhelper@declare@command@uncontrolled%
+ {output}%
\yquant@register@get@allowmultitrue%
- \yquant@register@get@ids{#1}%
- \ifdefined\yquant@lang@attr@type%
- \yquant@register@type@fromstring\yquant@lang@attr@type\yquant@circuit@settype@to%
- \else%
- % We don't know which type is desired. Scan all target registers and use the first wire that is available as a type.
- \let\yquant@circuit@settype@to=\yquant@register@type@none%
- \def\do##1{%
- \ifyquant@firsttoken\yquant@register@multi{##1}{%
- \let\yquant@register@multi@contiguous=\yquant@lang@@init@multi@@extract%
- \@fifthoffive##1%
- % we should reset multi@contiguous to the original command; but this is really just a placeholder. As long as it is \protected, everything is fine.
- }{%
- \edef\yquant@circuit@settype@to{\yquant@register@get@type{##1}}%
- }%
- \unless\ifx\yquant@circuit@settype@to\yquant@register@type@none%
- \expandafter\listbreak%
- \fi%
- }%
- \dolistloop\yquant@register@get@ids@list%
- \ifx\yquant@circuit@settype@to\yquant@register@type@none%
- % now we don't have a clue; assume it's a qubit
- \let\yquant@circuit@settype@to=\yquant@register@type@q%
- \fi%
- \edef\yquant@lang@attr@type{%
- \yquant@register@type@tostring\yquant@circuit@settype@to%
- }%
- \fi%
- \let\yquant@draw@callback@wire=\yquant@circuit@settype%
- \let\yquant@draw@@multi=\yquant@draw@@multiinit%
- \yquant@circuit@operator{}{}{#1}%
- % special case: if there were no operations at any affected wire before, we will replace the wire description
- \ifdim\yquant@circuit@operator@x=\yquant@config@operator@sep\relax%
- \def\yquant@circuit@operator@x{-.5\dimen2}%
- \let\yquant@draw@finalize@ctrl@single=\yquant@draw@finalize@ctrl@singleinit%
- \let\yquant@draw@finalize@ctrl@multi=\yquant@draw@finalize@ctrl@multiinit%
- \expandafter\yquant@draw@%
- \expandafter{\yquant@lang@attr@value}%
- {/yquant/every label, /yquant/every initial label, /yquant/every \yquant@lang@attr@type\space label}%
- \else%
- \expandafter\yquant@draw@%
- \expandafter{\yquant@lang@attr@value}%
- {/yquant/every label, /yquant/every \yquant@lang@attr@type\space label}%
- \fi%
-}
-
-\yquant@langhelper@declare@command@uncontrolled{output}\yquant@lang@@output
+ \yquant@circuit@output%
\yquant@langhelper@setup@attrs{output}{value}{}
-\def\yquant@lang@@output#1{%
- \yquant@register@get@allowmultitrue%
- \yquant@register@get@ids{#1}%
- \expandafter\yquant@circuit@output\expandafter{\yquant@register@get@ids@list}%
-}
-\yquant@langhelper@declare@command@uncontrolled{settype}\yquant@lang@@settype
+\yquant@langhelper@declare@command@uncontrolled%
+ {inspect}%
+ \yquant@register@get@allowmultitrue%
+ {%
+ \expandafter\yquant@prepare%
+ \expandafter{\yquant@lang@attr@value}%
+ {/yquant/operators/every inspect}%
+ }
+\yquant@langhelper@setup@attrs{inspect}{value}{}
+
+\yquant@langhelper@declare@command@uncontrolled%
+ {settype}%
+ {\yquant@langhelper@execclear@lastgatefalse}%
+ {%
+ \yquant@register@type@fromstring\yquant@lang@attr@value\yquant@circuit@settype@to%
+ \yquant@circuit@actonwires%
+ \yquant@circuit@settype@prepare%
+ \yquant@circuit@settype%
+ \yquant@circuit@operator@targets%
+ {}%
+ }
\yquant@langhelper@setup@attrs{settype}{value}{}
-\protected\def\yquant@lang@@settype#1{%
- \yquant@register@get@ids{#1}%
- \yquant@register@type@fromstring\yquant@lang@attr@value\yquant@circuit@settype@to%
- \yquant@circuit@actonwires%
- \yquant@circuit@settype%
- \yquant@register@get@ids@list%
- {}%
-}
-
-\def\yquant@lang@setwire{%
- \PackageWarning{yquant.sty}{`setwire' gate is deprecated as of yquant 0.1.2. Use `settype' instead.}%
- \yquant@lang@settype%
-}
-\yquant@langhelper@setup@attrs{setwire}{value}{}
-\yquant@langhelper@declare@command@uncontrolled{setstyle}\yquant@lang@@setstyle
+\ifnum\yquant@compat<2 %
+ \def\yquant@lang@setwire{%
+ \PackageWarning{yquant.sty}{`setwire' gate is deprecated as of yquant 0.1.2. Use `settype' instead.}%
+ \yquant@lang@settype%
+ }
+ \yquant@langhelper@setup@attrs{setwire}{value}{}
+\fi
+
+\yquant@langhelper@declare@command@uncontrolled%
+ {setstyle}%
+ {\yquant@langhelper@execclear@lastgatefalse}%
+ {%
+ \yquant@circuit@actonwires%
+ \@gobbletwo%
+ \yquant@circuit@setstyle%
+ \yquant@circuit@operator@targets%
+ {{\yquant@lang@attr@value}}%
+ }
\yquant@langhelper@setup@attrs{setstyle}{value}{}
-\protected\def\yquant@lang@@setstyle#1{%
- \yquant@register@get@ids{#1}%
- \yquant@circuit@actonwires%
- \yquant@circuit@setstyle%
- \yquant@register@get@ids@list%
- {{\yquant@lang@attr@value}}%
-}
-\yquant@langhelper@declare@command@uncontrolled{addstyle}\yquant@lang@@addstyle
+\yquant@langhelper@declare@command@uncontrolled%
+ {addstyle}%
+ {\yquant@langhelper@execclear@lastgatefalse}%
+ {%
+ \yquant@circuit@actonwires%
+ \@gobbletwo%
+ \yquant@circuit@addstyle%
+ \yquant@circuit@operator@targets%
+ {{\yquant@lang@attr@value}}%
+ }
\yquant@langhelper@setup@attrs{addstyle}{value}{}
-\protected\def\yquant@lang@@addstyle#1{%
- \yquant@register@get@ids{#1}%
- \yquant@circuit@actonwires%
- \yquant@circuit@addstyle%
- \yquant@register@get@ids@list%
- {{\yquant@lang@attr@value}}%
-}
% END_FOLD \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-langhelper.tex b/Master/texmf-dist/tex/latex/yquant/yquant-langhelper.tex
index 86114241940..72a5969cb60 100644
--- a/Master/texmf-dist/tex/latex/yquant/yquant-langhelper.tex
+++ b/Master/texmf-dist/tex/latex/yquant/yquant-langhelper.tex
@@ -1,4 +1,4 @@
-% Parsing attributes
+% BEGIN_FOLD Parsing attributes
\let\yquant@langhelper@list@attrs=\empty
\protected\long\def\yquant@langhelper@check@attrs[#1]{%
@@ -166,8 +166,9 @@
\PackageError{yquant.sty}{Required attribute `#1' missing}%
{You used a command that requires specifying the attribute `#1'.}%
}%
+% END_FOLD
-% Parsing command itself
+% BEGIN_FOLD Parsing command itself
\protected\def\yquant@langhelper@check@name#1 {%
\lowercase{\edef\cmd{#1}}%
\unless\ifcsname yquant@lang@\cmd\endcsname%
@@ -209,35 +210,84 @@
% Check all necessary attributes were given.
\csname yquant@langhelper@setup@attrs@check@\cmd\endcsname%
% Finally execute the command
- \csname yquant@lang@\cmd\endcsname%
+ \letcs\cmd{yquant@lang@\cmd}%
+ \yquant@langhelper@declare@command@@parse%
}
+% END_FOLD
+% BEGIN_FOLD Declarations
+\newif\ifyquant@langhelper@execclear@lastgate
% Defining commands that accept registers and take an optional value
% #1: name of the argument
-% #2: command that is to be called with three parameters: the indices of the positive and negative controls and registers, all as named lists
-\protected\def\yquant@langhelper@declare@command#1#2{%
+% #2: command (sequence) that is to be called before the target macros are filled
+% #3: command (sequence) that is to be called after the target macros are filled
+\protected\def\yquant@langhelper@declare@command#1#2#3{%
\begingroup%
\lowercase{\edef\cmd{#1}}%
- \long\protected\csgdef{yquant@lang@\cmd}{%
- \let\cmd=#2%
- \yquant@langhelper@declare@command@@parse%
+ \long\protected\csxdef{yquant@lang@\cmd}##1##2##3{%
+ \noexpand\yquant@langhelper@execclear@lastgatetrue%
+ \unexpanded{#2}%
+ \yquant@circuit@operator{##1}{##2}{##3}%
+ \noexpand\ifyquant@langhelper@execclear@lastgate%
+ \yquant@for \noexpand\i := \noexpand\yquant@circuit@operator@minctrl to \noexpand\yquant@circuit@operator@maxctrl {%
+ \yquant@register@execclear@lastgate{\noexpand\i}{\cmd}%
+ }%
+ \noexpand\fi%
+ \unexpanded{#3}%
}%
\endgroup%
}
-% Defining commands that accept registers and take an additional value
+% Defining commands that accept registers and take an optional value, but don't allow for controls
% #1: name of the argument
-% #2: command that is to be called with three parameters: the indices of the positive and negative controls and registers, all as named lists
-\protected\def\yquant@langhelper@declare@command@uncontrolled#1#2{%
+% #2: command (sequence) that is to be called before the target macros are filled
+% #3: command (sequence) that is to be called after the target macros are filled
+\protected\def\yquant@langhelper@declare@command@uncontrolled#1#2#3{%
\begingroup%
\lowercase{\edef\cmd{#1}}%
- \long\protected\csgdef{yquant@lang@\cmd}{%
- \def\cmd{\yquant@langhelper@declare@command@@uncontrolled{#2}}%
- \yquant@langhelper@declare@command@@parse%
+ \long\protected\csxdef{yquant@lang@\cmd}##1##2##3{%
+ \noexpand\ifstrempty{##1}\relax{%
+ \noexpand\PackageError{yquant.sty}{Positive controls are not allowed for the command `\cmd`}{}%
+ }%
+ \noexpand\ifstrempty{##2}\relax{%
+ \noexpand\PackageError{yquant.sty}{Negative controls are not allowed for the command `\cmd`}{}%
+ }%
+ \noexpand\yquant@langhelper@execclear@lastgatetrue%
+ \unexpanded{#2}%
+ \yquant@circuit@operator{}{}{##3}%
+ \noexpand\ifyquant@langhelper@execclear@lastgate%
+ \yquant@for \noexpand\i := \noexpand\yquant@circuit@operator@minctrl to \noexpand\yquant@circuit@operator@maxctrl {%
+ \yquant@register@execclear@lastgate{\noexpand\i}{\cmd}%
+ }%
+ \noexpand\fi%
+ \unexpanded{#3}%
}%
\endgroup%
}
+% Defining commands that accept an undefined register and take an optional value, but don't allow for controls
+% #1: name of the argument
+% #2: macro that is to be called with parameter #1 being the name of the register
+\protected\def\yquant@langhelper@declare@command@create#1#2{%
+ \begingroup%
+ \lowercase{\edef\cmd{#1}}%
+ \long\protected\csxdef{yquant@lang@\cmd}##1##2{%
+ \noexpand\ifstrempty{##1}\relax{%
+ \noexpand\PackageError{yquant.sty}{Positive controls are not allowed for the command `\cmd`}{}%
+ }%
+ \noexpand\ifstrempty{##2}\relax{%
+ \noexpand\PackageError{yquant.sty}{Negative controls are not allowed for the command `\cmd`}{}%
+ }%
+ \noexpand#2%
+ }%
+ \endgroup%
+}
+
+% make #1 an identical command to #2 (does not copy attributes)
+\protected\def\yquant@langhelper@declare@command@alias#1#2{%
+ \global\csletcs{yquant@lang@#1}{yquant@lang@#2}%
+}
+
\long\def\yquant@langhelper@declare@command@@parse#1;{%
\yquant@langhelper@declare@command@@extract@nctrl#1~;%
\yquant@env@rescan%
@@ -267,16 +317,7 @@
}%
\expandafter\cmd\params%
}
-
-\protected\def\yquant@langhelper@declare@command@@uncontrolled#1#2#3{%
- \ifstrempty{#2}\relax{%
- \PackageError{yquant.sty}{Positive controls are not allowed for this command}{}%
- }%
- \ifstrempty{#3}\relax{%
- \PackageError{yquant.sty}{Negative controls are not allowed for this command}{}%
- }%
- #1%
-}
+% END_FOLD
% shorthands for validation of property values
% #1: a macro that will contain the sanitized value
diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex b/Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex
new file mode 100644
index 00000000000..c9db0883b67
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex
@@ -0,0 +1,883 @@
+% Most drawing operations will be realized through nodes
+\let\yquant@prepare@callback@prepare=\@gobble
+\let\yquant@prepare@callback@draw=\@gobble%
+
+% #1: register name
+% #2: register index
+% #3: register type
+\protected\def\yquant@prepare@create#1#2#3{%
+ \ifdefined\yquant@lang@attr@input%
+ \expandafter\yquant@list@gdequeue\csname\yquant@prefix parameters\endcsname\outermap%
+ \ifx\outermap\empty%
+ \PackageError{yquant.sty}{Invalid subcircuit parameter count}%
+ {No outer register available for input register `#1[#2]`.}%
+ \fi%
+ \begingroup%
+ \let\yquant@prefix=\yquant@parent %
+ \unless\if#3\yquant@register@get@type\outermap%
+ \PackageError{yquant.sty}%
+ {Subcircuit expects wire of type `\yquant@register@type@tostring#3', but got `\yquant@register@type@tostring{\yquant@register@get@type\outermap}'}%
+ {Outer and inner wire types must match for input wire `#1[#2]`.}%
+ \fi%
+ \endgroup%
+ \unless\ifdefined\yquant@lang@attr@output%
+ \listcsxadd{\yquant@prefix inonly}%
+ {\the\numexpr\csname\yquant@prefix registers\endcsname+1\relax}%
+ \fi%
+ \yquant@register@alias{#3}{#1}{#2}\outermap%
+ \else%
+ \ifdefined\yquant@lang@attr@output%
+ \expandafter\yquant@list@gdequeue\csname\yquant@prefix parameters\endcsname\outermap%
+ \ifx\outermap\empty%
+ \PackageError{yquant.sty}{Invalid subcircuit parameter count}%
+ {No outer register available for output register `#1[#2]`.}%
+ \fi%
+ \begingroup%
+ \let\yquant@prefix=\yquant@parent%
+ \unless\if\yquant@register@type@none\yquant@register@get@type\outermap%
+ \PackageError{yquant.sty}%
+ {Subcircuit expects discarded wire, got `\yquant@register@type@tostring{\yquant@register@get@type\outermap}'}%
+ {Outer wire must be discarded before being acceptable for output-only register `#1[#2]`.}%
+ \fi%
+ \endgroup%
+ \yquant@register@alias{#3}{#1}{#2}\outermap%
+ \else%
+ \yquant@register@define{#3}{#1}{#2}%
+ \fi%
+ \fi%
+ % we must be allowed to change the wire types during preparation for various reasons, so we need to reset it here (TODO: can we eliminate all those reasons?)
+ \csxappto{\yquant@prefix draw}{%
+ \yquant@draw@init{\csname\yquant@prefix registers\endcsname}{#3}%
+ }%
+}
+
+% generic shape of an operator
+% #1: value
+% #2: tikz options that select the correct shape
+\protected\long\def\yquant@prepare#1#2{%
+ \yquant@sort@clear%
+ \def\yquant@prepare@injectcontrols@count{0}%
+ \def\idx{0}%
+ \yquant@prepare@ifs@direct%
+ \dimen2=\yquant@config@operator@minimum@width%
+ \ifyquant@circuit@operator@hasControls%
+ \edef\yquant@prepare@list{%
+ \yquant@list@range%
+ \yquant@circuit@operator@minctrl%
+ \yquant@circuit@operator@maxctrl%
+ }%
+ \else%
+ \let\yquant@prepare@list=\empty%
+ \fi%
+ % BEGIN_FOLD register
+ \def\do##1{%
+ \ifx\yquant@lang@attr@name\empty%
+ \let\nodename=\empty%
+ \else%
+ \edef\nodename{\yquant@lang@attr@name-\idx}%
+ \fi%
+ \ifyquant@firsttoken\yquant@register@multi{##1}{%
+ \yquant@prepare@multi{#1}{#2}{##1}%
+ }{%
+ \yquant@prepare@single{#1}{#2}{##1}%
+ }%
+ \expandafter%
+ \endpgfinterruptboundingbox%
+ \expandafter\dimen\expandafter0\expandafter=%
+ \the\dimexpr\pgf@picmaxx-\pgf@picminx\relax\relax%
+ \ifdim\dimen0>\dimen2 %
+ \dimen2=\dimen0 %
+ \fi%
+ \numdef\idx{\idx+1}%
+ }%
+ \dolistloop\yquant@circuit@operator@targets%
+ % END_FOLD
+ \yquant@prepare@controls%
+ \yquant@prepare@finalize{#1}{#2}%
+}
+
+\newcount\yquant@prepare@injections
+% generic shape of an operator - but delayed to some later point
+% #1: value
+% #2: tikz options that select the correct shape
+\protected\long\def\yquant@prepare@injection#1#2{%
+ \global\advance\yquant@prepare@injections by 1 % we just keep increasing, doesn't really matter
+ \edef\yquant@draw@group{\yquant@draw@injectiongroup{\the\yquant@prepare@injections}}%
+ \def\yquant@draw@endgroup{\noexpand\yquant@draw@endinjectiongroup}%
+ \yquant@prepare{#1}{#2}%
+ \csxdef{yquant@prepare@@injection@\the\yquant@prepare@injections}{%
+ {\the\dimen2}{\unexpanded\expandafter{\yquant@circuit@operator@targets}}%
+ }%
+ \forlistloop\yquant@prepare@injection@loop\yquant@circuit@operator@targets%
+}
+
+\protected\def\yquant@prepare@injection@loop#1{%
+ \ifyquant@firsttoken\yquant@register@multi{#1}{%
+ \edef\first{\@secondoffive#1}%
+ \edef\last{\@thirdoffive#1}%
+ \yquant@for \i := \first to \last {%
+ \yquant@register@set@lastgate\i{%
+ % we only need this once, but it may be called multiple times if acting on multiple registers
+ \noexpand\ifcsname yquant@prepare@@injection@\the\yquant@prepare@injections\noexpand\endcsname%
+ % first check whether this is valid - i.e., the list of targets for this measurement is in fact a subset of the list of positive controls for the next operation
+ \ifyquant@registersubset%
+ {\unexpanded\expandafter{\yquant@circuit@operator@targets}}%
+ {\noexpand\yquant@circuit@operator@pctrls}{%
+ \yquant@prepare@inject{\the\yquant@prepare@injections}%
+ }{%
+ \yquant@prepare@inject@discard{\the\yquant@prepare@injections}%
+ }%
+ \yquant@prepare@injection@clean{\first}{\last}%
+ \noexpand\fi
+ \noexpand\@gobble%
+ }%
+ }%
+ }{%
+ \yquant@register@set@lastgate{#1}{%
+ \noexpand\ifcsname yquant@prepare@@injection@\the\yquant@prepare@injections\noexpand\endcsname%
+ % first check whether this is valid - i.e., the list of targets for this measurement is in fact a subset of the list of positive controls for the next operation
+ \ifyquant@registersubset%
+ {\unexpanded\expandafter{\yquant@circuit@operator@targets}}%
+ {\noexpand\yquant@circuit@operator@pctrls}{%
+ \yquant@prepare@inject{\the\yquant@prepare@injections}%
+ }{%
+ \yquant@prepare@inject@discard{\the\yquant@prepare@injections}
+ }%
+ \noexpand\fi%
+ \noexpand\@gobble%
+ }%
+ }%
+}
+
+\protected\def\yquant@prepare@injection@clean#1#2{%
+ \yquant@for \i := #1 to #2 {%
+ \yquant@register@set@lastgate\i{}%
+ }%
+}
+
+\protected\def\yquant@prepare@inject#1{%
+ \letcs\yquant@prepare@inject@@data{yquant@prepare@@injection@#1}%
+ \csgundef{yquant@prepare@@injection@#1}%
+ \dimen0=\expandafter\@firstoftwo\yquant@prepare@inject@@data\relax%
+ \let\@tmpconti=\yquant@register@multi@contiguous%
+ \protected\def\yquant@register@multi@contiguous##1##2{%
+ \yquant@for \i := ##1 to ##2 {%
+ \cslet{yquant@prepare@replacecontrol@\i}\empty%
+ }%
+ }%
+ \expandafter\expandafter\expandafter\etb@forlistloop%
+ \expandafter\expandafter\expandafter{%
+ \expandafter\@secondoftwo%
+ \yquant@prepare@inject@@data%
+ }{\yquant@prepare@inject@loop{#1}}%
+ \let\yquant@register@multi@contiguous=\@tmpconti%
+}
+
+\protected\def\yquant@prepare@inject@loop#1#2{%
+ \ifyquant@firsttoken\yquant@register@multi{#2}{%
+ \@fifthoffive#2% this clears all the actions for the individual contiguous slices
+ % but we need to do something for the first register
+ \csedef{yquant@prepare@replacecontrol@\@secondoffive#2}{%
+ \noexpand\ifdim\the\dimen0>\dimen2 %
+ \dimen2=\the\dimen0 \relax%
+ \noexpand\fi%
+ \yquant@sort@eadd{%
+ \yquant@draw@inject{#1}%
+ }
+ }%
+ }{%
+ \csedef{yquant@prepare@replacecontrol@#2}{%
+ \noexpand\ifdim\the\dimen0>\dimen2 %
+ \dimen2=\the\dimen0 \relax%
+ \noexpand\fi%
+ \yquant@sort@eadd{%
+ \yquant@draw@inject{#1}%
+ }%
+ }%
+ }%
+}
+
+\protected\def\yquant@prepare@inject@discard#1{%
+ \csappto{\yquant@prefix draw}{%
+ \yquant@draw@inject@outer{#1}%
+ }%
+ \csgundef{yquant@prepare@@injection@#1}%
+}
+
+\def\yquant@prepare@sort#1#2{%
+ \yquant@prepare@sort@aux#1\relax#2\relax%
+ \expandafter\@firstoftwo%
+ \else%
+ \expandafter\@secondoftwo%
+ \fi%
+}
+
+\def\yquant@prepare@sort@aux#1#2#3\relax#4#5#6\relax{%
+ \unless\ifnum#2>#5\relax%
+}
+
+\protected\def\yquant@prepare@controls@loop#1#2{%
+ \ifx\yquant@lang@attr@name\empty%
+ \let\nodename=\empty%
+ \else%
+ \edef\nodename{\yquant@lang@attr@name-#1\idx}%
+ \fi%
+ \ifcsname yquant@prepare@replacecontrol@#2\endcsname%
+ \ifcsempty{yquant@prepare@replacecontrol@#2}\relax{%
+ % do something unorthodox
+ \csname yquant@prepare@replacecontrol@#2\endcsname%
+ \numdef\idx{\idx+1}%
+ \unless\ifdefined\yquant@prepare@controltype%
+ \edef\yquant@prepare@controltype{#2}%
+ \fi%
+ }%
+ \else%
+ \yquant@sort@eadd{%
+ \expandafter\noexpand\csname yquant@draw@#1control\endcsname%
+ {#2}% register index
+ {\nodename}%
+ }%
+ \numdef\idx{\idx+1}%
+ \unless\ifdefined\yquant@prepare@controltype%
+ \edef\yquant@prepare@controltype{#2}%
+ \fi%
+ \fi%
+}
+
+\protected\def\yquant@prepare@controls{%
+ \ifyquant@circuit@operator@hasControls%
+ \def\idx{0}%
+ \forlistloop{\yquant@prepare@controls@loop p}\yquant@circuit@operator@pctrls%
+ \def\idx{0}%
+ \forlistloop{\yquant@prepare@controls@loop n}\yquant@circuit@operator@nctrls%
+ \unless\ifdefined\yquant@prepare@controltype%
+ \PackageError{yquant.sty}{Internal inconsistency detected}%
+ {Controlled action without controls found.}%
+ \fi%
+ \fi%
+}
+
+\ifnum\yquant@compat>1 %
+ \expandafter\@firstoftwo
+\else
+ \expandafter\@secondoftwo
+\fi{
+ \def\yquant@prepare@ifs@Ifnum{\noexpand\ifnum}
+ \def\yquant@prepare@ifs@Ifcase{\noexpand\ifcase}
+ \def\yquant@prepare@ifs@Or{\noexpand\or}
+ \def\yquant@prepare@ifs@Else{\noexpand\else}
+ \def\yquant@prepare@ifs@Fi{\noexpand\fi}
+ \def\yquant@prepare@ifs@Unless{\noexpand\unless}
+ \def\yquant@prepare@ifs@The{\noexpand\the}
+ \protected\def\yquant@prepare@ifs@set{%
+ \let\Ifnum=\yquant@prepare@ifs@Ifnum%
+ \let\Ifcase=\yquant@prepare@ifs@Ifcase%
+ \let\Or=\yquant@prepare@ifs@Or%
+ \let\Else=\yquant@prepare@ifs@Else%
+ \let\Fi=\yquant@prepare@ifs@Fi%
+ \let\Unless=\yquant@prepare@ifs@Unless%
+ \let\The=\yquant@prepare@ifs@The%
+ }
+ \protected\def\yquant@prepare@ifs@direct{%
+ \let\Ifnum=\ifnum%
+ \let\Ifcase=\ifcase%
+ \let\Or=\or%
+ \let\Else=\else%
+ \let\Fi=\fi%
+ \let\Unless=\unless%
+ \let\The=\the%
+ }
+}{
+ \let\yquant@prepare@ifs@set=\relax%
+ \let\yquant@prepare@ifs@direct=\relax%
+}
+\protected\long\def\yquant@prepare@finalize#1#2{%
+ % We now know the dimensions of all the registers (though we didn't bother with the height of the control knobs [if present], we just assume they are too small to change this).
+ \protected\def\idx{}%#
+ \yquant@prepare@ifs@set%
+ \let\yquant@prepare@append=\empty%
+ \yquant@sort\yquant@prepare@sort%
+ \def\do##1{%
+ \appto\yquant@prepare@append{##1}%
+ \yquant@prepare@finalize@ctrl##1%
+ }%
+ \yquant@sort@dolistloop%
+ \protected@csxappto{\yquant@prefix draw}{%
+ \yquant@draw@group%
+ {\the\dimen2}%
+ \ifyquant@circuit@operator@hasControls%
+ \yquant@register@get@type\yquant@prepare@controltype%
+ \else%
+ F%
+ \fi% if-switch whether controls are present
+ {\yquant@attrs@remaining}% custom style
+ {#2}% operator style
+ {#1}%
+ {\yquant@prepare@list}%
+ \unexpanded\expandafter{\yquant@prepare@append}%
+ \yquant@draw@endgroup%
+ \ifyquant@circuit@operator@hasControls%
+ T%
+ \else%
+ F%
+ \fi%
+ \ifx\yquant@lang@attr@name\empty%
+ {}0%
+ \else%
+ {\yquant@lang@attr@name}%
+ \ifnum\yquant@circuit@operator@numtarget=1 %
+ \ifnum\yquant@circuit@operator@numpctrl=1 %
+ \ifnum\yquant@circuit@operator@numnctrl=1 %
+ 7%
+ \else%
+ 6%
+ \fi%
+ \else%
+ \ifnum\yquant@circuit@operator@numnctrl=1 %
+ 5%
+ \else%
+ 4%
+ \fi%
+ \fi%
+ \else%
+ \ifnum\yquant@circuit@operator@numpctrl=1 %
+ \ifnum\yquant@circuit@operator@numnctrl=1 %
+ 3%
+ \else%
+ 2%
+ \fi%
+ \else%
+ \ifnum\yquant@circuit@operator@numnctrl=1 %
+ 1%
+ \else%
+ 0%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ }%
+}
+
+\protected\def\yquant@prepare@single#1#2#3{%
+ \yquant@sort@eadd{%
+ \yquant@draw@single%
+ {#3}% register index
+ {\nodename}%
+ }%
+ \unless\ifyquant@circuit@operator@hasControls%
+ \listadd\yquant@prepare@list{#3}%
+ \fi%
+ % determine the actual dimensions by a virtual draw command
+ \pgfinterruptboundingbox%
+ \yquant@config@operator@multifalse%
+ \yquant@env@virtualize@path%
+ \path%
+ (0pt, 0pt)%
+ node[/yquant/every operator, #2, /yquant/this operator,%
+ name prefix=, name suffix=, name=] {#1};%
+ \yquant@register@update@height{#3}{\the\pgf@picmaxy}%
+ \yquant@register@update@depth{#3}{\the\dimexpr-\pgf@picminy\relax}%
+}
+
+\protected\def\yquant@prepare@multi#1#2#3{%
+ \yquant@sort@eadd{%
+ \yquant@draw@multi%
+ #3%
+ {\nodename}%
+ }%
+ \unless\ifyquant@circuit@operator@hasControls%
+ \eappto\yquant@prepare@list{%
+ \expandafter\yquant@list@range\@secondandthirdoffive#3%
+ }%
+ \fi%
+ \pgfinterruptboundingbox%
+ \yquant@config@operator@multitrue%
+ \yquant@env@virtualize@path%
+ \def\yquant@prepare@content{#1}%
+ \def\yquant@prepare@style{#2}%
+ \let\yquant@register@multi@contiguous=\yquant@prepare@multi@contiguous%
+ \@fifthoffive#3%
+ \ifdim\pgf@picmaxy=-16000pt %
+ % if there was no single contiguous part before, determine the width now
+ \path%
+ (0pt, 0pt)%
+ node[/yquant/every operator, #2, /yquant/this operator,%
+ name prefix=, name suffix=, name=] {#1};%
+ \fi%
+}
+
+\protected\def\yquant@prepare@multi@contiguous#1#2#3{%
+ \global\pgf@picmaxy=-16000pt %
+ \global\pgf@picminy=16000pt %
+ \edef\cmd{%
+ \noexpand\path (0pt, 0pt)%
+ node[/yquant/every operator, \yquant@prepare@style, /yquant/this operator,%
+ /yquant/internal/multi main=\ifnum#3=1 true\else false\fi,%
+ name prefix=, name suffix=, name=]%
+ {\unexpanded\expandafter{\yquant@prepare@content}};%
+ }%
+ \cmd%
+ \ifnum#1=#2 %
+ % this is a single register in disguise
+ \yquant@register@update@height{#1}{\the\pgf@picmaxy}%
+ \yquant@register@update@depth{#1}{\the\dimexpr-\pgf@picminy\relax}%
+ \else%
+ \yquant@register@update@multispace{#1}{#2}{\the\dimexpr\pgf@picmaxy-\pgf@picminy\relax}%
+ \fi%
+}
+
+\protected\def\yquant@prepare@multiinit#1#2#3{%
+ \yquant@sort@eadd{%
+ \yquant@draw@multiinit%
+ #3%
+ {\nodename}%
+ }%
+ \unless\ifyquant@circuit@operator@hasControls%
+ \eappto\yquant@prepare@list{%
+ \expandafter\yquant@list@range\@secondandthirdoffive#3%
+ }%
+ \fi%
+ \pgfinterruptboundingbox%
+ \yquant@config@operator@multitrue%
+ \yquant@env@virtualize@path%
+ \edef\first{\@secondoffive#3}%
+ \def\pgfdecorationsegmentaspect{0.5}%
+ \def\pgfdecorationsegmentfromto{0-1}%
+ \ifnum\yquant@compat<2 %
+ \path (0pt, 0pt)%
+ node[/yquant/every operator, #2, /yquant/every multi label,%
+ /yquant/this operator, name prefix=, name suffix=, name=] {#1};%
+ \else%
+ \path (0pt, 0pt)%
+ node[/yquant/every operator, #2,%
+ /yquant/this operator, name prefix=, name suffix=, name=] {#1};%
+ \fi%
+ \ifnum\@secondoffive#3=\@thirdoffive#3 %
+ % this is a single register in disguise
+ \yquant@register@update@height{\first}{\the\pgf@picmaxy}%
+ \yquant@register@update@depth{\first}{\the\dimexpr-\pgf@picminy\relax}%
+ \else%
+ % this may not be sufficient. Since the text position need not necessarily be at the center (if the register corresponding to the visual center is excluded), we may require some space here which we will later only use in parts, but then extend where we should not. However, resolving this would require a special handling when calculating the y positions at the end, meaning we could not use the multispace facility. Let's assume discontiguous init registers are so scarce that this does not matter (disable the acquiration by using the operator/overlay key).
+ \edef\upd{%
+ \yquant@register@update@multispace%
+ {\first}{\@thirdoffive#3}%
+ {\the\dimexpr\pgf@picmaxy-\pgf@picminy\relax}%
+ }%
+ \upd%
+ \fi%
+}
+
+\protected\long\def\yquant@prepare@output@single#1#2#3{%
+ \yquant@sort@eadd{%
+ \yquant@draw@output@single%
+ {#3}% register index
+ {\nodename}%
+ }%
+ \listadd\yquant@prepare@list{#3}%
+ % determine the actual dimensions by a virtual draw command
+ \pgfinterruptboundingbox%
+ \yquant@config@operator@multifalse%
+ \yquant@env@virtualize@path%
+ % #2 is empty anyway
+ \edef\cmd{%
+ \noexpand\path (0pt, 0pt)%
+ node[\ifnum\yquant@compat>1 /yquant/every operator, \fi /yquant/every output,%
+ /yquant/every \yquant@register@type@tostring{\yquant@register@get@type{#3}} output,%
+ \ifnum\yquant@compat>1 /yquant/this operator, \fi%
+ name prefix=, name suffix=, name=] {\unexpanded{#1}};%
+ }%
+ \cmd%
+ \yquant@register@update@height{#3}{\the\pgf@picmaxy}%
+ \yquant@register@update@depth{#3}{\the\dimexpr-\pgf@picminy\relax}%
+}
+
+\protected\long\def\yquant@prepare@output@multi#1#2#3{%
+ \yquant@sort@eadd{%
+ \yquant@draw@output@multi%
+ #3%
+ {\nodename}%
+ }%
+ \eappto\yquant@prepare@list{%
+ \expandafter\yquant@list@range\@secondandthirdoffive#3%
+ }%
+ \pgfinterruptboundingbox%
+ \yquant@config@operator@multitrue%
+ \yquant@env@virtualize@path%
+ % We need to draw a line with some vertical extent, so just take the current height, whether it makes sense or not. We only need an estimate
+ \edef\first{\@secondoffive#3}%
+ \def\pgfdecorationsgmentaspect{0.5}%
+ \def\pgfdecorationsegmentfromto{0-1}%
+ % #2 is empty anyway
+ \edef\cmd{%
+ \noexpand\path (0pt, 0pt)
+ node[\ifnum\yquant@compat>1 /yquant/every operator, /yquant/every output, \fi%
+ \ifnum\yquant@compat<2 /yquant/every multi output,\fi%
+ \ifnum\yquant@compat>1 /yquant/this operator,\fi%
+ name prefix=, name suffix=, name=] {\unexpanded{#1}};%
+ }%
+ \cmd%
+ \ifnum\@secondoffive#3=\@thirdoffive#3 %
+ % this is a single register in disguise
+ \yquant@register@update@height{\first}{\the\pgf@picmaxy}%
+ \yquant@register@update@depth{\first}{\the\dimexpr-\pgf@picminy\relax}%
+ \else%
+ % this may not be sufficient. Since the text position need not necessarily be at the center (if the register corresponding to the visual center is excluded), we may require some space here which we will later only use in parts, but then extend where we should not. However, resolving this would require a special handling when calculating the y positions at the end, meaning we could not use the multispace facility. Let's assume discontiguous output registers are so scarce that this does not matter (disable the acquiration by using the operator/overlay key).
+ \edef\upd{%
+ \yquant@register@update@multispace%
+ {\first}{\@thirdoffive#3}%
+ {\the\dimexpr\pgf@picmaxy-\pgf@picminy\relax}%
+ }%
+ \upd%
+ \fi%
+}
+
+% BEGIN_FOLD replacement commands for draw actions that just keep track of the width
+\protected\long\def\yquant@prepare@subcircuit@init#1#2{%
+ \csdef{\yquant@prefix xpos@#1}{0pt}%
+ \yquant@register@set@type{#1}{#2}%
+}
+
+\protected\def\yquant@prepare@subcircuit@getmaxx#1{%
+ \begingroup%
+ \dimen0=-16383.99999pt %
+ \def\do##1{%
+ \ifcsname\yquant@prefix xpos@##1\endcsname%
+ \dimen2=\csname\yquant@prefix xpos@##1\endcsname\relax%
+ \ifdim\dimen0<\dimen2 %
+ \dimen0=\dimen2 %
+ \fi%
+ \else%
+ \PackageError{yquant.sty}{Internal inconsistency detected}%
+ {Undefined internal wire x position.}%
+ \fi%
+ }%
+ \dolistloop{#1}%
+ \expandafter%
+ \endgroup%
+ \expandafter\def\expandafter\newx\expandafter{\the\dimen0}%
+}
+
+\protected\def\yquant@prepare@subcircuit@move@loop#1{%
+ \cslet{\yquant@prefix xpos@#1}\newx%
+}
+
+\protected\long\def\yquant@prepare@subcircuit@group#1#2#3#4#5#6#7\yquant@draw@endgroup{%
+ \begingroup%
+ \yquant@prepare@subcircuit@getmaxx{#6}%
+ % If the quotes library is loaded, activate it. (else, this is by default \relax)
+ \tikz@enable@node@quotes%
+ \yquant@config@operator@position@rightalignfalse%
+ \yquant@config@operator@position@advancetrue%
+ \yquant@set{#3}%
+ \let\next=\endgroup%
+ \ifyquant@config@operator@position@rightalign%
+ \ifdim#1>-\pgf@picminx%
+ \global\pgf@picminx=-\dimexpr#1\relax%
+ \fi%
+ \else%
+ \ifyquant@env@seamless{%
+ \ifdim\newx=0pt %
+ \dimdef\newx{%
+ \newx+#1%
+ }%
+ \else%
+ \dimdef\newx{%
+ \newx+\yquant@config@operator@sep+#1%
+ }%
+ \fi%
+ }{%
+ \dimdef\newx{%
+ \newx+\yquant@config@operator@sep+#1%
+ }%
+ }%
+ \ifdim\newx>\pgf@picmaxx%
+ \global\pgf@picmaxx=\newx%
+ \fi%
+ \ifyquant@config@operator@position@advance%
+ \edef\next{%
+ \endgroup%
+ \def\noexpand\newx{\newx}%
+ \noexpand\forlistloop\yquant@prepare@subcircuit@move@loop{#6}%
+ }%
+ \fi%
+ \fi%
+ \next%
+ \@gobblethree% three arguments for the endgroup
+}
+
+\protected\def\yquant@prepare@subcircuit@hspace#1#2{%
+ \yquant@prepare@subcircuit@getmaxx{#1}%
+ \dimdef\newx{\newx+#2}%
+ \forlistloop\yquant@prepare@subcircuit@move@loop{#1}%
+ \ifdim\newx>\pgf@picmaxx %
+ \global\pgf@picmaxx=\newx %
+ \fi%
+}
+
+\protected\def\yquant@prepare@subcircuit@endwires{%
+ \expandafter\ifx\csname\yquant@prefix outputs\endcsname\relax%
+ % to have a symmetric situation, we extend again one separation at the end, unless this is supposed to be seamless and we don't have outputs (for seamless circuits with outputs, extend - since this extension will be between last register and output)
+ \ifyquant@env@seamless\relax{%
+ \global\advance\pgf@picmaxx by \yquant@config@operator@sep\relax%
+ }%
+ \else%
+ % if we have outputs, those will be realized as additional drawing groups following this macro, so increasing the picture at this point is rather pointless. Instead, we adjust the wire positions appropriately. The additional separation will be inserted by the outputs.
+ \begingroup%
+ \dimen0=-16383.99999pt %
+ \yquant@fordown \i := \csname\yquant@prefix registers\endcsname downto 1 {%
+ \ifcsname\yquant@prefix xpos@\i\endcsname%
+ \dimen2=\csname\yquant@prefix xpos@\i\endcsname\relax%
+ \ifdim\dimen0<\dimen2 %
+ \dimen0=\dimen2 %
+ \fi%
+ \else%
+ \PackageError{yquant.sty}{Internal inconsistency detected}%
+ {Undefined internal wire x position.}%
+ \fi%
+ }%
+ \expandafter%
+ \endgroup%
+ \expandafter\def\expandafter\newx\expandafter{\the\dimen0}%
+ \yquant@fordown \i := \csname\yquant@prefix registers\endcsname downto 1 {%
+ \cslet{\yquant@prefix xpos@\i}\newx%
+ }%
+ \fi%
+ \let\yquant@circuit@endwires@finalize=\relax%
+ \forlistcsloop\yquant@prepare@subcircuit@endwires@loop{\yquant@prefix inonly}%
+}
+
+\protected\def\yquant@prepare@subcircuit@endwires@loop#1{%
+ \eappto\yquant@circuit@endwires@finalize{%
+ \yquant@register@set@type{#1}\noexpand\yquant@register@type@none%
+ }%
+}
+% END_FOLD
+
+\newbox\yquant@prepare@subcircuit@box
+
+\protected\long\def\yquant@prepare@subcircuit#1{%
+ \yquant@sort@clear%
+ \def\idx{0}%
+ \dimen2=\yquant@config@operator@minimum@width%
+ \ifyquant@circuit@operator@hasControls%
+ \edef\yquant@prepare@list{%
+ \yquant@list@range%
+ \yquant@circuit@operator@minctrl%
+ \yquant@circuit@operator@maxctrl%
+ }%
+ \else%
+ \let\yquant@prepare@list=\empty%
+ \fi%
+ % BEGIN_FOLD register
+ \def\do##1{%
+ \ifx\yquant@lang@attr@name\empty%
+ \let\nodename=\empty%
+ \else%
+ \edef\nodename{\yquant@lang@attr@name-\idx}%
+ \fi%
+ \ifyquant@firsttoken\yquant@register@multi{##1}{%
+ \yquant@prepare@subcircuit@multi{#1}{##1}%
+ }{%
+ \yquant@prepare@subcircuit@single{#1}{##1}%
+ }%
+ \pgfinterruptboundingbox%
+ % In order to determine the width of the subcircuit, we must execute the draw command at preparation time, where we will remap all relevant commands to virtual ones so that this has no effect and is not very costly. Although nothing should be drawn, as a precaution, we "draw" everything in a box that is dropped afterwards.
+ % There will still be some extra width and height taken by separations or other things related to the box itself.
+ \yquant@env@virtualize@path%
+ \begingroup%
+ \let\yquant@parent=\yquant@prefix%
+ \edef\yquant@prefix{yquant@env\yquant@circuit@subcircuit@id @}%
+ \let\yquant@draw@init=\yquant@prepare@subcircuit@init%
+ \let\yquant@draw@group=\yquant@prepare@subcircuit@group%
+ \let\yquant@draw@alias=\@gobble%
+ \let\yquant@draw@hspace=\yquant@prepare@subcircuit@hspace%
+ \let\yquant@circuit@endwires=\yquant@prepare@subcircuit@endwires%
+ \let\yquant@circuit@flushwire=\@gobble%
+ \let\yquant@circuit@setstyle=\@gobbletwo%
+ \let\yquant@circuit@addstyle=\@gobbletwo%
+ % do not overwrite \yquant@register@set@type, which may also occur - we want to change the register type!
+ % restore tikz commands... as in env@end
+ \let\path=\tikz@command@path%
+ \let\tikz@lib@scope@check=\yquant@env@substikz@scopecheck%
+ \let\tikz@scope@opt=\yquant@env@substikz@scope%
+ \let\endtikz@scope@env=\yquant@env@substikz@endscope%
+ \let\endscope=\endtikz@scope@env%
+ \let\stopscope=\endscope%
+ \global\pgf@picmaxx=0pt %
+ \global\pgf@picminx=0pt %
+ \global\setbox\yquant@prepare@subcircuit@box=\vbox to 1sp{%
+ \csname\yquant@prefix draw\endcsname%
+ }%
+ \ifdim\pgf@picmaxy=-16000pt %
+ \global\pgf@picmaxy=0pt %
+ \global\pgf@picminy=0pt %
+ \fi%
+ \ifyquant@env@seamless{%
+ % for seamless circuits, we do not have an initial separation. However, if there is an label to registers (which you should not do for seamless subcircuits), the "initial" separation is in fact an inner one, so we need it.
+ \ifdim\pgf@picminx<0pt %
+ \global\advance\pgf@picmaxx by \yquant@config@operator@sep\relax%
+ \fi%
+ }\relax%
+ \global\wd\yquant@prepare@subcircuit@box=\dimexpr\pgf@picmaxx-\pgf@picminx\relax%
+ \endgroup%
+ \edef\yquant@prepare@subcircuit@width{%
+ {\the\wd\yquant@prepare@subcircuit@box}% inner width
+ {\noexpand\the\dimexpr\pgf@picmaxx-\pgf@picminx\relax}% outer width
+ {\the\pgf@picminx}% left margin
+ }%
+ \pgfresetboundingbox%
+ \path%
+ (0pt, 0pt)%
+ node[/yquant/every operator, #1,%
+ /yquant/operators/every subcircuit box, /yquant/this operator,%
+ /yquant/operators/this subcircuit box,%
+ name prefix=, name suffix=, name=, y radius=0pt]%
+ {\box\yquant@prepare@subcircuit@box};%
+ % the extra height is taken care for by manually inserting it to the height of the first and last register in the subcircuit
+ \yquant@register@inject@extents{\pgf@picmaxy}{-\pgf@picminy}%
+ \edef\cmd{%
+ \dimen0=\the\dimexpr\pgf@picmaxx-\pgf@picminx\relax\relax%
+ \yquant@prepare@subcircuit@add%
+ }%
+ \expandafter%
+ \endpgfinterruptboundingbox%
+ \cmd%
+ \ifdim\dimen0>\dimen2 %
+ \dimen2=\dimen0 %
+ \fi%
+ \numdef\idx{\idx+1}%
+ }%
+ \dolistloop\yquant@circuit@operator@targets%
+ % END_FOLD
+ \yquant@prepare@controls%
+ \preto\yquant@attrs@remaining{internal/no advance,}%
+ \yquant@prepare@finalize{}{#1}%
+}
+
+\protected\def\yquant@prepare@subcircuit@single#1#2{%
+ \yquant@config@operator@multifalse%
+ \edef\yquant@circuit@subcircuit@param{#2\yquant@list@delim}%
+ \yquant@circuit@subcircuit{#1}%
+ \unless\ifyquant@circuit@operator@hasControls%
+ \listadd\yquant@prepare@list{#2}%
+ \fi%
+ \edef\yquant@prepare@subcircuit@add{%
+ \yquant@sort@eadd{%
+ \yquant@draw@subcircuit@single%
+ {#2}% register index
+ {\yquant@circuit@subcircuit@id}%
+ {\nodename}%
+ {\noexpand\yquant@prepare@subcircuit@width}%
+ }%
+ }%
+}
+
+\protected\def\yquant@prepare@subcircuit@multi#1#2{%
+ \yquant@config@operator@multitrue%
+ \edef\yquant@circuit@subcircuit@param{\@fifthoffive#2}%
+ \yquant@sort@list\yquant@circuit@subcircuit@param\yquant@sort@ascending%
+ \yquant@circuit@subcircuit{#1}%
+ \unless\ifyquant@circuit@operator@hasControls%
+ \eappto\yquant@prepare@list{%
+ \expandafter\yquant@list@range\@secondandthirdoffive#2%
+ }%
+ \fi%
+ \edef\yquant@prepare@subcircuit@add{%
+ \yquant@sort@eadd{%
+ \yquant@draw@subcircuit@multi%
+ #2%
+ {\yquant@circuit@subcircuit@id}%
+ {\nodename}%
+ {\noexpand\yquant@prepare@subcircuit@width}%
+ }%
+ }%
+}
+
+\protected\def\yquant@prepare@finalize@ctrl#1{%
+ \let\next=\yquant@prepare@finalize@ctrl@single%
+ \ifx\yquant@draw@multi#1%
+ \let\next=\yquant@prepare@finalize@ctrl@multi%
+ \else%
+ \ifx\yquant@draw@multiinit#1%
+ \let\next=\yquant@prepare@finalize@ctrl@multi%
+ \else%
+ \ifx\yquant@draw@output@multi#1%
+ \let\next=\yquant@prepare@finalize@ctrl@multi%
+ \else%
+ \ifx\yquant@draw@subcircuit@multi#1%
+ \let\next=\yquant@prepare@finalize@ctrl@subcircuit@multi%
+ \else%
+ \ifx\yquant@draw@subcircuit@single#1%
+ \let\next=\yquant@prepare@finalize@ctrl@subcircuit@single%
+ \else%
+ \ifx\yquant@draw@inject#1%
+ \let\next=\@gobble%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \fi%
+ \next%
+}
+
+\protected\def\yquant@prepare@finalize@ctrl@single#1#2{%
+ \eappto\yquant@prepare@append{%
+ \yquant@prepare@callback@draw{#1}%
+ }%
+ \yquant@prepare@callback@prepare{#1}%
+}
+
+\protected\def\yquant@prepare@finalize@ctrl@multi#1#2#3#4#5{%
+ \let\yquant@register@multi@contiguous=\yquant@prepare@finalize@ctrl@multi@contiguous%
+ \ifyquant@circuit@operator@hasControls%
+ \ifyquant@config@operator@multi@warn%
+ \def\yquant@prepare@finalize@ctrl@multi@contiguous@warn{0}%
+ \else%
+ \def\yquant@prepare@finalize@ctrl@multi@contiguous@warn{2}%
+ \fi%
+ \else%
+ \def\yquant@prepare@finalize@ctrl@multi@contiguous@warn{2}%
+ \fi%
+ \cslet{\yquant@prefix finalize@ctrl@prepare@appto}\empty%
+ #4%
+ \eappto\yquant@prepare@append{\csname\yquant@prefix finalize@ctrl@prepare@appto\endcsname}%
+ \csgundef{\yquant@prefix finalize@ctrl@prepare@appto}%
+}
+
+\protected\def\yquant@prepare@finalize@ctrl@multi@contiguous#1#2#3{%
+ \ifnum\yquant@prepare@finalize@ctrl@multi@contiguous@warn=1 %
+ \PackageWarning{yquant.sty}{Ambiguous operation: multiple discontiguous multi-register operations in combination with controls make it hard to visually determine on which registers the gates act on.}%
+ % switch the warning off for this group (which is a single operation)
+ \yquant@config@operator@multi@warnfalse%
+ \def\yquant@prepare@finalize@ctrl@multi@contiguous@warn{2}%
+ \else%
+ \numdef\yquant@prepare@finalize@ctrl@multi@contiguous@warn{%
+ \yquant@prepare@finalize@ctrl@multi@contiguous@warn+1%
+ }%
+ \fi%
+ {% save \body
+ \yquant@for \yquant@i := #1 to #2 {{% let inner loop mess up with macros
+ \csxappto{\yquant@prefix finalize@ctrl@prepare@appto}{%
+ \expandafter\yquant@prepare@callback@draw\expandafter{\yquant@i}%
+ }%
+ \expandafter\yquant@prepare@callback@prepare\expandafter{\yquant@i}%
+ }}%
+ }%
+}
+
+\def\yquant@prepare@finalize@ctrl@subcircuit@single#1#2#3#4{%
+ \yquant@prepare@finalize@ctrl@single{#1}{#3}%
+}
+
+\protected\def\yquant@prepare@finalize@ctrl@subcircuit@multi@loop#1{%
+ \eappto\yquant@prepare@append{%
+ \yquant@prepare@callback@draw{#1}%
+ }%
+ \yquant@prepare@callback@prepare{#1}%
+}
+
+\protected\def\yquant@prepare@finalize@ctrl@subcircuit@multi#1#2#3#4#5#6#7{%
+ % there are no contiguous parts here, don't call the normal @multi
+ \forlistloop\yquant@prepare@finalize@ctrl@subcircuit@multi@loop{#4}%
+} \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex b/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex
index c90a44614ca..2c44fd039bb 100644
--- a/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex
+++ b/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex
@@ -39,65 +39,70 @@
% BEGIN_FOLD Constructor: create single register and cleanup environment
% #1: type
-% #2: x position
-% #3: name
-% #4: index
-\protected\def\yquant@register@define#1#2#3#4{%
+% #2: name
+% #3: index
+\protected\def\yquant@register@define#1#2#3{%
\csnumgdef{\yquant@prefix registers}%
{\csname\yquant@prefix registers\endcsname+1}%
\csxdef{\yquant@prefix register@\csname\yquant@prefix registers\endcsname}{%
{#1}% type
- {#2}% x pos
- {{\the\dimexpr.5\dimexpr\yquant@config@register@minimum@height\relax\relax}%
- {\the\dimexpr.5\dimexpr\yquant@config@register@minimum@height\relax\relax}}% height and depth; at the end, the y position
- {{\yquant@env@create@x}{\yquant@env@create@x}{}{}}% wire start positions and clipping
+ {0pt}% x pos
+ {{\yquant@config@register@minimum@height}%
+ {\yquant@config@register@minimum@depth}%
+ {}}% height, depth, and multi-space parts; at the end, the y position
+ {{0pt}{0pt}{}{}}% wire start positions and clipping
{}% wire style
+ {\yquant@register@flag@clean}% information about the last gate
}%
- \global\csletcs{\yquant@prefix registername@#3[#4]}{\yquant@prefix registers}%
- \csxdef{\yquant@prefix registerhigh@#3}{#4}%
+ \global\csletcs{\yquant@prefix registername@#2[#3]}{\yquant@prefix registers}%
+ \csxdef{\yquant@prefix registerhigh@#2}{#3}%
\yquant@cleanup@csadd{\yquant@prefix register@\csname\yquant@prefix registers\endcsname}%
- \yquant@cleanup@csadd{\yquant@prefix registername@#3[#4]}%
- \ifnum0=#4\relax%
- \yquant@cleanup@csadd{\yquant@prefix registerhigh@#3}%
+ \yquant@cleanup@csadd{\yquant@prefix registername@#2[#3]}%
+ \ifnum0=#3\relax%
+ \yquant@cleanup@csadd{\yquant@prefix registerhigh@#2}%
\fi%
}
% in a subcircuit, create a new register that is only an alias for an existing register in the outer circuit.
-% #5: id in the outer circuit
-\protected\def\yquant@register@alias#1#2#3#4#5{%
+% #4: id in the outer circuit
+\protected\def\yquant@register@alias#1#2#3#4{%
\csnumgdef{\yquant@prefix registers}%
{\csname\yquant@prefix registers\endcsname+1}%
- \ifcsname\yquant@parent registermap@#5\endcsname%
+ \ifcsname\yquant@parent registermap@#4\endcsname%
% the parent is already an alias itself, pass this on transparently
\global\csletcs%
{\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname}%
- {\yquant@parent registermap@#5}%
+ {\yquant@parent registermap@#4}%
\else%
\csxdef{\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname}%
- {\yquant@parent register@#5}%
- \fi%
- % even though this is an alias, we still need to keep track of its internal dimensions
- \csgdef{\yquant@prefix registerdim@\csname\yquant@prefix registers\endcsname}%
- {{0pt}{0pt}}%
- \yquant@cleanup@csadd{\yquant@prefix registerdim@\csname\yquant@prefix registers\endcsname}%
- \global\csletcs{\yquant@prefix registername@#3[#4]}{\yquant@prefix registers}%
- \csxdef{\yquant@prefix registerhigh@#3}{#4}%
- \yquant@cleanup@csadd{\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname}%
- \yquant@cleanup@csadd{\yquant@prefix registername@#3[#4]}%
- \ifnum0=#4\relax%
- \yquant@cleanup@csadd{\yquant@prefix registerhigh@#3}%
+ {\yquant@parent register@#4}%
\fi%
- \csxdef{\yquant@prefix lastinput}{{\csname\yquant@prefix registers\endcsname}{#5}}%
- \unless\ifcsname\yquant@prefix firstinput\endcsname%
- \csxdef{\yquant@prefix firstinput}{{\csname\yquant@prefix registers\endcsname}{#5}}%
- \yquant@cleanup@csadd{\yquant@prefix firstinput}%
- \yquant@cleanup@csadd{\yquant@prefix lastinput}%
+ % we still store height, depth, and multi-space parts. To keep the same macros, we create a full register structure, but "abuse" the type component to contain the direct parent
+ \csxdef{\yquant@prefix register@\csname\yquant@prefix registers\endcsname}{%
+ {{\expandafter\yquant@register@alias@extract\yquant@parent}{#4}}% direct parent (circuit id, register id)
+ {}% unused
+ {{\yquant@config@register@minimum@height}%
+ {\yquant@config@register@minimum@depth}%
+ {}}% height, depth, and multi-space parts
+ {}% unused
+ {}% unused
+ {}% unused
+ }%
+ \global\csletcs{\yquant@prefix registername@#2[#3]}{\yquant@prefix registers}%
+ \csxdef{\yquant@prefix registerhigh@#2}{#3}%
+ \yquant@cleanup@csadd{\yquant@prefix register@\csname\yquant@prefix registers\endcsname}%
+ \yquant@cleanup@csadd{\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname}%
+ \yquant@cleanup@csadd{\yquant@prefix registername@#2[#3]}%
+ \ifnum0=#3\relax%
+ \yquant@cleanup@csadd{\yquant@prefix registerhigh@#2}%
\fi%
\expandafter\yquant@register@set@@aux%
\csname\csname\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname\endcsname\endcsname%
- \yquant@register@set@x@aux%
- {#2}%
+ \yquant@register@set@typelastgate@aux%
+ {{#1}{\yquant@register@flag@clean}}%
}
+
+\def\yquant@register@alias@extract yquant@env#1@{#1}%
% END_FOLD
% BEGIN_FOLD Converter: convert a register name to its id
@@ -162,19 +167,7 @@
\fi%
% pre-set y position
\yquant@for \idx := \idx to \numexpr \len -1\relax {%
- \yquant@register@define%
- \yquant@register@type@q%
- {\yquant@env@create@x}%
- \reg\idx%
- % Prepare to shipout
- \csxappto{\yquant@prefix draw}{%
- \yquant@lang@create@draw{\csname\yquant@prefix registers\endcsname}%
- {0pt}%
- {qubit}%
- 0%
- {}%
- {}%
- }%
+ \yquant@prepare@create\reg\idx\yquant@register@type@q%
}%
\endgroup%
}
@@ -680,7 +673,17 @@
\fi%
}
-\def\yquant@register@get@type@aux#1#2#3#4#5{#1}
+\def\yquant@register@get@parent#1{%
+ \ifcsname\yquant@prefix registermap@#1\endcsname%
+ \expandafter\expandafter\expandafter%
+ \yquant@register@get@type@aux\csname\yquant@prefix register@#1\endcsname%
+ \else%
+ \PackageError{yquant.sty}{Internal inconsistency detected}%
+ {Tried to get parent of a non-connected wire.}%
+ \fi%
+}
+
+\def\yquant@register@get@type@aux#1#2#3#4#5#6{#1}
\def\yquant@register@get@x#1{%
\ifcsname\yquant@prefix registermap@#1\endcsname%
@@ -692,31 +695,38 @@
\fi%
}
-\def\yquant@register@get@x@aux#1#2#3#4#5{#2}
+\def\yquant@register@get@x@aux#1#2#3#4#5#6{#2}
\def\yquant@register@get@height#1{%
- \ifcsname\yquant@prefix registermap@#1\endcsname%
- \expandafter\expandafter\expandafter%
- \@firstoftwo\csname\yquant@prefix registerdim@#1\endcsname%
- \else%
- \expandafter\expandafter\expandafter%
- \yquant@register@get@height@aux\csname\yquant@prefix register@#1\endcsname%
- \fi%
+ \expandafter\expandafter\expandafter%
+ \yquant@register@get@height@aux\csname\yquant@prefix register@#1\endcsname%
+}
+
+\def\yquant@register@peek@height#1#2{%
+ \expandafter\expandafter\expandafter%
+ \yquant@register@get@height@aux\csname yquant@env#1@register@#2\endcsname%
}
-\def\yquant@register@get@height@aux#1#2#3#4#5{\@firstoftwo#3}
+\def\yquant@register@get@height@aux#1#2#3#4#5#6{\@firstofthree#3}
\def\yquant@register@get@depth#1{%
- \ifcsname\yquant@prefix registermap@#1\endcsname%
- \expandafter\expandafter\expandafter%
- \@secondoftwo\csname\yquant@prefix registerdim@#1\endcsname%
- \else%
- \expandafter\expandafter\expandafter%
- \yquant@register@get@depth@aux\csname\yquant@prefix register@#1\endcsname%
- \fi%
+ \expandafter\expandafter\expandafter%
+ \yquant@register@get@depth@aux\csname\yquant@prefix register@#1\endcsname%
+}
+
+\def\yquant@register@peek@depth#1#2{%
+ \expandafter\expandafter\expandafter%
+ \yquant@register@get@depth@aux\csname yquant@env#1@register@#2\endcsname%
}
-\def\yquant@register@get@depth@aux#1#2#3#4#5{\@secondoftwo#3}
+\def\yquant@register@get@depth@aux#1#2#3#4#5#6{\@secondofthree#3}
+
+\def\yquant@register@get@multispace#1{%
+ \expandafter\expandafter\expandafter%
+ \yquant@register@get@multispace@aux\csname\yquant@prefix register@#1\endcsname%
+}
+
+\def\yquant@register@get@multispace@aux#1#2#3#4#5#6{\@thirdofthree#3}
% The y parameter get macros exist in two forms: The protected one is used during the storage to the draw macro; it should never be executed. The env environment then maps them to their proper expandable forms.
\protected\def\yquant@register@get@y{%
@@ -739,7 +749,7 @@
\fi%
}
-\def\yquant@register@get@y@aux#1#2#3#4#5{#3}
+\def\yquant@register@get@y@aux#1#2#3#4#5#6{#3}
% y distance between two registers.
\def\yquant@register@get@ydist#1#2{%
@@ -766,8 +776,8 @@
}%
}
-\protected\def\yquant@register@get@lastwire@aux#1#2#3#4#5#6{%
- \def#6{#4}%
+\protected\def\yquant@register@get@lastwire@aux#1#2#3#4#5#6#7{%
+ \def#7{#4}%
}
\def\yquant@register@get@style#1{%
@@ -780,7 +790,28 @@
\fi%
}
-\def\yquant@register@get@style@aux#1#2#3#4#5{#5}
+\def\yquant@register@get@style@aux#1#2#3#4#5#6{#5}
+
+\protected\long\def\yquant@register@execclear@lastgate#1#2{%
+ \ifcsname\yquant@prefix registermap@#1\endcsname%
+ \expandafter%
+ \yquant@register@execclear@lastgate@aux@i\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname{#2}%
+ \else%
+ \expandafter%
+ \yquant@register@execclear@lastgate@aux@i\csname\yquant@prefix register@#1\endcsname{#2}%
+ \fi%
+}
+
+\def\yquant@register@execclear@lastgate@aux@i#1{%
+ \expandafter\yquant@register@execclear@lastgate@aux@ii#1#1%
+}
+
+\long\def\yquant@register@execclear@lastgate@aux@ii#1#2#3#4#5#6#7#8{%
+ \ifstrempty{#6}\relax{%
+ #6{#8}%
+ \xdef#7{\unexpanded{{#1}{#2}{#3}{#4}{#5}{}}}%
+ }%
+}
\def\yquant@register@get@typeywire#1{%
\ifcsname\yquant@prefix registermap@#1\endcsname%
@@ -797,10 +828,10 @@
}%
}
-\protected\def\yquant@register@get@typeywire@aux#1#2#3#4#5#6#7#8{%
- \def#6{#1}%
- \def#7{#3}%
- \def#8{#4}%
+\protected\def\yquant@register@get@typeywire@aux#1#2#3#4#5#6#7#8#9{%
+ \def#7{#1}%
+ \def#8{#3}%
+ \def#9{#4}%
}%
% Set #1 to the maximum x value found between #2 and #3
@@ -833,6 +864,12 @@
\endgroup%
\expandafter\def\expandafter#1\expandafter{\the\dimen0}%
}
+
+\protected\def\yquant@register@flag@clean#1{%
+ \ifstrequal{#1}{init}{%
+ \advance\count8 by 1 %
+ }\relax%
+}
% END_FOLD
% BEGIN_FOLD Setters: change register information
@@ -856,8 +893,8 @@
\yquant@register@set@type@aux%
}
-\long\def\yquant@register@set@type@aux#1#2#3#4#5#6{%
- {#6}\unexpanded{{#2}{#3}{#4}{#5}}%
+\long\def\yquant@register@set@type@aux#1#2#3#4#5#6#7{%
+ {#7}\unexpanded{{#2}{#3}{#4}{#5}{#6}}%
}
\protected\def\yquant@register@set@x#1{%
@@ -876,23 +913,12 @@
\yquant@register@set@x@aux%
}
-\long\def\yquant@register@set@x@aux#1#2#3#4#5#6{%
- \unexpanded{{#1}}{#6}\unexpanded{{#3}{#4}{#5}}%
+\long\def\yquant@register@set@x@aux#1#2#3#4#5#6#7{%
+ \unexpanded{{#1}}{#7}\unexpanded{{#3}{#4}{#5}{#6}}%
}
\protected\def\yquant@register@update@height#1#2{%
- \ifcsname\yquant@prefix registermap@#1\endcsname%
- \ifdim#2>%
- \expandafter\expandafter\expandafter%
- \@firstoftwo\csname\yquant@prefix registerdim@#1\endcsname%
- \relax%
- \csxdef{\yquant@prefix registerdim@#1}{%
- {#2}%
- {\expandafter\expandafter\expandafter%
- \@secondoftwo\csname\yquant@prefix registerdim@#1\endcsname}%
- }%
- \fi%
- \else%
+ \unless\ifyquant@lang@attr@overlay@height%
\ifdim#2>%
\expandafter\expandafter\expandafter%
\yquant@register@get@height@aux\csname\yquant@prefix register@#1\endcsname%
@@ -904,25 +930,22 @@
\fi%
}
-\long\def\yquant@register@set@height@aux#1#2#3#4#5#6{%
+\protected\def\yquant@register@set@height@remote#1#2#3{%
+ \expandafter\yquant@register@set@@aux%
+ \csname yquant@env#1@register@#2\endcsname%
+ \yquant@register@set@height@aux{#3}%
+}
+
+\long\def\yquant@register@set@height@aux#1#2#3#4#5#6#7{%
\unexpanded{{#1}{#2}}%
- {{#6}{\unexpanded\expandafter{\@secondoftwo#3}}}%
- \unexpanded{{#4}{#5}}%
+ {{#7}%
+ {\unexpanded\expandafter{\@secondofthree#3}}%
+ {\unexpanded\expandafter{\@thirdofthree#3}}}%
+ \unexpanded{{#4}{#5}{#6}}%
}
\protected\def\yquant@register@update@depth#1#2{%
- \ifcsname\yquant@prefix registermap@#1\endcsname%
- \ifdim#2>%
- \expandafter\expandafter\expandafter%
- \@secondoftwo\csname\yquant@prefix registerdim@#1\endcsname%
- \relax%
- \csxdef{\yquant@prefix registerdim@#1}{%
- {\expandafter\expandafter\expandafter%
- \@firstoftwo\csname\yquant@prefix registerdim@#1\endcsname}%
- {#2}%
- }%
- \fi%
- \else%
+ \unless\ifyquant@lang@attr@overlay@depth%
\ifdim#2>%
\expandafter\expandafter\expandafter%
\yquant@register@get@depth@aux\csname\yquant@prefix register@#1\endcsname%
@@ -934,10 +957,75 @@
\fi%
}
-\long\def\yquant@register@set@depth@aux#1#2#3#4#5#6{%
+\protected\def\yquant@register@set@depth@remote#1#2#3{%
+ \expandafter\yquant@register@set@@aux%
+ \csname yquant@env#1@register@#2\endcsname%
+ \yquant@register@set@depth@aux{#3}%
+}
+
+\long\def\yquant@register@set@depth@aux#1#2#3#4#5#6#7{%
+ \unexpanded{{#1}{#2}}%
+ {{\unexpanded\expandafter{\@firstofthree#3}}%
+ {#7}%
+ {\unexpanded\expandafter{\@thirdofthree#3}}}%
+ \unexpanded{{#4}{#5}{#6}}%
+}
+
+\protected\def\yquant@register@update@multispace#1#2#3{%
+ \unless\ifnum#1<#2 %
+ \PackageError{yquant.sty}{Internal inconsistency detected}%
+ {Setting multispace part in wrong order.}%
+ \fi%
+ \unless\ifyquant@lang@attr@overlay@multi%
+ \begingroup%
+ \edef\tmp{%
+ \expandafter\expandafter\expandafter%
+ \yquant@register@get@multispace@aux\csname\yquant@prefix register@#1\endcsname%
+ }%
+ \let\old=\tmp%
+ \yquant@list@eupdateorinsert\tmp{#2}{#3}%
+ \unless\ifx\old\tmp%
+ \expandafter\yquant@register@set@@aux%
+ \csname\yquant@prefix register@#1\endcsname%
+ \yquant@register@set@multispace@aux\tmp%
+ \fi%
+ \endgroup%
+ \fi%
+}
+
+\long\def\yquant@register@set@multispace@aux#1#2#3#4#5#6#7{%
+ \unexpanded{{#1}{#2}}%
+ {{\unexpanded\expandafter{\@firstofthree#3}}%
+ {\unexpanded\expandafter{\@secondofthree#3}}%
+ {#7}}%
+ \unexpanded{{#4}{#5}{#6}}%
+}
+
+\protected\def\yquant@register@inject@extents#1#2{%
+ % enlarge the last subcircuit that was created previously by height #1 and depth #2.
+ % We enforce subcircuits to have registers, so no check needed.
+ \expandafter\yquant@register@set@@aux%
+ \csname yquant@env\the\yquant@env @register@1\endcsname%
+ \yquant@register@inject@height@aux{#1}%
+ \expandafter\yquant@register@set@@aux%
+ \csname yquant@env\the\yquant@env @register@\csname yquant@env\the\yquant@env @registers\endcsname\endcsname%
+ \yquant@register@inject@depth@aux{#2}%
+}
+
+\long\def\yquant@register@inject@height@aux#1#2#3#4#5#6#7{%
+ \unexpanded{{#1}{#2}}%
+ {{\the\dimexpr\@firstofthree#3+#7\relax}%
+ {\unexpanded\expandafter{\@secondofthree#3}}%
+ {\unexpanded\expandafter{\@thirdofthree#3}}}%
+ \unexpanded{{#4}{#5}{#6}}%
+}
+
+\long\def\yquant@register@inject@depth@aux#1#2#3#4#5#6#7{%
\unexpanded{{#1}{#2}}%
- {{\unexpanded\expandafter{\@firstoftwo#3}}{#6}}%
- \unexpanded{{#4}{#5}}%
+ {{\unexpanded\expandafter{\@firstofthree#3}}%
+ {\the\dimexpr\@secondofthree#3+#7\relax}%
+ {\unexpanded\expandafter{\@thirdofthree#3}}}%
+ \unexpanded{{#4}{#5}{#6}}%
}
\protected\def\yquant@register@set@y#1{%
@@ -956,8 +1044,8 @@
\yquant@register@set@y@aux%
}
-\long\def\yquant@register@set@y@aux#1#2#3#4#5#6{%
- \unexpanded{{#1}{#2}}{#6}\unexpanded{{#4}{#5}}%
+\long\def\yquant@register@set@y@aux#1#2#3#4#5#6#7{%
+ \unexpanded{{#1}{#2}}{#7}\unexpanded{{#4}{#5}{#6}}%
}
\protected\def\yquant@register@set@lastwire#1{%
@@ -976,8 +1064,22 @@
\yquant@register@set@lastwire@aux%
}
-\long\def\yquant@register@set@lastwire@aux#1#2#3#4#5#6{%
- \unexpanded{{#1}{#2}{#3}}{#6}\unexpanded{{#5}}%
+\long\def\yquant@register@set@lastwire@aux#1#2#3#4#5#6#7{%
+ \unexpanded{{#1}{#2}{#3}}{#7}\unexpanded{{#5}{#6}}%
+}
+
+\protected\def\yquant@register@set@typelastwire#1{%
+ \ifcsname\yquant@prefix registermap@#1\endcsname%
+ \PackageError{yquant.sty}{Internal inconsistency detected}%
+ {Setting type and lastwire was requested for a subcircuit.}%
+ \fi%
+ \expandafter\yquant@register@set@@aux%
+ \csname\yquant@prefix register@#1\endcsname%
+ \yquant@register@set@typelastwire@aux%
+}
+
+\long\def\yquant@register@set@typelastwire@aux#1#2#3#4#5#6#7{%
+ {\@firstoftwo#7}\unexpanded{{#2}{#3}}{\@secondoftwo#7}\unexpanded{{#5}{#6}}%
}
\protected\def\yquant@register@set@style#1{%
@@ -996,7 +1098,31 @@
\yquant@register@set@style@aux%
}
-\long\def\yquant@register@set@style@aux#1#2#3#4#5#6{%
- \unexpanded{{#1}{#2}{#3}{#4}}{#6}%
+\long\def\yquant@register@set@style@aux#1#2#3#4#5#6#7{%
+ \unexpanded{{#1}{#2}{#3}{#4}}{#7}\unexpanded{{#6}}%
+}
+
+\protected\def\yquant@register@set@lastgate#1{%
+ \ifcsname\yquant@prefix registermap@#1\endcsname%
+ \expandafter\@firstoftwo%
+ \else%
+ \expandafter\@secondoftwo%
+ \fi%
+ {%
+ \expandafter\yquant@register@set@@aux%
+ \csname\csname\yquant@prefix registermap@#1\endcsname\endcsname%
+ }{%
+ \expandafter\yquant@register@set@@aux%
+ \csname\yquant@prefix register@#1\endcsname%
+ }%
+ \yquant@register@set@lastgate@aux%
+}
+
+\long\def\yquant@register@set@lastgate@aux#1#2#3#4#5#6#7{%
+ \unexpanded{{#1}{#2}{#3}{#4}{#5}}{#7}%
+}
+
+\long\def\yquant@register@set@typelastgate@aux#1#2#3#4#5#6#7{%
+ {\@firstoftwo#7}\unexpanded{{#2}{#3}{#4}{#5}}{\@secondoftwo#7}%
}
% END_FOLD \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-shapes.tex b/Master/texmf-dist/tex/latex/yquant/yquant-shapes.tex
index 22b9601c4e0..88cddd66ddf 100644
--- a/Master/texmf-dist/tex/latex/yquant/yquant-shapes.tex
+++ b/Master/texmf-dist/tex/latex/yquant/yquant-shapes.tex
@@ -391,7 +391,7 @@
\fi%
\else%
\pgf@y=\dimexpr.5\ht\pgfnodeparttextbox+.5\dp\pgfnodeparttextbox+2pt\relax%
- \ifyquant@config@operator@multi@main%
+ \ifyquant@config@internal@multi@main%
\advance\pgf@y by 1.25mm %
\fi%
\ifdim\pgf@x<\pgf@y%
@@ -400,7 +400,7 @@
\fi%
}%
\savedanchor\stext{%
- \ifyquant@config@operator@multi@main%
+ \ifyquant@config@internal@multi@main%
\pgfqpoint%
{-.5\wd\pgfnodeparttextbox}%
{\dp\pgfnodeparttextbox}%
@@ -414,13 +414,13 @@
\pgf@x=\ht\pgfnodeparttextbox%
}%
\savedmacro\main{%
- \ifyquant@config@operator@multi@main%
- \def\main{\noexpand\yquant@config@operator@multi@maintrue}%
+ \ifyquant@config@internal@multi@main%
+ \def\main{\noexpand\yquant@config@internal@multi@maintrue}%
\else%
\ifdim\dimexpr\ht\pgfnodeparttextbox+\dp\pgfnodeparttextbox\relax=0pt%
- \def\main{\noexpand\yquant@config@operator@multi@maintrue}%
+ \def\main{\noexpand\yquant@config@internal@multi@maintrue}%
\else%
- \def\main{\noexpand\yquant@config@operator@multi@mainfalse}%
+ \def\main{\noexpand\yquant@config@internal@multi@mainfalse}%
\fi%
\fi%
}%
@@ -430,7 +430,7 @@
\anchor{text}{%
\stext%
\main%
- \ifyquant@config@operator@multi@main%
+ \ifyquant@config@internal@multi@main%
\pgf@y=\dimexpr-\yradius+1pt+\pgf@y\relax%
\fi%
}%
@@ -440,7 +440,7 @@
\beforebackgroundpath{%
\main%
% we only draw the meter symbol if this is the main part of a multi-register (or there is no text)
- \ifyquant@config@operator@multi@main%
+ \ifyquant@config@internal@multi@main%
% Make sure the meter does not extend beyond the box (we are in a scope here)
\path [clip]%
(-\xradius, \yradius) rectangle (\xradius, -\yradius);%
@@ -529,9 +529,6 @@
}
\pgfdeclareshape{yquant-line}{%
- \savedanchor\shorten{%
- \pgfqpoint\pgf@shorten@end@additional\pgf@shorten@start@additional%
- }%
\saveddimen\xradius{%
% we only need this for the border anchor; the value is automatically correct in the paths.
\pgf@x=.5\pgflinewidth%
@@ -544,18 +541,343 @@
}%
\inheritanchorborder[from=yquant-rectangle]%
\backgroundpath{%
- \shorten%
- \pgf@xa=\dimexpr\yradius-\pgf@x\relax%
- \pgf@ya=\dimexpr\yradius-\pgf@y\relax%
+ % manually shorten for the bounding box
+ \pgf@xa=\dimexpr\yradius-\pgf@shorten@end@additional\relax%
+ \pgf@ya=\dimexpr\yradius-\pgf@shorten@start@additional\relax%
+ \pgf@shorten@end@additional=0pt %
+ \pgf@shorten@start@additional=0pt %
\pgfpathmoveto{\pgfqpoint{0pt}{\pgf@xa}}%
\pgfpathlineto{\pgfqpoint{0pt}{-\pgf@ya}}%
}%
\clippath{%
- \shorten%
- \@tempdima=\dimexpr\yradius-\pgf@x\relax%
- \@tempdimb=\dimexpr\yradius-\pgf@y\relax%
+ \@tempdima=\dimexpr\yradius-\pgf@shorten@end@additional\relax%
+ \@tempdimb=\dimexpr\yradius-\pgf@shorten@start@additional\relax%
\pgfpathrectanglecorners%
{\pgfqpoint{-.5\pgflinewidth}{\@tempdima}}%
{\pgfqpoint{.5\pgflinewidth}{-\@tempdimb}}%
}%
+}
+
+% BEGIN_FOLD Gapped brace decoration
+\def\pgfdecorationsegmentfromto{0-1}%
+
+\protected\def\yquant@gappedbrace@extract#1-#2\yquant@sep{%
+ \dimdef\from{#1\pgfdecoratedremainingdistance}%
+ \dimdef\to{#2\pgfdecoratedremainingdistance}%
+}
+
+\def\yquant@gappedbrace@shiftloop#1{%
+ \yquant@gappedbrace@extract#1\yquant@sep%
+ \unless\ifdim\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance<\from %
+ \unless\ifdim\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance>\to %
+ % be careful about arch positions at the border
+ \ifdim\dimexpr\to-\from\relax<2\pgfdecorationsegmentamplitude %
+ % The arch is larger than the segment. We do not draw a line to it or an end line and place it in the mid of the segment, even if it is too short (this issues one extra \pgfpathmoveto command, but catching this rare case is not worth the effort).
+ \edef\pgfdecorationsegmentaspect{\pgfmath@tonumber{\dimexpr%
+ .5\dimexpr\from+\to\relax*65536/\pgfdecoratedremainingdistance%
+ \relax}}%
+ \else%
+ % The segment is large enough to cover the whole arch. But maybe we are too close at the border?
+ \ifdim\dimexpr\pgf@xc-\pgfdecorationsegmentamplitude\relax<\from %
+ \pgf@xc=\dimexpr\from+\pgfdecorationsegmentamplitude\relax%
+ \fi%
+ \ifdim\dimexpr\pgf@xc+\pgfdecorationsegmentamplitude\relax>\to %
+ \pgf@xc=\dimexpr\to-\pgfdecorationsegmentamplitude\relax%
+ \fi%
+ \edef\pgfdecorationsegmentaspect{\pgfmath@tonumber{\dimexpr%
+ \dimexpr\pgf@xc*65536/\pgfdecoratedremainingdistance%
+ \relax}}%
+ \fi%
+ \expandafter\expandafter\expandafter\listbreak%
+ \fi%
+ \fi%
+}
+
+% Assumes all decoration macros and lengths are filled. Checks whether the arch is too close at a corner and shifts it appropriately. Upon exit, \pgfdecorationsegmentaspect is modified.
+\protected\def\yquant@gappedbrace@calcshift{%
+ \pgf@xc=\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance%
+ \expandafter\forcsvlist\expandafter\yquant@gappedbrace@shiftloop%
+ \expandafter{\pgfdecorationsegmentfromto}%
+}
+
+\def\yquant@gappedbrace@loop#1{%
+ \yquant@gappedbrace@extract#1\yquant@sep%
+ \unless\ifdim\from=0pt %
+ \pgfpathmoveto{%
+ \pgfqpoint{\from}{.5\pgfdecorationsegmentamplitude}%
+ }%
+ \fi%
+ \unless\ifdim\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance<\from %
+ \unless\ifdim\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance>\to %
+ % be careful about arch positions at the border
+ \ifdim\dimexpr\to-\from\relax<2\pgfdecorationsegmentamplitude %
+ % The arch is larger than the segment. We do not draw a line to it or an end line and place it in the mid of the segment, even if it is too short (this issues one extra \pgfpathmoveto command, but catching this rare case is not worth the effort).
+ \pgfpathmoveto{%
+ \pgfqpoint{\dimexpr.5\dimexpr\from+\to\relax-\pgfdecorationsegmentamplitude\relax}%
+ {.5\pgfdecorationsegmentamplitude}%
+ }%
+ \edef\to{\the\pgfdecoratedremainingdistance}% to prevent the final line, we do not need "to" any more
+ \else%
+ % The segment is large enough to cover the whole arch. But maybe we are too close at the border?
+ \ifdim\dimexpr\pgf@xc-\pgfdecorationsegmentamplitude\relax<\from %
+ \pgf@xc=\dimexpr\from+\pgfdecorationsegmentamplitude\relax%
+ \fi%
+ \ifdim\dimexpr\pgf@xc+\pgfdecorationsegmentamplitude\relax>\to %
+ \pgf@xc=\dimexpr\to-\pgfdecorationsegmentamplitude\relax%
+ \fi%
+ % Both cases can't occur at the same time in this \else clause.
+ \pgfpathlineto{%
+ \pgfqpoint{\dimexpr\pgf@xc-\pgfdecorationsegmentamplitude\relax}%
+ {.5\pgfdecorationsegmentamplitude}%
+ }%
+ \fi%
+ \pgfpathcurveto{%
+ \pgfqpoint{\dimexpr\pgf@xc-.5\pgfdecorationsegmentamplitude\relax}%
+ {.5\pgfdecorationsegmentamplitude}%
+ }{%
+ \pgfqpoint{\dimexpr\pgf@xc-.15\pgfdecorationsegmentamplitude\relax}%
+ {.7\pgfdecorationsegmentamplitude}%
+ }{%
+ \pgfqpoint{\pgf@xc}{\pgfdecorationsegmentamplitude}%
+ }%
+ \pgfpathcurveto{%
+ \pgfqpoint{\dimexpr\pgf@xc+.15\pgfdecorationsegmentamplitude\relax}%
+ {.7\pgfdecorationsegmentamplitude}%
+ }{%
+ \pgfqpoint{\dimexpr\pgf@xc+.5\pgfdecorationsegmentamplitude\relax}%
+ {.5\pgfdecorationsegmentamplitude}%
+ }{%
+ \pgfqpoint{\dimexpr\pgf@xc+\pgfdecorationsegmentamplitude\relax}%
+ {.5\pgfdecorationsegmentamplitude}%
+ }%
+ \fi%
+ \fi%
+ \unless\ifdim\to=\pgfdecoratedremainingdistance %
+ \pgfpathlineto{%
+ \pgfqpoint{\to}{.5\pgfdecorationsegmentamplitude}%
+ }%
+ \fi%
+}
+
+% This is a variant of the brace in pathreplacing that allows for holes
+\pgfdeclaredecoration{gapped brace}{final}{%
+ \state{final}{%
+ \pgf@xc=\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance%
+ \pgfpathmoveto\pgfpointorigin% required for "raise" key
+ \pgfpathcurveto{%
+ \pgfqpoint{.15\pgfdecorationsegmentamplitude}{.3\pgfdecorationsegmentamplitude}%
+ }{%
+ \pgfqpoint{.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}%
+ }{%
+ \pgfqpoint{\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}%
+ }%
+ \expandafter\forcsvlist\expandafter\yquant@gappedbrace@loop%
+ \expandafter{\pgfdecorationsegmentfromto}%
+ \pgfpathlineto{%
+ \pgfqpoint{\dimexpr\pgfdecoratedremainingdistance-\pgfdecorationsegmentamplitude\relax}%
+ {.5\pgfdecorationsegmentamplitude}%
+ }%
+ \pgfpathcurveto{%
+ \pgfqpoint{\dimexpr\pgfdecoratedremainingdistance-.5\pgfdecorationsegmentamplitude\relax}%
+ {.5\pgfdecorationsegmentamplitude}%
+ }{%
+ \pgfqpoint{\dimexpr\pgfdecoratedremainingdistance-.15\pgfdecorationsegmentamplitude\relax}%
+ {.3\pgfdecorationsegmentamplitude}%
+ }{%
+ \pgfqpoint{\pgfdecoratedremainingdistance}{0pt}%
+ }%
+ }%
+}%
+
+\protected\def\yquant@gappedbrace@timer{%
+ \ifdim\tikz@time pt=-1pt %
+ % first set \pgfdecoratedremainingdistance appropriately
+ \pgfpointdiff\tikz@timer@start\tikz@timer@end%
+ \pgfmathsqrt@{\dimexpr\pgf@x*\pgf@x/65536+\pgf@y*\pgf@y/65536\relax\@gobbletwo}%
+ \pgfdecoratedremainingdistance=\pgfmathresult pt %
+ % now perform the transformation
+ \yquant@gappedbrace@calcshift%
+ % and finally let us return the desired position, just ignoring \tikz@time...
+ \pgftransformlineattime{\pgfdecorationsegmentaspect}{\tikz@timer@start}{\tikz@timer@end}%
+ \else%
+ \pgftransformlineattime{\tikz@time}{\tikz@timer@start}{\tikz@timer@end}%
+ \fi%
+}
+
+\pgfkeys{%
+ /pgf/decoration/from to/.store in=\pgfdecorationsegmentfromto%
+}
+% END_FOLD
+
+\pgfdeclareshape{yquant-init}{%
+ \saveddimen\xradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/x radius}}%
+ % inner xsep is between the brace tip and the right end of the text. Check if the decoration is raised (will define \def\tikz@dec@shift{\pgftransformyshift{#1}})
+ \iftikz@decoratepath%
+ \ifx\tikz@dec@shift\relax%
+ \pgf@xa=\pgfdecorationsegmentamplitude %
+ \else%
+ \pgfmathsetlength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift+\pgfdecorationsegmentamplitude}%
+ \fi%
+ \pgfmathaddtolength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \else%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \fi%
+ % outer xsep is (a lower bound) from the left end of the border to the left end of the text
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \@tempdima=.5\dimexpr\wd\pgfnodeparttextbox+\pgf@xa+\pgf@xb\relax%
+ \ifdim\@tempdima>\pgf@x%
+ \pgf@x=\@tempdima%
+ \fi%
+ }%
+ \saveddimen\yradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/y radius}}%
+ \@tempdima=.5\dimexpr\ht\pgfnodeparttextbox+\dp\pgfnodeparttextbox\relax%
+ \ifdim\@tempdima>\pgf@x%
+ \pgf@x=\@tempdima%
+ \fi%
+ \iftikz@decoratepath%
+ \ifdim2\pgfdecorationsegmentamplitude>\pgf@x%
+ \pgf@x=2\pgfdecorationsegmentamplitude%
+ \fi%
+ \fi%
+ }%
+ \savedanchor\stext{%
+ \iftikz@decoratepath%
+ % \pgf@x is still \yradius...
+ % first set \pgfdecoratedremainingdistance appropriately
+ \pgfdecoratedremainingdistance=2\pgf@x%
+ % now perform the transformation
+ \yquant@gappedbrace@calcshift%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}+\pgfdecorationsegmentamplitude}%
+ \unless\ifx\tikz@dec@shift\relax%
+ \pgfmathaddtolength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift}%
+ \fi%
+ \pgfqpoint%
+ {-\dimexpr\wd\pgfnodeparttextbox+\pgf@xa\relax}%
+ {\dimexpr.5\pgfdecoratedremainingdistance% = \yradius
+ -\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance% - aspect
+ -.5\ht\pgfnodeparttextbox+.5\dp\pgfnodeparttextbox% center there
+ \relax}%
+ \else%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \pgfqpoint%
+ {-\dimexpr\wd\pgfnodeparttextbox+\pgf@xa\relax}%
+ {-.5\dimexpr\ht\pgfnodeparttextbox-\dp\pgfnodeparttextbox\relax}%
+ \fi%
+ }%
+ % BEGIN_FOLD Operator anchors
+ \foreach \anc in {center, north, north east, east, south east, south, south west, west, north west} {%
+ \inheritanchor[from=yquant-rectangle]{\anc}%
+ }%
+ \anchor{text}{%
+ \stext%
+ \advance \pgf@x by \xradius\relax%
+ }%
+ \inheritanchorborder[from=yquant-rectangle]%
+ % END_FOLD
+ % BEGIN_FOLD Path
+ \backgroundpath{%
+ \pgfpathmoveto{\pgfqpoint{\xradius}{\yradius}}%
+ \pgfpathlineto{\pgfqpoint{\xradius}{-\yradius}}%
+ \pgfpointtransformed{\pgfqpoint{-\xradius}{\yradius}}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+ \pgfpointtransformed{\pgfqpoint{-\xradius}{-\yradius}}% for rotations
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+ }%
+ \clippath{%
+ \pgfpathrectanglecorners%
+ {\pgfqpoint{-\dimexpr\xradius\relax}%
+ {\dimexpr\yradius\relax}}%
+ {\pgfqpoint{\dimexpr\xradius+.5\pgflinewidth\relax}%
+ {-\dimexpr\yradius\relax}}%
+ }%
+ % END_FOLD
+}
+
+\pgfdeclareshape{yquant-output}{%
+ % Almost the same as in yquant-input, only a minimal change in \stext's x position
+ \saveddimen\xradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/x radius}}%
+ % inner xsep is from the brace tip and the left end of the text. Check if the decoration is raised (will define \def\tikz@dec@shift{\pgftransformyshift{#1}})
+ \iftikz@decoratepath%
+ \ifx\tikz@dec@shift\relax%
+ \pgf@xa=\pgfdecorationsegmentamplitude %
+ \else%
+ \pgfmathsetlength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift+\pgfdecorationsegmentamplitude}%
+ \fi%
+ \pgfmathaddtolength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \else%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \fi%
+ % outer xsep is (a lower bound) from the left end of the border to the left end of the text
+ \pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/outer xsep}}%
+ \@tempdima=.5\dimexpr\wd\pgfnodeparttextbox+\pgf@xa+\pgf@xb\relax%
+ \ifdim\@tempdima>\pgf@x%
+ \pgf@x=\@tempdima%
+ \fi%
+ }%
+ \saveddimen\yradius{%
+ \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/tikz/y radius}}%
+ \@tempdima=.5\dimexpr\ht\pgfnodeparttextbox+\dp\pgfnodeparttextbox\relax%
+ \ifdim\@tempdima>\pgf@x%
+ \pgf@x=\@tempdima%
+ \fi%
+ \iftikz@decoratepath%
+ \ifdim2\pgfdecorationsegmentamplitude>\pgf@x%
+ \pgf@x=2\pgfdecorationsegmentamplitude%
+ \fi%
+ \fi%
+ }%
+ \savedanchor\stext{%
+ \iftikz@decoratepath%
+ % \pgf@x is still \yradius...
+ % first set \pgfdecoratedremainingdistance appropriately
+ \pgfdecoratedremainingdistance=2\pgf@x%
+ % now perform the transformation
+ \yquant@gappedbrace@calcshift%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}+\pgfdecorationsegmentamplitude}%
+ \unless\ifx\tikz@dec@shift\relax%
+ \pgfmathaddtolength\pgf@xa{\expandafter\@secondoftwo\tikz@dec@shift}%
+ \fi%
+ \pgfqpoint%
+ {\dimexpr\pgf@xa\relax}%
+ {\dimexpr.5\pgfdecoratedremainingdistance% = \yradius
+ -\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance% - aspect
+ -.5\ht\pgfnodeparttextbox+.5\dp\pgfnodeparttextbox% center there
+ \relax}%
+ \else%
+ \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/inner xsep}}%
+ \pgfqpoint%
+ {\dimexpr\pgf@xa\relax}%
+ {-.5\dimexpr\ht\pgfnodeparttextbox-\dp\pgfnodeparttextbox\relax}%
+ \fi%
+ }%
+ % BEGIN_FOLD Operator anchors
+ \foreach \anc in {center, north, north east, east, south east, south, south west, west, north west} {%
+ \inheritanchor[from=yquant-init]{\anc}%
+ }%
+ \anchor{text}{%
+ \stext%
+ \advance \pgf@x by -\xradius\relax%
+ }%
+ \inheritanchorborder[from=yquant-init]%
+ % END_FOLD
+ % BEGIN_FOLD Path
+ \backgroundpath{%
+ \pgfpathmoveto{\pgfqpoint{-\xradius}{\yradius}}%
+ \pgfpathlineto{\pgfqpoint{-\xradius}{-\yradius}}%
+ \pgfpointtransformed{\pgfqpoint{\xradius}{\yradius}}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+ \pgfpointtransformed{\pgfqpoint{\xradius}{-\yradius}}% for rotations
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+ }%
+ \clippath{%
+ \pgfpathrectanglecorners%
+ {\pgfqpoint{-\dimexpr\xradius+.5\pgflinewidth\relax}%
+ {\dimexpr\yradius\relax}}%
+ {\pgfqpoint{\dimexpr\xradius\relax}%
+ {-\dimexpr\yradius\relax}}%
+ }%
+ % END_FOLD
} \ No newline at end of file
diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-tools.tex b/Master/texmf-dist/tex/latex/yquant/yquant-tools.tex
index 5f7efe5e037..4b31a4e35ed 100644
--- a/Master/texmf-dist/tex/latex/yquant/yquant-tools.tex
+++ b/Master/texmf-dist/tex/latex/yquant/yquant-tools.tex
@@ -30,6 +30,11 @@
\long\def\@thirdoffour#1#2#3#4{#3}%
\long\def\@fourthoffour#1#2#3#4{#4}%
\long\def\@thirdandfourthoffour#1#2#3#4{#3#4}%
+\long\def\@secondandthirdoffive#1#2#3#4#5{{#2}{#3}}
+\long\def\@firstoffive#1#2#3#4#5{#1} % unused
+\long\def\@secondoffive#1#2#3#4#5{#2}
+\long\def\@thirdoffive#1#2#3#4#5{#3}
+\long\def\@fourthoffive#1#2#3#4#5{#4} % unused
\long\def\@fifthoffive#1#2#3#4#5{#5}
% Loop #1 from min(#2, #3) to max(#2, #3), executing #4
@@ -184,6 +189,30 @@
\expandafter\yquant@sort@aux\expandafter0\expandafter{\the\numexpr\yquant@sort@count-1\relax}%
}
+% Returns the first item in the unordered sortlist when compared according to #1 and stores it in #2.
+\protected\def\yquant@sort@findfirst#1#2{%
+ \ifnum\yquant@sort@count<1 %
+ \let#2=\empty%
+ \else%
+ \letcs#2{yquant@sort@item0}%
+ \count0=1 %
+ \loop%
+ \ifnum\count0<\yquant@sort@count\relax%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter#1%
+ \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter{%
+ \expandafter\expandafter\expandafter#2%
+ \expandafter\expandafter\expandafter}%
+ \expandafter\expandafter\expandafter{%
+ \csname yquant@sort@item\the\count0\endcsname%
+ }%
+ \relax{%
+ \letcs#2{yquant@sort@item\the\count0}%
+ }%
+ \advance\count0 by 1 %
+ \repeat%
+ \fi%
+}
+
\def\yquant@sort@ascending#1#2{%
\ifnum#2>#1 %
\expandafter\@firstoftwo%
@@ -316,6 +345,7 @@
\begingroup
\catcode`\|=3
+\catcode`\&=3
\gdef\yquant@list@delim{|}
\protected\gdef\yquant@list@dequeue#1#2{%
@@ -338,8 +368,78 @@
\expandafter\yquant@list@dequeue@i#1\etb@lst@q@end{#1}{#2}\gdef%
}%
}
+
+\protected\gdef\yquant@list@eupdateorinsert#1#2#3{%
+ % the list items are of the form <number>:<value>. If an item is present where <number> = #2, then set its <value> to #3, if #3 is greater. If no item is present, add it.
+ \begingroup%
+ \def\etb@tempa##1|#2:##2|##3&{%
+ \endgroup%
+ \ifstrempty{##3}{%
+ \eappto#1{#2:#3|}%
+ }{%
+ \ifdim##2<#3 %
+ \yquant@list@ereplace#1{#2:##2}{#2:#3}%
+ \fi%
+ }%
+ }%
+ \expandafter\etb@tempa\expandafter|#1|#2:#3|&%
+}
+
+\protected\gdef\yquant@list@ereplace#1#2#3{%
+ \begingroup%
+ \def\etb@tempa##1|#2|##2&{%
+ \endgroup%
+ \ifstrempty{##1}{%
+ \edef#1{%
+ \unexpanded{##1}|#3|\unexpanded{##2}%
+ }%
+ }{%
+ \edef#1{%
+ \unexpanded\expandafter{\@gobble##1}|#3|\unexpanded{##2}%
+ }%
+ }%
+ }%
+ \expandafter\etb@tempa\expandafter|#1&
+}
+
+% expands to the contents of a list ranging from #1 to #2 (ascending)
+\gdef\yquant@list@range#1#2{%
+ \ifnum#1>#2 %
+ \expandafter\@firstoftwo%
+ \else%
+ \expandafter\@secondoftwo%
+ \fi{}{%
+ #1|%
+ \expandafter\yquant@list@range\expandafter{\the\numexpr#1+1\relax}{#2}%
+ }%
+}
\endgroup
+% performs #3 if #1 is a subset of #2; else, performs #4
+\protected\def\ifyquant@registersubset#1#2{%
+ \begingroup%
+ \let\yquant@register@multi=\@fourthoffour
+ \def\yquant@register@multi@contiguous##1##2##3{\yquant@list@range{##1}{##2}}%
+ \edef\listA{#1}%
+ \edef\listB{#2}%
+ \let\ifsuccess=\iftrue%
+ \forlistloop\yquant@registersubset@loop\listA%
+ \expandafter%
+ \endgroup%
+ \ifsuccess%
+ \expandafter\@firstoftwo%
+ \else%
+ \expandafter\@secondoftwo%
+ \fi%
+}
+
+\protected\def\yquant@registersubset@loop#1{%
+ \ifinlist{#1}\listB\relax{%
+ \let\ifsuccess=\iffalse%
+ \listbreak%
+ }%
+}
+
\def\ifyquant@OR#1#2{%
#1%
\expandafter\@firstoftwo%
diff --git a/Master/texmf-dist/tex/latex/yquant/yquant.sty b/Master/texmf-dist/tex/latex/yquant/yquant.sty
index 2d6631b8f2b..ecbee654e01 100644
--- a/Master/texmf-dist/tex/latex/yquant/yquant.sty
+++ b/Master/texmf-dist/tex/latex/yquant/yquant.sty
@@ -1,7 +1,7 @@
% yquant.sty
% Typesetting quantum circuits using a flow-oriented language
%
-% Copyright 2019-2020 Benjamin Desef
+% Copyright 2019-2021 Benjamin Desef
%
% This work may be distributed and/or modified under the conditions of the LaTeX Project
% Public License, either version 1.3c of this license or (at your option) any later
@@ -15,13 +15,27 @@
%
% The Current Maintainer of this work is Benjamin Desef.
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{yquant}[2020/10/27 v0.3.3 Yet another quantum circuit library for LaTeX]
+\ProvidesPackage{yquant}[2021/03/27 v0.4 Yet another quantum circuit library for LaTeX]
\RequirePackage{etoolbox}[2018/02/11]
\RequirePackage{tikz}[2015/08/29]
\RequirePackage{trimspaces}[2009/09/17]
+\RequirePackage{xkeyval}[2005/05/07]
\usetikzlibrary{arrows.meta,decorations.pathreplacing,decorations.pathmorphing}
+\define@choicekey+{yquant.sty}{compat}[\val\yquant@compat]{newest,0.3,0.4}{
+ \ifnum\yquant@compat=0 %
+ \def\yquant@compat{2} % current version
+ \fi%
+}{
+ \PackageWarning{yquant.sty}{Invalid value for `compat` key specified. Using `0.3`.}
+}
+\ProcessOptionsX
+\unless\ifdefined\yquant@compat
+ \PackageWarning{yquant.sty}{Please specify the `compat` key for yquant. Using `0.3`. Current version is `0.4`.}
+ \def\yquant@compat{1}
+\fi
+
\newif\ifyquantdebug
\input yquant-config.tex
\input yquant-tools.tex
@@ -29,6 +43,7 @@
\input yquant-env.tex
\input yquant-langhelper.tex
\input yquant-circuit.tex
+\input yquant-prepare.tex
\input yquant-draw.tex
\input yquant-shapes.tex
\input yquant-lang.tex
diff --git a/Master/texmf-dist/tex/latex/yquant/yquantlanguage-qasm.sty b/Master/texmf-dist/tex/latex/yquant/yquantlanguage-qasm.sty
index eaa848e03f2..d37aa6b9f0a 100644
--- a/Master/texmf-dist/tex/latex/yquant/yquantlanguage-qasm.sty
+++ b/Master/texmf-dist/tex/latex/yquant/yquantlanguage-qasm.sty
@@ -15,9 +15,9 @@
%
% The Current Maintainer of this work is Benjamin Desef.
\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{yquantlanguage-qasm}[2020/06/13 v0.3 yquant-qasm]
+\ProvidesPackage{yquantlanguage-qasm}[2021/03/27 v0.4 yquant-qasm]
-\RequirePackage{yquant}[2020/06/13]
+\RequirePackage{yquant}[2021/03/27]
% BEGIN_FOLD Environment definitions
\begingroup
@@ -222,17 +222,43 @@
\csname qasm@lang@\cmd\endcsname#2 \qasm@end%
}
-% Defining commands that accept registers and take an optional value
-% #1: name of the argument
-% #2: command that is to be called
-% #3: number of controls
-% #4: number of targets
-\protected\def\qasm@langhelper@declare@command#1#2#3#4{%
+% Defines a yquant command for qasm
+% #1: name of the command
+% #2: number of controls
+% #3: number of targets
+% #4: name of the yquant command
+% #5: pre-actions
+\protected\def\qasm@langhelper@alias@yquant#1#2#3#4#5{%
\begingroup%
\lowercase{\edef\cmd{#1}}%
% everything after the next space is just gobbled
\protected\long\csgdef{qasm@lang@\cmd}##1 ##2\qasm@end{%
- \qasm@langhelper@declare@command@@fetchargs{#3}{#4}{##1}{#2}%
+ \unexpanded{#5}%
+ \qasm@langhelper@declare@command@@fetchargs{#2}{#3}{##1}{\csname yquant@lang@#4\endcsname}%
+ \yquant@env@rescan%
+ }%
+ \endgroup%
+}
+
+% Defining commands that accept registers and take an optional value
+% #1: name of the argument
+% #2: number of controls
+% #3: number of targets
+% #4: actions to be taken before parsing
+% #5: actions to be taken after parsing
+\protected\def\qasm@langhelper@declare@command#1#2#3#4#5{%
+ \begingroup%
+ \lowercase{\edef\cmd{#1}}%
+ \long\protected\csxdef{qasm@lang@\cmd}##1 ##2\qasm@end{%
+ \noexpand\yquant@langhelper@execclear@lastgatetrue%
+ \unexpanded{#4}%
+ \qasm@langhelper@declare@command@@fetchargs{#2}{#3}{##1}\yquant@circuit@operator%
+ \noexpand\ifyquant@langhelper@execclear@lastgate%
+ \yquant@for \noexpand\i := \noexpand\yquant@circuit@operator@minctrl to \noexpand\yquant@circuit@operator@maxctrl {%
+ \yquant@register@execclear@lastgate{\noexpand\i}{\cmd}%
+ }%
+ \noexpand\fi%
+ \unexpanded{#5}%
\yquant@env@rescan%
}%
\endgroup%
@@ -488,18 +514,40 @@
\process%
}%
\fi%
- \yquant@lang@create@do{#1}[1][;%
+ \yquant@prepare@create{#1}0\yquant@lang@create@type%
+ \letcs\yquant@circuit@operator@maxtarget{\yquant@prefix registers}%
+ \numdef\yquant@circuit@operator@numtarget{1}%
+ \edef\yquant@circuit@operator@targets{\yquant@circuit@operator@maxtarget\yquant@list@delim}%
+ \let\yquant@circuit@operator@pctrls=\empty%
+ \def\yquant@circuit@operator@minpctrl{2147483647}%
+ \def\yquant@circuit@operator@maxpctrl{0}%
+ \let\yquant@circuit@operator@numpctrl=\yquant@circuit@operator@maxpctrl%
+ \let\yquant@circuit@operator@nctrls=\empty%
+ \let\yquant@circuit@operator@minnctrl=\yquant@circuit@operator@minpctrl%
+ \let\yquant@circuit@operator@maxnctrl=\yquant@circuit@operator@maxpctrl%
+ \let\yquant@circuit@operator@numnctrl=\yquant@circuit@operator@numpctrl%
+ \let\yquant@circuit@operator@minctrl=\yquant@circuit@operator@mintarget%
+ \let\yquant@circuit@operator@maxctrl=\yquant@circuit@operator@maxtarget%
+ \def\yquant@attrs@remaining{internal/move label}
+ \def\yquant@config@operator@minimum@width{0pt}%
+ \expandafter\yquant@prepare%
+ \expandafter{\yquant@lang@attr@value}%
+ {/yquant/every label, /yquant/every initial label,%
+ /yquant/every \yquant@lang@create@style\space label}%
+ \unless\ifx\yquant@lang@attr@value\empty%
+ \yquant@register@execclear@lastgate{\yquant@circuit@operator@maxtarget}{init}%
+ \fi%
\yquant@env@rescan%
}
\protected\def\qasm@lang@def#1,#2,'#3' #4\qasm@end{%
\lowercase{\def\cmd{#1}}%
- % we need to do a couple of case distictions (it might seem crazy to look for the existence of a particular macro in #3, but this is what qasm does)
+ % we need to do a couple of case distinctions (it might seem crazy to look for the existence of a particular macro in #3, but this is what qasm does)
\ifstrequal{#3}{bullet}{%
\edef\process{%
\def\expandafter\noexpand\csname qasm@lang@@def@\cmd\endcsname{%
\let\noexpand\yquant@lang@attr@value=\noexpand\empty%
- \noexpand\yquant@lang@@phase%
+ \noexpand\yquant@lang@phase%
}%
}%
}{%
@@ -519,32 +567,31 @@
% now check whether the text begins with \meter, \dmeter or \dmeterwide. This is not 100% equivalent to qasm, which only checks whether these macros are present, not whether they are at the beginning. But due to our node approach, anything different from the whole content being this macro does not make sense.
\expandafter\ifyquant@firsttoken\expandafter\meter\expandafter{\texcode}{%
\edef\process{%
- \def\expandafter\noexpand\csname qasm@lang@@def@\cmd\endcsname####1####2{%
- \noexpand\yquant@lang@@measure%
+ \def\expandafter\noexpand\csname qasm@lang@@def@\cmd\endcsname{%
+ \noexpand\yquant@lang@measure%
}%
}%
}{%
\expandafter\ifyquant@firsttoken\expandafter\dmeter\expandafter{\texcode}{%
\protected@edef\process{%
- \def\expandafter\noexpand\csname qasm@lang@@def@\cmd\endcsname####1####2{%
+ \def\expandafter\noexpand\csname qasm@lang@@def@\cmd\endcsname{%
\def\noexpand\yquant@lang@attr@value{\texcode}%
- \noexpand\yquant@lang@@dmeter%
+ \noexpand\yquant@lang@dmeter%
}%
}%
}{%
\expandafter\ifyquant@firsttoken\expandafter\dmeterwide\expandafter{\texcode}{%
\protected@edef\process{%
- \def\expandafter\noexpand\csname qasm@lang@@def@\cmd\endcsname####1####2{%
+ \def\expandafter\noexpand\csname qasm@lang@@def@\cmd\endcsname{%
\def\noexpand\yquant@lang@attr@value{\texcode}%
- \noexpand\yquant@lang@@dmeter%
+ \noexpand\yquant@lang@dmeter%
}%
}%
}{%
\edef\process{%
\def\expandafter\noexpand\csname qasm@lang@@def@\cmd\endcsname{%
- \yquant@draw%
- {$\unexpanded\expandafter{\texcode}$}%
- {/yquant/operators/every box}%
+ \def\noexpand\yquant@lang@attr@value{$\unexpanded\expandafter{\texcode}$}%
+ \noexpand\yquant@lang@box%
}%
}%
}%
@@ -586,9 +633,8 @@
\edef\process{%
\def\expandafter\noexpand\csname qasm@lang@@def@\cmd\endcsname{%
\noexpand\yquant@register@get@allowmultitrue%
- \yquant@draw%
- {$\unexpanded\expandafter{\texcode}$}%
- {/yquant/operators/every box}%
+ \def\noexpand\yquant@lang@attr@value{$\unexpanded\expandafter{\texcode}$}%
+ \noexpand\yquant@lang@box%
}%
% we don't use \qasm@langhelper@declare@command here, since it works globally
\protected\long\def\expandafter\noexpand\csname qasm@lang@\cmd\endcsname####1 ####2\noexpand\qasm@end{%
@@ -602,73 +648,68 @@
\yquant@env@scan%
}
-\qasm@langhelper@declare@command{measure}{\expandafter\yquant@lang@@measure\@gobbletwo}01
+\qasm@langhelper@alias@yquant{measure}01{measure}{}
-\qasm@langhelper@declare@command{H}\yquant@lang@@h01
+\qasm@langhelper@alias@yquant{h}01{h}{}
-\qasm@langhelper@declare@command{X}\yquant@lang@@x01
+\qasm@langhelper@alias@yquant{x}01{x}{}
-\qasm@langhelper@declare@command{Y}\yquant@lang@@y01
+\qasm@langhelper@alias@yquant{y}01{y}{}
-\qasm@langhelper@declare@command{Z}\yquant@lang@@z01
+\qasm@langhelper@alias@yquant{z}01{z}{}
-\qasm@langhelper@declare@command{S}\qasm@lang@@s01
-\def\qasm@lang@@s{%
- \yquant@draw%
+\qasm@langhelper@declare@command{S}01{}{%
+ \yquant@prepare%
{$S$}%
{/yquant/operators/every s}%
}
-\qasm@langhelper@declare@command{T}\qasm@lang@@t01
-\def\qasm@lang@@t{%
- \yquant@draw%
+\qasm@langhelper@declare@command{T}01{}{%
+ \yquant@prepare%
{$T$}%
{/yquant/operators/every t}%
}
-\qasm@langhelper@declare@command{nop}\qasm@lang@@nop01
-\def\qasm@lang@@nop#1#2#3{%
+\qasm@langhelper@alias@yquant{nop}01{hspace}{%
\dimdef\yquant@lang@attr@value{\yquant@config@operator@minimum@width+\yquant@config@operator@sep}%
- \yquant@lang@@hspace{#3}%
% we don't use a grid-based layout, so a nop really does nothing
}
-\qasm@langhelper@declare@command{zero}\qasm@lang@@zero01
-\def\qasm@lang@@zero#1#2#3{%
+\qasm@langhelper@alias@yquant{zero}01{init}{%
\let\yquant@lang@attr@value=\qasm@config@zero%
- \yquant@lang@@init{#3}%
+ \def\yquant@lang@attr@type{qubit}%
}
-\qasm@langhelper@declare@command{discard}{\expandafter\yquant@lang@@discard\@gobbletwo}01
+\qasm@langhelper@alias@yquant{discard}01{discard}{}
-\qasm@langhelper@declare@command{slash}{\expandafter\yquant@lang@@slash\@gobbletwo}01
+\qasm@langhelper@alias@yquant{slash}01{slash}{}
-\qasm@langhelper@declare@command{dmeter}{\expandafter\yquant@lang@@dmeter\@gobbletwo}01
+\qasm@langhelper@alias@yquant{dmeter}01{dmeter}{}
-\qasm@langhelper@declare@command{cnot}\yquant@lang@@not11
+\qasm@langhelper@alias@yquant{cnot}11{not}{}
-\qasm@langhelper@declare@command{c-z}\yquant@lang@@z11
+\qasm@langhelper@alias@yquant{c-z}11{z}{}
-\qasm@langhelper@declare@command{c-x}\yquant@lang@@x11
+\qasm@langhelper@alias@yquant{c-x}11{x}{}
-\qasm@langhelper@declare@command{toffoli}\yquant@lang@@not21
+\qasm@langhelper@alias@yquant{toffoli}21{not}{}
-\qasm@langhelper@declare@command{ZZ}{\expandafter\yquant@lang@@zz\@gobbletwo}02
+\qasm@langhelper@alias@yquant{zz}02{zz}{}
-\qasm@langhelper@declare@command{XX}\yquant@lang@@xx02
+\qasm@langhelper@alias@yquant{xx}02{xx}{}
-\qasm@langhelper@declare@command{swap}\yquant@lang@@swap02
+\qasm@langhelper@alias@yquant{swap}02{swap}{}
-\qasm@langhelper@declare@command{Utwo}\qasm@lang@@Utwo02
-\def\qasm@lang@@Utwo{%
+\qasm@langhelper@declare@command{Utwo}02{%
\yquant@register@get@allowmultitrue%
- \yquant@draw%
+}{%
+ \yquant@prepare%
{$U$}%
{/yquant/operators/every utwo}%
}
% space is a hspace _without_ wire - in priciple, we would have to discard and then re-initialize
-\qasm@langhelper@declare@command{space}\qasm@lang@@nop01
+\let\qasm@lang@space=\qasm@lang@nop
% END_FOLD
% some commands that might be used in boxes