Notion - Update docs

This commit is contained in:
shiffman 2024-02-12 16:49:28 +00:00 committed by GitHub
parent c90674539c
commit 7400fb312c
9 changed files with 28 additions and 24 deletions

View file

@ -297,7 +297,6 @@ if (num < 0.6) {
<pre class="codesplit" data-code-language="javascript">let h = random(200, 300);</pre>
<p>Is this an accurate algorithm for creating a population of monkey heights? Think of a crowded sidewalk in New York City. Pick any person off the street, and it may appear that their height is random. Nevertheless, its not the kind of random that <code>random()</code> produces by default. Peoples heights arent uniformly distributed; there are many more people of about average height than there are very tall or very short ones. To accurately reflect this population, random heights close to the <strong>mean</strong> (another word for <em>average</em>) should be more likely to be chosen, while outlying heights (very short or very tall) should be rarer.</p>
<p>Thats exactly how a normal distribution (sometimes called a Gaussian distribution, after mathematician Carl Friedrich Gauss) works. A graph of this distribution is informally known as a <strong>bell curve</strong>. The curve is generated by a mathematical function that defines the probability of any given value occurring as a function of the mean (often written as μ, the Greek letter mu) and standard deviation (σ, the Greek letter sigma).</p>
<p>In the case of height values from 200 to 300, you probably have an intuitive sense of the mean (average) as 250. However, what if I were to say that the standard deviation is 3? Or 15? What does this mean for the numbers? The graphs depicted in Figure 0.2 should give you a hint. On the left is a distribution with a very low standard deviation, with the majority of the values piling up around the mean (they dont deviate much from the standard). The version on the right has a higher standard deviation, so the values are more evenly spread out from the average (they deviate more).</p>
<figure>
<div class="col-list">
<div>
@ -309,6 +308,7 @@ if (num &#x3C; 0.6) {
</div>
<figcaption>Figure 0.2: Two example bell curves of a normal distribution, with a low (left) and high (right) standard deviation</figcaption>
</figure>
<p>In the case of height values from 200 to 300, you probably have an intuitive sense of the mean (average) as 250. However, what if I were to say that the standard deviation is 3? Or 15? What does this mean for the numbers? The graphs depicted in Figure 0.2 should give you a hint. On the left is a distribution with a very low standard deviation, with the majority of the values piling up around the mean (they dont deviate much from the standard). The version on the right has a higher standard deviation, so the values are more evenly spread out from the average (they deviate more).</p>
<p>The numbers work out as follows: given a population, 68 percent of its members will have values in the range of one standard deviation from the mean, 95 percent within two standard deviations, and 99.7 percent within three standard deviations. Given a standard deviation of 5 pixels, only 0.3 percent of the monkey heights will be less than 235 pixels (three standard deviations below the mean of 250) or greater than 265 pixels (three standard deviations above the mean of 250). Meanwhile, 68 percent of the monkey heights will be from 245 to 255 pixels.</p>
<div data-type="note">
<h3 id="calculating-mean-and-standard-deviation">Calculating Mean and Standard Deviation</h3>

View file

@ -502,11 +502,13 @@ circle(position.x, position.y, 48);</pre>
<div data-type="equation">w_y = 7 \times 3</div>
<div data-type="equation">\vec{w} = (-9,21)</div>
<p>This is exactly how the <code>mult()</code> function inside the <code>p5.Vector</code> class works:</p>
<pre class="codesplit" data-code-language="javascript">mult(n) {
<div class="avoid-break">
<pre class="codesplit" data-code-language="javascript">mult(n) {
// The components of the vector are multiplied by a number.
this.x = this.x * n;
this.y = this.y * n;
}</pre>
</div>
<p>Implementing multiplication in code is as simple as the following:</p>
<pre class="codesplit" data-code-language="javascript">let u = createVector(-3, 7);
// This <code>p5.Vector</code> is now three times the size and is equal to (9, 21). See Figure 1.9.
@ -578,9 +580,11 @@ u.div(2);</pre>
<p>Armed with this formula, we can now compute the magnitude of <span data-type="equation">\vec{v}</span> as follows:</p>
<div data-type="equation">||\vec{v}||=\sqrt{v_x * v_x + v_y * v_y}</div>
<p>In the <code>p5.Vector</code> class, the <code>mag()</code> function is defined using the same formula:</p>
<pre class="codesplit" data-code-language="javascript">mag() {
<div class="avoid-break">
<pre class="codesplit" data-code-language="javascript">mag() {
return sqrt(this.x * this.x + this.y * this.y);
}</pre>
</div>
<p>Heres a sketch that calculates the magnitude of the vector between the mouse and the center of the canvas, and visualizes it as a rectangle drawn across the top of the window.</p>
<div data-type="example">
<h3 id="example-15-vector-magnitude">Example 1.5: Vector Magnitude</h3>

View file

@ -366,18 +366,6 @@ moverB.applyForce(gravityB);</pre>
<p>The objects now fall at the same rate. Im still basically making up the gravity force by arbitrarily setting it to 0.1, but by scaling the force according to the objects mass, Im making it up in a way thats a little truer to Earths actual force of gravitational attraction. Meanwhile, because the strength of the wind force is independent of mass, the smaller circle still accelerates to the right more quickly when the mouse is pressed. (The online code for this example also includes a solution to Exercise 2.4, with the addition of a <code>radius</code> variable in the <code>Mover</code> class.)</p>
<h2 id="modeling-a-force">Modeling a Force</h2>
<p>Making up forces will actually get you quite far—after all, I just made up a pretty good approximation of Earths gravity. Ultimately, the world of p5.js is an orchestra of pixels, and youre the conductor, so whatever you deem appropriate to be a force, well by golly, thats the force it should be! Nevertheless, there may come a time when you find yourself wondering, “But how does it all <em>really</em> work?” Thats when modeling forces, instead of just making them up, enters the picture.</p>
<p>Open up any high school physics textbook and youll find diagrams and formulas describing various forces—gravity, electromagnetism, friction, tension, elasticity, and more. For the rest of this chapter, Im going to consider three forces—friction, drag, and gravitational attraction—and show how to model them with p5.js. The point Id like to make here is not that these are fundamental forces that you always need in your simulations. Rather, I want to demonstrate these forces as case studies for the following process:</p>
<ol>
<li>Understanding the concept behind a force</li>
<li>Deconstructing the forces formula into two parts:
<ol>
<li>How do you compute the forces direction?</li>
<li>How do you compute the forces magnitude?</li>
</ol>
</li>
<li>Translating that formula into p5.js code that calculates a vector to be passed through a <code>Mover</code> objects <code>applyForce()</code> method</li>
</ol>
<p>If you can follow these steps with the example forces Ill provide here, then hopefully when you find yourself googling <em>atomic nuclei weak nuclear force</em> at 3 AM, youll have the skills to take what you find and adapt it for p5.js.</p>
<div data-type="note">
<h3 id="parsing-formulas">Parsing Formulas</h3>
<p>In a moment, Im going to write out the formula for friction. This wont be the first time youve seen a formula in this book; I just finished up the discussion of Newtons second law, <span data-type="equation">\vec{F} = M \times \vec{A}</span> (or force equals mass times acceleration). You hopefully didnt spend a lot of time worrying about that formula, because its just a few characters and symbols. Nevertheless, its a scary world out there. Just take a look at the equation for a normal distribution, which I covered (without presenting the formula) in <a href="/random#a-normal-distribution-of-random-numbers">“A Normal Distribution of Random Numbers”</a>:</p>
@ -391,6 +379,18 @@ moverB.applyForce(gravityB);</pre>
<li><strong>When symbols are placed next to each other, this typically means multiply them.</strong> The right side of the friction formula has four elements: , <em>μ</em>, <em>N</em>, and <span data-type="equation">\hat{v}</span>. They should be multiplied together, reading the formula as <span data-type="equation">\vec{f} = -1 \times \mu \times N \times \hat{v}</span>.</li>
</ul>
</div>
<p>Open up any high school physics textbook and youll find diagrams and formulas describing various forces—gravity, electromagnetism, friction, tension, elasticity, and more. For the rest of this chapter, Im going to consider three forces—friction, drag, and gravitational attraction—and show how to model them with p5.js. The point Id like to make here is not that these are fundamental forces that you always need in your simulations. Rather, I want to demonstrate these forces as case studies for the following process:</p>
<ol>
<li>Understanding the concept behind a force</li>
<li>Deconstructing the forces formula into two parts:
<ol>
<li>How do you compute the forces direction?</li>
<li>How do you compute the forces magnitude?</li>
</ol>
</li>
<li>Translating that formula into p5.js code that calculates a vector to be passed through a <code>Mover</code> objects <code>applyForce()</code> method</li>
</ol>
<p>If you can follow these steps with the example forces Ill provide here, then hopefully when you find yourself googling <em>atomic nuclei weak nuclear force</em> at 3 AM, youll have the skills to take what you find and adapt it for p5.js.</p>
<h3 id="friction">Friction</h3>
<p>Lets begin with friction and follow the preceding steps. Whenever two surfaces come into contact, they experience <strong>friction</strong>. Friction is a <strong>dissipative force</strong>, meaning it causes the kinetic energy of an object to be converted into another form, giving the impression of loss, or dissipation.</p>
<p>Lets say youre driving a car. When you press your foot on the brake pedal, the cars brakes use friction to slow the motion of the tires. Kinetic energy (motion) is converted into thermal energy (heat). A complete model of friction would include separate cases for static friction (a body at rest against a surface) and kinetic friction (a body in motion against a surface), but for simplicity here, Im going to work through only the kinetic case. Figure 2.3 shows the formula for friction.</p>

View file

@ -21,11 +21,11 @@
<p>Ill start with the basics of working with angles in p5.js, then cover several aspects of trigonometry. In the end, Ill connect trigonometry with what you learned about forces in <a href="/forces#">Chapter 2</a>. This chapters content will pave the way for more sophisticated examples that require trig later in this book.</p>
<h2 id="angles">Angles</h2>
<p>Before going any further, I need to make sure you understand how the concept of an <strong>angle</strong> fits into creative coding in p5.js. If you have experience with p5.js, youve undoubtedly encountered this issue while using the <code>rotate()</code> function to rotate and spin objects.</p>
<p>Youre most likely to be familiar with the concept of an angle as measured in <strong>degrees</strong> (see Figure 3.1). A full rotation goes from 0 to 360 degrees, and 90 degrees (a right angle) is one-fourth of 360, shown in Figure 3.1 as two perpendicular lines.</p>
<figure>
<img src="images/03_oscillation/03_oscillation_2.png" alt="Figure 3.1: Angles measured in degrees">
<figcaption>Figure 3.1: Angles measured in degrees</figcaption>
</figure>
<p>Youre most likely to be familiar with the concept of an angle as measured in <strong>degrees</strong> (see Figure 3.1). A full rotation goes from 0 to 360 degrees, and 90 degrees (a right angle) is one-fourth of 360, shown in Figure 3.1 as two perpendicular lines.</p>
<div class="half-width-right">
<figure>
<img src="images/03_oscillation/03_oscillation_3.png" alt="Figure 3.2: A square rotated by 45 degrees">
@ -900,13 +900,13 @@ function draw() {
<p>You might have noticed that in Example 3.10s spring code, I never once used sine or cosine. Before you write off all this trigonometry stuff as a tangent, however, allow me to show an example of how it all fits together. Imagine a bob hanging from an anchor connected by a spring with a fully rigid connection that can be neither compressed nor extended. This idealized scenario describes a pendulum and provides an excellent opportunity to practice combining all that youve learned about forces and trigonometry.</p>
<p>A <strong>pendulum</strong> is a bob suspended by an arm from a pivot (previously called the <em>anchor</em> in the spring). When the pendulum is at rest, it hangs straight down, as in Figure 3.18. If you lift up the pendulum at an angle from its resting state and then release it, however, it starts to swing back and forth, tracing the shape of an arc. A real-world pendulum would live in a 3D space, but Im going to look at a simpler scenario: a pendulum in the 2D space of a p5.js canvas. Figure 3.19 shows the pendulum in a nonresting position and adds the forces at play: gravity and tension.</p>
<p>When the pendulum swings, its arm and bob are essentially rotating around the fixed point of the pivot. If no arm connected the bob and the pivot, the bob would simply fall to the ground under the influence of gravity. Obviously, that isnt what happens. Instead, the fixed length of the arm creates the second force—tension. However, Im not going to work with this scenario according to these forces, at least not in the way I approached the spring scenario.</p>
<p>Instead of using <em>linear</em> acceleration and velocity, Im going to describe the motion of the pendulum in terms of <em>angular</em> acceleration and <em>angular </em>velocity, which refer to the change of the arms angle <span data-type="equation">\theta</span> relative to the pendulums resting position. I should first warn you, especially if youre a seasoned physicist, that Im going to conveniently ignore several important concepts here: conservation of energy, momentum, centripetal force, and more. This isnt intended to be a comprehensive description of pendulum physics. My goal is to offer you an opportunity to practice your new skills in trigonometry and further explore the relationship between forces and angles through a concrete example.</p>
<div class="half-width-right">
<figure>
<img src="images/03_oscillation/03_oscillation_16.png" alt="Figure 3.19: A pendulum showing \theta as the angle relative to its resting position">
<figcaption>Figure 3.19: A pendulum showing <span data-type="equation">\theta</span> as the angle relative to its resting position</figcaption>
</figure>
</div>
<p>Instead of using <em>linear</em> acceleration and velocity, Im going to describe the motion of the pendulum in terms of <em>angular</em> acceleration and <em>angular </em>velocity, which refer to the change of the arms angle <span data-type="equation">\theta</span> relative to the pendulums resting position. I should first warn you, especially if youre a seasoned physicist, that Im going to conveniently ignore several important concepts here: conservation of energy, momentum, centripetal force, and more. This isnt intended to be a comprehensive description of pendulum physics. My goal is to offer you an opportunity to practice your new skills in trigonometry and further explore the relationship between forces and angles through a concrete example.</p>
<p>To calculate the pendulums angular acceleration, Im going to use Newtons second law of motion but with a little trigonometric twist. Take a look at Figure 3.19 and tilt your head so that the pendulums arm becomes the vertical axis. The force of gravity suddenly points askew, a little to the left—its at an angle with respect to your tilted head. If this is starting to hurt your neck, dont worry. Ill redraw the tilted figure and relabel the forces <span data-type="equation">F_g</span> for gravity and <span data-type="equation">T</span> for tension (Figure 3.20, left).</p>
<figure>
<img src="images/03_oscillation/03_oscillation_17.png" alt="Figure 3.20: On the left, the pendulum is drawn rotated so that the arm is the y-axis. The right shows F_g zoomed in and divided into components F_{gx} and F_{gy}.">

View file

@ -66,7 +66,8 @@ function draw() {
<p>This is about as simple as a particle can get. From here, I could take the particle in several directions. I could add the <code>applyForce()</code> method to affect the particles behavior (Ill do precisely this in a future example). I could also add variables to describe color and shape, or load a <code>p5.Image</code> to draw the particle in a more interesting way. For now, however, Ill focus on adding just one additional detail: <strong>life span</strong>.</p>
<p>Some particle systems involve an <strong>emitter</strong> that serves as the source of the particles. The emitter controls the initial settings for the particles: position, velocity, and more. It might emit a single burst of particles, a continuous stream of particles, or some variation thereof. The new feature here is that particles born at the emitter cant live forever. If they did, the p5.js sketch would eventually grind to a halt as the particles add up to an unwieldy number over time. As new particles are born, old particles need to be removed, creating the illusion of an infinite stream of particles without hurting the performance of the sketch.</p>
<p>There are many ways to decide when a particle is ready to be removed. For example, it could “die” when it comes into contact with another object or when it leaves the frame of the canvas. For now, Ill choose to give particles a <code>lifespan</code> variable that acts like a timer. It will start at 255 and count down to 0 as the sketch progresses, at which point the particle will be considered dead. Heres the added code in the <code>Particle</code> class:</p>
<pre class="codesplit" data-code-language="javascript">class Particle {
<div class="avoid-break">
<pre class="codesplit" data-code-language="javascript">class Particle {
constructor(x, y) {
this.position = createVector(x, y);
@ -90,6 +91,7 @@ function draw() {
circle(this.position.x, this.position.y, 8);
}
}</pre>
</div>
<p>With <code>lifespan</code> ranging from 255 to 0, it can conveniently double as the alpha transparency for the circle representing the particle. This way, when the particle is dead, it will have literally faded away.</p>
<p>With the addition of the <code>lifespan</code> property, Ill need one more method, one that can be queried (for a true or false answer) to determine whether the particle is alive or dead. This will come in handy when I write a separate class to manage the list of particles. Writing this method is pretty easy: I just need to check whether the value of <code>lifespan</code> is less than 0. If it is, return <code>true</code>; otherwise, return <code>false</code>:</p>
<pre class="codesplit" data-code-language="javascript"> isDead() {

View file

@ -480,11 +480,11 @@ function rules(a, b, c) {
<figcaption>Figure 7.27: Example scenarios for death and birth in the Game of Life</figcaption>
</figure>
<p>With the elementary CA, I visualized many generations at once, stacked as rows in a 2D grid. With the Game of Life, however, the CA is in two dimensions. I could try to create an elaborate 3D visualization of the results and stack all the generations in a cube structure (and in fact, you might want to try this as an exercise), but a more typical way to visualize the Game of Life is to treat each generation as a single frame in an animation. This way, instead of viewing all the generations at once, you see them one at a time, and the result resembles rapidly developing bacteria in a petri dish.</p>
<p>One of the exciting aspects of the Game of Life is that some known initial patterns yield intriguing results. For example, the patterns shown in Figure 7.28 remain static and never change.</p>
<figure>
<img src="images/07_ca/07_ca_29.png" alt="Figure 7.28: Initial configurations of cells that remain stable">
<figcaption>Figure 7.28: Initial configurations of cells that remain stable</figcaption>
</figure>
<p>One of the exciting aspects of the Game of Life is that some known initial patterns yield intriguing results. For example, the patterns shown in Figure 7.28 remain static and never change.</p>
<p>The patterns in Figure 7.29 oscillate back and forth between two states.</p>
<figure>
<img src="images/07_ca/07_ca_30.png" alt="Figure 7.29: Initial configurations of cells that oscillate between two states">

View file

@ -115,8 +115,7 @@
return n * factorial(n - 1);
}
}</pre>
<p>The <code>factorial()</code> function calls itself within its own definition. It may look a bit odd at first, but it works, as long as a stopping condition exists (in this case, <code>n &#x3C;= 1</code>) so the function doesnt get stuck calling itself forever. (Im using <code>&#x3C;=</code> instead of <code>===</code> as a safeguard against infinite recursion, but I should probably include additional error checking to manage noninteger or negative inputs to be more mathematically accurate.)</p>
<p>Figure 8.7 illustrates the steps that unfold when <code>factorial(4)</code> is called.</p>
<p>The <code>factorial()</code> function calls itself within its own definition. It may look a bit odd at first, but it works, as long as a stopping condition exists (in this case, <code>n &#x3C;= 1</code>) so the function doesnt get stuck calling itself forever. (Im using <code>&#x3C;=</code> instead of <code>===</code> as a safeguard against infinite recursion, but I should probably include additional error checking to manage noninteger or negative inputs to be more mathematically accurate.) Figure 8.7 illustrates the steps that unfold when <code>factorial(4)</code> is called.</p>
<figure>
<img src="images/08_fractals/08_fractals_9.png" alt="Figure 8.7: Visualizing the process of calling the recursive factorial() function">
<figcaption>Figure 8.7: Visualizing the process of calling the recursive <code>factorial()</code> function</figcaption>

View file

@ -518,12 +518,11 @@ function draw() {
<figcaption>Figure 10.10: Data points that are linearly separable (left) and data points that are nonlinearly separable, as a curve is required to separate the points (right)</figcaption>
</figure>
<p>Now imagine youre classifying plants according to soil acidity (x-axis) and temperature (y-axis). Some plants might thrive in acidic soils but only within a narrow temperature range, while other plants prefer less acidic soils but tolerate a broader range of temperatures. A more complex relationship exists between the two variables, so a straight line cant be drawn to separate the two categories of plants, <em>acidophilic</em> and <em>alkaliphilic</em> (see Figure 10.10, right). A lone perceptron cant handle this type of <strong>nonlinearly separable</strong> problem. (Caveat here: Im making up these scenarios. If you happen to be a botanist, please let me know if Im anywhere close to reality.)</p>
<p>One of the simplest examples of a nonlinearly separable problem is XOR (exclusive or). This is a logical operator, similar to the more familiar AND and OR. For <em>A</em> AND <em>B </em>to be true, both <em>A</em> and <em>B</em> must be true. With OR, either <em>A</em> or <em>B</em> (or both) can be true. These are both linearly separable problems. The truth tables in Figure 10.11 show their solution space. Each true or false value in the table shows the output for a particular combination of true or false inputs.</p>
<figure>
<img src="images/10_nn/10_nn_12.png" alt="Figure 10.11: Truth tables for the AND and OR logical operators. The true and false outputs can be separated by a line.">
<figcaption>Figure 10.11: Truth tables for the AND and OR logical operators. The true and false outputs can be separated by a line.</figcaption>
</figure>
<p>See how you can draw a straight line to separate the true outputs from the false ones?</p>
<p>One of the simplest examples of a nonlinearly separable problem is XOR (exclusive or). This is a logical operator, similar to the more familiar AND and OR. For <em>A</em> AND <em>B </em>to be true, both <em>A</em> and <em>B</em> must be true. With OR, either <em>A</em> or <em>B</em> (or both) can be true. These are both linearly separable problems. The truth tables in Figure 10.11 show their solution space. Each true or false value in the table shows the output for a particular combination of true or false inputs. See how you can draw a straight line to separate the true outputs from the false ones?</p>
<p>The XOR operator is the equivalent of (OR) AND (NOT AND). In other words, <em>A</em> XOR <em>B </em>evaluates to true only if one of the inputs is true. If both inputs are false or both are true, the output is false. To illustrate, lets say youre having pizza for dinner. You love pineapple on pizza, and you love mushrooms on pizza, but put them together, and yech! And plain pizza, thats no good either!</p>
<figure>
<img src="images/10_nn/10_nn_13.png" alt="Figure 10.12: The “truth” table for whether you want to eat the pizza (left) and XOR (right). Note how the true and false outputs cant be separated by a single line.">

View file

@ -278,11 +278,11 @@ function draw() {
<p>Now that Ive finished the <code>think()</code> method, the real challenge can begin: teaching the bird to win the game by consistently flapping its wings at the right moment. This is where the GA comes back into the picture. Recalling the discussion from <a href="/genetic-algorithms#">Chapter 9</a>, three key principles underpin Darwinian evolution: variation, selection, and heredity. Ill revisit each of these principles in turn as I implement the steps of the GA in this new context of neural networks.</p>
<h3 id="variation-a-flock-of-flappy-birds">Variation: A Flock of Flappy Birds</h3>
<p>A single bird with a randomly initialized neural network isnt likely to have any success at all. That lone bird will most likely jump incessantly and fly way off-screen, or sit perched at the bottom of the canvas awaiting collision after collision with the pipes. This erratic and nonsensical behavior is a reminder: a randomly initialized neural network lacks any knowledge or experience. The bird is essentially making wild guesses for its actions, so success is going to be rare.</p>
<p>This is where the first key principle of GAs comes in: <strong>variation</strong>. The hope is that by introducing as many different neural network configurations as possible, a few might perform slightly better than the rest. The first step toward variation is to add an array of many birds (Figure 11.4).</p>
<figure>
<img src="images/11_nn_ga/11_nn_ga_6.png" alt="Figure 11.4: A population of birds, each with unique neural networks, navigating through the pipes in the neuroevolution process">
<figcaption>Figure 11.4: A population of birds, each with unique neural networks, navigating through the pipes in the neuroevolution process</figcaption>
</figure>
<p>This is where the first key principle of GAs comes in: <strong>variation</strong>. The hope is that by introducing as many different neural network configurations as possible, a few might perform slightly better than the rest. The first step toward variation is to add an array of many birds (Figure 11.4).</p>
<pre class="codesplit" data-code-language="javascript">// Population size
let populationSize = 200;
// Array of birds