假设我有两个 csv 文件,分别表示一个复杂矩阵的实部和虚部。我想在 LaTeX 中很好地显示这个矩阵。困难在于正确地对数字进行舍入,并且如果数字舍入为 0 则不显示它们。
例如,1.0000000e+00 和 5.0000000e-01 应该给出 1+0.5i,而 5.0000000e-01 和 0.0000000e+00 不应该显示虚部(即 0.5)。
我从这些问题开始: 使用 siunitx 将复数对齐到表格中心和合并 csv 的列但无法提出令人满意的解决方案。
这里就是开始!
\documentclass{article}
\usepackage{pgfplotstable}
\begin{filecontents}{blah_real.csv}
re1 re2
1.0000000e+00 1.0000000e+00
5.0000000e-01 5.0000000e-01
0.0000000e+00 0.0000000e+00
5.0000000e-01 5.0000000e-01
\end{filecontents}
\begin{filecontents}{blah_im.csv}
0.0000000e+00 0.0000000e+00
5.0000000e-01 5.0000000e-01
1.0000000e+00 1.0000000e+00
5.0000000e-01 5.0000000e-01
\end{filecontents}
\begin{document}
\newcommand{\complex}[1]{%
\pgfplotstableread[col sep=space, trim cells=true]{#1_real.csv}\real
\pgfplotstableread[col sep=space, trim cells=true, header=false]{#1_im.csv}\imaginary
\pgfplotstablecreatecol[copy column from table={\imaginary}{[index] 0}]{im1}{\real}
\pgfplotstablecreatecol[copy column from table={\imaginary}{[index] 1}]{im2}{\real}
\pgfplotstabletypeset[
columns/complex1/.style={string type, column name={}},
create on use/complex1/.style={%
create col/assign/.code={%
\edef\value{%
\noexpand
\pgfmathprintcomplexnumber[fixed zerofill]{\thisrow{re1}}{\thisrow{im1}}}
\pgfkeyslet{/pgfplots/table/create col/next content}\value
}
},
columns/complex2/.style={string type, column name={}},
create on use/complex2/.style={%
create col/assign/.code={%
\edef\value{%
\noexpand
\pgfmathprintcomplexnumber[fixed zerofill]{\thisrow{re2}}{\thisrow{im2}}}
\pgfkeyslet{/pgfplots/table/create col/next content}\value
}
},
columns={complex1, complex2}
]{\real}
}
\makeatletter
\def\pgfmathprintcomplexnumber{%
% \protect allows to supply \pgfmathprintnumber inside of latex
% captions. The \csname yields \relax in case protect is undefined.
\pgf@texdist@protect\pgfmathprintcomplexnumber@protected
}%
\def\pgfmathprintcomplexnumber@protected{%
\pgfutil@ifnextchar[%
{\pgfmathprintcomplexnumber@OPT}%
{\pgfmathprintcomplexnumber@noopt}%
}
\def\pgfmathprintcomplexnumber@noopt#1#2{%
\begingroup
\pgfmathprintnumber@{#1}%
\let\pgfmathresultreal\pgfmathresult
\pgfmathfloatparsenumber{\pgfmathresult}
\pgfmathfloatifflags{\pgfmathresult}{0}{
\let\pgfmathresultreal\empty
\pgfqkeys{/pgf/number format}{showpos=false}%
}{
\pgfqkeys{/pgf/number format}{showpos=true}%
}%
\pgfmathprintnumber@{#2}%
\let\pgfmathresultim\pgfmathresult
\pgfmathfloatparsenumber{\pgfmathresult}
\pgfmathfloatifflags{\pgfmathresult}{0}{%
\let\pgfmathresultim\empty
}{
\edef\pgfmathresultim{\pgfmathresultim i}
}%
\ifpgfmathprintnumber@assumemathmode
\pgfmathresultreal\pgfmathresultim
\else
\pgfutilensuremath{\pgfmathresultreal\pgfmathresultim}%
\fi
\endgroup
}%
\def\pgfmathprintcomplexnumber@OPT[#1]#2#3{%
\begingroup
\pgfqkeys{/pgf/number format}{#1}%
\pgfmathprintnumber@{#2}%
\let\pgfmathresultreal\pgfmathresult
\pgfmathfloatparsenumber{\pgfmathresult}
\pgfmathfloatifflags{\pgfmathresult}{0}{
\let\pgfmathresultreal\empty
\pgfqkeys{/pgf/number format}{showpos=false}%
}{
\pgfqkeys{/pgf/number format}{showpos=true}%
}%
\pgfmathprintnumber@{#3}%
\let\pgfmathresultim\pgfmathresult
\pgfmathfloatparsenumber{\pgfmathresult}
\pgfmathfloatifflags{\pgfmathresult}{0}{%
\let\pgfmathresultim\empty
}{%
\edef\pgfmathresultim{\pgfmathresultim i}
}%
\ifpgfmathprintnumber@assumemathmode
\pgfmathresultreal\pgfmathresultim
\else
\pgfutilensuremath{\pgfmathresultreal\pgfmathresultim}%
\fi
\endgroup
}%
\makeatother
\complex{blah}
\end{document}
知道如何做到这一点吗?
编辑:几乎可以正常工作的示例,但我仍然有 0.00 + 1.00i,并且加号更接近虚部......
EDIT2: \pgfmathprintcomplexnumber 很大程度上受到 \pgfmathprintnumber 的启发。剩余问题:可能会显示 1i
答案1
当然,您需要应用“if number = 0 ... else ... endif”等条件。
如果你能做到
- 用于
\pgfmathfloatparsenumber
获取浮点格式的中间结果 - 用于
\pgfmathfloatifflags
检查数字是否为零、正数、负数、非数、inf、-inf。
这是一个例子(我简化了“合并不同的表”部分,因为它与格式化复数的任务无关):
\documentclass{standalone}
\usepackage{pgfplotstable}
\begin{document}
\pgfplotstabletypeset[
columns/complex1/.style={string type, column name={}},
create on use/complex1/.style={%
create col/assign/.code={%
\pgfmathfloatparsenumber{\thisrow{Re}}%
\let\valueRe=\pgfmathresult
\pgfmathfloatparsenumber{\thisrow{Im}}%
\let\valueIm=\pgfmathresult
\pgfmathfloatifflags{\valueRe}{0}{%
% Ah: re = 0.0
\def\valueRe{}%
}{%
\edef\valueRe{\noexpand\pgfmathprintnumber[fixed zerofill]{\valueRe}}%
}%
%\show\valueRe
\pgfmathfloatifflags{\valueIm}{0}{%
% Ah - im = 0.0
\def\valueIm{}%
}{%
\edef\valueIm{\noexpand\pgfmathprintnumber[showpos,fixed zerofill]{\valueIm}i}%
}%
%\show\valueIm
\toks0=\expandafter{\valueRe}%
\toks1=\expandafter{\valueIm}%
% we cannot use \edef\value{\valueRe\valueIm} as this would
% expand \pgfmathprintnumber - which is not expandable.
% Writing \the<tokenregister> expands the content of
% <tokenregister> exactly once:
\edef\value{\the\toks0 \the\toks1 }%
%\show\value
\pgfkeyslet{/pgfplots/table/create col/next content}\value
}
},
%debug,
columns={complex1},
]{
Re Im
1.0000000e+00 0.0000000e+00
5.0000000e-01 5.0000000e-01
0.0000000e+00 1.0000000e+00
5.0000000e-01 5.0000000e-01
}
\end{document}
参考文献:引用自 tikz 手册pgfmanual.pdf
:
\pgfmathfloatifflags{ floating point number }{ flag }{ true-code }{ false-code }
Invokes { true-code } if the flag of { floating point number } equals { flag } and { false-code } other-
wise.
The argument { flag } can be one of
0 to test for zero,
1 to test for positive numbers,
+ to test for positive numbers,
2 to test for negative numbers,
- to test for negative numbers,
3 for "not-a-number",
4 for +infty,
5 for -infty.
在我的文档中提到了 token-register 的魔法我应该从哪里开始 LaTeX 编程?
答案的下一部分是关于对齐的。乍一看似乎很有用,但实际上它不必要地复杂,因为只需分别排版“Re”和“Im”就可以轻松完成对齐。尽管如此,它还是有效的,并且可能有助于了解如何采用这些东西。
将这部分视为“高级用户的练习”。
这里有一个修改(仅在两个地方,在\edef\value
和中column type
),它使实部和虚部之间的结果对齐:
\documentclass{standalone}
\usepackage{pgfplotstable}
\begin{document}
\pgfplotstabletypeset[
columns/complex1/.style={string type, column type={r@{}l},column name={}},
create on use/complex1/.style={%
create col/assign/.code={%
\pgfmathfloatparsenumber{\thisrow{Re}}%
\let\valueRe=\pgfmathresult
\pgfmathfloatparsenumber{\thisrow{Im}}%
\let\valueIm=\pgfmathresult
\pgfmathfloatifflags{\valueRe}{0}{%
% Ah: re = 0.0
\def\valueRe{}%
}{%
\edef\valueRe{\noexpand\pgfmathprintnumber[fixed zerofill]{\valueRe}}%
}%
%\show\valueRe
\pgfmathfloatifflags{\valueIm}{0}{%
% Ah - im = 0.0
\def\valueIm{}%
}{%
\edef\valueIm{\noexpand\pgfmathprintnumber[showpos,fixed zerofill]{\valueIm}i}%
}%
%\show\valueIm
\toks0=\expandafter{\valueRe}%
\toks1=\expandafter{\valueIm}%
% we cannot use \edef\value{\valueRe\valueIm} as this would
% expand \pgfmathprintnumber - which is not expandable.
% Writing \the<tokenregister> expands the content of
% <tokenregister> exactly once:
\edef\value{\the\toks0 & \the\toks1 }%
%\show\value
\pgfkeyslet{/pgfplots/table/create col/next content}\value
}
},
%debug,
columns={complex1},
]{
Re Im
1.0000000e+00 0.0000000e+00
5.0000000e-01 5.0000000e-01
0.0000000e+00 1.0000000e+00
5.0000000e-01 5.0000000e-01
}
\end{document}