% \iffalse meta-comment % % Copyright (C) 2012, 2014, 2022 by Robert Fuster % % 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 Robert Fuster % % This work consists of the files calculator.dtx and calculator.ins % and the derived files calculator.sty, calculus.ins, and several % calculator.tex derived files. % % \fi % % \iffalse % %<*driver> \documentclass{ltxdoc} \ProvidesFile{calculator.dtx} [2022/09/15 v.2.1 documented calculator package] \usepackage{calculus} \usepackage{amsmath} \usepackage[lmargin=1.75in,rmargin=1in]{geometry} \usepackage{fancyvrb} \usepackage[colorlinks]{hyperref} \def\fileversion{2.1} \def\filedate{2022/09/15} \GetFileInfo{calculator.dtx} \title{The \textsf{calculator} and \textsf{calculus} packages% \thanks{This document corresponds to \textsf{calculator}~\fileversion{} and \textsf{calculus}~\fileversion, dated \filedate.}\\ Scientific calculations with \LaTeX} \author{Robert Fuster\\ Universitat Polit\`ecnica de Val\`encia \\ \texttt{rfuster@mat.upv.es}} \date{\filedate} \EnableCrossrefs \CodelineIndex \RecordChanges \def\partname{Part} \newcommand{\TBS}{\textbackslash} \newcommand{\Marg}[1]{\textnormal{\marg{#1}}} \newcommand{\newinversion}[1]{\textnormal{\textit{(new in version~#1)}}} \newcommand{\renewinversion}[2][]{\textnormal{\footnote{code modified in version~#2\ifx"#1"\else\space (#1)\fi.}}} \newcommand{\arccot}{\operatorname{arccot}} \newcommand{\arsinh}{\operatorname{arsinh}} \newcommand{\arcosh}{\operatorname{arcosh}} \newcommand{\artanh}{\operatorname{artanh}} \newcommand{\arcoth}{\operatorname{arcoth}} \newcounter{exem}\stepcounter{exem} \newenvironment{exemple}{% \VerbatimEnvironment\begin{VerbatimOut}[gobble=2]{./calculator\theexem.tex}}{% \end{VerbatimOut} \par\medskip\noindent \begin{minipage}{\linewidth} \begin{minipage}[t]{0.45\linewidth} \setlength{\parindent}{2ex} \noindent\textsf{\fbox{Ex. \theexem}} \bigskip\par \catcode`\%=14 \input{./calculator\theexem} \end{minipage}\hfill \begin{minipage}[t]{0.45\linewidth} \small \VerbatimInput{./calculator\theexem.tex} \end{minipage} \end{minipage} \stepcounter{exem}\par\bigskip\noindent} \newcommand{\textttit}[1]{\texttt{\textit{#1}}} %\OnlyDescription \begin{document} \maketitle \DocInput{calculator.dtx} \PrintChanges \PrintIndex \end{document} % % % \fi % % \CheckSum{3913} % \changes{v1.0}{2012/04/25}{First public version} % \changes{v1.0a}{2012/06/10}{calculator.dtx modified to make it autoinstallable. % calculus.dtx embedded in calculus.dtx} % \changes{v2.0}{2014/02/20}{new calculator.dtx and calculator.ins files} % \changes{v2.1}{2022/09/15}{Some bugs fixed} %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z %% Digits \0\1\2\3\4\5\6\7\8\9 %% Exclamation \! Double quote \" Hash (number) \# %% Dollar \$ Percent \% Ampersand \& %% Acute accent \' Left paren \( Right paren \) %% Asterisk \* Plus \+ Comma \, %% Minus \- Point \. Solidus \/ %% Colon \: Semicolon \; Less than \< %% Equals \= Greater than \> Question mark \? %% Commercial at \@ Left bracket \[ Backslash \\ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} % % \DoNotIndex{\newcommand,\newenvironment,\RequirePackage,\begin,\end} % \DoNotIndex{\begingroup,\endgroup,\expandafter,\undefined,\@ifnextchar} % \DoNotIndex{\def,\let,\edef,\xdef,\ifx,\ifdim,\ifnum,\else,\fi,\fi,\fi} % \DoNotIndex{\@whilenum,\advance,\divide,\do,\newdimen,\number} % \DoNotIndex{\noexpand,\ignorespaces,\p@,\z@,\strip@pt} % \DoNotIndex{\MessageBreak} % % \begin{abstract} % The \textsf{calculator} package allows us to use \LaTeX{} as a calculator, % with which we can perform many of the common scientific calculations % (with the limitation in accuracy imposed by the \TeX{} arithmetic). % % This package introduces several new instructions that allow you to do % several calculations with integer and decimal numbers using \LaTeX. % Apart from add, multiply or divide, we can calculate powers, square roots, % logarithms, trigonometric and hyperbolic functions \ldots % In addition, the \textsf{calculator} package supports some elementary calculations with % vectors % in two and three dimensions and square $2\times2$ and $3\times3$ matrices. % \smallskip % The % \textsf{calculus} package adds to the \textsf{calculator} package % several utilities to use and define various functions and their derivatives, % including elementary functions, operations with functions, % polar coordinates and vector-valued real functions. % Version 2.0 adds new capabilities to both packages. % Specifically, now, \textsf{calculator} and \textsf{calculus} % can evaluate the inverse trigonometric % and the inverse hyperbolic functions % (so that we can work with all the classic elementary functions), % and also can do some additional calculation with vectors % (such as the cross product and the angle between two vectors). % Version 2.1 fixes some bugs and calculation problems.\footnote{Thanks to % Schmitz Manuel, Thorsten Wolterin, Jim Cline, % Schremmer Alain and July Tikhonov.} % \end{abstract} % % \tableofcontents % % \section{Introduction} % The \textsf{calculator} package defines some instructions which allow % us to realize algebraic operations % (and to evaluate elementary functions) in our documents. % The operations implemented by the \textsf{calculator} package % include routines of assignment of variables, % arithmetical calculations with real and integer numbers, % two and three dimensional vector and matrix arithmetics % and the computation of square roots, % trigonometrical, exponential, logarithmic and hyperbolic functions. % In addition, some important numbers, such as $\sqrt2$, $\pi$ or $\mathrm e$, % are predefined. % % The name of all these commands is spelled in capital letters % (with very few exceptions: % the commands \cs{DEGtoRAD} and \cs{RADtoDEG} % and the control sequences that define special numbers, as % \cs{numberPI}) % and, in general, they all need one or more mandatory arguments, % the first one(s) of which is(are) number(s) and the last one(s) is(are) % the name(s) of the command(s) where % the results will be stored.\footnote{% % Logically, the control sequences that represent special numbers % (as \cs{numberPI}) does not need any argument.} % The new commands defined in this way work in any \LaTeX{} mode. % % % By example, this instruction % \begin{verbatim} % \MAX{3}{5}{\solution} % \end{verbatim} % stores |5| in the command \cs{solution}. In a similar way, % \begin{verbatim} % \FRACTIONSIMPLIFY{10}{12}{\numerator}{\denominator} % \end{verbatim} % defines \cs{numerator} and \cs{denominator} as |5| i |6|, respectively. % % The \emph{data} arguments should not be necessarily explicit numbers; % it may also consist in commands the value of which is a number. % This allows us to chain several calculations, since in the following % example: % \begin{exemple} % % \tempA=2,5^2 % \SQUARE{2.5}{\tempA} % % \tempB=sqrt(12) % \SQUAREROOT{12}{\tempB} % % \tempC=exp(3,4) % \EXP{3.4}{\tempC} % % \divisio=\tempA/tempB % \DIVIDE{\tempA}{\tempB}{\divisio} % % \sol=\divisio+\tempC % \ADD{\divisio}{\tempC}{\sol} % \begin{align*} % \frac{2.5^2}{\sqrt{12}}+\mathrm{e}^{3.4} % &= \frac{\tempA}{\tempB}+\tempC \\ % &= \divisio+\tempC \\ % &=\sol % \end{align*} % \end{exemple} % Observe that, in this example, we have followed exactly the same steps % that we would do to calculate % $\frac{2.5^2}{\sqrt{12}}+\mathrm{e}^{3.4}$ with a standard calculator: % We would calculate the square, the root and the exponential and, % finally, we would divide and add the results. % % It does not matter if the arguments \emph{results} are or not predefined. % But these commands act as declarations, so that its scope is local % in environments and groups. % \begin{exemple} % \SQUARE{5}\sol % The \texttt{\textbackslash sol} % command contains the square of $5$: % \[5^2=\sol\] % \begin{center} % \SQUAREROOT{5}\sol % Now, the \texttt{\textbackslash sol} % command is the square root of $5$: % \[\sqrt{5}=\sol\] % \end{center} % On having gone out of the \texttt{center} % environment, % the command recovers its previous value: % \sol % \end{exemple} % % The \textsf{calculus} package % goes a step further and allows us to define and use in a user-friendly % manner various functions and their derivatives. % % For exemple, using the % \textsf{calculus} package, you can define the $f(t)=t^2e^t-\cos 2t$ function % as follows: % \begin{Verbatim} % \PRODUCTfunction{\SQUAREfunction}{\EXPfunction}{\tempfunctionA} % \SCALEVARIABLEfunction{2}{\COSfunction}{\tempfunctionB} % \SUBTRACTfunction{\tempfunctionA}{\tempfunctionB}{\Ffunction} % \end{Verbatim} % % Then you cau compute any value of the new function |\Ffunction| % and its derivative: typing % \begin{quote} % |\Ffunction|\marg{num}\marg{\cs{sol}}\marg{\cs{Dsol}} % \end{quote} % the values of $f(\textit{num})$ and $f'(\textit{num})$ will be stored in % \textttit{\cs{sol}} and \textttit{\cs{Dsol}}. % % \part{The \textsf{calculator} package} % \section{Predefined numbers} % The \textsf{calculator} package predefines the following numbers: % \SpecialUsageIndex{\numberPI} % \SpecialUsageIndex{\numberHALFPI} % \SpecialUsageIndex{\numberTHREEHALFPI} % \SpecialUsageIndex{\numberTHIRDPI} % \SpecialUsageIndex{\numberQUARTERPI} % \SpecialUsageIndex{\numberFIFTHPI} % \SpecialUsageIndex{\numberSIXTHPI} % \SpecialUsageIndex{\numberTWOPI} % \SpecialUsageIndex{\numberE} % \SpecialUsageIndex{\numberINVE} % \SpecialUsageIndex{\numberETWO} % \SpecialUsageIndex{\numberINVETWO} % \SpecialUsageIndex{\numberLOGTEN} % \SpecialUsageIndex{\numberGOLD} % \SpecialUsageIndex{\numberINVGOLD} % \SpecialUsageIndex{\numberSQRTTWO} % \SpecialUsageIndex{\numberSQRTTHREE} % \SpecialUsageIndex{\numberSQRTFIVE} % \SpecialUsageIndex{\numberCOSXXX} % \SpecialUsageIndex{\numberCOSXLV} % \begin{center} % \begin{tabular}{llll} % \ttfamily \cs{numberPI} & $\numberPI\approx\pi$ & % \ttfamily \cs{numberHALFPI} & $\numberHALFPI\approx\pi/2$ \\ % \ttfamily \cs{numberTHREEHALFPI} & $\numberTHREEHALFPI\approx3\pi/2$ & % \ttfamily \cs{numberTHIRDPI} & $\numberTHIRDPI\approx\pi/3$ \\ % \ttfamily \cs{numberQUARTERPI} & $\numberQUARTERPI\approx\pi/4$ & % \ttfamily \cs{numberFIFTHPI} & $\numberFIFTHPI\approx\pi/5$ \\ % \ttfamily \cs{numberSIXTHPI} & $\numberSIXTHPI\approx\pi/6$ & % \ttfamily \cs{numberTWOPI} & $\numberTWOPI\approx2\pi$ \\ % \hline % \ttfamily \cs{numberE} & $\numberE\approx\mathrm e$ & % \ttfamily \cs{numberINVE} & $\numberINVE\approx1/\mathrm e$ \\ % \ttfamily \cs{numberETWO} & $\numberETWO\approx\mathrm e^2$ & % \ttfamily \cs{numberINVETWO} & $\numberINVETWO\approx1/\mathrm e^2$ \\ % \hline % \ttfamily \cs{numberLOGTEN} & $\numberLOGTEN\approx\log 10$ % \\ % \hline % \ttfamily \cs{numberGOLD} & $\numberGOLD\approx\phi$ & % \ttfamily \cs{numberINVGOLD} & $\numberINVGOLD\approx1/\phi$ \\ % \hline % \ttfamily \cs{numberSQRTTWO} & $\numberSQRTTWO\approx\sqrt2$ & % \ttfamily \cs{numberSQRTTHREE} & $\numberSQRTTHREE\approx\sqrt3$ \\ % \ttfamily \cs{numberSQRTFIVE} & $\numberSQRTFIVE\approx\sqrt5$ \\ % \hline % \ttfamily \cs{numberCOSXXX} & $\numberCOSXXX\approx\cos{\pi/6}$ & % \ttfamily \cs{numberCOSXLV} & $\numberCOSXLV\approx\cos{\pi/4}$ % \end{tabular} % \end{center} % \section{Operations with numbers} % \subsection{Assignments and comparisons} % The first command we describe here is used to store a number % in a control sequence. % The other two commands in this section determine the maximum and minimum % of a pair of numbers. % \begin{description} % \item[\cs{COPY}\marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\COPY}% % stores the number \textttit{num} to the command \textttit{\TBS cmd}. % \begin{exemple} % \COPY{-1.256}{\sol} % \sol % \end{exemple} % \item[\cs{MAX}\marg{num1}\marg{num2}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\MAX}% % stores in \textttit{\TBS cmd} the maximum of the numbers \textttit{num1} % and \textttit{num2}. % \begin{exemple} % \MAX{1.256}{3.214}{\sol} % \[\max(1.256,3.214)=\sol\] % \end{exemple} % \item[\cs{MIN}\marg{num1}\marg{num2}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\MIN}% % stores in \textttit{\TBS cmd} the minimum of \textttit{num1} and % \textttit{num2}. % \begin{exemple} % \MIN{1.256}{3.214}{\sol} % \sol % \end{exemple} % \end{description} % \subsection{Real arithmetic} % \subsubsection{The four basic operations} % The following commands calculate the four arithmetical basic operations. % \begin{description} % \item[\cs{ADD}\marg{num1}\marg{num2}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\ADD}% % Sum of numbers \textttit{num1} and \textttit{num2}. % \begin{exemple} % \ADD{1.256}{3.214}{\sol} % $1.256+3.214=\sol$ % \end{exemple} % % \item[\cs{SUBTRACT}\marg{num1}\marg{num2}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\SUBTRACT}% % Difference \textttit{num1}-\textttit{num2}. % \begin{exemple} % \SUBTRACT{1.256}{3.214}{\sol} % $1.256-3.214=\sol$ % \end{exemple} % % \item[\cs{MULTIPLY}\marg{num1}\marg{num2}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\MULTIPLY}% % Product \textttit{num1}$\times$\textttit{num2}. % \begin{exemple} % \MULTIPLY{1.256}{3.214}{\sol} % $1.256\times3.214=\sol$ % \end{exemple} % % \item[\cs{DIVIDE}\marg{num1}\marg{num2}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\DIVIDE}% % Quotient % \textttit{num1}/\textttit{num2}.\footnote{This command uses a modified % version of the division algorithm of Claudio Beccari.} % \begin{exemple} % \DIVIDE{1.256}{3.214}{\sol} % $1.256/3.214=\sol$ % \end{exemple} % \end{description} % \subsubsection{Powers with integer exponent} % \begin{description} % \item[\cs{SQUARE}\marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\SQUARE}% % Square of the number \textttit{num}. % \begin{exemple} % \SQUARE{-1.256}{\sol} % $(-1.256)^2=\sol$ % \end{exemple} % \item[\cs{CUBE}\marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\CUBE}% % Cube of \textttit{num}. % \begin{exemple} % \CUBE{-1.256}{\sol} % $(-1.256)^3=\sol$ % \end{exemple} % \item[\cs{POWER}\marg{num}\marg{exp}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\POWER}% % The \textttit{exp} power of \textttit{num}. % % The exponent, \textttit{exp}, must be an integer % (if you want to calculate powers % with non integer exponents, use the \cs{EXP} command). % \begin{exemple} % \POWER{-1.256}{-5}{\sola} % \POWER{-1.256}{5}{\solb} % \POWER{-1.256}{0}{\solc} % \[ % \begin{aligned} % (-1.256)^{-5}&=\sola % \\ % (-1.256)^{5}&=\solb % \\ % (-1.256)^{0}&=\solc % \end{aligned} % \] % \end{exemple} % \end{description} % % \subsubsection{Absolute value, integer part and fractional part} % \begin{description} % \item[\cs{ABSVALUE}\marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\ABSVALUE}% % Absolute value of \textttit{num}. % \begin{exemple} % \ABSVALUE{-1.256}{\sol} % $\left\vert-1.256\right\vert=\sol$ % \end{exemple} % \item[\cs{INTEGERPART}\marg{num}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\INTEGERPART}% % Integer part of \textttit{num}.\footnote{The integer part of $x$ % is the largest integer that is less than or equal to $x$.} % \begin{exemple} % \INTEGERPART{1.256}{\sola} % \INTEGERPART{-1.256}{\solb} % The integer part of $1.256$ is $\sola$, % but the integer part of $-1.256$ is $\solb$. % \end{exemple} % \item[\cs{FLOOR}]\SpecialUsageIndex{\FLOOR}% % is an alias of \cs{INTEGERPART}. % \begin{exemple} % \FLOOR{1.256}{\sol} % The integer part of $1.256$ is $\sol$. % \end{exemple} % \item[\cs{FRACTIONALPART}\marg{num}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\FRACTIONALPART}% % Fractional part of \textttit{num}.\renewinversion[thanks to July Tikhonov % who reported a bug and suggested the solution]{2.1} % \begin{exemple} % \FRACTIONALPART{1.256}{\sol} % \sol % % \FRACTIONALPART{-1.256}{\sol} % \sol % \end{exemple} % \end{description} % \subsubsection{Truncation and rounding} % \begin{description} % \item[\cs{TRUNCATE}\oarg{n}\marg{num}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\TRUNCATE}% % truncates the number \textttit{num} to \textttit{n} decimal places. % \item[\cs{ROUND}{[\textttit{n}]}\marg{num}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\ROUND}% % rounds the number \textttit{num} to \textttit{n} decimal places.% % \renewinversion[thanks to Jim Cline and Schremmer Alain % who reported a bug]{2.1} % % The optional argument \textttit{n} may be \texttt{0}, \texttt{1}, % \texttt{2}, \texttt{3} or \texttt{4} (the default is \texttt{2}).\footnote{% % Note than \cs{TRUNCATE[0]} is equivalent to \cs{INTEGERPART} % only for non-negative numbers.} % \begin{exemple} % \TRUNCATE[0]{1.25688}{\sol} % \sol % % \TRUNCATE[2]{1.25688}{\sol} % \sol % % \TRUNCATE[4]{1.25688}{\sol} % \sol % \end{exemple} % \begin{exemple} % \ROUND[0]{1.25688}{\sol} % \sol % % \ROUND[2]{1.25688}{\sol} % \sol % % \ROUND[4]{1.25688}{\sol} % \sol % \end{exemple} % \end{description} % % \subsection{Integers} % The operations described here are subject % to the same restrictions as those referring to decimal numbers. % In particular, although \TeX{} does not have this restriction % in its integer arithmetic, % the largest integer that can be used is 16383. % \subsubsection{Integer division, quotient and remainder} % \begin{description} % \item % [\cs{INTEGERDIVISION}\marg{num1}\marg{num2}\marg{\cs{cmd1}}\marg{\cs{cmd2}}] % \SpecialUsageIndex{\INTEGERDIVISION}% % stores in the \textttit{\TBS cmd1} and % \textttit{\TBS cmd2} commands the quotient and the remainder of the % integer division of the two integers % \textttit{num1} and \textttit{num2}. % The remainder is a non-negative number smaller than the divisor.\footnote{% % The scientific computing systems (such as Matlab. Scilab or Mathematica) % do not always return a non-negative residue % ---especially when the divisor is negative---. % However, the most reasonable definition of integer quotient is this one: % \emph{the quotient of the division $D/d$ is the largest number $q$ % for which $dq \leq D$}. % With this definition, the remainder $r=D-qd$ is a non-negative number.} % \begin{exemple} % \INTEGERDIVISION{435}{27}{\sola}{\solb} % $435=27\times\sola+\solb$ % % \INTEGERDIVISION{27}{435}{\sola}{\solb} % $27=435\times\sola+\solb$ % % \INTEGERDIVISION{-435}{27}{\sola}{\solb} % $-435=27\times(\sola)+\solb$ % % \INTEGERDIVISION{435}{-27}{\sola}{\solb} % $435=-27\times(\sola)+\solb$ % % \INTEGERDIVISION{-435}{-27}{\sola}{\solb} % $-435=-27\times\sola+\solb$ % \end{exemple} % \item[\cs{INTEGERQUOTIENT}\marg{num1}\marg{num2}\marg{\cs{cmd}}] % \SpecialUsageIndex{\INTEGERQUOTIENT}% % Integer part of the quotient of % \textttit{num1} and \textttit{num2}. These two numbers are not necessarily % integers. % \begin{exemple} % \INTEGERQUOTIENT{435}{27}{\sol} % \sol % % \INTEGERQUOTIENT{27}{435}{\sol} % \sol % % \INTEGERQUOTIENT{-43.5}{2.7}{\sol} % \sol % \end{exemple} % \item[\cs{MODULO}\marg{num1}\marg{num2}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\MODULO}% % Remainder of the integer division of % \textttit{num1} and \textttit{num2}. % \begin{exemple} % \MODULO{435}{27}{\sol} % \[ % 435 \equiv \sol \pmod{27} % \] % \MODULO{-435}{27}{\sol} % \[ % -435 \equiv \sol \pmod{27} % \] % \end{exemple} % \end{description} % \subsubsection{Greatest common divisor and least common multiple} % \begin{description} % \item % [\cs{GCD}\marg{num1}\marg{num2}\marg{\cs{cmd}}]\SpecialUsageIndex{\GCD}% % Greatest common divisor of the integers % \textttit{num1} and \textttit{num2}. % \begin{exemple} % \GCD{435}{27}{\sol} % $\gcd(435,27)=\sol$ % \end{exemple} % \item[\cs{LCM}\marg{num1}\marg{num2}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\LCM}% % Least common multiple of \textttit{num1} and \textttit{num2}. % \begin{exemple} % \newcommand{\lcm}{\operatorname{lcm}} % \LCM{435}{27}{\sol} % $\lcm(435,27)=\sol$ % \end{exemple} % \end{description} % \subsubsection{Simplifying fractions} % \begin{description} % \item[\cs{FRACTIONSIMPLIFY}\marg{num1}\marg{num2}\marg{\cs{cmd1}}% % \marg{\cs{cmd2}}]\SpecialUsageIndex{\FRACTIONSIMPLIFY}% % stores in the \TBS\textttit{cmd1} and \textttit{\TBS cmd2} commands % the numerator and denominator of the irreducible fraction equivalent to % \textttit{num1}/\textttit{num2}. % \begin{exemple} % \FRACTIONSIMPLIFY{435}{27}{\sola}{\solb} % $435/27=\sola/\solb$ % \end{exemple} % \end{description} % \subsection{Elementary functions} % \subsubsection{Square roots} % \begin{description} % \item[\cs{SQUAREROOT}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\SQUAREROOT}% % Square root of the number \textttit{num}. % \begin{exemple} % \SQUAREROOT{1.44}{\sol} % $\sqrt{1.44}=\sol$ % \end{exemple} % If the argument \textttit{num} is negative, the package returns % a warning message. % \end{description} % Instead of \cs{SQUAREROOT}, you can use the alias \cs{SQRT}.% % \SpecialUsageIndex{\SQRT} % % \subsubsection{Exponential and logarithm} % The \cs{EXP} and \cs{LOG} commands compute, by default, % exponentials and logarithms of the natural base $\mathrm{e}$. % They admit, however, an optional argument to choose another base. % \begin{description} % \item[\cs{EXP}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\EXP}% % Exponential of the number \textttit{num}. % \begin{exemple} % \EXP{0.5}{\sol} % $\exp(0.5)=\sol$ % \end{exemple} % The argument \textttit{num} must be in the interval $[-9.704,9.704]$.% % \footnote{$9.704$ is the logarithm of $16383$, % the largest number that supports the \TeX's arithmetic.} % % Moreover, the \cs{EXP} command accepts an optional argument, % to compute expressions such as $a^x$: % \item[\cs{EXP}% % \oarg{num1}\marg{num2}\marg{\cs{cmd}}]\SpecialUsageIndex{\EXP}% % Exponential with base \textttit{num1} of \textttit{num2}. % \textttit{num1} must be a positive number. % \begin{exemple} % \EXP[10]{1.3}{\sol} % $10^{1.3}=\sol$ % % \EXP[2]{0.33333}{\sol} % $2^{1/3}=\sol$ % % \end{exemple} % \item[\cs{LOG}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\LOG}% % logarithm of the number \textttit{num}. % \begin{exemple} % \LOG{0.5}{\sol} % $\log 0.5=\sol$ % \end{exemple} % \item[\cs{LOG}% % \oarg{num1}\marg{num2}\marg{\cs{cmd}}]\SpecialUsageIndex{\LOG}% % Logarithm in base \textttit{num1} of \textttit{num2}. % \begin{exemple} % \LOG[10]{0.5}{\sol} % $\log_{10} 0.5=\sol$ % \end{exemple} % \end{description} % \subsubsection{Trigonometric functions} % The arguments, in functions \cs{SIN}, \cs{COS}, \ldots, % are measured in radians. % If you measure angles in degrees (sexagesimal or not), use the % \cs{DEGREESSIN}, \cs{DEGREESCOS}, \dots\ commands. % \begin{description} % \item[\cs{SIN}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\SIN}% % Sine of \textttit{num}. % % \item[\cs{COS}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\COS}% % Cosine of \textttit{num}. % % \item[\cs{TAN}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\TAN}% % Tangent of \textttit{num}. % % \item[\cs{COT}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\COT}% % Cotangent of \textttit{num}. % \begin{exemple} % \SIN{\numberTHIRDPI}{\sol} % $\sin \pi/3=\sol$ % % \COS{\numberTHIRDPI}{\sol} % $\cos \pi/3=\sol$ % % \TAN{\numberTHIRDPI}{\sol} % $\tan \pi/3=\sol$ % % \COT{\numberTHIRDPI}{\sol} % $\cot \pi/3=\sol$ % \end{exemple} % % \item[\cs{DEGREESSIN}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\DEGREESSIN}% % Sine of \textttit{num} sexagesimal degrees. % % \item[\cs{DEGREESCOS}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\DEGREESCOS}% % Cosine of \textttit{num} sexagesimal degrees. % % \item[\cs{DEGREESTAN}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\DEGREESTAN}% % Tangent of \textttit{num} sexagesimal degrees. % % \item[\cs{DEGREESCOT}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\DEGREESCOT}% % Cotangent of \textttit{num} sexagesimal degrees. % % \begin{exemple} % \DEGREESSIN{60}{\sol} % $\sin 60^{\textrm o}=\sol$ % % \DEGREESCOS{60}{\sol} % $\cos 60^{\textrm o}=\sol$ % % \DEGREESTAN{60}{\sol} % $\tan 60^{\textrm o}=\sol$ % % \DEGREESCOT{60}{\sol} % $\cot 60^{\textrm o}=\sol$ % \end{exemple} % \end{description} % % The latter commands support an optional argument % that allows us to divide the circle % in an arbitrary number of \emph{degrees} (not necessarily $360$). % \begin{description} % \item[\cs{DEGREESSIN}% % \oarg{degrees}\marg{num}\marg{\cs{cmd}}] \mbox{} % \item[\cs{DEGREESCOS}% % \oarg{degrees}\marg{num}\marg{\cs{cmd}}] \mbox{} % \item[\cs{DEGREESTAN}% % \oarg{degrees}\marg{num}\marg{\cs{cmd}}] \mbox{} % \item[\cs{DEGREESCOT}% % \oarg{degrees}\marg{num}\marg{\cs{cmd}}] \mbox{} % \end{description} % % By example, |\DEGREESCOS[400]{50}| computes the cosine of 50 gradians % (a right angle has $100$ gradians, the whole circle has 400 gradians), % which are equivalent to 45 (sexagesimal) degrees or % $\pi/4$ radians. Or to 1 \emph{degree}, % if we divide the circle into 8 parts! % \begin{exemple} % \DEGREESCOS[400]{50}{\sol} % \sol % % \DEGREESCOS{45}{\sol} % \sol % % \COS{\numberQUARTERPI}{\sol} % \sol % % \DEGREESCOS[8]{1}{\sol} % \sol % \end{exemple} % % Moreover, we have a couple of commands % to convert between radians and degrees, % \begin{description} % \item[\cs{DEGtoRAD}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\DEGtoRAD}% % Equivalence in radians % of \textttit{num} sexagesimal degrees. % \item[\cs{RADtoDEG}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\RADtoDEG}% % Equivalence in sexagesimal degrees % of \textttit{num} radians. % \begin{exemple} % \DEGtoRAD{60}{\sol} % \sol % \end{exemple} % \end{description} % and two other commands to reduce arguments to basic intervals: % \begin{description} % \item[\cs{REDUCERADIANSANGLE}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\REDUCERADIANSANGLE}% % Reduces the arc \textttit{num} to the interval $]-\pi,\pi]$. % % \item[\cs{REDUCEDEGREESANGLE}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\REDUCEDEGREESANGLE}% % Reduces the angle \textttit{num} to the interval $]-180,180]$. % \begin{exemple} % \MULTIPLY{\numberTWOPI}{10}{\TWENTYPI} % \ADD{\numberPI}{\TWENTYPI}{\TWENTYONEPI} % \REDUCERADIANSANGLE{\TWENTYONEPI}{\sol} % \sol % % \REDUCEDEGREESANGLE{3690}{\sol} % \sol % \end{exemple} % % % \end{description} % % \subsubsection{Hyperbolic functions} % \begin{description} % \item[\cs{SINH}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\SINH}% % stores in \textttit{\TBS cmd} % the hyperbolic sine of \textttit{num}. % % \item[\cs{COSH}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\COSH}% % Hyperbolic cosine of \textttit{num}. % % \item[\cs{TANH}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\TANH}% % Hyperbolic tangent of \textttit{num}. % % \item[\cs{COTH}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\COTH}% % Hyperbolic cotangent of \textttit{num}. % % \begin{exemple} % \SINH{1.256}{\sol} % \sol % % \COSH{1.256}{\sol} % \sol % % \TANH{1.256}{\sol} % \sol % % \COTH{1.256}{\sol} % \sol % \end{exemple} % \end{description} % % \subsubsection{Inverse trigonometric functions\newinversion{2.0}} % \begin{description} % \item[\cs{ARCSIN}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\ARCSIN}% % stores in \textttit{\TBS cmd} % the arcsin (inverse of sine) of \textttit{num}. % % \item[\cs{ARCCOS}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\ARCCOS}% % arccos of \textttit{num}. % % \item[\cs{ARCTAN}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\ARCTAN}% % arctan of \textttit{num}. % % \item[\cs{ARCCOT}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\ARCCOT}% % arccot of \textttit{num}. % % \begin{exemple} % \ARCSIN{0.5}{\sol} % \sol % % \ARCCOS{0.5}{\sol} % \sol % % \ARCTAN{\numberSQRTTHREE}{\sol} % \sol % % \ARCCOT{-1}{\sol} % \sol % \end{exemple} % \end{description} % % \subsubsection{Inverse hyperbolic functions\newinversion{2.0}} % \begin{description} % \item[\cs{ARSINH}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\ARSINH}% % stores in \textttit{\TBS cmd} % the arsinh (inverse of hyperbolic sine) of \textttit{num}. % % \item[\cs{ARCOSH}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\ARCOSH}% % arcosh of \textttit{num}. % % \item[\cs{ARTANH}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\ARTANH}% % artanh of \textttit{num}. % % \item[\cs{ARCOTH}% % \marg{num}\marg{\cs{cmd}}]\SpecialUsageIndex{\ARCOTH}% % arcoth of \textttit{num}. % % \begin{exemple} % \ARSINH{1}{\sol} % \sol % % \ARCOSH{1}{\sol} % \sol % % \ARTANH{0.5}{\sol} % \sol % % \ARCOTH{2}{\sol} % \sol % \end{exemple} % \end{description} % % \section{Operations with lengths} % \begin{description} % \item[\cs{LENGTHDIVIDE}\marg{length1}\marg{length2}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\LENGTHDIVIDE}\mbox{} % % This command divides two lengths % and returns a number. % \begin{exemple} % \LENGTHDIVIDE{1in}{1cm}{\sol} % One inch equals $\sol$ centimeters. % \end{exemple} % % Commands \cs{LENGTHADD} and \cs{LENGTHSUBTRACT} return the sum and % the difference of two lengths \newinversion{2.0}. % % \item[\cs{LENGTHADD}\marg{length1}\marg{length2}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\LENGTHADD}\mbox{} % \item[\cs{LENGTHSUBTRACT}\marg{length1}\marg{length2}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\LENGTHSUBTRACT}\mbox{} % % (\cs{cmd} must be a predefined length). % \begin{exemple} % \newlength{\mylength} % \LENGTHADD{1in}{1cm}{\mylength} % $1in+1cm=\the\mylength$. % % \LENGTHSUBTRACT{1in}{1cm}{\mylength} % $1in-1cm=\the\mylength$. % \end{exemple} % \end{description} % % \section{Matrix arithmetic} % The \textsf{calculator} package defines the commands described below % to operate on vectors and matrices. % We only work with two or three-dimensional vectors and % $2\times2$ and $3\times3$ matrices. % Vectors are represented in the form % |(a1,a2)| or |(a1,a2,a3);|\footnote{But they are \emph{column} vectors.} % and, in the case of matrices, columns are separated \emph{\`a la matlab} % by semicolons: |(a11,a12;a21,a22)| % or |(a11,a12,a13;a21,a22,a23;a31,a32,a33)|. % \subsection{Vector operations} % \subsubsection{Assignments} % \begin{description} % \item[\cs{VECTORCOPY}\parg{x,y}\parg{\TBS cmd1,\TBS cmd2}]% % \SpecialUsageIndex{\VECTORCOPY}% % copy the entries of vector \parg{x,y} to the % \textttit{\TBS cmd1} and \textttit{\TBS cmd2} commands. % \item[\cs{VECTORCOPY}\parg{x,y,z}\parg{\TBS cmd1,\TBS cmd2,\TBS cmd3}] % copy the entries of vector (\textttit{x},\textttit{y},\textttit{z}) to the % \textttit{\TBS cmd1}, \textttit{\TBS cmd2} and % \textttit{\TBS cmd3} commands. % \begin{exemple} % \VECTORCOPY(1,-1)(\sola,\solb) % $(\sola,\solb)$ % % \VECTORCOPY(1,-1,2)(\sola,\solb,\solc) % $(\sola,\solb,\solc)$ % \end{exemple} % \end{description} % % \subsubsection{Vector addition and subtraction} % \begin{description} % \item[\cs{VECTORADD}\parg{x1,y1}\parg{x2,y2}\parg{\TBS cmd1,\TBS cmd2}] % \SpecialUsageIndex{\VECTORADD} % % \item[\cs{VECTORADD}\parg{x1,y1,z1}\parg{x2,y2,z2}% % \parg{\TBS cmd1,\TBS cmd2,\TBS cmd3}] % \SpecialUsageIndex{\VECTORADD} % % \item[\cs{VECTORSUB}\parg{x1,y1}\parg{x2,y2}\parg{\TBS cmd1,\TBS cmd2}] % \SpecialUsageIndex{\VECTORSUB} % % \item[\cs{VECTORSUB}\parg{x1,y1,z1}\parg{x2,y2,z2}% % \parg{\TBS cmd1,\TBS cmd2,\TBS cmd3}]\mbox{} % \SpecialUsageIndex{\VECTORSUB} % % \begin{exemple} % \VECTORADD(1,-1,2)(3,5,-1)(\sola,\solb,\solc) % $(1,-1,2)+(3,5,-1)=(\sola,\solb,\solc)$ % % \VECTORSUB(1,-1,2)(3,5,-1)(\sola,\solb,\solc) % $(1,-1,2)-(3,5,-1)=(\sola,\solb,\solc)$ % \end{exemple} % \end{description} % \subsubsection{Scalar-vector product} % \begin{description} % \item[\cs{SCALARVECTORPRODUCT}\marg{num}\parg{x,y}% % \parg{\cs{cmd1},\cs{cmd2}}]\mbox{} % \SpecialUsageIndex{\SCALARVECTORPRODUCT} % % \item[\cs{SCALARVECTORPRODUCT}\marg{num}\parg{x,y,z}% % \parg{\cs{cmd1},\cs{cmd2},\cs{cmd3}}]\mbox{} % \SpecialUsageIndex{\SCALARVECTORPRODUCT} % \begin{exemple} % \SCALARVECTORPRODUCT{2}(3,5)(\sola,\solb) % $2(3,5)=(\sola,\solb)$ % % \SCALARVECTORPRODUCT{2}(3,5,-1)(% % \sola,\solb,\solc) % $2(3,5,-1)=(\sola,\solb,\solc)$ % \end{exemple} % \end{description} % \subsubsection{Scalar (dot) product and euclidean norm} % \begin{description} % \item[\cs{SCALARPRODUCT}\parg{x1,y1}\parg{x2,y2}\marg{\cs{cmd}}] % \SpecialUsageIndex{\SCALARPRODUCT}% % % \item[\cs{SCALARPRODUCT}\parg{x1,y1,z1}\parg{x2,y2,z2}\marg{\cs{cmd}}] % \SpecialUsageIndex{\SCALARPRODUCT}% % % \item[\cs{DOTPRODUCT}]\SpecialUsageIndex{\DOTPRODUCT}% % is an alias of \cs{SCALARPRODUCT} \newinversion{2.0}. % % \item[\cs{VECTORNORM}\parg{x,y}\marg{\cs{cmd}}]\mbox{} % \SpecialUsageIndex{\VECTORNORM}% % % \item[\cs{VECTORNORM}\parg{x,y,z}\marg{\cs{cmd}}]\mbox{} % \SpecialUsageIndex{\VECTORNORM}% % \begin{exemple} % \SCALARPRODUCT(1,-1)(3,5){\sol} % $(1,-1)\cdot(3,5)=\sol$ % % \DOTPRODUCT(1,-1,2)(3,5,-1){\sol} % $(1,-1,2)\cdot(3,5,-1)=\sol$ % % \VECTORNORM(3,4)\sol % $\left\|(3,4)\right\|=\sol$ % % \VECTORNORM(1,2,-2)\sol % $\left\|(1,2,-2)\right\|=\sol$ % \end{exemple} % \end{description} % \subsubsection{Vector (cross) product \newinversion{2.0}} % \begin{description} % % \item[\cs{VECTORPRODUCT}\parg{x1,y1,z1}\parg{x2,y2,z2}\parg{\cs{cmd1},\cs{cmd2},\cs{cmd3}}] % \SpecialUsageIndex{\VECTORPRODUCT}% % % \item[\cs{CROSSPRODUCT}]\SpecialUsageIndex{\CROSSPRODUCT}% % is an alias of \cs{VECTORPRODUCT}. % \begin{exemple} % \CROSSPRODUCT(1,-1,2)(3,5,-1)% % (\sola,\solb,\solc) % $(1,-1,2)\times(3,5,-1)=(\sola,\solb,\solc)$ % % \VECTORPRODUCT(1,-1,2)(-3,3,-6)% % (\sola,\solb,\solc) % $(1,-1,2)\times(-3,3,-6)=(\sola,\solb,\solc)$ % % \end{exemple} % \end{description} % \subsubsection{Unit vector parallel to a given vector (normalized vector)} % \begin{description} % \item[\cs{UNITVECTOR}\parg{x,y}\parg{\TBS cmd1,\TBS cmd2}] % \SpecialUsageIndex{\UNITVECTOR}% % % \item[\cs{UNITVECTOR}\parg{x,y,z}\parg{\TBS cmd1,\TBS cmd2,\TBS cmd3}] % \mbox{}\SpecialUsageIndex{\UNITVECTOR} % \begin{exemple} % \UNITVECTOR(3,4)(\sola,\solb) % $(\sola,\solb)$ % % \UNITVECTOR(1,2,-2)(\sola,\solb,\solc) % $(\sola,\solb,\solc)$ % \end{exemple} % \end{description} % \subsubsection{Absolute value (in each entry of a given vector)} % \begin{description} % \item[\cs{VECTORABSVALUE}\parg{x,y}\parg{\TBS cmd1,\TBS cmd2}] % \SpecialUsageIndex{\VECTORABSVALUE}% % % \item[\cs{VECTORABSVALUE}\parg{x,y,z}\parg{\TBS cmd1,\TBS cmd2,\TBS cmd3}] % \mbox{} \SpecialUsageIndex{\VECTORABSVALUE} % \begin{exemple} % \VECTORABSVALUE(3,-4)(\sola,\solb) % $(\sola,\solb)$ % % \VECTORABSVALUE(3,-4,-1)(\sola,\solb,\solc) % $(\sola,\solb,\solc)$ % \end{exemple} % \end{description} % \subsubsection{Angle between two vectors \newinversion{2.0}} % \begin{description} % \item[\cs{TWOVECTORSANGLE}\parg{x1,y1}\parg{x2,y2}\marg{\cs{cmd}}] % \SpecialUsageIndex{\TWOVECTORSANGLE}% % % \item[\cs{TWOVECTORSANGLE}\parg{x1,y1,z1}\parg{x2,y2,z2}\marg{\cs{cmd}}] % \mbox{} \SpecialUsageIndex{TWOVECTORSANGLE} % \begin{exemple} % \TWOVECTORSANGLE(1,1)(0,1){\sol} % $\sol$ radians % \RADtoDEG{\sol}{\degsol} % (or $\degsol$ degrees) % % \TWOVECTORSANGLE(1,0,0)(0,1,0){\sol} % $\sol$ % \RADtoDEG{\sol}{\degsol} % (or $\degsol$ degrees) % \end{exemple} % \end{description} % % \subsection{Matrix operations} % \subsubsection{Assignments} % \begin{description} % \item[\cs{MATRIXCOPY}% % \parg{a11,a12;a21,a22}% % \parg{\cs{cmd11},\cs{cmd12};\cs{cmd21},\cs{cmd22}}]\mbox{} % \SpecialUsageIndex{\MATRIXCOPY}% % % \noindent % Use this command to store the matrix $\begin{bmatrix} % a11 & a12 \\ a21 & 22 % \end{bmatrix}$ in \textttit{\TBS cmm11}, \textttit{\TBS cmm12}, % \textttit{\TBS cmm21}, \textttit{\TBS cmm22}. % The analogous $3\times3$ version is % \item[\cs{MATRIXCOPY}% % \parg{a11,a12,a13; \textup{[\dots]} ,a33}% % \parg{\cs{cmd11},\cs{cmd12},\cs{cmd13};% % \textup{[\dots]} ,\cs{cmd33}}]\mbox{} % \SpecialUsageIndex{\MATRIXCOPY}% % \begin{exemple} % \MATRIXCOPY(1, -1, 2; % 3, 0, 5; % -1, 1, 4)% % (\sola,\solb,\solc; % \sold,\sole,\solf; % \solg,\solh,\soli) % $\begin{bmatrix} % \sola & \solb & \solc \\ % \sold & \sole & \solf \\ % \solg & \solh & \soli % \end{bmatrix}$ % \end{exemple} % \end{description} % % % Henceforth, we will present only the syntax for commands % operating with $2\times2$ matrices. % In all cases, the syntax is similar if we work with $3\times3$ matrices. % In the examples, we will work with either $2\times2$ or $3\times3$ matrices. % \subsubsection{Transposed matrix} % \begin{description} % \item[\cs{TRANSPOSEMATRIX}% % \parg{a11,a12;a21,a22}% % \parg{\cs{cmd11},\cs{cmd12};\cs{cmd21},\cs{cmd22}}]\mbox{} % \SpecialUsageIndex{\TRANSPOSEMATRIX}% % \begin{exemple} % \TRANSPOSEMATRIX(1,-1;3,0)% % (\sola,\solb;\solc,\sold) % $\begin{bmatrix} % 1 & -1 \\ 3 & 0 % \end{bmatrix}^T=\begin{bmatrix} % \sola & \solb \\ \solc & \sold % \end{bmatrix}$ % \end{exemple} % \end{description} % % % \subsubsection{Matrix addition and subtraction} % \begin{description} % \item[\cs{MATRIXADD}% % \parg{a11,a12;a21,a22}% % \parg{b11,b12;b21,b22}% % \parg{\cs{cmd11},\cs{cmd12};\cs{cmd21},\cs{cmd22}}] % \SpecialUsageIndex{\MATRIXADD}% % % \item[\cs{MATRIXSUB}% % \parg{a11,a12;a21,a22}% % \parg{b11,b12;b21,b22}% % \parg{\cs{cmd11},\cs{cmd12};\cs{cmd21},\cs{cmd22}}]\mbox{} % \SpecialUsageIndex{\MATRIXSUB}% % % \begin{exemple} % \MATRIXADD(1,-1;3,0)(3,5;-3,2)% % (\sola,\solb;\solc,\sold) % $\begin{bmatrix} % 1 & -1 \\ 3 & 0 % \end{bmatrix}+ % \begin{bmatrix} % 3 & 5 \\ -3 & 2 % \end{bmatrix}=\begin{bmatrix} % \sola & \solb \\ \solc & \sold % \end{bmatrix}$ % % \MATRIXSUB(1,-1;3,0)(3,5;-3,2)% % (\sola,\solb;\solc,\sold) % $\begin{bmatrix} % 1 & -1 \\ 3 & 0 % \end{bmatrix}- % \begin{bmatrix} % 3 & 5 \\ -3 & 2 % \end{bmatrix}=\begin{bmatrix} % \sola & \solb \\ \solc & \sold % \end{bmatrix}$ % \end{exemple} % \end{description} % \subsubsection{Scalar-matrix product} % \begin{description} % \item[\cs{SCALARMATRIXPRODUCT}\marg{num}% % \parg{a11,a12;a21,a22}% % \parg{\cs{cmd11},\cs{cmd12};\cs{cmd21},\cs{cmd22}}]\mbox{} % \SpecialUsageIndex{\SCALARMATRIXPRODUCT}% % % \begin{exemple} % \SCALARMATRIXPRODUCT{3}(1,-1,2; % 3, 0,5; % -1, 1,4)% % (\sola,\solb,\solc; % \sold,\sole,\solf; % \solg,\solh,\soli) % $3\begin{bmatrix} % 1 & -1 & 2 \\ 3 & 0 & 5 \\ -1 & 1 & 4 % \end{bmatrix} % =\begin{bmatrix} % \sola & \solb & \solc \\ % \sold & \sole & \solf \\ % \solg & \solh & \soli % \end{bmatrix}$ % \end{exemple} % \end{description} % \subsubsection{Matriu-vector product} % \begin{description} % \item[\cs{MATRIXVECTORPRODUCT}% % \parg{a11,a12;a21,a22}\parg{x,y}% % \parg{\cs{cmd1},\cs{cmd2}}]\mbox{} % \SpecialUsageIndex{\MATRIXVECTORPRODUCT}% % \begin{exemple} % \MATRIXVECTORPRODUCT(1,-1; % 0, 2)(3,5)(\sola,\solb) % $\begin{bmatrix} % 1 & -1 \\ 0 & 2 % \end{bmatrix} % \begin{bmatrix} % 3 \\ 5 % \end{bmatrix} % =\begin{bmatrix} % \sola \\ \solb % \end{bmatrix}$ % \end{exemple} % \end{description} % \subsubsection{Product of two square matrices} % \begin{description} % \item[\cs{MATRIXPRODUCT}% % \parg{a11,a12;a21,a22}% % \parg{b11,b12;b21,b22}% % \parg{\cs{cmd11},\cs{cmd12};\cs{cmd21},\cs{cmd22}}] % \mbox{} % \SpecialUsageIndex{\MATRIXPRODUCT}% % \begin{exemple} % \MATRIXPRODUCT(1,-1,2;3,0,5;-1,1,4)% % (3,5,-1;-3,2,-5;1,-2,3)% % (\sola,\solb,\solc; % \sold,\sole,\solf; % \solg,\solh,\soli) % \begin{multline*} % \begin{bmatrix} % 1 & -1 & 2 \\ 3 & 0 & 5 \\ -1 & 1 & 4 % \end{bmatrix} % \begin{bmatrix} % 3 & 5 & -1 \\ -3 & 2 & -5 \\ 1 & -2 & 3 % \end{bmatrix}\\ % =\begin{bmatrix} % \sola & \solb & \solc \\ % \sold & \sole & \solf \\ % \solg & \solh & \soli % \end{bmatrix} % \end{multline*} % \end{exemple} % \end{description} % \subsubsection{Determinant} % \begin{description} % \item[\cs{DETERMINANT}% % \parg{a11,a12;a21,a22} % \marg{\cs{cmd}}]\mbox{} % \begin{exemple} % \DETERMINANT(1,-1,2;3,0,5;-1,1,4){\sol} % \SpecialUsageIndex{\DETERMINANT}% % $\begin{vmatrix} % 1 & -1 & 2 \\ 3 & 0 & 5 \\ -1 & 1 & 4 % \end{vmatrix}=\sol$ % \end{exemple} % \end{description} % \subsubsection{Inverse matrix} % \begin{description} % \item[\cs{INVERSEMATRIX}% % \parg{a11,a12;a21,a22}% % \parg{\cs{cmd11},\cs{cmd12};\cs{cmd21},\cs{cmd22}}]\mbox{} % \SpecialUsageIndex{\INVERSEMATRIX}% % \begin{exemple} % \INVERSEMATRIX(1,-1;3,5)(% % \sola,\solb;\solc,\sold) % $\begin{bmatrix} % 1 & -1 \\ 3 & 5 % \end{bmatrix}^{-1}= % \begin{bmatrix} % \sola & \solb \\ \solc & \sold % \end{bmatrix}$ % \end{exemple} % % If the given matrix is singular, the \textsf{calculator} package returns % a warning message % and the \textttit{\cs{cmd11}}, \ldots, commands are marqued as undefined. % \end{description} % \subsubsection{Absolute value (in each entry)} % \begin{description} % \item[\cs{MATRIXABSVALUE}% % \parg{a11,a12;a21,a22}% % \parg{\cs{cmd11},\cs{cmd12};\cs{cmd21},\cs{cmd22}}]\mbox{} % \SpecialUsageIndex{\MATRIXABSVALUE}% % % \begin{exemple} % \MATRIXABSVALUE(1,-1,2;3,0,5;-1,1,4)% % (\sola,\solb,\solc; % \sold,\sole,\solf; % \solg,\solh,\soli) % $\begin{bmatrix} % \sola & \solb & \solc \\ % \sold & \sole & \solf \\ % \solg & \solh & \soli % \end{bmatrix}$ % \end{exemple} % \end{description} % \subsubsection{Solving a linear system} % \begin{description} % \item[\cs{SOLVELINEARSYSTEM}% % \parg{a11,a12;a21,a22}\parg{b1,b2}\parg{\cs{cmd1},\cs{cmd2}}] % \SpecialUsageIndex{\SOLVELINEARSYSTEM}% % solves the linear system % $\begin{pmatrix} % \textttit{a11}&\textttit{a12}\\ % \textttit{a21}&\textttit{a22} % \end{pmatrix} % \begin{pmatrix} % \textttit{x}\\ % \textttit{y}\end{pmatrix} % =\begin{pmatrix} % \textttit{b1}\\ % \textttit{b2} % \end{pmatrix}$ % and stores the solution in (\textttit{\cs{cmd1}},\textttit{\cs{cmd2}}). % \begin{exemple} % \SOLVELINEARSYSTEM(1,-1,2;3,0,5;-1,1,4)% % (-4,4,-2)% % (\sola,\solb,\solc) % Solving the linear system % \[ % \begin{bmatrix} % 1 & -1 & 2 \\ 3 & 0 & 5 \\ -1 & 1 & 4 % \end{bmatrix}\mathsf{X}=\begin{bmatrix} % -4\\4\\-2 % \end{bmatrix} % \] % we obtain % $\mathsf{X}=\begin{bmatrix} % \sola \\ \solb\\ \solc % \end{bmatrix}$ % \end{exemple} % If the given matrix is singular, the package \textsf{calculator} % returns a warning message. % When system is indeterminate, in the bi-dimensional case % one of the solutions is computed; % if the system is incompatible, % then the \verb+\sola+, \dots, commands are marqued as undefined. % For three equations systems, only determinate systems are solved.\footnote{% % This is the only command that does not behave the same way with % $2\times2$ and $3\times3$ matrices.} % \end{description} % % \part{The \textsf{calculus} package} % \section{What is a \emph{function}?} % From the point of view of this package, a \emph {function} $f$ is a pair of % formulae: the first one calculates $f(t)$; the other, $f'(t)$. % Therefore, any function is applied using three arguments: % the value of the variable $t$, % and two command names where $f(t)$ and $f'(t)$ will be stored. % For example, % \begin{quote} % \cs{SQUAREfunction}\Marg{num}\Marg{\TBS sol}\Marg{\TBS Dsol} % \end{quote} % computes $f(t)=t^2$ and $f'(t)=2t$ (where $t=$\textit{num}), % and stores the results in the commands % \textit{\TBS sol} and \textit{\TBS Dsol}.\footnote% % {Do not spect any control about the existence or differentiability % of the function; if the function or the derivative % are not well defined, a \TeX{} error will occur.} % % \begin{exemple} % \SQUAREfunction{3}{\sol}{\Dsol} % If $f(t)=t^2$, then % \[ % f(3)=\sol \mbox{ and } f'(3)=\Dsol % \] % \end{exemple} % \medskip % % \noindent % For all functions defined here, you must use the following syntax: % \begin{quote} % \textttit{\TBS functionname}\Marg{num}\Marg{\TBS cmd1}\Marg{\TBS cmd2} % \end{quote} % being \textit{num} a number (or a command whose value is a number), % and \verb+\+\textit{cmd1} and \verb+\+\textit{cmd2} two control sequence % names where the values of the function and its derivative (in this number) % will be stored. % \medskip % % The key difference between this \emph{functions} and the instructions % defined in the \textsf{calculator} package % is the inclusion of the derivative; for example, the |\SQUARE{3}{\sol}| % instruction computes, only, % the square power of number $3$, while |\SQUAREfunction{3}{\sol}{\Dsol}| % finds, also, the corresponding derivative. % \section{Predefined functions} % The \textsf{calculus} package % predefines the most commonly used elementary functions, % and includes several utilities for defining new ones. % The predefined functions are the following: % \SpecialUsageIndex{\ZEROfunction} % \SpecialUsageIndex{ONEfunction} % \SpecialUsageIndex{IDENTITYfunction} % \SpecialUsageIndex{RECIPROCALfunction} % \SpecialUsageIndex{SQUAREfunction} % \SpecialUsageIndex{CUBEfunction} % \SpecialUsageIndex{SQRTfunction} % \SpecialUsageIndex{EXPfunction} % \SpecialUsageIndex{LOGfunction} % \SpecialUsageIndex{COSfunction} % \SpecialUsageIndex{SINfunction} % \SpecialUsageIndex{TANfunction} % \SpecialUsageIndex{COTfunction} % \SpecialUsageIndex{COSHfunction} % \SpecialUsageIndex{SINHfunction} % \SpecialUsageIndex{TANHfunction} % \SpecialUsageIndex{COTHfunction} % \SpecialUsageIndex{HEAVISIDEfunction} % \begin{center} % \begin{tabular}{llll} % \ttfamily \cs{ZEROfunction} & $f(t)=0$ & % \ttfamily \cs{ONEfunction} & $f(t)=1$ \\ % \ttfamily \cs{IDENTITYfunction} & $f(t)=t$ & % \ttfamily \cs{RECIPROCALfunction} & $f(t)=1/t$ \\ % \ttfamily \cs{SQUAREfunction} & $f(t)=t^2$ & % \ttfamily \cs{CUBEfunction} & $f(t)=t^3$ \\ % \ttfamily \cs{SQRTfunction} & $f(t)=\sqrt t$ \\ % \ttfamily \cs{EXPfunction} & $f(t)=\exp t$ & % \ttfamily \cs{LOGfunction} & $f(t)=\log t$ \\ % \ttfamily \cs{COSfunction} & $f(t)=\cos t$ & % \ttfamily \cs{SINfunction} & $f(t)=\sin t$ \\ % \ttfamily \cs{TANfunction} & $f(t)=\tan t$ & % \ttfamily \cs{COTfunction} & $f(t)=\cot t$ \\ % \ttfamily \cs{COSHfunction} & $f(t)=\cosh t$ & % \ttfamily \cs{SINHfunction} & $f(t)=\sinh t$ \\ % \ttfamily \cs{TANHfunction} & $f(t)=\tanh t$ & % \ttfamily \cs{COTHfunction} & $f(t)=\coth t$ \\ % \ttfamily \cs{HEAVISIDEfunction} & $f(t)=\begin{cases} % 0 & \text{si $t<0$} \\ % 1 & \text{si $t\geq0$} % \end{cases}$ % \end{tabular} % \end{center} % % The following functions are added in version 2.0 \newinversion{2.0} % % \begin{center} % \begin{tabular}{llll} % \ttfamily \cs{ARCCOSfunction} & $f(t)=\arccos t$ & % \ttfamily \cs{ARCSINfunction} & $f(t)=\arcsin t$ \\ % \ttfamily \cs{ARCTANfunction} & $f(t)=\arctan t$ & % \ttfamily \cs{ARCCOTfunction} & $f(t)=\arccot t$ \\ % \ttfamily \cs{ARCOSHfunction} & $f(t)=\arcosh t$ & % \ttfamily \cs{ARSINHfunction} & $f(t)=\arsinh t$ \\ % \ttfamily \cs{ARTANHfunction} & $f(t)=\artanh t$ & % \ttfamily \cs{ARCOTHfunction} & $f(t)=\arcoth t$ \\ % \end{tabular} % \end{center} % % In the following example, we use the |\LOGfunction| function to compute % a table of the $\log$ function and its derivative. % \begin{exemple} % $\begin{array}{cll} % x & \log x & \log' x \\ % \LOGfunction{1}{\logx}{\Dlogx} % 1 &\logx & \Dlogx\\ % \LOGfunction{2}{\logx}{\Dlogx} % 2 &\logx & \Dlogx\\ % \LOGfunction{3}{\logx}{\Dlogx} % 3 &\logx & \Dlogx\\ % \LOGfunction{4}{\logx}{\Dlogx} % 4 &\logx & \Dlogx\\ % \LOGfunction{5}{\logx}{\Dlogx} % 5 &\logx & \Dlogx\\ % \LOGfunction{6}{\logx}{\Dlogx} % 6 &\logx & \Dlogx % \end{array}$ % \end{exemple} % % \section{Operations with functions} % We can define new functions using the following \emph{operations} % (the last argument is the name of the new function): % \begin{description} % \item[\cs{CONSTANTfunction}\Marg{num}\Marg{\TBS Function}]% % \SpecialUsageIndex{\CONSTANTfunction} % defines \textit{\TBS Function} as the constant function \textit{num}. % % Example. Definition of the $F(t)=5$ function: % % |\CONSTANTfunction{5}{\F}| % % \item[\cs{SUMfunction}\Marg{\TBS function1}\Marg{\TBS function2}% % \Marg{\TBS Function}]\SpecialUsageIndex{\SUMfunction} % defines \textit{\TBS Function} as the sum of functions % \textit{\TBS function1} and \textit{\TBS function2}. % % Example. Definition of the $F(t)=t^2+t^3$ function: % % |\SUMfunction{\SQUAREfunction}{\CUBEfunction}{\F}| % % \item[\cs{SUBTRACTfunction}\Marg{\TBS function1}\Marg{\TBS function2}% % \Marg{\TBS Function}]\SpecialUsageIndex{\SUBTRACTfunction} % defines \textit{\TBS Function} as the difference of functions % \textit{\TBS function1} and \textit{\TBS function2}. % % Example. Definition of the $F(t)=t^2-t^3$ function: % % |\SUBTRACTfunction{\SQUAREfunction}{\CUBEfunction}{\F}| % % \item[\cs{PRODUCTfunction}\Marg{\TBS function1}\Marg{\TBS function2}% % \Marg{\TBS Function}]\SpecialUsageIndex{\PRODUCTfunction} % defines \textit{\TBS Function} as the product of functions % \textit{\TBS function1} and \textit{\TBS function2} % % Example. Definition of the $F(t)=\mathrm e^t\cos t$ function: % % |\PRODUCTfunction{\EXPfunction}{\COSfunction}{\F}| % % \item[\cs{QUOTIENTfunction}\Marg{\TBS function1}\Marg{\TBS function2}% % \Marg{\TBS Function}]\SpecialUsageIndex{\QUOTIENTfunction} % defines \textit{\TBS Function} as the quotient of functions % \textit{\TBS function1} and \textit{\TBS function2}. % % Example. Definition of the $F(t)=\mathrm e^t/\cos t$ function: % % |\QUOTIENTfunction{\EXPfunction}{\COSfunction}{\F}| % % \item[\cs{COMPOSITIONfunction}\Marg{\TBS function1}\Marg{\TBS function2}% % \Marg{\TBS Function}]\SpecialUsageIndex{\COMPOSITIONfunction} % defines \textit{\TBS Function} as the composition of functions % \textit{\TBS function1} and \textit{\TBS function2}. % % Example. Definition of the $F(t)=\mathrm e^{\cos t}$ function: % % |\COMPOSITIONfunction{\EXPfunction}{\COSfunction}{\F}| % % (note than |\COMPOSITIONfunction{f}{g}{\F}| means |\F|$=f\circ g$). % % \item[\cs{SCALEfunction}\Marg{num}\Marg{\TBS function}\Marg{\TBS Function}]% % \SpecialUsageIndex{\SCALEfunction} % defines \textit{\TBS Function} as the product of number \textit{num} % and function \textit{\TBS function}. % % Example. Definition of the $F(t)=3{\cos t}$ function: % % |\SCALEfunction{3}{\COSfunction}{\F}| % % \item[\cs{SCALEVARIABLEfunction}\Marg{num}\Marg{\TBS function}% % \Marg{\TBS Function}]\SpecialUsageIndex{\SCALEVARIABLEfunction} % scales the variable by factor \textit{num} and then applies the function % \textit{\TBS function}. % % Example. Definition of the $F(t)=\cos 3t$ function: % % |\SCALEVARIABLEfunction{3}{\COSfunction}{\F}| % % \item[\cs{POWERfunction}\Marg{\TBS function}\Marg{num}\Marg{\TBS Function}]% % \SpecialUsageIndex{\POWERfunction} % defines \textit{\TBS Function} as the power of function % \textit{\TBS function} to the exponent \textit{num} (a positive integer). % Example. Definition of the $F(t)=t^5$ function: % % |\POWERfunction{\IDENTITYfunction}{5}{\F}| % % \item[\cs{LINEARCOMBINATIONfunction}\Marg{num1}\Marg{\TBS function1}% % \Marg{num2}\Marg{\TBS function2}\Marg{\TBS Function}] % \SpecialUsageIndex{\LINEARCOMBINATIONfunction} % defines \textit{\TBS Function} as the linear combination of functions % \textit{\TBS function1} and \textit{\TBS function2} % multiplied, respectively, by numbers \textit{num1} and \textit{num2}. % % Example. Definition of the $F(t)=2t-3\cos t$ function: % % |\LINEARCOMBINATIONfunction{2}{\IDENTITYfunction}{-3}{\COSfunction}{\F}| % \end{description} % % By combining properly this operations and the predefined functions, % many elementary functions can be defined. % % \begin{exemple} % % exp(-t) % \SCALEVARIABLEfunction % {-1}{\EXPfunction} % {\NEGEXPfunction} % % % exp(-t)cos(t) % \PRODUCTfunction % {\NEGEXPfunction} % {\COSfunction} % {\NEGEXPCOSfunction} % % % 3t^2-2exp(-t)cos(t) % \LINEARCOMBINATIONfunction % {3}{\SQUAREfunction} % {-2}{\NEGEXPCOSfunction} % {\myfunction} % % \myfunction{5}{\sol}{\Dsol} % % If % \[ % f(t)=3t^2-2\mathrm{e}^{-t}\cos t % \] % then % \[ % \begin{gathered} % f(5)=\sol\\ % f'(5)=\Dsol % \end{gathered} % \] % \end{exemple} % % \section{Polynomial functions} % Although polynomial functions can be defined using linear combinations % of power functions, % to facilitate our work, the \textsf{calculus} package includes the % following commands to define more easily the polynomials of % 1, 2, and 3 degrees: % |\newlpoly| (new \emph{linear} polynomial), |\newqpoly| % (new \emph{quadratic} polynomial), % and |\newcpoly| (new \emph{cubic} polynomial): % \begin{description} % \item[\cs{newlpoly}\Marg{\TBS Function}\Marg{a}\Marg{b}]% % \SpecialUsageIndex{\newlpoly} % stores the % $p(t)=\texttt{\textit{a}}+\texttt{\textit{b}}t$ % function in the \cs{\textit{Function}} command. % \item[\cs{newqpoly}\Marg{\TBS Function}% % \Marg{a}\Marg{b}\Marg{c}]\SpecialUsageIndex{\newqpoly} % stores the % $p(t)=\texttt{\textit{a}}+\texttt{\textit{b}}t+\texttt{\textit{c}}t^2$ % function in the \cs{\textit{Function}} command. % \item[\cs{newcpoly}\Marg{\TBS Function}\Marg{a}\Marg{b}\Marg{c}\Marg{d}]% % \SpecialUsageIndex{\newcpoly} % stores the % $p(t)=\texttt{\textit{a}}+\texttt{\textit{b}}t+ % \texttt{\textit{c}}t^2+\texttt{\textit{d}}t^3$ % function in the \cs{\textit{Function}} command. % \end{description} % \begin{exemple} % % \mypoly=1-x^2+x^3 % \newcpoly{\mypoly}{1}{0}{-1}{1} % \mypoly{2}{\sol}{\Dsol} % $p'(2)=\Dsol$ % \end{exemple} % These declarations behave similarly to to the declaration % |\newcommand|: % If the name you want to assign to the new function is that of % an already defined command, the \textsf{calculus} package returns % an error message and do not redefines this command. % To obtain any alternative behavior, our package includes % three other sets of declarations: % % \begin{description} % \item[\cs{renewlpoly}, \cs{renewqpoly}, \cs{renewcpoly}]% % \SpecialUsageIndex{\renewlpoly}% % \SpecialUsageIndex{\renewqpoly}% % \SpecialUsageIndex{\renewcpoly} % redefine the already existing command \cs{\textit{Function}}. % If this command does not exist, then % it is not defined and an error message occurs. % \item[\cs{ensurelpoly}, \cs{ensureqpoly}, \cs{ensurecpoly}]% % \SpecialUsageIndex{\ensurelpoly}% % \SpecialUsageIndex{\ensureqpoly}% % \SpecialUsageIndex{\ensurecpoly} % define a new function. % If the command \cs{\textit{Function}} already exists, % it is not redefined. % \item[\cs{forcelpoly}, \cs{forceqpoly}, \cs{forcecpoly}]% % \SpecialUsageIndex{\forcelpoly}% % \SpecialUsageIndex{\forceqpoly}% % \SpecialUsageIndex{\forcecpoly} % define a new function. % If the command \cs{\textit{Function}} already exists, % it is redefined. % \end{description} % \section{Vector-valued functions (or parametrically defined curves)} % The instruction % \begin{quote}\SpecialUsageIndex{\PARAMETRICfunction} % |\PARAMETRICfunction|\Marg{\TBS Xfunction}\Marg{\TBS Yfunction}% % \Marg{\TBS myvectorfunction} % \end{quote} % defines the new vector-valued function $f(t)=(x(t),y(t))$. % % The first and second arguments are a pair of functions already defined and, % the third, the name of the new function we define. % Once we have defined them, the new vector functions requires five arguments: % \begin{quote} % \textttit{\TBS myvectorfunction}\Marg{num}\Marg{\TBS cmd1}% % \Marg{\TBS cmd2}\Marg{\TBS cmd3}\Marg{\TBS cmd4} % \end{quote} % where % \begin{itemize} % \item \textit{num} is a number $t$, % \item \textit{\TBS cmd1} and \textit{\TBS cmd2} are two command names % where the values of the $x(t)$ function and its derivative $x'(t)$ % will be stored, and % \item \textit{\TBS cmd3} and \textit{\TBS cmd4} will store % $y(t)$ and $y'(t)$. % \end{itemize} % In short, in this context, a vector function is a pair of scalar functions. % % Instead of |\PARAMETRICfunction| we can use the alias |\VECTORfunction|.% % \SpecialUsageIndex{\VECTORfunction} % % \begin{exemple} % For the $f(t)=(t^2,t^3)$ function we have % \VECTORfunction % {\SQUAREfunction}{\CUBEfunction}{\F} % % \F{4}{\solx}{\Dsolx}{\soly}{\Dsoly} % % \[ % f(4)=(\solx,\soly), f'(4)=(\Dsolx,\Dsoly) % \] % \end{exemple} % % \section{Vector-valued functions in polar coordinates} % The following instruction: % \begin{quote}\SpecialUsageIndex{\POLARfunction} % |\POLARfunction|\Marg{\TBS rfunction}\Marg{\TBS Polarfunction} % \end{quote} % declares the vector function $f(\phi)=(r(\phi)\cos \phi,r(\phi)\sin \phi)$. % The first argument is the % $r=r(\phi)$ function, (an already defined function). % For example, we can define the \emph{Archimedean spiral} $r(\phi)=0{,}5\phi$, % as follows: % \begin{Verbatim}[gobble=2] % \SCALEfunction{0.5}{\IDENTITYfunction}{\rfunction} % \POLARfunction{\rfunction}{\archimedes} % \end{Verbatim} % \section{Low-level instructions} % Probably, many users of the package will not be interested % in the implementation of the commands this package includes. % If this is your case, you can ignore this section. % \subsection{The \cs{newfunction} declaration and its variants} % All the functions predefined by this package use the |\newfunction| % declaration. % This control sequence works as follows: % \begin{description} % \item[\cs{newfunction}\Marg{\TBS Function}\Marg{Instructions to compute % \cs{y} and \cs{Dy} from \cs{t}}] % \end{description} % where the second argument is the list of the instructions you need to run % to calculate the value of the function |\y| % and the derivative |\Dy| in the |\t| point. % % For example, if you want to define the $f(t)=t^2+\mathrm e^t\cos t$ function, % whose derivative is % $f'(t)=2t+\mathrm e^t(\cos t-\sin t)$, % using the high-level instructions we defined earlier, % you can write the following instructions: % \begin{Verbatim}[gobble=2] % \PRODUCTfunction{\EXPfunction}{\COSfunction}{\ffunction} % \SUMfunction{\SQUAREfunction}{\ffunction}{\Ffunction} % \end{Verbatim} % % But you can also define this function using the \cs{newfunction} % command as follows: % \begin{Verbatim}[gobble=2] % \newfunction{\Ffunction}{% % \SQUARE{\t}{\tempA} % A=t^2 % \EXP{\t}{\tempB} % B=e^t % \COS{\t}{\tempC} % C=cos(t) % \SIN{\t}{\tempD} % D=sin(t) % \MULTIPLY{2}{\t}{\tempE} % E=2t % \MULTIPLY{\tempB}{\tempC}{\tempC} % C=e^t cos(t) % \MULTIPLY{\tempB}{\tempD}{\tempD} % D=e^t sin(t) % \ADD{\tempA}{\tempC}{\y} % y=t^2 + e^t cos(t) % \ADD{\tempE}{\tempC}{\tempC} % C=t^2 + e^t cos(t) % \SUBTRACT{\tempC}{\tempD}{\Dy} % y'=t^2 + e^t cos(t) - e^t sin(t) % } % \end{Verbatim} % % It must be said, however, that the |\newfunction| declaration % behaves similarly to |\newcommand| or |\newlpoly|: % If the name you want to assign to the new function is that of an already % defined command, % the \textsf{calculus} package returns an error message % and does not redefines this command. % To obtain any alternative behavior, our package includes three other % versions of the |\newfunction| declarations: the % |\renewfunction|, |\ensurefunction| and |\forcefunction| declarations. % Each of these declarations behaves differently: % \begin{description} % \item[\cs{newfunction}]\SpecialUsageIndex{\newfunction} % defines a new function. If the command \cs{\textit{Function}} already exists, % it is not redefined and an error message occurs. % \item[\cs{renewfunction}]\SpecialUsageIndex{\renewfunction} % redefines the already existing command % \cs{\textit{Function}}. % If this command does not exists, then it is not defined % and an error message occurs. % \item[\cs{ensurefunction}]\SpecialUsageIndex{\ensurefunction} % defines a new function. % If the command \cs{\textit{Function}} already exists, % it is not redefined. % \item[\cs{forcefunction}]\SpecialUsageIndex{\forcefunction} % defines a new function. % If the command \cs{\textit{Function}} already exists, % it is redefined. % \end{description} % \subsection{Vector functions and polar coordinates} % You can (re)define a vector function $f(t)=(x(t),y(t))$ using the % |\newvectorfunction|% % \SpecialUsageIndex{\newvectorfunction}% % \SpecialUsageIndex{\renewvectorfunction}% % \SpecialUsageIndex{\ensurevectorfunction}% % \SpecialUsageIndex{\forcevectorfunction} % declaration or any % of its variants |\renewvectorfunction|, |\ensurevectorfunction| % and |\forcevectorfunction|: % \begin{description} % \item[\cs{newvectorfunction}\Marg{\TBS Function}\Marg{Instructions to compute % \cs{x}, \cs{Dx}, \cs{y} and \cs{Dy} from \cs{t}}] % \end{description} % % For example, you can define the function $f(t)=(t^2,t^3)$ % in the following way: % \begin{Verbatim}[gobble=2] % \newvectorfunction{\F}{% % \SQUARE{\t}{\x} % x=t^2 % \MULTIPLY{2}{\t}{\Dx} % x'=2t % \CUBE{\t}{\y} % y=t^3 % \MULTIPLY{3}{\x}{\Dy} % y'=3t^2 % } % \end{Verbatim} % \SpecialUsageIndex{\newpolarfunction}% % \SpecialUsageIndex{\renewpolarfunction}% % \SpecialUsageIndex{\ensurepolarfunction}% % \SpecialUsageIndex{\forcepolarfunction}% % Finally, to define the $r=r(\phi)$ function, in polar coordinates, % we have the declarations % |\newpolarfunction|, % |\renewpolarfunction|, |\ensurepolarfunction| and |\forcepolarfunction|. % \begin{description} % \item[\cs{newpolarfunction}\Marg{\TBS Function}\Marg{Instructions to compute % \cs{r} and \cs{Dr} from \cs{t}}] % \end{description} % % For example, you can define the \emph{cardioide} curve $r(\phi)=1+\cos \phi$, % using high level instructions, % \begin{Verbatim}[gobble=2] % \SUMfunction{\ONEfunction}{\COSfunction}{\ffunction} % y=1 + cos t % \POLARfunction{\ffunction}{\cardioide} % \end{Verbatim} % or, with the |\newpolarfunction| declaration, % \begin{Verbatim}[gobble=2] % \newpolarfunction{\cardioide}{% % \COS{\t}{\r} % \ADD{1}{\r}{\r} % r=1+cos t % \SIN{\t}{\Dr} % \MULTIPLY{-1}{\Dr}{\Dr} % r'=-sin t % } % \end{Verbatim} % % \StopEventually{} % % \part{Implementation} % \section{\textsf{calculator}} % \begin{macrocode} %<*calculator> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{calculator}[2022/09/15 v.2.1] % \end{macrocode} % \subsection{Internal lengths and special numbers} % \cs{cctr@lengtha} and \cs{cctr@lengthb} % will be used in internal calculations and comparisons. % \begin{macrocode} \newdimen\cctr@lengtha \newdimen\cctr@lengthb % \end{macrocode} % \begin{macro}{\cctr@epsilon} % \cs{cctr@epsilon} will store the closest to zero length % in the \TeX{} arithmetic: one scaled point % ($1\,\mathsf{sp}=1/65536\,\mathsf{pt}$). % This means the smallest positive number will be % $0.00002\approx1/65536=1/2^{16}$. % \begin{macrocode} \newdimen\cctr@epsilon \cctr@epsilon=1sp % \end{macrocode} % \end{macro} % \begin{macro}{\cctr@logmaxnum} % The largest \TeX{} number is $16383.99998\approx2^{14}$; % \cs{cctr@logmaxnum} is the logarithm of this number, % $9.704\approx\log16384$. % \begin{macrocode} \def\cctr@logmaxnum{9.704} % \end{macrocode} % \end{macro} % \subsection{Warning messages} % \begin{macrocode} \def\cctr@Warntruncate#1#2{% \PackageWarning{calculator}% {The optional argument in truncate \MessageBreak must be less than 5 \MessageBreak I copy #1 to #2 \MessageBreak without truncating}} \def\cctr@Warnround#1#2{% \PackageWarning{calculator}% {The optional argument in round \MessageBreak must be less than 5 \MessageBreak I copy #1 to #2 \MessageBreak without rounding}} \def\cctr@Warndivzero#1#2{% \PackageWarning{calculator}% {Division by 0.\MessageBreak I can't define #1/#2}} \def\cctr@Warnnogcd{% \PackageWarning{calculator}% {gcd(0,0) is not well defined}} \def\cctr@Warnnoposrad#1{% \PackageWarning{calculator}% {The argument in square root\MessageBreak must be non negative\MessageBreak I can't define sqrt(#1)}} \def\cctr@Warnnointexp#1#2{% \PackageWarning{calculator}% {The exponent in power function\MessageBreak must be an integer\MessageBreak I can't define #1^#2}} \def\cctr@Warnbigarcsin#1{% \PackageWarning{calculator}% {The argument in arcsin\MessageBreak must be a number between -1 and 1\MessageBreak I can't define arcsin(#1)}} \def\cctr@Warnbigarccos#1{% \PackageWarning{calculator}% {The argument in arccos\MessageBreak must be a number between -1 and 1\MessageBreak I can't define arccos(#1)}} \def\cctr@Warnsmallarcosh#1{% \PackageWarning{calculator}% {The argument in arcosh\MessageBreak must be a number greater or equal than 1\MessageBreak I can't define arcosh(#1)}} \def\cctr@Warnbigartanh#1{% \PackageWarning{calculator}% {The argument in artanh\MessageBreak must be a number between -1 and 1\MessageBreak I can't define artanh(#1)}} \def\cctr@Warnsmallarcoth#1{% \PackageWarning{calculator}% {The argument in arcoth\MessageBreak must be a number greater than 1\MessageBreak or smaller than -1\MessageBreak I can't define arcoth(#1)}} \def\cctr@Warnsingmatrix#1#2#3#4{% \PackageWarning{calculator}% {Matrix (#1 #2 ; #3 #4) is singular\MessageBreak Its inverse is not defined}} \def\cctr@WarnsingTDmatrix#1#2#3#4#5#6#7#8#9{% \PackageWarning{calculator}% {Matrix (#1 #2 #3; #4 #5 #6; #7 #8 #9) is singular\MessageBreak Its inverse is not defined}} \def\cctr@WarnIncLinSys{\PackageWarning{calculator}{% Incompatible linear system}} \def\cctr@WarnIncTDLinSys{\PackageWarning{calculator}{% Incompatible or indeterminate linear system\MessageBreak For 3x3 systems I can solve only determinate systems}} \def\cctr@WarnIndLinSys{\PackageWarning{calculator}{% Indeterminate linear system.\MessageBreak I will choose one of the infinite solutions}} \def\cctr@WarnZeroLinSys{\PackageWarning{calculator}{% 0x=0 linear system. Every vector is a solution!\MessageBreak I will choose the (0,0) solution}} \def\cctr@Warninftan#1{% \PackageWarning{calculator}{% Undefined tangent.\MessageBreak The cosine of #1 is zero and, then,\MessageBreak the tangent of #1 is not defined}} \def\cctr@Warninfcotan#1{% \PackageWarning{calculator}{% Undefined cotangent.\MessageBreak The sine of #1 is zero and, then,\MessageBreak the cotangent of #1 is not defined}} \def\cctr@Warninfexp#1{% \PackageWarning{calculator}{% The absolute value of the variable\MessageBreak in the exponential function must be less than \cctr@logmaxnum\MessageBreak (the logarithm of the max number I know)\MessageBreak I can't define exp(#1)}} \def\cctr@Warninfexpb#1#2{% \PackageWarning{calculator}{% The base\MessageBreak in the exponential function must be positive. \MessageBreak I can't define #1^(#2)}} \def\cctr@Warninflog#1{% \PackageWarning{calculator}{% The value of the variable\MessageBreak in the logarithm function must be positive\MessageBreak I can't define log(#1)}} \def\cctr@Warncrossprod(#1)(#2){% \PackageWarning{calculator}% {Vector product only defined\MessageBreak for 3 dimmensional vectors.\MessageBreak I can't define (#1)x(#2)}} \def\cctr@Warnnoangle(#1)(#2){% \PackageWarning{calculator}% {Angle between two vectors only defined\MessageBreak for nonzero vectors.\MessageBreak I can't define an angle between (#1) and (#2)}} % \end{macrocode} % \subsection{Operations with numbers} % \subsubsection*{Assignements and comparisons} % \begin{macro}{\COPY} % \cs{COPY}\marg{\#1}\marg{\#2} % defines the \textit{\#2} command as the number \textit{\#1}. % \begin{macrocode} \def\COPY#1#2{\edef#2{#1}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\GLOBALCOPY} % Global version of \cs{COPY}. % The new defined command \textit{\#2} is not changed outside groups. % \begin{macrocode} \def\GLOBALCOPY#1#2{\xdef#2{#1}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\@OUTPUTSOL} % \cs{@OUTPUTSOL}\marg{\#1}: an internal macro to save solutions % when a group is closed. % % The global c.s. \cs{cctr@outa} preserves solutions. % Whenever we use any temporary parameters in the definition % of an instruction, % we use a group to ensure the local character of those parameters. % The instruction \cs{@OUTPUTSOL} is a bypass to export the solution. % \begin{macrocode} \def\@OUTPUTSOL#1{\GLOBALCOPY{#1}{\cctr@outa}\endgroup\COPY{\cctr@outa}{#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\@OUTPUTSOLS} % Analogous to \cs{@OUTPUTSOL}, preserving a pair of solutions. % \begin{macrocode} \def\@OUTPUTSOLS#1#2{\GLOBALCOPY{#1}{\cctr@outa} \GLOBALCOPY{#2}{\cctr@outb}\endgroup \COPY{\cctr@outa}{#1}\COPY{\cctr@outb}{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\MAX} % \cs{MAX}\marg{\#1}\marg{\#2}\marg{\#3} % defines the \textit{\#3} command as the maximum of numbers % \textit{\#1} and \textit{\#2}. % \begin{macrocode} \def\MAX#1#2#3{% \ifdim #1\p@ < #2\p@ \COPY{#2}{#3}\else\COPY{#1}{#3}\fi\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\MIN} % \cs{MIN}\marg{\#1}\marg{\#2}\marg{\#3} % defines the \textit{\#3} command as the minimum of numbers % \textit{\#1} and \textit{\#2}. % \begin{macrocode} \def\MIN#1#2#3{% \ifdim #1\p@ > #2\p@ \COPY{#2}{#3}\else\COPY{#1}{#3}\fi\ignorespaces} % \end{macrocode} % \end{macro} % \subsubsection*{Real arithmetic} % \begin{macro}{\ABSVALUE} % \cs{ABSVALUE}\marg{\#1}\marg{\#2} % defines the \textit{\#2} command as the % absolute value of number \textit{\#1}. % \begin{macrocode} \def\ABSVALUE#1#2{% \ifdim #1\p@<\z@ \MULTIPLY{-1}{#1}{#2}\else\COPY{#1}{#2}\fi} % \end{macrocode} % \end{macro} % \paragraph*{Product, sum and difference} % \begin{macro}{\MULTIPLY} % \cs{MULTIPLY}\marg{\#1}\marg{\#2}\marg{\#3} % defines the \textit{\#3} command as the % product of numbers \textit{\#1} and \textit{\#2}. % \begin{macrocode} \def\MULTIPLY#1#2#3{\cctr@lengtha=#1\p@ \cctr@lengtha=#2\cctr@lengtha \edef#3{\expandafter\strip@pt\cctr@lengtha}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\ADD} % \cs{ADD}\marg{\#1}\marg{\#2}\marg{\#3} % defines the \textit{\#3} command as the % sum of numbers \textit{\#1} and \textit{\#2}. % \begin{macrocode} \def\ADD#1#2#3{\cctr@lengtha=#1\p@ \cctr@lengthb=#2\p@ \advance\cctr@lengtha by \cctr@lengthb \edef#3{\expandafter\strip@pt\cctr@lengtha}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\SUBTRACT} % \cs{SUBTRACT}\marg{\#1}\marg{\#2}\marg{\#3} % defines the \textit{\#3} command as the % difference of numbers \textit{\#1} and \textit{\#2}. % \begin{macrocode} \def\SUBTRACT#1#2#3{\ADD{#1}{-#2}{#3}} % \end{macrocode} % \end{macro} % \paragraph*{Divisions} % We define several kinds of \emph{divisions}: the quotient of % two real numbers, the integer quotient, and the quotient of % two lengths. % The basic algorithm is a lightly modified version of the Beccari's division. % \begin{macro}{\DIVIDE} % \cs{DIVIDE}\marg{\#1}\marg{\#2}\marg{\#3} % defines the \textit{\#3} command as the % quotient of numbers \textit{\#1} and \textit{\#2}. % \begin{macrocode} \def\DIVIDE#1#2#3{% \begingroup % \end{macrocode} % Absolute values of dividend and divisor % \begin{macrocode} \ABSVALUE{#1}{\cctr@tempD} \ABSVALUE{#2}{\cctr@tempd} % \end{macrocode} % The sign of quotient % \begin{macrocode} \ifdim#1\p@<\z@\ifdim#2\p@>\z@\COPY{-1}{\cctr@sign} \else\COPY{1}{\cctr@sign}\fi \else\ifdim#2\p@>\z@\COPY{1}{\cctr@sign} \else\COPY{-1}{\cctr@sign}\fi \fi % \end{macrocode} % Integer part of quotient % \begin{macrocode} \@DIVIDE{\cctr@tempD}{\cctr@tempd}{\cctr@tempq}{\cctr@tempr} \COPY{\cctr@tempq.}{\cctr@Q} % \end{macrocode} % Fractional part up to five decimal places. % \cs{cctr@ndec} is the number of decimal places already computed. % \begin{macrocode} \COPY{0}{\cctr@ndec} \@whilenum \cctr@ndec<5 \do{% % \end{macrocode} % Each decimal place is calculated by multiplying by 10 the last remainder % and dividing it by the divisor. % But when the remainder is greater than 1638.3, an overflow occurs, because % 16383.99998 is the greatest number. % So, instead, we multiply the divisor by 0.1. % \begin{macrocode} \ifdim\cctr@tempr\p@<1638\p@ \MULTIPLY{\cctr@tempr}{10}{\cctr@tempD} \else \COPY{\cctr@tempr}{\cctr@tempD} \MULTIPLY{\cctr@tempd}{0.1}{\cctr@tempd} \fi \@DIVIDE{\cctr@tempD}{\cctr@tempd}{\cctr@tempq}{\cctr@tempr} \COPY{\cctr@Q\cctr@tempq}{\cctr@Q} \ADD{1}{\cctr@ndec}{\cctr@ndec}}% % \end{macrocode} % Adjust the sign and return the solution. % \begin{macrocode} \MULTIPLY{\cctr@sign}{\cctr@Q}{#3} \@OUTPUTSOL{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\@DIVIDE} % The \cs{@DIVIDE}\parg{\#1} \parg{\#2}\parg{\#3}\parg{\#4} % command computes $\textit{\#1}/\textit{\#2}$ and % returns an integer quotient (\textit{\#3}) and a real remainder % (\textit{\#4}). % \begin{macrocode} \def\@DIVIDE#1#2#3#4{% \@INTEGERDIVIDE{#1}{#2}{#3} \MULTIPLY{#2}{#3}{#4} \SUBTRACT{#1}{#4}{#4}} % \end{macrocode} % \end{macro} % \begin{macro}{\@INTEGERDIVIDE} % \cs{@INTEGERDIVIDE} divides two numbers (not necessarily integer) % and returns an integer % (this is the integer quotient only for nonnegative integers). % \begin{macrocode} \def\@INTEGERDIVIDE#1#2#3{% \cctr@lengtha=#1\p@ \cctr@lengthb=#2\p@ \ifdim\cctr@lengthb=\z@ \let#3\undefined \cctr@Warndivzero#1#2% \else \divide\cctr@lengtha\cctr@lengthb \COPY{\number\cctr@lengtha}{#3} \fi\ignorespaces} % \end{macrocode} % \end{macro} % \changes{v2.0}{2014/02/13}{New commands: \cs{LENGTHADD}, % \cs{LENGTHSUBTRACT}} % \begin{macro}{\LENGTHADD} % The sum of two lengths. % \cs{LENGTHADD}\marg{\#1}\marg{\#2}\marg{\#3} % stores in \textit{\#3} the sum of the lenghts % \textit{\#1} and \textit{\#2} (\#3 must be a length). % \begin{macrocode} \def\LENGTHADD#1#2#3{\cctr@lengtha=#1 \cctr@lengthb=#2 \advance\cctr@lengtha by \cctr@lengthb \setlength{#3}{\cctr@lengtha}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\LENGTHSUBTRACT} % The difference of two lengths. % \cs{LENGTHSUBTRACT}\marg{\#1}\marg{\#2}\marg{\#3} % stores in \textit{\#3} the difference of the lenghts % \textit{\#1} and \textit{\#2} (\#3 must be a length). % \begin{macrocode} \def\LENGTHSUBTRACT#1#2#3{% \LENGTHADD{#1}{-#2}{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\LENGTHDIVIDE} % The quotient of two lengths must be a number (not a length). % For example, one inch over one centimeter equals $2.54$. % \cs{LENGTHDIVIDE}\marg{\#1}\marg{\#2}\marg{\#3} % stores in \textit{\#3} the quotient of the lenghts % \textit{\#1} and \textit{\#2}. % \begin{macrocode} \def\LENGTHDIVIDE#1#2#3{% \begingroup \cctr@lengtha=#1 \cctr@lengthb=#2 \edef\cctr@tempa{\expandafter\strip@pt\cctr@lengtha}% \edef\cctr@tempb{\expandafter\strip@pt\cctr@lengthb}% \DIVIDE{\cctr@tempa}{\cctr@tempb}{#3} \@OUTPUTSOL{#3}} % \end{macrocode} % \end{macro} % \paragraph*{Powers} % \begin{macro}{\SQUARE} % \cs{SQUARE}\marg{\#1}\marg{\#2} % stores \textit{\#1} squared in \textit{\#2}. % \begin{macrocode} \def\SQUARE#1#2{\MULTIPLY{#1}{#1}{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\CUBE} % \cs{CUBE}\marg{\#1}\marg{\#2} % stores \textit{\#1} cubed in \textit{\#2}. % \begin{macrocode} \def\CUBE#1#2{\MULTIPLY{#1}{#1}{#2}\MULTIPLY{#2}{#1}{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\POWER} % \cs{POWER}\marg{\#1}\marg{\#2}\marg{\#3} % stores in \textit{\#3} the power $\textit{\#1}^{\textit{\#2}}$ % \begin{macrocode} \def\POWER#1#2#3{% \begingroup \INTEGERPART{#2}{\cctr@tempexp} \ifdim \cctr@tempexp\p@<#2\p@ \cctr@Warnnointexp{#1}{#2} \let#3\undefined \else % \end{macrocode} % This ensures that power will be defined only if the exponent is an integer. % \begin{macrocode} \@POWER{#1}{#2}{#3}\fi\@OUTPUTSOL{#3}} % \end{macrocode} % \end{macro} % \begin{macrocode} \def\@POWER#1#2#3{% \begingroup \ifdim #2\p@<\z@ % \end{macrocode} % For negative exponents, $a^n=(1/a)^{-n}$. % \begin{macrocode} \DIVIDE{1}{#1}{\cctr@tempb} \MULTIPLY{-1}{#2}{\cctr@tempc} \@POWER{\cctr@tempb}{\cctr@tempc}{#3} \else \COPY{0}{\cctr@tempa} \COPY{1}{#3} \@whilenum \cctr@tempa<#2 \do {% \MULTIPLY{#1}{#3}{#3} \ADD{1}{\cctr@tempa}{\cctr@tempa}}% \fi\@OUTPUTSOL{#3}} % \end{macrocode} % \subsubsection*{Integer arithmetic and related things} % \begin{macro}{\INTEGERDIVISION} % \cs{INTEGERDIVISION}\marg{\#1}\marg{\#2}\marg{\#3}\marg{\#4} % computes the division $\textit{\#1}/\textit{\#2}$ and returns % an integer quotient and a positive remainder. % \begin{macrocode} \def\INTEGERDIVISION#1#2#3#4{% \begingroup \ABSVALUE{#2}{\cctr@tempd} \@DIVIDE{#1}{#2}{#3}{#4} \ifdim #4\p@<\z@ \ifdim #1\p@<\z@ \ifdim #2\p@<\z@ \ADD{#3}{1}{#3} \else \SUBTRACT{#3}{1}{#3} \fi \ADD{#4}{\cctr@tempd}{#4} \fi\fi\@OUTPUTSOLS{#3}{#4}} % \end{macrocode} % \end{macro} % \begin{macro}{\MODULO} % \cs{MODULO}\marg{\#1}\marg{\#2}\marg{\#3} % returns the remainder of division $\textit{\#1}/\textit{\#2}$. % \begin{macrocode} \def\MODULO#1#2#3{% \begingroup \INTEGERDIVISION{#1}{#2}{\cctr@temp}{#3}\@OUTPUTSOL{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\INTEGERQUOTIENT} % \cs{INTEGERQUOTIENT}\marg{\#1}\marg{\#2}\marg{\#3} % returns the integer quotient of division % $\textit{\#1}/\textit{\#2}$. % \begin{macrocode} \def\INTEGERQUOTIENT#1#2#3{% \begingroup \INTEGERDIVISION{#1}{#2}{#3}{\cctr@temp}\@OUTPUTSOL{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\INTEGERPART} % \cs{INTEGERPART}\marg{\#1}\marg{\#2} % returns the integer part of \textit{\#2}. % \begin{macrocode} \def\@@INTEGERPART#1.#2.#3)#4{\ifnum #11=1 \COPY{0}{#4} \else \ADD{0}{#1}{#4}\fi} \def\@INTEGERPART#1#2{\expandafter\@@INTEGERPART#1..){#2}} \def\INTEGERPART#1#2{\begingroup \ifdim #1\p@<\z@ \MULTIPLY{-1}{#1}{\cctr@temp} \INTEGERPART{\cctr@temp}{#2} \ifdim #2\p@<\cctr@temp\p@ \SUBTRACT{-#2}{1}{#2} \else \COPY{-#2}{#2} \fi \else \@INTEGERPART{#1}{#2} \fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\FLOOR} % \cs{FLOOR} is an alias for \cs{INTEGERPART}. % \begin{macrocode} \let\FLOOR\INTEGERPART % \end{macrocode} % \end{macro} % \begin{macro}{\FRACTIONALPART} % \cs{FRACTIONALPART}\marg{\#1}\marg{\#2} % returns the fractional part of % \textit{\#2}. % \changes{v2.1}{2022/09/15}{Bug fixed} % \begin{macrocode} \def\@@FRACTIONALPART#1.#2.#3)#4{\ifnum #21=1 \COPY{0}{#4} \else \ADD{0}{0.#2}{#4}\fi} \def\@FRACTIONALPART#1#2{\expandafter\@@FRACTIONALPART#1..){#2}} \def\FRACTIONALPART#1#2{\begingroup \ifdim #1\p@<\z@ \INTEGERPART{#1}{\cctr@tempA} \SUBTRACT{#1}{\cctr@tempA}{#2} \else \@FRACTIONALPART{#1}{#2} \fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\TRUNCATE} % \cs{TRUNCATE}\oarg{\#1}\marg{\#2}\marg{\#3} % truncates \textit{\#2} to \textit{\#1} (0, 1, 2 (default), 3 or 4) digits. % \changes{v2.1}{2022/09/15}{Bug fixed} % \begin{macrocode} \def\TRUNCATE{\@ifnextchar[\@@TRUNCATE\@TRUNCATE} \def\@TRUNCATE#1#2{\@@TRUNCATE[2]{#1}{#2}} \def\@@TRUNCATE[#1]#2#3{% \begingroup \ifdim #1\p@ > 4\p@ \cctr@Warntruncate{#2}{\noexpand#3} \COPY{#2}{#3} \else \INTEGERPART{#2}{\cctr@tempa} \ifdim \cctr@tempa\p@ = #2\p@ \expandafter\@@@TRUNCATE\cctr@tempa.00000.)[#1]{#3} \else \expandafter\@@@TRUNCATE#200000.)[#1]{#3} \fi\fi \@OUTPUTSOL{#3}} \def\@@@TRUNCATE#1.#2#3#4#5#6.#7)[#8]#9{% \ifcase #8 \COPY{#1}{#9} \or\COPY{#1.#2}{#9} \or\COPY{#1.#2#3}{#9} \or\COPY{#1.#2#3#4}{#9} \or\COPY{#1.#2#3#4#5}{#9} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\ROUND} % \cs{ROUND}\oarg{\#1}\marg{\#2}\marg{\#3} % rounds \textit{\#2} to \textit{\#1} (0, 1, 2 (default), 3 or 4) digits. % \changes{v2.1}{2022/09/15}{Bug fixed} % \begin{macrocode} \def\ROUND{\@ifnextchar[\@@ROUND\@ROUND} \def\@ROUND#1#2{\@@ROUND[2]{#1}{#2}} \def\@@ROUND[#1]#2#3{% \begingroup \ifdim #1\p@ > 4\p@ \cctr@Warnround{#2}{\noexpand#3} \COPY{#2}{#3} \else \INTEGERPART{#2}{\cctr@tempa} \ifdim \cctr@tempa\p@ = #2\p@ \expandafter\@@@ROUND\cctr@tempa.00000.)[#1]{#3} \else \expandafter\@@@ROUND#200000.)[#1]{#3} \fi \fi \@OUTPUTSOL{#3}} \def\@@@ROUND#1.#2#3#4#5#6.#7)[#8]#9{% \ifcase #8 \COPY{#1}{#9} \ifnum #2>4 \ADD{#1}{1}{\cctr@tempp}\COPY{\cctr@tempp}{#9} \fi \or\COPY{#1.#2}{#9} \ifnum #3>4 \ADD{#2}{1}\cctr@tempq\COPY{#1}{\cctr@tempp} \ifnum\cctr@tempq=10\ADD{\cctr@tempp}{1}\cctr@tempp\COPY{0}{\cctr@tempq}\fi \COPY{\cctr@tempp.\cctr@tempq}{#9} \fi \or\COPY{#1.#2#3}{#9} \ifnum #4>4 \ADD{#3}1\cctr@tempq\COPY{#2}{\cctr@tempp}\COPY{#1}{\cctr@tempo} \ifnum\cctr@tempq=10\ADD{\cctr@tempp}{1}{\cctr@tempp}\COPY{0}{\cctr@tempq}\fi \ifnum\cctr@tempp=10\ADD{\cctr@tempo}{1}\cctr@tempo\COPY{0}{\cctr@tempp}\fi \COPY{\cctr@tempo.\cctr@tempp\cctr@tempq}{#9} \fi \or\COPY{#1.#2#3#4}{#9} \ifnum #5>4 \ADD{#4}1\cctr@tempq\COPY{#3}{\cctr@tempp}\COPY{#2}{\cctr@tempo}\COPY{#1}{\cctr@tempn} \ifnum\cctr@tempq=10\ADD{\cctr@tempp}{1}{\cctr@tempp}\COPY{0}{\cctr@tempq}\fi \ifnum\cctr@tempp=10\ADD{\cctr@tempo}{1}\cctr@tempo\COPY{0}{\cctr@tempp}\fi \ifnum\cctr@tempo=10\ADD{\cctr@tempn}{1}\cctr@tempn\COPY{0}{\cctr@tempo}\fi \COPY{\cctr@tempn.\cctr@tempo\cctr@tempp\cctr@tempq}{#9} \fi \or\COPY{#1.#2#3#4#5}{#9} \ifnum #6>4 \ADD{#5}1\cctr@tempq\COPY{#4}{\cctr@tempp}\COPY{#3}{\cctr@tempo}\COPY{#2}{\cctr@tempn}\COPY{#1}{\cctr@tempm} \ifnum\cctr@tempq=10\ADD{\cctr@tempp}{1}{\cctr@tempp}\COPY{0}{\cctr@tempq}\fi \ifnum\cctr@tempp=10\ADD{\cctr@tempo}{1}\cctr@tempo\COPY{0}{\cctr@tempp}\fi \ifnum\cctr@tempo=10\ADD{\cctr@tempn}{1}\cctr@tempn\COPY{0}{\cctr@tempo}\fi \ifnum\cctr@tempn=10\ADD{\cctr@tempm}{1}\cctr@tempm\COPY{0}{\cctr@tempn}\fi \COPY{\cctr@tempm.\cctr@tempn\cctr@tempo\cctr@tempp\cctr@tempq}{#9} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\GCD} % \cs{GCD}\marg{\#1}\marg{\#2}\marg{\#3} % Greatest common divisor, using the Euclidean algorithm % \begin{macrocode} \def\GCD#1#2#3{% \begingroup \ABSVALUE{#1}{\cctr@tempa} \ABSVALUE{#2}{\cctr@tempb} \MAX{\cctr@tempa}{\cctr@tempb}{\cctr@tempc} \MIN{\cctr@tempa}{\cctr@tempb}{\cctr@tempa} \COPY{\cctr@tempc}{\cctr@tempb} \ifnum \cctr@tempa = 0 \ifnum \cctr@tempb = 0 \cctr@Warnnogcd \let#3\undefined \else \COPY{\cctr@tempb}{#3} \fi \else % \end{macrocode} % Euclidean algorithm: if $c\equiv b \pmod{a}$ then $\gcd(b,a)=\gcd(a,c)$. % Iterating this property, we obtain $\gcd(b,a)$ as the last nonzero residual. % \begin{macrocode} \@whilenum \cctr@tempa > \z@ \do {% \COPY{\cctr@tempa}{#3}% \MODULO{\cctr@tempb}{\cctr@tempa}{\cctr@tempc}% \COPY\cctr@tempa\cctr@tempb% \COPY\cctr@tempc\cctr@tempa} \fi\ignorespaces\@OUTPUTSOL{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\LCM} % \cs{LCM}\marg{\#1}\marg{\#2}\marg{\#3} % Least common multiple. % \begin{macrocode} \def\LCM#1#2#3{% \GCD{#1}{#2}{#3}% \ifx #3\undefined \COPY{0}{#3} \else \DIVIDE{#1}{#3}{#3} \MULTIPLY{#2}{#3}{#3} \ABSVALUE{#3}{#3} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\FRACTIONSIMPLIFY} % \cs{FRACTIONSIMPLIFY}\marg{\#1}\marg{\#2}\marg{\#3}\marg{\#4} % Fraction simplification: $\textit{\#3}/\textit{\#4}$ is the irreducible % fraction equivalent to $\textit{\#1}/\textit{\#2}$. % \begin{macrocode} \def\FRACTIONSIMPLIFY#1#2#3#4{% \ifnum #1=\z@ \COPY{0}{#3}\COPY{1}{#4} \else \GCD{#1}{#2}{#3}% \DIVIDE{#2}{#3}{#4} \DIVIDE{#1}{#3}{#3} \ifnum #4<0 \MULTIPLY{-1}{#4}{#4}\MULTIPLY{-1}{#3}{#3}\fi \fi\ignorespaces} % \end{macrocode} % \end{macro} % \subsubsection*{Elementary functions} % \paragraph*{Square roots} % \begin{macro}{\SQUAREROOT} % \cs{SQUAREROOT}\marg{\#1}\marg{\#2} % defines \textit{\#2} as the square root of \textit{\#1}, % using the Newton's method: $x_{n+1}=x_n-(x_n^2-\textit{\#1})/(2x_n)$. % \begin{macrocode} \def\SQUAREROOT#1#2{% \begingroup \ifdim #1\p@ = \z@ \COPY{0}{#2} \else \ifdim #1\p@ < \z@ \let#2\undefined \cctr@Warnnoposrad{#1}% \else % \end{macrocode} % We take \textit{\#1} as the initial approximation. % \begin{macrocode} \COPY{#1}{#2} % \end{macrocode} % \cs{cctr@lengthb} will be the difference of two successive iterations. % % We start with |\cctr@lengthb=5\p@| to ensure almost one iteration. % \begin{macrocode} \cctr@lengthb=5\p@ % \end{macrocode} % Successive iterations % \begin{macrocode} \@whilenum \cctr@lengthb>\cctr@epsilon \do {% % \end{macrocode} % Copy the actual approximation to \cs{cctr@tempw} % \begin{macrocode} \COPY{#2}{\cctr@tempw} \DIVIDE{#1}{\cctr@tempw}{\cctr@tempz} \ADD{\cctr@tempw}{\cctr@tempz}{\cctr@tempz} \DIVIDE{\cctr@tempz}{2}{\cctr@tempz} % \end{macrocode} % Now, \cs{cctr@tempz} is the new approximation. % \begin{macrocode} \COPY{\cctr@tempz}{#2} % \end{macrocode} % Finally, we store in \cs{cctr@lengthb} the difference % of the two last approximations, finishing the loop. % \begin{macrocode} \SUBTRACT{#2}{\cctr@tempw}{\cctr@tempw} \cctr@lengthb=\cctr@tempw\p@% \ifnum \cctr@lengthb<\z@ \cctr@lengthb=-\cctr@lengthb \fi} \fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\SQRT} % \cs{SQRT} is an alias for \cs{SQUAREROOT}. % \begin{macrocode} \let\SQRT\SQUAREROOT % \end{macrocode} % \end{macro} % \paragraph{Trigonometric functions} % For a variable close enough to zero, the sine and tangent functions % are computed using some continued fractions. % Then, all trigonometric functions are derived from well-known formulas. % \begin{macro}{\SIN} % \cs{SIN}\marg{\#1}\marg{\#2}. Sine of \textit{\#1}. % \begin{macrocode} \def\SIN#1#2{% \begingroup % \end{macrocode} % Exact sine for $t\in\{\pi/2,-\pi/2,3\pi/2\}$ % \begin{macrocode} \ifdim #1\p@=-\numberHALFPI\p@ \COPY{-1}{#2} \else \ifdim #1\p@=\numberHALFPI\p@ \COPY{1}{#2} \else \ifdim #1\p@=\numberTHREEHALFPI\p@ \COPY{-1}{#2} \else % \end{macrocode} % If $\left\vert t \right\vert>\pi/2$, change $t$ to a smaller value. % \begin{macrocode} \ifdim#1\p@<-\numberHALFPI\p@ \ADD{#1}{\numberTWOPI}{\cctr@tempb} \SIN{\cctr@tempb}{#2} \else \ifdim #1\p@<\numberHALFPI\p@ % \end{macrocode} % Compute the sine. % \begin{macrocode} \@BASICSINE{#1}{#2} \else \ifdim #1\p@<\numberTHREEHALFPI\p@ \SUBTRACT{\numberPI}{#1}{\cctr@tempb} \SIN{\cctr@tempb}{#2} \else \SUBTRACT{#1}{\numberTWOPI}{\cctr@tempb} \SIN{\cctr@tempb}{#2} \fi\fi\fi\fi\fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\@BASICSINE} % \cs{@BASICSINE}\marg{\#1}\marg{\#2} applies this approximation: % \[ % \sin x = \frac{x}{ % 1+\displaystyle\frac{x^2}{ % 2\cdot3-x^2+\displaystyle\frac{2\cdot3x^2}{ % 4\cdot5-x^2+\displaystyle\frac{4\cdot5x^2}{ % 6\cdot7-x^2+\cdots % } % } % } % } % \] % \begin{macrocode} \def\@BASICSINE#1#2{% \begingroup \ABSVALUE{#1}{\cctr@tempa} % \end{macrocode} % Exact sine of zero % \begin{macrocode} \ifdim\cctr@tempa\p@=\z@ \COPY{0}{#2} \else % \end{macrocode} % For $t$ very close to zero, $\sin t\approx t$. % \begin{macrocode} \ifdim \cctr@tempa\p@<0.009\p@\COPY{#1}{#2} \else % \end{macrocode} % Compute the continued fraction. % \begin{macrocode} \SQUARE{#1}{\cctr@tempa} \DIVIDE{\cctr@tempa}{42}{#2} \SUBTRACT{1}{#2}{#2} \MULTIPLY{#2}{\cctr@tempa}{#2} \DIVIDE{#2}{20}{#2} \SUBTRACT{1}{#2}{#2} \MULTIPLY{#2}{\cctr@tempa}{#2} \DIVIDE{#2}{6}{#2} \SUBTRACT{1}{#2}{#2} \MULTIPLY{#2}{#1}{#2} \fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\COS} % \cs{COS}\marg{\#1}\marg{\#2}. Cosine of \textit{\#1}: $\cos t=\sin(t+\pi/2)$. % \begin{macrocode} \def\COS#1#2{% \begingroup \ADD{\numberHALFPI}{#1}{\cctr@tempc} \SIN{\cctr@tempc}{#2}\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\TAN} % \cs{TAN}\marg{\#1}\marg{\#2}. Tangent of \textit{\#1}. % \begin{macrocode} \def\TAN#1#2{% \begingroup % \end{macrocode} % Tangent is infinite for $t=\pm\pi/2$ % \begin{macrocode} \ifdim #1\p@=-\numberHALFPI\p@ \cctr@Warninftan{#1} \let#2\undefined \else \ifdim #1\p@=\numberHALFPI\p@ \cctr@Warninftan{#1} \let#2\undefined \else % \end{macrocode} % If $\left\vert t \right\vert>\pi/2$, change $t$ to a smaller value. % \begin{macrocode} \ifdim #1\p@<-\numberHALFPI\p@ \ADD{#1}{\numberPI}{\cctr@tempb} \TAN{\cctr@tempb}{#2} \else \ifdim #1\p@<\numberHALFPI\p@ % \end{macrocode} % Compute the tangent. % \begin{macrocode} \@BASICTAN{#1}{#2} \else \SUBTRACT{#1}{\numberPI}{\cctr@tempb} \TAN{\cctr@tempb}{#2} \fi\fi\fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\@BASICTAN} % \cs{@BASICTAN}\marg{\#1}\marg{\#2} applies this approximation: % \[ % \tan x = \frac{1}{ % \displaystyle\frac{1}{x}-\displaystyle\frac{1}{ % \displaystyle\frac{3}{x}-\displaystyle\frac{1}{ % \displaystyle\frac{5}{x}-\displaystyle\frac{1}{ % \displaystyle\frac{7}{x}-\displaystyle\frac{1}{ % \displaystyle\frac{9}{x}-\displaystyle\frac{1}{ % \displaystyle\frac{11}{x}- % \cdots % } % } % } % } % } % } % \] % \begin{macrocode} \def\@BASICTAN#1#2{% \begingroup \ABSVALUE{#1}{\cctr@tempa} % \end{macrocode} % Exact tangent of zero. % \begin{macrocode} \ifdim\cctr@tempa\p@=\z@ \COPY{0}{#2} \else % \end{macrocode} % For $t$ very close to zero, $\tan t\approx t$. % \begin{macrocode} \ifdim\cctr@tempa\p@<0.04\p@ \COPY{#1}{#2} \else % \end{macrocode} % Compute the continued fraction. % \begin{macrocode} \DIVIDE{#1}{11}{#2} \DIVIDE{9}{#1}{\cctr@tempa} \SUBTRACT{\cctr@tempa}{#2}{#2} \DIVIDE{1}{#2}{#2} \DIVIDE{7}{#1}{\cctr@tempa} \SUBTRACT{\cctr@tempa}{#2}{#2} \DIVIDE{1}{#2}{#2} \DIVIDE{5}{#1}{\cctr@tempa} \SUBTRACT{\cctr@tempa}{#2}{#2} \DIVIDE{1}{#2}{#2} \DIVIDE{3}{#1}{\cctr@tempa} \SUBTRACT{\cctr@tempa}{#2}{#2} \DIVIDE{1}{#2}{#2} \DIVIDE{1}{#1}{\cctr@tempa} \SUBTRACT{\cctr@tempa}{#2}{#2} \DIVIDE{1}{#2}{#2} \fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\COT} % \cs{COT}\marg{\#1}\marg{\#2}. Cotangent of \textit{\#1}: % If $\cos t=0$ then $\cot t=0$; if $\tan t=0$ then $\cot t=\infty$. % Otherwise, $\cot t=1/\tan t$. % \begin{macrocode} \def\COT#1#2{% \begingroup \COS{#1}{#2} \ifdim #2\p@ = \z@ \COPY{0}{#2} \else \TAN{#1}{#2} \ifdim #2\p@ = \z@ \cctr@Warninfcotan{#1} \let#2\undefined \else \DIVIDE{1}{#2}{#2} \fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\DEGtoRAD} % \cs{DEGtoRAD}\marg{\#1}\marg{\#2}. Convert degrees to radians. % \begin{macrocode} \def\DEGtoRAD#1#2{\DIVIDE{#1}{57.29578}{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\RADtoDEG} % \cs{RADtoDEG}\marg{\#1}\marg{\#2}. Convert radians to degrees. % \begin{macrocode} \def\RADtoDEG#1#2{\MULTIPLY{#1}{57.29578}{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\REDUCERADIANSANGLE} % Reduces to the trigonometrically equivalent arc in $]{-}\pi,\pi]$. % \begin{macrocode} \def\REDUCERADIANSANGLE#1#2{% \COPY{#1}{#2} \ifdim #1\p@ < -\numberPI\p@ \ADD{#1}{\numberTWOPI}{#2} \REDUCERADIANSANGLE{#2}{#2} \fi \ifdim #1\p@ > \numberPI\p@ \SUBTRACT{#1}{\numberTWOPI}{#2} \REDUCERADIANSANGLE{#2}{#2} \fi \ifdim #1\p@ = -180\p@ \COPY{\numberPI}{#2} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\REDUCEDEGREESANGLE} % Reduces to the trigonometrically equivalent angle in $]{-}180,180]$. % \begin{macrocode} \def\REDUCEDEGREESANGLE#1#2{% \COPY{#1}{#2} \ifdim #1\p@ < -180\p@ \ADD{#1}{360}{#2} \REDUCEDEGREESANGLE{#2}{#2} \fi \ifdim #1\p@ > 180\p@ \SUBTRACT{#1}{360}{#2} \REDUCEDEGREESANGLE{#2}{#2} \fi \ifdim #1\p@ = -180\p@ \COPY{180}{#2} \fi} % \end{macrocode} % \end{macro} % \subparagraph*{Trigonometric functions in degrees} % Four next commands compute trigonometric functions % in \emph{degrees}. By default, a circle has $360$ % degrees, but we can use an arbitrary number of divisions % using the optional argument of these commands. % \begin{macro}{\DEGREESSIN} % \cs{DEGREESSIN}\oarg{\#1}\marg{\#2}\marg{\#3}. % Sine of \textit{\#2} \emph{degrees}. % \begin{macrocode} \def\DEGREESSIN{\@ifnextchar[\@@DEGREESSIN\@DEGREESSIN} % \end{macrocode} % \end{macro} % \begin{macro}{\DEGREESCOS} % \cs{DEGREESCOS}\oarg{\#1}\marg{\#2}\marg{\#3}. % Cosine of \textit{\#2} \emph{degrees}. % \begin{macrocode} \def\DEGREESCOS{\@ifnextchar[\@@DEGREESCOS\@DEGREESCOS} % \end{macrocode} % \end{macro} % \begin{macro}{\DEGREESTAN} % \cs{DEGREESTAN}\oarg{\#1}\marg{\#2}\marg{\#3}. % Tangent of \textit{\#2} \emph{degrees}. % \begin{macrocode} \def\DEGREESTAN{\@ifnextchar[\@@DEGREESTAN\@DEGREESTAN} % \end{macrocode} % \end{macro} % \begin{macro}{\DEGREESCOT} % \cs{DEGREESCOT}\oarg{\#1}\marg{\#2}\marg{\#3}. % Cotangent of \textit{\#2} \emph{degrees}. % \begin{macrocode} \def\DEGREESCOT{\@ifnextchar[\@@DEGREESCOT\@DEGREESCOT} % \end{macrocode} % \end{macro} % \begin{macro}{\@DEGREESSIN} % \cs{@DEGREESSIN} computes the sine in sexagesimal \emph{degrees}. % \begin{macrocode} \def\@DEGREESSIN#1#2{% \begingroup \ifdim #1\p@=-90\p@ \COPY{-1}{#2} \else \ifdim #1\p@=90\p@ \COPY{1}{#2} \else \ifdim #1\p@=270\p@ \COPY{-1}{#2} \else \ifdim#1\p@<-90\p@ \ADD{#1}{360}{\cctr@tempb} \DEGREESSIN{\cctr@tempb}{#2} \else \ifdim #1\p@<90\p@ \DEGtoRAD{#1}{\cctr@tempb} \@BASICSINE{\cctr@tempb}{#2} \else \ifdim #1\p@<270\p@ \SUBTRACT{180}{#1}{\cctr@tempb} \DEGREESSIN{\cctr@tempb}{#2} \else \SUBTRACT{#1}{360}{\cctr@tempb} \DEGREESSIN{\cctr@tempb}{#2} \fi\fi\fi\fi\fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\@DEGREESCOS} % \cs{@DEGREESCOS} computes the cosine in sexagesimal \emph{degrees}. % \begin{macrocode} \def\@DEGREESCOS#1#2{% \begingroup \ADD{90}{#1}{\cctr@tempc} \DEGREESSIN{\cctr@tempc}{#2}\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\@DEGREESTAN} % \cs{@DEGREESTAN} computes the tangent in sexagesimal \emph{degrees}. % \begin{macrocode} \def\@DEGREESTAN#1#2{% \begingroup \ifdim #1\p@=-90\p@ \cctr@Warninftan{#1} \let#2\undefined \else \ifdim #1\p@=90\p@ \cctr@Warninftan{#1} \let#2\undefined \else \ifdim #1\p@<-90\p@ \ADD{#1}{180}{\cctr@tempb} \DEGREESTAN{\cctr@tempb}{#2} \else \ifdim #1\p@<90\p@ \DEGtoRAD{#1}{\cctr@tempb} \@BASICTAN{\cctr@tempb}{#2} \else \SUBTRACT{#1}{180}{\cctr@tempb} \DEGREESTAN{\cctr@tempb}{#2} \fi\fi\fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\@DEGREESCOT} % \cs{@DEGREESCOT} computes the cotangent in sexagesimal \emph{degrees}. % \begin{macrocode} \def\@DEGREESCOT#1#2{% \begingroup \DEGREESCOS{#1}{#2} \ifdim #2\p@ = \z@ \COPY{0}{#2} \else \DEGREESTAN{#1}{#2} \ifdim #2\p@ = \z@ \cctr@Warninfcotan{#1} \let#2\undefined \else \DIVIDE{1}{#2}{#2} \fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % For an arbitrary number of \emph{degrees}, we normalise % to $360$ degrees and, then, call the former functions. % \begin{macro}{\@@DEGREESSIN} % \cs{@@DEGREESSIN} computes the sine. % A circle has \textit{\#1} \emph{degrees}. % \begin{macrocode} \def\@@DEGREESSIN[#1]#2#3{\@CONVERTDEG{#1}{#2} \@DEGREESSIN{\@DEGREES}{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\@@DEGREESCOS} % \cs{@@DEGREESCOS} computes the sine. % A circle has \textit{\#1} \emph{degrees}. % \begin{macrocode} \def\@@DEGREESCOS[#1]#2#3{\@CONVERTDEG{#1}{#2} \DEGREESCOS{\@DEGREES}{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\@@DEGREESTAN} % \cs{@@DEGREESTAN} computes the sine. % A circle has \textit{\#1} \emph{degrees}. % \begin{macrocode} \def\@@DEGREESTAN[#1]#2#3{\@CONVERTDEG{#1}{#2} \DEGREESTAN{\@DEGREES}{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\@@DEGREESCOT} % \cs{@@DEGREESCOT} computes the sine. % A circle has \textit{\#1} \emph{degrees}. % \begin{macrocode} \def\@@DEGREESCOT[#1]#2#3{\@CONVERTDEG{#1}{#2} \DEGREESCOT{\@DEGREES}{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\@CONVERTDEG} % \cs{@CONVERTDEG} normalises to sexagesimal degrees. % \begin{macrocode} \def\@CONVERTDEG#1#2{\DIVIDE{#2}{#1}{\@DEGREES} \MULTIPLY{\@DEGREES}{360}{\@DEGREES}} % \end{macrocode} % \end{macro} % \paragraph*{Exponential functions} % \begin{macro}{\EXP} % \cs{EXP}\oarg{\#1}\marg{\#2}\marg{\#3} computes % the exponential $\textit{\#3}=\textit{\#1}^{\textit{\#2}}$. % Default for \textit{\#1} is number $\mathrm e$. % \begin{macrocode} \def\EXP{\@ifnextchar[\@@EXP\@EXP} % \end{macrocode} % \end{macro} % \begin{macro}{\@@EXP} \cs{@@EXP}\oarg{\textit{\#1}}\marg{\#2}\marg{\#3} % computes $\textit{\#3}=\textit{\#1}^{\textit{\#2}}$ % \begin{macrocode} \def\@@EXP[#1]#2#3{% \begingroup % \end{macrocode} % \#1 must be a positive number. % \begin{macrocode} \ifdim #1\p@<\cctr@epsilon \cctr@Warninfexpb{#1}{#2} \let#3\undefined \else % \end{macrocode} % $a^b=\exp(b\log a)$. % \begin{macrocode} \LOG{#1}{\cctr@log} \MULTIPLY{#2}{\cctr@log}{\cctr@log} \@EXP{\cctr@log}{#3} \fi\@OUTPUTSOL{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\@EXP} \cs{@EXP}\marg{\#1}\marg{\#2} % computes $\textit{\#3}=\mathrm{e}^{\textit{\#2}}$ % \begin{macrocode} \def\@EXP#1#2{% \begingroup \ABSVALUE{#1}{\cctr@absval} % \end{macrocode} % If $\left\vert t\right\vert$ is greater than \cs{cctr@logmaxnum} % then $\exp t$ is too large. % \begin{macrocode} \ifdim \cctr@absval\p@>\cctr@logmaxnum\p@ \cctr@Warninfexp{#1} \let#2\undefined \else \ifdim #1\p@ < \z@ % \end{macrocode} % We call \cs{@BASICEXP} when $t\in [{-}6,3]$. % Otherwise we use the equality $\exp t=\left(\exp t/2\right)^2$. % \begin{macrocode} \ifdim #1\p@ > -6.00002\p@ \@BASICEXP{#1}{#2} \else \DIVIDE{#1}{2}{\cctr@expt} \@EXP{\cctr@expt}{\cctr@expy} \SQUARE{\cctr@expy}{#2} \fi \else \ifdim #1\p@ < 3.00002\p@ \@BASICEXP{#1}{#2} \else \DIVIDE{#1}{2}{\cctr@expt} \@EXP{\cctr@expt}{\cctr@expy} \SQUARE{\cctr@expy}{#2} \fi \fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\@BASICEXP} % \cs{@BASICEXP}\marg{\#1}\marg{\#2} applies this approximation: % \[ % \exp x \approx 1+\frac{2x}{ % 2-x+\displaystyle\frac{x^2/6}{ % 1+\displaystyle\frac{x^2/60}{ % 1+\displaystyle\frac{x^2/140}{ % 1+\displaystyle\frac{x^2/256}{ % 1+\displaystyle\frac{x^2}{396 % } % } % } % } % } % } % \] % \begin{macrocode} \def\@BASICEXP#1#2{% \begingroup \SQUARE{#1}\cctr@tempa \DIVIDE{\cctr@tempa}{396}{#2} \ADD{1}{#2}{#2} \DIVIDE\cctr@tempa{#2}{#2} \DIVIDE{#2}{256}{#2} \ADD{1}{#2}{#2} \DIVIDE\cctr@tempa{#2}{#2} \DIVIDE{#2}{140}{#2} \ADD{1}{#2}{#2} \DIVIDE\cctr@tempa{#2}{#2} \DIVIDE{#2}{60}{#2} \ADD{1}{#2}{#2} \DIVIDE\cctr@tempa{#2}{#2} \DIVIDE{#2}{6}{#2} \ADD{2}{#2}{#2} \SUBTRACT{#2}{#1}{#2} \DIVIDE{#1}{#2}{#2} \MULTIPLY{2}{#2}{#2} \ADD{1}{#2}{#2}\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \paragraph*{Hyperbolic functions} % \begin{macro}{\COSH} % \cs{COSH}. Hyperbolic cosine: $\cosh t=(\exp t+\exp(-t))/2$. % \begin{macrocode} \def\COSH#1#2{% \begingroup \ABSVALUE{#1}{\cctr@absval} \ifdim \cctr@absval\p@>\cctr@logmaxnum\p@ \cctr@Warninfexp{#1} \let#2\undefined \else \EXP{#1}{\cctr@expx} \MULTIPLY{-1}{#1}{\cctr@minust} \EXP{\cctr@minust}{\cctr@expminusx} \ADD{\cctr@expx}{\cctr@expminusx}{#2} \DIVIDE{#2}{2}{#2} \fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\SINH} % \cs{SINH}. Hyperbolic sine: $\sinh t=(\exp t-\exp(-t))/2$. % \begin{macrocode} \def\SINH#1#2{% \begingroup \ABSVALUE{#1}{\cctr@absval} \ifdim \cctr@absval\p@>\cctr@logmaxnum\p@ \cctr@Warninfexp{#1} \let#2\undefined \else \EXP{#1}{\cctr@expx} \MULTIPLY{-1}{#1}{\cctr@minust} \EXP{\cctr@minust}{\cctr@expminusx} \SUBTRACT{\cctr@expx}{\cctr@expminusx}{#2} \DIVIDE{#2}{2}{#2} \fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\TANH} % \cs{TANH}. Hyperbolic tangent: $\tanh t=\sinh t/{\cosh t}$. % \begin{macrocode} \def\TANH#1#2{% \begingroup \ABSVALUE{#1}{\cctr@absval} \ifdim \cctr@absval\p@>\cctr@logmaxnum\p@ \cctr@Warninfexp{#1} \let#2\undefined \else \SINH{#1}{\cctr@tanhnum} \COSH{#1}{\cctr@tanhden} \DIVIDE{\cctr@tanhnum}{\cctr@tanhden}{#2} \fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\COTH} % \cs{COTH}. Hyperbolic cotangent $\coth t=\cosh t/{\sinh t}$. % \begin{macrocode} \def\COTH#1#2{% \begingroup \ABSVALUE{#1}{\cctr@absval} \ifdim \cctr@absval\p@>\cctr@logmaxnum\p@ \cctr@Warninfexp{#1} \let#2\undefined \else \SINH{#1}{\cctr@tanhden} \COSH{#1}{\cctr@tanhnum} \DIVIDE\cctr@tanhnum\cctr@tanhden{#2} \fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \paragraph*{Logarithm} % \begin{macro}{\LOG} % \cs{LOG}\oarg{\#1}\marg{\#2}\marg{\#3} computes % the logarithm $\textit{\#3}=\log_{\textit{\#1}}{\textit{\#2}}$. % Default for \textit{\#1} is number $\mathrm e$. % \begin{macrocode} \def\LOG{\@ifnextchar[\@@LOG\@LOG} % \end{macrocode} % \end{macro} % \begin{macro}{\@LOG} \cs{@LOG}\marg{\textit{\#1}}\marg{\#2} % computes $\textit{\#2}=\log\textit{\#1}$ % \begin{macrocode} \def\@LOG#1#2{% \begingroup % \end{macrocode} % The argument $t$ must be positive. % \begin{macrocode} \ifdim #1\p@<\cctr@epsilon \cctr@Warninflog{#1} \let#2\undefined \else \ifdim #1\p@ > \numberETWO\p@ % \end{macrocode} % If $t>\mathrm{e}^2$, $\log t=\log\mathrm{e}+\log(t/{\mathrm{e}})=1+\log(t/{\mathrm{e}})$ % \begin{macrocode} \DIVIDE{#1}{\numberE}{\cctr@ae} \@LOG{\cctr@ae}{#2} \ADD{1}{#2}{#2} \else \ifdim #1\p@ < 1\p@ % \end{macrocode} % If $t<1$, $\log t=\log(1/\mathrm{e})+\log(t\mathrm{e})=-1+\log(t\mathrm{e})$ % \begin{macrocode} \MULTIPLY{\numberE}{#1}{\cctr@ae} \LOG{\cctr@ae}{#2} \SUBTRACT{#2}{1}{#2} \else % \end{macrocode} % For $t\in[1,\mathrm{e}^2]$ we call \cs{@@BASICLOG}. % \begin{macrocode} \@BASICLOG{#1}{#2} \fi\fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\@@LOG} \cs{@@LOG}\oarg{\textit{\#1}}\marg{\#2}\marg{\#3} % computes $\textit{\#3}=\log_\textit{\#1}\textit{\#2} % =\log(\textit{\#2})/\log(\textit{\#1})$ % \begin{macrocode} \def\@@LOG[#1]#2#3{\begingroup \@LOG{#1}{\cctr@loga} \@LOG{#2}{\cctr@logx} \DIVIDE{\cctr@logx}{\cctr@loga}{#3}\@OUTPUTSOL{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\@BASICLOG} \cs{@BASICLOG}\marg{\textit{\#1}}\marg{\#2} % applies the Newton's method to calculate $x=\log t$: % \[x_{n+1}=x_n+\frac{t}{\mathrm{e}^{x_n}}-1\] % \begin{macrocode} \def\@BASICLOG#1#2{\begingroup % We take $\textit{\#1}-1$ as the initial approximation. % \begin{macrocode} \SUBTRACT{#1}{1}{\cctr@tempw} % \end{macrocode} % % We start with |\cctr@lengthb=5\p@| to ensure almost one iteration. % \changes{v2.1}{2022/09/15}{Changed stop criterion on iterations to 2sp} % \begin{macrocode} \cctr@lengthb=5\p@% \cctr@epsilon=2\cctr@epsilon% % \end{macrocode} % Successive iterations % \begin{macrocode} \@whilenum \cctr@lengthb>\cctr@epsilon \do {% \COPY{\cctr@tempw}{\cctr@tempoldw} \EXP{\cctr@tempw}{\cctr@tempxw} \DIVIDE{#1}{\cctr@tempxw}{\cctr@tempxw} \ADD{\cctr@tempw}{\cctr@tempxw}{\cctr@tempw} \SUBTRACT{\cctr@tempw}{1}{\cctr@tempw} \SUBTRACT{\cctr@tempw}{\cctr@tempoldw}{\cctr@tempdif} \cctr@lengthb=\cctr@tempdif\p@% \ifnum \cctr@lengthb<\z@ \cctr@lengthb=-\cctr@lengthb \fi}% \COPY{\cctr@tempw}{#2}\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \paragraph*{Inverse trigonometric functions} % \changes{v2.0}{2014/02/13}{New commands: \cs{ARCSIN}, % \cs{ARCCOS}, \cs{ARCTAN}, % \cs{ARCCOT}} % \begin{macro}{\ARCSIN} % \cs{ARCSIN}\marg{\#1}\marg{\#2} % defines \textit{\#2} as the arcsin of \textit{\#1}, % using the Newton's method: $x_{n+1}=x_n-(\sin x_n-\textit{\#1})/(\cos x_n)$. % \begin{macrocode} \def\ARCSIN#1#2{% \begingroup \ifdim #1\p@ = \z@ \COPY{0}{#2} \else \ifdim #1\p@ = 1\p@ \COPY{\numberHALFPI}{#2} \else \ifdim #1\p@ = -1\p@ \COPY{-\numberHALFPI}{#2} \else \ifdim #1\p@ > 1\p@ \let#2\undefined \cctr@Warnbigarcsin{#1} \else \ifdim #1\p@ < -1\p@ \let#2\undefined \cctr@Warnbigarcsin{#1} \else % \end{macrocode} % If $x$ is close to $1$ we use $\arcsin x=\pi/2-2\arcsin\sqrt{(1-x)/2}$ % \begin{macrocode} \ifdim #1\p@ >0.89\p@ \SUBTRACT{1}{#1}{\cctr@tempx} \DIVIDE{\cctr@tempx}{2}{\cctr@tempx} \SQRT{\cctr@tempx}{\cctr@tempxx} \ARCSIN{\cctr@tempxx}{#2} \MULTIPLY{2}{#2}{#2} \SUBTRACT{\numberHALFPI}{#2}{#2} \else % \end{macrocode} % Symmetrically, for $x$ close to $-1$, $\arcsin x=-\pi/2+2\arcsin\sqrt{(1+x)/2}$ % \begin{macrocode} \ifdim #1\p@ <-0.89\p@ \ADD{1}{#1}{\cctr@tempx} \DIVIDE{\cctr@tempx}{2}{\cctr@tempx} \SQRT{\cctr@tempx}{\cctr@tempxx} \ARCSIN{\cctr@tempxx}{#2} \MULTIPLY{2}{#2}{#2} \SUBTRACT{#2}{\numberHALFPI}{#2} \else % \end{macrocode} % We take \textit{\#1} as the initial approximation. % \begin{macrocode} \COPY{#1}{#2} % \end{macrocode} % If $-0.4\leq t\leq 0.4$ then $\arcsin x\approx x$ is a good approximation. % Else, we apply the Newton method % \begin{macrocode} \ABSVALUE{#1}{\cctr@tempy} \ifdim \cctr@tempy\p@ < 0.04\p@ \else % \end{macrocode} % \cs{cctr@lengthb} will be the difference of two successive iterations, and % \cs{cctr@tempoldy}, \cs{cctr@tempy} will be the two last iterations. % % We start with |\cctr@lengthb=5\p@| and |\cctr@tempy=16383| to ensure almost one iteration. % \begin{macrocode} \cctr@lengthb=5\p@ \COPY{16383}{\cctr@tempy} % \end{macrocode} % Successive iterations % \begin{macrocode} \@whilenum \cctr@lengthb>\cctr@epsilon \do {% % \end{macrocode} % Copy the actual approximation to \cs{cctr@tempw} % \begin{macrocode} \COPY{#2}{\cctr@tempw} \COPY{\cctr@tempy}{\cctr@tempoldy} \SIN{\cctr@tempw}{\cctr@tempz} \SUBTRACT{\cctr@tempz}{#1}{\cctr@tempz} \COS{\cctr@tempw}{\cctr@tempy} \DIVIDE{\cctr@tempz}{\cctr@tempy}{\cctr@tempz} \SUBTRACT{\cctr@tempw}{\cctr@tempz}{\cctr@tempz} % \end{macrocode} % Now, \cs{cctr@tempz} is the new approximation. % \begin{macrocode} \COPY{\cctr@tempz}{#2} % \end{macrocode} % Finally, we store in \cs{cctr@lengthb} the difference % of the two last approximations, finishing the loop. % \begin{macrocode} \SUBTRACT{#2}{\cctr@tempw}{\cctr@tempy} \ABSVALUE{\cctr@tempy}{\cctr@tempy} \cctr@lengthb=\cctr@tempy\p@% \ifdim\cctr@tempy\p@=\cctr@tempoldy\p@ \cctr@lengthb=\z@ \fi}\fi\fi\fi\fi\fi\fi\fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\ARCCOS} % \cs{ARCCOS}\marg{\#1}\marg{\#2} % defines \textit{\#2} as the arccos of \textit{\#1}, % using the well know relation $\arccos x=\pi/2-\arcsin x$. % \begin{macrocode} \def\ARCCOS#1#2{% \begingroup \ifdim #1\p@ = \z@ \COPY{\numberHALFPI}{#2} \else \ifdim #1\p@ = 1\p@ \COPY{0}{#2} \else \ifdim #1\p@ = -1\p@ \COPY{\numberPI}{#2} \else \ifdim #1\p@ > 1\p@ \let#2\undefined \cctr@Warnbigarccos{#1} \else \ifdim #1\p@ < -1\p@ \let#2\undefined \cctr@Warnbigarccos{#1} \else \ARCSIN{#1}{#2} \SUBTRACT{\numberHALFPI}{#2}{#2} \fi\fi\fi\fi\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\ARCTAN} % \cs{ARCTAN}\marg{\#1}\marg{\#2}. arctan of \textit{\#1}. % \begin{macrocode} \def\ARCTAN#1#2{% \begingroup % \end{macrocode} % If $\left\vert t \right\vert>1$, compute $\arctan x$ using % $\arctan x=sign(x)\pi/2-\arctan(1/x)$. % \begin{macrocode} \ifdim#1\p@<-1\p@ \DIVIDE{1}{#1}{\cctr@tempb} \ARCTAN{\cctr@tempb}{#2} \SUBTRACT{-\numberHALFPI}{#2}{#2} \else \ifdim#1\p@>1\p@ \DIVIDE{1}{#1}{\cctr@tempb} \ARCTAN{\cctr@tempb}{#2} \SUBTRACT{\numberHALFPI}{#2}{#2} \else % \end{macrocode} % For $-1\leq x\leq 1$ call \cs{@BASICARCTAN}. % \begin{macrocode} \@BASICARCTAN{#1}{#2} \fi \fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\@BASICARCTAN} % \cs{@BASICARCTAN}\marg{\#1}\marg{\#2} applies this approximation: % \[ % \arctan x = \frac{x}{ % 1+\displaystyle\frac{x^2}{ % 3+\displaystyle\frac{(2x)^2}{ % 5+\displaystyle\frac{(3x)^2}{ % 7+\displaystyle\frac{(4x)^2}{ % 9+\cdots % } % } % } % } % } % \] % \begin{macrocode} \def\@BASICARCTAN#1#2{% \begingroup % \end{macrocode} % Exact arctan of zero % \begin{macrocode} \ifdim#1\p@=\z@ \COPY{0}{#2} \else % \end{macrocode} % Compute the continued fraction. % \begin{macrocode} \SQUARE{#1}{\cctr@tempa} \MULTIPLY{64}{\cctr@tempa}{#2} \ADD{15}{#2}{#2} \DIVIDE{\cctr@tempa}{#2}{#2} \MULTIPLY{49}{#2}{#2} \ADD{13}{#2}{#2} \DIVIDE{\cctr@tempa}{#2}{#2} \MULTIPLY{36}{#2}{#2} \ADD{11}{#2}{#2} \DIVIDE{\cctr@tempa}{#2}{#2} \MULTIPLY{25}{#2}{#2} \ADD{9}{#2}{#2} \DIVIDE{\cctr@tempa}{#2}{#2} \MULTIPLY{16}{#2}{#2} \ADD{7}{#2}{#2} \DIVIDE{\cctr@tempa}{#2}{#2} \MULTIPLY{9}{#2}{#2} \ADD{5}{#2}{#2} \DIVIDE{\cctr@tempa}{#2}{#2} \MULTIPLY{4}{#2}{#2} \ADD{3}{#2}{#2} \DIVIDE{\cctr@tempa}{#2}{#2} \ADD{1}{#2}{#2} \DIVIDE{#1}{#2}{#2} \fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\ARCCOT} % \cs{ARCCOT}\marg{\#1}\marg{\#2} % defines \textit{\#2} as the arccot of \textit{\#1}, % using the well know relation $\operatorname{arccot} x=\pi/2-\arctan x$. % \begin{macrocode} \def\ARCCOT#1#2{% \begingroup \ARCTAN{#1}{#2} \SUBTRACT{\numberHALFPI}{#2}{#2} \@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \paragraph*{Inverse hyperbolic functions} % \changes{v2.0}{2014/02/13}{New commands: \cs{ARSINH}, % \cs{ARCOSH}, \cs{ARTANH}, % \cs{ARCOTH}} % \begin{macro}{\ARSINH} % \cs{ARSINH}\marg{\#1}\marg{\#2}. Inverse hyperbolic sine of \textit{\#1}: % $\arsinh x = \log\left(x+\sqrt{1+x^2}\right)$ % \begin{macrocode} \def\ARSINH#1#2{% \begingroup \SQUARE{#1}{\cctr@tempa} \ADD{1}{\cctr@tempa}{\cctr@tempa} \SQRT{\cctr@tempa}{\cctr@tempb} \ADD{#1}{\cctr@tempb}{\cctr@tempb} \LOG\cctr@tempb{#2} \@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\ARCOSH} % \cs{ARCOSH}\marg{\#1}\marg{\#2}. Inverse hyperbolic sine of \textit{\#1}: % $\arcosh x = \log\left(x+\sqrt{x^2-1}\right)$ % \begin{macrocode} \def\ARCOSH#1#2{% \begingroup % \end{macrocode} % If $x<1$, this function is no defined % \begin{macrocode} \ifdim#1\p@<1\p@ \let#2\undefined \cctr@Warnsmallarcosh{#1} \else \SQUARE{#1}{\cctr@tempa} \SUBTRACT{\cctr@tempa}{1}{\cctr@tempa} \SQRT{\cctr@tempa}{\cctr@tempb} \ADD{#1}{\cctr@tempb}{\cctr@tempb} \LOG\cctr@tempb{#2} \fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\ARTANH} % \cs{ARTANH}\marg{\#1}\marg{\#2}. Inverse hyperbolic tangent of \textit{\#1}: % $\artanh x = \frac12\log \left((1+x)-\log(1-x)\right)$ % \begin{macrocode} \def\ARTANH#1#2{% \begingroup % \end{macrocode} % If $\left\vert x \right\vert\geq1$, this function is no defined % \begin{macrocode} \ifdim#1\p@<-0.99998\p@ \let#2\undefined \cctr@Warnbigartanh{#1} \else \ifdim#1\p@>0.99998\p@ \let#2\undefined \cctr@Warnbigartanh{#1} \else \COPY{#1}{\cctr@tempa} \ADD1\cctr@tempa\cctr@tempb \SUBTRACT1\cctr@tempa\cctr@tempc \LOG\cctr@tempb\cctr@tempB \LOG\cctr@tempc\cctr@tempC \SUBTRACT\cctr@tempB\cctr@tempC{#2} \DIVIDE{#2}{2}{#2} \fi \fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\ARCOTH} % \cs{ARCOTH}\marg{\#1}\marg{\#2}. Inverse hyperbolic cotangent of \textit{\#1}: % % $\arcoth x = sign(x)\frac12\log \left((x+1)-\log(x-1)\right)$ % \begin{macrocode} \def\ARCOTH#1#2{% \begingroup % \end{macrocode} % If $\left\vert x \right\vert\leq1$, this function is no defined % \begin{macrocode} \ifdim#1\p@>-0.99998\p@ \ifdim#1\p@<0.99998\p@ \let#2\undefined \cctr@Warnsmallarcoth{#1} \else \ifdim#1\p@>\p@ % \end{macrocode} % For $x>1$, calcule $\arcoth x = \frac12\log \left((x+1)-\log(x-1)\right)$ % \begin{macrocode} \COPY{#1}{\cctr@tempa} \ADD1\cctr@tempa\cctr@tempb \SUBTRACT\cctr@tempa1\cctr@tempc \LOG\cctr@tempb\cctr@tempB \LOG\cctr@tempc\cctr@tempC \SUBTRACT\cctr@tempB\cctr@tempC{#2} \DIVIDE{#2}{2}{#2} \else \fi \fi \else % \end{macrocode} % For $x<-1$, calcule $-\artanh(-x)$ % \begin{macrocode} \MULTIPLY{-1}{#1}{\cctr@tempa} \ARCOTH{\cctr@tempa}{#2} \COPY{-#2}{#2} \fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % % \subsection{Matrix arithmetics} % \subsubsection*{Vector operations} % \begin{macro}{\VECTORSIZE} % The \emph{size} of a vector is $2$ or $3$. % \cs{VECTORSIZE}\parg{\#1}\marg{\#2} stores in \textit{\#2} the % size of \parg{\#1}. % % Almost all vector commands needs to know the vector size. % \begin{macrocode} \def\VECTORSIZE(#1)#2{\expandafter\@VECTORSIZE(#1,,){#2}} \def\@VECTORSIZE(#1,#2,#3,#4)#5{\ifx$#3$\COPY{2}{#5} \else\COPY{3}{#5}\fi\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\VECTORCOPY} % \cs{VECTORCOPY}\parg{\#1,\#2}\parg{\#3,\#4} % stores \textit{\#1} and \textit{\#2} % in \textit{\#3} and \textit{\#4}. % % \noindent\cs{VECTORCOPY}\parg{\#1,\#2,\#3}\parg{\#4,\#5\#6} % stores \textit{\#1}, \textit{\#2} and \textit{\#3} % in \textit{\#4} and \textit{\#5} and \textit{\#6}. % \begin{macrocode} \def\@@VECTORCOPY(#1,#2)(#3,#4){% \COPY{#1}{#3}\COPY{#2}{#4}} \def\@@@VECTORCOPY(#1,#2,#3)(#4,#5,#6){% \COPY{#1}{#4}\COPY{#2}{#5}\COPY{#3}{#6}} \def\VECTORCOPY(#1)(#2){% \VECTORSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@VECTORCOPY(#1)(#2) \else \@@@VECTORCOPY(#1)(#2)\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\VECTORGLOBALCOPY} % \cs{VECTORGLOBALCOPY} is the global version of \cs{VECTORCOPY} % \begin{macrocode} \def\@@VECTORGLOBALCOPY(#1,#2)(#3,#4){% \GLOBALCOPY{#1}{#3}\GLOBALCOPY{#2}{#4}} \def\@@@VECTORGLOBALCOPY(#1,#2,#3)(#4,#5,#6){% \GLOBALCOPY{#1}{#4}\GLOBALCOPY{#2}{#5}\GLOBALCOPY{#3}{#6}} \def\VECTORGLOBALCOPY(#1)(#2){% \VECTORSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@VECTORGLOBALCOPY(#1)(#2) \else \@@@VECTORGLOBALCOPY(#1)(#2)\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\@OUTPUTVECTOR} % \begin{macrocode} \def\@@OUTPUTVECTOR(#1,#2){% \VECTORGLOBALCOPY(#1,#2)(\cctr@outa,\cctr@outb) \endgroup\VECTORCOPY(\cctr@outa,\cctr@outb)(#1,#2)} \def\@@@OUTPUTVECTOR(#1,#2,#3){% \VECTORGLOBALCOPY(#1,#2,#3)(\cctr@outa,\cctr@outb,\cctr@outc) \endgroup\VECTORCOPY(\cctr@outa,\cctr@outb,\cctr@outc)(#1,#2,#3)} \def\@OUTPUTVECTOR(#1){\VECTORSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@OUTPUTVECTOR(#1) \else \@@@OUTPUTVECTOR(#1)\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\SCALARPRODUCT} % Scalar product of two vectors. % \begin{macrocode} \def\@@SCALARPRODUCT(#1,#2)(#3,#4)#5{% \MULTIPLY{#1}{#3}{#5} \MULTIPLY{#2}{#4}\cctr@tempa \ADD{#5}{\cctr@tempa}{#5}} \def\@@@SCALARPRODUCT(#1,#2,#3)(#4,#5,#6)#7{% \MULTIPLY{#1}{#4}{#7} \MULTIPLY{#2}{#5}\cctr@tempa \ADD{#7}{\cctr@tempa}{#7} \MULTIPLY{#3}{#6}\cctr@tempa \ADD{#7}{\cctr@tempa}{#7}} \def\SCALARPRODUCT(#1)(#2)#3{% \begingroup \VECTORSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@SCALARPRODUCT(#1)(#2){#3} \else \@@@SCALARPRODUCT(#1)(#2){#3}\fi\@OUTPUTSOL{#3}} % \end{macrocode} % \end{macro} % \changes{v2.0}{2013/07/10}{New commands: \cs{DOTPRODUCT}, % \cs{VECTORPRODUCT}, \cs{CROSSPRODUCT}} % \begin{macro}{\DOTPRODUCT} % \cs{DOTPRODUCT} is an alias for \cs{SCALARPRODUCT}. % \begin{macrocode} \let\DOTPRODUCT\SCALARPRODUCT % \end{macrocode} % \end{macro} % \begin{macro}{\VECTORPRODUCT} % Vector product of two (three dimensional) vectors. % \begin{macrocode} \def\@@VECTORPRODUCT(#1)(#2)(#3,#4){% \let#3\undefined \let#4\undefined \cctr@Warncrossprod(#1)(#2)} \def\@@@VECTORPRODUCT(#1,#2,#3)(#4,#5,#6)(#7,#8,#9){% \DETERMINANT(#2,#3;#5,#6){#7} \DETERMINANT(#3,#1;#6,#4){#8} \DETERMINANT(#1,#2;#4,#5){#9}} \def\VECTORPRODUCT(#1)(#2)(#3){% \begingroup \VECTORSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@VECTORPRODUCT(#1)(#2)(#3) \else \@@@VECTORPRODUCT(#1)(#2)(#3)\fi\@OUTPUTSOL{#3}} % \end{macrocode} % \end{macro} % \begin{macro}{\CROSSPRODUCT} % \cs{CROSSPRODUCT} is an alias for \cs{VECTORPRODUCT}. % \begin{macrocode} \let\CROSSPRODUCT\VECTORPRODUCT % \end{macrocode} % \end{macro} % \begin{macro}{\VECTORADD} % Sum of two vectors. % \begin{macrocode} \def\@@VECTORADD(#1,#2)(#3,#4)(#5,#6){% \ADD{#1}{#3}{#5} \ADD{#2}{#4}{#6}} \def\@@@VECTORADD(#1,#2,#3)(#4,#5,#6)(#7,#8,#9){% \ADD{#1}{#4}{#7} \ADD{#2}{#5}{#8} \ADD{#3}{#6}{#9}} \def\VECTORADD(#1)(#2)(#3){% \VECTORSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@VECTORADD(#1)(#2)(#3) \else \@@@VECTORADD(#1)(#2)(#3)\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\VECTORSUB} % Difference of two vectors. % \begin{macrocode} \def\@@VECTORSUB(#1,#2)(#3,#4)(#5,#6){% \VECTORADD(#1,#2)(-#3,-#4)(#5,#6)} \def\@@@VECTORSUB(#1,#2,#3)(#4,#5,#6)(#7,#8,#9){% \VECTORADD(#1,#2,#3)(-#4,-#5,-#6)(#7,#8,#9)} \def\VECTORSUB(#1)(#2)(#3){% \VECTORSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@VECTORSUB(#1)(#2)(#3) \else \@@@VECTORSUB(#1)(#2)(#3)\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\VECTORABSVALUE} % Absolute value of a each entry of a vector. % \begin{macrocode} \def\@@VECTORABSVALUE(#1,#2)(#3,#4){% \ABSVALUE{#1}{#3}\ABSVALUE{#2}{#4}} \def\@@@VECTORABSVALUE(#1,#2,#3)(#4,#5,#6){% \ABSVALUE{#1}{#4}\ABSVALUE{#2}{#5}\ABSVALUE{#3}{#6}} \def\VECTORABSVALUE(#1)(#2){% \VECTORSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@VECTORABSVALUE(#1)(#2) \else \@@@VECTORABSVALUE(#1)(#2)\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\SCALARVECTORPRODUCT} % Scalar-vector product. % \begin{macrocode} \def\@@SCALARVECTORPRODUCT#1(#2,#3)(#4,#5){% \MULTIPLY{#1}{#2}{#4} \MULTIPLY{#1}{#3}{#5}} \def\@@@SCALARVECTORPRODUCT#1(#2,#3,#4)(#5,#6,#7){% \MULTIPLY{#1}{#2}{#5} \MULTIPLY{#1}{#3}{#6} \MULTIPLY{#1}{#4}{#7}} \def\SCALARVECTORPRODUCT#1(#2)(#3){% \VECTORSIZE(#2){\cctr@size} \ifnum\cctr@size=2 \@@SCALARVECTORPRODUCT{#1}(#2)(#3) \else \@@@SCALARVECTORPRODUCT{#1}(#2)(#3)\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\VECTORNORM} % Euclidean norm of a vector. % \begin{macrocode} \def\VECTORNORM(#1)#2{% \begingroup \SCALARPRODUCT(#1)(#1){\cctr@temp} \SQUAREROOT{\cctr@temp}{#2}\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\UNITVECTOR} % Unitary vector parallel to a given vector. % \begin{macrocode} \def\UNITVECTOR(#1)(#2){% \begingroup \VECTORNORM(#1){\cctr@tempa} \DIVIDE{1}{\cctr@tempa}{\cctr@tempa} \SCALARVECTORPRODUCT{\cctr@tempa}(#1)(#2)\@OUTPUTVECTOR(#2)} % \end{macrocode} % \end{macro} % \begin{macro}{\TWOVECTORSANGLE} % Angle between two vectors. % \begin{macrocode} \def\TWOVECTORSANGLE(#1)(#2)#3{% \begingroup \VECTORNORM(#1){\cctr@tempa} \VECTORNORM(#2){\cctr@tempb} \SCALARPRODUCT(#1)(#2){\cctr@tempc} \ifdim \cctr@tempa\p@ =\z@ \let#3\undefined \cctr@Warnnoangle(#1)(#2) \else \ifdim \cctr@tempb\p@ =\z@ \let#3\undefined \cctr@Warnnoangle(#1)(#2) \else \DIVIDE{\cctr@tempc}{\cctr@tempa}{\cctr@tempc} \DIVIDE{\cctr@tempc}{\cctr@tempb}{\cctr@tempc} \ARCCOS{\cctr@tempc}{#3} \fi\fi\@OUTPUTSOL{#3}} % \end{macrocode} % \end{macro} % \subsubsection*{Matrix operations} % Here, we need to define some internal macros % to simulate commands with more than nine arguments. % \begin{macro}{\@TDMATRIXCOPY} % This command copies a $3\times3$ matrix to the commands % \cs{cctr@solAA}, \cs{cctr@solAB}, \dots, \cs{cctr@solCC}. % \begin{macrocode} \def\@TDMATRIXCOPY(#1,#2,#3;#4,#5,#6;#7,#8,#9){% \COPY{#1}{\cctr@solAA} \COPY{#2}{\cctr@solAB} \COPY{#3}{\cctr@solAC} \COPY{#4}{\cctr@solBA} \COPY{#5}{\cctr@solBB} \COPY{#6}{\cctr@solBC} \COPY{#7}{\cctr@solCA} \COPY{#8}{\cctr@solCB} \COPY{#9}{\cctr@solCC}} % \end{macrocode} % \end{macro} % \begin{macro}{\@TDMATRIXSOL} % This command copies the commands % \cs{cctr@solAA}, \cs{cctr@solAB}, \dots, \cs{cctr@solCC} % to a $3\times3$ matrix. % This macro is used to store the results of a matrix operation. % \begin{macrocode} \def\@TDMATRIXSOL(#1,#2,#3;#4,#5,#6;#7,#8,#9){% \COPY{\cctr@solAA}{#1} \COPY{\cctr@solAB}{#2} \COPY{\cctr@solAC}{#3} \COPY{\cctr@solBA}{#4} \COPY{\cctr@solBB}{#5} \COPY{\cctr@solBC}{#6} \COPY{\cctr@solCA}{#7} \COPY{\cctr@solCB}{#8} \COPY{\cctr@solCC}{#9}} % \end{macrocode} % \end{macro} % \begin{macro}{\@TDMATRIXGLOBALSOL} % % \begin{macrocode} \def\@TDMATRIXGLOBALSOL(#1,#2,#3;#4,#5,#6;#7,#8,#9){% \GLOBALCOPY{\cctr@solAA}{#1} \GLOBALCOPY{\cctr@solAB}{#2} \GLOBALCOPY{\cctr@solAC}{#3} \GLOBALCOPY{\cctr@solBA}{#4} \GLOBALCOPY{\cctr@solBB}{#5} \GLOBALCOPY{\cctr@solBC}{#6} \GLOBALCOPY{\cctr@solCA}{#7} \GLOBALCOPY{\cctr@solCB}{#8} \GLOBALCOPY{\cctr@solCC}{#9}} % \end{macrocode} % \end{macro} % \begin{macro}{\@TDMATRIXNOSOL} % This command undefines a $3\times3$ matrix % when a matrix problem has no solution. % \begin{macrocode} \def\@TDMATRIXNOSOL(#1,#2,#3;#4,#5,#6;#7,#8,#9){% \let#1\undefined \let#2\undefined \let#3\undefined \let#4\undefined \let#5\undefined \let#6\undefined \let#7\undefined \let#8\undefined \let#9\undefined } % \end{macrocode} % \end{macro} % \begin{macro}{\@@TDMATRIXSOL} % This command stores or undefines the solution. % \begin{macrocode} \def\@@TDMATRIXSOL(#1,#2,#3;#4,#5,#6;#7,#8,#9){% \ifx\cctr@solAA\undefined \@TDMATRIXNOSOL(#1,#2,#3;#4,#5,#6;#7,#8,#9)% \else \@TDMATRIXSOL(#1,#2,#3;#4,#5,#6;#7,#8,#9)\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\@NUMBERSOL} % This command stores the scalar solution of a matrix operation. % \begin{macrocode} \def\@NUMBERSOL#1{\COPY{\cctr@sol}{#1}} % \end{macrocode} % \end{macro} % \begin{macro}{\MATRIXSIZE} % Size ($2$ or $3$) of a matrix. % \begin{macrocode} \def\MATRIXSIZE(#1)#2{\expandafter\@MATRIXSIZE(#1;;){#2}} \def\@MATRIXSIZE(#1;#2;#3;#4)#5{\ifx$#3$\COPY{2}{#5} \else\COPY{3}{#5}\fi\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\MATRIXCOPY} % Store a matrix in 4 or 9 commands. % \begin{macrocode} \def\@@MATRIXCOPY(#1,#2;#3,#4)(#5,#6;#7,#8){% \COPY{#1}{#5}\COPY{#2}{#6}\COPY{#3}{#7}\COPY{#4}{#8}} \def\@@@MATRIXCOPY(#1,#2,#3;#4,#5,#6;#7,#8,#9){% \@TDMATRIXCOPY(#1,#2,#3;#4,#5,#6;#7,#8,#9) \@TDMATRIXSOL} \def\MATRIXCOPY(#1)(#2){% \MATRIXSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@MATRIXCOPY(#1)(#2) \else \@@@MATRIXCOPY(#1)(#2)\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\MATRIXGLOBALCOPY} % Global version of \cs{MATRIXCOPY}. % \begin{macrocode} \def\@@MATRIXGLOBALCOPY(#1,#2;#3,#4)(#5,#6;#7,#8){% \GLOBALCOPY{#1}{#5}\GLOBALCOPY{#2}{#6}\GLOBALCOPY{#3}{#7}\GLOBALCOPY{#4}{#8}} \def\@@@MATRIXGLOBALCOPY(#1,#2,#3;#4,#5,#6;#7,#8,#9){% \@TDMATRIXCOPY(#1,#2,#3;#4,#5,#6;#7,#8,#9) \@TDMATRIXGLOBALSOL} \def\MATRIXGLOBALCOPY(#1)(#2){% \MATRIXSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@MATRIXGLOBALCOPY(#1)(#2) \else \@@@MATRIXGLOBALCOPY(#1)(#2)\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\@OUTPUTMATRIX} % \begin{macrocode} \def\@@OUTPUTMATRIX(#1,#2;#3,#4){% \MATRIXGLOBALCOPY(#1,#2;#3,#4)(\cctr@outa,\cctr@outb;\cctr@outc,\cctr@outd) \endgroup\MATRIXCOPY(\cctr@outa,\cctr@outb;\cctr@outc,\cctr@outd)(#1,#2;#3,#4)} \def\@@@OUTPUTMATRIX(#1,#2,#3;#4,#5,#6;#7,#8,#9){% \MATRIXGLOBALCOPY(#1,#2,#3;#4,#5,#6;#7,#8,#9)(% \cctr@outa,\cctr@outb,\cctr@outc; \cctr@outd,\cctr@oute,\cctr@outf; \cctr@outg,\cctr@outh,\cctr@outi) \endgroup\MATRIXCOPY(% \cctr@outa,\cctr@outb,\cctr@outc; \cctr@outd,\cctr@oute,\cctr@outf; \cctr@outg,\cctr@outh,\cctr@outi)(#1,#2,#3;#4,#5,#6;#7,#8,#9)} \def\@OUTPUTMATRIX(#1){\MATRIXSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@OUTPUTMATRIX(#1) \else \@@@OUTPUTMATRIX(#1)\fi} % \end{macrocode} % \end{macro} % \begin{macro}{\TRANSPOSEMATRIX} % Matrix transposition. % \begin{macrocode} \def\@@TRANSPOSEMATRIX(#1,#2;#3,#4)(#5,#6;#7,#8){% \COPY{#1}{#5}\COPY{#3}{#6}\COPY{#2}{#7}\COPY{#4}{#8}} \def\@@@TRANSPOSEMATRIX(#1,#2,#3;#4,#5,#6;#7,#8,#9){% \@TDMATRIXCOPY(#1,#4,#7;#2,#5,#8;#3,#6,#9) \@TDMATRIXSOL} \def\TRANSPOSEMATRIX(#1)(#2){% \begingroup \MATRIXSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@TRANSPOSEMATRIX(#1)(#2) \else \@@@TRANSPOSEMATRIX(#1)(#2)\fi\@OUTPUTMATRIX(#2)} % \end{macrocode} % \end{macro} % \begin{macro}{\MATRIXADD} % Sum of two matrices. % \begin{macrocode} \def\@@MATRIXADD(#1;#2)(#3;#4)(#5,#6;#7,#8){% \VECTORADD(#1)(#3)(#5,#6) \VECTORADD(#2)(#4)(#7,#8)} \def\@@@MATRIXADD(#1;#2;#3)(#4;#5;#6){% \VECTORADD(#1)(#4)(\cctr@solAA,\cctr@solAB,\cctr@solAC) \VECTORADD(#2)(#5)(\cctr@solBA,\cctr@solBB,\cctr@solBC) \VECTORADD(#3)(#6)(\cctr@solCA,\cctr@solCB,\cctr@solCC) \@TDMATRIXSOL} \def\MATRIXADD(#1)(#2)(#3){% \begingroup \MATRIXSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@MATRIXADD(#1)(#2)(#3) \else \@@@MATRIXADD(#1)(#2)(#3)\fi\@OUTPUTMATRIX(#3)} % \end{macrocode} % \end{macro} % \begin{macro}{\MATRIXSUB} % Difference of two matrices. % \begin{macrocode} \def\@@MATRIXSUB(#1;#2)(#3;#4)(#5,#6;#7,#8){% \VECTORSUB(#1)(#3)(#5,#6) \VECTORSUB(#2)(#4)(#7,#8)} \def\@@@MATRIXSUB(#1;#2;#3)(#4;#5;#6){% \VECTORSUB(#1)(#4)(\cctr@solAA,\cctr@solAB,\cctr@solAC) \VECTORSUB(#2)(#5)(\cctr@solBA,\cctr@solBB,\cctr@solBC) \VECTORSUB(#3)(#6)(\cctr@solCA,\cctr@solCB,\cctr@solCC) \@TDMATRIXSOL} \def\MATRIXSUB(#1)(#2)(#3){% \begingroup \MATRIXSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@MATRIXSUB(#1)(#2)(#3) \else \@@@MATRIXSUB(#1)(#2)(#3)\fi\@OUTPUTMATRIX(#3)} % \end{macrocode} % \end{macro} % \begin{macro}{\MATRIXABSVALUE} % Absolute value (of each entry) of a matrix. % \begin{macrocode} \def\@@MATRIXABSVALUE(#1;#2)(#3;#4){% \VECTORABSVALUE(#1)(#3)\VECTORABSVALUE(#2)(#4)} \def\@@@MATRIXABSVALUE(#1;#2;#3)(#4;#5;#6){% \VECTORABSVALUE(#1)(#4)\VECTORABSVALUE(#2)(#5)\VECTORABSVALUE(#3)(#6)} \def\MATRIXABSVALUE(#1)(#2){% \begingroup \MATRIXSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@MATRIXABSVALUE(#1)(#2) \else \@@@MATRIXABSVALUE(#1)(#2)\fi\@OUTPUTMATRIX(#2)} % \end{macrocode} % \end{macro} % \begin{macro}{\MATRIXVECTORPRODUCT} % Matrix-vector product. % \begin{macrocode} \def\@@MATRIXVECTORPRODUCT(#1;#2)(#3)(#4,#5){% \SCALARPRODUCT(#1)(#3){#4} \SCALARPRODUCT(#2)(#3){#5}} \def\@@@MATRIXVECTORPRODUCT(#1;#2;#3)(#4)(#5,#6,#7){% \SCALARPRODUCT(#1)(#4){#5} \SCALARPRODUCT(#2)(#4){#6} \SCALARPRODUCT(#3)(#4){#7}} \def\MATRIXVECTORPRODUCT(#1)(#2)(#3){% \begingroup \MATRIXSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@MATRIXVECTORPRODUCT(#1)(#2)(#3) \else \@@@MATRIXVECTORPRODUCT(#1)(#2)(#3)\fi\@OUTPUTVECTOR(#3)} % \end{macrocode} % \end{macro} % \begin{macro}{\VECTORMATRIXPRODUCT} % Vector-matrix product. % \begin{macrocode} \def\@@VECTORMATRIXPRODUCT(#1)(#2,#3;#4,#5)(#6,#7){% \SCALARPRODUCT(#1)(#2,#4){#6} \SCALARPRODUCT(#1)(#3,#5){#7}} \def\@@@VECTORMATRIXPRODUCT(#1,#2,#3)(#4;#5;#6)(#7){% \SCALARVECTORPRODUCT{#1}(#4)(#7) \SCALARVECTORPRODUCT{#2}(#5)(\cctr@tempa,\cctr@tempb,\cctr@tempc) \VECTORADD(#7)(\cctr@tempa,\cctr@tempb,\cctr@tempc)(#7) \SCALARVECTORPRODUCT{#3}(#6)(\cctr@tempa,\cctr@tempb,\cctr@tempc) \VECTORADD(#7)(\cctr@tempa,\cctr@tempb,\cctr@tempc)(#7)} \def\VECTORMATRIXPRODUCT(#1)(#2)(#3){% \begingroup \VECTORSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@VECTORMATRIXPRODUCT(#1)(#2)(#3) \else \@@@VECTORMATRIXPRODUCT(#1)(#2)(#3)\fi\@OUTPUTVECTOR(#3)} % \end{macrocode} % \end{macro} % \begin{macro}{\SCALARMATRIXPRODUCT} % Scalar-matrix product. % \begin{macrocode} \def\@@SCALARMATRIXPRODUCT#1(#2;#3)(#4,#5;#6,#7){% \SCALARVECTORPRODUCT{#1}(#2)(#4,#5) \SCALARVECTORPRODUCT{#1}(#3)(#6,#7)} \def\@@@SCALARMATRIXPRODUCT#1(#2;#3;#4){% \SCALARVECTORPRODUCT{#1}(#2)(\cctr@solAA,\cctr@solAB,\cctr@solAC) \SCALARVECTORPRODUCT{#1}(#3)(\cctr@solBA,\cctr@solBB,\cctr@solBC) \SCALARVECTORPRODUCT{#1}(#4)(\cctr@solCA,\cctr@solCB,\cctr@solCC) \@TDMATRIXSOL} \def\SCALARMATRIXPRODUCT#1(#2)(#3){% \begingroup \MATRIXSIZE(#2){\cctr@size} \ifnum\cctr@size=2 \@@SCALARMATRIXPRODUCT{#1}(#2)(#3) \else \@@@SCALARMATRIXPRODUCT{#1}(#2)(#3)\fi\@OUTPUTMATRIX(#3)} % \end{macrocode} % \end{macro} % \begin{macro}{\MATRIXPRODUCT} % Product of two matrices. % \begin{macrocode} \def\@@MATRIXPRODUCT(#1)(#2,#3;#4,#5)(#6,#7;#8,#9){% \MATRIXVECTORPRODUCT(#1)(#2,#4)(#6,#8) \MATRIXVECTORPRODUCT(#1)(#3,#5)(#7,#9)} \def\@@@MATRIXPRODUCT(#1;#2;#3)(#4){% \VECTORMATRIXPRODUCT(#1)(#4)(\cctr@solAA,\cctr@solAB,\cctr@solAC) \VECTORMATRIXPRODUCT(#2)(#4)(\cctr@solBA,\cctr@solBB,\cctr@solBC) \VECTORMATRIXPRODUCT(#3)(#4)(\cctr@solCA,\cctr@solCB,\cctr@solCC) \@TDMATRIXSOL} \def\MATRIXPRODUCT(#1)(#2)(#3){% \begingroup \MATRIXSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@MATRIXPRODUCT(#1)(#2)(#3) \else \@@@MATRIXPRODUCT(#1)(#2)(#3)\fi\@OUTPUTMATRIX(#3)} % \end{macrocode} % \end{macro} % \begin{macro}{\DETERMINANT} % Determinant of a matrix. % \begin{macrocode} \def\@@DETERMINANT(#1,#2;#3,#4)#5{% \MULTIPLY{#1}{#4}{#5} \MULTIPLY{#2}{#3}{\cctr@tempa} \SUBTRACT{#5}{\cctr@tempa}{#5}} \def\@@@DETERMINANT(#1,#2,#3;#4,#5,#6;#7,#8,#9){% \DETERMINANT(#5,#6;#8,#9){\cctr@det}\MULTIPLY{#1}{\cctr@det}{\cctr@sol} \DETERMINANT(#6,#4;#9,#7){\cctr@det}\MULTIPLY{#2}{\cctr@det}{\cctr@det} \ADD{\cctr@sol}{\cctr@det}{\cctr@sol} \DETERMINANT(#4,#5;#7,#8){\cctr@det}\MULTIPLY{#3}{\cctr@det}{\cctr@det} \ADD{\cctr@sol}{\cctr@det}{\cctr@sol} \@NUMBERSOL} \def\DETERMINANT(#1)#2{% \begingroup \MATRIXSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@DETERMINANT(#1){#2} \else \@@@DETERMINANT(#1){#2}\fi\@OUTPUTSOL{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\INVERSEMATRIX} % Inverse of a matrix. % \begin{macrocode} \def\@@INVERSEMATRIX(#1,#2;#3,#4)(#5,#6;#7,#8){% \ifdim \cctr@@det\p@ <\cctr@epsilon % Matrix is singular \let#5\undefined \let#6\undefined \let#7\undefined \let#8\undefined \cctr@Warnsingmatrix{#1}{#2}{#3}{#4}% \else \COPY{#1}{#8} \COPY{#4}{#5} \MULTIPLY{-1}{#3}{#7} \MULTIPLY{-1}{#2}{#6} \DIVIDE{1}{\cctr@det}{\cctr@det} \SCALARMATRIXPRODUCT{\cctr@det}(#5,#6;#7,#8)(#5,#6;#7,#8) \fi} \def\@@@INVERSEMATRIX(#1,#2,#3;#4,#5,#6;#7,#8,#9){% \ifdim \cctr@@det\p@ <\cctr@epsilon % Matrix is singular \@TDMATRIXNOSOL(\cctr@solAA,\cctr@solAB,\cctr@solAC; \cctr@solBA,\cctr@solBB,\cctr@solBC; \cctr@solCA,\cctr@solCB,\cctr@solCC) \cctr@WarnsingTDmatrix{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}% \else \@ADJMATRIX(#1,#2,#3;#4,#5,#6;#7,#8,#9) \@SCLRDIVVECT{\cctr@det}(\cctr@solAA,\cctr@solAB,\cctr@solAC)(% \cctr@solAA,\cctr@solAB,\cctr@solAC) \@SCLRDIVVECT{\cctr@det}(\cctr@solBA,\cctr@solBB,\cctr@solBC)(% \cctr@solBA,\cctr@solBB,\cctr@solBC) \@SCLRDIVVECT{\cctr@det}(\cctr@solCA,\cctr@solCB,\cctr@solCC)(% \cctr@solCA,\cctr@solCB,\cctr@solCC) \fi \@@TDMATRIXSOL} \def\@SCLRDIVVECT#1(#2,#3,#4)(#5,#6,#7){% \DIVIDE{#2}{#1}{#5}\DIVIDE{#3}{#1}{#6}\DIVIDE{#4}{#1}{#7}} \def\@ADJMATRIX(#1,#2,#3;#4,#5,#6;#7,#8,#9){% \DETERMINANT(#5,#6;#8,#9){\cctr@solAA} \DETERMINANT(#6,#4;#9,#7){\cctr@solBA} \DETERMINANT(#4,#5;#7,#8){\cctr@solCA} \DETERMINANT(#8,#9;#2,#3){\cctr@solAB} \DETERMINANT(#1,#3;#7,#9){\cctr@solBB} \DETERMINANT(#2,#1;#8,#7){\cctr@solCB} \DETERMINANT(#2,#3;#5,#6){\cctr@solAC} \DETERMINANT(#3,#1;#6,#4){\cctr@solBC} \DETERMINANT(#1,#2;#4,#5){\cctr@solCC}} \def\INVERSEMATRIX(#1)(#2){% \begingroup \DETERMINANT(#1){\cctr@det} \ABSVALUE{\cctr@det}{\cctr@@det} \MATRIXSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@INVERSEMATRIX(#1)(#2) \else \@@@INVERSEMATRIX(#1)(#2)\fi\@OUTPUTMATRIX(#2)} % \end{macrocode} % \end{macro} % \begin{macro}{\SOLVELINEARSYSTEM} % Solving a linear system (two equations and two unknowns % or three equations and three unknowns). % \begin{macrocode} \def\@INCSYS#1#2{\cctr@WarnIncLinSys \let#1\undefined\let#2\undefined} \def\@SOLPART#1#2#3#4{\cctr@WarnIndLinSys \DIVIDE{#1}{#2}{#3} \COPY{0}{#4}} \def\@TDINCSYS(#1,#2,#3){\cctr@WarnIncTDLinSys \let#1\undefined \let#2\undefined \let#3\undefined} \def\@@SOLVELINEARSYSTEM(#1,#2;#3,#4)(#5,#6)(#7,#8){% \DETERMINANT(#1,#2;#3,#4)\cctr@deta \DETERMINANT(#5,#2;#6,#4)\cctr@detb \DETERMINANT(#1,#5;#3,#6)\cctr@detc \ABSVALUE{\cctr@deta}{\cctr@@deta} \ABSVALUE{\cctr@detb}{\cctr@@detb} \ABSVALUE{\cctr@detc}{\cctr@@detc} \ifdim \cctr@@deta\p@>\cctr@epsilon% Regular matrix. Determinate system \DIVIDE{\cctr@detb}{\cctr@deta}{#7} \DIVIDE{\cctr@detc}{\cctr@deta}{#8} \else % Singular matrix \cctr@deta=0 \ifdim \cctr@@detb\p@>\cctr@epsilon% Incompatible system \@INCSYS#7#8 \else \ifdim \cctr@@detc\p@>\cctr@epsilon% Incompatible system \@INCSYS#7#8 \else \MATRIXABSVALUE(#1,#2;#3,#4)(\cctr@tempa,\cctr@tempb; \cctr@tempc,\cctr@tempd) \ifdim \cctr@tempa\p@ > \cctr@epsilon % Indeterminate system \@SOLPART{#5}{#1}{#7}{#8} \else \ifdim \cctr@tempb\p@ > \cctr@epsilon % Indeterminate system \@SOLPART{#5}{#2}{#8}{#7} \else \ifdim \cctr@tempc\p@ > \cctr@epsilon % Indeterminate system \@SOLPART{#6}{#3}{#7}{#8} \else \ifdim \cctr@tempd\p@ > \cctr@epsilon % Indeterminate system \@SOLPART{#6}{#4}{#8}{#7} \else \VECTORNORM(#5,#6){\cctr@tempa} \ifdim \cctr@tempa\p@ > \cctr@epsilon % Incompatible system \@INCSYS#7#8 \else \cctr@WarnZeroLinSys \COPY{0}{#7}\COPY{0}{#8} % 0x=0 Indeterminate system \fi\fi\fi\fi\fi\fi\fi\fi} \def\@@@SOLVELINEARSYSTEM(#1)(#2)(#3){% \DETERMINANT(#1){\cctr@det} \ABSVALUE{\cctr@det}{\cctr@@det} \ifdim\cctr@@det\p@<\cctr@epsilon \@TDINCSYS(#3) \else \@ADJMATRIX(#1) \MATRIXVECTORPRODUCT(\cctr@solAA,\cctr@solAB,\cctr@solAC; \cctr@solBA,\cctr@solBB,\cctr@solBC; \cctr@solCA,\cctr@solCB,\cctr@solCC)(#2)(#3) \@SCLRDIVVECT{\cctr@det}(#3)(#3) \fi} \def\SOLVELINEARSYSTEM(#1)(#2)(#3){% \begingroup \MATRIXSIZE(#1){\cctr@size} \ifnum\cctr@size=2 \@@SOLVELINEARSYSTEM(#1)(#2)(#3) \else \@@@SOLVELINEARSYSTEM(#1)(#2)(#3) \fi\@OUTPUTVECTOR(#3)} % \end{macrocode} % \end{macro} % \subsection*{Predefined numbers} % \begin{macro}{\numberPI} % The number $\pi$ % \begin{macrocode} \def\numberPI{3.14159} % \end{macrocode} % \end{macro} % \begin{macro}{\numberTWOPI} % $2\pi$ % \begin{macrocode} \MULTIPLY{\numberPI}{2}{\numberTWOPI} % \end{macrocode} % \end{macro} % \begin{macro}{\numberHALFPI} % $\pi/2$ % \begin{macrocode} \DIVIDE{\numberPI}{2}{\numberHALFPI} % \end{macrocode} % \end{macro} % \begin{macro}{\numberTHREEHALFPI} % $3\pi/2$ % \begin{macrocode} \MULTIPLY{\numberPI}{1.5}{\numberTHREEHALFPI} % \end{macrocode} % \end{macro} % \begin{macro}{\numberTHIRDPI} % $\pi/3$ % \begin{macrocode} \DIVIDE{\numberPI}{3}{\numberTHIRDPI} % \end{macrocode} % \end{macro} % \begin{macro}{\numberQUARTERPI} % $\pi/4$ % \begin{macrocode} \DIVIDE{\numberPI}{4}{\numberQUARTERPI} % \end{macrocode} % \end{macro} % \begin{macro}{\numberFIFTHPI} % $\pi/5$ % \begin{macrocode} \DIVIDE{\numberPI}{5}{\numberFIFTHPI} % \end{macrocode} % \end{macro} % \begin{macro}{\numberSIXTHPI} % $\pi/6$ % \begin{macrocode} \DIVIDE{\numberPI}{6}{\numberSIXTHPI} % \end{macrocode} % \end{macro} % \begin{macro}{\numberE} % The number $\mathrm e$ % \begin{macrocode} \def\numberE{2.71828} % \end{macrocode} % \end{macro} % \begin{macro}{\numberINVE} % $1/{\mathrm e}$ % \begin{macrocode} \DIVIDE{1}{\numberE}{\numberINVE} % \end{macrocode} % \end{macro} % \begin{macro}{\numberETWO} % $\mathrm e^2$ % \begin{macrocode} \SQUARE{\numberE}{\numberETWO} % \end{macrocode} % \end{macro} % \begin{macro}{\numberINVETWO} % $1/{\mathrm e^2}$ % \begin{macrocode} \SQUARE{\numberINVE}{\numberINVETWO} % \end{macrocode} % \end{macro} % \begin{macro}{\numberLOGTEN} % $\log 10$ % \begin{macrocode} \def\numberLOGTEN{2.30258} % \end{macrocode} % \end{macro} % \begin{macro}{\numberGOLD} % The golden ratio $\phi$ % \begin{macrocode} \def\numberGOLD{1.61803} % \end{macrocode} % \end{macro} % \begin{macro}{\numberINVGOLD} % $1/\phi$ % \begin{macrocode} \def\numberINVGOLD{0.61803} % \end{macrocode} % \end{macro} % \begin{macro}{\numberSQRTTWO} % $\sqrt 2$ % \begin{macrocode} \def\numberSQRTTWO{1.41421} % \end{macrocode} % \end{macro} % \begin{macro}{\numberSQRTTHREE} % $\sqrt 3$ % \begin{macrocode} \def\numberSQRTTHREE{1.73205} % \end{macrocode} % \end{macro} % \begin{macro}{\numberSQRTFIVE} % $\sqrt 5$ % \begin{macrocode} \def\numberSQRTFIVE{2.23607} % \end{macrocode} % \end{macro} % \begin{macro}{\numberCOSXLV} % $\cos 45^{\mathrm o}$ (or $\cos \pi/4$) % \begin{macrocode} \def\numberCOSXLV{0.70711} % \end{macrocode} % \end{macro} % \begin{macro}{\numberCOSXXX} % $\cos 30^{\mathrm o}$ (or $\cos \pi/6$) % \begin{macrocode} \def\numberCOSXXX{0.86603} % \end{macrocode} % \end{macro} % \begin{macrocode} % % \end{macrocode} % % \section{\textsf{calculus}} % \changes{v2.0}{2013/07/10}{Trivial error in documentation corrected} % \begin{macrocode} %<*calculus> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{calculus}[2014/02/20 v.2.0] % \end{macrocode} % This package requires the calculator package. % \begin{macrocode} \RequirePackage{calculator} % \end{macrocode} % \subsection{Error and info messages} % \subsubsection*{For scalar functions} % % Error message to be issued when you attempt to define, with \cs{newfunction}, % an already defined command: % \begin{macrocode} \def\ccls@ErrorFuncDef#1{% \PackageError{calculus}% {\noexpand#1 command already defined} {The \noexpand#1 control sequence is already defined\MessageBreak If you want to redefine the \noexpand#1 command as a function\MessageBreak please, use the \noexpand\renewfunction command}} % \end{macrocode} % Error message to be issued when you attempt to redefine, % with \cs{renewfunction}, an undefined command: % \begin{macrocode} \def\ccls@ErrorFuncUnDef#1{% \PackageError{calculus}% {\noexpand#1 command undefined} {The \noexpand#1 control sequence is not currently defined\MessageBreak If you want to define the \noexpand#1 command as a function\MessageBreak please, use the \noexpand\newfunction command}} % \end{macrocode} % Info message to be issued when \cs{ensurefunction} does not changes % an already defined command: % \begin{macrocode} \def\ccls@InfoFuncEns#1{% \PackageInfo{calculus}% {\noexpand#1 command already defined\MessageBreak the \noexpand\ensurefunction command will not redefine it}} % \end{macrocode} % \subsubsection*{For polar functions} % \begin{macrocode} \def\ccls@ErrorPFuncDef#1{% \PackageError{calculus}% {\noexpand#1 command already defined} {The \noexpand#1 control sequence is already defined\MessageBreak If you want to redefine the \noexpand#1 command as a polar function\MessageBreak please, use the \noexpand\renewpolarfunction command}} \def\ccls@ErrorPFuncUnDef#1{% \PackageError{calculus}% {\noexpand#1 command undefined} {The \noexpand#1 control sequence is not currently defined.\MessageBreak If you want to define the \noexpand#1 command as a polar function\MessageBreak please, use the \noexpand\newpolarfunction command}} \def\ccls@InfoPFuncEns#1{% \PackageInfo{calculus}% {\noexpand#1 command already defined\MessageBreak the \noexpand\ensurepolarfunction command does not redefine it}} % \end{macrocode} % \subsubsection*{For vector functions} % \begin{macrocode} \def\ccls@ErrorVFuncDef#1{% \PackageError{calculus}% {\noexpand#1 command already defined} {The \noexpand#1 control sequence is already defined\MessageBreak If you want to redefine the \noexpand#1 command as a vector function\MessageBreak please, use the \noexpand\renewvectorfunction command}} \def\ccls@ErrorVFuncUnDef#1{% \PackageError{calculus}% {\noexpand#1 command undefined} {The \noexpand#1 control sequence is not currently defined.\MessageBreak If you want to define the \noexpand#1 command as a vector function\MessageBreak please, use the \noexpand\newvectorfunction command}} \def\ccls@InfoVFuncEns#1{% \PackageInfo{calculus}% {\noexpand#1 command already defined\MessageBreak the \noexpand\ensurevectorfunction command does not redefine it}} % \end{macrocode} % \subsection{New functions} % \subsubsection*{New scalar functions} % % \begin{macro}{\newfunction} % The \cs{newfunction\{\#1\}\{\#2\}} instruction defines % a new function called \#1. % \#2 is the list of instructions to calculate the function % \cs{y} and his derivative \cs{Dy} from the \cs{t} variable. % \begin{macrocode} \def\newfunction#1#2{% \ifx #1\undefined \ccls@deffunction{#1}{#2} \else \ccls@ErrorFuncDef{#1} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\renewfunction} % \cs{renewfunction} redefines \#1, as a new function, % if this command is already defined. % \begin{macrocode} \def\renewfunction#1#2{% \ifx #1\undefined \ccls@ErrorFuncUnDef{#1} \else \ccls@deffunction{#1}{#2} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\ensurefunction} % \cs{ensurefunction} defines the new function \#1 % (only if this macro is undefined). % \begin{macrocode} \def\ensurefunction#1#2{% \ifx #1\undefined\ccls@deffunction{#1}{#2} \else \ccls@InfoFuncEns{#1} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\forcefunction} % \cs{forcefunction} defines (if undefined) or redefines (if defined) % the new function \#1. % \begin{macrocode} \def\forcefunction#1#2{% \ccls@deffunction{#1}{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\ccls@deffunction} % The private \cs{ccls@deffunction} command makes the real work. % The new functions will have three arguments: % \#\#1, a number, \#\#2, the value of the new function in that number, % and \#\#3, the derivative. % \begin{macrocode} \def\ccls@deffunction#1#2{% \def#1##1##2##3{% \begingroup \def\t{##1}% #2 \xdef##2{\y}% \xdef##3{\Dy}% \endgroup}\ignorespaces} % \end{macrocode} % \end{macro} % \subsubsection*{New polar functions} % % \begin{macro}{\newpolarfunction} % The \cs{newpolarfunction\{\#1\}\{\#2\}} instruction defines % a new polar function called \#1. % \#2 is the list of instructions to calculate the radius \cs{r} % and his derivative \cs{Dr} from the \cs{t} arc variable. % \begin{macrocode} \def\newpolarfunction#1#2{% \ifx #1\undefined \ccls@defpolarfunction{#1}{#2} \else \ccls@ErrorPFuncDef{#1} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\renewpolarfunction} % \cs{renewpolarfunction} redefines \#1 if already defined. % \begin{macrocode} \def\renewpolarfunction#1#2{% \ifx #1\undefined \ccls@ErrorPFuncUnDef{#1} \else \ccls@defpolarfunction{#1}{#2} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\ensurepolarfunction} % \cs{ensurepolarfunction} defines (only if undefined) \#1. % \begin{macrocode} \def\ensurepolarfunction#1#2{% \ifx #1\undefined\ccls@defpolarfunction{#1}{#2} \else \ccls@InfoPFuncEns{#1} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\forcepolarfunction} % \cs{forcepolarfunction} defines (if undefined) or redefines (if defined) \#1. % \begin{macrocode} \def\forcepolarfunction#1#2{% \ccls@defpolarfunction{#1}{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\ccls@defpolarfunction} % The private \cs{ccls@defpolarfunction} command makes the real work. % The new functions will have three arguments: % \#\#1, a number (the polar radius), % \#\#2, \#\#3, \#\#4, and \#\#5, the x and y component functions and % its derivatives at \#\#1. % \begin{macrocode} \def\ccls@defpolarfunction#1#2{% \def#1##1##2##3##4##5{% \begingroup \def\t{##1} #2 \COS{\t}\ccls@cost \MULTIPLY\r\ccls@cost{\x} \SIN{\t}\ccls@sint \MULTIPLY\r\ccls@sint{\y} \MULTIPLY\ccls@cost\Dr\Dx \SUBTRACT{\Dx}{\y}{\Dx} \MULTIPLY\ccls@sint\Dr\Dy \ADD{\Dy}{\x}{\Dy} \xdef##2{\x} \xdef##3{\Dx} \xdef##4{\y} \xdef##5{\Dy} \endgroup}\ignorespaces} % \end{macrocode} % \end{macro} % \subsubsection*{New vector functions} % % \begin{macro}{\newvectorfunction} % The \cs{newvectorfunction\{\#1\}\{\#2\}} instruction defines % a new vector (parametric) function called \#1. % \#2 is the list of instructions to calculate % \cs{x}, \cs{y}, \cs{Dx} and \cs{Dy} from the \cs{t} arc variable. % \begin{macrocode} \def\newvectorfunction#1#2{% \ifx #1\undefined \ccls@defvectorfunction{#1}{#2} \else \ccls@ErrorVFuncDef{#1} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\renewvectorfunction} % \cs{renewvectorfunction} redefines \#1 if already defined. % \begin{macrocode} \def\renewvectorfunction#1#2{% \ifx #1\undefined \ccls@ErrorVFuncUnDef{#1} \else \ccls@defvectorfunction{#1}{#2} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\ensurevectorfunction} % \cs{ensurevectorfunction} defines (only if undefined) \#1. % \begin{macrocode} \def\ensurevectorfunction#1#2{% \ifx #1\undefined\ccls@defvectorfunction{#1}{#2} \else \ccls@InfoVFuncEns{#1} \fi} % \end{macrocode} % \end{macro} % \begin{macro}{\forcevectorfunction} % \cs{forcevectorfunction} defines (if undefined) % or redefines (if defined) \#1. % \begin{macrocode} \def\forcevectorfunction#1#2{% \ccls@defvectorfunction{#1}{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\ccls@defvectorfunction} % The private \cs{ccls@defvectorfunction} command makes the real work. % The new functions will have three arguments: % \#\#1, a number, % \#\#2, \#\#3, \#\#4, and \#\#5, the x and y component functions % and its derivatives at \#\#1. % \begin{macrocode} \def\ccls@defvectorfunction#1#2{% \def#1##1##2##3##4##5{% \begingroup \def\t{##1} #2 \xdef##2{\x} \xdef##3{\Dx} \xdef##4{\y} \xdef##5{\Dy} \endgroup}\ignorespaces} % \end{macrocode} % \end{macro} % \subsection{Polynomials} % \subsubsection*{Linear (first degreee) polynomials} % % \begin{macro}{\newlpoly} % The \cs{newlpoly\{\#1\}\{\#2\}\{\#3\}} instruction defines % the linear polynomial % % $\#1=\#2+\#3t$. % \begin{macrocode} \def\newlpoly#1#2#3{% \newfunction{#1}{% \ccls@lpoly{#2}{#3}}} % \end{macrocode} % \end{macro} % \begin{macro}{\renewlpoly} % We define also the \cs{renewlpoly}, \cs{ensurelpoly} % and \cs{forcelpoly} variants. % \begin{macrocode} \def\renewlpoly#1#2#3{% \renewfunction{#1}{% \ccls@lpoly{#2}{#3}}} % \end{macrocode} % \end{macro} % \begin{macro}{\ensurelpoly} % \begin{macrocode} \def\ensurelpoly#1#2#3{% \ensurefunction{#1}{% \ccls@lpoly{#2}{#3}}} % \end{macrocode} % \end{macro} % \begin{macro}{\forcelpoly} % \begin{macrocode} \def\forcelpoly#1#2#3{% \forcefunction{#1}{% \ccls@lpoly{#2}{#3}}} % \end{macrocode} % \end{macro} % \begin{macro}{\ccls@lpoly} % The \cs{ccls@lpoly\{\#1\}\{\#2\}} macro defines the new polynomial function. % \begin{macrocode} \def\ccls@lpoly#1#2{% \MULTIPLY{#2}{\t}{\y} \ADD{\y}{#1}{\y} \COPY{#2}{\Dy}} % \end{macrocode} % \end{macro} % \subsubsection*{Quadratic polynomials} % % \begin{macro}{\newqpoly} % The \cs{newqpoly\{\#1\}\{\#2\}\{\#3\}\{\#4\}} % instruction defines the quadratic polynomial % % $\#1=\#2+\#3t+\#4t^2$. % \begin{macrocode} \def\newqpoly#1#2#3#4{% \newfunction{#1}{% \ccls@qpoly{#2}{#3}{#4}}} % \end{macrocode} % \end{macro} % \begin{macro}{\renewqpoly} % \begin{macrocode} \def\renewqpoly#1#2#3#4{% \renewfunction{#1}{% \ccls@qpoly{#2}{#3}{#4}}} % \end{macrocode} % \end{macro} % \begin{macro}{\ensureqpoly} % \begin{macrocode} \def\ensureqpoly#1#2#3#4{% \ensurefunction{#1}{% \ccls@qpoly{#2}{#3}{#4}}} % \end{macrocode} % \end{macro} % \begin{macro}{\forceqpoly} % \begin{macrocode} \def\forceqpoly#1#2#3#4{% \forcefunction{#1}{% \ccls@qpoly{#2}{#3}{#4}}} % \end{macrocode} % \end{macro} % \begin{macro}{\ccls@qpoly} % The \cs{ccls@qpoly\{\#1\}\{\#2\}} macro defines the new polynomial function. % \begin{macrocode} \def\ccls@qpoly#1#2#3{% \MULTIPLY{\t}{#3}{\y} \MULTIPLY{2}{\y}{\Dy} \ADD{#2}{\Dy}{\Dy} \ADD{#2}{\y}{\y} \MULTIPLY{\t}{\y}{\y} \ADD{#1}{\y}{\y}} % \end{macrocode} % \end{macro} % \subsubsection*{Cubic polynomials} % % \begin{macro}{\newcpoly} % The \cs{newcpoly\{\#1\}\{\#2\}\{\#3\}\{\#4\}\{\#5\}} % instruction defines the cubic polynomial % % $\#1=\#2+\#3t+\#4t^2+\#5t^3$. % \begin{macrocode} \def\newcpoly#1#2#3#4#5{% \newfunction{#1}{% \ccls@cpoly{#2}{#3}{#4}{#5}}} % \end{macrocode} % \end{macro} % \begin{macro}{\renewcpoly} % \begin{macrocode} \def\renewcpoly#1#2#3#4#5{% \renewfunction{#1}{% \ccls@cpoly{#2}{#3}{#4}{#5}}} % \end{macrocode} % \end{macro} % \begin{macro}{\ensurecpoly} % \begin{macrocode} \def\ensurecpoly#1#2#3#4#5{% \ensurefunction{#1}{% \ccls@cpoly{#2}{#3}{#4}{#5}}} % \end{macrocode} % \end{macro} % \begin{macro}{\forcecpoly} % \begin{macrocode} \def\forcecpoly#1#2#3#4#5{% \forcefunction{#1}{% \ccls@cpoly{#2}{#3}{#4}{#5}}} % \end{macrocode} % \end{macro} % \begin{macro}{\ccls@cpoly} % The \cs{ccls@cpoly\{\#1\}\{\#2\}} macro defines the new polynomial function. % \begin{macrocode} \def\ccls@cpoly#1#2#3#4{% \MULTIPLY{\t}{#4}{\y} \MULTIPLY{3}{\y}{\Dy} \ADD{#3}{\y}{\y} \MULTIPLY{2}{#3}{\ccls@temp} \ADD{\ccls@temp}{\Dy}{\Dy} \MULTIPLY{\t}{\y}{\y} \MULTIPLY{\t}{\Dy}{\Dy} \ADD{#2}{\y}{\y} \ADD{#2}{\Dy}{\Dy} \MULTIPLY{\t}{\y}{\y} \ADD{#1}{\y}{\y} } % \end{macrocode} % \end{macro} % \subsection{Elementary functions} % \begin{macro}{\ONEfunction} % The \cs{ONEfunction}: $y(t)=1$, $y'(t)=0$ % \begin{macrocode} \newfunction{\ONEfunction}{% \COPY{1}{\y} \COPY{0}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\ZEROfunction} % The \cs{ZEROfunction}: $y(t)=0$, $y'(t)=0$ % \begin{macrocode} \newfunction{\ZEROfunction}{% \COPY{0}{\y} \COPY{0}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\IDENTITYfunction} % The \cs{IDENTITYfunction}: $y(t)=t$, $y'(t)=1$ % \begin{macrocode} \newfunction{\IDENTITYfunction}{% \COPY{\t}{\y} \COPY{1}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\RECIPROCALfunction} % The \cs{RECIPROCALfunction}: $y(t)=1/t$, $y'(t)=-1/t^2$ % \begin{macrocode} \newfunction{\RECIPROCALfunction}{% \DIVIDE{1}{\t}{\y} \SQUARE{\y}{\Dy} \MULTIPLY{-1}{\Dy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\SQUAREfunction} % The \cs{SQUAREfunction}: $y(t)=t^2$, $y'(t)=2t$ % \begin{macrocode} \newfunction{\SQUAREfunction}{% \SQUARE{\t}{\y} \MULTIPLY{2}{\t}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\CUBEfunction} % The \cs{CUBEfunction}: $y(t)=t^3$, $y'(t)=3t^2$ % \begin{macrocode} \newfunction{\CUBEfunction}{% \SQUARE{\t}{\Dy} \MULTIPLY{\t}{\Dy}{\y} \MULTIPLY{3}{\Dy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\SQRTfunction} % The \cs{SQRTfunction}: $y(t)=\sqrt t$, $y'(t)=1/(2\sqrt t)$ % \begin{macrocode} \newfunction{\SQRTfunction}{% \SQRT{\t}{\y} \DIVIDE{0.5}{\y}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\EXPfunction} % The \cs{EXPfunction}: $y(t)=\exp t$, $y'(t)=\exp t$ % \begin{macrocode} \newfunction{\EXPfunction}{% \EXP{\t}{\y} \COPY{\y}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\COSfunction} % The \cs{COSfunction}: $y(t)=\cos t$, $y'(t)=-\sin t$ % \begin{macrocode} \newfunction{\COSfunction}{% \COS{\t}{\y} \SIN{\t}{\Dy} \MULTIPLY{-1}{\Dy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\SINfunction} % The \cs{SINfunction}: $y(t)=\sin t$, $y'(t)=\cos t$ % \begin{macrocode} \newfunction{\SINfunction}{% \SIN{\t}{\y} \COS{\t}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\TANfunction} % The \cs{TANfunction}: $y(t)=\tan t$, $y'(t)=1/(\cos t)^2$ % \begin{macrocode} \newfunction{\TANfunction}{% \TAN{\t}{\y} \COS{\t}{\Dy} \SQUARE{\Dy}{\Dy} \DIVIDE{1}{\Dy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\COTfunction} % The \cs{COTfunction}: $y(t)=\cot t$, $y'(t)=-1/(\sin t)^2$ % \begin{macrocode} \newfunction{\COTfunction}{% \COTAN{\t}{\y} \SIN{\t}{\Dy} \SQUARE{\Dy}{\Dy} \DIVIDE{-1}{\Dy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\COSHfunction} % The \cs{COSHfunction}: $y(t)=\cosh t$, $y'(t)=\sinh t$ % \begin{macrocode} \newfunction{\COSHfunction}{% \COSH{\t}{\y} \SINH{\t}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\SINHfunction} % The \cs{SINHfunction}: $y(t)=\sinh t$, $y'(t)=\cosh t$ % \begin{macrocode} \newfunction{\SINHfunction}{% \SINH{\t}{\y} \COSH{\t}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\TANHfunction} % The \cs{TANHfunction}: $y(t)=\tanh t$, $y'(t)=1/(\cosh t)^2$ % \begin{macrocode} \newfunction{\TANHfunction}{% \TANH{\t}{\y} \COSH{\t}{\Dy} \SQUARE{\Dy}{\Dy} \DIVIDE{1}{\Dy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\COTHfunction} % The \cs{COTHfunction}: $y(t)=\coth t$, $y'(t)=-1/(\sinh t)^2$ % \begin{macrocode} \newfunction{\COTHfunction}{% \COTANH{\t}{\y} \SINH{\t}{\Dy} \SQUARE{\Dy}{\Dy} \DIVIDE{-1}{\Dy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\LOGfunction} % The \cs{LOGfunction}: $y(t)=\log t$, $y'(t)=1/t$ % \begin{macrocode} \newfunction{\LOGfunction}{% \LOG{\t}{\y} \DIVIDE{1}{\t}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\HEAVISIDEfunction} % The \cs{HEAVISIDEfunction}: % $y(t)=\begin{cases} % 0 & \text{if } t<0 \\ % 1 & \text{if } t\geq 0 % \end{cases}$, % $y'(t)=0$ % \begin{macrocode} \newfunction{\HEAVISIDEfunction}{% \ifdim \t\p@<\z@ \COPY{0}{\y}\else\COPY{1}{\y}\fi \COPY{0}{\Dy}} % \end{macrocode} % \end{macro} % \changes{v2.0}{2014/02/13}{New commands: \cs{ARCSINfunction}, % \cs{ARCCOSfunction}, \cs{ARCTANfunction}, % \cs{ARCCOTfunction}} % \begin{macro}{\ARCSINfunction} % The \cs{ARCSINfunction}: $y(t)=\arcsin t$, $y'(t)=1/\sqrt{1-t^2}$ % \begin{macrocode} \newfunction{\ARCSINfunction}{% \ARCSIN{\t}{\y} \SQUARE{\t}{\yy} \SUBTRACT{1}{\yy}{\yy} \SQRT{\yy}{\Dy} \DIVIDE{1}{\Dy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\ARCCOSfunction} % The \cs{ARCCOSfunction}: $y(t)=\arccos t$, $y'(t)=-1/\sqrt{1-t^2}$ % \begin{macrocode} \newfunction{\ARCCOSfunction}{% \ARCCOS{\t}{\y} \SQUARE{\t}{\yy} \SUBTRACT{1}{\yy}{\yy} \SQRT{\yy}{\Dy} \DIVIDE{-1}{\Dy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\ARCTANfunction} % The \cs{ARCTANfunction}: $y(t)=\arctan t$, $y'(t)=1/(1+t^2)$ % \begin{macrocode} \newfunction{\ARCTANfunction}{% \ARCTAN{\t}{\y} \SQUARE{\t}{\yy} \ADD{1}{\yy}{\yy} \DIVIDE{1}{\yy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\ARCCOTfunction} % The \cs{ARCCOTfunction}: $y(t)=\arccot t$, $y'(t)=-1/(1+t^2)$ % \begin{macrocode} \newfunction{\ARCCOTfunction}{% \ARCCOT{\t}{\y} \SQUARE{\t}{\yy} \ADD{1}{\yy}{\yy} \DIVIDE{-1}{\yy}{\Dy}} % \end{macrocode} % \end{macro} % \changes{v2.0}{2014/02/13}{New commands: \cs{ARSINHfunction}, % \cs{ARCOSHfunction}, \cs{ARTANHfunction}, % \cs{ARCOTHfunction}} % \begin{macro}{\ARSINHfunction} % The \cs{ARSINHfunction}: $y(t)=\arsinh t$, $y'(t)=1/\sqrt{1+t^2}$ % \begin{macrocode} \newfunction{\ARSINHfunction}{% \ARSINH{\t}{\y} \SQUARE{\t}{\yy} \ADD{1}{\yy}{\yy} \SQRT{\yy}{\Dy} \DIVIDE{1}{\Dy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\ARCOSHfunction} % The \cs{ARSINHfunction}: $y(t)=\arcosh t$, $y'(t)=1/\sqrt{t^2-1}$ % \begin{macrocode} \newfunction{\ARCOSHfunction}{% \ARCOSH{\t}{\y} \SQUARE{\t}{\yy} \SUBTRACT{\yy}{1}{\yy} \SQRT{\yy}{\Dy} \DIVIDE{1}{\Dy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\ARTANHfunction} % The \cs{ARTANHfunction}: $y(t)=\artanh t$, $y'(t)=1/(t^2-1)$ % \begin{macrocode} \newfunction{\ARTANHfunction}{% \ARTANH{\t}{\y} \SQUARE{\t}{\yy} \SUBTRACT{1}{\yy}{\yy} \DIVIDE{1}{\yy}{\Dy}} % \end{macrocode} % \end{macro} % \begin{macro}{\ARCOTHfunction} % The \cs{ARCOTHfunction}: $y(t)=\arcoth t$, $y'(t)=1/(t^2-1)$ % \begin{macrocode} \newfunction{\ARCOTHfunction}{% \ARCOTH{\t}{\y} \SQUARE{\t}{\yy} \SUBTRACT{1}{\yy}{\yy} \DIVIDE{1}{\yy}{\Dy}} % \end{macrocode} % \end{macro} % \subsection{Operations with functions} % \begin{macro}{\CONSTANTfunction} % \cs{CONSTANTfunction} defines \#2 as the constant function $f(t)=\#1$. % \begin{macrocode} \def\CONSTANTfunction#1#2{% \def#2##1##2##3{% \xdef##2{#1}% \xdef##3{0}}} % \end{macrocode} % \end{macro} % \begin{macro}{\SUMfunction} % \cs{SUMfunction} defines \#3 as the sum of functions \#1 and \#2. % \begin{macrocode} \def\SUMfunction#1#2#3{% \def#3##1##2##3{% \begingroup #1{##1}{\ccls@SUMf}{\ccls@SUMDf}% #2{##1}{\ccls@SUMg}{\ccls@SUMDg}% \ADD{\ccls@SUMf}{\ccls@SUMg}{\ccls@SUMfg} \ADD{\ccls@SUMDf}{\ccls@SUMDg}{\ccls@SUMDfg} \xdef##2{\ccls@SUMfg}% \xdef##3{\ccls@SUMDfg}% \endgroup}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\SUBTRACTfunction} % \cs{SUBTRACTfunction} defines \#3 as the difference of functions \#1 and \#2. % \begin{macrocode} \def\SUBTRACTfunction#1#2#3{% \def#3##1##2##3{% \begingroup #1{##1}{\ccls@SUBf}{\ccls@SUBDf}% #2{##1}{\ccls@SUBg}{\ccls@SUBDg}% \SUBTRACT{\ccls@SUBf}{\ccls@SUBg}{\ccls@SUBfg} \SUBTRACT{\ccls@SUBDf}{\ccls@SUBDg}{\ccls@SUBDfg} \xdef##2{\ccls@SUBfg}% \xdef##3{\ccls@SUBDfg}% \endgroup}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\PRODUCTfunction} % \cs{PRODUCTfunction} defines \#3 as the product of functions \#1 and \#2. % \begin{macrocode} \def\PRODUCTfunction#1#2#3{% \def#3##1##2##3{% \begingroup #1{##1}{\ccls@PROf}{\ccls@PRODf}% #2{##1}{\ccls@PROg}{\ccls@PRODg}% \MULTIPLY{\ccls@PROf}{\ccls@PROg}{\ccls@PROfg} \MULTIPLY{\ccls@PROf}{\ccls@PRODg}{\ccls@PROfDg} \MULTIPLY{\ccls@PRODf}{\ccls@PROg}{\ccls@PRODfg} \ADD{\ccls@PROfDg}{\ccls@PRODfg}{\ccls@PRODfg} \xdef##2{\ccls@PROfg}% \xdef##3{\ccls@PRODfg}% \endgroup}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\QUOTIENTfunction} % \cs{QUOTIENTfunction} defines \#3 as the quotient of functions \#1 and \#2. % \begin{macrocode} \def\QUOTIENTfunction#1#2#3{% \def#3##1##2##3{% \begingroup #1{##1}{\ccls@QUOf}{\ccls@QUODf}% #2{##1}{\ccls@QUOg}{\ccls@QUODg}% \DIVIDE{\ccls@QUOf}{\ccls@QUOg}{\ccls@QUOfg} \MULTIPLY{\ccls@QUOf}{\ccls@QUODg}{\ccls@QUOfDg} \MULTIPLY{\ccls@QUODf}{\ccls@QUOg}{\ccls@QUODfg} \SUBTRACT{\ccls@QUODfg}{\ccls@QUOfDg}{\ccls@QUOnum} \SQUARE{\ccls@QUOg}{\ccls@qsquaretempg} \DIVIDE{\ccls@QUOnum}{\ccls@qsquaretempg}{\ccls@QUODfg} \xdef##2{\ccls@QUOfg}% \xdef##3{\ccls@QUODfg}% \endgroup}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\COMPOSITIONfunction} % \cs{COMPOSITIONfunction} defines \#3 as the composition % of functions \#1 and \#2. % \begin{macrocode} \def\COMPOSITIONfunction#1#2#3{% #3=#1(#2) \def#3##1##2##3{% \begingroup #2{##1}{\ccls@COMg}{\ccls@COMDg}% #1{\ccls@COMg}{\ccls@COMf}{\ccls@COMDf}% \MULTIPLY{\ccls@COMDg}{\ccls@COMDf}{\ccls@COMDf} \xdef##2{\ccls@COMf}% \xdef##3{\ccls@COMDf}% \endgroup}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\SCALEfunction} % \cs{SCALEfunction} defines \#3 as the product of number \#1 and function \#2. % \begin{macrocode} \def\SCALEfunction#1#2#3{% \def#3##1##2##3{% \begingroup #2{##1}{\ccls@SCFf}{\ccls@SCFDf}% \MULTIPLY{#1}{\ccls@SCFf}{\ccls@SCFaf} \MULTIPLY{#1}{\ccls@SCFDf}{\ccls@SCFDaf} \xdef##2{\ccls@SCFaf}% \xdef##3{\ccls@SCFDaf}% \endgroup}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\SCALEVARIABLEfunction} % \cs{SCALEVARIABLEfunction} scales the variable by number \#1 % and aplies function \#2. % \begin{macrocode} \def\SCALEVARIABLEfunction#1#2#3{% \def#3##1##2##3{% \begingroup% \MULTIPLY{#1}{##1}{\ccls@SCVat} #2{\ccls@SCVat}{\ccls@SCVf}{\ccls@SCVDf}% \MULTIPLY{#1}{\ccls@SCVDf}{\ccls@SCVDf} \xdef##2{\ccls@SCVf}% \xdef##3{\ccls@SCVDf}% \endgroup}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\POWERfunction} % \cs{POWERfunction} defines \#3 as the power of function \#1 to exponent \#2. % \begin{macrocode} \def\POWERfunction#1#2#3{% \def#3##1##2##3{% \begingroup #1{##1}{\ccls@POWf}{\ccls@POWDf}% \POWER{\ccls@POWf}{#2}{\ccls@POWfn} \SUBTRACT{#2}{1}{\ccls@nminusone} \POWER{\ccls@POWf}{\ccls@nminusone}{\ccls@POWDfn} \MULTIPLY{#2}{\ccls@POWDfn}{\ccls@POWDfn} \MULTIPLY{\ccls@POWDfn}{\ccls@POWDf}{\ccls@POWDfn} \xdef##2{\ccls@POWfn}% \xdef##3{\ccls@POWDfn}% \endgroup}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\LINEARCOMBINATIONfunction} % \cs{LINEARCOMBINATIONfunction} defines the new function \#5 % as the linear combination \#1\#2+\#3\#4. % \#1 and \#3 are two numbers. \#1 and \#3 are two functions. % \begin{macrocode} \def\LINEARCOMBINATIONfunction#1#2#3#4#5{% \def#5##1##2##3{% \begingroup #2{##1}{\ccls@LINf}{\ccls@LINDf}% #4{##1}{\ccls@LINg}{\ccls@LINDg}% \MULTIPLY{#1}{\ccls@LINf}{\ccls@LINf} \MULTIPLY{#3}{\ccls@LINg}{\ccls@LINg} \MULTIPLY{#1}{\ccls@LINDf}{\ccls@LINDf} \MULTIPLY{#3}{\ccls@LINDg}{\ccls@LINDg} \ADD{\ccls@LINf}{\ccls@LINg}{\ccls@LINafbg} \ADD{\ccls@LINDf}{\ccls@LINDg}{\ccls@LINDafbg} \xdef##2{\ccls@LINafbg}% \xdef##3{\ccls@LINDafbg}% \endgroup}\ignorespaces} % \end{macrocode} % \end{macro} % \begin{macro}{\POLARfunction} % \cs{POLARfunction} defines the polar curve \#2. % \#1 is a previously defined function. % \begin{macrocode} \def\POLARfunction#1#2{% \PRODUCTfunction{#1}{\COSfunction}{\ccls@polarx} \PRODUCTfunction{#1}{\SINfunction}{\ccls@polary} \PARAMETRICfunction{\ccls@polarx}{\ccls@polary}{#2}} % \end{macrocode} % \end{macro} % \begin{macro}{\PARAMETRICfunction} % \cs{PARAMETRICfunction} defines the parametric curve \#3. % \#1 and \#2 are the components functions (two previuosly defined functions). % \begin{macrocode} \def\PARAMETRICfunction#1#2#3{% \def#3##1##2##3##4##5{% #1{##1}{##2}{##3} #2{##1}{##4}{##5}}} % \end{macrocode} % \end{macro} % \begin{macro}{\VECTORfunction} % \cs{VECTORfunction}: an alias of \cs{PARAMETRICfunction}. % \begin{macrocode} \let\VECTORfunction\PARAMETRICfunction % \end{macrocode} % \end{macro} % % % \begin{macrocode} % % \end{macrocode} % \Finale %