|
| 1 | +### A Pluto.jl notebook ### |
| 2 | +# v0.12.12 |
| 3 | + |
| 4 | +using Markdown |
| 5 | +using InteractiveUtils |
| 6 | + |
| 7 | +# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). |
| 8 | +macro bind(def, element) |
| 9 | + quote |
| 10 | + local el = $(esc(element)) |
| 11 | + global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing |
| 12 | + el |
| 13 | + end |
| 14 | +end |
| 15 | + |
| 16 | +# ╔═╡ 5b44b6ec-7863-11eb-1ed4-3d0c9eadd065 |
| 17 | +using Markdown |
| 18 | + |
| 19 | +# ╔═╡ 66ca1514-7863-11eb-2fd9-c5a2e7d1a74d |
| 20 | +using InteractiveUtils |
| 21 | + |
| 22 | +# ╔═╡ 6f5370c6-7b78-11eb-2076-45dc8e4908ae |
| 23 | +using GraphRecipes, Plots |
| 24 | + |
| 25 | +# ╔═╡ d482635e-7ab4-11eb-0d53-398ca84dab54 |
| 26 | +using DecFP |
| 27 | + |
| 28 | +# ╔═╡ 8598d0ca-7863-11eb-1549-21bc81a5cb1f |
| 29 | +md"# Fundamentals of numerical methods |
| 30 | +
|
| 31 | +The goal of this session is to provide a brief overview of the elementary ideas used in numerical methods and approximation procedures. The discussion in this section mostly focusses on sources of inexactness in computational science, which are referred to as approximations. Errors generally arise from two basic aspects of numerical operations, rounding and truncation. We will talk about truncation errors at another time, for now the focus is on rounding errors. In order to appreciate rounding errors, we need to better understand floating point numbers and computer arithmetic. " |
| 32 | + |
| 33 | +# ╔═╡ e6a2f610-7ac6-11eb-2920-0ba6b5af0ee6 |
| 34 | +md" ### Floating point numbers " |
| 35 | + |
| 36 | +# ╔═╡ f1f991e0-7864-11eb-1b11-abf2aa055858 |
| 37 | +md"In this section we introduce the idea of floating point numbers. It is not crucial for the rest of the work, but it is useful to understand. Here is a nice video that motivates the usage of floating point numbers. I like the informal way in which it is discussed in the video." |
| 38 | + |
| 39 | +# ╔═╡ e25b1a6a-7b75-11eb-06de-bdfec783caa1 |
| 40 | +html""" |
| 41 | +
|
| 42 | +<iframe width="892" height="502" src="https://www.youtube.com/embed/PZRI1IfStY0" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> |
| 43 | +
|
| 44 | +""" |
| 45 | + |
| 46 | + |
| 47 | +# ╔═╡ e6015b5c-7b75-11eb-2671-b19f7e366107 |
| 48 | +md"You might have heard the term `binary` before. This refers to a base 2 number system. Each digit can take on the value of zero or one. `bit` stands for `binary` + `digit`. A `byte` is equal to 8 `bits`. From there we have that a `kilobyte` is $$10^3$$ `bytes` and a `megabyte` is $$10^6$$ `bytes`. This pattern continues for gigabytes, terabytes, petabytes, exabytes, zetabytes and so forth." |
| 49 | + |
| 50 | +# ╔═╡ 85552d00-7865-11eb-1a94-3d5d52ed1772 |
| 51 | +md" As an aside, we can determine the amount of memory used by an object with the `Base.summarysize` command in _Julia_. I am not aware a specific function that does this in _Matlab_, there is a `whos()` funtion that returns the size of all variables in the workspace. The _Julia_ equivalent of `whos()` is `varinfo()`." |
| 52 | + |
| 53 | +# ╔═╡ 84df01a6-7861-11eb-2e3d-bd2e48f379f0 |
| 54 | +x = rand(10, 10) |
| 55 | + |
| 56 | +# ╔═╡ 6db2ed2a-7862-11eb-0053-99ca2c0cc1e6 |
| 57 | +Base.summarysize(x) |
| 58 | + |
| 59 | +# ╔═╡ 305a2bfe-7863-11eb-06c7-39c0544baece |
| 60 | +md"A fixed point number system is a computer model for integers $$\mathbb{Z}$$, while the floating number system is a computer model for real numbers $$\mathbb{R}$$. We want to essentially use a finite set to replace real numbers. The fact that the real numbers are infinite along to dimensions (continuous and uncountable) is problematic in computing. One solution is to use the floating point numbers. " |
| 61 | + |
| 62 | +# ╔═╡ 3d20faae-78c5-11eb-3250-0932a784a744 |
| 63 | +md"The floating point representation of a real number is $$\pm d_0.d_1d_2 \ldots d_p \times b^e$$. For the computer the base is $$b = 2$$ and the digits $$d_i$$ are zero or one. |
| 64 | +
|
| 65 | +In the floating number system the computer stores a `sign bit`, the `significand` and the actual `exponent bit` plus a bias. |
| 66 | +
|
| 67 | +The first bit is a `sign bit`. Then there are $11$ `exponent bits`. Finally, we have $p = 52$ bits that form the `significand`. The $52$ bit `significand` precision gives $15$ significant decimal digit precision. |
| 68 | +
|
| 69 | +The following image is retrieved from the Wipedia entry on double floating point format and helps visualise the floating point representation." |
| 70 | + |
| 71 | +# ╔═╡ 7f430c70-7b4e-11eb-3f09-7bd60114d1de |
| 72 | +md" " |
| 73 | + |
| 74 | +# ╔═╡ ed6adbd2-7b4a-11eb-2ec3-b7f98e04c983 |
| 75 | +md"From this picture you can see which parts form the `sign`, `exponent` and `significand`. " |
| 76 | + |
| 77 | +# ╔═╡ d5191c50-7b55-11eb-20c9-896d13cd253e |
| 78 | +md"In _Julia_ (and most other programming languages) `1` and `1.0` are different values, because they have different types. **Types** are incredibly important and we will talk more about them at a later stage. We can determine the type of any object by using the `typeof()` command." |
| 79 | + |
| 80 | +# ╔═╡ ee60791a-7b55-11eb-0bed-2d54e6d2f18b |
| 81 | +typeof(1) |
| 82 | + |
| 83 | +# ╔═╡ f92a2226-7b55-11eb-2dd1-bbdb6d228fef |
| 84 | +typeof(1.0) |
| 85 | + |
| 86 | +# ╔═╡ a0592f30-7b78-11eb-2482-f5eaa3a66228 |
| 87 | +md" I have plotted the type hierarchy for floating point numbers below. Don't worry if you don't understand this, I will explain in the meeting what this means." |
| 88 | + |
| 89 | +# ╔═╡ 65b2d784-7b78-11eb-063b-1b7c30edd211 |
| 90 | +begin |
| 91 | + #pyplot(size=(800, 600)) |
| 92 | + gr(size=(1000, 1000)) |
| 93 | + theme(:default) |
| 94 | + |
| 95 | + plot(AbstractFloat, method=:tree, fontsize=8, nodeshape=:ellipse) |
| 96 | +end |
| 97 | + |
| 98 | +# ╔═╡ 4e406a14-7b56-11eb-109c-6136655fc096 |
| 99 | +md"Double precision numbers are the dominant data type in scientific computing. `Float64` is the type for double precision numbers in _Julia_. As far as I know, _Matlab_ only uses the double precision floating point number. These numbers utilise $64$ bits of memory. We can use the `bitstring()` command to see the bitstring representation." |
| 100 | + |
| 101 | +# ╔═╡ fd8a93ee-7b55-11eb-0574-5fe37395446f |
| 102 | +bitstring(1.0) |
| 103 | + |
| 104 | +# ╔═╡ fa7f40a4-7b56-11eb-196f-81682455b932 |
| 105 | +md" We can access the different components of the floating point values as follows:" |
| 106 | + |
| 107 | +# ╔═╡ e4769b72-7b56-11eb-3a0f-6f19f7325ab1 |
| 108 | +g = 1.0; @show g, sign(g), exponent(g), significand(g) |
| 109 | + |
| 110 | +# ╔═╡ c29d3700-7b55-11eb-16ce-41d7accc401a |
| 111 | +md"In the example below we use a slider to give an idea of what happens as we change the value of the number. Shift the slider to see what happens with the bitstring representation." |
| 112 | + |
| 113 | +# ╔═╡ 400f0d96-7b45-11eb-1aec-df466a986bed |
| 114 | +@bind y Slider(-9.9:0.1:9.9, default=1) |
| 115 | + |
| 116 | +# ╔═╡ 535617f8-7b49-11eb-320e-8f7517146820 |
| 117 | +y |
| 118 | + |
| 119 | +# ╔═╡ a12171e6-7ac8-11eb-1961-057baa390013 |
| 120 | +typeof(y) |
| 121 | + |
| 122 | +# ╔═╡ 1fddcac8-7b48-11eb-0ed3-51b5b644e675 |
| 123 | +bitstring(y) |
| 124 | + |
| 125 | +# ╔═╡ 5f54346a-7866-11eb-3df4-658de2c2ce5f |
| 126 | +md"### Floating point arithmetic" |
| 127 | + |
| 128 | +# ╔═╡ 5cf34e4e-7867-11eb-18ff-01b71b0d5934 |
| 129 | +md"From the previous section we know that all numbers in a computer are represented in binary format (zeros and ones). This can lead to some peculiar arithmetic properties even when you have simple expressions. It is super important to know how computers work with their representation of *real numbers*, otherwise we will make many mistakes. Let us show a simple example to illustrate." |
| 130 | + |
| 131 | +# ╔═╡ ac567efc-7867-11eb-07c3-21989feec15c |
| 132 | +begin |
| 133 | + a = 0.1 |
| 134 | + b = 0.1 |
| 135 | + c = 0.1 |
| 136 | + |
| 137 | + a + b + c == 0.3 |
| 138 | +end; |
| 139 | + |
| 140 | +# ╔═╡ 31795f9a-7b7a-11eb-1786-89aad77aff4b |
| 141 | +md" The reason that we have this issue is due to rounding. Rounding is necesarry when a number has more than $p$ `significand` bits. _Julia_ offers several rounding modes, with the default being `RoundNearest`. In our example here, the number `0.1` in the decimal system cannot be represented accurately as a floating point number." |
| 142 | + |
| 143 | +# ╔═╡ de5fc23a-7b7a-11eb-12b0-a513044b39a6 |
| 144 | +bitstring(0.1) |
| 145 | + |
| 146 | +# ╔═╡ e7475a98-7b7a-11eb-00a2-63e52e403c16 |
| 147 | +md"Do you see the repeating pattern in the `significand`? Even thought `0.1` can easily be represented with only two base-10 digits, it requires an infinite number of binary digits, which is cut off." |
| 148 | + |
| 149 | +# ╔═╡ 3310e738-7ac1-11eb-38ea-2f1cfc2f0090 |
| 150 | +md"Let us illustrate with another example that exact arithmetic and computer arithmetic don't always give the same answers. Consider the following:" |
| 151 | + |
| 152 | +# ╔═╡ 8f365958-7ac1-11eb-145b-69bff762b7a8 |
| 153 | +begin |
| 154 | + e = (1e-20 + 1) - 1 |
| 155 | + f = 1e-20 + (1 - 1) |
| 156 | + e == f |
| 157 | +end; |
| 158 | + |
| 159 | +# ╔═╡ 9fb90230-7ac1-11eb-1c50-634ba7a9a7bb |
| 160 | +md" The value we obtain for `e` is actually incorrect." |
| 161 | + |
| 162 | +# ╔═╡ f3fce35a-7b77-11eb-0935-13399babee72 |
| 163 | +e; |
| 164 | + |
| 165 | +# ╔═╡ f80d6c4e-7b77-11eb-31bc-d55c9905b0a6 |
| 166 | +f; |
| 167 | + |
| 168 | +# ╔═╡ fbf35d0a-7b77-11eb-3b36-194f011f00ab |
| 169 | +md" Even though the statements are mathematically the same (by the associative property of addition and subtraction), if we compare the values we see that `e` > `f`. In this case this is because adding numbers of different magnitudes does not always work like you would want. In the example, when we added $10^{-20}$ to $1$, it got rounded away. " |
| 170 | + |
| 171 | +# ╔═╡ 0b370ade-7b5d-11eb-14ae-8fb84aa69edc |
| 172 | +md"Another class of problems using floating point arithmentic is illustrated in the following example:" |
| 173 | + |
| 174 | +# ╔═╡ 19fd463c-7b5d-11eb-342c-293f27a0f396 |
| 175 | +begin |
| 176 | + h = 100000.2 |
| 177 | + i = 100000.1 |
| 178 | +end; |
| 179 | + |
| 180 | +# ╔═╡ 2f54327a-7b5d-11eb-0352-e713aba2460d |
| 181 | +h - i; |
| 182 | + |
| 183 | +# ╔═╡ 3a62156a-7b5d-11eb-1b66-a9d7d71d1051 |
| 184 | +md"Think about what you would expect the answer to the calculation to be. Did you get it right?" |
| 185 | + |
| 186 | +# ╔═╡ 96d3fed8-7b7b-11eb-1434-07da91c27aca |
| 187 | +md" What about the following example. Think about what the result should be and what the computer calculates. Did you get this one right? " |
| 188 | + |
| 189 | +# ╔═╡ c5f3dde8-7b7b-11eb-3a14-bbe7f374c856 |
| 190 | +begin |
| 191 | + j = 2.0^30 # Very large number |
| 192 | + k = 2.0^-30 # Very small number |
| 193 | + j + k == j |
| 194 | +end; |
| 195 | + |
| 196 | +# ╔═╡ 2a044f08-7b7b-11eb-19fc-9fe29ad589bf |
| 197 | +md"Both of the examples above showcase the idea of **catastrophic cancellation**. In the first instance the subtraction of two nearly equal numbers eleminates significant digits (since the numbers can't be precisely represented by the machine) and in the second case there is a potential loss of precision when subtracting close real numbers that are represented by floats. |
| 198 | +
|
| 199 | +For the first example we see that the values are approximately equal, as shown below." |
| 200 | + |
| 201 | +# ╔═╡ 8b29e5b4-7b7f-11eb-2679-bd248ed2d88b |
| 202 | +isapprox(100000.2 - 100000.1, 0.1) |
| 203 | + |
| 204 | +# ╔═╡ 0f9373f0-78c5-11eb-26ba-05bea8874141 |
| 205 | +md" These examples makes it somewhat difficult for us to trust calculations if we don't know what the pitfalls are. Look at the following investment calculation. Can we trust this answer?" |
| 206 | + |
| 207 | +# ╔═╡ 3933c4ee-78c5-11eb-2692-7989afac7ebb |
| 208 | +begin |
| 209 | + interest = 0.04 # Interest rate |
| 210 | + compounding = 365 * 24 # Compounded every hour for 365 days |
| 211 | + investment = 10e9 # Initial investment of R1 billion |
| 212 | + t = 100 # Time invested (100 years) |
| 213 | + daily = 1 + interest / compounding # Daily return |
| 214 | + sum = investment * (daily ^ (compounding * t)) # Simple investment calculation |
| 215 | +end; |
| 216 | + |
| 217 | +# ╔═╡ 6dda76f6-78c6-11eb-0fe0-a36a5663dfd7 |
| 218 | +md"We have done the calculation using floating point numbers, now we use the precise decimal representation for a comparison." |
| 219 | + |
| 220 | +# ╔═╡ add65ba2-78c7-11eb-0eb6-771466c0c417 |
| 221 | +import Pkg; Pkg.add("DecFP") |
| 222 | + |
| 223 | +# ╔═╡ 844fa292-7b48-11eb-0f9c-c521a4125ce6 |
| 224 | +Pkg.add("PlutoUI"); using PlutoUI |
| 225 | + |
| 226 | +# ╔═╡ 70ab6652-7ab4-11eb-1309-8f833821ef88 |
| 227 | +begin |
| 228 | + interest_1 = Dec64(interest) |
| 229 | + daily_1 = 1 + interest_1 / compounding |
| 230 | + investment_1 = Dec64(investment) |
| 231 | + sum_1 = investment_1*(daily_1 ^ (compounding * t)) # Using exact decimals |
| 232 | +end; |
| 233 | + |
| 234 | +# ╔═╡ 3cf74998-78c5-11eb-1191-a9f56dbadda6 |
| 235 | +md"Compare the results and see if there is a significant difference. " |
| 236 | + |
| 237 | +# ╔═╡ 3cfda932-78c5-11eb-3ad9-512459ffebc4 |
| 238 | +diff = sum_1 - Dec64(sum); |
| 239 | + |
| 240 | +# ╔═╡ 3d11b968-78c5-11eb-3962-f50b8e05803d |
| 241 | +md" Do you expect there to be any difference between the answers?" |
| 242 | + |
| 243 | +# ╔═╡ 3d198bac-78c5-11eb-35af-87b99956e4de |
| 244 | +md"We have to realise that real numbers are only presented with a certain precision. Most of the time we don't need to worry, but we want to make sure our code is robust. In other words, we shouldn't be surprised by the outcome of our code. The **numerical stability** of our code is important! " |
| 245 | + |
| 246 | +# ╔═╡ 9d74de0e-7ac6-11eb-10c2-e3ac9cf17111 |
| 247 | +md" One could also have **overflow** (**underflow**) problems. In these instances, this entails a real number that is too large (indistinguishable from zero)." |
| 248 | + |
| 249 | +# ╔═╡ 7bd38294-7b7c-11eb-0329-99e46b366e1b |
| 250 | +md" ## Rules for numerical computation " |
| 251 | + |
| 252 | +# ╔═╡ 64484bfa-7b7c-11eb-1d40-296fcf167f53 |
| 253 | +md" Some basic rules that we want to follow when doing computation. |
| 254 | +
|
| 255 | +1. Add small numbers together before adding larger ones |
| 256 | +2. Add numbers of like magnitude together. This is called pairing. |
| 257 | +3. Avoid subtraction of two numbers that are nearly equal. (Subtractive cancellation)" |
| 258 | + |
| 259 | +# ╔═╡ 0ff8fb0c-7b84-11eb-2a6a-0dedd44b3c7b |
| 260 | +md" Note that subtractive cancellation is one of the most common mechanisms introducing dramatic growth of errors in floating point computation " |
| 261 | + |
| 262 | +# ╔═╡ cc6069f2-7b7c-11eb-3cb9-afbd773708e2 |
| 263 | +md" You could have saved a lot of time and just looked at these rules, but the examples give an idea as to why you might want to implement the rules in the first place." |
| 264 | + |
| 265 | +# ╔═╡ 18b49d34-7b80-11eb-3b12-3774bdf47ae6 |
| 266 | +md" We will encounter more types of errors in approximation in the future, especially when we talk about calculating derivatives. Then we will introduce ways in which we can quantify the error with different metrics. However, I think this is enough information for one session. Your next step is to look at some of the exercises below." |
| 267 | + |
| 268 | +# ╔═╡ b2b0b842-7b57-11eb-1727-95c07b5b2de6 |
| 269 | +md" ## Exercises |
| 270 | +
|
| 271 | +For the first few exercises let's check whether floating-point numbers obey certain algebraic rules. For 2-5, one couterexample will suffice. |
| 272 | +
|
| 273 | +1. The associative rule for addition says `(x + y) + z == x + (y + z)`. Check this rule using `x = 0.1`, `y = 0.1` and `z = 1.0`. Explain what you find. |
| 274 | +2. Do floating-point numbers obey the associative rule for multiplication: `(x * y) * z == x * (y * z)`? |
| 275 | +3. Do floating-point numbers obey the distributive rule: `a * (x + y) == a * x + a * y`? |
| 276 | +4. Is `0 * x == 0` true for all `x` (where `x` is a floating point number)? |
| 277 | +5. Is `x / a == x * (1 / a)` always true?" |
| 278 | + |
| 279 | +# ╔═╡ 7779ed4c-7b7d-11eb-034b-5fe2925df5df |
| 280 | +md" 6. **[Hard]** In this problem we will use `for loops`, so be sure that you have an idea of how to use loops. We can expect floating point errors to accumulate randomly during computation, creating what is known as a **random walk**. On average we expect the errors to partially cancel out. Suppose you define a random sequence by $x_0 = 0$ and $x_n = x_{n-1} \pm 1$ with the signs chosen by tossing a fair coin for each $n$. et $\alpha_n$ and $\beta_n$ be the average value of $x_n$ and $|x_n|$ respectively over all such walks. Then a classic result of probability is that $\alpha_n = 0$ and $\lim_{n\rightarrow \infty} \frac{\pi \beta^{2}_{n}}{2n} = 1$. Perform a million random walks" |
| 281 | + |
| 282 | +# ╔═╡ Cell order: |
| 283 | +# ╟─8598d0ca-7863-11eb-1549-21bc81a5cb1f |
| 284 | +# ╠═5b44b6ec-7863-11eb-1ed4-3d0c9eadd065 |
| 285 | +# ╠═66ca1514-7863-11eb-2fd9-c5a2e7d1a74d |
| 286 | +# ╠═844fa292-7b48-11eb-0f9c-c521a4125ce6 |
| 287 | +# ╟─e6a2f610-7ac6-11eb-2920-0ba6b5af0ee6 |
| 288 | +# ╟─f1f991e0-7864-11eb-1b11-abf2aa055858 |
| 289 | +# ╟─e25b1a6a-7b75-11eb-06de-bdfec783caa1 |
| 290 | +# ╟─e6015b5c-7b75-11eb-2671-b19f7e366107 |
| 291 | +# ╟─85552d00-7865-11eb-1a94-3d5d52ed1772 |
| 292 | +# ╠═84df01a6-7861-11eb-2e3d-bd2e48f379f0 |
| 293 | +# ╠═6db2ed2a-7862-11eb-0053-99ca2c0cc1e6 |
| 294 | +# ╟─305a2bfe-7863-11eb-06c7-39c0544baece |
| 295 | +# ╟─3d20faae-78c5-11eb-3250-0932a784a744 |
| 296 | +# ╟─7f430c70-7b4e-11eb-3f09-7bd60114d1de |
| 297 | +# ╟─ed6adbd2-7b4a-11eb-2ec3-b7f98e04c983 |
| 298 | +# ╟─d5191c50-7b55-11eb-20c9-896d13cd253e |
| 299 | +# ╠═ee60791a-7b55-11eb-0bed-2d54e6d2f18b |
| 300 | +# ╠═f92a2226-7b55-11eb-2dd1-bbdb6d228fef |
| 301 | +# ╟─a0592f30-7b78-11eb-2482-f5eaa3a66228 |
| 302 | +# ╟─6f5370c6-7b78-11eb-2076-45dc8e4908ae |
| 303 | +# ╟─65b2d784-7b78-11eb-063b-1b7c30edd211 |
| 304 | +# ╟─4e406a14-7b56-11eb-109c-6136655fc096 |
| 305 | +# ╠═fd8a93ee-7b55-11eb-0574-5fe37395446f |
| 306 | +# ╟─fa7f40a4-7b56-11eb-196f-81682455b932 |
| 307 | +# ╠═e4769b72-7b56-11eb-3a0f-6f19f7325ab1 |
| 308 | +# ╟─c29d3700-7b55-11eb-16ce-41d7accc401a |
| 309 | +# ╟─400f0d96-7b45-11eb-1aec-df466a986bed |
| 310 | +# ╟─535617f8-7b49-11eb-320e-8f7517146820 |
| 311 | +# ╟─a12171e6-7ac8-11eb-1961-057baa390013 |
| 312 | +# ╟─1fddcac8-7b48-11eb-0ed3-51b5b644e675 |
| 313 | +# ╟─5f54346a-7866-11eb-3df4-658de2c2ce5f |
| 314 | +# ╟─5cf34e4e-7867-11eb-18ff-01b71b0d5934 |
| 315 | +# ╠═ac567efc-7867-11eb-07c3-21989feec15c |
| 316 | +# ╟─31795f9a-7b7a-11eb-1786-89aad77aff4b |
| 317 | +# ╠═de5fc23a-7b7a-11eb-12b0-a513044b39a6 |
| 318 | +# ╟─e7475a98-7b7a-11eb-00a2-63e52e403c16 |
| 319 | +# ╟─3310e738-7ac1-11eb-38ea-2f1cfc2f0090 |
| 320 | +# ╠═8f365958-7ac1-11eb-145b-69bff762b7a8 |
| 321 | +# ╟─9fb90230-7ac1-11eb-1c50-634ba7a9a7bb |
| 322 | +# ╠═f3fce35a-7b77-11eb-0935-13399babee72 |
| 323 | +# ╠═f80d6c4e-7b77-11eb-31bc-d55c9905b0a6 |
| 324 | +# ╟─fbf35d0a-7b77-11eb-3b36-194f011f00ab |
| 325 | +# ╟─0b370ade-7b5d-11eb-14ae-8fb84aa69edc |
| 326 | +# ╠═19fd463c-7b5d-11eb-342c-293f27a0f396 |
| 327 | +# ╠═2f54327a-7b5d-11eb-0352-e713aba2460d |
| 328 | +# ╟─3a62156a-7b5d-11eb-1b66-a9d7d71d1051 |
| 329 | +# ╟─96d3fed8-7b7b-11eb-1434-07da91c27aca |
| 330 | +# ╠═c5f3dde8-7b7b-11eb-3a14-bbe7f374c856 |
| 331 | +# ╟─2a044f08-7b7b-11eb-19fc-9fe29ad589bf |
| 332 | +# ╠═8b29e5b4-7b7f-11eb-2679-bd248ed2d88b |
| 333 | +# ╟─0f9373f0-78c5-11eb-26ba-05bea8874141 |
| 334 | +# ╠═3933c4ee-78c5-11eb-2692-7989afac7ebb |
| 335 | +# ╟─6dda76f6-78c6-11eb-0fe0-a36a5663dfd7 |
| 336 | +# ╠═add65ba2-78c7-11eb-0eb6-771466c0c417 |
| 337 | +# ╠═d482635e-7ab4-11eb-0d53-398ca84dab54 |
| 338 | +# ╠═70ab6652-7ab4-11eb-1309-8f833821ef88 |
| 339 | +# ╟─3cf74998-78c5-11eb-1191-a9f56dbadda6 |
| 340 | +# ╠═3cfda932-78c5-11eb-3ad9-512459ffebc4 |
| 341 | +# ╟─3d11b968-78c5-11eb-3962-f50b8e05803d |
| 342 | +# ╟─3d198bac-78c5-11eb-35af-87b99956e4de |
| 343 | +# ╟─9d74de0e-7ac6-11eb-10c2-e3ac9cf17111 |
| 344 | +# ╟─7bd38294-7b7c-11eb-0329-99e46b366e1b |
| 345 | +# ╟─64484bfa-7b7c-11eb-1d40-296fcf167f53 |
| 346 | +# ╟─0ff8fb0c-7b84-11eb-2a6a-0dedd44b3c7b |
| 347 | +# ╟─cc6069f2-7b7c-11eb-3cb9-afbd773708e2 |
| 348 | +# ╟─18b49d34-7b80-11eb-3b12-3774bdf47ae6 |
| 349 | +# ╟─b2b0b842-7b57-11eb-1727-95c07b5b2de6 |
| 350 | +# ╟─7779ed4c-7b7d-11eb-034b-5fe2925df5df |
0 commit comments