Jekyll2019-06-28T18:54:58+00:00https://hugogranstrom.com/feed.xmlHugo Granström - Math, Phyics and Python BlogMy Python programming, math and physics blogHugo GranströmMath Codified - Derivatives2018-12-08T00:00:00+00:002018-12-08T00:00:00+00:00https://hugogranstrom.com/math-codified-derivatives<p>This equation is probably somewhat familiar to most people who have studied a bit of calculus: <script type="math/tex">f'(x) = \lim_{h \to 0}\frac{f(x+h)-f(x)}{h}</script>. Today we are breaking it down and converting it to code to really see how this works, when the math notation has been stripped off.</p>
<p>To start with, how do we calculate the gradient (slope) of a function? We take the difference in y divided by the difference in x: <script type="math/tex">\frac{\Delta y}{\Delta x} = \frac{y_2-y_1}{x_2-x_1} = \frac{f(x_2)-f(x_1)}{x_2-x_1}</script></p>
<p>If our function is a straight line this will work no matter which <script type="math/tex">x_2</script> and <script type="math/tex">x_1</script> we choose (as long as <script type="math/tex">x_2 > x_1</script>, otherwise we get the wrong sign). If our function instead for example is a quadratic equation, we will not get the the gradient in a point, but the average gradient in a segment of the function. The smaller we make the distance between <script type="math/tex">x_2</script> and <script type="math/tex">x_1</script> the better of an approximation it will be for the function’s gradient at a certain point. This is where the <script type="math/tex">\lim_{h \to 0}</script> comes in. <script type="math/tex">h</script> is the difference between <script type="math/tex">x_2</script> and <script type="math/tex">x_1</script> and when it approaches <script type="math/tex">0</script> the result becomes the gradient at a single point <script type="math/tex">x</script>. The reason we only have a <script type="math/tex">h</script> in the denominator is because the x’s cancel out: <script type="math/tex">(x+h)-x = h</script>.</p>
<p>Now to the part you probably came here to read. Translating this math expression to a piece of code-cake:</p>
<p>Let’s first create a python function for our math-function. I choose the equation <script type="math/tex">f(x)=x^2</script></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="n">x</span><span class="o">**</span><span class="mi">2</span>
</code></pre></div></div>
<p>Next let’s define h, the very small difference between <script type="math/tex">x_2</script> and <script type="math/tex">x_1</script>. We can’t set it to 0 because we can’t divide by 0. So we choose a very small number instead, namely <script type="math/tex">h = 10^{-6}</script>:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">h</span> <span class="o">=</span> <span class="mi">10</span><span class="o">**-</span><span class="mi">6</span>
</code></pre></div></div>
<p>Now we have the <script type="math/tex">\lim_{h \to 0}</script> and f(x) part sorted. Now it’s time to define our python representation of <script type="math/tex">f(x)'</script>:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">derivative</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="n">x2</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">h</span>
<span class="n">y2</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">x2</span><span class="p">)</span>
<span class="n">x1</span> <span class="o">=</span> <span class="n">x</span>
<span class="n">y1</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">x1</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="p">(</span><span class="n">y2</span> <span class="o">-</span> <span class="n">y1</span><span class="p">)</span><span class="o">/</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">gradient</span><span class="p">)</span>
<span class="k">return</span> <span class="n">gradient</span>
</code></pre></div></div>
<p>If we test to call the derivative function with a x-value we can check if it work. The derivative function of <script type="math/tex">x^2</script> is <script type="math/tex">2x</script>:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">derivative</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="c"># returns 4.0000010006480125</span>
</code></pre></div></div>
<p>The actual value is 4 but this is a pretty good approximation I would say (it’s first at the 6’th decimal it gets it wrong). To get even more accurate results, choose a smaller <script type="math/tex">h</script>.</p>
<h2 id="how-to-choose-a-good-h">How to choose a good <script type="math/tex">h</script>?</h2>
<p>You may think that if you choose a really really small <script type="math/tex">h</script> like <script type="math/tex">10^{-100}</script> that you would get a super good approximation of the derivative. That would have been really nice but sadly normal computers can’t handle extremely small numbers at the same time as it handles large one. For example has Python no problems handling <script type="math/tex">10^{-100}</script> on it’s own put if you add it to <script type="math/tex">1</script> it is too small comparatively:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">print</span><span class="p">(</span><span class="mf">1e-100</span><span class="p">)</span> <span class="c"># same as 1 * 10 ** -100</span>
<span class="c"># prints: 1e-100</span>
<span class="k">print</span><span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="mf">1e-100</span><span class="p">)</span>
<span class="c"># prints: 1.0</span>
</code></pre></div></div>
<p>The reason for this is that computers save numbers with limited precision. Just like we for example can’t write <script type="math/tex">1/3 = 0.3333333333...</script> the entire decimal expansion on paper your computer can’t save all numbers exactly. The smallest number you can have between to two numbers is called machine epsilon and is denoted <script type="math/tex">\epsilon_M</script>. On a 64-bit computer a float (double precision to be more exact) has a <script type="math/tex">\epsilon_M \approx 2.2 * 10^{-16}</script>. If you want to get the machine epsilon on your machine using Python you can get it with numpy:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="n">eps</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">finfo</span><span class="p">(</span><span class="nb">float</span><span class="p">)</span><span class="o">.</span><span class="n">eps</span>
</code></pre></div></div>
<p>Now you may wonder why I have brought this up, what does it have to do with choosing a good <script type="math/tex">h</script>? The answer to that question is that we don’t want our h to be too close to <script type="math/tex">\epsilon_M</script> because then our computer won’t be able to see a difference between <script type="math/tex">f(x+h)</script> and <script type="math/tex">f(x)</script> (remember what the definition of <script type="math/tex">\epsilon_M</script> was?) and then <script type="math/tex">f(x+h)-f(x) = 0</script> which we don’t want. So how are we supposed to choose <script type="math/tex">h</script> then, what is small enough to get a good approximation while not being to close to <script type="math/tex">\epsilon_M</script>.</p>
<p><script type="math/tex">h = \sqrt{\epsilon_M} * x</script> happens to be a good choice. Here <script type="math/tex">x</script> is the x-value we want to evaluate the derivative of f(x) at. This works when <script type="math/tex">x \neq 0</script> because then <script type="math/tex">h = 0</script> which is problematic. We will have to add a check for that in our function. In Python we can modify our derivate function:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="k">def</span> <span class="nf">derivative</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">if</span> <span class="n">x</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">eps</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">finfo</span><span class="p">(</span><span class="nb">float</span><span class="p">)</span><span class="o">.</span><span class="n">eps</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">eps</span><span class="o">**</span><span class="mf">0.5</span> <span class="o">*</span> <span class="n">x</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">h</span> <span class="o">=</span> <span class="mf">1e-6</span>
<span class="n">x2</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">h</span>
<span class="n">y2</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">x2</span><span class="p">)</span>
<span class="n">x1</span> <span class="o">=</span> <span class="n">x</span>
<span class="n">y1</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">x1</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="p">(</span><span class="n">y2</span> <span class="o">-</span> <span class="n">y1</span><span class="p">)</span><span class="o">/</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">gradient</span><span class="p">)</span>
<span class="k">return</span> <span class="n">gradient</span>
</code></pre></div></div>
<p>Now our function chooses an appropriate <script type="math/tex">h</script> by itself. Cool, right!?</p>
<h2 id="are-there-more-accurate-methods">Are there more accurate methods?</h2>
<p>This is a question you may ask yourself. Are there any other, better ways to calculate the derivative of a function? The answer is: Yes there are! Instead of calculating the value of the function in <script type="math/tex">x</script> and <script type="math/tex">x+h</script> we now calculate it in <script type="math/tex">x-h</script> and <script type="math/tex">x+h</script>. This gives a <script type="math/tex">h = (x+h) - (x-h) = 2h</script>. The formula becomes:
<script type="math/tex">f'(x) = \frac{f(x+h) - f(x-h)}{2h}</script>. It doesn’t look that different from our old formula but it is actually more accurate. If we write it in Python using everything we have learned so far:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="k">def</span> <span class="nf">cool_function</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="n">x</span><span class="p">))</span> <span class="c"># f(x) = sin(e^x)</span>
<span class="k">def</span> <span class="nf">derivative</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
<span class="k">if</span> <span class="n">x</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">eps</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">finfo</span><span class="p">(</span><span class="nb">float</span><span class="p">)</span><span class="o">.</span><span class="n">eps</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">eps</span><span class="o">**</span><span class="mf">0.5</span> <span class="o">*</span> <span class="n">x</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">h</span> <span class="o">=</span> <span class="mf">1e-6</span>
<span class="n">x1</span> <span class="o">=</span> <span class="n">x</span> <span class="o">-</span> <span class="n">h</span>
<span class="n">x2</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">h</span>
<span class="n">y1</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">x1</span><span class="p">)</span>
<span class="n">y2</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">x2</span><span class="p">)</span>
<span class="n">gradient</span> <span class="o">=</span> <span class="p">(</span><span class="n">y2</span> <span class="o">-</span> <span class="n">y1</span><span class="p">)</span><span class="o">/</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="n">h</span><span class="p">)</span>
<span class="k">return</span> <span class="n">gradient</span>
</code></pre></div></div>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">derivative</span><span class="p">(</span><span class="n">cool_function</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span> <span class="c"># calculate the derivative of cool_function in x=3</span>
<span class="c"># returns: 6.600002091377974 </span>
</code></pre></div></div>
<p>The correct value is roughly 6.60000209300594833 so it’s a really good approximation. Our first method give the approximation 6.599993718167146 which isn’t far off either but it’s still 3 orders of magnitude less accurate than our second method.</p>
<p>It still begs the question: are there even more accurate methods? The answer is: Yes! But I won’t cover them in this article. I will leave you with one of them though, and it’s up to you to implement it in Python:</p>
<script type="math/tex; mode=display">f'(x) = \frac{-f(x + 2h) + 8f(x+h) - 8f(x-h) + f(x-2h)}{12h}</script>
<p>(Note: that this method appears to be more accurate then the previous one when <script type="math/tex">h</script> is bigger then <script type="math/tex">10^{-6}</script>. When it becomes smaller the inaccuracy becomes larger because we are adding more rounding errors together then we are in the others)</p>
<p>That was it. I hope you enjoyed this and learned something new. My hope is that if you have experience in programming but you didn’t fully understand derivatives in school, that this article helped you grasp it better.</p>Hugo GranströmThis equation is probably somewhat familiar to most people who have studied a bit of calculus: . Today we are breaking it down and converting it to code to really see how this works, when the math notation has been stripped off.Showing that 0.999… = 1 using geometric sums2018-07-31T00:00:00+00:002018-07-31T00:00:00+00:00https://hugogranstrom.com/0.999-equals-1<p>If you have browsed a forum where math is discussed, it is likely you have seen people claiming both that <script type="math/tex">0.999... = 1</script> and <script type="math/tex">0.999... \neq 1</script>. Today I will show you that the first one is correct using geometric sums. You don’t need to take my word for it, you will be able to prove it yourself.</p>
<h2 id="geometric-sums">Geometric Sums</h2>
<p>“What is a geometric sum?”, you may ask. Keep calm, I will get you covered. A geometric sum is a sum where the first term is a number, let’s call it <script type="math/tex">a_1</script> and the second term is a constant, <script type="math/tex">k</script>, times the first term, so <script type="math/tex">a_1*k</script>. The third term is the second term times the same constant so it becomes <script type="math/tex">a_1*k*k = a_1*k^2</script>. And then it continues like that for as long as we want to calculate the sum. If we want to calculate the sum of the first 5 terms the last one would be <script type="math/tex">a_1*k^4</script> because the first term don’t have a <script type="math/tex">k</script> in it. Generally the last term thus becomes <script type="math/tex">a_1*k^{n-1}</script> if we want to take the sum of the <script type="math/tex">n</script> first terms. A geometric sum is of the form:</p>
<script type="math/tex; mode=display">S_n = a_1 + a_1*k + a_1*k^2 + a_1*k^3 + a_1*k^4 + ... + a_1*k^{n-2} + a_1*k^{n-1}</script>
<p>Here <script type="math/tex">S_n</script> stands for “the sum of the <script type="math/tex">n</script> first terms”. The terms are quite similar so it isn’t to farfetched to think that there is a formula to calculate the the sum given only <script type="math/tex">a_1</script>, <script type="math/tex">k</script> and <script type="math/tex">n</script>. There is in fact a formula but I won’t just give it to you, we will derive it ourself to have a stable foundation for our argument.</p>
<h2 id="deriving-the-formula-for-a-geometric-sum">Deriving the formula for a Geometric Sum</h2>
<p>We start out with the equation for a general geometric sum:</p>
<script type="math/tex; mode=display">S_n = a_1 + a_1*k + a_1*k^2 + a_1*k^3 + a_1*k^4 + ... + a_1*k^{n-2} + a_1*k^{n-1}</script>
<p>Then we multiply both sides by <script type="math/tex">k</script>:</p>
<script type="math/tex; mode=display">k*S_n = a_1*k + a_1*k^2 + a_1*k^3 + a_1*k^4 + a_1*k^5 + ... + a_1*k^{n-1} + a_1*k^n</script>
<p>The reason we did this is because now we can see that the right side of the equation is nearly the same as it was before except <script type="math/tex">a_1</script> is missing and we have a new term, <script type="math/tex">a_1*k^n</script>. We can then utilize that fact to rewrite the equation like this:</p>
<script type="math/tex; mode=display">k*S_n = S_n + a_1*k^n - a_1</script>
<p>This is much neater, right? Now all we have to do is to solve for <script type="math/tex">S_n</script>. We start by subtracting <script type="math/tex">S_n</script> from both sides:</p>
<script type="math/tex; mode=display">k*S_n - S_n = a_1*k^n - a_1</script>
<p>Then we factor both sides by them self:</p>
<script type="math/tex; mode=display">S_n(k - 1) = a_1(k^n - 1)</script>
<p>Dividing by <script type="math/tex">(k-1)</script> will give us our formula:</p>
<script type="math/tex; mode=display">S_n = a_1 \frac{k^n - 1}{k - 1}</script>
<p>There we have it, a simple formula for calculating a geometric sum.</p>
<h2 id="lets-tackle-the-question">Let’s tackle the question</h2>
<p>I said we would show that <script type="math/tex">0.999... = 1</script> so let’s cut to the action. First what does <script type="math/tex">0.999...</script> really mean? In this context it means that the pattern shown will continue forever. In other words that there is an infinite amount of 9’s after the decimal sign. Just a quick reflection here: Is there any real number between 1 and 0.999…? Independent of your answer, what implications would that have? Think about it, and experiment. That’s how new mathematics are invented, people playing around with the rules of math. “What happens if I ignore that?” and “How would this work if it was like this” are questions reasonable to wonder about. Complex numbers (they are as real as the real numbers, not imaginary in any way) were found this way, when someone thought “What if negative numbers have a square root” and just rolled along.</p>
<p>Must have been an uneven cut because we seems to have sidetracked a bit from the action. 0.999… can if we separate every digit into a 9 times a power of a 10th be written as:</p>
<script type="math/tex; mode=display">0 + 9 \frac{1}{10} + 9 \frac{1}{10^2} + 9 \frac{1}{10^3} ...</script>
<p>This looks looks like a geometric sum, who could have guessed? <script type="math/tex">a_1</script> in this case is <script type="math/tex">9\frac{1}{10}</script>, <script type="math/tex">k</script> is <script type="math/tex">\frac{1}{10}</script> and <script type="math/tex">n</script> is <script type="math/tex">\infty</script>. We have a slight problem here: <script type="math/tex">n</script> is <script type="math/tex">\infty</script>. Let’s see how our formula handles that.</p>
<script type="math/tex; mode=display">S_n = a_1 \frac{k^n - 1}{k - 1}</script>
<p>If <script type="math/tex">k</script> is larger than or equal to 1, then the sum diverges and it doesn’t have a defined sum. If on the other hand <script type="math/tex">% <![CDATA[
k < 1 %]]></script>, then the sum converges. We can in fact simplify the formula when <strong>both</strong> <script type="math/tex">n = \infty</script> <strong>and</strong> <script type="math/tex">% <![CDATA[
k < 1 %]]></script> because <script type="math/tex">k^n</script> then becomes 0 at the limit:</p>
<script type="math/tex; mode=display">lim_{n\to\infty} a_1\frac{k^n-1}{k-1} = a_1\frac{0-1}{k-1} = \frac{-a_1}{k-1} = \frac{-a_1}{-(1-k)} = \frac{a_1}{1-k}</script>
<p>There we have a really nice and simple formula. It is quite remarkable that we can calculate something that has an infinite component using such a simple and beautiful formula. If we now insert our values into it we get:</p>
<script type="math/tex; mode=display">\frac{a_1}{1-k} = \frac{\frac{9}{10}}{1-\frac{1}{10}} = \frac{\frac{9}{10}}{\frac{9}{10}} = 1</script>
<p>There we have it! We have showed that <script type="math/tex">0.999... = 1</script> using a geometric sum. If someone ever tells you that it isn’t true, prove it to them yourself. You have all the tools you need for that now.</p>
<p>Can you come up with any other “debate-able” sequence of decimals that can be proven to be something using geometric sums? If you do, please let me know in the comments. Have a nice day and remember that the human fantasy is limitless (but not undefined).</p>Hugo GranströmIf you have browsed a forum where math is discussed, it is likely you have seen people claiming both that and . Today I will show you that the first one is correct using geometric sums. You don’t need to take my word for it, you will be able to prove it yourself.Making sense of the Monty Hall Problem2018-07-30T00:00:00+00:002018-07-30T00:00:00+00:00https://hugogranstrom.com/making-sense-monty-hall<p>The Monty Hall problem is a quiet famous problem where most people’s intuition are wrong. There are many variations of it but I will use one with playing card. It goes like this:</p>
<p><em>You and a friend sit at a table opposite of each other. On the table there are three faced down playing cards, one king and two knights. Your friend knows which card is which but you have no idea. The ultimate goal in this game is to figure out which card is the king. First you get to choose one of the cards, and you tell your friend which. He/She then flips one of the other card two cards and it is a knight. You are now offered to stay with the card you chose at first or to switch to the second faced down card. Which of these choices has the greatest probability of you picking the king?</em></p>
<p>Most people unfamiliar with this problem will probably say: “It doesn’t matter. They are equally likely”. We will here in a few different ways show that it does in fact matter if you switch or stay.</p>
<p>First let’s try a more obvious example. Instead of three card, we have ten, nine knights and one king. You choose a card like before but instead of flipping just one knight, your friend flips 8 knights. Now there remains just two faced down cards, your first choice and one other. The key here is that you always have just two cards in the end to choose from. Would you switch or would you stay? Here your intuition probably tells you to switch because there is a greater probability that the card you chose was a knight than a king. In fact there is just 1/10 probability that you chose the king as your first card and thus a 9/10 probability that any of the other cards are the king. Therefore you have a 9/10 probability to pick the king if you switch card because you know that 8 of the other cards are not the king. Are you on board? If not, think through this example one more time and remember the key: we are always left with just two cards in the end to choose from.</p>
<p>If we lower the amount of cards to nine, would it still be better to switch most of the time? Yes, you would have a 8/9 probability of picking the king if you switched. The same holds for 8, 7, 6, 5, 4 and 3 cards as well. Let’s look a little closer on the case of 4 cards. When you first choose a card you have 1/4 probability of picking the king. When you are left with just two card to choose from, the probability that you chose the king is still just 1/4 and therefore there must be a 3/4 probability that the other card is the king. We are nearly there now! Time for 3 cards: You have 1/3 probability of choosing the king and therefore a 2/3 probability that you did not choose the king. When one of the other cards are flipped and shown to be a knight, the probability still remains. You are more likely to have missed the king than to have picked it at first and therefore switching is the better option. In the case of 3 cards, you have a 2/3 probability to pick the king if you switch.</p>
<p>Now a more mathy way to attack the problem (keep calm, we won’t hurt it). Is there any probability that remains the same throughout the whole problem, both mathematically and intuition-wise? One such probability I think is the probability that we did NOT choose the king as our first card, <strong>P(not king)</strong>. This probability is 2/3 and it will not change during the game. The game goes as before but we pause when the knight has been flipped. The probability is still the same that we did NOT choose the king at first and therefore it is still just 1/3 that the card we chose is a king but it is 2/3 that any of the other card are the king. Now we also know that one of those cards are not the king and therefore the other card must have the probability 2/3 of being king. Switching cards therefore gives you a 2/3 chance to pick the king.</p>
<p>If this article didn’t make you understand the Monty Hall Problem then I recommend <a href="https://www.youtube.com/watch?v=4Lb-6rxZxx0">this</a> and <a href="https://www.youtube.com/watch?v=7u6kFlWZOWg">this</a> Youtube videos by a channel called Numberphile which explains this with pictures as well. They are by the way a really interesting channel for people interested in math.</p>
<p>Have a nice day!</p>Hugo GranströmThe Monty Hall problem is a quiet famous problem where most people’s intuition are wrong. There are many variations of it but I will use one with playing card. It goes like this:Gravity Simulator2018-07-21T00:00:00+00:002018-07-21T00:00:00+00:00https://hugogranstrom.com/gravity-simulator<p>This is a gravity simulator I have written in python using the library VPython/Glowscript. This project was inspired by an exercise my math teacher gave us where we were supposed to simulate the moon’s orbit around the earth in excel using differential equations.</p>
<p>Luckily there exists better tools for this, like python in conjunction with VPython where you get both vectors and graphics. So no need for splitting the vectors in an X-part and an Y-part, that is really convenient actually. My first intention was to just write the earth-moon simulation but then I thought: “Why not do the entire solar system instead”. And so I did, the Sun, the eight planets and Pluto (you will forever be a planet to me) all dancing together in a cosmic dance. Futhermore, I chose to use the Euler method for integration because it is easy to implement and it is the one most people are familiar with. This simulation won’t be near accurate enough to simulate the actual solar system anyway (for example relativity is not accounted for and the timestep is too big) so the inaccuracy doesn’t bother me. I just want to see some planets dance… and throw in a black hole later. I have also chosen to use other units then the SI-units: distance is measured in AU (average distance between earth and the sun), time is measured in days and mass in solar masses. This is because then the computer doesn’t have to handle such large numbers and hence it consumes less memory. A consequence of this is that G, the gravitational constant changes it’s values from the familiar 6.67e-11 to 2.959e-04. The size of the planets are scaled up by a factor of 1000 to make them visible. Otherwise are all the distances correct. The initial positions and velocities are real data from June 2018 from <a href="https://ssd.jpl.nasa.gov/horizons.cgi">here</a>. Watch it and have fun!</p>
<p>The source code can be found on Glowscript <a href="http://www.glowscript.org/#/user/hajenzoo/folder/Public/program/gravity-simulator">here</a> (click “View this program” to see the source code)</p>
<p>The simulation with a black hole can be found <a href="http://www.glowscript.org/#/user/hajenzoo/folder/Public/program/gravity-simulator-black-hole">here</a> (click “Run this program” in the upper left corner to start it)</p>
<p>A tutorial on how to code this yourself will be coming in the future. I the meanwhile if you’re interested, I have written comments in the code that may be helpful.</p>
<p>Remember, you can always count on your best friend, the calculator!</p>
<p>A heads up: running this simulation can drain quite a lot of power so if you’re on a laptop, I recommend that you have your charger plugged in while running this.</p>
<p>Controls:</p>
<ul>
<li>Zoom: scroll</li>
<li>Pan: Hold SHIFT and drag with left mouse button</li>
<li>Rotate: Hold and drag right mouse button</li>
</ul>
<p>Thanks to @marsater for ideas and feedback for this project.</p>
<div id="glowscript" class="glowscript">
<script type="text/javascript" src="https://s3.amazonaws.com/glowscript/lib/jquery/2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://s3.amazonaws.com/glowscript/lib/jquery/2.1/jquery-ui.custom.min.js"></script>
<script type="text/javascript" src="https://s3.amazonaws.com/glowscript/package/glow.2.7.min.js"></script>
<script type="text/javascript" src="https://s3.amazonaws.com/glowscript/package/RSrun.2.7.min.js"></script>
<script type="text/javascript"><!--//--><![CDATA[//><!--
;(function() { var __rt=srequire('streamline/lib/callbacks/runtime').runtime(__filename, false),__func=__rt.__func,__cb=__rt.__cb; var RS_modules = {};
RS_modules.pythonize = {};
(function() {
function strings() {
var string_funcs, exclude, name;
string_funcs = set("capitalize strip lstrip rstrip islower isupper isspace lower upper swapcase center count endswith startswith find rfind index rindex format join ljust rjust partition rpartition replace split rsplit splitlines zfill".split(" "));
if (!arguments.length) {
exclude = (function() {
var s = RS_set();
s.jsset.add("split");
s.jsset.add("replace");
return s;
})(); }
else if (arguments[0]) {
exclude = Array.prototype.slice.call(arguments); }
else {
exclude = null; } ;
if (exclude) {
string_funcs = string_funcs.difference(set(exclude)); } ;
var RS_Iter0 = RS_Iterable(string_funcs);
for (var RS_Index0 = 0; RS_Index0["<"](RS_Iter0.length); RS_Index0++) {
name = RS_Iter0[RS_Index0];
(RS_expr_temp = String.prototype)[((((typeof name === "number") && name["<"](0))) ? RS_expr_temp.length["+"](name) : name)] = (RS_expr_temp = RS_str.prototype)[((((typeof name === "number") && name["<"](0))) ? RS_expr_temp.length["+"](name) : name)]; }; }; RS_modules.pythonize.strings = strings;
})();
function main(_) { var version, box, sphere, cylinder, pyramid, cone, helix, ellipsoid, ring, arrow, compound, display, vector, print, scene, RS_ls, G, dt, time, scale_factor, AU, M, bodies, sun, earth, mercury, venus, mars, jupiter, saturn, uranus, neptune, pluto, time_label, body, __name__, strings, RS_Iter4, RS_Index4, RS_Iter5, RS_Index5, __this = this;
function Body() {
if ((this.RS_object_id === undefined)) { Object.defineProperty(this, "RS_object_id", { value: ++RS_object_counter }); };
Body.prototype.__init__.apply(this, arguments); }; var __frame = { name: "main", line: 32 }; return __func(_, this, arguments, main, 0, __frame, function __$main() { version = RS_list_decorate(["2.7","glowscript",]); Array.prototype["+"] = function(r) { return this.concat(r); }; Array.prototype["*"] = function(r) { return __array_times_number(this, r); }; __name__ = "__main__"; window.__GSlang = "vpython"; box = vp_box; sphere = vp_sphere; cylinder = vp_cylinder; pyramid = vp_pyramid; cone = vp_cone; helix = vp_helix; ellipsoid = vp_ellipsoid; ring = vp_ring; arrow = vp_arrow; compound = vp_compound; display = canvas; vector = vec; print = GSprint; scene = canvas(); strings = RS_modules.pythonize.strings; strings(); "8"; G = 0.00029592; "9"; dt = 0.01; "10"; time = 0; "11"; scale_factor = 1000; "12"; AU = 150000000000; "13"; M = 2e+30; "16"; bodies = RS_list_decorate([]); "18";
Body.prototype.__init__ = function __init__() {
var self = this;
var mass = ((((arguments[0] === undefined) || (((((0 === arguments.length["-"](1)) && (arguments[arguments.length["-"](1)] !== null)) && (typeof arguments[arguments.length["-"](1)] === "object")) && (arguments[arguments.length["-"](1)][RS_kwargs_symbol] === true))))) ? __init__.__defaults__.mass : arguments[0]);
var radius = ((((arguments[1] === undefined) || (((((1 === arguments.length["-"](1)) && (arguments[arguments.length["-"](1)] !== null)) && (typeof arguments[arguments.length["-"](1)] === "object")) && (arguments[arguments.length["-"](1)][RS_kwargs_symbol] === true))))) ? __init__.__defaults__.radius : arguments[1]);
var velocity = ((((arguments[2] === undefined) || (((((2 === arguments.length["-"](1)) && (arguments[arguments.length["-"](1)] !== null)) && (typeof arguments[arguments.length["-"](1)] === "object")) && (arguments[arguments.length["-"](1)][RS_kwargs_symbol] === true))))) ? __init__.__defaults__.velocity : arguments[2]);
var position = ((((arguments[3] === undefined) || (((((3 === arguments.length["-"](1)) && (arguments[arguments.length["-"](1)] !== null)) && (typeof arguments[arguments.length["-"](1)] === "object")) && (arguments[arguments.length["-"](1)][RS_kwargs_symbol] === true))))) ? __init__.__defaults__.position : arguments[3]);
var color = ((((arguments[4] === undefined) || (((((4 === arguments.length["-"](1)) && (arguments[arguments.length["-"](1)] !== null)) && (typeof arguments[arguments.length["-"](1)] === "object")) && (arguments[arguments.length["-"](1)][RS_kwargs_symbol] === true))))) ? __init__.__defaults__.color : arguments[4]);
var trail = ((((arguments[5] === undefined) || (((((5 === arguments.length["-"](1)) && (arguments[arguments.length["-"](1)] !== null)) && (typeof arguments[arguments.length["-"](1)] === "object")) && (arguments[arguments.length["-"](1)][RS_kwargs_symbol] === true))))) ? __init__.__defaults__.trail : arguments[5]);
var name = ((((arguments[6] === undefined) || (((((6 === arguments.length["-"](1)) && (arguments[arguments.length["-"](1)] !== null)) && (typeof arguments[arguments.length["-"](1)] === "object")) && (arguments[arguments.length["-"](1)][RS_kwargs_symbol] === true))))) ? __init__.__defaults__.name : arguments[6]);
var RS_kwargs_obj = arguments[arguments.length["-"](1)];
if ((((RS_kwargs_obj === null) || (typeof RS_kwargs_obj !== "object")) || (RS_kwargs_obj[RS_kwargs_symbol] !== true))) { RS_kwargs_obj = { }; };
if (Object.prototype.hasOwnProperty.call(RS_kwargs_obj, "mass")) {
mass = RS_kwargs_obj.mass; } ;
if (Object.prototype.hasOwnProperty.call(RS_kwargs_obj, "radius")) {
radius = RS_kwargs_obj.radius; } ;
if (Object.prototype.hasOwnProperty.call(RS_kwargs_obj, "velocity")) {
velocity = RS_kwargs_obj.velocity; } ;
if (Object.prototype.hasOwnProperty.call(RS_kwargs_obj, "position")) {
position = RS_kwargs_obj.position; } ;
if (Object.prototype.hasOwnProperty.call(RS_kwargs_obj, "color")) {
color = RS_kwargs_obj.color; } ;
if (Object.prototype.hasOwnProperty.call(RS_kwargs_obj, "trail")) {
trail = RS_kwargs_obj.trail; } ;
if (Object.prototype.hasOwnProperty.call(RS_kwargs_obj, "name")) {
name = RS_kwargs_obj.name; } ;
var RS_ls;
"20";
self.mass = mass;
"21";
self.velocity = velocity;
"22";
self.position = position;
"23";
self.color = color;
"24";
self.radius = radius;
"25";
self.forces = RS_list_decorate([]);
"26";
self.acc = vector(0, 0, 0);
"27";
self.sum_force = vector(0, 0, 0);
"28";
self.name = name;
"29";
self.label = RS_interpolate_kwargs.call(this, label, [RS_desugar_kwargs({ pos: self.position, text: self.name, height: 10 }),]);
"30";
self.sphere = RS_interpolate_kwargs.call(this, sphere, [RS_desugar_kwargs({ pos: self.position, color: self.color, radius: self.radius["*"](scale_factor), make_trail: trail, retain: 300 }),]);
"31";
bodies.append(self); };
if (!Body.prototype.__init__.__defaults__) { Object.defineProperties(Body.prototype.__init__, {
__defaults__: { value: { mass: 1, radius: 1, velocity: vector(0, 0, 0), position: vector(0, 0, 0), color: color.white, trail: true, name: "Body" } },
__handles_kwarg_interpolation__: { value: true },
__argnames__: { value: ["mass","radius","velocity","position","color","trail","name",] } }); } ;
Body.__argnames__ = Body.prototype.__init__.__argnames__;
Body.__handles_kwarg_interpolation__ = Body.prototype.__init__.__handles_kwarg_interpolation__;
Body.prototype.update = function update() {
var self = this;
var RS_ls, force;
"33";
self.forces = RS_list_decorate([]);
"34";
self.sum_force = vector(0, 0, 0);
"35";
self.gravitational_force();
"39";
var RS_Iter1 = RS_Iterable(self.forces);
for (var RS_Index1 = 0; RS_Index1["<"](RS_Iter1.length); RS_Index1++) {
force = RS_Iter1[RS_Index1];
"40";
self.sum_force = self.sum_force["+="](force); };
"43";
self.acc = self.sum_force["/"](self.mass);
"44";
self.velocity = self.velocity["+="](dt["*"](self.acc)); };
Body.prototype.move = function move() {
var self = this;
var RS_ls;
"47";
self.position = self.position["+="](dt["*"](self.velocity));
"50";
self.sphere.pos = self.position;
"51";
self.label.pos = self.position; };
Body.prototype.gravitational_force = function gravitational_force() {
var self = this;
var RS_ls, r, force, dir, body;
"55";
var RS_Iter2 = RS_Iterable(bodies);
for (var RS_Index2 = 0; RS_Index2["<"](RS_Iter2.length); RS_Index2++) {
body = RS_Iter2[RS_Index2];
"57";
r = mag(self.position["-"](body.position));
"59";
if (r["<"](self.radius["+"](body.radius))) {
"60";
continue; } ;
"62";
force = G["*"](self.mass)["*"](body.mass)["/"](GS_power(r, 2));
"64";
dir = norm(body.position["-"](self.position));
"66";
force = force["*"](dir);
"68";
self.forces.append(force); }; };
Body.prototype.updateVerlet = function updateVerlet() {
var self = this;
var RS_ls, force;
"72";
self.forces = RS_list_decorate([]);
"73";
self.sum_force = vector(0, 0, 0);
"74";
self.gravitational_force();
"78";
var RS_Iter3 = RS_Iterable(self.forces);
for (var RS_Index3 = 0; RS_Index3["<"](RS_Iter3.length); RS_Index3++) {
force = RS_Iter3[RS_Index3];
"79";
self.sum_force = self.sum_force["+="](force); };
"82";
self.position = self.position["+="](self.velocity["*"](dt)["+"](self.acc["/"](2)["*"](GS_power(dt, 2))));
"83";
self.velocity = self.velocity["+="](dt["/"](2)["*"](self.acc["+"](self.sum_force["/"](self.mass))));
"84";
self.acc = self.sum_force["/"](self.mass);
"86";
self.sphere.pos = self.position;
"87";
self.label.pos = self.position; };
Body.prototype.__repr__ = function __repr__() {
return "<"["+"](__name__)["+"](".")["+"](this.constructor.name)["+"](" #")["+"](this.RS_object_id)["+"](">"); };
Body.prototype.__str__ = function __str__() {
return this.__repr_; };
Object.defineProperty(Body.prototype, "__bases__", { value: [] });
Body.prototype.RS_ls = "19";
Body.prototype.RS_ls = "32";
Body.prototype.RS_ls = "46";
Body.prototype.RS_ls = "53";
Body.prototype.RS_ls = "71";
"92";
sun = RS_interpolate_kwargs_constructor.call(Object.create(Body.prototype), false, Body, [RS_desugar_kwargs({ mass: 1, radius: 700000000["*"](5)["/"](scale_factor)["/"](AU), color: color.yellow, trail: false, name: "Sun" }),]);
"100";
earth = RS_interpolate_kwargs_constructor.call(Object.create(Body.prototype), false, Body, [RS_desugar_kwargs({ mass: 6e+24["/"](M), radius: 6371000["/"](AU), position: vector(0.5111702950987252["-u"](), 0.8734341386147972["-u"](), 0.00003902531498407046), velocity: vector(0.01457401965494037, 0.008749957786090569["-u"](), 3.393201214360642e-7["-u"]()), color: color.green, name: "Earth" }),]);
"111";
mercury = RS_interpolate_kwargs_constructor.call(Object.create(Body.prototype), false, Body, [RS_desugar_kwargs({ mass: earth.mass["*"](0.055), radius: 6000000["/"](AU), position: vector(0.360006238731298, 0.08310671431721671["-u"](), 0.03981766501010686["-u"]()), velocity: vector(0.0008732371820239134, 0.0286750815794258, 0.002263026727476856), color: color.red, name: "Mercury" }),]);
"123";
venus = RS_interpolate_kwargs_constructor.call(Object.create(Body.prototype), false, Body, [RS_desugar_kwargs({ mass: earth.mass["*"](0.815), radius: 6000000["/"](AU), position: vector(0.5460148756311848["-u"](), 0.4654289630909307, 0.03789319798488837), velocity: vector(0.01319751648139675["-u"](), 0.01549708277964608["-u"](), 0.0005490020542624818), color: color.white, name: "Venus" }),]);
"135";
mars = RS_interpolate_kwargs_constructor.call(Object.create(Body.prototype), false, Body, [RS_desugar_kwargs({ mass: earth.mass["*"](0.107), radius: 6000000["/"](AU), velocity: vector(0.01444719742599419, 0.0002365918534978303["-u"](), 0.000359488561244826["-u"]()), position: vector(0.1508529480814324["-u"](), 1.460121856503524["-u"](), 0.02689190873994556["-u"]()), color: color.red, name: "Mars" }),]);
"145";
jupiter = RS_interpolate_kwargs_constructor.call(Object.create(Body.prototype), false, Body, [RS_desugar_kwargs({ mass: earth.mass["*"](318), radius: 70000000["/"](AU), velocity: vector(0.005611682808441865, 0.004596785105938998["-u"](), 0.0001064356940327842["-u"]()), position: vector(3.545075313382027["-u"](), 4.081361865858232["-u"](), 0.09627457319753692), color: color.blue, name: "Jupiter" }),]);
"155";
saturn = RS_interpolate_kwargs_constructor.call(Object.create(Body.prototype), false, Body, [RS_desugar_kwargs({ mass: earth.mass["*"](95), radius: 60000000["/"](AU), velocity: vector(0.005262021976694793, 0.0004141890616120753, 0.0002169327374705523["-u"]()), position: vector(0.7842529344684837, 10.03393486265119["-u"](), 0.1431896871358062), color: color.white, name: "Saturn" }),]);
"165";
uranus = RS_interpolate_kwargs_constructor.call(Object.create(Body.prototype), false, Body, [RS_desugar_kwargs({ mass: earth.mass["*"](14), radius: 25000000["/"](AU), velocity: vector(0.0019052013493924["-u"](), 0.003265505721711341, 0.000036690734434005), position: vector(17.46114323983198, 9.517430938519276, 0.1907513002050031["-u"]()), color: color.blue, name: "Uranus" }),]);
"175";
neptune = RS_interpolate_kwargs_constructor.call(Object.create(Body.prototype), false, Body, [RS_desugar_kwargs({ mass: earth.mass["*"](17), radius: 24000000["/"](AU), velocity: vector(0.0008427417626787077, 0.003035037625808767, 0.00008199842541642128["-u"]()), position: vector(28.80079206580985, 8.17390036348871["-u"](), 0.495478418972816["-u"]()), color: color.yellow, name: "Neptune" }),]);
"185";
pluto = RS_interpolate_kwargs_constructor.call(Object.create(Body.prototype), false, Body, [RS_desugar_kwargs({ mass: earth.mass["*"](0.0022), radius: 1000000["/"](AU), position: vector(11.20198708794019, 31.64123744663468["-u"](), 0.1446313453325374), velocity: vector(0.003029567845289497, 0.0003743167934314588, 0.000926069693706297["-u"]()), color: color.yellow, name: "Pluto" }),]);
"213";
time_label = RS_interpolate_kwargs.call(__this, label, [RS_desugar_kwargs({ pos: vector(75, 350, 0), pixel_pos: true, text: "Time: "["+"](str(time["/"](365)))["+"](" years") }),]);
"216"; return (function ___(__break) { var __more; var __loop = __cb(_, __frame, 0, 0, function __$main() { __more = false;
var __1 = true; if (__1) {
"217";
return rate(5000, __cb(_, __frame, 228, 8, function __$main() {
"219";
RS_Iter4 = RS_Iterable(bodies);
for (RS_Index4 = 0; RS_Index4["<"](RS_Iter4.length); RS_Index4++) {
body = RS_Iter4[RS_Index4];
"220";
body.update(); };
"222";
RS_Iter5 = RS_Iterable(bodies);
for (RS_Index5 = 0; RS_Index5["<"](RS_Iter5.length); RS_Index5++) {
body = RS_Iter5[RS_Index5];
"223";
body.move(); };
"224";
time_label.text = "Time: {:.2f} years".format(time["/"](365));
"225";
time = time["+="](dt); while (__more) { __loop(); }; __more = true; }, true)); } else { __break(); } ; }); do { __loop(); } while (__more); __more = true; })(_); });};
if (!main.__argnames__) { Object.defineProperties(main, {
__argnames__: { value: ["_",] } });};
;$(function(){ window.__context = { glowscript_container: $("#glowscript").removeAttr("id") }; main(__func) })})()
//--><!]]></script>
</div>Hugo GranströmThis is a gravity simulator I have written in python using the library VPython/Glowscript. This project was inspired by an exercise my math teacher gave us where we were supposed to simulate the moon’s orbit around the earth in excel using differential equations.Math Codified - Limits2018-07-12T00:00:00+00:002018-07-12T00:00:00+00:00https://hugogranstrom.com/math-codified-limits<h3 id="prerequisites">Prerequisites</h3>
<ul>
<li>I assume you have a basic understanding of python and math.</li>
<li>I will be using python 3.6 and above (sorry no legacy code here).</li>
<li>I recommend writing the code yourself (in a jupyter notebook perhaps) and to play around with it.</li>
<li>Being prepared for bad jokes</li>
</ul>
<h3 id="basics">Basics</h3>
<p>Limits are a concept in math used in various situations, for example when calculating derivatives. I have a article about how to understand derivatives using python <a href="https://hugogranstrom.com/math-codified-derivatives/">here</a>.</p>
<p>Limits are used when a function <script type="math/tex">f(x)</script> isn’t defined for a certain input <script type="math/tex">x</script> or if we want to see if the function has a limit at <script type="math/tex">+\infty</script> or <script type="math/tex">-\infty</script> ie if the function converges at infinity (functions can also converge to other functions but that is a matter for another day). That a function converges means that there is a number that the function approaches at <script type="math/tex">\infty</script>, an invisible line it never crosses. Often it can be seen as a “ceiling” or a “floor” like in this picture:</p>
<p><img src="https://hugogranstrom.com/images/2018-07/floor1.png" alt="Floor function" /></p>
<p>A limit is written as this:</p>
<script type="math/tex; mode=display">\lim_{x \to a} f(x)</script>
<p><script type="math/tex">\lim</script> stands for <em>limes</em> in latin but I always think of it as standing for the english word <em>limit</em>, so if you hear someone talk about <em>limes</em> they are probably talking about limits. <script type="math/tex">f(x)</script> is the function we want to get the limit of and <script type="math/tex">a</script> is the limit we want <script type="math/tex">x</script> to approach. We write <script type="math/tex">x \to a</script> to say “as <script type="math/tex">x</script> approaches <script type="math/tex">a</script>”. The whole expression if spoken would be <em>The limit of <script type="math/tex">f(x)</script> as <script type="math/tex">x</script> approaches <script type="math/tex">a</script></em>.</p>
<p>Can we with that in mind evaluate some limits of the function in the picture above, <script type="math/tex">f(x) = \frac{1}{x} + 2</script>? <strong>Let’s try!</strong></p>
<p>First let’s explore what happens when <script type="math/tex">x</script> becomes really big, namely when <script type="math/tex">x</script> approaches infinity. We would write the expression like this:</p>
<script type="math/tex; mode=display">\lim_{x \to \infty} f(x) = \lim_{x \to \infty} \frac{1}{x} + 2</script>
<p>If we study the graph we can see that the function never seems to go lower than the red-dashed line at <script type="math/tex">y=2</script>, in other words the limit as x approaches <script type="math/tex">\infty</script> is 2 or as a math expression:</p>
<script type="math/tex; mode=display">\lim_{x \to \infty} \frac{1}{x} + 2 = 2</script>
<p>When you just look at the equation that makes alot of sense as well, <script type="math/tex">\frac{1}{x}</script> becomes really small when <script type="math/tex">x</script> is large so it basically becomes <script type="math/tex">0 + 2</script> at <script type="math/tex">\infty</script>.</p>
<p>A quick note about when to use limits and when not to. If you have a well behaved function (defined everywhere basically) then the limit is just the function evaluated at that point:</p>
<script type="math/tex; mode=display">\lim_{ x \to a } f(x) = f(x)</script>
<p>It is just when a function isn’t defined for certain <script type="math/tex">x</script> (or if you want to see how it behaves at <script type="math/tex">\infty</script>) that limits are useful. We will show this in an code example below.</p>
<h3 id="exercise">Exercise</h3>
<p>That wasn’t too hard, right? Here comes an exercise for you to test yourself (the answer is at the bottom of this page):</p>
<p>Write a mathematical expression of the limit of <script type="math/tex">\lim_{x \to \infty} \frac{1}{x} + 2</script> as <script type="math/tex">x</script> approaches <script type="math/tex">0</script> and write a reasonable answer to that limit.</p>
<h1 id="code-time">Code Time!</h1>
<p>Now comes the juicy part you came here for! Put on your coding gear, here we GO! (don’t tell me you haven’t got any coding gear, let’s see… I know, take that old hoodie and… a pair of glasses! That looks rather code-ish, right?)</p>
<p>The way we are going to do limits in python is when <script type="math/tex">a</script> is a number we will add a small number <script type="math/tex">h</script> to it and evaluate an approximation of the value like this:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># our function. is the same as above</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="mi">1</span><span class="o">/</span><span class="n">x</span> <span class="o">+</span> <span class="mi">2</span>
<span class="c"># the small number we will add to x. </span>
<span class="n">h</span> <span class="o">=</span> <span class="mf">1e-3</span>
<span class="c"># The limit as x goes to 0</span>
<span class="n">x</span> <span class="o">=</span> <span class="mi">0</span> <span class="o">+</span> <span class="n">h</span>
<span class="n">limit</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">limit</span><span class="p">)</span>
<span class="c"># 1002.0</span>
</code></pre></div></div>
<p>Note: 1e-3 is scientfic notation for <script type="math/tex">1 \times 10^{-3}</script> and likewise is 7e3 the same as <script type="math/tex">7 \times 10^{3}</script>.</p>
<p>If we test with a smaller <script type="math/tex">h</script>, for example 1e-6, we get 1000002. This is a strong indication that it tends to infinity and if we choose even smaller values for <script type="math/tex">h</script> the limits get’s higher and higher. We can modify the code to write the answer for multiple values of <script type="math/tex">h</script> and that could help us see a trend:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="mi">1</span><span class="o">/</span><span class="n">x</span> <span class="o">+</span> <span class="mi">2</span>
<span class="n">x</span> <span class="o">=</span> <span class="mi">0</span>
<span class="c"># a list of the h's we want to test</span>
<span class="n">h_list</span> <span class="o">=</span> <span class="p">[</span><span class="mf">1e-3</span><span class="p">,</span> <span class="mf">1e-6</span><span class="p">,</span> <span class="mf">1e-9</span><span class="p">,</span> <span class="mf">1e-12</span><span class="p">]</span>
<span class="c"># loop over the h's and evaluate the function at each</span>
<span class="k">for</span> <span class="n">h</span> <span class="ow">in</span> <span class="n">h_list</span><span class="p">:</span>
<span class="n">limit</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="n">h</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">f</span><span class="s">"h: {h}, limit: {limit}"</span><span class="p">)</span>
<span class="c">#h: 0.001, limit: 1002.0</span>
<span class="c">#h: 1e-06, limit: 1000002.0</span>
<span class="c">#h: 1e-09, limit: 1000000001.9999999</span>
<span class="c">#h: 1e-12, limit: 1000000000002.0</span>
</code></pre></div></div>
<p>This is the structure we will be using now when we want to see how a function behaves as it approaches infinity. We will have a list of increasingly big numbers (instead of small):</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
<span class="k">return</span> <span class="mi">1</span><span class="o">/</span><span class="n">x</span> <span class="o">+</span> <span class="mi">2</span>
<span class="c"># list of big numbers</span>
<span class="n">x_list</span> <span class="o">=</span> <span class="p">[</span><span class="mf">1e3</span><span class="p">,</span> <span class="mf">1e6</span><span class="p">,</span> <span class="mf">1e9</span><span class="p">,</span> <span class="mf">1e12</span><span class="p">]</span>
<span class="c"># loop over the x's and evaluate the function at each</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">x_list</span><span class="p">:</span>
<span class="n">limit</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="k">print</span><span class="p">(</span><span class="n">f</span><span class="s">"x: {x}, limit: {limit}"</span><span class="p">)</span>
<span class="c">#x: 1000.0, limit: 2.001</span>
<span class="c">#x: 1000000.0, limit: 2.000001</span>
<span class="c">#x: 1000000000.0, limit: 2.000000001</span>
<span class="c">#x: 1000000000000.0, limit: 2.000000000001</span>
</code></pre></div></div>
<p>As we can see it seems to converge to 2 at infinity. If you continue to increase <script type="math/tex">x</script> you will soon surpass the precision of floating point numbers (that is shown) and it will just display “2.0”. Python is really convinient in the way that you can have really big numbers without worrying about what whether it should be an <em>unsigned</em>, <em>long</em> etc <em>int</em>. It just works! Test to print some really big number, preferably using the notation I have used above if you don’t want to hold the 0-button until the heat-death of the universe. It will handle quite big numbers, numbers to0 big for us to even imagine. 1e100, <script type="math/tex">10^{100}</script> also called a <em>googol</em> would need to divided by 2 one hundred times just to get down to <script type="math/tex">10^{70}</script>. Think about how big <script type="math/tex">2^{100}</script> is, even so it is just <script type="math/tex">\frac{1}{10^{68}}</script> % of a googol. A googol was probably a piece of cake for your computer, then I have a challenge for it: beware! The <em>googolplex</em> ! (the space after the word is to keep the size of the number down, in <em>fact</em> it would be so ridiculously huge that I don’t know how to write it in any other way then that). A <em>googolplex</em> is 10 to the power of a googol, <script type="math/tex">10^{10^{100}}</script>. Seeing as my computer can’t handle numbers larger than 1e300 I have a hard time seeing a computer being able to handle a googolplex without cheating. For anyone interested, a <em>googol</em> is about a <em>googol</em>-th (<script type="math/tex">\frac{1}{10^{98}}</script>%) of a percent of a <em>googolplex</em>.</p>
<p>If you are reading this at night I apologize for the last paragraph, it might have been a bit to math heavy for this article about codifying math. But I just think that it is remarkable that we can express really big numbers even though we can’t really comprehend them.</p>
<p>That was it for this time, I hope you learnt at least something new and that I haven’t scared you away from math. I would really like to discuss math and such with you so if you are in the mood you can find me on <a href="https://twitter.com/GranstromHugo">twitter</a> and on my email which both can be found in the footer.</p>
<p><strong>Have a nice day!</strong></p>
<h3 id="answer-to-exercise">Answer to Exercise</h3>
<script type="math/tex; mode=display">\lim_{ x \to 0 } \frac{1}{x} + 2 = \infty</script>
<p>An important note here is differentiate between <script type="math/tex">\lim_{ x \to 0 } \frac{1}{x} + 2 = \infty</script> and <script type="math/tex">\frac{1}{0} + 2 = \infty</script>. The first one is true but the second one is not, this is correct then:
<script type="math/tex">\frac{1}{0} + 2</script> <em>is undefined</em>.</p>
<h3 id="questions--contact">Questions & Contact</h3>
<p>If you got any questions comment them below, send me an email or contact me on twitter. The links are in the footer below. You can also contact me there casually just to discuss what’s at the <em>limit</em> of your imagination right now.</p>Hugo GranströmLimits are a concept in math used in various situations, for example when calculating derivatives. Limits are used when a function f(x) isn't defined for a certain input x or if we want to see if the function has a limit at infinity.Hello World!2018-05-06T00:00:00+00:002018-05-06T00:00:00+00:00https://hugogranstrom.com/hello-world<p>Hello World!</p>
<p>This is my first blog post here. I’m a science student in Sweden who is interested in mathematics and programming.
My programming language of choice is Python, mainly because I think Java (my first language) and the others look too cluttered with their overuse of curly brackets {}.</p>
<p>Here is the line of code most of us had as our first computer program:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">print</span><span class="p">(</span><span class="s">"Hello World!"</span><span class="p">)</span>
</code></pre></div></div>
<p>Ahh… What nostalgia! My memories come back from when I was 13 and coded Java on my 4 inch android phone with “Hacker’s Keyboard”. Though that time it was a more complicated expression I had to write…..</p>Hugo GranströmHello World!