From c5d14cb9174c3e6592b8972f459c0dd14dbc0927 Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 22 Jan 2025 21:50:31 -0800 Subject: [PATCH] FIR draft --- src/Advanced/Fast Inverse Root/main.tex | 84 + .../Fast Inverse Root/parts/0 logarithms.tex | 72 + .../Fast Inverse Root/parts/1 intro.tex | 44 + .../parts/2 multiplication.tex | 278 + .../Fast Inverse Root/parts/3 division.tex | 91 + .../Fast Inverse Root/parts/4 float.tex | 219 + .../Fast Inverse Root/parts/5 approximate.tex | 47 + .../Fast Inverse Root/parts/6 quake.tex | 71 + .../Fast Inverse Root/resources/rule.svg | 24144 ++++++++++++++++ src/Advanced/Fast Inverse Root/sliderule.sty | 534 + 10 files changed, 25584 insertions(+) create mode 100755 src/Advanced/Fast Inverse Root/main.tex create mode 100644 src/Advanced/Fast Inverse Root/parts/0 logarithms.tex create mode 100644 src/Advanced/Fast Inverse Root/parts/1 intro.tex create mode 100644 src/Advanced/Fast Inverse Root/parts/2 multiplication.tex create mode 100644 src/Advanced/Fast Inverse Root/parts/3 division.tex create mode 100644 src/Advanced/Fast Inverse Root/parts/4 float.tex create mode 100644 src/Advanced/Fast Inverse Root/parts/5 approximate.tex create mode 100644 src/Advanced/Fast Inverse Root/parts/6 quake.tex create mode 100755 src/Advanced/Fast Inverse Root/resources/rule.svg create mode 100755 src/Advanced/Fast Inverse Root/sliderule.sty diff --git a/src/Advanced/Fast Inverse Root/main.tex b/src/Advanced/Fast Inverse Root/main.tex new file mode 100755 index 0000000..4a1584c --- /dev/null +++ b/src/Advanced/Fast Inverse Root/main.tex @@ -0,0 +1,84 @@ +% use [nosolutions] flag to hide solutions. +% use [solutions] flag to show solutions. +\documentclass[ + singlenumbering, + solutions +]{../../resources/ormc_handout} +\usepackage{../../resources/macros} + + +\usepackage{pdfpages} +\usepackage{sliderule} +\usepackage{changepage} +\usepackage{listings} + +% Args: +% x, top scale y, label +\newcommand{\slideruleind}[3]{ + \draw[ + line width=1mm, + draw=black, + opacity=0.3, + text opacity=1 + ] + ({#1}, {#2 + 1}) + -- + ({#1}, {#2 - 1.1}) + node [below] {#3}; +} + + +\uptitlel{Advanced 2} +\uptitler{\smallurl{}} +\title{Fast Inverse Square Root} +\subtitle{Prepared by Mark on \today} + +\begin{document} + + \maketitle + + + \begin{center} + \begin{minipage}{6cm} + Dad says that anyone who can't use + a slide rule is a cultural illiterate + and should not be allowed to vote. + + \vspace{1ex} + + \textit{Have Space Suit --- Will Travel, 1958} + \end{minipage} + \end{center} + \hfill + + %\input{parts/0 logarithms.tex} + %\input{parts/1 intro.tex} + %\input{parts/2 multiplication.tex} + %\input{parts/3 division.tex} + \pagebreak + \input{parts/4 float.tex} + \input{parts/5 approximate.tex} + \input{parts/6 quake.tex} + + % Make sure the slide rule is on an odd page, + % so that double-sided prints won't require + % students to tear off problems. + \checkoddpage + \ifoddpage\else + \vspace*{\fill} + \begin{center} + { + \Large + \textbf{This page unintentionally left blank.} + } + \end{center} + \vspace{\fill} + \pagebreak + \fi + + %\includepdf[ + % pages=1, + % fitpaper=true + %]{resources/rule.pdf} + +\end{document} \ No newline at end of file diff --git a/src/Advanced/Fast Inverse Root/parts/0 logarithms.tex b/src/Advanced/Fast Inverse Root/parts/0 logarithms.tex new file mode 100644 index 0000000..17e43ac --- /dev/null +++ b/src/Advanced/Fast Inverse Root/parts/0 logarithms.tex @@ -0,0 +1,72 @@ +\section{Logarithms} + +\definition{} +The \textit{logarithm} is the inverse of the exponent. That is, if $b^p = c$, then $\log_b{c} = p$. \par +In other words, $\log_b{c}$ asks the question ``what power do I need to raise $b$ to to get $c$?'' + +\vspace{2mm} + +In both $b^p$ and $\log_b{c}$, the number $b$ is called the \textit{base}. + + +\problem{} +Evaluate the following by hand: + +\begin{enumerate} + \item $\log_{10}{(1000)}$ + \vfill + \item $\log_2{(64)}$ + \vfill + \item $\log_2{(\frac{1}{4})}$ + \vfill + \item $\log_x{(x)}$ for any $x$ + \vfill + \item $log_x{(1)}$ for any $x$ + \vfill +\end{enumerate} + +\pagebreak + + + +\problem{} +Prove the following identities: + +\begin{enumerate}[itemsep=2mm] + \item $\log_b{(b^x)} = x$ + \item $b^{\log_b{x}} = x$ + \item $\log_b{(xy)} = \log_b{(x)} + \log_b{(y)}$ + \item $\log_b{(\frac{x}{y})} = \log_b{(x)} - \log_b{(y)}$ + \item $\log_b{(x^y)} = y \log_b{(x)}$ +\end{enumerate} + +\vfill + +\begin{instructornote} + A good intro to the following sections is the linear slide rule: + + \begin{center} + \begin{tikzpicture}[scale=1] + \linearscale{2}{1}{} + \linearscale{0}{0}{} + + \slideruleind + {5} + {1} + {2 + 3 = 5} + \end{tikzpicture} + \end{center} + + Take two linear rulers, offset one, and you add. \par + If you do the same with a log scale, you multiply! + + \vspace{2mm} + + Note that the slide rules above start at 0. + + \linehack{} + + After assembling the paper slide rule, you can make a visor with some transparent tape. Wrap a strip around the slide rule, sticky side out, and stick it to itself to form a ring. Cover the sticky side with another layer of tape, and trim the edges to make them straight. Use the edge of the visor to read your slide rule! +\end{instructornote} + +\pagebreak \ No newline at end of file diff --git a/src/Advanced/Fast Inverse Root/parts/1 intro.tex b/src/Advanced/Fast Inverse Root/parts/1 intro.tex new file mode 100644 index 0000000..52e2d43 --- /dev/null +++ b/src/Advanced/Fast Inverse Root/parts/1 intro.tex @@ -0,0 +1,44 @@ +\section{Slide Rules} + +Mathematicians, physicists, and engineers needed to quickly solve complex equations even before computers were invented. + +\vspace{2mm} + +The \textit{slide rule} is an instrument that uses the logarithm to solve this problem. \par +Before you continue, tear off the last page of this handout and assemble your slide rule. + +\vspace{2mm} + +There are four scales on your slide rule, each labeled with a letter on the left side: + +\def\sliderulewidth{13} +\begin{center} +\begin{tikzpicture}[scale=1] + \tscale{0}{9}{T} + \kscale{0}{8}{K} + \abscale{0}{7}{A} + + \abscale{0}{5.5}{B} + \ciscale{0}{4.5}{CI} + \cdscale{0}{3.5}{C} + + \cdscale{0}{2}{D} + \lscale{0}{1}{L} + \sscale{0}{0}{S} +\end{tikzpicture} +\end{center} + +Each scale's ``generating function'' is on the right: +\begin{itemize} + \item T: $\tan$ + \item K: $x^3$ + \item A,B: $x^2$ + \item CI: $\frac{1}{x}$ + \item C, D: $x$ + \item L: $\log_{10}(x)$ + \item S: $\sin$ +\end{itemize} + +Once you understand the layout of your slide rule, move on to the next page. + +\pagebreak diff --git a/src/Advanced/Fast Inverse Root/parts/2 multiplication.tex b/src/Advanced/Fast Inverse Root/parts/2 multiplication.tex new file mode 100644 index 0000000..5a1a9a2 --- /dev/null +++ b/src/Advanced/Fast Inverse Root/parts/2 multiplication.tex @@ -0,0 +1,278 @@ +\section{Multiplication} + +We'll use the C and D scales of your slide rule to multiply. \par +Say we want to multiply $2 \times 3$. First, move the \textit{left-hand index} +of the C scale over the smaller number, $2$: + +\def\sliderulewidth{10} +\begin{center} +\begin{tikzpicture}[scale=1] + \cdscale{\cdscalefn(2)}{1}{C} + \cdscale{0}{0}{D} +\end{tikzpicture} +\end{center} + +Then we'll find the second number, $3$ on the C scale, and read the D scale under it: + +\begin{center} +\begin{tikzpicture}[scale=1] + \cdscale{\cdscalefn(2)}{1}{C} + \cdscale{0}{0}{D} + + \slideruleind + {\cdscalefn(6)} + {1} + {6} + +\end{tikzpicture} +\end{center} + +Of course, our answer is 6. + +\problem{} +What is $1.15 \times 2.1$? \par +Use your slide rule. + +\begin{solution} + \begin{center} + \begin{tikzpicture}[scale=1] + \cdscale{\cdscalefn(1.15)}{1}{C} + \cdscale{0}{0}{D} + + \slideruleind + {\cdscalefn(1.15)} + {1} + {1.15} + + \slideruleind + {\cdscalefn(1.15) + \cdscalefn(2.1)} + {1} + {2.415} + + \end{tikzpicture} + \end{center} +\end{solution} + +\vfill + +Note that your answer isn't exact. $1.15 \times 2.1 = 2.415$, but an answer accurate within +two decimal places is close enough for most practical applications. + +\pagebreak + + + + +Look at your C and D scales again. They contain every number between 1 and 10, but no more than that. +What should we do if we want to calculate $32 \times 210$? \par + +\problem{} +Using your slide rule, calculate $32 \times 210$. + + +\begin{solution} + \begin{center} + \begin{tikzpicture}[scale=1] + \cdscale{\cdscalefn(2.1)}{1}{C} + \cdscale{0}{0}{D} + + \slideruleind + {\cdscalefn(2.1)} + {1} + {2.1} + + \slideruleind + {\cdscalefn(2.1) + \cdscalefn(3.2)} + {1} + {6.72} + + \end{tikzpicture} + \end{center} + + Placing the decimal point correctly is your job. \par + $10^1 \times 10^2 = 10^3$, so our final answer is $6.72 \times 10^3 = 672$. +\end{solution} + +\vfill + +\problem{} +Compute the following: +\begin{enumerate} + \item $1.44 \times 52$ + \item $0.38 \times 1.24$ + \item $\pi \times 2.35$ +\end{enumerate} + +\begin{solution} + \begin{enumerate} + \item $1.44 \times 52 = 74.88$ + \item $0.38 \times 1.24 = 0.4712$ + \item $\pi \times 2.35 = 7.382$ + \end{enumerate} +\end{solution} + +\vfill + +\problem{} +Note that the numbers on your C and D scales are logarithmically spaced. + +\def\sliderulewidth{13} +\begin{center} +\begin{tikzpicture}[scale=1] + \cdscale{0}{1}{C} + \cdscale{0}{0}{D} +\end{tikzpicture} +\end{center} + +Why does our multiplication procedure work? + +\vfill +\pagebreak + +Now we want to compute $7.2 \times 5.5$: + +\def\sliderulewidth{10} +\begin{center} +\begin{tikzpicture}[scale=0.8] + \cdscale{\cdscalefn(5.5)}{1}{C} + \cdscale{0}{0}{D} + + \slideruleind + {\cdscalefn(5.5)} + {1} + {5.5} + + \slideruleind + {\cdscalefn(5.5) + \cdscalefn(7.2)} + {1} + {???} + +\end{tikzpicture} +\end{center} + +No matter what order we go in, the answer ends up off the scale. There must be another way. + +\vspace{2mm} + +Look at the far right of your C scale. There's an arrow pointing to the $10$ tick, labeled \textit{right-hand index}. +Move it over the \textit{larger} number, $7.2$: + +\begin{center} +\begin{tikzpicture}[scale=1] + \cdscale{\cdscalefn(7.2) - \cdscalefn(10)}{1}{C} + \cdscale{0}{0}{D} + + \slideruleind + {\cdscalefn(7.2)} + {1} + {7.2} + +\end{tikzpicture} +\end{center} + +Now find the smaller number, $5.5$, on the C scale, and read the D scale under it: + +\begin{center} +\begin{tikzpicture}[scale=1] + \cdscale{\cdscalefn(7.2) - \cdscalefn(10)}{1}{C} + \cdscale{0}{0}{D} + + + \slideruleind + {\cdscalefn(7.2)} + {1} + {7.2} + + \slideruleind + {\cdscalefn(3.96)} + {1} + {3.96} + +\end{tikzpicture} +\end{center} + +Our answer should be about $7 \times 5 = 35$, so let's move the decimal point: $5.5 \times 7.2 = 39.6$. +We can do this by hand to verify our answer. + +\vspace{2mm} + +\problem{} +Why does this work? + +\begin{solution} + Consider the following picture, where we have two D scales next to each other: + + \begin{center} + \begin{tikzpicture}[scale=0.7] + \cdscale{\cdscalefn(7.2) - \cdscalefn(10)}{1}{C} + \cdscale{0}{0}{} + \cdscale{-10}{0}{} + + \draw[ + draw=black, + ] + (0, 0) + -- + (0, -0.3) + node [below] {D}; + + \draw[ + draw=black, + ] + (-10, 0) + -- + (-10, -0.3) + node [below] {D}; + + \slideruleind + {-10 + \cdscalefn(7.2)} + {1} + {7.2} + + \slideruleind + {\cdscalefn(7.2)} + {1} + {7.2} + + \slideruleind + {\cdscalefn(3.96)} + {1} + {3.96} + + \end{tikzpicture} + \end{center} + + \vspace{2mm} + + The second D scale has been moved to the right by $(\log{10})$, so every value on it is $(\log{10})$ + smaller than it should be. + + \vspace{2mm} + + \vspace{2mm} + In other words, the answer we get from reverse multiplication is $\log{a} + \log{b} - \log{10}$. \par + This reduces to $\log{(\frac{a \times b}{10})}$, and explains the misplaced decimal point in $7.2 \times 5.5$. +\end{solution} + + +\vfill +\pagebreak + +\problem{} +Compute the following using your slide rule: +\begin{enumerate} + \item $9 \times 8$ + \item $15 \times 35$ + \item $42.1 \times 7.65$ +\end{enumerate} + +\begin{solution} + \begin{enumerate} + \item $9 \times 8 = 72$ + \item $15 \times 35 = 525$ + \item $42.1 \times 7.65 = 322.065$ + \end{enumerate} +\end{solution} + +\vfill +\pagebreak \ No newline at end of file diff --git a/src/Advanced/Fast Inverse Root/parts/3 division.tex b/src/Advanced/Fast Inverse Root/parts/3 division.tex new file mode 100644 index 0000000..5631c0b --- /dev/null +++ b/src/Advanced/Fast Inverse Root/parts/3 division.tex @@ -0,0 +1,91 @@ +\section{Division} + +Now that you can multiply, division should be easy. All you need to do is work backwards. \\ +Let's look at our first example again: $3 \times 2 = 6$. + +\medskip + +We can easily see that $6 \div 3 = 2$ + +\begin{center} +\begin{tikzpicture}[scale=1] + \cdscale{\cdscalefn(2)}{1}{C} + \cdscale{0}{0}{D} + + \slideruleind + {\cdscalefn(6)} + {1} + {Align here} + + \slideruleind + {\cdscalefn(2)} + {1} + {2} +\end{tikzpicture} +\end{center} + +and that $6 \div 2 = 3$: +\begin{center} +\begin{tikzpicture}[scale=1] + \cdscale{\cdscalefn(3)}{-3}{C} + \cdscale{0}{-4}{D} + + + \slideruleind + {\cdscalefn(6)} + {-3} + {Align here} + + \slideruleind + {\cdscalefn(3)} + {-3} + {3} + +\end{tikzpicture} +\end{center} + +If your left-hand index is off the scale, read the right-hand one. \\ +Consider $42.25 \div 6.5 = 6.5$: + +\begin{center} +\begin{tikzpicture}[scale=1] + \cdscale{\cdscalefn(6.5) - \cdscalefn(10)}{1}{C} + \cdscale{0}{0}{D} + + + \slideruleind + {\cdscalefn(4.225)} + {1} + {Align here} + + \slideruleind + {\cdscalefn(6.5)} + {1} + {6.5} + +\end{tikzpicture} +\end{center} + +Place your decimal points carefully. + +\vfill + +\problem{} +Compute the following using your slide rule. \par + +\begin{enumerate} + \item $135 \div 15$ + \item $68.2 \div 0.575$ + \item $(118 \times 0.51) \div 6.6$ +\end{enumerate} + +\begin{solution} + \begin{enumerate} + \item $135 \div 15 = 9$ + \item $68.2 \div 0.575 = 118.609$ + \item $(118 \times 0.51) \div 6.6 = 9.118$ + \end{enumerate} +\end{solution} + +\vfill +\pagebreak \ No newline at end of file diff --git a/src/Advanced/Fast Inverse Root/parts/4 float.tex b/src/Advanced/Fast Inverse Root/parts/4 float.tex new file mode 100644 index 0000000..515c1b3 --- /dev/null +++ b/src/Advanced/Fast Inverse Root/parts/4 float.tex @@ -0,0 +1,219 @@ + +\section{\texttt{int}s and \texttt{float}s} + +\definition{} +A \textit{signed 32-bit integer} (equivalently, a \texttt{long int}) consists of thirty-two binary digits, \par +and is used represent a subset of the integers. + +\vspace{2mm} + +The first bit of a \texttt{long} tells us its sign: +\begin{itemize} + \item if the first bit of a \texttt{long} is \texttt{1}, it represents a negative number; + \item if the first bit is \texttt{0}, it represents a positive number. +\end{itemize} +We do not need negative numbers today, so we will assume that the first bit is always zero. \par +\note{If you'd like to know how negative integers are written, look up \say{two's complement} after class.} + +\vspace{2mm} + +We'll denote binary strings with the prefix \texttt{0b}. \par +Underscores are added between every eight digits for readability, and have no meaning. + +\vspace{2mm} + + +The value of a positive signed \texttt{long} is simply the value of its binary digits. \par +For example: +\begin{itemize} + \item $\texttt{0b00000000\_00000000\_00000000\_00000000} = 0$ + \item $\texttt{0b00000000\_00000000\_00000000\_00000011} = 3$ + \item $\texttt{0b00000000\_00000000\_00000000\_00100000} = 32$ + \item $\texttt{0b00000000\_00000000\_00000000\_10000010} = 130$ +\end{itemize} + +Remember---we only need positive integers today. Assume the \say{sign} bit is always \texttt{0}. + +\problem{} +What is the largest number that can be represented with a \texttt{long}? + +\begin{solution} + $\texttt{0b01111111\_11111111\_11111111\_11111111} = 2^{31}$ +\end{solution} + +\vfill + + + +\problem{} +What is the smallest possible number that can be represented with a \texttt{long}? \par +\hint{ + You do not need to know \textit{how} negative numbers are represented. \par + Assume that we do not skip any integers, and don't forget about zero. +} + +\begin{solution} + There are $2^{64}$ possible 32-bit patterns, + of which 1 represents zero and $2^{31}$ represent positive numbers. + + \vspace{2mm} + + We therefore have access to $2^{64} - 1 - 2^{31}$ negative numbers, + giving us a minimum representable value of $-2^{31} + 1$. +\end{solution} + +\problem{} +What is the value of the following longs? +\begin{itemize} + \item \texttt{0b00000000\_00000000\_00000101\_00111001} + \item \texttt{0b00000000\_00000000\_00000001\_00101100} + \item \texttt{0b00000000\_00000000\_00000100\_10110000} +\end{itemize} +\hint{The third conversion is easy---look carefully at the second.} + +\begin{solution} + \begin{itemize} + \item $\texttt{0b00000000\_00000000\_00000101\_00111001} = 1337$ + \item $\texttt{0b00000000\_00000000\_00000001\_00101100} = 300$ + \item $\texttt{0b00000000\_00000000\_00000010\_01011000} = 1200$ + \end{itemize} + + Notice that the third long is the second shifted left twice (i.e, multiplied by 4) +\end{solution} + +\vfill +\pagebreak + + +\definition{} +A \textit{signed 32-bit floating-point decimal} (equivalently, a \textit{float}) +consists of 32 binary digits, and is used to represent a subset of the real numbers. +These 32 bits are interpreted as follows: + +\begin{center} + \begin{tikzpicture} + + + \node[anchor=south west] at (0, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (0.25, 0) {\texttt{\texttt{b}}}; + \node[anchor=south west] at (0.50, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (0.75, 0) {\texttt{\texttt{\_}}}; + + \node[anchor=south west] at (1.00, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (1.25, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (1.50, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (1.75, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (2.00, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (2.25, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (2.50, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (2.75, 0) {\texttt{\texttt{0}}}; + + \node[anchor=south west] at (3.00, 0) {\texttt{\texttt{\_}}}; + \node[anchor=south west] at (3.25, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (3.50, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (3.75, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (4.00, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (4.25, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (4.50, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (4.75, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (5.00, 0) {\texttt{\texttt{\_}}}; + + \node[anchor=south west] at (5.25, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (5.50, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (5.75, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (6.00, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (6.25, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (6.50, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (6.75, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (7.00, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (7.25, 0) {\texttt{\texttt{\_}}}; + + \node[anchor=south west] at (7.50, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (7.75, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (8.00, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (8.25, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (8.50, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (8.75, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (9.00, 0) {\texttt{\texttt{0}}}; + \node[anchor=south west] at (9.25, 0) {\texttt{\texttt{0}}}; + + + \draw (0.50, 0) -- (0.95, 0) node [midway, below=1mm] {sign}; + \draw (1.05, 0) -- (3.15, 0) node [midway, below=1mm] {exponent}; + \draw (3.30, 0) -- (9.70, 0) node [midway, below=1mm] {fraction}; + \end{tikzpicture} +\end{center} + +In other words: +\begin{itemize}[itemsep = 1mm] + \item The first bit denotes the sign of the float's value. We'll label it $s$. \par + If $s = 1$, this float is negative; if $s = 0$, it is positive. + + \item The next 8 bits represent the \textit{exponent} of this float. \par + We'll call the value of these eight bits $E$. \par + Naturally, $0 \leq E \leq 255$ + + \item The remaining 23 bits represent the \textit{fraction} of this float. \par + These 23 bits are interpreted as the fractional part of a binary decimal. \par + For example, the bits \texttt{0b1010000\_00000000\_00000000} represents $0.5 + 0.125 = 0.625$. +\end{itemize} + + +\vspace{2mm} + +The final value of a float with sign $s$, exponent $E$, and fraction $F$ is +\begin{equation*} + (-1)^s ~\times~ 2^{E - 127} ~\times~ \left(1 + \frac{F}{2^{23}}\right) +\end{equation*} + + +Notice that this is very similar to decimal scientific notation, which is written as +\begin{equation*} + (\pm 1) ~\times~ 10^{e} ~\times~ (f) +\end{equation*} + +\vfill +\pagebreak + +\problem{} +What is the value of \texttt{0b01000001\_10101000\_00000000\_00000000} if it is interpreted as a float? \par +\hint{$21 \div 16 = 1.3125$} + +\begin{solution} + This is 21: + \begin{align*} + &=~ 2^{131} \times \biggl(1 + \frac{2^{21} + 2^{19}}{2^{23}}\biggr) \\ + &=~ 2^{4} \times (1 + 0.25 + 0.0625) \\ + &=~ 16 \times (1.3125) \\ + &=~ 21 + \end{align*} +\end{solution} + +\vfill + +\problem{} +Encode $12.5$ as a float. \par +\hint{$12.5 \div 8 = 1.5625$} + +\vspace{2mm} + +What is the value of the resulting 32 bits if they are interpreted as a long? \par +\hint{A sum of powers of two is fine.} + +\begin{solution} + \begin{align*} + 12.5 + &=~ 8 \times 1.5625 \\ + &=~ 2^{3} \times \biggl(1 + (0.5 + 0.0625)\biggr) \\ + &=~ 2^{130} \times \biggl(1 + \frac{2^{22} + 2^{19}}{2^{23}}\biggr) + \end{align*} + + \linehack{} + + This is \texttt{0b01000001\_01001000\_00000000\_00000000}, \par + which is $2^{30} + 2^{24} + 2^{22} + 2^{19} = 11,095,237,632$ +\end{solution} + + +\vfill +\pagebreak \ No newline at end of file diff --git a/src/Advanced/Fast Inverse Root/parts/5 approximate.tex b/src/Advanced/Fast Inverse Root/parts/5 approximate.tex new file mode 100644 index 0000000..e3678dd --- /dev/null +++ b/src/Advanced/Fast Inverse Root/parts/5 approximate.tex @@ -0,0 +1,47 @@ +\section{Approximation} + +\definition{} +Say we have a bit string $x$. \par +Let $x_f$ denote the value of $x$ interpreted as a float, \par +and let $x_i$ denote the value of $x$ interpreted as an integer. + +\problem{} +Let $x = \texttt{0b01000001\_01001000\_00000000\_00000000}$. \ +What are $x_f$ and $x_i$? + +\begin{solution} + $x_f = 12.5$ \par + \vspace{2mm} + $x_i = 2^{30} + 2^{24} + 2^{22} + 2^{19} = 11,095,237,632$ +\end{solution} + + +\generic{Observation:} +For small values of $a$, $\log_2(1 + a)$ is approximately equal to $a$. \par +Note that this equality is exact for $a = 0$ and $a = 1$, since $\log_2(1) = 0$ and $\log_2(2) = 1$. + +\vspace{2mm} + +We'll add a \say{correction term} $\varepsilon$ to this approximation, so that $\log_2(1 + a) \approx a + \varepsilon$. + +TODO: why? Graphs. + +\problem{} +Use the fact that $\log_2(1 + a) \approx a + \varepsilon$ to approximate $\log_2(x_f)$ in terms of $x_i$, \par + + +\begin{solution} + Let $E$ and $F$ be the exponent and float bits of $x_f$. \par + We then have: + \begin{align*} + \log_2(x_f) + &=~ \log_2 \left( 2^{E-127} \times \left(1 + \frac{F}{2^{23}}\right) \right) \\ + &=~ E-127 + \log_2\left(1 + \frac{F}{2^{23}}\right) \\ + &\approx~ E-127 + \frac{F}{2^{23}} + \varepsilon \\ + &=~ \frac{1}{2^{23}}(2^{23}E + F) - 127 + \varepsilon \\ + &=~ \frac{1}{2^{23}}(x_i) - 127 + \varepsilon + \end{align*} +\end{solution} + +\vfill +\pagebreak \ No newline at end of file diff --git a/src/Advanced/Fast Inverse Root/parts/6 quake.tex b/src/Advanced/Fast Inverse Root/parts/6 quake.tex new file mode 100644 index 0000000..7626ad1 --- /dev/null +++ b/src/Advanced/Fast Inverse Root/parts/6 quake.tex @@ -0,0 +1,71 @@ +\section{The Fast Inverse Square Root} + +The following code is present in \textit{Quake III Arena} (1999): + +\lstset{ + breaklines=false, + numbersep=5pt, + xrightmargin=0in +} + +\begin{lstlisting}[language=C] +float Q_rsqrt( float number ) { + long i = * ( long * ) &number; + i = 0x5f3759df - ( i >> 1 ); + return * ( float * ) &i; +} +\end{lstlisting} + +It defines a method \texttt{Q\_rsqrt} that consumes a float named \texttt{number} and quickly approximates its inverse +square root (in other words, \texttt{Q\_rsqrt} computes $1/\sqrt{\texttt{number}}$). + +\vspace{8mm} + +If we rewrite this using the notation we're familiar with, we get the following: + +\begin{equation*} + \frac{1}{\sqrt{n_f}} \approx \kappa - (n_i \div 2) +\end{equation*} +Where $\kappa$ is the magic constant $6240089$ (which is \texttt{0x5f3759df} in hexadecimal) + +\problem{} +Find the exact value of $\kappa$ in terms of $\varepsilon$. \par +\hint{Remember that $\varepsilon$ is the correction term in the approximation $\log_2(1 + a) = a + \varepsilon$.} + +\problem{} +Rewrite $\log_2(1 / \sqrt{x})$ in terms of $\log_2{x}$. + +\begin{solution} + Say $g_f = \frac{1}{\sqrt{n_f}}$---that is, $g_f$ is the value we want to compute. \par + Then: + + \begin{align*} + \log_2(g_f) + &=\log_2(\frac{1}{\sqrt{n_f}}) \\ + &=\frac{-1}{2}\log_2(n_f) \\ + &=\frac{-1}{2}\left( \frac{n_i}{2^{23}} + \varepsilon - 127 \right) + \end{align*} + + But we also know that + + \begin{align*} + \log_2(g_f) + &=\frac{g_i}{2^{23}} + \varepsilon - 127 + \end{align*} + + So, + + \begin{align*} + \frac{g_i}{2^{23}} + \varepsilon - 127 + &=\frac{-1}{2}\left( \frac{n_i}{2^{23}} + \varepsilon - 127 \right) \\ + \frac{g_i}{2^{23}} + &=\frac{-1}{2}\left( \frac{n_i}{2^{23}} \right) + \frac{3}{2}(\varepsilon - 127) \\ + g_i + &=\frac{-1}{2}\left(n_i \right) + 2^{23}\frac{3}{2}(\varepsilon - 127) \\ + &=2^{23}\frac{3}{2}(\varepsilon - 127) - \frac{n_i}{2} + \end{align*} + + thus, $\kappa = 2^{23}\frac{3}{2}(\varepsilon - 127)$. +\end{solution} + +\pagebreak \ No newline at end of file diff --git a/src/Advanced/Fast Inverse Root/resources/rule.svg b/src/Advanced/Fast Inverse Root/resources/rule.svg new file mode 100755 index 0000000..9506a6d --- /dev/null +++ b/src/Advanced/Fast Inverse Root/resources/rule.svg @@ -0,0 +1,24144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Advanced/Fast Inverse Root/sliderule.sty b/src/Advanced/Fast Inverse Root/sliderule.sty new file mode 100755 index 0000000..13e3995 --- /dev/null +++ b/src/Advanced/Fast Inverse Root/sliderule.sty @@ -0,0 +1,534 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{sliderule}[2022/08/22 Slide rule tools] + +\RequirePackage{tikz} +\RequirePackage{ifthen} + + +% Scale functions: +% See https://sliderulemuseum.com/SR_Scales.htm +% +% l: length of the rule +% n: the number on the rule +% +% A/B: (l/2) * log(n) +% C/D: l / log(n) +% CI: abs(l * log(10 / n) - l) +% K: (l/3) * log(n) +% +% L: n * l +% T: l * log(10 * tan(n)) +% S: l * log(10 * sin(n)) + +\def\sliderulewidth{10} + +\def\abscalefn(#1){(\sliderulewidth/2) * log10(#1)} +\def\cdscalefn(#1){(\sliderulewidth * log10(#1))} +\def\ciscalefn(#1){(\sliderulewidth - \cdscalefn(#1))} +\def\kscalefn(#1){(\sliderulewidth/3) * log10(#1)} +\def\lscalefn(#1){(\sliderulewidth * #1)} +\def\tscalefn(#1){(\sliderulewidth * log10(10 * tan(#1)))} +\def\sscalefn(#1){(\sliderulewidth * log10(10 * sin(#1)))} + + +% Arguments: +% Label +% x of start +% y of start +\newcommand{\linearscale}[3]{ + \draw[black] ({#1}, #2) -- ({#1 + \sliderulewidth}, #2); + \draw[black] ({#1}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.9); + \draw[black] ({#1}, #2 + 0.9) -- ({#1}, #2 + 0.7); + \draw[black] ({#1 + \sliderulewidth}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.7); + + \draw ({#1 - 0.1}, #2 + 0.5) node[left] {#3}; + + % Numbers and marks + \foreach \i in {0,..., 10}{ + \draw[black] + ({#1 + (\sliderulewidth / 10) * \i}, #2) -- + ({#1 + (\sliderulewidth / 10) * \i}, #2 + 0.3) + node[above] {\i}; + } + + % Submarks + \foreach \n in {0, ..., 9} { + \foreach \i in {1,..., 9} { + \ifthenelse{\i=5}{ + \draw[black] + ({#1 + (\sliderulewidth / 10) * (\n + \i / 10)}, #2) -- + ({#1 + (\sliderulewidth / 10) * (\n + \i / 10)}, #2 + 0.2); + } { + \draw[black] + ({#1 + (\sliderulewidth / 10) * (\n + \i / 10)}, #2) -- + ({#1 + (\sliderulewidth / 10) * (\n + \i / 10)}, #2 + 0.1); + } + } + } +} + + +% Arguments: +% Label +% x of start +% y of start +\newcommand{\abscale}[3]{ + \draw[black] ({#1}, #2) -- ({#1 + \sliderulewidth}, #2); + \draw[black] ({#1}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.9); + \draw[black] ({#1}, #2 + 0.9) -- ({#1}, #2 + 0.7); + \draw[black] ({#1 + \sliderulewidth}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.7); + + + \draw ({#1 - 0.1}, #2 + 0.5) node[left] {#3}; + + % Numbers and marks 1 - 9 + \foreach \i in {1,..., 9}{ + \draw[black] + ({#1 + \abscalefn(\i)}, #2) -- + ({#1 + \abscalefn(\i)}, #2 + 0.3) + node[above] {\i}; + } + % Numbers and marks 10 - 100 + \foreach \i in {1,..., 10}{ + \draw[black] + ({#1 + \abscalefn(10 * \i)}, #2) -- + ({#1 + \abscalefn(10 * \i)}, #2 + 0.3) + node[above] {\ifthenelse{\i=10}{1}{\i}}; + } + + % Submarks 1 - 9 + \foreach \n in {1, ..., 9} { + \ifthenelse{\n<5}{ + \foreach \i in {1,..., 9} + } { + \foreach \i in {2,4,6,8} + } + { + \ifthenelse{\i=5}{ + \draw[black] + ({#1 + \abscalefn(\n + \i / 10)}, #2) -- + ({#1 + \abscalefn(\n + \i / 10)}, #2 + 0.2); + } { + \draw[black] + ({#1 + \abscalefn(\n + \i / 10)}, #2) -- + ({#1 + \abscalefn(\n + \i / 10)}, #2 + 0.1); + } + } + } + + % Submarks 10 - 100 + \foreach \n in {10,20,...,90} { + \ifthenelse{\n<50}{ + \foreach \i in {1,..., 9} + } { + \foreach \i in {2,4,6,8} + } + { + \ifthenelse{\i=5}{ + \draw[black] + ({#1 + \abscalefn(\n + \i)}, #2) -- + ({#1 + \abscalefn(\n + \i)}, #2 + 0.2); + } { + \draw[black] + ({#1 + \abscalefn(\n + \i)}, #2) -- + ({#1 + \abscalefn(\n + \i)}, #2 + 0.1); + } + } + } +} + +\newcommand{\cdscale}[3]{ + \draw[black] ({#1}, #2) -- ({#1 + \sliderulewidth}, #2); + \draw[black] ({#1}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.9); + \draw[black] ({#1}, #2 + 0.9) -- ({#1}, #2 + 0.7); + \draw[black] ({#1 + \sliderulewidth}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.7); + + + \draw ({#1 - 0.1}, #2 + 0.5) node[left] {#3}; + + % Numbers and marks 1 - 10 + \foreach \i in {1,..., 10}{ + \draw[black] + ({#1 + \cdscalefn(\i)}, #2) -- + ({#1 + \cdscalefn(\i)}, #2 + 0.3) + node[above] {\ifthenelse{\i=10}{1}{\i}}; + } + + % Submarks 1 - 9 + \foreach \n in {1, ..., 9} { + \ifthenelse{\n<3}{ + \foreach \i in {5,10,...,95} + } { + \foreach \i in {10,20,...,90} + } + { + \ifthenelse{\i=50}{ + \draw[black] + ({#1 + \cdscalefn(\n + \i / 100)}, #2) -- + ({#1 + \cdscalefn(\n + \i / 100)}, #2 + 0.2); + \ifthenelse{\n=1}{ + \draw + ({#1 + \cdscalefn(\n + \i / 100)}, #2 + 0.2) + node [above] {1.5}; + }{} + } { + \ifthenelse{ + \i=10 \OR \i=20 \OR \i=30 \OR \i=40 \OR + \i=60 \OR \i=70 \OR \i=80 \OR \i=90 + }{ + \draw[black] + ({#1 + \cdscalefn(\n + \i / 100)}, #2) -- + ({#1 + \cdscalefn(\n + \i / 100)}, #2 + 0.15); + } { + \draw[black] + ({#1 + \cdscalefn(\n + \i / 100)}, #2) -- + ({#1 + \cdscalefn(\n + \i / 100)}, #2 + 0.1); + } + } + } + } +} + +\newcommand{\ciscale}[3]{ + \draw[black] ({#1}, #2) -- ({#1 + \sliderulewidth}, #2); + \draw[black] ({#1}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.9); + \draw[black] ({#1}, #2 + 0.9) -- ({#1}, #2 + 0.7); + \draw[black] ({#1 + \sliderulewidth}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.7); + + + \draw ({#1 - 0.1}, #2 + 0.5) node[left] {#3}; + + % Numbers and marks + \foreach \i in {1,...,10}{ + \draw[black] + ({#1 + \ciscalefn(\i)}, #2) -- + ({#1 + \ciscalefn(\i)}, #2 + 0.3) + node[above] {\ifthenelse{\i=10}{1}{\ifthenelse{\i=0}{0}{.\i}}}; + } + + % Submarks 1 - 9 + \foreach \n in {1, ..., 9} { + \ifthenelse{\n<3}{ + \foreach \i in {5,10,...,95} + } { + \foreach \i in {10,20,...,90} + } + { + \ifthenelse{\i=50}{ + \draw[black] + ({#1 + \ciscalefn(\n + \i / 100)}, #2) -- + ({#1 + \ciscalefn(\n + \i / 100)}, #2 + 0.2); + \ifthenelse{\n=1}{ + \draw + ({#1 + \ciscalefn(\n + \i / 100)}, #2 + 0.2) + node [above] {1.5}; + }{} + } { + \ifthenelse{ + \i=10 \OR \i=20 \OR \i=30 \OR \i=40 \OR + \i=60 \OR \i=70 \OR \i=80 \OR \i=90 + }{ + \draw[black] + ({#1 + \ciscalefn(\n + \i / 100)}, #2) -- + ({#1 + \ciscalefn(\n + \i / 100)}, #2 + 0.15); + } { + \draw[black] + ({#1 + \ciscalefn(\n + \i / 100)}, #2) -- + ({#1 + \ciscalefn(\n + \i / 100)}, #2 + 0.1); + } + } + } + } +} + +\newcommand{\kscale}[3]{ + \draw[black] ({#1}, #2) -- ({#1 + \sliderulewidth}, #2); + \draw[black] ({#1}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.9); + \draw[black] ({#1}, #2 + 0.9) -- ({#1}, #2 + 0.7); + \draw[black] ({#1 + \sliderulewidth}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.7); + + + \draw ({#1 - 0.1}, #2 + 0.5) node[left] {#3}; + + % Numbers and marks 1 - 9 + \foreach \i in {1,...,9}{ + \draw[black] + ({#1 + \kscalefn(\i)}, #2) -- + ({#1 + \kscalefn(\i)}, #2 + 0.3) + node[above] {\i}; + } + % Numbers and marks 10 - 90 + \foreach \i in {1,..., 9}{ + \draw[black] + ({#1 + \kscalefn(10 * \i)}, #2) -- + ({#1 + \kscalefn(10 * \i)}, #2 + 0.3) + node[above] {\ifthenelse{\i=10}{1}{\i}}; + } + % Numbers and marks 100 - 1000 + \foreach \i in {1,..., 10}{ + \draw[black] + ({#1 + \kscalefn(100 * \i)}, #2) -- + ({#1 + \kscalefn(100 * \i)}, #2 + 0.3) + node[above] {\ifthenelse{\i=10}{1}{\i}}; + } + + % Submarks 1 - 9 + \foreach \n in {1, ..., 9} { + \ifthenelse{\n<4}{ + \foreach \i in {1,..., 9} + } { + \foreach \i in {2,4,6,8} + } + { + \ifthenelse{\i=5}{ + \draw[black] + ({#1 + \kscalefn(\n + \i / 10)}, #2) -- + ({#1 + \kscalefn(\n + \i / 10)}, #2 + 0.2); + } { + \draw[black] + ({#1 + \kscalefn(\n + \i / 10)}, #2) -- + ({#1 + \kscalefn(\n + \i / 10)}, #2 + 0.1); + } + } + } + + % Submarks 10 - 90 + \foreach \n in {10,20,...,90} { + \ifthenelse{\n<40}{ + \foreach \i in {1,..., 9} + } { + \foreach \i in {2,4,6,8} + } + { + \ifthenelse{\i=5}{ + \draw[black] + ({#1 + \kscalefn(\n + \i)}, #2) -- + ({#1 + \kscalefn(\n + \i)}, #2 + 0.2); + } { + \draw[black] + ({#1 + \kscalefn(\n + \i)}, #2) -- + ({#1 + \kscalefn(\n + \i)}, #2 + 0.1); + } + } + } + + % Submarks 100 - 1000 + \foreach \n in {100,200,...,900} { + \ifthenelse{\n<400}{ + \foreach \i in {10,20,...,90} + } { + \foreach \i in {20,40,60,80} + } + { + \ifthenelse{\i=50}{ + \draw[black] + ({#1 + \kscalefn(\n + \i)}, #2) -- + ({#1 + \kscalefn(\n + \i)}, #2 + 0.2); + } { + \draw[black] + ({#1 + \kscalefn(\n + \i)}, #2) -- + ({#1 + \kscalefn(\n + \i)}, #2 + 0.1); + } + } + } +} + +\newcommand{\lscale}[3]{ + \draw[black] ({#1}, #2) -- ({#1 + \sliderulewidth}, #2); + \draw[black] ({#1}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.9); + \draw[black] ({#1}, #2 + 0.9) -- ({#1}, #2 + 0.7); + \draw[black] ({#1 + \sliderulewidth}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.7); + + + \draw ({#1 - 0.1}, #2 + 0.5) node[left] {#3}; + + % Numbers and marks + \foreach \i in {0,..., 10}{ + \draw[black] + ({#1 + \lscalefn(\i / 10)}, #2) -- + ({#1 + \lscalefn(\i / 10)}, #2 + 0.3) + node[above] {\ifthenelse{\i=10}{1}{\ifthenelse{\i=0}{0}{.\i}}}; + } + + % Submarks + \foreach \n in {0, ..., 9} { + \foreach \i in {1,...,19} { + \ifthenelse{\i=10}{ + \draw[black] + ({#1 + \lscalefn((\n + (\i / 20))/10)}, #2) -- + ({#1 + \lscalefn((\n + (\i / 20))/10)}, #2 + 0.2); + } { + \ifthenelse{ + \i=1 \OR \i=3 \OR \i=5 \OR \i=7 \OR + \i=9 \OR \i=11 \OR \i=13 \OR \i=15 \OR + \i=17 \OR \i=19 + }{ + \draw[black] + ({#1 + \lscalefn((\n + (\i / 20))/10)}, #2) -- + ({#1 + \lscalefn((\n + (\i / 20))/10)}, #2 + 0.1); + } { + \draw[black] + ({#1 + \lscalefn((\n + (\i / 20))/10)}, #2) -- + ({#1 + \lscalefn((\n + (\i / 20))/10)}, #2 + 0.15); + } + } + } + } +} + +\newcommand{\tscale}[3]{ + \draw[black] ({#1}, #2) -- ({#1 + \sliderulewidth}, #2); + \draw[black] ({#1}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.9); + \draw[black] ({#1}, #2 + 0.9) -- ({#1}, #2 + 0.7); + \draw[black] ({#1 + \sliderulewidth}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.7); + + % First line + \draw[black] ({#1}, #2) -- ({#1}, #2 + 0.2); + + + \draw ({#1 - 0.1}, #2 + 0.5) node[left] {#3}; + + % Numbers and marks 6 - 10 + \foreach \i in {6,...,9,10,15,...,45}{ + \draw[black] + ({#1 + \tscalefn(\i)}, #2) -- + ({#1 + \tscalefn(\i)}, #2 + 0.3) + node[above] {\i}; + } + + % Submarks 6 - 10 + \foreach \n in {6, ..., 9} { + \foreach \i in {1,...,9}{ + \ifthenelse{\i=5}{ + \draw[black] + ({#1 + \tscalefn(\n + \i / 10)}, #2) -- + ({#1 + \tscalefn(\n + \i / 10)}, #2 + 0.2); + } { + \draw[black] + ({#1 + \tscalefn(\n + \i / 10)}, #2) -- + ({#1 + \tscalefn(\n + \i / 10)}, #2 + 0.1); + } + } + } + + % Submarks 15 - 45 + \foreach \n in {10, 15, ..., 40} { + \foreach \i in {1,...,24}{ + \ifthenelse{ + \i=5 \OR \i=10 \OR \i=15 \OR \i=20 + } { + \draw[black] + ({#1 + \tscalefn(\n + \i / 5)}, #2) -- + ({#1 + \tscalefn(\n + \i / 5)}, #2 + 0.2); + } { + \draw[black] + ({#1 + \tscalefn(\n + \i / 5)}, #2) -- + ({#1 + \tscalefn(\n + \i / 5)}, #2 + 0.1); + } + } + } +} + +\newcommand{\sscale}[3]{ + \draw[black] ({#1}, #2) -- ({#1 + \sliderulewidth}, #2); + \draw[black] ({#1}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.9); + \draw[black] ({#1}, #2 + 0.9) -- ({#1}, #2 + 0.7); + \draw[black] ({#1 + \sliderulewidth}, #2 + 0.9) -- ({#1 + \sliderulewidth}, #2 + 0.7); + + % First line + \draw[black] ({#1}, #2) -- ({#1}, #2 + 0.2); + + + \draw ({#1 - 0.1}, #2 + 0.5) node[left] {#3}; + + % Numbers and marks + \foreach \i in {6,...,9,10,15,...,30,40,50,...,60,90}{ + \draw[black] + ({#1 + \sscalefn(\i)}, #2) -- + ({#1 + \sscalefn(\i)}, #2 + 0.3) + node[above] {\i}; + } + + % Submarks 6 - 10 + \foreach \n in {6, ..., 9} { + \foreach \i in {1,...,9}{ + \ifthenelse{\i=5}{ + \draw[black] + ({#1 + \sscalefn(\n + \i / 10)}, #2) -- + ({#1 + \sscalefn(\n + \i / 10)}, #2 + 0.2); + } { + \draw[black] + ({#1 + \sscalefn(\n + \i / 10)}, #2) -- + ({#1 + \sscalefn(\n + \i / 10)}, #2 + 0.1); + } + } + } + + % Submarks 15 - 30 + \foreach \n in {10, 15, ..., 25} { + \foreach \i in {1,...,24}{ + \ifthenelse{ + \i=5 \OR \i=10 \OR \i=15 \OR \i=20 + } { + \draw[black] + ({#1 + \sscalefn(\n + \i / 5)}, #2) -- + ({#1 + \sscalefn(\n + \i / 5)}, #2 + 0.2); + } { + \draw[black] + ({#1 + \sscalefn(\n + \i / 5)}, #2) -- + ({#1 + \sscalefn(\n + \i / 5)}, #2 + 0.1); + } + } + } + + % Submarks 30 + \foreach \n in {30} { + \foreach \i in {1,...,19}{ + \ifthenelse{ + \i=2 \OR \i=4 \OR \i=6 \OR \i=8 \OR + \i=10 \OR \i=12 \OR \i=14 \OR \i=16 \OR + \i=18 + } { + \draw[black] + ({#1 + \sscalefn(\n + \i / 2)}, #2) -- + ({#1 + \sscalefn(\n + \i / 2)}, #2 + 0.2); + } { + \draw[black] + ({#1 + \sscalefn(\n + \i / 2)}, #2) -- + ({#1 + \sscalefn(\n + \i / 2)}, #2 + 0.1); + } + } + } + + % Submarks 40 - 50 + \foreach \n in {40, 50} { + \foreach \i in {1,...,9}{ + \ifthenelse{ + \i=5 \OR \i=10 \OR \i=15 \OR \i=20 + } { + \draw[black] + ({#1 + \sscalefn(\n + \i)}, #2) -- + ({#1 + \sscalefn(\n + \i)}, #2 + 0.2); + } { + \draw[black] + ({#1 + \sscalefn(\n + \i)}, #2) -- + ({#1 + \sscalefn(\n + \i)}, #2 + 0.1); + } + } + } + + % Submarks 60 + \foreach \i in {1,...,10}{ + \ifthenelse{ + \i=5 \OR \i=10 + } { + \draw[black] + ({#1 + \sscalefn(60 + \i * 2)}, #2) -- + ({#1 + \sscalefn(60 + \i * 2)}, #2 + 0.2); + } { + \draw[black] + ({#1 + \sscalefn(60 + \i * 2)}, #2) -- + ({#1 + \sscalefn(60 + \i * 2)}, #2 + 0.1); + } + } +} -- 2.47.1