我需要从以下任一方式稳健地生成显示的方程
1- 分子和分母的系数分别由\NumCoeffMat
和定义\DenCoeffMat
2- 或部分分数项定义为\PartialFraction
PS:分母中最高阶的系数始终为正数,因此数组中未给出。
任何零系数都应s
从书面表达式中排除与其相关的阶数。
\documentclass{article}
\edef\NumCoeffMat{{4, 32, 62}} % numerator coefficients (i.e. numerator = 4s^2 + 32s + 62)
\edef\DenCoeffMat{{12, 47, 60}} % denominator coefficients (i.e. denominator = s^3 + 12s^2 + 47s + 60)
\def\PartialFraction{1/-3, 2/-4, 1/-5} % gain/coefficient and root (i.e. 1/(s+3) + 2/(s+4) + 1/(s+5) )
\begin{document}
\[
\frac{4\,s^2 + 32\,s + 62}{s^3 + 12\,s^2 + 47\,s + 60}
\]
\end{document}
答案1
这是编写多项式的通用宏。第一个参数是不确定的,第二个参数是系数列表
\documentclass{article}
\usepackage{pgffor}
\newcount\degree
\newif\ifzero
\newif\ifcoeff
% \polynomial{<indeterminate>}{<list of coefficients>}
\newcommand*\polynomial[2]{%
\global\degree=0\relax
\foreach\x in {#2} {\global\advance\degree 1\relax}%
\ifnum\degree=0
0%
\else
\global\zerotrue
\foreach\coeff in {#2} {%
\global\advance\degree-1
\coefffalse
\ifnum\coeff=0 \else
\ifnum\coeff>0 \ifzero\else+\fi\fi
\ifnum\coeff=-1
-\ifnum\degree=0 1\fi
\else\ifnum\coeff=1
\ifnum\degree=0 1\fi
\else
\coefftrue
\coeff
\fi\fi
\ifnum\degree>0\relax\ifcoeff\,\fi{#1}\ifnum\degree>1^{\the\degree}\fi\fi
\global\zerofalse
\fi
}%
\ifzero 0\fi
\fi
}
\newcommand\PartialFraction[2][s]{%
\global\zerotrue
\foreach \n/\r in {#2} {%
\ifnum\n=0 \else
\ifnum\n<0
-\edef\n{\the\numexpr-\n\relax}%
\else
\ifzero\else +\fi
\fi
\global\zerofalse
\frac{\n}{s\ifnum\r>0 -\r\else\ifnum\r<0 +\the\numexpr-\r\relax\fi\fi}%
\fi}%
\ifzero 0\fi
}
\begin{document}
\[
\frac{\polynomial{s}{4,32,62}}{\polynomial{s}{1,12,47,60}}
\]
\[
\PartialFraction{1/-3, 2/-4, 1/-5}
\]
\end{document}
下一个宏允许你按照你想要的方式给出系数
% \Fraction[<indeterminate> defaults to s]
\newcommand\Fraction[1][s]{%
\begingroup
\def\polyaux##1{{1,##1}}%
\edef\next{\noexpand\frac{\unexpanded{\polynomial{#1}}\NumCoeffMat}{\unexpanded{\polynomial{#1}}\expandafter\polyaux\DenCoeffMat}}%
\next
\endgroup
}
\[
\def\NumCoeffMat{{4, 32, 62}} % numerator = 4s^2+32s+62
\def\DenCoeffMat{{12, 47, 60}} % denominator = s^3+12s^2+47s+60
\Fraction
\]
答案2
使用 expl3 clist....
\documentclass{article}
\def\NumCoeffMat{4, 32, 62} % numerator coefficients (i.e. numerator = 4s^2 + 32s + 62)
\def\DenCoeffMat{12, 47, 60} % denominator coefficients (i.e. denominator = s^3 + 12s^2 + 47s + 60)
\edef\DenCoeffMatX{1,\DenCoeffMat} % add the leading 1 back
\ExplSyntaxOn
\int_new:N\l_tmp_int
\tl_new:N\l_sep
\tl_set:Nn\l_sep{}
\def\z#1{
\int_set:Nn\l_tmp_int{\clist_count:N#1 - 1} % order of polynomial
\clist_map_inline:Nn#1{
\int_compare:nNnT{##1}> {0} % skip 0 terms
{\l_sep % + except first term
\int_compare:nNnT{##1}> {1}{##1\,} % skip coeff 1
\int_compare:nNnT{\l_tmp_int}> {0}{
s\int_compare:nNnT{\l_tmp_int}> {1}{^{\int_use:N\l_tmp_int}}}} % skip power 1
\int_decr:N\l_tmp_int
\tl_set:Nn\l_sep{+}
}}
\ExplSyntaxOff
\begin{document}
\[
\frac{\z\NumCoeffMat}{\z\DenCoeffMatX}
\]
\end{document}
答案3
这使用 展开多项式\foreach
。
\documentclass{article}
\usepackage{tikz}
\edef\NumCoeffMat{{4, 32, 62}}% numerator coefficients (i.e. numerator = 4s^2 + 32s + 62)
\newcounter{exponent}
\newcommand{\poly}[1]{\bgroup
\setcounter{exponent}{-1}%
\def\zero{0}%
\def\one{1}%
\expandafter\edef\expandafter\list#1
\foreach \x in \list {\stepcounter{exponent}}% max exponent
\foreach \x in \list {\ifnum\value{exponent}>0
\ifx\x\zero \else
\ifx\x\one \else \x \fi
\ifnum\value{exponent}>1 s^\theexponent +
\else s +
\fi
\fi
\else \x% last coeficient in polynomial
\fi
\addtocounter{exponent}{-1}}%
\egroup}
\begin{document}
$\poly{\NumCoeffMat}$
\end{document}
答案4
作为练习,我尝试用我的functional
包裹:
\documentclass{article}
\usepackage{functional}
\def\NumCoeffMat{4, 32, 62} % numerator coefficients (i.e. numerator = 4s^2 + 32s + 62)
\def\DenCoeffMat{12, 47, 60} % denominator coefficients (i.e. denominator = s^3 + 12s^2 + 47s + 60)
\edef\DenCoeffMatX{1,\DenCoeffMat} % add the leading 1 back
\IgnoreSpacesOn
\PrgNewFunction \Z {M} {
\IntSet \lTmpaInt {\ClistVarCount #1}
\IntDecr \lTmpaInt
\ClistClear \lTmpaClist
\ClistVarMapInline #1 {
\IntCompareTF {##1} > {0} {
\IntCompareTF {##1} > {1} {
\TlSet \lTmpaTl {##1}
}{
\TlSet \lTmpaTl {}
}
\IntCompareTF {\lTmpaInt} > {1} {
\TlPutRight \lTmpaTl {\Expand{s^{\OnlyValue\lTmpaInt}}}
}{
\IntCompareTF {\lTmpaInt} = {1} {
\TlPutRight \lTmpaTl {s}
} { }
}
\ClistPutRight \lTmpaClist {\Value\lTmpaTl}
} { }
\IntDecr \lTmpaInt
}
\ClistVarJoin \lTmpaClist {+}
}
\IgnoreSpacesOff
\begin{document}
\[ \frac{\Z\NumCoeffMat}{\Z\DenCoeffMatX} \]
\end{document}