diff options
Diffstat (limited to 'macros/latex/contrib/skmath/skmath.tex')
-rw-r--r-- | macros/latex/contrib/skmath/skmath.tex | 1072 |
1 files changed, 1072 insertions, 0 deletions
diff --git a/macros/latex/contrib/skmath/skmath.tex b/macros/latex/contrib/skmath/skmath.tex new file mode 100644 index 0000000000..424e795f6b --- /dev/null +++ b/macros/latex/contrib/skmath/skmath.tex @@ -0,0 +1,1072 @@ +%% skmath improved math commands +%% +%% Copyright (C) 2012-2019 by Simon Sigurdhsson <sigurdhsson@gmail.com> +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% 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.3 or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% The Current Maintainer of this work is Simon Sigurdhsson. +%% +%% This work consists of the file skmath.tex +%% and the derived file skmath.sty. +\PassOptionsToPackage{intlimits,sumlimits,namelimits}{amsmath} +\documentclass[commonsets,load]{skdoc} +\usepackage{amsmath} +\usepackage{csquotes} +\ProvideDocumentCommand\d{m}{#1} +\ProvideDocumentCommand\pd{smm}{#2#3} +\ProvideDocumentCommand\td{mm}{#1#2} +\ProvideDocumentCommand\abs{m}{#1} +\ProvideDocumentCommand\norm{m}{#1} +\ProvideDocumentCommand\abs{m}{#1} +\ProvideDocumentCommand\P{m}{#1} +\ProvideDocumentCommand\given{}{} +\ProvideDocumentCommand\E{m}{#1} +\ProvideDocumentCommand\var{m}{#1} +\ProvideDocumentCommand\cov{mm}{#1#2} +\ProvideDocumentCommand\N{}{} +\ProvideDocumentCommand\Z{}{} +\ProvideDocumentCommand\Q{}{} +\ProvideDocumentCommand\R{}{} +\ProvideDocumentCommand\C{}{} +\ProvideDocumentCommand\ii{}{i} +\ProvideDocumentCommand\jj{}{j} +\ProvideDocumentCommand\ee{}{e} +\ProvideDocumentCommand\sfrac{mm}{#1#2} +\ProvideDocumentCommand\argmin{om}{#1} +\ProvideDocumentCommand\argmax{om}{#1} + +% Declare the target files +\SelfPreambleTo{\mypreamble} +\DeclareFile[key=package,preamble=\mypreamble]{skmath.sty} +\OnlyDescription + +% Hack for LaTeX3 code +\ExplSyntaxOn +\cs_set_protected_nopar:Npn\ExplHack{ +\char_set_catcode_letter:n{ 58 } +\char_set_catcode_letter:n{ 95 } } +\ExplSyntaxOff + +% This is where the documentation begins +\begin{document} + % Change & version info + \version{0.5} + \changes{0.1}{Initial version} + \changes{0.1c}{Moved package from \pkg{docstrip} to \pkg{skdoc}} + \changes{0.1d}{Fixed fatal documentation and package errors} + \changes{0.1e}{Added statistics commands} + \changes{0.1g}{Documentation fixes} + \changes{0.2}{Use \pkg{expl3} functionality throughout the package} + \changes{0.3}{Added \cs{min}/\cs{max} and friends. Added \cs{pd}} + \changes{0.3a}{Added \cs{sinh}, \cs{cosh} and \cs{tanh}} + \changes{0.3b}{Detect empty arguments in trigonometric and logarithmic functions, fix \cs{ln}} + \changes{0.4}{Added \opt{notation} option, macros for complex numbers} + \changes{0.4a}{Replaced deprecated/removed \pkg{expl3} constructs} + \changes{0.4b}{Track \pkg{expl3} changes (thanks to Joseph Wright)} + \changes{0.5}{Added \cs{td} and \cs{ee}} + % Don't forget to update the version number and release date of + % the package declaration in the implementation! + + % Metadata + \package[ctan=skmath,vcs=https://github.com/urdh/skmath]{skmath} + \author{Simon Sigurdhsson} + \email{sigurdhsson@gmail.com} + + % First page + \maketitle + \begin{abstract} + The \thepackage\ package provides improved and new math commands + for superior typesetting with less effort. + \end{abstract} + + \section{Introduction} + This package intends to provide helpful (re-)definitions of commands + related to typesetting mathematics, and specifically typesetting + them in a more intuitive, less verbose and more beautiful way. + It was originally not intended for use by the public, and as such + there may be incompatibilities with other packages of which I am + not aware, but I figured it could be useful to other people as well. + + \section{Usage} + \subsection{Options} + As of version \theversion, the package provides two key-value options. + + \Option{commonsets}\WithValues{true,false}\AndDefault{false} + Optionally define \cs{N}, \cs{Z}, \cs{Q}, \cs{R} and \cs{C} as blackboard + variants of the respective letters, to represent the common sets + of numbers. + + \Option{notation}\WithValues{iso,english,german,legacy}\AndDefault{legacy} + This option controls the style of a few typographic elements that differ + between countries and standards (such as the style of integrals, derivatives + and greek letters). + + \subsection{New commands} + The package defines a number of new commands that aid in typesetting + certain mathematical formulae. + + \DescribeMacro\N + \DescribeMacro\Z + \DescribeMacro\Q + \DescribeMacro\R + \DescribeMacro\C + These commands are only available if the \opt{commonsets} + option is given. They typeset the set of natural, integer, rational, + real and complex numbers respectively. +\begin{example} +\begin{equation*} + \N, \Z, \Q, \R, \C. +\end{equation*} +\end{example} + + \DescribeMacro\ii + \DescribeMacro\jj + These commands typeset the imaginary unit (either \(\ii\) as used in + mathematics or \(\jj\) as used in electrotechnology). While normal use + of the package simply results in italic characters, setting the \opt{notation} + option to \texttt{iso} will set these upright. + + \DescribeMacro\ee + This command typesets Euler's number \(\ee = \sum_{n=0}^\infty\frac{1}{n!}\). + The style is affected by the \opt{notation} option in the same way as \Macro\exp. + + \DescribeMacro\norm{<expression>} + \DescribeMacro\abs{<expression>} + The commands \Macro\norm and \Macro\abs, quite expectedly, typeset + the norm ans absolute value of an expression, respectively. They + have one mandatory argument (the expression), and different norms + can be achieved by appending a subscript after the argument of + \Macro\norm. +\begin{example} +\begin{equation*} + \norm{\vec{x}}_p = + \left(\sum_{i=1}^n \abs{x_i}^p\right)% + ^{\sfrac{1}{p}} +\end{equation*} +\end{example} + + \DescribeMacro\d{<variable>} + There is also a command \Macro\d, with one mandatory argument, that + typesets the differential part of an integral. +\begin{example} +\begin{equation*} + \int_{\R}\! \frac{\sin{x}}{x} \d{x} +\end{equation*} +\end{example} + + \DescribeMacro\pd*{<function>}{<var>,\meta{var},...} + This macro typesets a partial derivative. The starred variant typesets + derivatives as subscripts, i.e. \(\pd*{f}{x^2,y}\), while the unstarred + variant typesets full fractions: +\begin{example} +\begin{equation*} + \pd{f}{x^m,y^n} +\end{equation*} +\end{example} + + As the example shows, the comma-separated list of variables also + supports superscripts to denote the number of derivatives, and the + sum of the variables is automatically calculated. + + \DescribeMacro\td{<function>}{<var>} + This macro typesets a total derivative. Unlike \Macro\pd, this macro does + not have a starred variant, and only typesets full fractions: +\begin{example} +\begin{equation*} + \td{f}{x^m} +\end{equation*} +\end{example} + + \DescribeMacro\E{<expression>} + The command \Macro\E typesets the expectation of a random variable. +\begin{example} +\begin{equation*} + \E{\hat{\mu}} = \mu +\end{equation*} +\end{example} + + \DescribeMacro\P{<expression>\AlsoMacro\given <expression>} + The \Macro\P command typesets a probability. The \Macro\given command + can be used to typeset conditional probabilities, within \Macro\P. +\begin{example} +\begin{equation*} + \P{A\given B} = + \frac{\P{B\given A}\P{A}}{\P{B}} +\end{equation*} +\end{example} + + \DescribeMacro\var{<expression>} + \DescribeMacro\cov{<expression>}{<expression>} + The commands \Macro\var and \Macro\cov typeset the variance and + covariance of an expression. +\begin{example} +\begin{gather*} + \var{X} = \E{(X-\mu)^2}\\ + \cov{X}{Y} = \E{XY}-\E{X}\E{Y} +\end{gather*} +\end{example} + + \subsection{Improved commands} + In addition to adding new commands, this package also redefines + already existing commands in a mostly backwards-compatible way + to improve their usefulness. + + \DescribeMacro\sin[<power>]{<expression>} + \DescribeMacro\arcsin{<expression>} + \DescribeMacro\cos[<power>]{<expression>} + \DescribeMacro\arccos{<expression>} + \DescribeMacro\tan[<power>]{<expression>} + \DescribeMacro\arctan{<expression>} + \DescribeMacro\cot[<power>]{<expression>} + \DescribeMacro\sinh[<power>]{<expression>} + \DescribeMacro\cosh[<power>]{<expression>} + \DescribeMacro\tanh[<power>]{<expression>} + The trigonometric functions have been redefined + to typeset more easily. They typeset \meta{expression} as an + argument of the expression, and (if applicable) \meta{power} as + a superscript between the function and its argument, + \emph{e.g.} \(\sin[2]{\phi}\). + When the argument is empty, no parentheses are emitted: \(\cos{}\). + + \DescribeMacro\ln{<expression>} + The natural logarithm macro \Macro\ln has also been redefined to + require an argument which is typeset as the argument of the logarithm. + \DescribeMacro\log[<base>]{<expression>} + The related macro \Macro\log is redefined in a similar way, but also + accepts an optional argument denoting the base of the logarithm: + \(\log[2]{x}\). + As with the trigonometric functions, no parentheses are emitted if + the mandatory argument is empty: \(\log{}\). + + \DescribeMacro\exp*{<expression>} + The exponential, \Macro\exp, is redefined to typeset its argument as a + superscript of \(\ee\) in some display styles, and as an argument of + \(\mathrm{exp}\) otherwise: + \begin{equation*} + \exp{\sqrt{2}\exp{x}} + \end{equation*} + Additionally, it is possible to force the \(\mathrm{exp}\) mode by + using the starred variant. + + \DescribeMacro\min*[<domain>]{<expression>} + \DescribeMacro\argmin*[<domain>]{<expression>} + \DescribeMacro\max*[<domain>]{<expression>} + \DescribeMacro\argmax*[<domain>]{<expression>} + \DescribeMacro\sup*[<domain>]{<expression>} + \DescribeMacro\inf*[<domain>]{<expression>} + The maximum/minimum macros have been redefined in a manner similar to + the trigonometric functions. They typeset \meta{expression} inside + curly brackets (the starred version omits the brackets), with the + optional \meta{domain} typeset in a subscript after the operator + (\emph{e.g.} \(\min*[x\in\R_{+}]{f(x)}\)). Argument variants are also + provided, and the \meta{expression} is centered underneath the operator + if possible: + \begin{equation*} + \argmin*[x\in\R_{+}]{f(x)} + \end{equation*} + + \subsection{Stylistic changes} + Some commands have been redefined in a completely backwards-compatible + way to improve the end result of their typesetting. + + \DescribeMacro\frac{<numerator>}{<denominator>} + The \Macro\frac command has been changed to improve typesetting, + allowing displaystyle math in some settings. + + \DescribeMacro\bar{<expression>} + \DescribeMacro\vec{<expression>} + The \Macro\bar command has been changed to cover the entire + \meta{expression} (\emph{i.e.} \(\bar{uv}\)), and \Macro\vec has + been changed to match the \cs{vectorsym} command provided by + \pkg{isomath}. + + \DescribeMacro\Re{<expression>} + \DescribeMacro\Im{<expression>} + These commands typeset the real and imaginary part of a number. Standard use + of the package takes definitions roughly from \pkg{amsmath}, while setting + the \opt{notation} option to \texttt{iso} changes the definitions to match + ISO~80000-2. + + \section{Known issues} + A list of current issues is available in the Github repository of this + package\footnote{\url{https://github.com/urdh/skmath/issues}}, but as + of the release of \theversion, there is one known issue. + \begin{description} + \item[\#15] The package is incompatible with (at least) + \pkg{blindtext}, when including math in the blind text. This + is due to the redifinition of \cs{sin} (and friends), which + is incompatible with the original \pkg{amsmath} definition. + This is a feature, not a bug. + \end{description} + + If you discover any bugs in this package, please report them to the issue + tracker in the \thepackage\ Github repository. + + \Implementation\ExplHack + \section{Implementation} + The package implementation is very simple. First, we do the standard + \LaTeXe\ preamble thing, then we require some dependencies. + \changes{0.1b}{Load \pkg{amsmath} with \texttt{intlimits} option} + \changes{0.2a}{Load \pkg{amsmath} with more \texttt{limits} options} +\begin{MacroCode}{package} +\RequirePackage{expl3,l3keys2e,xparse} +\ProvidesExplPackage{skmath} + {2018/12/29}{0.5}{improved math commands} +\PassOptionsToPackage{intlimits,sumlimits,namelimits}{amsmath} +\RequirePackage{amssymb,mathtools,xfrac} +\end{MacroCode} + +We start by declaring internal options related to the notation styles. +First, some placeholders to detect failures. +\begin{MacroCode}{package} +\msg_new:nnnn{skmath}{undefined-macro}{The~macro~`\token_to_str:N#1'~was~undefined!} + {This~is~an~error~in~the~notation~option~handling.~Please~file~an~issue\\ + on~Github~(https://github.com/urdh/skmath/issues)~with~a~copy~of~this\\ + message~attached~as~well~as~a~list~of~the~options~passed~to~`skmath'.} +\cs_gset_nopar:Npn\__skmath_integral_d:{ + \msg_critical:nnn{skmath}{undefined-macro}{\__skmath_integral_d:} +} +\cs_gset_nopar:Npn\__skmath_natural_log_e:{ + \msg_critical:nnn{skmath}{undefined-macro}{\__skmath_natural_log_e:} +} +\cs_gset_nopar:Npn\__skmath_imaginary_unit:n#1{ + \msg_critical:nnn{skmath}{undefined-macro}{\__skmath_imaginary_unit:n} +} +\cs_gset_nopar:Npn\__skmath_total_derivative_d:{ + \msg_critical:nnn{skmath}{undefined-macro}{\__skmath_total_derivative_d:n} +} +\end{MacroCode} +Then, the key-value options. +\begin{MacroCode}{package} +\keys_define:nn{skmath / internal}{ + % More on this: + % * http://en.wikipedia.org/wiki/Typographical_conventions_in_mathematical_formulae + % * ISO 80000-2 + % * http://www.tug.org/TUGboat/Articles/tb18-1/tb54becc.pdf + % * http://tex.stackexchange.com/q/14821/66 + integral-d .choice:, + integral-d .value_required:n = true, + integral-d / upright .code:n = { \cs_gset_nopar:Npn\__skmath_integral_d:{{\operator@font d}} }, + integral-d / slanted .code:n = { \cs_gset_nopar:Npn\__skmath_integral_d:{{d}} }, + isomath .bool_set:N = \g__skmath_load_isomath_bool, + isomath .value_required:n = true, + natural-log .choice:, + natural-log .value_required:n = true, + natural-log / upright .code:n = { \cs_gset_nopar:Npn\__skmath_natural_log_e:{{\operator@font e}} }, + natural-log / slanted .code:n = { \cs_gset_nopar:Npn\__skmath_natural_log_e:{{e}} }, + imaginary-unit .choice:, + imaginary-unit .value_required:n = true, + imaginary-unit / upright .code:n = { \cs_gset_nopar:Npn\__skmath_imaginary_unit:n##1{{\operator@font ##1}} }, + imaginary-unit / slanted .code:n = { \cs_gset_nopar:Npn\__skmath_imaginary_unit:n##1{{##1}} }, + complex-part-symbols .bool_set_inverse:N = \g__skmath_iso_complex_parts_bool, + complex-part-symbols .value_required:n = true, + total-derivative-d .choice:, + total-derivative-d .value_required:n = true, + total-derivative-d / upright .code:n = { \cs_gset_nopar:Npn\__skmath_total_derivative_d:{{\operator@font d}} }, + total-derivative-d / slanted .code:n = { \cs_gset_nopar:Npn\__skmath_total_derivative_d:{{d}} }, +} +\end{MacroCode} + +We also declare the \enquote{public} options. +\begin{MacroCode}{package} +\keys_define:nn{skmath}{ + commonsets .bool_set:N = \g__skmath_define_common_sets_bool, + commonsets .default:n = true, + commonsets .initial:n = false, + % TODO: write tests for the notation option + notation .choice:, + notation / iso .meta:nn = {skmath / internal}{ + integral-d = upright, + isomath = true, + natural-log = upright, + imaginary-unit = upright, + complex-part-symbols = false, + total-derivative-d = upright, + }, + notation / german .meta:nn = {skmath / internal}{ + integral-d = upright, + isomath = true, + natural-log = slanted, %??? + imaginary-unit = slanted, %??? + complex-part-symbols = true, %??? + total-derivative-d = upright, %??? + }, + notation / english .meta:nn = {skmath / internal}{ + integral-d = slanted, + isomath = true, + natural-log = slanted, %??? + imaginary-unit = slanted, %??? + complex-part-symbols = true, %??? + total-derivative-d = slanted, %??? + }, + notation / legacy .meta:nn = {skmath / internal}{ + integral-d = upright, + isomath = true, + natural-log = slanted, + imaginary-unit = slanted, + complex-part-symbols = true, + total-derivative-d = slanted, + }, + % Possibly more style sets... ? + notation .initial:n = legacy, % Or is it? Perhaps a legacy option is required. + notation .value_required:n = true, + % Note also that the styles should probably affect isomath and/or other packages. +} +\ProcessKeysOptions{skmath} +\end{MacroCode} + +We optionally load \pkg{isomath}, depending on notation style. +\begin{MacroCode}{package} +\bool_if:NTF\g__skmath_load_isomath_bool{ + \RequirePackage{isomath} +}{ + % TODO: check if there is an alternative package we should load here. +} +\end{MacroCode} + + Then, a utility conditional\ldots + \begin{macro*}{\__skmath_if_novalue_or_empty:nF}[1] + {Token or string} +\begin{MacroCode}{package} +\prg_new_conditional:Npnn\__skmath_if_novalue_or_empty:n#1{F}{ + \IfNoValueTF{#1}{ + \prg_return_true: + }{ + \tl_if_empty:nTF{#1}{ + \prg_return_true: + }{ + \prg_return_false: + } + } +} +\end{MacroCode} + \end{macro*} + + \ldots and a helper macro. + \begin{macro*}{\__skmath_parens:n}[1] + {Argument to wrap in parentheses, unless empty} +\begin{MacroCode}{package} +\cs_new_nopar:Npn\__skmath_parens:n#1{ + \__skmath_if_novalue_or_empty:nF{#1}{\left(#1\right)} +} +\end{MacroCode} + \end{macro*} + + We optionally provide commands to typeset common sets. +\begin{MacroCode}{package} +\bool_if:NT\g__skmath_define_common_sets_bool{ +\end{MacroCode} + \begin{macro}{\N} + \changes{0.1b}{Moved to \textsf{xparse} command definition} +\begin{MacroCode}{package} + \NewDocumentCommand\N{}{\ensuremath{\mathbb{N}}} +\end{MacroCode} + \end{macro} + \begin{macro}{\Z} + \changes{0.1b}{Moved to \textsf{xparse} command definition} +\begin{MacroCode}{package} + \NewDocumentCommand\Z{}{\ensuremath{\mathbb{Z}}} +\end{MacroCode} + \end{macro} + \begin{macro}{\Q} + \changes{0.1b}{Moved to \textsf{xparse} command definition} +\begin{MacroCode}{package} + \NewDocumentCommand\Q{}{\ensuremath{\mathbb{Q}}} +\end{MacroCode} + \end{macro} + \begin{macro}{\R} + \changes{0.1b}{Moved to \textsf{xparse} command definition} +\begin{MacroCode}{package} + \NewDocumentCommand\R{}{\ensuremath{\mathbb{R}}} +\end{MacroCode} + \end{macro} + \begin{macro}{\C} + \changes{0.1b}{Moved to \textsf{xparse} command definition} +\begin{MacroCode}{package} + \NewDocumentCommand\C{}{\ensuremath{\mathbb{C}}} +\end{MacroCode} + \end{macro} +\begin{MacroCode}{package} +} +\end{MacroCode} + + Then, macros related to complex numbers are defined. + \begin{macro}{\ii} +\begin{MacroCode}{package} +\DeclareDocumentCommand\ii{}{\ensuremath{\__skmath_imaginary_unit:n{i}}} +\end{MacroCode} + \end{macro} + \begin{macro}{\jj} +\begin{MacroCode}{package} +\DeclareDocumentCommand\jj{}{\ensuremath{\__skmath_imaginary_unit:n{j}}} +\end{MacroCode} + \end{macro} + \begin{macro}{\Re} +\begin{MacroCode}{package} +\bool_if:NTF\g__skmath_iso_complex_parts_bool{ + \cs_new_eq:NN\__skmath_Re:\Re + \DeclareDocumentCommand\Re{m}{\ensuremath{\__skmath_Re:\__skmath_parens:n{#1}}} +}{ + \DeclareDocumentCommand\Re{m}{\ensuremath{{\operator@font Re}{#1}}} +} +\end{MacroCode} + \end{macro} + \begin{macro}{\Im} +\begin{MacroCode}{package} +\bool_if:NTF\g__skmath_iso_complex_parts_bool{ + \cs_new_eq:NN\__skmath_Im:\Im + \DeclareDocumentCommand\Im{m}{\ensuremath{\__skmath_Im:\__skmath_parens:n{#1}}} +}{ + \DeclareDocumentCommand\Im{m}{\ensuremath{{\operator@font Im}{#1}}} +} +\end{MacroCode} + \end{macro} + + This is followed by commands to typeset the norm and absolute value. + \begin{macro}{\abs} +\begin{MacroCode}{package} +\DeclarePairedDelimiter\abs{\lvert}{\rvert} +\end{MacroCode} + \end{macro} + \begin{macro}{\norm} +\begin{MacroCode}{package} +\DeclarePairedDelimiter\norm{\lVert}{\rVert} +\end{MacroCode} + \end{macro} + + Next come the statistical commands. + \begin{macro}{\E} + \changes{0.1e}{Added \cs{E} command} + \changes{0.1f}{Fixed \enquote{Command \cs{E} already defined!} error} + \changes{0.2}{Use \cs{operatorname}} + Here, we define \cs{E} after the preamble since it may break otherwise. +\begin{MacroCode}{package} +\AtBeginDocument{ + \DeclareDocumentCommand\E{m}{% + \ensuremath{\operatorname{E}\left[#1\right]}% + } +} +\end{MacroCode} + \end{macro} + The \Macro\P command saves any old \Macro\given command, replacing + it locally with the new \Macro\given command provided by the package. + \begin{macro}{\P} + \changes{0.1e}{Added \cs{P} command} + \changes{0.2}{Use \cs{operatorname}, use \cs{cs_new_eq:NN} instead of + \cs{let}} +\begin{MacroCode}{package} +\DeclareDocumentCommand\P{m}{% + \ensuremath{\operatorname{P}% + \mkern-1.5mu\left(% + \cs_set_eq:NN\__skmath_saved_given:\given% +\end{MacroCode} + \begin{macro}{\given} + \changes{0.1e}{Added \cs{given} command} +\begin{MacroCode}{package} + \DeclareDocumentCommand\given{}{\mid}% +\end{MacroCode} + \end{macro} +\begin{MacroCode}{package} + #1% + \cs_set_eq:NN\given\__skmath_saved_given:% + \right)% + }% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\var} + \changes{0.1e}{Added \cs{var} command} + \changes{0.2}{Use \cs{operatorname}} +\begin{MacroCode}{package} +\DeclareDocumentCommand\var{m}{% + \ensuremath{\operatorname{Var}\left(#1\right)}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\cov} + \changes{0.1e}{Added \cs{cov} command} + \changes{0.2}{Use \cs{operatorname}} +\begin{MacroCode}{package} +\DeclareDocumentCommand\cov{mm}{% + \ensuremath{\operatorname{Cov}\left(#1,#2\right)}% +} +\end{MacroCode} + \end{macro} + + We replace all trigonometric functions and some other + common functions with alternatives that take an argument + (or optionally, several arguments). +\begin{MacroCode}{package} +\cs_new_eq:NN\__skmath_sin:\sin +\cs_new_eq:NN\__skmath_cos:\cos +\cs_new_eq:NN\__skmath_tan:\tan +\cs_new_eq:NN\__skmath_cot:\cot +\cs_new_eq:NN\__skmath_arcsin:\arcsin +\cs_new_eq:NN\__skmath_arccos:\arccos +\cs_new_eq:NN\__skmath_arctan:\arctan +\cs_new_eq:NN\__skmath_sinh:\sinh +\cs_new_eq:NN\__skmath_cosh:\cosh +\cs_new_eq:NN\__skmath_tanh:\tanh +\cs_new_eq:NN\__skmath_ln:\ln +\cs_new_eq:NN\__skmath_log:\log +\cs_new_eq:NN\__skmath_exp:\exp +\cs_new_eq:NN\__skmath_min:\min +\cs_new_eq:NN\__skmath_max:\max +\cs_new_eq:NN\__skmath_sup:\sup +\cs_new_eq:NN\__skmath_inf:\inf +\end{MacroCode} + \begin{macro}{\sin} +\begin{MacroCode}{package} +\RenewDocumentCommand\sin{om}{% + \IfNoValueTF{#1} + {\ensuremath{\__skmath_sin:\__skmath_parens:n{#2}}} + {\ensuremath{\__skmath_sin:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\cos} +\begin{MacroCode}{package} +\RenewDocumentCommand\cos{om}{% + \IfNoValueTF{#1} + {\ensuremath{\__skmath_cos:\__skmath_parens:n{#2}}} + {\ensuremath{\__skmath_cos:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\tan} +\begin{MacroCode}{package} +\RenewDocumentCommand\tan{om}{% + \IfNoValueTF{#1} + {\ensuremath{\__skmath_tan:\__skmath_parens:n{#2}}} + {\ensuremath{\__skmath_tan:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\cot} +\begin{MacroCode}{package} +\RenewDocumentCommand\cot{om}{% + \IfNoValueTF{#1} + {\ensuremath{\__skmath_cot:\__skmath_parens:n{#2}}} + {\ensuremath{\__skmath_cot:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\arcsin} +\begin{MacroCode}{package} +\RenewDocumentCommand\arcsin{m}{% + \ensuremath{\__skmath_arcsin:\__skmath_parens:n{#1}}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\arccos} +\begin{MacroCode}{package} +\RenewDocumentCommand\arccos{m}{% + \ensuremath{\__skmath_arccos:\__skmath_parens:n{#1}}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\arctan} +\begin{MacroCode}{package} +\RenewDocumentCommand\arctan{m}{% + \ensuremath{\__skmath_arctan:\__skmath_parens:n{#1}}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\sinh} +\begin{MacroCode}{package} +\RenewDocumentCommand\sinh{om}{% + \IfNoValueTF{#1} + {\ensuremath{\__skmath_sinh:\__skmath_parens:n{#2}}} + {\ensuremath{\__skmath_sinh:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\cosh} +\begin{MacroCode}{package} +\RenewDocumentCommand\cosh{om}{% + \IfNoValueTF{#1} + {\ensuremath{\__skmath_cosh:\__skmath_parens:n{#2}}} + {\ensuremath{\__skmath_cosh:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\tanh} +\begin{MacroCode}{package} +\RenewDocumentCommand\tanh{om}{% + \IfNoValueTF{#1} + {\ensuremath{\__skmath_tanh:\__skmath_parens:n{#2}}} + {\ensuremath{\__skmath_tanh:\c_math_superscript_token{#1}\__skmath_parens:n{#2}}}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\ln} +\begin{MacroCode}{package} +\RenewDocumentCommand\ln{m}{% + \ensuremath{\__skmath_ln:\__skmath_parens:n{#1}}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\log} +\begin{MacroCode}{package} +\RenewDocumentCommand\log{om}{% + \IfNoValueTF{#1} + {\ensuremath{\__skmath_log:\__skmath_parens:n{#2}}} + {\ensuremath{\__skmath_log:\c_math_subscript_token{#1}\__skmath_parens:n{#2}}}% +} +\end{MacroCode} + \end{macro} + \begin{macro}{\ee} + \begin{MacroCode}{package} + \DeclareDocumentCommand\ee{}{\ensuremath{\__skmath_natural_log_e:}} + \end{MacroCode} + \end{macro} + \begin{macro}{\exp} + \changes{0.1b}{Moved to \textsf{xparse} command definition} + \changes{0.3a}{Added starred variant} +\begin{MacroCode}{package} +\RenewDocumentCommand\exp{sm}{\ensuremath{ + \IfBooleanTF{#1}{ + \__skmath_exp:\__skmath_parens:n{#2} + }{ + \mathchoice + {\__skmath_natural_log_e:\c_math_superscript_token{#2}} + {\__skmath_exp:\left(#2\right)} + {\__skmath_exp:\left(#2\right)} + {\__skmath_exp:\left(#2\right)} + } +}} +\end{MacroCode} + \end{macro} + \begin{macro*}{\__skmath_minmax_backend:nnn} +\begin{MacroCode}{package} +\cs_new_nopar:Npn\__skmath_minmax_backend:nnnn#1#2#3#4{% + \use:c{__skmath_#1:} + \IfNoValueF{#3}{ + \c_math_subscript_token{ + \mathchoice{\mathclap{#3}}{#3}{#3}{#3} + } + } + \IfBooleanTF{#2}{#4}{\left\{#4\right\}} +} +\end{MacroCode} + \end{macro*} + \begin{macro}{\min} +\begin{MacroCode}{package} +\RenewDocumentCommand\min{som}{% + \ensuremath{\__skmath_minmax_backend:nnnn{min}{#1}{#2}{#3}} +} +\end{MacroCode} + \end{macro} + \begin{macro}{\argmin} +\begin{MacroCode}{package} +\NewDocumentCommand\argmin{som}{% + \ensuremath{\arg\__skmath_minmax_backend:nnnn{min}{#1}{#2}{#3}} +} +\end{MacroCode} + \end{macro} + \begin{macro}{\max} +\begin{MacroCode}{package} +\RenewDocumentCommand\max{som}{% + \ensuremath{\__skmath_minmax_backend:nnnn{max}{#1}{#2}{#3}} +} +\end{MacroCode} + \end{macro} + \begin{macro}{\argmax} +\begin{MacroCode}{package} +\NewDocumentCommand\argmax{som}{% + \ensuremath{\arg\__skmath_minmax_backend:nnnn{max}{#1}{#2}{#3}} +} +\end{MacroCode} + \end{macro} + \begin{macro}{\sup} +\begin{MacroCode}{package} +\RenewDocumentCommand\sup{som}{% + \ensuremath{\__skmath_minmax_backend:nnnn{sup}{#1}{#2}{#3}} +} +\end{MacroCode} + \end{macro} + \begin{macro}{\inf} +\begin{MacroCode}{package} +\RenewDocumentCommand\inf{som}{% + \ensuremath{\__skmath_minmax_backend:nnnn{inf}{#1}{#2}{#3}} +} +\end{MacroCode} + \end{macro} + + The fraction command is modified to improve typesetting. + \begin{macro}{\frac} + \changes{0.1b}{Moved to \textsf{xparse} command definition} +\begin{MacroCode}{package} +\RenewDocumentCommand\frac{mm}{\genfrac{}{}{}{}% + {\displaystyle #1}{\displaystyle #2}} +\end{MacroCode} + \end{macro} + + We introduce a couple of helper macros for \cs{pd} and \cs{td}. + \begin{macro*}{\__skmath_if_numerical_p:n} + \begin{macro*}{\__skmath_if_numerical:nT} + \begin{macro*}{\__skmath_if_numerical:nF} + \begin{macro*}{\__skmath_if_numerical:nTF}[1] + {Token or string} +\begin{MacroCode}{package} +\prg_new_conditional:Npnn\__skmath_if_numerical:n#1{p,T,F,TF}{ + \str_case_x:nnTF{#1}{ + {0}{} + {1}{} + {2}{} + {3}{} + {4}{} + {5}{} + {6}{} + {7}{} + {8}{} + {9}{} + } + {\prg_return_false:} + {\prg_return_false:} +} +\end{MacroCode} + \end{macro*} + \end{macro*} + \end{macro*} + \end{macro*} + \begin{macro*}{\__skmath_pd_vars_sum:n}[1] + {Comma-separated list of variables, possibly with superscripts} +\begin{MacroCode}{package} +\cs_new_nopar:Npn\__skmath_pd_vars_sum:n#1{ + \tl_clear:N\l_tmpa_tl + \int_zero:N\l_tmpa_int + \bool_set_true:N\l_tmpa_bool + \clist_set:Nn\l_tmpa_clist{#1} + \clist_map_inline:Nn\l_tmpa_clist{ + \seq_set_split:Nnn\l_tmpa_seq{^}{##1} + \int_compare:nT{\seq_count:N\l_tmpa_seq<\c_two}{ + \seq_put_right:Nn\l_tmpa_seq{1} + } + \seq_get_right:NN\l_tmpa_seq\l_tmpb_tl + \__skmath_if_numerical:nTF{\tl_use:N\l_tmpb_tl}{ + \int_add:Nn\l_tmpa_int{\tl_use:N\l_tmpb_tl} + }{ + \bool_set_false:N\l_tmpa_bool + \tl_if_empty:NF\l_tmpa_tl{\tl_put_right:Nn\l_tmpa_tl{+}} + \tl_put_right:Nx\l_tmpa_tl{\tl_use:N\l_tmpb_tl} + } + } + \int_compare:nT{\l_tmpa_int>\c_zero}{\int_use:N\l_tmpa_int} + \bool_if:NF\l_tmpa_bool{ + \int_compare:nT{\l_tmpa_int>\c_zero}{+} + \tl_use:N\l_tmpa_tl + } +} +\end{MacroCode} + \end{macro*} + \begin{macro*}{\__skmath_pd_if_vars_sum_above_one_p:n} + \begin{macro*}{\__skmath_pd_if_vars_sum_above_one:nT} + \begin{macro*}{\__skmath_pd_if_vars_sum_above_one:nF} + \begin{macro*}{\__skmath_pd_if_vars_sum_above_one:nTF}[1] + {Comma-separated list of variables, possibly with superscripts} +\begin{MacroCode}{package} +\prg_new_conditional:Npnn\__skmath_pd_if_vars_sum_above_one:n#1{p,T,F,TF}{ + \clist_set:Nn\l_tmpa_clist{#1} + \int_compare:nTF{\clist_count:N\l_tmpa_clist>\c_one}{ + \prg_return_true: + }{ + \clist_pop:NN\l_tmpa_clist\l_tmpa_tl + \seq_set_split:NnV\l_tmpa_seq{^}{\l_tmpa_tl} + \int_compare:nTF{\seq_count:N\l_tmpa_seq<\c_two}{ + \prg_return_false: + }{ + \prg_return_true: + } + } +} +\end{MacroCode} + \end{macro*} + \end{macro*} + \end{macro*} + \end{macro*} + \begin{macro*}{\__skmath_pd_superscript_vars:n}[1] + {Comma-separated list of variables, possibly with superscripts} +\begin{MacroCode}{package} +\cs_new_nopar:Npn\__skmath_pd_superscript_vars:n#1{ + \clist_set:Nn\l_tmpa_clist{#1} + \clist_map_inline:Nn\l_tmpa_clist{ + \partial + \seq_set_split:Nnn\l_tmpa_seq{^}{##1} + \seq_pop:NN\l_tmpa_seq\l_tmpb_tl + \tl_use:N\l_tmpb_tl + \int_compare:nT{\seq_count:N\l_tmpa_seq>0}{ + \seq_pop:NN\l_tmpa_seq\l_tmpb_tl + \c_math_superscript_token + \tl_use:N\l_tmpb_tl + } + } +} +\end{MacroCode} + \end{macro*} + \begin{macro*}{\__skmath_pd_subscript_vars:n}[1] + {Comma-separated list of variables, possibly with superscripts} +\begin{MacroCode}{package} +\cs_new_nopar:Npn\__skmath_pd_subscript_vars:n#1{ + \clist_set:Nn\l_tmpa_clist{#1} + \clist_map_inline:Nn\l_tmpa_clist{ + \seq_set_split:Nnn\l_tmpa_seq{^}{##1} + \seq_pop:NN\l_tmpa_seq\l_tmpa_tl + \int_set:Nn\l_tmpa_int{\c_one} + \int_compare:nT{\seq_count:N\l_tmpa_seq>\c_zero}{ + \seq_pop:NN\l_tmpa_seq\l_tmpb_tl + \int_set:Nn\l_tmpa_int{\tl_use:N\l_tmpb_tl} + } + \prg_replicate:nn{\l_tmpa_int}{\tl_use:N\l_tmpa_tl} + } +} +\end{MacroCode} + \end{macro*} + \begin{macro*}{\__skmath_pd_fraction:nn}[2] + {Tokens representing a mathematical function} + {Comma-separated list of variables, possibly with superscripts} +\begin{MacroCode}{package} +\cs_new_nopar:Npn\__skmath_pd_fraction:nn#1#2{ + \frac{ + \partial + \__skmath_pd_if_vars_sum_above_one:nT{#2}{ + \c_math_superscript_token{\__skmath_pd_vars_sum:n{#2}} + } + {#1} + }{ + \__skmath_pd_superscript_vars:n{#2} + } +} +\end{MacroCode} + \end{macro*} + \begin{macro*}{\__skmath_pd_subscript:nn}[2] + {Tokens representing a mathematical function} + {Comma-separated list of variables, possibly with superscripts} +\begin{MacroCode}{package} +\cs_new_nopar:Npn\__skmath_pd_subscript:nn#1#2{ + {#1}\c_math_subscript_token{ + \__skmath_pd_subscript_vars:n{#2} + } +} +\end{MacroCode} + \end{macro*} + \begin{macro*}{\__skmath_td_fraction:nn}[2] + {Tokens representing a mathematical function} + {A single variable, possibly with a superscript} +\begin{MacroCode}{package} +\cs_new_nopar:Npn\__skmath_td_fraction:nn#1#2{ + \frac{ + \__skmath_total_derivative_d: + \__skmath_pd_if_vars_sum_above_one:nT{#2}{ + \c_math_superscript_token{\__skmath_pd_vars_sum:n{#2}} + } + {#1} + }{ + \__skmath_total_derivative_d: + #2 + } +} +\end{MacroCode} + \end{macro*} + + Definition of \cs{bar}, \cs{pd}, \cs{td} and \cs{d} is deferred until after all + packages are loaded to avoid collisions with other packages. +\begin{MacroCode}{package} +\AtBeginDocument{% +\end{MacroCode} + The \cs{bar} command is modified to impove typesetting. + \begin{macro}{\bar} + \changes{0.1b}{Added \cs{bar} replacement} + \changes{0.1h}{Wrap in \cs{AtBeginDocument}} +\begin{MacroCode}{package} +\DeclareDocumentCommand\bar{m}{% + \ensuremath{\mkern 1.5mu\overline{\mkern-1.5mu{#1}\mkern-1.5mu}\mkern 1.5mu}} +\end{MacroCode} + \end{macro} + + This is the partial derivative macro, but most of the functionality + was defined as private macros earlier. + \begin{macro}{\pd}[3] + {Boolean distinguishing between starred and unstarred variant} + {Tokens representing a mathematical function} + {Comma-separated list of variables, possibly with superscripts} +\begin{MacroCode}{package} +\DeclareDocumentCommand\pd{smm}{ + \ensuremath{ + \IfBooleanTF{#1} + {\__skmath_pd_subscript:nn{#2}{#3}} + {\__skmath_pd_fraction:nn{#2}{#3}} + } +} +\end{MacroCode} + \end{macro} + + We also have the total derivative macro, + \begin{macro}{\td}[2] + {Tokens representing a mathematical function} + {A single variable, possibly with a superscript} +\begin{MacroCode}{package} +\DeclareDocumentCommand\td{mm}{ + \ensuremath{ + \__skmath_td_fraction:nn{#1}{#2} + } +} +\end{MacroCode} + \end{macro} + + We introduce a command to typeset the differential part + of integrals, shamefully stolen from an answer on \TeX.SE. + \begin{macro}{\d} + \changes{0.1a}{Fixed obtuse errors} + \changes{0.1b}{Moved to \textsf{xparse} command definition} + \changes{0.2}{Use \cs{peek_meaning_ignore_spaces:NT} instead of \cs{@ifnextchar}} + \changes{0.3b}{Use \cs{operator@font} instead of \cs{mathrm}} +\begin{MacroCode}{package} +\DeclareDocumentCommand\d{m}{\ensuremath{\,\__skmath_integral_d: #1% + \peek_meaning_ignore_spaces:NT\d{\!}}} +\end{MacroCode} + \end{macro} +\begin{MacroCode}{package} +} +\end{MacroCode} + + Finally, we define a nicer way to denote vectors. + \begin{macro}{\vec} + \changes{0.2}{Use \cs{cs_new_eq:NN} instead of \cs{let}} +\begin{MacroCode}{package} +\cs_set_eq:NN\vec\vectorsym +\end{MacroCode} + \end{macro} + +\begin{MacroCode}{package} +\endinput +\end{MacroCode} + + \Finale + \section{Installation} + The easiest way to install this package is using the package + manager provided by your \LaTeX\ installation if such a program + is available. Failing that, provided you have obtained the package + source (\file{skmath.tex} and \file{Makefile}) from either CTAN + or Github, running \texttt{make install} inside the source directory + works well. This will extract the documentation and code from + \file{skmath.tex}, install all files into the TDS tree at + \texttt{TEXMFHOME} and run \texttt{mktexlsr}. + + If you want to extract code and documentation without installing + the package, run \texttt{make all} instead. If you insist on not + using \texttt{make}, remember that packages distributed using + \pkg{skdoc} must be extracted using \texttt{pdflatex}, \emph{not} + \texttt{tex} or \texttt{latex}. + + \PrintChanges + \PrintIndex +\end{document} |