% \iffalse meta-comment %<*internal> \begingroup \input docstrip.tex \keepsilent \preamble ------------------------------------------------------------------ The calculator and calculus packages Copyright (C) 2012 by Robert Fuster All rights reserved This file 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 1999/12/01 or later. ------------------------------------------------------------------ \endpreamble \postamble \endpostamble \askforoverwritefalse \generateFile{calculator.sty}{t}{\from{calculator.dtx}{calculator}} \generateFile{calculus.sty}{t}{\from{calculator.dtx}{calculus}} \def\tmpa{plain} \ifx\tmpa\fmtname\endgroup\expandafter\bye\fi \endgroup % % % Copyright (C) 2012 by Robert Fuster % % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.2 % 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.2 or later is part of all distributions of LaTeX % version 1999/12/01 or later. % % \fi % \CheckSum{3135} % \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} %% \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 \~} % % \iffalse %<*driver> \documentclass{ltxdoc} \ProvidesFile{calculator.dtx} [2012/06/10 v.1.0a documented calculator package] \GetFileInfo{calculator.dtx} \usepackage{amsmath} \usepackage[lmargin=1.75in,rmargin=1in]{geometry} \usepackage{fancyvrb} \def\fileversion{1.0a} \def\filedate{2012/06/10} \usepackage{calculus} \title{The \textsf{calculator} and \textsf{calculus} packages% \thanks{This document corresponds to \textsf{calculator} 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 \newcommand{\TBS}{\textbackslash} \newcommand{\Marg}[1]{\textnormal{\marg{#1}}} \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}}} \begin{document} \maketitle \DocInput{calculator.dtx} \PrintChanges \PrintIndex \end{document} % % % \fi % % \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. % \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} % % In addition, the \cs{LENGTHDIVIDE} command divides two lengths % and returns a number. % \item[\cs{LENGTHDIVIDE}\marg{length1}\marg{length2}\marg{\cs{cmd}}]% % \SpecialUsageIndex{\LENGTHDIVIDE}\mbox{} % \begin{exemple} % \LENGTHDIVIDE{1in}{1cm}{\sol} % One inch equals $\sol$ centimeters. % \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}. % \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. % % 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 od 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} % \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 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{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$ % % \SCALARPRODUCT(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{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} % \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} % % 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{} % % \section{Implementation (\textsf{calculator})} % \begin{macrocode} %<*calculator> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{calculator}[2012/06/10 v.1.0a] % \end{macrocode} % \subsection{Internal lengths and special nmbers} % \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@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@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{xpicture}{% Incompatible linear system}} \def\cctr@WarnIncTDLinSys{\PackageWarning{xpicture}{% Incompatible or indeterminate linear system\MessageBreak For 3x3 systems I can solve only determinate systems}} \def\cctr@WarnIndLinSys{\PackageWarning{xpicture}{% Indeterminate linear system.\MessageBreak I will choose one of the infinite solutions}} \def\cctr@WarnZeroLinSys{\PackageWarning{xpicture}{% 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)}} % \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} % \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 \COPY{#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}. % \begin{macrocode} \def\@@FRACTIONALPART#1.#2.#3)#4{\ifnum #2=11 \COPY{0}{#4} \else \COPY{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. % \begin{macrocode} \def\TRUNCATE{\@ifnextchar[\@@TRUNCATE\@TRUNCATE} \def\@TRUNCATE#1#2{\@@TRUNCATE[2]{#1}{#2}} \def\@@TRUNCATE[#1]#2#3{% \begingroup \INTEGERPART{#2}{\cctr@tempa} \ifdim \cctr@tempa\p@ = #2\p@ \expandafter\@@@TRUNCATE#2.00000)[#1]{#3} \else \expandafter\@@@TRUNCATE#200000.)[#1]{#3} \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. % \begin{macrocode} \def\ROUND{\@ifnextchar[\@@ROUND\@ROUND} \def\@ROUND#1#2{\@@ROUND[2]{#1}{#2}} \def\@@ROUND[#1]#2#3{% \begingroup \ifdim#2\p@<\z@ \MULTIPLY{-1}{#2}{\cctr@temp} \@@ROUND[#1]{\cctr@temp}{#3}\COPY{-#3}{#3} \else \@@TRUNCATE[#1]{#2}{\cctr@tempe} \SUBTRACT{#2}{\cctr@tempe}{\cctr@tempc} \POWER{10}{#1}{\cctr@tempb} \MULTIPLY{\cctr@tempb}{\cctr@tempc}{\cctr@tempc} \ifdim\cctr@tempc\p@<0.5\p@ \else \DIVIDE{1}{\cctr@tempb}{\cctr@tempb} \ADD{\cctr@tempe}{\cctr@tempb}{\cctr@tempe} \fi \@@TRUNCATE[#1]{\cctr@tempe}{#3} \fi \@OUTPUTSOL{#3}} % \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. % \begin{macrocode} \cctr@lengthb=5\p@% \cctr@lengtha=\cctr@epsilon% % \end{macrocode} % Successive iterations % \begin{macrocode} \@whilenum \cctr@lengthb>\cctr@lengtha \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} % \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} % \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} % \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{Implementation (\textsf{calculator})} % \begin{macrocode} %<*calculus> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{calculus} [2012/06/10 v.1.0a] % \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} % \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 %