From 4cfa4e4da7746e07042dc7186de15892e99ac784 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Wed, 4 Jan 2023 16:55:18 +0000 Subject: [PATCH] Start copying background material --- .gitignore | 3 + LocalPreferences.toml | 2 + Project.toml | 23 + notebooks/Asymptotics.aux | 23 + notebooks/Asymptotics.log | 675 +++++++++++++++++++++++++++ notebooks/Asymptotics.out | 5 + notebooks/Asymptotics.pdf | Bin 0 -> 45724 bytes notebooks/Asymptotics.tex | 334 ++++++++++++++ src/MATH50003NumericalAnalysis.jl | 78 ++++ src/notes/Asymptotics.jmd | 192 ++++++++ src/notes/Numbers.jmd | 738 ++++++++++++++++++++++++++++++ 11 files changed, 2073 insertions(+) create mode 100644 LocalPreferences.toml create mode 100644 Project.toml create mode 100644 notebooks/Asymptotics.aux create mode 100644 notebooks/Asymptotics.log create mode 100644 notebooks/Asymptotics.out create mode 100644 notebooks/Asymptotics.pdf create mode 100644 notebooks/Asymptotics.tex create mode 100644 src/MATH50003NumericalAnalysis.jl create mode 100644 src/notes/Asymptotics.jmd create mode 100644 src/notes/Numbers.jmd diff --git a/.gitignore b/.gitignore index 29126e4..573a2c7 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ docs/site/ # committed for packages, but should be committed for applications that require a static # environment. Manifest.toml + +*.ipynb_checkpoints +.DS_Store diff --git a/LocalPreferences.toml b/LocalPreferences.toml new file mode 100644 index 0000000..0ef57d2 --- /dev/null +++ b/LocalPreferences.toml @@ -0,0 +1,2 @@ +[CPUSummary] +hwloc = false diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..719a7b2 --- /dev/null +++ b/Project.toml @@ -0,0 +1,23 @@ +[deps] +ApproxFun = "28f2ccd6-bb30-5033-b560-165f7b14dc2f" +BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" +ColorBitstring = "ce91de38-7578-4b98-aebb-6a5df05791d6" +DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa" +DualNumbers = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" +IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" +Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0" +Interact = "c601a237-2ae4-5e1e-952c-7a85b0c7eef1" +IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +SetRounding = "3cc68bcd-71a2-5612-b932-767ffbe40ab0" +SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" +StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +TaylorSeries = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea" +TestImages = "5e47fb64-e119-507b-a336-dd2b206d9990" +Weave = "44d3d7a6-8a23-5bf8-98c5-b353f8df5ec9" + +[extras] +CPUSummary = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" diff --git a/notebooks/Asymptotics.aux b/notebooks/Asymptotics.aux new file mode 100644 index 0000000..87c9286 --- /dev/null +++ b/notebooks/Asymptotics.aux @@ -0,0 +1,23 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument} +\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined +\global\let\oldcontentsline\contentsline +\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}} +\global\let\oldnewlabel\newlabel +\gdef\newlabel#1#2{\newlabelxx{#1}#2} +\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}} +\AtEndDocument{\ifx\hyper@anchor\@undefined +\let\contentsline\oldcontentsline +\let\newlabel\oldnewlabel +\fi} +\fi} +\global\let\hyper@last\relax +\gdef\HyperFirstAtBeginDocument#1{#1} +\providecommand*\HyPL@Entry[1]{} +\HyPL@Entry{0<>} +\@writefile{toc}{\contentsline {section}{\numberline {1}A Asymptotics and Computational Cost}{1}{section.1}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}1. Asymptotics as $n \ensuremath {\rightarrow } \ensuremath {\infty }$}{1}{subsection.1.1}\protected@file@percent } +\@writefile{toc}{\contentsline {subsubsection}{\numberline {1.1.1}Rules}{2}{subsubsection.1.1.1}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.2}2. Asymptotics as $x \ensuremath {\rightarrow } x_0$}{2}{subsection.1.2}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.3}3. Computational cost}{3}{subsection.1.3}\protected@file@percent } diff --git a/notebooks/Asymptotics.log b/notebooks/Asymptotics.log new file mode 100644 index 0000000..a549727 --- /dev/null +++ b/notebooks/Asymptotics.log @@ -0,0 +1,675 @@ +This is XeTeX, Version 3.14159265-2.6-0.999991 (TeX Live 2019) (preloaded format=xelatex 2019.9.26) 4 JAN 2023 16:53 +entering extended mode + \write18 enabled. + %&-line parsing enabled. +**Asymptotics.tex +(./Asymptotics.tex +LaTeX2e <2018-12-01> +(/usr/local/texlive/2019/texmf-dist/tex/latex/base/article.cls +Document Class: article 2018/09/03 v1.4i Standard LaTeX document class +(/usr/local/texlive/2019/texmf-dist/tex/latex/base/size12.clo +File: size12.clo 2018/09/03 v1.4i Standard LaTeX file (size option) +) +\c@part=\count80 +\c@section=\count81 +\c@subsection=\count82 +\c@subsubsection=\count83 +\c@paragraph=\count84 +\c@subparagraph=\count85 +\c@figure=\count86 +\c@table=\count87 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/geometry/geometry.sty +Package: geometry 2018/04/16 v5.8 Page Geometry + +(/usr/local/texlive/2019/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 2014/10/28 v1.15 key=value parser (DPC) +\KV@toks@=\toks14 +) +(/usr/local/texlive/2019/texmf-dist/tex/generic/oberdiek/ifpdf.sty +Package: ifpdf 2018/09/07 v3.3 Provides the ifpdf switch +) +(/usr/local/texlive/2019/texmf-dist/tex/generic/oberdiek/ifvtex.sty +Package: ifvtex 2016/05/16 v1.6 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +) +(/usr/local/texlive/2019/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) +\Gm@cnth=\count88 +\Gm@cntv=\count89 +\c@Gm@tempcnt=\count90 +\Gm@bindingoffset=\dimen103 +\Gm@wd@mp=\dimen104 +\Gm@odd@mp=\dimen105 +\Gm@even@mp=\dimen106 +\Gm@layoutwidth=\dimen107 +\Gm@layoutheight=\dimen108 +\Gm@layouthoffset=\dimen109 +\Gm@layoutvoffset=\dimen110 +\Gm@dimlist=\toks15 +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/lm/lmodern.sty +Package: lmodern 2009/10/30 v1.6 Latin Modern Fonts +LaTeX Font Info: Overwriting symbol font `operators' in version `normal' +(Font) OT1/cmr/m/n --> OT1/lmr/m/n on input line 22. +LaTeX Font Info: Overwriting symbol font `letters' in version `normal' +(Font) OML/cmm/m/it --> OML/lmm/m/it on input line 23. +LaTeX Font Info: Overwriting symbol font `symbols' in version `normal' +(Font) OMS/cmsy/m/n --> OMS/lmsy/m/n on input line 24. +LaTeX Font Info: Overwriting symbol font `largesymbols' in version `normal' +(Font) OMX/cmex/m/n --> OMX/lmex/m/n on input line 25. +LaTeX Font Info: Overwriting symbol font `operators' in version `bold' +(Font) OT1/cmr/bx/n --> OT1/lmr/bx/n on input line 26. +LaTeX Font Info: Overwriting symbol font `letters' in version `bold' +(Font) OML/cmm/b/it --> OML/lmm/b/it on input line 27. +LaTeX Font Info: Overwriting symbol font `symbols' in version `bold' +(Font) OMS/cmsy/b/n --> OMS/lmsy/b/n on input line 28. +LaTeX Font Info: Overwriting symbol font `largesymbols' in version `bold' +(Font) OMX/cmex/m/n --> OMX/lmex/m/n on input line 29. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal' +(Font) OT1/cmr/bx/n --> OT1/lmr/bx/n on input line 31. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal' +(Font) OT1/cmss/m/n --> OT1/lmss/m/n on input line 32. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal' +(Font) OT1/cmr/m/it --> OT1/lmr/m/it on input line 33. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal' +(Font) OT1/cmtt/m/n --> OT1/lmtt/m/n on input line 34. +LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `bold' +(Font) OT1/cmr/bx/n --> OT1/lmr/bx/n on input line 35. +LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold' +(Font) OT1/cmss/bx/n --> OT1/lmss/bx/n on input line 36. +LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold' +(Font) OT1/cmr/bx/it --> OT1/lmr/bx/it on input line 37. +LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold' +(Font) OT1/cmtt/m/n --> OT1/lmtt/m/n on input line 38. +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/amsfonts/amssymb.sty +Package: amssymb 2013/01/14 v3.01 AMS font symbols + +(/usr/local/texlive/2019/texmf-dist/tex/latex/amsfonts/amsfonts.sty +Package: amsfonts 2013/01/14 v3.01 Basic AMSFonts support +\@emptytoks=\toks16 +\symAMSa=\mathgroup4 +\symAMSb=\mathgroup5 +LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold' +(Font) U/euf/m/n --> U/euf/b/n on input line 106. +)) +(/usr/local/texlive/2019/texmf-dist/tex/latex/amsmath/amsmath.sty +Package: amsmath 2018/12/01 v2.17b AMS math features +\@mathmargin=\skip43 + +For additional information on amsmath, use the `?' option. +(/usr/local/texlive/2019/texmf-dist/tex/latex/amsmath/amstext.sty +Package: amstext 2000/06/29 v2.01 AMS text + +(/usr/local/texlive/2019/texmf-dist/tex/latex/amsmath/amsgen.sty +File: amsgen.sty 1999/11/30 v2.0 generic functions +\@emptytoks=\toks17 +\ex@=\dimen111 +)) +(/usr/local/texlive/2019/texmf-dist/tex/latex/amsmath/amsbsy.sty +Package: amsbsy 1999/11/29 v1.2d Bold Symbols +\pmbraise@=\dimen112 +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/amsmath/amsopn.sty +Package: amsopn 2016/03/08 v2.02 operator names +) +\inf@bad=\count91 +LaTeX Info: Redefining \frac on input line 223. +\uproot@=\count92 +\leftroot@=\count93 +LaTeX Info: Redefining \overline on input line 385. +\classnum@=\count94 +\DOTSCASE@=\count95 +LaTeX Info: Redefining \ldots on input line 482. +LaTeX Info: Redefining \dots on input line 485. +LaTeX Info: Redefining \cdots on input line 606. +\Mathstrutbox@=\box27 +\strutbox@=\box28 +\big@size=\dimen113 +LaTeX Font Info: Redeclaring font encoding OML on input line 729. +LaTeX Font Info: Redeclaring font encoding OMS on input line 730. +\macc@depth=\count96 +\c@MaxMatrixCols=\count97 +\dotsspace@=\muskip10 +\c@parentequation=\count98 +\dspbrk@lvl=\count99 +\tag@help=\toks18 +\row@=\count100 +\column@=\count101 +\maxfields@=\count102 +\andhelp@=\toks19 +\eqnshift@=\dimen114 +\alignsep@=\dimen115 +\tagshift@=\dimen116 +\tagwidth@=\dimen117 +\totwidth@=\dimen118 +\lineht@=\dimen119 +\@envbody=\toks20 +\multlinegap=\skip44 +\multlinetaggap=\skip45 +\mathdisplay@stack=\toks21 +LaTeX Info: Redefining \[ on input line 2844. +LaTeX Info: Redefining \] on input line 2845. +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/tools/bm.sty +Package: bm 2017/01/16 v1.2c Bold Symbol Support (DPC/FMi) +\symboldoperators=\mathgroup6 +\symboldletters=\mathgroup7 +\symboldsymbols=\mathgroup8 +LaTeX Font Info: Redeclaring math alphabet \mathbf on input line 141. +LaTeX Info: Redefining \bm on input line 207. +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 2017/06/01 v1.1a Enhanced LaTeX Graphics (DPC,SPQR) + +(/usr/local/texlive/2019/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2017/06/25 v1.2c Standard LaTeX Graphics (DPC,SPQR) + +(/usr/local/texlive/2019/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 2016/01/03 v1.10 sin cos tan (DPC) +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/graphics-cfg/graphics.cfg +File: graphics.cfg 2016/06/04 v1.11 sample graphics configuration +) +Package graphics Info: Driver file: xetex.def on input line 99. + +(/usr/local/texlive/2019/texmf-dist/tex/latex/graphics-def/xetex.def +File: xetex.def 2017/06/24 v5.0h Graphics/color driver for xetex +)) +\Gin@req@height=\dimen120 +\Gin@req@width=\dimen121 +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/microtype/microtype.sty +Package: microtype 2019/02/28 v2.7b Micro-typographical refinements (RS) +\MT@toks=\toks22 +\MT@count=\count103 +LaTeX Info: Redefining \textls on input line 790. +\MT@outer@kern=\dimen122 +LaTeX Info: Redefining \textmicrotypecontext on input line 1336. +\MT@listname@count=\count104 + +(/usr/local/texlive/2019/texmf-dist/tex/latex/microtype/microtype-xetex.def +File: microtype-xetex.def 2019/02/28 v2.7b Definitions specific to xetex (RS) +LaTeX Info: Redefining \lsstyle on input line 258. +) +Package microtype Info: Loading configuration file microtype.cfg. + +(/usr/local/texlive/2019/texmf-dist/tex/latex/microtype/microtype.cfg +File: microtype.cfg 2019/02/28 v2.7b microtype main configuration file (RS) +)) +(/usr/local/texlive/2019/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2018/11/30 v6.88e Hypertext links for LaTeX + +(/usr/local/texlive/2019/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2016/05/16 v1.14 Bundle oberdiek, subset hyperref (HO) + + +(/usr/local/texlive/2019/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2016/05/16 v1.14 Bundle oberdiek, subset generic (HO) +Package: hobsub 2016/05/16 v1.14 Construct package bundles (HO) +Package: infwarerr 2016/05/16 v1.4 Providing info/warning/error messages (HO) +Package: ltxcmds 2016/05/16 v1.23 LaTeX kernel commands for general use (HO) +Package: ifluatex 2016/05/16 v1.4 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package hobsub Info: Skipping package `ifvtex' (already loaded). +Package: intcalc 2016/05/16 v1.2 Expandable calculations with integers (HO) +Package hobsub Info: Skipping package `ifpdf' (already loaded). +Package: etexcmds 2016/05/16 v1.6 Avoid name clashes with e-TeX commands (HO) +Package: kvsetkeys 2016/05/16 v1.17 Key value parser (HO) +Package: kvdefinekeys 2016/05/16 v1.4 Define keys (HO) +Package: pdftexcmds 2018/09/10 v0.29 Utility functions of pdfTeX for LuaTeX (HO +) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: pdfTeX >= 1.30 not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode not found. +Package: pdfescape 2016/05/16 v1.14 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2016/05/16 v1.4 Expandable calculations on big integers (HO +) +Package: bitset 2016/05/16 v1.2 Handle bit-vector datatype (HO) +Package: uniquecounter 2016/05/16 v1.3 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2016/05/16 v1.5 Let assignment for LaTeX macros (HO) +Package: hopatch 2016/05/16 v1.3 Wrapper for package hooks (HO) +Package: xcolor-patch 2016/05/16 xcolor patch +Package: atveryend 2016/05/16 v1.9 Hooks at the very end of document (HO) +Package atveryend Info: \enddocument detected (standard20110627). +Package: atbegshi 2016/06/09 v1.18 At begin shipout hook (HO) +Package: refcount 2016/05/16 v3.5 Data extraction from label references (HO) +Package: hycolor 2016/05/16 v1.8 Color options for hyperref/bookmark (HO) +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2016/05/16 v1.4 Hooks for auxiliary files (HO) +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2016/05/16 v3.12 Key value format for package options (HO) +) +\@linkdim=\dimen123 +\Hy@linkcounter=\count105 +\Hy@pagecounter=\count106 + +(/usr/local/texlive/2019/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2018/11/30 v6.88e Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count107 + +(/usr/local/texlive/2019/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Hyper figures OFF on input line 4519. +Package hyperref Info: Link nesting OFF on input line 4524. +Package hyperref Info: Hyper index ON on input line 4527. +Package hyperref Info: Plain pages OFF on input line 4534. +Package hyperref Info: Backreferencing OFF on input line 4539. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4772. +\c@Hy@tempcnt=\count108 + +(/usr/local/texlive/2019/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip11 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +LaTeX Info: Redefining \url on input line 5125. +\XeTeXLinkMargin=\dimen124 +\Fld@menulength=\count109 +\Field@Width=\dimen125 +\Fld@charsize=\dimen126 +Package hyperref Info: Hyper figures OFF on input line 6380. +Package hyperref Info: Link nesting OFF on input line 6385. +Package hyperref Info: Hyper index ON on input line 6388. +Package hyperref Info: backreferencing OFF on input line 6395. +Package hyperref Info: Link coloring OFF on input line 6400. +Package hyperref Info: Link coloring with OCG OFF on input line 6405. +Package hyperref Info: PDF/A mode OFF on input line 6410. +LaTeX Info: Redefining \ref on input line 6450. +LaTeX Info: Redefining \pageref on input line 6454. +\Hy@abspage=\count110 +\c@Item=\count111 +\c@Hfootnote=\count112 +) +Package hyperref Info: Driver (autodetected): hxetex. + +(/usr/local/texlive/2019/texmf-dist/tex/latex/hyperref/hxetex.def +File: hxetex.def 2018/11/30 v6.88e Hyperref driver for XeTeX + +(/usr/local/texlive/2019/texmf-dist/tex/latex/hyperref/puenc.def +File: puenc.def 2018/11/30 v6.88e Hyperref: PDF Unicode definition (HO) +) +(/usr/local/texlive/2019/texmf-dist/tex/generic/oberdiek/stringenc.sty +Package: stringenc 2016/05/16 v1.11 Convert strings between diff. encodings (HO +) +) +\pdfm@box=\box29 +\c@Hy@AnnotLevel=\count113 +\HyField@AnnotCount=\count114 +\Fld@listcount=\count115 +\c@bookmark@seq@number=\count116 + +(/usr/local/texlive/2019/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2016/05/16 v1.8 Rerun checks for auxiliary files (HO) +Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 2 +82. +) +\Hy@SectionHShift=\skip46 +) +(/usr/local/texlive/2019/texmf-dist/tex/generic/oberdiek/se-ascii-print.def +File: se-ascii-print.def 2016/05/16 v1.11 stringenc: Printable ASCII characters + +) +Package hyperref Info: Option `colorlinks' set `true' on input line 20. + +(/usr/local/texlive/2019/texmf-dist/tex/latex/upquote/upquote.sty +Package: upquote 2012/04/19 v1.3 upright-quote and grave-accent glyphs in verba +tim + +(/usr/local/texlive/2019/texmf-dist/tex/latex/base/textcomp.sty +Package: textcomp 2018/08/11 v2.0j Standard LaTeX package +Package textcomp Info: Sub-encoding information: +(textcomp) 5 = only ISO-Adobe without \textcurrency +(textcomp) 4 = 5 + \texteuro +(textcomp) 3 = 4 + \textohm +(textcomp) 2 = 3 + \textestimated + \textcurrency +(textcomp) 1 = TS1 - \textcircled - \t +(textcomp) 0 = TS1 (full) +(textcomp) Font families with sub-encoding setting implement +(textcomp) only a restricted character set as indicated. +(textcomp) Family '?' is the default used for unknown fonts. +(textcomp) See the documentation for details. +Package textcomp Info: Setting ? sub-encoding to TS1/1 on input line 79. + +(/usr/local/texlive/2019/texmf-dist/tex/latex/base/ts1enc.def +File: ts1enc.def 2001/06/05 v3.0e (jk/car/fm) Standard LaTeX file +) +LaTeX Info: Redefining \oldstylenums on input line 334. +Package textcomp Info: Setting cmr sub-encoding to TS1/0 on input line 349. +Package textcomp Info: Setting cmss sub-encoding to TS1/0 on input line 350. +Package textcomp Info: Setting cmtt sub-encoding to TS1/0 on input line 351. +Package textcomp Info: Setting cmvtt sub-encoding to TS1/0 on input line 352. +Package textcomp Info: Setting cmbr sub-encoding to TS1/0 on input line 353. +Package textcomp Info: Setting cmtl sub-encoding to TS1/0 on input line 354. +Package textcomp Info: Setting ccr sub-encoding to TS1/0 on input line 355. +Package textcomp Info: Setting ptm sub-encoding to TS1/4 on input line 356. +Package textcomp Info: Setting pcr sub-encoding to TS1/4 on input line 357. +Package textcomp Info: Setting phv sub-encoding to TS1/4 on input line 358. +Package textcomp Info: Setting ppl sub-encoding to TS1/3 on input line 359. +Package textcomp Info: Setting pag sub-encoding to TS1/4 on input line 360. +Package textcomp Info: Setting pbk sub-encoding to TS1/4 on input line 361. +Package textcomp Info: Setting pnc sub-encoding to TS1/4 on input line 362. +Package textcomp Info: Setting pzc sub-encoding to TS1/4 on input line 363. +Package textcomp Info: Setting bch sub-encoding to TS1/4 on input line 364. +Package textcomp Info: Setting put sub-encoding to TS1/5 on input line 365. +Package textcomp Info: Setting uag sub-encoding to TS1/5 on input line 366. +Package textcomp Info: Setting ugq sub-encoding to TS1/5 on input line 367. +Package textcomp Info: Setting ul8 sub-encoding to TS1/4 on input line 368. +Package textcomp Info: Setting ul9 sub-encoding to TS1/4 on input line 369. +Package textcomp Info: Setting augie sub-encoding to TS1/5 on input line 370. +Package textcomp Info: Setting dayrom sub-encoding to TS1/3 on input line 371. +Package textcomp Info: Setting dayroms sub-encoding to TS1/3 on input line 372. + +Package textcomp Info: Setting pxr sub-encoding to TS1/0 on input line 373. +Package textcomp Info: Setting pxss sub-encoding to TS1/0 on input line 374. +Package textcomp Info: Setting pxtt sub-encoding to TS1/0 on input line 375. +Package textcomp Info: Setting txr sub-encoding to TS1/0 on input line 376. +Package textcomp Info: Setting txss sub-encoding to TS1/0 on input line 377. +Package textcomp Info: Setting txtt sub-encoding to TS1/0 on input line 378. +Package textcomp Info: Setting lmr sub-encoding to TS1/0 on input line 379. +Package textcomp Info: Setting lmdh sub-encoding to TS1/0 on input line 380. +Package textcomp Info: Setting lmss sub-encoding to TS1/0 on input line 381. +Package textcomp Info: Setting lmssq sub-encoding to TS1/0 on input line 382. +Package textcomp Info: Setting lmvtt sub-encoding to TS1/0 on input line 383. +Package textcomp Info: Setting lmtt sub-encoding to TS1/0 on input line 384. +Package textcomp Info: Setting qhv sub-encoding to TS1/0 on input line 385. +Package textcomp Info: Setting qag sub-encoding to TS1/0 on input line 386. +Package textcomp Info: Setting qbk sub-encoding to TS1/0 on input line 387. +Package textcomp Info: Setting qcr sub-encoding to TS1/0 on input line 388. +Package textcomp Info: Setting qcs sub-encoding to TS1/0 on input line 389. +Package textcomp Info: Setting qpl sub-encoding to TS1/0 on input line 390. +Package textcomp Info: Setting qtm sub-encoding to TS1/0 on input line 391. +Package textcomp Info: Setting qzc sub-encoding to TS1/0 on input line 392. +Package textcomp Info: Setting qhvc sub-encoding to TS1/0 on input line 393. +Package textcomp Info: Setting futs sub-encoding to TS1/4 on input line 394. +Package textcomp Info: Setting futx sub-encoding to TS1/4 on input line 395. +Package textcomp Info: Setting futj sub-encoding to TS1/4 on input line 396. +Package textcomp Info: Setting hlh sub-encoding to TS1/3 on input line 397. +Package textcomp Info: Setting hls sub-encoding to TS1/3 on input line 398. +Package textcomp Info: Setting hlst sub-encoding to TS1/3 on input line 399. +Package textcomp Info: Setting hlct sub-encoding to TS1/5 on input line 400. +Package textcomp Info: Setting hlx sub-encoding to TS1/5 on input line 401. +Package textcomp Info: Setting hlce sub-encoding to TS1/5 on input line 402. +Package textcomp Info: Setting hlcn sub-encoding to TS1/5 on input line 403. +Package textcomp Info: Setting hlcw sub-encoding to TS1/5 on input line 404. +Package textcomp Info: Setting hlcf sub-encoding to TS1/5 on input line 405. +Package textcomp Info: Setting pplx sub-encoding to TS1/3 on input line 406. +Package textcomp Info: Setting pplj sub-encoding to TS1/3 on input line 407. +Package textcomp Info: Setting ptmx sub-encoding to TS1/4 on input line 408. +Package textcomp Info: Setting ptmj sub-encoding to TS1/4 on input line 409. +)) +(/usr/local/texlive/2019/texmf-dist/tex/latex/listings/listings.sty +\lst@mode=\count117 +\lst@gtempboxa=\box30 +\lst@token=\toks23 +\lst@length=\count118 +\lst@currlwidth=\dimen127 +\lst@column=\count119 +\lst@pos=\count120 +\lst@lostspace=\dimen128 +\lst@width=\dimen129 +\lst@newlines=\count121 +\lst@lineno=\count122 +\lst@maxwidth=\dimen130 + +(/usr/local/texlive/2019/texmf-dist/tex/latex/listings/lstmisc.sty +File: lstmisc.sty 2019/02/27 1.8b (Carsten Heinz) +\c@lstnumber=\count123 +\lst@skipnumbers=\count124 +\lst@framebox=\box31 +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/listings/listings.cfg +File: listings.cfg 2019/02/27 1.8b listings configuration +)) +Package: listings 2019/02/27 1.8b (Carsten Heinz) + +(/usr/local/texlive/2019/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2016/05/11 v2.12 LaTeX color extensions (UK) + +(/usr/local/texlive/2019/texmf-dist/tex/latex/graphics-cfg/color.cfg +File: color.cfg 2016/01/02 v1.6 sample color configuration +) +Package xcolor Info: Driver file: xetex.def on input line 225. +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1348. +Package xcolor Info: Model `RGB' extended on input line 1364. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1366. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1367. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1368. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1369. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1370. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1371. +) +(./Asymptotics.aux) +\openout1 = `Asymptotics.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 120. +LaTeX Font Info: ... okay on input line 120. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 120. +LaTeX Font Info: ... okay on input line 120. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 120. +LaTeX Font Info: ... okay on input line 120. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 120. +LaTeX Font Info: ... okay on input line 120. +LaTeX Font Info: Checking defaults for TU/lmr/m/n on input line 120. +LaTeX Font Info: ... okay on input line 120. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 120. +LaTeX Font Info: ... okay on input line 120. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 120. +LaTeX Font Info: ... okay on input line 120. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 120. +LaTeX Font Info: ... okay on input line 120. +LaTeX Font Info: Checking defaults for PU/pdf/m/n on input line 120. +LaTeX Font Info: ... okay on input line 120. +LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 120. +LaTeX Font Info: Try loading font information for TS1+cmr on input line 120. + + +(/usr/local/texlive/2019/texmf-dist/tex/latex/base/ts1cmr.fd +File: ts1cmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions +) +LaTeX Font Info: ... okay on input line 120. + +*geometry* driver: auto-detecting +*geometry* detected driver: xetex +*geometry* verbose mode - [ preamble ] result: +* driver: xetex +* paper: a4paper +* layout: +* layoutoffset:(h,v)=(0.0pt,0.0pt) +* hratio: 1:1 +* vratio: 1:1 +* modes: +* h-part:(L,W,R)=(64.0187pt, 469.47046pt, 64.0187pt) +* v-part:(T,H,B)=(64.01874pt, 717.00935pt, 64.01875pt) +* \paperwidth=597.50787pt +* \paperheight=845.04684pt +* \textwidth=469.47046pt +* \textheight=717.00935pt +* \oddsidemargin=-8.25128pt +* \evensidemargin=-8.25128pt +* \topmargin=-45.25125pt +* \headheight=12.0pt +* \headsep=25.0pt +* \topskip=12.0pt +* \footskip=30.0pt +* \marginparwidth=35.0pt +* \marginparsep=10.0pt +* \columnsep=10.0pt +* \skip\footins=10.8pt plus 4.0pt minus 2.0pt +* \hoffset=0.0pt +* \voffset=0.0pt +* \mag=1000 +* \@twocolumnfalse +* \@twosidefalse +* \@mparswitchfalse +* \@reversemarginfalse +* (1in=72.27pt=25.4mm, 1cm=28.453pt) + +LaTeX Info: Redefining \microtypecontext on input line 120. +Package microtype Info: Character protrusion enabled (level 2). +Package microtype Info: Using default protrusion set `alltext'. +Package microtype Info: No adjustment of tracking. +Package microtype Info: No adjustment of spacing. +Package microtype Info: No adjustment of kerning. + +(/usr/local/texlive/2019/texmf-dist/tex/latex/microtype/mt-LatinModernRoman.cfg +File: mt-LatinModernRoman.cfg 2013/03/13 v1.0 microtype config. file: Latin Mod +ern Roman (RS) +) +\AtBeginShipoutBox=\box32 +Package hyperref Info: Link coloring ON on input line 120. + (/usr/local/texlive/2019/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2016/05/21 v2.44 Cross-referencing by name of section + +(/usr/local/texlive/2019/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2016/05/16 v1.5 Cleanup title references (HO) +) +\c@section@level=\count125 +) +LaTeX Info: Redefining \ref on input line 120. +LaTeX Info: Redefining \pageref on input line 120. +LaTeX Info: Redefining \nameref on input line 120. + +(./Asymptotics.out) (./Asymptotics.out) +\@outlinefile=\write3 +\openout3 = `Asymptotics.out'. + +\c@lstlisting=\count126 +LaTeX Font Info: Try loading font information for OT1+lmr on input line 128. + + +(/usr/local/texlive/2019/texmf-dist/tex/latex/lm/ot1lmr.fd +File: ot1lmr.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +Package microtype Info: Loading generic protrusion settings for font family +(microtype) `lmr' (encoding: OT1). +(microtype) For optimal results, create family-specific settings. +(microtype) See the microtype manual for details. +LaTeX Font Info: Try loading font information for OML+lmm on input line 128. + + +(/usr/local/texlive/2019/texmf-dist/tex/latex/lm/omllmm.fd +File: omllmm.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +LaTeX Font Info: Try loading font information for OMS+lmsy on input line 128 +. + +(/usr/local/texlive/2019/texmf-dist/tex/latex/lm/omslmsy.fd +File: omslmsy.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +LaTeX Font Info: Try loading font information for OMX+lmex on input line 128 +. + +(/usr/local/texlive/2019/texmf-dist/tex/latex/lm/omxlmex.fd +File: omxlmex.fd 2009/10/30 v1.6 Font defs for Latin Modern +) +LaTeX Font Info: External font `lmex10' loaded for size +(Font) <12> on input line 128. +LaTeX Font Info: External font `lmex10' loaded for size +(Font) <8> on input line 128. +LaTeX Font Info: External font `lmex10' loaded for size +(Font) <6> on input line 128. +LaTeX Font Info: Try loading font information for U+msa on input line 128. + +(/usr/local/texlive/2019/texmf-dist/tex/latex/amsfonts/umsa.fd +File: umsa.fd 2013/01/14 v3.01 AMS symbols A +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/microtype/mt-msa.cfg +File: mt-msa.cfg 2006/02/04 v1.1 microtype config. file: AMS symbols (a) (RS) +) +LaTeX Font Info: Try loading font information for U+msb on input line 128. + +(/usr/local/texlive/2019/texmf-dist/tex/latex/amsfonts/umsb.fd +File: umsb.fd 2013/01/14 v3.01 AMS symbols B +) +(/usr/local/texlive/2019/texmf-dist/tex/latex/microtype/mt-msb.cfg +File: mt-msb.cfg 2005/06/01 v1.0 microtype config. file: AMS symbols (b) (RS) +) +LaTeX Font Info: External font `lmex10' loaded for size +(Font) <14.4> on input line 137. +LaTeX Font Info: External font `lmex10' loaded for size +(Font) <10> on input line 137. +LaTeX Font Info: External font `lmex10' loaded for size +(Font) <7> on input line 137. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `math shift' on input line 137. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\rightarrow' on input line 137. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\infty' on input line 137. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `math shift' on input line 137. + + +Package amsmath Warning: Foreign command \over; +(amsmath) \frac or \genfrac should be used instead +(amsmath) on input line 148. + +[1 + +] + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `math shift' on input line 212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `\rightarrow' on input line 212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `subscript' on input line 212. + + +Package hyperref Warning: Token not allowed in a PDF string (Unicode): +(hyperref) removing `math shift' on input line 212. + +[2] +Package microtype Info: Loading generic protrusion settings for font family +(microtype) `lmtt' (encoding: TU). +(microtype) For optimal results, create family-specific settings. +(microtype) See the microtype manual for details. +LaTeX Font Info: Font shape `TU/lmtt/bx/n' in size <10> not available +(Font) Font shape `TU/lmtt/b/n' tried instead on input line 274. + [3] +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 334. + [4] +Package atveryend Info: Empty hook `AfterLastShipout' on input line 334. + (./Asymptotics.aux) +Package atveryend Info: Empty hook `AtVeryEndDocument' on input line 334. +Package atveryend Info: Executing hook `AtEndAfterFileList' on input line 334. +Package rerunfilecheck Info: File `Asymptotics.out' has not changed. +(rerunfilecheck) Checksum: 10CB56C83864291DC8D0AA3EBA5E11F8. +Package atveryend Info: Empty hook `AtVeryVeryEnd' on input line 334. + ) +Here is how much of TeX's memory you used: + 12953 strings out of 492916 + 189308 string characters out of 6133345 + 318451 words of memory out of 5000000 + 16841 multiletter control sequences out of 15000+600000 + 49999 words of font info for 74 fonts, out of 8000000 for 9000 + 1348 hyphenation exceptions out of 8191 + 31i,9n,45p,641b,931s stack positions out of 5000i,500n,10000p,200000b,80000s + +Output written on Asymptotics.pdf (4 pages). diff --git a/notebooks/Asymptotics.out b/notebooks/Asymptotics.out new file mode 100644 index 0000000..27ffe88 --- /dev/null +++ b/notebooks/Asymptotics.out @@ -0,0 +1,5 @@ +\BOOKMARK [1][-]{section.1}{A\040Asymptotics\040and\040Computational\040Cost}{}% 1 +\BOOKMARK [2][-]{subsection.1.1}{1.\040Asymptotics\040as\040n\040\040}{section.1}% 2 +\BOOKMARK [3][-]{subsubsection.1.1.1}{Rules}{subsection.1.1}% 3 +\BOOKMARK [2][-]{subsection.1.2}{2.\040Asymptotics\040as\040x\040\040x0}{section.1}% 4 +\BOOKMARK [2][-]{subsection.1.3}{3.\040Computational\040cost}{section.1}% 5 diff --git a/notebooks/Asymptotics.pdf b/notebooks/Asymptotics.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9f1c0865ccf5e14b8a7ca9ac2b5aa543245156bc GIT binary patch literal 45724 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 literal 0 HcmV?d00001 diff --git a/notebooks/Asymptotics.tex b/notebooks/Asymptotics.tex new file mode 100644 index 0000000..a6a3f03 --- /dev/null +++ b/notebooks/Asymptotics.tex @@ -0,0 +1,334 @@ +\documentclass[12pt,a4paper]{article} + +\usepackage[a4paper,text={16.5cm,25.2cm},centering]{geometry} +\usepackage{lmodern} +\usepackage{amssymb,amsmath} +\usepackage{bm} +\usepackage{graphicx} +\usepackage{microtype} +\usepackage{hyperref} +\setlength{\parindent}{0pt} +\setlength{\parskip}{1.2ex} + +\hypersetup + { pdfauthor = { }, + pdftitle={ }, + colorlinks=TRUE, + linkcolor=black, + citecolor=blue, + urlcolor=blue + } + + + + +\usepackage{upquote} +\usepackage{listings} +\usepackage{xcolor} +\lstset{ + basicstyle=\ttfamily\footnotesize, + upquote=true, + breaklines=true, + breakindent=0pt, + keepspaces=true, + showspaces=false, + columns=fullflexible, + showtabs=false, + showstringspaces=false, + escapeinside={(*@}{@*)}, + extendedchars=true, +} +\newcommand{\HLJLt}[1]{#1} +\newcommand{\HLJLw}[1]{#1} +\newcommand{\HLJLe}[1]{#1} +\newcommand{\HLJLeB}[1]{#1} +\newcommand{\HLJLo}[1]{#1} +\newcommand{\HLJLk}[1]{\textcolor[RGB]{148,91,176}{\textbf{#1}}} +\newcommand{\HLJLkc}[1]{\textcolor[RGB]{59,151,46}{\textit{#1}}} +\newcommand{\HLJLkd}[1]{\textcolor[RGB]{214,102,97}{\textit{#1}}} +\newcommand{\HLJLkn}[1]{\textcolor[RGB]{148,91,176}{\textbf{#1}}} +\newcommand{\HLJLkp}[1]{\textcolor[RGB]{148,91,176}{\textbf{#1}}} +\newcommand{\HLJLkr}[1]{\textcolor[RGB]{148,91,176}{\textbf{#1}}} +\newcommand{\HLJLkt}[1]{\textcolor[RGB]{148,91,176}{\textbf{#1}}} +\newcommand{\HLJLn}[1]{#1} +\newcommand{\HLJLna}[1]{#1} +\newcommand{\HLJLnb}[1]{#1} +\newcommand{\HLJLnbp}[1]{#1} +\newcommand{\HLJLnc}[1]{#1} +\newcommand{\HLJLncB}[1]{#1} +\newcommand{\HLJLnd}[1]{\textcolor[RGB]{214,102,97}{#1}} +\newcommand{\HLJLne}[1]{#1} +\newcommand{\HLJLneB}[1]{#1} +\newcommand{\HLJLnf}[1]{\textcolor[RGB]{66,102,213}{#1}} +\newcommand{\HLJLnfm}[1]{\textcolor[RGB]{66,102,213}{#1}} +\newcommand{\HLJLnp}[1]{#1} +\newcommand{\HLJLnl}[1]{#1} +\newcommand{\HLJLnn}[1]{#1} +\newcommand{\HLJLno}[1]{#1} +\newcommand{\HLJLnt}[1]{#1} +\newcommand{\HLJLnv}[1]{#1} +\newcommand{\HLJLnvc}[1]{#1} +\newcommand{\HLJLnvg}[1]{#1} +\newcommand{\HLJLnvi}[1]{#1} +\newcommand{\HLJLnvm}[1]{#1} +\newcommand{\HLJLl}[1]{#1} +\newcommand{\HLJLld}[1]{\textcolor[RGB]{148,91,176}{\textit{#1}}} +\newcommand{\HLJLs}[1]{\textcolor[RGB]{201,61,57}{#1}} +\newcommand{\HLJLsa}[1]{\textcolor[RGB]{201,61,57}{#1}} +\newcommand{\HLJLsb}[1]{\textcolor[RGB]{201,61,57}{#1}} +\newcommand{\HLJLsc}[1]{\textcolor[RGB]{201,61,57}{#1}} +\newcommand{\HLJLsd}[1]{\textcolor[RGB]{201,61,57}{#1}} +\newcommand{\HLJLsdB}[1]{\textcolor[RGB]{201,61,57}{#1}} +\newcommand{\HLJLsdC}[1]{\textcolor[RGB]{201,61,57}{#1}} +\newcommand{\HLJLse}[1]{\textcolor[RGB]{59,151,46}{#1}} +\newcommand{\HLJLsh}[1]{\textcolor[RGB]{201,61,57}{#1}} +\newcommand{\HLJLsi}[1]{#1} +\newcommand{\HLJLso}[1]{\textcolor[RGB]{201,61,57}{#1}} +\newcommand{\HLJLsr}[1]{\textcolor[RGB]{201,61,57}{#1}} +\newcommand{\HLJLss}[1]{\textcolor[RGB]{201,61,57}{#1}} +\newcommand{\HLJLssB}[1]{\textcolor[RGB]{201,61,57}{#1}} +\newcommand{\HLJLnB}[1]{\textcolor[RGB]{59,151,46}{#1}} +\newcommand{\HLJLnbB}[1]{\textcolor[RGB]{59,151,46}{#1}} +\newcommand{\HLJLnfB}[1]{\textcolor[RGB]{59,151,46}{#1}} +\newcommand{\HLJLnh}[1]{\textcolor[RGB]{59,151,46}{#1}} +\newcommand{\HLJLni}[1]{\textcolor[RGB]{59,151,46}{#1}} +\newcommand{\HLJLnil}[1]{\textcolor[RGB]{59,151,46}{#1}} +\newcommand{\HLJLnoB}[1]{\textcolor[RGB]{59,151,46}{#1}} +\newcommand{\HLJLoB}[1]{\textcolor[RGB]{102,102,102}{\textbf{#1}}} +\newcommand{\HLJLow}[1]{\textcolor[RGB]{102,102,102}{\textbf{#1}}} +\newcommand{\HLJLp}[1]{#1} +\newcommand{\HLJLc}[1]{\textcolor[RGB]{153,153,119}{\textit{#1}}} +\newcommand{\HLJLch}[1]{\textcolor[RGB]{153,153,119}{\textit{#1}}} +\newcommand{\HLJLcm}[1]{\textcolor[RGB]{153,153,119}{\textit{#1}}} +\newcommand{\HLJLcp}[1]{\textcolor[RGB]{153,153,119}{\textit{#1}}} +\newcommand{\HLJLcpB}[1]{\textcolor[RGB]{153,153,119}{\textit{#1}}} +\newcommand{\HLJLcs}[1]{\textcolor[RGB]{153,153,119}{\textit{#1}}} +\newcommand{\HLJLcsB}[1]{\textcolor[RGB]{153,153,119}{\textit{#1}}} +\newcommand{\HLJLg}[1]{#1} +\newcommand{\HLJLgd}[1]{#1} +\newcommand{\HLJLge}[1]{#1} +\newcommand{\HLJLgeB}[1]{#1} +\newcommand{\HLJLgh}[1]{#1} +\newcommand{\HLJLgi}[1]{#1} +\newcommand{\HLJLgo}[1]{#1} +\newcommand{\HLJLgp}[1]{#1} +\newcommand{\HLJLgs}[1]{#1} +\newcommand{\HLJLgsB}[1]{#1} +\newcommand{\HLJLgt}[1]{#1} + + +\begin{document} + + + +\section{A Asymptotics and Computational Cost} +We introduce Big-O, little-o and asymptotic notation and see how they can be used to describe computational cost. + +\begin{itemize} +\item[1. ] Asymptotics as $n \ensuremath{\rightarrow} \ensuremath{\infty}$ + + +\item[2. ] Asymptotics as $x \ensuremath{\rightarrow} x_0$ + + +\item[3. ] Computational cost + +\end{itemize} +\subsection{1. Asymptotics as $n \ensuremath{\rightarrow} \ensuremath{\infty}$} +Big-O, little-o, and "asymptotic to" are used to describe behaviour of functions at infinity. + +\textbf{Definition (Big-O)} + +\[ +f(n) = O(\ensuremath{\phi}(n)) \qquad \hbox{(as $n \ensuremath{\rightarrow} \ensuremath{\infty}$)} +\] +means + +\[ +\left|{f(n) \over \ensuremath{\phi}(n)}\right| +\] +is bounded for sufficiently large $n$. That is, there exist constants $C$ and $N_0$ such that, for all $n \geq N_0$, $|{f(n) \over \ensuremath{\phi}(n)}| \leq C$. + +\textbf{Definition (little-O)} + +\[ +f(n) = o(\ensuremath{\phi}(n)) \qquad \hbox{(as $n \ensuremath{\rightarrow} \ensuremath{\infty}$)} +\] +means + +\[ +\lim_{n \ensuremath{\rightarrow} \ensuremath{\infty}} {f(n) \over \ensuremath{\phi}(n)} = 0. +\] +\textbf{Definition (asymptotic to)} + +\[ +f(n) \ensuremath{\sim} \ensuremath{\phi}(n) \qquad \hbox{(as $n \ensuremath{\rightarrow} \ensuremath{\infty}$)} +\] +means + +\[ +\lim_{n \ensuremath{\rightarrow} \ensuremath{\infty}} {f(n) \over \ensuremath{\phi}(n)} = 1. +\] +\textbf{Examples} + +\[ +{\cos n \over n^2 -1} = O(n^{-2}) +\] +as + +\[ +\left|{{\cos n \over n^2 -1} \over n^{-2}} \right| \leq \left| n^2 \over n^2 -1 \right| \leq 2 +\] +for $n \geq N_0 = 2$. + +\[ +\log n = o(n) +\] +as + +\[ +lim_{n \ensuremath{\rightarrow} \ensuremath{\infty}} {\log n \over n} = 0. +\] +\[ +n^2 + 1 \ensuremath{\sim} n^2 +\] +as + +\[ +{n^2 +1 \over n^2} \ensuremath{\rightarrow} 1. +\] +Note we sometimes write $f(O(\ensuremath{\phi}(n)))$ for a function of the form $f(g(n))$ such that $g(n) = O(\ensuremath{\phi}(n))$. + +\subsubsection{Rules} +We have some simple algebraic rules: + +\textbf{Proposition (Big-O rules)} + + +\begin{align*} +O(\ensuremath{\phi}(n))O(\ensuremath{\psi}(n)) = O(\ensuremath{\phi}(n)\ensuremath{\psi}(n)) \qquad \hbox{(as $n \ensuremath{\rightarrow} \ensuremath{\infty}$)} \\ +O(\ensuremath{\phi}(n)) + O(\ensuremath{\psi}(n)) = O(|\ensuremath{\phi}(n)| + |\ensuremath{\psi}(n)|) \qquad \hbox{(as $n \ensuremath{\rightarrow} \ensuremath{\infty}$)}. +\end{align*} +\subsection{2. Asymptotics as $x \ensuremath{\rightarrow} x_0$} +We also have Big-O, little-o and "asymptotic to" at a point: + +\textbf{Definition (Big-O)} + +\[ +f(x) = O(\ensuremath{\phi}(x)) \qquad \hbox{(as $x \ensuremath{\rightarrow} x_0$)} +\] +means + +\[ +|f(x) \over \ensuremath{\phi}(x)| +\] +is bounded in a neighbourhood of $x_0$. That is, there exist constants $C$ and $r$ such that, for all $0 \leq |x - x_0| \leq r$, $|{f(x) \over \ensuremath{\phi}(x)}| \leq C$. + +\textbf{Definition (little-O)} + +\[ +f(x) = o(\ensuremath{\phi}(x)) \qquad \hbox{(as $x \ensuremath{\rightarrow} x_0$)} +\] +means + +\[ +\lim_{x \ensuremath{\rightarrow} x_0} {f(x) \over \ensuremath{\phi}(x)} = 0. +\] +\textbf{Definition (asymptotic to)} + +\[ +f(x) \ensuremath{\sim} \ensuremath{\phi}(x) \qquad \hbox{(as $x \ensuremath{\rightarrow} x_0$)} +\] +means + +\[ +\lim_{x \ensuremath{\rightarrow} x_0} {f(x) \over \ensuremath{\phi}(x)} = 1. +\] +\textbf{Example} + +\[ +\exp x = 1 + x + O(x^2) \qquad \hbox{as $x \ensuremath{\rightarrow} 0$} +\] +Since + +\[ +\exp x = 1 + x + {\exp t \over 2} x^2 +\] +for some $t \in [0,x]$ and + +\[ +\left|{{\exp t \over 2} x^2 \over x^2}\right| \leq {3 \over 2} +\] +provided $x \leq 1$. + +\subsection{3. Computational cost} +We will use Big-O notation to describe the computational cost of algorithms. Consider the following simple sum + +\[ +\sum_{k=1}^n x_k^2 +\] +which we might implement as: + + +\begin{lstlisting} +(*@\HLJLk{function}@*) (*@\HLJLnf{sumsq}@*)(*@\HLJLp{(}@*)(*@\HLJLn{x}@*)(*@\HLJLp{)}@*) + (*@\HLJLn{n}@*) (*@\HLJLoB{=}@*) (*@\HLJLnf{length}@*)(*@\HLJLp{(}@*)(*@\HLJLn{x}@*)(*@\HLJLp{)}@*) + (*@\HLJLn{ret}@*) (*@\HLJLoB{=}@*) (*@\HLJLnfB{0.0}@*) + (*@\HLJLk{for}@*) (*@\HLJLn{k}@*) (*@\HLJLoB{=}@*) (*@\HLJLni{1}@*)(*@\HLJLoB{:}@*)(*@\HLJLn{n}@*) + (*@\HLJLn{ret}@*) (*@\HLJLoB{=}@*) (*@\HLJLn{ret}@*) (*@\HLJLoB{+}@*) (*@\HLJLn{x}@*)(*@\HLJLp{[}@*)(*@\HLJLn{k}@*)(*@\HLJLp{]}@*)(*@\HLJLoB{{\textasciicircum}}@*)(*@\HLJLni{2}@*) + (*@\HLJLk{end}@*) + (*@\HLJLn{ret}@*) +(*@\HLJLk{end}@*) + +(*@\HLJLn{n}@*) (*@\HLJLoB{=}@*) (*@\HLJLni{100}@*) +(*@\HLJLn{x}@*) (*@\HLJLoB{=}@*) (*@\HLJLnf{randn}@*)(*@\HLJLp{(}@*)(*@\HLJLn{n}@*)(*@\HLJLp{)}@*) +(*@\HLJLnf{sumsq}@*)(*@\HLJLp{(}@*)(*@\HLJLn{x}@*)(*@\HLJLp{)}@*) +\end{lstlisting} + +\begin{lstlisting} +103.37928495486999 +\end{lstlisting} + + +Each step of this algorithm consists of one memory look-up (\texttt{z = x[k]}), one multiplication (\texttt{w = z*z}) and one addition (\texttt{ret = ret + w}). We will ignore the memory look-up in the following discussion. The number of CPU operations per step is therefore 2 (the addition and multiplication). Thus the total number of CPU operations is $2n$. But the constant $2$ here is misleading: we didn't count the memory look-up, thus it is more sensible to just talk about the asymptotic complexity, that is, the \emph{computational cost} is $O(n)$. + +Now consider a double sum like: + +\[ +\sum_{k=1}^n \sum_{j=1}^k x_j^2 +\] +which we might implement as: + + +\begin{lstlisting} +(*@\HLJLk{function}@*) (*@\HLJLnf{sumsq2}@*)(*@\HLJLp{(}@*)(*@\HLJLn{x}@*)(*@\HLJLp{)}@*) + (*@\HLJLn{n}@*) (*@\HLJLoB{=}@*) (*@\HLJLnf{length}@*)(*@\HLJLp{(}@*)(*@\HLJLn{x}@*)(*@\HLJLp{)}@*) + (*@\HLJLn{ret}@*) (*@\HLJLoB{=}@*) (*@\HLJLnfB{0.0}@*) + (*@\HLJLk{for}@*) (*@\HLJLn{k}@*) (*@\HLJLoB{=}@*) (*@\HLJLni{1}@*)(*@\HLJLoB{:}@*)(*@\HLJLn{n}@*) + (*@\HLJLk{for}@*) (*@\HLJLn{j}@*) (*@\HLJLoB{=}@*) (*@\HLJLni{1}@*)(*@\HLJLoB{:}@*)(*@\HLJLn{k}@*) + (*@\HLJLn{ret}@*) (*@\HLJLoB{=}@*) (*@\HLJLn{ret}@*) (*@\HLJLoB{+}@*) (*@\HLJLn{x}@*)(*@\HLJLp{[}@*)(*@\HLJLn{j}@*)(*@\HLJLp{]}@*)(*@\HLJLoB{{\textasciicircum}}@*)(*@\HLJLni{2}@*) + (*@\HLJLk{end}@*) + (*@\HLJLk{end}@*) + (*@\HLJLn{ret}@*) +(*@\HLJLk{end}@*) + +(*@\HLJLn{n}@*) (*@\HLJLoB{=}@*) (*@\HLJLni{100}@*) +(*@\HLJLn{x}@*) (*@\HLJLoB{=}@*) (*@\HLJLnf{randn}@*)(*@\HLJLp{(}@*)(*@\HLJLn{n}@*)(*@\HLJLp{)}@*) +(*@\HLJLnf{sumsq2}@*)(*@\HLJLp{(}@*)(*@\HLJLn{x}@*)(*@\HLJLp{)}@*) +\end{lstlisting} + +\begin{lstlisting} +4309.772948636952 +\end{lstlisting} + + +Now the inner loop is $O(1)$ operations (we don't try to count the precise number), which we do $k$ times for $O(k)$ operations as $k \ensuremath{\rightarrow} \ensuremath{\infty}$. The outer loop therefore takes + +\[ +\ensuremath{\sum}_{k = 1}^n O(k) = O\left(\ensuremath{\sum}_{k = 1}^n k\right) = O\left( {n (n+1) \over 2} \right) = O(n^2) +\] +operations. + + + +\end{document} diff --git a/src/MATH50003NumericalAnalysis.jl b/src/MATH50003NumericalAnalysis.jl new file mode 100644 index 0000000..f7cc311 --- /dev/null +++ b/src/MATH50003NumericalAnalysis.jl @@ -0,0 +1,78 @@ +using Weave + +nkwds = (out_path="notebooks/", doctype = "md2pdf") +pkwds = (out_path="sheets/", jupyter_path="$(homedir())/.julia/conda/3/bin/jupyter", nbconvert_options="--allow-errors --clear-output") +skwds = (out_path="sheets/", jupyter_path="$(homedir())/.julia/conda/3/bin/jupyter", nbconvert_options="--allow-errors") +ekwds = (out_path="exams/", jupyter_path="$(homedir())/.julia/conda/3/bin/jupyter", nbconvert_options="--allow-errors --clear-output") +eskwds = (out_path="exams/", jupyter_path="$(homedir())/.julia/conda/3/bin/jupyter", nbconvert_options="--allow-errors") + +## +# notes +## + +weave("src/notes/Asymptotics.jmd"; nkwds...) + + +notebook("src/Julia.jmd"; nkwds...) +notebook("src/Asymptotics.jmd"; nkwds...) +notebook("src/SpectralTheorem.jmd"; nkwds...) + +notebook("src/Numbers.jmd"; nkwds...) +notebook("src/Differentiation.jmd"; nkwds...) + +notebook("src/StructuredMatrices.jmd"; nkwds...) +notebook("src/Decompositions.jmd"; nkwds...) +notebook("src/SingularValues.jmd"; nkwds...) +notebook("src/DifferentialEquations.jmd"; nkwds...) + +notebook("src/Fourier.jmd"; nkwds...) +notebook("src/OrthogonalPolynomials.jmd"; nkwds...) +notebook("src/Quadrature.jmd"; nkwds...) + +notebook("src/Applications.jmd"; nkwds...) + + +## +# problem sheets +## + +notebook("src/week1.jmd"; pkwds...) +notebook("src/week2.jmd"; pkwds...) +notebook("src/week4.jmd"; pkwds...) +notebook("src/week5.jmd"; pkwds...) +notebook("src/week9.jmd"; pkwds...) +notebook("src/week10.jmd"; pkwds...) +notebook("src/advanced1.jmd"; pkwds...) +notebook("src/advanced2.jmd"; pkwds...) +notebook("src/advanced3.jmd"; pkwds...) + +## +# solutions +### + +notebook("src/week1s.jmd"; skwds...) +notebook("src/week2s.jmd"; skwds...) +notebook("src/week3s.jmd"; skwds...) +notebook("src/week4s.jmd"; skwds...) +notebook("src/week5s.jmd"; skwds...) +notebook("src/week6s.jmd"; skwds...) +notebook("src/week7s.jmd"; skwds...) +notebook("src/week8s.jmd"; skwds...) +notebook("src/week9s.jmd"; skwds...) +notebook("src/week10s.jmd"; skwds...) + + +## +# exams +## + +notebook("src/practice.jmd"; ekwds...) +notebook("src/practices.jmd"; eskwds...) +notebook("src/computerexam.jmd"; ekwds...) +notebook("src/computerexams.jmd"; ekwds...) + +## +# extras +## + +notebook("src/juliasheet.jmd"; skwds...) \ No newline at end of file diff --git a/src/notes/Asymptotics.jmd b/src/notes/Asymptotics.jmd new file mode 100644 index 0000000..c1fc9b0 --- /dev/null +++ b/src/notes/Asymptotics.jmd @@ -0,0 +1,192 @@ +# A Asymptotics and Computational Cost + +We introduce Big-O, little-o and asymptotic notation and see +how they can be used to describe computational cost. + +1. Asymptotics as $n → ∞$ +2. Asymptotics as $x → x_0$ +3. Computational cost + +## 1. Asymptotics as $n → ∞$ + +Big-O, little-o, and "asymptotic to" are used to describe behaviour of functions +at infinity. + +**Definition (Big-O)** +$$ +f(n) = O(ϕ(n)) \qquad \hbox{(as $n → ∞$)} +$$ +means +$$ +\left|{f(n) \over ϕ(n)}\right| +$$ +is bounded for sufficiently large $n$. That is, +there exist constants $C$ and $N_0$ such +that, for all $n \geq N_0$, $|{f(n) \over ϕ(n)}| \leq C$. + +**Definition (little-O)** +$$ +f(n) = o(ϕ(n)) \qquad \hbox{(as $n → ∞$)} +$$ +means +$$ +\lim_{n → ∞} {f(n) \over ϕ(n)} = 0. +$$ + +**Definition (asymptotic to)** +$$ +f(n) ∼ ϕ(n) \qquad \hbox{(as $n → ∞$)} +$$ +means +$$ +\lim_{n → ∞} {f(n) \over ϕ(n)} = 1. +$$ + +**Examples** +$$ +{\cos n \over n^2 -1} = O(n^{-2}) +$$ +as +$$ +\left|{{\cos n \over n^2 -1} \over n^{-2}} \right| \leq \left| n^2 \over n^2 -1 \right| \leq 2 +$$ +for $n \geq N_0 = 2$. +$$ +\log n = o(n) +$$ +as +$$ +lim_{n → ∞} {\log n \over n} = 0. +$$ +$$ +n^2 + 1 ∼ n^2 +$$ +as +$$ +{n^2 +1 \over n^2} → 1. +$$ + + +Note we sometimes write $f(O(ϕ(n)))$ for a function of the form +$f(g(n))$ such that $g(n) = O(ϕ(n))$. + +### Rules + +We have some simple algebraic rules: + +**Proposition (Big-O rules)** +$$ +\begin{align*} +O(ϕ(n))O(ψ(n)) = O(ϕ(n)ψ(n)) \qquad \hbox{(as $n → ∞$)} \\ +O(ϕ(n)) + O(ψ(n)) = O(|ϕ(n)| + |ψ(n)|) \qquad \hbox{(as $n → ∞$)}. +\end{align*} +$$ + + +## 2. Asymptotics as $x → x_0$ + +We also have Big-O, little-o and "asymptotic to" at a point: + +**Definition (Big-O)** +$$ +f(x) = O(ϕ(x)) \qquad \hbox{(as $x → x_0$)} +$$ +means +$$ +|f(x) \over ϕ(x)| +$$ +is bounded in a neighbourhood of $x_0$. That is, +there exist constants $C$ and $r$ such +that, for all $0 \leq |x - x_0| \leq r$, $|{f(x) \over ϕ(x)}| \leq C$. + +**Definition (little-O)** +$$ +f(x) = o(ϕ(x)) \qquad \hbox{(as $x → x_0$)} +$$ +means +$$ +\lim_{x → x_0} {f(x) \over ϕ(x)} = 0. +$$ + +**Definition (asymptotic to)** +$$ +f(x) ∼ ϕ(x) \qquad \hbox{(as $x → x_0$)} +$$ +means +$$ +\lim_{x → x_0} {f(x) \over ϕ(x)} = 1. +$$ + +**Example** +$$ +\exp x = 1 + x + O(x^2) \qquad \hbox{as $x → 0$} +$$ +Since +$$ +\exp x = 1 + x + {\exp t \over 2} x^2 +$$ +for some $t \in [0,x]$ and +$$ +\left|{{\exp t \over 2} x^2 \over x^2}\right| \leq {3 \over 2} +$$ +provided $x \leq 1$. + + +## 3. Computational cost + +We will use Big-O notation to describe the computational cost of algorithms. +Consider the following simple sum +$$ +\sum_{k=1}^n x_k^2 +$$ +which we might implement as: +```julia +function sumsq(x) + n = length(x) + ret = 0.0 + for k = 1:n + ret = ret + x[k]^2 + end + ret +end + +n = 100 +x = randn(n) +sumsq(x) +``` +Each step of this algorithm consists of one memory look-up (`z = x[k]`), +one multiplication (`w = z*z`) and one addition (`ret = ret + w`). +We will ignore the memory look-up in the following discussion. +The number of CPU operations per step is therefore 2 (the addition and multiplication). +Thus the total number of CPU operations is $2n$. But the constant $2$ here is +misleading: we didn't count the memory look-up, thus it is more sensible to +just talk about the asymptotic complexity, that is, the _computational cost_ is $O(n)$. + +Now consider a double sum like: +$$ +\sum_{k=1}^n \sum_{j=1}^k x_j^2 +$$ +which we might implement as: +```julia +function sumsq2(x) + n = length(x) + ret = 0.0 + for k = 1:n + for j = 1:k + ret = ret + x[j]^2 + end + end + ret +end + +n = 100 +x = randn(n) +sumsq2(x) +``` + +Now the inner loop is $O(1)$ operations (we don't try to count the precise number), +which we do $k$ times for $O(k)$ operations as $k → ∞$. The outer loop therefore takes +$$ +∑_{k = 1}^n O(k) = O\left(∑_{k = 1}^n k\right) = O\left( {n (n+1) \over 2} \right) = O(n^2) +$$ +operations. \ No newline at end of file diff --git a/src/notes/Numbers.jmd b/src/notes/Numbers.jmd new file mode 100644 index 0000000..9327028 --- /dev/null +++ b/src/notes/Numbers.jmd @@ -0,0 +1,738 @@ +# Numbers + + +Reference: [Overton](https://cs.nyu.edu/~overton/book/) + +In this chapter, we introduce the [Two's-complement](https://en.wikipedia.org/wiki/Two's_complement) +storage for integers and the +[IEEE Standard for Floating-Point Arithmetic](https://en.wikipedia.org/wiki/IEEE_754). +There are many possible ways of representing real numbers on a computer, as well as +the precise behaviour of operations such as addition, multiplication, etc. +Before the 1980s each processor had potentially a different representation for +real numbers, as well as different behaviour for operations. +IEEE introduced in 1985 was a means to standardise this across +processors so that algorithms would produce consistent and reliable results. + +This chapter may seem very low level for a mathematics course but there are +two important reasons to understand the behaviour of integers and floating-point numbers: +1. Integer arithmetic can suddenly start giving wrong negative answers when numbers +become large. +2. Floating-point arithmetic is very precisely defined, and can even be used +in rigorous computations as we shall see in the problem sheets. But it is not exact +and its important to understand how errors in computations can accumulate. +3. Failure to understand floating-point arithmetic can cause catastrophic issues +in practice, with the extreme example being the +[explosion of the Ariane 5 rocket](https://youtu.be/N6PWATvLQCY?t=86). + + +In this chapter we discuss the following: + +1. Binary representation: Any real number can be represented in binary, that is, +by an infinite sequence of 0s and 1s (bits). We review binary representation. +2. Integers: There are multiple ways of representing integers on a computer. We discuss the +the different types of integers and their representation as bits, and how arithmetic operations behave +like modular arithmetic. As an advanced topic we discuss `BigInt`, which uses variable bit length storage. +2. Floating-point numbers: Real numbers are stored on a computer with a finite number of bits. +There are three types of floating-point numbers: _normal numbers_, _subnormal numbers_, and _special numbers_. +3. Arithmetic: Arithmetic operations in floating-point are exact up to rounding, and how the +rounding mode can be set. This allows us to bound errors computations. +4. High-precision floating-point numbers: As an advanced topic, we discuss how the precision of floating-point arithmetic can be increased arbitrary +using `BigFloat`. + +Before we begin, we load two external packages. SetRounding.jl allows us +to set the rounding mode of floating-point arithmetic. ColorBitstring.jl + implements functions `printbits` (and `printlnbits`) +which print the bits (and with a newline) of floating-point numbers in colour. +```julia +using SetRounding, ColorBitstring +``` + + + +## 1. Binary representation + +Any integer can be presented in binary format, that is, a sequence of `0`s and `1`s. + +**Definition** +For $B_0,\ldots,B_p \in \{0,1\}$ denote a non-negative integer in _binary format_ by: +$$ +(B_p\ldots B_1B_0)_2 := 2^pB_p + \cdots + 2B_1 + B_0 +$$ +For $b_1,b_2,\ldots \in \{0,1\}$, Denote a non-negative real number in _binary format_ by: +$$ +(B_p \ldots B_0.b_1b_2b_3\ldots)_2 = (B_p \ldots B_0)_2 + {b_1 \over 2} + {b_2 \over 2^2} + {b_3 \over 2^3} + \cdots +$$ + + + +First we show some examples of verifying a numbers binary representation: + +**Example (integer in binary)** +A simple integer example is $5 = 2^2 + 2^0 = (101)_2$. + +**Example (rational in binary)** +Consider the number `1/3`. In decimal recall that: +$$ +1/3 = 0.3333\ldots = \sum_{k=1}^\infty {3 \over 10^k} +$$ +We will see that in binary +$$ +1/3 = (0.010101\ldots)_2 = \sum_{k=1}^\infty {1 \over 2^{2k}} +$$ +Both results can be proven using the geometric series: +$$ +\sum_{k=0}^\infty z^k = {1 \over 1 - z} +$$ +provided $|z| < 1$. That is, with $z = {1 \over 4}$ we verify the binary expansion: +$$ +\sum_{k=1}^\infty {1 \over 4^k} = {1 \over 1 - 1/4} - 1 = {1 \over 3} +$$ +A similar argument with $z = 1/10$ shows the decimal case. + + + +## 2. Integers + + +On a computer one typically represents integers by a finite number of $p$ bits, +with $2^p$ possible combinations of 0s and 1s. For _unsigned integers_ (non-negative integers) +these bits are just the first $p$ binary digits: $(B_{p-1}\ldots B_1B_0)_2$. + +Integers on a computer follow [modular arithmetic](https://en.wikipedia.org/wiki/Modular_arithmetic): + +**Definition (ring of integers modulo $m$)** Denote the ring +$$ +{\mathbb Z}_{m} := \{0 \ ({\rm mod}\ m), 1 \ ({\rm mod}\ m), \ldots, m-1 \ ({\rm mod}\ m) \} +$$ + +Integers represented with $p$-bits on a computer actually +represent elements of ${\mathbb Z}_{2^p}$ and integer arithmetic on a computer is +equivalent to arithmetic modulo $2^p$. + +**Example (addition of 8-bit unsigned integers)** Consider the addition of +two 8-bit numbers: +$$ +255 + 1 = (11111111)_2 + (00000001)_2 = (100000000)_2 = 256 +$$ +The result is impossible to store in just 8-bits! It is way too slow +for a computer to increase the number of bits, or to throw an error (checks are slow). +So instead it treats the integers as elements of ${\mathbb Z}_{256}$: +$$ +255 + 1 \ ({\rm mod}\ 256) = (00000000)_2 \ ({\rm mod}\ 256) = 0 \ ({\rm mod}\ 256) +$$ +We can see this in Julia: +```julia +x = UInt8(255) +y = UInt8(1) +printbits(x); println(" + "); printbits(y); println(" = ") +printbits(x + y) +``` + + +**Example (multiplication of 8-bit unsigned integers)** +Multiplication works similarly: for example, +$$ +254 * 2 \ ({\rm mod}\ 256) = 252 \ ({\rm mod}\ 256) = (11111100)_2 \ ({\rm mod}\ 256) +$$ +We can see this behaviour in code by printing the bits: +```julia +x = UInt8(254) # 254 represented in 8-bits as an unsigned integer +y = UInt8(2) # 2 represented in 8-bits as an unsigned integer +printbits(x); println(" * "); printbits(y); println(" = ") +printbits(x * y) +``` + +### Signed integer + +Signed integers use the [Two's complemement](https://epubs.siam.org/doi/abs/10.1137/1.9780898718072.ch3) +convention. The convention is if the first bit is 1 then the number is negative: the number $2^p - y$ +is interpreted as $-y$. +Thus for $p = 8$ we are interpreting +$2^7$ through $2^8-1$ as negative numbers. + +**Example (converting bits to signed integers)** +What 8-bit integer has the bits `01001001`? Adding the corresponding decimal places we get: +```julia +2^0 + 2^3 + 2^6 +``` +What 8-bit (signed) integer has the bits `11001001`? Because the first bit is `1` we know it's a negative +number, hence we need to sum the bits but then subtract `2^p`: +```julia +2^0 + 2^3 + 2^6 + 2^7 - 2^8 +``` +We can check the results using `printbits`: +```julia +printlnbits(Int8(73)) +printbits(-Int8(55)) +``` + +Arithmetic works precisely +the same for signed and unsigned integers. + +**Example (addition of 8-bit integers)** +Consider `(-1) + 1` in 8-bit arithmetic. The number $-1$ has the same bits as +$2^8 - 1 = 255$. Thus this is equivalent to the previous question and we get the correct +result of `0`. In other words: +$$ +-1 + 1 \ ({\rm mod}\ 2^p) = 2^p-1 + 1 \ ({\rm mod}\ 2^p) = 2^p \ ({\rm mod}\ 2^p) = 0 \ ({\rm mod}\ 2^p) +$$ + + +**Example (multiplication of 8-bit integers)** +Consider `(-2) * 2`. $-2$ has the same bits as $2^{256} - 2 = 254$ and $-4$ has the +same bits as $2^{256}-4 = 252$, and hence from the previous example we get the correct result of `-4`. +In other words: +$$ +(-2) * 2 \ ({\rm mod}\ 2^p) = (2^p-2) * 2 \ ({\rm mod}\ 2^p) = 2^{p+1}-4 \ ({\rm mod}\ 2^p) = -4 \ ({\rm mod}\ 2^p) +$$ + + + + + +**Example (overflow)** We can find the largest and smallest instances of a type using `typemax` and `typemin`: +```julia +printlnbits(typemax(Int8)) # 2^7-1 = 127 +printbits(typemin(Int8)) # -2^7 = -128 +``` +As explained, due to modular arithmetic, when we add `1` to the largest 8-bit integer we get the smallest: +```julia +typemax(Int8) + Int8(1) # returns typemin(Int8) +``` +This behaviour is often not desired and is known as _overflow_, and one must be wary +of using integers close to their largest value. + + +### Variable bit representation (**advanced**) + +An alternative representation for integers uses a variable number of bits, +with the advantage of avoiding overflow but with the disadvantage of a substantial +speed penalty. In Julia these are `BigInt`s, which we can create by calling `big` on an +integer: +```julia +x = typemax(Int64) + big(1) # Too big to be an `Int64` +``` +Note in this case addition automatically promotes an `Int64` to a `BigInt`. +We can create very large numbers using `BigInt`: +```julia +x^100 +``` +Note the number of bits is not fixed, the larger the number, the more bits required +to represent it, so while overflow is impossible, it is possible to run out of memory if a number is +astronomically large: go ahead and try `x^x` (at your own risk). + + +## Division + + In addition to `+`, `-`, and `*` we have integer division `÷`, which rounds down: +```julia +5 ÷ 2 # equivalent to div(5,2) +``` +Standard division `/` (or `\` for division on the right) creates a floating-point number, +which will be discussed shortly: +```julia +5 / 2 # alternatively 2 \ 5 +``` + + We can also create rational numbers using `//`: +```julia +(1//2) + (3//4) +``` +Rational arithmetic often leads to overflow so it +is often best to combine `big` with rationals: +```julia +big(102324)//132413023 + 23434545//4243061 + 23434545//42430534435 +``` + +## 3. Floating-point numbers + +Floating-point numbers are a subset of real numbers that are representable using +a fixed number of bits. + +**Definition (floating-point numbers)** +Given integers $σ$ (the "exponential shift") $Q$ (the number of exponent bits) and +$S$ (the precision), define the set of +_Floating-point numbers_ by dividing into _normal_, _sub-normal_, and _special number_ subsets: +$$ +F_{σ,Q,S} := F^{\rm normal}_{σ,Q,S} \cup F^{\rm sub}_{σ,Q,S} \cup F^{\rm special}. +$$ +The _normal numbers_ +$F^{\rm normal}_{σ,Q,S} \subset {\mathbb R}$ are defined by +$$ +F^{\rm normal}_{σ,Q,S} = \{\pm 2^{q-σ} \times (1.b_1b_2b_3\ldots b_S)_2 : 1 \leq q < 2^Q-1 \}. +$$ +The _sub-normal numbers_ $F^{\rm sub}_{σ,Q,S} \subset {\mathbb R}$ are defined as +$$ +F^{\rm sub}_{σ,Q,S} = \{\pm 2^{1-σ} \times (0.b_1b_2b_3\ldots b_S)_2\}. +$$ +The _special numbers_ $F^{\rm special} \not\subset {\mathbb R}$ are defined later. + +Note this set of real numbers has no nice algebraic structure: it is not closed under addition, subtraction, etc. +We will therefore need to define approximate versions of algebraic operations later. + +Floating-point numbers are stored in $1 + Q + S$ total number of bits, in the format +$$ +sq_{Q-1}\ldots q_0 b_1 \ldots b_S +$$ +The first bit ($s$) is the sign bit: 0 means positive and 1 means +negative. The bits $q_{Q-1}\ldots q_0$ are the exponent bits: +they are the binary digits of the unsigned integer $q$: +$$ +q = (q_{Q-1}\ldots q_0)_2. +$$ +Finally, the bits $b_1\ldots b_S$ are the significand bits. +If $1 \leq q < 2^Q-1$ then the bits represent the normal number +$$ +x = \pm 2^{q-σ} \times (1.b_1b_2b_3\ldots b_S)_2. +$$ +If $q = 0$ (i.e. all bits are 0) then the bits represent the sub-normal number +$$ +x = \pm 2^{1-σ} \times (0.b_1b_2b_3\ldots b_S)_2. +$$ +If $q = 2^Q-1$ (i.e. all bits are 1) then the bits represent a special number, discussed +later. + + +### IEEE floating-point numbers + +**Definition (IEEE floating-point numbers)** +IEEE has 3 standard floating-point formats: 16-bit (half precision), 32-bit (single precision) and +64-bit (double precision) defined by: +$$ +\begin{align*} +F_{16} &:= F_{15,5,10} \\ +F_{32} &:= F_{127,8,23} \\ +F_{64} &:= F_{1023,11,52} +\end{align*} +$$ + +In Julia these correspond to 3 different floating-point types: + +1. `Float64` is a type representing double precision ($F_{64}$). +We can create a `Float64` by including a +decimal point when writing the number: +`1.0` is a `Float64`. `Float64` is the default format for +scientific computing (on the _Floating-Point Unit_, FPU). +2. `Float32` is a type representing single precision ($F_{32}$). We can create a `Float32` by including a +`f0` when writing the number: +`1f0` is a `Float32`. `Float32` is generally the default format for graphics (on the _Graphics Processing Unit_, GPU), +as the difference between 32 bits and 64 bits is indistinguishable to the eye in visualisation, +and more data can be fit into a GPU's limitted memory. +3. `Float16` is a type representing half-precision ($F_{16}$). +It is important in machine learning where one wants to maximise the amount of data +and high accuracy is not necessarily helpful. + + +**Example (rational in `Float32`)** How is the number $1/3$ stored in `Float32`? +Recall that +$$ +1/3 = (0.010101\ldots)_2 = 2^{-2} (1.0101\ldots)_2 = 2^{125-127} (1.0101\ldots)_2 +$$ +and since $ +125 = (1111101)_2 +$ the exponent bits are `01111101`. +. +For the significand we round the last bit to the nearest element of $F_{32}$, (this is explained in detail in +the section on rounding), so we have +$$ +1.010101010101010101010101\ldots \approx 1.01010101010101010101011 \in F_{32} +$$ +and the significand bits are `01010101010101010101011`. +Thus the `Float32` bits for $1/3$ are: +```julia +printbits(1f0/3) +``` + + +For sub-normal numbers, the simplest example is zero, which has $q=0$ and all significand bits zero: +```julia +printbits(0.0) +``` +Unlike integers, we also have a negative zero: +```julia +printbits(-0.0) +``` +This is treated as identical to `0.0` (except for degenerate operations as explained in special numbers). + + + +### Special normal numbers + +When dealing with normal numbers there are some important constants that we will use +to bound errors. + +**Definition (machine epsilon/smallest positive normal number/largest normal number)** _Machine epsilon_ is denoted +$$ +ϵ_{{\rm m},S} := 2^{-S}. +$$ +When $S$ is implied by context we use the notation $ϵ_{\rm m}$. +The _smallest positive normal number_ is $q = 1$ and $b_k$ all zero: +$$ +\min |F_{σ,Q,S}^{\rm normal}| = 2^{1-σ} +$$ +where $|A| := $\{|x| : x \in A \}$. +The _largest (positive) normal number_ is +$$ +\max F_{σ,Q,S}^{\rm normal} = 2^{2^Q-2-σ} (1.11\ldots1)_2 = 2^{2^Q-2-σ} (2-ϵ_{\rm m}) +$$ + + +We confirm the simple bit representations: +```julia +σ,Q,S = 127,23,8 # Float32 +εₘ = 2.0^(-S) +printlnbits(Float32(2.0^(1-σ))) # smallest positive Float32 +printlnbits(Float32(2.0^(2^Q-2-σ) * (2-εₘ))) # largest Float32 +``` +For a given floating-point type, we can find these constants using the following functions: +```julia +eps(Float32),floatmin(Float32),floatmax(Float32) +``` + +**Example (creating a sub-normal number)** If we divide the smallest normal number by two, we get a subnormal number: +```julia +mn = floatmin(Float32) # smallest normal Float32 +printlnbits(mn) +printbits(mn/2) +``` +Can you explain the bits? + + + + +### Special numbers + +The special numbers extend the real line by adding $\pm \infty$ but also a notion of "not-a-number". + +**Definition (not a number)** +Let ${\rm NaN}$ represent "not a number" and define +$$ +F^{\rm special} := \{\infty, -\infty, {\rm NaN}\} +$$ + +Whenever the bits of $q$ of a floating-point number are all 1 then they represent an element of $F^{\rm special}$. +If all $b_k=0$, then the number represents either $\pm\infty$, called `Inf` and `-Inf` for 64-bit floating-point numbers (or `Inf16`, `Inf32` +for 16-bit and 32-bit, respectively): +```julia +printlnbits(Inf16) +printbits(-Inf16) +``` +All other special floating-point numbers represent ${\rm NaN}$. One particular representation of ${\rm NaN}$ +is denoted by `NaN` for 64-bit floating-point numbers (or `NaN16`, `NaN32` for 16-bit and 32-bit, respectively): +```julia +printbits(NaN16) +``` +These are needed for undefined algebraic operations such as: +```julia +0/0 +``` + + +**Example (many `NaN`s)** What happens if we change some other $b_k$ to be nonzero? +We can create bits as a string and see: +```julia +i = parse(UInt16, "0111110000010001"; base=2) +reinterpret(Float16, i) +``` +Thus, there are more than one `NaN`s on a computer. + + +## 4. Arithmetic + + +Arithmetic operations on floating-point numbers are _exact up to rounding_. +There are three basic rounding strategies: round up/down/nearest. +Mathematically we introduce a function to capture the notion of rounding: + +**Definition (rounding)** ${\rm fl}^{\rm up}_{σ,Q,S} : \mathbb R \rightarrow F_{σ,Q,S}$ denotes +the function that rounds a real number up to the nearest floating-point number that is greater or equal. +${\rm fl}^{\rm down}_{σ,Q,S} : \mathbb R \rightarrow F_{σ,Q,S}$ denotes +the function that rounds a real number down to the nearest floating-point number that is greater or equal. +${\rm fl}^{\rm nearest}_{σ,Q,S} : \mathbb R \rightarrow F_{σ,Q,S}$ denotes +the function that rounds a real number to the nearest floating-point number. In case of a tie, +it returns the floating-point number whose least significant bit is equal to zero. +We use the notation ${\rm fl}$ when $σ,Q,S$ and the rounding mode are implied by context, +with ${\rm fl}^{\rm nearest}$ being the default rounding mode. + + + +In Julia, the rounding mode is specified by tags `RoundUp`, `RoundDown`, and +`RoundNearest`. (There are also more exotic rounding strategies `RoundToZero`, `RoundNearestTiesAway` and +`RoundNearestTiesUp` that we won't use.) + + + +**WARNING (rounding performance, advanced)** These rounding modes are part +of the FPU instruction set so will be (roughly) equally fast as the default, `RoundNearest`. +Unfortunately, changing the rounding mode is expensive, and is not thread-safe. + + + + +Let's try rounding a `Float64` to a `Float32`. + +```julia +printlnbits(1/3) # 64 bits +printbits(Float32(1/3)) # round to nearest 32-bit +``` +The default rounding mode can be changed: +```julia +printbits(Float32(1/3,RoundDown) ) +``` +Or alternatively we can change the rounding mode for a chunk of code +using `setrounding`. The following computes upper and lower bounds for `/`: +```julia +x = 1f0 +setrounding(Float32, RoundDown) do + x/3 +end, +setrounding(Float32, RoundUp) do + x/3 +end +``` + +**WARNING (compiled constants, advanced)**: Why did we first create a variable `x` instead of typing `1f0/3`? +This is due to a very subtle issue where the compiler is _too clever for it's own good_: +it recognises `1f0/3` can be computed at compile time, but failed to recognise the rounding mode +was changed. + +In IEEE arithmetic, the arithmetic operations `+`, `-`, `*`, `/` are defined by the property +that they are exact up to rounding. Mathematically we denote these operations as follows: +$$ +\begin{align*} +x\oplus y &:= {\rm fl}(x+y) \\ +x\ominus y &:= {\rm fl}(x - y) \\ +x\otimes y &:= {\rm fl}(x * y) \\ +x\oslash y &:= {\rm fl}(x / y) +\end{align*} +$$ +Note also that `^` and `sqrt` are similarly exact up to rounding. + + +**Example (decimal is not exact)** `1.1+0.1` gives a different result than `1.2`: +```julia +x = 1.1 +y = 0.1 +x + y - 1.2 # Not Zero?!? +``` +This is because ${\rm fl}(1.1) \neq 1+1/10$, but rather: +$$ +{\rm fl}(1.1) = 1 + 2^{-4}+2^{-5} + 2^{-8}+2^{-9}+\cdots + 2^{-48}+2^{-49} + 2^{-51} +$$ + +**WARNING (non-associative)** These operations are not associative! E.g. $(x \oplus y) \oplus z$ is not necessarily equal to $x \oplus (y \oplus z)$. +Commutativity is preserved, at least. +Here is a surprising example of non-associativity: +```julia +(1.1 + 1.2) + 1.3, 1.1 + (1.2 + 1.3) +``` +Can you explain this in terms of bits? + + +### Bounding errors in floating point arithmetic + +Before we dicuss bounds on errors, we need to talk about the two notions of errors: + +**Definition (absolute/relative error)** If $\tilde x = x + δ_{rm a} = x (1 + δ_{\rm r})$ then +$|δ_{\rm a}|$ is called the _absolute error_ and $|δ_{\rm r}|$ is called the +_relative error_ in approximating $x$ by $\tilde x$. + +We can bound the error of basic arithmetic operations in terms of machine epsilon, provided +a real number is close to a normal number: + +**Definition (normalised range)** The _normalised range_ ${\cal N}_{σ,Q,S} \subset {\mathbb R}$ +is the subset of real numbers that lies +between the smallest and largest normal floating-point number: +$$ +{\cal N}_{σ,Q,S} := \{x : \min |F_{σ,Q,S}| \leq |x| \leq \max F_{σ,Q,S} \} +$$ +When $σ,Q,S$ are implied by context we use the notation ${\cal N}$. + +We can use machine epsilon to determine bounds on rounding: + +**Proposition (rounding arithmetic)** +If $x \in {\cal N}$ then +$$ +{\rm fl}^{\rm mode}(x) = x (1 + \delta_x^{\rm mode}) +$$ +where the _relative error_ is +$$ +\begin{align*} +|\delta_x^{\rm nearest}| &\leq {ϵ_{\rm m} \over 2} \\ +|\delta_x^{\rm up/down}| &< {ϵ_{\rm m}}. +\end{align*} +$$ + + +This immediately implies relative error bounds on all IEEE arithmetic operations, e.g., +if $x+y \in {\cal N}$ then +we have +$$ +x \oplus y = (x+y) (1 + \delta_1) +$$ +where (assuming the default nearest rounding) +$ +|\delta_1| \leq {ϵ_{\rm m} \over 2}. +$ + +**Example (bounding a simple computation)** We show how to bound the error in computing +$$ +(1.1 + 1.2) + 1.3 +$$ +using floating-point arithmetic. First note that `1.1` on a computer is in +fact ${\rm fl}(1.1)$. Thus this computation becomes +$$ +({\rm fl}(1.1) \oplus {\rm fl}(1.2)) \oplus {\rm fl}(1.3) +$$ +First we find +$$ +({\rm fl}(1.1) \oplus {\rm fl}(1.2)) = (1.1(1 + δ_1) + 1.2 (1+δ_2))(1 + δ_3) + = 2.3 + 1.1 δ_1 + 1.2 δ_2 + 2.3 δ_3 + 1.1 δ_1 δ_3 + 1.2 δ_2 δ_3 + = 2.3 + δ_4 + $$ +where (note $δ_1 δ_3$ and $δ_2 δ_3$ are tiny so we just round up our bound to the nearest decimal) +$$ +|δ_4| \leq 2.3 ϵ_{\rm m} +$$ +Thus the computation becomes +$$ +((2.3 + δ_4) + 1.3 (1 + δ_5)) (1 + δ_6) = 3.6 + δ_4 + 1.3 δ_5 + 3.6 δ_6 + δ_4 δ_6 + 1.3 δ_5 δ_6 = 3.6 + δ_7 +$$ +where the _absolute error_ is +$$ +|δ_7| \leq 4.8 ϵ_{\rm m} +$$ +Indeed, this bound is bigger than the observed error: +```julia +abs(3.6 - (1.1+1.2+1.3)), 4.8eps() +``` + + +### Arithmetic and special numbers + +Arithmetic works differently on `Inf` and `NaN` and for undefined operations. +In particular we have: +```julia +1/0.0 # Inf +1/(-0.0) # -Inf +0.0/0.0 # NaN + +Inf*0 # NaN +Inf+5 # Inf +(-1)*Inf # -Inf +1/Inf # 0.0 +1/(-Inf) # -0.0 +Inf - Inf # NaN +Inf == Inf # true +Inf == -Inf # false + +NaN*0 # NaN +NaN+5 # NaN +1/NaN # NaN +NaN == NaN # false +NaN != NaN # true +``` + + +### Special functions (advanced) + +Other special functions like `cos`, `sin`, `exp`, etc. are _not_ part of the IEEE standard. +Instead, they are implemented by composing the basic arithmetic operations, which accumulate +errors. Fortunately many are designed to have _relative accuracy_, that is, `s = sin(x)` +(that is, the Julia implementation of $\sin x$) satisfies +$$ +{\tt s} = (\sin x) ( 1 + \delta) +$$ +where $|\delta| < cϵ_{\rm m}$ for a reasonably small $c > 0$, +_provided_ that $x \in {\rm F}^{\rm normal}$. +Note these special functions are written in (advanced) Julia code, for example, +[sin](https://github.com/JuliaLang/julia/blob/d08b05df6f01cf4ec6e4c28ad94cedda76cc62e8/base/special/trig.jl#L76). + + +**WARNING (sin(fl(x)) is not always close to sin(x))** This is possibly a misleading statement +when one thinks of $x$ as a real number. Consider $x = \pi$ so that $\sin x = 0$. +However, as ${\rm fl}(\pi) \neq \pi$. Thus we only have relative accuracy compared +to the floating point approximation: +```julia +π₆₄ = Float64(π) +πᵦ = big(π₆₄) # Convert 64-bit approximation of π to higher precision. Note its the same number. +abs(sin(π₆₄)), abs(sin(π₆₄) - sin(πᵦ)) # only has relative accuracy compared to sin(πᵦ), not sin(π) +``` +Another issue is when $x$ is very large: +```julia +ε = eps() # machine epsilon, 2^(-52) +x = 2*10.0^100 +abs(sin(x) - sin(big(x))) ≤ abs(sin(big(x))) * ε +``` +But if we instead compute `10^100` using `BigFloat` we get a completely different +answer that even has the wrong sign! +```julia +x̃ = 2*big(10.0)^100 +sin(x), sin(x̃) +``` +This is because we commit an error on the order of roughly +$$ +2 * 10^{100} * ϵ_{\rm m} \approx 4.44 * 10^{84} +$$ +when we round $2*10^{100}$ to the nearest float. + + +**Example (polynomial near root)** +For general functions we do not generally have relative accuracy. +For example, consider a simple +polynomial $1 + 4x + x^2$ which has a root at $\sqrt 3 - 2$. But +```julia +f = x -> 1 + 4x + x^2 +x = sqrt(3) - 2 +abserr = abs(f(big(x)) - f(x)) +relerr = abserr/abs(f(x)) +abserr, relerr # very large relative error +``` +We can see this in the error bound (note that $4x$ is exact for floating point numbers +and adding $1$ is exact for this particular $x$): +$$ +(x \otimes x \oplus 4x) + 1 = (x^2 (1 + \delta_1) + 4x)(1+\delta_2) + 1 = x^2 + 4x + 1 + \delta_1 x^2 + 4x \delta_2 + x^2 \delta_1 \delta_2 +$$ +Using a simple bound $|x| < 1$ we get a (pessimistic) bound on the absolute error of +$3 ϵ_{\rm m}$. Here `f(x)` itself is less than $2 ϵ_{\rm m}$ so this does not imply +relative accuracy. (Of course, a bad upper bound is not the same as a proof of inaccuracy, +but here we observe the inaccuracy in practice.) + + + + + + +## 5. High-precision floating-point numbers (advanced) + +It is possible to set the precision of a floating-point number +using the `BigFloat` type, which results from the usage of `big` +when the result is not an integer. +For example, here is an approximation of 1/3 accurate +to 77 decimal digits: +```julia +big(1)/3 +``` +Note we can set the rounding mode as in `Float64`, e.g., +this gives (rigorous) bounds on +`1/3`: +```julia +setrounding(BigFloat, RoundDown) do + big(1)/3 +end, setrounding(BigFloat, RoundUp) do + big(1)/3 +end +``` +We can also increase the precision, e.g., this finds bounds on `1/3` accurate to +more than 1000 decimal places: +```julia +setprecision(4_000) do # 4000 bit precision + setrounding(BigFloat, RoundDown) do + big(1)/3 + end, setrounding(BigFloat, RoundUp) do + big(1)/3 + end +end +``` +In the problem sheet we shall see how this can be used to rigorously bound ${\rm e}$, +accurate to 1000 digits. \ No newline at end of file