线性系统自动解答中的分数格式问题

线性系统自动解答中的分数格式问题

我正在尝试对线性系统进行自动回答,但是我对分数格式遇到了一些问题。

\documentclass{article}
\usepackage{xparse,xfp,xfrac,amsmath,amsfonts}
\usepackage[nice]{nicefrac}
\usepackage{pgf}
\usepgflibrary{fpu}
\def \x {1/2}
\def \y {4/7}
\def \z {3}
\def \w {4}
\begin{document}
\pgfkeys{/pgf/number format/.cd,frac, frac whole=false}%
Consider the Matrix:
\[
\mathbb{A}=\left [
\begin{matrix}
\x & \y \\
\z & \w
\end{matrix}
\right ]
\]
Determinant should be calculated by:
$$
\mathrm{det}(\mathbb{A})=\x \cdot \w - (\y \cdot \z) = \pgfmathprintnumber{\fpeval{\x*\w}} - \pgfmathprintnumber{\fpeval{\y*\z}} = \pgfmathprintnumber{\fpeval{\x*\w-\z*\y}}
$$

But, I wanna like this:

$$
\mathrm{det}(\mathbb{A})=\frac{1}{2} \cdot \w - (\frac{4}{7} \cdot \z) = 2 -\frac{12}{7} = \frac{2}{7}
$$
\end{document}

渲染视图

答案1

更新:一个全自动解决方案。它跟踪分子和分母。解析器很大程度上受到calcTi 库的启发Z.\PrintFrac{<expression>}通过除以最大公约数来解析和简化表达式。表达式可以包含整数、、+-*/目前没有括号)。

\documentclass{article}
\usepackage{amsmath,amsfonts}
\usepackage[nice]{nicefrac}
\usepackage{pgf}
\usepgflibrary{fpu}
\makeatletter
%\def\mymessage#1{\message{#1^^J}}
\def\mymessage#1{}%
\pgfmathdeclarefunction{intfrac}{1}{%
\begingroup%
\edef\temp{\noexpand\pgfmathfracparse#1;}%
\temp%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\long\def\pgfmathfracparse#1{%
\begingroup% 
\def\pgf@frac@numerator{0}%
\def\pgf@frac@denominator{1}%
\def\pgf@current@frac@numerator{}%
\def\pgf@current@frac@denominator{}%
\def\pgf@local@frac@numerator{}%
\def\pgf@local@frac@denominator{1}%
\def\pgf@local@frac@above{1}%
\def\pgf@frac@factor{1}% 
\def\pgf@local@frac@isprod{0}%
\def\pgf@prod@frac@numerator{1}%
\def\pgf@prod@frac@denominator{1}%
\pgf@frac@parse#1% 
}% 
\def\pgf@frac@parse{% 
\pgfutil@ifnextchar;{% 
% Ok, we found the end... 
\pgf@frac@end% 
} 
{\pgfutil@ifnextchar+{% 
% Ok, we found a term... 
\pgf@frac@add% 
}{% 
\pgfutil@ifnextchar-{% 
\pgf@frac@sub% 
}{% 
\pgfutil@ifnextchar/{% 
\pgf@frac@div% 
}{% 
\pgfutil@ifnextchar *{% 
\pgf@frac@prod% 
}{% \tikzerror{+ or - or * or / expected}% 
%\pgf@frac@end%
\pgf@frac@consume%
}% 
}% 
}% 
}% 
}%
}%
\def\pgf@frac@consume#1{%
\ifnum\pgf@local@frac@above=1
\edef\pgf@local@frac@numerator{\pgf@local@frac@numerator#1}%
\else
\edef\pgf@local@frac@denominator{\pgf@local@frac@denominator#1}%
\fi%
\mymessage{consuming #1 (numerator=\pgf@local@frac@numerator, denominator=\pgf@local@frac@denominator)^^J}%
\pgf@frac@parse%
}%
\def\pgf@frac@end;{% 
%\mymessage{end\pgf@frac@numerator/\pgf@frac@denominator^^J}
%\def\pgf@local@frac@isprod{0}%
\pgf@frac@sumup%
\edef\pgfmathresult{\pgf@frac@numerator/\pgf@frac@denominator}%
\pgfmathsmuggle\pgfmathresult\endgroup}% 
% 
\def\pgf@frac@add+{% 
\mymessage{saw a +^^J}%
\pgf@frac@sumup%
\def\pgf@frac@factor{1}% 
\def\pgf@local@frac@isprod{0}%
\pgf@frac@parse% 
}% 
\def\pgf@frac@sub-{%
\mymessage{saw a -^^J}% 
\pgf@frac@sumup%
\def\pgf@frac@factor{-1}%
\pgf@frac@parse% 
}% 
\def\pgf@frac@div/{% 
\def\pgf@local@frac@above{0}%
\def\pgf@local@frac@denominator{}%
\pgf@frac@parse% 
}%
\def\pgf@frac@prod *{%
\mymessage{* found^^J}%
\def\pgf@local@frac@above{1}%
%\mymessage{numerator was \pgf@prod@frac@numerator, denominator was \pgf@prod@frac@denominator^^J}%
\ifnum\pgf@local@frac@isprod=1
\pgfmathtruncatemacro{\pgf@prod@frac@numerator}{%
    \pgf@prod@frac@numerator*\pgf@local@frac@numerator}%
\pgfmathtruncatemacro{\pgf@prod@frac@denominator}{%
    \pgf@prod@frac@denominator*\pgf@local@frac@denominator}%
%\mymessage{numerator is \pgf@prod@frac@numerator, denominator is \pgf@local@frac@denominator^^J}%
\else
\def\pgf@local@frac@isprod{1}%
\pgfmathtruncatemacro{\pgf@prod@frac@numerator}{%
    \pgf@local@frac@numerator}%
\pgfmathtruncatemacro{\pgf@prod@frac@denominator}{%
    \pgf@local@frac@denominator}%
\fi
\def\pgf@local@frac@numerator{}%
\def\pgf@local@frac@denominator{1}%
\pgf@frac@consume% 
}%
% 
\def\pgf@frac@wrapupmul{% 
\mymessage{wrap up *^^J}%
\mymessage{\pgf@prod@frac@numerator*\pgf@local@frac@numerator/\pgf@prod@frac@denominator*\pgf@local@frac@denominator^^J}%
 \pgfmathtruncatemacro{\pgf@local@frac@numerator}{%
  \pgf@prod@frac@numerator*\pgf@local@frac@numerator}%
 \pgfmathtruncatemacro{\pgf@local@frac@denominator}{%
  \pgf@prod@frac@denominator*\pgf@local@frac@denominator}%
\mymessage{now \pgf@local@frac@numerator/\pgf@local@frac@denominator^^J}%
 \def\pgf@local@frac@isprod{0}%
}
\def\pgf@frac@sumup{% 
 \ifnum\pgf@local@frac@isprod=1
  \pgf@frac@wrapupmul%
 \fi
 \ifnum\pgf@frac@factor<0
 \mymessage{negative^^J}%
 \fi
 \pgfmathtruncatemacro{\pgf@current@frac@numerator}{%
 \pgf@frac@factor*\pgf@frac@denominator*\pgf@local@frac@numerator+%
 \pgf@frac@numerator*\pgf@local@frac@denominator}%
 \mymessage{numerator:\pgf@frac@factor*\pgf@frac@denominator*\pgf@local@frac@numerator+%
 \pgf@frac@numerator*\pgf@local@frac@denominator^^J}%
 \pgfmathtruncatemacro{\pgf@current@frac@denominator}{%
 \pgf@frac@denominator*\pgf@local@frac@denominator}%
 \mymessage{denominator:\pgf@frac@denominator*\pgf@local@frac@denominator^^J}%
 \mymessage{current numerator=\pgf@current@frac@numerator, current denominator=\pgf@current@frac@denominator^^J}%
 %\mymessage{\pgf@frac@denominator*\pgf@local@frac@denominator^^J}%
 \pgfmathtruncatemacro{\pgf@current@gcd}{gcd(\pgf@current@frac@denominator,%
 \pgf@current@frac@numerator)}%
 \pgfmathtruncatemacro{\pgf@frac@denominator}{\pgf@current@frac@denominator/\pgf@current@gcd}%
 \pgfmathtruncatemacro{\pgf@frac@numerator}{\pgf@current@frac@numerator/\pgf@current@gcd}%
%\mymessage{fraction now:\pgf@frac@numerator/\pgf@frac@denominator^^J}%
\def\pgf@local@frac@above{1}%
\def\pgf@local@frac@numerator{}%
\def\pgf@local@frac@denominator{1}%
\def\pgf@local@frac@isprod{0}%
\def\pgf@prod@frac@numerator{1}%
\def\pgf@prod@frac@denominator{1}%
}%
\makeatother
\def \x {1/2}
\def \y {4/7}
\def \z {3}
\def \w {4}
\newcommand{\PrintFrac}[1]{\begingroup%
\def\pft##1/##2;{\def\mynum{##1}\def\myden{##2}}%
%\message{massaging #1^^J}%
\edef\temp{\noexpand\pgfmathsetmacro{\noexpand\ftest}{intfrac("#1")}}%
\temp%
\expandafter\pft\ftest;%
\ifnum\myden=1
\ensuremath{\mynum}%
\else
\ensuremath{\frac{\mynum}{\myden}}%
\fi
\endgroup}
\begin{document}
Consider the Matrix:
\[
\mathbb{A}=\left [
\begin{matrix}
\x & \y \\
\z & \w
\end{matrix}
\right ]
\]
Determinant should be calculated by:
\[
\det(\mathbb{A})=\PrintFrac{\x} \cdot \w - 
(\PrintFrac{\y} \cdot \z) 
= \PrintFrac{\x*\w} - 
\PrintFrac{\y*\z} = \PrintFrac{\x*\w-\z*\y}
\]

\[\det(\mathbb{A})=\frac{1}{2} \cdot \w - (\frac{4}{7} \cdot \z) = 2 -\frac{12}{7} = \frac{2}{7}
\]

\PrintFrac{1/2+3*2/7-4*3/5}
\end{document}

在此处输入图片描述

这不是一个完全自动化的解决方案,但它涵盖了更多的情况。这是通过

  1. 用于fpu计算,
  2. 使用frac shift=2默认值,并且
  3. frac denom在更复杂的情况下添加明确说明。

这些操作都是通过\PrintFrac宏完成的,宏会计算分数并执行上述操作。它需要一个可选参数,您可以在其中更改键。

\documentclass{article}
\usepackage{amsmath,amsfonts}
\usepackage[nice]{nicefrac}
\usepackage{pgf}
\usepgflibrary{fpu}
\def \x {1/2}
\def \y {4/7}
\def \z {3}
\def \w {4}
\newcommand{\PgfmathsetmacroFPU}[2]{\begingroup% https://tex.stackexchange.com/a/503835
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\pgfmathsetmacro{#1}{#2}%
\pgfmathsmuggle#1\endgroup}%
\newcommand{\PrintFrac}[2][]{%
\PgfmathsetmacroFPU{\temp}{#2}%
\begingroup\pgfkeys{/pgf/number format/.cd,frac,frac whole=false,
/pgf/number format/frac shift=1,#1}%
\pgfmathprintnumber{\temp}\endgroup}
\begin{document}
\pgfkeys{/pgf/number format/.cd,frac, frac whole=false}%
Consider the Matrix:
\[
\mathbb{A}=\left [
\begin{matrix}
\x & \y \\
\z & \w
\end{matrix}
\right ]
\]
Determinant should be calculated by:
\[
\det(\mathbb{A})=\PrintFrac{\x} \cdot \w - 
(\PrintFrac{\y} \cdot \z) 
= \PrintFrac{\x*\w} - 
\PrintFrac{\y*\z} = \PrintFrac[frac denom=7]{\x*\w-\z*\y}
\]
\end{document}

在此处输入图片描述

PS我确实认为应该可以计算出一个涵盖所有情况的解析器。

相关内容