% \iffalse meta-comment
%
% File: physics3.dtx
% -----------------------------------------------------------------------
%   Copyright (C) 2026      by Mingyu Xia     <myhsia@outlook.com>      *
%   Copyright (C) 2022-2024 by Tingxuan Zhang <alphaztx@163.com>        *
% -----------------------------------------------------------------------
%   This work may be distributed and/or modified under the conditions   *
%   of the LaTeX Project Public License (LPPL), either version 1.3c of  *
%   this license or (at your option) any later version.                 *
%   The latest version of this license is in                            *
%                                                                       *
%       http://www.latex-project.org/lppl.txt                           *
%                                                                       *
%   and version 1.3c or later is part of all distributions of LaTeX     *
%   version 2008 or later.                                              *
%                                                                       *
%   This work has the LPPL maintenance status `maintained'.             *
%                                                                       *
%   The Current Maintainer of this work is Mingyu Xia.                  *
% -----------------------------------------------------------------------
%   This work consists of the files physics3.dtx,                       *
%                                   physics3.ins,                       *
%                 the derived files physics3.sty,                       *
%                                   phx-ab.sty,                         *
%                                   phx-ab.braket.sty,                  *
%                                   phx-braket.sty,                     *
%                                   phx-doubleprod.sty,                 *
%                                   phx-diagmat.sty,                    *
%                                   phx-xmat.sty,                       *
%                                   phx-operator.sty,                   *
%                                   phx-bm-um.sty,                      *
%                                   phx-ab.legacy.sty,                  *
%                                   phx-qtext.legacy.sty,               *
%           the documentation files physics3.pdf,                       *
%                               and README.md.                          *
% -----------------------------------------------------------------------
%                                                                       *
%   Any modification of this file should ensure that the copyright and  *
%   license information is placed in the derived files.                 *
%                                                                       *
% -----------------------------------------------------------------------
%
%<*internal>
\iffalse
%</internal>
%
%<*readme>
[![CTAN Version](https://img.shields.io/ctan/v/physics3)](https://ctan.org/pkg/physics3)
[![GitHub Release](https://img.shields.io/github/v/release/myhsia/physics3)](https://github.com/myhsia/physics3/releases/latest)
[![GitHub Last Commit](https://img.shields.io/github/last-commit/myhsia/physics3)](https://github.com/myhsia/physics3/commits)
[![Actions Status](https://github.com/myhsia/physics3/actions/workflows/main.yaml/badge.svg?branch=main)](https://github.com/myhsia/physics3/actions)
[![GitHub Repo stars](https://img.shields.io/github/stars/myhsia/physics3)](https://github.com/myhsia/physics3)

The `physics3` Package
======================

This package defines commands for typesetting math formulae faster and
more simply. `physics3` is a modularized package, each module provides its
own function while `physics3.sty` itself only provides very few functions.
Therefore you can load modules separately after loading `physics3`.

Modules of `physics3` provide the following supports:

- Automatic braces;
- Dirac bra-ket notation;
- Easy way to typeset diagonal matrices and matrices with similar entries;
- Double cross and double dot (binary) operators for tensors;

Issues
------

The issue tracker for `physics3` is currently located
[on GitHub](https://github.com/myhsia/physics3).

Copyright and License
---------------------

Copyright (C) 2026      by Mingyu Xia     \<myhsia@outlook.com\>

Copyright (C) 2022-2024 by Tingxuan Zhang \<alphaztx@163.com\>

This work may be distributed and/or modified under the conditions
of the LaTeX Project Public License (LPPL), either version 1.3c of
this license or (at your option) any later version.
The latest version of this license is in

    http://www.latex-project.org/lppl.txt

and version 1.3c or later is part of all distributions of LaTeX
version 2008 or later.

This work has the LPPL maintenance status `maintained'.

The Current Maintainer of this work is **Mingyu Xia**.
%</readme>
%
%<*internal>
\fi
%</internal>
%
%<*driver>
\documentclass[11pt, letterpaper, cs-break = true]{l3doc}
\usepackage[mono = false]{libertine}
\usepackage{mathtools, fixdif, derivative, xcolor}
\usepackage[warnings-off={mathtools-colon, mathtools-overbracket}]{unicode-math}
\usepackage{physics3}
\usephxmodu{ab, ab.braket, diagmat, doubleprod, operator}
\usephxmodu{xmat}
\usephxmodu{ab.legacy, qtext.legacy, bm-um}
\setcounter{tocdepth}{2}
\ExplSyntaxOn \makeatletter
\DeclareDocumentCommand \key { s m }
  {
    \IfBooleanTF {#1} { \textcolor{red}{\ttfamily \bfseries #2} }
      {
        \ttfamily
        \seq_set_from_clist:Nn \l_tmpa_seq {#2}
        \seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq
          { \exp_not:n { \textcolor{red}{\bfseries ##1} } }
        \seq_use:Nn \l_tmpb_seq { ,~ } \:=\:
      }
  }
\DeclareCommandCopy \val \meta
\def \TTF {true\textup{\textbar\textbf{false}\makebox[0pt][r]{^^A
  \underline {\phantom{\bfseries true}\kern-0.1em}}}}
\def \TTF {\textup{\textbf{true}\makebox[0pt][r]{^^A
  \underline {\phantom{\bfseries true}\kern-0.1em}}\textbar}false}
\newlist{keyval}{itemize}{10}
\setlist[keyval]{leftmargin = 0pt, labelsep = 0pt}
\newwrite\example@out
\def\example@name{\jobname.example.aux}
\long\def\example@start{\begingroup\@bsphack
  \immediate\openout\example@out=\example@name
  \let\do\@makeother\dospecials\catcode`\^^M\active
  \def\verbatim@processline{\immediate\write\example@out{\the\verbatim@line}}^^A
  \verbatim@start}
\long\def\example@end#1{\immediate\closeout\example@out\@esphack\endgroup
  \catcode`\%14\relax
  \everymath{\displaystyle}
  \par\smallskip\noindent
  \fbox{\parbox[c][#1]{.6\linewidth}{\small\verbatiminput \example@name}}^^A
  \hfill
  \fbox{\parbox[c][#1]{.36\linewidth}
    {\centering\normalsize\input \example@name}}^^A
  \par\smallskip
  \catcode`\%9\relax}
\NewDocumentEnvironment{example}{m}{\example@start}
  {\example@end{#1\baselineskip}}
\protect \def \pardanger {\noindent \hbox to \z@{\hss \dbend \enspace}}
\providecommand \modu[1]{\texorpdfstring{\texttt{#1}}{“#1”}}
\linespread{1.06}
\@addtoreset{CodelineNo}{section}
\newbox\@tempboxb
\DeclareDocumentCommand\macrodef{O{4em}O{.6}mo+m}{\leavevmode
\ensuremath{^^A
  \setbox\@tempboxa\hbox to #1 {\hss\cs{#3}}^^A
  \setbox\@tempboxb\vbox{\hsize=#2\textwidth
    \textwidth=\hsize
    \leftskip=\z@
    \parindent=\z@
    \textbf{begindef}\IfValueT{#4}{ \textcolor{gray}{(#4)}}\par
    \begingroup\leftskip2em\parindent-1em#5\par\endgroup
    \textbf{enddef}^^A
  }^^A
  \dp\@tempboxb=\dimexpr\ht\@tempboxb-\ht\@tempboxa\relax
  \ht\@tempboxb=\ht\@tempboxa
  \box\@tempboxa\leftarrow\box\@tempboxb
}}
\protected \long \def \macroifelse#1#2#3{\par
  \textbf{if} #1 \textbf{then}\par
  \begingroup\advance\leftskip1em#2\par\endgroup
  \textbf{else}\par
  \begingroup\advance\leftskip1em#3\par\endgroup
  \textbf{endif}\par
}
\protected \def \macrocr{\par}
\newdimen\ttwd
\newdimen\sttwd
\protected\def\updatettwd{^^A
  \setbox\@tempboxa\hbox{\normalsize\ttfamily x}
  \ttwd=\wd\@tempboxa
  \setbox\@tempboxb\hbox{\small\ttfamily x}
  \sttwd=\wd\@tempboxb
}
\updatettwd
\makeatother \ExplSyntaxOff
\begin{document}
  \DeleteShortVerb\|
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \begin{documentation}
%
% \title{The \pkg{physics3} package\thanks{^^A
%   \url{https://github.com/myhsia/physics3},
%   \url{https://ctan.org/pkg/physics3}}
% }
%
% \author{Mingyu Xia\thanks{\texttt{^^A
%     \href{mailto:xiamingyu@westlake.edu.cn}{xiamingyu@westlake.edu.cn}^^A
%   }}
% }
%
% \date{Released 2026-01-26\quad \texttt{v0.1A}}
%
% \maketitle
%
% \begin{abstract}
% This is the document for \pkg{physics3} package, which defines commands for
% typesetting math formulae faster and more simply. \pkg{physics3} is a
% modularized package, each module provides its own function.
%
% If you are a user of the legacy \pkg{physics} package, you can click
% \hyperref[sec:physics-legacy]{here} to see the section for \pkg{physics} users
% before you start. If you never used \pkg{physics} package before, just read
% \emph{this} documentation.
% 
% The upstream maintainer of the similar package is Tingxuan Zhang^^A
% \footnote{\ttfamily\href{mailto:alphaztx@163.com}{alphaztx@163.com}}.
% This package is based on his \pkg{physics2} package, then added some
% high-level macros and optimized the packing workflow.
% \end{abstract}
%
% \tableofcontents
% 
% \clearpage
%
% \section{Introduction}
%
% The \pkg{physics3} package aims to provide a bundle of commands for
% typesetting math faster in different modules. The commands provided by
% \pkg{physics3} and its different modules are designed to be short and easy
% to memorize.
%
% \subsection{Packages required}
%
% The \pkg{physics3} package itself only requires the \pkg{keyval} package,
% which is part of the \pkg{latex-graphics} bundle. Almost every \LaTeX\
% distribution will include this bundle.
%
% Different modules of \pkg{physics3} might require different packages. It will
% be explained in the following sections that which module requires which
% package.
%
% The \pkg{physics3} package requires \LaTeXe\ kernel released after 2020/10.
% Please make sure that your \LaTeX\ distribution is not too old.
%
% \subsection{Loading \pkg{physics3} and its modules}
%
% Just like loading any package, write
% \begin{quote}
%   "\usepackage{physics3}"
% \end{quote}
% in the preamble to load the \pkg{physics3} package. In the current version,
% \pkg{physics3} doesn't provide a package option.
%
% \pkg{physics3} itself doesn't provide many features.
% You need to load different modules of \pkg{physics3} by using the
% \cs{usephxmodu} command only \emph{after} loading this package in the
% preamble to have different features applied to your document.
% \begin{function}{\usephxmodu}
%   \begin{syntax}
%     \cs{usephxmodu} \oarg{options} \marg{module}
%   \end{syntax}
% \end{function}
% The usage of \cs{usephxmodu} is similar to \cs{usepackage},
% so you can load several modules in one line. For example,
% \begin{quote}
%   "\usephxmodu [tightbraces = true] {ab}"\\
%   "\usephxmodu {ab.braket, doubleprod}"
% \end{quote}
% The options of a \pkg{physics3} module can be a comma-separated key-value
% list. These two lines load the \modu{ab} module with option
% "tightbraces = true" and load \modu{ab.braket} and \modu{doubleprod} modules.
%
% The following section introduce all the user-level modules of \pkg{physics3}.
% The modules have similar names like \meta{module}".legacy" are designed to
% provide solutions to maintain documents written with the legacy \pkg{physics}
% package. It's not suggested to use them in a new document.
%
% \section{Modules of \pkg{physics3}}
%
% \subsection{Features of the bare \pkg{physics3} package}
%
% The following commands are available once you load \pkg{physics3} in preamble.
% \begin{function}{\delopen, \delclose}
%   \begin{syntax}
% \cs{delopen} \meta{math delimiter} ... \cs{delclose} \meta{math delimeter}
%   \end{syntax}
%   \cs{delopen} and \cs{delclose}, followed by a math delimiter. They can be
%   regarded as abbreviations of ``open delimiter'' and ``close delimiter''. If
%   you had heard of the \pkg{mleftright} package.
%   You can regard \cs{delopen} and \cs{delclose} as a simpler version of
%   \cs[no-index]{mleft} and \cs[no-index]{mright}.
% \end{function}
% For example,
% \iffalse
%<*example>
% \fi
\begin{example}{2}
$ 0 \left(\frac12\right) 3 $\quad
$ 0 \delopen(\frac12\delclose) 3 $
\end{example}
% \iffalse
%</example>
% \fi
% \cs{biggg} and \cs{Biggg}, followed by a math delimiter. They are even bigger
% than \cs{Bigg}. \cs{biggg} and \cs{Biggg} may be useful when you need to write
% something really tall in math mode, but most OpenType math font do not support
% \cs{langle} (or U+27E8) and \cs{rangle} (or U+27E9) in this large size. Take
% an example,
% \iffalse
%<*example>
% \fi
\begin{example}{3}
$ \Biggg(\biggg(\Bigg(\bigg(
  \Big(\big(()\big)\Big)
  \bigg)\Bigg)\biggg)\Biggg) $
\end{example}
% \iffalse
%</example>
% \fi
% \cs{bigggl}, \cs{bigggm}, \cs{bigggr}, \cs{Bigggl}, \cs{Bigggm}
% and~\cs{Bigggr} are also supported.
%
% \subsection{The \modu{ab} module --- automatic braces}
%
% This module provides the command \cs{ab}. The \cs{ab} command, as a shorthand
% of ``automatic braces'', would specify the size of the following pair of
% delimiters. The delimiters after \cs{ab} should not be out of the range
% described by the following chart.
% \begin{function}{\ab}
%   \begin{syntax}
% \cs{ab}" ( ... ) "    \cs{ab}" [ ... ] "
% \cs{ab}"\{ ... \}" or \cs{ab} \cs{lbrace} ... \cs{rbrace}
% \cs{ab}" < ... > " or \cs{ab} \cs{langle} ... \cs{rangle}
% \cs{ab}" | ... | " or \cs{ab} \cs{vert}   ... \cs{vert}
% \cs{ab}"\| ... \|" or \cs{ab} \cs{Vert}   ... \cs{Vert}
%   \end{syntax}
% \end{function}
% For example, it's illegal to write an ``"\ab("'' without a ``")"'';
% it's also illegal to write "\ab=foo=". Take some correct examples:
% \iffalse
%<*example>
% \fi
\begin{example}{3}
$ \ab ( \frac12 )  $ \quad
$ \ab [ \frac12 ]  $ \quad
$ \ab\{ \frac12 \} $
\end{example}
% \iffalse
%</example>
% \fi
% You can also write a command from \cs{big} to \cs{Biggg} between \cs{ab}
% and the first delimiter, which means to specify the size of delimiters manually.
% Also, you can write a star ("*") between \cs{ab} and the first delimiter,
% to prevent \cs{ab} from setting the size of delimiters. For example,
% \iffalse
%<*example>
% \fi
\begin{example}{3}
$ \ab      <\frac12>  $\quad
$ \ab\biggg|\frac12|  $\quad
$ \ab*    \|\frac12\| $
\end{example}
% \iffalse
%</example>
% \fi
% \pardanger
% Always remember, do not put an \cs{ab} separately at the end of math mode like
% "$\ab$", because \cs{ab} will try to absorb the following math shift
% character ("$") as its argument.
%
% \begin{texnote}
%   The \modu{ab} module uses ``document commands''
%   module of \LaTeXe\ kernel (source file: ltcmd.dtx). This \LaTeXe\ kernel
%   module provides a document-level command parser. \cs{ab} is a complex
%   encapsulation of some internal document-level commands. Take an example,
%   if you define a document-level command like this:
%   \begin{quote}
%   "\NewDocumentCommand \foo { r() } {::#1::}"
%   \end{quote}
%   You can write "\foo(bar)" legally, but "\foo(()" will be regarded
%   illegal when you write another document-level command or end the paragraph.
%   Similarly, things like "\ab(()" will also cause errors.
% \end{texnote}
%
% The \modu{ab} module also provides \texttt{\textbackslash}$X$\texttt{ab}
% commands, where $X$ can be "p", "b", "B", "a", "v" and "V". These commands
% take a normal argument but not an argument delimited with paired delimiters.
% For example,
% \iffalse
%<*example>
% \fi
\begin{example}{3}
\def\0{\frac12}
$ \pab{\0} $ $ \bab{\0} $ $ \Bab{\0} $
$ \aab{\0} $ $ \vab{\0} $ $ \Vab{\0} $
\end{example}
% \iffalse
%</example>
% \fi
% These \texttt{\textbackslash$X$ab} commands can take an optional star and
% an optional \oarg{biggg} argument. Star stands for using the default sizes.
% For example,
% \iffalse
%<*example>
% \fi
\begin{example}{2}
\def\0{n+\frac12}
$ \pab[Big]{\0} $\quad $ \bab*{\0} $
\end{example}
% \iffalse
%</example>
% \fi
% \begin{keyval}
%   \item[\key{tightbraces}]\val{\TTF}: Influences whether thin skips are
%   reserved around the paired delimiters. It only works with the automatically
%   sized delimiters.
% \end{keyval}
%
% \subsection{The \modu{ab.braket} and \modu{braket} module
%   --- Dirac bra-ket notation}
%
% This two modules both contain four basic commands
% \begin{quote}
%   \cs{bra},\quad \cs{ket},\quad \cs{braket},\quad \cs{ketbra}
% \end{quote}
% These commands in the two modules share the same goal, but differ in syntax.\\
% \DescribeOption{ab.braket}
% A star ("*") or a size command can follow these commands,
% which are similar to the syntaxes of \cs{ab} module. The size commands can
% take the control sequences:
% \begin{quote}
% \cs{big},\quad \cs{Big},\quad \cs{bigg},\quad \cs{Bigg},\quad
% \cs{biggg}\quad or\quad \cs{Biggg}.
% \end{quote}
% \DescribeOption{braket}
% A star ("*") or a square-bracket-delimited size option, the size option can
% take the following values:
% \begin{quote}
% " ""big",\quad " ""Big",\quad " ""bigg",\quad " ""Bigg",\quad
% " ""biggg"\quad or\quad " ""Biggg".
% \end{quote}
% The star in the two modules stands for ``do not size the bra-ket
% automatically''. Four basic commands' syntaxes are described as
% follows respectively.
% \textbf{Please notice that the two module are conflict with each other,
% so don't use them together.} One can choose one module according to
% personal habit.
% \begin{function}{\bra, \ket}
%   \begin{syntax}
%     \cs{bra} \meta{* or size command}   "<" \meta{subformula} "|"^^A
% \hfill --> \makebox[15\sttwd][r]{\modu{ab.braket} modu.}
%     \cs{ket} \meta{* or size command}   "|" \meta{subformula} ">"^^A
% \hfill --> \makebox[15\sttwd][r]{\modu{ab.braket} modu.}
%     \cs{bra} \meta{\meta{*} or \oarg{size option}} \marg{subformula}^^A
% \hfill --> \makebox[15\sttwd][r]{\modu{braket} modu.}
%     \cs{ket} \meta{\meta{*} or \oarg{size option}} \marg{subformula}^^A
% \hfill --> \makebox[15\sttwd][r]{\modu{braket} modu.}
%   \end{syntax}
%   \begin{itemize}[leftmargin = 0pt]
%     \item In \modu{ab.braket} module,
%     the argument of \cs{bra} should be delimited with "<" and "|", and
%     the argument of \cs{ket} should be delimited with "|" and ">".\\
%     \pardanger
%     If you want to write ``$>$'' and ``$<$'' for relations in the argument of
%     \cs{bra} and \cs{ket}, you can write "\mathrel{>}" and "\mathrel{<}".
%     \item In \modu{braket} module, \cs{bra} and \cs{ket} take one mandatory
%     argument, which should be braced  with "{" and "}".
%   \end{itemize}
% \end{function}
% For example, in \modu{ab.braket} module,
% \iffalse
%<*example>
% \fi
\begin{example}{5}
\def\0{\frac\phi2}
$ \bra<\0| $\quad $ \bra*<\0|      $%
            \quad $ \bra\Big<\phi| $\\[1ex]
$ \ket|\0> $\quad $ \ket*|\0>      $%
            \quad $ \ket\Big|\psi> $
\end{example}
% \iffalse
%</example>
% \fi
% and in \modu{braket} module
% \iffalse
%<*example>
% \fi
\begingroup
\makeatletter\def\phx@requiremodule#1{}%
\def\PackageWarning#1#2{}%
\catcode`\%14\relax \input phx-braket.sty \catcode`\%9\relax \makeatother
\begin{example}{5}
\def\0{\frac\phi2}
$ \bra  \0 $\quad $ \bra*     \0   $%
            \quad $ \bra[Big] \psi $\\[1ex]
$ \ket  \0 $\quad $ \ket*     \0   $%
            \quad $ \ket[Big] \psi $
\end{example}
\endgroup
% \iffalse
%</example>
% \fi
% \begin{function}{\braket}
%   \begin{syntax}
%     \cs{braket} \meta{* or size command}\:       "<" \meta{subformula} ">"^^A
% \hfill --> \makebox[15\sttwd][r]{\modu{ab.braket} modu.}
%     \cs{braket} \meta{* or \oarg{size option, i}} i*\marg{subformula}^^A
% \hfill --> \makebox[15\sttwd][r]{\modu{braket} modu.}
%   \end{syntax}
%   \begin{itemize}[leftmargin = 0pt]
%     \item In \modu{ab.braket} module, the argument of \cs{braket} should be
%     delimited with "<" and ">", every ``"|"'' will be regarded as an
%     extensible vertical bar in the \meta{subformula} argument.
%     \pardanger
%     If you want to write ``$>$'' and ``$<$'' for relations in the argument of
%     \cs{braket} and \cs{ketbra} in this module,
%     you can write \cs{>} and \cs{<}.
%     It is quite different from "\mathrel{>}" or "\mathrel{<}" because in these
%     commands' argument, ">" and "<" will be redefined.
%     \item In \modu{braket} module, the \cs{braket} command, in default, can
%     take two arguments. If you want \cs{braket} to take one or three
%     arguments, you can specific the number of arguments by number "i" in the
%     square bracket, separate from the size option with a comma.
%   \end{itemize}
% \end{function}
% For example, in \modu{ab.braket} and \modu{braket} module,
% \iffalse
%<*example>
% \fi
\begin{example}{7}
\def\0{\frac\phi2}
$ \braket     <\hat A>  $\quad
$ \braket     <\0|\hat A|\psi> $\quad
$ \braket\big <\0|\psi> $\quad\\[1ex]
$ \braket*    <\0|\psi> $\quad
$ \braket\Big <\0|\psi> $\quad
$ \ab|{\braket<\psi|\hat A|\psi>}| $
\end{example}
% \iffalse
%</example>
% \fi
% \pardanger
% Commands from \modu{ab.braket} should not be placed barely in
% \cs{ab}"|"\meta{subformula}"|" or errors will arise.
% So, adding braces like the last line in the example above.
% \iffalse
%<*example>
% \fi
\begingroup
\makeatletter\def\phx@requiremodule#1{}%
\def\PackageWarning#1#2{}%
\catcode`\%14\relax \input phx-braket.sty \catcode`\%9\relax \makeatother
\begin{example}{7}
\def\0{\frac\phi2}
$ \braket  [1]     {\hat A}       $\quad
$ \braket  [3] {\0}{\hat A}{\psi} $\quad
$ \braket[big] {\0}{\psi} $\quad\\[1ex]
$ \braket*     {\0}{\psi} $\quad
$ \braket[Big] {\0}{\psi} $\quad
$ \ab|{\braket[3]{\psi}{\hat A}{\psi}}| $
\end{example}
\endgroup
% \iffalse
%</example>
% \fi
% \begin{function}{\ketbra}
%   \begin{syntax}
%     \cs{ketbra} \meta{* or size command}\:       "|" \meta{subformula_1} ">"
% ""        \meta{optional formula}\:        "<" \meta{subformula_2} "|"^^A
% \hfill --> \makebox[15\sttwd][r]{\modu{ab.braket} modu.}
%     \cs{ketbra} \meta{* or \oarg{size option}}      \marg{subformula_1}
% ""        \meta{optional formula}         \:\marg{subformula_2}^^A
% \hfill --> \makebox[15\sttwd][r]{\modu{braket} modu.}
%   \end{syntax}
%   \begin{itemize}[leftmargin = 0pt]
%     \item In \modu{ab.braket} module, the argument of \cs{ketbra} should be
%     delimited with "|" and "|", ">" and "<" will be regarded as extensible
%     $\rangle$ and $\langle$ in the argument.
%     \item In \modu{braket} module, the \cs{ketbra} command takes two
%     mandatory arguments by default, and one optional argument between the
%     two mandatory arguments ($\rangle$ and $\langle$).
%   \end{itemize}
% \end{function}
% For example, in \modu{ab.braket} and \modu{braket} module,
% \iffalse
%<*example>
% \fi
\begin{example}{4}
\def\0{\frac\phi2}
$ \ketbra         | \0 >< \psi | $\quad
$ \ketbra*        | \0 >< \psi | $\quad
$ \ketbra\Big | \0 >_x^y< \psi | $
\end{example}
% \iffalse
%</example>
% \fi
% \iffalse
%<*example>
% \fi
\begingroup
\makeatletter\def\phx@requiremodule#1{}^^A
\def\PackageWarning#1#2{}^^A
\catcode`\%14\relax \input phx-braket.sty \catcode`\%9\relax \makeatother
\begin{example}{4}
\def\0{\frac\phi2}
$ \ketbra        {\0} {\psi} $\quad
$ \ketbra*       {\0} {\psi} $\quad
$ \ketbra  [Big] {\0} [_x^y] {\psi} $
\end{example}
\endgroup
% \iffalse
%</example>
% \fi
% For convince, the two modules also contain three advanced commands
% \begin{quote}
%   \cs{bknorm},\quad \cs{kbproj},\quad \cs{expval}
% \end{quote}
% These commands have the same syntax in the two modules.
% \begin{function}{\bknorm, \kbproj, \expval}
%   \begin{syntax}
%     \cs{bknorm} \meta{*} \oarg{size} \marg{basis}
%     \cs{kbproj} \meta{*} \oarg{size} \marg{basis}
%     \cs{expval} \meta{*} \oarg{basis, size} \marg{operator}
%   \end{syntax}
% \end{function}
% For example,
% \iffalse
%<*example>
% \fi
\begin{example}{8}
\def \0{\frac\alpha2}
\edef\1{\uparrow,\downarrow}
$ \bknorm \0 $\quad $ \bknorm [big]\0 $
              \quad $ \bknorm*\0 $\\[2ex]
$ \kbproj \0 $\quad $ \kbproj [big]\0 $
              \quad $ \kbproj*\0 $\\[2ex]
$ \expval [\1, Big] {\hat A} $\quad
$ \expval*[\psi, Big]\0 $
\end{example}
% \iffalse
%</example>
% \fi
%
% \subsection{The \modu{doubleprod} module --- tensors' double product operator}
% 
% This module provides the \cs{doublecross} and \cs{doubledot} commands,
% which are regarded as binary operators by \TeX.
% Take an example of this module:
% \iffalse
%<*example>
% \fi
\begin{example}{1}
$ A \doublecross B \doubledot C $
\end{example}
% \iffalse
%</example>
% \fi
% \begin{keyval}
%   \item[\key{crossscale, dotscale}]\val{fp num}: Scales of ``$\times$''
%   and ``$\cdot$'' (Default: ".8" and "1").
%   \item[\key{crossopenup, dotopenup}]\val{fp num}: Spaces between
%   ``$\times$''s and ``$\cdot$''s "=" \val{fp num} "*" font size
%   (Default: ".02" and ".2").
%   \item[\key{doubledot, crosssymbol}]\val{symbol}: Pieces of
%   \cs{doublecross} and \cs{doubledot} (Default: \cs{times}, \cs{ldotp}).
% \end{keyval}
% Their default values can be configured in module option. For example,
% \begin{quote}
% "\usephxmodu[crossscale  = .75, dotscale  = 1.2,"\\
% "            crossopenup = .05, dotopenup = .25]{doubleprod}"
% \end{quote}
%
% \subsection{The \modu{diagmat} module --- simple diagonal matrices}
%
% This module requires the \pkg{mathtools} package and provides six
% \cs{*diagmat} commands:
% \begin{function}
%   {\diagmat, \pdiagmat, \bdiagmat, \Bdiagmat, \vdiagmat, \Vdiagmat}
% \begin{syntax}
%   \cs{\meta{delimiter type}diagmat}\meta{*} \oarg{options} \marg{diag}
% \end{syntax}
% where \meta{diag} is the diagonal of the diagonal matrix. The entries should
% be separated by commas.
% Prefixes like "p", "b", "V" have the same meanings as "pmatrix", "bmatrix" and
% "Vmatrix" in the \pkg{mathtools} package, a star ("*") follows the
% \cs{*diagmat} commands correspond to "*smallmatrix" in the
% \pkg{mathtools} package.
% \end{function}
% \begin{keyval}
%   \item[\key{empty}]\val{token list}:
%   Value of \cs{diagmat}'s empty entries (Default is blanck).
%   \item[\key{align}]\val{l\textup\textbar{c}\textup\textbar{r}}:
%   Align of \cs{diagmat}'s diagonal entries (Default: "r").
% \end{keyval}
% Their default values can be configured in the module option like this:
% \begin{quote}
% "\usephxmodu[empty = \cdot, align = r]{diagmat}"
% \end{quote}
% For example,
% \iffalse
%<*example>
% \fi
\begin{example}{4}
$ \pdiagmat [empty = \mathbf O] {
    \diagmat*[align = r]{1, \sqrt[3]4},
    \diagmat*{a, b} } $,
$ \bdiagmat* {1, -1, -1, -1} $
\end{example}
% \iffalse
%</example>
% \fi
%
% \subsection{The \modu{xmat} module --- matrices with formatted entries}
%
% This module requires the \pkg{mathtools} package and provides six
% \cs{*xmat} commands:
% \begin{function}{\xmat, \pxmat, \bxmat, \Bxmat, \vxmat, \Vxmat}
% \begin{syntax}
%   \cs{\meta{delimeter type}xmat}\meta{*} \oarg{options} \marg{entry}^^A
% \marg{rows shown} \marg{cols shown}
% \end{syntax}
% Prefixes like "p", "b", "V" have the same meanings as "pmatrix", "bmatrix" and
% "Vmatrix" in the \pkg{mathtools} package, a star ("*") follows the
% \cs{*xmat} commands correspond to "*smallmatrix" in the
% \pkg{mathtools} package.
% For example,
% \iffalse
%<*example>
% \fi
\begin{example}{2}
$ \vxmat{a}{2}{3} $
\end{example}
% \iffalse
%</example>
% \fi
% If \meta{rows shown} or \meta{cols shown} contains non-digit characters,
% extra dots will be added. For example,
% \iffalse
%<*example>
% \fi
\begin{example}{2}
$ \bxmat*[showtop = 1, showleft = 2]
    {X}{m}{n} $
\end{example}
% \iffalse
%</example>
% \fi
% \begin{keyval}
%   \item[\key{showtop, showleft}]\val{int num}: Numbers of rows and columns to
%   be shown at the top and the left side (Default: "MaxMatrixCols - 2").
% \end{keyval}
% Their default values can be configured in the module option like this:
% \begin{quote}
%   "\usephxmodu[showtop = 1, showleft = 2]{xmat}"
% \end{quote}
% This will also influence ``\cs{xmat}''s with digital \meta{rows shown} and
% \meta{cols shown} they are larger than the values corresponding to "showtop"
% and "showleft". For example,
% \iffalse
%<*example>
% \fi
\begin{example}{2}
$ \pxmat*[showtop  = 1,
          showleft = 2]{A}{8}{8} $
\end{example}
% \iffalse
%</example>
% \fi
% The "format" option allows users to use a new entry format.
% \begin{keyval}
%   \item[\key{format}]\val{custom entry format in terms of \#1, \#2, and \#3}:
%   \begin{arguments}
%     \item The common entry, or the first mandatory \meta{entry} argument
%     of \cs{xmat};
%     \par \vspace{-12pt}
%     \begin{multicols}{2}
%     \item The row index;
%     \item The column index.
%     \end{multicols}
%     \par \vspace{-12pt}
%   \end{arguments}
% \end{keyval}
% This option should be only used in the optional argument of \cs{xmat}.
% For example,
% \iffalse
%<*example>
% \fi
\begin{example}{3}
$ \Bxmat*[showtop = 2, showleft = 1,
          format = \texttt{#1[#2][#3]}]
    {x}{m}{n} $
\end{example}
% \iffalse
%</example>
% \fi
% \end{function}
%
% \subsection{The \modu{operator} module}
%
% This module provides a series of commands for log-like operators and some
% commands for nabla-related operators ($\nabla$)
% \begin{quote}
%   "\asin  \acos  \atan  \acsc  \asec  \acot  \rank  \erf"\\
%   "\Tr    \tr    \Res   \res   \PV    \pv    \upe   \iu "\\
%   "\Re    \Im    \identity     \grad  \curl  \div   \laplacian"
% \end{quote}
% \begin{itemize}[leftmargin = 0pt]
%   \item The first two lines of commands yield what they look like in math mode
%   \item \cs{PV} yields ``$\PV$'' as an ordinary symbol and \cs{pv}
%   yields ``$\pv$''.
%   \item \cs{Re} and \cs{Im} are redefined as ``$\Re$'' and ``$\Im$''.
%   $\Resymbol$ and $\Imsymbol$ are redefined as \cs{Resymbol} and
%   \cs{Imsymbol}, in default.
%   \item The ``$\divsymbol$'' symbol was redefined as \cs{divsymbol}.
% \end{itemize}
% \begin{keyval}
%   \item[\key{ReIm}]\val{\TTF}: Determines whether to redefine \cs{Re}
%   and \cs{Im}.
%   If you want to reserve the definition of \cs{Re} and \cs{Im}, you can write
%   like this:
%   \begin{quote}
%     "\usephxmodu[ReIm = false]{operator}"
%   \end{quote}
% \end{keyval}
% For example,
% \iffalse
%<*example>
% \fi
\begingroup
\makeatletter\def\phx@requiremodule#1{}^^A
\def\PackageWarning#1#2{}^^A
\catcode`\%14\relax \input phx-braket.sty \catcode`\%9\relax \makeatother
\begin{example}{6}
% \usephxmodu{braket}
$ \asin x  $, $ \PV f(z) = \pv f(z) $\\[1ex]
$ \identity = \int \d^2 \alpha
  \kbproj\alpha/\pi $\\[1ex]
$ \Re z = \Im z = \upe^{\iu\pi} = -1$\\[1ex]
$ \grad V$, $\div (x,y,z)$, $ \curl(x,y,z) $
\end{example}
\endgroup
% \iffalse
%</example>
% \fi
% This module requires the \pkg{fixdif} package with file date "2023/01/31"
% at minimum.
%
% \subsection{The \modu{bm-um} module}
%
% Similarly to the \pkg{bm} package, this module also provides a
% \cs[no-index]{bm} command, but can take \emph{a series of} math characters as
% its argument, which works for the \pkg{unicode-math} package.
%
% The Latin letters or Greek letters in the argument will be switched to the
% bold italic glyphs corresponding to them (if there exists bold italic
% glyphs); else \cs[no-index]{bm} would switch to the bold upright glyphs.
% For example,
% \iffalse
%<*example>
% \fi
\begin{example}{1}
$ \bm {0 A z \alpha \Omega} $
\end{example}
% \iffalse
%</example>
% \fi
%
% \subsection{The \modu{ab.legacy} module}
%
% \begin{function}{\abs, \norm, \eval (\peval \beval), \order}
% This module provides the above commands.
% They share the same syntax as
% \begin{syntax}
%   \cs{\meta{cmd}}"*"\oarg{biggg}\marg{subformula}.
% \end{syntax}
% Star and \meta{biggg} are optional. Star stands for ``use the default size''.
% \end{function}
% For example,
% \iffalse
%<*example>
% \fi
\begin{example}{2}
\def\0{1+\frac12}
$ \abs\0 $, $ \norm[Big]\0 $, $ \order*\0 $
\end{example}
% \iffalse
%</example>
% \fi
% \iffalse
%<*example>
% \fi
\begin{example}{4}
\def\0{1+\frac x2}
$ \eval      {\0}_a^b $,
$ \peval*    {\0}_a^b $,
$ \beval[big]{\0}_a^b $
\end{example}
% \iffalse
%</example>
% \fi
% You can set the ``order'' symbol in this module through
% the "order" option like this:
% \begin{quote}
%   "\usephxmodu[order = O]{ab.legacy}"
% \end{quote}
% Then "$\order{N}$" yields $O(N)$.
%
% \subsection{The \modu{qtext.legacy} module}
%
% The \modu{qtext.legacy} module provides the \cs{q}\meta{foo} commands
% for \cs{quad}-wrapped texts. These commands have the same syntax as
% \pkg{physics}. For example,
% \iffalse
%<*example>
% \fi
\begin{example}{5}
% \usephxmodu{qtext.legacy}
$ A \qq {foo bar} B $\\[1ex]
$ A \qq*{foo bar} B $\\[1ex]
$ C \qcc D \qcc*  E $\\[1ex]
$ F \qif G \qthen H $
\end{example}
% \iffalse
%</example>
% \fi
% All the commands described in \S2.4 of
% \href{http://mirrors.ctan.org/macros/latex/contrib/physics/physics.pdf}^^A
%   {\textsf{physics} documentation} are supported when using
% \modu{qtext.legacy} module, but I don't recommend using this module unless
% you are maintaining a document written with \pkg{physics}'s \cs{q}\meta{foo}
% commands.
% \clearpage
%
% \section{For the legacy \pkg{physics} users}\label{sec:physics-legacy}
%
% This section describes \pkg{physics3} package for those who are
% used to the \pkg{physics} package, which is only a simple reference
% manual for:
% \begin{itemize}
%   \item Frequent users of the legacy \pkg{physics} package;
%   \item Those who have to maintain a document written with \pkg{physics};
%   \item Users who failed to use \pkg{unicode-math} with \pkg{physics}.
% \end{itemize}
%
% In this section, the modules of \pkg{physics3} will be introduced in
% the same order as the \pkg{physics} documentation.
%
% \subsection{Legacy problems with \pkg{physics} package}^^A
% \label{subsec:physics-legacy-problems}
% The \pkg{physics} package provides \cs[no-index]{qty} command for
% automatic-sizing braces. The \cs[no-index]{qty} command would cause conflict
% with the \pkg{siunitx} package, which provides a unified method to typeset
% numbers and units correctly.
%
% Besides, after you loaded \pkg{physics}, when you
% type \cs[no-index]{homework} you will get Maxwell equations and Schr\"odinger
% equation. The \cs[no-index]{homework} command is ``declared'' in
% \file{physics.sty} but it was not described in the documentation. That is, if
% you have defined \cs[no-index]{homework} before loading \pkg{physics}
% package, \pkg{physics} would overwrite the definition ``silently''.
%
% The vector-notation part of \pkg{physics} uses \pkg{amsmath}'s (more
% exactly, \file{amsbsy.sty}'s) \cs[no-index]{boldsymbol} command to generate
% bold vectors. Commands for cross/dot product are defined
% with \cs[no-index]{boldsymbol}. \cs[no-index]{boldsymbol} uses
% \cs[no-index]{mathversion}, a \LaTeXe\ kernel command that works well with
% traditional TFM-based fonts but fails when using \pkg{unicode-math}.
%
% In the definition of \cs[no-index]{imat}, \cs[no-index]{xmat},~
% \cs[no-index]{dmat} and \cs[no-index]{admat} commands
% from \pkg{physics}, there is a \cs{newtoks} command which allocates a token
% list register and two \cs{newcount} commands allocating two count registers.
% Every time you write a command like \cs[no-index]{imat} in your document,
% then one token list register and two count registers will be wasted. What's
% even worse is that, if you wrote really too many matrix commands from
% \pkg{physics} (for example, 32767 \cs{imat}s in \hologo{LuaLaTeX}), there'd
% be no room for a new \cs{count}.
%
% \pkg{physics} integrated all the functions in one file (\texttt{physics.sty}),
% that is, you cannot load one of the total seven parts of functions; you have
% to load the seven parts altogether, even included the extra
% \cs[no-index]{homework} command we mentioned in the first paragraph.
%
% Moreover, the code of \file{physics.sty} ``abuses'' the "g"-type
% arguments of \pkg{xparse} package. Therefore the syntax of \pkg{physics}
% package looks kind of weird.
% See \href{https://tex.stackexchange.com/questions/470819/macros-dv-and-pdv-eat-the-subsequent-parenthesis-argument/470842#470842}
% {here} for more.
%
% \subsection{Loading \pkg{physics3}}
%
% The \pkg{physics3} package includes different modules, among which every
% module focuses on one single function.
%
% Write the following line in the preamble to load \pkg{physics3}:
% \begin{quote}
% "\usepackage{physics3}"
% \end{quote}
% But this is not enough. \pkg{physics3} contains different modules.
% If you want to load any module of \pkg{physics3}, write this line after
% loading \pkg{physics3} package:
% \begin{quote}
% \cs{usephxmodu}\marg{module list}
% \end{quote}
% For example, ``"\usephxmodu{ab, doubleprod}"'' loads the \modu{ab}
% module and the \modu{doubleprod} module.
%
% You can also load a module with options:
% \begin{quote}
%   \cs{usephxmodu}\oarg{option list}\marg{module}
% \end{quote}
% For example, ``"\usephxmodu[legacy]{ab}"'' loads \modu{ab} with the
% option ``"legacy"''.
%
% \pardanger Attention, if you used any font package in your document, remember
% that \pkg{physics3} requires to be loaded \emph{after} font packages.
%
% \subsection{List of commands}
%
% \subsubsection{Automatic bracing}
% As mentioned in \S\ref{subsec:physics-legacy-problems}, the \cs{qty} command
% from \pkg{physics} will conflict with \pkg{siunitx}. The command for
% automatic braces in \pkg{physics3} is \cs{ab}, short for \textbf automatic
% \textbf braces.
%
% \pkg{physics} also provides the following commands:
% \begin{quote}
% "\abs"\quad  "\norm"\quad  "\eval"\quad "\order"\quad
% \begingroup\color{gray}^^A
% "\comm"\quad "\acomm"\quad "\pb"
% \endgroup
% \end{quote}
% \pardanger These commands are not originally supported by \pkg{physics3}, but
% the first four commands can be used through the \modu{ab.legacy} module of
% \pkg{physics3}:
% \begin{quote}
% "\usephxmodu{ab.legacy}"
% \end{quote}
% Users of the legacy \pkg{physics} package should notice that the syntax of
% \cs{eval} has been changed. The \modu{ab.legacy} module abandoned the
% "\eval(foo|"-like syntax. The new \cs{eval}'s syntax is just like other
% commands in this module. There are also two variants of \cs{eval} ---
% \cs{peval} and \cs{beval}.
%
% The \cs{comm}, \cs{acomm} and \cs{pb} (Poisson bracket) are not supported.
% But you can write like "\ab[foo,baz]" or "\bab{foo,baz}" instead.
%
% By the way, you can set the ``order'' symbol in \modu{ab.legacy} through
% the "order" option like this:
% \begin{quote}
% "\usephxmodu[order = O]{ab.legacy}"
% \end{quote}
% Then "$\order(N)$" yields $O(N)$.
%
% \subsubsection{Vector notation}
%
% Unfortunately, there is not a plan for \pkg{physics3} to support this part
% of \pkg{physics} completely, but the rest of this section will show some
% methods to maintain the document written with \pkg{physics}.
%
% The \cs{vb}("*"), \cs{va}("*") and \cs{vu}("*") are not supported
% in any module of \pkg{physics3}. But these commands can be defined by copying
% the following lines below and pasting them in the preamble:
% \begin{quote}
% "\makeatletter"\\
% "\newcommand\vb{\@ifstar\boldsymbol\mathbf}"\\
% "\newcommand\va[1]{\@ifstar{\vec{#1}}{\vec{\mathrm{#1}}}}"\\
% "\newcommand\vu[1]{%"\\
%   "\@ifstar{\hat{\boldsymbol{#1}}}{\hat{\mathbf{#1}}}}"\\
% "\makeatother"
% \end{quote}
% The \cs{boldsymbol} command requires the \pkg{amsmath} or \pkg{bm} package.
% If you prefer to use \pkg{bm}, you can also use the \cs{bm} command.
% What's more, if you tried the commands above, you might find that,
% the result of \cs{va} above is different from that of \pkg{physics}.
% This is because, if you choose to present a vector in bold, there's almost
% no need to put a \cs{vec} ($\vec{\mskip9mu}$) sign above it.
%
% However, the method above may not work well with \pkg{unicode-math}
% because there are so many OpenType math fonts without a bold version.
% When using \pkg{unicode-math}, it's recommended to use \cs{symbf} and
% \cs{symbfit} for a separate vector. For example, "$\symbf{0}$" yields
% $\symbf{0}$, and "$\symbfit{A}$" yields $\symbfit{A}$.
%
% The \cs{vdot} and \cs{cross} commands are not supported in any module
% of \pkg{physics3}. Actually, there is no need to use a bold ``$\cdot$''
% or ``$\times$'' for the products of two vectors. Using \cs{cdot} and
% \cs{times} is enough.
%
% The commands related to ``$\nabla$'' are supported through \modu{operator}
% module. These commands are \cs{grad}, \cs{div} and \cs{curl}. These commands
% should not be put in the end of a math formula either (just like \cs{ab}).
% Notice that the former \cs{div} command for a ``$\divsymbol$'' (if there
% exists one) is redefined as \cs{divsymbol}.
%
% Actually, the nabla-related commands end with \cs{ab}. Thus, the subformula
% after these commands can be delimited with "()", "[]" and "\{\}".
%
% The \modu{operator} requires the \pkg{fixdif} package at least
% version 2.0 (file date on or after 2023/01/31).
%
% By the way, if you are used to writing \cs{bm} for a vector but interested in
% \pkg{unicode-math}, the \modu{bm-um} module would be a passable
% alternative to \pkg{bm} package. Notice that the \cs{bm} command from the
% \modu{bm-um} module can only take \emph{one} letter (or \emph{one}
% digit) as its argument.
%
% \subsubsection{Operators}
%
% There's no plan for \pkg{physics3} to support this part of \pkg{physics}
% completely. The syntax in this part of \pkg{physics} (such as "\tan[2](x)")
% abuses \pkg{xparse}.
%
% It's suggested to write like this if you used the \modu{ab} module:
% \begin{quote}
% "$ \sin^2 \ab( \frac{\alpha}{2} ) $"
% \end{quote}
% Rather than take the superscript as an optional argument of the command of
% log-like functions.
%
% The \pkg{physics} package provides a bundle of commands for log-like functions
% that have not been defined in the \LaTeXe\ kernel. They can be used with the
% \modu{operator} module; this module does not support the syntax
% of \pkg{physics} either.
%
% The \cs{Re} and \cs{Im} commands are redefined as operators ``$\Re$'' and
% ``$\Im$'', while $\Resymbol$ and $\Imsymbol$ are reserved as \cs{Resymbol} and
% \cs{Imsymbol}. $\Resymbol$ and $\Imsymbol$ are ordinary symbols but $\Re$ and
% $\Im$ are operators.
%
% \subsubsection{Quick quad text}
%
% All the commands described in \S2.4 of
% \href{http://mirrors.ctan.org/macros/latex/contrib/physics/physics.pdf}^^A
%   {\textsf{physics} documentation} are supported when using
% \modu{qtext.legacy} module. Click here to see the \modu{qtext.legacy} module.
%
% \subsubsection{Derivatives}
%
% There is no plan for \pkg{physics3} to support this part of \pkg{physics}. If
% you want to typeset the differential operators on a better sense, you can try
% the \pkg{fixdif} package; if you want an easy way to type derivatives, you
% can try the \pkg{derivative} package. These two packages can be used
% together. For example,
% \iffalse
%<*example>
% \fi
\begin{example}{3}
% \usepackage{fixdif, derivative}
$ \pdv{f}{x,y,z} \d x $\\[1ex]
Math ($\d x$) v.s.\ Text (\d x)
\end{example}
% \iffalse
%</example>
% \fi
% Here are the documentations of
% \href{http://mirrors.ctan.org/macros/latex/contrib/fixdif/fixdif.pdf}
%   {\pkg{fixdif}} and
% \href{http://mirrors.ctan.org/macros/latex/contrib/derivative/derivative.pdf}
%   {\pkg{derivative}}.
% \pkg{fixdif}'s commands behave better in superscripts and subscripts.
%
% \subsubsection{Dirac bra-ket notation}
%
% There are two solutions to Dirac bra-ket in \pkg{physics3} ---
% \modu{ab.braket} and \modu{braket}. These two modules are \emph{not}
% compatible and neither of them supports \pkg{physics}'s syntax completely.
% Click \hyperlink{para:ab.braket}{\textcolor{cyan}{here}} to see the
% \modu{ab.braket} module and \hyperlink{para:braket}{\textcolor{cyan}{here}}
% to see the \modu{braket} module.
%
% \subsubsection{Matrix macros}
%
% Unfortunately, \pkg{physics3} do not support the \cs{mqty} command from
% \pkg{physics}. If you are used to this command, you can write like this:
% \begin{quote}
% "\newcommand\mqty[1]{\begin{matrix}#1\end{matrix}}"\\
% "\newcommand\pmqty[1]{\begin{pmatrix}#1\end{pmatrix}}"\\
% "$\ab(\mqty{foo})$"  or  "$\pmqty{foo}$"
% \end{quote}
% These are equal to physics's "\mqty(foo)" (require \pkg{amsmath}).
%
% \pkg{physics3}'s \modu{diagmat} module provides \cs{diagmat} command
% for diagonal matrices.
% \cs{pdiagmat}, \cs{bdiagmat}, \cs{Bdiagmat}, \cs{vdiagmat} and \cs{Vdiagmat}
% are also available.
%
% \pkg{physics3}'s \modu{xmat} module provides \cs{xmat} command
% for matrices with formatted entries.
% \cs{pxmat}, \cs{bxmat}, \cs{Bxmat}, \cs{vxmat} and \cs{Vxmat} are
% also available.
% \end{documentation}
% \clearpage
% \begin{implementation}
% \section{Code Implementation}
% \subsection{The \pkg{physics3} package}
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
% We use "phx" as the namespace for \pkg{physics3} modules.
%    \begin{macrocode}
%<@@=phx>
%    \end{macrocode}
%    \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}[2020/10/01]
\def \phx@date    {2026-01-23}
\def \phx@version {v0.1A}
\ProvidesExplPackage {physics3} {2026-01-26} {v0.1A}
  {Tools for typesetting math for physics.}
%    \end{macrocode}
% \subsubsection{Common variables}
% \begin{variable}{\l_@@_tmpa_box}
%   \begin{quote}
%     \cs{phx@temp}\meta{register type}\meta{a or b}
%   \end{quote}
%   Some \LaTeXe\ variables starting with ``"\phx@temp"''.
%   These variables can be shared by any module of \pkg{physics3}.
%    \begin{macrocode}
\box_new:N \l_@@_tmpa_box
%    \end{macrocode}
% \end{variable}
% \subsubsection{Package requirements and module-loading methods}
% \pkg{physics3} requires \pkg{keyval} (part of the graphics bundle) to
% process options of modules.
%    \begin{macrocode}
\RequirePackage{keyval}
\def\phx@true{true}
\def\phx@false{false}
%    \end{macrocode}
% \begin{macro}{\@@_define_key:nnnn, \@@_setkeys:nn, \@@_processkeyopt:n}
%   \begin{quote}
%     \cs{phx@define@key} \marg{module} \marg{key}^^A
%       \oarg{default value} \marg{code}\\
%     \cs{phx@setkeys} \marg{module} \marg{key-val list}\\
%     \cs{phx@processkeyopt} \marg{module}
%   \end{quote}
%   The position of \cs{phx@processkeyopt} in a \pkg{physics3} module is just
%   the same as the position of \cs{ProcessOptions} in a regular
%   \LaTeX\ package.
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_define_key:nnnn #1#2#3#4
  { \define@key {phx-#1} {#2} [#3] {#4} }
\cs_new_nopar:Npn \@@_setkeys:nn     #1#2
  { \setkeys    {phx-#1} {#2}           }
\cs_new:Npn       \@@_processkeyopt:n #1
  {
    \let\reserved@a\@empty
    \edef\reserved@a{\@ptionlist{\@currname.\@currext}}%
    \edef\reserved@a{\noexpand\phx@setkeys{#1}{\reserved@a}}%
    \reserved@a% the next line thanks to `geometry'
    \AtEndOfPackage{\let\@unprocessedoptions\relax}
  }
\cs_set_eq:NN \phx@define@key    \@@_define_key:nnnn
\cs_set_eq:NN \phx@setkeys       \@@_setkeys:nn
\cs_set_eq:NN \phx@processkeyopt \@@_processkeyopt:n
%    \end{macrocode}
% \end{macro}
% We use almost the same way to load \pkg{physics3} modules as \LaTeXe\ kernel
% does. We use a lot of kernel commands in \LaTeXe.
% \begin{macro}{\usephxmodu, \phx@requiremodule}
%   \begin{quote}
%     \cs{usephxmodu} \oarg{key-val options}^^A
%       \marg{module} \oarg{key-val options}\\
%     \cs{phx@requiremodule} \oarg{key-val options}^^A
%       \marg{module} \oarg{key-val options}
%   \end{quote}
%   \cs{usephxmodu} is a user command, and \cs{phx@requiremodule} is a
%   developer command.
%    \begin{macrocode}
\def\usephxmodu{\phx@FWoptions\@pkgextension}
\let\phx@requiremodule\usephxmodu
\@onlypreamble\usephxmodu
\def\phx@FWoptions#1{\@ifnextchar[%]
  {\phx@FW@ptions#1}{\phx@FW@ptions#1[]}}
\@onlypreamble\phx@FWoptions
\def\phx@FW@ptions#1[#2]#3{\@ifnextchar[%]
  {\phx@FW@pti@ns#1[{#2}]#3}{\phx@FW@pti@ns#1[{#2}]#3[]}}
\@onlypreamble\phx@FW@ptions
\def\phx@FW@pti@ns#1[#2]#3[#4]{%
  \def\reserved@b##1,{%
  \ifx\@nnil##1\relax\else
    \ifx\@nnil##1\@nnil\else
      \noexpand\@onefilewithoptions{phx-##1}[{\unexpanded{#2}}][{#4}]%
      \noexpand\@pkgextension
    \fi
    \expandafter\reserved@b
  \fi}%
  \edef\reserved@a{\zap@space#3~\@empty}%
  \edef\reserved@a{\expandafter\reserved@b\reserved@a,\@nnil,}%
  \reserved@a}
\@onlypreamble\phx@FW@pti@ns
%    \end{macrocode}
% \end{macro}
% \subsubsection{The (used to be) \modu{common} module}
% The code below used to be the automatically-loaded \modu{common} module,
% but now we load it together with \pkg{physics3}'s code. This change may
% bring better performance in Windows system.
%
% Check if \pkg{unicode-math} loaded and (re)define the vert symbols.
% The \cs{relax}'s at the ends of \cs{vert} and \cs{Vert}'s definitions must
% not be removed. They are for \cs{ifx} to compare. \pkg{unicode-math} sets
% these symbols \cs{fam}1, \cs{symoperators} is equal to 1 in \LaTeXe\ kernel.
% Moreover, we make \cs{mid} as a delimiter but it may not work.
%    \begin{macrocode}
\AtBeginDocument{\ifcsname symrm\endcsname
  \protected\def\|{\Udelimiter 0 \symoperators "2016 }%
  \protected\def\vert{\Udelimiter 0 \symoperators "007C\relax}%
  \protected\def\Vert{\Udelimiter 0 \symoperators "2016\relax}%
  \protected\def\mid{\Udelimiter 3 \symoperators "007C }%
\fi}
\protected\def\Vert{\delimiter"026B30D\relax}
\protected\def\mid{\delimiter"326A30C }
%    \end{macrocode}
% \begin{macro}{\delopen, \delclose}
%   \begin{quote}
%     \cs{delopen} \meta{left delimiter}\\
%     \cs{delclose} \meta{right delimiter}
%   \end{quote}
%   Actually in \TeX, \cs{left} and \cs{right} will enclose the subformula as
%   ``inner'', but \cs{delopen} and \cs{delclose} will make the subformula an
%   empty open node and a non-empty close node.
%    \begin{macrocode}
\DeclareRobustCommand\delopen{\mathopen{}\mathclose\bgroup\left}
\DeclareRobustCommand\delclose{\aftergroup\egroup\right}
% Extension to 2e kernel's or amsmath's biggggg commands.
%    \end{macrocode}
% \end{macro}
% \cs{bBigg@} is a command from \pkg{amsmath}. The code below should
% update with \pkg{amsmath} together.
%    \begin{macrocode}
\ifdefined\bBigg@
  \DeclareRobustCommand\biggg{\bBigg@{3}}
  \DeclareRobustCommand\Biggg{\bBigg@{3.5}}
\else
  \DeclareRobustCommand\biggg[1]{\leavevmode@ifvmode
    {\hbox{$\left#1\vbox to20.5\p@{}\right.\n@space$}}}
  \DeclareRobustCommand\Biggg[1]{\leavevmode@ifvmode
    {\hbox{$\left#1\vbox to23.5\p@{}\right.\n@space$}}}
  \AtBeginDocument{\ifdefined\bBigg@
    \DeclareRobustCommand\biggg{\bBigg@{3}}%
    \DeclareRobustCommand\Biggg{\bBigg@{3.5}}%
  \fi}
\fi
\DeclareRobustCommand\bigggl{\mathopen\biggg}
\DeclareRobustCommand\bigggm{\mathrel\biggg}
\DeclareRobustCommand\bigggr{\mathclose\biggg}
\DeclareRobustCommand\Bigggl{\mathopen\Biggg}
\DeclareRobustCommand\Bigggm{\mathrel\Biggg}
\DeclareRobustCommand\Bigggr{\mathclose\Biggg}
%    \end{macrocode}
% \begin{macro}{\@@_mathvphantom:n}
%   \begin{quote}
%     \cs{phx@mathvphantom} \marg{math mode material}
%   \end{quote}
%   This command is just like \cs{vphantom} in \LaTeXe\ kernel but only works
%   in math mode.
%    \begin{macrocode}
\cs_new:Npn \@@_mathvphantom:n #1
  {
    \hbox_set:Nn \l_@@_tmpa_box {}
    \tex_mathchoice:D
      {
        \hbox_set:Nn    \l_tmpa_box    { $\displaystyle#1$ }
        \box_set_ht:Nn  \l_@@_tmpa_box { \box_ht:N \l_tmpa_box }
        \box_set_dp:Nn  \l_@@_tmpa_box { \box_dp:N \l_tmpa_box }
        \box_use_drop:N \l_@@_tmpa_box
      }
      {
        \hbox_set:Nn    \l_tmpa_box    { $\textstyle#1$ }
        \box_set_ht:Nn  \l_@@_tmpa_box { \box_ht:N \l_tmpa_box }
        \box_set_dp:Nn  \l_@@_tmpa_box { \box_dp:N \l_tmpa_box }
        \box_use_drop:N \l_@@_tmpa_box
      }
      {
        \hbox_set:Nn    \l_tmpa_box    { $\scriptstyle#1$ }
        \box_set_ht:Nn  \l_@@_tmpa_box { \box_ht:N \l_tmpa_box }
        \box_set_dp:Nn  \l_@@_tmpa_box { \box_dp:N \l_tmpa_box }
        \box_use_drop:N \l_@@_tmpa_box
      }
      {
        \hbox_set:Nn    \l_tmpa_box    { $\scriptscriptstyle#1$ }
        \box_set_ht:Nn  \l_@@_tmpa_box { \box_ht:N \l_tmpa_box }
        \box_set_dp:Nn  \l_@@_tmpa_box { \box_dp:N \l_tmpa_box }
        \box_use_drop:N \l_@@_tmpa_box
      }
  }
\cs_set_eq:NN \phx@mathvphantom \@@_mathvphantom:n
%    \end{macrocode}
% \end{macro}
% \subsubsection{The (used to be) \modu{explsetup} module}
% \begin{variable}{\l_@@_tmpa_tl, \l_@@_tmpb_tl}
% Some common variables and functions for experimental \LaTeX3 syntax.
%    \begin{macrocode}
\tl_new:N \l_@@_tmpa_tl
\tl_new:N \l_@@_tmpb_tl
%    \end{macrocode}
% \end{variable}
% The function that can gobble one token.
%    \begin{macrocode}
\cs_new:Npn \_@@_gobble_i:n #1 { }
%    \end{macrocode}
%    \begin{macrocode}
\file_input_stop:
%    \end{macrocode}
%    \begin{macrocode}
%</package>
%    \end{macrocode}
% Temporally disable the namespace.
%    \begin{macrocode}
%<@@=>
%    \end{macrocode}
% \subsection{The \modu{ab} module}
% \begingroup\color{gray}%
% \noindent$\langle*\hbox{\sffamily gibberish}\rangle$\par
% This module is important but the code is hard to read. One of the motivations
% I manage \pkg{physics3} with \pkg{DocStrip} is that, when I tried to write a
% new module based on \modu{ab} after 5 months when I maintained \pkg{physics3}
% the last time, I found that I could not understand the code I wrote at all!
% Therefore, it's significant to comment out the alien code in \modu{ab}.\par
% \noindent$\langle/\hbox{\sffamily gibberish}\rangle$\par
% \endgroup
%    \begin{macrocode}
%<*ab>
\ProvidesFile {phx-ab.sty}
  [\phx@date\ `ab' (autobraces) module of physics3]
%    \end{macrocode}
% If you don't know when to use \cs{phx@define@key}, \cs{phx@setkeys} and
% \cs{phx@processkeyopt} in a module, see ahead. In \modu{ab}, the |tightbraces|
% option can control if the automatically-sized braces are tight or not. Do you
% remember \cs{delopen} and \cs{delclose}?
%    \begin{macrocode}
\phx@define@key{ab}{tightbraces}{true}{\def\@phx@abtight{#1}}
\phx@setkeys{ab}{tightbraces=true}
\phx@processkeyopt{ab}
%    \end{macrocode}
% \begin{macro}[int]{\phx@abopen, \phx@abclose}
%   \begin{quote}
%     \cs{phx@abopen} \meta{left delimiter}\\
%     \cs{phx@abclose} \meta{right delimiter}
%   \end{quote}
%   They are defined either \{\cs{delopen}, \cs{delclose}\} or
%   \{\cs{left}, \cs{right}\}. If a module requires \modu{ab},
%   these two commands are likely to be used.
%    \begin{macrocode}
\ifx\@phx@abtight\phx@true
  \let\phx@abopen\delopen
  \let\phx@abclose\delclose
\else
  \let\phx@abopen\left
  \let\phx@abclose\right
\fi
%    \end{macrocode}
% \end{macro}
% \subsubsection{The implementation of \cs{ab}}
% This is the alienest part of \modu{ab}. It's better to draw something rather
% than write boring comments. First let's take a look at \cs{ab}'s syntax.
% After \cs{ab} should be a pair of delimiters; take \texttt{()} as an example.
% Between \cs{ab} and ``\texttt{(}'' can be a biggg command or star, or even
% nothing. \cs{ab} is defined as follows:
% \[ \macrodef{ab}{\cs{phx@d@lx} \texttt{\{mb\}} \texttt{\{ab\}}} \]
% where \texttt{ab} is the branch name of "\ab()", and \texttt{mb} is the branch
% name of "\ab\big()" and "\ab*()". Then let's see the syntax of \cs{phx@d@lx}.
% \begin{quote}
%   \cs{phx@d@lx} \marg{biggg or star branch name}\\
%     \marg{automatic branch name} "{#3}"
% \end{quote}
% Here exists an \texttt{\#3}. \texttt{\#3} is one token immediately following
% \cs{ab}, which can be \{\,a biggg command or a star\,\} or a ``\texttt{(}'',
% under our assumption.
%
% \cs{phx@d@lx} is defined as follows:
% \[
%   \macrodef {phx@d@lx} [
%     \#1: biggg or star branch name, \meta{mb};
%     \#2: automatic branch name, \meta{ab};
%     \#3, the token after \cs{ab} ]
%     {%
%       \macroifelse {\#3 == biggg or \#3 == star
%         ($\Leftrightarrow$ csname \{phx@del\cs{string}\#3\} is defined)}
%         {let \meta{next cs} = csname \{phx@d@lx\meta{mb}\}}
%         {let \meta{next cs} = csname \{phx@d@lx\meta{ab}\}}
%       \meta{next cs} \#3
%     }
% \]
% The condition should be true when \#3 is "\big" or "*", and it should be
% false when \#3 is ``"("''. Accordingly, in math mode,
% \begin{align*}
%   \hbox{\cs{ab} \cs{big} "("}           & \quad \to \quad
%   \hbox{\cs{phx@d@lxmb} \cs{big} "("}   \\
%   \hbox{\cs{ab} \phantom{\cs{big}} "("} & \quad \to \quad
%   \hbox{\cs{phx@d@lxab} \phantom{\cs{big}} "("}
% \end{align*}
% Then we meet two new commands --- \cs{phx@d@lxmb} and \cs{phx@d@lxab}. Syntax
% is as follows.
% \begin{quote}
%   \cs{phx@d@lxmb} \meta{biggg or *}            \meta{left delimiter}\\
%   "   "\meta{subformula} \meta{right delimiter} \\
%    \cs{phx@d@lxab} \phantom{\meta{biggg or *}} \meta{left delimiter}\\
%   "   "\meta{subformula} \meta{right delimiter}
% \end{quote}
% Notice that \texttt{ab} and \texttt{mb} in the above commands are names of
% \cs{ab}'s two branches --- they are like namespaces. \cs{phx@d@lxmb} and
% \cs{phx@d@lxab} are defined by the following two lines:
% \begin{quote}
%   "\phx@d@l@genxm{mb}"
%   "\phx@d@l@genxa{ab}"
% \end{quote}
% \cs{phx@d@l@genxm} and \cs{phx@d@l@genxa} are defined as follows:
% \begin{align*}
%   & \macrodef {phx@d@l@genxm} [\#1: biggg or star branch name, \meta{mb}]
%     {%
%       \macrodef [12\ttwd] {phx@d@lx\meta{mb}}
%         [\#\#1: biggg or star; \#\#2: left delimiter]
%         {%
%           \cs{begingroup}
%           \macroifelse {\#\#1 == star}
%             {\meta{temp} $\gets$ \cs{relax}}
%             {\meta{temp} $\gets$ \#\#1}
%           csname \{phx@\meta{mb}@\cs{string}\#\#2\} \meta{temp} \#\#2 \macrocr
%           \% requires an \cs{endgroup} after the right delimiter
%         }
%     } \\[1ex]
%     & \macrodef {phx@d@l@genxa} [\#1: automatic branch name, \meta{ab}]
%     {%
%       \macrodef [12\ttwd] {phx@d@lx\meta{ab}} [\#\#1: left delimiter]
%         {%
%           csname \{phx@\meta{ab}@\cs{string}\#\#1\} \#\#1
%         }
%     }
% \end{align*}
% So we can get
% \begin{align*}
%   \hbox{\ttfamily\cs{ab} \cs{big} (}&\quad\to\quad
%   \hbox{\cs{begingroup} csname \{phx@mb@(\} \cs{big}\hskip2\ttwd\ \texttt(}\\
%   \hbox{\ttfamily\cs{ab} *\phantom{big} (}&\quad\to\quad
%   \hbox{\cs{begingroup} csname \{phx@mb@(\} \cs{relax} \texttt(}\\
%   \hbox{\ttfamily\cs{ab} \phantom{\cs{big}} (}&\quad\to\quad
%   \hbox{\hskip11\ttwd\ csname \{phx@ab@(\} \texttt(}
% \end{align*}
% The csnames above (\cs{phx@mb@(} and \cs{phx@ab@(}) are generated
% with \cs{phx@AB@gen}.
% \begin{quote}
%   \cs{phx@AB@gen} \marg{branch name} \meta{left delimiter}\\
%   "  "\marg{arg spec} \marg{definition}
% \end{quote}
% If \meta{branch name} is \texttt{mb}, \marg{arg spec} should be "mr()",
% where "m" is for biggg or star;
% If \meta{branch name} is \texttt{ab}, \marg{arg spec} should be "r()".
% \begin{texnote}
% The ``"("'' in the example above must not be replaced by a subformula braced
% by a pair of "{}".
% \end{texnote}
% \begin{macro}[int]{\phx@AB@gen}
%   \begin{quote}
%     \cs{phx@AB@gen} \marg{branch name} \meta{left delimiter}\\
%     "  "\marg{arg spec} \marg{definition}
%   \end{quote}
%    \begin{macrocode}
\def\phx@AB@gen#1#2{\expandafter
  \DeclareDocumentCommand\csname phx@#1@\string#2\endcsname}
    \phx@AB@gen{ab}({r()}%
      {\phx@abopen(#1\phx@abclose)}
    \phx@AB@gen{ab}[{r[]}%
      {\phx@abopen[#1\phx@abclose]}
    \phx@AB@gen{ab}\{{r\{\}}%
      {\phx@abopen\{#1\phx@abclose\}}
    \phx@AB@gen{ab}|{r||}%
      {\phx@abopen|#1\phx@abclose|}
    \phx@AB@gen{ab}\|{r\|\|}%
      {\phx@abopen\|#1\phx@abclose\|}
    \phx@AB@gen{ab}<{r<>}%
      {\phx@abopen<#1\phx@abclose>}
    \phx@AB@gen{ab}\lbrace{r\lbrace\rbrace}%
      {\phx@abopen\lbrace#1\phx@abclose\rbrace}
    \phx@AB@gen{ab}\vert{r\vert\vert}%
      {\phx@abopen\vert#1\phx@abclose\vert}
    \phx@AB@gen{ab}\Vert{r\Vert\Vert}%
      {\phx@abopen\Vert#1\phx@abclose\Vert}
    \phx@AB@gen{ab}\langle{r\langle\rangle}%
      {\phx@abopen\langle#1\phx@abclose\rangle}
%    \end{macrocode}
% \cs{endgroup}'s in the end of the following definitions are corresponding to
% \cs{begingroup}'s in the definition of \cs{phx@d@l@genxm}.
%    \begin{macrocode}
\phx@AB@gen{mb}({mr()}%
  {\mathopen#1(#2\mathclose#1)\endgroup}
\phx@AB@gen{mb}[{mr[]}%
  {\mathopen#1[#2\mathclose#1]\endgroup}
\phx@AB@gen{mb}\{{mr\{\}}%
  {\mathopen#1\lbrace#2\mathclose#1\rbrace\endgroup}
\phx@AB@gen{mb}|{mr||}%
  {\mathopen#1\vert#2\mathclose#1\vert\endgroup}
\phx@AB@gen{mb}\|{mr\|\|}%
  {\mathopen#1\Vert#2\mathclose#1\Vert\endgroup}
\phx@AB@gen{mb}<{mr<>}%
  {\mathopen#1\langle#2\mathclose#1\rangle\endgroup}
\phx@AB@gen{mb}\lbrace{mr\lbrace\rbrace}%
  {\mathopen#1\lbrace#2\mathclose#1\rbrace\endgroup}
\phx@AB@gen{mb}\vert{mr\vert\vert}%
  {\mathopen#1\vert#2\mathclose#1\vert\endgroup}
\phx@AB@gen{mb}\Vert{mr\Vert\Vert}%
  {\mathopen#1\Vert#2\mathclose#1\Vert\endgroup}
\phx@AB@gen{mb}\langle{mr\langle\rangle}%
  {\mathopen#1\langle#2\mathclose#1\rangle\endgroup}
%    \end{macrocode}
% \end{macro}
% \begin{macro}[int]{\phx@del}
%   The syntax seems not important. These following lines seems only
%   for \cs{ifcsname} to judge if the commands are defined.
%    \begin{macrocode}
\def\phx@del#1#2#3{\phx@abopen#1#3\phx@abclose#2}
\expandafter\def\csname phx@del\string*\endcsname
  #1#2#3{\mathopen#1#3\mathclose#2}
\expandafter\def\csname phx@del\string\big\endcsname
  #1#2#3{\bigl#1#3\bigr#2}
\expandafter\def\csname phx@del\string\Big\endcsname
  #1#2#3{\Bigl#1#3\Bigr#2}
\expandafter\def\csname phx@del\string\bigg\endcsname
  #1#2#3{\biggl#1#3\biggr#2}
\expandafter\def\csname phx@del\string\Bigg\endcsname
  #1#2#3{\Biggl#1#3\Biggr#2}
\expandafter\def\csname phx@del\string\biggg\endcsname
  #1#2#3{\bigggl#1#3\bigggr#2}
\expandafter\def\csname phx@del\string\Biggg\endcsname
  #1#2#3{\Bigggl#1#3\Bigggr#2}
%    \end{macrocode}
% \end{macro}
% \begin{macro}[int]{\phx@d@lx}
%   \begin{quote}
%     \cs{phx@d@lx} \marg{biggg or star branch name} \marg{automatic branch name} "{#3}"
%   \end{quote}
%    \begin{macrocode}
\def\phx@d@lx#1#2#3{%
  \ifcsname phx@del\string#3\endcsname
    \def\reserved@a{#1}% #3 is star or \biggg
  \else
    \def\reserved@a{#2}% #3 is delimiter
  \fi
  \csname phx@d@lx\reserved@a\endcsname#3}
%    \end{macrocode}
% \end{macro}
% \begin{macro}[int]{\phx@d@l@genxm, \phx@d@l@genxa}
%   \begin{quote}
%     \cs{phx@d@l@genxm} \marg{biggg or star branch name}\\
%     \cs{phx@d@l@genxa} \marg{automatic branch name}
%   \end{quote}
%    \begin{macrocode}
\def\phx@d@l@genxm#1{%
  \expandafter\def\csname phx@d@lx#1\endcsname##1##2{%
    \begingroup % \endgroup is at the end of #4 of \phx@AB@gen
    \ifx##1*\let\phx@tempa=\relax\else\let\phx@tempa=##1\fi
    \csname phx@#1@\string##2\endcsname\phx@tempa##2}}
\def\phx@d@l@genxa#1{%
  \expandafter\def\csname phx@d@lx#1\endcsname##1{%
    \csname phx@#1@\string##1\endcsname##1}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}[int]{\phx@d@lxmb, \phx@d@lxab}
%   \begin{quote}
%     \cs{phx@d@lxmb} \meta{biggg or *} \meta{left delimiter}\\
%     "  "\meta{subformula} \meta{right delimiter}\\
%     \cs{phx@d@lxab} \phantom{\meta{biggg or *}} \meta{left delimiter}\\
%     "  "\meta{subformula} \meta{right delimiter}
%   \end{quote}
%    \begin{macrocode}
\phx@d@l@genxm{mb}
\phx@d@l@genxa{ab}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\ab}
%   The users' command \cs{ab}.
%    \begin{macrocode}
\DeclareRobustCommand\ab{\phx@d@lx{mb}{ab}}
%    \end{macrocode}
% \end{macro}
% \subsubsection{\cs{pab}-like commands}
% This is so simple. No need to comment a lot.
% \begin{macro}[int]{\phx@d@l@geny}
%   \begin{quote}
%     \cs{phx@d@l@geny} \meta{command} \meta{left delimiter} \meta{right delimiter}
%   \end{quote}
%   This command used to define commands like \cs{pab}.
%    \begin{macrocode}
\def\phx@d@l@geny#1#2#3{%
%    \end{macrocode}
% \begin{multicols}{3}
% \begin{arguments}
%   \item star;
%   \item bigg (csname);
%   \item subformula.
% \end{arguments}
% \end{multicols}
%    \begin{macrocode}
  \DeclareDocumentCommand#1{som}{
    \IfBooleanTF{##1}%
      {#2##3#3}%
      {\IfValueTF{##2}%
        {\csname##2l\endcsname#2##3\csname##2r\endcsname#3}%
        {\phx@abopen#2##3\phx@abclose#3}%
      }%
  }%
}
\phx@d@l@geny\pab()
\phx@d@l@geny\bab[]
\phx@d@l@geny\Bab\lbrace\rbrace
\phx@d@l@geny\vab\vert\vert
\phx@d@l@geny\aab\langle\rangle
\phx@d@l@geny\Vab\Vert\Vert
%    \end{macrocode}
%    \begin{macrocode}
\protect \endinput
%    \end{macrocode}
%    \begin{macrocode}
%</ab>
%    \end{macrocode}
% \end{macro}
% \subsection{The \modu{ab.braket} module}
%    \begin{macrocode}
%<*ab.braket>
\ProvidesFile {phx-ab.braket.sty}
  [\phx@date\ `ab.braket' module of physics3]
%    \end{macrocode}
% This module requires \cs{phx@abopen} and \cs{phx@abclose} from \modu{ab}.
% This module may have conflict with \modu{braket}.
%    \begin{macrocode}
\phx@requiremodule{ab}
\ifdefined\phx@bra@@
  \PackageWarning{physics3}{You cannot load `ab.braket' and `braket'
    modules together.\MessageBreak Only `ab.braket' module works now.}
\fi
%    \end{macrocode}
% \begin{macro}{\bra}
%   \begin{quote}
%     \cs{bra} \char`\<\ \meta{subformula} \char`\|
%   \end{quote}
% \end{macro}
%    \begin{macrocode}
\phx@AB@gen{br.m}<{mr<|}{\mathopen#1\langle#2\mathclose#1\vert\endgroup}
\phx@AB@gen{br.a}<{r<|}{\phx@abopen\langle#1\phx@abclose\vert}
\phx@d@l@genxm{br.m}
\phx@d@l@genxa{br.a}
\DeclareRobustCommand\bra{\phx@d@lx{br.m}{br.a}}
%    \end{macrocode}
% \begin{macro}{\ket}
%   \begin{quote}
%     \cs{ket} \char`\|\ \meta{subformula} \char`\>
%   \end{quote}
% \end{macro}
%    \begin{macrocode}
\phx@AB@gen{kt.m}|{mr|>}{\mathopen#1\vert#2\mathclose#1\rangle\endgroup}
\phx@AB@gen{kt.a}|{r|>}{\phx@abopen\vert#1\phx@abclose\rangle}
\phx@d@l@genxm{kt.m}
\phx@d@l@genxa{kt.a}
\DeclareRobustCommand\ket{\phx@d@lx{kt.m}{kt.a}}
%    \end{macrocode}
% \begin{macro}{\braket}
%   \begin{quote}
%     \cs{braket} \char`\<\ \meta{subformula 1} \char`\|\ \meta{subformula 2} {\color{gray}\textrm{[}\char`\|\ \meta{subformula 3} \textrm{\dots]}} \char`\>
%   \end{quote}
%    \begin{macrocode}
\begingroup
\catcode`\|=\active
\gdef\phx@@mb@bk#1#2{\begingroup
  \mathcode`\|="8000\def|{\egroup#1\vert\bgroup}%
  \def\<{\mathrel{<}}\def\>{\mathrel{>}}%
  \mathopen#1\langle\bgroup#2\egroup\mathclose#1\rangle\endgroup}
\gdef\phx@@ab@bk#1{\begingroup
  \mathcode`\|="8000\def|{\egroup\phx@abb@bkv\bgroup}%
  \def\<{\mathrel{<}}\def\>{\mathrel{>}}%
  \phx@abopen\langle\bgroup#1\egroup\phx@abclose\rangle\endgroup}
\endgroup
\def\phx@abb@bkv{\middle\vert}
\phx@AB@gen{bk.m}<{mr<>}{\phx@@mb@bk#1{#2}\endgroup}
\phx@AB@gen{bk.a}<{r<>}{\phx@@ab@bk{#1}}
\phx@d@l@genxm{bk.m}
\phx@d@l@genxa{bk.a}
\DeclareRobustCommand \braket {\phx@d@lx{bk.m}{bk.a}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\ketbra}
%   \begin{quote}
%     \cs{braket} \char`\|\ \meta{subformula 1} \char`\>\ \meta{subformula 2} \char`\<\ \meta{subformula 3} \char`\|
%   \end{quote}
%    \begin{macrocode}
\begingroup
\catcode`\<=\active
\catcode`\>=\active
\gdef\phx@@mb@kb#1#2{\begingroup
  \mathcode`\<="8000 \mathcode`\>="8000%
  \def<{#1\langle}\def>{#1\rangle}%
  \def\<{\phx@abb@l}\def\>{\phx@abb@r}%
  \mathopen#1\vert#2\mathclose#1\vert\endgroup}
\endgroup
\gdef\phx@@ab@kb#1>#2<#3\phx@@end{\begingroup
  \def\<{\phx@abb@l}\def\>{\phx@abb@r}%
  \phx@abopen\vert\mathopen{\phx@mathvphantom{#3}}#1\phx@abclose\rangle#2%
  \phx@abopen\langle#3\mathclose{\phx@mathvphantom{#1}}\phx@abclose\vert
\endgroup}
\AtBeginDocument{\ifcsname symbf\endcsname
  \def\phx@abb@l{\Umathchar 3 \symoperators "003C }%
  \def\phx@abb@r{\Umathchar 3 \symoperators "003E }%
\fi}
\def\phx@abb@l{\mathchar"313C }
\def\phx@abb@r{\mathchar"313E }
\phx@AB@gen{kb.m}|{mr||}{\phx@@mb@kb#1{#2}\endgroup}
\phx@AB@gen{kb.a}|{r||}{\phx@@ab@kb#1\phx@@end}
\phx@d@l@genxm{kb.m}
\phx@d@l@genxa{kb.a}
\DeclareRobustCommand \ketbra {\phx@d@lx{kb.m}{kb.a}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bknorm, \kbproj, \expval}
% Define some high-level commands for inner product, outer product of basis
% and expectation value.
%    \begin{macrocode}
\DeclareDocumentCommand \bknorm { s o m }
  {%
    \IfBooleanTF{#1} {\mathopen\langle#3\vert #3\mathclose\rangle}
      {%
        \IfValueTF{#2}
          {\expanded{\noexpand\phx@d@lx{bk.m}{bk.a}%
            \expandafter\noexpand\csname #2\endcsname}<#3|#3>}
          {\phx@d@lx{bk.m}{bk.a}<#3|#3>}%
      }%
  }
\DeclareDocumentCommand \kbproj { s o m }
  {%
    \IfBooleanTF{#1}
      {%
        \mathopen\vert#3\mathclose\rangle
        \mathopen\langle#3\mathclose\vert
      }
      {%
        \IfValueTF{#2}
          {\expanded{\noexpand\phx@d@lx{kb.m}{kb.a}%
            \expandafter\noexpand\csname #2\endcsname}|#3><#3|}
          {\phx@d@lx{kb.m}{kb.a}|#3><#3|}%
      }%
  }
%    \end{macrocode}
% Parsing the optional argument of \cs{expval}.
%    \begin{macrocode}
\def\@phx@ev@do@pt#1,{\ifx#1\relax\@empty\else
  \edef\reserved@a{\zap@space#1 \@empty}%
  \ifx\reserved@a\@empty\else
    \ifcsname phx@del\expandafter\expandafter\expandafter
    \expandafter\expandafter\expandafter\expandafter
    \expandafter\expandafter\expandafter\expandafter
    \expandafter\expandafter\expandafter\expandafter \string
    \expandafter\expandafter\expandafter\expandafter
    \expandafter\expandafter\expandafter \csname
    \expandafter\expandafter\expandafter \detokenize
    \expandafter{\reserved@a}\endcsname \endcsname
      \xdef\@phx@ev{\reserved@a}%
    \else
      \xdef\@phx@ev@basis{%
        \reserved@a}%
    \fi
  \fi
  \expandafter\@phx@ev@do@pt\fi}
\def\phx@ev@doopt#1{%
  \edef\@phx@ev{\@empty}\edef\@phx@ev@basis{\@empty}\@phx@ev@do@pt#1,\relax,}
\DeclareDocumentCommand \expval { s o m }
  {%
    \phx@ev@doopt{#2}%
    \IfValueTF {#2}
      {%
        \ifx\@phx@ev\@empty
          \ifx \@phx@ev@basis\@empty \else
          \IfBooleanTF{#1}
            {\phx@d@lx{bk.m}{bk.a}*<\@phx@ev@basis|#3|\@phx@ev@basis>}
            {\phx@d@lx{bk.m}{bk.a}<\@phx@ev@basis |#3|\@phx@ev@basis>}%
          \fi
        \else
          \ifx\@phx@ev@basis\@empty
            \IfBooleanTF{#1} {\phx@d@lx{bk.m}{bk.a}*<#3>}
              {%
                \expanded{%
                  \noexpand \phx@d@lx{bk.m}{bk.a}\expandafter \noexpand
                  \csname \@phx@ev\endcsname}<#3>%
              }%
          \else
            \IfBooleanTF{#1}
              {%
                \phx@d@lx{bk.m}{bk.a}*<\@phx@ev@basis|#3|\@phx@ev@basis>%
              }
              {%
                \expanded{%
                  \noexpand \phx@d@lx{bk.m}{bk.a}\expandafter
                  \noexpand \csname \@phx@ev\endcsname}%
                <\@phx@ev@basis|#3|\@phx@ev@basis>%
              }%
          \fi
        \fi
      }
      {%
        \IfBooleanTF{#1}
          {\phx@d@lx{bk.m}{bk.a}*<#3>} {\phx@d@lx{bk.m}{bk.a}<#3>}%
      }%
  }
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\protect \endinput
%    \end{macrocode}
%    \begin{macrocode}
%</ab.braket>
%    \end{macrocode}
% \subsection{The \modu{braket} module}
%    \begin{macrocode}
%<*braket>
\ProvidesFile {phx-braket.sty}
  [\phx@date\ `braket' module of physics3]
%    \end{macrocode}
% This module requires \cs{phx@abopen} and \cs{phx@abclose} from \modu{ab}.
% This module may have conflict with \modu{ab.braket}.
%    \begin{macrocode}
\phx@requiremodule{ab}
\ifdefined\phx@abb@bkv
  \PackageWarning{physics3}{You cannot load `ab.braket' and `braket'
    modules together.\MessageBreak Only `braket' module works now.}
\fi
%    \end{macrocode}
% \begin{macro}{\bra}
%   \begin{quote}
%     \cs{bra} * \oarg{biggg} \marg{subformula}
%   \end{quote}
%    \begin{macrocode}
\DeclareDocumentCommand\bra{ s o m }{%
  \IfBooleanTF{#1}
    {\mathopen\langle#3\mathclose\vert}
    {\IfValueTF{#2}
      {\csname#2l\endcsname\langle#3\csname#2r\endcsname\vert}
      {\phx@abopen\langle#3\phx@abclose\vert}%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\ket}
%   \begin{quote}
%     \cs{ket} * \oarg{biggg} \marg{subformula}
%   \end{quote}
%    \begin{macrocode}
\DeclareDocumentCommand\ket{ s o m }{%
  \IfBooleanTF{#1}
    {\mathopen\vert#3\mathclose\rangle}
    {\IfValueTF{#2}
      {\csname#2l\endcsname\vert#3\csname#2r\endcsname\rangle}
      {\phx@abopen\vert#3\phx@abclose\rangle}%
    }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\braket}
%   \begin{quote}
%     \cs{ket} * [\meta{biggg}, $n \in \{1,2,3\}$] \marg{subformula 1} \dots \marg{subformula $n$}
%   \end{quote}
%    \begin{macrocode}
\DeclareDocumentCommand \braket { s O{} }
  {%
    \IfBooleanTF{#1}
      {%
        \gdef\@phx@bk@argnum{ii}%
        \phx@bk@doopt{#2}%
        \gdef\@phx@bk@l{mathopen}%
        \gdef\@phx@bk@m{mathord}%
        \gdef\@phx@bk@r{mathclose}%
      }
      {%
        \gdef\@phx@bk@argnum{ii}%
        \gdef\@phx@bk@l{phx@abopen}%
        \gdef\@phx@bk@m{middle}%
        \gdef\@phx@bk@r{phx@abclose}%
        \phx@bk@doopt{#2}%
      }%
    \csname phx@bk@in@\@phx@bk@argnum\endcsname
  }
%    \end{macrocode}
% \end{macro}
% \begin{macro}[int]{\phx@bk@in@i, \phx@bk@in@ii, \phx@bk@in@iii}
%   \begin{quote}
%     \cs{phx@bk@in@\meta{n.roman}} \marg{subformula 1} \dots \marg{subformula $n$}
%   \end{quote}
%   \meta{n.roman} is $n$ in roman lowercase, where $n \in \{1,2,3\}$.
%    \begin{macrocode}
\def\phx@bk@in@i#1{%
  \csname\@phx@bk@l\endcsname\langle{#1}%
  \csname\@phx@bk@r\endcsname\rangle}
\def\phx@bk@in@ii#1#2{%
  \csname\@phx@bk@l\endcsname\langle{#1}%
  \csname\@phx@bk@m\endcsname\vert{#2}%
  \csname\@phx@bk@r\endcsname\rangle}
\def\phx@bk@in@iii#1#2#3{%
  \csname\@phx@bk@l\endcsname\langle{#1}%
  \csname\@phx@bk@m\endcsname\vert{#2}%
  \csname\@phx@bk@m\endcsname\vert{#3}%
  \csname\@phx@bk@r\endcsname\rangle}
%    \end{macrocode}
% \end{macro}
% \begin{macro}[int]{\phx@bk@doopt, \phx@bk@do@pt}
%   \begin{quote}
%     \cs{phx@bk@doopt} \marg{clist}
%   \end{quote}
%   Parse the optional argument of \cs{braket}. This will add 3 entries to hash.
%    \begin{macrocode}
\def\@phx@bk@do@pt#1,{\ifx#1\relax\@empty\else
  \edef\reserved@a{\zap@space#1 \@empty}%
  \ifx\reserved@a\@empty\else
    \ifcsname phx@del\expandafter\string\csname\reserved@a\endcsname\endcsname
      \xdef\@phx@bk@l{\reserved@a l}%
      \xdef\@phx@bk@m{\reserved@a}% but not m (m stands for \mathrel)
      \xdef\@phx@bk@r{\reserved@a r}%
    \else
      \ifnum\reserved@a>3%
        \PackageError{physics3}{\string\braket\space can only take 3
          mandatory arguments at most}{Check if you had written a number
          more than 3 in the [optional] argument.}%
      \fi
      \xdef\@phx@bk@argnum{\romannumeral\reserved@a}%
    \fi
  \fi
  \expandafter\@phx@bk@do@pt\fi}
\def\phx@bk@doopt#1{\@phx@bk@do@pt#1,\relax,}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\ketbra}
%   \begin{quote}
%     \cs{ketbra} * [\meta{biggg}] \marg{subformula 1}\\
%     "  "\oarg{between 1 and 2} \marg{subformula 2}
%   \end{quote}
%    \begin{macrocode}
\DeclareDocumentCommand \ketbra { s o m O{} m }
  {%
    \IfBooleanTF{#1}
      {%
        \mathopen\vert#3\mathclose\rangle#4%
        \mathopen\langle#5\mathclose\vert
      }
      {%
        \IfValueTF{#2}
          {\csname#2l\endcsname\vert#3\csname#2r\endcsname\rangle#4%
            \csname#2l\endcsname\langle#5\csname#2r\endcsname\vert}
          {\begingroup
            \phx@abopen\vert
              \mathopen{\phx@mathvphantom{#5}}#3\phx@abclose\rangle#4%
            \phx@abopen\langle#5
              \mathclose{\phx@mathvphantom{#3}}\phx@abclose\vert
          \endgroup}%
      }%
  }
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\bknorm, \kbproj, \expval}
% Define some high-level commands for inner product, outer product of basis
% and expectation value.
%    \begin{macrocode}
\DeclareDocumentCommand \bknorm { s o m }
  {%
    \IfBooleanTF{#1}
      {%
        \gdef\@phx@bk@l{mathopen}%
        \gdef\@phx@bk@m{mathord}%
        \gdef\@phx@bk@r{mathclose}%
      }
      {%
        \gdef\@phx@bk@l{phx@abopen}%
        \gdef\@phx@bk@m{middle}%
        \gdef\@phx@bk@r{phx@abclose}%
        \IfValueT{#2}
          {%
            \ifcsname phx@del\expandafter\string\csname#2\endcsname\endcsname
              \xdef\@phx@bk@l{#2l}%
              \xdef\@phx@bk@m{#2}%
              \xdef\@phx@bk@r{#2r}%
            \fi
          }%
      }%
    \phx@bk@in@ii {#3} {#3}%
  }
\DeclareDocumentCommand \kbproj { s o m }
  {%
    \IfBooleanTF{#1}
      {%
        \mathopen\vert#3\mathclose\rangle
        \mathopen\langle#3\mathclose\vert
      }
      {%
        \IfValueTF{#2}
          {\csname#2l\endcsname\vert#3\csname#2r\endcsname\rangle
            \csname#2l\endcsname\langle#3\csname#2r\endcsname\vert}
          {\begingroup
            \phx@abopen\vert
              \mathopen{\phx@mathvphantom{#3}}#3\phx@abclose\rangle
            \phx@abopen\langle#3
              \mathclose{\phx@mathvphantom{#3}}\phx@abclose\vert
          \endgroup}%
      }%
  }
\def\@phx@ev@do@pt#1,{\ifx#1\relax\@empty\else
  \edef\reserved@a{\zap@space#1 \@empty}%
  \ifx\reserved@a\@empty\else
    \ifcsname phx@del\expandafter\expandafter\expandafter
    \expandafter\expandafter\expandafter\expandafter
    \expandafter\expandafter\expandafter\expandafter
    \expandafter\expandafter\expandafter\expandafter \string
    \expandafter\expandafter\expandafter\expandafter
    \expandafter\expandafter\expandafter \csname
    \expandafter\expandafter\expandafter \detokenize
    \expandafter{\reserved@a}\endcsname \endcsname
      \xdef\@phx@ev{\reserved@a}%
    \else
      \xdef\@phx@ev@basis{%
        \reserved@a}%
    \fi
  \fi
  \expandafter\@phx@ev@do@pt\fi}
\def\phx@ev@doopt#1{%
  \edef\@phx@ev{\@empty}\edef\@phx@ev@basis{\@empty}\@phx@ev@do@pt#1,\relax,}
\DeclareDocumentCommand \expval { s O{} m }
  {
    \phx@ev@doopt{#2}%
    \IfBooleanTF{#1}
      {%
        \gdef\@phx@bk@l{mathopen}%
        \gdef\@phx@bk@m{mathord}%
        \gdef\@phx@bk@r{mathclose}%
      }
      {%
        \gdef\@phx@bk@l{phx@abopen}%
        \gdef\@phx@bk@m{middle}%
        \gdef\@phx@bk@r{phx@abclose}%
        \ifx \@phx@ev\@empty \else
          \xdef\@phx@bk@l{\@phx@ev l}%
          \xdef\@phx@bk@m{\@phx@ev}%
          \xdef\@phx@bk@r{\@phx@ev r}%
        \fi
      }%
      \ifx \@phx@ev@basis\@empty
        \phx@bk@in@i {#3}%
      \else
        \phx@bk@in@iii {\@phx@ev@basis} {#3} {\@phx@ev@basis}%
      \fi
  }
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\protect \endinput
%    \end{macrocode}
%    \begin{macrocode}
%</braket>
%    \end{macrocode}
% Restore the namespace.
%    \begin{macrocode}
%<@@=phx>
%    \end{macrocode}
% \subsection{The \modu{doubleprod} module}
%    \begin{macrocode}
%<*doubleprod>
\ProvidesExplFile {phx-doubleprod.sty} {\phx@date} {\phx@version}
  {`doubleprod' (vertically stacked binary operators) module of physics3}
%    \end{macrocode}
% Boolean options.
%    \begin{macrocode}
\@@_define_key:nnnn { doubleprod } { crosssymbol } { } { \def\@phx@dbl@c {#1} }
\@@_define_key:nnnn { doubleprod } { dotsymbol   } { } { \def\@phx@dbl@d {#1} }
\@@_define_key:nnnn { doubleprod } { crossscale  } { } { \def\@phx@dbl@sc{#1} }
\@@_define_key:nnnn { doubleprod } { dotscale    } { } { \def\@phx@dbl@sd{#1} }
\@@_define_key:nnnn { doubleprod } { crossopenup } { } { \def\@phx@dbl@oc{#1} }
\@@_define_key:nnnn { doubleprod } { dotopenup   } { } { \def\@phx@dbl@od{#1} }
\@@_setkeys:nn      { doubleprod }
  {
    crosssymbol = \times, crossscale = 0.8, crossopenup = .02,
    dotsymbol   = \ldotp, dotscale   = 1,   dotopenup   = .2
  }
\@@_processkeyopt:n { doubleprod }
\def\phx@dbl@gen#1#2#3#4{%
  \DeclareRobustCommand#1{\mathbin{\vcenter{\baselineskip\z@skip%
    \lineskip#4\phx@dblcurrf@size%
    \hbox_set:Nn \l_tmpa_box {\fontsize{#2\phx@dblcurrf@size}\z@$#3$}
    \box_use:N \l_tmpa_box \box_use_drop:N \l_tmpa_box}}}}
\def\phx@dblcurrf@size{\dimexpr\f@size pt\relax}
\phx@dbl@gen\doublecross\@phx@dbl@sc\@phx@dbl@c\@phx@dbl@oc
\phx@dbl@gen\doubledot\@phx@dbl@sd\@phx@dbl@d\@phx@dbl@od
%    \end{macrocode}
%    \begin{macrocode}
\file_input_stop:
%    \end{macrocode}
%    \begin{macrocode}
%</doubleprod>
%    \end{macrocode}
% \subsection{The \modu{diagmat} module}
%    \begin{macrocode}
%<*diagmat>
\ProvidesExplFile {phx-diagmat.sty} {\phx@date} {\phx@version}
  {`diagmat' module of physics3}
%    \end{macrocode}
% This module requires \pkg{mathtools} and \pkg{xpatch}.
%    \begin{macrocode}
\RequirePackage { mathtools, etoolbox }
%    \end{macrocode}
% Do expansion of column specification argument (thanks @egreg
% on \href{https://tex.stackexchange.com/a/758530/299948}^^A
%   {\TeX\ \textsf{Stack\textbf{Exchange}}}).
%    \begin{macrocode}
\patchcmd \MT_matrix_begin:N { \exp_args:Ne \array } { \exp_args:Ne \array } {}
  { \patchcmd \MT_matrix_begin:N { \array } { \exp_args:Ne \array } {} {} }
%    \end{macrocode}
%    \begin{macrocode}
\@@_define_key:nnnn { diagmat } { empty } {   }
  { \tl_gset:Nn \l_@@_mat_empty_tl { #1 } }
\@@_define_key:nnnn { diagmat } { align } { r }
  { \tl_gset:Nn \l_@@_mat_align_tl { #1 } }
%    \end{macrocode}
% \begin{variable}
%   {
%     \l_@@_mat_diag_clist,
%     \l_@@_mat_dim_int,
%     \l_@@_mat_line_tl,
%     \l_@@_diagmat_tl,
%     \l_@@_mat_empty_tl,
%     \l_@@_mat_align_tl,
%   }
% This module requires some new variables.
%    \begin{macrocode}
\clist_new:N \l_@@_mat_diag_clist
\int_new:N   \l_@@_mat_dim_int
\tl_new:N    \l_@@_mat_line_tl
\tl_new:N    \l_@@_diagmat_tl
\tl_new:N    \l_@@_mat_empty_tl
\tl_new:N    \l_@@_mat_align_tl
\@@_processkeyopt:n { diagmat }
\keys_define:nn { phy/diagmat }
  {
    empty   .tl_set:N  = \l_@@_mat_empty_tl,
    align   .tl_set:N  = \l_@@_mat_align_tl,
  }
%    \end{macrocode}
% \end{variable}
% \begin{macro}{\diagmat, \pdiagmat, \bdiagmat, \Bdiagmat, \vdiagmat, \Vdiagmat}
%   \begin{quote}
%     \cs{\meta{delimiter type}diagmat} \oarg{key-val list} \marg{diagonal}
%   \end{quote}
%    \begin{macrocode}
\clist_map_inline:nn { {}, p, b, B, v, V }
  {
    \exp_args:Nc \DeclareDocumentCommand { #1diagmat } { s O{} m }
      {
        \IfBooleanTF { ##1 }
          { \@@_diagmat_type:nnn { #1small } { ##2 } { ##3 } }
          { \@@_diagmat_type:nnn { #1      } { ##2 } { ##3 } }
      }
  }
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\_@@_diagmat_type:nnn}
%   \begin{quote}
%     \cs{@@_diagmat_type:nnn} \marg{delimiter type}\\
%     "  "\marg{key-val list} \marg{diagonal}
%   \end{quote}
%    \begin{macrocode}
\cs_new:Npn \_@@_diagmat_type:nnn #1#2#3
  {
    \group_begin:
    \clist_set:Nn \l_@@_mat_diag_clist {#3}
    \int_set:Nn \l_@@_mat_dim_int { \clist_count:N \l_@@_mat_diag_clist }
    \int_compare:nNnT { \l_@@_mat_dim_int } > { \value { MaxMatrixCols } }
      { \setcounter { MaxMatrixCols } { \l_@@_mat_dim_int } }
    \keys_set:nn { phy/diagmat } {#2}
    \tl_gclear:N \l_@@_diagmat_tl
    \int_step_inline:nnn { 1 } { \l_@@_mat_dim_int }
      {
        \int_step_inline:nnn { 1 } { \l_@@_mat_dim_int }
          {
            \int_compare:nNnTF { ##1 } = { ####1 }
              {
                \clist_gpop:NN \l_@@_mat_diag_clist \l_@@_tmpa_tl
                \tl_if_empty:NTF \l_@@_tmpa_tl
                  { \tl_gput_right:Nn \l_@@_mat_line_tl { \l_@@_mat_empty_tl } }
%    \end{macrocode}
% Maybe it's better to use
% "\expandafter\scantokens\expandafter{"\cs{l_@@_tmpa_tl}"}" in the next line.
%    \begin{macrocode}
                  { \tl_gput_right:No \l_@@_mat_line_tl { \l_@@_tmpa_tl } }
              }
              { \tl_gput_right:Nn \l_@@_mat_line_tl { \l_@@_mat_empty_tl } }
            \int_compare:nNnTF { ####1 } = { \l_@@_mat_dim_int }
              {
                \tl_gput_right:Nn \l_@@_mat_line_tl { \\ }
              }
              {
                \tl_gput_right:Nn \l_@@_mat_line_tl { & }
              }
          }
        \tl_gput_right:No \l_@@_diagmat_tl { \l_@@_mat_line_tl }
        \tl_gclear:N \l_@@_mat_line_tl
      }
    \tl_if_empty:NTF { \l_@@_mat_align_tl }
      {
        \begin { #1 matrix }
          \tl_use:N \l_@@_diagmat_tl
        \end { #1 matrix }
      }
      {
        \begin { #1 matrix* } [ \l_@@_mat_align_tl ]
          \tl_use:N \l_@@_diagmat_tl
        \end { #1 matrix* }
      }
    \group_end:
  }
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\file_input_stop:
%    \end{macrocode}
%    \begin{macrocode}
%</diagmat>
%    \end{macrocode}
% \subsection{The \modu{xmat} module}
%    \begin{macrocode}
%<*xmat>
\ProvidesExplFile {phx-xmat.sty} {\phx@date} {\phx@version}
  {`xmat' module of physics3}
%    \end{macrocode}
% This module requires \pkg{mathtools} and \pkg{xpatch}.
%    \begin{macrocode}
\RequirePackage { mathtools, etoolbox }
%    \end{macrocode}
% Do expansion of column specification argument (thanks @egreg
% on \href{https://tex.stackexchange.com/a/758530/299948}^^A
%   {\TeX\ \textsf{Stack\textbf{Exchange}}}).
%    \begin{macrocode}
\patchcmd \MT_matrix_begin:N { \exp_args:Ne \array } { \exp_args:Ne \array } {}
  { \patchcmd \MT_matrix_begin:N { \array } { \exp_args:Ne \array } {} {} }
%    \end{macrocode}
%    \begin{macrocode}
\@@_define_key:nnnn { xmat } { showtop } { }
  { \int_gset:Nn \l_@@_xmat_showtop_int { #1 } }
\@@_define_key:nnnn { xmat } { showleft } { }
  { \int_gset:Nn \l_@@_xmat_showleft_int { #1 } }
%    \end{macrocode}
% \begin{variable}
%   {
%     \l_@@_xmat_extra_vdots_bool,
%     \l_@@_xmat_extra_cdots_bool,
%     \l_@@_xmat_showtop_int,
%     \l_@@_xmat_showleft_int,
%     \l_@@_xmat_tl,
%     \l_@@_xmat_showtop_int,
%     \l_@@_xmat_showleft_int,
%   }
% This module requires some new variables.
%    \begin{macrocode}
\bool_new:N  \l_@@_xmat_extra_vdots_bool
\bool_new:N  \l_@@_xmat_extra_cdots_bool
\int_new:N   \l_@@_xmat_showtop_int
\int_new:N   \l_@@_xmat_showleft_int
\tl_new:N    \l_@@_xmat_tl
\int_gset:Nn \l_@@_xmat_showtop_int  { \value { MaxMatrixCols } - 2 }
\int_gset:Nn \l_@@_xmat_showleft_int { \value { MaxMatrixCols } - 2 }
%    \end{macrocode}
% \end{variable}
%    \begin{macrocode}
\cs_new:Npn \_@@_xmat_entry_format:nnn #1#2#3
  {
    #1 \c_math_subscript_token { #2 #3 }
  }
\@@_processkeyopt:n { xmat }
\clist_map_inline:nn { {}, p, b, B, v, V }
  {
    \exp_args:Nc \DeclareDocumentCommand { #1xmat } { s O{} m m m }
      {
        \IfBooleanTF { ##1 }
          { \_@@_xmat_type:nnnnn { #1small } { ##2 } { ##3 } { ##4 } { ##5 } }
          { \_@@_xmat_type:nnnnn { #1      } { ##2 } { ##3 } { ##4 } { ##5 } }
      }
  }
\keys_define:nn { phx / xmat }
  {
    format  .cs_set:Np = \_@@_xmat_entry_format:nnn #1#2#3 ,
    showtop .int_set:N = \l_@@_xmat_showtop_int ,
    showleft.int_set:N = \l_@@_xmat_showleft_int ,
  }
%    \end{macrocode}
% \begin{macro}[pTF]{\_@@_if_digits_only:n}
%   \begin{quote}
%     \cs{@@_if_digits_only:nTF} \marg{token list} \marg{true code} \marg{flase code}
%   \end{quote}
%   Use \LaTeX3 regular expression to tell if \meta{token list}
%   (the numbers of rows or columns) contain digits only.
% \end{macro}
%    \begin{macrocode}
\prg_new_conditional:Npnn \_@@_if_digits_only:n #1 { TF }
  {
    \regex_match:nnTF { \A [[:digit:]]* \Z } { #1 }
      { \prg_return_true: } { \prg_return_false: }
  }
%    \end{macrocode}
% \begin{macro}{\_@@_xmat_type:nnnnn}
%   \begin{quote}
%     \cs{@@_xmat_type:nnnnn} \marg{delimiter type} \marg{key-val list}\\
%     "  "\marg{common entry} \marg{row number} \marg{column number}
%   \end{quote}
% \end{macro}
%    \begin{macrocode}
\cs_new:Npn \_@@_xmat_type:nnnnn #1#2#3#4#5
  {
    \group_begin:
    \tl_gclear:N \l_@@_xmat_tl
    \keys_set:nn { phx / xmat } { #2 } %
    \_@@_if_digits_only:nTF { #4 }
      {
        \int_compare:nNnTF { #4 } < { \l_@@_xmat_showtop_int + 1 }
          {
            \int_set:Nn \l_@@_xmat_showtop_int { #4 }
            \bool_set_false:N \l_@@_xmat_extra_vdots_bool
          }
          {
            \bool_set_true:N \l_@@_xmat_extra_vdots_bool
          }
      }
      {
        \bool_set_true:N \l_@@_xmat_extra_vdots_bool
      }
    \_@@_if_digits_only:nTF { #5 }
      {
        \int_compare:nNnTF { #5 } < { \l_@@_xmat_showleft_int + 1 }
          {
            \int_set:Nn \l_@@_xmat_showleft_int { #5 }
            \bool_set_false:N \l_@@_xmat_extra_cdots_bool
          }
          {
            \bool_set_true:N \l_@@_xmat_extra_cdots_bool
          }
      }
      {
        \bool_set_true:N \l_@@_xmat_extra_cdots_bool
      }
    \int_step_inline:nn { \l_@@_xmat_showtop_int }
      {
        \tl_put_right:Nn \l_@@_xmat_tl
          { \_@@_xmat_entry_format:nnn { #3 } { ##1 } { 1 } }
        \int_step_inline:nnn { 2 } { \l_@@_xmat_showleft_int }
          {
            \tl_put_right:Nn \l_@@_xmat_tl
              { & \_@@_xmat_entry_format:nnn { #3 } { ##1 } { ####1 } }
          }
        \bool_if:NT \l_@@_xmat_extra_cdots_bool
          {
            \tl_put_right:Nn \l_@@_xmat_tl
              { & \cdots & \_@@_xmat_entry_format:nnn { #3 } { ##1 } { #5 } }
          }
        \tl_put_right:Nn \l_@@_xmat_tl { \\ }
      }
    \bool_if:NT \l_@@_xmat_extra_vdots_bool
      {
        \tl_put_right:Nn \l_@@_xmat_tl { \vdots }
        \prg_replicate:nn { \l_@@_xmat_showleft_int - 1 }
          {
            \tl_put_right:Nn \l_@@_xmat_tl { & \vdots }
          }
        % Add \ddots if vdots_bool and cdots_bool be true simultaneously.
        \bool_if:NT \l_@@_xmat_extra_cdots_bool
          {
            \tl_put_right:Nn \l_@@_xmat_tl { & \ddots & \vdots }
          } % else relax
        \tl_put_right:Nn \l_@@_xmat_tl { \\ }
        % The last row.
        \tl_put_right:Nn \l_@@_xmat_tl
          { \_@@_xmat_entry_format:nnn { #3 } { #4 } { 1 } }
        \int_step_inline:nnn { 2 } { \l_@@_xmat_showleft_int }
          {
            \tl_put_right:Nn \l_@@_xmat_tl
              { & \_@@_xmat_entry_format:nnn { #3 } { #4 } { ##1 } }
          }
        \bool_if:NT \l_@@_xmat_extra_cdots_bool
          {
            \tl_put_right:Nn \l_@@_xmat_tl
              { & \cdots & \_@@_xmat_entry_format:nnn { #3 } { #4 } { #5 } }
          }
      } % else relax
    \begin { #1 matrix }
      \tl_use:N \l_@@_xmat_tl
    \end { #1 matrix }
    \group_end:
  }
%    \end{macrocode}
%    \begin{macrocode}
\file_input_stop:
%    \end{macrocode}
%    \begin{macrocode}
%</xmat>
%    \end{macrocode}
% \subsection{The \modu{operator} module}
%    \begin{macrocode}
%<*operator>
\ProvidesExplFile {phx-operator.sty} {\phx@date} {\phx@version}
  {`operator' module of physics3}
\@@_define_key:nnnn { op.lega } { ReIm } { true } { \def\phx@reserveda{#1}  }
\@@_define_key:nnnn { op.lega } { PV   } {      } { \def\@phx@oplega@PV{#1} }
\@@_define_key:nnnn { op.lega } { pv   } {      } { \def\@phx@oplega@pv{#1} }
\@@_setkeys:nn     { op.lega } { PV = \mathcal{P}, pv = {p.v.}, ReIm = true}
\@@_processkeyopt:n { ab }
%    \end{macrocode}
% \begin{macro}[int]
%   {
%     \asin,  \acos,  \atan,  \acsc,  \asec,  \acot,
%     \Tr,    \tr,    \rank,  \erf,   \Res,   \res,
%     \PV,    \pv,    \upe,   \iu,    \identity
%   }
%    \begin{macrocode}
\clist_map_inline:nn
  { asin, acos, atan, acsc, asec, acot, Tr, tr, rank, erf, Res, res }
  {
    \exp_args:Nc \DeclareRobustCommand {#1}
      { \mathop { \operator@font #1 } \nolimits }
  }
  \DeclareRobustCommand\PV  {\mathord{\@phx@oplega@PV}}
  \DeclareRobustCommand\pv  {\mathop{\operator@font\@phx@oplega@pv{}}\nolimits}
  \DeclareRobustCommand\upe {\mathrm e}
  \DeclareRobustCommand\iu  {\mathrm i\mkern1mu}
  \DeclareRobustCommand\identity{\mathbb I}
%    \end{macrocode}
% \end{macro}
% \begin{macro}[int]{\Re, \Im}
% Restore \cs{Re} and \cs{Im} in \cs{Resymbol} and \cs{Imsymbol}.
% The \cs{AtBeginDocument}
% hook is used for the compatibility of \pkg{unicode-math}.
%    \begin{macrocode}
\ifx \phx@reserveda \phx@true
\AtBeginDocument
{
  \let\Resymbol\Re
  \let\Imsymbol\Im
  \DeclareRobustCommand\Re{\mathop{\operator@font Re}\nolimits}%
  \DeclareRobustCommand\Im{\mathop{\operator@font Im}\nolimits}%
  }
  \fi
%    \end{macrocode}
% \end{macro}
% Requires \pkg{fixdif} version 2.$x$.
%    \begin{macrocode}
\RequirePackage{fixdif}[2023/01/31]
\letdif\phx@nl@nabla{nabla}
%    \end{macrocode}
% \begin{macro}[int]{\grad, \div, \curl, \laplacian}
%   $\nabla$-related operators.
%    \begin{macrocode}
\phx@requiremodule{ab}
\AtBeginDocument
  {
    \ifcsname div\endcsname\let\divsymbol\div\fi
    \DeclareRobustCommand \grad     {\phx@nl@nabla\ab}
    \DeclareRobustCommand \div      {\phx@nl@nabla\cdot\ab}
    \DeclareRobustCommand \curl     {\phx@nl@nabla\times\ab}
    \DeclareRobustCommand \laplacian{\phx@nl@nabla^2\ab}
  }
%    \end{macrocode}
% \end{macro}
%    \begin{macrocode}
\file_input_stop:
%    \end{macrocode}
%    \begin{macrocode}
%</operator>
%    \end{macrocode}
% \subsection{The \modu{bm-um} module}
%    \begin{macrocode}
%<*bm-um>
\ProvidesExplFile {phx-bm-um.sty} {\phx@date} {\phx@version}
  {`bm-um' module of physics3}
\AtBeginDocument
  {
    \cs_if_exist:cF { symbf }
      {
        \PackageError { physics3 }
          {
            The ~ `bm-um' ~ module ~ requires ~
            `unicode-math' ~ package
          }
          {
            Have ~ you ~ used ~ `unicode-math' ~
            in ~ the ~ preamble?
          }
      }
  }
\DeclareDocumentCommand \bm { m }
  {
    \mode_if_math:TF
      {
        \tl_map_inline:nn { #1 }
          {
            \tl_if_head_eq_catcode:nNTF { ##1 } A
              { \symbfit { ##1 } } { \symbf { ##1 } }
          }
      }
      {
        \msg_error:nn { physics3 }
          { The ~ \string\bm\space command ~ requires ~ math ~ mode. }
      }
  }
%    \end{macrocode}
%    \begin{macrocode}
\file_input_stop:
%    \end{macrocode}
%    \begin{macrocode}
%</bm-um>
%    \end{macrocode}
% \subsection{The \modu{ab.legacy} module}
%    \begin{macrocode}
%<*ab.legacy>
\ProvidesFile {phx-ab.legacy.sty}
  [\phx@date\ `ab.legacy' module of physics3]
%    \end{macrocode}
% Requires \modu{ab}'s "tight" option.
%    \begin{macrocode}
\phx@requiremodule{ab}
\phx@define@key{ab.legacy}{order}{\mathcal O}{\def\phx@ab@ordersym{#1}}
\phx@setkeys{ab.legacy}{order}
\phx@processkeyopt{ab.legacy}
\phx@d@l@geny\abs\vert\vert
\phx@d@l@geny\norm\Vert\Vert
\DeclareDocumentCommand\order{som}{%
  \phx@ab@ordersym
  \IfBooleanTF{#1}
    {(#3)}
    {\IfValueTF{#2}
      {\csname#2l\endcsname(#3\csname#2r\endcsname)}
      {\phx@abopen(#3\phx@abclose)}%
    }%
}
\phx@d@l@geny\eval.\vert
\phx@d@l@geny\peval(\vert
\phx@d@l@geny\beval[\vert
%    \end{macrocode}
%    \begin{macrocode}
\protect \endinput
%    \end{macrocode}
%    \begin{macrocode}
%</ab.legacy>
%    \end{macrocode}
% \subsection{The \modu{qtext.legacy} module}
% This module is written for the compatibility with the bad commands provided by
% \pkg{physics} only. The commands in this module should NEVER be used!
%    \begin{macrocode}
%<*qtext.legacy>
\ProvidesExplFile {phx-qtext.legacy.sty} {\phx@date} {\phx@version}
  {`qtext.legacy' module of physics3.sty}
\RequirePackage{amstext}
\def\phx@qtext@#1#2{#1\text{#2}\quad}
\DeclareRobustCommand\qqtext{\@ifstar{\phx@qtext@{}}{\phx@qtext@\quad}}
\DeclareRobustCommand\qq{\qqtext}
\DeclareRobustCommand\qcomma{,\quad}
\DeclareRobustCommand\qc{\qcomma}
\DeclareRobustCommand\qcc{\@ifstar{\phx@qtext@{}{c.c}}{\phx@qtext@\quad{c.c}}}
\clist_map_inline:nn
  {
    if,       then,   else,   otherwise,  unless,
    give,     using,  unless, assume,     since,
    let,      for,    all,    even,       odd,
    integer,  and,    or,     as,         in
  }
  {
    \exp_args:Nc \DeclareRobustCommand { q#1 }
      { \@ifstar{ \phx@qtext@ {} {#1} } { \phx@qtext@ \quad {#1} } }
  }
%    \end{macrocode}
%    \begin{macrocode}
\file_input_stop:
%    \end{macrocode}
%    \begin{macrocode}
%</qtext.legacy>
%    \end{macrocode}
% \end{implementation}
% \clearpage
% \PrintIndex
