Jaan Tollander de Balschhttps://jaantollander.github.io/2020-01-24T00:00:00+02:00<em>Do the math.</em>How to Implement Continuous-Time Multi-Agent Crowd Simulation2020-01-24T00:00:00+02:002020-01-24T00:00:00+02:00Jaan Tollander de Balschtag:jaantollander.github.io,2020-01-24:/crowd-dynamics.html
<p><img src="../images/crowddynamics/crowddynamics.svg.png" /></p>
<blockquote>
</blockquote>
<p>In this article, we discuss the mathematics on how to implement a continuous-time multi-agent crowd simulation. The article covers two agent models, circular, unorientable model, and three-circle, orientable model. We include extensive discussion about simulation objects, simulation mechanics, and implementation details and conclude by addressing the shortcoming and challenges of this type of simulation. We intended this article as a reference implementation for crowd simulation. We have experimented with the implementation in the <a href="https://github.com/jaantollander/crowddynamics">crowddynamics</a> library.</p>
<p><img src="../images/crowddynamics/crowddynamics.svg.png" /></p>
<blockquote>
</blockquote>
<p>In this article, we discuss the mathematics on how to implement a continuous-time multi-agent crowd simulation. The article covers two agent models, circular, unorientable model, and three-circle, orientable model. We include extensive discussion about simulation objects, simulation mechanics, and implementation details and conclude by addressing the shortcoming and challenges of this type of simulation. We intended this article as a reference implementation for crowd simulation. We have experimented with the implementation in the <a href="https://github.com/jaantollander/crowddynamics">crowddynamics</a> library.</p>
<p><strong>Contents</strong></p>
<!-- TOC -->
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#geometric-primitives">Geometric Primitives</a></li>
<li><a href="#objects">Objects</a></li>
<li><a href="#agents">Agents</a>
<ul>
<li><a href="#circular-model">Circular Model</a></li>
<li><a href="#three-circle-model">Three-circle Model</a></li>
</ul></li>
<li><a href="#variables">Variables</a>
<ul>
<li><a href="#between-two-distinct-circular-agents">Between Two Distinct Circular Agents</a></li>
<li><a href="#between-circular-agent-and-line-obstacle">Between Circular Agent and Line-obstacle</a></li>
</ul></li>
<li><a href="#total-force">Total Force</a>
<ul>
<li><a href="#adjusting-force">Adjusting Force</a></li>
<li><a href="#contact-force">Contact Force</a></li>
<li><a href="#fluctuation-force">Fluctuation Force</a></li>
<li><a href="#social-force">Social Force</a></li>
</ul></li>
<li><a href="#total-torque">Total Torque</a>
<ul>
<li><a href="#adjusting-torque">Adjusting Torque</a></li>
<li><a href="#contact-torque">Contact Torque</a></li>
<li><a href="#fluctuation-torque">Fluctuation Torque</a></li>
</ul></li>
<li><a href="#pathfinding-and-obstacle-avoidance">Pathfinding and Obstacle Avoidance</a>
<ul>
<li><a href="#continuous-shortest-path">Continuous Shortest Path</a></li>
<li><a href="#desired-direction">Desired Direction</a></li>
<li><a href="#exponential-%CE%BB-function">Exponential λ-function</a></li>
<li><a href="#piecewise-linear-%CE%BB-function">Piecewise Linear λ-function</a></li>
</ul></li>
<li><a href="#computing-interactions">Computing Interactions</a>
<ul>
<li><a href="#agent-agent-interactions">Agent-Agent Interactions</a></li>
<li><a href="#agent-obstacle-interactions">Agent-Obstacle Interactions</a></li>
</ul></li>
<li><a href="#updating-the-system">Updating the System</a>
<ul>
<li><a href="#adaptive-timestep">Adaptive Timestep</a></li>
<li><a href="#verlet-integration">Verlet Integration</a></li>
</ul></li>
<li><a href="#parameter-and-attribute-values">Parameter and Attribute Values</a></li>
<li><a href="#implementation">Implementation</a></li>
<li><a href="#conclusion">Conclusion</a></li>
<li><a href="#references">References</a></li>
</ul>
<!-- /TOC -->
<p><strong>Keywords</strong>: crowd dynamics, crowd simulation, multi-agent, continuous-time, social force model, computational physics</p>
<h2 id="introduction">Introduction</h2>
<iframe width="1015" height="571" src="https://www.youtube.com/embed/PuAU3uNSHX4" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen>
</iframe>
<blockquote>
</blockquote>
<p>In this article, we discuss the implementation of a simulation model for crowd dynamics. We define <em>crowd dynamics</em> as the movement of crowds of people in respect of time. We implemented the simulation model using a continuous-time, Newtonian mechanics with an <em>agent-based</em> model, where each agent is a rigid body, in a two-dimensional lattice. In the model, the agents are intelligent self-propelled particles, whose movement is produced by non-physical and physical forces. The non-physical forces are referred to as <em>social forces</em>, for example, the desire to move toward a goal or collision avoidance. Hence, we refer to the model as the <em>social force model</em>, a term originating from <span class="citation" data-cites="Helbing2000a">(<a href="#ref-Helbing2000a" role="doc-biblioref">1</a>)</span>.</p>
<p>There also exist other types of models, such as <em>cellular automata</em> which models agents as an occupied or unoccupied cells in a discrete lattice, that is, a grid, and <em>continuum-based</em> models which model the crowd as a continuous mass. The agent-based model has the advantage of being the most realistic model, but it is also computationally the most challenging model.</p>
<p>There are real-life applications for research on how crowds of people move, for example:</p>
<ul>
<li>Improving the safety of buildings, mass events, and crowded places.</li>
<li>Estimating evacuation times and improving the evacuation process.</li>
<li>Venue design and improving the flow rate of the crowd in crowded places, such as subways.</li>
<li>Producing realistic movement in games, animations, and virtual reality.</li>
</ul>
<p>The authors of the book <span class="citation" data-cites="gibelli2019">(<a href="#ref-gibelli2019" role="doc-biblioref">2</a>)</span> give a comprehensive look at the subject of crowd dynamics.</p>
<p>In the following sections, we are going to explain in-depth the mathematics behind the agent-based model and how to implement the simulation.</p>
<h2 id="geometric-primitives">Geometric Primitives</h2>
<p>We define two-dimensional geometric primitives as follows:</p>
<ul>
<li><em>Point</em> is denoted as <span class="math inline">\(𝐩∈ℝ^2.\)</span></li>
<li><em>Circle</em> is defined as a pair <span class="math inline">\((𝐩, r)\)</span> where <span class="math inline">\(𝐩\)</span> is the center, and <span class="math inline">\(r\)</span> is the radius.</li>
<li><em>Line segment</em> is defined as a pair of points <span class="math inline">\((𝐩_1,𝐩_2)\)</span>.</li>
<li><em>Polygonal chain</em> is a sequence of points <span class="math inline">\((𝐩_1,...,𝐩_m),m≥2\)</span> where each pair <span class="math inline">\((𝐩_i,𝐩_{i+1})\)</span> for <span class="math inline">\(i=1,...,m-1\)</span> is a line segment.</li>
<li><em>Closed polygonal chain</em> is a polygonal chain where the endpoints <span class="math inline">\((𝐩_1,𝐩_m)\)</span> form a line segment.</li>
<li><em>Polygon</em> is a filled shape whose exterior is a closed polygonal chain.</li>
</ul>
<p>We use these geometric primitives for implementing some of the objects in the simulation.</p>
<h2 id="objects">Objects</h2>
<figure>
<img src="../images/crowddynamics/field.svg" alt="" /><figcaption>Example of a field with two sources, one target, obstacles and no agents. <a href="https://www.geogebra.org/m/bpvwdgx6">Link to Geogebra figure.</a></figcaption>
</figure>
<blockquote>
</blockquote>
<p>We will refer to the collection of objects that exists in the simulation as the <em>field</em>. The field consists of the following objects:</p>
<ul>
<li><p>The <em>domain</em> <span class="math inline">\(Ω⊂ℝ^2\)</span>, a subset of the lattice which contains all the other objects.</p></li>
<li><p>The set of <em>agents</em> <span class="math inline">\(\mathcal{A}_i⊂Ω\)</span> for <span class="math inline">\(i∈A\)</span> where <span class="math inline">\(A=\{1,...,n\}\)</span> are the indices. An agent is an impassable, dynamic object. We will denote two distinct agents using the indices as <span class="math inline">\(i,j∈A\)</span> where <span class="math inline">\(i≠j\)</span>.</p></li>
<li><p>The set of <em>obstacles</em> <span class="math inline">\(\mathcal{O}⊂Ω\)</span>. An obstacle is an impassable, static object. We denote obstacles using the subscript <span class="math inline">\(w∈W\)</span>, that is, <span class="math inline">\(\mathcal{O}_w ⊂ \mathcal{O}\)</span>.</p></li>
<li><p>The set of <em>targets</em> <span class="math inline">\(\mathcal{T}⊂Ω\)</span>. A target is a passable, static object.</p></li>
<li><p>The set of <em>sources</em> <span class="math inline">\(\mathcal{S}⊂Ω\)</span>. A source is a passable, static object. Initially, we place the agents inside a source without overlapping each other. For example, we can sample agent positions inside the source from a uniform distribution and whether the agent overlaps with other agents. If not, place the agent; otherwise, we will resample.</p></li>
</ul>
<p>We implement the obstacles using polygonal chains and the domain, targets, and sources using polygons. We describe the implementation of the agent’s shape in the <a href="#agents">Agents</a> section.</p>
<h2 id="agents">Agents</h2>
<figure>
<img src="../images/crowddynamics/agent-models.svg" alt="" /><figcaption>Circular and three-circle agent models. <a href="https://www.geogebra.org/m/wsyeuy42">Link to Geogebra figure.</a></figcaption>
</figure>
<blockquote>
</blockquote>
<p>In the agent-based model, each agent is a discrete object, modeled as a rigid body. We use two models for modeling the shape of the agent; circular and three-circle, models. In addition to shape, agents have other attributes such as mass and desired velocity.</p>
<h3 id="circular-model">Circular Model</h3>
<p>In the <em>circular model</em>, we model the agent’s shape using a circle. It is the simplest model and rotationally symmetrical. It is easiest to implement and compute and work well for sparse and medium-density crowds. However, it is not a very realistic model of the cross-section of the human torso. In reality, the human body is narrower and can fit through smaller spaces. In dense crowds, the circle model can result in artifacts and unrealistic density measures.</p>
<p>Each circular agent <span class="math inline">\(i∈A\)</span> has the following attributes.</p>
<ul>
<li><span class="math inline">\(𝐱_i\)</span> <em>center of mass</em></li>
<li><span class="math inline">\(𝐯_i\)</span> <em>velocity</em></li>
<li><span class="math inline">\(𝐟_i\)</span> <em>force</em></li>
<li><span class="math inline">\(\hat{𝐞}_i\)</span> <em>desired direction</em></li>
<li><span class="math inline">\(v_i\)</span> <em>desired velocity</em></li>
<li><span class="math inline">\(r_i\)</span> <em>radius</em></li>
<li><span class="math inline">\(m_i\)</span> <em>mass</em></li>
</ul>
<h3 id="three-circle-model">Three-circle Model</h3>
<p>The <em>three-circle model</em> consists of three circles representing the shoulders and midsection. The three-circle model is a more realistic representation of the human cross-section. However, since it is not rotationally symmetrical, simulation mechanics become more complex. For example, the model must include rotational motion and more complicated collision detection. In dense crowds, agents can move sideways, which requires solving desired body rotation. <span class="citation" data-cites="Langston2006 Korhonen2008b Stuvel2016a Hidalgo2017">(<a href="#ref-Langston2006" role="doc-biblioref">3</a>–<a href="#ref-Hidalgo2017" role="doc-biblioref">6</a>)</span></p>
<p>Each orientable agent has following additional attributes:</p>
<ul>
<li><span class="math inline">\(φ_i\)</span> <em>orientation</em></li>
<li><span class="math inline">\(ω_i\)</span> <em>angular velocity</em></li>
<li><span class="math inline">\(M_i\)</span> <em>torque</em></li>
<li><span class="math inline">\(φ_i^0\)</span> <em>desired orientation</em></li>
<li><span class="math inline">\(ω_i^0\)</span> <em>desired angular velocity</em></li>
<li><span class="math inline">\(I_i\)</span> <em>rotational moment</em></li>
</ul>
<p>We constrained the values of the orientations <span class="math inline">\(φ\)</span> and <span class="math inline">\(φ^0\)</span> into interval <span class="math inline">\([-π,π].\)</span></p>
<p>In addition to the attributes of the circular and rotatable agent, each three-circle agent has attributes as follows.</p>
<ul>
<li><span class="math inline">\(r_i^{t}\)</span> <em>torso radius</em></li>
<li><span class="math inline">\(r_i^{s}\)</span> <em>shoulder radius</em></li>
<li><span class="math inline">\(r_i^{ts}\)</span> <em>torso-to-shoulder radius</em></li>
</ul>
<p>Identity <span class="math inline">\(r_i^{ts} + r_i^s = r_i\)</span> holds for these attributes.</p>
<p>The following sections will discuss the simulation mechanics, including forces and torques. We cover the mechanics for the circular model in detail. The forces for the circular model can be generalized for the three-circle agent model by deriving the <a href="#variables">variables</a>, <a href="#social-force">social force</a>, and <a href="#contact-force">contact force</a> between three-circle agents and three-circle agent and line obstacle. However, for simplicity reasons, we have left the generalization out from this article for now.</p>
<h2 id="variables">Variables</h2>
<p>We define the <em>relative position</em> <span class="math inline">\(\tilde{𝐱}\)</span>, <em>relative velocity</em> <span class="math inline">\(\tilde{𝐯}\)</span>, <em>skin-to-skin distance</em> <span class="math inline">\(h\)</span> (can be negative), <em>normal (unit) vector</em> <span class="math inline">\(\hat{𝐧}\)</span> and <em>tangent (unit) vector</em> <span class="math inline">\(\hat{𝐭}\)</span>. We use these variables for computing the interaction potentials. We use <span class="math inline">\(R(ϕ)\)</span> to define the rotation matrix in two dimensions where <span class="math inline">\(ϕ∈[0°,360°]\)</span> is the angle in degrees.</p>
<h3 id="between-two-distinct-circular-agents">Between Two Distinct Circular Agents</h3>
<figure>
<img src="../images/crowddynamics/variables-circular-circular.svg" alt="" /><figcaption><a href="https://www.geogebra.org/m/rvw4bqxz">Link to Geogebra figure.</a></figcaption>
</figure>
<blockquote>
</blockquote>
<p>Between two distinct circular agents <span class="math inline">\(i,j∈A,i≠j\)</span> we have the variables as follows: Relative position <span class="math inline">\(\tilde{𝐱}=𝐱_j-𝐱_i\)</span>, relative velocity <span class="math inline">\(\tilde{𝐯}=𝐯_j-𝐯_i\)</span>, normal vector <span class="math inline">\(\hat{𝐧}=\tilde{𝐱}/\|\tilde{𝐱}\|\)</span>, tangent vector <span class="math inline">\(\hat{𝐭}=R(270°)⋅\hat{𝐧}\)</span> and skin-to-skin distance <span class="math inline">\(h=\|\tilde{𝐱}\|-(r_j+r_i).\)</span></p>
<h3 id="between-circular-agent-and-line-obstacle">Between Circular Agent and Line-obstacle</h3>
<figure>
<img src="../images/crowddynamics/variables-circular-line.svg" alt="" /><figcaption><a href="https://www.geogebra.org/m/aanhamfq">Link to Geogebra figure.</a></figcaption>
</figure>
<blockquote>
</blockquote>
<p>Between a circular agent <span class="math inline">\(i\)</span> and static line-obstacle <span class="math inline">\(w\)</span> defined as line segment <span class="math inline">\((𝐩_1,𝐩_2)\)</span>, we have following auxialiary variables: Line vector <span class="math inline">\(\tilde{𝐩} = 𝐩_2-𝐩_1\)</span>, line length <span class="math inline">\(l = \|\tilde{𝐩}\|\)</span>, line tangent <span class="math inline">\(𝐭_w = \tilde{𝐩}/l\)</span>, line normal <span class="math inline">\(𝐧_w = R(90°) ⋅ 𝐭_w\)</span>, two vectors from the agent’s center of mass to the line points <span class="math inline">\(𝐪_1 = 𝐩_1 - 𝐱_i\)</span> and <span class="math inline">\(𝐪_2 = 𝐩_2 - 𝐱_i\)</span>, and tangential distance of agent’s center of mass from line points <span class="math inline">\(l_t = 𝐭_w⋅(𝐪_1 + 𝐪_2).\)</span></p>
<p>Now, we determine the relative position of the center of mass compared to the line segment. We have three distinct cases:</p>
<ol type="1">
<li><span class="math inline">\(l_t > l\)</span>: Center of mass <span class="math inline">\(𝐱_i\)</span> is on the left of the line perpendicular to <span class="math inline">\(\tilde{𝐩}\)</span> intersecting <span class="math inline">\(𝐩_1\)</span>.</li>
<li><span class="math inline">\(l_t < -l\)</span>: Center of mass <span class="math inline">\(𝐱_i\)</span> is on the right of the line perpendicular to <span class="math inline">\(\tilde{𝐩}\)</span> intersecting <span class="math inline">\(𝐩_2\)</span>.</li>
<li>Otherwise: The center of mass <span class="math inline">\(𝐱_i\)</span> is between the perpendicular lines.</li>
</ol>
<p>We define the variables as follows: Skin-to-skin distance is <span class="math display">\[
\begin{aligned}
d&=
\begin{cases}
\|𝐪_1\| & l_t > l \\
\|𝐪_2\| & l_t < -l \\
|𝐪_1⋅𝐧_w| & \mathrm{otherwise}
\end{cases}
\\
h&=d-r_i
\end{aligned}.
\]</span></p>
<p>Normal vector is <span class="math display">\[
\hat{𝐧}=
\begin{cases}
𝐪_1/\|𝐪_1\| & l_t > l \\
𝐪_2/\|𝐪_2\| & l_t < -l \\
\operatorname{sign}(𝐪_1⋅𝐧_w) 𝐧_w & \mathrm{otherwise}
\end{cases}.
\]</span></p>
<p>Tangent vector <span class="math inline">\(\hat{𝐭}=R(270°)⋅\hat{𝐧}\)</span>, and relative velocity <span class="math inline">\(\tilde{𝐯}=𝐯_i-𝐯_w=𝐯_i.\)</span> We do not need the relative position <span class="math inline">\(\tilde{𝐱}\)</span> between agent and line-obstacle.</p>
<h2 id="total-force">Total Force</h2>
<p>The total force on an agent <span class="math inline">\(i∈A\)</span> consists of the adjusting force, physical contact forces, social forces and fluctuation force. We define it as <span class="math display">\[
𝐟_i = 𝐟_{i}^{adj} + ∑_{j∈A,j≠i} (𝐟_{i,j}^{soc} + 𝐟_{i,j}^{con}) + ∑_{w∈W} 𝐟_{i,w}^{con} + \mathbf{ξ}_i.
\label{eq:1}
\tag{1}
\]</span> This section discuss about computing each of these constituents.</p>
<h3 id="adjusting-force">Adjusting Force</h3>
<p>The adjusting force accounts for the agent’s desire to reach its destination. It works by adjusting the total force to align with the desired direction <span class="math inline">\(\hat{𝐞}\)</span> in the characteristic time <span class="math inline">\(τ_{adj}\)</span>. We define it as <span class="math display">\[
𝐟_{adj} = \frac{m}{τ_{adj}} (v \hat{𝐞} - 𝐯),
\label{eq:2}
\tag{2}
\]</span> where <span class="math inline">\(m\)</span> is the mass, <span class="math inline">\(v\)</span> is the desired velocity, <span class="math inline">\(𝐯\)</span> is the current velocity, and <span class="math inline">\(τ_{adj}\)</span> is the characteristic time.</p>
<h3 id="contact-force">Contact Force</h3>
<p>The contact force account for the physical contact with agents and other objects. We define the contact force as the sum of <em>tangential friction</em>, <em>counter compressive</em>, and <em>damping</em> forces <span class="math display">\[
𝐟_{con} =
\begin{cases}
h κ (\tilde{𝐯} ⋅ \hat{𝐭}) \hat{𝐭} - h μ \hat{𝐧} + γ (\tilde{𝐯} ⋅ \hat{𝐧}) \hat{𝐧} & h≤0 \\
0, & h>0
\end{cases}
\label{eq:3}
\tag{3}
\]</span> where <span class="math inline">\(κ\)</span> is tangential friction coefficient, <span class="math inline">\(μ\)</span> is the counter compressive coefficient, <span class="math inline">\(γ\)</span> is the damping coefficient, <span class="math inline">\(\hat{𝐧}\)</span> is the normal unit vector and <span class="math inline">\(\hat{𝐭}\)</span> is the normal tangent vector. It follows the original formula used by <span class="citation" data-cites="Helbing2000a">(<a href="#ref-Helbing2000a" role="doc-biblioref">1</a>)</span> with the addition of the damping by <span class="citation" data-cites="Langston2006">(<a href="#ref-Langston2006" role="doc-biblioref">3</a>)</span>.</p>
<p>It is important to note that the friction model models the whole friction between two objects. Therefore, if an agent touches multiple line obstacles, we must compute the force as a weighted average of the contact forces between all of the line-obstacles. Otherwise, the model would give inconsistent results for friction between similar objects. For example, if we compute we naively computed the friction between the agent and line obstacle, and then split the line obstacle into two line-obstacles in the point of contact, the model would give twice as high friction between the split obstacle.</p>
<h3 id="fluctuation-force">Fluctuation Force</h3>
<p>Fluctuation force is a stochastic force analogous to heat in particle systems. It accounts for the lateral movement of the agents and breaks symmetries in the simulation. <span class="math display">\[
\mathbf{ξ}=ξ\hat{𝐮}(φ)
\label{eq:4}
\tag{4}
\]</span></p>
<p>We draw the magnitude of the fluctuation force from a truncated normal distribution <span class="math inline">\(ξ∼N(0, σ_ξ^2)\)</span> where <span class="math inline">\(σ_ξ^2\)</span> is the variance and the direction from a uniform distribution <span class="math inline">\(φ∼U(0, 2π)\)</span>. The normal distribution <span class="math inline">\(N\)</span> is truncated to three standard deviations. We define <span class="math inline">\(\hat{𝐮}(φ)\)</span> to be a unit vector to direction <span class="math inline">\(φ\)</span>.</p>
<h3 id="social-force">Social Force</h3>
<p>The social force between agents accounts for collision avoidance. The original social force model used social force only dependent on the distance between agents. However, <span class="citation" data-cites="Karamouzas2014a Karamouzas2014b">(<a href="#ref-Karamouzas2014a" role="doc-biblioref">7</a>, <a href="#ref-Karamouzas2014b" role="doc-biblioref">8</a>)</span> introduced a more realistic, statistical mechanics-based approach for modeling this interaction. The interaction depends on the linearly estimated future positions on the agents, which takes into account the positions and velocities of the agents. The authors derived it from a pair-wise interaction potential that follows the power law, and it is backed up by experimental data. The potential is defined <span class="math display">\[
E(τ) = m \frac{k}{τ^2} \exp \left( -\frac{τ}{τ_{soc}} \right),
\label{eq:5}
\tag{5}
\]</span> where <span class="math inline">\(k\)</span> is a social force scaling coefficient and <span class="math inline">\(τ_{soc}\)</span> is the interaction time horizon. The time-to-collision <span class="math inline">\(τ\)</span> is obtained by linear extrapolation of the current trajectories of the agents and solving the root for <em>skin-to-skin</em> distance <span class="math inline">\(h\)</span> as a function of <span class="math inline">\(τ\)</span> between these agents. The resulting <span class="math inline">\(τ\)</span> is a function of the relative position <span class="math inline">\(\tilde{𝐱}\)</span>. We can derive the corresponding force by taking the spatial gradient of the potential <span class="math display">\[
𝐟_{soc} = -∇_{\tilde{𝐱}} E(τ) = - m k \left(\frac{1}{τ^2}\right) \left(\frac{2}{τ} + \frac{1}{τ_{soc}}\right) \exp\left (-\frac{τ}{τ_{soc}}\right ) ∇_{\tilde{𝐱}} τ.
\label{eq:6}
\tag{6}
\]</span> If <span class="math inline">\(τ\)</span> is not defined, the force <span class="math inline">\(𝐟_{soc}\)</span> is equal to zero.</p>
<p>For two circular agents with radius <span class="math inline">\(r_i\)</span> and <span class="math inline">\(r_j\)</span> the skin-to-skin distance is the distance between their positions subtracted by the sum of the radii <span class="math display">\[
\begin{aligned}
h(τ) &= \|(𝐱_i + τ 𝐯_i) - (𝐱_j + τ 𝐯_j)\| - (r_i+r_j) \\
&= \|\tilde{𝐱} + τ \tilde{𝐯}\| - (r_i+r_j).
\end{aligned}
\]</span> We receive the quadratic equation in terms of <span class="math inline">\(τ\)</span> by settings <span class="math inline">\(h(τ)=0\)</span> <span class="math display">\[
\begin{aligned}
\|\tilde{𝐱} + τ \tilde{𝐯}\| - (r_i+r_j) &= 0 \\
\|\tilde{𝐱} + τ \tilde{𝐯}\|^2 &= (r_i+r_j)^2 \\
\|\tilde{𝐯}\|^2 τ^2 + (\tilde{𝐱}⋅\tilde{𝐯}) τ + \|\tilde{𝐱}\|^2 - (r_i+r_j)^2 &= 0.
\end{aligned}
\]</span> We solve the quadratic equation <span class="math display">\[
τ = \frac{b-\sqrt{b^2-ac}}{a},
\label{eq:7}
\tag{7}
\]</span> where <span class="math inline">\(a=\|\tilde{𝐯}\|^2\)</span>, <span class="math inline">\(b=-\tilde{𝐱}⋅\tilde{𝐯}\)</span>, and <span class="math inline">\(c=\|\tilde{𝐱}\|^2-(r_i+r_j)^2\)</span>. Now we can solve the gradient <span class="math display">\[
∇_{\tilde{𝐱}} τ = \frac{1}{a} \left(\tilde{𝐯} - \frac{a \tilde{𝐱}+b\tilde{𝐯}}{\sqrt{b^2-a c}}\right).
\label{eq:8}
\tag{8}
\]</span> By substituting the gradient to the social force, we can use it in the simulation.</p>
<h2 id="total-torque">Total Torque</h2>
<p>The total torque on agent <span class="math inline">\(i∈A\)</span> consists of the adjusting, contact and fluctuation torque. We define it as <span class="math display">\[
M_i = M_i^{adj} + ∑_j M_{i,j}^{con} + ∑_w M_{i,w}^{con} + η.
\label{eq:9}
\tag{9}
\]</span> This section discuss about computing each of these constituents.</p>
<h3 id="adjusting-torque">Adjusting Torque</h3>
<p>The adjusting torque accounts for the agent’s desire to rotate its body to aligh with the desired orientation <span class="math inline">\(φ_0\)</span> in the characteristic time <span class="math inline">\(τ_{rot}\)</span>. We define it as <span class="math display">\[
M_{adj} = \frac{I}{τ_{rot}} \left(\frac{w_π(φ_0-φ)}{π} ω_0 - ω\right)
\label{eq:10}
\tag{10}
\]</span></p>
<p>The function <span class="math inline">\(w_π\)</span> wraps an arbitrary angle <span class="math inline">\(φ\)</span> in radians to the interval <span class="math inline">\((-π,π]\)</span>. The function <span class="math inline">\(w_π\)</span> is defined as <span class="math display">\[
\begin{aligned}
w_π(φ) &= w_π'(φ \mod 2π) \\
w_π'(\hat{φ}) &=
\begin{cases}
\hat{φ} & \hat{φ}≤π \\
\hat{φ}-2π & \hat{φ}>π
\end{cases}.
\end{aligned}
\label{eq:11}
\tag{11}
\]</span></p>
<p>We can set the desired orientation <span class="math inline">\(φ_0\)</span> to walking direction. In dense crowds, the realistic behavior of the desired orientation might be different. For example, an agent might try to squeeze sideways through two agents. However, we have not implemented algorithms for modeling such behavior.</p>
<h3 id="contact-torque">Contact Torque</h3>
<p>The contact torque account for the torque caused by the contact force <span class="math inline">\(𝐟_{con}\)</span>. We define it as <span class="math display">\[
M_{con} = 𝐫 × 𝐟_{con},
\label{eq:12}
\tag{12}
\]</span> where <span class="math inline">\(𝐫\)</span> is the contact position vector. The contact position vector is a vector from the agents center of mass <span class="math inline">\(𝐱\)</span> to the contact point.</p>
<p>The cross product between two <span class="math inline">\(2\)</span>-dimensional vectors <span class="math inline">\(𝐮\)</span> and <span class="math inline">\(𝐯\)</span> is defined as <span class="math display">\[
𝐮×𝐯 = u_0 v_1 - u_1 v_0.
\label{eq:13}
\tag{13}
\]</span> It is the <span class="math inline">\(z\)</span>-component of <span class="math inline">\(3\)</span>-dimensional cross product of vectors <span class="math inline">\(𝐮\)</span> and <span class="math inline">\(𝐯\)</span> with <span class="math inline">\(z\)</span>-components that are zero.</p>
<h3 id="fluctuation-torque">Fluctuation Torque</h3>
<p>The fluctuation torque accounts for the stochastic fluctuation in the agent’s orientation. We define it as <span class="math display">\[
η = I ζ,
\label{eq:14}
\tag{14}
\]</span> where the magnitude is drawn from a truncated normal distribution <span class="math inline">\(ζ ∼ N(0, σ_ζ^2)\)</span> with variance <span class="math inline">\(σ_ζ^2.\)</span> The normal distribution is truncated to three standard deviations.</p>
<h2 id="pathfinding-and-obstacle-avoidance">Pathfinding and Obstacle Avoidance</h2>
<figure>
<img src="../images/crowddynamics/AvoidObstacle.png" alt="" /><figcaption>In the figure, the contour represents the distance map, and the arrows represent the direction map to the target while avoiding the obstacles. <a href="../images/crowddynamics/AvoidObstacle.html">Link to HTML figure.</a></figcaption>
</figure>
<blockquote>
</blockquote>
<p>In this simulation, we handle the psychological avoidance of obstacles by altering the agent’s desired direction away from obstacles if they get too close. We handle the pathfinding by assuming that agents follow the shortest path to their targets, taking into account the finite size of the agents. The approach is computationally efficient since we have to compute the shortest path only once. <span class="citation" data-cites="Kretz2011a Cristiani2015b">(<a href="#ref-Kretz2011a" role="doc-biblioref">9</a>, <a href="#ref-Cristiani2015b" role="doc-biblioref">10</a>)</span></p>
<h3 id="continuous-shortest-path">Continuous Shortest Path</h3>
<p>The solution to <a href="https://en.wikipedia.org/wiki/Eikonal_equation"><em>eikonal equation</em></a> gives us the minimal amount of time required to travel from <span class="math inline">\(x\)</span> to the boundary <span class="math inline">\(∂Ω\)</span>. The eikonal equation is defined as <span class="math display">\[
\begin{aligned}
\|S(𝐱)\| &= \frac{1}{f(𝐱)},\quad 𝐱∈Ω, \\
S(𝐱) &= q(𝐱),\quad 𝐱∈∂Ω
\end{aligned}
\label{eq:15}
\tag{15}
\]</span> where <span class="math inline">\(f:Ω→(0,+∞)\)</span> is the <em>speed of travel</em> and <span class="math inline">\(q:∂Ω→[0,+∞)\)</span> is the <em>exit-time penalty</em>. The solution with a constant speed of travel <span class="math inline">\(f\)</span> is a continuous shortest path, refered as a <em>distance map</em>.</p>
<p>We will also define a unit-vector field, referred as a <em>direction map</em>, which points towards the boundary with the lowest exit-time penalty, as the normalized gradient <span class="math display">\[
D(S(𝐱))=-\frac{∇S(𝐱)}{\| ∇S(𝐱) \|}.
\label{eq:16}
\tag{16}
\]</span></p>
<p>We can solve the Eikonal equation using existing algorithms, such as <em>Fast Marching Method</em>.</p>
<h3 id="desired-direction">Desired Direction</h3>
<p>We define a <em>avoidance radius</em> as <span class="math inline">\(r>0\)</span> and <em>buffered obstacles</em> <span class="math inline">\(𝓞'\)</span> as the set of points at a distance less or equal to <span class="math inline">\(r\)</span> from obstacles <span class="math inline">\(𝓞.\)</span> We define the <em>desired direction</em> as a weighted average of two direction maps, one pointing to the target and one away from obstacles such that the weight depends on the proximity from the obstacles. When agents are closer to the obstacles, they desire more strongly away from them, and when they are further away from obstacles, they desire more strongly towards targets.</p>
<p>Let <span class="math inline">\(T(𝐱)\)</span> be a distance map to target <span class="math inline">\(𝓣\)</span> with domain <span class="math inline">\(Ω\)</span> and exit-time penalty <span class="math inline">\(T(𝐱) = 0,\, 𝐱 ∈ 𝓣\)</span> and <span class="math inline">\(T(𝐱) → ∞,\, 𝐱 ∈ 𝓞'\)</span>. Let <span class="math inline">\(O(𝐱)\)</span> be the distance map to obstacles <span class="math inline">\(𝓞\)</span> with domain <span class="math inline">\(Ω\)</span> and exit-time penalty <span class="math inline">\(O(𝐱) = 0,\, 𝐱 ∈ 𝓞\)</span>. The desired direction is then defined as <span class="math display">\[
\hat{𝐞}(𝐱) = λ(O(𝐱)) D(T(𝐱)) + (1 - λ(O(𝐱))) D(O(𝐱)),
\label{eq:17}
\tag{17}
\]</span> where <span class="math inline">\(λ: ℝ^+ → [0, 1]\)</span> is decreasing function, <span class="math inline">\(\frac{d}{dx} λ(x)≤0\)</span>, such that <span class="math inline">\(λ(0) = 1\)</span> and <span class="math inline">\(\lim_{x→∞} λ(x) = 0\)</span>.</p>
<p>We will set the avoidance radius <span class="math inline">\(r\)</span> sufficiently larger than <span class="math inline">\(\max_{i∈A} r_i\)</span>, which ensures that agents tend away from the obstacles.</p>
<h3 id="exponential-λ-function">Exponential λ-function</h3>
<p>For example, we can use the exponential function, defined as <span class="math inline">\(λ(x) = ab^{c x},\)</span> with coefficients <span class="math inline">\(a,b,c\)</span> where <span class="math inline">\(b>0\)</span>, which we can solve from the properties of function <span class="math inline">\(λ\)</span>. Additionally, we require <span class="math inline">\(λ(r)=ϵ>0\)</span> such that <span class="math inline">\(ϵ\)</span> is close to zero.</p>
<ol type="1">
<li><span class="math inline">\(λ(0)=a=1\)</span></li>
<li><span class="math inline">\(λ(r)=b^{c r}=ϵ\)</span> gives us <span class="math inline">\(c=\frac{\log_b ϵ}{r}\)</span> therefore <span class="math inline">\(λ(x)=ϵ^{x/r}\)</span></li>
<li><span class="math inline">\(\lim_{x→∞} λ(x) = 0\)</span> implies <span class="math inline">\(ϵ<1\)</span></li>
<li>Lastly, we verify that the function is decreasing, that is, <span class="math inline">\(\frac{d}{dx} λ(x)=\frac{\log ϵ}{r} ϵ^{x/r}<0.\)</span> Note that <span class="math inline">\(\log ϵ<0\)</span> because <span class="math inline">\(0<ϵ<1.\)</span></li>
</ol>
<p>The resulting function <span class="math inline">\(λ\)</span> is defined as <span class="math display">\[
λ(x)=ϵ^{x/r},
\label{eq:18}
\tag{18}
\]</span> where <span class="math inline">\(0<ϵ<1\)</span> is referred as <em>strength</em> and <span class="math inline">\(r>0\)</span> is the avoidance radius.</p>
<h3 id="piecewise-linear-λ-function">Piecewise Linear λ-function</h3>
<p>We can also use a piecewise linear function such that <span class="math inline">\(λ(r)=0\)</span>. Then we have <span class="math display">\[
λ(x)=
\begin{cases}
-x/r+1 & x≤r \\
0 & x>r
\end{cases}.
\label{eq:19}
\tag{19}
\]</span> This formulation is also a logical choice since the smoothness of the exponential formulation does not bring any additional value in the agent-based simulation.</p>
<h2 id="computing-interactions">Computing Interactions</h2>
<figure>
<img src="../images/crowddynamics/computing-interactions.svg" alt="" /><figcaption>Figure illustrating the idea of fixed-radius near neighbor search. We partition the bounding box of the agents into cells of size <span class="math inline">\(r_c\)</span>. Therefore, all agents, at most distance <span class="math inline">\(r_c\)</span>, from agents in cell <span class="math inline">\(c\)</span> are within cell <span class="math inline">\(c\)</span> or its neighboring cells. We add the padding cells to avoid bounds checks during computation. <a href="https://www.geogebra.org/m/hp52zjwg">Link to Geogebra figure.</a></figcaption>
</figure>
<blockquote>
</blockquote>
<p>In the simulation, we have two types of <em>interactions</em>, agent-agent and agent-obstacle interactions. Interactions are computationally the most challenging part of the simulation, and therefore it is worth-while to optimize how we compute them.</p>
<p>The equations <span class="math inline">\(\eqref{eq:1}\)</span> and <span class="math inline">\(\eqref{eq:9}\)</span> express the interactions as the summation of the interaction potentials, that is, contact and social forces and torques. Both interactions depend on the distance between the objects.</p>
<ul>
<li><p>Contact interactions only take place if the objects collide with each other.</p></li>
<li><p>Social force approaches zero at exponential speed as time-to-collision increases, that is, as the distance between agents increases. Therefore, we can define a cutoff distance <span class="math inline">\(r_{c}≥0\)</span> such that when <span class="math inline">\(h>r_{c}\)</span>, the social force is close enough to zero that we can approximate it as zero.</p></li>
</ul>
<p>We will refer to these interactions that have a finite range as <em>local interactions</em>. For local interactions, computing the total interaction potential requires summing the interaction potentials with the pairs of objects within the interaction radius <span class="math inline">\(r_{c}≥0\)</span>. Fortunately, there exist efficient methods for finding such pairs of objects, which we will briefly discuss in this section.</p>
<h3 id="agent-agent-interactions">Agent-Agent Interactions</h3>
<p>To find neighboring agent pairs within distance <span class="math inline">\(r\)</span>, we can use <em>fixed-radius nearest neighbor search</em>. In particular, we use the <em>cell lists</em> algorithm, which improves the difficulty over brute force, from <span class="math inline">\(O(n^2)\)</span> to <span class="math inline">\(O(n).\)</span> Agents are required to have two properties:</p>
<ol type="1">
<li>Agent-agent interactions are local.</li>
<li>Agents have a finite size. Therefore, only a finite amount of agents can fit inside a finite area.</li>
</ol>
<p>In practice, Cell Lists is better once the number of agent <span class="math inline">\(n\)</span> is large enough due to the size of the constant term in the <span class="math inline">\(O\)</span>-notation and overhead of the cell lists algorithm. The exact size of <span class="math inline">\(n\)</span> when Cell lists is better must be determined experimentally. We have implemented the <a href="https://github.com/jaantollander/cell_lists">Cell lists</a> algorithm in the link.</p>
<h3 id="agent-obstacle-interactions">Agent-Obstacle Interactions</h3>
<p>Implementing efficient collision detection between agents and obstacles is not covered in this article. We recommend looking at spatial hashing techniques or how other physics engines implement collision detection.</p>
<h2 id="updating-the-system">Updating the System</h2>
<p>In order to update the system, we need to solve the second-order differential equations numerically. The translational motion is defined by the equation <span class="math display">\[
m \frac{d^2}{dt^2} 𝐱(t) = 𝐟(t).
\label{eq:20}
\tag{20}
\]</span></p>
<p>The rotational motion is defined by the equation <span class="math display">\[
I \frac{d^2}{dt^2} φ(t) = M(t).
\label{eq:21}
\tag{21}
\]</span></p>
<p>Because computing the total force on the agents is computationally expensive, we will use the first-order integrator. We chose to use <em>Verlet integration</em> with <em>adaptive timestep</em> <span class="math inline">\(Δt\)</span>.</p>
<h3 id="adaptive-timestep">Adaptive Timestep</h3>
<p>Adaptive timestep is selected from interval <span class="math inline">\([Δt_{min}, Δt_{max}]\)</span> such that we limit the maximum distance that an agent can move in each iteration. First, we define <span class="math display">\[
Δt_{mid} = Δt_{max} \frac{\max_{i∈A} v_i}{\max_{i∈A} \|𝐯_i\|}
\label{eq:22}
\tag{22}
\]</span> where <span class="math inline">\(\|𝐯_i\|\)</span> is agent’s current velocity and <span class="math inline">\(v_i\)</span> is agent’s target velocity. Then, the adaptive timestep is defined <span class="math display">\[
Δ t =
\begin{cases}
Δt_{min} & Δt_{mid} < Δt_{min} \\
Δt_{mid} & \mathrm{otherwise} \\
Δt_{max} & Δt_{mid} > Δt_{max}
\end{cases}.
\label{eq:23}
\tag{23}
\]</span></p>
<p>The adaptive timestep helps to avoid numerical errors in the simulation.</p>
<h3 id="verlet-integration">Verlet Integration</h3>
<p>Verlet integration algorithm updates the new velocity and position at iteration <span class="math inline">\(k=0,1,...\)</span> as follows</p>
<p><span class="math display">\[
\begin{aligned}
𝐯'&=𝐯_k+𝐚_k Δt/2 \\
𝐚_{k+1}&=𝐟_{k+1}/m \\
𝐱_{k+1}&=𝐱_k+𝐯' Δt \\
𝐯_{k+1}&=𝐯'+𝐚_{k+1} Δt/2
\end{aligned}
\label{eq:24}
\tag{24}
\]</span></p>
<p>The main difference to Euler integration is that Verlet integration updates the velocity using the mean of current and previous accelerations. Verlet integration for the rotational motion work similarly. <span class="math display">\[
\begin{aligned}
ω'&=ω_k+α_k Δt/2 \\
α_{k+1}&=M_{k+1}/I \\
φ_{k+1}&=φ_k+ω' Δt \\
ω_{k+1}&=ω'+α_{k+1} Δt/2
\end{aligned}
\label{eq:25}
\tag{25}
\]</span></p>
<p>Also, we wrap the new orientation to pi <span class="math display">\[
φ_{k+1} = w_π(φ_{k+1})
\]</span></p>
<h2 id="parameter-and-attribute-values">Parameter and Attribute Values</h2>
<table>
<caption>Anthropological data of human dimensions. <span class="citation" data-cites="Korhonen2008c">(<a href="#ref-Korhonen2008c" role="doc-biblioref">11</a>)</span></caption>
<thead>
<tr class="header">
<th></th>
<th>adult</th>
<th>male</th>
<th>female</th>
<th>child</th>
<th>eldery</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>torso ratio <span class="math inline">\(k_{t}\)</span> [%]</td>
<td>0.5882</td>
<td>0.5926</td>
<td>0.5833</td>
<td>0.5714</td>
<td>0.6</td>
</tr>
<tr class="even">
<td>shoulder ratio <span class="math inline">\(k_{s}\)</span> [%]</td>
<td>0.3725</td>
<td>0.3704</td>
<td>0.375</td>
<td>0.3333</td>
<td>0.36</td>
</tr>
<tr class="odd">
<td>torso-to-shoulder ratio <span class="math inline">\(k_{ts}\)</span> [%]</td>
<td>0.6275</td>
<td>0.6296</td>
<td>0.625</td>
<td>0.6667</td>
<td>0.64</td>
</tr>
<tr class="even">
<td>average radius <span class="math inline">\(r\)</span> [m]</td>
<td>0.255±0.035</td>
<td>0.27±0.02</td>
<td>0.24±0.02</td>
<td>0.21±0.015</td>
<td>0.25±0.02</td>
</tr>
<tr class="odd">
<td>average velocity <span class="math inline">\(v\)</span> [m/s]</td>
<td>1.25±0.3</td>
<td>1.35±0.2</td>
<td>1.15±0.2</td>
<td>0.9±0.3</td>
<td>0.8±0.3</td>
</tr>
<tr class="even">
<td>average mass <span class="math inline">\(m\)</span> [kg]</td>
<td>73.5</td>
<td>80</td>
<td>67</td>
<td>57</td>
<td>70</td>
</tr>
</tbody>
</table>
<p>Agent <span class="math inline">\(i∈A\)</span> initial values and attributes are:</p>
<ul>
<li><span class="math inline">\(𝐱_i\)</span>: The center of mass is drawn from random uniform distribution inside a designated source without overlapping with other agents or obstacles.</li>
<li><span class="math inline">\(𝐯_i\)</span>: The velocity is set zero vector or to an instance dependent value.</li>
<li><span class="math inline">\(𝐟_i\)</span>: The force is set to zero vector.</li>
<li><span class="math inline">\(\hat{𝐞}_i\)</span>: The desired direction is set to zero vector or to an instance dependent value.</li>
<li><span class="math inline">\(v_i\)</span>: The desired velocity is set according to the anthropological data, for example, as the average walking speed of a human.</li>
<li><span class="math inline">\(r_i\)</span>: The radius is set according to the anthropological data.</li>
<li><span class="math inline">\(m_i\)</span>: The mass is set according to the anthropological data.</li>
</ul>
<p>Orientable agent model initial values and attributes:</p>
<ul>
<li><span class="math inline">\(φ_i\)</span>: The orientation is set to same angle an initial direction.</li>
<li><span class="math inline">\(ω_i\)</span>: The angular velocity is set to zero.</li>
<li><span class="math inline">\(M_i\)</span>: The torque is set to zero.</li>
<li><span class="math inline">\(φ_i^0\)</span>: The desired orientation set to same angle an initial direction.</li>
<li><span class="math inline">\(ω_i^0\)</span>: The desired angular velocity is set to <span class="math inline">\(2π/3.\)</span></li>
<li><span class="math inline">\(I_i\)</span>: The rotational moment is set to value <span class="math inline">\(4π (m_i/m_0) (r_i/r_0)^2\)</span> where <span class="math inline">\(m_0=80\)</span> and <span class="math inline">\(r_0=0.27\)</span>, which means that agent with mass <span class="math inline">\(m_0\)</span> and radius <span class="math inline">\(r_0\)</span> has moment <span class="math inline">\(4π\)</span> and other values are scaled according to the equation for moment of inertia.</li>
</ul>
<p>Three-circle agent model attributes:</p>
<ul>
<li><span class="math inline">\(r_i^t=k_{t} r_i\)</span>: Torso radius is set according to the anthropological data.</li>
<li><span class="math inline">\(r_i^s=k_{s} r_i\)</span>: Shoulder radius is set according to the anthropological data.</li>
<li><span class="math inline">\(r_i^{ts}=k_{ts} r_i\)</span>: Torso-to-shoulder radius is set according to the anthropological data.</li>
</ul>
<p>Force parameters:</p>
<ul>
<li><span class="math inline">\(t_{adj}=0.5\)</span></li>
<li><span class="math inline">\(κ=4⋅10^4\)</span></li>
<li><span class="math inline">\(μ=1.2⋅10^5\)</span></li>
<li><span class="math inline">\(γ=500\)</span></li>
<li><span class="math inline">\(σ_ξ^2=0.1^2\)</span></li>
<li><span class="math inline">\(k=1.5\)</span></li>
<li><span class="math inline">\(τ_{soc}=3.0\)</span></li>
</ul>
<p>Torque parameters:</p>
<ul>
<li><span class="math inline">\(τ_{rot}=0.2\)</span></li>
<li><span class="math inline">\(σ_ζ^2=0.1\)</span></li>
</ul>
<p>Integrator parameters:</p>
<ul>
<li><span class="math inline">\(Δt_{min}=0.001\)</span></li>
<li><span class="math inline">\(Δt_{max}=0.01\)</span></li>
</ul>
<h2 id="implementation">Implementation</h2>
<p>We have experimented with the algorithms in the <a href="https://github.com/jaantollander/crowddynamics">crowddynamics</a> library and verified that they operate correctly. However, based on the experiences of implementing the library, we learned that creating large, complex simulations is implausible without a <em>graphical user interface</em> (GUI) and <em>extendable program architecture</em>. For example, if we wish to create and edit the field, logic, and set initial parameter and attribute values graphically, we require these features. For this reason, we advise building the simulation on top of existing software, such as a <em>physics engine</em> or <em>game engine</em>. We have the following suggestion for the software features required of this software.</p>
<ul>
<li><p><em>Optional GUI</em>. Ability to simulate with or without the graphical user interface. For example, we may wish to develop the simulation on our local machine with graphics and then run multiple scenarios in parallel in the cloud without the graphics only to obtain numerical results.</p></li>
<li><p><em>IO</em>. Support for saving and loading simulation data and configurations from and to file. Essential for sharing and reproducing simulations.</p></li>
<li><p><em>Interactive graphics</em>. Display the simulation progress in real-time. Buttons for starting, stopping, and resuming the simulation. Menu options for choosing the simulation data and configurations files.</p></li>
<li><p><em>Field, parameter, and attribute editor</em>. Ability to manipulate simulation fields graphically. Create, edit, and remove obstacles, agents, sources, and targets. Set attribute values for agents and select their source positions and targets.</p></li>
<li><p><em>Logic editor</em>. Ability to create individual simulation logic blocks (e.g., forces, torque, integrator) and then connect them into the full simulation logic graphically. Allows changing individual parts of simulation logic for developing and testing new algorithms without having to break simulations that depend on different logic configurations.</p></li>
</ul>
<p>The programming language choice depends on the chosen engine. Engines typically use C++. Also, installation and getting started should be made as easy as possible to attract users outside the research community.</p>
<h2 id="conclusion">Conclusion</h2>
<p>In reality, human movement can be very complicated. For example, the motivation to move to a specific direction can be affected by many factors, such as sensory inputs and internal motivations. It would be difficult and even undesirable to attempt to model all the aspects of human movement. Therefore, the models we have presented in this article focus on capturing only the essential aspects of the human movement. It requires making simplifying assumptions in the models.</p>
<ul>
<li><p><em>Newtonian model</em>. Numerical simulation of Newtonian mechanics can create artifacts and non-realistic behavior, which we should account for in the implementation. For these reasons, we use adaptive timestep and Verlet integration.</p></li>
<li><p><em>Planar motion</em>. In reality, human movement is 3-dimensional, but creating 3-dimensional simulation is significantly more challenging.</p></li>
<li><p><em>Agent models</em>. The circular agent model is sufficient for modeling low-density crowds, but in high-density crowds, it is unrealistic. The orientable, three-circle model improves this shortcoming by more accurately representing the human torso and allowing body rotation. However, it requires algorithms for rotational motion and improved collision detection. Also, desired body rotation is not a completely solved problem.</p></li>
</ul>
<p>The results from simulations are stochastic. Therefore, we need to run multiple simulations with different initial configurations and analyze the resulting data using statistical methods to obtain meaningful information.</p>
<h2 id="references" class="unnumbered">References</h2>
<div id="refs" class="references" role="doc-bibliography">
<div id="ref-Helbing2000a">
<p>1. HELBING, D, FARKAS, I and VICSEK, T. Simulating dynamical features of escape panic. <em>Nature</em> [online]. 2000. Vol. 407, no. 6803, p. 487–490. DOI <a href="https://doi.org/10.1038/35035023">10.1038/35035023</a>. Available from: <a href="http://arxiv.org/abs/0009448">http://arxiv.org/abs/0009448</a></p>
</div>
<div id="ref-gibelli2019">
<p>2. GIBELLI, L and BELLOMO, N. <em>Crowd Dynamics, Volume 1: Theory, Models, and Safety Problems</em>. Springer International Publishing, 2019. Modeling and simulation in science, engineering and technology. ISBN <a href="https://worldcat.org/isbn/9783030051297">9783030051297</a>. </p>
</div>
<div id="ref-Langston2006">
<p>3. LANGSTON, Paul A., MASLING, Robert and ASMAR, Basel N. Crowd dynamics discrete element multi-circle model. <em>Safety Science</em>. 2006. DOI <a href="https://doi.org/10.1016/j.ssci.2005.11.007">10.1016/j.ssci.2005.11.007</a>. </p>
</div>
<div id="ref-Korhonen2008b">
<p>4. KORHONEN, T., HOSTIKKA, S., HELIÖVAARA, S. and EHTAMO, H. FDS+ Evac: An Agent Based Fire Evacuation Model. <em>Pedestrian and Evacuation Dynamics 2008</em>. 2008. P. 109–120. DOI <a href="https://doi.org/10.1007/978-3-642-04504-2">10.1007/978-3-642-04504-2</a>. </p>
</div>
<div id="ref-Stuvel2016a">
<p>5. STÜVEL, Sybren Anton. <em>Dense Crowds of Virtual Humans</em>. 2016. ISBN <a href="https://worldcat.org/isbn/9789039365151">9789039365151</a>. </p>
</div>
<div id="ref-Hidalgo2017">
<p>6. HIDALGO, R C, PARISI, D R and ZURIGUEL, I. Simulating competitive egress of noncircular pedestrians. <em>PHYSICAL REVIEW E</em>. 2017. Vol. 95. DOI <a href="https://doi.org/10.1103/PhysRevE.95.042319">10.1103/PhysRevE.95.042319</a>. </p>
</div>
<div id="ref-Karamouzas2014a">
<p>7. KARAMOUZAS, Ioannis, SKINNER, Brian and GUY, Stephen J. Universal power law governing pedestrian interactions. <em>Physical Review Letters</em> [online]. 2014. DOI <a href="https://doi.org/10.1103/PhysRevLett.113.238701">10.1103/PhysRevLett.113.238701</a>. Available from: <a href="http://arxiv.org/abs/arXiv:1412.1082v1">http://arxiv.org/abs/arXiv:1412.1082v1</a></p>
</div>
<div id="ref-Karamouzas2014b">
<p>8. KARAMOUZAS, Ioannis, SKINNER, Brian and GUY, Stephen J. Supplemental material for: Universal Power Law Governing Pedestrian Interactions Ioannis. <em>Physical Review Letters</em> [online]. 2014. DOI <a href="https://doi.org/10.1103/PhysRevLett.113.238701">10.1103/PhysRevLett.113.238701</a>. Available from: <a href="http://arxiv.org/abs/arXiv:1412.1082v1">http://arxiv.org/abs/arXiv:1412.1082v1</a></p>
</div>
<div id="ref-Kretz2011a">
<p>9. KRETZ, Tobias, GROßE, Andree, HENGST, Stefan, KAUTZSCH, Lukas, POHLMANN, Andrej and VORTISCH, Peter. Quickest Paths in Simulations of Pedestrians. <em>Advances in Complex Systems</em> [online]. 2011. Vol. 14(5), p. 733–759. DOI <a href="https://doi.org/10.1142/S0219525911003281">10.1142/S0219525911003281</a>. Available from: <a href="http://arxiv.org/abs/1107.2004">http://arxiv.org/abs/1107.2004</a></p>
</div>
<div id="ref-Cristiani2015b">
<p>10. CRISTIANI, Emiliano and PERI, Daniele. Handling obstacles in pedestrian simulations: Models and optimization. [online]. 2015. Available from: <a href="http://arxiv.org/abs/1512.08528">http://arxiv.org/abs/1512.08528</a></p>
</div>
<div id="ref-Korhonen2008c">
<p>11. KORHONEN, Timo, HOSTIKKA, Simo, TECHNICAL, V T T, EHTAMO, Harri, ANALYSIS, Systems, BOX, Technology P O, SIMULATOR, Fire Dynamics and THE, Introduction. FDS+Evac: Modelling Social Interactions in Fire Evacuation.. 2008. DOI <a href="https://doi.org/10.1007/978-3-642-04504-2_8">10.1007/978-3-642-04504-2_8</a>. </p>
</div>
</div>
Computer Algebra with SymPy and Jupyter2019-11-16T00:00:00+02:002019-11-16T00:00:00+02:00Jaan Tollander de Balschtag:jaantollander.github.io,2019-11-16:/computer-algebra-with-sympy-and-jupyter.html
<!-- 800×400 pixels (bigger with similar aspect ratio will be scaled) -->
<p><img src="../images/computer_algebra/jupyter_sympy.png" /></p>
<blockquote>
</blockquote>
<p>In this article, we briefly discuss the benefits and challenges of present-day computer algebra systems. Our primary motivation is how to use computer algebra systems to automate the manipulating mathematical expressions instead of having to rely on tedious and error-prone manual methods. The article presents a practical guide on how to install and work with the open-source computer algebra system, SymPy, in the Jupyter notebook. We made an <a href="https://gist.github.com/jaantollander/39a6ce5ba66d310b55d33812354256c2">example notebook</a> available as a GitHub gist.</p>
<!-- 800×400 pixels (bigger with similar aspect ratio will be scaled) -->
<p><img src="../images/computer_algebra/jupyter_sympy.png" /></p>
<blockquote>
</blockquote>
<p>In this article, we briefly discuss the benefits and challenges of present-day computer algebra systems. Our primary motivation is how to use computer algebra systems to automate the manipulating mathematical expressions instead of having to rely on tedious and error-prone manual methods. The article presents a practical guide on how to install and work with the open-source computer algebra system, SymPy, in the Jupyter notebook. We made an <a href="https://gist.github.com/jaantollander/39a6ce5ba66d310b55d33812354256c2">example notebook</a> available as a GitHub gist.</p>
<p><strong>Contents</strong></p>
<!-- TOC depthFrom:2 depthTo:6 withLinks:1 updateOnSave:1 orderedList:0 -->
<ul>
<li><a href="#definitions">Definitions</a></li>
<li><a href="#benefits-of-computer-algebra-systems">Benefits of Computer Algebra Systems</a></li>
<li><a href="#using-jupyter-and-sympy">Using Jupyter and SymPy</a></li>
</ul>
<!-- /TOC -->
<p><strong>Keywords</strong>: Computer Algebra, Computer Algebra System, SymPy</p>
<h2 id="definitions">Definitions</h2>
<p>First off, we present some relevant definitions related to the topic of this article.</p>
<ul>
<li><p><a href="https://en.wikipedia.org/wiki/Algebra"><strong>Algebra</strong></a> is the study of mathematical symbols and the rules for manipulating these symbols. It is one of the fundamental parts of mathematics, and it is essential for conducting mathematics, science, and engineering.</p></li>
<li><p><a href="https://en.wikipedia.org/wiki/Computer_algebra"><strong>Computer algebra</strong></a>, a part of <a href="https://en.wikipedia.org/wiki/Computational_mathematics"><strong>computational mathematics</strong></a>, studies algorithms for manipulating mathematical expressions and other mathematical objects. It can be though, as meta-mathematics, as it relies on mathematical methods for manipulating mathematical expressions.</p></li>
<li><p><a href="https://en.wikipedia.org/wiki/Computer_algebra_system"><strong>Computer algebra system</strong></a> is any mathematical software with the ability to manipulate mathematical expressions. <strong>General-purpose computer algebra system</strong> aims to be useful to any user working in any scientific field that requires manipulation of mathematical expressions.</p></li>
</ul>
<p>In the next section, we will discuss the differences between manual and computational algebraic expression manipulation.</p>
<h2 id="benefits-of-computer-algebra-systems">Benefits of Computer Algebra Systems</h2>
<p>Traditionally, the manipulation of mathematical expressions has required a person skilled in mathematics and lots of mental stamina. In general, handling mathematical expressions is a tedious and error-prone task for humans, and requires extensive training. In order to overcome these deficiencies, we require the aid of computer algorithms.</p>
<p>The emergence of computers in the 20th century has spiked an interest in algorithmic manipulation of mathematical expressions. The development of algorithms for performing algebraic manipulations has allowed a computer to perform this task. These algorithms are then bundled in computer algebra systems and made available to users.</p>
<p>We have listed some of the benefits of the use of computer algebra systems below.</p>
<ul>
<li>The manipulation of larger expressions is feasible.</li>
<li>The manipulation of expressions can be automated, which is especially useful when the same operations are performed multiple times for different inputs.</li>
<li>There is a decreased risk of error when manipulating expressions computationally.</li>
<li>Results are much easier to share. Also, online sharing is possible.</li>
<li>The computer is better at representing mathematical expressions. There is no disambiguation between symbols.</li>
</ul>
<p>However, computer algebra systems are not without their challenges.</p>
<ul>
<li>The learning curve of computer algebra systems is often quite steep. Initially, even simple operations can require more work compared if done by hand.</li>
<li>Computer algebra systems may not have implemented all required capabilities, which may require manual intervention.</li>
</ul>
<p>In conclusion, we will still need to rely on a hybrid approach where we combine manual and computational work. As technology improves, we can perform an increasing quantity of our algebraic manipulations using computers. In the next section, we discuss open-source computer algebra systems and how to use them.</p>
<h2 id="using-jupyter-and-sympy">Using Jupyter and SymPy</h2>
<p>This part focused on open-source software for computer algebra. We will discuss how to use the <em>Jupyter notebook</em> and <em>Python</em> programming language with the <em>SymPy</em> library. Additionally, we install the SymEngine library for improved performance of symbolic operations. Each of the software can be installed using the <em>Conda</em> package manager.</p>
<ol type="1">
<li><p>Install the Conda package manager. We recommend installing the <a href="https://docs.conda.io/en/latest/miniconda.html">Miniconda</a> distribution with the latest Python interpreter.</p></li>
<li><p>Now Jupyter and SymPy can be installed using Conda using the command</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1"></a><span class="ex">conda</span> install jupyter sympy</span></code></pre></div></li>
<li><p>Additionally, we may choose to install SymEngine and its Python wrappers</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1"></a><span class="ex">conda</span> install python-symengine symengine -c symengine -c conda-forge</span></code></pre></div></li>
<li><p>Jupyter notebook is started using the command</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1"></a><span class="ex">jupyter</span> notebook</span></code></pre></div></li>
<li><p>Create a new Jupyter notebook and select the Python kernel.</p></li>
<li><p>Include the following lines of code at the beginning of the Jupyter notebook. First-line imports all the functions from SymPy, making them available to the global variables. The second line enables math rendering in the browser, similarly to LaTeX via MathJax.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a href="#cb4-1"></a><span class="im">from</span> sympy <span class="im">import</span> <span class="op">*</span></span>
<span id="cb4-2"><a href="#cb4-2"></a>init_printing(<span class="st">"mathjax"</span>)</span></code></pre></div></li>
</ol>
<p>Now we are ready to start working with SymPy. Take a look at the <a href="https://gist.github.com/jaantollander/39a6ce5ba66d310b55d33812354256c2">SymPy examples</a> Jupyter notebook. It contains a showcase of the essential SymPy features.</p>
<p>SymPy and SymEngine is also available for Julia programming language through the wrappers <code>Sympy.jl</code> and <code>SymEngine.jl</code>. Julia kernel can be added to Jupyter using <code>IJulia.jl</code> package.</p>
How to Manage Tasks with Kanban2019-04-07T00:00:00+03:002019-04-07T00:00:00+03:00Jaan Tollander de Balschtag:jaantollander.github.io,2019-04-07:/how-to-manage-tasks-with-kanban.html
<p><img src="../images/kanban/KanbanFlowBoard_1000_2x.png" /></p>
<blockquote>
</blockquote>
<p>This article provides a quick overview of the Kanban project management system and how it can be used for managing tasks, increasing productivity, and visualizing workload. My introduction to Kanban came from <a href="https://www.youtube.com/watch?v=UdvwVYAaWEc">John Sonmez</a> as I was searching for tools for managing assignments in university. Since then, I have been using Kanban for managing university assignments, improving my blog, and managing work-related tasks. As an example, the article explains how to use <a href="https://kanbanflow.com/">KanbanFlow</a> for managing school assignments. We chose KanbanFlow because it has a good set of <a href="https://kanbanflow.com/features">features</a>, and it’s easy to use and works both on desktop and mobile.</p>
<p><img src="../images/kanban/KanbanFlowBoard_1000_2x.png" /></p>
<blockquote>
</blockquote>
<p>This article provides a quick overview of the Kanban project management system and how it can be used for managing tasks, increasing productivity, and visualizing workload. My introduction to Kanban came from <a href="https://www.youtube.com/watch?v=UdvwVYAaWEc">John Sonmez</a> as I was searching for tools for managing assignments in university. Since then, I have been using Kanban for managing university assignments, improving my blog, and managing work-related tasks. As an example, the article explains how to use <a href="https://kanbanflow.com/">KanbanFlow</a> for managing school assignments. We chose KanbanFlow because it has a good set of <a href="https://kanbanflow.com/features">features</a>, and it’s easy to use and works both on desktop and mobile.</p>
<p>Two articles, <a href="https://productivityland.com/blog/what-is-kanban-board/">What is Kanban Board?</a> and <a href="https://productivityland.com/lists/best-kanban-apps/">Best Kanban Apps</a> inspired this article. I recommend reading them in conjunction with this article as they give a broader picture of Kanban.</p>
<p><strong>Keywords</strong>: Productivity, Project Management, Kanban, Pomodoro, KanbanFlow</p>
<h2 id="overview-of-kanban">Overview of Kanban</h2>
<p><strong>Kanban</strong> is a project management system initially used in lean manufacturing, but more recently, it has become popular in knowledge work. We can use Kanban in Agile software development, but it also works for managing school assignments or writing tasks for a blog. The core principles of Kanban are:</p>
<ol type="1">
<li>Visualize your work</li>
<li>Limit your work in process</li>
<li>Focus on flow</li>
</ol>
<p>The <strong>Kanban board</strong> consists of <strong>columns</strong> and <strong>cards</strong>. It visualizes the project such that each card represents an individual <strong>task</strong> in the project, and each column represents the <strong>state</strong> of the particular task. By convention, we move the cards from left to right. Kanban board can also have multiple <strong>members</strong> working on the project. Kanban board can also be associated with a <strong>timer</strong>. The timer can be used to measure the amount of time it takes to complete a task, which can then be used to estimate the future workload of similar tasks.</p>
<p>The standard columns are:</p>
<ul>
<li><strong><em>To-Do</em></strong> – Unstarted tasks.</li>
<li><strong><em>Work In Progress (WIP)</em></strong> – Tasks that are in progress. This column can be limited to only be able to have a certain number of tasks at a time to limit multitasking.</li>
<li><strong><em>Done</em></strong> – Completed tasks.</li>
</ul>
<p>Columns can be added, removed, and modified as needed for the project. Each card has the following attributes:</p>
<ul>
<li><strong><em>Title</em></strong> – The name of the task.</li>
<li><strong><em>Description</em></strong> – Description of the task.</li>
<li><strong><em>Due date</em></strong> – The date and time when the task is due.</li>
<li><strong><em>Subtasks</em></strong> – Subtasks needed to complete the task. Subtasks should be simple; otherwise, consider creating another Kanban card of that subtask.</li>
<li><strong><em>Color</em></strong> – Colors can be used to indicate the type of the task.</li>
<li><strong><em>Label</em></strong> – Labels can be used to classify tasks.</li>
<li><strong><em>Member</em></strong> – Project members assigned to the task.</li>
</ul>
<p>The timer has two options:</p>
<ul>
<li><strong><em>Stopwatch</em></strong> – Stopwatch can be used to measure the time taken to complete a task.</li>
<li><strong><em>Pomodoro</em></strong> – <a href="https://kanbanflow.com/pomodoro-technique">Pomodoro technique</a> is a time management technique based on using 25 minute timeboxes for focused work, referred as Pomodoro. We can take a short 3-5 minute break after each Pomodoro and longer 15-30 minutes break after four Pomodori.</li>
</ul>
<h2 id="example-managing-school-assignments">Example: Managing School Assignments</h2>
<p><img src="../images/kanban/school_assignments.png" /></p>
<p>My personal Kanban board for school assignments consists of the standard columns: <em>To-do</em>, <em>In progress</em> and <em>Done</em>. We’ll add tasks into <em>To-do</em> column with a title containing the course name or an abbreviation of it, the exercise round, and the name. Also, we can set a due date for each task. Some tasks have subtasks, which should be listed. We can set colors for tasks such that each course has a unique color. Colors make different courses easier to identify.</p>
<p>The workflow follows the standard pattern. Move tasks from <em>To-do</em> to <em>In progress</em> column as you start working on them. Once we complete the task, we move it into the <em>Done</em> column.</p>
Exploring the Pointwise Convergence of Legendre Series for Piecewise Analytic Functions2019-03-09T00:00:00+02:002019-03-09T00:00:00+02:00Jaan Tollander de Balschtag:jaantollander.github.io,2019-03-09:/legendre-series.html
<p><img src="../images/legendre_series/legendre_series.png" /></p>
<p>In this article, we explore the behavior of the pointwise convergence of the Legendre series for piecewise analytic functions using numerical methods. The article extensively covers the mathematics required for forming and computing the series as well as pseudocode code for some of the non-trivial algorithms. It extends the research made in the papers by Babuska and Hakula <span class="citation" data-cites="Babuska2014 Babuska2019">(<a href="#ref-Babuska2014" role="doc-biblioref">1</a>, <a href="#ref-Babuska2019" role="doc-biblioref">2</a>)</span> by proving evidence for the conjectures about the Legendre series in a large number of points in the domain and up to very high degree series approximations. We present the numerical results as figures and provide explanations. We also provide the Python code for computing and recreating the results in <a href="https://github.com/jaantollander/LegendreSeries">LegendreSeries</a> repository.</p>
<p><img src="../images/legendre_series/legendre_series.png" /></p>
<p>In this article, we explore the behavior of the pointwise convergence of the Legendre series for piecewise analytic functions using numerical methods. The article extensively covers the mathematics required for forming and computing the series as well as pseudocode code for some of the non-trivial algorithms. It extends the research made in the papers by Babuska and Hakula <span class="citation" data-cites="Babuska2014 Babuska2019">(<a href="#ref-Babuska2014" role="doc-biblioref">1</a>, <a href="#ref-Babuska2019" role="doc-biblioref">2</a>)</span> by proving evidence for the conjectures about the Legendre series in a large number of points in the domain and up to very high degree series approximations. We present the numerical results as figures and provide explanations. We also provide the Python code for computing and recreating the results in <a href="https://github.com/jaantollander/LegendreSeries">LegendreSeries</a> repository.</p>
<p><strong>Table of contents</strong></p>
<!-- TOC -->
<ul>
<li><a href="#legendre-polynomials">Legendre Polynomials</a></li>
<li><a href="#legendre-series">Legendre Series</a></li>
<li><a href="#piecewise-analytic-functions">Piecewise Analytic Functions</a></li>
<li><a href="#legendre-series-of-step-function">Legendre Series of Step Function</a></li>
<li><a href="#legendre-series-of-v-function">Legendre Series of V Function</a></li>
<li><a href="#pointwise-convergence">Pointwise Convergence</a></li>
<li><a href="#convergence-line">Convergence Line</a></li>
<li><a href="#conjectures-of-pointwise-convergence">Conjectures of Pointwise Convergence</a></li>
<li><a href="#results">Results</a>
<ul>
<li><a href="#step-function">Step Function</a></li>
<li><a href="#v-function">V Function</a></li>
</ul></li>
<li><a href="#python-code">Python Code</a></li>
<li><a href="#conclusions">Conclusions</a></li>
<li><a href="#references">References</a></li>
</ul>
<!-- /TOC -->
<p><strong>Keywords</strong>: Legendre polynomials, Classical orthogonal polynomials, Piecewise analytic functions, Legendre series, Generalized Fourier series, Convergence of Fourier series</p>
<h2 id="legendre-polynomials">Legendre Polynomials</h2>
<p><img src="../images/legendre_series/legendre_polynomials.png" /></p>
<p><a href="https://en.wikipedia.org/wiki/Legendre_polynomials">Legendre polynomials</a> are a system of complete and orthogonal polynomials defined over the <strong>domain</strong> <span class="math inline">\(Ω=[-1, 1]\)</span> which is an interval between the <strong>edges</strong> <span class="math inline">\(-1\)</span> and <span class="math inline">\(1\)</span>, as a <strong>recursive formula</strong> <span class="math display">\[
\begin{aligned}
P_{0}(x) &= 1\\
P_{1}(x) &= x \\
P_{n}(x) &= \frac{2n-1}{n} x P_{n-1}(x) - \frac{n-1}{n} P_{n-2}(x), n≥2.
\end{aligned}
\tag{1}
\label{recursive-formula}
\]</span> The recursive definition enables efficient computing of numerical values of high degree Legendre polynomials at specific points in the domain.</p>
<p>Legendre polynomials also have important properties which are used for forming the Legendre series. The <strong>terminal values</strong>, i.e. the values at the edges, of Legendre polynomials can be derived from the recursive formula <span class="math display">\[
\begin{aligned}
P_{n}(1) &= 1 \\
P_{n}(-1) &= (-1)^n.
\end{aligned}
\tag{2}
\label{terminal-values}
\]</span> The <strong>symmetry</strong> property also follows from the recursive formula <span class="math display">\[
\begin{aligned}
P_n(-x) = (-1)^n P_n(x).
\end{aligned}
\tag{3}
\label{symmetry}
\]</span> The <strong>inner product</strong> is denoted by the angles <span class="math display">\[
\begin{aligned}
⟨P_m(x), P_n(x)⟩_{2} &= \int_{-1}^{1} P_m(x) P_n(x) \,dx \\
&= \frac{2}{2n + 1} δ_{mn},
\end{aligned}
\tag{4}
\label{inner-product}
\]</span> where <span class="math inline">\(δ_{mn}\)</span> is Kronecker delta. <!-- **Orthogonality** which follows from the inner product
\[
\begin{aligned}
\|P_{n}\|_{2}^{2} = \frac{2}{2n + 1}.
\end{aligned}
\] --> <strong>Differentiation</strong> of Legendre polynomials can be defined in terms of Legendre polynomials themselves as <span class="math display">\[
(2n+1) P_n(x) = \frac{d}{dx} \left[ P_{n+1}(x) - P_{n-1}(x) \right].
\tag{5}
\label{differentiation-rule}
\]</span> The differentiation <span class="math inline">\(\eqref{differentiation-rule}\)</span> rule can also be formed into the <strong>integration rule</strong> <span class="math display">\[
∫P_n(x)dx = \frac{1}{2n+1} (P_{n+1}(x) - P_{n-1}(x)).
\tag{6}
\label{integration-rule}
\]</span></p>
<h2 id="legendre-series">Legendre Series</h2>
<p>The <strong>Legendre series</strong> is a <a href="https://en.wikipedia.org/wiki/Series_expansion">series expansion</a> which is formed using Legendre polynomials. Legendre series of function <span class="math inline">\(f\)</span> is defined as <span class="math display">\[
f(x) = ∑_{n=0}^{∞}C_{n}P_{n}(x).
\tag{7}
\label{legendre-series}
\]</span> where <span class="math inline">\(C_n∈ℝ\)</span> are the <strong>Legendre series coefficients</strong> and <span class="math inline">\(P_n(x)\)</span> Legendre polynomials of degree <span class="math inline">\(n\)</span>. The formula for the coefficients is defined <span class="math display">\[
C_n = \frac{2n+1}{2} \int_{-1}^{1} f(x) P_{n}(x)\,dx.
\tag{8}
\label{legendre-series-coefficients}
\]</span></p>
<hr />
<p><strong>Proof</strong>: The Legendre series coefficients can be derived using the Legendre series formula <span class="math inline">\(\eqref{legendre-series}\)</span> and the inner product <span class="math inline">\(\eqref{inner-product}\)</span>. <span class="math display">\[
\begin{aligned}
f(x) &= ∑_{m=0}^{∞}C_{m}P_{m}(x) \\
P_{n}(x) f(x) &= P_{n}(x) \sum _{m=0}^{\infty }C_{m}P_{m}(x) \\
∫_{-1}^{1}P_{n}(x) f(x)\,dx &= ∫_{-1}^{1} P_{n}(x) \sum _{m=0}^{\infty }C_{m}P_{m}(x)\,dx \\
∫_{-1}^{1}P_{n}(x) f(x)\,dx &= \sum _{m=0}^{\infty }C_{m}∫_{-1}^{1} P_{n}(x) P_{m}(x)\,dx \\
∫_{-1}^{1}P_{n}(x) f(x)\,dx &= C_{n}∫_{-1}^{1} P_{n}(x) P_{n}(x)\,dx \\
C_{n} &= {\langle f,P _{n}\rangle _{2} \over \|P _{n}\|_{2}^{2}} \\
C_n &= \frac{2n+1}{2} \int_{-1}^{1} f(x) P_{n}(x)\,dx.
\end{aligned}
\]</span></p>
<hr />
<p>The <strong>partial sum</strong> of the series expansion gives us an approximation of the function <span class="math inline">\(f\)</span>. It’s obtained by limiting the series to a finite number of terms <span class="math inline">\(k\)</span> <span class="math display">\[
f_k(x)=\sum _{n=0}^{k}C_{n}P_{n}(x).
\tag{9}
\label{partial-sum}
\]</span> The <strong>approximation error</strong> <span class="math inline">\(ε_k\)</span> is obtained by subtracting the partial sum <span class="math inline">\(f_k\)</span> from the real value of the function <span class="math inline">\(f\)</span> <span class="math display">\[
ε_k(x) = f(x)-f_k(x).
\tag{10}
\label{approximation-error}
\]</span> The actual analysis of the approximation errors will be using the absolute value of the error <span class="math inline">\(|ε_k(x)|.\)</span></p>
<h2 id="piecewise-analytic-functions">Piecewise Analytic Functions</h2>
<p><img src="../images/legendre_series/piecewise_functions.png" /></p>
<p>The motivation for studying a series expansion for piecewise analytic functions is to understand the behavior of a continuous approximation of a function with non-continuous or non-differentiable points. We will study the series expansion on two special cases of piecewise analytic functions, the <strong>step function</strong> and the <strong>V function</strong>. The results obtained from studying these two special cases generalizes into all piecewise analytic functions, but this is not proven here.</p>
<p><strong>Piecewise analytic function</strong> <span class="math inline">\(f(x):Ω → ℝ\)</span> is defined <span class="math display">\[
f(x) = \sum_{i=1}^{m} c_i | x-a_i |^{b_i} + v(x),
\tag{11}
\label{piecewise-analytic-function}
\]</span> where <span class="math inline">\(a_i∈(-1,1)\)</span> are the <strong>singularities</strong>, <span class="math inline">\(b_i∈ℕ_0\)</span> are the <strong>degrees</strong>, <span class="math inline">\(c_i∈ℝ\)</span> are the scaling coefficients and <span class="math inline">\(v(x)\)</span> is an analytic function. The <strong>V function</strong> is piecewise analytic function of degree <span class="math inline">\(b=1\)</span> and it is defined as <span class="math display">\[
u(x) = c ⋅ |x - a| + (α + βx).
\tag{12}
\label{v-function}
\]</span> The <strong>step function</strong> is piecewise analytic function of degree <span class="math inline">\(b=0\)</span> and it is obtained as the derivative of the V-function <span class="math display">\[
\frac{d}{dx} u(x) = u'(x) = c ⋅ \operatorname{sign}{(x - a)} + β.
\tag{13}
\label{step-function}
\]</span> As can be seen, the V function is the absolute value scaled with <span class="math inline">\(c\)</span>, translated with <span class="math inline">\(α\)</span> and rotated by <span class="math inline">\(βx\)</span> and the step function is sign function that is scaled with <span class="math inline">\(c\)</span> and translated with <span class="math inline">\(β\)</span>.</p>
<p>We’ll also note that the <strong>derivative of step function</strong> is zero <span class="math display">\[
\frac{d}{dx} u'(x) = u''(x) = 0.
\tag{14}
\label{step-function-derivative}
\]</span> This will be used when forming the Legendre series.</p>
<h2 id="legendre-series-of-step-function">Legendre Series of Step Function</h2>
<iframe width="1280" height="640" src="https://www.youtube.com/embed/lFiMoiqpuCg" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen>
</iframe>
<p>The coefficients for the Legendre series of the step function will be referred as <strong>step function coefficients</strong>. A formula for them in terms of Legendre polynomials at the singularity <span class="math inline">\(a\)</span> can be obtained by substituting the step function <span class="math inline">\(\eqref{step-function}\)</span> in place of the function <span class="math inline">\(f\)</span> in the Legendre series coefficient formula <span class="math inline">\(\eqref{legendre-series-coefficients}\)</span> <span class="math display">\[
\begin{aligned}
A_n &= \frac{2n+1}{2} \int_{-1}^{1} u'(x) P_{n}(x)\,dx \\
&=
\begin{cases}
β-ac, & n=0 \\
c(P_{n-1}(a)-P_{n+1}(a)), & n≥1\\
\end{cases}.
\end{aligned}
\tag{15}
\label{step-function-coefficients}
\]</span></p>
<hr />
<p><strong>Proof</strong>: The coefficients for degree <span class="math inline">\(n=0\)</span> are obtained from direct integration <span class="math display">\[
\begin{aligned}
A_{0} &= \frac{1}{2} \int_{-1}^{1} u^{\prime}(x) \,dx \\
&= \beta + \frac{1}{2} c \int_{-1}^{1} \operatorname{sign}{\left (x - a \right )}\,dx \\
&= \beta + \frac{1}{2} c \left(\int_{-1}^{a} -1\,dx + \int_{a}^{1} 1\,dx\right) \\
&= \beta - ac.
\end{aligned}
\tag{16}
\label{step-function-coefficients-0}
\]</span></p>
<p>The coefficients for degrees <span class="math inline">\(n≥1\)</span> are obtained by using <a href="https://en.wikipedia.org/wiki/Integration_by_parts">integration by parts</a>, integral rule <span class="math inline">\(\eqref{integration-rule}\)</span>, terminal values <span class="math inline">\(\eqref{terminal-values}\)</span> and the derivative of step function <span class="math inline">\(\eqref{step-function-derivative}\)</span> <span class="math display">\[
\begin{aligned}
A_{n} &= \frac{2n+1}{2} \int_{-1}^{1} u^{\prime}(x) P_{n}(x)\,dx, n≥1\\
&= \frac{2n+1}{2} \left( \left[u^\prime(x) \int P_n(x) dx\right]_{-1}^{1} - \int_{-1}^{1} u^{\prime\prime}(x) P_n(x) dx \right) \\
&= \frac{2n+1}{2} \left[ \frac{1}{2n+1} (P_{n+1}(x) - P_{n-1}(x)) u^\prime(x) \right]_{-1}^{1} \\
&= \frac{1}{2} \left[ (P_{n+1}(x) - P_{n-1}(x)) u^\prime(x) \right]_{-1}^{1} \\
&= \frac{1}{2} \left(\left[ (P_{n+1}(x) - P_{n-1}(x)) u^\prime(x) \right]_{-1}^{a} + \left[ (P_{n+1}(x) - P_{n-1}(x)) u^\prime(x) \right]_{a}^{1}\right) \\
&= \frac{1}{2} \left(\left[ (P_{n+1}(x) - P_{n-1}(x)) \cdot (-c+\beta) \right]_{-1}^{a} + \left[ (P_{n+1}(x) - P_{n-1}(x)) \cdot (c+\beta) \right]_{a}^{1}\right) \\
&= c \cdot \left(P_{n-1}(a) - P_{n+1}(a)\right).
\end{aligned}
\tag{17}
\label{step-function-coefficients-n}
\]</span></p>
<h2 id="legendre-series-of-v-function">Legendre Series of V Function</h2>
<iframe width="1280" height="640" src="https://www.youtube.com/embed/kEzZ1tElEHk" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen>
</iframe>
<p>The coefficients for the Legendre series of the step function will be referred as <strong>V function coefficients</strong>. A formula for them in terms of step function coefficients can be obtained by substituting the V function <span class="math inline">\(\eqref{v-function}\)</span> in place of the function <span class="math inline">\(f\)</span> in the Legendre series coefficient formula <span class="math inline">\(\eqref{legendre-series-coefficients}\)</span> <span class="math display">\[
\begin{aligned}
B_n &= \frac{2n+1}{2} \int_{-1}^{1} u(x) P_{n}(x)\,dx. \\
&=
\begin{cases}
\frac{a^{2} c}{2} + α + \frac{c}{2}, & n=0 \\
-\frac{A_{n+1}}{2n +3} + \frac{A_{n-1}}{2n - 1}, & n≥1
\end{cases}.
\end{aligned}
\tag{18}
\label{v-function-coefficients}
\]</span></p>
<hr />
<p><strong>Proof</strong>: The coefficients for degree <span class="math inline">\(n=0\)</span> are obtained from direct integration <span class="math display">\[
\begin{aligned}
B_{0} &= \frac{1}{2} ∫_{-1}^{1} u(x) \,dx \\
&= \frac{a^{2} c}{2} + α + \frac{c}{2}.
\end{aligned}
\tag{19}
\label{v-function-coefficients-0}
\]</span></p>
<p>The coefficients for degrees <span class="math inline">\(n≥1\)</span> are obtained by using <a href="https://en.wikipedia.org/wiki/Integration_by_parts">integration by parts</a>, integral rule <span class="math inline">\(\eqref{integration-rule}\)</span> and substituting the step function coefficient formula <span class="math inline">\(\eqref{step-function-coefficients}\)</span> <span class="math display">\[
\begin{aligned}
B_{n} =& \frac{2n+1}{2} \int_{-1}^{1} u(x) P_{n}(x)\,dx, \quad n \geq 1 \\
=& \frac{2n + 1}{2} \left ( \left [ u(x) \int P_n(x)\,dx \right ]_{-1}^{1} - \int_{-1}^{1} u'(x) \int P_{n}\,dx\,dx \right ) \\
=& -\frac{1}{2} \int_{-1}^{1} \left [ P_{n+1}(x) - P_{n-1}(x) \right ] u'(x) \,dx\\
=& -\frac{1}{2} \int_{-1}^{1} P_{n+1}(x) u'(x)\,dx + \frac{1}{2} \int_{-1}^{1} P_{n-1}(x) u'(x)\,dx.\\
=& -\frac{A_{n+1}}{2n +3} + \frac{A_{n-1}}{2n - 1}.
\end{aligned}
\tag{20}
\label{v-function-coefficients-n}
\]</span></p>
<!-- ## The Approximation Error
Lets denote
\[
a'_n = P_{n-1}(a) - P_{n+1}(a)
\]
When substituted in the series formula the series takes form
\[
\begin{aligned}
u^{\prime}_k(x) &= \beta - a c + c \sum_{n=1}^{k} a'_n P_{n}(x)
\end{aligned}
\]
The absolute values of the error \(ε\) for the series is defined as
\[
\begin{aligned}
ε_k(x) &= u^′(x) - u_k^′(x) \\
&= c \left(\operatorname{sign}{\left (x - a \right )} - \left(-a + \sum_{n=1}^{k} P_{n}(x) \left(P_{n-1}(a) - P_{n+1}(a)\right)\right) \right).
\end{aligned}
\]
TODO: isolate the effect of β on the error
Lets denote
\[
b'_n = -\frac{a'_{n+1}}{2n +3} + \frac{a'_{n-1}}{2n - 1}, n≥2
\]
Then
\[
u_k(x) = \frac{a^{2} c}{2} + α + \frac{c}{2} + b_1 P(1) + c\sum_{n=2}^{k}b'_nP(x) \\
= α + b_1 P(1) + c\left(\frac{a^{2}+1}{2} + \sum_{n=2}^{k}b'_nP(x)\right)
\]
Error
\[
ε_k(x) = |u(x) - u_k(x)| \\
= c ⋅ |x - a| + (α + βx) - \Big(\frac{a^{2} c}{2} + α + \frac{c}{2} + \sum_{n=1}^{k}b_nP(x)\Big)
\] -->
<h2 id="pointwise-convergence">Pointwise Convergence</h2>
<figure>
<img src="../images/legendre_series/pointwise_convergence/step_function/0.5/-0.9000000.png" alt="" /><figcaption><em>Example of pointwise convergence a step function series.</em></figcaption>
</figure>
<blockquote>
</blockquote>
<p>The series is said to <a href="https://en.wikipedia.org/wiki/Pointwise_convergence"><strong>converge pointwise</strong></a> if the partial sum <span class="math inline">\(f_k(x)\)</span> tends to the value <span class="math inline">\(f(x)\)</span> as the degree <span class="math inline">\(k\)</span> approaches infinity in every <span class="math inline">\(x\)</span> in the domain <span class="math inline">\(Ω\)</span> <span class="math display">\[
\lim_{k→∞} f_k(x)=f(x).
\tag{21}
\label{pointwise_convergence}
\]</span> Equivalently in terms of the approximation error which approaches zero <span class="math display">\[
\lim_{k→∞} ε_k(x)=0.
\tag{22}
\label{approximation_error_convergence}
\]</span> Numerical exploration of the pointwise convergence explores the behavior of the approximation error <span class="math inline">\(ε_k(x)\)</span> as a function of degree <span class="math inline">\(k\)</span> up to a finite degree <span class="math inline">\(n\)</span> at some finite amount of points <span class="math inline">\(x\)</span> selected from the domain <span class="math inline">\(Ω.\)</span> The numerical approach answers to <em>how the series converges</em> contrary to the analytical approach which answers <em>if the series converges</em>.</p>
<h2 id="convergence-line">Convergence Line</h2>
<p>We will perform the exploration by computing a <strong>convergence line</strong> which contains two parameters:</p>
<ol type="1">
<li><p>The <strong>convergence rate</strong> which is the maximal rate at which the error approaches zero as the degree grows.</p></li>
<li><p>The <strong>convergence distance</strong> which is a value proportional to the degree when the series reaches the maximal rate of convergence.</p></li>
</ol>
<p>The definition of the converge line requires a definition for a line. A <strong>line between two points</strong> <span class="math inline">\((x_0,y_0)\)</span> and <span class="math inline">\((x_1,y_1)\)</span> where <span class="math inline">\(x_0≠x_1\)</span> is defined as <span class="math display">\[
y=(x-x_{0})\,{\frac {y_{1}-y_{0}}{x_{1}-x_{0}}}+y_{0}.
\tag{23}
\label{line1}
\]</span> An alternative form of this formula is <span class="math display">\[
y=\tilde{a}x+\tilde{β},
\tag{24}
\label{line2}
\]</span> where the coefficient <span class="math inline">\(\tilde{α}=\frac {y_{1}-y_{0}}{x_{1}-x_{0}}\)</span> is referred as the <strong>slope</strong> and the coefficient <span class="math inline">\(\tilde{β}=(y_{0}-x_{0}\tilde{α})\)</span> is referred as the <strong>intercept</strong>.</p>
<hr />
<p>The pseudocode for the convergence line algorithm is then as follows:</p>
<p><strong>Input</strong>: A sequence of strictly monotonically increasing positive real numbers <span class="math inline">\((x_1,x_2,...,x_n)\)</span> and a sequence of positive real numbers <span class="math inline">\((y_1,y_2,...,y_n)\)</span> that converges towards zero (decreasing). Limit for the smallest value of the slope <span class="math inline">\(\tilde{α}_{min}\)</span>.</p>
<p><strong>Output</strong>: A convergence line defined by the values <span class="math inline">\(\tilde{α}\)</span> and <span class="math inline">\(\tilde{β}\)</span> which minimizes <span class="math inline">\(\tilde{α}\)</span> and minimizes <span class="math inline">\(\tilde{β}\)</span> such that <span class="math inline">\(\tilde{α}≥\tilde{α}_{min}\)</span> and <span class="math inline">\(y_i=\tilde{α}x_i+\tilde{β}\)</span> for all <span class="math inline">\(i=1,2,...,n.\)</span></p>
<p><span class="math inline">\(\operatorname{Find-Convergence-Line}((x_1,x_2,…,x_n),(y_1,y_2,…,y_n),\tilde{α}_{min})\)</span></p>
<ol type="1">
<li><span class="math inline">\(i=1\)</span></li>
<li><span class="math inline">\(j=i\)</span></li>
<li><strong>while</strong> <span class="math inline">\(j≠n\)</span></li>
<li>….. <span class="math inline">\(k=\underset{k>j}{\operatorname{argmax}}\left(\dfrac{y_k-y_j}{x_k-x_j}\right)\)</span></li>
<li>….. <span class="math inline">\(\tilde{α} = \dfrac{y_k-y_j}{x_k-x_j}\)</span></li>
<li>….. <strong>if</strong> <span class="math inline">\(\tilde{α} < \tilde{α}_{min}\)</span></li>
<li>….. ….. <strong>break</strong></li>
<li>….. <span class="math inline">\(i=j\)</span></li>
<li>….. <span class="math inline">\(j=k\)</span></li>
<li><span class="math inline">\(\tilde{α}=\dfrac{y_j-y_i}{x_j-x_i}\)</span></li>
<li><span class="math inline">\(\tilde{β}=y_i-x_i \tilde{α}\)</span></li>
<li><strong>return</strong> <span class="math inline">\((\tilde{α}, \tilde{β})\)</span></li>
</ol>
<hr />
<p>The approximation errors generated by the Legendre series have linear convergence in the logarithmic scale, and therefore we need to convert the values into a logarithmic scale, find the convergence line and then convert the line into exponential form <span class="math inline">\(βx^{-α}\)</span>.</p>
<p><strong>Input</strong>: The degrees <span class="math inline">\((k_1,k_2,...,k_n)\)</span> corresponding to the approximation errors <span class="math inline">\((ε_1,ε_2,...,ε_n)\)</span> generated by a series and the limit <span class="math inline">\(\tilde{α}_{min}\)</span>.</p>
<p><strong>Output</strong>: The coefficient <span class="math inline">\(α\)</span> correspond to the rate of convergence, and the coefficient <span class="math inline">\(β\)</span> corresponds to the distance of convergence such that <span class="math inline">\(ε_k≤βk_i^{-α}\)</span> for all <span class="math inline">\(i=1,2,...,n.\)</span></p>
<p><span class="math inline">\(\operatorname{Find-Convergence-Line-Log}((k_1,k_2,...,k_n),(ε_1,ε_2,...,ε_n),a_{min})\)</span></p>
<ol type="1">
<li><span class="math inline">\(x=(\log_{10}(k_1),\log_{10}(k_2),...,\log_{10}(k_n))\)</span></li>
<li><span class="math inline">\(y=(\log_{10}(|ε_1|,\log_{10}(|ε_2|,...,\log_{10}(|ε_n|))\)</span></li>
<li><span class="math inline">\((\tilde{α},\tilde{b})=\operatorname{Find-Convergence-Line}(x,y,\tilde{α}_{min})\)</span></li>
<li><span class="math inline">\(α=-\tilde{α}\)</span></li>
<li><span class="math inline">\(β=10^\tilde{β}\)</span></li>
<li><strong>return</strong> <span class="math inline">\((α,β)\)</span></li>
</ol>
<!-- Transform line back into exponential form
\[
\begin{aligned}
\hat{y} &= ax + b \\
10^{\hat{y}} &= 10^{ax+b} \\
10^{\hat{y}} &= 10^b ⋅ {(10^x)}^a \\
\end{aligned}
\] -->
<h2 id="conjectures-of-pointwise-convergence">Conjectures of Pointwise Convergence</h2>
<p>The papers by Babuska and Hakula <span class="citation" data-cites="Babuska2014 Babuska2019">(<a href="#ref-Babuska2014" role="doc-biblioref">1</a>, <a href="#ref-Babuska2019" role="doc-biblioref">2</a>)</span> introduced two conjectures about the convergence rate and convegence distance. They are stated as follows. The convergence rate <span class="math inline">\(α\)</span> depends on <span class="math inline">\(x\)</span> and the degree <span class="math inline">\(b\)</span> <span class="math display">\[
α(x,b)=
\begin{cases}
\max(b,1), & x=a \\
b+1/2, & x∈\{-1,1\} \\
b+1, & x∈(-1,a)∪(a,1). \\
\end{cases}
\tag{25}
\label{convergence-rate}
\]</span> As can be seen, there are different convergence rates at the edges, singularity and elsewhere.</p>
<p>The convergence distance <span class="math inline">\(β\)</span> depends on <span class="math inline">\(x\)</span> but is independent of the degree <span class="math inline">\(b\)</span>. <strong>Near singularity</strong> we have <span class="math display">\[
β(a±ξ)≤Dξ^{-ρ}, ρ=1
\tag{26}
\label{convergence-distance-near-singularity}
\]</span> and <strong>near edges</strong> we have <span class="math display">\[
β(±(1-ξ))≤Dξ^{-ρ}, ρ=1/4
\tag{27}
\label{convergence-distance-near-edges}
\]</span> where <span class="math inline">\(ξ\)</span> is small positive number and <span class="math inline">\(D\)</span> is a positive constant. The behaviour near the singularity is related to the <a href="https://en.wikipedia.org/wiki/Gibbs_phenomenon">Gibbs phenomenom</a>.</p>
<h2 id="results">Results</h2>
<p>The results were obtained by computing the approximation error <span class="math inline">\(\eqref{approximation-error}\)</span> for the step function and V function up to degree <span class="math inline">\(n=10^5.\)</span> The values of <span class="math inline">\(x\)</span> from the domain <span class="math inline">\(Ω\)</span> were chosen to include the edges, singularity, and its negation, zero, points near the edges and singularity, and points elsewhere in the domain. Then pointwise convergence was analyzed by finding the convergence line, i.e., the values for the rate of convergence <span class="math inline">\(α\)</span> and the distance of convergence <span class="math inline">\(β\)</span> for the approximation errors. The values were then verified to follow the conjectures <span class="math inline">\(\eqref{convergence-rate}\)</span>, <span class="math inline">\(\eqref{convergence-distance-near-edges}\)</span> and <span class="math inline">\(\eqref{convergence-distance-near-singularity}\)</span> as can be seen from the figures below.</p>
<h3 id="step-function">Step Function</h3>
<p>The following results where <span class="math inline">\(a=0.5\)</span> and <span class="math inline">\(b=0\)</span> for the step function.</p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/-1.0000000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/1.0000000.png" /></p>
<p>Pointwise convergence at the edges has a convergence rate of <span class="math inline">\(α=1/2\)</span>.</p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/-0.5000000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/0.5000000.png" /></p>
<p>Pointwise convergence at the singularity and its negation have a convergence rate of <span class="math inline">\(α=1\)</span>.</p>
<!-- ![](../images/legendre_series/pointwise_convergence/step_function/0.5/0.0000000.png) -->
<!-- Zero -->
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/0.4900000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/0.4990000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/0.4999000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/0.5100000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/0.5010000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/0.5001000.png" /></p>
<p>Pointwise convergence near singularity <span class="math inline">\(a±ξ\)</span> has a rate of convergence <span class="math inline">\(α=1\)</span>, but as can be seen, the distance of convergence <span class="math inline">\(β\)</span> increases as <span class="math inline">\(x\)</span> moves closer to the singularity from either side.</p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/-0.9990000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/-0.9999000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/-0.9999900.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/0.9990000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/0.9999000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/step_function/0.5/0.9999900.png" /></p>
<p>Pointwise convergence near edges <span class="math inline">\(±(1-ξ)\)</span> has a rate of convergence <span class="math inline">\(α=1\)</span> but similarly to points near singularity as <span class="math inline">\(x\)</span> moves closer to the edges the distance of convergence <span class="math inline">\(β\)</span> increases. Also, the pre-asymptotic region, i.e., a region with a different convergence rate, is visible.</p>
<p><img src="../images/legendre_series/convergence_distances/step_function/0.5.png" /></p>
<p>We have plotted the convergence distances <span class="math inline">\(β\)</span> into a graph as a function of <span class="math inline">\(x\)</span>. We can see the behavior at the near edges and near singularity. Values in these regions can be plotted on a logarithmic scale.</p>
<p><img src="../images/legendre_series/convergence_distances_loglog/step_function/0.5/near_left_a.png" /></p>
<p><img src="../images/legendre_series/convergence_distances_loglog/step_function/0.5/near_right_a.png" /></p>
<p>Near-singularity convergence distances <span class="math inline">\(β(a±ξ)\)</span> as a function of <span class="math inline">\(x\)</span> are linear at the logarithmic scale where the parameter <span class="math inline">\(ρ≈1.0.\)</span></p>
<p><img src="../images/legendre_series/convergence_distances_loglog/step_function/0.5/near_left_edge.png" /></p>
<p><img src="../images/legendre_series/convergence_distances_loglog/step_function/0.5/near_right_edge.png" /></p>
<p>Near edges, convergence distances <span class="math inline">\(β(±(1-ξ))\)</span> as a function of <span class="math inline">\(x\)</span> are linear at the logarithmic scale where the parameter <span class="math inline">\(ρ≈1/4.\)</span></p>
<h3 id="v-function">V Function</h3>
<p>The following results where <span class="math inline">\(a=0.5\)</span> and <span class="math inline">\(b=1\)</span> for the V function. The results are similar, but not identical to those of the step function.</p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/-1.0000000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/1.0000000.png" /></p>
<p>Pointwise convergence at the edges has a convergence rate of <span class="math inline">\(α=1+1/2\)</span>.</p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/-0.5000000.png" /></p>
<p>Pointwise convergence at the negation of singularity has convergence rate of <span class="math inline">\(α=2\)</span></p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/0.5000000.png" /></p>
<p>Pointwise convergence at the singularity has a convergence rate of <span class="math inline">\(α=1\)</span>. As can be seen, the convergence pattern is almost linear with very little oscillation.</p>
<!-- ![](../images/legendre_series/pointwise_convergence/v_function/0.5/0.0000000.png) -->
<!-- Zero -->
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/0.4900000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/0.4990000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/0.4999000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/0.5100000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/0.5010000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/0.5001000.png" /></p>
<p>Pointwise convergence near singularity <span class="math inline">\(a±ξ\)</span> has a rate of convergence <span class="math inline">\(α=2\)</span>, but as can be seen, the distance of convergence <span class="math inline">\(β\)</span> increases as <span class="math inline">\(x\)</span> moves closer to the singularity from either side.</p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/-0.9990000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/-0.9999000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/-0.9999900.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/0.9990000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/0.9999000.png" /></p>
<p><img src="../images/legendre_series/pointwise_convergence/v_function/0.5/0.9999900.png" /></p>
<p>Pointwise convergence near edges <span class="math inline">\(±(1-ξ)\)</span> has a rate of convergence <span class="math inline">\(α=2\)</span> but similarly to points near singularity as <span class="math inline">\(x\)</span> moves closer to the edges the distance of convergence <span class="math inline">\(β\)</span> increases. Also, the pre-asymptotic region, i.e., a region with a different convergence rate, is visible.</p>
<p><img src="../images/legendre_series/convergence_distances/v_function/0.5.png" /></p>
<p>We have plotted the convergence distances <span class="math inline">\(β\)</span> into a graph as a function of <span class="math inline">\(x\)</span>. We can see the behavior at the near edges and near singularity. Values in these regions can be plotted on a logarithmic scale.</p>
<p><img src="../images/legendre_series/convergence_distances_loglog/v_function/0.5/near_left_a.png" /></p>
<p><img src="../images/legendre_series/convergence_distances_loglog/v_function/0.5/near_right_a.png" /></p>
<p>Near-singularity convergence distances <span class="math inline">\(β(a±ξ)\)</span> as a function of <span class="math inline">\(x\)</span> are linear at the logarithmic scale where the parameter <span class="math inline">\(ρ≈1.0.\)</span></p>
<p><img src="../images/legendre_series/convergence_distances_loglog/v_function/0.5/near_left_edge.png" /></p>
<p><img src="../images/legendre_series/convergence_distances_loglog/v_function/0.5/near_right_edge.png" /></p>
<p>Near edges, convergence distances <span class="math inline">\(β(±(1-ξ))\)</span> as a function of <span class="math inline">\(x\)</span> are linear at the logarithmic scale where the parameter <span class="math inline">\(ρ≈1/4.\)</span></p>
<h2 id="python-code">Python Code</h2>
<p>The source code for the algorithms, plots, and animations is available in <a href="https://github.com/jaantollander/LegendreSeries">LegendreSeries</a> GitHub repository. It also contains instructions on how to run the code.</p>
<h2 id="conclusions">Conclusions</h2>
<p>The results show that the Legendre series for piecewise analytic functions follows the conjectures <span class="math inline">\(\eqref{convergence-rate}, \eqref{convergence-distance-near-singularity}\)</span> and <span class="math inline">\(\eqref{convergence-distance-near-edges}\)</span> with high precision upto very high degree series expansion.</p>
<p>The future research could be extended to study the effects of the position of the singularity <span class="math inline">\(a\)</span> to the constant <span class="math inline">\(D\)</span> or to study series expansion using other classical orthogonal polynomials and special cases of Jacobi polynomials such as Chebyshev polynomials. However, their formulas are unlikely to have convenient closed-form solutions and could, therefore, be more challenging to study.</p>
<h2 id="references" class="unnumbered">References</h2>
<div id="refs" class="references" role="doc-bibliography">
<div id="ref-Babuska2014">
<p>1. BABUŠKA, Ivo and HAKULA, Harri. On the $p$-version of FEM in one dimension: The known and unknown features. [online]. 2014. P. 1–25. Available from: <a href="http://arxiv.org/abs/1401.1483">http://arxiv.org/abs/1401.1483</a></p>
</div>
<div id="ref-Babuska2019">
<p>2. BABUŠKA, Ivo and HAKULA, Harri. Pointwise error estimate of the Legendre expansion : The known and unknown features. <em>Computer Methods in Applied Mechanics and Engineering</em> [online]. 2019. Vol. 345, no. 339380, p. 748–773. DOI <a href="https://doi.org/10.1016/j.cma.2018.11.017">10.1016/j.cma.2018.11.017</a>. Available from: <a href="https://doi.org/10.1016/j.cma.2018.11.017">https://doi.org/10.1016/j.cma.2018.11.017</a></p>
</div>
</div>
Noise Filtering Using 1€ Filter2018-12-29T00:00:00+02:002018-12-29T00:00:00+02:00Jaan Tollander de Balschtag:jaantollander.github.io,2018-12-29:/noise-filtering-using-one-euro-filter.html
<p><img src="../images/one_euro_filter.gif" /></p>
<blockquote>
</blockquote>
<p>This article explores the 1€ Filter, a simple, but powerful algorithm for filtering noisy real-time signals. The article focuses on the practical implementation of the algorithm, and it covers the mathematical basis, a pseudocode implementation, and simple, pure Python implementation of the algorithm. In order to understand why and how the filter works, we recommend reading the original article <span class="citation" data-cites="one_euro_filter">(<a href="#ref-one_euro_filter" role="doc-biblioref">1</a>)</span>.</p>
<p><img src="../images/one_euro_filter.gif" /></p>
<blockquote>
</blockquote>
<p>This article explores the 1€ Filter, a simple, but powerful algorithm for filtering noisy real-time signals. The article focuses on the practical implementation of the algorithm, and it covers the mathematical basis, a pseudocode implementation, and simple, pure Python implementation of the algorithm. In order to understand why and how the filter works, we recommend reading the original article <span class="citation" data-cites="one_euro_filter">(<a href="#ref-one_euro_filter" role="doc-biblioref">1</a>)</span>.</p>
<p><strong>Contents</strong></p>
<!-- TOC -->
<ul>
<li><a href="#the-1%E2%82%AC-filter">The 1€ Filter</a></li>
<li><a href="#the-algorithm">The Algorithm</a></li>
<li><a href="#tuning-the-filter">Tuning the Filter</a></li>
<li><a href="#python-implementation">Python Implementation</a></li>
<li><a href="#references">References</a></li>
</ul>
<!-- /TOC -->
<p><strong>Keywords</strong>: Noise filtering, 1€ Filter, 1e filter, 1 euro filter, One Euro Filter</p>
<h2 id="the-1-filter">The 1€ Filter</h2>
<p>The <a href="http://cristal.univ-lille.fr/~casiez/1euro/">1€ Filter</a> is a low pass filter for filtering noisy signals in real time. It’s also a simple filter with only two configurable parameters. The signal at time <span class="math inline">\(T_i\)</span> is denoted as a value <span class="math inline">\(X_i\)</span> and the filtered signal as value <span class="math inline">\(\hat{X}_i\)</span>. The filter is implemented using <em>exponential smoothing</em> <span class="math display">\[
\hat{X}_1 = X_1 \\
\hat{X}_i = α X_i + (1-α) \hat{X}_{i-1}, i≥2
\tag{exponential-smoothing}
\label{exponential-smoothing}
\]</span> where the smoothing factor <span class="math inline">\(α∈[0, 1]\)</span>, instead of being a constant, is adaptive, i.e. dynamically computed using information about the rate of change (speed) of the signal. This aims to balance the jitter versus lag trade-off since people are more sensitive to jitter at low speeds and more sensitive to lag at high speeds. The smoothing factor is defined as <span class="math display">\[
α = \frac{1}{1 + \dfrac{τ}{T_e}},
\tag{smoothing-factor}
\label{smoothing-factor}
\]</span> where <span class="math inline">\(T_e\)</span> is the sampling period computed from the time difference between the samples <span class="math display">\[
T_e=T_i-T_{i-1}
\tag{sampling-period}
\]</span> and <span class="math inline">\(τ\)</span> is time constant computed using the cutoff frequency <span class="math display">\[
τ = \frac{1}{2πf_C}.
\tag{time-constant}
\]</span></p>
<p>The cutoff frequency <span class="math inline">\(f_C\)</span> which is designed to increase linearly as the rate of change, aka speed, increases <span class="math display">\[
f_C=f_{C_{min}} + β|\hat{\dot{X}}_i|
\tag{cutoff-frequency}
\]</span> where <span class="math inline">\(f_{C_{min}}>0\)</span> is the <em>minimum cutoff frequency</em>, <span class="math inline">\(β>0\)</span> is the <em>speed coefficient</em> and <span class="math inline">\(\hat{\dot{X}}_i\)</span> is the filtered rate of change. The rate of change <span class="math inline">\(\hat{X}_i\)</span> is defined as the discrete derivative of the signal <span class="math display">\[
\dot{X}_1 = 0 \\
\dot{X}_i = \frac{X_i-\hat{X}_{i-1}}{T_e}, i≥2,
\tag{derivative}
\]</span> which is then filtered using <span class="math inline">\(\eqref{exponential-smoothing}\)</span> with a constant cutoff frequency <span class="math inline">\(f_{C_d},\)</span> by default <span class="math inline">\(f_{C_d}=1\)</span>.</p>
<h2 id="the-algorithm">The Algorithm</h2>
<p>The One Euro Filter algorithm as pseudocode. The precise implementation of the One-Euro-filter will depend on the programming language and paradigm in question. We have written this algorithm using a functional style.</p>
<p><span class="math inline">\(\operatorname{Smoothing-Factor}(f_C, T_e)\)</span></p>
<ol type="1">
<li><span class="math inline">\(r=2π⋅f_c⋅T_e\)</span></li>
<li><strong>return</strong> <span class="math inline">\(\dfrac{r}{r+1}\)</span></li>
</ol>
<p><span class="math inline">\(\operatorname{Exponential-Smoothing}(α, X_i, \hat{X}_{i-1})\)</span></p>
<ol type="1">
<li><strong>return</strong> <span class="math inline">\(α X_i + (1-α) \hat{X}_{i-1}\)</span></li>
</ol>
<p><span class="math inline">\(\operatorname{One-Euro-Filter}(T_i,X_i,T_{i-1},\hat{X}_{i-1},\hat{\dot{X}}_{i-1},f_C,β,f_{C_d})\)</span> for <span class="math inline">\(i≥2\)</span></p>
<ol type="1">
<li><span class="math inline">\(T_e=T_i-T_{i-1}\)</span></li>
<li><span class="math inline">\(α_d=\operatorname{Smoothing-Factor}(T_e, f_{C_d})\)</span></li>
<li><span class="math inline">\(\dot{X}_i = \dfrac{X_i-\hat{X}_{i-1}}{T_e}\)</span></li>
<li><span class="math inline">\(\hat{\dot{X}}_i=\operatorname{Exponential-Smoothing}(α_d, \dot{X}_i, \hat{\dot{X}}_{i-1})\)</span></li>
<li><span class="math inline">\(f_C=f_{C_{min}} + β|\hat{\dot{X}}_i|\)</span></li>
<li><span class="math inline">\(α=\operatorname{Smoothing-Factor}(f_C, T_e)\)</span></li>
<li><span class="math inline">\(\hat{X}_i=\operatorname{Exponential-Smoothing}(α, X_i, \hat{X}_{i-1})\)</span></li>
<li><strong>return</strong> <span class="math inline">\(T_i,\hat{X}_i,\hat{\dot{X}}_i\)</span></li>
</ol>
<h2 id="tuning-the-filter">Tuning the Filter</h2>
<p>There are two configurable parameters in the model, the <em>minimum cutoff frequency</em> <span class="math inline">\(f_{C_{min}}\)</span> and the <em>speed coefficient</em> <span class="math inline">\(β\)</span>. Decreasing the minimum cutoff frequency will decrease slow speed jitter. Increasing the speed coefficient will decrease speed lag.</p>
<h2 id="python-implementation">Python Implementation</h2>
<p>The following object-oriented Python implementation is also available in <a href="https://github.com/jaantollander/OneEuroFilter">OneEuroFilter</a> GitHub repository. The object-oriented approach stores the previous values inside the object instead of giving them explicitly as a return value as functional implementation would. It should be relatively simple to implement this algorithm in other languages.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1"></a><span class="im">import</span> math</span>
<span id="cb1-2"><a href="#cb1-2"></a></span>
<span id="cb1-3"><a href="#cb1-3"></a></span>
<span id="cb1-4"><a href="#cb1-4"></a><span class="kw">def</span> smoothing_factor(t_e, cutoff):</span>
<span id="cb1-5"><a href="#cb1-5"></a> r <span class="op">=</span> <span class="dv">2</span> <span class="op">*</span> math.pi <span class="op">*</span> cutoff <span class="op">*</span> t_e</span>
<span id="cb1-6"><a href="#cb1-6"></a> <span class="cf">return</span> r <span class="op">/</span> (r <span class="op">+</span> <span class="dv">1</span>)</span>
<span id="cb1-7"><a href="#cb1-7"></a></span>
<span id="cb1-8"><a href="#cb1-8"></a></span>
<span id="cb1-9"><a href="#cb1-9"></a><span class="kw">def</span> exponential_smoothing(a, x, x_prev):</span>
<span id="cb1-10"><a href="#cb1-10"></a> <span class="cf">return</span> a <span class="op">*</span> x <span class="op">+</span> (<span class="dv">1</span> <span class="op">-</span> a) <span class="op">*</span> x_prev</span>
<span id="cb1-11"><a href="#cb1-11"></a></span>
<span id="cb1-12"><a href="#cb1-12"></a></span>
<span id="cb1-13"><a href="#cb1-13"></a><span class="kw">class</span> OneEuroFilter:</span>
<span id="cb1-14"><a href="#cb1-14"></a> <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>, t0, x0, dx0<span class="op">=</span><span class="fl">0.0</span>, min_cutoff<span class="op">=</span><span class="fl">1.0</span>, beta<span class="op">=</span><span class="fl">0.0</span>,</span>
<span id="cb1-15"><a href="#cb1-15"></a> d_cutoff<span class="op">=</span><span class="fl">1.0</span>):</span>
<span id="cb1-16"><a href="#cb1-16"></a> <span class="co">"""Initialize the one euro filter."""</span></span>
<span id="cb1-17"><a href="#cb1-17"></a> <span class="co"># The parameters.</span></span>
<span id="cb1-18"><a href="#cb1-18"></a> <span class="va">self</span>.min_cutoff <span class="op">=</span> <span class="bu">float</span>(min_cutoff)</span>
<span id="cb1-19"><a href="#cb1-19"></a> <span class="va">self</span>.beta <span class="op">=</span> <span class="bu">float</span>(beta)</span>
<span id="cb1-20"><a href="#cb1-20"></a> <span class="va">self</span>.d_cutoff <span class="op">=</span> <span class="bu">float</span>(d_cutoff)</span>
<span id="cb1-21"><a href="#cb1-21"></a> <span class="co"># Previous values.</span></span>
<span id="cb1-22"><a href="#cb1-22"></a> <span class="va">self</span>.x_prev <span class="op">=</span> <span class="bu">float</span>(x0)</span>
<span id="cb1-23"><a href="#cb1-23"></a> <span class="va">self</span>.dx_prev <span class="op">=</span> <span class="bu">float</span>(dx0)</span>
<span id="cb1-24"><a href="#cb1-24"></a> <span class="va">self</span>.t_prev <span class="op">=</span> <span class="bu">float</span>(t0)</span>
<span id="cb1-25"><a href="#cb1-25"></a></span>
<span id="cb1-26"><a href="#cb1-26"></a> <span class="kw">def</span> <span class="fu">__call__</span>(<span class="va">self</span>, t, x):</span>
<span id="cb1-27"><a href="#cb1-27"></a> <span class="co">"""Compute the filtered signal."""</span></span>
<span id="cb1-28"><a href="#cb1-28"></a> t_e <span class="op">=</span> t <span class="op">-</span> <span class="va">self</span>.t_prev</span>
<span id="cb1-29"><a href="#cb1-29"></a></span>
<span id="cb1-30"><a href="#cb1-30"></a> <span class="co"># The filtered derivative of the signal.</span></span>
<span id="cb1-31"><a href="#cb1-31"></a> a_d <span class="op">=</span> smoothing_factor(t_e, <span class="va">self</span>.d_cutoff)</span>
<span id="cb1-32"><a href="#cb1-32"></a> dx <span class="op">=</span> (x <span class="op">-</span> <span class="va">self</span>.x_prev) <span class="op">/</span> t_e</span>
<span id="cb1-33"><a href="#cb1-33"></a> dx_hat <span class="op">=</span> exponential_smoothing(a_d, dx, <span class="va">self</span>.dx_prev)</span>
<span id="cb1-34"><a href="#cb1-34"></a></span>
<span id="cb1-35"><a href="#cb1-35"></a> <span class="co"># The filtered signal.</span></span>
<span id="cb1-36"><a href="#cb1-36"></a> cutoff <span class="op">=</span> <span class="va">self</span>.min_cutoff <span class="op">+</span> <span class="va">self</span>.beta <span class="op">*</span> <span class="bu">abs</span>(dx_hat)</span>
<span id="cb1-37"><a href="#cb1-37"></a> a <span class="op">=</span> smoothing_factor(t_e, cutoff)</span>
<span id="cb1-38"><a href="#cb1-38"></a> x_hat <span class="op">=</span> exponential_smoothing(a, x, <span class="va">self</span>.x_prev)</span>
<span id="cb1-39"><a href="#cb1-39"></a></span>
<span id="cb1-40"><a href="#cb1-40"></a> <span class="co"># Memorize the previous values.</span></span>
<span id="cb1-41"><a href="#cb1-41"></a> <span class="va">self</span>.x_prev <span class="op">=</span> x_hat</span>
<span id="cb1-42"><a href="#cb1-42"></a> <span class="va">self</span>.dx_prev <span class="op">=</span> dx_hat</span>
<span id="cb1-43"><a href="#cb1-43"></a> <span class="va">self</span>.t_prev <span class="op">=</span> t</span>
<span id="cb1-44"><a href="#cb1-44"></a></span>
<span id="cb1-45"><a href="#cb1-45"></a> <span class="cf">return</span> x_hat</span></code></pre></div>
<p>Here we provide an example of how to use the One Euro Filter for filtering a signal in real-time.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1"></a><span class="co"># Let signal be a generator that yields a tuple (t, x)</span></span>
<span id="cb2-2"><a href="#cb2-2"></a><span class="co"># where t is time and x the values of the signal.</span></span>
<span id="cb2-3"><a href="#cb2-3"></a>signal <span class="op">=</span> ...</span>
<span id="cb2-4"><a href="#cb2-4"></a></span>
<span id="cb2-5"><a href="#cb2-5"></a><span class="co"># Instantiate the OneEuroFilter with initial values and</span></span>
<span id="cb2-6"><a href="#cb2-6"></a><span class="co"># your value for parameters min_cutoff and beta.</span></span>
<span id="cb2-7"><a href="#cb2-7"></a>t0, x0 <span class="op">=</span> <span class="bu">next</span>(signal)</span>
<span id="cb2-8"><a href="#cb2-8"></a>one_euro_filter <span class="op">=</span> OneEuroFilter(</span>
<span id="cb2-9"><a href="#cb2-9"></a> t0<span class="op">=</span>t0,</span>
<span id="cb2-10"><a href="#cb2-10"></a> x0<span class="op">=</span>x0,</span>
<span id="cb2-11"><a href="#cb2-11"></a> min_cutoff<span class="op">=</span>...,</span>
<span id="cb2-12"><a href="#cb2-12"></a> beta<span class="op">=</span>...</span>
<span id="cb2-13"><a href="#cb2-13"></a>)</span>
<span id="cb2-14"><a href="#cb2-14"></a></span>
<span id="cb2-15"><a href="#cb2-15"></a><span class="co"># Filter the signal in real time.</span></span>
<span id="cb2-16"><a href="#cb2-16"></a><span class="cf">for</span> (t, x) <span class="kw">in</span> signal:</span>
<span id="cb2-17"><a href="#cb2-17"></a> x_hat <span class="op">=</span> one_euro_filter(t, x)</span>
<span id="cb2-18"><a href="#cb2-18"></a> ...</span></code></pre></div>
<h2 id="references" class="unnumbered">References</h2>
<div id="refs" class="references" role="doc-bibliography">
<div id="ref-one_euro_filter">
<p>1. CASIEZ, Géry, ROUSSEL, Nicolas and VOGEL, Daniel. 1€ filter: A simple speed-based low-pass filter for noisy input in interactive systems. In : <em>Proceedings of the sigchi conference on human factors in computing systems</em>. ACM, 2012. p. 2527–2530. </p>
</div>
</div>
Tools and Methods for Reading Articles Online2018-12-19T00:00:00+02:002018-12-19T00:00:00+02:00Jaan Tollander de Balschtag:jaantollander.github.io,2018-12-19:/reading-articles-online.html
<p><img src="../images/feedly-interface.png" /></p>
<p>The internet is full of written online resources for learning, such as blog articles, technical documentation, and encyclopedia. However, it can be challenging to manage all the resources we have read and then find them again at a later date. This article explores tools and methods for managing online text. It’s written for students, researchers, and people who are interested in reading or research.</p>
<p><img src="../images/feedly-interface.png" /></p>
<p>The internet is full of written online resources for learning, such as blog articles, technical documentation, and encyclopedia. However, it can be challenging to manage all the resources we have read and then find them again at a later date. This article explores tools and methods for managing online text. It’s written for students, researchers, and people who are interested in reading or research.</p>
<p><strong>Contents</strong></p>
<!-- TOC -->
<ul>
<li><a href="#technology-overview">Technology Overview</a></li>
<li><a href="#using-feedly-and-pocket">Using Feedly and Pocket</a></li>
</ul>
<!-- /TOC -->
<p><strong>Keywords</strong>: Feedly, Pocket</p>
<!-- TODO: Weava -->
<h2 id="technology-overview">Technology Overview</h2>
<p><img src="../images/pocket-interface.png" /></p>
<p>Most online content is often recurrent, meaning the creators update it on a daily, weekly, or monthly basis. <a href="https://en.wikipedia.org/wiki/Web_syndication">Web syndication</a> can be used to follow the updates of recurrent content. Standard formats of syndication include RSS and Atom. We refer syndicated content as a <em>feed</em>, and we manage them using an application referred to as a <em>feed aggregator</em>.</p>
<p><a href="https://feedly.com/"><strong>Feedly</strong></a> is a popular feed aggregator that works on the browser and various mobile devices. Its minimalistic and functional interface is perfect for saving, managing, and reviewing feeds. Articles can be saved to boards such <em>read later</em>.</p>
<p>Unfortunately, feeds don’t always contain the full article, but only a summary of the contents. Therefore, we cannot rely just on the feed aggregator for reading the article, but we either need to visit the website or use an aggregator to read it. We recommend aggregating articles if possible because it makes reading them more comfortable by getting rid of unnecessary distractions like popups in websites, standardizing the format, and allowing custom features such as pagination.</p>
<p><a href="https://getpocket.com/"><strong>Pocket</strong></a> is an application that can be used to save, aggregate, and read web content. Pocket integrates Kobo e-readers out of the box, and Kindle users can use a service like <a href="https://p2k.co/">Pocket to Kindle</a>. Feedly integrates with Pocket allowing articles saved to Pocket directly from Feedly.</p>
<h2 id="using-feedly-and-pocket">Using Feedly and Pocket</h2>
<div style="position:relative;height:0;padding-bottom:56.21%">
<iframe src="https://www.youtube.com/embed/6lLe1wkbGQ8?ecver=2" style="position:absolute;width:100%;height:100%;left:0" width="641" height="360" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen>
</iframe>
</div>
<blockquote>
</blockquote>
<p>Here are the steps of using Feedly and Pocket.</p>
<!-- following feeds -->
<ol type="1">
<li><p><strong>Follow</strong> – Any website that includes a feed such as Atom or RSS can be followed using Feedly. To follow a feed, we can use the <em>add content</em> button in the Feedly application, or use Feedly’s browser extension on the website. On mobile, we can use the <em>share</em> option and select Feedly from the application menu.</p></li>
<li><p><strong>Organize</strong> – When adding new feeds, place them in feeds named after their genre. For example, if you were to follow this blog, you could put it under <em>Programming</em>.</p></li>
</ol>
<!-- review process -->
<ol start="3" type="1">
<li><strong>Review</strong> – Select a board such as <em>All</em> or one of your custom boards. New content should show next to the sidebar. Select the first one, decide if the content of the feed is interesting by reading the title and the summary. If so, add the content to the <em>read later</em> board and then move to the next one and repeat this step.</li>
</ol>
<!-- reading process -->
<ol start="4" type="1">
<li><p><strong>Read</strong> – After reviewing new content, select the <em>read later</em> board. Some feeds have their full content provided by the feed and can be read using Feedly, and others have to be read from the website or aggregated using Pocket. If aggregation is needed, use the <em>save to Pocket</em> button.</p></li>
<li><p><strong>Save</strong> – After reading the content, we can save it to a board where we can find it later. When using Pocket, archive the content.</p></li>
</ol>
Tools and Methods for Reading Books and Articles on E-Reader2018-11-29T00:00:00+02:002018-11-29T00:00:00+02:00Jaan Tollander de Balschtag:jaantollander.github.io,2018-11-29:/reading-on-e-reader.html
<p><img src="../images/kobo-koreader-pdf-landscape.jpg" /></p>
<blockquote>
</blockquote>
<p>This article delves into details on how to read and manage electronic books and articles in EPUB and PDF formats. It offers practical advice on which tools, software, and methods to use, based on my experience. We directed this article towards students, researchers, and people who are interested in a more systematic and organized way of managing and reading books and written material in electronic formats. The article continues from the article <a href="../2018/2018-08-02-electronic-literature.html"><em>Reading and Managing Electronic Literature</em></a>, which touched on the subject more abstractly.</p>
<p><img src="../images/kobo-koreader-pdf-landscape.jpg" /></p>
<blockquote>
</blockquote>
<p>This article delves into details on how to read and manage electronic books and articles in EPUB and PDF formats. It offers practical advice on which tools, software, and methods to use, based on my experience. We directed this article towards students, researchers, and people who are interested in a more systematic and organized way of managing and reading books and written material in electronic formats. The article continues from the article <a href="../2018/2018-08-02-electronic-literature.html"><em>Reading and Managing Electronic Literature</em></a>, which touched on the subject more abstractly.</p>
<p><strong>Contents</strong></p>
<!-- TOC -->
<ul>
<li><a href="#technology-overview">Technology Overview</a></li>
<li><a href="#managing-e-books-with-goodreads-and-calibre">Managing E-books with Goodreads and Calibre</a></li>
<li><a href="#managing-research-papers-using-mendeley">Managing Research Papers using Mendeley</a></li>
<li><a href="#optimizing-pdfs-using-k2pdfopt">Optimizing PDFs using K2pdfopt</a></li>
<li><a href="#reading-pdfs-using-koreader">Reading PDFs using KOReader</a></li>
</ul>
<!-- /TOC -->
<p><strong>Keywords</strong>: EPUB, PDF, E-book, E-reader, Goodreads, Calibre, Mendeley, k2pdfopt, KOReader</p>
<h2 id="technology-overview">Technology Overview</h2>
<p><img src="../images/calibre-goodreads-koreader-kobo.png" /></p>
<p>This article discusses methods and tools to manage and read e-books and articles in <strong>EPUB</strong> and <strong>PDF</strong> file formats. In practice, EPUBs are easier to handle on an e-reader device, but at the time of writing, they cannot handle well special formatting such as equations. PDF is a widely used file format for scientific and technical documents, but due to the fixed layout, that is, they display the same way on all devices, PDFs are somewhat inflexible when it comes to the formatting. EPUB files, on the other hand, were designed to be reflowable, that is, they adjust to the display. For example, you cannot resize the text on PDFs, and Kobo e-readers do not support highlighting natively. This article list some ways to overcome these challenges. Here are the hardware and software used in the making of the article:</p>
<ul>
<li><p><a href="https://us.kobobooks.com/products/kobo-aura-one"><strong>Kobo Aura One</strong></a> – I will be using the Kobo Aura One e-reading device. We based the software recommendations on compatibility with this device. There are also other e-readers, the most popular being Kindle. You should explore your options and make your choice based on your needs. I chose a Kobo device because they don’t require jailbreaking for installing custom software, whereas the Kindle device does.</p></li>
<li><p><a href="http://koreader.rocks/"><strong>Koreader</strong></a> – <em>Koreader</em> is a document viewer for E-ink devices. We can install it on the side of the standard Kobo software, <em>Nickel</em>. KOReader has a more sophisticated and advanced PDF reader than Nickel. It’s able to crop whitespace to display PDFs better and supports highlighting for PDFs.</p></li>
<li><p><a href="https://www.goodreads.com"><strong>Goodreads</strong></a> – Goodreads is a popular social cataloging website for books, annotations, and reviews. It has a large community of readers and an extensive database for searching books and authors. These qualities make Goodreads excellent application for keeping lists of books such as <em>want to read</em>, <em>reading</em> and <em>read</em>. Goodreads also has a community of other readers to discuss books.</p></li>
<li><p><a href="https://calibre-ebook.com/"><strong>Calibre</strong></a> – Calibre is an application for managing e-book files and metadata. It’s a free, open-source, cross-platform e-book manager software that supports all major e-book formats, including EPUB and PDF formats. Calibre’s Kobo plugin enables Calibre to be used to send and delete books on Kobo devices.</p></li>
</ul>
<h2 id="managing-e-books-with-goodreads-and-calibre">Managing E-books with Goodreads and Calibre</h2>
<div style="position:relative;height:0;padding-bottom:56.21%">
<iframe src="https://www.youtube.com/embed/mYyXUSsThtI?ecver=2" style="position:absolute;width:100%;height:100%;left:0" width="641" height="360" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen>
</iframe>
</div>
<blockquote>
</blockquote>
<p>Managing e-books consists of tracking books you want to read, are currently reading, and have read, controlling an electronic library of the e-book files and their metadata and sending them to the e-reader. The process of managing e-books using Goodreads and Calibre consists of the following steps:</p>
<ol type="1">
<li><p><strong>Search</strong> – Search for the book you are looking for in Goodreads. If it doesn’t exist in the database, users can add new books to the database.</p></li>
<li><p><strong>Review</strong> – Reading reviews or summaries can help to understand the main points made in the book. This knowledge can help you to read the book and decide if it’s worth investing time into reading it in the first place.</p></li>
<li><p><strong>Shelve</strong> – Add the book to <code>Want to Read</code> shelve. Also, adding it to a custom shelve, usually named by its genre, helps to categorize your books. Under <code>Genres</code> subtitle, Goodreads lists the names of the shelves where other people have added the given book. Use these as suggestions when categorizing your book.</p></li>
<li><p><strong>Acquire</strong> – Acquire a copy of the book. Goodreads contain links to buy the book from retailers. These links can be found under the section <em>get a copy</em>. Some books are free and can be found using the URL or searching in Google.</p></li>
<li><p><strong>Add to Calibre</strong> – Add the book to Calibre by using the <code>add books</code> button.</p></li>
<li><p><strong>Metadata</strong> – Use Calibre to fetch the metadata and the cover image from the web and to check that the metadata is correct and update it if needed.</p></li>
<li><p><strong>Connect e-reader</strong> – Connect your e-reader to the computer. Calibre should automatically detect it.</p></li>
<li><p><strong>Send to a Device</strong> – Select book and press <code>send to a device</code> to send it to the e-reader.</p></li>
</ol>
<p>You can now safely eject your e-reader, and you should be able to start reading the books. You might also want to track your reading process. Goodreads can be used to track books that you are currently reading and have read.</p>
<ol type="1">
<li><p><strong>Currently Reading</strong> – Add the book to <code>Currently Reading</code> when you have invested a sufficient amount of effort into reading it, for example, the first 30 pages.</p></li>
<li><p><strong>Read</strong> – Add the book to <code>Read</code> shelve once you have read it. Remember to add the date when you finished reading the book. This way, you can track your reading progress. Optionally, if you want to review the book later, add it also to a custom shelve called <code>needs review</code>.</p></li>
</ol>
<p>One of the benefits of tracking your reading is to share it with other people. For instance, check out my profile on <a href="https://www.goodreads.com/jaantollander">Goodreads</a> to the kind of books that I have read or my favorite books.</p>
<h2 id="managing-research-papers-using-mendeley">Managing Research Papers using Mendeley</h2>
<p><img src="../images/mendeley_k2pdfopt.png" /></p>
<p>Compared to books, managing research papers requires managing the metadata for generating citations. Also, an optional but useful action is to optimize the PDF files for e-readers, which makes them easier and faster to read. For this purpose, we have two software, <em>Mendeley</em> and <em>k2pdfopt</em>. Both of the software are free and cross-platform.</p>
<ul>
<li><p><a href="https://www.mendeley.com/"><strong>Mendeley</strong></a> is an application for managing and organizing scholarly papers and citations. Mendeley can automatically fetch article metadata. It can store the articles on the device and cloud and generate citations for them. Because Mendeley can store pure citation data, by adding BibTeX files, it can be used to store citation data for books that you may have stored in Calibre.</p></li>
<li><p><a href="http://www.willus.com/k2pdfopt/"><strong>k2pdfopt</strong></a> is a software that can optimize PDF (and DJVU) files for e-readers, for example by removing whitespace, increasing the font size or converting two-column text into one column. These functions are beneficial for reading research papers because their layout is often not optimal for e-reader screens.</p></li>
</ul>
<p>The process of managing research papers consists of:</p>
<ol type="1">
<li><p>Add the document to <em>Mendeley</em>. Mendeley will store the paper on a designated directory. We can set choose directory in the settings.</p></li>
<li><p>(Optional) Use <em>k2pdfopt</em> generate an optimized version of the original version.</p></li>
<li><p>Add the optimized version to <em>Calibre</em> from where we can add it to the E-reader.</p></li>
</ol>
<h2 id="optimizing-pdfs-using-k2pdfopt">Optimizing PDFs using K2pdfopt</h2>
<figure>
<img src="../images/k2pdfopt_conversion.png" alt="" /><figcaption>Optimized PDF file. <a href="../documents/ieee_twocolumn_template.pdf">Original version</a> on left side, <a href="../documents/ieee_twocolumn_template_k2opt.pdf">optimized version</a> on the right size.</figcaption>
</figure>
<blockquote>
</blockquote>
<figure>
<img src="../images/k2pdfopt_interface.png" alt="" /><figcaption>The Linux terminal interface of k2pdfopt.</figcaption>
</figure>
<blockquote>
</blockquote>
<p>There are many examples of how to use k2pdfopt on the website. For Linux users, after installation, typing <code>k2pdfopt <filename></code> on the terminal will open an interface that will display all the different options for optimizing the document. For example, download <a href="../documents/iee_twocolumn_template.pdf"><code>iee_twocolumn_template.pdf</code></a> and optimize it using <code>k2pdfopt iee_twocolumn_template.pdf -col 2 -n</code>.</p>
<h2 id="reading-pdfs-using-koreader">Reading PDFs using KOReader</h2>
<figure>
<img src="../images/kobo-koreader-pdf-landscape.jpg" alt="" /><figcaption><em>Displaying a PDF in landscape mode using KOReader.</em></figcaption>
</figure>
<blockquote>
</blockquote>
<p>The Kobo devices ship with the ability to read pdf files, but the capabilities of the Kobo standard software, <em>Nickel</em>, are limited. <a href="http://koreader.rocks/"><em>KOReader</em></a> is an alternative document reader for E-ink devices. It’s better for reading pdf files because it’s faster and has features that the standard reader is lacking, such as:</p>
<ul>
<li>Sophisticated whitespace cropping</li>
<li>Ability to toggle between landscape and portrait modes</li>
<li>Ability to highlight text</li>
<li>Ability to navigate using the table of contents</li>
<li>Better page flipping and scrolling</li>
<li>Ability to toggle scroll mode on and off</li>
</ul>
<p>I recommend to watch a review about Koreader made by the eBook Reader: <a href="https://www.youtube.com/watch?v=i2oSOeAnD10"><em>Kobo Aura One KOReader PDF Review</em></a>.</p>
<p>KOReader has to installed on the e-reading device separately. Currently, we can find the supported devices on their website. The Wiki contains the official installation instructions for the supported devices. As of August 2018, the installation KOReader on Kobo Aura One involved downloading archived files, copying files over to the Kobo device, and connecting and disconnecting the device to let it update. It was quite simple and straightforward, but I would still recommend to backup your Kobo files before the installation.</p>
Reading and Managing Electronic Literature2018-08-02T00:00:00+03:002018-08-02T00:00:00+03:00Jaan Tollander de Balschtag:jaantollander.github.io,2018-08-02:/electronic-literature.html
<p><img src="../images/reading-hardware.png" /></p>
<p>In our increasingly more electronic world where the internet is connecting people around the world, and we have greater access to information than ever before in history, the publishing of written word has changed. Even though physical books and magazines remain popular, electronic publishing has seen a significant increase, which has lead to the development of new technology for reading. To thrive in this new era, we have to adapt our old process for managing, reading, and understanding the written word by utilizing the capabilities of modern technology. In this article, we explain the reading process and go through these new technologies.</p>
<p><img src="../images/reading-hardware.png" /></p>
<p>In our increasingly more electronic world where the internet is connecting people around the world, and we have greater access to information than ever before in history, the publishing of written word has changed. Even though physical books and magazines remain popular, electronic publishing has seen a significant increase, which has lead to the development of new technology for reading. To thrive in this new era, we have to adapt our old process for managing, reading, and understanding the written word by utilizing the capabilities of modern technology. In this article, we explain the reading process and go through these new technologies.</p>
<blockquote>
</blockquote>
<p><strong>Contents</strong></p>
<!-- TOC depthFrom:2 depthTo:6 withLinks:1 updateOnSave:1 orderedList:0 -->
<ul>
<li><a href="#why-is-reading-important">Why is Reading Important</a></li>
<li><a href="#the-goal-of-reading">The Goal of Reading</a></li>
<li><a href="#finding-content">Finding Content</a></li>
<li><a href="#components-of-written-works">Components of Written Works</a>
<ul>
<li><a href="#content">Content</a></li>
<li><a href="#metadata">Metadata</a></li>
</ul></li>
<li><a href="#the-reading-process">The Reading Process</a>
<ul>
<li><a href="#motivation">Motivation</a></li>
<li><a href="#understanding-content">Understanding Content</a></li>
</ul></li>
<li><a href="#technology">Technology</a>
<ul>
<li><a href="#common-file-formats">Common File Formats</a></li>
<li><a href="#common-content-types">Common Content Types</a></li>
<li><a href="#devices-and-hardware">Devices and Hardware</a></li>
</ul></li>
</ul>
<!-- /TOC -->
<p>This article is an introductory part of a multipart post about how to read and manage electronic literature. This part will explain the fundamental concepts of the reading process and technologies related to electronic reading and publishing. Subsequent sections will cover in detail various reading and managing workflows for different types of content using specific software.</p>
<h2 id="why-is-reading-important">Why is Reading Important</h2>
<p>Reading is a way to access the valuable information and insights that people have had and collected while working in a particular field or technology without having to experience the same mistakes and the journey as the authors have. In other words, reading shortcuts the process of trial and error for learning, making it an essential skill for any person who wants to learn new concepts faster and more efficiently. Reading gives a unique perspective on the world, improving your sense of what is possible. However, always accompany new information with a healthy dose of skepticism, which prevents the knowledge from turning into constraints.</p>
<h2 id="the-goal-of-reading">The Goal of Reading</h2>
<p>For some people, the goal of reading may be simply the pleasure of reading and passing the time, but most people seek to learn new concepts. I think learning should be the goal of reading, and it should determine the methods we use. The processes for efficient reading include taking highlights and notes, writing about the subject, making connections to other literature and the world, and engaging with the community. Most people are not accustomed to this kind of rigorousness because it requires significantly more thinking and work than simply reading. Also, we should aim to apply what we have learned. The outcomes may correspond to the expectation in the literature or create new knowledge which can then be written down and passed on to other people.</p>
<h2 id="finding-content">Finding Content</h2>
<p>Finding good content to read can initially be challenging. My strategy is to discover people through media, such as podcasts, presentations, conference recordings, and talks. Usually, engaging people who have exciting work or stories stand out. This strategy also helps to create a connection to these people, validate their legitimacy, and understand their values. The approach also acts as a filter because the guests have to be approved by the host, increasing the likelihood that their content is something that you would too value. Once you start reading the content of these authors, their sources, and the works that have influenced them might also begin to interest you.</p>
<h2 id="components-of-written-works">Components of Written Works</h2>
<p>Reading and managing (electronic) written works require understanding their components, the <strong>content</strong>, and the <strong>metadata</strong>. The next sections will explain the meaning and further break down of these components.</p>
<h3 id="content">Content</h3>
<p>Content refers to the informational part of the writing. The internal structure is different for different types of content. Here are some important structural elements and explanation about why they are relevant:</p>
<ul>
<li><p><strong>Body</strong> refers to the main part of the writing, the part that contains the actual content. The body is grouped into sections and subsections by common themes or topics. Sections consist mainly of text, images, and citations but may contain special elements, such as formulas, equations, or source code, depending on the context.</p></li>
<li><p><strong>Contents</strong>, or <strong>Table of Contents</strong>, is a list of section titles with their page numbers. Contents aids in navigating the work. It informs about the general structure and grouping of the topics. It is beneficial to read through the contents before reading the body.</p></li>
<li><p><strong>Glossary</strong> is an alphabetical listing of words. In the context of a written work, a glossary contains explanations of terms specific to the subject of the work. Going through the glossary may help to understand the content.</p></li>
<li><p><strong>About the authors</strong> is a section that contains information about the authors. This section helps to understand the authors’ motivations for writing the work. You should also search the internet for the authors’ or the book’s name, and look for presentations or podcasts they have given relating to their work.</p></li>
<li><p><strong>Acknowledgements</strong> contains the author’s expressions of gratitude to others. These may be people or entities who helped or inspired the creation of the work. Learning about these people help you to grow the network of people researching and writing about interesting topics.</p></li>
<li><p><strong>Bibliography</strong>, or <strong>references</strong>, is a list of citations to the published and unpublished sources. References are essential to all academic and technical writing. They offer a way to fact check statements and to find related literature.</p></li>
</ul>
<h3 id="metadata">Metadata</h3>
<p>Metadata provides information about the writing, which makes it important for content management. Electronic literature comes in a file, which usually contains the metadata related to the writing. Metadata includes:</p>
<ul>
<li><p><strong>Title</strong> is the name of the writing. It is the most important piece of information for its identification. Usually, titles are unique, but not always.</p></li>
<li><p><strong>Authors</strong> field lists the names of the people who created the writing. Books often have only one author, but scholarly papers may have many authors.</p></li>
<li><p><strong>File format</strong> defines the structure and type of data stored in a file. The most common file formats for electronic literature are EPUB, PDF, and HTML. We explain the different file formats in the technology section.</p></li>
<li><p><strong>Cover art</strong> is an image on the outside of the work which serves as promotional and aesthetic functions. In literature, usually, books and comics have cover art. Along with the title, the cover is a crucial piece of identifying information for managing a library of books.</p></li>
<li><p><strong>Rating</strong> is a numeric score, usually from one to five stars, given by the users to access the work.</p></li>
<li><p><strong>Tags</strong> are individual pieces of information, like keywords, that describe the contents of the work. They are relevant for managing electronic libraries.</p></li>
<li><p><strong>Ids</strong> are the identifiers of the work. There exists various different identifiers such as <a href="http://www.issn.org/understanding-the-issn/what-is-an-issn/">ISSN</a>, <a href="https://www.isbn-international.org/content/what-isbn">ISBN</a>, <a href="https://www.doi.org">DOI</a> and site-specific identifiers such <a href="https://arxiv.org/">ArXiv ID</a> or <a href="https://www.ncbi.nlm.nih.gov/pubmed/">PMID</a>.</p></li>
<li><p><strong>Published</strong> is the date when the work was published.</p></li>
<li><p><strong>Publisher</strong> is the name of the entity that published the work.</p></li>
<li><p><strong>Languages</strong> is the language of the work.</p></li>
<li><p><strong>Summary</strong> or <strong>abstract</strong> contains a condensed presentation of the contents.</p></li>
</ul>
<h2 id="the-reading-process">The Reading Process</h2>
<p>After finding interesting books, articles, papers, or reading the material, the next challenge will be the reading itself. Both the motivation to read and understand the content play essential roles in the reading process.</p>
<h3 id="motivation">Motivation</h3>
<p>Motivation translates into the time and effort that we are willing to put into reading. Here are some of the ways I keep myself motivated to read more.</p>
<ol type="1">
<li><p><strong>Physical Place</strong> – For reading, find a place without distractions. The library, cafe, or beach in the summer are some excellent options. Prefer areas with natural light and avoid places with artificial lights, they cause unnecessary visual stress. In noisy situations, use earplugs or noise-canceling headphones.</p></li>
<li><p><strong>Reading Quota</strong> – Having a quota of reading a certain number of pages per day can help to break down the reading goals. For instance, reading fifty pages per day would yield around one book a week.</p></li>
<li><p><strong>Create Habits</strong> – Making reading a daily habit by going to your preferred place, having coffee, tea, or other beverage or stimulant and sitting down to read your daily reading quota. If you are reading at the beach, you can go swimming every time you finish a certain number of pages. Be creative at creating the reading habits so that they will stick.</p></li>
<li><p><strong>Progress List</strong> – Keeping a progress list of what you have read helps to track progress and to share it with others. Visualizing progress can motivate the reading process, especially if you share the list with others increasing your sense of accountability.</p></li>
</ol>
<h3 id="understanding-content">Understanding Content</h3>
<p>To ensure that we don’t waste time and effort when reading, you should aim to understand the concent. The true efficiency of reading is determined, not just by how much you read, but by how much you understand and learn. The difficulty of fully understanding a written work depends on its content. Books, with only text and simple images written for the public, are often easier to read than a research paper dedicated to a specific area of research containing specialized content such as formulas and equations, charts, or source code. Below I note some of the different steps of understanding the content, unlocking its knowledge, and getting more value out of reading.</p>
<p>While reading, you can:</p>
<ol type="1">
<li><p><strong>Highlight Text and Take Notes</strong> – Making reading a more conscious process by highlighting and taking notes can help to retain the read information. We can use the highlights and notes later to review the work.</p></li>
<li><p><strong>Read Out Loud</strong> – Certain types of literature, such as stories and poetry, can be read out loud, which is a way to practice speaking and pronunciation of words.</p></li>
<li><p><strong>Breaks</strong> – Take active breaks. Go for a walk, swimming, or do some other low-level physical activity, preferably outside in nature. Breaks help de-stressing and let the unconscious parts of the brain to do their work.</p></li>
</ol>
<p>The review process consists of:</p>
<ol type="1">
<li><p><strong>Review the Highlights and Notes</strong> – Read the highlights and notes either directly from your device or export them. From the highlights, it’s worth writing down word for word definitions and challenging paragraphs to understand them thoroughly. For more extended highlights, compress them into your own words. This method can help you retain and understand the information and make it easier to access the book’s knowledge at a later time. Writing things down can be very tedious; therefore, focus only on key concepts and information.</p></li>
<li><p><strong>Re-read</strong> – Reading the whole work or parts of it multiple times will improve your understanding of the content. Reading the entire work may be impractical for long books, but we can easily read shorter texts like articles multiple times.</p></li>
<li><p><strong>Use the Knowledge</strong> – Use the work’s knowledge in your writings. Teach it to other people. Make connections between this work and other works, resources, and your own experiences, which is one of the core reasons for reading in the first place.</p></li>
</ol>
<h2 id="technology">Technology</h2>
<h3 id="common-file-formats">Common File Formats</h3>
<p><img src="../images/reading-file-formats.png" /></p>
<p>In regards to the technology of electronic literature, we need to understand the most common file formats for electronic, written content. The differences between the file formats impact the choices of technologies and the process that needs to use. The most common file formats, <strong>EPUB</strong>, <strong>PDF</strong> and <strong>HTML</strong> are explained below.</p>
<ul>
<li><p><a href="https://en.wikipedia.org/wiki/EPUB"><strong>Electronic Publication</strong> (EPUB)</a> is a file format designed for electronic publications and the preferred file format for e-books. EPUB uses the extension <code>.epub</code>. Documents in EPUB format are <em>reflowable</em>, which means that users can adjust the document layout. For example, re-sizable fonts, changeable text, and adjustable margins allow optimizing the text for a particular display, which makes reading easier. Page bookmarking and passage-highlighting and notes are also supported, and they are essential for the reading process. EPUB format also can store metadata, which enables electronic libraries that can store books. These libraries are useful for managing electronic publications.</p></li>
<li><p><a href="https://en.wikipedia.org/wiki/PDF"><strong>Portable Document Format</strong> (PDF)</a> is a file format with the extension <code>.pdf</code>. PDFs can represent documents in fixed-layout independent of the platform. Fixed-layout means that each file encapsulates the complete description of the document, including the text, fonts, graphics, and other information. For this reason, the displayed layout of the document cannot be (easily) adjusted by the user compared to EPUBs. PDFs are a popular format for academic publishing, which often requires special formatting, such as equations.</p></li>
<li><p><a href="https://en.wikipedia.org/wiki/HTML"><strong>Hypertext Markup Language</strong> (HTML)</a> with <a href="https://en.wikipedia.org/wiki/Cascading_Style_Sheets"><strong>Cascading Style Sheets</strong> (CSS)</a> are the languages responsible for the text, links and presentation of a web page. JavaScript (JS) provides web content its interactivity, but we will ignore and focus static (non-interactive) content. The files are usually served by the server and displayed by the browser without the user having to interact with the actual raw files.</p></li>
</ul>
<h3 id="common-content-types">Common Content Types</h3>
<p><img src="../images/reading-content-types.png" /></p>
<p>Different electronic content types use different file formats. The format affects the process of managing and reading a particular type of content. Common content types including <strong>electronic books</strong>, <strong>academic publications</strong>, <strong>online articles</strong> and <strong>software documentation</strong> are explained below.</p>
<ul>
<li><p><a href="https://en.wikipedia.org/wiki/E-book"><strong>Electronic books</strong> (e-books)</a> are usually distributed in EPUB format. However, books that require specialized formatting, such as equations, are often distributed in PDF format. Compared to traditional books, e-books are portable, easy to reference, and highlight, allow searching them using keywords and are easier to organize and manage. Dedicated e-readers make reading e-books more convenient and easier than traditional books.</p></li>
<li><p><strong>Academic publications</strong> such as scholarly papers, are usually distributed in PDF format due to special formatting requirements.</p></li>
<li><p><strong>Online articles</strong> are found in blogs, online newspapers and magazines, Wikipedia, and other online publications, are served through websites in HTML format. Since online articles come from various sites with different layouts, popups, advertisements, and other distractions, I suggest using an aggregator to aggregate the content and display it in a simplified format. Aggregation makes reading online articles easier, reducing potential distractions, allowing pagination, and increasing efficiency.</p></li>
<li><p><a href="https://en.wikipedia.org/wiki/Software_documentation"><strong>Software documentation</strong></a> is a class of documents that describe how a particular software operates and the roles of the people involved in its development. Documentation types include requirements, architecture/design, technical, end-user, and marketing documents. Software documentation is part of the software engineering discipline. The documents themselves are usually in HTML and PDF format, and sometimes also in EPUB format.</p></li>
</ul>
<h3 id="devices-and-hardware">Devices and Hardware</h3>
<p><img src="../images/reading-hardware.png" /></p>
<p>The best hardware choice depends on the activity in the reading process and the content type. The choice for reading a book with lots of text and few pictures is different from reading web articles with interactive content. Similarly, the choice for managing content is different from reading it. The hardware choices considered in this article are <strong>desktops</strong>, <strong>laptops</strong>, <strong>tablets</strong>, <strong>smartphones</strong> and <strong>e-readers</strong>. Users should decide the best choice from the properties of the given hardware. Here is a list of the fundamental properties and how they affect reading and managing electronic content:</p>
<ul>
<li><p><strong>Dimensions</strong> – The physical size and weight determine the portability of the device. Smaller, thinner, and lighter devices are easier to carry than larger, heavier devices. Smaller ones, like smartphones, fit into a pocket, but larger ones, like tablets, e-readers, and laptops, require to be carried in hand, backpack, or briefcase. Desktops aren’t portable.</p></li>
<li><p><strong>Screen Type</strong> – There are many types of screens; computer, tablet, and smartphone screens use LCD, OLED, and AMOLED. E-readers have their kind of screen, the <a href="https://en.wikipedia.org/wiki/E_Ink">E-ink</a> screen. E-ink screens have a more paper-like look. They are eye-friendly and facilitate longer battery life compared to other devices (days vs. hours). However, the tradeoff is a slower refresh rate, which makes E-ink screen more tedious for interactive tasks, such as highlighting or taking notes, than other screen types.</p></li>
<li><p><strong>Screen Size</strong> – The screen size affects the difficulty of reading from the device and how much information the screen displays. The optimal screen size for reading is the one that displays just enough information and is easy to read from – displaying excessive information or other information that the actual content can be distractive and drain mental energy. Usually, screen sizes from smallest to largest are a smartphone, e-reader, tablet, laptop, and desktop.</p></li>
<li><p><strong>Features</strong> – Available features and software depend on the device and its operating system, and have a direct effect on usability. Different devices require different software for reading and managing the various types of content. We should consider the differences between the devices when choosing them. For example, interacting with a device requires either the input or output of information. Usually, more powerful devices, like computers, are faster at handling inputs, which makes them more suited for input dependent tasks such as managing content. On the other hand output dependent tasks, such as reading, if done for an extended period benefit from using less powerful, more domain-specific devices, like e-readers, because the reduced input speed makes them less distracting.</p></li>
<li><p><strong>Price</strong> – The price is determining factor when choosing hardware. Consider investing in the most useful and versatile hardware first, for example, a (hybrid) laptop.</p></li>
</ul>
<p>To choose the right hardware, find reviews comparing different hardware and their properties. Video reviews or websites that compare different hardware are an excellent place to start.</p>
Scientific Writing with Markdown2018-01-25T00:00:00+02:002018-01-25T00:00:00+02:00Jaan Tollander de Balschtag:jaantollander.github.io,2018-01-25:/scientific-writing-with-markdown.html
<p><img src="../images/writing-markdown-image.png" /></p>
<blockquote>
</blockquote>
<p>This blog post covers how to use Markdown for scientific and technical writing, which often involves writing equations, code blocks, citations, and other unique features depending on the document in question. We have included software recommendations for writing and converting Markdown it into other formats such as HTML (blog posts, slides, documentation), PDF (essays, reports) or EPUB (books). For example, I wrote this blog post using Markdown.</p>
<p><img src="../images/writing-markdown-image.png" /></p>
<blockquote>
</blockquote>
<p>This blog post covers how to use Markdown for scientific and technical writing, which often involves writing equations, code blocks, citations, and other unique features depending on the document in question. We have included software recommendations for writing and converting Markdown it into other formats such as HTML (blog posts, slides, documentation), PDF (essays, reports) or EPUB (books). For example, I wrote this blog post using Markdown.</p>
<p><strong>Contents</strong></p>
<!-- TOC -->
<ul>
<li><a href="#what-is-markdown-and-when-to-use-it">What is Markdown and When to use it</a></li>
<li><a href="#creating-documents">Creating Documents</a></li>
<li><a href="#software-for-markdown">Software for Markdown</a></li>
<li><a href="#markdown-syntax">Markdown Syntax</a>
<ul>
<li><a href="#basics">Basics</a></li>
<li><a href="#syntax-highlighting">Syntax Highlighting</a></li>
<li><a href="#equations">Equations</a></li>
<li><a href="#citations">Citations</a></li>
</ul></li>
</ul>
<!-- /TOC -->
<p><strong>Keywords</strong>: Markdown, Pandoc, LaTeX</p>
<h2 id="what-is-markdown-and-when-to-use-it">What is Markdown and When to use it</h2>
<p><a href="https://daringfireball.net/projects/markdown/">Markdown</a> is a lightweight markup language with plain text formatting syntax, created for creating web content such as emails and blog posts (HTML), but can be converted into other formats such as PDF via tools like Pandoc. I use Markdown due to its popularity, simple syntax, and availability of tools that can convert Markdown into other formats.</p>
<p>Unlike word or google docs, Markdown is written in a plain text document and then converted into the final format. Markdown is not the best choice for documents that require lots of small customizations in styles, fonts, or outlook. For example, it is easier to writen a resume using Google docs because the customizations with colors, indentations, and fonts would be a real hassle using Markdown. On the other hand, Markdown excels at creating documents that need little customization or have premade styles available such as reports. Markdown is also among the easiest ways to create web content.</p>
<h2 id="creating-documents">Creating Documents</h2>
<div style="position:relative;height:0;padding-bottom:56.25%">
<iframe src="https://www.youtube.com/embed/bUhuwmyvbqg?ecver=2" style="position:absolute;width:100%;height:100%;left:0" width="640" height="360" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen>
</iframe>
</div>
<blockquote>
</blockquote>
<p>We can use Markdown for writing many different types of documents. The most common use case is to write web content such as blog posts, but writing essays, research papers, books, documentation, slides, among many other types are possible. I made GitHub repository <a href="https://github.com/jaantollander/Markdown-Templates"><strong>Markdown Templates</strong></a> that contains example documents. The examples are structured as follows:</p>
<ul>
<li><code><filename>.md</code> is the source file written in Markdown.</li>
<li><code><filename>.bib</code> is the <em>optional</em> file for bibliography entries.</li>
<li><code>Makefile</code> contains the commands to compile the Markdown documents into the desired format.</li>
</ul>
<p>The following sections cover the required software and the basics of Markdown syntax.</p>
<h2 id="software-for-markdown">Software for Markdown</h2>
<p>To get started writing Markdown on <strong>desktop</strong>, we need to download software for writing and converting Markdown into documents.</p>
<ol type="1">
<li><a href="https://pandoc.org/installing.html"><strong>Install Pandoc</strong></a>. <a href="https://pandoc.org/">Pandoc</a> is the primary tool that we are going to use for converting markup formats into other formats.</li>
<li><a href="https://www.latex-project.org/get/"><strong>Install LaTeX</strong></a>. <a href="https://www.latex-project.org/">LaTeX</a> is a typesetting system designed for the production of technical and scientific documentation. We require LaTeX installation for creating PDF documents.</li>
<li><a href="https://atom.io/"><strong>Install Atom</strong></a>. <a href="https://atom.io/">Atom</a> is a modern, cross-platform code editor built using web technologies. The use of web-technologies allows Atom to be extensible, customizable, and it enables other useful features. This guide heavily relies on the packages that are available to the Atom editor. Install following packages for writing Markdown by navigating to <code>Edit > Preferences > Packages</code>
<ul>
<li><code>language-markdown</code> for better Markdown syntax support compared to the default package <code>language-gfm</code> (GitHub-flavored Markdown).</li>
<li><code>markdown-preview-plus</code> package allow Markdown preview using Pandoc, which support equations and citations. You need to disable <code>markdown-preview</code> for this package to work correctly.</li>
<li><code>platformio-ide-terminal</code> for a terminal inside Atom. We use the terminal for invoking the command for converting Markdown files using Pandoc.</li>
<li><code>pdf-view</code> can be used for viewing PDF documents converting Markdown to pdf.</li>
</ul></li>
</ol>
<p>For writing Markdown <strong>online</strong>, for example, edit Markdown file inside Google Drive can try <a href="https://stackedit.io/">StackEdit</a>, or for emails, there is browser plugin called <a href="https://markdown-here.com/">Markdown Here</a>.</p>
<h2 id="markdown-syntax">Markdown Syntax</h2>
<p>This section covers the basic syntax of Markdown and specific features for scientific writing such as syntax highlighting, equations, and citations.</p>
<h3 id="basics">Basics</h3>
<p>Demonstrations about the basic Markdown syntax can be found from <a href="https://daringfireball.net/projects/markdown/syntax">John Gruber’s original spec</a> or <a href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet">Markdown Cheatsheet</a> in GitHub. I recommend reading at least Markdown-Cheatsheet to understand the basics. In addition to Markdown understanding, basics on HTML can be useful for creating web content if using inline HTML.</p>
<h3 id="syntax-highlighting">Syntax Highlighting</h3>
<p>Regular Markdown syntax supports code blocks but not syntax highlighting. Support for syntax highlighting can be achieved through the use of converters such as Pandoc that supports it as well as sites such as GitHub supports it by default.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1"></a><span class="kw">def</span> foo():</span>
<span id="cb1-2"><a href="#cb1-2"></a> <span class="cf">return</span> <span class="st">"bar"</span></span></code></pre></div>
<h3 id="equations">Equations</h3>
<p>Equations can be written either using <code>\[ ... \]</code> or inline using <code>\( ... \)</code>. For example, Cauchy’s integral formula can be written as</p>
<p><code>\[ f(a)={\frac {1}{2\pi i}}\oint _{\gamma }{\frac {f(z)}{z-a}}\,dz \]</code></p>
<p>which in HTML will be displayed by <a href="https://www.mathjax.org/">Mathjax</a> as</p>
<p><span class="math display">\[ f(a)={\frac {1}{2\pi i}}\oint _{\gamma }{\frac {f(z)}{z-a}}\,dz \]</span></p>
<p>Inline equations such as <span class="math inline">\(a^2 + b^2 = c^2\)</span> which in Markdown translates to <code>\(a^2 + b^2 = c^2\)</code> will display on the same line as the text. In order for this to work in HTML, we need to use Pandoc option <code>--mathjax</code>.</p>
<p>Another feature that can make writing complicated equations easier is using <a href="https://unicode-table.com/en/">unicode characters</a> for mathematical symbols. For instance <code>\[ 𝐱 ∈ ℝ^2 \]</code> can be rendered by Mathjax</p>
<p><span class="math display">\[ 𝐱 ∈ ℝ^2 \]</span></p>
<p>In order to easily input these mathematical symbols install Atom package <code>latex-completions</code>. A mapping between corresponding Unicode characters and latex commands can be found at <a href="http://milde.users.sourceforge.net/LUCR/Math/data/unimathsymbols.txt">unimathsymbols.txt</a>.</p>
<h3 id="citations">Citations</h3>
<p>Citations can be used inside Markdown by using <a href="https://hackage.haskell.org/package/pandoc-citeproc">pandoc-citeproc</a> library, which included in the Pandoc installation. To use pandoc-citeproc Pandoc needs to be invoked using options.</p>
<ol type="1">
<li><code>--filter pandoc-citeproc</code> and</li>
<li><code>--bibliography=FILE</code> to include the given bibliography file.</li>
</ol>
<p>Bibliography entries are stored in a bibliography file <code><filename>.bib</code> using <code>biblatex</code> syntax. For example, articles are stored using <code>@article</code></p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bibtex"><code class="sourceCode bibtex"><span id="cb2-1"><a href="#cb2-1"></a><span class="va">@article</span>{<span class="ot">key_article</span>,</span>
<span id="cb2-2"><a href="#cb2-2"></a> <span class="dt">author</span> = {Peter Adams},</span>
<span id="cb2-3"><a href="#cb2-3"></a> <span class="dt">title</span> = {The title of the work},</span>
<span id="cb2-4"><a href="#cb2-4"></a> <span class="dt">journal</span> = {The name of the journal},</span>
<span id="cb2-5"><a href="#cb2-5"></a> <span class="dt">year</span> = {1993},</span>
<span id="cb2-6"><a href="#cb2-6"></a> <span class="dt">number</span> = {2},</span>
<span id="cb2-7"><a href="#cb2-7"></a> <span class="dt">pages</span> = {201-213},</span>
<span id="cb2-8"><a href="#cb2-8"></a> <span class="dt">month</span> = {7},</span>
<span id="cb2-9"><a href="#cb2-9"></a> <span class="dt">note</span> = {An optional note},</span>
<span id="cb2-10"><a href="#cb2-10"></a> <span class="dt">volume</span> = {4}</span>
<span id="cb2-11"><a href="#cb2-11"></a>}</span></code></pre></div>
<p>Online resources such as websites are stored using <code>@online</code></p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bibtex"><code class="sourceCode bibtex"><span id="cb3-1"><a href="#cb3-1"></a><span class="va">@online</span>{<span class="ot">key_online</span>,</span>
<span id="cb3-2"><a href="#cb3-2"></a> <span class="dt">title</span> = {Generating Bibliographies with biblatex and biber},</span>
<span id="cb3-3"><a href="#cb3-3"></a> <span class="dt">organization</span> = {Wikibooks},</span>
<span id="cb3-4"><a href="#cb3-4"></a> <span class="dt">date</span> = {2016},</span>
<span id="cb3-5"><a href="#cb3-5"></a> <span class="dt">urldate</span> = {2016-03-07},</span>
<span id="cb3-6"><a href="#cb3-6"></a> <span class="dt">url</span> = {https://en.wikibooks.org/wiki/LaTeX/Generating_Bibliographies_with_biblatex_and_biber},</span>
<span id="cb3-7"><a href="#cb3-7"></a> <span class="dt">keywords</span> = {untrusted},</span>
<span id="cb3-8"><a href="#cb3-8"></a>}</span></code></pre></div>
<p>These entries can be referred to using <code>@key_name</code>. The full Biblatex reference documentation can be found from <a href="http://tug.ctan.org/macros/latex/exptl/biblatex/doc/biblatex.pdf">biblatex.pdf</a>.</p>
<p>Optionally citation styles can be changed using the option <code>--cls=FILE</code>. Citation files use <a href="http://citationstyles.org/">Citation Style Language (CSL)</a>. Different citation styles and examples of them can be found from <a href="https://www.zotero.org/styles">Zotero Styles</a>. In order to use these styles, you can either download them or refer directly to the raw CLS file in <a href="https://github.com/citation-style-language/styles">Citation Styles (GitHub)</a>.</p>
Customizing Unity for Productivity2018-01-03T11:47:00+02:002018-01-03T11:47:00+02:00Jaan Tollander de Balschtag:jaantollander.github.io,2018-01-03:/customizing-unity-for-productivity.html
<p><img src="../images/ubuntu-desktop-2.png" /></p>
<blockquote>
</blockquote>
<p>This blog post covers customizations that I have found useful for the overall feel and usage of the Unity desktop environment, the default on Ubuntu 16.04. We explain how to set up useful features such as workspaces, hiding the launcher, changing to a custom theme as well as modifying the date and time format of the clock and changing default user folder paths.</p>
<p><img src="../images/ubuntu-desktop-2.png" /></p>
<blockquote>
</blockquote>
<p>This blog post covers customizations that I have found useful for the overall feel and usage of the Unity desktop environment, the default on Ubuntu 16.04. We explain how to set up useful features such as workspaces, hiding the launcher, changing to a custom theme as well as modifying the date and time format of the clock and changing default user folder paths.</p>
<p><strong>Contents</strong></p>
<!-- TOC -->
<ul>
<li><a href="#unity-tweak-tool">Unity Tweak Tool</a></li>
<li><a href="#launcher-and-dash">Launcher and Dash</a></li>
<li><a href="#workspaces">Workspaces</a></li>
<li><a href="#theme">Theme</a></li>
<li><a href="#wallpaper">Wallpaper</a></li>
<li><a href="#date-and-time-format">Date and Time Format</a></li>
<li><a href="#default-user-folders">Default User Folders</a></li>
</ul>
<!-- /TOC -->
<p><strong>Keywords</strong>: Ubuntu, Unity</p>
<h2 id="unity-tweak-tool">Unity Tweak Tool</h2>
<p><img src="../images/unity-tweak-tool.png" /></p>
<p>To start, we need to install <strong>Unity Tweak Tool</strong>, a settings manager for the Unity desktop.</p>
<pre><code>sudo apt-get install unity-tweak-tool</code></pre>
<p>We require the Unity Tweak Tool for changing settings that we can’t set using the default Ubuntu settings menu and would otherwise require the use of the command line.</p>
<h2 id="launcher-and-dash">Launcher and Dash</h2>
<div style="position:relative;height:0;padding-bottom:56.21%">
<iframe src="https://www.youtube.com/embed/BCjEZ7HtSQI?ecver=2" style="position:absolute;width:100%;height:100%;left:0" width="641" height="360" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen>
</iframe>
</div>
<blockquote>
</blockquote>
<p>Unity launcher is the sidebar on the left side of the desktop. I recommend hiding the launcher to increase the usable screen size and reduce distraction. <strong>Auto-hide the launcher</strong> by navigating to <code>Unity Tweak Tool > Launcher</code> and toggling on <code>Auto-hide</code>.</p>
<p>Instead of having to click icons on the launcher, you should press the <em>super key</em> (windows key in most keyboards) to open the Dash and type the name of the program, select it, and press Enter. This method is faster and saves cognitive energy.</p>
<h2 id="workspaces">Workspaces</h2>
<div style="position:relative;height:0;padding-bottom:56.21%">
<iframe src="https://www.youtube.com/embed/R_fObp2J8s4?ecver=2" style="position:absolute;width:100%;height:100%;left:0" width="641" height="360" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen>
</iframe>
</div>
<blockquote>
</blockquote>
<p>Workspaces are virtual desktops that can reduce clutter and make the desktop more comfortable to navigate. <strong>Workspaces can be enabled</strong> by navigating to <code>Unity Tweak Tool > Workspace Settings</code> and toggling on the <code>workspace switcher</code>. You can adjust the number of horizontal and vertical workspaces available to suit your needs.</p>
<h2 id="theme">Theme</h2>
<div style="position:relative;height:0;padding-bottom:56.21%">
<iframe src="https://www.youtube.com/embed/D26R-o8c464?ecver=2" style="position:absolute;width:100%;height:100%;left:0" width="641" height="360" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen>
</iframe>
</div>
<blockquote>
</blockquote>
<p>Unity allows the use of custom themes. You should set up a theme that you find pleasant to look at when working on the computer.</p>
<p>I prefer darker themes over lighter themes. Darker themes reduce visual stress when working on the computer and look better than lighter ones. Following a suggestion in ask Ubuntu article <a href="https://askubuntu.com/questions/800730/dark-gtk-theme-for-ubuntu-16-04-unity"><em>Dark GTK theme for Ubuntu 16.04</em></a>, I switched to a theme called Arc-theme. Install this theme using commands:</p>
<pre><code>sudo add-apt-repository ppa:noobslab/themes
sudo apt-get update
sudo apt-get install arc-theme</code></pre>
<p>We can change the new theme by navigating to <code>Unity Tweak Tool > Theme</code> and selecting <code>Arc-dark</code>.</p>
<h2 id="wallpaper">Wallpaper</h2>
<figure>
<img src="../images/ubuntu_os_logo_black_yellow_28786_1680x1050.jpg" alt="" /><figcaption><a href="https://wallpaperscraft.com/download/ubuntu_os_logo_black_yellow_28786/1680x1050"><em>My wallpaper</em></a></figcaption>
</figure>
<blockquote>
</blockquote>
<p>I use minimalistic dark wallpaper to match the Arc-dark theme. Right wallpaper makes your desktop look cool, and dark wallpapers reduce the amount of light emitted by the empty screen. The easiest way to set up a new wallpaper is to right-click it to select <code>Set as Wallpaper</code>. Ubuntu saves Wallpapers to a directory at <code>Pictures/Wallpapers</code>.</p>
<h2 id="date-and-time-format">Date and Time Format</h2>
<figure>
<img src="../images/dconf-editor-datetime.png" alt="" /><figcaption><em>dconf Editor</em></figcaption>
</figure>
<blockquote>
</blockquote>
<p>The date and time format of the clock in the Ubuntu panel can be set to have a custom format. I use the form of <code>YYYY-MM-DD H:M</code>. To configure the time format, you need first to install the dconf Editor.</p>
<pre><code>sudo apt-get dconf-editor</code></pre>
<p>After installation navigate to <code>dconf Editor > com > canonical > indicator > datetime</code>. In this menu toggle <code>time-format</code> to <code>custom</code> and set the value inside <code>custom-time-format</code> to the format you want.</p>
<p>We have based these instructions on the article <a href="http://ubuntuhandbook.org/index.php/2015/12/time-date-format-ubuntu-panel/"><em>How to Customize Time & Date Format in Ubuntu Panel</em></a>.</p>
<h2 id="default-user-folders">Default User Folders</h2>
<figure>
<img src="../images/default-user-folders-2.png" alt="" /><figcaption><em>Custom location for default user folders</em></figcaption>
</figure>
<blockquote>
</blockquote>
<p>Anyone with a computer setup with a separate SSD disk and mass storage might want to change the paths of their default user folders such as <code>Documents/</code>, <code>Downloads/</code>, <code>Music/</code>, <code>Pictures</code> and <code>Videos</code> to the mass storage location to save space on the SSD. We can change these paths by modifying the configuration file located at <code>~/.config/user-dirs.dirs</code>.</p>
<blockquote>
</blockquote>
<figure>
<img src="../images/user-dirs-gedit.png" alt="" /><figcaption><em>Modified paths for default user folders</em></figcaption>
</figure>
<blockquote>
</blockquote>
<p>Open the file using a text editor of your choice, for example, Gedit.</p>
<pre><code>gedit ~/.config/user-dirs.dirs</code></pre>
<p>Then replace the default path with the path of your custom location. Initially, I found these instructions from the article <a href="https://askubuntu.com/questions/67044/change-default-user-folders-path"><em>Change default user folders path</em></a>.</p>
Mathematical Programming Workflow with Julia and Atom2017-10-25T08:15:00+03:002017-10-25T08:15:00+03:00Jaan Tollander de Balschtag:jaantollander.github.io,2017-10-25:/mathematical-programming-workflow-with-atom-and-julia.html
<p><img src="../images/atom-euler.png" /></p>
<blockquote>
</blockquote>
<p>One of the challenges at university, studying applied mathematics, has been finding tools for efficiently solving mathematical and algorithmic problems, and documenting them using a computer. This post covers how to improve your workflow for this kind of problem using the capabilities of modern code editors and programming languages. It increases your productivity and makes problem-solving more fun and documenting easier.</p>
<p><img src="../images/atom-euler.png" /></p>
<blockquote>
</blockquote>
<p>One of the challenges at university, studying applied mathematics, has been finding tools for efficiently solving mathematical and algorithmic problems, and documenting them using a computer. This post covers how to improve your workflow for this kind of problem using the capabilities of modern code editors and programming languages. It increases your productivity and makes problem-solving more fun and documenting easier.</p>
<h2 id="required-software">Required Software</h2>
<p>The list of software and tools we are going to be using</p>
<ul>
<li><a href="https://atom.io/">Atom</a> is modern, cross-platform code editor built using web technologies. The use of web-technologies allows Atom to be extensible, customizable, and it enables lots of useful features to work.</li>
<li><a href="https://julialang.org/">Julia</a> is high-level, a high-performance dynamic programming language for numerical computing.</li>
<li><a href="https://pandoc.org/">Pandoc</a> is a tool for converting markup formats into another.</li>
<li><a href="https://daringfireball.net/projects/markdown/">Markdown</a> is a lightweight markup language with plain text formatting syntax. Markdown is commonly used to write web content such as blog posts or documentation. Markdown files can be converted into HTML for web documentation or PDFs via Pandoc.</li>
<li><a href="https://www.latex-project.org/">LaTeX</a> is a high-quality typesetting system designed for the production of technical and scientific documentation. We require LaTeX for creating PDFs from Markdown using Pandoc, which is useful for creating handouts from assignments.</li>
</ul>
<p>Installation instructions</p>
<ul>
<li><a href="https://atom.io/">Install Atom</a></li>
<li><a href="https://julialang.org/downloads/">Download Julia</a></li>
<li><a href="https://pandoc.org/installing.html">Install Pandoc</a></li>
<li><a href="https://www.latex-project.org/get/">Download LaTeX</a></li>
</ul>
<p>Add Julia, Pandoc, and LaTeX to the path if they were not added to the path during installation.</p>
<h2 id="atom-packages">Atom Packages</h2>
<figure>
<img src="../images/atom-packages.png" alt="" /><figcaption><em>Atom preferences</em></figcaption>
</figure>
<blockquote>
</blockquote>
<p>Packages are what give Atom its powers. Packages can be added from <code>Edit > Preferences > Packages</code>. Here is a shortlist of the packages that are needed:</p>
<ul>
<li><code>language-julia</code></li>
<li><code>uber-juno</code></li>
<li><code>latex-completions</code> (This does not work with markdown files when language-markdown is enabled. I don’t yet know how to fix it. Works fine otherwise.)</li>
<li><code>hasklig</code> (optional but improves the readability of Julia code since Julia uses a similar syntax as Haskell for some operations)</li>
<li><code>language-markdown</code></li>
<li><code>markdown-preview-plus</code> uses Pandoc to preview markdown files. It enables support for equations through <code>mathjax</code> and support for citations through <code>pandoc-citeproc</code>.</li>
</ul>
<p>Some configurations you should configure in the plugins.</p>
<ul>
<li>Enable <code>mathjax</code> for <code>markdown-preview-plus</code> plugin</li>
</ul>
<h2 id="practicing-skills">Practicing Skills</h2>
<figure>
<img src="../images/project-Euler-p001-example.png" alt="" /><figcaption><em>Project Euler workflow using Julia and Atom. This image shows how to solve problem 1 using naive and efficient algorithm.</em></figcaption>
</figure>
<blockquote>
</blockquote>
<figure>
<img src="../images/project-Euler-example-markdown.png" alt="" /><figcaption><em>Example of using Markdown with markdown-preview plugin</em></figcaption>
</figure>
<blockquote>
</blockquote>
<p>One of my favorite ways to practice algorithmic problem solving is <a href="https://projecteuler.net/">Project Euler</a>. Project Euler contains various problems that require both programming and mathematical skills to obtain a solution, especially for harder problems.</p>
<ol type="1">
<li><code><problem>.jl</code>: Write the algorithm into the Julia file. A common pattern to write the
<ul>
<li>Write the actual algorithm. Julia has a lot of useful properties for mathematical programming, which can be found by reading <a href="https://docs.julialang.org/en/stable/">documentation</a>. <!-- - Use `assert(...)` to test that your algorithm works, for example, values that were given in the problem description. --></li>
<li>Use <code>@time</code> macro to receive running time and allocated memory. Be sure to do this after compiling the function once to obtain a good measurement.</li>
</ul></li>
<li><code><problem>.md</code>: Write the relevant mathematics into the markdown file. Use markdown preview to preview the HTML version. This step is optional but useful for complicated problems.</li>
</ol>
Ergonomic Workstation2017-10-01T11:52:00+03:002017-10-01T11:52:00+03:00Jaan Tollander de Balschtag:jaantollander.github.io,2017-10-01:/ergonomic-workstation.html
<p><img src="../images/photos/workroom.jpg" /></p>
<blockquote>
</blockquote>
<p>In this post, we explain the importance of an ergonomic workstation for people who are working long hours on a computer. We cover the components of such a workstation and why they can improve health and productivity. For example, we can avoid back, neck, and wrist problems, improve typing speed, and work longer without discomfort.</p>
<p><img src="../images/photos/workroom.jpg" /></p>
<blockquote>
</blockquote>
<p>In this post, we explain the importance of an ergonomic workstation for people who are working long hours on a computer. We cover the components of such a workstation and why they can improve health and productivity. For example, we can avoid back, neck, and wrist problems, improve typing speed, and work longer without discomfort.</p>
<p><strong>Contents</strong></p>
<!-- TOC -->
<ul>
<li><a href="#table-and-chair">Table and Chair</a></li>
<li><a href="#monitors">Monitors</a></li>
<li><a href="#keyboard">Keyboard</a></li>
<li><a href="#computer">Computer</a></li>
<li><a href="#workroom">Workroom</a></li>
</ul>
<!-- /TOC -->
<p><strong>Keywords</strong>: Ergonomic, Workstation, Furniture, Hardware</p>
<h2 id="table-and-chair">Table and Chair</h2>
<p>Negative health aspects of sitting have received more attention in recent years. It can result in problems such as lower back and neck pain and decreased blood circulation. The right choice of furniture can help you to minimize these negative aspects by improving posture when sitting. For example, Salli, a Finnish company that manufactures ergonomic furniture, produces saddle chairs, <a href="http://salli.com/en/salli-swingfit">Salli SwingFit</a>, and height-adjustable tables, <a href="http://salli.com/en/salli-office">Salli Office</a>, which improve the sitting posture. As the name suggests, the saddle chair mimics how one would sit in a saddle on horseback, which enhances the position of the lower back.</p>
<h2 id="monitors">Monitors</h2>
<figure>
<img src="../images/benq-xl2411-1.png" alt="" /><figcaption><em>BenQ ZOWIE XL2411 144Hz 24 inch e-Sports Monitor</em></figcaption>
</figure>
<blockquote>
</blockquote>
<p>The right monitor type is also essential for the ergonomic workstation. The monitor should be height-adjustable, tiltable, and rotateable. The monitor should support an adequate color spectrum for your work and have settings for eye-friendliness, such as a lower blue-light setting and refresh rate. Height-adjustability allows for a better neck position. Additionally, we can turn rotatable monitors into vertical monitors for displaying large text files. For example, my setup includes two 24" BenQ Zowie monitors, which have these properties.</p>
<h2 id="keyboard">Keyboard</h2>
<figure>
<img src="../images/kinesis-advantage-2.jpg" alt="" /><figcaption><em>Kinesis Advantage 2 keyboard</em></figcaption>
</figure>
<blockquote>
</blockquote>
<p>The keyboard is an essential part of an ergonomic workstation. The right keyboard will reduce unnecessary shoulder stress and significantly increase typing speed and convenience. An example of such a keyboard is the <a href="https://www.kinesis-ergo.com/shop/advantage2/">Kinesis Advantage 2</a> ergonomic keyboard. This keyboard separates the keys into two groups, one for the left and one for the right hand, with space in the middle. This grouping allows the hands to be in a more natural position in the keyboard, which reduces unnecessary stress from the shoulders. The keyboard has a 3-dimensional layout, which makes the key more reachable, thus more comfortable and fasters to type using all ten fingers. The keys use the <em>Cherry MX brown</em> switches, which require just the right amount of force for pleasant, fast typing.</p>
<p>To practice touch typing with an ergonomic keyboard, we will need a typing tutor software. For example, I used <a href="https://www.gnu.org/software/gtypist/index.html">GNU typist</a> to learn to type with the Kinesis Advantage keyboard. It took me around four days to get to a comfortable skill level such that typing was smooth again.</p>
<h2 id="computer">Computer</h2>
<figure>
<img src="../images/ubuntu-details.png" alt="" /><figcaption><em>Details of my computer</em></figcaption>
</figure>
<blockquote>
</blockquote>
<p>The computer should be quiet and powerful enough to support your work without lag. A noisy machine can be extremely irritating and have a substantial negative impact on productivity. It’s a good strategy to choose quiet computer parts with suitable performance. When it comes to the operating system, Linux based distributions, such as Ubuntu, are the programmers choice.</p>
<h2 id="workroom">Workroom</h2>
<p>Here are some considerations about the workroom itself.</p>
<ul>
<li><p>Avoid strong overhead lighting. Additional artificial lights can cause extra fatigue and reduce productivity.</p></li>
<li><p>The workroom should have a window. We can open it for fresh air. Also, Natural light is better than artificial light.</p></li>
</ul>
Scala Programming using IntelliJ IDEA2016-11-30T00:00:00+02:002016-11-30T00:00:00+02:00Jaan Tollander de Balschtag:jaantollander.github.io,2016-11-30:/scala-programming-intellij.html
<p><img src="../images/intellij-scala.png" /></p>
<blockquote>
</blockquote>
<p>This short article illustrates reasons for switching to <a href="https://www.jetbrains.com/idea/">IntelliJ IDEA</a> as an alternative IDE for writing Scala as opposed to using Eclipse. We also show how to do the setup. IntelliJ IDEA is a Java IDE from JetBrains, which supports Scala. IntelliJ’s <a href="https://www.youtube.com/user/intellijideavideo">youtube channel</a> contains more material and guides for those who are interested.</p>
<p><img src="../images/intellij-scala.png" /></p>
<blockquote>
</blockquote>
<p>This short article illustrates reasons for switching to <a href="https://www.jetbrains.com/idea/">IntelliJ IDEA</a> as an alternative IDE for writing Scala as opposed to using Eclipse. We also show how to do the setup. IntelliJ IDEA is a Java IDE from JetBrains, which supports Scala. IntelliJ’s <a href="https://www.youtube.com/user/intellijideavideo">youtube channel</a> contains more material and guides for those who are interested.</p>
<h2 id="reasons-to-use-intellij">Reasons to Use IntelliJ</h2>
<p>Here are some reasons why I use IntelliJ.</p>
<ul>
<li>It’s easy and intuitive to learn for people of any skill level.</li>
<li>It has a user-friendly and sophisticated interface.</li>
<li>It has an option to choose a dark theme, such as <em>Darcula</em>, which is much more pleasant for the eyes, especially later in the evening.</li>
<li>It uses <a href="https://fonts.google.com/specimen/Source+Code+Pro">Source Code Pro</a> font by default, which is font designed for programming.</li>
<li>It has powerful refactoring and static code analysis tools.</li>
<li>It is intended to be used with the keyboard and doesn’t require a lot of mouse movement.</li>
</ul>
<h2 id="setting-up-intellij-idea">Setting Up IntelliJ IDEA</h2>
<p>The official <a href="https://www.jetbrains.com/help/idea/meet-intellij-idea.html">IntelliJ IDEA guide</a> offers in-depth details for using IntelliJ and contains <a href="https://www.jetbrains.com/help/idea/scala.html">Scala section</a>. Here is the list of steps to get up and running with IntelliJ.</p>
<ol type="1">
<li>Request for a <a href="https://www.jetbrains.com/student/">student license</a>. With a student license, you can get the professional versions of JetBrains products for free.</li>
<li><a href="https://www.jetbrains.com/idea/download">Download IntelliJ IDEA</a>. If you applied for a student license, download the <em>Ultimate</em> edition; otherwise, download the <em>Community</em> edition.</li>
<li>Install the Scala plugin.</li>
<li><em>Optional</em>: Set theme to <em>Darcula</em>.</li>
<li><em>Linux users</em>: Make desktop entry, by searching from settings <em>create desktop entry</em>.</li>
</ol>
<h2 id="importing-a-project">Importing a Project</h2>
<div style="position:relative;height:0;padding-bottom:56.21%">
<iframe src="https://www.youtube.com/embed/V_gcPUO7X-I?ecver=2" style="position:absolute;width:100%;height:100%;left:0" width="641" height="360" frameborder="0" gesture="media" allowfullscreen>
</iframe>
</div>
<blockquote>
</blockquote>
<p>In this section, we show how to import a project for the Aalto University Scala programming courses. We use the <em>CS-A1140 Data Structures and Algorithms</em> course files as an example.</p>
<ul>
<li>Project dependensies: <code>A1140-libs.zip</code></li>
<li>Project file. E.g. <code>A1140-r1-peakFinder.zip</code></li>
</ul>
<p>Import Eclipse project files</p>
<ol type="1">
<li>Open IntelliJ Idea</li>
<li>Choose <code>Import Project</code></li>
<li>Select the extracted project files folder. E.g. <code>A1140-r1-peakFinder</code></li>
<li>Choose to import as <code>Eclipse project</code></li>
<li>Keep pressing <code>next</code> and finally press <code>finish</code></li>
</ol>
<p>Setting up Scala SDK</p>
<ol type="1">
<li>Set scala SDK by opening exercise file in IntelliJ and pop should suggest to setup scala SDK.</li>
</ol>
<p>Setting up the dependencies</p>
<ol type="1">
<li>Open <code>project structure</code> window</li>
<li>Select <code>modules</code> choose <code>Dependencies</code> tab</li>
<li>Press the <em>plus</em> sign to add new dependencies</li>
<li>Select all the <code>.jar</code> files inside the <code>A1140-libs/lib</code> directory</li>
<li>Press <em>OK</em></li>
</ol>