<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Thomas Antony</title>
    <subtitle>My personal website and notes</subtitle>
    <link rel="self" type="application/atom+xml" href="https://www.thomasantony.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://www.thomasantony.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-12-29T01:23:21+00:00</updated>
    <id>https://www.thomasantony.com/atom.xml</id>
    <entry xml:lang="en">
        <title>GPU-Agnostic Programming using CubeCL</title>
        <published>2025-12-29T01:23:21+00:00</published>
        <updated>2025-12-29T01:23:21+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/posts/gpu-agnostic-programming-using-cubecl/"/>
        <id>https://www.thomasantony.com/posts/gpu-agnostic-programming-using-cubecl/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/posts/gpu-agnostic-programming-using-cubecl/">&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;cubecl&quot;&gt;CubeCL&lt;&#x2F;a&gt; is a Rust crate that is used for writing GPU programs in pure Rust, which is compatible with a wide range of GPU platforms. It is the underlying library powering the “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;burn.dev&#x2F;&quot;&gt;Burn&lt;&#x2F;a&gt;” machine learning framework.&lt;&#x2F;p&gt;
&lt;p&gt;This article will look at some of the basics of how to use CubeCL and some of its quirks. You can find the example code in this repository: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;cubecl-recipes&quot;&gt;thomasantony&#x2F;cubecl-recipes&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cubecl-topology&quot;&gt;CubeCL Topology&lt;&#x2F;h2&gt;
&lt;p&gt;Before diving into the code, it helps to understand CubeCL’s execution model and terminology. If you’re familiar with CUDA or other GPU programming frameworks, CubeCL uses different names for similar concepts:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;CubeCL Term&lt;&#x2F;th&gt;&lt;th&gt;CUDA Equivalent&lt;&#x2F;th&gt;&lt;th&gt;Description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Unit&lt;&#x2F;td&gt;&lt;td&gt;Thread&lt;&#x2F;td&gt;&lt;td&gt;A single execution unit running your kernel code&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Cube&lt;&#x2F;td&gt;&lt;td&gt;Block&lt;&#x2F;td&gt;&lt;td&gt;A group of units that can share memory and synchronize&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Hyper-Cube&lt;&#x2F;td&gt;&lt;td&gt;Grid&lt;&#x2F;td&gt;&lt;td&gt;The entire collection of cubes dispatched for a kernel&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Plane&lt;&#x2F;td&gt;&lt;td&gt;Warp&#x2F;Subgroup&lt;&#x2F;td&gt;&lt;td&gt;A subset of units in a cube that execute in lockstep&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The following diagram illustrates the relationship between Units, Cubes, and Hyper-Cubes:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;cubecl.drawio.svg&quot; alt=&quot;CubeCL Topology&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;A cube is composed of units, so a 3x3x3 cube has 27 units that can be accessed by their positions along the x, y, and z axes. Similarly, a hyper-cube is composed of cubes, just as a cube is composed of units. Each cube in the hyper-cube can be accessed by its position relative to the hyper-cube along the x, y, and z axes. Hence, a hyper-cube of 3x3x3 will have 27 cubes. In this example, the total number of working units would be 27 x 27 = 729.&lt;&#x2F;p&gt;
&lt;p&gt;— &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;burn.dev&#x2F;books&#x2F;cubecl&#x2F;getting-started&#x2F;parallel_reduction.html#cubecl---topology&quot;&gt;CubeCL Book&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The following table (also from the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;burn.dev&#x2F;books&#x2F;cubecl&#x2F;getting-started&#x2F;parallel_reduction.html#cubecl---topology&quot;&gt;CubeCL Book&lt;&#x2F;a&gt;) shows how CubeCL’s topology constants map to CUDA and WebGPU equivalents:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;CubeCL&lt;&#x2F;th&gt;&lt;th&gt;CUDA&lt;&#x2F;th&gt;&lt;th&gt;WebGPU&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CUBE_COUNT_X&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;gridDim.x&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;num_workgroups.x&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CUBE_COUNT_Y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;gridDim.y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;num_workgroups.y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CUBE_COUNT_Z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;gridDim.z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;num_workgroups.z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CUBE_POS_X&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;blockIdx.x&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;workgroup_id.x&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CUBE_POS_Y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;blockIdx.y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;workgroup_id.y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CUBE_POS_Z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;blockIdx.z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;workgroup_id.z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CUBE_DIM_X&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;blockDim.x&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;workgroup_size.x&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CUBE_DIM_Y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;blockDim.y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;workgroup_size.y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;CUBE_DIM_Z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;blockDim.z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;workgroup_size.z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;UNIT_POS&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;N&#x2F;A&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;local_invocation_index&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;UNIT_POS_X&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;threadIdx.x&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;local_invocation_id.x&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;UNIT_POS_Y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;threadIdx.y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;local_invocation_id.y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;UNIT_POS_Z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;threadIdx.z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;local_invocation_id.z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;PLANE_DIM&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;warpSize&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;subgroup_size&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ABSOLUTE_POS_X&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;N&#x2F;A&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;global_id.x&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ABSOLUTE_POS_Y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;N&#x2F;A&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;global_id.y&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;ABSOLUTE_POS_Z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;N&#x2F;A&lt;&#x2F;td&gt;&lt;td&gt;&lt;code&gt;global_id.z&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Throughout this article, I may use CUDA terminology (thread, block) interchangeably with CubeCL terminology (unit, cube) since many readers will be more familiar with the CUDA terms.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hello-world&quot;&gt;Hello, World&lt;&#x2F;h2&gt;
&lt;p&gt;We will start with a very simple parallel program - one that takes an array of numbers and doubles each element. Roughly the same as the following python function, except that it will be using the GPU and executing in parallel&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;double_array&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;numbers&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;    output = []
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;i &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;(numbers)):
&lt;&#x2F;span&gt;&lt;span&gt;        output[i] = numbers[i] * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2.0
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;output
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Yes, I am aware that this could have been simplified using numpy or a list comprehension. But the point of the above code was to give a direct correlation to the GPU code that we will be writing.&lt;&#x2F;p&gt;
&lt;p&gt;We start off by creating a new Rust project using &lt;code&gt;cargo&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span&gt; new first-gpu-program
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span&gt; first-gpu-program
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we need to add the dependencies - in this case, just &lt;code&gt;cubecl&lt;&#x2F;code&gt; with the &lt;code&gt;wgpu&lt;&#x2F;code&gt; feature enabled. The WGPU backend allows running your code on a wide range of GPUs. Add the following under &lt;code&gt;[dependencies]&lt;&#x2F;code&gt; in &lt;code&gt;Cargo.toml&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;toml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-toml &quot;&gt;&lt;code class=&quot;language-toml&quot; data-lang=&quot;toml&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cubecl &lt;&#x2F;span&gt;&lt;span&gt;= { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;version &lt;&#x2F;span&gt;&lt;span&gt;= &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;0.8.1&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;features &lt;&#x2F;span&gt;&lt;span&gt;= [&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;wgpu&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;] }
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Build and run the program using &lt;code&gt;cargo run&lt;&#x2F;code&gt; and the program should build and print out “Hello, world!”.&lt;&#x2F;p&gt;
&lt;p&gt;Just like on other GPU programming platforms, the basic unit of a parallel program in CubeCL is a “kernel”. This is a function that gets dispatched to execute on the GPU. See the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;burn.dev&#x2F;books&#x2F;cubecl&#x2F;getting-started&#x2F;parallel_reduction.html&quot;&gt;CubeCL book&lt;&#x2F;a&gt; for more details. Kernels do not have a return value and will be returning data instead by writing to mutable array references that are passed into it.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the CubeCL version of the Python program given above:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;cubecl::prelude::*;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cube&lt;&#x2F;span&gt;&lt;span&gt;(launch)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;kernel_double_numbers&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;input_data&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;Array&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;output_data&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;Array&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ABSOLUTE_POS is equivalent to CUBE_POS * CUBE_DIM + UNIT_POS
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; index = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;ABSOLUTE_POS&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    output_data[index] = input_data[index] * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; device = Default::default();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; client = cubecl::wgpu::WgpuRuntime::client(&amp;amp;device);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; input_data = (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;).collect::&amp;lt;Vec&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Input: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;amp;input_data);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; num_elements = input_data.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; zeros = vec![&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;; num_elements];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; input_data_gpu = client.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::as_bytes(&amp;amp;input_data));
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; output_data_gpu = client.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::as_bytes(&amp;amp;zeros));
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        kernel_double_numbers::launch::&amp;lt;cubecl::wgpu::WgpuRuntime&amp;gt;(
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;amp;client,
&lt;&#x2F;span&gt;&lt;span&gt;            CubeCount::Static(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            CubeDim::new(num_elements as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&amp;amp;input_data_gpu, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&amp;amp;output_data_gpu, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; result = client.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;read_one&lt;&#x2F;span&gt;&lt;span&gt;(output_data_gpu.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;clone&lt;&#x2F;span&gt;&lt;span&gt;());
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; output = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::from_bytes(&amp;amp;result).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;to_vec&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Output: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, output);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Compile and run the program and you should see the following:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;Input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
&lt;&#x2F;span&gt;&lt;span&gt;Output: [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let’s look at the code in more detail:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;defining-the-kernel&quot;&gt;Defining the Kernel&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cube&lt;&#x2F;span&gt;&lt;span&gt;(launch)]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is a Rust macro that converts a Rust function into a GPU kernel that can be dispatched. It generates the &lt;code&gt;::launch&lt;&#x2F;code&gt; method that is used to dispatch the kernel to the GPU. Within the kernel, you write the code for &lt;em&gt;one&lt;&#x2F;em&gt; of the threads. You identify the element of the array that you are supposed to operate on using the intrinsic values &lt;code&gt;CUBE_POS&lt;&#x2F;code&gt;, &lt;code&gt;UNIT_POS&lt;&#x2F;code&gt; etc. (see &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;posts&#x2F;gpu-agnostic-programming-using-cubecl&#x2F;#cubecl-topology&quot;&gt;CubeCL Topology&lt;&#x2F;a&gt; above for details on these constants).&lt;&#x2F;p&gt;
&lt;p&gt;In the example code, we assume that the array is to be accessed in the following manner:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;[x x x x x x x x | x x x x x x x x]
&lt;&#x2F;span&gt;&lt;span&gt; ^.............^   ^.............^
&lt;&#x2F;span&gt;&lt;span&gt;      Block 0           Block 1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is accomplished by using &lt;code&gt;ABSOLUTE_POS&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ABSOLUTE_POS is equivalent to CUBE_POS * CUBE_DIM + UNIT_POS
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; index = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;ABSOLUTE_POS&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;initializing-the-cubecl-device-and-runtime&quot;&gt;Initializing the CubeCL Device and Runtime&lt;&#x2F;h3&gt;
&lt;p&gt;Going to the &lt;code&gt;main()&lt;&#x2F;code&gt; function, the first step is initializing the GPU and the CubeCL runtime:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; device = Default::default();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; client = cubecl::wgpu::WgpuRuntime::client(&amp;amp;device);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you were using a different runtime (say CUDA), you would initialize that here instead of WGPU.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;initializing-gpu-buffers-and-copying-input-data&quot;&gt;Initializing GPU buffers and copying input data&lt;&#x2F;h3&gt;
&lt;p&gt;The next step is to take the input data and copy it into GPU buffers. GPU buffers need to be defined for the output buffer as well:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; input_data = (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;..&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;).collect::&amp;lt;Vec&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Input: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;amp;input_data);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; num_elements = input_data.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; zeros = vec![&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;; num_elements];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; input_data_gpu = client.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::as_bytes(&amp;amp;input_data));
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; output_data_gpu = client.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::as_bytes(&amp;amp;zeros));
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note here that the &lt;code&gt;zeros&lt;&#x2F;code&gt; variable (and any other CPU-side buffer) can be reused if multiple buffers need to be created. The values are copied to the GPU buffer in each case.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;launching-the-kernel&quot;&gt;Launching the kernel&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        kernel_double_numbers::launch::&amp;lt;cubecl::wgpu::WgpuRuntime&amp;gt;(
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;amp;client,
&lt;&#x2F;span&gt;&lt;span&gt;            CubeCount::Static(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            CubeDim::new(num_elements as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&amp;amp;input_data_gpu, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&amp;amp;output_data_gpu, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This section actually launches the kernel, and dispatches it to the GPU for execution. The first argument is the client object that was initialized earlier.&lt;&#x2F;p&gt;
&lt;p&gt;The second and third arguments specify the “shape” and size of the “cubes” to be scheduled on the GPU. The kernel is executed on a “HyperCube” (called a Grid in CUDA) of cubes, and each cube consists of multiple units (threads). &lt;code&gt;CubeCount&lt;&#x2F;code&gt; specifies the size of the hypercube along X, Y, and Z dimensions (only X is used in this example), and &lt;code&gt;CubeDim&lt;&#x2F;code&gt; specifies the number of units&#x2F;threads in each cube.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;ArrayArg&lt;&#x2F;code&gt; objects take in the GPU buffer handles created before using &lt;code&gt;client.create()&lt;&#x2F;code&gt; and pass them as arguments to the kernel. These values map on to the &lt;code&gt;&amp;amp;Array&amp;lt;u32&amp;gt;&lt;&#x2F;code&gt; and &lt;code&gt;&amp;amp;mut Array&amp;lt;u32&amp;gt;&lt;&#x2F;code&gt; parameters in the kernel.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;extracting-the-output-values&quot;&gt;Extracting the output values&lt;&#x2F;h3&gt;
&lt;p&gt;Once the computation is complete, the values need to be copied back to the RAM so that we can use them elsewhere.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; result = client.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;read_one&lt;&#x2F;span&gt;&lt;span&gt;(output_data_gpu.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;clone&lt;&#x2F;span&gt;&lt;span&gt;());
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; output = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::from_bytes(&amp;amp;result).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;to_vec&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Output: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, output);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;output_data_gpu&lt;&#x2F;code&gt; handle is cloned here in case it needs to be used again elsewhere (maybe for launching another kernel).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;scalar-arguments&quot;&gt;Scalar Arguments&lt;&#x2F;h2&gt;
&lt;p&gt;You are also able to pass scalar values to the kernel - lets say, an integer that will be used in place of &lt;code&gt;2&lt;&#x2F;code&gt; for scaling the arrays. This is done by passing in an instance of &lt;code&gt;ScalarArg&lt;&#x2F;code&gt;. Modify the kernel as follows:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cube&lt;&#x2F;span&gt;&lt;span&gt;(launch)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;kernel_scale_numbers&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;input_data&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;Array&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;scale&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;output_data&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;Array&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ABSOLUTE_POS is equivalent to CUBE_POS * CUBE_DIM + UNIT_POS
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; index = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;ABSOLUTE_POS&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    output_data[index] = input_data[index] * scale;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;                                       ^ used instead of 2
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The kernel is then launched as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        kernel_scale_numbers::launch::&amp;lt;cubecl::wgpu::WgpuRuntime&amp;gt;(
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;amp;client,
&lt;&#x2F;span&gt;&lt;span&gt;            CubeCount::Static(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            CubeDim::new(num_elements as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&amp;amp;input_data_gpu, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            ScalarArg::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;),  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; &amp;lt;-- scalar argument
&lt;&#x2F;span&gt;&lt;span&gt;            ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&amp;amp;output_data_gpu, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Running the program should now give the output:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;Input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
&lt;&#x2F;span&gt;&lt;span&gt;Output: [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;backend-agnostic-code&quot;&gt;Backend-Agnostic Code&lt;&#x2F;h2&gt;
&lt;p&gt;The examples above hardcoded the WGPU runtime as the CubeCL backend to use for running the code. This is not ideal if the code is to be distributed as a crate&#x2F;library. CubeCL offers a generics-based pattern for making your code agnostic to the GPU platform. The kernel itself remains identical as it does not have any platform-specific references. However, the launching of the kernel needs to be extracted out into a separate function.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;launch_scale_numbers_kernel&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;R: Runtime&amp;gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;client&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;ComputeClient&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;R::&lt;&#x2F;span&gt;&lt;span&gt;Server&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;Handle,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;scale&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;output&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;Handle,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;num_elements&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        kernel_scale_numbers::launch::&amp;lt;R&amp;gt;(
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;amp;client,
&lt;&#x2F;span&gt;&lt;span&gt;            CubeCount::Static(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            CubeDim::new(num_elements as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(input, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            ScalarArg::new(scale),
&lt;&#x2F;span&gt;&lt;span&gt;            ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(output, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The function is then called as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;    launch_scale_numbers_kernel::&amp;lt;cubecl::wgpu::WgpuRuntime&amp;gt;(
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;amp;client,
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;amp;input_data_gpu,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;amp;output_data_gpu,
&lt;&#x2F;span&gt;&lt;span&gt;        num_elements,
&lt;&#x2F;span&gt;&lt;span&gt;    );
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;launch_scale_numbers_kernel&lt;&#x2F;code&gt; could be in a separate crate and is completely agnostic to the specific GPU platform that it will be deployed to. The platform is only specified when the function is called.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cube-functions&quot;&gt;Cube functions&lt;&#x2F;h2&gt;
&lt;p&gt;You may want to split out small chunks of your kernel code so that it can be reused in multiple kernels. This is done using by defining functions that use the &lt;code&gt;#[cube]&lt;&#x2F;code&gt; macro and comes with a few caveats. The arguments to such functions can either be scalar values (&lt;code&gt;u32&lt;&#x2F;code&gt;, &lt;code&gt;f32&lt;&#x2F;code&gt; etc.), or a type like &lt;code&gt;Array&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cube&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;do_scale&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;Array&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;scale&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ABSOLUTE_POS is equivalent to CUBE_POS * CUBE_DIM + UNIT_POS
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; index = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;ABSOLUTE_POS&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    input[index] * scale
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cube&lt;&#x2F;span&gt;&lt;span&gt;(launch)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;kernel_scale_numbers&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;input_data&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;Array&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;scale&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;output_data&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;Array&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ABSOLUTE_POS is equivalent to CUBE_POS * CUBE_DIM + UNIT_POS
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; index = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;ABSOLUTE_POS&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    output_data[index] = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;do_scale&lt;&#x2F;span&gt;&lt;span&gt;(input_data, scale);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;shared-memory&quot;&gt;Shared Memory&lt;&#x2F;h2&gt;
&lt;p&gt;Shared Memory is allocated in kernels and used for sharing information between threads in the same “cube” (aka block). Since this is implemented as on-chip SRAM, it is significantly faster than the “global” GPU memory. It is allocated in a kernel using the &lt;code&gt;SharedMemory&lt;&#x2F;code&gt; type:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; smem_histogram = SharedMemory::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;SIZE&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the above example, &lt;code&gt;SIZE&lt;&#x2F;code&gt; must be a constant known at compile-time. This can be limiting when you want to write flexible kernels where the shared memory size depends on launch parameters. CubeCL’s &lt;code&gt;#[comptime]&lt;&#x2F;code&gt; feature (described in the next section) provides a solution to this constraint.&lt;&#x2F;p&gt;
&lt;p&gt;Shared memory can be used like any other array, except that the data in it is only shared across the threads in the same cube.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;comptime-parameters&quot;&gt;Comptime Parameters&lt;&#x2F;h2&gt;
&lt;p&gt;CubeCL provides a &lt;code&gt;#[comptime]&lt;&#x2F;code&gt; attribute for kernel parameters that need to be known at kernel compile time, but can vary between different kernel invocations. This is particularly useful for &lt;code&gt;SharedMemory&lt;&#x2F;code&gt; sizes that depend on launch configuration.&lt;&#x2F;p&gt;
&lt;p&gt;When you mark a parameter with &lt;code&gt;#[comptime]&lt;&#x2F;code&gt;, the value is baked into the kernel during JIT compilation. CubeCL will compile a specialized version of the kernel for each unique combination of comptime values you use.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cube&lt;&#x2F;span&gt;&lt;span&gt;(launch)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;kernel_with_comptime&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;data&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;Array&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    #[comptime] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;buffer_size&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; buffer_size is known at kernel compile time
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; shared_buffer = SharedMemory::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;::new(buffer_size);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ... use shared_buffer
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The kernel is launched by passing the comptime value as a regular argument:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    kernel_with_comptime::launch::&amp;lt;R&amp;gt;(
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;amp;client,
&lt;&#x2F;span&gt;&lt;span&gt;        cube_count,
&lt;&#x2F;span&gt;&lt;span&gt;        cube_dim,
&lt;&#x2F;span&gt;&lt;span&gt;        ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&amp;amp;data_gpu, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;        buffer_size,  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; comptime parameter - no wrapper needed
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A practical example of this pattern is shown in the &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;posts&#x2F;gpu-agnostic-programming-using-cubecl&#x2F;#block-exclusive-sum&quot;&gt;Block Exclusive Sum&lt;&#x2F;a&gt; section below, where &lt;code&gt;#[comptime]&lt;&#x2F;code&gt; is used to configure the number of planes for shared memory allocation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;atomic-variables&quot;&gt;Atomic Variables&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;Atomic&lt;&#x2F;code&gt; type allows definition of variables that are used for atomic read&#x2F;write operations. Such operations are useful for avoiding race conditions. For Shared Memory, this is defined as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; smem_histogram = SharedMemory::&amp;lt;Atomic&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;SIZE&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For global memory, in CubeCL, it is not necessary to allocate the memory as Atomic. Instead, it is enough to change the type of the parameter to the kernel to say &lt;code&gt;&amp;amp;Array&amp;lt;Atomic&amp;lt;u32&amp;gt;&amp;gt;&lt;&#x2F;code&gt; instead of &lt;code&gt;&amp;amp;Array&amp;lt;u32&amp;gt;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Read operations are performed as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; val = Atomic::load(&amp;amp;smem_histogram[i]);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Write operations can be done as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;Atomic::store(&amp;amp;smem_histogram[i], val);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;See all the valid atomic operations on this &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;cubecl-core&#x2F;0.8.1&#x2F;cubecl_core&#x2F;frontend&#x2F;struct.Atomic.html&quot;&gt;page&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;plane-intrinsics&quot;&gt;Plane Intrinsics&lt;&#x2F;h2&gt;
&lt;p&gt;In CubeCL, there is a concept of something called a “plane”. This is a sub-set of the threads in a block. This has to do with how the threads are actually scheduled on the GPU for execution. On NVIDIA GPUs, threads are scheduled for execution as sets of 32 threads called “warps”. These are guaranteed to be running simultaneously on a GPU. If you schedule blocks that are larger than the warp-size on the GPU, the block gets split up into warps (aka planes in CubeCL), and gets swapped in and out.&lt;&#x2F;p&gt;
&lt;p&gt;CubeCL offers some GPU primitives that operate at the level of all threads on the plane. These are not very well documented at the time of writing unless you wade through some of the unit tests.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;plane-exclusive-sum&quot;&gt;Plane Exclusive Sum&lt;&#x2F;h3&gt;
&lt;p&gt;Here is an example where we use plane intrinsics to compute an “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Prefix_sum#Inclusive_and_exclusive_scans&quot;&gt;exclusive sum&lt;&#x2F;a&gt;”. The algorithm will take an array like &lt;code&gt;[1, 1, 1, 1]&lt;&#x2F;code&gt; and return &lt;code&gt;[0, 1, 2, 3]&lt;&#x2F;code&gt;. It uses the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;cubecl&#x2F;latest&#x2F;cubecl&#x2F;frontend&#x2F;fn.plane_exclusive_sum.html&quot;&gt;plane_exclusive_sum&lt;&#x2F;a&gt; function.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cube&lt;&#x2F;span&gt;&lt;span&gt;(launch)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;kernel_plane_exclusive_sum&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;input_data&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;Array&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;output_data&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;Array&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ABSOLUTE_POS is equivalent to CUBE_POS * CUBE_DIM + UNIT_POS
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; index = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;ABSOLUTE_POS&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; local_data = input_data[index];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; local_sum = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;plane_exclusive_sum&lt;&#x2F;span&gt;&lt;span&gt;(local_data);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    output_data[index] = local_sum;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; device = Default::default();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; client = cubecl::wgpu::WgpuRuntime::client(&amp;amp;device);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span&gt;R = cubecl::wgpu::WgpuRuntime;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; input_data = vec![&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Input: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;amp;input_data);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; num_elements = input_data.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; zeros = vec![&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;; num_elements];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; input_data_gpu = client.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::as_bytes(&amp;amp;input_data));
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; output_data_gpu = client.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::as_bytes(&amp;amp;zeros));
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;SMALL_BLOCK_SIZE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; num_blocks = num_elements &#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;SMALL_BLOCK_SIZE&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        kernel_plane_exclusive_sum::launch::&amp;lt;R&amp;gt;(
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;amp;client,
&lt;&#x2F;span&gt;&lt;span&gt;            CubeCount::Static(num_blocks as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            CubeDim::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;SMALL_BLOCK_SIZE &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&amp;amp;input_data_gpu, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&amp;amp;output_data_gpu, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; result = client.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;read_one&lt;&#x2F;span&gt;&lt;span&gt;(output_data_gpu.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;clone&lt;&#x2F;span&gt;&lt;span&gt;());
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; output = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::from_bytes(&amp;amp;result).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;to_vec&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Plane Exclusive Sum: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, output);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The magic happens in these lines:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; local_data = input_data[index];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; local_sum = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;plane_exclusive_sum&lt;&#x2F;span&gt;&lt;span&gt;(local_data);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    output_data[index] = local_sum;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;plane_exclusive_sum&lt;&#x2F;code&gt; takes the value of &lt;code&gt;local_data&lt;&#x2F;code&gt; from every other unit&#x2F;thread in the current plane&#x2F;warp and computes an exclusive sum, and returns the value that should be returned by the current thread.&lt;&#x2F;p&gt;
&lt;p&gt;One caveat here is that this is limited to the plane (usually a maximum of 32-64 threads depending on the GPU platform). In the above example, we use an array with 16 elements and enforce a block-size (and hence plane size) of 8. This will give us the following result:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;Input: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
&lt;&#x2F;span&gt;&lt;span&gt;Plane Exclusive Sum: [0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you want to perform an exclusive scan over the entire block (possibly multiple planes), we need to use a more complicated algorithm where shared memory is used to accumulate results between planes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;block-exclusive-sum&quot;&gt;Block Exclusive Sum&lt;&#x2F;h3&gt;
&lt;p&gt;This example demonstrates the &lt;code&gt;#[comptime]&lt;&#x2F;code&gt; pattern described earlier. Instead of hardcoding the shared memory size, we pass &lt;code&gt;num_planes&lt;&#x2F;code&gt; as a comptime parameter, making the kernel flexible for different block sizes.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F; Performs exclusive sum over all elements in a block, using plane primitives
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cube&lt;&#x2F;span&gt;&lt;span&gt;(launch)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;kernel_block_exclusive_sum&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;input_data&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;Array&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;output_data&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span&gt;Array&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    #[comptime] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;num_planes&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; thread_id = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;UNIT_POS&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; plane_thread_idx = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;UNIT_POS_PLANE&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; plane_idx = thread_id &#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;PLANE_DIM&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; ABSOLUTE_POS is equivalent to CUBE_POS * CUBE_DIM + UNIT_POS
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; thread_idx = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;ABSOLUTE_POS&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Select plane size as the smaller of the current block size or the max plane size
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; So if block size is 8, plane size will be 8
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; If block size is 64, plane size will be 32 (if that is the maximum)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; plane_size = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;CUBE_DIM &lt;&#x2F;span&gt;&lt;span&gt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;PLANE_DIM &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;CUBE_DIM
&lt;&#x2F;span&gt;&lt;span&gt;    } &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;else &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;PLANE_DIM
&lt;&#x2F;span&gt;&lt;span&gt;    };
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Define shared memory for inter-plane communication
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Size is determined at kernel compile time via comptime parameter
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; shared_totals = SharedMemory::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;::new(num_planes);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; 1. local scan
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; original = input_data[thread_idx];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; local_scan = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;plane_exclusive_sum&lt;&#x2F;span&gt;&lt;span&gt;(original);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; 2. plane totals → shared mem
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; plane_total =
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;plane_shuffle&lt;&#x2F;span&gt;&lt;span&gt;(local_scan, plane_size - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;plane_shuffle&lt;&#x2F;span&gt;&lt;span&gt;(original, plane_size - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; plane_thread_idx == &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        shared_totals[plane_idx] = plane_total;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;sync_cube&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; 3. scan totals (single plane or serial)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; plane_idx == &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;&amp;amp; plane_thread_idx &amp;lt; num_planes {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; offset = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;plane_exclusive_sum&lt;&#x2F;span&gt;&lt;span&gt;(shared_totals[plane_thread_idx]);
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; reuse shared_totals for storing offsets
&lt;&#x2F;span&gt;&lt;span&gt;        shared_totals[plane_thread_idx] = offset;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;sync_cube&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; 4. apply offset
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; result = local_scan + shared_totals[plane_idx];
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    output_data[thread_idx] = result;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; device = Default::default();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; client = cubecl::wgpu::WgpuRuntime::client(&amp;amp;device);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span&gt;R = cubecl::wgpu::WgpuRuntime;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; input_data = vec![&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Input: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;amp;input_data);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; num_elements = input_data.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; input_data_gpu = client.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::as_bytes(&amp;amp;input_data));
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; zeros = vec![&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;; num_elements];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; output_data_gpu = client.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;create&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::as_bytes(&amp;amp;zeros));
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;BLOCK_SIZE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;NUM_PLANES&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32 &lt;&#x2F;span&gt;&lt;span&gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;BLOCK_SIZE &lt;&#x2F;span&gt;&lt;span&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;PLANE_DIM &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; num_blocks = num_elements &#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;BLOCK_SIZE&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        kernel_block_exclusive_sum::launch::&amp;lt;R&amp;gt;(
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;amp;client,
&lt;&#x2F;span&gt;&lt;span&gt;            CubeCount::Static(num_blocks as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            CubeDim::new(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;BLOCK_SIZE &lt;&#x2F;span&gt;&lt;span&gt;as &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&amp;amp;input_data_gpu, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            ArrayArg::from_raw_parts::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;(&amp;amp;output_data_gpu, num_elements, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;NUM_PLANES&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; comptime parameter for shared memory size
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; result = client.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;read_one&lt;&#x2F;span&gt;&lt;span&gt;(output_data_gpu.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;clone&lt;&#x2F;span&gt;&lt;span&gt;());
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; output = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;::from_bytes(&amp;amp;result).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;to_vec&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span&gt;    println!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Block Exclusive Sum: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;{:?}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, output);
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here, we use a larger array with 64 elements to make sure that the block size exceeds the plane size (on WGPU) of 32. The &lt;code&gt;NUM_PLANES&lt;&#x2F;code&gt; constant is computed from &lt;code&gt;BLOCK_SIZE &#x2F; PLANE_DIM&lt;&#x2F;code&gt; and passed to the kernel, where it determines the shared memory allocation size.&lt;&#x2F;p&gt;
&lt;p&gt;The algorithm works as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The local scan takes the 64-long array &lt;code&gt;[1, 1, ... 1]&lt;&#x2F;code&gt; and converts it into &lt;code&gt;[0, 1, ... 31, 0, 1, ... 31]&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The next step is to compute the “shared totals”. This is the total sum from each plane accumulated into a shared memory array. In this case, it would be &lt;code&gt;[32, 32]&lt;&#x2F;code&gt;. This is done by adding the last value of the local scan in the current plane, with the last value of the input array processed by the current plane.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;To compute this, we use another plane-intrinsic function called &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;cubecl&#x2F;latest&#x2F;cubecl&#x2F;frontend&#x2F;fn.plane_shuffle.html&quot;&gt;plane_shuffle&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;plane_shuffle&lt;&#x2F;span&gt;&lt;span&gt;(local_scan, plane_size - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The above function call returns the value of &lt;code&gt;local_scan&lt;&#x2F;code&gt; from the thread index &lt;code&gt;plane_size - 1&lt;&#x2F;code&gt; (aka the final thread in the plane). So the shared total is computed as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; plane_total =
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;plane_shuffle&lt;&#x2F;span&gt;&lt;span&gt;(local_scan, plane_size - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) + &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;plane_shuffle&lt;&#x2F;span&gt;&lt;span&gt;(original, plane_size - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; plane_thread_idx == &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        shared_totals[plane_idx] = plane_total;
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The value is then stored into the shared memory by a single thread (gated by the &lt;code&gt;if&lt;&#x2F;code&gt; condition). There is no point in all of the threads trying to write the exact same value to the shared array.&lt;&#x2F;p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Compute the offsets from the shared totals using another exclusive scan, i.e. &lt;code&gt;[32, 32]&lt;&#x2F;code&gt; becomes &lt;code&gt;[0, 32]&lt;&#x2F;code&gt;. These are the values to be added to each plane’s local scan results. So we add &lt;code&gt;0&lt;&#x2F;code&gt; to the local scan results from plane 0, &lt;code&gt;32&lt;&#x2F;code&gt; to the local scan results from plane 1, etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This exclusive scan can also be performed using the &lt;code&gt;plane_exclusive_sum&lt;&#x2F;code&gt; function - except that we make sure to not use more threads than are required.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; offset = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;plane_exclusive_sum&lt;&#x2F;span&gt;&lt;span&gt;(shared_totals[plane_thread_idx]);
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; reuse shared_totals for storing offsets
&lt;&#x2F;span&gt;&lt;span&gt;        shared_totals[plane_thread_idx] = offset;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Now applying the offset is as simple as taking the current thread’s local scan result (&lt;code&gt;local_scan&lt;&#x2F;code&gt;) and adding the appropriate offset to it.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;: &lt;code&gt;sync_cube()&lt;&#x2F;code&gt; is used to synchronize processing between all the threads&#x2F;units in a block. All the threads will wait at these points until every other thread in the block has reached the same point.&lt;&#x2F;p&gt;
&lt;p&gt;This should now give the result:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;Input: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
&lt;&#x2F;span&gt;&lt;span&gt;Block Exclusive Sum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;gotchas&quot;&gt;Gotchas&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;CubeCL does not like mutable unused variables without a type definition.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you add the following to a kernel or a #[cube] function :&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; mynumber = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you do not use this value anywhere in a way that lets the compiler infer its type, you will get an error message like:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;error[E0283]: type annotations needed
&lt;&#x2F;span&gt;&lt;span&gt;  --&amp;gt; src&#x2F;main.rs:88:1
&lt;&#x2F;span&gt;&lt;span&gt;   |
&lt;&#x2F;span&gt;&lt;span&gt;88 | #[cube(launch)]
&lt;&#x2F;span&gt;&lt;span&gt;   | ^^^^^^^^^^^^^^^ cannot infer type for struct `ExpandElementTyped&amp;lt;_&amp;gt;`
&lt;&#x2F;span&gt;&lt;span&gt;   |
&lt;&#x2F;span&gt;&lt;span&gt;   = note: multiple `impl`s satisfying `ExpandElementTyped&amp;lt;_&amp;gt;: IntoMut` found in the `cubecl_core` crate:
&lt;&#x2F;span&gt;&lt;span&gt;           - impl&amp;lt;T&amp;gt; IntoMut for ExpandElementTyped&amp;lt;T&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;             where T: ExpandElementIntoMut;
&lt;&#x2F;span&gt;&lt;span&gt;           - impl&amp;lt;T&amp;gt; IntoMut for ExpandElementTyped&amp;lt;cubecl::frontend::SharedMemory&amp;lt;T&amp;gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;             where T: CubePrimitive;
&lt;&#x2F;span&gt;&lt;span&gt;   = note: this error originates in the attribute macro `cube` (in Nightly builds, run with -Z macro-backtrace for more info)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It doesn’t say which line of the code causes the error, so it can be confusing if you did not know what to look for.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;CubeCL provides a compelling approach to GPU programming in Rust, offering the ability to write portable GPU code that can target multiple backends (WGPU, CUDA, etc.) from a single codebase. While the documentation is still maturing, the core concepts map well to existing GPU programming paradigms, making it accessible to developers familiar with CUDA or other GPU frameworks.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Inner Product of Functions</title>
        <published>2025-11-23T20:06:28.023+00:00</published>
        <updated>2025-11-23T20:06:28.023+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202510231206-inner-product-of-functions/"/>
        <id>https://www.thomasantony.com/notes/202510231206-inner-product-of-functions/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202510231206-inner-product-of-functions/">&lt;p&gt;The inner&#x2F;dot product for Euclidean vectors is defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\langle u, v \rangle = \sum_{i} u_i v_i
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Following on from how we defined a &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202510231156-norm-of-a-function&#x2F;&quot;&gt;norm&lt;&#x2F;a&gt; for &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202510231154-functions-form-a-vector-space&#x2F;&quot;&gt;square integrable functions&lt;&#x2F;a&gt;, we can similarly define an inner product for such functions in $\mathbb{L}^2$:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\langle f, g \rangle = \int_{-\infty}^{\infty} f(x) g(x) dx
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This inner product can now be used to define a &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202510231156-norm-of-a-function&#x2F;&quot;&gt;norm&lt;&#x2F;a&gt;&#x2F;length for our space:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
|| f || = \sqrt{ \langle f, f \rangle } = \sqrt{\int_{-\infty}^{\infty} |f(x)|^2 dx}
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Norm of a Function or Square integrable functions</title>
        <published>2025-11-23T19:56:54.213+00:00</published>
        <updated>2025-11-23T19:56:54.213+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202510231156-norm-of-a-function/"/>
        <id>https://www.thomasantony.com/notes/202510231156-norm-of-a-function/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202510231156-norm-of-a-function/">&lt;p&gt;We know that &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202510231154-functions-form-a-vector-space&#x2F;&quot;&gt;functions can be treated as infinite dimensional vectors&lt;&#x2F;a&gt;. A vector has a norm or length defined for it. How do we do that for a function?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;square-integrable-functions&quot;&gt;Square integrable functions&lt;&#x2F;h2&gt;
&lt;p&gt;Assume that we have a function: $f: \mathbb{R} \to \mathbb{C}$. It is said to be &lt;em&gt;square integrable&lt;&#x2F;em&gt; if it satisfies the following condition:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\int_{-\infty}^{\infty} |f(x)|^2 dx &amp;lt; \infty
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This is similar to the squared sum of all elements in a vector and can be considered equivalent to a squared Euclidean norm ($\sum_i v_i$). This is a measure of &lt;em&gt;length&lt;&#x2F;em&gt; and the condition above is asserting that this “length” is finite for the given function (vector). For functions, this quantity is typically called &lt;em&gt;energy&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The set of such functions are commonly denoted as $\mathbb{L}^2$ and is a subset of the &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202510231154-functions-form-a-vector-space&#x2F;&quot;&gt;vector space of all functions&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Functions form a Vector Space</title>
        <published>2025-11-23T19:54:51.959+00:00</published>
        <updated>2025-11-23T19:54:51.959+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202510231154-functions-form-a-vector-space/"/>
        <id>https://www.thomasantony.com/notes/202510231154-functions-form-a-vector-space/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202510231154-functions-form-a-vector-space/">&lt;p&gt;Functions can be treated as infinite dimensional vectors. For example, typically a vector is interpreted as an ordered list of numbers. This could also be interpreted as a function mapping the indices to the values. E.g. a vector in $\mathbb{R}^3$ can be considered to be a function mapping the domain $1, 2, 3$ to the codomain $\mathbb{R}$ (since the values in the vector are real numbers).&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
v: \{1, 2, 3\} \to \mathbb{R}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;If our vector was $N$ dimensional, then this would become: $v: {1, 2, …, N} \to \mathbb{R}$. This could even be defined for infinite $N$ in which case the function becomes a mapping from the natural numbers $\mathbb{N}$ to the real numbers: $v: \mathbb{N} \to \mathbb{R}$.&lt;&#x2F;p&gt;
&lt;p&gt;What if we allowed the “index” to be any real (or complex) number: $v: \mathbb{R} \to \mathbb{R}? This “vector” is just a function from reals to reals. It can be proven&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; that functions, together with the standard addition and scalar multiplication operations form a vector space.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;eli.thegreenplace.net&#x2F;2025&#x2F;hilbert-space-treating-functions-as-vectors&#x2F;&quot;&gt;Hilbert space: treating functions as vectors - Appendix A&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Inner Product Space</title>
        <published>2025-11-23T19:39:29.694+00:00</published>
        <updated>2025-11-23T19:39:29.694+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202510231139-inner-product-space/"/>
        <id>https://www.thomasantony.com/notes/202510231139-inner-product-space/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202510231139-inner-product-space/">&lt;p&gt;An inner product space&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; is a real or complex vector space that has an operation called an “inner product” defined for it. The inner product of two vectors is a scalar, and is typically denoted by angle brackets like $\langle a, b\rangle$.&lt;&#x2F;p&gt;
&lt;p&gt;This is a generalization of the dot product that is defined in Euclidean vector spaces ($a \cdot b = \sum a_i b_i $). The existence of an inner product also allows generalized definition of other concepts such as angles, lengths and orthogonality (zero inner product) between the vectors in the vector space.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Inner_product_space&quot;&gt;Inner Product Space&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hilbert Spaces</title>
        <published>2025-11-23T19:37:16.546+00:00</published>
        <updated>2025-11-23T19:37:16.546+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202510231137-hilbert-spaces/"/>
        <id>https://www.thomasantony.com/notes/202510231137-hilbert-spaces/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202510231137-hilbert-spaces/">&lt;p&gt;A Hilbert space is an &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202510231139-inner-product-space&#x2F;&quot;&gt;inner product space&lt;&#x2F;a&gt; that is also “complete” w.r.t the inner product - i.e. no sequence of elements in the set converges to an element outside the set. This is a generalization of the Euclidean vector space to infinite dimensions.&lt;&#x2F;p&gt;
&lt;p&gt;The key intuition behind this is to treat &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202510231154-functions-form-a-vector-space&#x2F;&quot;&gt;functions as infinite dimensional vectors&lt;&#x2F;a&gt;, which have &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202510231206-inner-product-of-functions&#x2F;&quot;&gt;inner products&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202510231156-norm-of-a-function&#x2F;&quot;&gt;norms&lt;&#x2F;a&gt; just like Euclidean vectors. This allows us to generalize many concepts from vectors to apply to functions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;generalized-fourier-series&quot;&gt;Generalized Fourier Series&lt;&#x2F;h2&gt;
&lt;p&gt;A fourier series&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; is a way of expressing a perioding function as a weighted sum of sines and cosines of different frequencies.&lt;&#x2F;p&gt;
&lt;p&gt;For functions in $\mathbb{L}^2$, the inner product allows us to define the concepts of &lt;em&gt;orthogonality&lt;&#x2F;em&gt; and &lt;em&gt;basis vectors&lt;&#x2F;em&gt;. This in turn lets us express these functions as a weighted sum of of a series of &lt;em&gt;orthogonal basis functions&lt;&#x2F;em&gt; that span the space. This allows us to apply concepts from Linear Algebra such as the Gram-Schmidt process&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#3&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; to the space of functions. This is how we get orthogonal basis functions such as Chebyshev polynomials &lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#4&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and Legendre polynomials&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#5&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;5&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;eli.thegreenplace.net&#x2F;2025&#x2F;hilbert-space-treating-functions-as-vectors&#x2F;&quot;&gt;Hilbert space: treating functions as vectors&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fourier_series&quot;&gt;Fourier Series&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gram%E2%80%93Schmidt_process&quot;&gt;Gram-Schmidt process&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;4&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Chebyshev_polynomials&quot;&gt;Chebyshev Polynomials&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;5&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;4&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Legendre_polynomials&quot;&gt;Legendre Polynomials&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Volumetric Scene Representations</title>
        <published>2025-11-11T19:19:52.957+00:00</published>
        <updated>2025-11-11T19:19:52.957+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202510111119-scene-representations/"/>
        <id>https://www.thomasantony.com/notes/202510111119-scene-representations/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202510111119-scene-representations/">&lt;p&gt;A volumetric scene represenation is a data structure or algorithmic representation of a scene - typically associated with computer vision. It can be either “implicit” or “explicit”. Some examples of scene representations are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Point Clouds&lt;&#x2F;li&gt;
&lt;li&gt;Depth Maps&lt;&#x2F;li&gt;
&lt;li&gt;Meshes&lt;&#x2F;li&gt;
&lt;li&gt;Voxel Grids&lt;&#x2F;li&gt;
&lt;li&gt;Octrees&lt;&#x2F;li&gt;
&lt;li&gt;Signed Distance Functions&lt;&#x2F;li&gt;
&lt;li&gt;Neural Fields
&lt;ul&gt;
&lt;li&gt;NeRF - Neural Radiance Fields&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;3D Gaussian Splats&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Volume Rendering</title>
        <published>2025-11-06T05:38:34.009+00:00</published>
        <updated>2025-11-06T05:38:34.009+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202510052138-volume-rendering/"/>
        <id>https://www.thomasantony.com/notes/202510052138-volume-rendering/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202510052138-volume-rendering/">&lt;p&gt;Volumetric rendering is an algorithm used for rendering radiance fields such as [[NeRFs]] and [[3D Gaussian Splats]]&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You start with some implicit or explicit &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202510111119-scene-representations&#x2F;&quot;&gt;scene representation&lt;&#x2F;a&gt; that can be sampled at 3D positions along a ray in a scene, to return a color, $c$, and an opacity $\alpha$.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
C = \sum_{i=1}^{N} T_i \alpha_i c_i ~\text{ where } T_i = \prod_{j=1}^{i-1} (1 - \alpha_i)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The “output” of this gives the color $C$ of a single pixel by sampling a ray at multiple discrete points in the scene. Depending on the underlying representation (NeRF, 3DGS etc.), the opacity $\alpha_i$ and the color $c_i$ are computed in different ways. $T_i$ is the cumulative “transmittance” of all the pixels so far in the ray. This essentially zeros out all the pixels “behind” an opaque surface. Once the ray reaches an opaque surface (i.e. $\alpha_i \approx 1$), $T_i$ for all subsequent values of $i$ will be multiplied by $(1- \alpha_i) = 0$.&lt;&#x2F;p&gt;
&lt;p&gt;This allows a continuous, differentiable function for the color which also “switches off” once an opaque function is encountered.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;repo-sam.inria.fr&#x2F;fungraph&#x2F;3d-gaussian-splatting&#x2F;3d_gaussian_splatting_low.pdf&quot;&gt;3D Gaussian Splatting for Real-Time Radiance Field Rendering&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=Ikqj1B-AfUE&quot;&gt;3D Gaussian Splatting for Real-Time Radiance Field Rendering - YouTube&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git Worktrees</title>
        <published>2025-10-12T19:03:44.388+00:00</published>
        <updated>2025-10-12T19:03:44.388+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202509121203-git-worktrees/"/>
        <id>https://www.thomasantony.com/notes/202509121203-git-worktrees/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202509121203-git-worktrees/">&lt;p&gt;Git worktrees allow you to check out multiple branches simultaneously without re-cloning the repository multiple times &lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. This is an alternative to using “stash” to save uncommited changes and switching branches.&lt;&#x2F;p&gt;
&lt;p&gt;For example, if we are currently on branch &lt;code&gt;feature&#x2F;ticket-number-xxxx&lt;&#x2F;code&gt; and want to go work on &lt;code&gt;bugfix&#x2F;ticket-yyyy&lt;&#x2F;code&gt;, we can run the command&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span&gt; worktree add ..&#x2F;proj-ticket-yyyy bugfix&#x2F;ticket-yyyy
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The command is to be run from the root directory of your repo, but the worktree itself will be created in the parent directory (or elsewhere). There is no &lt;code&gt;.git&lt;&#x2F;code&gt; folder in the new folder that gets created, but instead it has a &lt;code&gt;.git&lt;&#x2F;code&gt; file. It is recommended to do it this way to avoid confusion from nesting folders in the same repo.&lt;&#x2F;p&gt;
&lt;p&gt;You can run git commands such as commit, push, pull, rebase etc. in the separate worktree folder even while another branch is checked out in your original folder.&lt;&#x2F;p&gt;
&lt;p&gt;Once you are done with the branch, you can run &lt;code&gt;git worktree remove .&lt;&#x2F;code&gt; to remove the folder with the worktree.&lt;&#x2F;p&gt;
&lt;p&gt;A worktree is also useful when doing code reviews if you want to check out an existing branch without moving away from whatever branch you were working on. This is especially useful on projects with long compile times when switching between branches.&lt;&#x2F;p&gt;
&lt;p&gt;Worktrees are also very useful when working with agentic coding tools like Claude Code. You can have multiple parallel instances of the AI working on different branches of the code simultaneously &lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=ntM7utSjeVU&quot;&gt;Git Worktrees - An Alternative to Git Stash&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.fsck.com&#x2F;2025&#x2F;10&#x2F;05&#x2F;how-im-using-coding-agents-in-september-2025&#x2F;&quot;&gt;How I am using Coding Agents in September 2025&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sandwich Bread v0.1 (Sep 2025) - 129 cal per 60g slice</title>
        <published>2025-09-25T03:24:50.136+00:00</published>
        <updated>2025-09-25T03:24:50.136+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202508242024-sandwich-bread-v0-1-sep-2025-129-cal-per-60g-slice/"/>
        <id>https://www.thomasantony.com/notes/202508242024-sandwich-bread-v0-1-sep-2025-129-cal-per-60g-slice/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202508242024-sandwich-bread-v0-1-sep-2025-129-cal-per-60g-slice/">&lt;h2 id=&quot;ingredients&quot;&gt;Ingredients&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Water - 131ml&lt;&#x2F;li&gt;
&lt;li&gt;2% Ultra-Filtered Milk - 93ml&lt;&#x2F;li&gt;
&lt;li&gt;All Purpose Flour - 320g&lt;&#x2F;li&gt;
&lt;li&gt;Red Star Instant Yeast - 8 g&lt;&#x2F;li&gt;
&lt;li&gt;Diamond Crystal salt - 6g&lt;&#x2F;li&gt;
&lt;li&gt;Granulated Sugar - 15g&lt;&#x2F;li&gt;
&lt;li&gt;Vital Wheat Gluten (Anthony’s) - 1.0 tbsp&lt;&#x2F;li&gt;
&lt;li&gt;Kerrygold Unsalted Butter - 30g&lt;&#x2F;li&gt;
&lt;li&gt;Diastatic malt (Hoosier Farms) - 10g&lt;&#x2F;li&gt;
&lt;li&gt;Ascorbic acid powder - 1&#x2F;8 tsp (very helpful for making the dough stronger)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;equipment&quot;&gt;Equipment&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Stand Mixer (you could make this with a no-knead process similar to what is described by Chain Baker, but I did not do that here)&lt;&#x2F;li&gt;
&lt;li&gt;Scale&lt;&#x2F;li&gt;
&lt;li&gt;Thermometer&lt;&#x2F;li&gt;
&lt;li&gt;Cutting board&#x2F;flat surface&lt;&#x2F;li&gt;
&lt;li&gt;Rolling pin&lt;&#x2F;li&gt;
&lt;li&gt;Loaf pan&lt;&#x2F;li&gt;
&lt;li&gt;Parchment paper&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;method&quot;&gt;Method&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Mix the water and milk. Microwave for ~10 seconds at a time until the temperature is around ~90F.&lt;&#x2F;li&gt;
&lt;li&gt;Add a small amount of sugar to the liquid and then add the yeast. Set aside for ~10 minutes for the yeast to “bloom”&lt;&#x2F;li&gt;
&lt;li&gt;Mix all the other dry ingredients (i.e. &lt;strong&gt;all except the butter&lt;&#x2F;strong&gt;) throughly (use a whisk or a sieve). You can also add it to the stand mixer and run with dough hook for a minute or so to mix it.&lt;&#x2F;li&gt;
&lt;li&gt;Add the yeast mixture with the stand mixer on its slowest setting until fully incorporated. Wait for the dough to form. If there are some dry bits at the bottom, add a bit more water about 1&#x2F;4 tsp at a time until a smooth dough ball forms.&lt;&#x2F;li&gt;
&lt;li&gt;Increase the speed of the mixer a couple of notches and run it for ~3 minutes. The dough should have developed a bit now and shouldn’t tear easily if pulled&lt;&#x2F;li&gt;
&lt;li&gt;Turn down the mixer’s speed and add the butter about one teaspoon at a time. Once all the butter is added, turn up the speed again. Run it for ~2-3 minutes, or until the dough is a smooth ball again. Adding in the butter will disrupt the gluten in the original dough ball so it might become a shaggy mess at first.&lt;&#x2F;li&gt;
&lt;li&gt;Once the dough is a smooth ball again and passes the window-pane test&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, cover the bowl with a towel and place in a warm area. One easy method is to run the oven (gas-fired) for 1 minute at whatever temperature and shut it off. It should then be approximately 90-100F. Let the dough rise for 1.5-2 hours.&lt;&#x2F;li&gt;
&lt;li&gt;The dough should now have doubled in size (or more). De-gas the dough by “punching it down”. Roll it out into a sheet about 1&#x2F;2 inch thick and about the same width as the loaf pan.&lt;&#x2F;li&gt;
&lt;li&gt;Spray the loaf pan with some oil, add a piece of parchment paper to cover the interior and place the dough into the loaf pan&lt;&#x2F;li&gt;
&lt;li&gt;Let the loaf pan sit in the same warm area as before, for another hour or so. The dough should now puff up again.&lt;&#x2F;li&gt;
&lt;li&gt;Pre-heat the oven to 350F (without the loaf-pan&#x2F;dough in it of course). Brush the outside of the bread with some milk for some extra browning. Bake the dough for ~25-30 minutes. When the bread is done, the interior temperature will be around 190F.&lt;&#x2F;li&gt;
&lt;li&gt;As prepared by me, this resulted in a loaf of approximately 700g. Sliced into 12 pieces, thats around 60 grams per slice.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;nutrition-facts&quot;&gt;Nutrition Facts&lt;&#x2F;h2&gt;
&lt;p&gt;Assuming each slice is ~60g (about 0.25 inches), the macros are the following (for the particular brand of ingredients that I used):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Calories: 129&lt;&#x2F;li&gt;
&lt;li&gt;Carbohydrates: 22.5g
&lt;ul&gt;
&lt;li&gt;Fiber: 0.8g&lt;&#x2F;li&gt;
&lt;li&gt;Sugar: 1.8g&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Fat: 2.5g
&lt;ul&gt;
&lt;li&gt;Saturated Fat: 1.4g&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Protein: 3.8g&lt;&#x2F;li&gt;
&lt;li&gt;Cholesterol: 6.2mg&lt;&#x2F;li&gt;
&lt;li&gt;Sodium: 212mg&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;remarks&quot;&gt;Remarks&lt;&#x2F;h2&gt;
&lt;p&gt;I adapted this from Joshua Weissman’s bread recipe&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. My inital attempts at increasing fiber&#x2F;protein failed miserably, and so I switched to the original reference recipe. I scaled it down to 75% to cut the calories, added the vitamin C&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#3&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; (ascorbic acid), hoping it would make the dough stronger and possibly bigger. And it seems to work! The dough, even if it is scaled down, completely filled and puffed up out of my loaf pan.&lt;&#x2F;p&gt;
&lt;p&gt;In the next version, I will try scaling it down further and adding a little bit more gluten and maybe some oat fiber.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=lipLAgZkWN0&quot;&gt;Joshua Weissman’s Sandwich Bread Recipe&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.kingarthurbaking.com&#x2F;blog&#x2F;2022&#x2F;10&#x2F;14&#x2F;what-is-the-windowpane-test-for-bread-dough&quot;&gt;What is the Windowpane Test for Bread Dough? - King Arthur Baking&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.chainbaker.com&#x2F;vitamin-c&#x2F;&quot;&gt;This is How Vitamin C (Ascorbic Acid) Affects Bread Dough - ChainBaker&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>IFR Alternate Requirements</title>
        <published>2025-05-26T18:00:35.953+00:00</published>
        <updated>2025-05-26T18:00:35.953+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202504261100-ifr-alternate-requirements/"/>
        <id>https://www.thomasantony.com/notes/202504261100-ifr-alternate-requirements/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202504261100-ifr-alternate-requirements/">&lt;h2 id=&quot;the-1-2-3-rule&quot;&gt;The 1-2-3 Rule&lt;&#x2F;h2&gt;
&lt;p&gt;For an IFR flight, you &lt;strong&gt;do not&lt;&#x2F;strong&gt; have to file an alternative if the following conditions are forecast at ETA +&#x2F;- &lt;strong&gt;1&lt;&#x2F;strong&gt; hour:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;At least &lt;strong&gt;2&lt;&#x2F;strong&gt;000 ft ceiling&lt;&#x2F;li&gt;
&lt;li&gt;At least &lt;strong&gt;3&lt;&#x2F;strong&gt; SM visibility&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;alternate-minimums&quot;&gt;Alternate Minimums&lt;&#x2F;h2&gt;
&lt;p&gt;In order to qualify as an alternate, an airport must be forecast to have at least:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;600 ft ceiling and 2 SM visibility for precision approaches&lt;&#x2F;li&gt;
&lt;li&gt;800 ft ceiling and 2 SM visibility for non-precision approaches&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If the airport has non-standard alternate minimums defined for it (identified by an “A” icon in the notes section of their FAA approach plates)), those values apply instead. These non-standard minima are published in the U.S. Terminal Procedures Publication (TPP).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Engine start procedure for Cirrus SR22T-G6</title>
        <published>2025-05-24T19:45:38.319+00:00</published>
        <updated>2025-05-24T19:45:38.319+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202504241245-engine-start-procedure-for-cirrus-sr22t-g6/"/>
        <id>https://www.thomasantony.com/notes/202504241245-engine-start-procedure-for-cirrus-sr22t-g6/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202504241245-engine-start-procedure-for-cirrus-sr22t-g6/">&lt;h2 id=&quot;cold-start-first-start-of-the-day-or-oil-temp-100f&quot;&gt;Cold Start (First start of the day or Oil temp &amp;lt; 100F)&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Mixture: Full Rich&lt;&#x2F;li&gt;
&lt;li&gt;Power Lever: Full Forward&lt;&#x2F;li&gt;
&lt;li&gt;Fuel Pump - PRIME (2-3 seconds), then BOOST&lt;&#x2F;li&gt;
&lt;li&gt;Power Lever: Open 1&#x2F;4 inch&lt;&#x2F;li&gt;
&lt;li&gt;Start&lt;&#x2F;li&gt;
&lt;li&gt;Oil pressure check, Amp check&lt;&#x2F;li&gt;
&lt;li&gt;Lean for Max RPM&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;hot-start-oil-temp-100f&quot;&gt;Hot Start (Oil temp &amp;gt; 100F)&lt;&#x2F;h2&gt;
&lt;p&gt;If the engine is warm, no priming is required. Remaining procedure is the same.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hot-start-oil-temp-is-nw-150f-and-200f&quot;&gt;Hot Start (Oil temp is nw&#x2F; 150F and 200F)&lt;&#x2F;h2&gt;
&lt;p&gt;Alternate technique:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;No priming&lt;&#x2F;li&gt;
&lt;li&gt;Mixture at cutoff, power at half (“W”)&lt;&#x2F;li&gt;
&lt;li&gt;Fuel pump to BOOST right as you turn ignition to START&lt;&#x2F;li&gt;
&lt;li&gt;Bring mixture to full rich over three seconds while cranking&lt;&#x2F;li&gt;
&lt;li&gt;Bring power back once engine starts&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;flooded-engine&quot;&gt;Flooded Engine&lt;&#x2F;h2&gt;
&lt;p&gt;Weak intermittent firing followed by puffs of black smoke from the exhaust stack indicates over-priming or flooding.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Turn fuel pump off&lt;&#x2F;li&gt;
&lt;li&gt;Allow fuel to drain from intake tubes&lt;&#x2F;li&gt;
&lt;li&gt;Set mixture to full lean, and power lever to full forward&lt;&#x2F;li&gt;
&lt;li&gt;Crank the engine through several turns&lt;&#x2F;li&gt;
&lt;li&gt;When engine starts, release ignition switch, retard power and add mixture to full rich&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt; Limit cranking to intervals of 10 seconds with a 20-second cooling period between cranks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;[1] Cirrus IFOM - Chapter 2, Section 5
[2] Cirrus SR22T-G6 POH - Section 4-11
[3] https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=eFAb9JK–HM&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cirrus SR22T: Abnormal Procedures for the Turbocharger</title>
        <published>2025-05-18T19:40:25.631+00:00</published>
        <updated>2025-05-18T19:40:25.631+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202504181240-cirrus-sr22t-abnormal-procedures-for-the-turbocharger/"/>
        <id>https://www.thomasantony.com/notes/202504181240-cirrus-sr22t-abnormal-procedures-for-the-turbocharger/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202504181240-cirrus-sr22t-abnormal-procedures-for-the-turbocharger/">&lt;p&gt;In the event of an unexplained loss of manifold pressure in an SR22T, the engine reverts to operating like a naturally aspirated engine. However, depending on the cause of the anomaly, this could be anything from a benign to a serious event. However, since it is not possible to accurately determine the exact cause, any such event should require an immediate diversion.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Induction leak&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This is on the “cold side” of the turbo (i.e with fresh air), and the intake air is leaking out before&#x2F;after it is pressurized. This is typically not a significant hazard and the only consequence is that the engine reverts to performance of a naturally aspirated engine. Adjust flight profile as necessary and land as soon as possible. However, the next three possibilities on the “hot side” could pose more significant hazards.&lt;&#x2F;p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Exhaust leak&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;An exhaust leak prior to the turbocharger could result in an engine fire if the high-velocity and hot exhaust gases interacts with combustible components at any point.&lt;&#x2F;p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Wastegate failure&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Wastegate is held closed by oil pressure. Loss of oil pressure would cause it to open, resulting in a loss of turbo performance. This could be a significant problem as the engine could get starved of oil. Monitor oil pressure.&lt;&#x2F;p&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Turbocharger failure&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The turbo is lubricated with oil, and so a failure here could also cause a loss of oil.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;itunes.apple.com&#x2F;WebObjects&#x2F;MZStore.woa&#x2F;wa&#x2F;viewBook?id=1072487639&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What Is A Schmitt Trigger?</title>
        <published>2025-03-25T04:55:30.123+00:00</published>
        <updated>2025-03-25T04:55:30.123+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202502242155-what-is-a-schmitt-trigger/"/>
        <id>https://www.thomasantony.com/notes/202502242155-what-is-a-schmitt-trigger/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202502242155-what-is-a-schmitt-trigger/">&lt;p&gt;A Schmitt trigger is a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Comparator&quot;&gt;Comparator&lt;&#x2F;a&gt; with hysteris. A typical comparator returns HIGH when the input exceeds a threshold and LOW once it is below. This can cause oscillations&#x2F;noise at borderline values. A Schmitt trigger instead has two thresholds. Between the two thresholds, the output does not change. The output goes LOW only once the input goes below the lower threshold and HIGH when it goes above the upper threshold. An inverting Schmitt trigger has basically the opposite output as the Schmitt trigger (put a NOT in front of it).&lt;&#x2F;p&gt;
&lt;p&gt;One simple application of this is for debouncing a button input.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;[1] https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=woTiKij76cA&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>SINDy: Sparse Identification of Nonlinear Dynamics</title>
        <published>2024-08-05T20:18:21.325+00:00</published>
        <updated>2024-08-05T20:18:21.325+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202407052118-sindy-sparse-identification-of-nonlinear-dynamics/"/>
        <id>https://www.thomasantony.com/notes/202407052118-sindy-sparse-identification-of-nonlinear-dynamics/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202407052118-sindy-sparse-identification-of-nonlinear-dynamics/">&lt;p&gt;SINDy&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; is an algorithm for identifying a nonlinear dynamic model from data. The algorithm fits a dynamic model, $\dot{x} = f(\mathbf{x}(t))$, for a state vector $\mathbf{x}$. Steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Sample $\mathbf{x}$ and $\mathbf{\dot{x}}$ at $m$ points in time into matrices $\mathbf{X}$ and $\mathbf{\dot{X}}$
. The derivative may also be approximated here using numerical methods.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Compute a “library” matrix $\Theta(\mathbf{X})$ where each column is a candidate nonlinear function like $1$, $X$, $X^2$, $\sin{X}$ etc. This is completely arbitrary and is chosen based on intuition or prior knowledge about the system.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A vector of coefficients $\Xi = {\xi_1, \xi_2, … }$ are fit such that $\mathbf{\dot{X}} = \Phi(\mathbf{X}) \Xi$. The fitting is done while encouraging sparsity in $\Xi$ in order to have the fewest number of terms in the final dynamic equations.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Libraries like PySINDy&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; implements this algorithm.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=NxAn0oglMVw&quot;&gt;Sparse Identification of Nonlinear Dynamics (SINDy): Sparse Machine Learning Models 5 Years Later&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pysindy.readthedocs.io&#x2F;en&#x2F;latest&#x2F;examples&#x2F;index.html&quot;&gt;PySINDy Examples&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fragment Shaders</title>
        <published>2023-11-16T02:42:56.608+00:00</published>
        <updated>2023-11-16T02:42:56.608+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202310151842-fragment-shaders/"/>
        <id>https://www.thomasantony.com/notes/202310151842-fragment-shaders/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202310151842-fragment-shaders/">&lt;p&gt;A fragment shader is a program that is part of a rendering pipeline&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; which takes as input a fragment (generated by rasterizing the outputs of a &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202310151836-vertex-shaders&#x2F;&quot;&gt;vertex shader&lt;&#x2F;a&gt;) and outputs a pixel color value and depth.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.khronos.org&#x2F;opengl&#x2F;wiki&#x2F;Fragment&quot;&gt;Fragment - OpenGL Wiki&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.khronos.org&#x2F;opengl&#x2F;wiki&#x2F;Fragment_Shader&quot;&gt;Fragment Shader - OpenGL Wiki&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.khronos.org&#x2F;opengl&#x2F;wiki&#x2F;Rendering_Pipeline_Overview&quot;&gt;Rendering Pipeline Overview - OpenGL Wiki&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Vertex Shaders</title>
        <published>2023-11-16T02:36:56.132+00:00</published>
        <updated>2023-11-16T02:36:56.132+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202310151836-vertex-shaders/"/>
        <id>https://www.thomasantony.com/notes/202310151836-vertex-shaders/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202310151836-vertex-shaders/">&lt;p&gt;A vertex shader is a program that runs on the GPU that is one of the stages in a “rendering pipeline” (e.g. the OpenGL rendering pipelline&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;). It is typically written ina special programming language such as GLSL&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#3&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; or WGSL&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#4&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. The job of a vertex shader is to take a single vertex as input and output a single vertex (usually in 4D homogenous coordinates), in “clip-space”, after doing some user-defined transformation on it. It may also generate other user-defined outputs.&lt;&#x2F;p&gt;
&lt;p&gt;The rendering pipeline takes these outputs and the output vertex and then interpolates them to generate values for points between two vertices (e.g. on a triangle formed by three vertices). These are called “Fragments”. The pipeline then eventually calls the &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202310151842-fragment-shaders&#x2F;&quot;&gt;fragment shader&lt;&#x2F;a&gt; to generate pixels (of some color) corresponding to these fragments.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;4&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.khronos.org&#x2F;opengl&#x2F;wiki&#x2F;Vertex_Shader&quot;&gt;Vertex Shader - OpenGL Wiki&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.khronos.org&#x2F;opengl&#x2F;wiki&#x2F;Rendering_Pipeline_Overview&quot;&gt;Rendering Pipeline Overview - OpenGL Wiki&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;3&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;OpenGL_Shading_Language&quot;&gt;GLSL&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;4&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;3&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;google.github.io&#x2F;tour-of-wgsl&#x2F;&quot;&gt;WebGPU Shading Language&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Understanding 3D Gaussian Splats by writing a software renderer</title>
        <published>2023-11-13T19:10:35-08:00</published>
        <updated>2023-11-13T19:10:35-08:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/posts/2023/gaussian-splatting-renderer/"/>
        <id>https://www.thomasantony.com/posts/2023/gaussian-splatting-renderer/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/posts/2023/gaussian-splatting-renderer/">&lt;p&gt;If you want to skip to the code, you can find it &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;splat&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;repo-sam.inria.fr&#x2F;fungraph&#x2F;3d-gaussian-splatting&#x2F;&quot;&gt;3D gaussian splats&lt;&#x2F;a&gt; have been all the rage since they were published. They may end up revolutionizing how we model realistic 3D worlds and seems to be the successor to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.nerf.studio&#x2F;&quot;&gt;NeRFs&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Most of the articles that I have seen about them addresses the training-side of it (which is arguably more important). Hardly any addresses the nitty-gritty details on how to parse a pre-trained model and view it. While differentiable rendering is a key part of what makes this technology possible, the differentiable part is not really necessary if all you are interested in is viewing a pre-trained model.&lt;&#x2F;p&gt;
&lt;p&gt;There are a few indepndantly written renderers on github - most of them using OpenGL, and some using WebGPU or WebGL. Some of the Python versions require CUDA (and are hence tied to NVIDIA systems). There is also a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Lichtso&#x2F;splatter&quot;&gt;Rust version&lt;&#x2F;a&gt; that is pretty platform-agnostic.&lt;&#x2F;p&gt;
&lt;p&gt;However, even the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;limacv&#x2F;GaussianSplattingViewer&quot;&gt;simplest&lt;&#x2F;a&gt; of these use shaders - pieces of code written a special languages that run on the GPU. The particular example I linked also depends on OpenGL 4.3 and hence does not run on macOS.&lt;&#x2F;p&gt;
&lt;p&gt;My goal with this project was to write a renderer in plain Rust, doing all the rendering math on the CPU. And after spinning my wheels for a bit, I realized that I need to start even simpler - with a version written in pure Python in a [Jupyter notebook].&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-are-3d-gaussian-splats&quot;&gt;What are 3D gaussian splats?&lt;&#x2F;h2&gt;
&lt;p&gt;3D Gaussian Splats are a method of encoding information from a scene such that we can synthesize “novel views”, that were not in the original set of photos used to generate it. There are some very neat examples on the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;repo-sam.inria.fr&#x2F;fungraph&#x2F;3d-gaussian-splatting&#x2F;&quot;&gt;official site&lt;&#x2F;a&gt; for the paper. There have been also been a few web-based viwers (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gsplat.tech&#x2F;&quot;&gt;https:&#x2F;&#x2F;gsplat.tech&#x2F;&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;poly.cam&#x2F;gaussian-splatting&quot;&gt;https:&#x2F;&#x2F;poly.cam&#x2F;gaussian-splatting&lt;&#x2F;a&gt; ) that show off some really good examples.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;results&quot;&gt;Results&lt;&#x2F;h2&gt;
&lt;p&gt;As of the time of writing, I have a working CPU-based Gaussian splat renderer prototype written in Python and a faster one written in Rust. On my M1 Max Macbook Pro, the Python version takes about 2-3 minutes to render a 2560x1440 image for the “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gsplat.tech&#x2F;&quot;&gt;push sledge&lt;&#x2F;a&gt;” model (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;media.reshot.ai&#x2F;models&#x2F;plush_sledge&#x2F;output.zip&quot;&gt;download here&lt;&#x2F;a&gt;) with about ~284000 gaussians in it. The Rust version renders the same model pretty much instantly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How it works&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;python-version&quot;&gt;Python version&lt;&#x2F;h3&gt;
&lt;p&gt;While the CPU-based renderer does not use any OpenGL or WebGPU shaders, it still follows mostly the same logic. For the Python version, I had to add in some (not-so-efficient) versions of things that are typically handled by the graphics rendering pipeline on a GPU. Here is the overall workflow for the renderer in the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;splat&#x2F;blob&#x2F;master&#x2F;notes&#x2F;00_Gaussian_Projection.ipynb&quot;&gt;Jupyter notebook&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Load the gaussians from the .ply file. I used the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;ply-rs&#x2F;latest&#x2F;ply_rs&#x2F;&quot;&gt;ply-rs&lt;&#x2F;a&gt; crate in the Rust version and the &lt;code&gt;load_plyfile&lt;&#x2F;code&gt; functions from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;limacv&#x2F;GaussianSplattingViewer&#x2F;blob&#x2F;main&#x2F;util_gau.py&quot;&gt;util_gau.py&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;tqdm &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;tqdm
&lt;&#x2F;span&gt;&lt;span&gt; model = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;load_ply&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;point_cloud.ply&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Loading gaussians ...&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt; gaussian_objects = []
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;(pos, scale, rot, opacity, sh) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;tqdm&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;zip&lt;&#x2F;span&gt;&lt;span&gt;(model.xyz, model.scale, model.rot, model.opacity, model.sh)):
&lt;&#x2F;span&gt;&lt;span&gt;     gaussian_objects.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gaussian&lt;&#x2F;span&gt;&lt;span&gt;(pos, scale, rot, opacity, sh))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Initialize a Camera model with a certain dimensions and position. I used one based off of the version at https:&#x2F;&#x2F;github.com&#x2F;limacv&#x2F;GaussianSplattingViewer&#x2F; .&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt; (h, w) = (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;720&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1280&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt; camera = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Camera&lt;&#x2F;span&gt;&lt;span&gt;(h, w, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;position&lt;&#x2F;span&gt;&lt;span&gt;=(-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.57651054&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2.99040512&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.03924271&lt;&#x2F;span&gt;&lt;span&gt;), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;target&lt;&#x2F;span&gt;&lt;span&gt;=(-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Sort the gaussians by depth from the camera model (this may need to be repeated if the camera can be moved).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Sorting the gaussians by depth&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt; indices = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;argsort&lt;&#x2F;span&gt;&lt;span&gt;([gau.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;get_depth&lt;&#x2F;span&gt;&lt;span&gt;(camera) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;gau &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;gaussian_objects])
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;xoft.tistory.com&#x2F;49&quot;&gt;Project the 3D gaussians&lt;&#x2F;a&gt; on to the camera plane to form ellipses. Compute the parameters of this ellipse (which represents a 2D gaussian and is represted by a variable called &lt;code&gt;conic&lt;&#x2F;code&gt;). See the &lt;code&gt;get_cov2d()&lt;&#x2F;code&gt; and the &lt;code&gt;get_conic_and_bb()&lt;&#x2F;code&gt; methods in the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;splat&#x2F;blob&#x2F;master&#x2F;notes&#x2F;00_Gaussian_Projection.ipynb&quot;&gt;Jupyter notebook&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This step is a quirk of how graphics rendering pipelines work. We start with a list of four 3D vertices (called a “quad”). In a typical 3D rendering pipeline, these may be actual vertices from a 3D model. In our case, we make the quad cover the entire screen. This is represented by the vertices [-1, 1], [1, 1], [1, -1] and [-1, -1]. This is essentially a square centered at the origin. These are in something called “Normalized Device Coordinates” which is agnostic to the actual resolution of the camera model or the screen.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;    vertices = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;array&lt;&#x2F;span&gt;&lt;span&gt;([[-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;], [-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]])
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Four values (bounds of the values used to evaluate gaussian)
&lt;&#x2F;span&gt;&lt;span&gt;    bboxsize_cam = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;multiply&lt;&#x2F;span&gt;&lt;span&gt;(vertices, bboxsize_cam)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    view_matrix = camera.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;get_view_matrix&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;    projection_matrix = camera.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;get_projection_matrix&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    position4 = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.pos, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    g_pos_view = view_matrix @ position4
&lt;&#x2F;span&gt;&lt;span&gt;    g_pos_screen = projection_matrix @ g_pos_view
&lt;&#x2F;span&gt;&lt;span&gt;    g_pos_screen = g_pos_screen &#x2F; g_pos_screen[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Bounds of gaussian in Normalized Device Coordinates (-1 to 1)
&lt;&#x2F;span&gt;&lt;span&gt;    bbox_ndc = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;multiply&lt;&#x2F;span&gt;&lt;span&gt;(vertices, bboxsize_ndc) + g_pos_screen[:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    bbox_ndc = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;hstack&lt;&#x2F;span&gt;&lt;span&gt;((bbox_ndc, np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;zeros&lt;&#x2F;span&gt;&lt;span&gt;((vertices.shape[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))))
&lt;&#x2F;span&gt;&lt;span&gt;    bbox_ndc[:,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;] = g_pos_screen[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Since the final rendered view consists of a combination of all the gaussians, we add identical full-screen quads for each gaussian and procees them one by one. For each one, we generate the 2D gaussian parameters, as well as the bounding box of the gaussian in screen-coordinates.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In an actual graphics pipeline, this bounding box is then used to determine what pixels to draw on the screen. Since we are doing everything manually in the Python version, I scale the 2D gaussian bounding box by the screen size and iterate over each pixel within it, one by one. See the &lt;code&gt;plot_opacity()&lt;&#x2F;code&gt; function in the notebook for details.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For each pixel, sample the gaussian to obtain the opacity (alpha) value. Use the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;xoft.tistory.com&#x2F;50&quot;&gt;spherical harmonics coefficients&lt;&#x2F;a&gt; to determine the RGB color of the pixel for the particular viewing direction from the camera to the gaussian. This pixel value is then added to the output image.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;rust-version&quot;&gt;Rust version&lt;&#x2F;h3&gt;
&lt;p&gt;The Rust version uses the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zesterer&#x2F;euc&quot;&gt;euc&lt;&#x2F;a&gt; software rendering crate. I define a rendering pipeline with a “vertex” and “fragment” shader. It works very similar to how OpenGL or other graphics library does things. So I did not have to iterate over individual pixels like I did in the Python version.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;repository-layout&quot;&gt;Repository layout&lt;&#x2F;h3&gt;
&lt;p&gt;Github: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;splat&#x2F;&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;splat&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;.
&lt;&#x2F;span&gt;&lt;span&gt;├── Cargo.lock
&lt;&#x2F;span&gt;&lt;span&gt;├── Cargo.toml
&lt;&#x2F;span&gt;&lt;span&gt;├── LICENSE
&lt;&#x2F;span&gt;&lt;span&gt;├── README.md
&lt;&#x2F;span&gt;&lt;span&gt;├── notes
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── 00_Gaussian_Projection.ipynb  &amp;lt;--- Python prototype
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── requirements.txt              &amp;lt;--- install before running notebook
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── util.py
&lt;&#x2F;span&gt;&lt;span&gt;│   └── util_gau.py
&lt;&#x2F;span&gt;&lt;span&gt;├── notes.md
&lt;&#x2F;span&gt;&lt;span&gt;├── src
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── bin
&lt;&#x2F;span&gt;&lt;span&gt;│   │   ├── 00_ply_load.rs        &amp;lt;-- PLY file loading in Rust
&lt;&#x2F;span&gt;&lt;span&gt;│   │   ├── 01_naive_gaussian.rs  &amp;lt;-- Rendering some hard-coded gaussians
&lt;&#x2F;span&gt;&lt;span&gt;│   │   ├── 02_ply_demo.rs        &amp;lt;-- First version the worked
&lt;&#x2F;span&gt;&lt;span&gt;│   │   └── attempt03.rs          &amp;lt;-- incomplete attempt at a different approach
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── camera.rs
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── gaussians.rs
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── lib.rs
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── main.rs                   &amp;lt;-- Current version
&lt;&#x2F;span&gt;&lt;span&gt;│   └── pipelines.rs
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;When working on a new project, it is always better if you have a working example, or at least some kind of data or reference that you can use to figure out if you are going in the right direction. In this case, the “naive gaussians” example from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;limacv&#x2F;GaussianSplattingViewer&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;limacv&#x2F;GaussianSplattingViewer&lt;&#x2F;a&gt;, as well as viewing the GPU buffers for that code using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;renderdoc.org&#x2F;&quot;&gt;RenderDoc&lt;&#x2F;a&gt; was extremely helpful&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Unless you are familiar with the field, it is really easy to mess up simple things like loading data from a data file. For example, the PLY model files used for storing the gaussian splats all contain fields called &lt;code&gt;opacity&lt;&#x2F;code&gt; and &lt;code&gt;scale&lt;&#x2F;code&gt;, the former being the visual opacity of the gaussian and the latter being a 3-vector describing the spread of the gaussian. It is easy to assume that &lt;code&gt;opacity&lt;&#x2F;code&gt; is a value between &lt;code&gt;[0,1]&lt;&#x2F;code&gt; and &lt;code&gt;scale&lt;&#x2F;code&gt; can be used directly to scale the gaussians. It turned out that the opacity was actually &lt;code&gt;log(opacity)&lt;&#x2F;code&gt; and had to be exponentiated before use.  Similarly, the &lt;code&gt;scale&lt;&#x2F;code&gt; parameter had to be passed through a sigmoid function before use. For someone not too familar with this field, it seems entirely arbitrary (though it makes sense later once you read about it). I would have been stuck with this for a lot longer if I had not seen the existing examples.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;      ...
&lt;&#x2F;span&gt;&lt;span&gt;      (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;scale_0&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, Property::Float(v)) =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.scale[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] = v.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;exp&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;      (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;scale_1&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, Property::Float(v)) =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.scale[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;] = v.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;exp&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;      (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;scale_2&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, Property::Float(v)) =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.scale[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;] = v.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;exp&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;      (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;opacity&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, Property::Float(v)) =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.opacity = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1.0 &lt;&#x2F;span&gt;&lt;span&gt;&#x2F; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1.0 &lt;&#x2F;span&gt;&lt;span&gt;+ (-v).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;exp&lt;&#x2F;span&gt;&lt;span&gt;()),
&lt;&#x2F;span&gt;&lt;span&gt;      ...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;nalgebra.org&#x2F;&quot;&gt;nalgebra&lt;&#x2F;a&gt; crate, while being a great library for numerical manipulation, has some quirks that can trip you up. For example, if you print a matrix using the debug formatter (&lt;code&gt;{:?}&lt;&#x2F;code&gt;), it will print the transpose of the matrix for some reason. This led to me wasting a couple of hours trying to figure out why matrix multiplication no longer worked how I thought it did.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-a.max(b)&lt;&#x2F;code&gt; is not the same as &lt;code&gt;(-a).max(b)&lt;&#x2F;code&gt; in Rust&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;renderdoc.org&#x2F;&quot;&gt;RenderDoc&lt;&#x2F;a&gt; does not seem to be able to capture frames from OpenGL programs run in WSL2&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;What’s Next&lt;&#x2F;h2&gt;
&lt;p&gt;While the Python version is far from being real-time, it seems like the rust version is performant enough to run in real-time. Some possible improvements:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use “structure-of-arrays” layout to hold the data. This may make a few operations such as sorting the gaussians significantly faster. I opted for array-of-structures in the current version due to how the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;ply-rs&#x2F;latest&#x2F;ply_rs&#x2F;&quot;&gt;ply-rs&lt;&#x2F;a&gt; file parses data from the point cloud (PLY) files.&lt;&#x2F;li&gt;
&lt;li&gt;Use a “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zesterer&#x2F;euc&#x2F;blob&#x2F;290e14c0cbe7505867c44ca33a994a9fcfa00fb1&#x2F;src&#x2F;pipeline.rs#L221&quot;&gt;geometry shader&lt;&#x2F;a&gt;” to generate the vertices for each gaussian.&lt;&#x2F;li&gt;
&lt;li&gt;Add camera controls using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;emilk&#x2F;egui&quot;&gt;egui&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;imgui-rs&#x2F;imgui-rs&quot;&gt;imgui&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;&#x2F;h2&gt;
&lt;p&gt;The following articles&#x2F;code bases were extremely helpful in teaching me about how 3D Gaussian Splats work&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@AriaLeeNotAriel&#x2F;numbynum-3d-gaussian-splatting-for-real-time-radiance-field-rendering-kerbl-et-al-60c0b25e5544&quot;&gt;numbyNum :: 3D Gaussian Splatting for Real-Time Radiance Field Rendering (Reviewed) | Medium&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reshot.ai&#x2F;3d-gaussian-splatting&quot;&gt;3D Gaussian Splatting -
A beginner friendly introduction to 3D Gaussian Splats and tutorial on how to train them.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;limacv&#x2F;GaussianSplattingViewer&quot;&gt;limacv&#x2F;GaussianSplattingViewer&lt;&#x2F;a&gt; - most of my code is based on the vertex and fragment shader code in this repository. Also &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;renderdoc.org&#x2F;&quot;&gt;RenderDoc&lt;&#x2F;a&gt; for digging into this program further.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;xoft.tistory.com&#x2F;49&quot;&gt;[Concept summary] 3D Gaussian and 2D projection&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Understanding 3D Gaussian Splats by writing a software renderer</title>
        <published>2023-11-13T19:10:35-08:00</published>
        <updated>2023-11-13T19:10:35-08:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/posts/gaussian-splatting-renderer/"/>
        <id>https://www.thomasantony.com/posts/gaussian-splatting-renderer/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/posts/gaussian-splatting-renderer/">&lt;p&gt;If you want to skip to the code, you can find it &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;splat&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;repo-sam.inria.fr&#x2F;fungraph&#x2F;3d-gaussian-splatting&#x2F;&quot;&gt;3D gaussian splats&lt;&#x2F;a&gt; have been all the rage since they were published. They may end up revolutionizing how we model realistic 3D worlds and seems to be the successor to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.nerf.studio&#x2F;&quot;&gt;NeRFs&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Most of the articles that I have seen about them addresses the training-side of it (which is arguably more important). Hardly any addresses the nitty-gritty details on how to parse a pre-trained model and view it. While differentiable rendering is a key part of what makes this technology possible, the differentiable part is not really necessary if all you are interested in is viewing a pre-trained model.&lt;&#x2F;p&gt;
&lt;p&gt;There are a few indepndantly written renderers on github - most of them using OpenGL, and some using WebGPU or WebGL. Some of the Python versions require CUDA (and are hence tied to NVIDIA systems). There is also a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Lichtso&#x2F;splatter&quot;&gt;Rust version&lt;&#x2F;a&gt; that is pretty platform-agnostic.&lt;&#x2F;p&gt;
&lt;p&gt;However, even the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;limacv&#x2F;GaussianSplattingViewer&quot;&gt;simplest&lt;&#x2F;a&gt; of these use shaders - pieces of code written a special languages that run on the GPU. The particular example I linked also depends on OpenGL 4.3 and hence does not run on macOS.&lt;&#x2F;p&gt;
&lt;p&gt;My goal with this project was to write a renderer in plain Rust, doing all the rendering math on the CPU. And after spinning my wheels for a bit, I realized that I need to start even simpler - with a version written in pure Python in a [Jupyter notebook].&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-are-3d-gaussian-splats&quot;&gt;What are 3D gaussian splats?&lt;&#x2F;h2&gt;
&lt;p&gt;3D Gaussian Splats are a method of encoding information from a scene such that we can synthesize “novel views”, that were not in the original set of photos used to generate it. There are some very neat examples on the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;repo-sam.inria.fr&#x2F;fungraph&#x2F;3d-gaussian-splatting&#x2F;&quot;&gt;official site&lt;&#x2F;a&gt; for the paper. There have been also been a few web-based viwers (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gsplat.tech&#x2F;&quot;&gt;https:&#x2F;&#x2F;gsplat.tech&#x2F;&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;poly.cam&#x2F;gaussian-splatting&quot;&gt;https:&#x2F;&#x2F;poly.cam&#x2F;gaussian-splatting&lt;&#x2F;a&gt; ) that show off some really good examples.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;results&quot;&gt;Results&lt;&#x2F;h2&gt;
&lt;p&gt;As of the time of writing, I have a working CPU-based Gaussian splat renderer prototype written in Python and a faster one written in Rust. On my M1 Max Macbook Pro, the Python version takes about 2-3 minutes to render a 2560x1440 image for the “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gsplat.tech&#x2F;&quot;&gt;push sledge&lt;&#x2F;a&gt;” model (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;media.reshot.ai&#x2F;models&#x2F;plush_sledge&#x2F;output.zip&quot;&gt;download here&lt;&#x2F;a&gt;) with about ~284000 gaussians in it. The Rust version renders the same model pretty much instantly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How it works&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;python-version&quot;&gt;Python version&lt;&#x2F;h3&gt;
&lt;p&gt;While the CPU-based renderer does not use any OpenGL or WebGPU shaders, it still follows mostly the same logic. For the Python version, I had to add in some (not-so-efficient) versions of things that are typically handled by the graphics rendering pipeline on a GPU. Here is the overall workflow for the renderer in the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;splat&#x2F;blob&#x2F;master&#x2F;notes&#x2F;00_Gaussian_Projection.ipynb&quot;&gt;Jupyter notebook&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Load the gaussians from the .ply file. I used the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;ply-rs&#x2F;latest&#x2F;ply_rs&#x2F;&quot;&gt;ply-rs&lt;&#x2F;a&gt; crate in the Rust version and the &lt;code&gt;load_plyfile&lt;&#x2F;code&gt; functions from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;limacv&#x2F;GaussianSplattingViewer&#x2F;blob&#x2F;main&#x2F;util_gau.py&quot;&gt;util_gau.py&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;tqdm &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;tqdm
&lt;&#x2F;span&gt;&lt;span&gt; model = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;load_ply&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;point_cloud.ply&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Loading gaussians ...&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt; gaussian_objects = []
&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;(pos, scale, rot, opacity, sh) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;tqdm&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;zip&lt;&#x2F;span&gt;&lt;span&gt;(model.xyz, model.scale, model.rot, model.opacity, model.sh)):
&lt;&#x2F;span&gt;&lt;span&gt;     gaussian_objects.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gaussian&lt;&#x2F;span&gt;&lt;span&gt;(pos, scale, rot, opacity, sh))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Initialize a Camera model with a certain dimensions and position. I used one based off of the version at https:&#x2F;&#x2F;github.com&#x2F;limacv&#x2F;GaussianSplattingViewer&#x2F; .&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt; (h, w) = (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;720&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1280&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt; camera = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Camera&lt;&#x2F;span&gt;&lt;span&gt;(h, w, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;position&lt;&#x2F;span&gt;&lt;span&gt;=(-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.57651054&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2.99040512&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.03924271&lt;&#x2F;span&gt;&lt;span&gt;), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;target&lt;&#x2F;span&gt;&lt;span&gt;=(-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.0&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Sort the gaussians by depth from the camera model (this may need to be repeated if the camera can be moved).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Sorting the gaussians by depth&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt; indices = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;argsort&lt;&#x2F;span&gt;&lt;span&gt;([gau.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;get_depth&lt;&#x2F;span&gt;&lt;span&gt;(camera) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;gau &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;gaussian_objects])
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;xoft.tistory.com&#x2F;49&quot;&gt;Project the 3D gaussians&lt;&#x2F;a&gt; on to the camera plane to form ellipses. Compute the parameters of this ellipse (which represents a 2D gaussian and is represted by a variable called &lt;code&gt;conic&lt;&#x2F;code&gt;). See the &lt;code&gt;get_cov2d()&lt;&#x2F;code&gt; and the &lt;code&gt;get_conic_and_bb()&lt;&#x2F;code&gt; methods in the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;splat&#x2F;blob&#x2F;master&#x2F;notes&#x2F;00_Gaussian_Projection.ipynb&quot;&gt;Jupyter notebook&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This step is a quirk of how graphics rendering pipelines work. We start with a list of four 3D vertices (called a “quad”). In a typical 3D rendering pipeline, these may be actual vertices from a 3D model. In our case, we make the quad cover the entire screen. This is represented by the vertices [-1, 1], [1, 1], [1, -1] and [-1, -1]. This is essentially a square centered at the origin. These are in something called “Normalized Device Coordinates” which is agnostic to the actual resolution of the camera model or the screen.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;    vertices = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;array&lt;&#x2F;span&gt;&lt;span&gt;([[-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;], [-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]])
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Four values (bounds of the values used to evaluate gaussian)
&lt;&#x2F;span&gt;&lt;span&gt;    bboxsize_cam = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;multiply&lt;&#x2F;span&gt;&lt;span&gt;(vertices, bboxsize_cam)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    view_matrix = camera.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;get_view_matrix&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;    projection_matrix = camera.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;get_projection_matrix&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    position4 = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.pos, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    g_pos_view = view_matrix @ position4
&lt;&#x2F;span&gt;&lt;span&gt;    g_pos_screen = projection_matrix @ g_pos_view
&lt;&#x2F;span&gt;&lt;span&gt;    g_pos_screen = g_pos_screen &#x2F; g_pos_screen[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Bounds of gaussian in Normalized Device Coordinates (-1 to 1)
&lt;&#x2F;span&gt;&lt;span&gt;    bbox_ndc = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;multiply&lt;&#x2F;span&gt;&lt;span&gt;(vertices, bboxsize_ndc) + g_pos_screen[:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    bbox_ndc = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;hstack&lt;&#x2F;span&gt;&lt;span&gt;((bbox_ndc, np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;zeros&lt;&#x2F;span&gt;&lt;span&gt;((vertices.shape[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))))
&lt;&#x2F;span&gt;&lt;span&gt;    bbox_ndc[:,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;] = g_pos_screen[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Since the final rendered view consists of a combination of all the gaussians, we add identical full-screen quads for each gaussian and procees them one by one. For each one, we generate the 2D gaussian parameters, as well as the bounding box of the gaussian in screen-coordinates.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In an actual graphics pipeline, this bounding box is then used to determine what pixels to draw on the screen. Since we are doing everything manually in the Python version, I scale the 2D gaussian bounding box by the screen size and iterate over each pixel within it, one by one. See the &lt;code&gt;plot_opacity()&lt;&#x2F;code&gt; function in the notebook for details.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For each pixel, sample the gaussian to obtain the opacity (alpha) value. Use the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;xoft.tistory.com&#x2F;50&quot;&gt;spherical harmonics coefficients&lt;&#x2F;a&gt; to determine the RGB color of the pixel for the particular viewing direction from the camera to the gaussian. This pixel value is then added to the output image.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;rust-version&quot;&gt;Rust version&lt;&#x2F;h3&gt;
&lt;p&gt;The Rust version uses the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zesterer&#x2F;euc&quot;&gt;euc&lt;&#x2F;a&gt; software rendering crate. I define a rendering pipeline with a “vertex” and “fragment” shader. It works very similar to how OpenGL or other graphics library does things. So I did not have to iterate over individual pixels like I did in the Python version.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;repository-layout&quot;&gt;Repository layout&lt;&#x2F;h3&gt;
&lt;p&gt;Github: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;splat&#x2F;&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;splat&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;.
&lt;&#x2F;span&gt;&lt;span&gt;├── Cargo.lock
&lt;&#x2F;span&gt;&lt;span&gt;├── Cargo.toml
&lt;&#x2F;span&gt;&lt;span&gt;├── LICENSE
&lt;&#x2F;span&gt;&lt;span&gt;├── README.md
&lt;&#x2F;span&gt;&lt;span&gt;├── notes
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── 00_Gaussian_Projection.ipynb  &amp;lt;--- Python prototype
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── requirements.txt              &amp;lt;--- install before running notebook
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── util.py
&lt;&#x2F;span&gt;&lt;span&gt;│   └── util_gau.py
&lt;&#x2F;span&gt;&lt;span&gt;├── notes.md
&lt;&#x2F;span&gt;&lt;span&gt;├── src
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── bin
&lt;&#x2F;span&gt;&lt;span&gt;│   │   ├── 00_ply_load.rs        &amp;lt;-- PLY file loading in Rust
&lt;&#x2F;span&gt;&lt;span&gt;│   │   ├── 01_naive_gaussian.rs  &amp;lt;-- Rendering some hard-coded gaussians
&lt;&#x2F;span&gt;&lt;span&gt;│   │   ├── 02_ply_demo.rs        &amp;lt;-- First version the worked
&lt;&#x2F;span&gt;&lt;span&gt;│   │   └── attempt03.rs          &amp;lt;-- incomplete attempt at a different approach
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── camera.rs
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── gaussians.rs
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── lib.rs
&lt;&#x2F;span&gt;&lt;span&gt;│   ├── main.rs                   &amp;lt;-- Current version
&lt;&#x2F;span&gt;&lt;span&gt;│   └── pipelines.rs
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;When working on a new project, it is always better if you have a working example, or at least some kind of data or reference that you can use to figure out if you are going in the right direction. In this case, the “naive gaussians” example from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;limacv&#x2F;GaussianSplattingViewer&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;limacv&#x2F;GaussianSplattingViewer&lt;&#x2F;a&gt;, as well as viewing the GPU buffers for that code using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;renderdoc.org&#x2F;&quot;&gt;RenderDoc&lt;&#x2F;a&gt; was extremely helpful&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Unless you are familiar with the field, it is really easy to mess up simple things like loading data from a data file. For example, the PLY model files used for storing the gaussian splats all contain fields called &lt;code&gt;opacity&lt;&#x2F;code&gt; and &lt;code&gt;scale&lt;&#x2F;code&gt;, the former being the visual opacity of the gaussian and the latter being a 3-vector describing the spread of the gaussian. It is easy to assume that &lt;code&gt;opacity&lt;&#x2F;code&gt; is a value between &lt;code&gt;[0,1]&lt;&#x2F;code&gt; and &lt;code&gt;scale&lt;&#x2F;code&gt; can be used directly to scale the gaussians. It turned out that the opacity was actually &lt;code&gt;log(opacity)&lt;&#x2F;code&gt; and had to be exponentiated before use.  Similarly, the &lt;code&gt;scale&lt;&#x2F;code&gt; parameter had to be passed through a sigmoid function before use. For someone not too familar with this field, it seems entirely arbitrary (though it makes sense later once you read about it). I would have been stuck with this for a lot longer if I had not seen the existing examples.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;      ...
&lt;&#x2F;span&gt;&lt;span&gt;      (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;scale_0&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, Property::Float(v)) =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.scale[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;] = v.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;exp&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;      (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;scale_1&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, Property::Float(v)) =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.scale[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;] = v.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;exp&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;      (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;scale_2&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, Property::Float(v)) =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.scale[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;] = v.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;exp&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;      (&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;opacity&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, Property::Float(v)) =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.opacity = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1.0 &lt;&#x2F;span&gt;&lt;span&gt;&#x2F; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1.0 &lt;&#x2F;span&gt;&lt;span&gt;+ (-v).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;exp&lt;&#x2F;span&gt;&lt;span&gt;()),
&lt;&#x2F;span&gt;&lt;span&gt;      ...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;nalgebra.org&#x2F;&quot;&gt;nalgebra&lt;&#x2F;a&gt; crate, while being a great library for numerical manipulation, has some quirks that can trip you up. For example, if you print a matrix using the debug formatter (&lt;code&gt;{:?}&lt;&#x2F;code&gt;), it will print the transpose of the matrix for some reason. This led to me wasting a couple of hours trying to figure out why matrix multiplication no longer worked how I thought it did.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-a.max(b)&lt;&#x2F;code&gt; is not the same as &lt;code&gt;(-a).max(b)&lt;&#x2F;code&gt; in Rust&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;renderdoc.org&#x2F;&quot;&gt;RenderDoc&lt;&#x2F;a&gt; does not seem to be able to capture frames from OpenGL programs run in WSL2&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;What’s Next&lt;&#x2F;h2&gt;
&lt;p&gt;While the Python version is far from being real-time, it seems like the rust version is performant enough to run in real-time. Some possible improvements:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use “structure-of-arrays” layout to hold the data. This may make a few operations such as sorting the gaussians significantly faster. I opted for array-of-structures in the current version due to how the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;ply-rs&#x2F;latest&#x2F;ply_rs&#x2F;&quot;&gt;ply-rs&lt;&#x2F;a&gt; file parses data from the point cloud (PLY) files.&lt;&#x2F;li&gt;
&lt;li&gt;Use a “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zesterer&#x2F;euc&#x2F;blob&#x2F;290e14c0cbe7505867c44ca33a994a9fcfa00fb1&#x2F;src&#x2F;pipeline.rs#L221&quot;&gt;geometry shader&lt;&#x2F;a&gt;” to generate the vertices for each gaussian.&lt;&#x2F;li&gt;
&lt;li&gt;Add camera controls using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;emilk&#x2F;egui&quot;&gt;egui&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;imgui-rs&#x2F;imgui-rs&quot;&gt;imgui&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;&#x2F;h2&gt;
&lt;p&gt;The following articles&#x2F;code bases were extremely helpful in teaching me about how 3D Gaussian Splats work&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@AriaLeeNotAriel&#x2F;numbynum-3d-gaussian-splatting-for-real-time-radiance-field-rendering-kerbl-et-al-60c0b25e5544&quot;&gt;numbyNum :: 3D Gaussian Splatting for Real-Time Radiance Field Rendering (Reviewed) | Medium&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reshot.ai&#x2F;3d-gaussian-splatting&quot;&gt;3D Gaussian Splatting -
A beginner friendly introduction to 3D Gaussian Splats and tutorial on how to train them.&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;limacv&#x2F;GaussianSplattingViewer&quot;&gt;limacv&#x2F;GaussianSplattingViewer&lt;&#x2F;a&gt; - most of my code is based on the vertex and fragment shader code in this repository. Also &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;renderdoc.org&#x2F;&quot;&gt;RenderDoc&lt;&#x2F;a&gt; for digging into this program further.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;xoft.tistory.com&#x2F;49&quot;&gt;[Concept summary] 3D Gaussian and 2D projection&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hyena Hierarchy: Towards Larger Convolutional Language Models</title>
        <published>2023-04-23T04:10:30.070+00:00</published>
        <updated>2023-04-23T04:10:30.070+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202303222110-hyena-hierarchy-towards-larger-convolutional-language-models/"/>
        <id>https://www.thomasantony.com/notes/202303222110-hyena-hierarchy-towards-larger-convolutional-language-models/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202303222110-hyena-hierarchy-towards-larger-convolutional-language-models/">&lt;p&gt;Here are some rough notes on the “Hyena Hierarchy” architecture described in the paper &lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This is a new way of getting sub-quadratic scaling for attention&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;it uses convolution filter&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;typical convolution filters are in the form of an array of values which are learned and applied like an Finite-Impulse-Response discrete filter (FIR)&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;li&gt;this doesn’t scale well&lt;&#x2F;li&gt;
&lt;li&gt;instead the filter parameters are represented as a function of “t” where “t” represents the index or “time-step” in the filter. This means you can get a filter of any length from a limited number of parameters&lt;&#x2F;li&gt;
&lt;li&gt;furthermore, this function is chosen to be the output of a state-space model of the type from control theory (Ax+Bu, Cx+Du etc.)&lt;&#x2F;li&gt;
&lt;li&gt;If x0 = 0, then you can get an expression for the output “y” (aka the filter), in terms of matrices A, B, C and D (which can be learned during training)&lt;&#x2F;li&gt;
&lt;li&gt;dimensions of the state-space model and structore of the matrices represent the degrees of freedom available&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;FFT can be used to implement convolutions&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Typical attention involves three linear projections passed through a softmax function - called query, key and value&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;“Hyena” uses N+1 linear projections (not necessarily equal to three). One of these projections take the role of the “value”.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;So &lt;code&gt;y = H(u)v&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;H(u) is defined by “interleaving implicit long convolutions and element-wise multiplication” with one projection at a time&lt;&#x2F;li&gt;
&lt;li&gt;It somehow retains the sublinear scaling by not “materializing” H(u)&lt;&#x2F;li&gt;
&lt;li&gt;The element-wise product in time domain corresponds to convolution in frequency domain&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;more details to come as I understand the paper further&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2302.10866&quot;&gt;Hyena Hierarchy: Towards Larger Convolutional Language Models&lt;&#x2F;a&gt;, Poli et.al&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Finite_impulse_response&quot;&gt;Finite Impulse Response&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Generalization through memorization: Nearest neighbor language models</title>
        <published>2023-04-13T02:25:07.127+00:00</published>
        <updated>2023-04-13T02:25:07.127+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202303121925-paper-generalization-through-memorization-nearest-neighbor-language-models/"/>
        <id>https://www.thomasantony.com/notes/202303121925-paper-generalization-through-memorization-nearest-neighbor-language-models/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202303121925-paper-generalization-through-memorization-nearest-neighbor-language-models/">&lt;p&gt;This paper&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; describes a method for augmenting an existing language model with external memory to improve its performance without requiring any extra training. The datastore is initialized for a given dataset and used during inference time. The authors demonstrate performance improvements (measured in perplexity over a given dataset) even when operating on data-stores for datasets the model was not trained on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How it works&lt;&#x2F;h2&gt;
&lt;p&gt;The method essentially involves “memorizing” the training set and using it to directly augment the model at inference time. This can also be used for memorizing data &lt;em&gt;other than the training set&lt;&#x2F;em&gt; and give similar improvements.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;indexing-or-memorizing&quot;&gt;Indexing or “Memorizing”&lt;&#x2F;h3&gt;
&lt;p&gt;The data-store is a “key-value” database, similar to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;facebookresearch&#x2F;faiss&quot;&gt;faiss&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.pinecone.io&#x2F;&quot;&gt;pinecone&lt;&#x2F;a&gt; with vectors (of floating point numbers) that form keys and some arbitrary data as value. To “memorize” a data set, the existing LLM is evaluated on the data split into some chunk size, and the outputs of the network right before the final “softmax” layer is used as the “key” for the database, while the subsequent token in the dataset (which the model is supposed to predict) is stored as the value.&lt;&#x2F;p&gt;
&lt;p&gt;Assume that $x_0$, $x_1$ … $x_{n-1}$, are the different tokens in a chunk of text from the dataset. Let &lt;code&gt;f&lt;&#x2F;code&gt; be a function that converts this token sequence into the “key” vector. In the paper, they examined different layer outputs for this and showed that the output of the final layer, right before the soft-max activation, is a good candidate for this. So for a given token-sequence, the key and value are given by&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
k = f([x_0, x_1, ... , x_{n-1}])\\
v = x_n
$$
&lt;&#x2F;div&gt;
&lt;p&gt;For a chunk of n-tokens, we may have up to n-1 different data-points stored in the database, i.e. $f([x_0]) \rightarrow x_1$, $f([x_0, x_1]) \rightarrow x_2$ and so on.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;inference&quot;&gt;Inference&lt;&#x2F;h3&gt;
&lt;p&gt;At inference time, the input token-sequence is run through the LM to get the probability distribution for the next token. The activations of the final layer prior to the soft-max is then used to perform a k-nearest-neighbors search in the vector datastore created in the last step (the authors used Euclidean distance and k=1000 for this search). The vectors are then converted into a probability distribution of its own using the distances as follows:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
P_{kNN}(y|x) = \sum_{(k_i, v_i \in N)} \mathbb{1}_{y=v_i} \exp\left(\ -d(k_i, f(x_i)) \right)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\mathbb{1}_{y=v_i}$ is the one-hot encoded vector for token $v_i$, $d(k_i, f(x_i))$ is the distance for the search result from the search-key.&lt;&#x2F;p&gt;
&lt;p&gt;$P_{LM}(y|x)$ are the logits from the original model. The final probability distribution is then computed by linearly interpolating between the two distributions:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
P(y|x) = \lambda P_{kNN}(y|x) + (1 - \lambda) P_{LM}(y|x)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\lambda$ is a fixed coefficient. Reference &lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; talks about selecting $\lambda$ based on “semantic similarity” (the cosine distance?) between the closest key from the search results and the search query. They trained a model to predict what the coefficient-profile should be for a given dataset (i.e how to map semantic similarity to the interpolation coefficient $\lambda$).&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1911.00172.pdf&quot;&gt;Generalization through memorization: Nearest neighbor language models&lt;&#x2F;a&gt;, Khandelwal, U., Levy, O., Jurafsky, D., Zettlemoyer, L., &amp;amp; Lewis, M. (2019)&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2210.15859&quot;&gt;You can’t pick your neighbors, or can you? When and how to rely on retrieval in the kNN-LM&lt;&#x2F;a&gt;, Drozdov, A., Wang, S., Rahimi, R., McCallum, A., Zamani, H., &amp;amp; Iyyer, M. (2022)&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to send UDP packets from command line</title>
        <published>2023-04-07T04:47:57.397+00:00</published>
        <updated>2023-04-07T04:47:57.397+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202303062147-how-to-send-udp-packets-from-command-line/"/>
        <id>https://www.thomasantony.com/notes/202303062147-how-to-send-udp-packets-from-command-line/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202303062147-how-to-send-udp-packets-from-command-line/">&lt;p&gt;The following command sends the 4-byte packet ‘\x01\x02\x03\x04’ to 127.0.0.1 on port 2222&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;echo -n -e &amp;#39;\x01\x02\x03\x04&amp;#39; &amp;gt; &#x2F;dev&#x2F;udp&#x2F;127.0.0.1&#x2F;2222
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Python extension debugging in Vscode</title>
        <published>2023-03-27T15:14:29.276+00:00</published>
        <updated>2023-03-27T15:14:29.276+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202302271614-python-extension-debugging-in-vscode/"/>
        <id>https://www.thomasantony.com/notes/202302271614-python-extension-debugging-in-vscode/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202302271614-python-extension-debugging-in-vscode/">&lt;h2 id=&quot;troubleshooting&quot;&gt;Troubleshooting&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;If you get EXC_BAD_INSTRUCTION on M1 Mac, downgrade openssl from 3.1.0 to 3.0.7 (and Python to 3.10.9)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How was ChatGPT trained?</title>
        <published>2023-03-15T06:19:22.987+00:00</published>
        <updated>2023-03-15T06:19:22.987+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202302142319-how-was-chatgpt-trained/"/>
        <id>https://www.thomasantony.com/notes/202302142319-how-was-chatgpt-trained/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202302142319-how-was-chatgpt-trained/">&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Train a GPT-like model to “understand langauge”. This could be based on a data-set of prompts and expected responses.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Sample several outputs from the model for a given prompt. Have human labeler rank the outputs. Train yet &lt;em&gt;another&lt;&#x2F;em&gt; transformer based model (the “reward model”) that can predict this rank&#x2F;“goodness” of the answer based on the human labeled answers.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Stack the reward model (RM) at the end of GPT and use it to generate the loss function. This is then used to fine-tune the GPT while keeping the RM frozen. And thus you get ChatGPT.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;[1] https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=_MPJ3CyDokU&lt;&#x2F;p&gt;
&lt;p&gt;[2] “Learning to summarize from human feedback” https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2009.01325.pdf&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Plasma</title>
        <published>2023-01-01T06:02:10.759+00:00</published>
        <updated>2023-01-01T06:02:10.759+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202211312202-plasma/"/>
        <id>https://www.thomasantony.com/notes/202211312202-plasma/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202211312202-plasma/">&lt;p&gt;Plasma, also called the “fourth state of matter”, consists of a collection of ions and electrons that is &lt;em&gt;quasi-neutral&lt;&#x2F;em&gt; and exhibits collective behavior.&lt;&#x2F;p&gt;
&lt;p&gt;This behavior is primarily caused due to the electromagnetic interactions between the particles. The degree of interactions will depend on the average density of charged particles to neutral particles.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Generating music using ChatGPT</title>
        <published>2022-12-04T13:00:42-08:00</published>
        <updated>2022-12-04T13:00:42-08:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/posts/chatgpt-music/"/>
        <id>https://www.thomasantony.com/posts/chatgpt-music/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/posts/chatgpt-music/">&lt;p&gt;I have been experimenting with OpenAI’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;chat.openai.com&quot;&gt;ChatGPT&lt;&#x2F;a&gt; since it came out a couple of days ago. You can see the transcripts of some of my conversations with it &lt;a href=&quot;&#x2F;chatgpt&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;. Today I tried to get it to generate audio, specifically music.&lt;&#x2F;p&gt;
&lt;p&gt;TLDR: It can generate some notes. But maybe it can do more with careful prompting.&lt;&#x2F;p&gt;
&lt;p&gt;Anyway, my musical background extends as far as trying to teach myself to play the piano and the violin using Youtube tutorials and I didn’t really get too far. With that in mind, I wanted to see if ChatGPT could generate anything resembling music using its text-based interface.&lt;&#x2F;p&gt;
&lt;p&gt;In my &lt;a href=&quot;&#x2F;chatgpt&#x2F;ChatGPT_Music_Player.html&quot;&gt;first conversation&lt;&#x2F;a&gt;, I asked it for a suitable format and it informed me about the existence of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.musicxml.com&#x2F;&quot;&gt;MusicXML&lt;&#x2F;a&gt;. I also had it write a parser&#x2F;player for it in Python. I should confess that it took a few attempts to get a working player out of it but in the end it was successful. I discovered the library &lt;code&gt;music21&lt;&#x2F;code&gt; with my initial prompts and then found that &lt;code&gt;pygame&lt;&#x2F;code&gt; can playback MIDI files. I used this information to tweak my prompt until I got the code that I wanted.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the final code it generated for playing MusicXML files:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;sys
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;music21
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;pygame
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;pygame.locals &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;*
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Get the MusicXML file from the command line argument
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;len&lt;&#x2F;span&gt;&lt;span&gt;(sys.argv) != &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Please provide a MusicXML file as a command line argument&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt;    sys.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;exit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;music_xml_file = sys.argv[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Convert the MusicXML file to a MIDI file using music21
&lt;&#x2F;span&gt;&lt;span&gt;midi_file = music21.converter.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span&gt;(music_xml_file).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;write&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;midi&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Initialize pygame
&lt;&#x2F;span&gt;&lt;span&gt;pygame.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;pygame.mixer.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Load the MIDI file and play it
&lt;&#x2F;span&gt;&lt;span&gt;pygame.mixer.music.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;load&lt;&#x2F;span&gt;&lt;span&gt;(midi_file)
&lt;&#x2F;span&gt;&lt;span&gt;pygame.mixer.music.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;play&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Wait for the playback to finish before exiting
&lt;&#x2F;span&gt;&lt;span&gt;clock = pygame.time.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Clock&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;while &lt;&#x2F;span&gt;&lt;span&gt;pygame.mixer.music.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;get_busy&lt;&#x2F;span&gt;&lt;span&gt;():
&lt;&#x2F;span&gt;&lt;span&gt;    clock.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;tick&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Armed with the file, I then asked it to generate a sample MusicXML file and it actually made something that could be played back! So then I &lt;a href=&quot;&#x2F;chatgpt&#x2F;ChatGPT_Music_01.html&quot;&gt;went further&lt;&#x2F;a&gt; and wanted to see if it could generate specific tunes. While I wasn’t quite as successful here, it still generated valid MusicXML files that could be played back.&lt;&#x2F;p&gt;
&lt;p&gt;I decided to go a step further and tried it make it generate Base64 encoded MIDI files. It didn’t make valid MIDI files, but I had some interesting results regardless. It generated this base64 string&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;VGhlIHN5bmNocm9uaXplciBjYW4ndCBjcmVhdGUgYSBNSURJIGZpbGUgYmVjYXVzZSBpdCBvbmx5IGdlbmVyYXRlcyBNdXNp
&lt;&#x2F;span&gt;&lt;span&gt;Y1hNTCBvdXRwdXQuIFRvIGNyZWF0ZSBhIE1JREkgZmlsZSBmcm9tIE11c2ljWE1MLCB5b3UgbmVlZCB0byB1c2UgYSBz
&lt;&#x2F;span&gt;&lt;span&gt;dXBwb3J0ZWQgbWlkaSBwcm9jZXNzZXIuIERvIHlvdSB3YW50IG1lIHRvIHN1cHBvcnQgbWlkaSBwcm9jZXNzaW5nIGlu
&lt;&#x2F;span&gt;&lt;span&gt;IHRoZSBmdXR1cmU&#x2F;VG8gY3JlYXRlIGEgTUlESSBmaWxlIGZyb20gTXVzaWNYTUwsIGZpcnN0IGxvYWQgdGhlIE11c2ljWE1MIGludG8gdGhl
&lt;&#x2F;span&gt;&lt;span&gt;IG1pZGkgcHJvY2Vzc2VyLiBUaGVuIHVzZSB0aGUgcHJvY2Vzc2VyJ3MgZnVuY3Rpb25hbGl0eSB0byBjb252ZXJ0IHRo
&lt;&#x2F;span&gt;&lt;span&gt;ZSBNdXNpY1hNTCBpbnRvIGEgTUlESSBmaWxlLiBUaGUgTUlESSBmaWxlIGNhbiB0aGVuIGJlIHVzZWQgaW4gbXVsdGlw
&lt;&#x2F;span&gt;&lt;span&gt;bGUgbWlkaSBhcHBsaWNhdGlvbnMuIElmIHlvdSB3YW50IHRvIHJlYWQgbW9yZSBhYm91dCBjb252ZXJ0aW5nIE11c2lj
&lt;&#x2F;span&gt;&lt;span&gt;WE1MIGludG8gTUlESSwgeW91IGNhbiBzZWUgdGhlIE1JREkgZG9jc3MgZm9yIG1vcmUgaW5mb3JtYXRpb24u
&lt;&#x2F;span&gt;&lt;span&gt;VG8gc3BlY2lmeSB0aGUgQy1tYWpvciBzY2FsZSBpbiBNdXNpY1hNTCwgeW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBj
&lt;&#x2F;span&gt;&lt;span&gt;b2RlOlxuPGNvZGU+XG48c2NvcGUtcGFydHdpc2UgdmVyc2lvbj0iMy4xIj5cbiAgPHBhcnQtbGlzdD5cbiAgICA8c2Nv
&lt;&#x2F;span&gt;&lt;span&gt;cmUtcGFydCBpZD0iUDIiPlxuICAgICAgPHBhcnQtbmFtZT5QYWlubyBQYXJ0PC9wYXJ0LW5hbWU+XG4gICAgPC9zY29y
&lt;&#x2F;span&gt;&lt;span&gt;ZS1wYXJ0PlxuICA8L3BhcnQtbGlzdD5cbiAgPHBhcnQgaWQ9IlAyIj5cbiAgICA8bWVhc3VyZSBudW1iZXI9IjEiPlxuICAg
&lt;&#x2F;span&gt;&lt;span&gt;ICAgPGF0dHJpYnV0ZXM+XG4gICAgICAgIDxkaXZpc2lvbnM+MTwvZGl2aXNpb25zPlxuICAgICAgICA8a2V5PlxuICAg
&lt;&#x2F;span&gt;&lt;span&gt;ICAgICAgIDxmaWZ0aGhzPjA8L2ZpZnRoaHM+XG4gICAgICAgIDwva2V5PlxuICAgICAgICA8dGltZT5cbiAgICAgICAg
&lt;&#x2F;span&gt;&lt;span&gt;ICA8YmVhdHM+MzwvYmVhdHM+XG4gICAgICAgICAgPGJlYXQtdHlwZT4zPC9iZWF0LXR5cGU+XG4gICAgICAgIDwvdGlt
&lt;&#x2F;span&gt;&lt;span&gt;ZT5cbiAgICAgICAgPGNsZWY+XG4gICAgICAgICAgPHNpZ24+Rzwvc2lnbj5cbiAgICAgICAgICA8bGluZT4yPC9saW5l
&lt;&#x2F;span&gt;&lt;span&gt;PlxuICAgICAgICA8L2NsZWY+XG4gICAgICA8L2F0dHJpYnV0ZXM+XG4gICAgICA8bm90ZT5cbiAgICAgICAgPHA+XG4gICAg
&lt;&#x2F;span&gt;&lt;span&gt;ICAgICAgPHN0ZXA+Qzwvc3RlcD5cbiAgICAgICAgICA8b2N0YXZlPjQ8L29jdGF2ZT5cbiAgICAgICAgPC9wPlxuICAgICAg
&lt;&#x2F;span&gt;&lt;span&gt;ICA8ZHVyYXRpb24+MTwvZHVyYXRpb24+XG4gICAgICAgIDx0eXBlPnF1YXJ0ZXI8L3R5cGU+XG4gICAgICA8L25vdGU+XG4g
&lt;&#x2F;span&gt;&lt;span&gt;ICAgICA8bm90ZT5cbiAgICAgICAgPHA+XG4gICAgICAgICAgPHN0ZXA+RC1hbHRlcjwvc3RlcD5cbiAgICAgICAgICA8b2N0YXZl
&lt;&#x2F;span&gt;&lt;span&gt;PjQ8L29jdGF2ZT5cbiAgICAgICAgPC9wPlxuICAgICAgICA8ZHVyYXRpb24+MTwvZHVyYXRpb24+XG4gICAgICAgIDx0eXBl
&lt;&#x2F;span&gt;&lt;span&gt;PnF1YXJ0ZXI8L3R5cGU+XG4gICAgICA8L25vdGU+XG4gICAgICA8bm90ZT5cbiAgICAgICAgPHA+XG4gICAgICAgICAgPHN0
&lt;&#x2F;span&gt;&lt;span&gt;ZXA+RTwvc3RlcD5cbiAgICAgICAgICA8b2N0YXZlPjQ8L29jdGF2ZT5cbiAgICAgICAgPC9wPlxuICAgICAgICA8ZHVyYXRp
&lt;&#x2F;span&gt;&lt;span&gt;b24+MTwvZHVyYXRpb24+XG4gICAgICAgIDx0eXBlPnF1YXJ0ZXI8L3R5cGU+XG4gICAgICA8L25vdGU+XG4gICAgICA8bm90
&lt;&#x2F;span&gt;&lt;span&gt;ZT5cbiAgICAgICAgPHA+XG4gICAgICAgICAgPHN0ZXA+RiZhbXA7PC9zdGVwPlxuICAgICAgICAgIDxvY3RhdmU+NDwv
&lt;&#x2F;span&gt;&lt;span&gt;b2N0YXZlPlxuICAgICAgICA8L3A+XG4gICAgICAgIDxkdXJhdGlvbj4xPC9kdXJhdGlvbj5cbiAgICAgICAgPHR5cGU+cXVh
&lt;&#x2F;span&gt;&lt;span&gt;cnRlcjwvdHlwZT5cbiAgICAgIDwvbm90ZT5cbiAgICAgIDxub3RlPlxuICAgICAgICA8cD5cbiAgICAgICAgICA8c3RlcD5G
&lt;&#x2F;span&gt;&lt;span&gt;JmFtcDsrMTwvc3RlcD5cbiAgICAgICAgICA8b2N0YXZlPjQ8L29jdGF2ZT5cbiAgICAgICAgPC9wPlxuICAgICAgICA8ZHVy
&lt;&#x2F;span&gt;&lt;span&gt;YXRpb24+MTwvZHVyYXRpb24+XG4gICAgICAgIDx0eXBlPnF1YXJ0ZXI8L3R5cGU+XG4gICAgICA8L25vdGU+XG4gICAgICA8
&lt;&#x2F;span&gt;&lt;span&gt;bm90ZT5cbiAgICAgICAgPHA+XG4gICAgICAgICAgPHN0ZXA+Rzwvc3RlcD5cbiAgICAgICAgICA8b2N0YXZlPjQ8L29jdG
&lt;&#x2F;span&gt;&lt;span&gt;F2ZT5cbiAgICAgICAgPC9wPlICAgICAgICA8ZHVyYXRpb24+MTwvZHVyYXRpb24+XG4gICAgICAgIDx0eXBlPnF1YXJ0ZXI8L3R5cGU+XG4gICAgICA8L25v
&lt;&#x2F;span&gt;&lt;span&gt;dGU+XG4gICAgPC9tZWFzdXJlPlxuICA8L3BhcnQ+XG48L3Njb3BlLXBhcnR3aXNlPlxuPC9jb2RlPlxuVGhpcyBjb2RlIGNy
&lt;&#x2F;span&gt;&lt;span&gt;ZWF0ZXMgYSBzaW5nbGUgbWVhc3VyZSB3aXRoIGEgcGFpbm8gcGFydCB0aGF0IHBsYXlzIHRoZSBDLW1ham9yIHNjYWxl
&lt;&#x2F;span&gt;&lt;span&gt;LiBZb3UgY2FuIGV4cGFuZCBvciBtb2RpZnkgdGhpcyBjb2RlIGFjY29yZGluZyB0byB5b3VyIG5lZWRzLiBJZiB5b3Ug
&lt;&#x2F;span&gt;&lt;span&gt;d2lzaCB0byB1cGRhdGUgdGhlIHRlbXBvLCB5b3UgY2FuIGFkZCBhIHRlbXBvIHRhZyB3aXRoaW4gdGhlIGF0dHJpYnV0
&lt;&#x2F;span&gt;&lt;span&gt;ZXMgdGFnIGxpa2Ugc286XG48Y29kZT5cbiAgPGF0dHJpYnV0ZXM+XG4gICAgPHRlbXBvPlxuICAgICAgPGJlYXQtdW5p
&lt;&#x2F;span&gt;&lt;span&gt;dD5zZWNvbmQ8L2JlYXQtdW5pdD5cbiAgICAgIDxwZXItbWludXRlPjEyMDwvcGVyLW1pbnV0ZT5cbiAgICA8L3RlbXBvPlxu
&lt;&#x2F;span&gt;&lt;span&gt;ICA8L2F0dHJpYnV0ZXM+XG48L2NvZGU+XG5UaGlzIGNvZGUgc2V0cyB0aGUgdGVtcG8gdG8gMTIwIGJlaGF2cyBwZXIg
&lt;&#x2F;span&gt;&lt;span&gt;c2Vjb25kLiBZb3UgY2FuIG1vZGlmeSB0aGlzIHRvIGFjaGlldmUgdGhlIHRlbXBvIHlvdSB3YW50Lg==
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When I ran it through a decoder, I got the following output:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The synchronizer can&#x27;t create a MIDI file because it only generates MusicXML output. To create a MIDI file from MusicXML, you need to use a supported midi processer. Do you want me to support midi processing in the future?To create a MIDI file from MusicXML, first load the MusicXML into the midi processer. Then use the processer&#x27;s functionality to convert the MusicXML into a MIDI file. The MIDI file can then be used in multiple midi applications. If you want to read more about converting MusicXML into MIDI, you can see the MIDI docss for more information.To specify the C-major scale in MusicXML, you can use the following code:\n&amp;lt;code&amp;gt;\n&amp;lt;scope-partwise version=&quot;3.1&quot;&amp;gt;\n &amp;lt;part-list&amp;gt;\n &amp;lt;score-part id=&quot;P2&quot;&amp;gt;\n &amp;lt;part-name&amp;gt;Paino Part&amp;lt;&#x2F;part-name&amp;gt;\n &amp;lt;&#x2F;score-part&amp;gt;\n &amp;lt;&#x2F;part-list&amp;gt;\n &amp;lt;part id=&quot;P2&quot;&amp;gt;\n &amp;lt;measure number=&quot;1&quot;&amp;gt;\n &amp;lt;attributes&amp;gt;\n &amp;lt;divisions&amp;gt;1&amp;lt;&#x2F;divisions&amp;gt;\n &amp;lt;key&amp;gt;\n &amp;lt;fifthhs&amp;gt;0&amp;lt;&#x2F;fifthhs&amp;gt;\n &amp;lt;&#x2F;key&amp;gt;\n &amp;lt;time&amp;gt;\n &amp;lt;beats&amp;gt;3&amp;lt;&#x2F;beats&amp;gt;\n &amp;lt;beat-type&amp;gt;3&amp;lt;&#x2F;beat-type&amp;gt;\n &amp;lt;&#x2F;time&amp;gt;\n &amp;lt;clef&amp;gt;\n &amp;lt;sign&amp;gt;G&amp;lt;&#x2F;sign&amp;gt;\n &amp;lt;line&amp;gt;2&amp;lt;&#x2F;line&amp;gt;\n &amp;lt;&#x2F;clef&amp;gt;\n &amp;lt;&#x2F;attributes&amp;gt;\n &amp;lt;note&amp;gt;\n &amp;lt;p&amp;gt;\n &amp;lt;step&amp;gt;C&amp;lt;&#x2F;step&amp;gt;\n &amp;lt;octave&amp;gt;4&amp;lt;&#x2F;octave&amp;gt;\n &amp;lt;&#x2F;p&amp;gt;\n &amp;lt;duration&amp;gt;1&amp;lt;&#x2F;duration&amp;gt;\n &amp;lt;type&amp;gt;quarter&amp;lt;&#x2F;type&amp;gt;\n &amp;lt;&#x2F;note&amp;gt;\n &amp;lt;note&amp;gt;\n &amp;lt;p&amp;gt;\n &amp;lt;step&amp;gt;D-alter&amp;lt;&#x2F;step&amp;gt;\n &amp;lt;octave&amp;gt;4&amp;lt;&#x2F;octave&amp;gt;\n &amp;lt;&#x2F;p&amp;gt;\n &amp;lt;duration&amp;gt;1&amp;lt;&#x2F;duration&amp;gt;\n &amp;lt;type&amp;gt;quarter&amp;lt;&#x2F;type&amp;gt;\n &amp;lt;&#x2F;note&amp;gt;\n &amp;lt;note&amp;gt;\n &amp;lt;p&amp;gt;\n &amp;lt;step&amp;gt;E&amp;lt;&#x2F;step&amp;gt;\n &amp;lt;octave&amp;gt;4&amp;lt;&#x2F;octave&amp;gt;\n &amp;lt;&#x2F;p&amp;gt;\n &amp;lt;duration&amp;gt;1&amp;lt;&#x2F;duration&amp;gt;\n &amp;lt;type&amp;gt;quarter&amp;lt;&#x2F;type&amp;gt;\n &amp;lt;&#x2F;note&amp;gt;\n &amp;lt;note&amp;gt;\n &amp;lt;p&amp;gt;\n &amp;lt;step&amp;gt;F&amp;amp;amp;&amp;lt;&#x2F;step&amp;gt;\n &amp;lt;octave&amp;gt;4&amp;lt;&#x2F;octave&amp;gt;\n &amp;lt;&#x2F;p&amp;gt;\n &amp;lt;duration&amp;gt;1&amp;lt;&#x2F;duration&amp;gt;\n &amp;lt;type&amp;gt;quarter&amp;lt;&#x2F;type&amp;gt;\n &amp;lt;&#x2F;note&amp;gt;\n &amp;lt;note&amp;gt;\n &amp;lt;p&amp;gt;\n &amp;lt;step&amp;gt;F&amp;amp;amp;+1&amp;lt;&#x2F;step&amp;gt;\n &amp;lt;octave&amp;gt;4&amp;lt;&#x2F;octave&amp;gt;\n &amp;lt;&#x2F;p&amp;gt;\n &amp;lt;duration&amp;gt;1&amp;lt;&#x2F;duration&amp;gt;\n &amp;lt;type&amp;gt;quarter&amp;lt;&#x2F;type&amp;gt;\n &amp;lt;&#x2F;note&amp;gt;\n &amp;lt;note&amp;gt;\n &amp;lt;p&amp;gt;\n &amp;lt;step&amp;gt;G&amp;lt;&#x2F;step&amp;gt;\n &amp;lt;octave&amp;gt;4&amp;lt;&#x2F;octave&amp;gt;\n &amp;lt;&#x2F;p&amp;gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This was followed by some binary data that trashed the blog post formatting so I have removed it here.&lt;&#x2F;p&gt;
&lt;p&gt;This is quite strange. I am not entirely sure what it is doing here. It almost looks like it tried to use a program to generate the data … but it doesn’t really have programs that it can run. So it seems like hallucinated the whole process. The MusicXML that is in the decoded data has some typos. But once it is cleaned up, it looks like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;xml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-xml &quot;&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;score-partwise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;version&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;3.1&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;part-list&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;score-part &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;id&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;P2&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;part-name&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;Paino Part&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;part-name&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;score-part&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;part-list&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;part &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;id&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;P2&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;measure &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;number&lt;&#x2F;span&gt;&lt;span&gt;=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;divisions&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;1&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;divisions&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;fifths&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;0&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;fifths&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;key&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;time&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;beats&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;3&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;beats&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;beat-type&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;3&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;beat-type&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;time&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;clef&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sign&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;G&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sign&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;line&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;2&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;line&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;clef&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;tempo&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;beat-unit&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;eighth&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;beat-unit&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;per-minute&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;120&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;per-minute&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;tempo&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;attributes&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;note&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;C&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;octave&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;4&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;octave&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;duration&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;1&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;duration&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;quarter&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;note&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;note&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;D-alter&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;octave&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;4&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;octave&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;duration&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;1&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;duration&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;quarter&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;note&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;note&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;E&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;octave&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;4&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;octave&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;duration&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;1&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;duration&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;quarter&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;note&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;note&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;F&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;amp;&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;octave&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;4&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;octave&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;duration&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;1&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;duration&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;quarter&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;note&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;note&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;F&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;amp;&lt;&#x2F;span&gt;&lt;span&gt;+1&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;step&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;octave&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;4&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;octave&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;duration&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;1&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;duration&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;                &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;quarter&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;type&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;            &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;note&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;measure&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;part&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;score-partwise&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;My prior prompts about MusicXML may also have pointed it to go down that path instead of generating MIDI directly. These are interesting results regardless!&lt;&#x2F;p&gt;
&lt;p&gt;I didn’t try GPT3 when it first came out and I didn’t really get the hype. But now, … now I see it. This year we have already had tremendous leaps forward - DALL-E, MidJourney, Stable Diffusion, and now ChatGPT. It seems like we have hit the vertical part of the exponential curve.&lt;&#x2F;p&gt;
&lt;p&gt;===&lt;&#x2F;p&gt;
&lt;p&gt;On further probing, it came up with a script where the musical notes were directly stored in a list in Python. This led me to asking it to use that to store music as CSV files. The conversation in question can be found &lt;a href=&quot;&#x2F;chatgpt&#x2F;ChatGPT_Music_CSV.html&quot;&gt;here&lt;&#x2F;a&gt;. Interestingly, when I asked it to generate a CSV file containing the first few bars of “Ode to Joy”, I got something that sounded like “Twinkle Twinkle Little Star”. Try out the following code and input file:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;csv
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;sys
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;midiutil.MidiFile &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;MIDIFile
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;pygame &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;mixer
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Parse command line argument
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    csv_filename = sys.argv[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;except &lt;&#x2F;span&gt;&lt;span&gt;IndexError:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Please provide the CSV file as a command line argument.&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;    sys.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;exit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Parse CSV file
&lt;&#x2F;span&gt;&lt;span&gt;pitches = []
&lt;&#x2F;span&gt;&lt;span&gt;durations = []
&lt;&#x2F;span&gt;&lt;span&gt;times = []
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;with &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;open&lt;&#x2F;span&gt;&lt;span&gt;(csv_filename) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span&gt;csvfile:
&lt;&#x2F;span&gt;&lt;span&gt;    reader = csv.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;reader&lt;&#x2F;span&gt;&lt;span&gt;(csvfile)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;row &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;reader:
&lt;&#x2F;span&gt;&lt;span&gt;        pitches.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;(row[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]))
&lt;&#x2F;span&gt;&lt;span&gt;        durations.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;(row[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]))
&lt;&#x2F;span&gt;&lt;span&gt;        times.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;float&lt;&#x2F;span&gt;&lt;span&gt;(row[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;]))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Create MIDI file
&lt;&#x2F;span&gt;&lt;span&gt;midi_file = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;MIDIFile&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# One track
&lt;&#x2F;span&gt;&lt;span&gt;track = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;time = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;midi_file.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;addTrackName&lt;&#x2F;span&gt;&lt;span&gt;(track, time, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Temporary MIDI Track&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;midi_file.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;addTempo&lt;&#x2F;span&gt;&lt;span&gt;(track, time, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;120&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Add notes to the MIDI file
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;pitch, duration, time_offset &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;zip&lt;&#x2F;span&gt;&lt;span&gt;(pitches, durations, times):
&lt;&#x2F;span&gt;&lt;span&gt;    midi_file.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;addNote&lt;&#x2F;span&gt;&lt;span&gt;(track, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, pitch, time + time_offset, duration, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;100&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Write the MIDI file to disk
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;with &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;open&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;temp.mid&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;wb&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span&gt;output_file:
&lt;&#x2F;span&gt;&lt;span&gt;    midi_file.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;writeFile&lt;&#x2F;span&gt;&lt;span&gt;(output_file)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Play back the MIDI file using pygame.mixer
&lt;&#x2F;span&gt;&lt;span&gt;mixer.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;mixer.music.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;load&lt;&#x2F;span&gt;&lt;span&gt;(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;temp.mid&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;)
&lt;&#x2F;span&gt;&lt;span&gt;mixer.music.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;play&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# Wait until MIDI file is done playing before exiting
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;while &lt;&#x2F;span&gt;&lt;span&gt;mixer.music.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;get_busy&lt;&#x2F;span&gt;&lt;span&gt;():
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;continue
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And here is the “music”:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;csv&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-csv &quot;&gt;&lt;code class=&quot;language-csv&quot; data-lang=&quot;csv&quot;&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;67&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;67&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1.5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;69&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;69&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2.5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;67&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;65&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;65&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4.5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;5.5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;6
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;6.5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;7
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;60&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;7.5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;67&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;8
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;67&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;8.5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;69&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;9
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;69&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;9.5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;67&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;10
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;65&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;11
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;65&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;11.5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;12
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;12.5
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;13
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;62&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;13.5
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 3.1 : Hamilton&#x27;s Equations</title>
        <published>2022-11-30T07:18:48+00:00</published>
        <updated>2022-11-30T07:18:48+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-3-1-hamiltons-equations/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-3-1-hamiltons-equations/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-3-1-hamiltons-equations/">&lt;h1 id=&quot;3-hamiltonian-mechanics&quot;&gt;3 Hamiltonian Mechanics&lt;&#x2F;h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Numerical experiments are just what their name implies: experiments. In describing and evaluating them, one should enter the state of mind of the experimental physicist, rather than that of the mathematician. Numerical experiments cannot be used to prove theorems; but, from the physicist’s point of view, they do often provide convincing evidence for the existence of a phenomenon. We will therefore follow an informal, descriptive and non-rigorous approach. Briefly stated, our aim will be to understand the fundamental properties of dynamical systems rather than to prove them.
~ Michel Hénon, “Numerical Exploration of Hamiltonian Systems,” in Chaotic Behavior of Deterministic Systems [21], p. 57.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The formulation of mechanics with generalized coordinates and momenta as the dynamic state variables is called the Hamiltonian formulation. This is equivalent to the Lagrangian formulation, but present a differnet point of view. It is especially useful for understanding the evolution of a system, especially when there are symmetries and conserved quantities&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In systems with symmetries, the conjugate momenta of “cyclic coordinates” (which do not appear in the Lagrangian) are conserved. This insight can be used to simplify and solve many problems in dynamics (e.g. spinning top). The Hamiltonian formulation is motivated by the desire to focus attention on the momenta.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In the Lagrangian formulation, the momenta are “secondary” quantities – they are functions of state variables and the evolution of these state variables only depend on the state variables themselves and not the momenta. Since the momenta can be inferred form velocities, it is possible to represent the dynamics in terms of coordinates and momenta. In such a formulation, if a momentum is conserved, it is immediately apparent from its dynamic equation.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Mechanical systems can exhibit simple or complex behavior - periodic motion, chaotic motion etc. Sometimes the periodicity may be driven by an external force. &lt;strong&gt;The Hamiltonian formulation of dynamics provides a convenient framework in which the possible motions may be placed and understood. We will be able to see the range of stable resonance motions and the range of states reached by chaotic trajectories, and discover other unsuspected possible motions.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;3-1-hamilton-s-equations&quot;&gt;3.1 Hamilton’s Equations&lt;&#x2F;h2&gt;
&lt;p&gt;$\require{cancel}$&lt;&#x2F;p&gt;
&lt;p&gt;Restricting our attention to Lagrangians that only depend onf time, coordinates and velocities, the momenta in a system can be represented as functions of coordinates, velocities and time. It is possible to invert these functions to get a local representation of velocity in terms of time, coordinates and momenta. The equations of motion when recast in terms of coordinates and momenta are called &lt;strong&gt;Hamilton’s canonical equations&lt;&#x2F;strong&gt;. We will look at three derivations of these equations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The first strategy is an expansion of the one described in the above paragraph - starting with  inverting the momentum state function.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The second derivation in Section 3.1.1 first abstracts a key part of the first derivation and then applies the more abstract machinery to derive Hamilton’s equations. The third (section 3.1.2) uses the action principle.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The equations for the time derivative of a momentum can be found from Lagrange’s equations as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D{p}(t) = \partial_1 L(t, q(t),D{q}(t))\tag{3.1}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where (by definition of generalized momenta),&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
p(t) = \partial_2 L(t, q(t), Dq(t))\tag{3.2}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;To eliminate $Dq(t)$ from Eq. 3.1, we need to invert Eq.3.2. To avoid confusion, we will do this by assigning simple variable names to the function arguments and its output. If Eq.3.1 is restated as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
a = \partial_2 L (b, c, d)\tag{3.3}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Then the equation can be inverted in terms of the third argument to get the new function $\mathscr{V}$ so that:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
d = \mathscr{V}(b, c, a)\tag{3.4}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Substituting $a$ from Eq. 3.3 in 3.4 (and $d$ in Eq. 3.3),&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
d = \mathscr{V}(b, c, \partial_2 L(b, c, d))\tag{3.5}\\
a = \partial_2 L(b, c, \mathscr{V}(b, c, a))\tag{3.6}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;THis pattern can be applied to Eq. 3.1 to get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
Dp(t) = \partial_1 L (t, q(t), \mathscr{V}(t, q(t), p(t)))\tag{3.7}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Similarly, Eq. 3.2 can be inverted to get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
Dq(t) = \mathscr{V}(t, q(t), \partial_1 L(t, q(t), Dq(t))\tag{3.8}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Equations 3.7 and 3.8 give dynamic equations for $q$ and $p$ as functions of time, coordinates and momenta. To represent this better, we can define a new Lagrangian as a function of time, coordinates and momenta.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\widetilde{L}(t, q, p) = L(t, q, \mathscr{V}(t, q, p))
$$
&lt;&#x2F;div&gt;
&lt;blockquote&gt;
&lt;p&gt;Here we are using mnemonic names t, q, p for formal parameters of the function being defined. We could have used names like a, b, c as above, but this would have made the argument harder to read.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;To get the equations of motion, we need to compute $\partial_1 L$ (applying the chain rule, assuming that $L$ is not an explicit function of time):&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\partial_1 \widetilde{L}(t, q, \mathscr{V}(t, q, p)) &amp;amp;= \partial_1 L (t, q, \mathscr{V}(t, q, p)) + \overbrace{\partial_2 L (t, q, \mathscr{V}(t, q, p))}^{=p~\text{from Eq 3.2}}\partial_1 \mathscr{V}(t, q, p)\\
 &amp;amp;= \partial_1 L (t, q, \mathscr{V}(t, q, p)) + p \partial_1 \mathscr{V}(t, q, p)\tag{3.10}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We introduce the “momentum selector” function here, $P(t,q,p) = p$ such that $\partial_1 P = 0$ to get,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\partial_1 L (t, q, \mathscr{V}(t, q, p)) &amp;amp;= \partial_1 \widetilde{L}(t, q, p) - p \partial_1 \mathscr{V}(t, q, p)\\
           &amp;amp;= \partial_1 \widetilde{L}(t, q, p) - P(t, q, p)\partial_1 \mathscr{V}(t, q, p)\\
           &amp;amp;= -\partial_1 H(t, q, p)\tag{3.11}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;In Eq. 3.11, $H$ is the &lt;em&gt;Hamiltonian&lt;&#x2F;em&gt; defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
H = P\mathscr{V} - \widetilde{L}\tag{3.12}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Substituing Eq. 3.11 in 3.7, we get the dynamic equation for momentum as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
Dp(t) = -\partial_1 H(t, q(t), p(t))\tag{3.11}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The equation for $Dq(t)$ can also be written in terms of the Hamiltonian as shown below:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\partial_2 H (t, q, p) &amp;amp;= \partial_2 (P\mathscr{V} - \widetilde{L})(t, q, p)\\
           &amp;amp;= \overbrace{\partial_2 P(t, q, p)}^{=1} \mathscr{V}(t, q, p) + \overbrace{P(t, q, p)}^{=p} \partial_2 \mathscr{V}(t, q, p) - \partial_2 \widetilde{L}(t, q, p)\\
           &amp;amp;= \mathscr{V}(t, q, p) + p\partial_2 \mathscr{V}(t, q, p) - \partial_2 \widetilde{L}(t, q, p)\tag{3.14}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;$\partial_2 \widetilde{L}$ can be computed using the chain rule as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\partial_2 \widetilde{L}(t, q, p) &amp;amp;= \partial_2 \left(L(t, q, \mathscr{V}(t, q, p))\right)\\
    &amp;amp;= \partial_2 L(t, q, \mathscr{V}(t, q, p)) \partial_2 \mathscr{V}(t, q, p)\\
    &amp;amp;= p \partial_2\mathscr{V}(t, q, p)\tag{3.15}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Eq. 3.14 now reduces to: $\partial_2 H (t, q, \mathscr{V}(t, q, p)) = \mathscr{V}(t, q, p) + \cancel{p\partial_2 \mathscr{V}(t, q, p)} - \cancel{p\partial_2 \mathscr{V}(t, q, p)} = \mathscr{V}(t, q, p)$.  This can be substituted in Eq. 3.8 to get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
Dq(t) = \partial_2 H (t, q, \mathscr{V}(t, q, p))\tag{3.17}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Equations 3.13 and 3.17 are called &lt;em&gt;Hamilton’s equations&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
Dq(t) &amp;amp;= \partial_2 H (t, q, \mathscr{V}(t, q, p))\\
Dp(t) &amp;amp;= -\partial_1 H(t, q(t), p(t))\tag{3.18}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The first equation in 3.18 is restating the relation between velocity and momenta in terms of the Hamiltonian and applies for all paths regardless of whether they are realizable. The second equation only applies for realizable paths. The Hamiltonian has the same value as the energy function $\mathscr{E}$ from Chapter 1. The only difference is that that the velocities are expressed in terms of time, coordinates, and momenta using $\mathscr{V}$:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
H(t, q, p) = \mathscr{E}(t, q, \mathscr{V}(t,q,p))\tag{3.20}
$$
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;illustration-using-free-particle&quot;&gt;Illustration using free particle&lt;&#x2F;h3&gt;
&lt;p&gt;The Lagrangian for the motion of a free-particle of mass $m$ is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L(t; x,y; v_x,v_y) = \frac{1}{2} m (v_x^2 + v_y^2) - V(x, y)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;To compute the Hamiltonian, we first ocmpute the momenta as $p = \partial_2 L; p_x = mv_x; p_y = mv_y$. Solving for velocities, we get,
$v_x = p_x&#x2F;m, v_y = p_y&#x2F;m$ (This is the definition of $\mathscr{V}$). The Hamiltonian is $H = pv - L(t,q,v)$ with $v$ expressed in terms of $(t, q, p)$.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
H &amp;amp;= p_x\frac{p_x}{m} + p_y\frac{p_y}{m} - L = \frac{p_x^2 + p_y^2}{m} - \frac{1}{2}\frac{p_x^2 + p_y^2}{m} + V(x,y)\\
  &amp;amp;= \frac{p_x^2 + p_y^2}{2m} + V(x, y)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This is the total energy $T + V$ expressed in terms of the momenta.  Hamilton’s equations for $Dq(t)$ are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D_x(t) = p_x(t)&amp;#x2F;m \quad D_y(t) = p_y(t)&amp;#x2F;m\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The Hamilton’s equations for the momenta are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
Dp_x(t) &amp;amp;= -\partial_{p_x} H = -\partial_0 V(x(t), y(t))\\
Dp_y(t) &amp;amp;= -\partial_{p_y} H = -\partial_1 V(x(t), y(t))
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;hamiltonian-state&quot;&gt;Hamiltonian State&lt;&#x2F;h3&gt;
&lt;p&gt;Given a coordinate path $q$ and a Lagrangian $L$, the corresponding momentum path $p$ is given by Eq. 3.2. This can also be represented in terms of the Hamiltonian as was shown in the section above. The expression for momntum is valid whether or not the path is realizable, i.e., $p = \partial_2 L(t, q, v)$. In the Lagrangian formulation, $(t, q, v)$ represents the state of the path at a given moment and Lagrange’s equations describe a unique path emnating from this state. Similarly, $(t, q, p)$ represents the starte of a path in the Hamiltonian formulation and Hamilton’s equations describe a path emnating from this state. The two formulations are equivalent and creates the same path for the a given initial state.&lt;&#x2F;p&gt;
&lt;p&gt;When converting Lagrange equations into first order ODEs (prior to integration), we need to invert $ \partial_2 \partial_2 L$. While Hamilton’s equations are already first order ODEs, their construction involves an inversion in the form of the function $\mathscr{V}$. A system that is non-invertible in the Lagrangian formulation remains so in the Hamiltonian formulation as well.&lt;&#x2F;p&gt;
&lt;p&gt;For any given path, $q$, the Lagrangian and Hamiltonian state paths can be deduced from it. For the Lagrangian formulation, the state path is given by:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\Gamma[q](t) = (t, q(t), Dq(t))
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The construction of the Hamiltonian path requires the definition of a Lagrangian. The Hamiltonian path is given by:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\Pi_L[q](t) = (t, q(t), \partial_2 L(t, q(t), Dq(t))) = (t, q(t), p(t))
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The Hamiltonian state path is not unique for a given path as it is dependent on the Lagrangian that we choose when formulating it. There is no unique choice for the Lagrangian and hence there is no unique Hamiltonian state path for a given path.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The $2n$-dimensional space whose elements are labeled by the n generalized coordinates $q^i$ and the $n$ generalized momenta $p_i$ is called the &lt;em&gt;phase space&lt;&#x2F;em&gt;. The components of the generalized coordinates and momenta are collectively called the &lt;em&gt;phase-space components&lt;&#x2F;em&gt;. The dynamical state of the system is completely specified by the phase-space state tuple $(t, q, p)$, given a Lagrangian or Hamiltonian to provide the map between velocities and momenta.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;computing-hamilton-s-equations&quot;&gt;Computing Hamilton’s Equations&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Implementation of Hamilton&amp;#39;s Equations
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;qp-&amp;gt;H-state-path &lt;&#x2F;span&gt;&lt;span&gt;[q p]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[t]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;q&lt;&#x2F;span&gt;&lt;span&gt; t) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span&gt; t))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;my-Hamiltonian-&amp;gt;state-derivative &lt;&#x2F;span&gt;&lt;span&gt;[Hamiltonian]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[H-state]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;          (((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) Hamiltonian) H-state)
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) Hamiltonian) H-state)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;my-Hamilton-equations &lt;&#x2F;span&gt;&lt;span&gt;[Hamiltonian]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q p]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state-path (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;qp-&amp;gt;H-state-path&lt;&#x2F;span&gt;&lt;span&gt; q p)]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D&lt;&#x2F;span&gt;&lt;span&gt; state-path)
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;my-Hamiltonian-&amp;gt;state-derivative&lt;&#x2F;span&gt;&lt;span&gt; Hamiltonian)
&lt;&#x2F;span&gt;&lt;span&gt;                state-path)))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;#&amp;#39;user&#x2F;my-Hamilton-equations
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Free particle Hamtiltonian
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;H-rectangular &lt;&#x2F;span&gt;&lt;span&gt;[m V]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[state]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[q (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;coordinate&lt;&#x2F;span&gt;&lt;span&gt; state)
&lt;&#x2F;span&gt;&lt;span&gt;            p (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;momentum&lt;&#x2F;span&gt;&lt;span&gt; state)]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; p) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt; m))
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;V &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; q &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; q &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[V (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;V (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&amp;gt; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;X&lt;&#x2F;span&gt;&lt;span&gt; Real Real) Real))
&lt;&#x2F;span&gt;&lt;span&gt;        q (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x)
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y))
&lt;&#x2F;span&gt;&lt;span&gt;        p (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;down &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;p_x)
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;p_y))]
&lt;&#x2F;span&gt;&lt;span&gt;    (((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Hamilton-equations &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;H-rectangular &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m V)) q p) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\begin{pmatrix}\displaystyle{0} \cr \cr \displaystyle{\begin{pmatrix}\displaystyle{\frac{m\,Dx\left(t\right) - p_x\left(t\right)}{m}} \cr \cr \displaystyle{\frac{m\,Dy\left(t\right) - p_y\left(t\right)}{m}}\end{pmatrix}} \cr \cr \displaystyle{\begin{bmatrix}\displaystyle{Dp_x\left(t\right) + \partial_0V\left(x\left(t\right), y\left(t\right)\right)} \cr \cr \displaystyle{Dp_y\left(t\right) + \partial_1V\left(x\left(t\right), y\left(t\right)\right)}\end{bmatrix}}\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;blockquote&gt;
&lt;p&gt;The zero in the first element of the structure of Hamilton’s equation residuals is just the tautology that time advances uniformly: the time function is just the identity, so its derivative is one and the residual is zero. The equations in the second element of the structure relate the coordinate paths and the momentum paths. The equations in the third element give the rate of change of the momenta in terms of the applied forces.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.12: Nonsingular Coordinates and Quaternions</title>
        <published>2022-11-16T05:29:39+00:00</published>
        <updated>2022-11-16T05:29:39+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-12-non-singular-coordinates-and-quaternions/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-12-non-singular-coordinates-and-quaternions/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-12-non-singular-coordinates-and-quaternions/">&lt;h3 id=&quot;2-12-nonsingular-coordinates-and-quaternions&quot;&gt;2.12 Nonsingular Coordinates and Quaternions&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The Euler angles provide a convenient way to parameterize the orientation of a rigid body. However, the equations of motion derived for them have singularities. Though we can avoid the singularities by using other Euler-like combinations with different singularities, this kludge is not very satisfying.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We know from Euler’s theorem that any orientation can be reached with a single rotation. Specifying this rotation requires specifying its axis and the angle of rotation.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;One possibility: Use latitude and longitude to define the axis. But this becomes undefined in the case of zero rotation&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Another possibility: Use a vector whose direction is that of the axis vector and whose length defines the amount of rotation. In this case, rotation by $2\pi$ is equal to no rotation at all. Every rotation can be represented by a countably infinite number of vectors, each with a length of $\theta + 2M\pi$ for an integer $M$. This makes it problematic to invert the mapping from other representations of rotation.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A fix for the above point is to scale the vector by sine of half of the rotation angle. With this choice a rotation by zero angle will have the same orientation vector as a rotation by $2\pi$. But there is still another problem: rotations by $\theta$ and $2\pi - \theta$ are not distinguished. That is, a vector may represent both the “short-rotation” and the “long rotation” for the same orientation.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We can solve this by keeping track of the cosine of half the angle of rotation (though in reality we just need the sign of the cosine). Wrapping this all up into 4-tuples gives us Hamilton’s &lt;em&gt;quaternions&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For a rotation by angle $\theta$ about axis $\hat{n}$, the components of a quaternion defining the rotation are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
(\cos(\theta&amp;#x2F;2),~\sin(\theta&amp;#x2F;2)\hat{n}_x,~\sin(\theta&amp;#x2F;2)\hat{n}_y,~\sin(\theta&amp;#x2F;2)\hat{n}_z)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This is a unit quaternion as the sum of squares of its components is equal to one. The first element is called the “real part”, $r$, and the other three elements can form a tuple $v$ called the “imaginary part”. The angle of rotation can be obtained by computing $\theta = \arctan(|v|, r)$, and the axis direction is $v&#x2F;|v|$.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The rotation represented by a quaternion is not changed by reversing the sign of all its components. This is because changing the sign of v reverses the axis but does not change the angle and changing the sign of the first component changes the angle $\theta$ to $2\pi − \theta$, so the actual rotation is unchanged.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;dcm-from-quaternion&quot;&gt;DCM from Quaternion&lt;&#x2F;h3&gt;
&lt;p&gt;Given the four elements of a quaternion, we can do compute the corresponding rotation matrix. First we get the angle $\theta$ and axis, $\hat{n}$ when given a quaternion. We rotate by angle $\theta$ about the $z$ axis and then transform this rotation by a rotation to the axis specified by the colatitude ($\varphi$) and longitude ($\lambda$) of the axis $\hat{n}$:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{R}(\theta, \hat{n}) = \mathbf{R}_z(\lambda)\mathbf{R}_y(\varphi)~\mathbf{R}_z(\theta)~\mathbf{R}_y(\varphi)^\mathscr{T}\mathbf{R}_z(\lambda)^\mathscr{T}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\varphi = \arccos(\hat{n_z})$ and $\lambda = \arctan(\hat{n}_y, \hat{n}_x)$.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;my-angle-axis-&amp;gt;rotation-matrix &lt;&#x2F;span&gt;&lt;span&gt;[theta n]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[nx (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        ny (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        nz (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        colatitude (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;acos&lt;&#x2F;span&gt;&lt;span&gt; nz)
&lt;&#x2F;span&gt;&lt;span&gt;        longitude (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;atan&lt;&#x2F;span&gt;&lt;span&gt; ny nx)]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rotate-z-matrix&lt;&#x2F;span&gt;&lt;span&gt; longitude)
&lt;&#x2F;span&gt;&lt;span&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rotate-y-matrix&lt;&#x2F;span&gt;&lt;span&gt; colatitude)
&lt;&#x2F;span&gt;&lt;span&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rotate-z-matrix&lt;&#x2F;span&gt;&lt;span&gt; theta)
&lt;&#x2F;span&gt;&lt;span&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;transpose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rotate-y-matrix&lt;&#x2F;span&gt;&lt;span&gt; colatitude))
&lt;&#x2F;span&gt;&lt;span&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;transpose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rotate-z-matrix&lt;&#x2F;span&gt;&lt;span&gt; longitude)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;my-angle-axis-&amp;gt;rotation-matrix &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; pi &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0 0 1&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\mathsf{matrix-by-rows}\left(\begin{pmatrix}\displaystyle{0.7071067811865476} \cr \cr \displaystyle{-0.7071067811865475} \cr \cr \displaystyle{0}\end{pmatrix}, \begin{pmatrix}\displaystyle{0.7071067811865475} \cr \cr \displaystyle{0.7071067811865476} \cr \cr \displaystyle{0}\end{pmatrix}, \begin{pmatrix}\displaystyle{0.0} \cr \cr \displaystyle{0.0} \cr \cr \displaystyle{1}\end{pmatrix}\right)
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;quaternion-&amp;gt;angle-axis &lt;&#x2F;span&gt;&lt;span&gt;[q]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[v (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;quat&#x2F;three-vector&lt;&#x2F;span&gt;&lt;span&gt; q)
&lt;&#x2F;span&gt;&lt;span&gt;        sintheta (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sqrt &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;dot-product&lt;&#x2F;span&gt;&lt;span&gt; v v))
&lt;&#x2F;span&gt;&lt;span&gt;        theta (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;atan&lt;&#x2F;span&gt;&lt;span&gt; sintheta (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;quat&#x2F;real-part&lt;&#x2F;span&gt;&lt;span&gt; q)))
&lt;&#x2F;span&gt;&lt;span&gt;        axis (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; v sintheta)]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; theta axis)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Quaternion to DCM
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;quaternion-&amp;gt;DCM &lt;&#x2F;span&gt;&lt;span&gt;[q]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[aa (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;quaternion-&amp;gt;angle-axis&lt;&#x2F;span&gt;&lt;span&gt; q)
&lt;&#x2F;span&gt;&lt;span&gt;        theta (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; aa &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        n (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; aa &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;angle-axis-&amp;gt;rotation-matrix&lt;&#x2F;span&gt;&lt;span&gt; theta n)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; 30 degrees about z axis
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;render &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;quaternion-&amp;gt;DCM &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;quat&#x2F;make &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; pi &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0 0 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; pi &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    matrix-by-rows(up(0.8660254037844387, -0.49999999999999994, 0), up(0.49999999999999994, 0.8660254037844387, 0), up(0.0, 0.0, 1))
&lt;&#x2F;div&gt;
&lt;p&gt;The matrix terms here are all divided by the magnitude of $q$ which can be ignored since we use unit quaternions. Once this is removed, we get the following form for the rotation matrix from a quaternion $(q_0, q_1, q_2, q_3)$:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}q_0^2 + q_1^2 - q_2^2 -q_3^2 &amp;amp; -2q_0q_3 + 2q_1q_2 &amp;amp; 2q_0q_2 + 2q_1q_3 \\
2q_0q_3 + 2q_1q_2 &amp;amp; q_0^2 - q_1^2 + q_2^2 - q_3^2 &amp;amp; -2q_0q_1 + 2q_2q_3\\
-2q_0q_2 + 2q_1q_3 &amp;amp; 2q_0q_1 + 2q_2q_3 &amp;amp; q_0^2 - q_1^2 - q_2^2 + q_3^2\\
\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;quaternion-&amp;gt;rotation-matrix &lt;&#x2F;span&gt;&lt;span&gt;[q]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[q-vec (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;quat&#x2F;-&amp;gt;vector&lt;&#x2F;span&gt;&lt;span&gt; q)
&lt;&#x2F;span&gt;&lt;span&gt;        q0 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; q-vec &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) 
&lt;&#x2F;span&gt;&lt;span&gt;        q1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; q-vec &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        q2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; q-vec &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        q3 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; q-vec &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        m-2
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;matrix-by-rows
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;list &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;                    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; q1 q2) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; q0 q3)))
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; q1 q3) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; q0 q2))))
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;list &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; q1 q2) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; q0 q3)))
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;                    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; q2 q3) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; q0 q1))))
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;list &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; q1 q3) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; q0 q2)))
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; q2 q3) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; q0 q1)))
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;                    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; q2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)))))
&lt;&#x2F;span&gt;&lt;span&gt;         m-2)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; This function can be further used to compute the components of angular velocity using M-&amp;gt;omega-body
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermat
&lt;&#x2F;span&gt;&lt;span&gt;  ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rigid&#x2F;M-&amp;gt;omega-body
&lt;&#x2F;span&gt;&lt;span&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose&lt;&#x2F;span&gt;&lt;span&gt; quaternion-&amp;gt;rotation-matrix quat&#x2F;make))
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;q_0 &amp;#39;q_1 &amp;#39;q_2 &amp;#39;q_3)
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;qdot_0 &amp;#39;qdot_1 &amp;#39;qdot_2 &amp;#39;qdot_3))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\begin{bmatrix}\displaystyle{\begin{pmatrix}\displaystyle{\frac{2\,q_0\,{\dot q}_1 -2\,q_1\,{\dot q}_0 -2\,q_2\,{\dot q}_3 + 2\,q_3\,{\dot q}_2}{{q_0}^{2} + {q_1}^{2} + {q_2}^{2} + {q_3}^{2}}} \cr \cr \displaystyle{\frac{2\,q_0\,{\dot q}_2 + 2\,q_1\,{\dot q}_3 -2\,q_2\,{\dot q}_0 -2\,q_3\,{\dot q}_1}{{q_0}^{2} + {q_1}^{2} + {q_2}^{2} + {q_3}^{2}}} \cr \cr \displaystyle{\frac{2\,q_0\,{\dot q}_3 -2\,q_1\,{\dot q}_2 + 2\,q_2\,{\dot q}_1 -2\,q_3\,{\dot q}_0}{{q_0}^{2} + {q_1}^{2} + {q_2}^{2} + {q_3}^{2}}}\end{pmatrix}}\end{bmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Ignoring the denominator, the quaternion is independent of the scale of the quaternion. And since it is a fucntion of time, the rates of $q$ are also independent of scale. This can be further simplified by representing the products in the numerator as a matrix product. Define the following matrices:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathbf{i} &amp;amp;= \begin{pmatrix}0 &amp;amp; +1 &amp;amp; 0 &amp;amp; 0\\
-1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0\\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; -1\\
0 &amp;amp; 0 &amp;amp; +1 &amp;amp; 0\\\end{pmatrix}\\
\mathbf{j} &amp;amp;= \begin{pmatrix}0 &amp;amp; 0 &amp;amp; +1 &amp;amp; 0\\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; +1\\
-1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0\\
0 &amp;amp; -1 &amp;amp; 0 &amp;amp; 0\\\end{pmatrix}\\
\mathbf{k} &amp;amp;= \begin{pmatrix}0 &amp;amp; 0 &amp;amp; 0 &amp;amp; +1\\
0 &amp;amp; 0 &amp;amp; -1 &amp;amp; 0\\
0 &amp;amp; +1 &amp;amp; 0 &amp;amp; 0\\
-1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0\\\end{pmatrix}\tag{2.125}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The angular velocity components can now be written as :&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\omega^a &amp;amp;= 2\mathscr{q}^\mathscr{T}\mathbf{i}\dot{\mathscr{q}}~&amp;#x2F;~\|\mathscr{q}\|^2\\
\omega^b &amp;amp;= 2\mathscr{q}^\mathscr{T}\mathbf{j}\dot{\mathscr{q}}~&amp;#x2F;~\|\mathscr{q}\|^2\\
\omega^c &amp;amp;= 2\mathscr{q}^\mathscr{T}\mathbf{k}\dot{\mathscr{q}}~&amp;#x2F;~\|\mathscr{q}\|^2\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\mathscr{q}$ is a column vector of the components of $q$. The anti-symmetric matrices $\mathbf{i}$, $\mathbf{j}$ and $\mathbf{k}$ have the interesting properties that make it the basis vectors for the quaternions:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{i}^2 = \mathbf{j}^2 = \mathbf{k}^2 = \mathbf{i}\mathbf{j}\mathbf{k} = -\mathbf{1}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\mathbf{1}$ is the identity matrix.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;composition-of-rotations&quot;&gt;Composition of rotations&lt;&#x2F;h3&gt;
&lt;p&gt;An easy way to compose ttwo rotations would be to convert ehm to DCMs and multiply them. However this results in a very messy results where each component is scaled by a factor of $|q||p|$ (which is equal to $1$ for unit quaternions). Eliminating this scale factor, we get the following form for composition of quaternions&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}
p_0q_0-p_1q_1-p_2q_2-p_3q_3\\
p_0q_1+p_1q_0-p_2q_3+p_3q_2\\
p_0q_2+p_1q_3+p_2q_0-p_3q_1\\
p_0q_3-p_1q_2+p_2q_1+p_3q_0\\
\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This can be re-stated as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
r_0 = q_0p_0 - v_q \cdot v_p\\
$$
&lt;&#x2F;div&gt;
&lt;div&gt;
    $$
v_r = q_0v_p+p_0v_q + v_q \times v_p\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $r_0$ is the scalar part of the result, $v_r$ is the vector part of the result and $v_p$ and $v_q$ are the vector parts of the original quaternions. This can be considered to be the product of the two quaternions.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{r} = \mathbf{q}\mathbf{p}
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.11.1: Spin-Orbit Coupling - Development of Potential Energy</title>
        <published>2022-11-13T20:54:32+00:00</published>
        <updated>2022-11-13T20:54:32+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-11-1-spin-orbit-coupling-potential-energy/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-11-1-spin-orbit-coupling-potential-energy/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-11-1-spin-orbit-coupling-potential-energy/">&lt;h2 id=&quot;2-11-spin-orbit-coupling&quot;&gt;2.11 Spin Orbit Coupling&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The rotation of planets and natural satellites is affected by the gravitational forces from other celestial bodies. As an extended application of the Lagrangian method for forced rigid bodies, we consider the rotation of celestial objects subject to gravitational forces.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;In this section, we will develop expressions for potential energy for the graviational interaction of an “extended body” (i.e. not a point mass) with an external point mass. Combined with the rigid body kinetic energy, this can be used to create Lagrangians that model a number of systems.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-11-1-development-of-the-potential-energy&quot;&gt;2.11.1 Development of the Potential Energy&lt;&#x2F;h3&gt;
&lt;p&gt;The rigid body can be modeled as a collection of particles subject to rigid constraints. Similar to the kinetic energy decribed in the previous section, the potential energy of a rigid body can also be expressed in terms of the moment of inertia and later expressed in terms of generalized coordinates.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;projects&#x2F;sicm-workbook&#x2F;figure-2.9.jpg&quot; alt=&quot;Figure 2.9&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 2.9 The gravitational potential energy of a point mass and a rigid body is the sum of the gravitational potential energy of the point mass with each constituent mass element of the rigid body.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The gravitational potential energy of a rigid body is the sum of the potential energies of the individual point masses that make up the rigid body.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
V = - \sum_\alpha \frac{G M&amp;#x27; m_\alpha}{r_\alpha}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $M’$ is the mass of the external point mass that is the source of the gravity, $r_\alpha$ is the distance from the point mass to the component particle in the rigid body and $G$ is the universal gravitational constant. The position of the component particle can be resolved as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\vec{r}_alpha = \vec{R} - \vec{\xi}_\alpha\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\vec{R}$ is the vector from the external point mass to the center of mass of the rigid body. With this formulation, the distance to the particle, $r_\alpha$ becomes, $r_\alpha = R^2 + \xi^2_\alpha - 2R\xi_\alpha \cos\theta_\alpha$, where $\theta_\alpha$ is the angle between the lines from the center of mass to the constituent particle and to the point mass (see Figure 2.9).&lt;&#x2F;p&gt;
&lt;p&gt;Given that this is a three-dimensional body, $\xi_\alpha$ and $\theta_\alpha$ cannot uniquely specify the p0osition of the constituent particle. However, these are the only parameters required to define the potential energy as it is simply a function of the distance between the particle and the distant point mass. The potential energy is therefore defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{eqnarray}
V &amp;amp;= -GM&amp;#x27; \sum_\alpha \frac{m_\alpha}{\left(R^2 + \xi^2_\alpha - 2R\xi_\alpha \cos\theta_\alpha\right)^{1&amp;#x2F;2}}\\
  &amp;amp;= -GM&amp;#x27; \sum_\alpha m_\alpha \left(R^2 + \xi^2_\alpha - 2R\xi_\alpha \cos\theta_\alpha\right)^{-1&amp;#x2F;2}
\end{eqnarray}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This can be expanded using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Legendre_polynomials#Expanding_a_1&#x2F;r_potential&quot;&gt;Legendre Polynomials&lt;&#x2F;a&gt;. The Legendre polynomials $P_l$ may be obtained by expanding the expression $(1 + y^2 − 2yx)^{1&#x2F;2}$ as a power series in $y$. The coefficient of $y_l$ is $P_l(x)$. The first few Legendre polynomials are: $P_0(x) = 1$, $P_1(x) = x$,  $P_2(x)=\frac{3}{2}x^2−\frac{1}{2}$ , and so on. Then we get the following expression for potential energy:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
V = \frac{-GM&amp;#x27;}{R} \sum_\alpha m_\alpha \sum_l \frac{\xi^l_\alpha}{R^l}P_l \cos(\theta_\alpha)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Successive terms in this expansion typically drop off quickly since the distance between celestial bodies are vastly bigger than their size. Each term in the series has an upper bound. This is because the Legendre polynomials all have a magnitude less than one for arguments between -1 and 1 (which $\cos(\theta_\alpha)$ satisfies), and the distances $\xi_\alpha$ are all less than some maximum size $\xi_{max}$. Therefore, the sum over $m_\alpha$ times the upper bounds of each term is just $M$ times the upper bounds. Therefore,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\left|\sum_\alpha m_\alpha \frac{\xi^l_\alpha}{R^l}P_l \cos(\theta_\alpha)\right| \leq M \frac{\xi^l_{max}}{R^l}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Successive terms decrease by a factor of $\frac{\xi_{max}}{R}$. A body with a sufficiently strong gravitational force overcomes the material strength of the rigid body and converts it into a sphere over time. The higher order terms in the series are measuring the deviation of the rigid body from a sphere. We can truncate the series to different values of $l$ based on the fidelity required.&lt;&#x2F;p&gt;
&lt;p&gt;When $l=0$, the sum over $\alpha$ gives the total mass $M$ of the rigid body. For $l=1$, the sum is zero because $\vec{\xi}_\alpha$ is defiend relative to the center of mass. For $l=2$, the sum can be written in terms of the moment of inertia of the body as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\sum_\alpha m_\alpha \xi^2_\alpha P_2 \cos(\theta_\alpha) &amp;amp;= \sum_\alpha m_\alpha \xi^2_\alpha\left(\frac{3}{2}\cos^2\theta_\alpha -\frac{1}{2} \right)\\
&amp;amp;= \sum_\alpha m_\alpha \xi^2_\alpha\left(\frac{3}{2}(1 - \sin^2\theta_\alpha) -\frac{1}{2} \right)\\
&amp;amp;= \sum_\alpha m_\alpha \xi^2_\alpha\left((1 - \frac{3}{2}\sin^2\theta_\alpha) \right)\\
&amp;amp;= \frac{1}{2}( A + B + C - 3I )\tag{2.97}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $A, B, C$ are the principal moments of inertia and $I$ is the moment of inertia of the body about the line between the center of mass of the body and the external point mass. $I$ depends on the orientation of the body w.r.t line between the bodies. Therefore, the potential energy of the body with terms up to $l=2$ is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
V = \frac{-GM M&amp;#x27;}{R} - \frac{GM&amp;#x27;}{R} \left( A + B + C - 3I \right)\tag{2.98}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This is also called &lt;em&gt;MacCullagh’s formula&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;projects&#x2F;sicm-workbook&#x2F;figure-2.10.jpg&quot; alt=&quot;Figure 2.10&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 2.10: The orientation of the rigid body is specified by the three angles from the line between the centers and the principal axes.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Figure 2.10 shows a method for computing $I$ in terms of the principal moment of inertia. Let $\theta_a$, $\theta_b$, and $\theta_c$, are the angles of the principal axes $\hat{a}, \hat{b}, \hat{c}$, respectively, from the line connecting the center of mass and the point mass. Then $I$ can be found to be:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
I = A \cos^2\theta_a + B \cos^2\theta_b + C \cos^2\theta_c\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The potential energy is then:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
V = \frac{-GM M&amp;#x27;}{R} - \frac{GM&amp;#x27;}{R} \left[ (1-3\cos^2\theta_a)A + (1-3\cos^2\theta_b)B + (1-3\cos^2\theta_c)C\right]\tag{2.99}
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 2.13: Bicycle Wheel (incomplete)</title>
        <published>2022-11-13T20:15:14+00:00</published>
        <updated>2022-11-13T20:15:14+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-13/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-13/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-13/">&lt;h3 id=&quot;exercise-2-13-bicycle-wheel&quot;&gt;Exercise 2.13: Bicycle Wheel&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;a. Imagine that you are holding a bicycle wheel by the axle (in both hands) and the wheel is spinning so that the top edge is going away from your face. If you torque the wheel by pushing down with your right hand and pulling up with your left hand the wheel will precess. Which way does it try to turn?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;$$\require{cancel}$$&lt;&#x2F;p&gt;
&lt;p&gt;Assume that the axle of the wheel forms the $z$ axis of the system (positive to the right). Let the $x$ axis point forward, and the $y$ axis point up, forming a right-handed coordinate system. The bicycle wheel starts spinning about the axle with some speed $\omega^c$. Therefore the angular velocity vector is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\vec{\omega} = \omega^c \hat{z}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Pushing the axle down on the right side and pulling it up on the left equals a positive torque about the $x$ axis, that is,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\vec{T} = \mathbf{T}_a \hat{x}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;From Eq. 2.83 in the book&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
A D \omega^a - \left(B - C\right) \omega^b \omega^c &amp;amp;= \mathbf{T}_a\tag{2.83a}\\
B D \omega^b - \left(C - A\right) \omega^c \omega^a &amp;amp;= \mathbf{T}_b\tag{2.83b}\\
C D \omega^c - \left(A - B\right) \omega^a \omega^b &amp;amp;= \mathbf{T}_c\tag{2.83c}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Substituting $A = B$ (as the wheel is symmetric) and $\mathbf{T}_c = 0$ in Eq. 2.83c, we find that $D \boldsymbol{\omega^c} = 0$ which means that $\omega^c$ is a constant. Substituting $\mathbf{T}_b = 0$ and $A = B$ in Eq.2.83b,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\overbrace{B}^{=A} D \omega^b - \left(C - A\right) \omega^c \omega^a &amp;amp;= 0\\
\frac{ A D \omega^b}{\left(C - A\right)\omega^c} &amp;amp;=  \omega^a\\
\frac{A}{K_1} D \omega^b = \omega^a
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $K_1 = (C - A)\omega^c$. Substituting $\omega^a$ in Eq.2.83a, along with $A = B$,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathbf{T}_a &amp;amp;= A D \omega^a - \left(\overbrace{B}^{=A} - C\right) \omega^b \omega^c\\
        &amp;amp;= A D ( \frac{A}{K_1} D \omega^b ) - (A - C) \omega^c \omega^b\\
        &amp;amp;= \frac{A^2}{K_1}  D^2 \omega^b + K_1 \omega^b\\
\mathbf{T}_a &amp;amp;= \frac{ A^2 }{K_1} D^2 \omega^b + K_1 \omega^b\\
K_1 \mathbf{T}_a &amp;amp;= A^2 D^2 \omega^b + K_1^2 \omega^b
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This shows that the $\omega^b$ has a motion governed by a second order differential equation dependent on the magnitude of torque applied about the $x$ axis. So the bicycle wheel will try to precess about the $y$ axis (i.e. turn left&#x2F;right).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;b. A free bicycle wheel rolls on a horizontal surface. If it starts to tilt, the torque from gravity will cause the wheel to turn. Which way will it turn? The reasoning that applied to part a does not directly apply to the rolling bicycle wheel, which is not a holonomic system. However, it is interesting to think about whether the behavior of the two systems is related.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 2.12: Derivation of Euler Angle Kinematics</title>
        <published>2022-11-13T07:06:08+00:00</published>
        <updated>2022-11-13T07:06:08+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-12/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-12/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-12/">&lt;h3 id=&quot;exercise-2-12-derivation-of-euler-angle-kinematics&quot;&gt;Exercise 2.12: Derivation of Euler Angle Kinematics&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Fill in the details of the derivation of equation (2.73). You may want to use the computer to help with the algebra.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}D\theta \\ D\varphi \\ D\psi \end{pmatrix} = \frac{1}{\sin\theta} \begin{pmatrix} 
\cos\psi \sin\theta &amp;amp; -\sin\psi\sin\theta &amp;amp; 0 \\
\sin\psi &amp;amp; \cos\psi &amp;amp; 0 \\
-\sin\psi \cos\theta &amp;amp; -\cos\psi\cos\theta &amp;amp; \sin\theta \\
\end{pmatrix}\begin{pmatrix}\omega^a \\ \omega^b \\ \omega^c\end{pmatrix}\tag{2.73}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;Note how the order of $\theta$, $\varphi$ and $\psi$ are different in the vector&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;$$\require{cancel}$$&lt;&#x2F;p&gt;
&lt;p&gt;With 3-1-3 Euler angles, $\mathbf{M}$ is defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{M} = \mathbf{R}_z(\varphi)\cdot\mathbf{R}_x(\theta)\cdot\mathbf{R}_z(\psi)\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;For 3-1-3 Euler angles, there are three rotations with two intermediate frames starting from the inertial frame. Let the inertial frame be represented by the $\hat{a}$, the frame after first rotation by $\hat{b’}$, and the frame after the second rotation by $\hat{b’’}$. Let $\hat{b}$ represent the final “body-frame”.&lt;&#x2F;p&gt;
&lt;p&gt;Therefore, ${}^{A}\omega^{B’} = \dot{\varphi} \hat{a}_3 = \dot{\varphi} \hat{b}_3’$, $^{B’}\omega^{B’‘} = \dot{\theta} \hat{b}_1’ = \dot{\theta} \hat{b}_1’‘$ and $^{B’‘}\omega^{B} = \dot{\psi} \hat{b}_3’’ = \dot{\psi} \hat{b}_3$ .&lt;&#x2F;p&gt;
&lt;p&gt;The total angular velocity is the sum of all three components, that is,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
^{A}\vec{\omega}^{B} &amp;amp;=~^{A}\omega^{B&amp;#x27;} +~^{B&amp;#x27;}\omega^{B&amp;#x27;&amp;#x27;} +~^{B&amp;#x27;&amp;#x27;}\omega^{B} \\
                     &amp;amp;=\dot{\varphi} \hat{b}_3&amp;#x27; + \dot{\theta} \hat{b}_1&amp;#x27;&amp;#x27; + \dot{\psi} \hat{b}_3 \\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;To get the components in body-frame, we need to convert $\hat{b}_3’$ and $\hat{b}_1’’$ to be in terms of $\hat{b}$.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We know that the $\hat{b}$‘’ rotated about its $z$ axis, forms the body-frame, $\hat{b}$. Therefore, (need to draw coordinate frame rotations to get this expression)&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}\hat{b}_1&amp;#x27;&amp;#x27;\\ \hat{b}_2&amp;#x27;&amp;#x27; \\ \hat{b}_3&amp;#x27;&amp;#x27;\end{pmatrix} = \begin{pmatrix}\cos\psi &amp;amp; -\sin\psi &amp;amp; 0\\ \sin\psi &amp;amp; \cos\psi &amp;amp; 0 \\0 &amp;amp; 0 &amp;amp; 1\\ \end{pmatrix} \begin{pmatrix}\hat{b}_1\\ \hat{b}_2 \\ \hat{b}_3\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;div&gt;
    $$
\begin{align*}
\hat{b}_1&amp;#x27;&amp;#x27; &amp;amp;= \cos{\psi}~\hat{b}_1 - \sin\psi~\hat{b}_2\\
\hat{b}_2&amp;#x27;&amp;#x27; &amp;amp;= \sin{\psi}~\hat{b}_1 + \cos\psi~\hat{b}_2\\
\hat{b}_3&amp;#x27;&amp;#x27; &amp;amp;= \hat{b}_3
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Similarly, for the $\hat{b}’$ frame,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}\hat{b}_1&amp;#x27;\\ \hat{b}_2&amp;#x27; \\ \hat{b}_3&amp;#x27;\end{pmatrix} = \begin{pmatrix}
1 &amp;amp; 0 &amp;amp; 0\\ 
0 &amp;amp; \cos\theta &amp;amp; -\sin\theta\\
0 &amp;amp; \sin\theta &amp;amp; \cos\theta\\
\end{pmatrix} \begin{pmatrix}\hat{b}&amp;#x27;&amp;#x27;_1\\ \hat{b}&amp;#x27;&amp;#x27;_2 \\ \hat{b}&amp;#x27;&amp;#x27;_3\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;div&gt;
    $$
\begin{align*}
\hat{b}_3&amp;#x27; &amp;amp;= \sin\theta~\hat{b}_2&amp;#x27;&amp;#x27; + \cos\theta~\hat{b}_3&amp;#x27;&amp;#x27;\\
 &amp;amp;= \sin\theta\left(\sin{\psi}~\hat{b}_1 + \cos\psi~\hat{b}_2\right) + \cos\theta~\hat{b}_3\\
 &amp;amp;= \sin\theta\sin{\psi}~\hat{b}_1 + \sin\theta\cos\psi~\hat{b}_2 + \cos\theta~\hat{b}_3\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Assuming that the body-frame is the principal axes frame, the angular velocity vector is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\vec{\omega} &amp;amp;= \dot{\varphi} \hat{b}_3&amp;#x27; + \dot{\theta} \hat{b}_1&amp;#x27;&amp;#x27; + \dot{\psi} \hat{b}_3 \\
 &amp;amp;= \dot{\varphi} \left(\sin\psi \sin\theta~\hat{b}_1 + \cos\psi\sin\theta~\hat{b}_2 + \cos\theta~\hat{b}_3 \right) + \dot{\theta}\left(\cos{\psi}~\hat{b}_1 - \sin\psi~\hat{b}_2\right) + \dot{\psi}~\hat{b}_3\\
\omega^a \hat{b}_1  + \omega^b \hat{b}_2 + \omega^c \hat{b}_3 &amp;amp;= (\sin\psi \sin\theta\dot{\varphi} + \dot{\theta} \cos{\psi})~\hat{b}_1 + \left( + \cos\psi \sin{\theta}\dot{\varphi} - \dot{\theta}\sin\psi\right)\hat{b}_2 + \left( \dot{\varphi}\cos\theta + \dot{\psi} \right)\hat{b}_3
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This can be written in matrix form as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}\omega^a \\ \omega^b \\ \omega^c\end{pmatrix} = \begin{pmatrix}
\sin\psi \sin\theta &amp;amp; \cos{\psi} &amp;amp; 0\\
\cos\psi\sin\theta &amp;amp; -\sin\psi &amp;amp; 0\\
\cos\theta &amp;amp; 0 &amp;amp; 1
\end{pmatrix}
\begin{pmatrix}\dot{\varphi} \\ \dot{\theta} \\ \dot{\psi}\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Inverting this equation, we get:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;theta, phi, psi = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;symbols&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;theta phi psi&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;real&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;A = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span&gt;([ [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt;(psi)*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt;(theta), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt;(psi), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt;(psi)*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt;(theta), -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt;(psi), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;], [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt;(theta), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;] ])
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;simplify&lt;&#x2F;span&gt;&lt;span&gt;(A.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;inv&lt;&#x2F;span&gt;&lt;span&gt;())
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $\displaystyle \left[\begin{matrix}\frac{\sin{\left(\psi \right)}}{\sin{\left(\theta \right)}} &amp;amp; \frac{\cos{\left(\psi \right)}}{\sin{\left(\theta \right)}} &amp;amp; 0\\\cos{\left(\psi \right)} &amp;amp; - \sin{\left(\psi \right)} &amp;amp; 0\\- \frac{\sin{\left(\psi \right)}}{\tan{\left(\theta \right)}} &amp;amp; - \frac{\cos{\left(\psi \right)}}{\tan{\left(\theta \right)}} &amp;amp; 1\end{matrix}\right]$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}\dot{\varphi} \\ \dot{\theta} \\ \dot{\psi}\end{pmatrix} = \frac{1}{\sin\theta}\begin{pmatrix}
\sin\psi &amp;amp; \cos{\psi} &amp;amp; 0\\
\cos\psi\sin\theta &amp;amp; -\sin\psi\sin\theta &amp;amp; 0\\
-\sin\psi\cos\theta &amp;amp; -\cos\psi\cos\theta &amp;amp; \sin\theta
\end{pmatrix}\begin{pmatrix}\omega^a \\ \omega^b \\ \omega^c\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Swapping the rows 1 and 2 to match the order in the question, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}D\theta \\ D\varphi \\D\psi\end{pmatrix} = \begin{pmatrix}\dot{\theta} \\ \dot{\varphi} \\\dot{\psi}\end{pmatrix} = \frac{1}{\sin\theta}\begin{pmatrix}
\cos\psi\sin\theta &amp;amp; -\sin\psi\sin\theta &amp;amp; 0\\
\sin\psi &amp;amp; \cos{\psi} &amp;amp; 0\\
-\sin\psi\cos\theta &amp;amp; -\cos\psi\cos\theta &amp;amp; \sin\theta
\end{pmatrix}\begin{pmatrix}\omega^a \\ \omega^b \\ \omega^c\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;&#x2F;h3&gt;
&lt;p&gt;[1] : &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=af041z8jujU&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=af041z8jujU&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 2.11: Conservation of Angular Momentum</title>
        <published>2022-11-12T22:10:11+00:00</published>
        <updated>2022-11-12T22:10:11+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-11/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-11/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-11/">&lt;h3 id=&quot;exercise-2-11-conservation-of-angular-momentum&quot;&gt;Exercise 2.11: Conservation of Angular Momentum&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Fill in the details of the argument that Noether’s theorem implies that vector angular momentum is conserved by the motion of the free rigid body.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;$$\require{cancel}$$&lt;&#x2F;p&gt;
&lt;p&gt;According to &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-1-8-5-noethers-theorem&#x2F;&quot;&gt;Noether’s theorem&lt;&#x2F;a&gt;, for any continuous symmetry in a system (aka a parametric family of symmetries), there is a conserved quantity.&lt;&#x2F;p&gt;
&lt;p&gt;In the case of rigid bodies, rotations about any axis is a symmetry. This can be proved as shown below:&lt;&#x2F;p&gt;
&lt;p&gt;The Lagrangian in rectangular coordinates for a rigid body with particles indexed by $\alpha$ is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L(t; x,y,z; v_x, v_y, v_z) = \frac{1}{2} \sum_\alpha m_\alpha \left( \dot{x}_\alpha^2 + \dot{y}_\alpha^2 + \dot{z}_\alpha^2\right) \tag{1}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Consider a parameteric rotation about the $z$-axis:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}x_\alpha \\y_\alpha \\z_\alpha \end{pmatrix} = 
R_z(s)\begin{pmatrix}x_\alpha&amp;#x27; \\y_\alpha&amp;#x27; \\z_\alpha&amp;#x27; \end{pmatrix} = \begin{pmatrix}x_\alpha&amp;#x27; \cos{s} - y_\alpha&amp;#x27;\sin{s}\\x_\alpha&amp;#x27; \sin{s} + y_\alpha&amp;#x27;\cos{s}\\z_\alpha&amp;#x27;\end{pmatrix}\tag{2}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Since a rotation is an orthogonal transformation, it does not change the magnitude of the vector,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
x_\alpha^2 + y_\alpha^2 + z_\alpha^2 = (x_\alpha&amp;#x27;)^2 + (y_\alpha&amp;#x27;)^2 + (z_\alpha&amp;#x27;)^2\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Similarly, differentiating Eq.2 along a path, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}\dot{x}_\alpha\\ \dot{y}_\alpha\\ \dot{z}_\alpha\end{pmatrix} =
R_z(s)\begin{pmatrix}\dot{x}_\alpha&amp;#x27;\\ \dot{y}_\alpha&amp;#x27;\\ \dot{z}_\alpha&amp;#x27;\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\dot{x}_\alpha^2 + \dot{y}_\alpha^2 + \dot{z}_\alpha^2 = \dot{x}_\alpha&amp;#x27;^2 + \dot{y}_\alpha&amp;#x27;^2 + \dot{z}_\alpha&amp;#x27;^2
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Combining these, we can see that the post-transformation Lagrangian $L’$ is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L&amp;#x27;(t; x_\alpha&amp;#x27;,y_\alpha&amp;#x27;,z_\alpha&amp;#x27;; \dot{x}_\alpha&amp;#x27;,\dot{y}_\alpha&amp;#x27;,\dot{z}_\alpha&amp;#x27;) = \frac{1}{2} \sum_\alpha m \left(\dot{x}_\alpha&amp;#x27;^2 + \dot{y}_\alpha&amp;#x27;^2 + \dot{z}_\alpha&amp;#x27;^2 \right)\tag{3}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore $L’$ in Eq.3 is the exact same function as $L$ in Eq. 1 and hence there is a conserved value corresponding to the rotational symmetry about the z-axis. The momenta are defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\partial_2 L = \left[\sum_\alpha m_\alpha \dot{x}, \sum_\alpha m_\alpha \dot{y}, \sum_\alpha m_\alpha \dot{z}\right]
$$
&lt;&#x2F;div&gt;
&lt;p&gt;and&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D\widetilde{F}(0)(t;x,y,z)=D\widetilde{R}_z(0)(x,y,z) = [ y, -x, 0]\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore the Noether integral is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathscr{I}(t; x_\alpha,y_\alpha,z_\alpha; \dot{x}_\alpha,\dot{y}_\alpha,\dot{z}_\alpha) &amp;amp;= ((\partial_2 L)(D\widetilde{F}(0))) (t; x_\alpha,y_\alpha,z_\alpha; \dot{x}_\alpha,\dot{y}_\alpha,\dot{z}_\alpha) \\
&amp;amp;= \sum_\alpha \left(m_\alpha \dot{x}_\alpha~y_\alpha -m_\alpha \dot{y}_\alpha~x_\alpha + (m_\alpha \dot{z}_\alpha)(0) \right) \\
&amp;amp;= \sum_\alpha m_\alpha \left(y_\alpha \dot{x}_\alpha - x_\alpha \dot{y}_\alpha \right)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This is the $z$ component of the angular momentum vector $\sum_\alpha \vec{\xi_\alpha} \times (m_\alpha \dot{\vec{\xi}}_\alpha)$&lt;&#x2F;p&gt;
&lt;p&gt;In the following program, we compute the noether integrals for rotations around all three coordinate axes.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;RotX &lt;&#x2F;span&gt;&lt;span&gt;[angle]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[x&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; z]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[ca (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; angle)
&lt;&#x2F;span&gt;&lt;span&gt;            sa (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; angle)]
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x
&lt;&#x2F;span&gt;&lt;span&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; ca y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; sa z))
&lt;&#x2F;span&gt;&lt;span&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; sa y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; ca z))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;RotY &lt;&#x2F;span&gt;&lt;span&gt;[angle]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[x&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; z]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[ca (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; angle)
&lt;&#x2F;span&gt;&lt;span&gt;            sa (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; angle)]
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; ca x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; sa z))
&lt;&#x2F;span&gt;&lt;span&gt;              y
&lt;&#x2F;span&gt;&lt;span&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; sa x)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; ca z))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;RotZ &lt;&#x2F;span&gt;&lt;span&gt;[angle]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[x&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; z]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[ca (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; angle)
&lt;&#x2F;span&gt;&lt;span&gt;            sa (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; angle)]
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; ca x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; sa y))
&lt;&#x2F;span&gt;&lt;span&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; sa x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; ca y))
&lt;&#x2F;span&gt;&lt;span&gt;              z))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Coordinate transformation with three angular &amp;quot;inputs&amp;quot; for rotations about
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; all three axes
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Composing with `coordinate`, extracts the second element of the tuple that is passed in as the argument
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;F-tilde &lt;&#x2F;span&gt;&lt;span&gt;[angle-x angle-y angle-z]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;RotX&lt;&#x2F;span&gt;&lt;span&gt; angle-x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;RotY&lt;&#x2F;span&gt;&lt;span&gt; angle-y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;RotZ&lt;&#x2F;span&gt;&lt;span&gt; angle-z) coordinate))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Lagrangian for motion of single particle in rigid body
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-rigid-body_particle &lt;&#x2F;span&gt;&lt;span&gt;[m]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[t q v]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Define the Noether integral
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;the-Noether-integral
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-rigid-body_particle &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_alpha)]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) L) ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D&lt;&#x2F;span&gt;&lt;span&gt; F-tilde) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0 0 0&lt;&#x2F;span&gt;&lt;span&gt;))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;the-Noether-integral
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_alpha &amp;#39;y_alpha &amp;#39;z_alpha)
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;xdot_alpha &amp;#39;ydot_alpha &amp;#39;zdot_alpha))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{bmatrix}\displaystyle{- m_{\alpha}\,y_{\alpha}\,{\dot z}_{\alpha} + m_{\alpha}\,{\dot y}_{\alpha}\,z_{\alpha}} \cr \cr \displaystyle{m_{\alpha}\,x_{\alpha}\,{\dot z}_{\alpha} - m_{\alpha}\,{\dot x}_{\alpha}\,z_{\alpha}} \cr \cr \displaystyle{- m_{\alpha}\,x_{\alpha}\,{\dot y}_{\alpha} + m_{\alpha}\,{\dot x}_{\alpha}\,y_{\alpha}}\end{bmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;The results above correspond to the components of the angular momentum vector for a single particle in a rigid body. Therefore the conserved quantities for a rigid body are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\sum_\alpha m_\alpha &amp;amp; \left( z_\alpha{\dot{y}_\alpha} - \dot{z}_\alpha y_\alpha \right)\\
\sum_\alpha m_\alpha &amp;amp; \left( x_\alpha{\dot{z}_\alpha} - \dot{x}_\alpha z_\alpha \right)\\
\sum_\alpha m_\alpha &amp;amp; \left( y_\alpha{\dot{x}_\alpha} - \dot{y}_\alpha x_\alpha \right)\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This proves that all three components of the angular moementum vector are conserved for a rigid body in free-rotation.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.9: Euler&#x27;s Equations</title>
        <published>2022-11-09T07:13:05+00:00</published>
        <updated>2022-11-09T07:13:05+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-9-eulers-equations/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-9-eulers-equations/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-9-eulers-equations/">&lt;h2 id=&quot;2-9-euler-s-equations&quot;&gt;2.9 Euler’s Equations&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;For a free rigid body we have seen that the components of the angular momentum on the principal axes comprise a self-contained dynamical system: the variation of the principal axis components depends only on the principal axis components. Here we derive equations that govern the evolution of these components.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The components of angular momentum (in column matrix form) on the principal axes are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\overline{\mathbf{L}}&amp;#x27; = \mathbf{I}&amp;#x27;\boldsymbol{\omega}&amp;#x27;\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\boldsymbol{\omega}‘$ are the angular velocity components on the principal axes and $\mathbf{I}’$ is the diagonal inertia tensor in the principal axes basis:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{I}&amp;#x27; = \begin{bmatrix}A &amp;amp; 0 &amp;amp; 0 \\ 0 &amp;amp; B &amp;amp; 0 \\ 0 &amp;amp; 0 &amp;amp; C\end{bmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;If $\mathbf{M}$ is the rotation that rotates all vectorsand the body from the fixed reference frame to the actual orientation, then the components of angualr momentum in the inertial frame $\hat{e}_i$ are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{L} = \mathbf{M} \mathbf{\overline{L}}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;For a free rigid vody, the vector angular momentum and therefore its components in the inertial frame are conserved. Therefore:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
D\mathbf{L} = D (\mathbf{M} \mathbf{\overline{L}}&amp;#x27;) &amp;amp;= D\mathbf{M}\mathbf{\overline{L}}&amp;#x27; + \mathbf{M} D\mathbf{\overline{L}&amp;#x27;}\\
\implies \mathbf{M} D\mathbf{\overline{L}&amp;#x27;} &amp;amp;= -D\mathbf{M}\mathbf{\overline{L}}&amp;#x27;\\
D\mathbf{\overline{L}&amp;#x27;} &amp;amp;= -\mathbf{M}^{\mathscr{T}} D\mathbf{M}\mathbf{\overline{L}}&amp;#x27;\tag{2.65}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;From &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-2-2-kinematics-of-rotation&#x2F;&quot;&gt;section 2.2&lt;&#x2F;a&gt;, we know that the components of the angular velocity can be written as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\boldsymbol{\omega}&amp;#x27; &amp;amp;= \mathbf{M}^\mathscr{T}  \mathscr{A}^{-1}(D \mathbf{M} \mathbf{M}^\mathscr{T}) \tag{2.21}\\
\implies \mathbf{M}\boldsymbol{\omega}&amp;#x27; &amp;amp;= \mathscr{A}^{-1}(D \mathbf{M} \mathbf{M}^\mathscr{T}) \tag{2.21a}\\
\implies \mathscr{A}(\mathbf{M}\boldsymbol{\omega}&amp;#x27;) &amp;amp;= D \mathbf{M} \mathbf{M}^\mathscr{T} \tag{2.21b}\\
\implies \mathscr{A}(\mathbf{M}\boldsymbol{\omega}&amp;#x27;)\mathbf{M} &amp;amp;= D \mathbf{M} \tag{2.21c}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Substituting Eq.2.21c in Eq.2.65 along with $\mathbf{I}‘\boldsymbol{\omega}’ = \overline{\mathbf{L}}’$&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathbf{I}&amp;#x27; D\boldsymbol{\omega}&amp;#x27; &amp;amp;= -\mathbf{M}^{\mathscr{T}} D\mathbf{M}\mathbf{I}&amp;#x27;\boldsymbol{\omega}&amp;#x27;\\
    &amp;amp;= -\mathbf{M}^{\mathscr{T}} \mathscr{A}(\mathbf{M}\boldsymbol{\omega}&amp;#x27;) \mathbf{M}~  \mathbf{I}&amp;#x27;\boldsymbol{\omega}&amp;#x27; \tag{2.66}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt;: The function $\mathscr{A}$ converts a vector into an anti-symmetric matrix. Multiplying this matrix with a vector is equivalent to taking a cross product of the original vector with this second vector. We also know that rotating the cross product of two vectors gives the same vector as is obtained by taking the cross product of two rotated vectors, or $R(\vec{u} \times \vec{v}) = (R\vec{u} )\times(R\vec{v})$&lt;&#x2F;p&gt;
&lt;p&gt;These two terms can be written in terms of $\mathscr{A}$ as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
R(\vec{u} \times \vec{v}) = \mathbf{R} \mathscr{A}(\mathbf{u}) \mathbf{v}
$$
&lt;&#x2F;div&gt;
&lt;div&gt;
    $$
(R\vec{u})\times(R\vec{v}) = \mathscr{A}(\mathbf{R} \mathbf{u}) \mathbf{R}\mathbf{v}\\
$$
&lt;&#x2F;div&gt;
&lt;div&gt;
    $$
\begin{align*}
\implies \mathbf{R} \mathscr{A}(\mathbf{u}) \mathbf{v} &amp;amp;= \mathscr{A}(\mathbf{R} \mathbf{u}) \mathbf{R} \mathbf{v}\\
\implies \mathbf{R} \mathscr{A}(\mathbf{u}) &amp;amp;=  \mathscr{A}(\mathbf{R} \mathbf{u}) \mathbf{R}\\
\mathscr{A}(\mathbf{u}) &amp;amp;=  \mathbf{R}^{\mathscr{T}} \mathscr{A}(\mathbf{R} \mathbf{u}) \mathbf{R}\tag{2.67}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Substituting Eq. 2.67 in Eq. 2.66:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathbf{I}&amp;#x27; D\boldsymbol{\omega}&amp;#x27; &amp;amp;= - \mathscr{A}(\boldsymbol{\omega}&amp;#x27;) \mathbf{I}&amp;#x27;\boldsymbol{\omega}&amp;#x27; \tag{2.68}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This is the matrix form of &lt;strong&gt;Euler’s Equations&lt;&#x2F;strong&gt; that gives the derivative of the body components of angular velocity entirely in terms of the angular velocity components and the principal moments of inertia. If the components of $\boldsymbol{\omega}’$ are $(\omega^a, \omega^b, \omega^c)$, then the equations can be re-written as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
A D\omega^a &amp;amp;= (B - C) \omega^b \omega^c\\
B D\omega^b &amp;amp;= (C - A) \omega^c \omega^a\\
C D\omega^c &amp;amp;= (A - B) \omega^a \omega^b\tag{2.69}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;These equations can also be written in terms of the components of angular momentum as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
D L_a &amp;amp;= \left(\frac{1}{C} - \frac{1}{B}\right) L_b L_c\\
D L_b &amp;amp;= \left(\frac{1}{A} - \frac{1}{C}\right) L_c L_a\\
D L_c &amp;amp;= \left(\frac{1}{B} - \frac{1}{A}\right) L_a L_b\tag{2.69}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;These equations &lt;em&gt;only&lt;&#x2F;em&gt; depend on the principal axes components of $L$. Equations 2.21b and 2.67 can be used to get the derivatives of the orientation of the body in terms of the angular velocity.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
D \mathbf{M} &amp;amp;= \mathscr{A}(\mathbf{M}\boldsymbol{\omega}&amp;#x27;)\mathbf{M}\tag{2.21c}\\
             &amp;amp;= \mathbf{M} \overbrace{\mathbf{M}^{\mathscr{T}}~\mathscr{A}(\mathbf{M}\boldsymbol{\omega}&amp;#x27;)\mathbf{M}}^{\text{Refer Eq. 2.67}}\\
             &amp;amp;= \mathbf{M} \mathscr{A}(\boldsymbol{\omega}&amp;#x27;)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;div&gt;
    $$
D\mathbf{M} = \mathbf{M}\mathscr{A}(\boldsymbol{\omega}&amp;#x27;)\tag{2.71}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;When the orientation of the body is represented by a DCM, this gives nine ordinary differential equations. These equations can be integrated witht eh initial conditions determined by the initial configuration matrix to get the evolution of the spatial orientation of the body. Combined with Euler’s equations, these equations completely definet the motion of a rigid body.&lt;&#x2F;p&gt;
&lt;p&gt;However, having to integrate nine equations is rather cumbersome when we know that the orientation can be represented by just three states (the Euler angles). In order to reduce this to a system of three equations we can go back to parameterizing the rotation matrix with the Euler angles. We can form the matrix $\mathbf{M}$ by composing $\mathscr{M}$ with an Euler coordinate path (i.e. write it as the product of three rotation matrices, $R_z$, $R_x$ and $R_z$). We can then solve for $D\theta$, $D\phi$ and $D\psi$ as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}
D\theta \\ D\phi \\ D\psi
\end{pmatrix} = \frac{1}{\sin\theta}\begin{pmatrix}
\cos\psi\sin\theta &amp;amp; -\sin\psi\sin\theta &amp;amp; 0\\
\sin\psi &amp;amp; \cos\psi &amp;amp; 0 \\
-\sin\psi\cos\theta &amp;amp; -\cos\psi\cos\theta &amp;amp; \sin\theta\end{pmatrix} \begin{pmatrix}\omega^a\\ \omega^b\\ \omega^c \end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;These equations are singular for $\theta = 0$, as expected. To quote the book:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The singularity in the equations of motion for $\theta = 0$ does not correspond to anything funny in the motion of the rigid body. A practical solution to the singularity problem is to choose another set of Euler-like angles that have a singularity in a different place, and switch from one to the other when the going gets tough.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;euler-s-equations-for-forced-rigid-bodies&quot;&gt;Euler’s equations for forced rigid bodies&lt;&#x2F;h2&gt;
&lt;p&gt;$$\require{cancel}$$&lt;&#x2F;p&gt;
&lt;p&gt;In this section, we derive Euler’s equations for a rigid body subject to an external torque. Consider a rigid body subject to some potential energy that is a function of time and configuration ($t$ and $q$). A suitable Lagrangian is $L = T - V$. If we use the 3-1-3 Euler angle set as the coordinates, the last of the three active rotations that define the coordinate is about the $z$ axis by the angle $\phi$. The Lagrange equation for $\phi$ is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D \partial_{\dot{\phi}} L = -D \underbrace{p_\phi}_{\text{conjugate momentum of }\phi} = \partial_{1,1} V(t; \theta(t), \phi(t), \psi(t))
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\partial_{1,1}$ refers to a partial derivative with respect to a component (at index 1 or $\phi$) of the coordinate argument of the potential energy function. If we define the torque component $T_z$, to be minus the derivative of the potential energy with respect to the angle of rotation of the body about the z axis, then,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
T_z(t) = -D p_\phi = \partial_{1,1} V(t; \theta(t), \phi(t), \psi(t))
$$
&lt;&#x2F;div&gt;
&lt;p&gt;and so $D p_\phi (t) = T_z$. Since the orientation of the coordinate axes are arbitrary, we may choose and orient them as we want. Thus if we want any component of the vector torque, we may choose the z-axis so that we can compute it in this way. Therefore the vector torque gives the derivative of the vector angular momentum (&lt;strong&gt;why?&lt;&#x2F;strong&gt;):&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D\vec{L} = \vec{T}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This can be substituted in Eq. 2.65 with $\mathbf{T}$ being the torque components in a column vector.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D\overline{\mathbf{L}} = \overline{\mathbf{T}} = D\mathbf{M}~\overline{\mathbf{L}}&amp;#x27; + \mathbf{M}D\overline{\mathbf{L}}&amp;#x27;\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Substituting in $\mathbf{I}‘\boldsymbol{\omega}’ = \overline{\mathbf{L}}’$, and $D\mathbf{M}$ from Eq. 2.21c,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\overline{\mathbf{T}} &amp;amp;= \left(\mathscr{A}(\mathbf{M}\boldsymbol{\omega}&amp;#x27;)\mathbf{M}\right)~\mathbf{I}&amp;#x27;\boldsymbol{\omega}&amp;#x27; + \mathbf{M}\mathbf{I}&amp;#x27;D\boldsymbol{\omega}&amp;#x27;\\
\implies \mathbf{M}^\mathscr{T} \overline{\mathbf{T}} &amp;amp;= \underbrace{\left(\mathbf{M}^\mathscr{T}  \mathscr{A}(\mathbf{M}\boldsymbol{\omega}&amp;#x27;)\mathbf{M}\right)}_{\text{see Eq. 2.67}}~\mathbf{I}&amp;#x27;\boldsymbol{\omega}&amp;#x27; + \mathbf{I}&amp;#x27;D\boldsymbol{\omega}&amp;#x27;\\
\implies \overbrace{\mathbf{M}^\mathscr{T} \overline{\mathbf{T}}}^{= \overline{\mathbf{T}}&amp;#x27;} &amp;amp;= \mathscr{A}(\boldsymbol{\omega}&amp;#x27;) \mathbf{I}&amp;#x27;\boldsymbol{\omega}&amp;#x27; + \mathbf{I}&amp;#x27; D\boldsymbol{\omega}&amp;#x27;\\
\implies \overline{\mathbf{T}}&amp;#x27; &amp;amp;= \mathscr{A}(\boldsymbol{\omega}&amp;#x27;) \mathbf{I}&amp;#x27;\boldsymbol{\omega}&amp;#x27; + \mathbf{I}&amp;#x27; D\boldsymbol{\omega}&amp;#x27;\tag{2.82}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\overline{\mathbf{T}}‘$ represents the torque vector components on the principal axes and $\mathbf{I}’$ is the inertia tensor in the basis vectors of the principal axes. The angular velocity rates can be determined from Eq. 2.82 as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
A D \boldsymbol{\omega^a} - \left(B - C\right) \omega^b \omega^c &amp;amp;= \mathbf{T}_a\\
B D \boldsymbol{\omega^b} - \left(C - A\right) \omega^c \omega^a &amp;amp;= \mathbf{T}_b\\
C D \boldsymbol{\omega^c} - \left(A - B\right) \omega^a \omega^b &amp;amp;= \mathbf{T}_c\tag{2.83}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The angular velocity components (on the principal axes) can be substituted by the angular momentum components on the principal axes as: $\omega^a = \frac{L_a}{A}, \omega^b = \frac{L_b}{B}, \omega^c = \frac{L_c}{C}$, to get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\cancel{A} \frac{D L_a}{\cancel{A}} - \left(B - C\right) \frac{L_b L_c}{BC} &amp;amp;= T_a\\
\cancel{B} \frac{D L_b}{\cancel{B}} - \left(C - A\right) \frac{L_c L_a}{CA} &amp;amp;= T_b\\
\cancel{C} \frac{D L_c}{\cancel{C}} - \left(A - B\right) \frac{L_a L_b}{AB} &amp;amp;= T_c\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This simplifies into:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
T_a &amp;amp;= D L_a - \left(\frac{1}{C} - \frac{1}{B}\right) L_b L_c\\
T_b &amp;amp;= D L_b - \left(\frac{1}{A} - \frac{1}{C}\right) L_c L_a\\
T_c &amp;amp;= D L_c - \left(\frac{1}{B} - \frac{1}{A}\right) L_a L_b\tag{2.80}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where the torque components on the principal axes can be obtained as: $\overline{\mathbf{T}}’ = \mathbf{M}^{-1}\overline{\mathbf{T}}$.&lt;&#x2F;p&gt;
&lt;p&gt;It is to be noted that the torque does not affect the orientation directly, but instead only affects the angular momentum or angular velocity. Therefore Euler’s equations define the dynamics of the system while the derivatives of orientation define the kinematics of the system.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.8.2: Qualitative Features of Free Rigid Body Motion</title>
        <published>2022-11-08T06:21:27+00:00</published>
        <updated>2022-11-08T06:21:27+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-8-2-qualitative-features-of-free-rigid-body-motion/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-8-2-qualitative-features-of-free-rigid-body-motion/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-8-2-qualitative-features-of-free-rigid-body-motion/">&lt;h2 id=&quot;2-8-2-qualitative-features-of-free-rigid-body-motion&quot;&gt;2.8.2 Qualitative Features of Free Rigid Body Motion&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The evolution of the components of the angular momentum on the principal axes has a remarkable property. For almost every initial condition the body components of the angular momentum periodically trace a simple closed curve.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;projects&#x2F;sicm-workbook&#x2F;figure-2.3.jpg&quot; alt=&quot;Figure 2.3: Trajectories of the components of the angular momentum vector on the principal axes, projected onto a plane. Each closed curve, except for the separatrix, is a different trajectory. All the trajectories shown here have the same energy.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 2.3: Trajectories of the components of the angular momentum vector on the principal axes, projected onto a plane. Each closed curve, except for the separatrix, is a different trajectory. All the trajectories shown here have the same energy&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The above figure shows the components of the angular momentum vector on the principal axes for different initial conditions.  For most initial conditions we find a one-dimensional simple closed curve. Some trajectories on the front side appear to cross trajectories on the back side, but this is an artifact of projection. The family of trajectories appears to intersect at two points. The curve that is the union of these trajectories is called a &lt;em&gt;separatrix&lt;&#x2F;em&gt;; it separates different types of motion.&lt;&#x2F;p&gt;
&lt;p&gt;The state space for the motion of a rigid body is six-dimensional - the three Euler angles and their time derivatives. Noether’s theorem gives us four conserved quantities - the three components of angular momentum as well as energy. This means the motion only has two degrees of freedom. The numerical result above also shows that the three components of angular momentum trace one-dimensional paths.&lt;&#x2F;p&gt;
&lt;p&gt;The total angular momentum is also conserved as its components are conserved. That is,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L^2 = L_x^2 + L_y^2 +L_z^2\tag{2.58}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;While the components themselves do not change, their projection on to the principal axes change as the axes themselves are in motion, attached to the body. The magnitude of $L$ should be the same even if evaluated in the principal axes coordinates. Therefore,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L^2 = L_a^2 + L_b^2 + L_c^2\tag{2.59}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Previously, we found expressions for angular momentum and kinetic energy as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
T_R &amp;amp;= \frac{1}{2} \left[ A(\omega^a)^2 + B(\omega^b)^2 + C(\omega^c)^2\right]\tag{2.41}\\
L_a &amp;amp;= A\omega^a\\
L_b &amp;amp;= B\omega^b\\
L_c &amp;amp;= C\omega^c\tag{2.51}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;These can be combined to get the following expression for kinetic energy in terms of the components of $L$&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
E = \frac{1}{2}\left( \frac{L_a^2}{A} + \frac{L_b^2}{B} + \frac{L_c^2}{C} \right)\tag{2.60}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Equations 2.59 and 2.60 constrain the motion of the components of angular momentum vector on the principal axes. Eq. 2.59 is the equation of a sphere and Eq. 2.60 is the equation of a triaxial ellipsoid. Since the angular momentum components satisfy both conditions, the component of the $L$ vector moves along the intersection of the angular momentum sphere and the energy ellipsoid. The intersection of a sphere and ellipsoid with the same center typically forms two closed curves.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The above equations were constructed with the assumption $A \leq B \leq C$. This means that the longest axis of the ellipsoid corresponds with the $\hat{c}$ direction which is the principal axis with the largest moment of inertia. And similarly the shortest axis of the energy ellipsoid coincides with the $\hat{a}$ direction (prinicipal axis for the smallest moment of inertia).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The intersection curves can be seen to shrink to a point for two axes, $\hat{a}$ and $\hat{c}$, corresponding to the principal axes with the largest and smallest moments of inertia, respectively. If the $L$ vector starts at these points, they tend to stay there. This is called an &lt;em&gt;equilibrium point&lt;&#x2F;em&gt;. Small displacements from this point at the start causes them to orbit the equilibrium point. This means that when the body rotates, the principal axes will describe a small orbit around the angular momentum vector in space (since the vector itself is constant). This is called a &lt;em&gt;relative equilibrium&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Conversely, for the $\hat{b}$ axis, or the intermediate axis, the curves appear to cross. This is also an equilibrium point. If the angular moment starts exactly at that point, it will stay at that point. However, if the system is slightly displaced, it tends to move away from the point very quickly. This denotes an unstable equilibrium point. So a body starting its rotation close to the intermediate axis will quickly end up in a tumble (while the $L$ vector &lt;em&gt;still&lt;&#x2F;em&gt; remains fixed in space).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;This leads to the “intermediate axis theorem”, also known as the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tennis_racket_theorem&quot;&gt;tennis racket theorem&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Now consider the case where the rotating rigid body is somehow dissipating energy - maybe due to some flexing structural member. Since this is an internal process, this only decreases the energy while the angular momentum remains constant. This means that the intersection curve on which the system moves starts to deform. For a given $L$, there is a lower limit for energy. For this lowest energy state, the intersection is a pair of points on the maximum moment of inertia axis. This shows that with dissipating energy, a rotating rigid body ends up rotating around the principal axis of highest inertia - this is the lowest energy state consistent with a constant angular momentum.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A simple “proof” of this can be obtained from Eq.2.60 . In order to minimize $E$, we need to increase the component of $L$ corresponding to the smallest scale factor, ($1&#x2F;C$), while keeping the magnitude of $L$ constant. This can be achieved by maximizing the $L_c$.&lt;&#x2F;li&gt;
&lt;li&gt;This was what caused eventual failure of the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Explorer_1#Results&quot;&gt;Explorer 1&lt;&#x2F;a&gt; satellite. This same process happens at a larger cosmic scale with planets and moons.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;The deviations from principal axis rotation for the Earth are tiny: the angle between the angular momentum vector and the ĉ axis for the Earth is less than one arc-second.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The above-mentioned deviations could be caused by Earthquakes, tides etc. In fact almost every other planet, asteroid and moon rotates about its principal axis with the largest moment of inertia. There are some exceptions - notably comets - which has reactions caused by the volatile jets that affect their rotation as they get closer to the Sun.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Among the natural satellites, the only known exception is Saturn’s satellite Hyperion, which is tumbling chaotically. Hyperion is especially out of round and subject to strong gravitational torques from Saturn.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.8.1: Computing the Motion of Free Rigid Bodies (incomplete)</title>
        <published>2022-11-08T05:05:00+00:00</published>
        <updated>2022-11-08T05:05:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-8-1-computing-the-motion-of-free-rigid-bodies/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-8-1-computing-the-motion-of-free-rigid-bodies/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-8-1-computing-the-motion-of-free-rigid-bodies/">&lt;h2 id=&quot;2-8-1-computing-the-motion-of-free-rigid-bodies&quot;&gt;2.8.1 Computing the Motion of Free Rigid Bodies&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Lagrange’s equations for the motion of a free rigid body in terms of Euler angles are quite disgusting, so we will not show them here.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Some configurations may have coordinate singularities when using Euler angles (e.g. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gimbal_lock&quot;&gt;gimbal lock&lt;&#x2F;a&gt;). In the explicit Lagrange equations, the singularity arises when we try to find the expression for generalized accelerations. The expression for this involves the inverse of $\partial_2 \partial_2 L$. The determinant of this quantity may become zero when the Euler angle $\theta$ is zero (for 3-1-3 Euler angles).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;Euler-state
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta &amp;#39;varphi &amp;#39;psi)
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;thetadot &amp;#39;varphidot &amp;#39;psidot)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;determinant
&lt;&#x2F;span&gt;&lt;span&gt;    (((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rigid&#x2F;T-rigid-body &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;A &amp;#39;B &amp;#39;C)) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; rigid&#x2F;T-rigid-body = T-body-Euler from book
&lt;&#x2F;span&gt;&lt;span&gt;     Euler-state)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
A\,B\,C\,{\sin}^{2}\left(\theta\right)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;So we cannot solve for the second derivatives when $\theta = 0$ and the Euler angles may change drastically when $\theta$ is small. This does not mean the actual motion of the rigid body is anything but well-behaved. The problem lies entirely in the representation of the motion using Euler angles. We may use another set of Euler angles when necessary to avoid this problem, but this tends to be cumbersome. In this section, we will be limiting our focus to trajectories that will not contain singularities for the chosen Euler angle set.&lt;&#x2F;p&gt;
&lt;p&gt;To obtain trjectories, we numerically integrate the Lagrange equations. The system derivative can be obtained directly from the Lagrangian using &lt;code&gt;Lagrangian-&amp;gt;state-derivative&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;TBD: Figure out plotting in Clojupyter&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;rigid-sysder &lt;&#x2F;span&gt;&lt;span&gt;[A B C]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrangian-&amp;gt;state-derivative &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rigid&#x2F;T-rigid-body&lt;&#x2F;span&gt;&lt;span&gt; A B C)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;monitor-errors &lt;&#x2F;span&gt;&lt;span&gt;[win A B C L0 E0]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[state]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;time&lt;&#x2F;span&gt;&lt;span&gt; state)
&lt;&#x2F;span&gt;&lt;span&gt;        L ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rigid&#x2F;Euler-state-&amp;gt;L-body&lt;&#x2F;span&gt;&lt;span&gt; A B C) state)
&lt;&#x2F;span&gt;&lt;span&gt;        E ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rigid&#x2F;T-rigid-body&lt;&#x2F;span&gt;&lt;span&gt; A B C) state)]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;plot-point&lt;&#x2F;span&gt;&lt;span&gt; win t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;relative-error &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; L &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; L0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;plot-point&lt;&#x2F;span&gt;&lt;span&gt; win t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;relative-error &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; L &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; L0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;plot-point&lt;&#x2F;span&gt;&lt;span&gt; win t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;relative-error &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; L &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; L0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;plot-point&lt;&#x2F;span&gt;&lt;span&gt; win t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;relative-error&lt;&#x2F;span&gt;&lt;span&gt; E E0)))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;Syntax error compiling at (REPL:9:5).
&lt;&#x2F;span&gt;&lt;span&gt;Unable to resolve symbol: plot-point in this context
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;  Util.java:   221 clojure.lang.Util&#x2F;runtimeException
&lt;&#x2F;span&gt;&lt;span&gt;   core.clj:  3214 clojure.core$eval&#x2F;invokeStatic
&lt;&#x2F;span&gt;&lt;span&gt;   core.clj:  3210 clojure.core$eval&#x2F;invoke
&lt;&#x2F;span&gt;&lt;span&gt;   main.clj:   437 clojure.main$repl$read_eval_print__9086$fn__9089&#x2F;invoke
&lt;&#x2F;span&gt;&lt;span&gt;   main.clj:   458 clojure.main$repl$fn__9095&#x2F;invoke
&lt;&#x2F;span&gt;&lt;span&gt;   main.clj:   368 clojure.main$repl&#x2F;doInvoke
&lt;&#x2F;span&gt;&lt;span&gt;RestFn.java:  1523 clojure.lang.RestFn&#x2F;invoke
&lt;&#x2F;span&gt;&lt;span&gt;   AFn.java:    22 clojure.lang.AFn&#x2F;run
&lt;&#x2F;span&gt;&lt;span&gt;   AFn.java:    22 clojure.lang.AFn&#x2F;run
&lt;&#x2F;span&gt;&lt;span&gt;Thread.java:  1589 java.lang.Thread&#x2F;run
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 2.10: Uniformly accelerated rigid body</title>
        <published>2022-11-08T02:34:39+00:00</published>
        <updated>2022-11-08T02:34:39+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-10/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-10/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-10/">&lt;h3 id=&quot;exercise-2-10-uniformly-accelerated-rigid-body&quot;&gt;Exercise 2.10: Uniformly accelerated rigid body&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Show that a rigid body subject to a uniform acceleration rotates as a free rigid body, while the center of mass has a parabolic trajectory.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;$$\require{cancel}$$&lt;&#x2F;p&gt;
&lt;p&gt;The kinetic energy of the rigid body is equal to the sum of the translational and rotational kinetic energy ($T_R$).&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
T = \frac{1}{2} m \left(\dot{x}^2 + \dot{y}^2 + \dot{z}^2 \right) + T_R(q_R)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The potential energy of the body is equal to $V = m g y$ where $m$ is the total mass of the body assuming that the acceleration is acting in the negative $y$ direction. The potential energy here is not dependent on the mass distribution of the body (aka the moments of inertia) as it does not vary with distance (as in the case of a central potential).&lt;&#x2F;p&gt;
&lt;p&gt;If the position of the body is represented by rectangular coordinates $(x, y, z)$ and orientation is being represented by some set of generalized coordinates $q_R$, then the Lagrangian is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L(t; x,y,z, q_R; \dot{q},\dot{q_R}) = \frac{1}{2} m \left(\dot{x}^2 + \dot{y}^2 + \dot{z}^2 \right) - mgy + T_R(q_R) 
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The Lagrangian can be decoupled into terms for translation (the first two terms) and rotation ($T_R(q_R)$). Therefore the Lagrange equations for the system also decouple as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D(\partial_2 L) - \partial_1 L = D([mx, my, mz]) - [0, mg, 0] = 0\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore the translational equations of motion are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{bmatrix}\ddot{x}\\
\ddot{y}\\
\ddot{z}\end{bmatrix} = \begin{bmatrix} 0\\ -g \\ 0\end{bmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Integrating these w.r.t time, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\begin{bmatrix}\dot{x}\\ \dot{y} \\ \dot{z}\end{bmatrix} &amp;amp;= \begin{bmatrix}X_1\\-gt + Y_1 \\ Z_1\end{bmatrix}\\
\implies \begin{bmatrix}x\\y \\ z\end{bmatrix} &amp;amp;= \begin{bmatrix}X_1 t + X_2 \\ -\frac{1}{2}gt^2 + Y_1 t + Y_2 \\ Z_1 t + Z_2\end{bmatrix}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;These equations describe a parabola.&lt;&#x2F;p&gt;
&lt;p&gt;The motion of the rigid body is given by the Lagrangian, $T_R(q_R)$ which produces the dynamic equations for a free rigid body.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.8 : Motion of a Free Rigid Body</title>
        <published>2022-11-07T08:17:06+00:00</published>
        <updated>2022-11-07T08:17:06+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-8-motion-of-a-free-rigid-body/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-8-motion-of-a-free-rigid-body/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-8-motion-of-a-free-rigid-body/">&lt;h2 id=&quot;2-8-motion-of-a-free-rigid-body&quot;&gt;2.8 Motion of a Free Rigid Body&lt;&#x2F;h2&gt;
&lt;p&gt;The kinetic energy of a rigid body, expressed in suitable generalized coordinates, is a Lagrangian for its motion. In &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-2-2-kinematics-of-rotation&#x2F;&quot;&gt;section 2.2&lt;&#x2F;a&gt; we showed that the kinetic energy of a rigid body can be separated into translational and rotational kinetic energy. If we use two separate sets of coordinats to represent the translation and rotation, the Lagrangian becomes the sum of a translational Lagrangian and a rotational Lagrangian. In this section, we will look at the rotational motion of a rigid body, modeled using Euler angles as the generalized coordinates.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;conserved-quantities&quot;&gt;Conserved Quantities&lt;&#x2F;h3&gt;
&lt;p&gt;Since the Lagrangian of a rigid body has no explicit time-dependence, we can infer that energy (i.e. kinetic energy) is conserved. The Lagrangian also does not depend on the Euler angle $\varphi$ (since the expressions for the $\omega$ vector did not depend on $\varphi$ in &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-2-7-euler-angles&#x2F;&quot;&gt;section 2.7&lt;&#x2F;a&gt;), and therefore its momentum conjugate (the component of $\partial_2 L$ corresponding to $\phi$) is conserved. An explicit expression for the momentum conjugate of $\varphi$ is computed as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;Euler-state
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta &amp;#39;varphi &amp;#39;psi)
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;thetadot &amp;#39;varphidot &amp;#39;psidot)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;momentum-phi
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref &lt;&#x2F;span&gt;&lt;span&gt;(((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rigid&#x2F;T-rigid-body &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;A &amp;#39;B &amp;#39;C)) Euler-state)
&lt;&#x2F;span&gt;&lt;span&gt;       &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd&lt;&#x2F;span&gt;&lt;span&gt; momentum-phi)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
A\,\dot {\varphi}\,{\sin}^{2}\left(\psi\right)\,{\sin}^{2}\left(\theta\right) + B\,\dot {\varphi}\,{\sin}^{2}\left(\theta\right)\,{\cos}^{2}\left(\psi\right) + A\,\dot {\theta}\,\sin\left(\psi\right)\,\sin\left(\theta\right)\,\cos\left(\psi\right) - B\,\dot {\theta}\,\sin\left(\psi\right)\,\sin\left(\theta\right)\,\cos\left(\psi\right) + C\,\dot {\varphi}\,{\cos}^{2}\left(\theta\right) + C\,\dot {\psi}\,\cos\left(\theta\right)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Due to the symmetries in the Lagrangian, we know that the quantity described above ($p_\varphi$) is conserved during the motion of a rigid body.&lt;&#x2F;p&gt;
&lt;p&gt;In the absence of external torques, we would also expect the angular momentum to be conserved. This can be verified by the Lagrangian formulation. The quantity computed above, $p_\varphi$, can be shown to be the $z$ component of the angular momentum. This is verified below:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L_z &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rigid&#x2F;Euler-state-&amp;gt;L-space &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;A &amp;#39;B &amp;#39;C) Euler-state)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; L_z momentum-phi))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
0
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Similar to the case of &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-1-8-3-central-forces-in-three-dimensions&#x2F;&quot;&gt;motion in a central potential&lt;&#x2F;a&gt;, since the choice of coordinate frames is arbitrary, if one rectangular component of $L$ is conserved, then all of its components are conserved. Therefore, &lt;strong&gt;the vector angular momentum is conserved for a rigid body&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This fact can also be shown using &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-1-8-5-noethers-theorem&#x2F;&quot;&gt;Noether’s theorem&lt;&#x2F;a&gt;. There exists a continuous family of rotations that can transform any orientation into any other orientation. The orientation of coordinate axes used to define the Euler angles are arbitrary and the kinetic energy (the Lagrangian) is the same regardless of choice of coordinate system. This meets the requirements of Noether’s theorem which tells us that there is an associated conserved quantity.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;In particular, the family of rotations around each coordinate axis gives us conservation of the angular momentum component on that axis. We construct the vector angular momentum by combining these contributions.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;See Exercise 2.11 for detailed proof of this (tbd .. will update link once completed).&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 2.9: Euler angles</title>
        <published>2022-11-07T08:15:00+00:00</published>
        <updated>2022-11-07T08:15:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-9/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-9/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-9/">&lt;h2 id=&quot;exercise-2-9-euler-angles&quot;&gt;Exercise 2.9: Euler Angles&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;It is not immediately obvious that all orientations can be represented in terms of the Euler angles. To show that the Euler angles are adequate to represent all orientations, solve for the Euler angles that give an arbitrary rotation $R$. Keep in mind that some orientations do not correspond to a unique representation in terms of Euler angles.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We will solve this for the “3-1-3” euler angles which involves an initial rotation around the $z$ axis, followed by the $x$ axis and then the $z$ axis again.&lt;&#x2F;p&gt;
&lt;p&gt;From &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-2-7-euler-angles&#x2F;&quot;&gt;Section 2.7&lt;&#x2F;a&gt;, we know that rotations about $z$ and $x$ axes can be represented as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathbf{R}_z(\psi) &amp;amp;= \begin{bmatrix}
              \cos\psi &amp;amp; -\sin\psi &amp;amp; 0\\
              \sin\psi &amp;amp; \cos\psi &amp;amp; 0\\
              0 &amp;amp; 0 &amp;amp; 1\\
             \end{bmatrix}\\
\mathbf{R}_x(\psi) &amp;amp;= \begin{bmatrix}
              1 &amp;amp; 0 &amp;amp; 0\\
              0 &amp;amp; \cos\psi &amp;amp; -\sin\psi\\
              0 &amp;amp; \sin\psi &amp;amp; \cos\psi\\
             \end{bmatrix}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The rotation $R$ can then be represented in matrix form as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathbf{R}_{zxz}(\theta, \varphi, \psi) = \mathbf{R}_z(\varphi) \mathbf{R}_x(\theta) \mathbf{R}_z(\psi)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Expanding this matrix multiplication, we can get the matrix $\mathbf{R}_{zxz}$ as a function of $(\theta, \varphi, \psi)$&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;t = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;symbols&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;real&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;theta, phi, psi = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;symbols&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;theta phi psi&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;real&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Rz = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span&gt;([[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt;(t), -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt;(t), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;],
&lt;&#x2F;span&gt;&lt;span&gt;             [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt;(t), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt;(t), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;],
&lt;&#x2F;span&gt;&lt;span&gt;             [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]])
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Rx = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span&gt;([[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;],
&lt;&#x2F;span&gt;&lt;span&gt;             [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt;(t), -&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt;(t)],
&lt;&#x2F;span&gt;&lt;span&gt;             [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt;(t), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt;(t)]])
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;R_zxz = Rz.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;subs&lt;&#x2F;span&gt;&lt;span&gt;(t, phi) * Rx.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;subs&lt;&#x2F;span&gt;&lt;span&gt;(t, theta) * Rz.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;subs&lt;&#x2F;span&gt;&lt;span&gt;(t, psi)
&lt;&#x2F;span&gt;&lt;span&gt;R_zxz
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $\displaystyle \left[\begin{matrix}- \sin{\left(\phi \right)} \sin{\left(\psi \right)} \cos{\left(\theta \right)} + \cos{\left(\phi \right)} \cos{\left(\psi \right)} &amp;amp; - \sin{\left(\phi \right)} \cos{\left(\psi \right)} \cos{\left(\theta \right)} - \sin{\left(\psi \right)} \cos{\left(\phi \right)} &amp;amp; \sin{\left(\phi \right)} \sin{\left(\theta \right)}\\\sin{\left(\phi \right)} \cos{\left(\psi \right)} + \sin{\left(\psi \right)} \cos{\left(\phi \right)} \cos{\left(\theta \right)} &amp;amp; - \sin{\left(\phi \right)} \sin{\left(\psi \right)} + \cos{\left(\phi \right)} \cos{\left(\psi \right)} \cos{\left(\theta \right)} &amp;amp; - \sin{\left(\theta \right)} \cos{\left(\phi \right)}\\\sin{\left(\psi \right)} \sin{\left(\theta \right)} &amp;amp; \sin{\left(\theta \right)} \cos{\left(\psi \right)} &amp;amp; \cos{\left(\theta \right)}\end{matrix}\right]$
&lt;&#x2F;div&gt;
&lt;p&gt;Any proper rotation can be represented by the rotation matrix $\mathbf{R}$ where&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{R} = \begin{bmatrix}R_{11} &amp;amp; R_{12} &amp;amp; R_{13}\\
R_{21} &amp;amp; R_{22} &amp;amp; R_{23}\\
R_{31} &amp;amp; R_{32} &amp;amp; R_{33}\\
\end{bmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Comparing $\mathbf{R}$ and $\mathbf{R}_{zxz}$, we get&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\cos{\theta} &amp;amp;= R_{33} \implies \theta = \arccos{(R_{33})}\\
\sin(\phi)\sin(\theta) &amp;amp;= R_{13}\\
-\cos(\phi)\sin(\theta) &amp;amp;= R_{23}\\
\sin{(\theta)}\cos{(\psi)} &amp;amp;= R_{32}\\
\sin{(\theta)}\sin{(\psi)} &amp;amp;= R_{31}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We can therefore compute $(\theta, \phi, \psi)$ for a given arbitrary rotation. The particular set of Euler angles chosen may have coordinate singularities. For example, in the z-x-z Euler angle set chosen above, when $\theta = 0$, $\phi$ and $\psi$ are not defined. However, in this case, another set of Euler angles may be chosen that does not have a singularity in that particular configuration.&lt;&#x2F;p&gt;
&lt;p&gt;We have shown above that any arbitrary rotation, as represented by a direction cosine matrix, can be written in terms of Euler angles. &lt;strong&gt;This proves that Euler angles can represent any arbitrary rotation.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.7: Euler Angles</title>
        <published>2022-11-07T05:40:17+00:00</published>
        <updated>2022-11-07T05:40:17+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-7-euler-angles/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-7-euler-angles/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-7-euler-angles/">&lt;h2 id=&quot;2-7-euler-angles&quot;&gt;2.7 Euler Angles&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;em&gt;Euler Angles&lt;&#x2F;em&gt; are a set of generalized coordinates for describing the orientation of a rigid body. To quote the book:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Though the Euler angles allow us to specify all orientations and thus can be used as generalized coordinates, the definition of Euler angles is pretty arbitrary. In fact no reasoning has led us to them. This is reflected in our presentation of them by just saying “here they are.” Euler angles are well suited for some problems, but cumbersome for others.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We start with the reference orientation so that principal-axis unit vectors $\hat{a}, \hat{b}, \hat{c}$ are coincident with the basis vectors $\hat{e}_i$, labeled here by $\hat{x}, \hat{y}, \hat{z}$. The Euler angles are defined in terms of simple rotations about the coordinate axes. Let $R_x(\psi)$ be a right-handed rotation about $\hat{x}$ by angle $\psi$, and $R_z(\psi)$ be a right-handed rotation about $\hat{z}$ by angle $\psi$. The function $\mathscr{M}$ for Euler angles is written as a composition of three of these simple coordinate axis rotations:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{M}(\theta, \varphi, \psi) = R_z(\varphi) \circ R_x(\theta) \circ R_z(\psi)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;for Euler angles $\theta, \varphi, \psi$. While these angles can represent any orientation, any specific orientation may be represented by more than one set of Euler angle. For example, when $\theta = 0$, then the orientation does not uniquely define either $\varphi$ or $\psi$.&lt;&#x2F;p&gt;
&lt;p&gt;There are other sets of Euler angles that can serve as generlized coordinates. For example, we can use the Euler angles defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{M}(\theta, \varphi, \psi) = R_x(\varphi) \circ R_y(\theta) \circ R_z(\psi)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Sometimes these are useful when we want to control where in the configuration space the “singularity” in the coordinates show up. The fundamental rotations themselves can be represented as rotation matrices:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathbf{R}_z(\psi) &amp;amp;= \begin{bmatrix}
              \cos\psi &amp;amp; -\sin\psi &amp;amp; 0\\
              \sin\psi &amp;amp; \cos\psi &amp;amp; 0\\
              0 &amp;amp; 0 &amp;amp; 1\\
             \end{bmatrix}\\
\mathbf{R}_x(\psi) &amp;amp;= \begin{bmatrix}
              1 &amp;amp; 0 &amp;amp; 0\\
              0 &amp;amp; \cos\psi &amp;amp; -\sin\psi\\
              0 &amp;amp; \sin\psi &amp;amp; \cos\psi\\
             \end{bmatrix}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The rotation $\mathscr{M}$ can then be written as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{M}(\theta, \varphi, \psi) = \mathbf{R}_x(\varphi) \mathbf{R}_y(\theta) \mathbf{R}_z(\psi)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The rotation matrices and their products can be computed as shown below. These can then be combined with the procedures &lt;code&gt; M-of-q-&amp;gt;omega-of-t&lt;&#x2F;code&gt; and &lt;code&gt;M-of-q-&amp;gt;omega-body-of-t&lt;&#x2F;code&gt; from &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-2.2-kinematics-of-rotation&quot;&gt;section 2.2&lt;&#x2F;a&gt; to compute the components of the angular velocity vector and the body components of the angular velocity vector.&lt;&#x2F;p&gt;
&lt;p&gt;The code below computes the components of the angular velocity vector for the given Euler angle set.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;Rz-matrix &lt;&#x2F;span&gt;&lt;span&gt;[angle]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;matrix-by-rows
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;list &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; angle) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; angle)) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;list &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; angle) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; angle) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;list &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0 0 1&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;Rx-matrix &lt;&#x2F;span&gt;&lt;span&gt;[angle]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;matrix-by-rows
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;list &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1 0 0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;list &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; angle) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; angle)))
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;list &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; angle) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; angle))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Rotation function, M
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;my-Euler-&amp;gt;M &lt;&#x2F;span&gt;&lt;span&gt;[[theta&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; phi&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; psi]]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Rz-matrix&lt;&#x2F;span&gt;&lt;span&gt; phi)
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Rx-matrix&lt;&#x2F;span&gt;&lt;span&gt; theta)
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Rz-matrix&lt;&#x2F;span&gt;&lt;span&gt; psi)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Methods from section 2.2 are defined in the &amp;quot;rigid&amp;quot; namespace of sicmutils
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Body-components of angular velocity for given Euler angles
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;matrix&#x2F;-&amp;gt;structure
&lt;&#x2F;span&gt;&lt;span&gt;  (((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rigid&#x2F;M-of-q-&amp;gt;omega-body-of-t&lt;&#x2F;span&gt;&lt;span&gt; my-Euler-&amp;gt;M)
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta)
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;varphi)
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;psi)))
&lt;&#x2F;span&gt;&lt;span&gt;   &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\begin{bmatrix}\displaystyle{\begin{pmatrix}\displaystyle{\sin\left(\psi\left(t\right)\right)\,\sin\left(\theta\left(t\right)\right)\,D\varphi\left(t\right) + \cos\left(\psi\left(t\right)\right)\,D\theta\left(t\right)} \cr \cr \displaystyle{\cos\left(\psi\left(t\right)\right)\,\sin\left(\theta\left(t\right)\right)\,D\varphi\left(t\right) - \sin\left(\psi\left(t\right)\right)\,D\theta\left(t\right)} \cr \cr \displaystyle{\cos\left(\theta\left(t\right)\right)\,D\varphi\left(t\right) + D\psi\left(t\right)}\end{pmatrix}}\end{bmatrix}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Components of angular velocity vector (inertial?)
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;matrix&#x2F;-&amp;gt;structure
&lt;&#x2F;span&gt;&lt;span&gt;  ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rigid&#x2F;M-&amp;gt;omega-body&lt;&#x2F;span&gt;&lt;span&gt; Euler-&amp;gt;M)
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta &amp;#39;varphi &amp;#39;psi)
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;thetadot &amp;#39;varphidot &amp;#39;psidot)))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\begin{bmatrix}\displaystyle{\begin{pmatrix}\displaystyle{\dot {\varphi}\,\sin\left(\psi\right)\,\sin\left(\theta\right) + \dot {\theta}\,\cos\left(\psi\right)} \cr \cr \displaystyle{\dot {\varphi}\,\cos\left(\psi\right)\,\sin\left(\theta\right) - \dot {\theta}\,\sin\left(\psi\right)} \cr \cr \displaystyle{\dot {\varphi}\,\cos\left(\theta\right) + \dot {\psi}}\end{pmatrix}}\end{bmatrix}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; This can be further create a procedure that returns the omega vector for the 3-1-3 (z-x-z) Euler angle set
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;Euler-state-&amp;gt;omega-body &lt;&#x2F;span&gt;&lt;span&gt;[[t&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[theta&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; phi&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; psi]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[thetadot&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; phidot&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; psidot]]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[omega-a (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+
&lt;&#x2F;span&gt;&lt;span&gt;                       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; thetadot (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; psi))
&lt;&#x2F;span&gt;&lt;span&gt;                       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; phidot (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; psi)))
&lt;&#x2F;span&gt;&lt;span&gt;            omega-b (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+
&lt;&#x2F;span&gt;&lt;span&gt;                       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;-1&lt;&#x2F;span&gt;&lt;span&gt; thetadot (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; psi))
&lt;&#x2F;span&gt;&lt;span&gt;                       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; phidot (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; psi)))
&lt;&#x2F;span&gt;&lt;span&gt;            omega-c (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+
&lt;&#x2F;span&gt;&lt;span&gt;                       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; phidot (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta)) psidot)]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; omega-a omega-b omega-c)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Euler-state-&amp;gt;omega-body
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta &amp;#39;varphi &amp;#39;psi)
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;thetadot &amp;#39;varphidot &amp;#39;psidot))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\begin{pmatrix}\displaystyle{\dot {\varphi}\,\sin\left(\psi\right)\,\sin\left(\theta\right) + \dot {\theta}\,\cos\left(\psi\right)} \cr \cr \displaystyle{\dot {\varphi}\,\cos\left(\psi\right)\,\sin\left(\theta\right) - \dot {\theta}\,\sin\left(\psi\right)} \cr \cr \displaystyle{\dot {\varphi}\,\cos\left(\theta\right) + \dot {\psi}}\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The &lt;code&gt;Euler-state-&amp;gt;omega-body&lt;&#x2F;code&gt; procedure can now be used to write functions to compute kinetic energy and angular momentum&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; From section 2.5
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;T-body &lt;&#x2F;span&gt;&lt;span&gt;[A B C]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[omega-body]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2
&lt;&#x2F;span&gt;&lt;span&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; A (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; omega-body &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; B (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; omega-body &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; C (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; omega-body &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; From section 2.6
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-body &lt;&#x2F;span&gt;&lt;span&gt;[A B C] 
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[omega-body]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;down &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; A (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; omega-body &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; B (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; omega-body &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; C (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; omega-body &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Kinetic energy
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;T-body-Euler &lt;&#x2F;span&gt;&lt;span&gt;[A B C]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[local]
&lt;&#x2F;span&gt;&lt;span&gt;      ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;T-body&lt;&#x2F;span&gt;&lt;span&gt; A B C)
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Euler-state-&amp;gt;omega-body&lt;&#x2F;span&gt;&lt;span&gt; local))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Angular momentum in principal axes coordinates
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-body-Euler &lt;&#x2F;span&gt;&lt;span&gt;[A B C] 
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[local]
&lt;&#x2F;span&gt;&lt;span&gt;      ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-body&lt;&#x2F;span&gt;&lt;span&gt; A B C)
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Euler-state-&amp;gt;omega-body&lt;&#x2F;span&gt;&lt;span&gt; local))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; L in reference-frame
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-space-Euler &lt;&#x2F;span&gt;&lt;span&gt;[A B C]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[local]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[angles (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;coordinate&lt;&#x2F;span&gt;&lt;span&gt; local)]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-body-Euler&lt;&#x2F;span&gt;&lt;span&gt; A B C) local)
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;transpose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Euler-&amp;gt;M&lt;&#x2F;span&gt;&lt;span&gt; angles))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; These are all local-tuple functions similar to the Lagrangian
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 2.6: Principal moments of inertia</title>
        <published>2022-11-07T03:04:57+00:00</published>
        <updated>2022-11-07T03:04:57+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-6/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-6/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-6/">&lt;h2 id=&quot;exercise-2-5-principal-moments-of-inertia&quot;&gt;Exercise 2.5: Principal moments of inertia&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;For each of the configurations described below find the principal moments of inertia with respect to the center of mass, and find the corresponding principal axes.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;a. A regular tetrahedron consisting of four equal point masses tied together with rigid massless wire.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let the sides of the tetrohedron be two units long. The coordinates of the masses are (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tetrahedron#Coordinates_for_a_regular_tetrahedron&quot;&gt;Reference&lt;&#x2F;a&gt;]:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
(\pm 1, 0, -\frac{1}{\sqrt{2}}), (0, \pm 1, \frac{1}{\sqrt{2}})\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;If the point masses all have mass $m$, the moments of inertia are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I_{00} &amp;amp;= \sum_i m_i \left(y_i^2 + z_i^2 \right)\\
       &amp;amp;= m (0 + \frac{1}{2} + 0 + \frac{1}{2} + 1 + \frac{1}{2} + 1 + \frac{1}{2} = 4m\\
I_{01} &amp;amp;= -\sum\nolimits_i m_i x_i y_i \\
       &amp;amp;= -m ( 0 + 0 + 0 + 0 ) = 0\\
I_{02} &amp;amp;= -\sum\nolimits_i m_i x_i z_i \\
       &amp;amp;= -m ( -\frac{1}{\sqrt{2}} + \frac{1}{\sqrt{2}} + 0 + 0) = 0\\
\\
I_{10} &amp;amp;= - \sum\nolimits_i m_i y_i x_i\\
       &amp;amp;= - m (0 + 0 + 0 + 0) = 0\\
I_{11} &amp;amp;= \sum\nolimits_i m_i \left(x_i^2 + z_i^2 \right)\\
       &amp;amp;= m(1 + \frac{1}{2} + 1 + \frac{1}{2} + 0 + \frac{1}{2} + 0 + \frac{1}{2}) = 4m\\
I_{12} &amp;amp;= -\sum\nolimits_i m_i y_i z_i\\
       &amp;amp;= - m(0 + 0 + \frac{1}{\sqrt{2}} - \frac{1}{\sqrt{2}} ) = 0
\\
I_{20} &amp;amp;= - \sum\nolimits_i m_i z_i x_i\\
       &amp;amp;= - m(-\frac{1}{\sqrt{2}} + \frac{1}{\sqrt{2}} + 0 + 0) = 0\\
I_{21} &amp;amp;= - \sum\nolimits_i m_i z_i y_i\\
       &amp;amp;= - m(0 + 0 + \frac{1}{\sqrt{2}} - \frac{1}{\sqrt{2}}) = 0\\
I_{22} &amp;amp;= \sum\nolimits_i m_i \left(x_i^2 + y_i^2 \right)\\
       &amp;amp;= m(1 + 0 + 1 + 0 + 1 + 0 + 1 + 0) = 4m\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The inertia matrix is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I &amp;amp;= \begin{bmatrix}4m &amp;amp; 0 &amp;amp; 0\\
                     0 &amp;amp; 4m &amp;amp; 0\\
                     0 &amp;amp; 0 &amp;amp; 4m\end{bmatrix}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Since the matrix is already diagonal, the values of the diagonal elements are the principal moments of inertia:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
A = B = C = 4m\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The principal axes are $\hat{x}, \hat{y}, \hat{z}$.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;b. A cube of uniform density&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Assume origin at center of the cube. The moments of inertia are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I_{xx} = \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \left(y^2 + z^2\right) \rho~dx dy dz\\
I_{yy} = \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \left(x^2 + z^2\right) \rho~dx dy dz\\
I_{zz} = \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \left(x^2 + y^2\right) \rho~dx dy dz\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\rho$ is the density of the material, $\rho = \frac{M}{L^3}$. Since the cube is symmetric, the moments of inertia are all equal to each other, $I_{xx} = I_{yy} = I_{zz}$&lt;&#x2F;p&gt;
&lt;p&gt;Products of inertia are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I_{xy} &amp;amp;= \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} xy \rho~dx dy dz\\
I_{yz} &amp;amp;= \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} yz \rho~dx dy dz\\
I_{zx} &amp;amp;= \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} zx \rho~dx dy dz\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;As calculated below, the inertia matrix is diagonal with elements equal to $\frac{M L^2}{6}$. Therefore the principal moments of inertia are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
A = B = C = \frac{M L^2}{6}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The principal axes are $\hat{x}, \hat{y}, \hat{z}$.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;x, y, z = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;symbols&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;x y z&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;real&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;M, L = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;symbols&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;M L&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;positive&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;rho = M&#x2F;L**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Ixx = rho * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;integrate&lt;&#x2F;span&gt;&lt;span&gt;(y**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;+ z**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, (x, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (y, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (z, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;Iyy = rho * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;integrate&lt;&#x2F;span&gt;&lt;span&gt;(x**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;+ z**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, (x, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (y, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (z, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;Izz = rho * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;integrate&lt;&#x2F;span&gt;&lt;span&gt;(x**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;+ y**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, (x, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (y, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (z, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Ixy = rho * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;integrate&lt;&#x2F;span&gt;&lt;span&gt;(x*y, (x, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (y, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (z, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;Iyz = rho * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;integrate&lt;&#x2F;span&gt;&lt;span&gt;(y*z, (x, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (y, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (z, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;Ixz = rho * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;integrate&lt;&#x2F;span&gt;&lt;span&gt;(x*z, (x, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (y, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (z, -L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, L&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Iyx, Izy, Izx = Ixy, Iyz, Ixz
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;I = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span&gt;([[Ixx, Ixy, Ixz],
&lt;&#x2F;span&gt;&lt;span&gt;            [Iyx, Iyy, Iyz],
&lt;&#x2F;span&gt;&lt;span&gt;            [Izx, Izy, Izz]])
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;I
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $\displaystyle \left[\begin{matrix}\frac{L^{2} M}{6} &amp;amp; 0 &amp;amp; 0\\0 &amp;amp; \frac{L^{2} M}{6} &amp;amp; 0\\0 &amp;amp; 0 &amp;amp; \frac{L^{2} M}{6}\end{matrix}\right]$
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;c. Five equal point masses rigidly connected by massless stuff. The point masses are at the rectangular coordinates:
(−1, 0, 0), (1, 0, 0), (1, 1, 0), (0, 0, 0), (0, 0, 1).&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The center of mass is at $[\frac{1}{5}, \frac{1}{5}, \frac{1}{5}]$.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;numpy &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span&gt;np
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;points = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;array&lt;&#x2F;span&gt;&lt;span&gt;([[-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;],
&lt;&#x2F;span&gt;&lt;span&gt;                   [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;],
&lt;&#x2F;span&gt;&lt;span&gt;                   [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;],
&lt;&#x2F;span&gt;&lt;span&gt;                   [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;],
&lt;&#x2F;span&gt;&lt;span&gt;                   [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]])
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;N = points.shape[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;center_of_mass = points.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;mean&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;axis&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;cx,cy,cz = center_of_mass
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Ixx = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;([(y - cy)**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;+ (z - cz)**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;x, y, z &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;points])
&lt;&#x2F;span&gt;&lt;span&gt;Iyy = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;([(x - cx)**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;+ (z - cz)**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;x, y, z &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;points])
&lt;&#x2F;span&gt;&lt;span&gt;Izz = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;([(x - cx)**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;+ (y - cy)**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;x, y, z &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;points])
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Iyz = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;([(y - cy)*(z - cz)**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;x, y, z &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;points])
&lt;&#x2F;span&gt;&lt;span&gt;Ixz = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;([(x - cx)*(z - cz)**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;x, y, z &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;points])
&lt;&#x2F;span&gt;&lt;span&gt;Ixy = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;([(x - cx)*(y - cy)**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;x, y, z &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;points])
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;I = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span&gt;([[Ixx, Ixy, Ixz],
&lt;&#x2F;span&gt;&lt;span&gt;            [Iyx, Iyy, Iyz],
&lt;&#x2F;span&gt;&lt;span&gt;            [Izx, Izy, Izz]]) * m
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;I
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $\displaystyle \left[\begin{matrix}1.6 m &amp;amp; 0.48 m &amp;amp; - 0.12 m\\0 &amp;amp; 3.6 m &amp;amp; - 0.12 m\\0 &amp;amp; 0 &amp;amp; 3.6 m\end{matrix}\right]$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;eigenvects = I.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eigenvects&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;eigenvects
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;[(1.6*m,
&lt;&#x2F;span&gt;&lt;span&gt;  1,
&lt;&#x2F;span&gt;&lt;span&gt;  [Matrix([
&lt;&#x2F;span&gt;&lt;span&gt;   [1.0],
&lt;&#x2F;span&gt;&lt;span&gt;   [  0],
&lt;&#x2F;span&gt;&lt;span&gt;   [  0]])]),
&lt;&#x2F;span&gt;&lt;span&gt; (3.6*m,
&lt;&#x2F;span&gt;&lt;span&gt;  2,
&lt;&#x2F;span&gt;&lt;span&gt;  [Matrix([
&lt;&#x2F;span&gt;&lt;span&gt;   [0.24],
&lt;&#x2F;span&gt;&lt;span&gt;   [ 1.0],
&lt;&#x2F;span&gt;&lt;span&gt;   [   0]])])]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;a = eigenvects[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;b = eigenvects[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;][&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;c = a.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cross&lt;&#x2F;span&gt;&lt;span&gt;(b)
&lt;&#x2F;span&gt;&lt;span&gt;c
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $\displaystyle \left[\begin{matrix}0\\0\\1.0\end{matrix}\right]$
&lt;&#x2F;div&gt;
&lt;p&gt;The principal moments of inertia are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
A = 1.6m, B = C = 3.6m\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The principal axes are: $\hat{x},~ 0.24\hat{x} + 1.0\hat{y},~\hat{z}$&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 2.8: Rotational angular momentum</title>
        <published>2022-11-06T08:12:45+00:00</published>
        <updated>2022-11-06T08:12:45+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-8/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-8/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-8/">&lt;h2 id=&quot;exercise-2-8-rotational-angular-momentum&quot;&gt;Exercise 2.8: Rotational angular momentum&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Verify that expression in Eq. (2.50) for the components of the rotational angular momentum Eq. (2.49) in terms of the inertia tensor is correct.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\vec{L} = \sum_\alpha m_\alpha \vec{\xi}_\alpha \times \left(\vec{\omega} \times  \vec{\xi}_\alpha \right)\tag{2.49}
$$
&lt;&#x2F;div&gt;
&lt;div&gt;
    $$
L_j = \sum_k I_{jk} \omega^k\tag{2.50}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Consider an arbitrary inertial coordinate frame its the origin at the center of rotation and basis vectors $\hat{e}_0$, $\hat{e}_1$ and $\hat{e}_2$, such that $\hat{e}_0 \times \hat{e}_1 = \hat{e}_2$. If the components of $\vec{\omega}$ in this frame are $\omega^0$, $\omega^1$ and $\omega^2$,
The inertia matrix of a body in this coordinate frame is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\vec{L} &amp;amp;= \sum_\alpha m_\alpha \vec{\xi}_\alpha \times \left(\vec{\omega} \times  \vec{\xi}_\alpha \right) \\
          L_i = \vec{L}\cdot \hat{e}_i &amp;amp;= \left( \sum_\alpha m_\alpha \vec{\xi}_\alpha \times \left(\vec{\omega} \times  \vec{\xi}_\alpha \right) \right) \cdot \hat{e}_i\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Applying the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Triple_product#Properties&quot;&gt;triple product formula&lt;&#x2F;a&gt;, ${\displaystyle (\mathbf {a} \times \mathbf {b} )\cdot \mathbf {c} = \mathbf {a} \cdot (\mathbf {b} \times \mathbf {c} ) }$,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
L_j &amp;amp;= \sum_\alpha \left( m_\alpha \overbrace{\vec{\xi}_\alpha}^{&amp;quot;\mathbf{a}&amp;quot;} \times \underbrace{\left(\vec{\omega} \times  \vec{\xi}_\alpha \right)}_{&amp;quot;\mathbf{b}&amp;quot;} \right) \cdot \overbrace{\hat{e}_j}^{&amp;quot;\mathbf{c}&amp;quot;}\\
&amp;amp;= \sum_\alpha m_\alpha \vec{\xi}_\alpha \cdot \left[ \left(\vec{\omega} \times  \vec{\xi}_\alpha \right) \times \hat{e}_j\right]\\
&amp;amp;= \sum_\alpha m_\alpha \vec{\xi}_\alpha \cdot \left[ \left(\sum_k \hat{e}_k \omega^k \times  \vec{\xi}_\alpha \right) \times \hat{e}_j \right]\\
&amp;amp;= \sum_k \omega^k \sum_\alpha m_\alpha \vec{\xi}_\alpha \cdot \left[ \left(\hat{e}_k \times  \vec{\xi}_\alpha \right) \times \hat{e}_j \right]\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Applying the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Triple_product#Properties&quot;&gt;triple product formula&lt;&#x2F;a&gt; again, ${\displaystyle \mathbf {a} \cdot (\mathbf {b} \times \mathbf {c} )=\mathbf {b} \cdot (\mathbf {c} \times \mathbf {a} )}$,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
L_j &amp;amp;= \sum_k \omega^k \sum_\alpha m_\alpha \underbrace{\vec{\xi}_\alpha}_{&amp;quot;\mathbf{a}&amp;quot;} \cdot \left[ \overbrace{\left(\hat{e}_k \times  \vec{\xi}_\alpha \right)}^{&amp;quot;\mathbf{b}&amp;quot;} \times \underbrace{\hat{e}_j}_{&amp;quot;\mathbf{c}&amp;quot;} \right]\\
    &amp;amp;= \sum_k \omega^k \sum_\alpha m_\alpha \left(\hat{e}_k \times  \vec{\xi}_\alpha \right) \cdot \left[ \hat{e}_j \times \vec{\xi}_\alpha \right]\\
    &amp;amp;= \sum_k \omega^k \underbrace{\sum_\alpha m_\alpha \left(\hat{e}_j \times  \vec{\xi}_\alpha \right) \cdot \left( \hat{e}_k \times \vec{\xi}_\alpha \right)}_{I_{jk}}\\
    \\
L_j &amp;amp;= \sum_k I_{jk} \omega^k
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $I_{jk}$ are components of the inertia tensor.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.6: Vector Angular Momentum</title>
        <published>2022-11-06T07:14:48+00:00</published>
        <updated>2022-11-06T07:14:48+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-6-vector-angular-momentum/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-6-vector-angular-momentum/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-6-vector-angular-momentum/">&lt;h2 id=&quot;2-6-vector-angular-momentum&quot;&gt;2.6 Vector Angular Momentum&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The vector angular momentum of a particle is the cross product of its position vector and its linear momentum vector. For a rigid body the vector angular momentum is the sum of the vector angular momentum of each of the constituents.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The vector angular momentum of a rigid body is&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\sum_\alpha \vec{x}_\alpha \times (m_\alpha \dot{\vec{x}}_\alpha)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Similar to rotational kinetic energy, the vector angular momentum of a rigid body can also be decomposed to the angular momentum of the center of mass and the angular momentum about the center of mass. If we represent the position vectors as sum of the position of the center of mass, $\vec{X}$ and the vectors from the center of mass, $\vec{\xi}_\alpha$, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\vec{x}_\alpha &amp;amp;= \vec{X} + \vec{\xi}_\alpha\tag{2.43}\\
\dot{\vec{x}}_\alpha &amp;amp;= \dot{\vec{X}} + \dot{\vec{\xi}}_\alpha\tag{2.44}\\
\text{where }\vec{X} &amp;amp;= \frac{\sum_\alpha m_\alpha \vec{x}_\alpha}{M} \\
 M &amp;amp;= \sum_\alpha m_\alpha
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;As a result of $\vec{X}$ being the center of mass,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\sum_\alpha m_\alpha \vec{\xi}_\alpha = \sum_\alpha m_\alpha (\vec{x}_\alpha - \vec{X}) = \underbrace{\sum_\alpha m_\alpha \vec{x}_\alpha}_{= M\vec{X}} - \overbrace{\sum_\alpha m_\alpha}^{=M} \vec{X} = 0\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Similarly, $\sum_\alpha m_\alpha \dot{\vec{\xi}}_\alpha$ is also equal to zero. Substituting these in the angular momentum, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\sum_\alpha &amp;amp; m_\alpha \left(\vec{X} + \vec{\xi}_\alpha \right) \times  \left(\dot{\vec{X}} + \dot{\vec{\xi}}_\alpha\right)\\
          &amp;amp;= \sum_\alpha m_\alpha (\vec{X} \times \dot{\vec{X}} + \vec{X} \times  \dot{\vec{\xi}}_\alpha + \vec{\xi}_\alpha \times  \dot{\vec{X}} + \vec{\xi}_\alpha \times  \dot{\vec{\xi}}_\alpha )\\
          &amp;amp;= \vec{X} \times M\dot{\vec{X}} +  \vec{X} \times \cancelto{0}{\sum_\alpha m_\alpha \dot{\vec{\xi}}_\alpha} + \cancelto{0}{\sum_\alpha m_\alpha \vec{\xi}_\alpha } \times \dot{\vec{X}}   + \sum_\alpha m_\alpha \vec{\xi}_\alpha \times  \dot{\vec{\xi}}_\alpha\\
          &amp;amp;= \vec{X} \times M\dot{\vec{X}} +  \sum_\alpha \vec{\xi}_\alpha \times  (m_\alpha \dot{\vec{\xi}}_\alpha)\tag{2.46}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The first term of Eq. 2.46, $\vec{X} \times M\dot{\vec{X}}$ is the angular momentum of the center of mass and the rotational angular momentum is $\sum_\alpha \vec{\xi_\alpha} \times  (m_\alpha \dot{\vec{\xi_\alpha}})$. By substituting $\dot{\vec{\xi_\alpha}} = \vec{\omega} \times \vec{\xi_\alpha}$, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\vec{L} = \sum_\alpha m_\alpha \vec{\xi}_\alpha \times \left(\vec{\omega} \times  \vec{\xi}_\alpha \right)\tag{2.49}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Using the same technique as done for the rotational kinetic energy in &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-2-3-moments-of-inertia&#x2F;&quot;&gt;Section 2.3&lt;&#x2F;a&gt;, we can resolve $\vec{\omega}$ into its components to find the angular momentum in terms of the moments of inertia as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L_j = \sum_k I_{jk} \omega^k\tag{2.50}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $I_{jk}$ are components of the inertia tensor (the same one used to compute rotational kinetic energy). In terms of the principal moments of inertia, the components of $L$ are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
L_a &amp;amp;= A\omega^a\\
L_b &amp;amp;= B\omega^b\\
L_c &amp;amp;= C\omega^c\tag{2.51}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;These are also the partial derivatives of kinetic energy $T_R$ w.r.t angular velocities (Eq. 2.41 in &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-2-5-principal-moments-of-inertia&#x2F;&quot;&gt;Section 2.5&lt;&#x2F;a&gt;). Therefore $\vec{L}$ is written as a down-tuple (or a row-matrix).&lt;&#x2F;p&gt;
&lt;p&gt;If $\mathbf{M}$ is the matrix representation of the rotation that takes an angular-velocity vector  $\boldsymbol{\omega}’$ to a rotated vector $\boldsymbol{\omega}$, the components transform as $\boldsymbol{\omega} = \mathbf{M}\boldsymbol{\omega}$.
It is also conventient to work with a column matrix of the angular momentum components, $\overline{\mathbf{L}} = \mathbf{L}^{\mathscr{T}}$.&lt;&#x2F;p&gt;
&lt;p&gt;Applying this transformation along with $\mathbf{I}’ = \mathbf{M}\mathbf{I}\mathbf{M}^{\mathscr{T}}$ to angular momentum&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\overline{\mathbf{L}} &amp;amp;= \mathbf{I}\boldsymbol{\omega}\\
                      &amp;amp;= \mathbf{M}\mathbf{I}\mathbf{M}^{\mathscr{T}} \mathbf{M}\boldsymbol{\omega}&amp;#x27;\\
                      &amp;amp;= \mathbf{M}\mathbf{I}\boldsymbol{\omega}&amp;#x27;
                      &amp;amp;= \mathbf{M} \overline{\mathbf{L}}&amp;#x27;\tag{2.52}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Transposing the result in Eq. 2.52,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{L} = (\overline{\mathbf{L}})^{\mathscr{T}} = (\mathbf{M} \overline{\mathbf{L}}&amp;#x27;)^{\mathscr{T}} = \mathbf{L}&amp;#x27; \mathbf{M}^{\mathscr{T}}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore, the angular momentum components transform as: $\mathbf{L} = \mathbf{L}’ \mathbf{M}^{\mathscr{T}}$&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-body &lt;&#x2F;span&gt;&lt;span&gt;[A B C]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[omega-a omega-b omega-c]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;down &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; A omega-a)
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; B omega-b)
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; C omega-c))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-space &lt;&#x2F;span&gt;&lt;span&gt;[M]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[A B C]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[omega-body]
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-body&lt;&#x2F;span&gt;&lt;span&gt; A B C) omega-body)
&lt;&#x2F;span&gt;&lt;span&gt;             (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;transpose&lt;&#x2F;span&gt;&lt;span&gt; M)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-body &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;A &amp;#39;B &amp;#39;C)
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;omega_a &amp;#39;omega_b &amp;#39;omega_c)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\begin{bmatrix}\displaystyle{A\,{\omega}_a}&amp;amp;\displaystyle{B\,{\omega}_b}&amp;amp;\displaystyle{C\,{\omega}_c}\end{bmatrix}
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 1.8.3: Central Forces in Three Dimensions</title>
        <published>2022-11-06T00:16:30+00:00</published>
        <updated>2022-11-06T00:16:30+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-1-8-3-central-forces-in-three-dimensions/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-1-8-3-central-forces-in-three-dimensions/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-1-8-3-central-forces-in-three-dimensions/">&lt;h2 id=&quot;1-8-3-central-forces-in-three-dimensions&quot;&gt;1.8.3 Central Forces in Three Dimensions&lt;&#x2F;h2&gt;
&lt;p&gt;Consider the motion of a particle in a potential field $V(r)$ in three dimensions using spherical coordinates, $r, \theta, \varphi$, where $\theta$ is the colatitude and $\varphi$ is the longitude. The kinetic energy is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
T(t; r, \theta, \varphi; \dot{r}, \dot{\theta}, \dot{\varphi} = \frac{1}{2} m \left(\dot{r}^2 + r^2\dot{\theta}^2 + r^2(\sin\theta)^2\dot{\varphi}^2 \right)
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;T3-spherical &lt;&#x2F;span&gt;&lt;span&gt;[m]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[r&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; theta&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[rdot&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; thetadot&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; phidot]]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m
&lt;&#x2F;span&gt;&lt;span&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; rdot)
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r thetadot))
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta) phidot))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Lagrangian = T-V
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L3-central &lt;&#x2F;span&gt;&lt;span&gt;[m Vr]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;Vs &lt;&#x2F;span&gt;&lt;span&gt;[[_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[r&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Vr&lt;&#x2F;span&gt;&lt;span&gt; r))
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;T3-spherical&lt;&#x2F;span&gt;&lt;span&gt; m) Vs))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;#&amp;#39;user&#x2F;L3-central
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; The generalized forces can be computed by taking the partial derivative of the Lagrangian w.r.t the coordinates
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;( ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L3-central &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;V)))
&lt;&#x2F;span&gt;&lt;span&gt;             (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r &amp;#39;theta &amp;#39;phi)
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;rdot &amp;#39;thetadot &amp;#39;phidot))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Here \varphi is a &amp;quot;cyclic coordinate&amp;quot; as it does not appear in the Lagrangian explicitly 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; and hence does not have a force associated with it
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{bmatrix}\displaystyle{m\,{\dot {\phi}}^{2}\,r\,{\sin}^{2}\left(\theta\right) + m\,r\,{\dot {\theta}}^{2} - DV\left(r\right)} \cr \cr \displaystyle{m\,{\dot {\phi}}^{2}\,{r}^{2}\,\sin\left(\theta\right)\,\cos\left(\theta\right)} \cr \cr \displaystyle{0}\end{bmatrix}
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Compute the momenta by taking partial derivative w.r.t generalized velocities
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;( ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L3-central &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;V)))
&lt;&#x2F;span&gt;&lt;span&gt;             (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r &amp;#39;theta &amp;#39;phi)
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;rdot &amp;#39;thetadot &amp;#39;phidot))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{bmatrix}\displaystyle{m\,\dot r} \cr \cr \displaystyle{m\,{r}^{2}\,\dot {\theta}} \cr \cr \displaystyle{m\,\dot {\phi}\,{r}^{2}\,{\sin}^{2}\left(\theta\right)}\end{bmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;The momentum conjugate to $\varphi$ is conserved. We can show that this is actually the $z$ component of the angular momentum vector $r \times (m\vec{v})$, for position $\vec{r}$ and linear momentum $m\vec{v}$ by writing the $z$ component of the angular momentum in spherical coordinates:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; z component of ang momentum
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;ang-mom-z &lt;&#x2F;span&gt;&lt;span&gt;[m]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; xyz&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; v]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cross-product&lt;&#x2F;span&gt;&lt;span&gt; xyz (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m v)) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Coordinate conversion
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;s-&amp;gt;r2 &lt;&#x2F;span&gt;&lt;span&gt;[[_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[r&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; theta&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; phi]]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;            y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;            z (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta))]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x y z)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt; ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ang-mom-z &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F-&amp;gt;C&lt;&#x2F;span&gt;&lt;span&gt; s-&amp;gt;r))
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t
&lt;&#x2F;span&gt;&lt;span&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r &amp;#39;theta &amp;#39;phi)
&lt;&#x2F;span&gt;&lt;span&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;rdot &amp;#39;thetadot &amp;#39;phidot)))) 
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; results in m phidot r² sin²(θ) which is equal to the momentum conjugate of phi
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
m\,\dot {\phi}\,{r}^{2}\,{\sin}^{2}\left(\theta\right)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Since the choice of $z$ axis arbitrary based on the coordinate system, if one component is conserved, then all components are conserved. Therefore, angular momentum is conserved. We can &lt;strong&gt;choose&lt;&#x2F;strong&gt; the $z$ axis such that all the angular momentum is in the $z$ component.&lt;&#x2F;p&gt;
&lt;p&gt;So for a general position vector $\vec{x}$, since $\vec{x}\cdot L = \vec{x}\cdot(m\vec{x}\times\vec{v}) = \vec{v}\cdot(\vec{x}\times\vec{x}) = 0$ ( from the scalar triple product), the motion is confined to the plane perpendicular to the angular momentum i.e., colatitude $\theta = \pi&#x2F;2$ and $\dot{\theta} = 0$. This motion was discussed before in Section 1.6&lt;&#x2F;p&gt;
&lt;p&gt;Ref: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;physics.stackexchange.com&#x2F;q&#x2F;731892&#x2F;47598&quot;&gt;https:&#x2F;&#x2F;physics.stackexchange.com&#x2F;q&#x2F;731892&#x2F;47598&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Computing the energy from the Lagrangian, we can see that it does equal $T+V$&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt;  ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrangian-&amp;gt;energy &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L3-central &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;V)))
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r &amp;#39;theta &amp;#39;phi)
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;rdot &amp;#39;thetadot &amp;#39;phidot))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; The energy is conserved because the Lagrangian has no explicit time dependence.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\frac{1}{2}\,m\,{\dot {\phi}}^{2}\,{r}^{2}\,{\sin}^{2}\left(\theta\right) + \frac{1}{2}\,m\,{r}^{2}\,{\dot {\theta}}^{2} + \frac{1}{2}\,m\,{\dot r}^{2} + V\left(r\right)
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 2.5: A constraint on the moments of inertia</title>
        <published>2022-11-06T00:07:04+00:00</published>
        <updated>2022-11-06T00:07:04+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-5/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-5/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-5/">&lt;h2 id=&quot;exercise-2-5-a-constraint-on-the-moments-of-inertia&quot;&gt;Exercise 2.5: A constraint on the moments of inertia&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Show that the sum of any two of the moments of inertia is greater than or equal to the third moment of inertia. You may assume the moments of inertia are with respect to orthogonal axes.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Consider an arbitrary orthogonal coordinate frame with axes $x$, $y$ and $z$. The inertia matrix of a body in this coordinate frame is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I = \begin{bmatrix}\sum\nolimits_i m_i \left(y_i^2 + z_i^2 \right) &amp;amp; -\sum\nolimits_i m_i x_i y_i &amp;amp; -\sum\nolimits_i m_i x_i z_i\\
- \sum\nolimits_i m_i y_i x_i &amp;amp; \sum\nolimits_i m_i \left(x_i^2 + z_i^2 \right) &amp;amp; -\sum\nolimits_i m_i y_i z_i\\
- \sum\nolimits_i m_i z_i x_i &amp;amp; -\sum\nolimits_i m_i z_i y_i &amp;amp; \sum\nolimits_i m_i \left(x_i^2 + y_i^2 \right)\\
\end{bmatrix}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore the moments of inertia are: $\left[ \sum\nolimits_i m_i \left(y_i^2 + z_i^2 \right), \sum\nolimits_i m_i \left(x_i^2 + z_i^2 \right), \sum\nolimits_i m_i \left(x_i^2 + y_i^2 \right) \right]$&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I_{xx} + I_{yy} - I_{zz} &amp;amp;= \sum\nolimits_i m_i \left(y_i^2 + z_i^2 \right) + \sum\nolimits_i m_i \left(x_i^2 + z_i^2 \right) - \sum\nolimits_i m_i \left(x_i^2 + y_i^2 \right)\\
                &amp;amp;= \sum\nolimits_i m_i \left(\cancel{y_i^2} + 2 z_i^2 + \cancel{x_i^2} - \cancel{x_i^2} - \cancel{y_i^2}\right)\\
                &amp;amp;= \sum\nolimits_i m_i \left(2 z_i^2\right)\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Since $z_i^2$ are all positive, $\sum\nolimits_i m_i \left(2 z_i^2\right) \geq 0$. Therefore,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I_{xx} + I_{yy} - I_{zz} &amp;amp;\geq 0 \\
\implies I_{xx} + I_{yy} &amp;amp;\geq I_{zz} \\
\end{align*}
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 2.4: Jupiter</title>
        <published>2022-11-05T23:47:04+00:00</published>
        <updated>2022-11-05T23:47:04+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-4/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-4/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-4/">&lt;h2 id=&quot;exercise-2-4-jupiter&quot;&gt;Exercise 2.4: Jupiter&lt;&#x2F;h2&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;a. The density of a planet increases toward the center. Provide an argument that the moment of inertia of a planet is less than that of a sphere of uniform density of the same mass and radius.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The higher masses at the center of the planet are scaled by the smaller distances and the smaller masses at the periphery are multiplied the larger distances. With uniform density, there would be more mass at the periphery, contributing to a higher total moment of inertia.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;b. The density as a function of radius inside Jupiter is well approximated by&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\rho(r) = \frac{M}{R^3} \frac{\sin{(\pi r&amp;#x2F;R)}}{4r&amp;#x2F;R}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;where $M$ is the mass and $R$ is the radius of Jupiter. Find the moment of inertia of Jupiter in terms of $M$ and $R$.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;               | z axis
&lt;&#x2F;span&gt;&lt;span&gt;               |
&lt;&#x2F;span&gt;&lt;span&gt;               |
&lt;&#x2F;span&gt;&lt;span&gt;              &amp;gt;|      |&amp;lt;--- r sinΦ
&lt;&#x2F;span&gt;&lt;span&gt;         , - ~ ~ ~ - ,|  
&lt;&#x2F;span&gt;&lt;span&gt;     , &amp;#39;       |------&amp;lt;&amp;gt;&amp;#39; ,  
&lt;&#x2F;span&gt;&lt;span&gt;   ,           |      &#x2F;    ,
&lt;&#x2F;span&gt;&lt;span&gt;  ,            | Φ  &#x2F;R      ,
&lt;&#x2F;span&gt;&lt;span&gt; ,             |   &#x2F;         ,
&lt;&#x2F;span&gt;&lt;span&gt; ,             +-&#x2F;--------R--&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt; ,             |             ,
&lt;&#x2F;span&gt;&lt;span&gt;  ,            |            ,
&lt;&#x2F;span&gt;&lt;span&gt;   ,           |           ,
&lt;&#x2F;span&gt;&lt;span&gt;     ,         |        , &amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;       &amp;#39; - , _ _ _ ,  &amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;               |
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Consider an infinitesimal volume at position $(r, \theta, \phi)$ where $r$ is the radial distance from the center, $\theta$ is the longitude and $\phi$ is the colatitude. Assume that the north-south axis is the axis we are interested in. The distance of the volume from the axis is $r_\perp = r\sin\phi$. The dimensions of the elemental volume are $dr$ in the radial direction, $d\theta$ along the longitude and $d\phi$ along the colatitude. The arc lengths of the “sides” of the element are $r\sin\phi d\theta$ and $r d\phi$. The volume is $dV = r\sin\phi~d\theta~rd\phi~dr$.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I &amp;amp;= \iiint_Q r_\perp^2 dm \\
  &amp;amp;= \iiint_Q r^2 \sin^2{\phi}~\rho(r)~dV \\
  &amp;amp;= \iiint_Q r^2 \sin^2{\phi}~\rho(r)~r\sin\phi~d\theta~rd\phi~dr \\
  &amp;amp;= \iiint_Q r^2 \sin^2{\phi}~\rho(r)~r^2 \sin{\phi}~d\theta~d\phi~dr \\
  &amp;amp;= \iiint_Q \rho(r) r^4 \sin^3{\phi}~d\theta~d\phi~dr \\
  &amp;amp;= \int_0^R \int_{-\pi}^{\pi} \int_{0}^{\pi} \rho(r) r^4 \sin^3{\phi}~d\phi~d\theta~dr\\
  &amp;amp;= \int_0^R \rho(r) r^4 \int_{-\pi}^{\pi} \int_{0}^{\pi} \sin^3{\phi}~d\phi~d\theta~dr\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Reference: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;math.stackexchange.com&#x2F;questions&#x2F;1475096&#x2F;why-does-the-volume-element-in-spherical-polar-coordinates-contain-a-sine-of-the&quot;&gt;https:&#x2F;&#x2F;math.stackexchange.com&#x2F;questions&#x2F;1475096&#x2F;why-does-the-volume-element-in-spherical-polar-coordinates-contain-a-sine-of-the&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;r = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;symbols&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;positive&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;theta, phi = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;symbols&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;theta phi&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;real&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;M, R = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;symbols&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;M R&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;positive&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;rho = M&#x2F;R**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt;(pi*r&#x2F;R)&#x2F;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;*r&#x2F;R)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;integral_1 = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;integrate&lt;&#x2F;span&gt;&lt;span&gt;( &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt;(phi)**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;, (phi, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, pi))
&lt;&#x2F;span&gt;&lt;span&gt;integral_2 = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;integrate&lt;&#x2F;span&gt;&lt;span&gt;( integral_1, (theta, -pi, pi) )
&lt;&#x2F;span&gt;&lt;span&gt;integral_3 = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;integrate&lt;&#x2F;span&gt;&lt;span&gt;( rho * r**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4 &lt;&#x2F;span&gt;&lt;span&gt;* integral_2, (r, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, R))
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;simplify&lt;&#x2F;span&gt;&lt;span&gt;(integral_3)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $\displaystyle \frac{2 M R^{2} \left(-6 + \pi^{2}\right)}{3 \pi^{2}}$
&lt;&#x2F;div&gt;
&lt;p&gt;The moment of inertia of Jupiter is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
I = \frac{2}{3\pi^2} MR^2 \left(\pi^2 -6\right)
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 2.3: Some useful moments of inertia</title>
        <published>2022-11-05T19:11:34+00:00</published>
        <updated>2022-11-05T19:11:34+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-3/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-3/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-3/">&lt;h2 id=&quot;exercise-2-3-some-useful-moments-of-inertia&quot;&gt;Exercise 2.3: Some useful moments of inertia&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Show that the moments of inertia of the following objects are as given:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;a. The moment of inertia of a sphere of uniform density with mass $M$ and radius $R$ about any line through the center is&lt;&#x2F;strong&gt; $\frac{2}{5} M R^2$&lt;&#x2F;p&gt;
&lt;p&gt;$$\require{cancel}$$&lt;&#x2F;p&gt;
&lt;p&gt;The moment of inertia of a body about some axis is given by the expression:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
I_{P}=\iiint _{Q}\rho (x,y,z)\left\|\mathbf {r} \right\|^{2}dV\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Since the sphere is symmetric, the moment of inertia about any axis through its center of mass is the same. Here we assume that the axis is the $z$ axis. We split the sphere into a collection of infinitesimally thin concentric cylinderical shells around the $z$ axis.&lt;&#x2F;p&gt;
&lt;p&gt;The moment of inertia is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
I = \int x^2 dm\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $r$ is the distance of a cylinderal shell from the $z$ axis and $dm$ is its mass. The mass $dm$ is equal to $\rho dV$ where $\rho$ is the density of the material and $dV$ is the volume of the cylindrical shell.&lt;&#x2F;p&gt;
&lt;p&gt;For a sphere of radius $R$, the density $\rho$ is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\rho = \frac{M}{\frac{4}{3}\pi R^3} = \frac{3M}{4\pi R^3}\\
$$
&lt;&#x2F;div&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;       z
&lt;&#x2F;span&gt;&lt;span&gt;       |
&lt;&#x2F;span&gt;&lt;span&gt;  .---------.
&lt;&#x2F;span&gt;&lt;span&gt; (     |     ) --
&lt;&#x2F;span&gt;&lt;span&gt; ||~--------~|| |
&lt;&#x2F;span&gt;&lt;span&gt; ||    |     || |
&lt;&#x2F;span&gt;&lt;span&gt; ||    |     || |
&lt;&#x2F;span&gt;&lt;span&gt; ||    |     || y
&lt;&#x2F;span&gt;&lt;span&gt; ||    |     || |
&lt;&#x2F;span&gt;&lt;span&gt; ||    |&amp;lt;-x-&amp;gt;|| |
&lt;&#x2F;span&gt;&lt;span&gt;-------.------------- 
&lt;&#x2F;span&gt;&lt;span&gt; ||          ||
&lt;&#x2F;span&gt;&lt;span&gt; ||          ||
&lt;&#x2F;span&gt;&lt;span&gt; ||          ||
&lt;&#x2F;span&gt;&lt;span&gt; ||          ||
&lt;&#x2F;span&gt;&lt;span&gt; ||          ||
&lt;&#x2F;span&gt;&lt;span&gt; ||          ||
&lt;&#x2F;span&gt;&lt;span&gt; (------------)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The height of the cylindrical shell at distance $x$ from the $z$ axis is equal to $2y$. The thickness of shell is erqual to $dx$ . Therefore volume of the cylindrical shell is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
dV &amp;amp;= 2 \pi r h \Delta r\\
   &amp;amp;= 2 \pi x (2y) dx \\
   &amp;amp;= 4 \pi x \sqrt{R^2 - x^2} dx\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore the mass of the cylindrical shell is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
dm &amp;amp;= \rho dV \\
   &amp;amp;= \frac{3 M}{\cancel{4\pi} R^3} \cancel{4 \pi} x \sqrt{R^2 - x^2} dx \\
dm   &amp;amp;= \frac{3 M}{R^3} x \sqrt{R^2 - x^2} dx\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The moment of inertia is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I = \int_{-R}^{+R} x^2 dm \\
  = \int_{-R}^{+R} x^2 \frac{3 M}{R^3} x \sqrt{R^2 - x^2} dx \\
  = \frac{3 M}{R^3}\int_{-R}^{+R} x^3 \sqrt{R^2 - x^2} dx\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This expression is integrated using &lt;code&gt;sympy&lt;&#x2F;code&gt; below:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;R, M = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;symbols&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;R M&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;positive&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;x = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;symbols&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;real&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;*M &#x2F; R**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;) * &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;integrate&lt;&#x2F;span&gt;&lt;span&gt;(x**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sqrt&lt;&#x2F;span&gt;&lt;span&gt;(R**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;- x**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;), (x, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, R))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $\displaystyle \frac{2 M R^{2}}{5}$
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;b. The moment of inertia of a spherical shell with mass $M$ and radius $R$ about any line through the center is:&lt;&#x2F;strong&gt; $\frac{2}{3} MR^2$&lt;&#x2F;p&gt;
&lt;p&gt;Again, we can pick any diameter as the axis, and we choose the $z$-axis. Consider an infinitesimally thin ring around the z-axis that is part of the shell (which is itself of radius $R$).&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;               | z axis
&lt;&#x2F;span&gt;&lt;span&gt;               |
&lt;&#x2F;span&gt;&lt;span&gt;         , - ~ ~ ~ - ,  
&lt;&#x2F;span&gt;&lt;span&gt;     , &amp;#39;=======|=======&amp;#39; ,  &amp;lt;-- thickness is R dθ
&lt;&#x2F;span&gt;&lt;span&gt;   ,           |      &#x2F;    ,
&lt;&#x2F;span&gt;&lt;span&gt;  ,            | θ  &#x2F;R      ,
&lt;&#x2F;span&gt;&lt;span&gt; ,             |   &#x2F;         ,
&lt;&#x2F;span&gt;&lt;span&gt; ,             +-&#x2F;--------R--&amp;gt;,
&lt;&#x2F;span&gt;&lt;span&gt; ,             |             ,
&lt;&#x2F;span&gt;&lt;span&gt;  ,            |            ,
&lt;&#x2F;span&gt;&lt;span&gt;   ,           |           ,
&lt;&#x2F;span&gt;&lt;span&gt;     ,         |        , &amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;       &amp;#39; - , _ _ _ ,  &amp;#39;
&lt;&#x2F;span&gt;&lt;span&gt;               |
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If the angle of a line from the origin to the edge of the ring to the $z$ axis is $\theta$, the radius of the ring is therefore $R\sin{\theta}$. The thickness of the ring is $R d\theta$. Area of the ring is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
dA &amp;amp;= 2\pi (r) Rd\theta \\
   &amp;amp;= 2\pi R\sin{\theta} R d\theta\\
   &amp;amp;= 2\pi R^2 \sin{\theta} d\theta
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;If $\sigma$ is the area-density of the sphere ($\sigma = \frac{M}{4 \pi R^2}$), the mass of the ring $dm = dA \sigma$. The moment of inertia of the ring is therefore:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
dI &amp;amp;= r^2 dm \\
   &amp;amp;= R^2 \sin^2{\theta} dm \\
   &amp;amp;= R^2 \sin^2{\theta} \sigma dA \\
   &amp;amp;= (R^2 \sin^2{\theta}) \sigma (2\pi R^2 \sin{\theta} d\theta)\\
   &amp;amp;= (R^2 \sin^2{\theta}) (\frac{M}{\cancelto{2}{4} \cancel{\pi R^2}} \cancel{2} \cancel{\pi R^2} \sin{\theta} d\theta)\\
   &amp;amp;= R^2\frac{M}{2} \sin^3{\theta} d \theta\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;To obtain the moment of inertia of the body, we integrate $dI$ over $\theta$ from $0$ to $\pi$ ($\theta = 0$ corresponds to the “north pole” of the sphere and $\theta = \pi$ corresponds to the south pole.)&lt;&#x2F;p&gt;
&lt;p&gt;Reference: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=Y2X0xjwxxwI&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=Y2X0xjwxxwI&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;R, M = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;symbols&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;R M&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;positive&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;theta = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;symbols&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;theta&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;real&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;M * R**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;integrate&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt;(theta)**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;, (theta, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, pi))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $\displaystyle \frac{2 M R^{2}}{3}$
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;c. The moment of inertia of a cylinder of uniform density with mass M and radius R about the axis of the cylinder is&lt;&#x2F;strong&gt; $\frac{1}{2} M R^2$&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;      z
&lt;&#x2F;span&gt;&lt;span&gt;      |
&lt;&#x2F;span&gt;&lt;span&gt;  .--------.
&lt;&#x2F;span&gt;&lt;span&gt; (    |    ) --
&lt;&#x2F;span&gt;&lt;span&gt; |~--------~|  |
&lt;&#x2F;span&gt;&lt;span&gt; |    |     |  |
&lt;&#x2F;span&gt;&lt;span&gt; |    |     |  |
&lt;&#x2F;span&gt;&lt;span&gt; |    |     | H&#x2F;2
&lt;&#x2F;span&gt;&lt;span&gt; |    |     |  |
&lt;&#x2F;span&gt;&lt;span&gt; |    |&amp;lt;-R-&amp;gt;|  |
&lt;&#x2F;span&gt;&lt;span&gt;-------.------------- 
&lt;&#x2F;span&gt;&lt;span&gt; |          |
&lt;&#x2F;span&gt;&lt;span&gt; |          |
&lt;&#x2F;span&gt;&lt;span&gt; |          |
&lt;&#x2F;span&gt;&lt;span&gt; |          |
&lt;&#x2F;span&gt;&lt;span&gt; |          |
&lt;&#x2F;span&gt;&lt;span&gt; |          |
&lt;&#x2F;span&gt;&lt;span&gt; (----------)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let $z$ axis be the axis of the cylinder. Split the cylinder into concentric infinitesimally thin cylindrical shell around the $z$ axis. The radius of such a shell is $x$ and its thickness is $dx$. The volume of the shell is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
dV &amp;amp;= 2 \pi r h \Delta r\\
   &amp;amp;= 2 \pi x H dx
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The density of the cylinder is $\rho = \frac{M}{\pi R^2 H}$. Therefore the mass of the cylindrical shell is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
dm &amp;amp;= \rho dV \\
   &amp;amp;= \frac{M}{\cancel{\pi} R^2 \cancel{H}} 2 \cancel{\pi} x \cancel{H} dx\\
   &amp;amp;= \frac{2 M}{R^2} x dx\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore the moment of inertia of the entire cylinder is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I &amp;amp;= \int dI\\
  &amp;amp;= \int_0^R x^2 dm \\
  &amp;amp;= \int_0^R x^2 \frac{2 M}{R^2} x dx \\
  &amp;amp;= \frac{2 M}{R^2} \int_0^R x^3 dx \\
  &amp;amp;= \frac{2 M}{R^2} \left.\left[ \frac{x^4}{4}\right]\right\vert_{0}^{R}\\
  &amp;amp;= \frac{\cancel{2} M}{\cancel{R^2}} \left[ \frac{R^\cancelto{2}{4}}{\cancelto{2}{4}} \right]\\
  &amp;amp;= \frac{1}{2}MR^2\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;d. The moment of inertia of a thin rod of uniform density per unit length with mass M and length L about an axis perpendicular to the rod through the center of mass is&lt;&#x2F;strong&gt; $\frac{1}{12} ML^2$&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;              y-axis
&lt;&#x2F;span&gt;&lt;span&gt;              ^
&lt;&#x2F;span&gt;&lt;span&gt;              |
&lt;&#x2F;span&gt;&lt;span&gt;              |&amp;lt;---- L&#x2F;2 ---&amp;gt;|
&lt;&#x2F;span&gt;&lt;span&gt;              |              | 
&lt;&#x2F;span&gt;&lt;span&gt;              |       dx     |
&lt;&#x2F;span&gt;&lt;span&gt;              |      &amp;gt;||&amp;lt;    | 
&lt;&#x2F;span&gt;&lt;span&gt;              |---x--&amp;gt;||     |
&lt;&#x2F;span&gt;&lt;span&gt;==============+==============| --&amp;gt; x-axis
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Consider an element at distance $x$ from the center of mass with length $dx$. The mass of this element is $dm = dx \sigma$ if $\sigma$ is the linear-density of the rod, $\sigma = \frac{M}{L}$.&lt;&#x2F;p&gt;
&lt;p&gt;The moment of inertia of this element is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
dI = x^2 dm = x^2 \sigma dx = \frac{M}{L} x^2 dx\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore the moment of inertia of the rod is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I &amp;amp;= \int_{-L&amp;#x2F;2}^{L&amp;#x2F;2} \frac{M}{L} x^2 dx \\
  &amp;amp;= \frac{M}{L} \left.\left[ \frac{x^3}{3} \right]\right\vert_{-L&amp;#x2F;2}^{L&amp;#x2F;2}\\
  &amp;amp;= \frac{M}{L} \left[ \frac{L^3}{24} - \frac{-L^3}{24} \right] \\
  &amp;amp;= \frac{M}{\cancel{L}} \left[ \frac{L^\cancelto{2}{3}}{12} \right]\\
  &amp;amp;= \frac{1}{12} M L^2\\
\end{align*}
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.5: Principal Moments of Inertia</title>
        <published>2022-11-05T17:53:57+00:00</published>
        <updated>2022-11-05T17:53:57+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-5-principal-moments-of-inertia/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-5-principal-moments-of-inertia/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-5-principal-moments-of-inertia/">&lt;h2 id=&quot;2-5-principal-moments-of-inertia&quot;&gt;2.5 Principal Moments of Inertia&lt;&#x2F;h2&gt;
&lt;p&gt;In the &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-2.4-inertia-tensor&quot;&gt;previous section&lt;&#x2F;a&gt;, we showed how the inertia tensor transforms under a rotation:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{I}&amp;#x27; = \mathbf{R}^{\mathscr{T}} \mathbf{I} \mathbf{R} \tag{2.35}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This transformation can be used to show that there are special rectangular coordinate frames for which the inertia tensor is diagonal, that is, $I^\prime_{ij} = 0\text{ for }i \neq j$. Let’s assume that $\mathbf{I}^\prime$ is diagonal and we need to solve for the rotation matrix $\mathbf{R}$ the gets us $\mathbf{I}^\prime$ from $\mathbf{I}$.&lt;&#x2F;p&gt;
&lt;p&gt;Left-multiply both sides of Eq. 2.35 by $\mathbf{R}$ to get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathbf{R} \mathbf{I&amp;#x27;} &amp;amp;= \mathbf{R}\mathbf{R}^{\mathscr{T}} \mathbf{I} \mathbf{R} \\
&amp;amp;= \mathbf{I} \mathbf{R}\tag{2.36}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We can extract out the columns of this matrix by mutliplying it on the right with the coordinate axis unit vectors, $\mathbf{e}_i$. These vectors have a 1 in the $i$-th row and zero elsewhere. Multiply $\mathbf{R}$ with $\mathbf{e}_i$ extracts out the basis vector of the rotated frame, $\mathbf{e}^\prime_i$. That is, $\mathbf{e}^\prime_i = \mathbf{R} \mathbf{e}_i$. Right-multiplying Eq. 2.36 by $\mathbf{e}_i$, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{R} \mathbf{I^\prime} \mathbf{e}_i = \mathbf{I}\mathbf{R}\mathbf{e}_i = \mathbf{I}\mathbf{e}^\prime_i\tag{2.37}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Since $\mathbf{I}^\prime$ is diagonal,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{I}\mathbf{e}^\prime_i = I^\prime_{ii} \mathbf{e}^\prime_i \tag{2.38}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;From Eqs. 2.37 and 2.38, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{I} \mathbf{e}^\prime_i = I^\prime_{ii} \mathbf{e}^\prime_i\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This equation says that transforming the vector $\mathbf{e}^\prime_i$ using the matrix $\mathbf{I}$ is equivalent to scaling the vector by the scalar value $I^\prime_{ii}$. This means that $I^\prime_{ii}$ is an eigen-value and $\mathbf{e}^\prime_i$ is the associated eigen-vector of $\mathbf{I}$.&lt;&#x2F;p&gt;
&lt;p&gt;Since $\mathbf{e}^\prime_i$ are the columns of a rotation matrix, and rotqtion matrix are orthogonal, the vectors themselves are orthonormal, i.e. they are unit vectors and their dot products with each other are zero.&lt;&#x2F;p&gt;
&lt;p&gt;For a real, symmetric matrix (like $\mathbf{I}$). the eigen values are real. If the eigen values are distinct, then the eigen-vectors are orthogonal. However, if the eigen values are not distinct (say in the case of a symmetric body liuke a sphere), we have degrees of freedom on choosing the eigen vectors - and we may pick $\mathbf{e}_i$ that are orthogonal. For example, for a cylinder, one of the eigen vectors(corresponding to the central axis) are distinct and the other two (corrsponding to the diameters of the circular faces) are equal. This means that any of the diameters can be considered an eigen vector.&lt;&#x2F;p&gt;
&lt;p&gt;This the rotated coordinate system has a special orientation with respect to the body. The basis vectors correspond to particular directions w.r.t the body. The axes through the center of mass in these directions are defined as the &lt;em&gt;principal axes&lt;&#x2F;em&gt;. Thus the moments of inertia about the principal axes are the eigenvalues $I^\prime_{ii}$ and are called the &lt;em&gt;principal moments of inertia&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The principal moments of inertia are often labeled according their size: $A \leq B \leq C$ with the corresponding axes: $\hat{a}$, $\hat{b}$ or $\hat{c}$. The components of some vector $\mathbf{x}$ when represented in terms of the principal axes are called &lt;em&gt;body components&lt;&#x2F;em&gt; of the vector. Rewriting the kinetic energy in terms of the principal moments of inertia,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
T_R = \frac{1}{2} \left[ A(\omega^a)^2 + B(\omega^b)^2 + C(\omega^c)^2\right]\tag{2.41}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $(\omega^a, \omega^b, \omega^c)$ are the components of the angular momentum vector on the principal axes.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;T-body &lt;&#x2F;span&gt;&lt;span&gt;[A B C]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[omega-body]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2
&lt;&#x2F;span&gt;&lt;span&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; A (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; omega-body &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; B (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; omega-body &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; C (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; omega-body &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;T-body &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;A &amp;#39;B &amp;#39;C)
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;omega_a &amp;#39;omega_b &amp;#39;omega_c)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\frac{1}{2}\,A\,{{\omega}_a}^{2} + \frac{1}{2}\,B\,{{\omega}_b}^{2} + \frac{1}{2}\,C\,{{\omega}_c}^{2}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 2.2: Steiner&#x27;s Theorem</title>
        <published>2022-11-04T05:30:04+00:00</published>
        <updated>2022-11-04T05:30:04+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-2/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-2/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-2/">&lt;h3 id=&quot;exercise-2-2-steiner-s-theorem&quot;&gt;Exercise 2.2: Steiner’s theorem&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Let I be the moment of inertia of a body with respect to some given line through the center of mass. Show that the moment of inertia I′ with respect to a second line parallel to the first is&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
I&amp;#x27; = I + M R^2\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;where $M$ is the mass of the body and $R$ is the distance between the lines.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;$$\require{cancel}$$&lt;&#x2F;p&gt;
&lt;p&gt;The position of any particle with respect to the axis can be resolved into a parallel component and a perpendicular component. Only the perpendicular component influences the moment of inertia and so the analysis can be performed in a plane perpendicular to the axis and generalized to the whole object.&lt;&#x2F;p&gt;
&lt;p&gt;So consider a cross sectional area of the object such that the original axis is perpendicular to this area. Let the center of mass of the area be the origin of the coordinate frame, with basis vectors $\hat{x}$ and $\hat{y}$ in the plane and perpendicular to each other, and $\hat{z}$ being the rotational axis. Let the new parallel axis be passing through the point $w$ on this plane at position $(x_w, y_w)$, parallel to the $\hat{z}$ axis. The distance of this point $w$ from the origin is $R = \sqrt{x_w^2 + y_w^2}$.&lt;&#x2F;p&gt;
&lt;p&gt;The moment of inertia of about the original axis through the center of mass is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I &amp;amp;= \sum\nolimits_\alpha m_\alpha r_\alpha ^2
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $r_\alpha$ is the distance of the particle at index $\alpha$ from the origin (the center of mass) and is equal to $\sqrt{x^2_\alpha + y^2_\alpha}$.&lt;&#x2F;p&gt;
&lt;p&gt;The distance a particle $\alpha$ to the new axis is given by $d_\alpha = \sqrt{ (x_\alpha - x_w)^2 + (y_\alpha - y_w)^2 }$. Therefore, the moment of inertia about the new axis is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I&amp;#x27; &amp;amp;= \sum\nolimits_\alpha m_\alpha d_\alpha ^2 \\
   &amp;amp;= \sum\nolimits_\alpha m_\alpha \left( (x_\alpha - x_w)^2 + (y_\alpha - y_w)^2 \right)\\
   &amp;amp;= \sum\nolimits_\alpha m_\alpha \left( x_\alpha^2 + x^2_w - 2x_\alpha x_w + y^2_\alpha +y^2_w - 2y_\alpha y_w \right) \\
   &amp;amp;= \sum\nolimits_\alpha m_\alpha \left( \underbrace{(x_\alpha^2 + y^2_\alpha)}_{=r_\alpha ^2} + \underbrace{(x^2_w + y^2_w)}_{=R^2} - 2x_\alpha x_w  - 2y_\alpha y_w \right) \\
   &amp;amp;= \sum\nolimits_\alpha m_\alpha r_\alpha ^2 + \sum\nolimits_\alpha m_\alpha R^2 -2 x_w \sum\nolimits_\alpha m_\alpha x_\alpha -2 y_w \sum\nolimits_\alpha m_\alpha y_\alpha
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The total mass of the body $M = \sum\nolimits_\alpha m_\alpha$. Since the origin is the center of mass of the plane, $ \sum\nolimits_\alpha m_\alpha x_\alpha = \sum\nolimits_\alpha m_\alpha y_\alpha = 0$.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I&amp;#x27; &amp;amp;= \sum\nolimits_\alpha m_\alpha r_\alpha ^2 + \sum\nolimits_\alpha m_\alpha R^2 -2 x_w \cancel{\sum\nolimits_\alpha m_\alpha x_\alpha} -2 y_w \cancel{\sum\nolimits_\alpha m_\alpha y_\alpha}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore, the moment of inertia about the parallel axis is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
I&amp;#x27; = I + MR^2\\
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.4: Inertia Tensor</title>
        <published>2022-11-04T04:44:49+00:00</published>
        <updated>2022-11-04T04:44:49+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-4-inertia-tensor/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-4-inertia-tensor/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-4-inertia-tensor/">&lt;h2 id=&quot;2-4-inertia-tensor&quot;&gt;2.4 Inertia Tensor&lt;&#x2F;h2&gt;
&lt;p&gt;The representation of kinetic energy in terms of the inertia tensor involved a rectangular coordinate frame with basis vectors, $\hat{e}$. However the kinetic energy must be the same regardless of the coordinate frame use. This fact can be used to derive how the inertia tensor transforms if the body or the coordinate frame are rotated.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;active-and-passive-rotations&quot;&gt;Active and passive rotations&lt;&#x2F;h4&gt;
&lt;p&gt;Rotating the vector $\vec{x}$ by the rotation $R$ produces a new vector $\vec{x’} = R\vec{x}$. $\vec{x}$ may be written in terms of some arbitrary rectangular coordinate system with the basis vectors ($\hat{e_1}$, $\hat{e_2}$, $\hat{e_3}$). Let $\mathbf{x}$ represent the &lt;em&gt;column vector&lt;&#x2F;em&gt; components $x^0$, $x^1$ and $x^2$ fo the vector in this coordinate frame. Let $\mathbf{R}$ be the matrix representation of the rotaton $R$ w.r.t the same coordinate frame. With these definitions, the rotation can be written as: $\mathbf{x}’ = \mathbf{R}\mathbf{x}$. Since this rotation carries the vectors to new vectors, it is an &lt;strong&gt;active rotation&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Alternately, we can rotate the basis vectors used to represent the vectors. While the vectors themselves may be unchanged, the components used to represent them are changed because the basis vectors are now in new orientations. If the new, rotated basis vector are represented by $\hat{e}‘_i = R\hat{e}_i$. The componenet along the rotated basis vector is the dot product of the vector $\vec{x}$ with the new basis vector, that is: $(x’)^i = \vec{x} \cdot \hat{e}’_i = \vec{x} \cdot (R \hat{e}_i)$.&lt;&#x2F;p&gt;
&lt;p&gt;Since the rotation of two vectors preserves the angle (and hence the dot product), between them,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\vec{x} \cdot \vec{y} &amp;amp;= (R\vec{x})\cdot(R\vec{y})\\
=&amp;gt; R^{-1} \vec{x} \cdot \vec{y} &amp;amp;= \vec{x} \cdot (R\vec{y})\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
(x&amp;#x27;)^i = \vec{x} \cdot (\mathbf{R} \hat{e}_i) = R^{-1} \vec{x} \cdot \hat{e}_i \\
=&amp;gt; \mathbf{x}&amp;#x27; = \mathbf{R}^{-1} \mathbf{x}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This type of rotation is called a &lt;strong&gt;passive rotation&lt;&#x2F;strong&gt; where the vectors were unchanged and the coordinate frame was rotated. For such a rotation, the components of a fixed vector changes &lt;strong&gt;as if it was actively rotated by the inverse rotation&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;transformation-of-moments-of-inertia-under-rotation&quot;&gt;Transformation of moments of inertia under rotation&lt;&#x2F;h4&gt;
&lt;p&gt;The kinetic energy in terms of the coordinate frame $\hat{e}_i$ is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
T = \frac{1}{2} \sum\nolimits_{ij} \omega^i \omega^j I_{ij} \tag{2.30}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;In matrix notation, this can be written as :&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
T = \frac{1}{2} \boldsymbol{\omega}^{\mathscr{T}} \mathbf{I} \boldsymbol{\omega}\tag{2.31}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\boldsymbol{\omega}$ is the column vector containing the components of the angular velocity vector $\vec{\omega}$ in the $\hat{e}_i$ coordinate frame. Applying a passive rotation $R$ to the coordinate frame gets us the new coordinate frame basis vectors $\hat{e}’_i = R \hat{e}_i$. The components of $\boldsymbol{\omega}$ in the new frame satisfies the condition:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\boldsymbol{\omega}&amp;#x27; &amp;amp;= \mathbf{R}^{-1} \boldsymbol{\omega}\\
=&amp;gt; \boldsymbol{\omega} &amp;amp;= \mathbf{R} \boldsymbol{\omega}&amp;#x27;
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore the kinetic energy is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
T &amp;amp;= \frac{1}{2} \boldsymbol{\omega}^{\mathscr{T}} \mathbf{I} \boldsymbol{\omega} \\
  &amp;amp;= \frac{1}{2} (\mathbf{R} \boldsymbol{\omega}&amp;#x27;)^{\mathscr{T}} \mathbf{I} \mathbf{R} \boldsymbol{\omega}&amp;#x27; \\
  &amp;amp;= \frac{1}{2} (\boldsymbol{\omega}&amp;#x27;)^{\mathscr{T}}\mathbf{R}^{\mathscr{T}} \mathbf{I} \mathbf{R} \boldsymbol{\omega}&amp;#x27;\tag{2.33} \\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;However, the kinetic energy in the $\hat{e}’$ frame is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
T = \frac{1}{2} (\boldsymbol{\omega}&amp;#x27;)^{\mathscr{T}} \mathbf{I}&amp;#x27; \boldsymbol{\omega} \tag{2.34}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where the components are in terms of the $\hat{e}’$ frame. Comparing equations 2.34 and 2.33, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{I}&amp;#x27; = \mathbf{R}^{\mathscr{T}} \mathbf{I} \mathbf{R} \tag{2.35}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This type of transformation is called a “similarity transformation” and this is how the inertia tensor transforms under passive rotation.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Seam carving algorithm</title>
        <published>2022-11-04T01:54:02.252+00:00</published>
        <updated>2022-11-04T01:54:02.252+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202210031854-seam-carving-algorithm/"/>
        <id>https://www.thomasantony.com/notes/202210031854-seam-carving-algorithm/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202210031854-seam-carving-algorithm/">&lt;p&gt;Seam carving is an algorithm that can be used to resize an image while removing the least important pixels from it.&lt;&#x2F;p&gt;
&lt;p&gt;One possible implementation is to use an edge-detection algorithm first to create an edge-map&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. This is followed by finding continuous lines that run from top to the bottom, where the only directions of movement allowed are “south”, “south-east” and “south-west”, that minimize the sum of “edge” values. This can be solved using a dynamic programming approach of starting at the bottom and assigning the “minimum-cost-to-bottom” to each cell.&lt;&#x2F;p&gt;
&lt;p&gt;Once this is done, we can find the path throug hthe image with the least cost and remove it.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=rpB6zQNsbQU&quot;&gt;Seam Carving | Week 2 | 18.S191 MIT Fall 2020 | Grant Sanderson&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 1.6.2: Systems with Rigid Constraints</title>
        <published>2022-11-03T05:17:50+00:00</published>
        <updated>2022-11-03T05:17:50+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-1-6-2-systems-with-rigid-constraints/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-1-6-2-systems-with-rigid-constraints/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-1-6-2-systems-with-rigid-constraints/">&lt;h2 id=&quot;1-6-2-systems-with-rigid-constraints&quot;&gt;1.6.2 Systems with Rigid Constraints&lt;&#x2F;h2&gt;
&lt;p&gt;So far we have found $L = T-V$ to be a suitable Lagrangian for systems of point particles subject to forces derived from a potential. In this section, we will find that $L = T − V$, expressed in &lt;em&gt;irredundant&lt;&#x2F;em&gt; coordinates, is also a suitable Lagrangian for modeling systems of point particles with rigid constraints.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lagrangians-for-rigidly-constrained-systems&quot;&gt;Lagrangians for rigidly constrained systems&lt;&#x2F;h3&gt;
&lt;p&gt;We start with a system of $N$ point masses, indexed by $\alpha$ in 3D space. We choose a set of generalized coordinates $q$ that have the system constraints built into them. The rectangular coordinates can then be defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{x}_\alpha = f_\alpha(t, q)\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where all the coordinate constraints are built into the functions $f_\alpha$. The velocities can then be obtained in terms of the generalized velocities, $v$ in the same manner as in the last section as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{v}_\alpha = \partial_0 f_\alpha(t, q) + \partial_1 f_\alpha(t, q) v\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The kinetic energy in rectangular coordinates can be obtained as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\widetilde{T}(t; x_0 ... x_{N-1}; v_0 ... v_{N-1}) = \sum_\alpha \frac{1}{2} m_\alpha \mathbf{v}_\alpha^2\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Converting to generalized coordinates:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
T(t, q, v) = \sum_\alpha \frac{1}{2} m_\alpha \left( \partial_0 f_\alpha(t, q) + \partial_1 f_\alpha(t, q) v \right)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Similarly, the potential energy in generalized coordinates is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
V(t, q, v) = \widetilde{V}(t, f(t, q))
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The Lagrangian can then be obtained as $L = T - V$.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-pendulum-driven-at-the-pivot&quot;&gt;A pendulum driven at the pivot&lt;&#x2F;h3&gt;
&lt;p&gt;Consider a pendulum of length $l$ and mass $m$, modeled as a point mass, supported by a pivot that is driven in the vertical direction by a given function of time $y_s(t)$. This system has a single degree of freedom and can be represented by the generalized coordinate $\theta$, the angle of the pendulum from the vertical.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;tgvaughan.github.io&#x2F;sicm&#x2F;images&#x2F;Art_P138.jpg&quot; alt=&quot;Figure 1.2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The position of the bob is given in rectangular coordinates by&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
x = l\sin{\theta} \text{ and } y = y_s(t) - l\cos{\theta}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The velocities are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
v_x = l\dot{\theta}\cos{\theta} \text{ and } v_y = Dy_s(t) + l\dot{\theta}\sin{\theta}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The kinetic energy is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\widetilde{T}(t; x,y; v_x, v_y) &amp;amp;= \frac{1}{2}m(v_x^2 + v_y^2) \\
T(t,\theta,\dot{\theta}) &amp;amp;= \frac{1}{2}m ( (l\dot{\theta}\cos{\theta})^2 + (Dy_s(t) + l\dot{\theta}\sin{\theta})^2 \\
&amp;amp;= \frac{1}{2}m \left( l^2\dot{\theta}^2(\cos^2{\theta} + \sin^2{\theta}) + (Dy_s(t))^2 + 2l\dot{\theta}\sin{\theta}Dy_s(t) \right)\\
&amp;amp;= \frac{1}{2}m \left( l^2\dot{\theta}^2 + (Dy_s(t))^2 + 2l\sin{\theta}Dy_s(t) \dot{\theta} \right)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The potential energy $\widetilde{V}(t; x,y) = mgy$ in rectangular coordinates. Therefore in generalized coordinates,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
V(t,\theta,\dot{\theta}) = mg (y_s(t) - l\cos{\theta})
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Computing EoMs
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;T-pend-on-pivot &lt;&#x2F;span&gt;&lt;span&gt;[m l g y_s]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[t [theta] [thetadot]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[Dy_s ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D&lt;&#x2F;span&gt;&lt;span&gt; y_s) t)]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m 
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; l thetadot))
&lt;&#x2F;span&gt;&lt;span&gt;                  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; Dy_s)
&lt;&#x2F;span&gt;&lt;span&gt;                  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt; l (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta) Dy_s thetadot)
&lt;&#x2F;span&gt;&lt;span&gt;              )
&lt;&#x2F;span&gt;&lt;span&gt;           )
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;V-pend-on-pivot &lt;&#x2F;span&gt;&lt;span&gt;[m l g y_s]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[t [theta] [thetadot]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m g (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;y_s&lt;&#x2F;span&gt;&lt;span&gt; t) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; l (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta))))
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-pend-on-pivot &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; T-pend-on-pivot V-pend-on-pivot))
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; (render
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;;  (let [local ((Gamma (up (literal-function &amp;#39;theta))) &amp;#39;t)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;;        L (L-pend-on-pivot &amp;#39;m &amp;#39;l &amp;#39;g (literal-function &amp;#39;y_s))
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;;        ]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;;      (L local)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;;      ))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; EOMs for pendulum driven at pivot
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-pend-on-pivot &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;l &amp;#39;g (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y_s))
&lt;&#x2F;span&gt;&lt;span&gt;      state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta))]
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;(((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations&lt;&#x2F;span&gt;&lt;span&gt; L) state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{bmatrix}\displaystyle{g\,l\,m\,\sin\left(\theta\left(t\right)\right) + {l}^{2}\,m\,{D}^{2}\theta\left(t\right) + l\,m\,\sin\left(\theta\left(t\right)\right)\,{D}^{2}y_s\left(t\right)}\end{bmatrix}
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 2.1: Rotational kinetic energy</title>
        <published>2022-11-02T06:11:12+00:00</published>
        <updated>2022-11-02T06:11:12+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-1/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-1/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-2-1/">&lt;h3 id=&quot;exercise-2-1-rotational-kinetic-energy&quot;&gt;Exercise 2.1: Rotational kinetic energy&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Show that the rotational kinetic energy can also be written as:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
T = \frac{1}{2} I\omega^2\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;where $I$ is the moment of inertia about the line through the center of mass with direction $\hat{\omega}$ and $\omega$ is the instantaneous rate of rotation.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;$$\require{cancel}$$&lt;&#x2F;p&gt;
&lt;p&gt;Let $\hat{\omega}$ be one of the basis vectors of the coordinate system, $\hat{e_0}$, and with its origin at the center of mass of the body. For a constituent particle in the body, $(\xi_\alpha^1)^2 + (\xi_\alpha^2)^2 = \xi_\alpha^\perp$ will equal to the distance from the particle to the line $\hat{e_0}$ which is the same as the line $\hat{\omega}$. Therefore, the inertia component, $I_{00}$ is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I_{00} &amp;amp;= \sum_\alpha m_\alpha \left( (\xi_\alpha^1)^2 + (\xi_\alpha^2)^2 \right) \\
       &amp;amp;= \sum_\alpha m_\alpha \left( \xi_\alpha^\perp \right)^2\\
       &amp;amp;= I\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $I$ is the moment of inertia about the line $\hat{\omega}$. Also, by definition, the components of the angular velocity vector, $\vec{\omega}$, are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\omega^0 &amp;amp;= \omega\\
\omega^1 &amp;amp;= 0\\
\omega^2 &amp;amp;= 0\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;since we defined $\vec{\omega}$ as being in the direction $\hat{\omega} = \hat{e}_0$. Therefore the kinetic energy is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
T &amp;amp;= \frac{1}{2} \sum_{ij} \omega^i\omega^j I_{ij} \\
  &amp;amp;= \frac{1}{2} \left( \omega^0\omega^0 I_{00} +  \omega^0\cancel{\omega^1} I_{01} + \omega^0 \cancel{\omega^2} I_{02} + ... \right) \\
  &amp;amp;= \frac{1}{2} I_{00} \omega^0 \omega^0
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;All the other terms in the expression for $T$ cancel out as the components $\omega^1$ and $\omega^2$ are equal to zero. Therefore,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
T = \frac{1}{2} I (\omega)^2\\
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.3: Moments of Inertia</title>
        <published>2022-11-02T06:01:17+00:00</published>
        <updated>2022-11-02T06:01:17+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-3-moments-of-inertia/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-3-moments-of-inertia/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-3-moments-of-inertia/">&lt;h2 id=&quot;2-3-moments-of-inertia&quot;&gt;2.3 Moments of Inertia&lt;&#x2F;h2&gt;
&lt;p&gt;The rotational kinetic energy consists of the sum of the kinetic energies of all the constituent particles. This can in turn be written in terms of the angular velocities and some aggregate properties that describe the mass distribution in the rigid body.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
T = \frac{1}{2}\sum_\alpha m_\alpha \dot{\vec{\xi}}_\alpha \cdot \dot{\vec{\xi}}_\alpha\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;substituting in the relation between $\vec{\omega}$ and $\dot{\vec{\xi}}_{\alpha}$&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\frac{1}{2}\sum_\alpha m_\alpha \dot{\vec{\xi}}_{\alpha} \cdot \dot{\vec{\xi}}_\alpha = 
\frac{1}{2}\sum_\alpha m_\alpha \left( \vec{\omega} \times \vec{\xi}_{\alpha} \right) \cdot \left(  \vec{\omega} \times \vec{\xi}_\alpha \right)\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Here, we introduce an arbitrary inertial coordinate frame its the origin at the center of rotation and basis vectors $\hat{e}_0$, $\hat{e}_1$ and $\hat{e}_2$, such that $\hat{e}_0 \times \hat{e}_1 = \hat{e}_2$. If the components of $\vec{\omega}$ in this frame are $\omega^0$, $\omega^1$ and $\omega^2$,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\frac{1}{2} &amp;amp; \sum_\alpha m_\alpha \left( \left(\sum_i \hat{e}_i \omega^i \right) \times \vec{\xi}_\alpha \right) \cdot \left(  \left(\sum_j \hat{e}_j \omega^j \right) \times \vec{\xi}_\alpha \right)\\
 &amp;amp;= \frac{1}{2} \sum_{ij} \omega^i\omega^j\sum_\alpha m_\alpha ( \hat{e}_i \times \vec{\xi}_\alpha) \cdot (\hat{e}_j \times \vec{\xi}_\alpha) \\
 &amp;amp;= \frac{1}{2} \sum_{ij} \omega^i\omega^j I_{ij}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
I_{ij} = \sum_\alpha m_\alpha ( \hat{e}_i \times \vec{\xi}_\alpha) \cdot (\hat{e}_j \times \vec{\xi}_\alpha)\tag{2.24}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The nine &lt;em&gt;time-dependent&lt;&#x2F;em&gt; (?!) quantities, $I_{ij}$ form the components of the &lt;em&gt;inertia tensor&lt;&#x2F;em&gt; w.r.t the chosen coordinate system.&lt;&#x2F;p&gt;
&lt;p&gt;If the components of $\vec{\xi_\alpha}$ are $\xi_{\alpha}^0$, $\xi_{\alpha}^1$ and $\xi_{\alpha}^2$, we can rewrite  $\vec{\xi}_\alpha$ as a sum over its components and simplify the vector products of the basis vectors. Thus we can get expressions for the components of the inertia tensor. The components of the inertia tensor can be arranged to form the &lt;em&gt;inertia matrix&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{I} = \begin{bmatrix}I_{00} &amp;amp; I_{01} &amp;amp; I_{02}\\
I_{10} &amp;amp; I_{11} &amp;amp; I_{12}\\
I_{20} &amp;amp; I_{21} &amp;amp; I_{22}\end{bmatrix}\tag{2.25}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
I_{00} &amp;amp;= \sum_\alpha m_\alpha \left( (\xi_\alpha^1)^2 + (\xi_\alpha^2)^2 \right)\\
I_{11} &amp;amp;= \sum_\alpha m_\alpha \left( (\xi_\alpha^2)^2 + (\xi_\alpha^0)^2 \right)\\
I_{22} &amp;amp;= \sum_\alpha m_\alpha \left( (\xi_\alpha^0)^2 + (\xi_\alpha^1)^2 \right)\\
I_{ij} &amp;amp;= - \sum_\alpha m_\alpha \xi_\alpha^i \xi_\alpha^j\quad\text{ for } i \neq j\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The components of the inertia tensor are real and symmetric, i.e., $I_{jk} = I_{kj}$. In general, the &lt;em&gt;moment of inertia&lt;&#x2F;em&gt; about a line can be defined as $\sum_\alpha m_\alpha (\xi_\alpha^\perp)^2$ where $\xi_\alpha^\perp$ is the distance from the line to the particle with index $\alpha$. The diagonal components of the inertia tensor are the moments of inertia about the lines coinciding with the basis vectors. The off-diagonal components are called the &lt;em&gt;products of inertia&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Since the inertia tensor involves only the second order moments of mass, the motion of a free rigid body does not depend on the detailed shape of the body. If two bodies have the same inertia tensor, they have the same kinetic energy regardless of what they look like. The potential energy might have effects based on the shape of the body but for the kinetic energy, the inertia tensor is all that matters.&lt;&#x2F;p&gt;
&lt;p&gt;For solid objects, the summation has to be converted to an integral. The general expression for moment of inertia is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
I_{P}=\iiint _{Q}\rho (x,y,z)\left\|\mathbf {r} \right\|^{2}dV
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\rho (x,y,z)$ is the density of the material, $\mathbf {r}$  is a vector perpendicular to the axis of rotation and extending from a point on the rotation axis to a point  $(x,y,z)$ in the solid, and the integration is evaluated over the volume $V$ of the body $Q$.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 1.8.4: The Restricted Three Body Problem</title>
        <published>2022-11-02T04:49:30+00:00</published>
        <updated>2022-11-02T04:49:30+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-1-8-4-the-restricted-3bp/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-1-8-4-the-restricted-3bp/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-1-8-4-the-restricted-3bp/">&lt;h2 id=&quot;1-8-4-the-restricted-three-body-problem&quot;&gt;1.8.4 The Restricted Three-Body Problem&lt;&#x2F;h2&gt;
&lt;p&gt;Consider two bodies of masses $M_0$ and $M_1$ in circular orbits about their barycenter. Assume that a third particle has a small enough mass $m$ to not have any effect on the orbits of the other two objects. This third particle moves in a field of time-varying gravitational potential energy.&lt;&#x2F;p&gt;
&lt;p&gt;Let $a$ be the constant distance between the two bodies. If the center of mass is at the origin of the coordinate system, then the distances of the two bodies from the origin are given by:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
a_0 = \frac{M_1}{M_0 + M_1}a, \quad a_1 =  \frac{M_0}{M_0 + M_1}a\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Each body revolves around the barycenter with angular frequency $\Omega$, with radii as defined above. Kepler’s Law gives the relation between $\Omega$ and $a$ as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\Omega^2a^3 = G(M_0 + M_1)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We choose our axes so that at time $t_0$, mass $M_1$ is on the positive $\hat{x}$-axis and $M_0$ is on the negative $\hat{x}$-axis. The gravitational potential energy function is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
V(t, r) = - \left(\frac{GM_0m}{r_0} + \frac{GM_1m}{r_1} \right)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
r_0 &amp;amp;= \sqrt{(x-x_0)^2 + (y-y_0)^2} \\
r_1 &amp;amp;= \sqrt{(x-x_1)^2 + (y-y_1)^2} \\
\\
x_0 &amp;amp;= -a_0\cos(\Omega t) \\
y_0 &amp;amp;= -a_0\sin(\Omega t) \\
x_1 &amp;amp;=  a_1\cos(\Omega t) \\
y_1 &amp;amp;= -a_1\sin(\Omega t) \\
\Omega &amp;amp;= \frac{G(M_0+M_1)}{a^3} 
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;It is convenient to instead use a coordinate frame that is rotating along with the two bigger bodies, such that the bodies appear fixed. place the axes so that the two bodies are on the new $\hat{x}’$ axis and we can choose rotating and non-rotating axes to be coincident at time, $t=0$. We can transform to the rotating rectangular coordinates as we did in Section 1.6.1 and get the new Lagrangian as&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L(t; x_r, y_r; \dot{x}_r, \dot{y}_r) = \frac{1}{2}m(\dot{x}_r^2 + \dot{y}_r^2) + \frac{1}{2}m\Omega^2(x_r^2 + y_r^2) + m\Omega(x_r \dot{y}_r - \dot{x}_r y_r) + \frac{G M_0 m}{r_0} + \frac{G M_1 m}{r_1} \tag{1.150}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where now $r_0^2 = (x_r - -a_0)^2 + (y_r-0)^2$ and $r_0^2 = (x_r - a_1)^2 + (y_r-0)^2$.&lt;&#x2F;p&gt;
&lt;p&gt;This Lagrangian in rotating coordinates is &lt;em&gt;independent&lt;&#x2F;em&gt; of time. Therefore the energy state function defined by this Lagrangian is conserved. Since it is clearest if we express this in terms of $\Omega$, $a_0$ and $a_1$, we should make those explicit parameters to the Lagrangian.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L0 &lt;&#x2F;span&gt;&lt;span&gt;[m V]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[t&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; q&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; v]]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;V&lt;&#x2F;span&gt;&lt;span&gt; t q))
&lt;&#x2F;span&gt;&lt;span&gt;      ))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;V_3BP &lt;&#x2F;span&gt;&lt;span&gt;[a GM0 GM1 m]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[t [x y]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[Omega (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sqrt &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; GM0 GM1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;expt&lt;&#x2F;span&gt;&lt;span&gt; a &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;            a0 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; GM1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; GM0 GM1)) a)
&lt;&#x2F;span&gt;&lt;span&gt;            a1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; GM0 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; GM0 GM1)) a)
&lt;&#x2F;span&gt;&lt;span&gt;            x0 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;-1&lt;&#x2F;span&gt;&lt;span&gt; a0 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; Omega t)))
&lt;&#x2F;span&gt;&lt;span&gt;            y0 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;-1&lt;&#x2F;span&gt;&lt;span&gt; a0 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; Omega t)))
&lt;&#x2F;span&gt;&lt;span&gt;            x1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;+1&lt;&#x2F;span&gt;&lt;span&gt; a1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; Omega t)))
&lt;&#x2F;span&gt;&lt;span&gt;            y1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;+1&lt;&#x2F;span&gt;&lt;span&gt; a1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; Omega t)))
&lt;&#x2F;span&gt;&lt;span&gt;            r0 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sqrt &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; x x0)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; y y0))))
&lt;&#x2F;span&gt;&lt;span&gt;            r1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sqrt &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; x x1)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; y y1))))]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; GM0 m) r0) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; GM1 m) r1))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;LR3B &lt;&#x2F;span&gt;&lt;span&gt;[m a0 a1 Omega GM0 GM1]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[t&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; q&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; qdot]]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; q &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; q &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        r0 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sqrt &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; x a0)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; y)))
&lt;&#x2F;span&gt;&lt;span&gt;        r1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sqrt &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; x a1)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; y)))
&lt;&#x2F;span&gt;&lt;span&gt;        xdot (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; qdot &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        ydot (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; qdot &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; qdot))
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; Omega) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; q))
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m Omega (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; x ydot) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; xdot y)))
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; GM0 m) r0) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; GM1 m) r1)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd &lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrangian-&amp;gt;energy 
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;LR3B &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;a_0 &amp;#39;a_1 &amp;#39;Omega &amp;#39;GM_0 &amp;#39;GM_1)
&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_r &amp;#39;y_r) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;v_rx &amp;#39;v_ry)))
&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\frac{\frac{-1}{2}\,{\Omega}^{2}\,m\,{x_r}^{2}\,\sqrt {{a_0}^{2}\,{a_1}^{2} -2\,{a_0}^{2}\,a_1\,x_r + {a_0}^{2}\,{x_r}^{2} + {a_0}^{2}\,{y_r}^{2} + 2\,a_0\,{a_1}^{2}\,x_r -4\,a_0\,a_1\,{x_r}^{2} + 2\,a_0\,{x_r}^{3} + 2\,a_0\,x_r\,{y_r}^{2} + {a_1}^{2}\,{x_r}^{2} + {a_1}^{2}\,{y_r}^{2} -2\,a_1\,{x_r}^{3} -2\,a_1\,x_r\,{y_r}^{2} + {x_r}^{4} + 2\,{x_r}^{2}\,{y_r}^{2} + {y_r}^{4}} + \frac{-1}{2}\,{\Omega}^{2}\,m\,{y_r}^{2}\,\sqrt {{a_0}^{2}\,{a_1}^{2} -2\,{a_0}^{2}\,a_1\,x_r + {a_0}^{2}\,{x_r}^{2} + {a_0}^{2}\,{y_r}^{2} + 2\,a_0\,{a_1}^{2}\,x_r -4\,a_0\,a_1\,{x_r}^{2} + 2\,a_0\,{x_r}^{3} + 2\,a_0\,x_r\,{y_r}^{2} + {a_1}^{2}\,{x_r}^{2} + {a_1}^{2}\,{y_r}^{2} -2\,a_1\,{x_r}^{3} -2\,a_1\,x_r\,{y_r}^{2} + {x_r}^{4} + 2\,{x_r}^{2}\,{y_r}^{2} + {y_r}^{4}} + \frac{1}{2}\,m\,{v_{rx}}^{2}\,\sqrt {{a_0}^{2}\,{a_1}^{2} -2\,{a_0}^{2}\,a_1\,x_r + {a_0}^{2}\,{x_r}^{2} + {a_0}^{2}\,{y_r}^{2} + 2\,a_0\,{a_1}^{2}\,x_r -4\,a_0\,a_1\,{x_r}^{2} + 2\,a_0\,{x_r}^{3} + 2\,a_0\,x_r\,{y_r}^{2} + {a_1}^{2}\,{x_r}^{2} + {a_1}^{2}\,{y_r}^{2} -2\,a_1\,{x_r}^{3} -2\,a_1\,x_r\,{y_r}^{2} + {x_r}^{4} + 2\,{x_r}^{2}\,{y_r}^{2} + {y_r}^{4}} + \frac{1}{2}\,m\,{v_{ry}}^{2}\,\sqrt {{a_0}^{2}\,{a_1}^{2} -2\,{a_0}^{2}\,a_1\,x_r + {a_0}^{2}\,{x_r}^{2} + {a_0}^{2}\,{y_r}^{2} + 2\,a_0\,{a_1}^{2}\,x_r -4\,a_0\,a_1\,{x_r}^{2} + 2\,a_0\,{x_r}^{3} + 2\,a_0\,x_r\,{y_r}^{2} + {a_1}^{2}\,{x_r}^{2} + {a_1}^{2}\,{y_r}^{2} -2\,a_1\,{x_r}^{3} -2\,a_1\,x_r\,{y_r}^{2} + {x_r}^{4} + 2\,{x_r}^{2}\,{y_r}^{2} + {y_r}^{4}} - {GM}_0\,m\,\sqrt {{a_1}^{2} -2\,a_1\,x_r + {x_r}^{2} + {y_r}^{2}} - {GM}_1\,m\,\sqrt {{a_0}^{2} + 2\,a_0\,x_r + {x_r}^{2} + {y_r}^{2}}}{\sqrt {{a_0}^{2}\,{a_1}^{2} -2\,{a_0}^{2}\,a_1\,x_r + {a_0}^{2}\,{x_r}^{2} + {a_0}^{2}\,{y_r}^{2} + 2\,a_0\,{a_1}^{2}\,x_r -4\,a_0\,a_1\,{x_r}^{2} + 2\,a_0\,{x_r}^{3} + 2\,a_0\,x_r\,{y_r}^{2} + {a_1}^{2}\,{x_r}^{2} + {a_1}^{2}\,{y_r}^{2} -2\,a_1\,{x_r}^{3} -2\,a_1\,x_r\,{y_r}^{2} + {x_r}^{4} + 2\,{x_r}^{2}\,{y_r}^{2} + {y_r}^{4}}}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;With some “hand simplification (tbd)” this turns into:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;(+ (* 1&#x2F;2 m (expt v_r^x 2))
&lt;&#x2F;span&gt;&lt;span&gt;   (* 1&#x2F;2 m (expt v_r^y 2))
&lt;&#x2F;span&gt;&lt;span&gt;   (&#x2F; (* -1 GM_0 m)
&lt;&#x2F;span&gt;&lt;span&gt;      (sqrt (+ (expt (+ x_r a_0) 2) (expt y_r 2))))
&lt;&#x2F;span&gt;&lt;span&gt;   (&#x2F; (* -1 GM_1 m)
&lt;&#x2F;span&gt;&lt;span&gt;      (sqrt (+ (expt (- x_r a_1) 2) (expt y_r 2))))
&lt;&#x2F;span&gt;&lt;span&gt;   (* -1&#x2F;2 m (expt Omega 2) (expt x_r 2))
&lt;&#x2F;span&gt;&lt;span&gt;   (* -1&#x2F;2 m (expt Omega 2) (expt y_r 2)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we separate this into a velocity-dependent part and a velocity-independent part we get&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{E}(t; x_r, y_r; \dot{x}_r, \dot{y}_r) = \frac{1}{2} m (\dot{x}_r^2 + \dot{y}_r^2) + mU_r(x_r, y_r)\\
\text{where}\\
U_r(x_r, y_r) = - \left( \frac{GM_0}{r_0} + \frac{GM_1}{r_1} + \frac{1}{2} \Omega^2 (x_r^2 + y_r^2) \right)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;This constant of motion is called the &lt;em&gt;Jacobi Constant&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt;. This is traditionally defined as $C_\mathscr{J} = -2\mathscr{E}$. Note that this energy state function does not have terms that are linear in $\dot{x}_r$ or $\dot{y}_r$, although they appear in the Lagrangian.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 1.6 : How to Find Lagrangians</title>
        <published>2022-11-02T03:45:51+00:00</published>
        <updated>2022-11-02T03:45:51+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-1-6-how-to-find-lagrangians/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-1-6-how-to-find-lagrangians/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-1-6-how-to-find-lagrangians/">&lt;h2 id=&quot;1-6-how-to-find-lagrangians&quot;&gt;1.6 How to Find Lagrangians&lt;&#x2F;h2&gt;
&lt;p&gt;It is possible to work back from Newton’s second law and obtain the Lagrangian $L = T - V$.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;constant-acceleration&quot;&gt;Constant Acceleration&lt;&#x2F;h3&gt;
&lt;p&gt;Consider a particle of mass $m$ in a gravitational field with acceleration, $g$. The potential energy is $mgh$ and kinetic energy is $\frac{1}{2} m v^2$. Therefore, a Lagrangian for the system is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L(t; x,y; v_x, v_y) = \frac{1}{2} m (v_x^2 + v_y^2) - mgy\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The EOMs for this system can be obtained by applying the EL equations as follows:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-const-accel &lt;&#x2F;span&gt;&lt;span&gt;[m g]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_  [x y] [v_x v_y]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_y))) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m g y))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-const-accel &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;g)
&lt;&#x2F;span&gt;&lt;span&gt;      state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y))]
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;(((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations&lt;&#x2F;span&gt;&lt;span&gt; L) state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{bmatrix}\displaystyle{m\,{D}^{2}x\left(t\right)} \cr \cr \displaystyle{g\,m + m\,{D}^{2}y\left(t\right)}\end{bmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;The above equations describe constant velocity in the $x$ direction and constant acceleration in the $y$ direction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;central-force-field&quot;&gt;Central Force Field&lt;&#x2F;h3&gt;
&lt;p&gt;Consider the motion of a particle of mass $m$ through a potential field, $U(r)$ whose value depends only on the distance $r$ to the center of attraction (e.g. gravity). In rectangular coordinates, the Lagrangian is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L(t; x,y; v_x, v_y) =  \frac{1}{2} m (v_x^2 + v_y^2) - U(\sqrt{x^2 + y^2})
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Applying EL equations, the equations of motion can be derived as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-central-rectangular &lt;&#x2F;span&gt;&lt;span&gt;[m U]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_  [x y] [v_x v_y]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sqrt &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; y)))]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_y))) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;U&lt;&#x2F;span&gt;&lt;span&gt; r)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-central-rectangular &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-central-rectangular &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;U))]
&lt;&#x2F;span&gt;&lt;span&gt;                                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations&lt;&#x2F;span&gt;&lt;span&gt; L)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y))]
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-central-rectangular&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{bmatrix}\displaystyle{\frac{m\,{D}^{2}x\left(t\right)\,\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2}} + x\left(t\right)\,DU\left(\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2}}\right)}{\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2}}}} \cr \cr \displaystyle{\frac{m\,{D}^{2}y\left(t\right)\,\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2}} + y\left(t\right)\,DU\left(\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2}}\right)}{\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2}}}}\end{bmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;These equations can be rewriten as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
m D^2 x(t) = -\frac{x(t)}{r(t)} DU(r(t)) \\
m D^2 y(t) = -\frac{y(t)}{r(t)} DU(r(t)) \\
\text{where }r(t) = \sqrt{x(t)^2 + y(t)^2}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This is the same form as two components of $F = ma$ where the particle is acted upon by a radial force of magnitude $-D U(r)$.&lt;&#x2F;p&gt;
&lt;p&gt;If we describe the system in polar coordinates instead, then $x = r \cos{\varphi} \text{ and } y = r \sin{\varphi}$.&lt;&#x2F;p&gt;
&lt;p&gt;Consider a configuration path that is represented in both rectangular and polar coordinates. Let $\widetilde{x}$ and $\widetilde{y}$ be components of the rectangular coordinate path, and let $\widetilde{r}$ and $\widetilde{\varphi}$ be components of the corresponding polar coordinate path. Applying the above conversion and differentiating, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\widetilde{x}(t) &amp;amp;= \widetilde{r}(t) \cos{ \widetilde{\varphi}(t) } \\
\widetilde{y}(t) &amp;amp;= \widetilde{r}(t) \sin{ \widetilde{\varphi}(t) } \\
=&amp;gt; D \widetilde{x}(t) &amp;amp;= D \widetilde{r}(t) \cos{\widetilde{\varphi}(t)} -  \widetilde{r}(t) \sin{\widetilde{\varphi}(t)} D \widetilde{\varphi}(t) \\
D \widetilde{y}(t) &amp;amp;= D \widetilde{r}(t) \sin{\widetilde{\varphi}(t)} +  \widetilde{r}(t) \cos{\widetilde{\varphi}(t)} D \widetilde{\varphi}(t) \\
=&amp;gt; v_x &amp;amp;= \dot{r}\cos{\varphi} - r\dot{\varphi} \sin{\varphi} \\
v_y &amp;amp;= \dot{r}\sin{\varphi} + r\dot{\varphi} \cos{\varphi}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;From the above expressions for generalized velocities, the expression for kinetic energy can be obtained as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
T = \frac{1}{2} m ( \dot{r}^2 + r^2\dot{\varphi}^2 )
$$
&lt;&#x2F;div&gt;
&lt;p&gt;And the Lagrangian as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L = \frac{1}{2} m ( \dot{r}^2 + r^2\dot{\varphi}^2 ) - U(r)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Applying Lagrange’s Equations, we get:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-central-polar &lt;&#x2F;span&gt;&lt;span&gt;[m U]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_  [r phi] [rdot phidot]]]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; rdot) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; r) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; phidot)))) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;U&lt;&#x2F;span&gt;&lt;span&gt; r))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-central-polar &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-central-polar &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;U))]
&lt;&#x2F;span&gt;&lt;span&gt;                                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations&lt;&#x2F;span&gt;&lt;span&gt; L)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;varphi))]
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-central-polar&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{bmatrix}\displaystyle{- m\,{\left(D\varphi\left(t\right)\right)}^{2}\,r\left(t\right) + m\,{D}^{2}r\left(t\right) + DU\left(r\left(t\right)\right)} \cr \cr \displaystyle{2\,m\,D\varphi\left(t\right)\,r\left(t\right)\,Dr\left(t\right) + m\,{\left(r\left(t\right)\right)}^{2}\,{D}^{2}\varphi\left(t\right)}\end{bmatrix}
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; F-&amp;gt;C in book
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;F2C &lt;&#x2F;span&gt;&lt;span&gt;[F] 
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q-prime]
&lt;&#x2F;span&gt;&lt;span&gt;        ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F&lt;&#x2F;span&gt;&lt;span&gt; q-prime)) &amp;#39;t)
&lt;&#x2F;span&gt;&lt;span&gt;    ))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;p2r &lt;&#x2F;span&gt;&lt;span&gt;[[_ [r phi] [rdot phidot]]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;            y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; phi))]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x y)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Local tuple after coordinate conversion from polar -&amp;gt; rectilinear
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F2C&lt;&#x2F;span&gt;&lt;span&gt; p2r)
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t 
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;phi))
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;rdot) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;phidot)))
&lt;&#x2F;span&gt;&lt;span&gt;            ))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{t} \cr \cr \displaystyle{\begin{pmatrix}\displaystyle{r\left(t\right)\,\cos\left(\phi\left(t\right)\right)} \cr \cr \displaystyle{r\left(t\right)\,\sin\left(\phi\left(t\right)\right)}\end{pmatrix}} \cr \cr \displaystyle{\begin{pmatrix}\displaystyle{- r\left(t\right)\,\sin\left(\phi\left(t\right)\right)\,D\phi\left(t\right) + Dr\left(t\right)\,\cos\left(\phi\left(t\right)\right)} \cr \cr \displaystyle{r\left(t\right)\,\cos\left(\phi\left(t\right)\right)\,D\phi\left(t\right) + Dr\left(t\right)\,\sin\left(\phi\left(t\right)\right)}\end{pmatrix}}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;The first equation says that mass times radial acceleration is equal to the sum of the force due to the potential field ($U(r)$) and the centrifugal force $mr\dot{\varphi}^2$. The second equation can be interpreted as $\frac{d}{dt}(mr^2 \dot{\varphi}) = 0$ or that the angular momentum is conserved.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 1.6.1: Coordinate Transformations</title>
        <published>2022-11-02T03:45:41+00:00</published>
        <updated>2022-11-02T03:45:41+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-1-6-1-coordinate-transformations/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-1-6-1-coordinate-transformations/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-1-6-1-coordinate-transformations/">&lt;h2 id=&quot;1-6-1-coordinate-transformations&quot;&gt;1.6.1 Coordinate Transformations&lt;&#x2F;h2&gt;
&lt;p&gt;Assume we have a mechanical system whose motion is described by a Lagrangian that depends on time, position and velocities. Assume also that we have a coordinate transformation $x = F(t, x’)$ that goes from “primed” to “unprimed” coordinates. The Lagrangian $L$ is expressed in unprimed coordinates. We want to find the Lagrangian expressed in primed coordinates. If $q$ is a configuration path in unprimed coordinates an $q’$ is in primed coordinates, then they must satisfy:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L&amp;#x27; \circ \Gamma[q&amp;#x27;] = L \circ \Gamma [q]\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;In general, the requirement that paths in two different coordinate systems be consistent with the coordinate transformation can be used to deduce how all of the components of the local tuple transform. Given a coordinate transformation $F$, let $C$ be the corresponding function that maps local tuples in the primed coordinate system to corresponding local tuples in the unprimed coordinate system:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
C \circ \Gamma[q&amp;#x27;] = \Gamma[q]
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L&amp;#x27; = L \circ C\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Substituting q and q’ into the coordinate transformation, and taking its derivative w.r.t $t$ and applying the chain rule,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
Dq(t) = \partial_0 F(t, q&amp;#x27;(t)) + \partial_1 F(t, q&amp;#x27;(t)) Dq&amp;#x27;(t) \\
\\
\text{where } \partial_0 F(t, q&amp;#x27;(t)) \text{ is the time derivative of } F(t, q&amp;#x27;(t)) \\
\text{ and } \partial_1 F(t, q&amp;#x27;(t)) \text{ is the Jacobian of F w.r.t q&amp;#x27;}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore the generalized velocity transforms as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
v = \partial_0 F(t, x&amp;#x27;) + \partial_1 F(t, x&amp;#x27;) v&amp;#x27;\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;If our local tuples have higher-derivative components,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
(t, x, v, ... ) &amp;amp;= C(t, x&amp;#x27;, v&amp;#x27;, ...) \\
                &amp;amp;= (t, F(t&amp;#x27; x&amp;#x27;), \partial_0 F(t, x&amp;#x27;) + \partial_1 F(t, x&amp;#x27;) v&amp;#x27;, ...)
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;h4 id=&quot;note&quot;&gt;Note&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;$L’ = L \circ C$ and $C$ converts from &lt;strong&gt;primed&lt;&#x2F;strong&gt; to &lt;strong&gt;unprimed&lt;&#x2F;strong&gt;. Therefore, the coordinate conversion function from  &lt;strong&gt;primed&lt;&#x2F;strong&gt; to &lt;strong&gt;unprimed&lt;&#x2F;strong&gt; is used to create the conversion from &lt;strong&gt;unprimed&lt;&#x2F;strong&gt; to &lt;strong&gt;primed&lt;&#x2F;strong&gt; Lagrangian. There is sort of an opposite thing going on here.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.2: Kinematics of Rotation</title>
        <published>2022-11-02T03:01:37+00:00</published>
        <updated>2022-11-02T03:01:37+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-2-kinematics-of-rotation/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-2-kinematics-of-rotation/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-2-kinematics-of-rotation/">&lt;h2 id=&quot;2-2-kinematics-of-rotation&quot;&gt;2.2 Kinematics of Rotation&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The motion of a rigid body about a center of rotation (a body-fixed reference point) is characterized at each point in time by an axis of rotation and a rate of rotation&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;According to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Euler%27s_rotation_theorem&quot;&gt;Euler’s theorem of rotations&lt;&#x2F;a&gt;, we can go from one orientation of a rigid body to another in a single rotation&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Rotations are not commutative in general, i.e., the order of rotations matter&lt;&#x2F;li&gt;
&lt;li&gt;However the combination of any number of rotations in some order can be represented by a single rotation&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Orientations are specified by the rotations it takes to reach that orientation from some reference orientation.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Let $q$ by the path describing the motion of the body and $M(q(t))$ be the rotation that takes the body from a reference orientation to the orientation specified by $q(t)$. Let $\vec{\xi_\alpha}(t)$ be some vector in the body-frame (to some constituent particle) in orientation given by $q(t)$, and $\vec{\xi’_\alpha}$ be the same body-frame vector in the reference orientation, then:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\vec{\xi}_\alpha(t) = \mathscr{M}(q(t)) \vec{\xi&amp;#x27;}_\alpha\tag{2.11}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;To find the kinetic energy, we need to combine the contributions of all the constituent particles, aka, the velocities of the particles.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\vec{\xi}_\alpha(t) = \mathscr{M}(q(t)) \vec{\xi&amp;#x27;}_\alpha = M(t)\vec{\xi&amp;#x27;}_\alpha\tag{2.12}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where  $M = \mathscr{M} \circ q$. Taking the time derivative:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D\vec{\xi}_\alpha(t) = DM(t)\vec{\xi&amp;#x27;}_\alpha\tag{2.13}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;By inverting Eq. 2.12, we can write $\vec{\xi’}_{\alpha}$ in terms of $\vec{\xi}_{\alpha}$,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D\vec{\xi}_\alpha(t) = DM(t)(M(t))^{-1}\vec{\xi}_\alpha(t)\tag{2.13}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Since $M(t)$ is a rotation represented by an orthogonal matrix $\mathbf{M}(t)$, with the property, $(\mathbf{M}(t))^{-1}$ = $(\mathbf{M}(t))^{\intercal}$. Therefore, $\mathbf{M}(t)(\mathbf{M}(t))^{\intercal}$ = $\mathbf{I}$ and hence $D(\mathbf{M}\mathbf{M}^\intercal) = \mathbf{0}$.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{0} = D(\mathbf{M}\mathbf{M}^\intercal) = D(\mathbf{M})\mathbf{M}^\intercal + \mathbf{M}D \mathbf{M}^\intercal\tag{2.15}
$$
&lt;&#x2F;div&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: $(AB)^\intercal = B^\intercal A^\intercal =&amp;gt; (D\mathbf{M}\mathbf{M}^\intercal)^\intercal = (\mathbf{M}^\intercal)^\intercal D\mathbf{M}^\intercal = \mathbf{M}D \mathbf{M}^\intercal$&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;div&gt;
    $$
D(\mathbf{M})\mathbf{M}^\intercal = -\mathbf{M}D \mathbf{M}^\intercal = -(D\mathbf{M}\mathbf{M}^\intercal)^\intercal\tag{2.16}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This shows that $D(\mathbf{M})\mathbf{M}^\intercal$ is anti-symmetric. If $\mathbf{u}$ has the components $(x, y, z)
$, all anti-symmetric 3x3 matrices have the following form:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{A}(\mathbf{u}) = \begin{pmatrix}0 &amp;amp;-z&amp;amp; y\\ z &amp;amp;0 &amp;amp;-x\\-y &amp;amp;x &amp;amp;0\end{pmatrix}\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Multuplying this matrix by a vector is equivalent to a cross-product by the vector $\vec{u}$ (and $\mathbf{u}$ is the matrix representation of $\vec{u}$. The inverse of the function $\mathscr{A}$ is one that extracts the components of $\mathbf{u}$ from a given skew-symmetric matrix.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: $\mathscr{A}^{-1}$ is &lt;em&gt;not&lt;&#x2F;em&gt; the inverse of the skew-symmetric matrix. Rather, this is a function that by definition, extracts the components of $\vec{u}$ from a skew-symmetric matrix.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;So the matrix multiplication $D\mathbf{M}\mathbf{M}^\intercal$ can be interpreted as a cross-product with a vector that we can call $\vec{\omega}$ which is the angular velocity vector. Therefore,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\boldsymbol{\omega} = \mathscr{A}^{-1}(D \mathbf{M} \mathbf{M}^\intercal) \tag{2.18}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore the differential equations of the constituent particles can be written as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D \vec{\xi}_\alpha(t) = \vec{\omega}(t) \times \vec{\xi}_\alpha(t)\tag{2.19}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This shows that the velocity o the constituent particles are perpendicular to their position vectors and proportional to the rate of rotation and distance from the instantaneous center:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\dot{\vec{\xi}}_\alpha = \vec{\omega} \times \vec{\xi}_\alpha\tag{2.20}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The components, $\boldsymbol{\omega}‘$ of the angular velocity vector in the body frame are $\boldsymbol{\omega}’ = \mathbf{M}^\intercal \boldsymbol{\omega}$, or&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\boldsymbol{\omega}&amp;#x27; = \mathbf{M}^\intercal  \mathscr{A}^{-1}(D \mathbf{M} \mathbf{M}^\intercal) \tag{2.21}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;Note: Need to figure out why it is $\mathbf{M}^\intercal$ and not $\mathbf{M}$ in Eq. 2.21. Is this not a “rotation” of the vector? Question posted at: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;physics.stackexchange.com&#x2F;questions&#x2F;734684&#x2F;angular-velocity-in-body-frame-vs-inertial-frame&quot;&gt;https:&#x2F;&#x2F;physics.stackexchange.com&#x2F;questions&#x2F;734684&#x2F;angular-velocity-in-body-frame-vs-inertial-frame&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a kinematic relationship that is valid for any path and can be used to obtain the components of angular velocity given the configuration and velocity at any time.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;implementation-of-angular-velocity-functions&quot;&gt;Implementation of angular velocity functions&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;M-of-q-&amp;gt;omega-of-t &lt;&#x2F;span&gt;&lt;span&gt;[M-of-q]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[t]
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[M-on-path (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose&lt;&#x2F;span&gt;&lt;span&gt; M-of-q q)
&lt;&#x2F;span&gt;&lt;span&gt;                omega-cross t]
&lt;&#x2F;span&gt;&lt;span&gt;             (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D&lt;&#x2F;span&gt;&lt;span&gt; M-on-path) t)
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;transpose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;M-on-path&lt;&#x2F;span&gt;&lt;span&gt; t)))
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rigid&#x2F;antisymmetric-&amp;gt;column-matrix &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;omega-cross&lt;&#x2F;span&gt;&lt;span&gt; t)))
&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; `omega-cross` produces the matrix representation of cross product &amp;quot;omega x&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; antisymmetric-&amp;gt;column-matrix corresponds to A^{-1} and extracts vector components from
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; a skew symmetric matrix
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; This function gives components of omega in body-fixed axes
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;M-of-q-&amp;gt;omega-body-of-t &lt;&#x2F;span&gt;&lt;span&gt;[M-of-q]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[t]
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;transpose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;M-of-q &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;q&lt;&#x2F;span&gt;&lt;span&gt; t)))
&lt;&#x2F;span&gt;&lt;span&gt;             (((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;M-of-q-&amp;gt;omega-of-t&lt;&#x2F;span&gt;&lt;span&gt; M-of-q) q) t)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; We use Gamma-bar to convert these functions of path to functions of local tuple
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;M-&amp;gt;omega &lt;&#x2F;span&gt;&lt;span&gt;[M-of-q]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma-bar
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;M-of-q-&amp;gt;omega-of-t&lt;&#x2F;span&gt;&lt;span&gt; M-of-q)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;M-&amp;gt;omega-body &lt;&#x2F;span&gt;&lt;span&gt;[M-of-q]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma-bar
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;M-of-q-&amp;gt;omega-body-of-t&lt;&#x2F;span&gt;&lt;span&gt; M-of-q)))
&lt;&#x2F;span&gt;&lt;span&gt; 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;:ok
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;:ok
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These procedures will return angular velocities as a function of state (aka local tuple)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.12: Lagrange&#x27;s Equations</title>
        <published>2022-11-01T01:59:57+00:00</published>
        <updated>2022-11-01T01:59:57+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-12/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-12/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-12/">&lt;h3 id=&quot;exercise-1-12-lagrange-s-equations&quot;&gt;Exercise 1.12: Lagrange’s Equations&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Compute Lagrange’s equations for the Lagrangians in exercise 1.9 using the Lagrange-equations procedure.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;a. An ideal planar pendulum consists of a bob of mass m connected to a pivot by a massless rod of length $l$ subject to uniform gravitational acceleration g. A Lagrangian is $L(t, \theta, \dot{\theta}) = \frac{1}{2} m l^2 \dot{\theta}^2 + m g l\cos{\theta}$ . The formal parameters of $L$ are $t$, $\theta$, and $\dot{\theta}$; $\theta$ measures the angle of the pendulum rod to a plumb line and $\dot{\theta}$ is the angular velocity of the rod.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-pendulum &lt;&#x2F;span&gt;&lt;span&gt;[m g l]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ [theta] [thetadot]]] 
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; l) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; thetadot))
&lt;&#x2F;span&gt;&lt;span&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m g l (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-pendulum 
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-pendulum &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;g &amp;#39;l)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta))]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-pendulum&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{bmatrix}\displaystyle{g\,l\,m\,\sin\left(\theta\left(t\right)\right) + {l}^{2}\,m\,{D}^{2}\theta\left(t\right)}\end{bmatrix}
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;b. A particle of mass m moves in a two-dimensional potential $V(x, y) = (x^2 + y^2)&#x2F;2 + x^2y − y^3&#x2F;3$, where $x$ and $y$ are rectangular coordinates of the particle. A Lagrangian is $L(t;x,y;v_x,v_y)=\frac{1}{2} m (v_x^2+v_y^2) − V(x,y)$.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;potential-field &lt;&#x2F;span&gt;&lt;span&gt;[x y] 
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; y)) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; x) y)
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cube&lt;&#x2F;span&gt;&lt;span&gt; y) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;    ))
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-particle-potential-field &lt;&#x2F;span&gt;&lt;span&gt;[m V]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ [x y] [v_x v_y]]] 
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_y)))
&lt;&#x2F;span&gt;&lt;span&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;V&lt;&#x2F;span&gt;&lt;span&gt; x y))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-particle-potential-field 
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-particle-potential-field &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m potential-field)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y))]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-particle-potential-field&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{m\,{D}^{2}x\left(t\right) + 2\,x\left(t\right)\,y\left(t\right) + x\left(t\right)} \cr \cr \displaystyle{m\,{D}^{2}y\left(t\right) + {\left(x\left(t\right)\right)}^{2} - {\left(y\left(t\right)\right)}^{2} + y\left(t\right)}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;c. A Lagrangian for a particle of mass m constrained to move on a sphere of radius $R$ is $L(t;\theta,\phi;\alpha,\beta)=\frac{1}{2}mR^2(\alpha^2+(\beta \sin\theta)^2)$. The angle $\theta$ is the colatitude of the particle and $\phi$ is the longitude; the rate of change of the colatitude is $\alpha$ and the rate of change of the longitude is $\beta$.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-particle-on-sphere &lt;&#x2F;span&gt;&lt;span&gt;[m R]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ [theta phi] [alpha beta]]] 
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; R) 
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; alpha) 
&lt;&#x2F;span&gt;&lt;span&gt;                    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; beta (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta)))
&lt;&#x2F;span&gt;&lt;span&gt;                  )
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-particle-on-sphere
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-particle-on-sphere &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;R)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec  &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;phi))]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-particle-on-sphere&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{- {R}^{2}\,m\,\sin\left(\theta\left(t\right)\right)\,{\left(D\phi\left(t\right)\right)}^{2}\,\cos\left(\theta\left(t\right)\right) + {R}^{2}\,m\,{D}^{2}\theta\left(t\right)} \cr \cr \displaystyle{2\,{R}^{2}\,m\,\sin\left(\theta\left(t\right)\right)\,D\phi\left(t\right)\,\cos\left(\theta\left(t\right)\right)\,D\theta\left(t\right) + {R}^{2}\,m\,{\sin}^{2}\left(\theta\left(t\right)\right)\,{D}^{2}\phi\left(t\right)}\end{pmatrix}
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.14: Coordinate-independence of Lagrange Equations</title>
        <published>2022-11-01T01:56:19+00:00</published>
        <updated>2022-11-01T01:56:19+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-14/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-14/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-14/">&lt;h3 id=&quot;exercise-1-14-coordinate-independence-of-lagrange-equations&quot;&gt;Exercise 1.14: Coordinate-independence of Lagrange equations&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Check that the Lagrange equations for central force motion in polar coordinates and in rectangular coordinates are equivalent.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;In order to do this, compute the expressions for accelerations $a_x(t)$ and $a_y(t)$ in terms of the polar coordinates and substitute into the lagrange’s equations in cartesian coordinates.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-central-rectangular &lt;&#x2F;span&gt;&lt;span&gt;[m U]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_  [x y] [v_x v_y]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sqrt &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; y)))]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_y))) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;U&lt;&#x2F;span&gt;&lt;span&gt; r)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-central-rectangular &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-central-rectangular &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;U))]
&lt;&#x2F;span&gt;&lt;span&gt;                                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations&lt;&#x2F;span&gt;&lt;span&gt; L)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-central-r2p &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r)
&lt;&#x2F;span&gt;&lt;span&gt;     phi (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;varphi)
&lt;&#x2F;span&gt;&lt;span&gt;     rt (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r)
&lt;&#x2F;span&gt;&lt;span&gt;     x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;     y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;     v_x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D&lt;&#x2F;span&gt;&lt;span&gt; x)
&lt;&#x2F;span&gt;&lt;span&gt;     v_y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D&lt;&#x2F;span&gt;&lt;span&gt; y)
&lt;&#x2F;span&gt;&lt;span&gt;     a_x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D&lt;&#x2F;span&gt;&lt;span&gt; v_x)
&lt;&#x2F;span&gt;&lt;span&gt;     a_y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D&lt;&#x2F;span&gt;&lt;span&gt; v_y)
&lt;&#x2F;span&gt;&lt;span&gt;     state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x y)
&lt;&#x2F;span&gt;&lt;span&gt;     eom ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-central-rectangular&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)
&lt;&#x2F;span&gt;&lt;span&gt;     ]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;apply&lt;&#x2F;span&gt;&lt;span&gt; up eom)
&lt;&#x2F;span&gt;&lt;span&gt;    ))
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex&lt;&#x2F;span&gt;&lt;span&gt; eom-central-r2p)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{- m\,\cos\left(\varphi\left(t\right)\right)\,{\left(D\varphi\left(t\right)\right)}^{2}\,r\left(t\right) -2\,m\,D\varphi\left(t\right)\,\sin\left(\varphi\left(t\right)\right)\,Dr\left(t\right) - m\,r\left(t\right)\,\sin\left(\varphi\left(t\right)\right)\,{D}^{2}\varphi\left(t\right) + m\,\cos\left(\varphi\left(t\right)\right)\,{D}^{2}r\left(t\right) + \cos\left(\varphi\left(t\right)\right)\,DU\left(r\left(t\right)\right)} \cr \cr \displaystyle{- m\,{\left(D\varphi\left(t\right)\right)}^{2}\,r\left(t\right)\,\sin\left(\varphi\left(t\right)\right) + 2\,m\,\cos\left(\varphi\left(t\right)\right)\,D\varphi\left(t\right)\,Dr\left(t\right) + m\,\cos\left(\varphi\left(t\right)\right)\,r\left(t\right)\,{D}^{2}\varphi\left(t\right) + m\,\sin\left(\varphi\left(t\right)\right)\,{D}^{2}r\left(t\right) + \sin\left(\varphi\left(t\right)\right)\,DU\left(r\left(t\right)\right)}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[eom eom-central-r2p
&lt;&#x2F;span&gt;&lt;span&gt;      eom1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; eom &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;      eom2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; eom &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;simplify &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; eom1 eom2)))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{- m\,\cos\left(\varphi\left(t\right)\right)\,{\left(D\varphi\left(t\right)\right)}^{2}\,r\left(t\right) - m\,{\left(D\varphi\left(t\right)\right)}^{2}\,r\left(t\right)\,\sin\left(\varphi\left(t\right)\right) + 2\,m\,\cos\left(\varphi\left(t\right)\right)\,D\varphi\left(t\right)\,Dr\left(t\right) + m\,\cos\left(\varphi\left(t\right)\right)\,r\left(t\right)\,{D}^{2}\varphi\left(t\right) -2\,m\,D\varphi\left(t\right)\,\sin\left(\varphi\left(t\right)\right)\,Dr\left(t\right) - m\,r\left(t\right)\,\sin\left(\varphi\left(t\right)\right)\,{D}^{2}\varphi\left(t\right) + m\,\cos\left(\varphi\left(t\right)\right)\,{D}^{2}r\left(t\right) + m\,\sin\left(\varphi\left(t\right)\right)\,{D}^{2}r\left(t\right) + \cos\left(\varphi\left(t\right)\right)\,DU\left(r\left(t\right)\right) + \sin\left(\varphi\left(t\right)\right)\,DU\left(r\left(t\right)\right)}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;Rewriting the above equations, we get&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
-mr\dot{\varphi}^2 \cos{\varphi} + (mr\ddot{\varphi} + 2m\dot{r}\dot{\varphi})(-\sin{\varphi}) + m\ddot{r}\cos{\varphi} + DU(r)\cos{\varphi} &amp;amp;= 0 \\
-mr\dot{\varphi}^2 \sin{\varphi} + (mr\ddot{\varphi} + 2m\dot{r}\dot{\varphi})\cos{\varphi} + m\ddot{r}\sin{\varphi} + DU(r)\sin{\varphi} &amp;amp;= 0
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Multiply first eqn by $\cos{\varphi}$ and the second by $\sin{\varphi}$ and add&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
-mr\dot{\varphi}^2 + m\ddot{r} + DU(r) = 0\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Multiply first eqn by $\sin{\varphi}$ and the second by $\cos{\varphi}$ and subtract to get&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
mr \ddot{\varphi} + 2m\dot{r}\dot{\varphi} = 0\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;These are the same equations of motion that we obtained by directly building the Lagrangian from polar coordinates.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.13: Higher-derivative Lagrangians</title>
        <published>2022-11-01T01:56:16+00:00</published>
        <updated>2022-11-01T01:56:16+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-13/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-13/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-13/">&lt;h3 id=&quot;exercise-1-13-higher-derivative-lagrangians&quot;&gt;Exercise 1.13: Higher-derivative Lagrangians&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;a. Write a procedure to compute the Lagrange equations for Lagrangians that depend upon acceleration, as in exercise 1.10. Note that Gamma can take an optional argument giving the length of the initial segment of the local tuple needed. The default length is 3, giving components of the local tuple up to and including the velocities.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Lagrange’s equations for Lagrangians that depend on acceleration was derived as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D^2(\partial_3 L \cdot \Gamma[q]) − D(\partial_2 L\cdot \Gamma[q])+\partial_1 L\cdot \Gamma[q]=0\\
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;Lagrange-equations-accel &lt;&#x2F;span&gt;&lt;span&gt;[L]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state-path (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; q &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;)]
&lt;&#x2F;span&gt;&lt;span&gt;                   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;) L) state-path)))
&lt;&#x2F;span&gt;&lt;span&gt;                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) L) state-path)))
&lt;&#x2F;span&gt;&lt;span&gt;                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) L) state-path))
&lt;&#x2F;span&gt;&lt;span&gt;            )))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;#&amp;#39;user&#x2F;Lagrange-equations-accel
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;b. Use your procedure to compute the Lagrange equations for the Lagrangian:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L(t, x, v, a) = - \frac{1}{2} m x a - \frac{1}{2} k x^2\\
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-accel &lt;&#x2F;span&gt;&lt;span&gt;[m k]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[ [_ [x] [v] [a]] ]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;-1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m x a) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2 &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;k (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; x)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-L-accel
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations-accel &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-accel &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;k)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec  &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x))]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-L-accel&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{- k\,x\left(t\right) - m\,{D}^{2}x\left(t\right)}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;c. For more fun, write the general Lagrange equation procedure that takes a Lagrangian that depends on any number of derivatives, and the number of derivatives, to produce the required equations of motion.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Generaized Lagrange’s Equation seems like a sum of alternate signed terms based on examination.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L = \sum_{i=0}^{n} (-1)^i D^i \left( \partial_{i+1} L \cdot \Gamma[q] \right)
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.11: Kepler&#x27;s Third Law</title>
        <published>2022-10-31T01:33:12+00:00</published>
        <updated>2022-10-31T01:33:12+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-11/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-11/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-11/">&lt;h3 id=&quot;exercise-1-11-kepler-s-third-law&quot;&gt;Exercise 1.11: Kepler’s third law&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;A Lagrangian suitable for studying the relative motion of two particles, of masses $m_1$ and $m_2$, with potential energy $V$, is:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L = \frac{1}{2} m \left(\dot{r}^2 + (r\dot{\phi})^2\right) + V(r)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;The argument $m$ is the reduced mass of the system:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
m = \frac{m_1 m_2}{m_1 + m_2}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;For gravity, the potential energy function is:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
V(r) = -\frac{G m_1 m_2}{r}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;Consider the simple situation of the particles in circular orbits around their common center of mass. Construct a circular orbit and plug it into the Lagrange equations. Show that the residual gives Kepler’s law:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
n^2 a^3 = G(m_1 + m_2)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;where $n$ is the angular frequency of the orbit and a is the distance between particles.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Define Lagrangian and derive EoMs
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-central-polar &lt;&#x2F;span&gt;&lt;span&gt;[m V]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ [r phi] [rdot phidot]]] 
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; rdot) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r phidot))) )
&lt;&#x2F;span&gt;&lt;span&gt;         (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;V&lt;&#x2F;span&gt;&lt;span&gt; r))
&lt;&#x2F;span&gt;&lt;span&gt;        ))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;m &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_1 &amp;#39;m_2) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_1 &amp;#39;m_2) ))
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;V &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[r] (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;G &amp;#39;m_1 &amp;#39;m_2) r))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-kepler 
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-central-polar&lt;&#x2F;span&gt;&lt;span&gt; m V)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;phi))]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-kepler&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Circular orbit
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;; r(t) = a
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;; phi(t) = n * t  
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;circ-solution
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[t] &amp;#39;a) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[t] (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;n t))))
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;circ-solution &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-kepler&lt;&#x2F;span&gt;&lt;span&gt; circ-solution) &amp;#39;t))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{\frac{- {a}^{3}\,m_1\,m_2\,{n}^{2} + G\,{m_1}^{2}\,m_2 + G\,m_1\,{m_2}^{2}}{{a}^{2}\,m_1 + {a}^{2}\,m_2}} \cr \cr \displaystyle{0}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;The above equation simplifies to:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
-a^3 m_1 m_2 n^2 + G m_1 m_2 (m_1 + m_2) &amp;amp;= 0 \\
=&amp;gt; G (m_1 + m_2) &amp;amp;= a^3 n^2\\
\end{align*}
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.15: Equivalence</title>
        <published>2022-10-31T01:09:08+00:00</published>
        <updated>2022-10-31T01:09:08+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-15/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-15/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-15/">&lt;h3 id=&quot;exercise-1-15-equivalence&quot;&gt;Exercise 1.15: Equivalence&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Here we use the &lt;code&gt;p-&amp;gt;r&lt;&#x2F;code&gt; conversion function to convert the Lagrangian in rectangular coordinates to polar coordinates (and compare to results from notes and exercise 1.14 where it was computed explicitly).&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; The Coordinate conversion function `C`
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;p2r &lt;&#x2F;span&gt;&lt;span&gt;[[_ [r phi] [rdot phidot]]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;            y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; phi))]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x y)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; F-&amp;gt;C is part of sicmutils and is more complex than in the book for this section
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;F2C &lt;&#x2F;span&gt;&lt;span&gt;[F]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[local]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[v (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; local &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;            t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ref&lt;&#x2F;span&gt;&lt;span&gt; local &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;)]
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; t
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F&lt;&#x2F;span&gt;&lt;span&gt; local)
&lt;&#x2F;span&gt;&lt;span&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) F) local)
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;(((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) F) local) v))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-central-rectangular &lt;&#x2F;span&gt;&lt;span&gt;[m U]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L &lt;&#x2F;span&gt;&lt;span&gt;[[_  [x y] [v_x v_y]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sqrt &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; y)))]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2 &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_y))) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;U&lt;&#x2F;span&gt;&lt;span&gt; r)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; L&amp;#39; = L . C
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-central-polar-using-F2C &lt;&#x2F;span&gt;&lt;span&gt;[m U]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q-prime]
&lt;&#x2F;span&gt;&lt;span&gt;        ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-central-rectangular&lt;&#x2F;span&gt;&lt;span&gt; m U) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F2C&lt;&#x2F;span&gt;&lt;span&gt; p2r))  
&lt;&#x2F;span&gt;&lt;span&gt;           q-prime)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Verify LE in polar coordinates match what was expected
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-central-polar-using-F2C &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;U))
&lt;&#x2F;span&gt;&lt;span&gt;      state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;varphi))]
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;(((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations&lt;&#x2F;span&gt;&lt;span&gt; L) state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{bmatrix}\displaystyle{- m\,r\left(t\right)\,{\left(D\varphi\left(t\right)\right)}^{2} + m\,{D}^{2}r\left(t\right) + DU\left(r\left(t\right)\right)}&amp;amp;\displaystyle{m\,{\left(r\left(t\right)\right)}^{2}\,{D}^{2}\varphi\left(t\right) + 2\,m\,r\left(t\right)\,D\varphi\left(t\right)\,Dr\left(t\right)}\end{bmatrix}
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.16: Central force motion</title>
        <published>2022-10-31T01:09:03+00:00</published>
        <updated>2022-10-31T01:09:03+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-16/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-16/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-16/">&lt;h3 id=&quot;exercise-1-16-central-force-motion&quot;&gt;Exercise 1.16: Central force motion&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Find Lagrangians for central force motion in three dimensions in rectangular coordinates and in spherical coordinates. First, find the Lagrangians analytically, then check the results with the computer by generalizing the programs that we have presented.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; 3D central force Lagrange&amp;#39;s eqns
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-central-rect-3d &lt;&#x2F;span&gt;&lt;span&gt;[m U]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L &lt;&#x2F;span&gt;&lt;span&gt;[[_  [x y z] [v_x v_y v_z]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sqrt &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; z)))]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2 &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_z))) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;U&lt;&#x2F;span&gt;&lt;span&gt; r)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-central-rect-3d &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-central-rect-3d &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;U))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;z))]
&lt;&#x2F;span&gt;&lt;span&gt; ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-central-rect-3d&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{\frac{m\,{D}^{2}x\left(t\right)\,\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2} + {\left(z\left(t\right)\right)}^{2}} + x\left(t\right)\,DU\left(\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2} + {\left(z\left(t\right)\right)}^{2}}\right)}{\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2} + {\left(z\left(t\right)\right)}^{2}}}} \cr \cr \displaystyle{\frac{m\,\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2} + {\left(z\left(t\right)\right)}^{2}}\,{D}^{2}y\left(t\right) + y\left(t\right)\,DU\left(\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2} + {\left(z\left(t\right)\right)}^{2}}\right)}{\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2} + {\left(z\left(t\right)\right)}^{2}}}} \cr \cr \displaystyle{\frac{m\,\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2} + {\left(z\left(t\right)\right)}^{2}}\,{D}^{2}z\left(t\right) + z\left(t\right)\,DU\left(\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2} + {\left(z\left(t\right)\right)}^{2}}\right)}{\sqrt {{\left(x\left(t\right)\right)}^{2} + {\left(y\left(t\right)\right)}^{2} + {\left(z\left(t\right)\right)}^{2}}}}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;p2r-3d &lt;&#x2F;span&gt;&lt;span&gt;[[_ [r theta phi] _]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;            y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;            z (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; phi))]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x y z)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-central-polar-3d-using-F2C &lt;&#x2F;span&gt;&lt;span&gt;[m U]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q-prime]
&lt;&#x2F;span&gt;&lt;span&gt;        ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-central-rect-3d&lt;&#x2F;span&gt;&lt;span&gt; m U) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F-&amp;gt;C&lt;&#x2F;span&gt;&lt;span&gt; p2r-3d))
&lt;&#x2F;span&gt;&lt;span&gt;           q-prime)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-central-polar-3d-using-F2C &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-central-polar-3d-using-F2C &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;U))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;varphi))
&lt;&#x2F;span&gt;&lt;span&gt;        local ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;p2r-3d&lt;&#x2F;span&gt;&lt;span&gt; local)))
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;render 
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;varphi))
&lt;&#x2F;span&gt;&lt;span&gt;        local ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)
&lt;&#x2F;span&gt;&lt;span&gt;        L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-central-polar-3d-using-F2C &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;U))
&lt;&#x2F;span&gt;&lt;span&gt;       ]
&lt;&#x2F;span&gt;&lt;span&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L&lt;&#x2F;span&gt;&lt;span&gt; local)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;varphi))
&lt;&#x2F;span&gt;&lt;span&gt;       ]
&lt;&#x2F;span&gt;&lt;span&gt;     ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-central-polar-3d-using-F2C&lt;&#x2F;span&gt;&lt;span&gt; state)&amp;#39;t)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; &amp;quot;exercise for the reader ...&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{\frac{- m\,r\left(t\right)\,{\sin}^{2}\left(\theta\left(t\right)\right)\,{\left(D\varphi\left(t\right)\right)}^{2}\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} - m\,r\left(t\right)\,{\sin}^{2}\left(\theta\left(t\right)\right)\,{\left(D\theta\left(t\right)\right)}^{2}\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} - m\,r\left(t\right)\,{\cos}^{2}\left(\varphi\left(t\right)\right)\,{\left(D\varphi\left(t\right)\right)}^{2}\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} + m\,r\left(t\right)\,\sin\left(\theta\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\,{D}^{2}\theta\left(t\right) - m\,r\left(t\right)\,\cos\left(\varphi\left(t\right)\right)\,\sin\left(\varphi\left(t\right)\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\,{D}^{2}\varphi\left(t\right) + 2\,m\,\sin\left(\theta\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,D\theta\left(t\right)\,Dr\left(t\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} -2\,m\,\cos\left(\varphi\left(t\right)\right)\,\sin\left(\varphi\left(t\right)\right)\,D\varphi\left(t\right)\,Dr\left(t\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} + m\,{\sin}^{2}\left(\theta\left(t\right)\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\,{D}^{2}r\left(t\right) + m\,{\cos}^{2}\left(\varphi\left(t\right)\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\,{D}^{2}r\left(t\right) + {\sin}^{2}\left(\theta\left(t\right)\right)\,DU\left(r\left(t\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)\,DU\left(r\left(t\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\right)}{\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}}} \cr \cr \displaystyle{\frac{- m\,{\left(r\left(t\right)\right)}^{2}\,\sin\left(\theta\left(t\right)\right)\,{\left(D\varphi\left(t\right)\right)}^{2}\,\cos\left(\theta\left(t\right)\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} - m\,{\left(r\left(t\right)\right)}^{2}\,\sin\left(\theta\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,{\left(D\theta\left(t\right)\right)}^{2}\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} + m\,{\left(r\left(t\right)\right)}^{2}\,{\cos}^{2}\left(\theta\left(t\right)\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\,{D}^{2}\theta\left(t\right) + 2\,m\,r\left(t\right)\,{\cos}^{2}\left(\theta\left(t\right)\right)\,D\theta\left(t\right)\,Dr\left(t\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} + m\,r\left(t\right)\,\sin\left(\theta\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\,{D}^{2}r\left(t\right) + r\left(t\right)\,\sin\left(\theta\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,DU\left(r\left(t\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\right)}{\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}}} \cr \cr \displaystyle{\frac{2\,m\,{\left(r\left(t\right)\right)}^{2}\,\sin\left(\theta\left(t\right)\right)\,D\varphi\left(t\right)\,\cos\left(\theta\left(t\right)\right)\,D\theta\left(t\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} + m\,{\left(r\left(t\right)\right)}^{2}\,\cos\left(\varphi\left(t\right)\right)\,\sin\left(\varphi\left(t\right)\right)\,{\left(D\varphi\left(t\right)\right)}^{2}\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} - m\,{\left(r\left(t\right)\right)}^{2}\,{\cos}^{2}\left(\varphi\left(t\right)\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\,{D}^{2}\varphi\left(t\right) - m\,{\left(r\left(t\right)\right)}^{2}\,{\cos}^{2}\left(\theta\left(t\right)\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\,{D}^{2}\varphi\left(t\right) -2\,m\,r\left(t\right)\,{\cos}^{2}\left(\varphi\left(t\right)\right)\,D\varphi\left(t\right)\,Dr\left(t\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} -2\,m\,r\left(t\right)\,D\varphi\left(t\right)\,{\cos}^{2}\left(\theta\left(t\right)\right)\,Dr\left(t\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} - m\,r\left(t\right)\,\cos\left(\varphi\left(t\right)\right)\,\sin\left(\varphi\left(t\right)\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\,{D}^{2}r\left(t\right) + 2\,m\,{\left(r\left(t\right)\right)}^{2}\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\,{D}^{2}\varphi\left(t\right) + 4\,m\,r\left(t\right)\,D\varphi\left(t\right)\,Dr\left(t\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)} - r\left(t\right)\,\cos\left(\varphi\left(t\right)\right)\,\sin\left(\varphi\left(t\right)\right)\,DU\left(r\left(t\right)\,\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}\right)}{\sqrt {{\sin}^{2}\left(\theta\left(t\right)\right) + {\cos}^{2}\left(\varphi\left(t\right)\right)}}}\end{pmatrix}
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.17: Bead on a helical wire</title>
        <published>2022-10-31T01:02:55+00:00</published>
        <updated>2022-10-31T01:02:55+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-17/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-17/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-17/">&lt;h3 id=&quot;exercise-1-17-bead-on-a-helical-wire&quot;&gt;Exercise 1.17: Bead on a helical wire&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;A bead of mass $m$ is constrained to move on a frictionless helical wire. The helix is oriented so that its axis is horizontal. The diameter of the helix is $d$ and its pitch (turns per unit length) is $h$. The system is in a uniform gravitational field with vertical acceleration $g$. Formulate a Lagrangian that describes the system and find the Lagrange equations of motion.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The system here has a single degree of freedom - the parameter $s$ describing the horizontal position of the bead along the x-axis. Let $r$ be the radius of the helix. The bead advances horizontally by distance $1&#x2F;h$ for every rotation around the helix. The angle around the helix is equal to $\frac{2\pi}{1&#x2F;h}s = 2\pi hs$.&lt;&#x2F;p&gt;
&lt;p&gt;So when $s = 0$, $x, y, z = 0, 0, 0$. Halfway up the first loop,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
s = \frac{1}{2h}\\
x = s = \frac{1}{2h},\\
y = r \cos{\left(2\pi h \frac{1}{2h}\right)} = r\cos{\pi},\\
y = r \sin{\left(2\pi h \frac{1}{2h}\right)} = r\sin{\pi},\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The coordinates of the bead in rectangular coordinates are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
x(t) &amp;amp;= s(t) \\
y(t) &amp;amp;= \frac{d}{2} \cos{2 \pi h s} \\
y(t) &amp;amp;= \frac{d}{2} \sin{2 \pi h s} \\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The velocities in rectangular coordinates are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
v_x(t) &amp;amp;= \dot{s}\\
v_y(t) &amp;amp;= -\pi d h \dot{s} \sin{2 \pi h s}  \\
v_z(t) &amp;amp;= \pi d h \dot{s} \cos{2 \pi h s} \\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The kinetic energy in generalized coordinates is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
T(t,s,\dot{s}) &amp;amp;= \frac{1}{2} m \left({v_x}^2 + {v_y}^2 + {v_z}^2\right) \\
               &amp;amp;= \frac{1}{2} m \left( \dot{s}^2 + \left( \pi^2 d^2 h^2 \dot{s}^2 \right) (\sin^2{2 \pi h s} + \cos^2{2 \pi h s}) \right) \\
               &amp;amp;= \frac{1}{2} m \dot{s}^2 \left( 1 + \pi^2 d^2 h^2 \right)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The potential energy in generalized coordinates is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
V(t,s,\dot{s}) = mgy(t) = m g \frac{d}{2} \cos{2 \pi h s}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Computing EoMs
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;T-bead-helical &lt;&#x2F;span&gt;&lt;span&gt;[m g d h]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[t [s] [sdot]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; sdot) 
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;pi) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; d) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; h))
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;V-bead-helical &lt;&#x2F;span&gt;&lt;span&gt;[m g d h]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[t [s] [sdot]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m g (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; d &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;pi h s)))
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-bead-helical &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; T-bead-helical V-bead-helical))
&lt;&#x2F;span&gt;&lt;span&gt;    
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;render
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[local ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;s))) &amp;#39;t)
&lt;&#x2F;span&gt;&lt;span&gt;       L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-bead-helical &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;g &amp;#39;d &amp;#39;h)
&lt;&#x2F;span&gt;&lt;span&gt;       ]
&lt;&#x2F;span&gt;&lt;span&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L&lt;&#x2F;span&gt;&lt;span&gt; local)
&lt;&#x2F;span&gt;&lt;span&gt;     ))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; EOMs for bead on helical wire under gravity
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-bead-helical &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;g &amp;#39;d &amp;#39;h)
&lt;&#x2F;span&gt;&lt;span&gt;      state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;s))]
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;(((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations&lt;&#x2F;span&gt;&lt;span&gt; L) state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{bmatrix}\displaystyle{- d\,g\,h\,m\,\pi\,\sin\left(2\,h\,\pi\,s\left(t\right)\right) + {d}^{2}\,m\,{D}^{2}s\left(t\right) + {h}^{2}\,m\,{D}^{2}s\left(t\right) + m\,{\pi}^{2}\,{D}^{2}s\left(t\right) + m\,{D}^{2}s\left(t\right)}\end{bmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;The equations of motion for the bead on a helical wire is derived as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\ddot{s} = \frac{dgh\pi \sin{\left( 2\pi h s \right)}} { d^2  + h^2  +  \pi^2 + 1 }
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.19: Two-bar linkage</title>
        <published>2022-10-31T01:02:53+00:00</published>
        <updated>2022-10-31T01:02:53+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-19/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-19/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-19/">&lt;h3 id=&quot;exercise-1-19-two-bar-linkage&quot;&gt;Exercise 1.19: Two-bar linkage&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;The two-bar linkage shown in the figure below is constrained to move in the plane. It is composed of three small massive bodies interconnected by two massless rigid rods in a uniform gravitational field with vertical acceleration g. The rods are pinned to the central body by a hinge that allows the linkage to fold. The system is arranged so that the hinge is completely free: the members can go through all configurations without collision. Formulate a Lagrangian that describes the system and find the Lagrange equations of motion. Use the computer to do this, because the equations are rather big.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;projects&#x2F;sicm-workbook&#x2F;figure-1.3.jpg&quot; alt=&quot;Figure 1.3&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 1.3&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Use three sets of rectangular coordinates, one for each body. The generalized coordinates could be represented by the position of $m_2$ and two angles, $\theta_1$ and $\theta_3$, positive CCW and measured from the X axis.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
x_1(t) &amp;amp;= x + l_1\cos\theta_1 \\
x_1(t) &amp;amp;= y + l_1\sin\theta_1 \\
x_2(t) &amp;amp;= x\\
y_2(t) &amp;amp;= y\\
x_3(t) &amp;amp;= x + l_1\cos\theta_3 \\
x_3(t) &amp;amp;= y + l_1\sin\theta_3 \\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;twobar-linkage-&amp;gt;rect &lt;&#x2F;span&gt;&lt;span&gt;[l_1 l_2]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ [x y theta_1 theta_3] _]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; l_1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta_1)))
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; l_1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta_1)))
&lt;&#x2F;span&gt;&lt;span&gt;            x
&lt;&#x2F;span&gt;&lt;span&gt;            y
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; l_2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta_3)))
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; l_2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta_3)))
&lt;&#x2F;span&gt;&lt;span&gt;        )))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-const-accel-three-bodies &lt;&#x2F;span&gt;&lt;span&gt;[m_1 m_2 m_3 g]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_  [x_1 y_1 x_2 y_2 x_3 y_3] [v_x1 v_y1 v_x2 v_y2 v_x3 v_y3]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[T1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m_1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_x1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_y1))))
&lt;&#x2F;span&gt;&lt;span&gt;              T2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m_2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_x2) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_y2))))
&lt;&#x2F;span&gt;&lt;span&gt;              T3 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m_3 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_x3) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_y3))))
&lt;&#x2F;span&gt;&lt;span&gt;              T (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; T1 T2 T3)
&lt;&#x2F;span&gt;&lt;span&gt;              V1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m_1 g y_1)
&lt;&#x2F;span&gt;&lt;span&gt;              V2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m_2 g y_2)
&lt;&#x2F;span&gt;&lt;span&gt;              V3 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m_3 g y_3)
&lt;&#x2F;span&gt;&lt;span&gt;              V (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; V1 V2 V3)]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; T V))))
&lt;&#x2F;span&gt;&lt;span&gt;           
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-twobar-linkage &lt;&#x2F;span&gt;&lt;span&gt;[m_1 m_2 m_3 g l_1 l_2]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q-prime]
&lt;&#x2F;span&gt;&lt;span&gt;          ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-const-accel-three-bodies&lt;&#x2F;span&gt;&lt;span&gt; m_1 m_2 m_3 g) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F-&amp;gt;C &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;twobar-linkage-&amp;gt;rect&lt;&#x2F;span&gt;&lt;span&gt; l_1 l_2)))
&lt;&#x2F;span&gt;&lt;span&gt;           q-prime)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-twobar-linkage  
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-twobar-linkage &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_1 &amp;#39;m_2 &amp;#39;m_3 &amp;#39;g &amp;#39;l_1 &amp;#39;l_2)]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations&lt;&#x2F;span&gt;&lt;span&gt; L)
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta_1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta_3))]
&lt;&#x2F;span&gt;&lt;span&gt;     ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-twobar-linkage&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{- l_1\,m_1\,\cos\left({\theta}_1\left(t\right)\right)\,{\left(D{\theta}_1\left(t\right)\right)}^{2} - l_2\,m_3\,\cos\left({\theta}_3\left(t\right)\right)\,{\left(D{\theta}_3\left(t\right)\right)}^{2} - l_1\,m_1\,\sin\left({\theta}_1\left(t\right)\right)\,{D}^{2}{\theta}_1\left(t\right) - l_2\,m_3\,\sin\left({\theta}_3\left(t\right)\right)\,{D}^{2}{\theta}_3\left(t\right) + m_1\,{D}^{2}x\left(t\right) + m_2\,{D}^{2}x\left(t\right) + m_3\,{D}^{2}x\left(t\right)} \cr \cr \displaystyle{- l_1\,m_1\,{\left(D{\theta}_1\left(t\right)\right)}^{2}\,\sin\left({\theta}_1\left(t\right)\right) - l_2\,m_3\,{\left(D{\theta}_3\left(t\right)\right)}^{2}\,\sin\left({\theta}_3\left(t\right)\right) + l_1\,m_1\,\cos\left({\theta}_1\left(t\right)\right)\,{D}^{2}{\theta}_1\left(t\right) + l_2\,m_3\,\cos\left({\theta}_3\left(t\right)\right)\,{D}^{2}{\theta}_3\left(t\right) + g\,m_1 + g\,m_2 + g\,m_3 + m_1\,{D}^{2}y\left(t\right) + m_2\,{D}^{2}y\left(t\right) + m_3\,{D}^{2}y\left(t\right)} \cr \cr \displaystyle{g\,l_1\,m_1\,\cos\left({\theta}_1\left(t\right)\right) + {l_1}^{2}\,m_1\,{D}^{2}{\theta}_1\left(t\right) + l_1\,m_1\,\cos\left({\theta}_1\left(t\right)\right)\,{D}^{2}y\left(t\right) - l_1\,m_1\,\sin\left({\theta}_1\left(t\right)\right)\,{D}^{2}x\left(t\right)} \cr \cr \displaystyle{g\,l_2\,m_3\,\cos\left({\theta}_3\left(t\right)\right) + {l_2}^{2}\,m_3\,{D}^{2}{\theta}_3\left(t\right) + l_2\,m_3\,\cos\left({\theta}_3\left(t\right)\right)\,{D}^{2}y\left(t\right) - l_2\,m_3\,\sin\left({\theta}_3\left(t\right)\right)\,{D}^{2}x\left(t\right)}\end{pmatrix}
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.20: Sliding pendulum</title>
        <published>2022-10-31T01:02:50+00:00</published>
        <updated>2022-10-31T01:02:50+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-20/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-20/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-20/">&lt;hr &#x2F;&gt;
&lt;h3 id=&quot;exercise-1-20-sliding-pendulum&quot;&gt;Exercise 1.20: Sliding pendulum&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Consider a pendulum of length $l$ attached to a support that is free to move horizontally, as shown in the figure. Let the mass of the support be $m_1$ and the mass of the pendulum bob be $m_2$. Formulate a Lagrangian and derive Lagrange’s equations for this system.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;projects&#x2F;sicm-workbook&#x2F;figure-1.4.jpg&quot; alt=&quot;Figure 1.4&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 1.4&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Consider the two bodies with their rectangular coordinates:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
x_1 &amp;amp;= x \\
y_1 &amp;amp;= y \\
x_2 &amp;amp;= x + l\cos{\theta} \\
y_2 &amp;amp;= y + l\sin{\theta} \\
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Use coordinate transform along with a constant-acceleration lagrangian for two particles to compute the equations for the system&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;sliding-pend-&amp;gt;rect &lt;&#x2F;span&gt;&lt;span&gt;[l]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ [x y theta] _]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x
&lt;&#x2F;span&gt;&lt;span&gt;            y
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; l (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta)))
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; l (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta)))
&lt;&#x2F;span&gt;&lt;span&gt;        )))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-const-accel-two-bodies &lt;&#x2F;span&gt;&lt;span&gt;[m_1 m_2 g]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_  [x_1 y_1 x_2 y_2] [v_x1 v_y1 v_x2 v_y2]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[T1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m_1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_x1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_y1))))
&lt;&#x2F;span&gt;&lt;span&gt;              T2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m_2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_x2) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v_y2))))
&lt;&#x2F;span&gt;&lt;span&gt;              T (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; T1 T2)
&lt;&#x2F;span&gt;&lt;span&gt;              V1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m_1 g y_1)
&lt;&#x2F;span&gt;&lt;span&gt;              V2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m_2 g y_2)
&lt;&#x2F;span&gt;&lt;span&gt;              V (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; V1 V2)]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; T V))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-sliding-pend &lt;&#x2F;span&gt;&lt;span&gt;[m_1 m_2 g l]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q-prime]
&lt;&#x2F;span&gt;&lt;span&gt;          ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-const-accel-two-bodies&lt;&#x2F;span&gt;&lt;span&gt; m_1 m_2 g) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F-&amp;gt;C &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sliding-pend-&amp;gt;rect&lt;&#x2F;span&gt;&lt;span&gt; l)))
&lt;&#x2F;span&gt;&lt;span&gt;           q-prime)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-sliding-pend 
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-sliding-pend &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_1 &amp;#39;m_2 &amp;#39;g &amp;#39;l)]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations&lt;&#x2F;span&gt;&lt;span&gt; L)
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta))]
&lt;&#x2F;span&gt;&lt;span&gt;     ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-sliding-pend&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{- l\,m_2\,\cos\left(\theta\left(t\right)\right)\,{\left(D\theta\left(t\right)\right)}^{2} - l\,m_2\,\sin\left(\theta\left(t\right)\right)\,{D}^{2}\theta\left(t\right) + m_1\,{D}^{2}x\left(t\right) + m_2\,{D}^{2}x\left(t\right)} \cr \cr \displaystyle{- l\,m_2\,{\left(D\theta\left(t\right)\right)}^{2}\,\sin\left(\theta\left(t\right)\right) + l\,m_2\,\cos\left(\theta\left(t\right)\right)\,{D}^{2}\theta\left(t\right) + g\,m_1 + g\,m_2 + m_1\,{D}^{2}y\left(t\right) + m_2\,{D}^{2}y\left(t\right)} \cr \cr \displaystyle{g\,l\,m_2\,\cos\left(\theta\left(t\right)\right) + {l}^{2}\,m_2\,{D}^{2}\theta\left(t\right) + l\,m_2\,\cos\left(\theta\left(t\right)\right)\,{D}^{2}y\left(t\right) - l\,m_2\,\sin\left(\theta\left(t\right)\right)\,{D}^{2}x\left(t\right)}\end{pmatrix}
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.18: Bead on a triaxial surface</title>
        <published>2022-10-31T01:02:48+00:00</published>
        <updated>2022-10-31T01:02:48+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-18/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-18/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-18/">&lt;h3 id=&quot;exercise-1-18-bead-on-a-triaxial-surface&quot;&gt;Exercise 1.18: Bead on a triaxial surface&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;A bead of mass $m$ moves without friction on a triaxial ellipsoidal surface. In rectangular coordinates the surface satisfies&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} = 1
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;for some constants $a$, $b$, and $c$. Identify suitable generalized coordinates, formulate a Lagrangian, and find Lagrange’s equations.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The parameteric equations for an ellipsoid are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
x &amp;amp;= a\sin{\theta}\cos{\varphi} \\
y &amp;amp;= b\sin{\theta}\sin{\varphi} \\
z &amp;amp;= c\cos{\theta}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-free-particle &lt;&#x2F;span&gt;&lt;span&gt;[mass]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ _ v]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; mass (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;dot-product&lt;&#x2F;span&gt;&lt;span&gt; v v)))   
&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;elliptical-&amp;gt;rect &lt;&#x2F;span&gt;&lt;span&gt;[a b c]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ [theta phi] _]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; a (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; b (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; c (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; ;; L&amp;#39; = L . C
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-ellipsoid &lt;&#x2F;span&gt;&lt;span&gt;[m a b c]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q-prime]
&lt;&#x2F;span&gt;&lt;span&gt;          ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-free-particle&lt;&#x2F;span&gt;&lt;span&gt; m) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F-&amp;gt;C &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;elliptical-&amp;gt;rect&lt;&#x2F;span&gt;&lt;span&gt; a b c)))
&lt;&#x2F;span&gt;&lt;span&gt;           q-prime)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-ellipsoid  
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-ellipsoid &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;a &amp;#39;b &amp;#39;c)]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations&lt;&#x2F;span&gt;&lt;span&gt; L)
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;varphi))]
&lt;&#x2F;span&gt;&lt;span&gt;     ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-ellipsoid&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{- {a}^{2}\,m\,{\cos}^{2}\left(\varphi\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,{\left(D\theta\left(t\right)\right)}^{2}\,\sin\left(\theta\left(t\right)\right) - {a}^{2}\,m\,{\cos}^{2}\left(\varphi\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,\sin\left(\theta\left(t\right)\right)\,{\left(D\varphi\left(t\right)\right)}^{2} -2\,{a}^{2}\,m\,\cos\left(\varphi\left(t\right)\right)\,{\cos}^{2}\left(\theta\left(t\right)\right)\,D\theta\left(t\right)\,D\varphi\left(t\right)\,\sin\left(\varphi\left(t\right)\right) + 2\,{b}^{2}\,m\,\cos\left(\varphi\left(t\right)\right)\,{\cos}^{2}\left(\theta\left(t\right)\right)\,D\theta\left(t\right)\,D\varphi\left(t\right)\,\sin\left(\varphi\left(t\right)\right) - {b}^{2}\,m\,\cos\left(\theta\left(t\right)\right)\,{\left(D\theta\left(t\right)\right)}^{2}\,\sin\left(\theta\left(t\right)\right)\,{\sin}^{2}\left(\varphi\left(t\right)\right) - {b}^{2}\,m\,\cos\left(\theta\left(t\right)\right)\,\sin\left(\theta\left(t\right)\right)\,{\left(D\varphi\left(t\right)\right)}^{2}\,{\sin}^{2}\left(\varphi\left(t\right)\right) + {a}^{2}\,m\,{\cos}^{2}\left(\varphi\left(t\right)\right)\,{\cos}^{2}\left(\theta\left(t\right)\right)\,{D}^{2}\theta\left(t\right) - {a}^{2}\,m\,\cos\left(\varphi\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,\sin\left(\theta\left(t\right)\right)\,\sin\left(\varphi\left(t\right)\right)\,{D}^{2}\varphi\left(t\right) + {b}^{2}\,m\,\cos\left(\varphi\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,\sin\left(\theta\left(t\right)\right)\,\sin\left(\varphi\left(t\right)\right)\,{D}^{2}\varphi\left(t\right) + {b}^{2}\,m\,{\cos}^{2}\left(\theta\left(t\right)\right)\,{\sin}^{2}\left(\varphi\left(t\right)\right)\,{D}^{2}\theta\left(t\right) + {c}^{2}\,m\,\cos\left(\theta\left(t\right)\right)\,{\left(D\theta\left(t\right)\right)}^{2}\,\sin\left(\theta\left(t\right)\right) + {c}^{2}\,m\,{\sin}^{2}\left(\theta\left(t\right)\right)\,{D}^{2}\theta\left(t\right)} \cr \cr \displaystyle{{a}^{2}\,m\,\cos\left(\varphi\left(t\right)\right)\,{\left(D\theta\left(t\right)\right)}^{2}\,{\sin}^{2}\left(\theta\left(t\right)\right)\,\sin\left(\varphi\left(t\right)\right) + {a}^{2}\,m\,\cos\left(\varphi\left(t\right)\right)\,{\sin}^{2}\left(\theta\left(t\right)\right)\,{\left(D\varphi\left(t\right)\right)}^{2}\,\sin\left(\varphi\left(t\right)\right) + 2\,{a}^{2}\,m\,\cos\left(\theta\left(t\right)\right)\,D\theta\left(t\right)\,\sin\left(\theta\left(t\right)\right)\,D\varphi\left(t\right)\,{\sin}^{2}\left(\varphi\left(t\right)\right) + 2\,{b}^{2}\,m\,{\cos}^{2}\left(\varphi\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,D\theta\left(t\right)\,\sin\left(\theta\left(t\right)\right)\,D\varphi\left(t\right) - {b}^{2}\,m\,\cos\left(\varphi\left(t\right)\right)\,{\left(D\theta\left(t\right)\right)}^{2}\,{\sin}^{2}\left(\theta\left(t\right)\right)\,\sin\left(\varphi\left(t\right)\right) - {b}^{2}\,m\,\cos\left(\varphi\left(t\right)\right)\,{\sin}^{2}\left(\theta\left(t\right)\right)\,{\left(D\varphi\left(t\right)\right)}^{2}\,\sin\left(\varphi\left(t\right)\right) - {a}^{2}\,m\,\cos\left(\varphi\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,\sin\left(\theta\left(t\right)\right)\,\sin\left(\varphi\left(t\right)\right)\,{D}^{2}\theta\left(t\right) + {a}^{2}\,m\,{\sin}^{2}\left(\theta\left(t\right)\right)\,{\sin}^{2}\left(\varphi\left(t\right)\right)\,{D}^{2}\varphi\left(t\right) + {b}^{2}\,m\,{\cos}^{2}\left(\varphi\left(t\right)\right)\,{\sin}^{2}\left(\theta\left(t\right)\right)\,{D}^{2}\varphi\left(t\right) + {b}^{2}\,m\,\cos\left(\varphi\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,\sin\left(\theta\left(t\right)\right)\,\sin\left(\varphi\left(t\right)\right)\,{D}^{2}\theta\left(t\right)}\end{pmatrix}
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.40: Bead on a triaxial surface (incomplete)</title>
        <published>2022-10-31T00:25:47+00:00</published>
        <updated>2022-10-31T00:25:47+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-40/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-40/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-40/">&lt;h3 id=&quot;exercise-1-40-bead-on-a-triaxial-surface&quot;&gt;Exercise 1.40: Bead on a triaxial surface&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Consider again the motion of a bead constrained to move on a triaxial surface (exercise 1.18). Reformulate this using rectangular coordinates as the generalized coordinates with an explicit constraint that the bead must stay on the surface. Find a Lagrangian and show that the Lagrange equations are equivalent to those found in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tgvaughan.github.io&#x2F;sicm&#x2F;chapter001.html#Exe_1-18&quot;&gt;exercise 1.18&lt;&#x2F;a&gt; (&lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;sicm-exercise-1-18&#x2F;&quot;&gt;solution&lt;&#x2F;a&gt;).&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We model the system as a point mass constrained to stay on a triaxial surface using the following coordinate constraint:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\varphi(t; x,y,z; \dot{x},\dot{y},\dot{z}) = \frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} - 1 = 0
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $a$, $b$ and $c$ are parameters defining the surface. The augmented Lagrangian is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L&amp;#x27; = \frac{1}{2} m \dot{x}^2 + \lambda \left(\frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} - 1\right)
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-free-particle &lt;&#x2F;span&gt;&lt;span&gt;[mass]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ _ v]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; mass (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;dot-product&lt;&#x2F;span&gt;&lt;span&gt; v v)))   
&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;ellipsoid-constraint &lt;&#x2F;span&gt;&lt;span&gt;[a b c]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ [x y z] _]] 
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; a)) 
&lt;&#x2F;span&gt;&lt;span&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; b))
&lt;&#x2F;span&gt;&lt;span&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; z) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; c))) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;Augment-Lagrangian &lt;&#x2F;span&gt;&lt;span&gt;[L lambda phi]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; lambda phi)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-bead-on-ellipsoid &lt;&#x2F;span&gt;&lt;span&gt;[m a b c]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[t [x y z lambda] [xdot ydot zdot lambdadot]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-free-particle&lt;&#x2F;span&gt;&lt;span&gt; m)
&lt;&#x2F;span&gt;&lt;span&gt;              phi (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;ellipsoid-constraint&lt;&#x2F;span&gt;&lt;span&gt; a b c)
&lt;&#x2F;span&gt;&lt;span&gt;              q (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x y z) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; xdot ydot zdot))]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L&lt;&#x2F;span&gt;&lt;span&gt; q) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; lambda (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;phi&lt;&#x2F;span&gt;&lt;span&gt; q))))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;#&amp;#39;user&#x2F;L-bead-on-ellipsoid
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-system 
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-bead-on-ellipsoid &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;a &amp;#39;b &amp;#39;c)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eqs-system &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;z) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;lambda))]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-system&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec&lt;&#x2F;span&gt;&lt;span&gt; eqs-system)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{\frac{{a}^{2}\,m\,{D}^{2}x\left(t\right) -2\,x\left(t\right)\,\lambda\left(t\right)}{{a}^{2}}} \cr \cr \displaystyle{\frac{{b}^{2}\,m\,{D}^{2}y\left(t\right) -2\,y\left(t\right)\,\lambda\left(t\right)}{{b}^{2}}} \cr \cr \displaystyle{\frac{{c}^{2}\,m\,{D}^{2}z\left(t\right) -2\,z\left(t\right)\,\lambda\left(t\right)}{{c}^{2}}} \cr \cr \displaystyle{\frac{{a}^{2}\,{b}^{2}\,{c}^{2} - {a}^{2}\,{b}^{2}\,{\left(z\left(t\right)\right)}^{2} - {a}^{2}\,{c}^{2}\,{\left(y\left(t\right)\right)}^{2} - {b}^{2}\,{c}^{2}\,{\left(x\left(t\right)\right)}^{2}}{{a}^{2}\,{b}^{2}\,{c}^{2}}}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;We can eliminate one of the coordinate as the system only has two degrees of freedom. First lets define some terminology:&lt;&#x2F;p&gt;
&lt;p&gt;$$\require{cancel}$$&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
K_1 &amp;amp;= \frac{a^2}{c^2}, K_2 = \frac{a^2}{b^2}\\
D^2(x(t)) &amp;amp;= \ddot{x}, D^2 y(t) = \ddot{y}, D^2 z(t) = \ddot{z}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;From the constraint,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
a^2 x &amp;amp;= a^2 b^2 c^2 - a^2 b^2 z - a^2 c^2 y \\
x &amp;amp;= \frac{a^2 b^2 c^2 - a^2 b^2 z - a^2 c^2 y}{b^2 c^2} \\
x &amp;amp;= a^2 - K_1 z - K_2 y
\\
=&amp;gt; \dot{x} &amp;amp;= - K_1 \dot{z} - K_2 \dot{y} \\
=&amp;gt; \ddot{x} &amp;amp;= -K_1 (\ddot{z}z + \dot{z}^2) -K_2 (\ddot{y}y + \dot{y}^2)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;From the first equation,&lt;&#x2F;p&gt;
&lt;p&gt;$\lambda = \frac{m a^2 \ddot{x}}{x}$&lt;&#x2F;p&gt;
&lt;p&gt;Substituting $\lambda$ into the second equation, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
b^2 \cancel{m} \ddot{y} &amp;amp;=  2 y \frac{\cancel{m} a^2 \ddot{x}}{x} \\
=&amp;gt; \ddot{y} &amp;amp;= 2 y \frac{a^2}{b^2} \left(\frac{-K_1 (\ddot{z}z + \dot{z}^2) -K_2 (\ddot{y}y + \dot{y}^2)}{a^2 - K_1 z - K_2 y}\right)\\
=&amp;gt; \ddot{y} &amp;amp;= - 2 y K_2 \frac{K_1 (\ddot{z}z + \dot{z}^2) + K_2 (\ddot{y}y + \dot{y}^2)}{a^2 - K_1 z - K_2 y}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Substituting $\lambda$ into the third equation, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
c^2 \cancel{m} \ddot{z} &amp;amp;=  2 y \frac{\cancel{m} a^2 \ddot{x}}{x} \\
=&amp;gt; \ddot{z} &amp;amp;= 2 z \frac{a^2}{c^2} \left(\frac{-K_1 (\ddot{z}z + \dot{z}^2) -K_2 (\ddot{y}y + \dot{y}^2)}{a^2 - K_1 z - K_2 y}\right)\\
=&amp;gt; \ddot{z} &amp;amp;= - 2 z K_1 \frac{K_1 (\ddot{z}z + \dot{z}^2) + K_2 (\ddot{y}y + \dot{y}^2)}{a^2 - K_1 z - K_2 y}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 2.1: Rotational Kinetic Energy</title>
        <published>2022-10-30T04:42:17+00:00</published>
        <updated>2022-10-30T04:42:17+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-2-1-rotational-kinetic-energy/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-2-1-rotational-kinetic-energy/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-2-1-rotational-kinetic-energy/">&lt;h2 id=&quot;2-rigid-bodies&quot;&gt;2 Rigid Bodies&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The polhode rolls without slipping on the herpolhode lying in the invariable plane.&lt;&#x2F;p&gt;
&lt;p&gt;Herbert Goldstein, &lt;em&gt;Classical Mechanics&lt;&#x2F;em&gt;, footnote, p. 207.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A rotating top - an axisymmetric body subject to gravity, with a point on the axis of symmetry that is fixed in space&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The axis of the top precesses about the vertical, apparently moving perpendicular to the direction in which gravity is pulling it&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Book thrown into the air - has two stable configurations about longest and shortest axes. Starts tumbling when rotated about intermediate axis&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The Moon always points the same face towards the Earth regardless of the interactions with the Sun and other planets&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A rigid body can be thought to consist of a large number of constituent particles with rigid constraints among them. While the dynamics are the same as any other rigidly constrained system, new tools are needed as the number of particles&#x2F;constraints are very high.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We need to define the kinetic and potential energies to define the Lagrangian for a system&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The strategy is to first rewrite the kinetic and potential energies in terms of quantities that characterize essential aspects of the distribution of mass in the body and the state of motion of the body&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For rotational kinetic energy, a small number of parameters completely specify the state of motion and the relevant aspects of the distribution of mass in the body&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For potential energy, some specific problems the potential energy can be represented with a small number of parameters, but in general we have to make approximations to obtain a representation with a manageable number of parameters&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;2-1-rotational-kinetic-energy&quot;&gt;2.1 Rotational Kinetic Energy&lt;&#x2F;h2&gt;
&lt;p&gt;A rigid body can be considered to consist of a large number of particles with mass $m_\alpha$, $\vec{x_\alpha}$, and velocities $\dot{\vec{x}}_\alpha$ with positional constraints between them. The kinetic energy is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\sum_{\alpha} \frac{1}{2} m_\alpha\dot{\vec{x}}_\alpha \cdot \dot{\vec{x}}_\alpha\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The configuration of a rigid body is fully specified by the position of &lt;em&gt;any&lt;&#x2F;em&gt; point inthe body and the orientation of the body. Therefore, we define the position vectors based on a reference point on the body $X$. The position of each particle relative to the reference point can be represented by $\xi_\alpha$:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\vec{x}_\alpha = \vec{X} + \vec{\xi}_\alpha\tag{2.2}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The corresponding velocities are given by:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\dot{\vec{x}}_\alpha = \dot{\vec{X}} + \dot{\vec{\xi}}_\alpha\tag{2.3}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The kinetic energy of the body can be rewritten as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\sum_{\alpha} \frac{1}{2} &amp;amp; m_\alpha  (\vec{X} + \vec{\xi}_\alpha) \cdot (\vec{X} + \vec{\xi}_\alpha) \\
        &amp;amp;= \sum_{\alpha} \frac{1}{2} m_\alpha  (\vec{X} \cdot \vec{X} + \vec{X} \cdot \vec{\xi}_\alpha  + \vec{\xi}_\alpha\cdot\vec{\xi}_\alpha)\tag{2.4}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;If we choose the center of mass of the body as the reference point,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\vec{X} = \frac{1}{M}  \sum_{\alpha} m_\alpha\vec{x}_\alpha\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $M = \sum_\alpha m_\alpha$ is the total mass of the body, then&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\sum_{\alpha} m_\alpha\vec{\xi_\alpha} = \sum_\alpha m_\alpha (\vec{x}_\alpha - \vec{X})\tag{2.6}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Taking the derivative of this, we can see that the relative velocities satisfy $\sum_\alpha m_\alpha \dot{\xi}_\alpha = 0$. So the kinetic energy is equal to:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
T &amp;amp;= \frac{1}{2} \left(\sum_{\alpha} m_\alpha \dot{\vec{X}} \cdot \dot{\vec{X}} + \sum_{\alpha} m_\alpha \dot{\vec{X}} \cdot \vec{\xi}_\alpha  + \sum_{\alpha} m_\alpha \dot{\vec{\xi}}_\alpha\cdot\dot{\vec{\xi}}_\alpha\right) \\
  &amp;amp;= \frac{1}{2} \left(\sum_{\alpha} m_\alpha \dot{\vec{X}} \cdot \dot{\vec{X}} + \dot{\vec{X}} \sum_{\alpha} \underbrace{m_\alpha \dot{\vec{\xi}}_\alpha}_{= 0} + \sum_{\alpha} m_\alpha \dot{\vec{\xi}}_\alpha\cdot\dot{\vec{\xi}}_\alpha\right)\\
  &amp;amp;= \frac{1}{2} \sum_{\alpha} m_\alpha \dot{\vec{X}} \cdot \dot{\vec{X}} + \frac{1}{2} \sum_{\alpha} m_\alpha \dot{\vec{\xi}}_\alpha \cdot \dot{\vec{\xi}}_\alpha\tag{2.8}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This shows that kinetic energy of the rigid body can be separated into two pieces. The translational kinetic energy is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\frac{1}{2} \sum_{\alpha} m_\alpha \dot{\vec{X}} \cdot \dot{\vec{X}}\tag{2.9}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The rotational kinetic energy is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\frac{1}{2} \sum_{\alpha} m_\alpha \dot{\vec{\xi}}_\alpha \cdot \dot{\vec{\xi}}_\alpha\tag{2.10}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;When written in appropriate generalized coordinates, the kinetic energy is a Lagrangian for a free rigid body. Choosing generalized coordinates such that the coordinates specifying the position of the center of mass is separate from those specifying the orientation, then the Lagrange equations completely decouple. This makes the dynamics of translation decoupled from that of translation.&lt;&#x2F;p&gt;
&lt;p&gt;However, this is not true in the general case once potential energies are included in the system. So the motion of the center of mass and the rigid body may be coupled through the potential energy. However, in some specific cases, such as for example, a rigid body moving in a uniform gravitational field, the equations may decouple.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.39: Combining Lagrangians</title>
        <published>2022-10-30T00:29:36+00:00</published>
        <updated>2022-10-30T00:29:36+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-39/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-39/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-39/">&lt;h3 id=&quot;exercise-1-39-combining-lagrangians&quot;&gt;Exercise 1.39: Combining Lagrangians&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;a. Make another primitive component, compatible with the spring-mass structures described in &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-1.10.1-coordinate-constraints#building-systems-from-parts&quot;&gt;this section&lt;&#x2F;a&gt;. For example, make a pendulum that can attach to the spring-mass system. Build a combination and derive the equations of motion. Be careful, the algebra is horrible if you choose bad coordinates.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Assume that the springs only move horizontally and are not affected by gravity
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;LspringmassA &lt;&#x2F;span&gt;&lt;span&gt;[m_1 k_1]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L1 &lt;&#x2F;span&gt;&lt;span&gt;[[_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[x_1]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[xdot_1]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m_1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; xdot_1)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; k_1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; x_1)))
&lt;&#x2F;span&gt;&lt;span&gt;    ))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;LspringmassB &lt;&#x2F;span&gt;&lt;span&gt;[m_2 k_2]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L2 &lt;&#x2F;span&gt;&lt;span&gt;[[_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[x_2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; xi]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[xdot_2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; xidot]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m_2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; xdot_2 xidot))) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; k_2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; x_2)))
&lt;&#x2F;span&gt;&lt;span&gt;    ))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; pendulum is attached at the end of the second spring-mass
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; x_3 defines the attachment point and is constrained to be equal to
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; X_1 + X_2 + x_1 + x_2
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-pendulum &lt;&#x2F;span&gt;&lt;span&gt;[m l g]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L3 &lt;&#x2F;span&gt;&lt;span&gt;[[_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[x_3 theta]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[x3_dot thetadot]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; l) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; thetadot)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; x3_dot))) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m g l (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta)))
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-system &lt;&#x2F;span&gt;&lt;span&gt;[m_1 m_2 m_3 k_1 k_2 l g]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L &lt;&#x2F;span&gt;&lt;span&gt;[[t&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[x_1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x_2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x_3&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; xi&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; theta&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt;lambda_1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt;lambda_2]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[xdot_1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; xdot_2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; xdot_3&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; xidot&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; thetadot&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; lambdadot1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; lambdadot2]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;LspringmassA&lt;&#x2F;span&gt;&lt;span&gt; m_1 k_1)
&lt;&#x2F;span&gt;&lt;span&gt;              L2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;LspringmassB&lt;&#x2F;span&gt;&lt;span&gt; m_2 k_2)
&lt;&#x2F;span&gt;&lt;span&gt;              L3 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-pendulum&lt;&#x2F;span&gt;&lt;span&gt; m_3 l g)
&lt;&#x2F;span&gt;&lt;span&gt;              phi1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; xi (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;X_1 x_1)) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; linking two spring-mass systems
&lt;&#x2F;span&gt;&lt;span&gt;              phi2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; x_3 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;X_1 x_1 &amp;#39;X_2 x_2)) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; connecting pendulum to second spring-mass
&lt;&#x2F;span&gt;&lt;span&gt;              ]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L1 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x_1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;down&lt;&#x2F;span&gt;&lt;span&gt; xdot_1)))
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L2 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x_2 xi) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; xdot_2 xidot)))
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L3 &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x_3 theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; xdot_3 thetadot)))
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; lambda_1 phi1)
&lt;&#x2F;span&gt;&lt;span&gt;               (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; lambda_2 phi2)
&lt;&#x2F;span&gt;&lt;span&gt;            )
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_2) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_3) 
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;xi) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) 
&lt;&#x2F;span&gt;&lt;span&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;lambda_1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;lambda_2))
&lt;&#x2F;span&gt;&lt;span&gt;       local ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)]
&lt;&#x2F;span&gt;&lt;span&gt;    ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-system &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_1 &amp;#39;m_2 &amp;#39;m_3 &amp;#39;k_1 &amp;#39;k_2 &amp;#39;l &amp;#39;g) local)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
{l}^{2}\,m_3\,{\left(D\theta\left(t\right)\right)}^{2} + g\,l\,m_3\,\cos\left(\theta\left(t\right)\right) + \frac{-1}{2}\,k_1\,{\left(x_1\left(t\right)\right)}^{2} + \frac{-1}{2}\,k_2\,{\left(x_2\left(t\right)\right)}^{2} + \frac{1}{2}\,m_1\,{\left(Dx_1\left(t\right)\right)}^{2} + \frac{1}{2}\,m_2\,{\left(Dx_2\left(t\right)\right)}^{2} + m_2\,Dx_2\left(t\right)\,D\xi\left(t\right) + \frac{1}{2}\,m_2\,{\left(D\xi\left(t\right)\right)}^{2} + m_3\,{\left(Dx_3\left(t\right)\right)}^{2} - X_1\,{\lambda}_1\left(t\right) - X_1\,{\lambda}_2\left(t\right) - X_2\,{\lambda}_2\left(t\right) - x_2\left(t\right)\,{\lambda}_2\left(t\right) - x_1\left(t\right)\,{\lambda}_1\left(t\right) - x_1\left(t\right)\,{\lambda}_2\left(t\right) + {\lambda}_1\left(t\right)\,\xi\left(t\right) + {\lambda}_2\left(t\right)\,x_3\left(t\right)
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-system 
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-system &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_1 &amp;#39;m_2 &amp;#39;m_3 &amp;#39;k_1 &amp;#39;k_2 &amp;#39;l &amp;#39;g)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_2) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_3) 
&lt;&#x2F;span&gt;&lt;span&gt;                         (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;xi) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) 
&lt;&#x2F;span&gt;&lt;span&gt;                         (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;lambda_1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;lambda_2))]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-system&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{k_1\,x_1\left(t\right) + m_1\,{D}^{2}x_1\left(t\right) + {\lambda}_1\left(t\right) + {\lambda}_2\left(t\right)} \cr \cr \displaystyle{k_2\,x_2\left(t\right) + m_2\,{D}^{2}x_2\left(t\right) + m_2\,{D}^{2}\xi\left(t\right) + {\lambda}_2\left(t\right)} \cr \cr \displaystyle{2\,m_3\,{D}^{2}x_3\left(t\right) - {\lambda}_2\left(t\right)} \cr \cr \displaystyle{m_2\,{D}^{2}x_2\left(t\right) + m_2\,{D}^{2}\xi\left(t\right) - {\lambda}_1\left(t\right)} \cr \cr \displaystyle{g\,l\,m_3\,\sin\left(\theta\left(t\right)\right) + 2\,{l}^{2}\,m_3\,{D}^{2}\theta\left(t\right)} \cr \cr \displaystyle{X_1 + x_1\left(t\right) - \xi\left(t\right)} \cr \cr \displaystyle{X_1 + X_2 + x_2\left(t\right) + x_1\left(t\right) - x_3\left(t\right)}\end{pmatrix}
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 1.11: Summary</title>
        <published>2022-10-29T21:22:55+00:00</published>
        <updated>2022-10-29T21:22:55+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-1-11-summary/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-1-11-summary/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-1-11-summary/">&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;This chapter was primarily introducing the Lagrangian method of analyzing mechanical systems. Here are some of the key points:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;To start with, we need to distinguish between realizable motions and other possible motions of the system. This is achieved using the “action function”, which is constructed to be stationary only on paths that describe realizable motions, with respect to variations in the path. This is called the &lt;em&gt;principle of stationary action&lt;&#x2F;em&gt; or &lt;em&gt;principle of least action&lt;&#x2F;em&gt; and is the foundation of classical mechanics (and apparently electrodynamics, quantum mechanics and general relativity). The stationary action principle is a coordinate-independent description of realizable paths. Regardless of if the system has constraints, we may choose any system of coordinates that uniquely determines the configuration of the system.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An action is defined as the integral of a function, &lt;em&gt;the Lagrangian&lt;&#x2F;em&gt; along a path. For many mechanical systems, the appropriate choice for a Lagrangian is the difference between the kinetic energy and potential energy of the system. This is not unique and there may be many choices of valid Lagrangians for a given system.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;By applying the Euler-Lagrange operator to the Lagrangian, we can derive a set of ordinary differential equations called the &lt;em&gt;Lagrange equations&lt;&#x2F;em&gt; that describes the motion of the system. Any realizable path saisfies these &lt;em&gt;equations of motion&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We can add a “total-time derivative” to a Lagrangian without affecting the Lagrange equations of system&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The entire time-history of a system can be simulated from a starting point with an initial state (which usually consists of the coordinates and the rate of change of the coordinates at the initial time) using these equations of motion&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If there are continuous symmetries in a system, there are conserved quantities associated with that system (&lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-1.8.5-noethers-theorem&quot;&gt;Noether’s theorem&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If the Lagrangian can be formulated such that the symmetries manifest as missing coordinates in the Lagrangian,  then there are conserved momenta that are “conjugate” to these coordinates&lt;&#x2F;li&gt;
&lt;li&gt;If the Lagrangian is independent of time then there is a conserved energy.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-1.10-constrained-motion&quot;&gt;Constraints&lt;&#x2F;a&gt; in a dynamic system can be either holonomic or non-holonomic&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The constraints can be added to the systems by augmenting the Lagrangian with the constraint function.&lt;&#x2F;li&gt;
&lt;li&gt;With Holonomic constraints, the “Lagrange multiplier” $\lambda$ and redundant coordinates can be eliminated from the system and the dynamic equations formulated in terms of just the coordinates and velocities.
&lt;ul&gt;
&lt;li&gt;Holonomic constraints are those which are either coordinate functions, or can be represented as coordinate functions (called integrable constraints)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Non-holonomic constraints have a velocity dependency and systems with these constraints do not currently have a general solution&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 1.10.3: Non-holonomic Constraints</title>
        <published>2022-10-29T20:57:43+00:00</published>
        <updated>2022-10-29T20:57:43+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-1-10-3-non-holonomic-systems/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-1-10-3-non-holonomic-systems/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-1-10-3-non-holonomic-systems/">&lt;h2 id=&quot;1-10-3-non-holonomic-systems&quot;&gt;1.10.3 Non-holonomic Systems&lt;&#x2F;h2&gt;
&lt;p&gt;Systems with constraints that are no integrable are called &lt;em&gt;non-holonomic systems&lt;&#x2F;em&gt;. A constraint is considered to be non-integrable if it cannot be written in terms of an equivalent coordinate constraint. One example of this is a ball rolling without slipping in a bowl, or any 2D surface. The ball may return to the same spot in the bowl, but its orientation when it gets there is entirely dependent on the path that it took to get there and may be completely different. So the constraint cannot be used to eliminate any coordinates.&lt;&#x2F;p&gt;
&lt;p&gt;There is no general solution for equations of motion governing nonholonomic systems. Her we can look at a restricted set of nonholonomic systems with constraints that are linear in velocities, i.e.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\psi(t, q, v) = G_1(t,q)v + G_0(t,q)\tag{1.230}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We assume that $\psi$ is not a total time derivative. Based on some of the references in the book, if $L$ is the Lagrangian for the unconstrained system, the equations of motions are asserted to be:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{E}[L] \circ \Gamma[q] = \lambda(G_1 \circ \Gamma[q]) = \lambda(\partial_2 \psi \circ \Gamma[q]) \tag{1.231}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;With $\psi = 0$, the system is completely specified and the evolution of its dynamics is defined. While Eq.1.231 is identical to Eq. 1.218 from the &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-1.10.2-derivative-constraints&quot;&gt;previous section&lt;&#x2F;a&gt;, the derivation does not apply here since the assumptions made there do not hold.&lt;&#x2F;p&gt;
&lt;p&gt;Eq. 1.185 in &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-1.10-constrained-motion&quot;&gt;Section 1.10&lt;&#x2F;a&gt; defines the condition that the variation $\eta$ must satisfy in order for it to be consistent with the velocity-dependent constraint function $\psi$. It is restated here:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
(\partial_1 \psi \circ \Gamma[q])\eta + (\partial_2 \psi \circ \Gamma[q])D\eta = 0\tag{1.185}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We can no longer eliminate $\eta$ by the logic used in Section 1.10.1, because $\eta$ is no longer orthogonal to $\partial_1 \psi \circ \Gamma[q]$ and we cannot rewrite the constraint as a coordinate constraint because it is not integrable by assumption.&lt;&#x2F;p&gt;
&lt;p&gt;The following derivation for of the nonholonomic equations is from Arnold et.al[6]. We define a “virtual velocity”, $\xi$ to be any velocity satisfying the following condition:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
(\partial_2 \psi \circ \Gamma[q])\xi = 0\tag{1.236}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The “principle of d’Alembert–Lagrange” states that:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
(\mathscr{E}[L] \psi \circ \Gamma[q])\xi = 0\tag{1.237}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;for any virtual velocity, $\xi$. This could also be restated as “any virtual velocity $\xi$ is orthogonal to $\mathscr{E}[L] \psi \circ \Gamma[q]$. We picked $\xi$ to be arbitrary except that it be orthogonal to $\partial_2 \psi \circ \Gamma[q]$. Therefore, $\partial_2 \psi \circ \Gamma[q]$ must be parallel to $\mathscr{E}[L] \psi \circ \Gamma[q]$. So,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{E}[L] \circ \Gamma[q] = \lambda(\partial_2 \psi \circ \Gamma[q]) \tag{1.238}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;which are the non-holonomic equations.&lt;&#x2F;p&gt;
&lt;p&gt;The basic idea at the end is that the nonholonomic equations do not follow from the action principle. To quote the book:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;It comes down to this: the nonholonomic equations do not follow from the action principle. They are something else. Whether they are correct or not depends on whether or not they agree with experiment.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;In the previous sections, we showed how for systems with coordinate constraints or derivative constraints, the Lagrange equations can be derived from a Lagrangian that is augmented with the constraint. However, if we apply the same technique with non-holonomic constraints, the Lagrange equations obtained are not the same as Eq. 1.238 (or 1.231). For example, consider the following augmented Lagrangian:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L[&amp;#x27;(t; q,\lambda; \dot{q},\dot{\lambda})=L(t,q,\dot{q})+\lambda\psi(t,q,\dot{q}) \tag{1.239}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The Lagrange equations associated with the coordinates are found to be:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
0 &amp;amp;= \mathscr{E}[L]\circ\Gamma[q] \\
  &amp;amp;\quad + D\lambda(\partial_2 \psi \circ \Gamma[q]) + \lambda D (\partial_2 \psi \circ \Gamma[q]) - \lambda(\partial_1 \psi \circ \Gamma[q]) \tag{1.240}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The Lagrange equation associated with tthe constraint is the constraint equation: $\psi\circ\Gamma[q] = 0$. The equations here involve both $\lambda$ and $D\lambda$. The usual state variables, $q$ and $Dq$ and the constraint are not enough to completely specify the initial conditions for the dynamic system. We need to specify an initial value for $\lambda$ as well (and possibly integrate it along with the states?). This reminds me of the Euler-Lagrange equations as applied to optimal control problems were we have a “costate” $\lambda$ that is integrated along with the states.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;In general, for any particular physical system, equations (1.231) and (1.240) are not the same, and in fact they have different solutions. It is not apparent that either set of equations accurately models the physical system.  The first approach to nonholonomic systems is not justified by extension of the arguments for the holonomic case and the other is not fully determined. Perhaps this indicates that the models are inadequate, that more details of how the constraints are maintained need to be specified.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;[6] V. I. Arnold, V. V. Kozlov, and A. I. Neishtadt, “Mathematical Aspects of Classical and Celestial Mechanics,” Dynamical Systems III, Springer Verlag, 1988.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 1.10.2: Derivative Constraints</title>
        <published>2022-10-29T19:41:05+00:00</published>
        <updated>2022-10-29T19:41:05+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-1-10-2-derivative-constraints/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-1-10-2-derivative-constraints/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-1-10-2-derivative-constraints/">&lt;h2 id=&quot;1-10-2-derivative-constraints&quot;&gt;1.10.2 Derivative Constraints&lt;&#x2F;h2&gt;
&lt;p&gt;In this section we look at a specific type of velocity-dependent constraints, which are “total-time derivatives” of a velocity independent function. The methods in &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;sicm-1.10.1-coordinate-constraints&quot;&gt;Section 1.10.1&lt;&#x2F;a&gt; do not apply here as the constraint is velocity-dependent.&lt;&#x2F;p&gt;
&lt;p&gt;Let this constraint $\psi = 0$ be a velocity-dependent constraint. If $\psi$ is a total-time derivative, this means that there exists some &lt;em&gt;velocity-independent&lt;&#x2F;em&gt; function, $\varphi$ such that:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\psi \circ \Gamma[q] = D(\varphi \circ \Gamma[q])
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Since $\varphi$ is velocity independant, $\partial_2 \varphi = 0$. The relationship between $\psi$ and $\varphi$ can be restated (as local-tuple functions) as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\psi = D_t \varphi = \partial_0 \varphi + \partial_1 \varphi \dot{Q}\tag{1.214}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We can find $\psi$ by solving this PDE. The constraint is defined as $\psi = 0$. This implies that $\varphi = K$ for some constant $K$. Conversely, if we know that $\varphi = K$, then $\psi = 0$ follows. &lt;strong&gt;Thus, the velocity-dependent constraint, $\psi = 0$ is equivalent to the velocity-independent constraint, $\varphi = K$&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If $L$ is the unconstrained Lagrangian, the Lagrange equations with the constraint $\varphi = K$ are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{E}[L] \circ \Gamma[q] + \lambda(\mathscr{E}[\varphi] \circ \Gamma[q]) = 0\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\lambda$ is a function of time that will be eliminated during the solution process. $K$ can be ignored here as $\lambda(\varphi - K)$ and $\lambda(\varphi)$ result in the same Lagrange equations. The function $\varphi$ is independent of velocity and $\partial_2 \varphi = 0$. So we can use the same techniques from Section 1.10.1 to get the Lagrange equations for the system as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{E}[L] \circ \Gamma[q] - \lambda(\partial_1 \varphi \circ \Gamma[q]) = 0\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;From Eq. 1.214, we can also infer that $\psi$ is the partial of $\varphi$ w.r.t velocity, or $\partial_2 \psi = \partial_1 \varphi$. Therefore, the Lagrange equations with the constraint $\psi = 0$ can also be written as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{E}[L] \circ \Gamma[q] - \lambda(\partial_2 \psi \circ \Gamma[q]) = 0\tag{1.218}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This is important because it shows that we can write the Lagrangian in terms of $\psi$ without having to compute $\varphi$, &lt;em&gt;as long as we can show that $\varphi$ exists&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We can also get the same result using the Augmetned Lagrangian technique. Consider the augmented Lagrangian below&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L&amp;#x27; = L + \lambda&amp;#x27; \psi\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The Lagrange equations for $L’$ are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{E}[L&amp;#x27;] \circ \Gamma[q] = -D\lambda (\partial_2 \varphi \circ \Gamma[q]) \tag{1.218}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $D\lambda’ = \lambda$. This shows that Eq. 1.218 and Eq. 1.219 are the same equations.&lt;&#x2F;p&gt;
&lt;p&gt;The technique defined in this section can be used for systems with constraints that can be written in terms of the derivative of a &lt;em&gt;velocity-independent constraint&lt;&#x2F;em&gt;. Such constraints are called &lt;em&gt;integrable constraints&lt;&#x2F;em&gt;. Any system where the constraints are coordinate constraints, or can be put in the form of a coordinate constraint are called &lt;strong&gt;holonomic constraints&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;goldstein-s-hoop&quot;&gt;Goldstein’s Hoop&lt;&#x2F;h3&gt;
&lt;p&gt;$$\require{cancel}$$&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;projects&#x2F;sicm-workbook&#x2F;figure-1.10.jpg&quot; alt=&quot;Figure 1.10&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 1.10: A massive hoop rolling, without slipping, down an inclined plane.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;“Goldstein’s hoop” is an example of a dynamic system with an integrable constraint: a hoop of mass $M$ and radius $R$ rolling down a one-dimensional inclined plane (Figure 1.10). This problem can be formulated in terms of two coordinates, $\varphi$, the angular displacement of an arbitrary point on the hoop from some arbitrary reference line, and $x$, the linear progress of the center of the hoop down the plane. The cojnstraint is that the hoop rolls without slipping, or in other words, the change is $\theta$ is directly reflected a change in $x$. The constraint function is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\psi(t; x,\theta; \dot{x},\dot{\varphi}) = R\dot{\theta} - \dot{x} = 0\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This constraint is represented as a relation between generalized velocities, which can be integrated to get $x = R\theta + c$. This integrated constraint is a velocity-independent constraint. The augmented Lagrangian can be formulated in terms of the original constraint or its derivative.&lt;&#x2F;p&gt;
&lt;p&gt;The kinetic energy consists of the energy of rotation of the hoop (described later in Chapter 2 as $\frac{1}{2}MR^2\dot{\theta}^2$) and the energy from the motion of its center of mass. The potential energy of the system decreses as the hoop proceeds down the slope. Thus the augmented Lagrangian is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L(t; x,\theta,\lambda; \dot{x},\dot{\theta},\dot{\lambda}) = \frac{1}{2}MR^2\dot{\theta}^2 + \frac{1}{2}M\dot{x}^2 - (-Mg x\sin\varphi) + \lambda(R\dot{\theta} - \dot{x})\tag{1.122}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Lagrange equations for this Lagrangian can be obtained as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
M D^2x - D\lambda &amp;amp;= Mg \sin\varphi \tag{1.223}\\
M R^2 D^2\theta + R D\lambda &amp;amp;= 0 \tag{1.224}\\
R D\theta - Dx &amp;amp;= 0 \tag{1.225}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Differentiating the third equation, we get&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
R D^2\theta = D^2 x\tag{1.226}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Multiplying Eq. 1.223 by R and adding with Rq. 1.224&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
0 &amp;amp;= M R D^2x - \cancel{RD\lambda} - M R g \sin\varphi
 + M R^2 D^2\theta + \cancel{R D\lambda} \\
 &amp;amp;= \cancel{M} \cancel{R} D^2x - \cancel{M} \cancel{R} g \sin\varphi + \cancel{M} R^\cancel{2} D^2\theta \\
 &amp;amp;= D^2x + R D^2\theta - g \sin\varphi \\
 &amp;amp;= 2 D^2x - g\sin\varphi \\
=&amp;gt; D^2x &amp;amp;= -\frac{1}{2}g\sin\varphi \tag{1.227}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This acceleration is just half of what the acceleration would have been for a point mass sliding down a frictionless inclied plane. Also notable is that the acceleration is independent of both $M$ and $R$. From the Lagrange equations, $D\lambda$ can be interepreted as the frictional force that is causing the hoop to roll instead of slide. Combining Eq. 1.223 and Eq. 1.227, this force can be found to be:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D\lambda = \frac{1}{2} Mg \sin\varphi\tag{1.228}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;and the angular acceleration $D^2\theta$ is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
-\frac{1}{2}\frac{g}{R}\sin\varphi\tag{1.229}
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 1.10.1: Coordinate Constraints</title>
        <published>2022-10-29T07:27:33+00:00</published>
        <updated>2022-10-29T07:27:33+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-1-10-1-coordinate-constraints/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-1-10-1-coordinate-constraints/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-1-10-1-coordinate-constraints/">&lt;h2 id=&quot;1-10-1-coordinate-constraints&quot;&gt;1.10.1 Coordinate Constraints&lt;&#x2F;h2&gt;
&lt;p&gt;In the &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-1.10-constrained-motion&quot;&gt;previous section&lt;&#x2F;a&gt;, we showed that for motion of a system with the constraint $\varphi(t, q(t), Dq(t)) = 0$, for stationary action, the path variations, $\eta(t)$, must be tangent to the constraint surface. And in order for the variation to be tangent to the constraint at a given time, it must satisfy the condition:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
(\partial_1 \varphi \circ \Gamma[q])\eta + (\partial_2 \varphi \circ \Gamma[q])D\eta = 0
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Now consider constraints that are only functions of the coordinates, i.e,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\partial_2 \varphi = 0\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Now the variation is tangent to the constraint if&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
(\partial_1 \varphi \circ \Gamma[q])\eta = 0 \tag{1.186}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We also know from Eq. 1.183 in the previous section that,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\{ (\partial_1 L \circ \Gamma[q]) - D\left( \partial_2 L \circ \Gamma[q] \right) \} \eta = 0 \tag{1.183}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Eq. 1.186 and 1.183 together should determine the motion of the constrained system.&lt;&#x2F;p&gt;
&lt;p&gt;Eq 1.183 is satisfied if the dot product of the first term (aka the residual of Lagranges Equations) and $\eta(t)$ is zero at all times. This is also the definition for two functions of time to be orthogonal to each other. To quote footnote 92 from the book:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;We take two tuple-valued functions of time to be orthogonal if at each instant the dot product of the tuples is zero. Similarly, tuple-valued functions are considered parallel if at each moment one of the tuples is a scalar multiple of the other. The scalar multiplier is in general a function of time.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;So the residual of the Lagrange equations is orthogonal to any $\eta(t)$. Also, $\eta(t)$ is tangent to the constraint surface, which means that it is orthogonal to the normal to the constraint surface.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;A vector that is orthogonal to all vectors orthogonal to a given vector is parallel to the given vector.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Therefore, the residual of Lagrange equations is parallel to the normal to the constraint surface; which means the two functions are proportional:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
(\partial_1 L \circ \Gamma[q]) - D\left( \partial_2 L \circ \Gamma[q] \right) = \lambda (\partial_1 \varphi \circ \Gamma[q])\tag{1.187}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The proportionality factor $\lambda$ is itself a function of time and need not be a constant. This equation, along with the constraint equation $\varphi \circ \Gamma[q] = 0$ is enough to determine the path $q$ and to eliminate the unknown function $\lambda$.&lt;&#x2F;p&gt;
&lt;p&gt;We can now form an augmented Lagrangian by treating $\lambda$ as one of the coordinates.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L&amp;#x27;(t; q,\lambda;\dot{q},\dot{\lambda}) = L(t,q,\dot{q})+ \lambda\varphi(t,q,\dot{q})
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The Lagrange equations associated with the coordinates are just the modified Lagrangian in Eq. 1.187. The equation assoicated with $\lambda$ is just the constraint equation. So the system is fully specified. This Lagrangian is also of the same form as the one described in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tgvaughan.github.io&#x2F;sicm&#x2F;chapter001.html#h3_1-6-2&quot;&gt;Section 1.6.2&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-do-we-eliminate-lambda-from-the-lagrange-equations&quot;&gt;How do we eliminate $\lambda$ from the Lagrange Equations?&lt;&#x2F;h3&gt;
&lt;p&gt;If the new function $\lambda$, can be written as a composition of a local tuple function over the original, &lt;em&gt;unaugmented&lt;&#x2F;em&gt; path: $\lambda = \Lambda \circ \Gamma[q]$, then it is a redundant degree of freedom and can be eliminated from the system if required.&lt;&#x2F;p&gt;
&lt;p&gt;Consider the Lagrangian with an extra term $\Lambda\varphi$ where $\varphi$ is the constraint function:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L&amp;#x27;&amp;#x27; = L + \Lambda\varphi\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The Lagrange equations for $L’‘$ is the same as that for $L$ but with some extra terms arising from $\Lambda\varphi$. Applying the &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;sicm-exercise-1-38&quot;&gt;Euler-Lagrange operator&lt;&#x2F;a&gt; to $L’’$:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathscr{E}[L&amp;#x27;&amp;#x27;] &amp;amp;= \mathscr{E}[L + \Lambda\varphi] = \mathscr{E}[L] + \mathscr{E}[\Lambda\varphi]\\
 &amp;amp;=  \mathscr{E}[L] + \mathscr{E}[\Lambda] \varphi + \Lambda\mathscr{E}[\varphi] + (D_t \Lambda)\partial_2 \varphi + (D_t \varphi)\partial_2 \Lambda
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Composing $\mathscr{E}[L]$ with $\Lambda[q]$ results in the Lagrange equations for $L’’$. Since the constraints are satisfied on the path, $\varphi \circ \Gamma[q] = 0$, which implies that $D_t(\Lambda \circ \Gamma[q]) = 0$.&lt;&#x2F;p&gt;
&lt;p&gt;Therefore, composing $\mathscr{E}[L]$ with $\Lambda[q]$, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathscr{E}[L&amp;#x27;&amp;#x27;]\circ\Gamma[q] &amp;amp;= \mathscr{E}[L]\circ\Gamma[q] + (\mathscr{E}[\Lambda]\circ\Gamma[q])\underbrace{\cancel{\varphi}}_{=0}
+ \underbrace{(\Lambda\circ\Gamma[q])}_{=\lambda}(\mathscr{E}[\varphi]\circ\Gamma[q])\\
&amp;amp;\quad+ (D_t \Lambda)(\partial_2 \varphi\circ\Gamma[q]) + (\underbrace{\cancel{D_t \varphi}}_{=0})(\partial_2 \Lambda\circ\Gamma[q]) \\
&amp;amp;= \mathscr{E}[L]\circ\Gamma[q] + \lambda(\mathscr{E}[\varphi]\circ\Gamma[q]) + (D_t \Lambda)(\partial_2 \varphi\circ\Gamma[q])
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;$\partial_2\varphi = 0$ as the constraints do not depend on velocity. Then,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{E}[L&amp;#x27;&amp;#x27;]\circ\Gamma[q] = \mathscr{E}[L]\circ\Gamma[q] + \lambda(\mathscr{E}[\varphi]\circ\Gamma[q])\tag{1.192}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We can see here that the Lagrange equations for $L’‘$ is the same as that for $L’$, with an extra term. Comparing this to Eq. 1.187, we can see that $\lambda = \Lambda \circ \Gamma[q]$, which is determined purely by the unaugmented state. Therefore $\lambda$ can be eliminated from the Lagrange equations of the augmented Lagrangian.&lt;&#x2F;p&gt;
&lt;p&gt;The explicit Lagrange equations derived from the augmented Lagrangian depend on the accelerations $D^2 q$ as well as $\lambda$. Now that $\lambda$ has been showed to be derived purely form the unaugmented state, so too is $D^2 q$ (as there are no other elements in the dynamic equations). Therefore the dynamic evolution of the system is determined purely by the dynamical state.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-pendulum-using-constraints&quot;&gt;The Pendulum using Constraints&lt;&#x2F;h3&gt;
&lt;p&gt;$$\require{cancel}$$&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;projects&#x2F;sicm-workbook&#x2F;figure-1.8.jpg&quot; alt=&quot;Figure 1.8&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 1.8&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The pendulum can be modeled as a point-mass constrained to always be at a constant distance from a pivot point. The system can be represented by the following Lagrangian and constraint:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
L(t; x,y; v_x,v_y) &amp;amp;= \frac{1}{2} m (v_x^2 + v_y^2) - mgy\\
x^2+y^2-l^2 &amp;amp;= 0
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The augmented Lagrangian is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L(t; x,y,\lambda; v_x,v_y,\dot{\lambda}) = \frac{1}{2} m (v_x^2 + v_y^2) - mgy + \lambda(x^2+y^2-l^2)\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The Lagrange equations for this augmented Lagrangian is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
m D^2x - 2\lambda x = 0 \tag{1.196}\\
m D^2y + mg - 2\lambda y = 0 \tag{1.197}\\
x^2 + y^2 - l^2 = 0\tag{1.198}\\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;These equations can be simplified by switching to polar coordinates, $x = r\sin{\theta}$ and $y = -r\cos{\theta}$. Substituting this in the constraint equation, we get, $r = l$. Plugging this into the equations 1.196 and 1.197:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
0 &amp;amp; = m D^2 (l\sin\theta) - 2\lambda l\sin\theta \\
    &amp;amp; = m (D(l \cos\theta D\theta)) - 2\lambda l\sin\theta\\
0 &amp;amp;= ml (\cos\theta D^2\theta - \sin\theta (D\theta)^2) - 2\lambda l\sin\theta \tag{1.200}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;div&gt;
    $$
\begin{align*}
0 &amp;amp;= m D^2 (-l\cos\theta) + mgl - 2\lambda (-l\cos\theta) \\
  &amp;amp;= m (D(l \sin\theta D\theta)) + 2\lambda l\cos\theta \\
0 &amp;amp;= ml (\sin\theta D^2\theta + \cos\theta (D\theta)^2) + 2\lambda l\cos\theta + mg \tag{1.201}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Multiply Eq. 1.200 by $\cos\theta$ and Eq. 1.201 by $\sin{\theta}$ and add to get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
0 &amp;amp;=ml (\cos\theta D^2\theta - \sin\theta (D\theta)^2)\cos\theta - \cancel{2\lambda l\sin\theta \cos \theta}\\
  &amp;amp; \quad+ ml (\sin\theta D^2\theta + \cos\theta (D\theta)^2)\sin\theta + \cancel{2\lambda l\cos\theta \sin\theta} + mg\sin\theta\\
 &amp;amp;= ml (\cos^2\theta D^2\theta) - \cancel{ml \sin\theta \cos\theta(D\theta)^2} \\
  &amp;amp; \quad+ ml (\sin^2 \theta D^2\theta) + \cancel{ml \cos\theta \sin\theta(D\theta)^2} + mg\sin\theta \\
 &amp;amp;=ml D^2\theta (\cos^2\theta + \sin^2 \theta ) + mg\sin\theta \\
0&amp;amp;= ml D^2\theta + mg\sin\theta 
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This is indeed the same equation as what we get if we used $\theta$ as an unconstrained generalized coordinate for the pendulum. We can also compute $\lambda$ in terms of the other variables from Eq.1.196 as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\lambda &amp;amp;= \frac{m D^2 x}{2x} = \frac{m D^2 (l\sin\theta)}{2l\sin\theta} \\
        &amp;amp;= \frac{m (D(l \cos\theta D\theta))}{2l\sin\theta} \\
        &amp;amp;= \frac{ml \cos\theta D^2\theta - ml \sin\theta (D\theta)^2}{2l\sin\theta} \\
        &amp;amp;= \frac{\overbrace{ml D^2\theta}^{-mg\sin\theta}\cos\theta  - ml \sin\theta (D\theta)^2}{2l\sin\theta} \\
        &amp;amp;= \frac{-mg\cancel{\sin\theta}\cos\theta  - ml \cancel{\sin\theta} (D\theta)^2}{2l\cancel{\sin\theta}} \\
\lambda &amp;amp; = \frac{-1}{2l} \left(mg\cos\theta - ml(D\theta)^2\right)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This further confirms what we showed in the previous section, that $\lambda$ really is the composition function of the local state of the path. Also, to be noted here is the $2l\lambda$ is a force – the sum of the outward component of gravity and the centrifugal force. This is the tension in the pendulum rod. It is effectively the force that is constraining the mass to stay at a constant distance from the pivot.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;building-systems-from-parts&quot;&gt;Building systems from parts&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;projects&#x2F;sicm-workbook&#x2F;figure-1.8.jpg&quot; alt=&quot;Figure 1.9&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 1.9: A compound spring-mass system is decomposed into two subsystems.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can analyze compound systems using augmented Lagrangians to enforce constraints between the individual parts. Consider the compound spring-mass system at the top of Figure 1.9. One way to analyze this is as a single system with two coordinates $x_1$ and $x_2$ to represent the extension of the springs from their equilibrium lengths of $X_1$ and $X_2$.&lt;&#x2F;p&gt;
&lt;p&gt;An alternative procedure would be to break it into two parts – one being the spring-mass attached to the wall, and the other being the second spring-mass system with its attachment point specified by an additional coordinate $\xi$ (which may have its own velocity). The Lagrangian for each part can be written separately. The Lagrangian of the combined system is the sum of the two component Lagrangians along with a constraint $\xi = X_1 + x_1$ to ensure that the two systems are attached.&lt;&#x2F;p&gt;
&lt;p&gt;So the Lagrangian for the part attached to the wall is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L_1(t; x_1; \dot{x_1}) = \frac{1}{2}m_1\dot{x_1}^2 - \frac{1}{2}k_1 x_1^2\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;and the Lagrangian for the part that attaches to it is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L_2(t; \xi,x_2; \dot{\xi},\dot{x_2}) = \frac{1}{2}m_2(\dot{\xi} + \dot{x_2})^2 - \frac{1}{2}k_2 x_2^2\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Combining the two Lagrangians with the contact constraint, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L(t; x_1, x_2, \xi; \dot{x_1},\dot{x_2},\dot{\xi}) = L_1(t; x_1; \dot{x_1}) + L_2(t; \xi,x_2; \dot{\xi},\dot{x_2}) + \lambda(\xi - (X_1 + x_1))
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The Lagrange’s equations for the system are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
m_1D^2 x_1 = -k_1 x_1 - \lambda \tag{1.207} \\
m_2(D^2\xi + D^2 x_2) = -k_2 x_2 \tag{1.208} \\
m_2(D^2\xi + D^2 x_2) = \lambda \tag{1.209} \\
0 = \xi - (X_1 + x_1) \tag{1.210}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;For eliminating $\xi$ and $\lambda$, substitute Eq. 1.210 into Eq. 1.209,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
m( \underbrace{D^2X_1}_{=0} + D^2 x_1 + D^2 x_2 ) = \lambda\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Substituting for $\lambda$ in Eq. 1.207,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
m_1 D^2 x_1 &amp;amp;= -k_1 x_1 - m_2 D^2 x_1 - m_2 D^2 x_2\\
m_1 D^2 x_1 + m_2 (D^2 x_1 + D^2 x_2) + k_1 x_1 &amp;amp;= 0\tag{1.211}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Substituting for $\xi$ in Eq. 1.208,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
m_2(D^2 x_1+ D^2 x_2) + k_2 x_2 &amp;amp;= 0\tag{1.212}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Equations 1.211 and 1.212 are the equations of motion for the compound system. This is a general strategy that can be used to create a library of primitive components.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Each component may be characterized by a Lagrangian with additional degrees of freedom for the terminals where that component may be attached to others. We then can construct composite Lagrangians by combining components, using constraints to glue together the terminals.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 1.10 : Constrained Motion</title>
        <published>2022-10-28T01:12:02+00:00</published>
        <updated>2022-10-28T01:12:02+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-1-10-constrained-motion/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-1-10-constrained-motion/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-1-10-constrained-motion/">&lt;h2 id=&quot;1-10-constrained-motion&quot;&gt;1.10 Constrained Motion&lt;&#x2F;h2&gt;
&lt;p&gt;When using the Lagrangian method, we may choose the coordinate system that is the most convenient - the number of coordinates may match exactly with the number of degrees of freedom of the system, or we may pick a system that has redundant coordinates along with explicit constraints among coordinates. As an example, a pendulum can be modeled using just the angle of the pendulum from the vertical, or as a point mass with a constraint stating that it should stay a constant distance from the pivot point. The constraints described in this section are more general than the ones developed in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tgvaughan.github.io&#x2F;sicm&#x2F;chapter001.html#h3_1-6-2&quot;&gt;Section 1.6.2&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Consider a dynamic system with $n$ degrees of freedom, specified by $n+1$ coordinates, along with a path constraint of the form:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\varphi(t, q(t), Dq(t)) = 0\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;In order to formulate the equations of motion, one approach would be to use the constraint equation to eliminate one of the coordinates, and then use the resulting irredundant coordinates to develop Lagrange’s Equations. Any equations developed using redundant coordinates with constraints should be equivalent.&lt;&#x2F;p&gt;
&lt;p&gt;In order to do this, consider the method used originally for deriving Lagrange’s equations. Realizable paths were those that had a stationary “action” compared to nearby paths. “Stationary” here means that the action does not change for small changes in the path. We considering constrained motion, these varied paths must also satisfy the constraints. This has some effects on the derivation of Lagrange’s equations. Regardless of the method used, the condition for stationary action condenses to the following form (Eq. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tgvaughan.github.io&#x2F;sicm&#x2F;chapter001.html#disp_1.17&quot;&gt;1.17&lt;&#x2F;a&gt; or Eq. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tgvaughan.github.io&#x2F;sicm&#x2F;chapter001.html#disp_1.34&quot;&gt;1.34&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
0 = \int_{t_0}^{t_f} \{ (\partial_1 L \circ \Gamma[q]) - D\left( \partial_2 L \circ \Gamma[q] \right) \} \eta \tag{1.182}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\eta$ is the variation in the path. In the unconstrained case, we may have arbitrary variations and so the only way for Eq.1.182 to be satisfied was for the integrand to be zero. Furthermore, since $\eta$ can be arbitrarily chosen, the term multiplying with $\eta$ must be zero for the action to be stationary, thereby getting to Lagrange’s equations.&lt;&#x2F;p&gt;
&lt;p&gt;Once we add in constraints, $\eta$ can no longer be arbitrarily chosen. While the intgrand must still be zero for Eq. 1.182 to be satisfied, we can no loner conclude that the factor multiplying $\eta$ must be zero. Therefore,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\{ (\partial_1 L \circ \Gamma[q]) - D\left( \partial_2 L \circ \Gamma[q] \right) \} \eta  = 0 \tag{1.183}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;with $\eta$ subject to the constraints of the dynamic system.&lt;&#x2F;p&gt;
&lt;p&gt;A path $q$ satisfies the constraint if $\bar{\varphi}[q] = \varphi \circ \Gamma[q] = 0$. Since we only allow varied paths that satisfy the constraint, the variation of the constraint must be zero:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\delta_\eta(\bar{\varphi}) = 0 \tag{1.184}
$$
&lt;&#x2F;div&gt;
&lt;blockquote&gt;
&lt;p&gt;The variation must be “tangent” to the constraint surface&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Expanding Eq. 1.184 with the chain rule (Eq. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tgvaughan.github.io&#x2F;sicm&#x2F;chapter001.html#disp_1.26&quot;&gt;1.26&lt;&#x2F;a&gt;) and the definition $\delta_\eta \Gamma&lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;projects&#x2F;sicm-workbook&#x2F;section-1-10-constrained-motion&#x2F;t&quot;&gt;q&lt;&#x2F;a&gt; = (0,\eta(t),D\eta(t))$ (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tgvaughan.github.io&#x2F;sicm&#x2F;chapter001.html#disp_1.31&quot;&gt;Eq. 1.31&lt;&#x2F;a&gt;), the variation is tangent to the constraint surface if:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\delta_\eta(\bar{\varphi}) &amp;amp;= \delta_\eta( \varphi \circ \Gamma[q]) \\
   &amp;amp;= (D\varphi \circ \Gamma[q]) \delta_\eta\Gamma[q] \\
   &amp;amp;= \left(\partial_0 \varphi \circ \Gamma[q], \partial_1 \varphi \circ \Gamma[q], \partial_2 \varphi \circ \Gamma[q]\right) \cdot [0, \eta, D\eta] \\
   &amp;amp;= (\partial_1 \varphi \circ \Gamma[q])\eta + (\partial_2 \varphi \circ \Gamma[q])D\eta = 0\tag{1.185}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;These are functions of time, so the variation at a given time is tangent to the constraint surface at that time.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.38: Properties of ℰ, the Euler Lagrange Operator</title>
        <published>2022-10-27T06:15:32+00:00</published>
        <updated>2022-10-27T06:15:32+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-38/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-38/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-38/">&lt;h3 id=&quot;exercise-1-38-properties-of-mathscr-e-the-euler-lagrange-operator&quot;&gt;Exercise 1.38: Properties of $\mathscr{E}$, the Euler-Lagrange Operator&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Refer to &lt;a href=&quot;&#x2F;projects&#x2F;sicm-workbook&#x2F;section-1-9-abstraction-of-path-functions#lagrange-equations-at-a-moment-or-the-euler-lagrange-operator&quot;&gt;Section 1.9&lt;&#x2F;a&gt; for more details&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let $F$ and $G$ be two Lagrangian-like functions of a local tuple, $C$ be a local-tuple transformation function, and $c$ a constant. Demonstrate the following properties:&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h4 id=&quot;a-mathscr-e-f-g-mathscr-e-f-mathscr-e-g&quot;&gt;a. $\mathscr{E}[F+G]=\mathscr{E}[F]+\mathscr{E}[G]$&lt;&#x2F;h4&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathscr{E}[F+G] &amp;amp;= D_t\partial_2 (F + G) - \partial_1 (F + G) \\
 &amp;amp;= D_t\partial_2 F - \partial_1 F + D_t\partial_2 G - \partial_1 G \\
 \\
\therefore \mathscr{E}[F+G] &amp;amp;= \mathscr{E}[F] + \mathscr{E}[G] \\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;h4 id=&quot;b-mathscr-e-cf-c-mathscr-e-f&quot;&gt;b. $\mathscr{E}[cF]=c\mathscr{E}[F]$&lt;&#x2F;h4&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathscr{E}[cF] &amp;amp;= D_t\partial_2 (cF) - \partial_1 (cF) \\
 &amp;amp;= c D_t\partial_2 F - c \partial_1 F = c (D_t\partial_2 F - \partial_1 F)\\
 \\
\therefore \mathscr{E}[cF] &amp;amp;= c \mathscr{E}[F]
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;h4 id=&quot;c-mathscr-e-fg-mathscr-e-f-g-f-mathscr-e-g-d-t-f-partial-2-g-partial-2-f-d-t-g&quot;&gt;c. $\mathscr{E}[FG]=\mathscr{E}[F]G+F\mathscr{E}[G]+(D_t F)\partial_2 G+\partial_2 F(D_t G)$&lt;&#x2F;h4&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathscr{E}[FG] &amp;amp;= D_t\partial_2 (FG) - \partial_1 (FG) \\
 &amp;amp;= D_t G\partial_2 F + F \partial_2 G) - F\partial_1 G -G\partial_1 F\\
 &amp;amp;= D_t (G\partial_2 F) + D_t(F \partial_2 G) - F\partial_1 G -G\partial_1 F \\
 &amp;amp;= (D_t G)(\partial_2 F) + (D_t \partial_2 F)(G) + (D_t F)(\partial_2 G) + (D_t \partial_2 G)(F) - F (\partial_1 G) -G (\partial_1 F) \quad ; \text{Rearranging terms .. }\\ 
 &amp;amp;= \left(D_t \partial_2 F - \partial_1 F \right)(G) + F\left(D_t \partial_2 G - \partial_1 G\right) + (D_t F)\partial_2 G + (D_t G)\partial_2 F \\
 \\
\therefore \mathscr{E}[FG] &amp;amp;= \mathscr{E}[F] G + F\mathscr{E}[G] + (D_t F)\partial_2 G + (D_t G)\partial_2 F 
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;h4 id=&quot;d-mathscr-e-f-circ-c-d-t-d-f-circ-c-partial-2c-d-f-circ-c-mathscr-e-c&quot;&gt;d. $\mathscr{E}[F \circ C]=D_t(D F\circ C)\partial_2C+D F \circ C\mathscr{E}[C]$&lt;&#x2F;h4&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathscr{E}[F \circ C] &amp;amp;= D_t(\partial_2 (F \circ C)) - \partial_1 (F \circ C) \\
&amp;amp;= D_t \big( (DF \circ C)(\partial_2 C) \big) - (DF \circ C )\partial_1 C \qquad;\text{by chain rule}\frac{\partial F(C(v))}{\partial v} = \underbrace{\frac{\partial F}{\partial C}}_{= DF \circ C} \frac{\partial C}{\partial v}\\
&amp;amp;= D_t (DF \circ C) (\partial_2 C) + (DF \circ C) D_t \partial_2 C - (DF \circ C )\partial_1 C \\
\\
\therefore \mathscr{E}[F \circ C] &amp;amp;= D_t (DF \circ C) (\partial_2 C) + (DF \circ C)\mathscr{E}[C]
\end{align*}
$$
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.37: Velocity transformation</title>
        <published>2022-10-27T05:15:14+00:00</published>
        <updated>2022-10-27T05:15:14+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-37/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-37/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-37/">&lt;h3 id=&quot;exercise-1-38-velocity-transformation&quot;&gt;Exercise 1.38: Velocity transformation&lt;&#x2F;h3&gt;
&lt;p&gt;Use the procedure Gamma-bar to construct a procedure that transforms velocities given a coordinate transformation. Apply this procedure to the procedure &lt;code&gt;p-&amp;gt;r&lt;&#x2F;code&gt; to deduce (again) equation (1.67) on page 42.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
v_x &amp;amp;= \dot{r} \cos{\varphi} − r \dot{\varphi} \sin{\varphi} \\
v_y &amp;amp;= \dot{r} \sin{\varphi} + r \dot{\varphi} \cos{\varphi}\tag{1.67}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We need to define a function &lt;code&gt;F-&amp;gt;C_v&lt;&#x2F;code&gt; that takes a local tuple coordinate transformation function $F$ and returns a new local tuple function $C_v$. $C_v$ when evaluated on a local tuple, returns the expression for velocity in terms of the new coordinates.&lt;&#x2F;p&gt;
&lt;p&gt;If the fucntion $F$ is defined as $x = F(t, x’)$, then $v = C_v(t, x’, v’)$.&lt;&#x2F;p&gt;
&lt;p&gt;We start with a path-dependent function $\bar{C_v}$ with path $q’$ as its input, defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\bar{C_v}[q&amp;#x27;] :=  \dot{Q} \circ \Gamma \left[ F \circ \Gamma[q&amp;#x27;] \right]
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\dot{Q}$ is a selector function that extracts the velocity component of a local tuple. We get $C_v$ by applying the &lt;code&gt;Gamma-bar&lt;&#x2F;code&gt; function on $\bar{C_v}$&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
C_v = \bar{\Gamma}[ \bar{C_v} ]
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;F-&amp;gt;C_v
&lt;&#x2F;span&gt;&lt;span&gt;    [F]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;C_v &lt;&#x2F;span&gt;&lt;span&gt;[local]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[f-bar (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q-prime]
&lt;&#x2F;span&gt;&lt;span&gt;                        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[q (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose&lt;&#x2F;span&gt;&lt;span&gt; F (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; q-prime))] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; q = F . Gamma[q&amp;#39;]
&lt;&#x2F;span&gt;&lt;span&gt;                        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose&lt;&#x2F;span&gt;&lt;span&gt; velocity (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; q))         &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; 
&lt;&#x2F;span&gt;&lt;span&gt;                    ))
&lt;&#x2F;span&gt;&lt;span&gt;              ]
&lt;&#x2F;span&gt;&lt;span&gt;        ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma-bar&lt;&#x2F;span&gt;&lt;span&gt; f-bar) local))
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F-&amp;gt;C_v&lt;&#x2F;span&gt;&lt;span&gt; p-&amp;gt;r)
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r &amp;#39;varphi) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;rdot &amp;#39;varphidot)))
&lt;&#x2F;span&gt;&lt;span&gt;           )
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{- r\,\dot {\varphi}\,\sin\left(\varphi\right) + \dot r\,\cos\left(\varphi\right)} \cr \cr \displaystyle{r\,\dot {\varphi}\,\cos\left(\varphi\right) + \dot r\,\sin\left(\varphi\right)}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;^ The above answer matches Eq. 1.67&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 1.9: Abstraction of Path Functions</title>
        <published>2022-10-27T01:12:46+00:00</published>
        <updated>2022-10-27T01:12:46+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-1-9-abstraction-of-path-functions/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-1-9-abstraction-of-path-functions/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-1-9-abstraction-of-path-functions/">&lt;h2 id=&quot;1-9-abstraction-of-path-functions&quot;&gt;1.9 Abstraction of Path Functions&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Note: This section may seem rather dry from its title. But this is driving towards some important results.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When we were deriving the local-tuple transformation $C$, corresponding to a coordinate transformation $F$, the main factor was finding the relationship between the velocities in the two coordinate systems (e.g. $v$ and $v’$). We did this by inserting coordinate paths into the transformation function, $F$, finding its derivatives and then extracting out the velocity components.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
x &amp;amp;= F(t, x&amp;#x27;) \\
=&amp;gt; v &amp;amp;= \partial_0 F + \partial_1 F v&amp;#x27;
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This last step is an example from a more general scenario where we want to abstract a local tuple function from a path function. Consider a function, $f$ of the local tuple. We typically apply $f$ to a path by composing it with $\Gamma$. $\Gamma$ is a function which extracts the local tuple from a path (the path itself is usually denoted computationally as symbolic coordinate functions like $x(t)$, $y(t)$ etc.). Given $f$, a corresponding path-dependent function $\bar{f}[q]$ can be defined using $\Gamma$ as $\bar{f}[q] = f \circ \Gamma[q]$. The question now is given $\bar{f}$, how can we reconstitute $f$.&lt;&#x2F;p&gt;
&lt;p&gt;We know that $f$ depends only on a certain finite number of components, $n$ of the local-tuple (say, $t$, $x$ and $v$). Therefore $\bar{f}$ also depends only on the corresponding local components of the path. It is important to note that the path may be more complex than can be represented by $n$ components. Even so, the path-dependent function $\bar{f}$ &lt;em&gt;still&lt;&#x2F;em&gt; has same value for all the paths that share the same first $n$ local components.&lt;&#x2F;p&gt;
&lt;p&gt;By “reconstituting” $f$, what we mean here is that we want to find the value of $f$ for some local tuple argument, when we only know the function definition of $\bar{f}$. To do this, we take the argument of $f$ (which is a finite initial segment of the local tuple), constructing a path that has this local description (say, using a power series), and then finding the value of $\bar{f}$ for this path.&lt;&#x2F;p&gt;
&lt;p&gt;Two paths that have the same $n$ initial components of the local tuple in its description (or “have the same local description up to the nth derivative”) are said to &lt;em&gt;osculate with order $n$ contact&lt;&#x2F;em&gt;. One example of this is a path, and a truncated power series representation of the path up to order $n$, have order $n$ contact. If we have a power-series representation of the path available up to $n$-th order, and a local tuple function takes fewer than $n$ components of the local tuple, then as far as this function is concerned, the path and the trunctated power series are equivalent.&lt;&#x2F;p&gt;
&lt;p&gt;Let $O$ be a function that generates an osculating path with the given local tuple components, i.e.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
O(t, q, v, ...)(t) &amp;amp;= q \\
D(O(t, q, v, ...))(t) &amp;amp;= v\\
\text{etc. and in general:}\\
(t, q, v, ...) &amp;amp;= \Gamma[O(t, q, v, ...)](t)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;$O$ is defined to take a finite number of local tuple components, $n$. $O$ can be considered to be “inverse” of the $\Gamma$ function. One caveat is that it only make sense to use $O$ when we have concrete expressions defining the entire local tuple of interest, rather than symbolic functions. One possible way of construction $O$ is using a power series:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
O(t, q, v, ...)(t&amp;#x27;) = q + v(t&amp;#x27; - t) + \frac{1}{2} a (t&amp;#x27; - t)^2 + ...\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;So, given a path function $\bar{f}$, we can reconstitute the $f$ function as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
f(t, q, v, ...) &amp;amp;= (f \circ \Gamma[O(t, q, v, ...)]) (t)\\
                &amp;amp;= \bar{f}[O(t,q,v,...)](t)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Using this we can define $\bar{\Gamma}$ as a function that takes a path function and returns the corresponding local-tuple function, $f = \bar{\Gamma}[\bar{f}]$.  $\bar{\Gamma}$ is defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\bar{\Gamma}[f](t, q, v, ...) = \bar{f}[O(t, q, v, ...)](t)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;$\bar{\Gamma}$ is defined in Clojure below. &lt;code&gt;osculating-path&lt;&#x2F;code&gt; is the implementation of the $O$ function.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;osculating-path2
&lt;&#x2F;span&gt;&lt;span&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Defines a path function f(t) using a Taylor series about the time given in reference state&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;    [state_ref]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[[t_ref q_ref] state_ref
&lt;&#x2F;span&gt;&lt;span&gt;           N (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;count&lt;&#x2F;span&gt;&lt;span&gt; state_ref)]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[t]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[dt (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; t t_ref)]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;loop &lt;&#x2F;span&gt;&lt;span&gt;[n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2
&lt;&#x2F;span&gt;&lt;span&gt;                   sum q_ref
&lt;&#x2F;span&gt;&lt;span&gt;                   dt**n-by-n! dt]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; n N) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; exit loop when n == N
&lt;&#x2F;span&gt;&lt;span&gt;                sum       &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; return sum
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;recur &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;inc&lt;&#x2F;span&gt;&lt;span&gt; n)      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; update loop variables and repeat
&lt;&#x2F;span&gt;&lt;span&gt;                   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; sum (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;nth&lt;&#x2F;span&gt;&lt;span&gt; state_ref n) dt**n-by-n!))
&lt;&#x2F;span&gt;&lt;span&gt;                   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; dt**n-by-n! dt) n)))
&lt;&#x2F;span&gt;&lt;span&gt;)))))
&lt;&#x2F;span&gt;&lt;span&gt;        
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;Gamma-bar2 &lt;&#x2F;span&gt;&lt;span&gt;[f-bar]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;f &lt;&#x2F;span&gt;&lt;span&gt;[local]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;first&lt;&#x2F;span&gt;&lt;span&gt; local)]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;f-bar &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;osculating-path2&lt;&#x2F;span&gt;&lt;span&gt; local)) t)
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Despite it’s name &lt;code&gt;Gamma-bar2&lt;&#x2F;code&gt; is &lt;strong&gt;not&lt;&#x2F;strong&gt; the inverse of $\Gamma[q]$. $\Gamma[q]$ takes a path, and returns a local tuple (the inverse of $\Gamma[q]$ is actually $O$ which takes a local tuple and returns a path). &lt;code&gt;Gamma-bar2&lt;&#x2F;code&gt; takes a function of a path, and returns a function of local tuples – this is a subtle but important difference. One operates on the path&#x2F;tuple, and the other operates on functions of paths&#x2F;tuples.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Gamma-bar2&lt;&#x2F;code&gt; can be used to define a more general version of the &lt;code&gt;F-&amp;gt;C&lt;&#x2F;code&gt; function.  The procedure &lt;code&gt;F-&amp;gt;C&lt;&#x2F;code&gt; first constructs a path-dependent procedure &lt;code&gt;f-bar&lt;&#x2F;code&gt; that takes a coordinate path in the primed system and returns the local tuple of the corresponding path in the unprimed coordinate system. It then uses &lt;code&gt;Gamma-bar2&lt;&#x2F;code&gt; to abstract f-bar to arbitrary local tuples in the primed coordinate system. The resulting procedure &lt;code&gt;C&lt;&#x2F;code&gt; can take local tuples with &lt;code&gt;n&lt;&#x2F;code&gt; components in the primed coordinate system and generate local tuples of &lt;code&gt;n&lt;&#x2F;code&gt; terms in the unprimed coordinate system.&lt;&#x2F;p&gt;
&lt;p&gt;E.g. &lt;code&gt;p-&amp;gt;r&lt;&#x2F;code&gt; which is defined as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;p-&amp;gt;r &lt;&#x2F;span&gt;&lt;span&gt;[[t&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[r&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; phi]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[rdot&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; phidot]]]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;        y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; phi))]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x y)
&lt;&#x2F;span&gt;&lt;span&gt;  )
&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;p-&amp;gt;r&lt;&#x2F;code&gt; takes a local tuple in polar coordinates and returns a &lt;strong&gt;path&lt;&#x2F;strong&gt; in rectangular coordinates (&lt;strong&gt;NOT&lt;&#x2F;strong&gt; the local tuple). &lt;code&gt;f-bar&lt;&#x2F;code&gt; takes the &lt;strong&gt;input path&lt;&#x2F;strong&gt; &lt;code&gt;q-prime&lt;&#x2F;code&gt; in polar coordinates. Converts it into local tuple in polar coordinates using &lt;code&gt;Gamma[q-prime]&lt;&#x2F;code&gt;. This local tuple is then passed to &lt;code&gt;p-&amp;gt;r&lt;&#x2F;code&gt; which returns a &lt;strong&gt;path&lt;&#x2F;strong&gt; in rectangular coordinates. This is then passed to &lt;code&gt;Gamma&lt;&#x2F;code&gt; to return the local tuple of &lt;code&gt;n&lt;&#x2F;code&gt; components in rectangular coordinates. &lt;code&gt;Gamma-bar&lt;&#x2F;code&gt; ensures that the input which consists of a polar local tuple of &lt;code&gt;n&lt;&#x2F;code&gt; components is converted to a path before being handed off to &lt;code&gt;f-bar&lt;&#x2F;code&gt; which then returns a local tuple of &lt;code&gt;n&lt;&#x2F;code&gt; components in rectangular coordinates.&lt;&#x2F;p&gt;
&lt;p&gt;So to summarize, &lt;code&gt;p-&amp;gt;r&lt;&#x2F;code&gt; takes in a &lt;strong&gt;tuple&lt;&#x2F;strong&gt; and outputs a &lt;strong&gt;path&lt;&#x2F;strong&gt; or coordinate function in rectangular coordinates. However, instead of passing in a tuple directly to &lt;code&gt;p-&amp;gt;r&lt;&#x2F;code&gt;, we pass in a &lt;strong&gt;path&lt;&#x2F;strong&gt;, and convert it into a tuple first by calling &lt;code&gt;(Gamma q-prime)&lt;&#x2F;code&gt;. The output of &lt;code&gt;p-&amp;gt;r&lt;&#x2F;code&gt; is then wrapped in &lt;code&gt;Gamma &amp;lt;&amp;gt; n&lt;&#x2F;code&gt; to extract &lt;code&gt;n&lt;&#x2F;code&gt; components of the local tuple out of this new path, which is then returned to the caller. This whole function is a path-dependent function that takes a path in polar coordinates as the input and spits out a local tuple in rectangular coordinates. Wrapping this in &lt;code&gt;Gamma-bar&lt;&#x2F;code&gt; makes it a function that instead takes a local tuple as input.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;super-F-&amp;gt;C &lt;&#x2F;span&gt;&lt;span&gt;[F]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;C &lt;&#x2F;span&gt;&lt;span&gt;[local]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[n (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;count&lt;&#x2F;span&gt;&lt;span&gt; local)
&lt;&#x2F;span&gt;&lt;span&gt;              f-bar (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q-prime]
&lt;&#x2F;span&gt;&lt;span&gt;                    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[q (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose&lt;&#x2F;span&gt;&lt;span&gt; F (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; q-prime))]
&lt;&#x2F;span&gt;&lt;span&gt;                        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; q n)))]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma-bar2&lt;&#x2F;span&gt;&lt;span&gt; f-bar) local))
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;p2r &lt;&#x2F;span&gt;&lt;span&gt;[[_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[r&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; phi]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _]]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[x (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;        y (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; r (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; phi))]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x y)
&lt;&#x2F;span&gt;&lt;span&gt;  )
&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; This can be demonstrated using the existing coordinate conversion 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; function p-&amp;gt;r which converts from polar coordinates to rectangular 
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; coordinates. Here it is shown operating on a local tuple with 4 terms.
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex
&lt;&#x2F;span&gt;&lt;span&gt;  ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;super-F-&amp;gt;C&lt;&#x2F;span&gt;&lt;span&gt; p2r)
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;r &amp;#39;theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;rdot &amp;#39;thetadot) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;rdotdot &amp;#39;thetadotdot))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is a very convoluted function at first look but also elegant in certain ways. My understanding is that we go through this roundabout way of path-&amp;gt;tuple-&amp;gt;path-&amp;gt;tuple so that we can expand&#x2F;contract the number of components of the path description that we are interested in. One example of this can be seen when applying &lt;code&gt;F-&amp;gt;C&lt;&#x2F;code&gt; to the &lt;code&gt;coordinate&lt;&#x2F;code&gt; function which simply extracts the position out of the local tuple (it returns the same local tuple that was passed in).&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;(rendertex
&lt;&#x2F;span&gt;&lt;span&gt;  ((super-F-&amp;gt;C coordinate)
&lt;&#x2F;span&gt;&lt;span&gt;   (up &amp;#39;t (up &amp;#39;r &amp;#39;theta) (up &amp;#39;rdot &amp;#39;thetadot) (up &amp;#39;rdotdot &amp;#39;thetadotdot))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\begin{pmatrix}\displaystyle{t} \cr \cr \displaystyle{\begin{pmatrix}\displaystyle{r} \cr \cr \displaystyle{\theta}\end{pmatrix}} \cr \cr \displaystyle{\begin{pmatrix}\displaystyle{\dot r} \cr \cr \displaystyle{\dot {\theta}}\end{pmatrix}} \cr \cr \displaystyle{\begin{pmatrix}\displaystyle{\ddot r} \cr \cr \displaystyle{\ddot {\theta}}\end{pmatrix}}\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The &lt;code&gt;F&lt;&#x2F;code&gt; function “contracts” (probably inaccurate terminology here) the local tuple that is passed in into just the position coordinates aka “path”. And to extract out more components from this, it is necessary to wrap the input in &lt;code&gt;Gamma&lt;&#x2F;code&gt; and the function itself in &lt;code&gt;Gamma-bar&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Gamma-bar&lt;&#x2F;code&gt; can also be used to compute the total time derivative $D_t F$ of the local tuple function $F$.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D_t (F \circ \Gamma[q]) = \bar{\Gamma}[ D(F \circ \Gamma[q]) ]
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;Need more explanation as to why this works&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Given a procedure $F$ implementing a local-tuple function and a path $q$, we construct a new procedure &lt;code&gt;(compose F (Gamma q))&lt;&#x2F;code&gt;. The   procedure &lt;code&gt;DF-on-path&lt;&#x2F;code&gt; implements the derivative of this function of time. We then abstract this off the path with &lt;code&gt;Gamma-bar&lt;&#x2F;code&gt; to give the total time derivative.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;code&gt;Dt&lt;&#x2F;code&gt; takes as input a function of the local tuple &lt;code&gt;F&lt;&#x2F;code&gt; and outputs a function of the local tuple. This function when evaluated for a some local tuple state, returns the time-derivative of &lt;code&gt;F&lt;&#x2F;code&gt; at that time. &lt;code&gt;Dt&lt;&#x2F;code&gt; is used to define the Euler-Lagrange operator in the next section&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;Dt &lt;&#x2F;span&gt;&lt;span&gt;[F]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;DtF &lt;&#x2F;span&gt;&lt;span&gt;[state]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[n (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;count&lt;&#x2F;span&gt;&lt;span&gt; state)
&lt;&#x2F;span&gt;&lt;span&gt;          DF-on-path (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q]
&lt;&#x2F;span&gt;&lt;span&gt;                    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose&lt;&#x2F;span&gt;&lt;span&gt; F (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; q (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)))))]
&lt;&#x2F;span&gt;&lt;span&gt;      ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma-bar&lt;&#x2F;span&gt;&lt;span&gt; DF-on-path) state)))
&lt;&#x2F;span&gt;&lt;span&gt;  )
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;lagrange-equations-at-a-moment-or-the-euler-lagrange-operator&quot;&gt;Lagrange equations “at a moment” or the Euler Lagrange operator&lt;&#x2F;h3&gt;
&lt;p&gt;The Euler-Lagrange equations can be defined as a path-dependent function, $\bar{\mathscr{E}}[L][q]$, the operates on a path, $q$ and returns zero if it s feasible path (according to the Lagrangian $L$).&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\bar{\mathscr{E}}[L][q] = D_t(\partial_2 L \circ \Gamma[q]) - \partial_1 L \circ \Gamma[q]
$$
&lt;&#x2F;div&gt;
&lt;p&gt;These path-dependent E-L equations can be converted to local-tuple function, $\mathscr{E}[L]$ using &lt;code&gt;Gamma-bar&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{E}[L] = \bar{\Gamma}(\bar{\mathcal{E}}[L]) \\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;$\mathscr{E}[L] \circ \Gamma[q] = 0$ for realizable paths. $\mathscr{E}$ is called the &lt;strong&gt;Euler-Lagrange operator&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{E}[L] = D_t \partial_2 L - \partial_1 L \tag{1.180}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;my-Euler-Lagrange-operator &lt;&#x2F;span&gt;&lt;span&gt;[L]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Dt &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) L)) ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) L)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-harmonic &lt;&#x2F;span&gt;&lt;span&gt;[m k]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ q v]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; k (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; q)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;my-Euler-Lagrange-operator
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-harmonic &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;k))
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t &amp;#39;x &amp;#39;v &amp;#39;a)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Euler-Lagrange-operator &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-harmonic &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;k))
&lt;&#x2F;span&gt;&lt;span&gt;   (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt; &amp;#39;t)
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;strong&gt;Euler-Lagrange operator&lt;&#x2F;strong&gt; takes in a Lagrangian function as input and directly create a new function which will define the Euler-Lagrange equations on passing in the local tuple.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;The functions&#x2F;operators introduced in this section such as &lt;code&gt;Gamma-bar&lt;&#x2F;code&gt;, &lt;code&gt;Dt&lt;&#x2F;code&gt; and &lt;code&gt;Euler-Lagrange-operator&lt;&#x2F;code&gt; seem to be aimed at delaying evaluation as much as possible. We can stay in the realm of functions until the very end where we evaluate it on a local tuple to get the answer. Because these functions are eventually operating on paths, we need to make sure they are represented as path-dependent functions before transforming them. However, we wrap the path-dependant function in &lt;code&gt;Gamma-bar&lt;&#x2F;code&gt; at the end to make sure that we can still pass in the input as a local tuple.&lt;&#x2F;p&gt;
&lt;p&gt;While there is still more I could understand about the mechanism&#x2F;logic by which this is possible, this is where I will stop for now.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.36: Noether integral</title>
        <published>2022-10-25T06:24:52+00:00</published>
        <updated>2022-10-25T06:24:52+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-36/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-36/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-36/">&lt;h3 id=&quot;exercise-1-36-noether-integral&quot;&gt;Exercise 1.36: Noether integral&lt;&#x2F;h3&gt;
&lt;p&gt;Consider motion on an ellipsoidal surface. The surface is specified by $\frac{x^2}{a^2}+\frac{y^2}{b^2}+\frac{z^2}{c^2}=1$&lt;&#x2F;p&gt;
&lt;p&gt;Formulate a Lagrangian for frictionless motion on this surface. Assume that two of the axes of the ellipsoid are equal: b = c.&lt;&#x2F;p&gt;
&lt;p&gt;Using angular coordinates $(\theta, \phi)$, where $\theta$ is colatitude from the $z$-axis, and $\phi$ is longitude measured from the $x$-axis, formulate a Lagrangian that captures the symmetry of this ellipsoid: rotational symmetry around the $x$-axis. Formulate a parametric transformation that represents this symmetry and show that the Lagrangian you formulated is invariant under this transformation. Compute the Noether integral associated with this symmetry.&lt;&#x2F;p&gt;
&lt;p&gt;Note that the choice of coordinates does not build in this symmetry.&lt;&#x2F;p&gt;
&lt;p&gt;With $\theta$ being the colatitude from the $z$-axis, and $\phi$ being the longitude measured from the $x$ axis,
The parameteric equations for an ellipsoid are:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
x &amp;amp;= a\sin{\theta}\cos{\phi} \\
y &amp;amp;= b\sin{\theta}\sin{\phi} \\
z &amp;amp;= c\cos{\theta}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Coordinate transformation for (theta, phi) to rectilinear coordinates
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;elliptical-&amp;gt;rect &lt;&#x2F;span&gt;&lt;span&gt;[a b c]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ [theta phi] _]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; a (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; b (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; phi))
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; c (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta)))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Free particle Lagrangian
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-free-particle &lt;&#x2F;span&gt;&lt;span&gt;[mass]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_ _ v]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; mass (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;dot-product&lt;&#x2F;span&gt;&lt;span&gt; v v)))   
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Lagrangian for motion constrained to the ellipsoid
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-ellipsoid &lt;&#x2F;span&gt;&lt;span&gt;[m a b c]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q-prime]
&lt;&#x2F;span&gt;&lt;span&gt;          ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-free-particle&lt;&#x2F;span&gt;&lt;span&gt; m) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F-&amp;gt;C &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;elliptical-&amp;gt;rect&lt;&#x2F;span&gt;&lt;span&gt; a b c)))
&lt;&#x2F;span&gt;&lt;span&gt;           q-prime)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;phi))
&lt;&#x2F;span&gt;&lt;span&gt;       local ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)
&lt;&#x2F;span&gt;&lt;span&gt;       ]
&lt;&#x2F;span&gt;&lt;span&gt;     ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-ellipsoid &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;a &amp;#39;b &amp;#39;c) local)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\frac{1}{2}\,{a}^{2}\,m\,{\cos}^{2}\left(\phi\left(t\right)\right)\,{\cos}^{2}\left(\theta\left(t\right)\right)\,{\left(D\theta\left(t\right)\right)}^{2} - {a}^{2}\,m\,\cos\left(\phi\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,D\theta\left(t\right)\,\sin\left(\theta\left(t\right)\right)\,\sin\left(\phi\left(t\right)\right)\,D\phi\left(t\right) + \frac{1}{2}\,{a}^{2}\,m\,{\sin}^{2}\left(\theta\left(t\right)\right)\,{\sin}^{2}\left(\phi\left(t\right)\right)\,{\left(D\phi\left(t\right)\right)}^{2} + \frac{1}{2}\,{b}^{2}\,m\,{\cos}^{2}\left(\phi\left(t\right)\right)\,{\sin}^{2}\left(\theta\left(t\right)\right)\,{\left(D\phi\left(t\right)\right)}^{2} + {b}^{2}\,m\,\cos\left(\phi\left(t\right)\right)\,\cos\left(\theta\left(t\right)\right)\,D\theta\left(t\right)\,\sin\left(\theta\left(t\right)\right)\,\sin\left(\phi\left(t\right)\right)\,D\phi\left(t\right) + \frac{1}{2}\,{b}^{2}\,m\,{\cos}^{2}\left(\theta\left(t\right)\right)\,{\left(D\theta\left(t\right)\right)}^{2}\,{\sin}^{2}\left(\phi\left(t\right)\right) + \frac{1}{2}\,{c}^{2}\,m\,{\left(D\theta\left(t\right)\right)}^{2}\,{\sin}^{2}\left(\theta\left(t\right)\right)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The above Lagrangian is for the motion of a particle constrained to move on an ellipsoid.&lt;&#x2F;p&gt;
&lt;p&gt;The question asks that we look at a spheroid with $b = c$ and look at the symmetry about the $x$ axis. Without losing generality, we can instead consider the case where $a = b$ and look at the symmetry about the $z$ axis. This rotation gets reduced to a simple addition to $\phi$, i.e.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}\theta\\\phi\end{pmatrix} = R_x(s)(\begin{pmatrix}\theta&amp;#x27;\\\phi&amp;#x27;\end{pmatrix}) = \begin{pmatrix}\theta&amp;#x27;\\\phi&amp;#x27; + s\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Assuming two of the axes are equal, i.e., a = b
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-ellipsoid-sym &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-ellipsoid &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m &amp;#39;a &amp;#39;a &amp;#39;c))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;phi))
&lt;&#x2F;span&gt;&lt;span&gt;       local ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)
&lt;&#x2F;span&gt;&lt;span&gt;       ]
&lt;&#x2F;span&gt;&lt;span&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-ellipsoid-sym&lt;&#x2F;span&gt;&lt;span&gt; local)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\frac{1}{2}\,{a}^{2}\,m\,{\cos}^{2}\left(\theta\left(t\right)\right)\,{\left(D\theta\left(t\right)\right)}^{2} + \frac{1}{2}\,{a}^{2}\,m\,{\sin}^{2}\left(\theta\left(t\right)\right)\,{\left(D\phi\left(t\right)\right)}^{2} + \frac{1}{2}\,{c}^{2}\,m\,{\left(D\theta\left(t\right)\right)}^{2}\,{\sin}^{2}\left(\theta\left(t\right)\right)
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Defining a parameteric transformation to rotate about the &amp;quot;z&amp;quot; axis
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;RotZ &lt;&#x2F;span&gt;&lt;span&gt;[angle]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[theta&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; phi]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up
&lt;&#x2F;span&gt;&lt;span&gt;        theta
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; phi angle))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Compose with &amp;quot;coordinate&amp;quot; to extract `q` from local tuple (t, q, qdot)
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;F-tilde &lt;&#x2F;span&gt;&lt;span&gt;[angle]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;RotZ&lt;&#x2F;span&gt;&lt;span&gt; angle) coordinate))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;F-tilde-rotated-by-s &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F-tilde &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;s))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Lagrangian after &amp;quot;s&amp;quot; degree rotation about X-axis
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-ellipsoid-sym-rotated
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q-prime]
&lt;&#x2F;span&gt;&lt;span&gt;          ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose&lt;&#x2F;span&gt;&lt;span&gt; L-ellipsoid-sym (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F-&amp;gt;C&lt;&#x2F;span&gt;&lt;span&gt; F-tilde-rotated-by-s))
&lt;&#x2F;span&gt;&lt;span&gt;           q-prime)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;phi))
&lt;&#x2F;span&gt;&lt;span&gt;       local ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)
&lt;&#x2F;span&gt;&lt;span&gt;       ]
&lt;&#x2F;span&gt;&lt;span&gt;     (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-ellipsoid-sym-rotated&lt;&#x2F;span&gt;&lt;span&gt; local)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\frac{1}{2}\,{a}^{2}\,m\,{\cos}^{2}\left(\theta\left(t\right)\right)\,{\left(D\theta\left(t\right)\right)}^{2} + \frac{1}{2}\,{a}^{2}\,m\,{\sin}^{2}\left(\theta\left(t\right)\right)\,{\left(D\phi\left(t\right)\right)}^{2} + \frac{1}{2}\,{c}^{2}\,m\,{\left(D\theta\left(t\right)\right)}^{2}\,{\sin}^{2}\left(\theta\left(t\right)\right)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The symmetry about $z$ axis is verified as the Lagrangian is unchanged post-rotation as shown above.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Define the Noether integral
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;the-Noether-integral
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) L-ellipsoid-sym) ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D&lt;&#x2F;span&gt;&lt;span&gt; F-tilde) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;the-Noether-integral
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta &amp;#39;phi)
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;thetadot &amp;#39;phidot))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
{a}^{2}\,m\,\dot {\phi}\,{\sin}^{2}\left(\theta\right)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The conserved quantity is $m (a\sin{\theta})^2\dot{\phi}$. Here, $\dot{\phi}$ is the rate of angular movement of the particle about the $z$ axis or the rate of change of longitude, and $a\sin(\theta)$ is the “radius”. This quantity is analogous to angular momentum.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Section 1.8.5: Noether&#x27;s Theorem</title>
        <published>2022-10-24T01:14:12+00:00</published>
        <updated>2022-10-24T01:14:12+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/section-1-8-5-noethers-theorem/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/section-1-8-5-noethers-theorem/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/section-1-8-5-noethers-theorem/">&lt;h2 id=&quot;1-8-5-noether-s-theorem&quot;&gt;1.8.5 Noether’s Theorem&lt;&#x2F;h2&gt;
&lt;p&gt;If a dynamical system has a symmetry, a coordinate system can be chosen so that the Lagrangian does not depend on a coordinate associated with the symmetry. There is also a conserved quantity associated with the symmetry (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;tgvaughan.github.io&#x2F;sicm&#x2F;chapter001.html#h1-6c&quot;&gt;Section 1.8&lt;&#x2F;a&gt;). However, there are general symmetries that no coordinate systems can fully express. For example, motion around a central potential is spherically symmetric, i.e., the dynamical system is invariant under rotation about any axis. However, the Lagrangian for this system only demonstrates symmetry about a single axis.&lt;&#x2F;p&gt;
&lt;p&gt;In general, &lt;strong&gt;a Lagrangian is said to have a symmetry if there exists a coordinate transformation that leaves the Lagrangian unchanged&lt;&#x2F;strong&gt;.
In this section we consider the more general case of &lt;strong&gt;continous symmetries&lt;&#x2F;strong&gt;. A &lt;strong&gt;continuous symmetry&lt;&#x2F;strong&gt; is defined as a parametric family of symmetries. &lt;strong&gt;Emmy Noether proved that for any continuous symmetry, there is a conserved quantity&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Consider a parametric coordinate transformation, $\widetilde{F}$ with parameter $s$. This means that $\widetilde{F}$ represents an infinite number of coordinate transformations, one for each value of $s$.&lt;&#x2F;p&gt;
&lt;p&gt;An example would be a function that takes an angle, $s$, as the input and spits out a coordinate transformation that rotates the primed coordinate frame, $x’$ about some axis by that angle.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
x = \widetilde{F}(s) (t, x&amp;#x27;)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;There is a corresponding parametreic state transformation $\widetilde{C}$ associated with $\widetilde{F}$ that transforms the velocity $v’$ as well the time (i.e. the local tuple that forms the input to the Lagrangian).&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
(t, x, v) &amp;amp;= \widetilde{C}(s) (t, x&amp;#x27;, v&amp;#x27;) \\
          &amp;amp;= (t, \widetilde{F}(t,x&amp;#x27;),  \partial_0 \widetilde{F} + \partial_1 \widetilde{F} v&amp;#x27;, ...)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We require that $\widetilde{F}(0)$ represent the identity transformation $x’ = \widetilde{F}(0)(t, x’)$, with $\widetilde{C}$ as the corresponding identity state transformation. If the Lagrangian $L$ has a continous symmetry corresponding to $\widetilde{F}$, then the Lagrangian should be unchanged when the coordinates are transformed using $\widetilde{F}$. Therefore:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\widetilde{L}(s) = L\cdot \widetilde{C}(s) = L\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;for any $s$. Expanding $\widetilde{C}$ in the above expression, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\widetilde{L}(s) = L\left(t,\quad\widetilde{F}(s)(t, x&amp;#x27;),\quad\partial_1\widetilde{F}(s)(t, x&amp;#x27;)v&amp;#x27; \right)\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Undoing the “chainrule” in the second term and writing it in terms of the total time derivative,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\widetilde{L}(s) = L\left(t,\quad\widetilde{F}(s)(t, x&amp;#x27;),\quad D_t\widetilde{F}(s)(t, x&amp;#x27;, v&amp;#x27;) \right)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;Note: One of the assumptions in the following derivation is that $\partial_0 L = \frac{\partial L}{\partial t} = 0$&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;That $\widetilde{L}(s) = L$ for any $s$ implies that $D\widetilde{L}(s) = 0$ (where the $D$ operator represents derivative w.r.t $s$). Therefore, applying the chain rule for each of the components of $\widetilde{L}$, the derivative of $\widetilde{L}$ w.r.t $s$ is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
0 &amp;amp;= D\widetilde({L}(s)(t, x&amp;#x27;, v&amp;#x27;))\\
  &amp;amp;= \left(\underbrace{\partial_0 L}_{=\frac{\partial L}{\partial t} = 0} + \partial_1 L(t, x, v)\right) (D\widetilde{F})(s)(t, x&amp;#x27;) + \underbrace{\partial_2 L(t,x,v) D(D_t\widetilde{F}(s)(t, x&amp;#x27;)}_{\text{can swap }D_t\text{ and }D\text{, as }D\text{ w.r.t }s\text{ is unstructured}} \\
  &amp;amp;= \partial_1 L(t, x, v) (D\widetilde{F})(s)(t, x&amp;#x27;) + \partial_2 L(t,x,v) D_t(D\widetilde{F}(s))(t, x&amp;#x27;) \\ 
  &amp;amp;= (\partial_1 L \circ \Gamma[q]) \left( (D\widetilde{F})(s) \circ \Gamma[q&amp;#x27;]\right) + (\partial_2 L \circ \Gamma[q])\left( D_t(D\widetilde{F}(s)) \circ \Gamma[q&amp;#x27;]\right) \tag{1.157}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;According to Lagrange equations, the first term of Eq. 1.157 is: $(\partial_1 L \circ \Gamma[q]) \left( (D\widetilde{F})(s) \circ \Gamma[q’]\right) = (D_t\partial_2 L \circ \Gamma[q]) \left((D\widetilde{F})(s) \circ \Gamma[q’]\right)$. Substituting this in Eq. 1.157,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
0 = (D_t \partial_2 L \circ \Gamma[q])\left( (D\widetilde{F}(s)) \circ \Gamma[q&amp;#x27;]\right) +  (\partial_2 L \circ \Gamma[q])\left( D_t(D\widetilde{F}(s)) \circ \Gamma[q&amp;#x27;]\right) \tag{1.159}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;When $s = 0$, since $\widetilde{F}(0)$ is the identity transformation, the paths $q$ and $q’$ are the same. Therefore, $\Gamma[q] = \Gamma[q’]$ and Eq. 1.158 becomes&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
0 &amp;amp;= \left ((D_t \partial_2 L)(D\widetilde{F}(0)) +  (\partial_2 L)(D_t(D\widetilde{F}(0)))\right) \circ \Gamma[q] \\
  &amp;amp;= D_t ((\partial_2 L) (D\widetilde{F}(0))) \circ \Gamma[q] \tag{1.160}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore the state function $\mathscr{I}$:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathscr{I} = (\partial_2 L) (D\widetilde{F}(0))
$$
&lt;&#x2F;div&gt;
&lt;p&gt;is conserved along all solution trajectories. This quantity is called the &lt;em&gt;&lt;strong&gt;Noether integral&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;. It is the product of the momentum $\partial_2 L$ and a vector associated with the symmetry.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;illustration-motion-in-a-central-potential&quot;&gt;Illustration : Motion in a Central Potential&lt;&#x2F;h3&gt;
&lt;p&gt;Consider the motion of a particle in a central potential. The Lagrangian in rectangular coordinates is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L(t; x,y,z; v_x, v_y, v_z) = \frac{1}{2} m \left( v_x^2 + v_y^2 + v_z^2\right) - U(\sqrt{x^2 + y^2 + z^2})
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Consider a parameteric rotation about the $z$-axis:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}x\\y\\z\end{pmatrix} = 
R_z(s)(\begin{pmatrix}x&amp;#x27;\\y&amp;#x27;\\z&amp;#x27;\end{pmatrix}) = \begin{pmatrix}x&amp;#x27; \cos{s} - y&amp;#x27;\sin{s}\\x&amp;#x27; \sin{s} + y&amp;#x27;\cos{s}\\z&amp;#x27;\end{pmatrix}
\tag{1.163}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Since a rotation is an orthogonal transformation, it does not change the magnitude of the vector,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
x^2 + y^2 + z^2 = (x&amp;#x27;)^2 + (y&amp;#x27;)^2 + (z&amp;#x27;)^2\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Similarly, differentiating Eq.1.163 along a path, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{pmatrix}v_x\\v_y\\v_z\end{pmatrix} =
R_z(s)\begin{pmatrix}v_x&amp;#x27;\\v_y&amp;#x27;\\v_z&amp;#x27;\end{pmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore, $v_x^2 + v_y^2 + v_z^2 = v_x’^2 + v_y’^2 + v_z’^2$. Combining these, we can see that the post-transformation Lagrangian $L’$ is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L&amp;#x27;(t; x&amp;#x27;,y,z&amp;#x27;; v_x&amp;#x27;,v_y&amp;#x27;,v_z&amp;#x27;) = \frac{1}{2} m \left( (v&amp;#x27;_x)^2 + (v&amp;#x27;_y)^2 + (v&amp;#x27;_z)^2\right) - U(\sqrt{(x&amp;#x27;)^2 + (y&amp;#x27;)^2 + (z&amp;#x27;)^2
})
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore $L’$ is the exact same function as $L$ and hence there is a conserved value corresponding to the rotational symmetry about the z-axis. The momenta are defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\partial_2 L = [m v_x, m v_y, m v_z]
$$
&lt;&#x2F;div&gt;
&lt;p&gt;and&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D\widetilde{F}(0)(t;x,y,z)=D\widetilde{R}_z(0)(x,y,z) = [ y, -x, 0]
$$
&lt;&#x2F;div&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Note about the $D$ operator&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The $D$ operator has the highest precedence, and therefore:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
D\widetilde{F}(0)(t; x,y,z) = D\widetilde{F}(s)(x, y, z)|_{s=0} = \left.\begin{bmatrix} -x \sin{s} - y\cos{s}\\x \cos{s} - y\sin{s}\\0\end{bmatrix}\right|_{s=0}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Here we are taking the derivative w.r.t $s$ and consider $x$, $y$ and $z$ to be constants. Also note that the original $\widetilde{F}(s)$ was defined in terms of the primed coordinates while here it was evaluated on the unprimed coordinates.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Therefore, the Noether integral is:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\mathscr{I}(t; x,y,z; v_x,v_y,v_z) &amp;amp;= ((\partial_2 L)(D\widetilde{F}(0))) (t; x,y,z; v_x,v_y,v_z) \\
&amp;amp;= mv_xy -mv_yx + (mv_z)(0) \\
&amp;amp;= m(yv_x - xv_y)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This is the $z$ component of the angular momentum vector, $\vec{x} \times m\vec{v}$&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;RotX &lt;&#x2F;span&gt;&lt;span&gt;[angle]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[x&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; z]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[ca (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; angle)
&lt;&#x2F;span&gt;&lt;span&gt;            sa (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; angle)]
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up&lt;&#x2F;span&gt;&lt;span&gt; x
&lt;&#x2F;span&gt;&lt;span&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; ca y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; sa z))
&lt;&#x2F;span&gt;&lt;span&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; sa y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; ca z))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;RotY &lt;&#x2F;span&gt;&lt;span&gt;[angle]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[x&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; z]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[ca (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; angle)
&lt;&#x2F;span&gt;&lt;span&gt;            sa (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; angle)]
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; ca x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; sa z))
&lt;&#x2F;span&gt;&lt;span&gt;              y
&lt;&#x2F;span&gt;&lt;span&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; sa x)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; ca z))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;RotZ &lt;&#x2F;span&gt;&lt;span&gt;[angle]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[x&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; z]]
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[ca (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; angle)
&lt;&#x2F;span&gt;&lt;span&gt;            sa (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; angle)]
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; ca x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; sa y))
&lt;&#x2F;span&gt;&lt;span&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; sa x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; ca y))
&lt;&#x2F;span&gt;&lt;span&gt;              z))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Coordinate transformation with three angular &amp;quot;inputs&amp;quot; for rotations about
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; all three axes
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Composing with `coordinate`, extracts the second element of the tuple that is passed in as the argument
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;F-tilde &lt;&#x2F;span&gt;&lt;span&gt;[angle-x angle-y angle-z]
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;RotX&lt;&#x2F;span&gt;&lt;span&gt; angle-x) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;RotY&lt;&#x2F;span&gt;&lt;span&gt; angle-y) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;RotZ&lt;&#x2F;span&gt;&lt;span&gt; angle-z) coordinate))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Lagrangian for motion in central potential
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-central-rectangular &lt;&#x2F;span&gt;&lt;span&gt;[m U]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[t q v]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; v))
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;U &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sqrt &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; q))))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Define the Noether integral
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;the-Noether-integral
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-central-rectangular &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;U))]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;partial &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;) L) ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;D&lt;&#x2F;span&gt;&lt;span&gt; F-tilde) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0 0 0&lt;&#x2F;span&gt;&lt;span&gt;))))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertex
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;the-Noether-integral
&lt;&#x2F;span&gt;&lt;span&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;t
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x &amp;#39;y &amp;#39;z)
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;v_x &amp;#39;v_y &amp;#39;v_z))))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{bmatrix}\displaystyle{- m\,v_y\,z + m\,v_z\,y}&amp;amp;\displaystyle{m\,v_x\,z - m\,v_z\,x}&amp;amp;\displaystyle{- m\,v_x\,y + m\,v_y\,x}\end{bmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;These are all three components of the angular momentum. Therefore, angular momentum is conserved for a particle in motion in a central potential&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exercise 1.21: A dumbbell</title>
        <published>2022-10-20T03:14:33+00:00</published>
        <updated>2022-10-20T03:14:33+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-21/"/>
        <id>https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-21/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/projects/sicm-workbook/sicm-exercise-1-21/">&lt;h3 id=&quot;exercise-1-21-a-dumbbell&quot;&gt;Exercise 1.21: A dumbbell&lt;&#x2F;h3&gt;
&lt;p&gt;In this exercise we will recapitulate the derivation of the Lagrangian for constrained systems for a particular simple system.&lt;&#x2F;p&gt;
&lt;p&gt;Consider two massive particles in the plane constrained by a massless rigid rod to remain a distance l apart, as in figure 1.5. There are apparently four degrees of freedom for two massive particles in the plane, but the rigid rod reduces this number to three.&lt;&#x2F;p&gt;
&lt;p&gt;We can uniquely specify the configuration with the redundant coordinates of the particles, say $x_0(t)$, $y_0(t)$ and $x_1(t)$, $y_1(t)$. The constraint $(x_1(t) − x_0(t))^2 + (y_1(t) − y_0(t))^2 = l^2$ eliminates one degree of freedom.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;projects&#x2F;sicm-workbook&#x2F;figure-1.5.jpg&quot; alt=&quot;Figure 1.5&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure 1.5&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;a. Write Newton’s equations for the balance of forces for the four rectangular coordinates of the two particles, given that the scalar tension in the rod is $F$.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
m_0 \ddot{x}_0 &amp;amp;= F \cos\theta = F \frac{x_1 - x_0}{l}\\
m_0 \ddot{y}_0 &amp;amp;= F \sin\theta = F \frac{y_1 - y_0}{l}\\
m_1 \ddot{x}_1 &amp;amp;= -F \cos\theta = -F \frac{x_1 - x_0}{l}\\
m_1 \ddot{y}_1 &amp;amp;= -F \sin\theta = -F \frac{x_1 - x_0}{l} \\
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;b. Write the formal Lagrangian $\mathbf{L}(t;x_0,y_0,x_1,y_1,F;\dot{x}_0,\dot{y}_0,\dot{x}_1,\dot{y}_1,\dot{F})$ such that Lagrange’s equations will yield the Newton’s equations you derived in part a.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Restating Eq. 1.93 from the book:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L(t; x, F; \dot{x}, \dot{F}) = \sum_\alpha \frac{1}{2}m_\alpha\mathbf{\dot{x}_\alpha}^2 - V(t,x) + \sum_{\{\alpha,\beta | \alpha&amp;lt;\beta, \beta\leftrightarrow\alpha\}} \frac{F_{\alpha\beta}}{2l_{\alpha\beta}}[ (\mathbf{x_\beta}(t) - \mathbf{x_\alpha}(t))^2 - l_{\alpha\beta}^2 ] \tag{1.93}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This is a Lagrangian that can reproduce Newton’s equations for particles constrained by a fixed-distance constraint using force $F_{\alpha\beta}$.&lt;&#x2F;p&gt;
&lt;p&gt;For the dumb-bell, the Lagrangian is&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
L = \frac{1}{2} \left(m_0 (\dot{x_0}^2 + \dot{y_0}^2) + m_1 (\dot{x_1}^2 + \dot{y_1}^2) \right) + \frac{F}{2l}[ (x_1 - x_0)^2 + (y_1 - y_0)^2 - l^2 ]
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-dumbbell &lt;&#x2F;span&gt;&lt;span&gt;[m0 m1 l]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[x0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; x1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; F]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[vx0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; vy0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; vx1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; vy1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; dF]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[T1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m0 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; vx0) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; vy0)))
&lt;&#x2F;span&gt;&lt;span&gt;              T2 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; vx1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; vy1)))
&lt;&#x2F;span&gt;&lt;span&gt;              dx (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; x1 x0)
&lt;&#x2F;span&gt;&lt;span&gt;              dy (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; y1 y0)
&lt;&#x2F;span&gt;&lt;span&gt;              dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; dx) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; dy))
&lt;&#x2F;span&gt;&lt;span&gt;              F-by-2l (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; F (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt; l))]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; T1 T2
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; F-by-2l (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; l)))
&lt;&#x2F;span&gt;&lt;span&gt;           )
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-dumbbell &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_0 &amp;#39;m_1 &amp;#39;l)
&lt;&#x2F;span&gt;&lt;span&gt;            state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_0) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y_0) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y_1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;F))
&lt;&#x2F;span&gt;&lt;span&gt;            local ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)
&lt;&#x2F;span&gt;&lt;span&gt;            ]
&lt;&#x2F;span&gt;&lt;span&gt;           (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L&lt;&#x2F;span&gt;&lt;span&gt; local)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\frac{\frac{1}{2}\,l\,m_0\,{\left(Dx_0\left(t\right)\right)}^{2} + \frac{1}{2}\,l\,m_0\,{\left(Dy_0\left(t\right)\right)}^{2} + \frac{1}{2}\,l\,m_1\,{\left(Dx_1\left(t\right)\right)}^{2} + \frac{1}{2}\,l\,m_1\,{\left(Dy_1\left(t\right)\right)}^{2} + \frac{-1}{2}\,{l}^{2}\,F\left(t\right) + \frac{1}{2}\,F\left(t\right)\,{\left(x_1\left(t\right)\right)}^{2} - F\left(t\right)\,x_1\left(t\right)\,x_0\left(t\right) + \frac{1}{2}\,F\left(t\right)\,{\left(x_0\left(t\right)\right)}^{2} + \frac{1}{2}\,F\left(t\right)\,{\left(y_1\left(t\right)\right)}^{2} - F\left(t\right)\,y_1\left(t\right)\,y_0\left(t\right) + \frac{1}{2}\,F\left(t\right)\,{\left(y_0\left(t\right)\right)}^{2}}{l}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Deriving Lagrange equations for L-dumbbell
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-dumbbell &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-dumbbell &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_0 &amp;#39;m_1 &amp;#39;l)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_0) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y_0) 
&lt;&#x2F;span&gt;&lt;span&gt;                              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y_1) 
&lt;&#x2F;span&gt;&lt;span&gt;                              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;F))]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-dumbbell&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{\frac{l\,m_0\,{D}^{2}x_0\left(t\right) + F\left(t\right)\,x_1\left(t\right) - F\left(t\right)\,x_0\left(t\right)}{l}} \cr \cr \displaystyle{\frac{l\,m_0\,{D}^{2}y_0\left(t\right) + F\left(t\right)\,y_1\left(t\right) - F\left(t\right)\,y_0\left(t\right)}{l}} \cr \cr \displaystyle{\frac{l\,m_1\,{D}^{2}x_1\left(t\right) - F\left(t\right)\,x_1\left(t\right) + F\left(t\right)\,x_0\left(t\right)}{l}} \cr \cr \displaystyle{\frac{l\,m_1\,{D}^{2}y_1\left(t\right) - F\left(t\right)\,y_1\left(t\right) + F\left(t\right)\,y_0\left(t\right)}{l}} \cr \cr \displaystyle{\frac{\frac{1}{2}\,{l}^{2} + \frac{-1}{2}\,{\left(x_1\left(t\right)\right)}^{2} + x_1\left(t\right)\,x_0\left(t\right) + \frac{-1}{2}\,{\left(x_0\left(t\right)\right)}^{2} + \frac{-1}{2}\,{\left(y_1\left(t\right)\right)}^{2} + y_1\left(t\right)\,y_0\left(t\right) + \frac{-1}{2}\,{\left(y_0\left(t\right)\right)}^{2}}{l}}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;These equations of motion are equivalent to the Newtonian equations derivated initially, along with the constraint equation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;1.21 c. Make a change of coordinates to a coordinate system with center of mass coordinates $x_{CM}$, $y_{CM}$, angle $\theta$, distance between the particles $c$, and tension force $F$. Write the Lagrangian in these coordinates, and write the Lagrange equations.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Mass $m_0$ is at a distance $\frac{m_1 c}{m_0 + m_1}$ from the center of mass and $m_1$ is at a distance $\frac{m_0 c}{m_0 + m_1}$ from the center of mass. Therefore the change of coordinates can be defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
x_0 = x_{CM} - \frac{m_1 c}{m_0 + m_1} \cos{\theta} \\
y_0 = y_{CM} - \frac{m_1 c}{m_0 + m_1} \sin{\theta} \\
x_1 = x_{CM} + \frac{m_0 c}{m_0 + m_1} \cos{\theta} \\
y_1 = y_{CM} + \frac{m_0 c}{m_0 + m_1} \sin{\theta} \\
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We can use the &lt;code&gt;F-&amp;gt;C&lt;&#x2F;code&gt; coordinate change function to derive the new Lagrangian.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Coordinate transform from CM-coordinates to rectangular
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;CM-&amp;gt;rect &lt;&#x2F;span&gt;&lt;span&gt;[m0 m1]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[x_cm&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y_cm&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; theta&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; F]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _ ]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[total-mass (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; m0 m1)
&lt;&#x2F;span&gt;&lt;span&gt;              m0dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; c (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; m1 total-mass))
&lt;&#x2F;span&gt;&lt;span&gt;              m1dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; c (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; m0 total-mass))
&lt;&#x2F;span&gt;&lt;span&gt;              ]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up 
&lt;&#x2F;span&gt;&lt;span&gt;                (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; x_cm (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m0dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta)))
&lt;&#x2F;span&gt;&lt;span&gt;                (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; y_cm (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m0dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta)))
&lt;&#x2F;span&gt;&lt;span&gt;                (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; x_cm (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m1dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta)))
&lt;&#x2F;span&gt;&lt;span&gt;                (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; y_cm (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m1dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta)))
&lt;&#x2F;span&gt;&lt;span&gt;                F
&lt;&#x2F;span&gt;&lt;span&gt;             )
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-dumbbell-CM &lt;&#x2F;span&gt;&lt;span&gt;[m0 m1 l]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q-prime]
&lt;&#x2F;span&gt;&lt;span&gt;      ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-dumbbell&lt;&#x2F;span&gt;&lt;span&gt; m0 m1 l) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F-&amp;gt;C &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;CM-&amp;gt;rect&lt;&#x2F;span&gt;&lt;span&gt; m0 m1)))
&lt;&#x2F;span&gt;&lt;span&gt;       q-prime)))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-dumbbell-CM &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_0 &amp;#39;m_1 &amp;#39;l)
&lt;&#x2F;span&gt;&lt;span&gt;            state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_CM) 
&lt;&#x2F;span&gt;&lt;span&gt;                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y_CM) 
&lt;&#x2F;span&gt;&lt;span&gt;                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) 
&lt;&#x2F;span&gt;&lt;span&gt;                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;c) 
&lt;&#x2F;span&gt;&lt;span&gt;                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;F))
&lt;&#x2F;span&gt;&lt;span&gt;            local ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)
&lt;&#x2F;span&gt;&lt;span&gt;            ]
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L&lt;&#x2F;span&gt;&lt;span&gt; local)
&lt;&#x2F;span&gt;&lt;span&gt;          ))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\frac{l\,m_0\,m_1\,{\left(c\left(t\right)\right)}^{2}\,{\left(D\theta\left(t\right)\right)}^{2} + l\,{m_0}^{2}\,{\left(Dx_{CM}\left(t\right)\right)}^{2} + l\,{m_0}^{2}\,{\left(Dy_{CM}\left(t\right)\right)}^{2} + l\,m_0\,m_1\,{\left(Dc\left(t\right)\right)}^{2} + 2\,l\,m_0\,m_1\,{\left(Dx_{CM}\left(t\right)\right)}^{2} + 2\,l\,m_0\,m_1\,{\left(Dy_{CM}\left(t\right)\right)}^{2} + l\,{m_1}^{2}\,{\left(Dx_{CM}\left(t\right)\right)}^{2} + l\,{m_1}^{2}\,{\left(Dy_{CM}\left(t\right)\right)}^{2} - {l}^{2}\,m_0\,F\left(t\right) - {l}^{2}\,m_1\,F\left(t\right) + m_0\,F\left(t\right)\,{\left(c\left(t\right)\right)}^{2} + m_1\,F\left(t\right)\,{\left(c\left(t\right)\right)}^{2}}{2\,l\,m_0 + 2\,l\,m_1}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Computing Lagrange Equations
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-dumbbell-cm &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-dumbbell-CM &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_0 &amp;#39;m_1 &amp;#39;l)))
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_CM) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y_CM) 
&lt;&#x2F;span&gt;&lt;span&gt;                              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) 
&lt;&#x2F;span&gt;&lt;span&gt;                              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;c) 
&lt;&#x2F;span&gt;&lt;span&gt;                              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;F))]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-dumbbell-cm&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{m_0\,{D}^{2}x_{CM}\left(t\right) + m_1\,{D}^{2}x_{CM}\left(t\right)} \cr \cr \displaystyle{m_0\,{D}^{2}y_{CM}\left(t\right) + m_1\,{D}^{2}y_{CM}\left(t\right)} \cr \cr \displaystyle{\frac{m_0\,m_1\,{\left(c\left(t\right)\right)}^{2}\,{D}^{2}\theta\left(t\right) + 2\,m_0\,m_1\,c\left(t\right)\,D\theta\left(t\right)\,Dc\left(t\right)}{m_0 + m_1}} \cr \cr \displaystyle{\frac{- l\,m_0\,m_1\,c\left(t\right)\,{\left(D\theta\left(t\right)\right)}^{2} + l\,m_0\,m_1\,{D}^{2}c\left(t\right) - m_0\,F\left(t\right)\,c\left(t\right) - m_1\,F\left(t\right)\,c\left(t\right)}{l\,m_0 + l\,m_1}} \cr \cr \displaystyle{\frac{\frac{1}{2}\,{l}^{2} + \frac{-1}{2}\,{\left(c\left(t\right)\right)}^{2}}{l}}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;From the first two equations, the acceleration of the center of mass is zero. From the 5th equation, we can deduce that $c(t) = l$ and therefore, $Dc = 0$ and $D^2 c = 0$.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;1.21d. You may deduce from one of these equations that $c(t) = l$. From this fact we get that $D c = 0$ and $D^2 c = 0$. Substitute these into the Lagrange equations you just computed to get the equation of motion for $x_{CM}$, $y_{CM}$, $\theta$.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Substituting $c(t) = l$ in the EOMs, we get:
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_CM) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y_CM) 
&lt;&#x2F;span&gt;&lt;span&gt;                              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta) 
&lt;&#x2F;span&gt;&lt;span&gt;                              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[t] &amp;#39;l) 
&lt;&#x2F;span&gt;&lt;span&gt;                              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;F))]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-dumbbell-cm&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{m_0\,{D}^{2}x_{CM}\left(t\right) + m_1\,{D}^{2}x_{CM}\left(t\right)} \cr \cr \displaystyle{m_0\,{D}^{2}y_{CM}\left(t\right) + m_1\,{D}^{2}y_{CM}\left(t\right)} \cr \cr \displaystyle{\frac{{l}^{2}\,m_0\,m_1\,{D}^{2}\theta\left(t\right)}{m_0 + m_1}} \cr \cr \displaystyle{\frac{- l\,m_0\,m_1\,{\left(D\theta\left(t\right)\right)}^{2} - m_0\,F\left(t\right) - m_1\,F\left(t\right)}{m_0 + m_1}} \cr \cr \displaystyle{0}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;The third equation now reduces to $\ddot{\theta} = 0$. The fourth equation has the quantity $\frac{m_0 m_1}{m_0 + m_1}$ which is called the “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Reduced_mass&quot;&gt;reduced mass&lt;&#x2F;a&gt;” in a Newtonian two-body problem. ().&lt;&#x2F;p&gt;
&lt;p&gt;Substituting the reduced mass as $m$ in the fourth EOM, we get:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
-l m \dot{\theta}^2 = F(t)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This expression is very similar to the expression for centrifugal force.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;1.21e. Make a Lagrangian ($= T − V$) for the system described with the irredundant generalized coordinates $x_{CM}$, $y_{CM}$, $\theta$ and compute the Lagrange equations from this Lagrangian. They should be the same equations as you derived for the same coordinates in part d.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We define a Lagrangian for two free particles with masses $m_0$ and $m_1$ and then apply a coordinate transformation to the irredundant coordinates using &lt;code&gt;F-&amp;gt;C&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Lagrangian with just the end particles
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-free-two-particles &lt;&#x2F;span&gt;&lt;span&gt;[m0 m1]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[vx0 vy0 vx1 vy1]]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[T0 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m0 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; vx0) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; vy0)))
&lt;&#x2F;span&gt;&lt;span&gt;              T1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;* &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&#x2F;2&lt;&#x2F;span&gt;&lt;span&gt; m1 (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; vx1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;square&lt;&#x2F;span&gt;&lt;span&gt; vy1)))]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; T0 T1)
&lt;&#x2F;span&gt;&lt;span&gt;    )))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Coordinate transform with irredundant coordinates (unlike in part d, no &amp;quot;c&amp;quot; or &amp;quot;F&amp;quot; here)
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;dumbbell-&amp;gt;rect &lt;&#x2F;span&gt;&lt;span&gt;[m0 m1 l]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[[_&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;[x_cm&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; y_cm&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; theta]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; _ ]]
&lt;&#x2F;span&gt;&lt;span&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[total-mass (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; m0 m1)
&lt;&#x2F;span&gt;&lt;span&gt;              m0dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; l (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; m1 total-mass))
&lt;&#x2F;span&gt;&lt;span&gt;              m1dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; l (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt; m0 total-mass))
&lt;&#x2F;span&gt;&lt;span&gt;              ]
&lt;&#x2F;span&gt;&lt;span&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up 
&lt;&#x2F;span&gt;&lt;span&gt;                (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; x_cm (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m0dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta)))
&lt;&#x2F;span&gt;&lt;span&gt;                (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; y_cm (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m0dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta)))
&lt;&#x2F;span&gt;&lt;span&gt;                (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; x_cm (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m1dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt; theta)))
&lt;&#x2F;span&gt;&lt;span&gt;                (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; y_cm (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; m1dist (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt; theta)))
&lt;&#x2F;span&gt;&lt;span&gt;             )
&lt;&#x2F;span&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;       
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;defn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;L-dumbbell-part-e &lt;&#x2F;span&gt;&lt;span&gt;[m0 m1 l]
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span&gt;[q-prime]
&lt;&#x2F;span&gt;&lt;span&gt;      ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;compose &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-free-two-particles&lt;&#x2F;span&gt;&lt;span&gt; m0 m1) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;F-&amp;gt;C &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;dumbbell-&amp;gt;rect&lt;&#x2F;span&gt;&lt;span&gt; m0 m1 l)))
&lt;&#x2F;span&gt;&lt;span&gt;       q-prime)))
&lt;&#x2F;span&gt;&lt;span&gt;        
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendermd
&lt;&#x2F;span&gt;&lt;span&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[L (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-dumbbell-part-e &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_0 &amp;#39;m_1 &amp;#39;l)
&lt;&#x2F;span&gt;&lt;span&gt;            state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_CM) 
&lt;&#x2F;span&gt;&lt;span&gt;                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y_CM) 
&lt;&#x2F;span&gt;&lt;span&gt;                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta))
&lt;&#x2F;span&gt;&lt;span&gt;            local ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Gamma&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)
&lt;&#x2F;span&gt;&lt;span&gt;            ]
&lt;&#x2F;span&gt;&lt;span&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L&lt;&#x2F;span&gt;&lt;span&gt; local)
&lt;&#x2F;span&gt;&lt;span&gt;          ))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    $$
\frac{{l}^{2}\,m_0\,m_1\,{\left(D\theta\left(t\right)\right)}^{2} + {m_0}^{2}\,{\left(Dx_{CM}\left(t\right)\right)}^{2} + {m_0}^{2}\,{\left(Dy_{CM}\left(t\right)\right)}^{2} + 2\,m_0\,m_1\,{\left(Dx_{CM}\left(t\right)\right)}^{2} + 2\,m_0\,m_1\,{\left(Dy_{CM}\left(t\right)\right)}^{2} + {m_1}^{2}\,{\left(Dx_{CM}\left(t\right)\right)}^{2} + {m_1}^{2}\,{\left(Dy_{CM}\left(t\right)\right)}^{2}}{2\,m_0 + 2\,m_1}
$$
&lt;&#x2F;div&gt;
&lt;pre data-lang=&quot;clojure&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-clojure &quot;&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;;; Computing Lagrange Equations
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;eom-dumbbell-part-e &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;Lagrange-equations &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;L-dumbbell-part-e &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;m_0 &amp;#39;m_1 &amp;#39;l)))
&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;rendertexvec &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;[state (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;up &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;x_CM) (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;y_CM) 
&lt;&#x2F;span&gt;&lt;span&gt;                              (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;literal-function &lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;theta))]
&lt;&#x2F;span&gt;&lt;span&gt;            ((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;eom-dumbbell-part-e&lt;&#x2F;span&gt;&lt;span&gt; state) &amp;#39;t)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div&gt;
    \begin{pmatrix}\displaystyle{m_0\,{D}^{2}x_{CM}\left(t\right) + m_1\,{D}^{2}x_{CM}\left(t\right)} \cr \cr \displaystyle{m_0\,{D}^{2}y_{CM}\left(t\right) + m_1\,{D}^{2}y_{CM}\left(t\right)} \cr \cr \displaystyle{\frac{{l}^{2}\,m_0\,m_1\,{D}^{2}\theta\left(t\right)}{m_0 + m_1}}\end{pmatrix}
&lt;&#x2F;div&gt;
&lt;p&gt;These equations of motion are identical to the ones obtained in &lt;strong&gt;part d&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Coordinate Functions aka Charts</title>
        <published>2022-10-16T06:26:58.868+00:00</published>
        <updated>2022-10-16T06:26:58.868+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202209152326-differential-geometry-coordinate-functions-or-charts/"/>
        <id>https://www.thomasantony.com/notes/202209152326-differential-geometry-coordinate-functions-or-charts/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202209152326-differential-geometry-coordinate-functions-or-charts/">&lt;p&gt;A coordinate function $\chi$ maps a point in a coordinate patch of a &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202209152300-differential-geometry-manifolds&#x2F;&quot;&gt;manifold&lt;&#x2F;a&gt; to a coordinate tuple of real numbers:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
x = \chi(m)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $x$ represents a convenient tuple structure. $x$ is usually represented as an “up vector” indexed by superscripts. The number of components of $x$ is equal to the number of dimensions of the manifold.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;coordinate-transformations&quot;&gt;Coordinate transformations&lt;&#x2F;h2&gt;
&lt;p&gt;Assume we have two coordinate functions $\chi$ and $\chi’$. The coordinate transformation from $\chi’$ coordinates to $\chi’$ coordinates is just the composition $\chi \circ \chi’^{-1}$, where $\chi’^{-1}
$ is the functional inverse of $\chi’$&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Point On A Manifold</title>
        <published>2022-10-16T06:20:21.404+00:00</published>
        <updated>2022-10-16T06:20:21.404+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202209152320-differential-geometry-point/"/>
        <id>https://www.thomasantony.com/notes/202209152320-differential-geometry-point/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202209152320-differential-geometry-point/">&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is just my current understanding while studying &lt;em&gt;Functional Differential Geometry&lt;&#x2F;em&gt;. This may be completely wrong and may change in the future.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;A point on a manifold is an abstract entity representing a location&#x2F;place on the manifold. When we actually do anything with a point, we use coordinates to represent it. Coordinate functions or &lt;em&gt;charts&lt;&#x2F;em&gt; are used to convert a point into a coordinate tuple. These charts may also have an “inverse”. However the inverse is always used along with another chart in order to get a different coordinate tuple.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Manifolds</title>
        <published>2022-10-16T06:00:54.961+00:00</published>
        <updated>2022-10-16T06:00:54.961+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202209152300-differential-geometry-manifolds/"/>
        <id>https://www.thomasantony.com/notes/202209152300-differential-geometry-manifolds/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202209152300-differential-geometry-manifolds/">&lt;p&gt;A &lt;em&gt;manifold&lt;&#x2F;em&gt; is a generalization of the idea of a smooth surface embedded in Euclidean space. The critical feature of an n-dimensional manifold is that locally (near any point), it looks like n-dimensional Euclidean space.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;parts-of-a-manifold&quot;&gt;Parts of a Manifold&lt;&#x2F;h2&gt;
&lt;p&gt;Around every &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202209152320-differential-geometry-point&#x2F;&quot;&gt;point&lt;&#x2F;a&gt; on the manifold, is a “simply-connected open set” called the &lt;em&gt;coordinate patch&lt;&#x2F;em&gt;, that maps every point to a tuple of n real numbers, and a one-to-one continuous function, the &lt;em&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202209152326-differential-geometry-coordinate-functions-or-charts&#x2F;&quot;&gt;coordinate function&lt;&#x2F;a&gt;&lt;&#x2F;em&gt; or &lt;em&gt;chart&lt;&#x2F;em&gt;, mapping every point in that open set to a tuple of n real numbers, the &lt;em&gt;coordinates&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A consistent system of coordinate patches and coordinate functions that covers the entire manifold is called an &lt;em&gt;atlas&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;examples&quot;&gt;Examples&lt;&#x2F;h2&gt;
&lt;p&gt;An example of a two-dimensional manifold is the surface of a sphere or of a coffee cup. The space of all configurations of a double pendulum is a more abstract example (and has the shape of a torus).&lt;&#x2F;p&gt;
&lt;p&gt;An example of a coordinate function is mapping of points on a sphere to the tuple of latitude and longitude. It is to be noted that the “simply connected open set” or “patch” here does not include either poles (as longitude is undefined at the poles ) or the 180 deg meridian (due to discontinuity in longitude). These places will have to be covered by other coordinate systems.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;xahlee.info&#x2F;math&#x2F;i&#x2F;functional_geometry_2013_sussman_14322.pdf&quot;&gt;Functional Differential Geometry&lt;&#x2F;a&gt;, Sussman and Wisdom&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Generating Perpendicular Basis Vectors in a Plane</title>
        <published>2022-10-14T03:14:56.441+00:00</published>
        <updated>2022-10-14T03:14:56.441+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202209132014-generating-perpendicular-basis-vectors-in-a-plane/"/>
        <id>https://www.thomasantony.com/notes/202209132014-generating-perpendicular-basis-vectors-in-a-plane/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202209132014-generating-perpendicular-basis-vectors-in-a-plane/">&lt;p&gt;This is an easier&#x2F;less computationally expensive method compared to the one described in &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202207231849-points-in-a-plane-using-null-space&#x2F;&quot;&gt;Points in a plane using null space&lt;&#x2F;a&gt;. This is based on &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202209132012-cross-product-by-matrix-multiplication&#x2F;&quot;&gt;Cross Product By Matrix Multiplication&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We start with the unit vector $\mathbf{u}$, normal to the plane of interest. We compute the cross product matrix $U_\times$ as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
U_\times = \begin{bmatrix}
0    &amp;amp; -u_3 &amp;amp; u_2\\
u_3  &amp;amp; 0  &amp;amp; -u_1\\
-u_2 &amp;amp; u_1 &amp;amp; 0
\end{bmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $u_1$, $u_2$ and $u_3$ are the components of $\mathbf{u}$. Since $\mathbf{u}$ is a non-null unit vector, either the first or the second column of $U_\times$ will be a non-null vector. This vector will also be perpendicular to $\mathbf{u}$. This can be verified by the dot product:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
(\text{Column 1}) \cdot \mathbf{u} &amp;amp;= u_3 u_2 - u_2 u_3 = 0 \\
(\text{Column 2}) \cdot \mathbf{u} &amp;amp;= -u_3 u_1 + u_1 u_3 = 0 \\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We pick either the first or second column of $U_\times$ and convert it into a unit vector, depending on whichever one is non-null. This will be the first of the orthogonal unit vectors, $\mathbf{v}$. The second orthogonal unit vector is computed as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{w} = \frac{\mathbf{u} \times \mathbf{v}}{|\mathbf{u} \times \mathbf{v}|}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Linear combinations of $\mathbf{v}$ and $\mathbf{w}$ can be used to generate vectors in the plane normal to $\mathbf{u}$.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cross Product by Matrix Multiplication</title>
        <published>2022-10-14T03:12:52.909+00:00</published>
        <updated>2022-10-14T03:12:52.909+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202209132012-cross-product-by-matrix-multiplication/"/>
        <id>https://www.thomasantony.com/notes/202209132012-cross-product-by-matrix-multiplication/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202209132012-cross-product-by-matrix-multiplication/">&lt;p&gt;For two vectors $\vec{a}$ and $\vec{b}$, the cross product $\vec{a} \times \vec{b}$ can be computed using matrix multiplcation&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\vec{a} \times \vec{b} = A_\times \vec{b}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $A_\times$ is defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
A_\times = \begin{bmatrix}
0    &amp;amp; -a_3 &amp;amp; a_2\\
a_3  &amp;amp; 0  &amp;amp; -a_1\\
-a_2 &amp;amp; a_1 &amp;amp; 0
\end{bmatrix}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $a_1$, $a_2$ and $a_3$ are the components of $\vec{a}$.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cross_product#Conversion_to_matrix_multiplication&quot;&gt;Cross Product: Conversion to Matrix Multiplication&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bdot attitude controller</title>
        <published>2022-09-15T01:34:31.565+00:00</published>
        <updated>2022-09-15T01:34:31.565+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202208141834-bdot-attitude-controller/"/>
        <id>https://www.thomasantony.com/notes/202208141834-bdot-attitude-controller/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202208141834-bdot-attitude-controller/">&lt;p&gt;A “bdot” (or $\mathbf{\dot{B}}$) attitude controller is used to detumble a spacecraft using just a magnetometer and torque rods. It does not require any other rate-sensing instruments like gyros. The controller is usually implemented as a derivative controller acting on the sensed magnetic field $\mathbf{B}$. The control torque in the body frame is defined as:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\tau_x = - \frac{k_x \mathbf{\dot{B}}_x}{|\mathbf{B}|}, \quad
\tau_y = - \frac{k_y \mathbf{\dot{B}}_y}{|\mathbf{B}|}, \quad
\tau_z = - \frac{k_z \mathbf{\dot{B}}_y}{|\mathbf{B}|}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\mathbf{\dot{B}}_i$ is the component of the derivative of $\mathbf{B}$ about the $i$ axis. $\mathbf{\dot{B}}$ is computed using a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; title=&quot;Smooth Low Noise Differentiators&quot; href=&quot;http:&#x2F;&#x2F;www.holoborodko.com&#x2F;pavel&#x2F;numerical-methods&#x2F;numerical-derivative&#x2F;smooth-low-noise-differentiators&#x2F;&quot;&gt;digital differentiator filter&lt;&#x2F;a&gt; from discrete samples of $\mathbf{B}$.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;caveats&quot;&gt;Caveats&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This method will obviously only work when the spacecraft is operating within a magnetic field (e.g. in near-Earth space)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The sampling cadence should be set up such that the use of the torque rods do not cause errors in magnetometer measurements. This can be ensured by sampling the data when the torque rods are not energized. That should also be sufficient delay after the rods are turned off in order to avoid residual effects from the rods’ magnetic fields.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>NAND2Tetris Note 05 - Hack Assembly Language</title>
        <published>2022-09-05T04:09:53.894+00:00</published>
        <updated>2022-09-05T04:09:53.894+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202208042109-nand2tetris-note-05-hack-assembly-language/"/>
        <id>https://www.thomasantony.com/notes/202208042109-nand2tetris-note-05-hack-assembly-language/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202208042109-nand2tetris-note-05-hack-assembly-language/">&lt;p&gt;The “Hack” computer built during this course has its own instruction set consisting of two instructions: the A-command and the C-command.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;registers&quot;&gt;Registers&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;A&lt;&#x2F;code&gt; -&amp;gt; address. Used to access memory
&lt;code&gt;D&lt;&#x2F;code&gt; -&amp;gt; General purpose data register
&lt;code&gt;M&lt;&#x2F;code&gt; -&amp;gt; Psuedo register that actually accesses &lt;code&gt;RAM[A]&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-instruction&quot;&gt;A-instruction&lt;&#x2F;h2&gt;
&lt;p&gt;Denoted as &lt;code&gt;@&amp;lt;a&amp;gt;&lt;&#x2F;code&gt; where &lt;code&gt;a&lt;&#x2F;code&gt; is a positive number, this instruction loads the specified literal into the &lt;code&gt;A&lt;&#x2F;code&gt; (or address) register. This is encoded as:&lt;&#x2F;p&gt;
&lt;p&gt;0 &amp;lt;value (15 bits)&amp;gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;c-instruction&quot;&gt;C-instruction&lt;&#x2F;h2&gt;
&lt;p&gt;The c-command has the format: &lt;code&gt;dest = comp; jmp&lt;&#x2F;code&gt;, where &lt;code&gt;dest&lt;&#x2F;code&gt; is the destination (if any), &lt;code&gt;comp&lt;&#x2F;code&gt; is the computation to be performed and &lt;code&gt;jmp&lt;&#x2F;code&gt; is a jumpy instruction. This is encoded as the following in a 16-bit instruction:&lt;&#x2F;p&gt;
&lt;p&gt;111 a c1 c2 c3 c4 c5 c6 d1 d2 d3 j1 j2 j3
^
denotes “C”&lt;&#x2F;p&gt;
&lt;p&gt;a through c6 defines the computation to be performed as inputs to the ALU. There is a table describing every operation allowed here. d1 d2 d3 defines the destination of the computation (or 0 0 0 for null), j1 j2 j3 reperesents a jump instruction (conditional, uncondtional, null etc.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;i-o&quot;&gt;I&#x2F;O&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x2F;O is performed by writing&#x2F;reading from specific memory addresses. Display on the screen is accomplished by writing to 8K 16-bit registers starting at address &lt;code&gt;16384&lt;&#x2F;code&gt;. Each bit represents a pixel in a 256x512 matrix stored in row-major form.&lt;&#x2F;p&gt;
&lt;p&gt;For pixel at (row, col):
32*row + col&#x2F;16  -&amp;gt; word index
col % 16 -&amp;gt; bit index within word&lt;&#x2F;p&gt;
&lt;p&gt;The keyboard value is represented by a single 16-bit value at the address &lt;code&gt;24576&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;assembly-language&quot;&gt;Assembly language&lt;&#x2F;h2&gt;
&lt;p&gt;R1-R15 are built-in symbols for addresses from 1-15. This helps remove confusion between literals and addresses to some extent when using the A instruction. SCREEN and KBD and I&#x2F;O base addresses.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;labels&quot;&gt;Labels&lt;&#x2F;h3&gt;
&lt;p&gt;Labels can be specified as (LABEL). This can be used as jump destinations. Example:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;&#x2F;&#x2F; Infinite loop
&lt;&#x2F;span&gt;&lt;span&gt;(END)
&lt;&#x2F;span&gt;&lt;span&gt;@END
&lt;&#x2F;span&gt;&lt;span&gt;0;JMP
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;variables&quot;&gt;Variables&lt;&#x2F;h3&gt;
&lt;p&gt;@&lt;name&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Automatically uses an available memory address as long as there is no corresponding label. Allocated from address 16 onward.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>NAND2Tetris Note 04 - Sequential Logic and Memory</title>
        <published>2022-09-04T19:36:00.037+00:00</published>
        <updated>2022-09-04T19:36:00.037+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202208041236-nand2tetris-note-04-sequential-logic-and-memory/"/>
        <id>https://www.thomasantony.com/notes/202208041236-nand2tetris-note-04-sequential-logic-and-memory/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202208041236-nand2tetris-note-04-sequential-logic-and-memory/">&lt;p&gt;All of the chips described in the previous course notes used what is called “combinational logic”, where the output is available instantenously and there is no time-component to their operation. Combinational chips compute functions that depend solely on combinations of their input values.&lt;&#x2F;p&gt;
&lt;p&gt;Sequential logic incorporates the concept of time, or more specifically, discretized time in the form of a clock signal into determining their output. This is the core concept behind digital circuits with memory. Just like how NAND formed the basic building blocks of combinational logic, the “D-Flip-Flip” is the fundamental building block used to build sequential logic. A D-Flip-Flop can be built out of nand-gates using a loop-based design but that is beyond the scope of the course.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;clocked-data-flip-flop-d-flip-flop-or-dff&quot;&gt;Clocked Data Flip Flop (D Flip-Flop or DFF)&lt;&#x2F;h2&gt;
&lt;p&gt;The D Flip-Flop has one input “in” and one output “out”. There’s also an implicit “clock” signal that cycles from high to low and back to high to make a single “clock cycle”. The output of the D flip-flip is simply the input of the last time step (with the output of the initial timestep being indeterminate).&lt;&#x2F;p&gt;
&lt;p&gt;D-Flip-Flops are combined in various ways with combinational logic circuits to build up basic memory units like a 1-bit register, larger addressed registers (RAM) and counters that form the basis of computer memory.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;one-bit-register&quot;&gt;One-Bit Register&lt;&#x2F;h2&gt;
&lt;p&gt;A bit regsiter has two inputs “in” and “load” and a single output “out”. The output is the same as the last output if “load” is zero. It is equal to “in” if “load” is set to one. The HDL imlementation uses a Mux to select between the lastOutput and the current input. This is then passed into a DFF and the output of the DFF is the output of the register.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;Mux(a=lastOutput, b=in, sel=load, out=dffIn);
&lt;&#x2F;span&gt;&lt;span&gt;DFF(in=dffIn, out=out, out=lastOutput);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The output of the DFF is fanned out to the input of the Mux as well. This is possible because HDL is &lt;em&gt;not&lt;&#x2F;em&gt; a programming language. It can be thought of as a description of electrical wiring. So the output line of the DFF is looped back to the input of the Mux here.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;16-bit-register&quot;&gt;16-bit register&lt;&#x2F;h2&gt;
&lt;p&gt;A 16-bit register chip has a 16-bit input &lt;code&gt;in&lt;&#x2F;code&gt;, a single bit &lt;code&gt;load&lt;&#x2F;code&gt; input and a 16-bit output, &lt;code&gt;out&lt;&#x2F;code&gt;. This can be implemented by stacking 8 one-bit register and fanning out the load input to all of them. The inputs and outputs of each “bit” chip is wired to the individual bits of &lt;code&gt;in&lt;&#x2F;code&gt; and &lt;code&gt;out&lt;&#x2F;code&gt; respectively.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ram8-chip&quot;&gt;RAM8 chip&lt;&#x2F;h2&gt;
&lt;p&gt;This is a chip that can store 8 “words” (in this case 16-bit words). The chip has a 16-bit &lt;code&gt;in&lt;&#x2F;code&gt; input, 3-bit &lt;code&gt;address&lt;&#x2F;code&gt;  input and a 16-bit output, &lt;code&gt;out&lt;&#x2F;code&gt;. It uses a Demuxer to split out the &lt;code&gt;address&lt;&#x2F;code&gt; into 8 different &lt;code&gt;load&lt;&#x2F;code&gt; bits which are then fed into &lt;code&gt;Register&lt;&#x2F;code&gt; chips. &lt;code&gt;in&lt;&#x2F;code&gt; is fanned out to all the underlying &lt;code&gt;Register&lt;&#x2F;code&gt; chips. The outputs of the registers are then connected to the &lt;code&gt;out&lt;&#x2F;code&gt; pin through a Multiplexer with the &lt;code&gt;address&lt;&#x2F;code&gt; as its selector.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ram64-ram512-ram4k-and-ram16k&quot;&gt;RAM64, RAM512, RAM4K and RAM16K&lt;&#x2F;h2&gt;
&lt;p&gt;These are built in the same manner as &lt;code&gt;RAM8&lt;&#x2F;code&gt; but by composing &lt;code&gt;RAMx&lt;&#x2F;code&gt; chips using a Demuxer and Muxer. &lt;code&gt;RAM64&lt;&#x2F;code&gt; has a 6-bit &lt;code&gt;address&lt;&#x2F;code&gt; input, where the 3 most-significant bits select the underlying &lt;code&gt;RAM8&lt;&#x2F;code&gt; chip and the 3 LSBs signify the address in the underlying &lt;code&gt;RAM8&lt;&#x2F;code&gt;. Therefore the &lt;code&gt;load&lt;&#x2F;code&gt; bit is wired to the &lt;code&gt;RAM8&lt;&#x2F;code&gt; chips through a Demuxer with &lt;code&gt;address[3..5]&lt;&#x2F;code&gt; as the &lt;code&gt;sel&lt;&#x2F;code&gt; input and &lt;code&gt;address[0..2]&lt;&#x2F;code&gt; is passed through directly to the underlying chips. The output is similarly muxed using &lt;code&gt;address[3..5]&lt;&#x2F;code&gt; as the selector. The higher capacity chips are built in the same way by stacking 4 or 8 lower capacity chips and an appropriately sized Demuxer and Muxer.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>NAND2Tetris Note 03 - The Hack ALU</title>
        <published>2022-09-04T19:35:45.742+00:00</published>
        <updated>2022-09-04T19:35:45.742+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202208041235-nand2tetris-note-03-the-hack-alu/"/>
        <id>https://www.thomasantony.com/notes/202208041235-nand2tetris-note-03-the-hack-alu/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202208041235-nand2tetris-note-03-the-hack-alu/">&lt;p&gt;The Airthmetic and Logic Unit is a core part of a computer based on the Von Neumann architecture. It consists of digital circuitry that can perform a variety of arthmetic or logic operations as the name suggests. The Nand2Tetris has a relative simple design for an ALU that can perform a few different functions defined below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The ALU Computes one of the following functions:
&lt;ul&gt;
&lt;li&gt;x+y, x-y, y-x, 0, 1, -1, x, y, -x, -y, !x, !y,&lt;&#x2F;li&gt;
&lt;li&gt;x+1, y+1, x-1, y-1, x&amp;amp;y, x|y on two 16-bit inputs,&lt;&#x2F;li&gt;
&lt;li&gt;according to 6 input bits denoted zx,nx,zy,ny,f,no.&lt;&#x2F;li&gt;
&lt;li&gt;In addition, the ALU computes two 1-bit outputs:&lt;&#x2F;li&gt;
&lt;li&gt;if the ALU output == 0, zr is set to 1; otherwise zr is set to 0;&lt;&#x2F;li&gt;
&lt;li&gt;if the ALU output &amp;lt; 0, ng is set to 1; otherwise ng is set to 0.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The input bits &lt;code&gt;zx&lt;&#x2F;code&gt;, &lt;code&gt;nx&lt;&#x2F;code&gt;, &lt;code&gt;zy&lt;&#x2F;code&gt; and &lt;code&gt;ny&lt;&#x2F;code&gt; define the “pre-processing” tasks to be performed on the inputs &lt;code&gt;x&lt;&#x2F;code&gt; and &lt;code&gt;y&lt;&#x2F;code&gt; prior to computation. &lt;code&gt;zx&lt;&#x2F;code&gt; zeros out the whole &lt;code&gt;x&lt;&#x2F;code&gt; input if set to one and nx inverts the input (after the effect of &lt;code&gt;zx&lt;&#x2F;code&gt; if any) if it is set to true. &lt;code&gt;zy&lt;&#x2F;code&gt; and &lt;code&gt;ny&lt;&#x2F;code&gt; performs similar actions on the y input. &lt;code&gt;f&lt;&#x2F;code&gt; selects between the operations &lt;code&gt;x &amp;amp; y&lt;&#x2F;code&gt; (if f == 0) and &lt;code&gt;x + y&lt;&#x2F;code&gt; (if f == 1). &lt;code&gt;no&lt;&#x2F;code&gt; performs a bitwise inverse on the output of the operation due to &lt;code&gt;f&lt;&#x2F;code&gt; if it is set to true. Different combinations of input flags results in one of the 18 operations described above.&lt;&#x2F;p&gt;
&lt;p&gt;The two extra outputs &lt;code&gt;zr&lt;&#x2F;code&gt; and &lt;code&gt;ng&lt;&#x2F;code&gt; are set based on the characteristics of the final output. This ALU design is specific to the “Hack” computer being developed as part of this course. Other computers may have more options implemented in the ALU. This is a design trade-off as to how many operations need to be implemented in hardware as opposed to software. In case of “Hack”, operations like multiplication and division will be implemented in software later.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Two&#x27;s Complement Notation for Binary Addition</title>
        <published>2022-09-04T03:41:18.681+00:00</published>
        <updated>2022-09-04T03:41:18.681+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202208032041-two-s-complement-notation-for-binary-addition/"/>
        <id>https://www.thomasantony.com/notes/202208032041-two-s-complement-notation-for-binary-addition/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202208032041-two-s-complement-notation-for-binary-addition/">&lt;p&gt;Two’s complement is a format for representing negative numbers in binary. A number &lt;code&gt;-X&lt;&#x2F;code&gt; is represented as an &lt;code&gt;N&lt;&#x2F;code&gt; bit value using the binary value of &lt;code&gt;2^N-X&lt;&#x2F;code&gt;. E.g. -5 in 4-bit integers would be &lt;code&gt;2^4 - 5&lt;&#x2F;code&gt; = &lt;code&gt;11&lt;&#x2F;code&gt; (or &lt;code&gt;0b1010&lt;&#x2F;code&gt;). The advantage of using this representation is that it makes addition of negative numbers possible with existing binary adder circuits (or logic gate implementation). The reason this works is that the output we get from an adder circuit is actually the “modulo 2^n” representation.&lt;&#x2F;p&gt;
&lt;p&gt;Example: -2 + -3 using 4-bit integers&lt;&#x2F;p&gt;
&lt;p&gt;-2 in 2’s complement is 2^4 - 2 = 16-2 = 14 or &lt;code&gt;0b1110&lt;&#x2F;code&gt;
-3 in 2’s complement is 2^4 - 3 = 16-3 = 13 or &lt;code&gt;0b1101&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Performing binary addition of &lt;code&gt;0b1110&lt;&#x2F;code&gt; and &lt;code&gt;0b1101&lt;&#x2F;code&gt; we get, &lt;code&gt;0b1011&lt;&#x2F;code&gt; and a carry bit of 1 which is discarded. &lt;code&gt;0b1011&lt;&#x2F;code&gt; is &lt;code&gt;11&lt;&#x2F;code&gt; in decimal. This is equal to &lt;code&gt;-5&lt;&#x2F;code&gt; in 2’s complement representation which is the correct answer.&lt;&#x2F;p&gt;
&lt;p&gt;In order to do subtractions using a digital adder circuit, it becomes necessary to compute “-x” given a value “x”. This is done as follows:&lt;&#x2F;p&gt;
&lt;p&gt;Negative value of X in 2’s complement notation is given by&lt;&#x2F;p&gt;
&lt;p&gt;2^n - x = 1 + 2^n - 1 - x = 1 + (2^n -1 ) - x
= 1 + (0b111111… - x)
= 1 + ~X where ~ is the bitwise inverse
= ~(X + 0b11111…) (from ALU truth table)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-properties&quot;&gt;Other properties&lt;&#x2F;h2&gt;
&lt;p&gt;(x + 1) = ~(~x + 0b1111….)
(x - 1) = x + 0b1111….
(x - y) = ~(~x + y)
(y - x) = ~(x + y)&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;Nand2Tetris Unit 2.3&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Two%27s_complement#Addition&quot;&gt;Two’s complement - Wikipedia&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>NAND2Tetris Note 02 - Elementary Logic Gates</title>
        <published>2022-09-01T04:35:04.243+00:00</published>
        <updated>2022-09-01T04:35:04.243+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202207312135-nand2tetris-note-02-elementary-logic-gates/"/>
        <id>https://www.thomasantony.com/notes/202207312135-nand2tetris-note-02-elementary-logic-gates/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202207312135-nand2tetris-note-02-elementary-logic-gates/">&lt;h2 id=&quot;elementary-logic-gates&quot;&gt;Elementary Logic Gates&lt;&#x2F;h2&gt;
&lt;p&gt;NOT
AND
OR
XOR =&amp;gt; output 1 if inputs different
MUX: =&amp;gt; a, b, sel; if sel == 0: out = a, else: out = b
DMUX: =&amp;gt; in, sel (outputs a and b): if sel == 0: a = in else b = in&lt;&#x2F;p&gt;
&lt;h2 id=&quot;16-bit-variants&quot;&gt;16-bit variants&lt;&#x2F;h2&gt;
&lt;p&gt;NOT16 : 16 bits in and out
AND16 : Two 16-bit inputs, One 16-it output
OR16 : Two 16-bit inputs, One 16-it output&lt;&#x2F;p&gt;
&lt;h2 id=&quot;multi-way-variants&quot;&gt;Multi-way variants&lt;&#x2F;h2&gt;
&lt;p&gt;Or8Way : Single 16-bit input, 1 bit output
Mux4Way16 : Four 16-bit inputs, One 2-bit “sel” input, One 8-bit output
Mux8Way16 : Eight 16-bit inputs, One 3-bit “sel” input, One 8-bit ouput
DMux4Way : Single 1-bit input, 2-bit selector, Four 1-bit outputs
DMux8Way : Single 1-bit input, 3-bit selector, Eight 1-bit outputs&lt;&#x2F;p&gt;
&lt;p&gt;The multi-way mux and dmux can be implemented by composing the other mux&#x2F;dmux components.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>NAND2Tetris Note 01</title>
        <published>2022-09-01T01:49:00.451+00:00</published>
        <updated>2022-09-01T01:49:00.451+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202207311849-nand2tetris-note-01/"/>
        <id>https://www.thomasantony.com/notes/202207311849-nand2tetris-note-01/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202207311849-nand2tetris-note-01/">&lt;p&gt;Nand2tetris is a course where we build a full general purpose computer up from basic logic gates - in fact, just NAND gates. This is because a NAND gate can be used to form all the other basic logic gates - AND, OR and NOT. The “hardware” will be built in a simplified Hardware Description Language (or HDL). This HDL is similar to the “actual” HDLs like Verilog and VHDL. The course also introduces a “testing” language which provides a way to define a bunch of test cases with inputs and outputs for a given “chip” spec. The supplied “Hardware Simulation” program is able to load HDL files as well as testing scripts and verify designs.&lt;&#x2F;p&gt;
&lt;p&gt;The goal is to build up the next building blocks - CPU, RAM and “chipset” from the basic logic gates, and tehn build it into a computer platform with its own assembly language. Later the second part of the course involves building a language called “Hack” which can presumably be used to build Tetris.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Points in a plane using null space</title>
        <published>2022-08-24T01:49:19.119+00:00</published>
        <updated>2022-08-24T01:49:19.119+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202207231849-points-in-a-plane-using-null-space/"/>
        <id>https://www.thomasantony.com/notes/202207231849-points-in-a-plane-using-null-space/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202207231849-points-in-a-plane-using-null-space/">&lt;p&gt;A plane can be defined using its normal vector &lt;code&gt;n&lt;&#x2F;code&gt;. Points in the plane represented by this vector can be generated by first computing the null space of this vector. This gives the two basis vectors (assuming 3D space) for the plane. These basis vectors can then be scaled as necessary to generate points. For example, to generate a circle of points in a plane:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;numpy &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span&gt;np
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;scipy &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span&gt;sp
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;scipy.linalg
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;n = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;array&lt;&#x2F;span&gt;&lt;span&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;]);
&lt;&#x2F;span&gt;&lt;span&gt;plane_basis = sp.linalg.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;null_space&lt;&#x2F;span&gt;&lt;span&gt;([n])
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;numPoints = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;4
&lt;&#x2F;span&gt;&lt;span&gt;theta = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;linspace&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;*np.pi, numPoints+&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;x = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;cos&lt;&#x2F;span&gt;&lt;span&gt;(theta[:-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;])
&lt;&#x2F;span&gt;&lt;span&gt;y = np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span&gt;(theta[:-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;])
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;# points is a 3xnumPoints matrix where each column is a point
&lt;&#x2F;span&gt;&lt;span&gt;points = plane_basis @ np.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;array&lt;&#x2F;span&gt;&lt;span&gt;([x, y])
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;An easier&#x2F;less expensive method can be found at [[202209132014_generating-perpendicular-basis-vectors-in-a-plane]]&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Allocating Torques to Reaction Wheels</title>
        <published>2022-08-20T01:49:19.119+00:00</published>
        <updated>2022-08-20T01:49:19.119+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202207231848-allocating-torques-to-reaction-wheels/"/>
        <id>https://www.thomasantony.com/notes/202207231848-allocating-torques-to-reaction-wheels/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202207231848-allocating-torques-to-reaction-wheels/">&lt;p&gt;Allocating torques to RWAs are accomplished by first defining a “distribution matrix” which contains the spin axes of the individual wheels, and then using this matrix to allocate torques.Each column of the distribution matrix consists of the unit vector for the spin axis of one wheel, resulting in a 3xN matrix for an RWA with N wheels.&lt;&#x2F;p&gt;
&lt;p&gt;In general:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;tau_RWA = rwaMatrixInv * tau_b + alpha * rwaNullSpace
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where &lt;code&gt;tau_b&lt;&#x2F;code&gt; is the required torque in the body frame, &lt;code&gt;rwaMatrixInv&lt;&#x2F;code&gt; is the inverse of the distribution matrix, &lt;code&gt;alpha&lt;&#x2F;code&gt; is a row vector of size &lt;code&gt;m&lt;&#x2F;code&gt; where &lt;code&gt;m&lt;&#x2F;code&gt; is the nullity of &lt;code&gt;rwaMatrix&lt;&#x2F;code&gt; .&lt;&#x2F;p&gt;
&lt;p&gt;For a three wheel system, the null space is empty and therefore the second term of the above expression does not apply.There is a unique solution to allocate any torques for a properly oriented RWA.The solution is the one that minimizes the L2 norm of the allocated torques and is a unique solution.&lt;&#x2F;p&gt;
&lt;p&gt;For RWAs with  more than three wheels, the null-space presents flexibility in allocating torques to satisfy various conditions.If &lt;code&gt;alpha&lt;&#x2F;code&gt; is selected as a zero vector, the solution minimizes the L2-norm of the allocated torques.&lt;code&gt;alpha&lt;&#x2F;code&gt; can be selected to further optimize the allocation to satisfy other conditions.Minimizing the L-infinity norm of hte torque better uses the capacity of the RWA.However, computing alpha in the general case is non-trivial.Ref [1] describes a method for minimizing the L-infinity norm for four-wheel RWAs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;four-wheel-reaction-wheel-allocator-for-pyramid-configurations&quot;&gt;Four wheel reaction wheel allocator for pyramid configurations&lt;&#x2F;h2&gt;
&lt;p&gt;For a four wheel system, the nullity of &lt;code&gt;rwaMatrix&lt;&#x2F;code&gt; is equal to one and hence &lt;code&gt;alpha&lt;&#x2F;code&gt; is a scalar.i.e.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;tau_L2 = rwaMatrixInv * tau_b
&lt;&#x2F;span&gt;&lt;span&gt;tau_Linf = tau_L2 + alpha * tau_null
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where &lt;code&gt;tau_null&lt;&#x2F;code&gt; is the null space of &lt;code&gt;rwaMatrix&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For symmetric 4 wheel configurations, &lt;code&gt;tau_null&lt;&#x2F;code&gt; is equal to &lt;code&gt;[1, 1, 1, 1]&lt;&#x2F;code&gt; and the value of alpha can be computed as:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;alpha = - (min(tau_L2) + max(tau_L2))&#x2F;2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For non-symmetric pyramid configurations, a different method is used where six separate values are computed as follows:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;alpha_1 = - (tau_L2(1) + tau_L2(2)) &#x2F; ( tau_null(1) + tau_null(2) )
&lt;&#x2F;span&gt;&lt;span&gt;alpha_2 = - (tau_L2(1) + tau_L2(3)) &#x2F; ( tau_null(1) + tau_null(3) )
&lt;&#x2F;span&gt;&lt;span&gt;alpha_3 = - (tau_L2(1) + tau_L2(4)) &#x2F; ( tau_null(1) + tau_null(4) )
&lt;&#x2F;span&gt;&lt;span&gt;alpha_4 = - (tau_L2(2) + tau_L2(3)) &#x2F; ( tau_null(2) + tau_null(3) )
&lt;&#x2F;span&gt;&lt;span&gt;alpha_5 = - (tau_L2(2) + tau_L2(4)) &#x2F; ( tau_null(2) + tau_null(4) )
&lt;&#x2F;span&gt;&lt;span&gt;alpha_6 = - (tau_L2(3) + tau_L2(4)) &#x2F; ( tau_null(3) + tau_null(4) )
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The value of alpha that gives the smallest maximum absolute value of &lt;code&gt;tau_rwa&lt;&#x2F;code&gt; is selected.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The above algorthms assume that the null space of &lt;code&gt;rwaMatrix&lt;&#x2F;code&gt; is entirely positive (or equal to &lt;code&gt;[1, 1, 1, 1]&lt;&#x2F;code&gt; in case of symmetric RWAs).However, it is possible that some of these may be negative based on how the axes are oriented.In this case, the sign of the corresponding column in &lt;code&gt;rwaMatrix&lt;&#x2F;code&gt; is the be negated and the direction of the torque allocated for that particular wheel has to be reversed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;[1] “Optimal uses of reaction wheels in the pyramid configuration using a new minimum infinity-norm solution”, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.researchgate.net&#x2F;publication&#x2F;265687712_Optimal_uses_of_reaction_wheels_in_the_pyramid_configuration_using_a_new_minimum_infinity-norm_solution&quot;&gt;Link&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What is TLA+?</title>
        <published>2022-06-10T03:31:49.999+00:00</published>
        <updated>2022-06-10T03:31:49.999+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202205092031-what-is-tla/"/>
        <id>https://www.thomasantony.com/notes/202205092031-what-is-tla/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202205092031-what-is-tla/">&lt;p&gt;TLA+ is a language for creating “specifications” for computer programs&#x2F;algorithms and then verify all the possible execution paths and mathematically prove assertions. The program is represented as a state machine where everything from variables to the program counter “pc” is part of the state. The spec contains an initial state and rule specifying “next state” as a bunch of logical statements linked by “and” (&#x2F;) or “or” aka &#x2F; clauses.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=rkZzg7Vowao&quot;&gt;The Man Who Revolutionized Computer Science With Math&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;lamport.azurewebsites.net&#x2F;video&#x2F;intro.html&quot;&gt;Introduction to TLA+&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Attitude Control using Reaction Wheels</title>
        <published>2022-05-19T05:47:36.416+00:00</published>
        <updated>2022-05-19T05:47:36.416+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202204182247-attitude-control-using-reaction-wheels/"/>
        <id>https://www.thomasantony.com/notes/202204182247-attitude-control-using-reaction-wheels/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202204182247-attitude-control-using-reaction-wheels/">&lt;p&gt;Reactions wheels are used for controlling spacecraft attitude to a very high precision. It works by using an electric motor to spin a flywheel that causes the spacecraft to rotate in the opposite direction. A set of three orthogonally arranged reaction wheels can fully control the spacecraft attitude. In an isolated system, a reaction wheel assembly (RWA) can be used indefinitely without requiring any energy input other than power for the motors. However, disturbance torques add energy into the system, causing the angular momentum of the wheels to increase. When they get saturated, some other source of torque, such as RCS thrusters or torque-rods need to be used to desaturate them.&lt;&#x2F;p&gt;
&lt;p&gt;Torque allocation to a 3-wheel system can be accomplished by projecting the torque vector to each individual spin axis via a dot product. With more than three wheels, the added degrees of freedom results in an infinite number of possible solutions. The optimal solution in this case is picked by one of the following strategies. More generalized strategies are available for &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202207231848-allocating-torques-to-reaction-wheels&#x2F;&quot;&gt;allocating torques&lt;&#x2F;a&gt; in systems with more than three reaction wheels [1].&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;[1] Section 4.3.8, “Fundamentals of Spacecraft Attitude Determination and Control”, Markley, F. L. and Crassidis, J. L.,&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>TRIAD Algorithm For Attitude Determination</title>
        <published>2022-04-04T03:13:13.208+00:00</published>
        <updated>2022-04-04T03:13:13.208+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202203032013-triad-algorithm-for-attitude-determination/"/>
        <id>https://www.thomasantony.com/notes/202203032013-triad-algorithm-for-attitude-determination/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202203032013-triad-algorithm-for-attitude-determination/">&lt;p&gt;The TRIAD or Tri-Axial Attitude Determination algorithm is used for attitude determination given two body-frame vectors ($b_1$ and $b_2$) and two corresponding inertial or “reference” frame vectors ($r_1$ and $r_2$). The attitude is determined as an “Attitude matrix”, $\mathbf{A}$, which is the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; title=&quot;Direction Cosine Matrix&quot; href=&quot;https:&#x2F;&#x2F;en.wikiversity.org&#x2F;wiki&#x2F;PlanetPhysics&#x2F;Direction_Cosine_Matrix&quot;&gt;DCM&lt;&#x2F;a&gt; that rotates the vectors from the reference frame to the body frame.&lt;&#x2F;p&gt;
&lt;p&gt;The first vector is assumed to have more accurate measurement and so the algorithm is set up such that the estimate satisfies $\mathbf{A} r_1 = b_1$, exactly and $\mathbf{A} r_2 = b_2$ only approximately.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;algorithm&quot;&gt;Algorithm&lt;&#x2F;h2&gt;
&lt;p&gt;The TRIAD algorithm forms the orthogonal triads, {$v_1$, $v_2$, $v_3$} from $r_1$ and $r_2$ and {$w_1$, $w_2$, $w_3$} from $b_1$ and $b_2$, respectively.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
v_1 &amp;amp;= r_1,&amp;amp;\quad v_2 = r_x = \frac{r_1 \times r_2}{||r_1 \times r_1||},&amp;amp; \quad &amp;amp;v_3 = r_1 &amp;amp;\times r_x&amp;amp; \\
w_1 &amp;amp;= b_1,&amp;amp;\quad w_2 = b_x = \frac{b_1 \times b_2}{||b_1 \times b_1||},&amp;amp; \quad &amp;amp;w_3 = b_1 &amp;amp;\times b_x&amp;amp;
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The estimate of A is given by:
$$
\mathbf{A} = w_1 v_1^\intercal + w_3 v_3^\intercal + w_2 v_2^\intercal
$$&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Solving VulnHub CTF - Mercury</title>
        <published>2022-03-20T05:08:47.753+00:00</published>
        <updated>2022-03-20T05:08:47.753+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202202192208-solving-vulnhub-ctf-mercury/"/>
        <id>https://www.thomasantony.com/notes/202202192208-solving-vulnhub-ctf-mercury/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202202192208-solving-vulnhub-ctf-mercury/">&lt;p&gt;Used a walkthrough for tips here. Here are the rough steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Run kali linux VM alongside the CTF vm with &lt;a href=&quot;https:&#x2F;&#x2F;www.thomasantony.com&#x2F;notes&#x2F;202202192208-running-virtualbox-vms-with-networking&#x2F;&quot;&gt;Running Virtualbox VMs with networking&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Run &lt;code&gt;sudo netdiscover&lt;&#x2F;code&gt; to find out the IP of target&lt;&#x2F;li&gt;
&lt;li&gt;Run &lt;code&gt;nmap &amp;lt;ip&amp;gt;&lt;&#x2F;code&gt; to discover open ports and find that &lt;code&gt;8080&lt;&#x2F;code&gt; is open&lt;&#x2F;li&gt;
&lt;li&gt;Port 8080 hosts a web app that can be accessed through the browser&lt;&#x2F;li&gt;
&lt;li&gt;Visit &lt;code&gt;&#x2F;robots.txt&lt;&#x2F;code&gt; to find a new path &lt;code&gt;&#x2F;mercuryfacts&lt;&#x2F;code&gt;. (&lt;code&gt;dirb&lt;&#x2F;code&gt; command in kali can also be used to “discover” robots.txt if not known already)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;mercuryfacts&#x2F;&amp;lt;id&amp;gt;&lt;&#x2F;code&gt; is vulnerable to SQL injection as found by putting backtick in place of the ID&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;sqlmap&lt;&#x2F;code&gt; can be used to further exploit this to eventually show passwords in the table &lt;code&gt;users&lt;&#x2F;code&gt; in the database &lt;code&gt;mercury&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The password for &lt;code&gt;webmaster&lt;&#x2F;code&gt; can be used to ssh into the machine. &lt;code&gt;cat user_flag.txt&lt;&#x2F;code&gt; for user flag.&lt;&#x2F;li&gt;
&lt;li&gt;Check the &lt;code&gt;mercuryfacts&#x2F;notes.txt&lt;&#x2F;code&gt; file to see a base64 encoded password for &lt;code&gt;linuxmaster&lt;&#x2F;code&gt;. Login as &lt;code&gt;linuxmaster&lt;&#x2F;code&gt;. Run &lt;code&gt;sudo -l&lt;&#x2F;code&gt; to figure out what all commands are allowed. Discover the script at &lt;code&gt;&#x2F;usr&#x2F;bin&#x2F;check_syslog.sh&lt;&#x2F;code&gt; that uses the &lt;code&gt;tail&lt;&#x2F;code&gt; command&lt;&#x2F;li&gt;
&lt;li&gt;Add current directory to PATH. Create a symlink to &lt;code&gt;vim&lt;&#x2F;code&gt; named &lt;code&gt;tail&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Run &lt;code&gt;sudo –preserve-env=PATH &#x2F;usr&#x2F;bin&#x2F;check_syslog.sh&lt;&#x2F;code&gt; to enter vim as superuser&lt;&#x2F;li&gt;
&lt;li&gt;Run &lt;code&gt;:!&#x2F;bin&#x2F;sh&lt;&#x2F;code&gt; to enter root shell.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;cat &#x2F;root&#x2F;root_flag.txt&lt;&#x2F;code&gt; for root flag&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Running Virtualbox VMs with networking</title>
        <published>2022-03-20T05:08:45.753+00:00</published>
        <updated>2022-03-20T05:08:45.753+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202202192208-running-virtualbox-vms-with-networking/"/>
        <id>https://www.thomasantony.com/notes/202202192208-running-virtualbox-vms-with-networking/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202202192208-running-virtualbox-vms-with-networking/">&lt;p&gt;Run the VMs with “Host-Only Networking”. This should allow each VM to get its own IP address and let them communicate with each other.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Solve Wordle Using Information Theory</title>
        <published>2022-02-06T17:05:33.089+00:00</published>
        <updated>2022-02-06T17:05:33.089+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202201061105-solve-wordle-using-information-theory/"/>
        <id>https://www.thomasantony.com/notes/202201061105-solve-wordle-using-information-theory/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202201061105-solve-wordle-using-information-theory/">&lt;p&gt;This is a note about how to use information theory to create an optimal strategy for solving “Wordle”.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;initial-ideas&quot;&gt;Initial ideas&lt;&#x2F;h2&gt;
&lt;p&gt;For any given word, we can find a distribution for probabilities for each pattern of colors that could be revealed. Example, for “WEARY”, there is some number of words that do not contain any of the letters, some that contain W, some with W and E, some with E at the first position, etc.&lt;&#x2F;p&gt;
&lt;p&gt;We can geenrate the list of all possible outcomes for a given word, and check how many words in the list match the patterns to come up with a probability.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Key&lt;&#x2F;strong&gt; A guess is “informative” if it is unlikely, i.e., the more unlikely the  pattern, the fewer possibilities remain to be checked. A highly unlikely guess, if correct, significantly cuts down the solution space.&lt;&#x2F;p&gt;
&lt;p&gt;The expected amount of information from the distribution for a certain word is&lt;&#x2F;p&gt;
&lt;p&gt;$$
E[\text{Information}] = \sum_x {p(x) \cdot \text{Something}}
$$&lt;&#x2F;p&gt;
&lt;p&gt;This “something” should measure how informative that pattern is. We could try to lower the average number of matches. The fewer the number of matches for a pattern, the more informative that pattern is. Instead we can use a concept from information theory.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-a-bit&quot;&gt;What is a “bit”?&lt;&#x2F;h2&gt;
&lt;p&gt;An observation that can cut the space of possibilities in half, that is called a bit of information.&lt;&#x2F;p&gt;
&lt;p&gt;Therefore&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;p(1 bit) = 1&#x2F;2
&lt;&#x2F;span&gt;&lt;span&gt;p(2 bits) = 1&#x2F;4
&lt;&#x2F;span&gt;&lt;span&gt;p(3 bits) = 1&#x2F;8 etc.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or, for information $I$&lt;&#x2F;p&gt;
&lt;p&gt;$$
\left(\frac{1}{2}\right)^I = p \implies 2^I = \frac{1}{p}\
I = \log_2{\left(\frac{1}{p}\right)}
$$&lt;&#x2F;p&gt;
&lt;p&gt;This is a better way of representing probability. You can say that you get 20 bits of information instead of saying that the probability of such a thing occuring is 0.00000095.&lt;&#x2F;p&gt;
&lt;p&gt;Information (or bits) add together the same way probabilities multiply, thanks to the logarithm.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;applying-information-theory-to-the-problem&quot;&gt;Applying information theory to the problem&lt;&#x2F;h2&gt;
&lt;p&gt;$$
E[\text{Information}] = \sum_x {p(x) \cdot \log_2{\left(\frac{1}{p(x)}\right)}
}
$$&lt;&#x2F;p&gt;
&lt;p&gt;This is the average number of bits you could get from a  certain word. The higher the probability of seeing a pattern, the lower the number of bits.&lt;&#x2F;p&gt;
&lt;p&gt;This metric can be used to rank the guess in order of number of expected bits of information.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;**This expected value of information is also called “entropy” ($H$). This was a suggestion by von Neumann to Claude Shannon. While this has some connection to the entropy from thermodynamics, Shannon was dealing purely with probability distribution when he used the term. **&lt;&#x2F;p&gt;
&lt;h2 id=&quot;strategy&quot;&gt;Strategy&lt;&#x2F;h2&gt;
&lt;p&gt;First give a guess based on the word that gives the highest expected number of bits of information. Then for the next guess use the more restricted list of words based on the result of the first guess, and so on.&lt;&#x2F;p&gt;
&lt;p&gt;The solver can be run across every single word in the word-list to work out an average score.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-better-strategy&quot;&gt;A better strategy?&lt;&#x2F;h2&gt;
&lt;p&gt;Assign a probability for each word for being in the final list based on frequency of use in the English language instead of a uniform distribution. Grant ranks them by frequency and uses a sigmoid function to assign probabilities. Use this to measure the “remaining uncertainty” of the possible word candidates left. So even if the number of possible words is higher, the uncertainty would be lower thanks to the weighted distribution.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;expected-score&quot;&gt;Expected Score&lt;&#x2F;h2&gt;
&lt;p&gt;TBD.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;[1] &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=v68zYyaEmEA&quot;&gt;The mathematically optimal Wordle strategy&lt;&#x2F;a&gt;, 3Blue1Brown&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Orbiter Addon Development in Rust</title>
        <published>2022-01-10T23:49:12-06:00</published>
        <updated>2022-01-10T23:49:12-06:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/posts/orbiter-addon-rust/"/>
        <id>https://www.thomasantony.com/posts/orbiter-addon-rust/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/posts/orbiter-addon-rust/">&lt;p&gt;This short article will explore how to create a spacecraft addon for the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;orbit.medphys.ucl.ac.uk&#x2F;&quot;&gt;Orbiter&lt;&#x2F;a&gt; spaceflight simulator in the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;rust-lang.org&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt; programming language. I previously took a stab at this back in 2020 with &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;RustMFD&quot;&gt;limited success&lt;&#x2F;a&gt;. I was much less knowledgeable about Rust at the time and the tooling around C++ bindings were not as mature then. This post is a companion to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;orbiter-rs&quot;&gt;this new repository&lt;&#x2F;a&gt; that contains a proof-of-concept for building a spacecraft addon for Orbiter in Rust.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-rust&quot;&gt;Why Rust?&lt;&#x2F;h2&gt;
&lt;p&gt;Rust is a relatively new high level systems programming language with a focus on safety. Orbiter is written in C++ and therefore its addons are also typically written in C++. Rust development for Orbiter is facilitated using the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cxx.rs&quot;&gt;cxx&lt;&#x2F;a&gt; crate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;design&quot;&gt;Design&lt;&#x2F;h2&gt;
&lt;p&gt;The repository in its current form produces a DLL file as its build artifact that can be loaded into Orbiter as an addon module. &lt;del&gt;Anyone wanting to create a Rust addon will clone&#x2F;fork the repository and build it along with the the Rust code for their addon.&lt;&#x2F;del&gt;(See update below).&lt;&#x2F;p&gt;
&lt;p&gt;There are a limited number of Orbiter SDK functions currently available as Rust bindings in this prototype.
This will expand in the future to hopefully encompass the majority of the API. The repository includes a demo addon that models NASA’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Surveyor_program&quot;&gt;Surveyor&lt;&#x2F;a&gt; probe. This follows from the C++ tutorial at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.orbiterwiki.org&#x2F;wiki&#x2F;Vessel_Tutorial_1&quot;&gt;OrbiterWiki&lt;&#x2F;a&gt; and implements retro-thruster staging and differential thrust attitude control.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;developing-custom-spacecraft-addons&quot;&gt;Developing custom spacecraft addons&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update 01&#x2F;11&#x2F;2022: This section has been changed to reflect changes to the crate&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;
&lt;del&gt;All the spacecraft-specific code in the repository lives in its own file (&lt;code&gt;src&#x2F;shuttle_pb.rs&lt;&#x2F;code&gt; for example).&lt;&#x2F;del&gt;
An addon crate implementing a spacecraft should import the &lt;code&gt;orbiter_rs&lt;&#x2F;code&gt; crate. It should then set its crate-type to &lt;code&gt;cdylib&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;toml&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-toml &quot;&gt;&lt;code class=&quot;language-toml&quot; data-lang=&quot;toml&quot;&gt;&lt;span&gt;[package]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;name &lt;&#x2F;span&gt;&lt;span&gt;= &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;shuttlepb&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;version &lt;&#x2F;span&gt;&lt;span&gt;= &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;0.1.0&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;authors &lt;&#x2F;span&gt;&lt;span&gt;= [&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Thomas Antony&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;edition &lt;&#x2F;span&gt;&lt;span&gt;= &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;2018&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;[lib]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;crate-type &lt;&#x2F;span&gt;&lt;span&gt;= [&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;cdylib&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;]
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;[dependencies]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;orbiter_rs &lt;&#x2F;span&gt;&lt;span&gt;= { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;version &lt;&#x2F;span&gt;&lt;span&gt;= &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;0.1&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;path &lt;&#x2F;span&gt;&lt;span&gt;= &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;&#x2F;path&#x2F;to&#x2F;orbiter-rs&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; }
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The crate should then have a &lt;code&gt;lib.rs&lt;&#x2F;code&gt; containing a struct that implements the &lt;code&gt;OrbiterVessel&lt;&#x2F;code&gt; trait. It should then use the &lt;code&gt;init_vessel&lt;&#x2F;code&gt; macro as shown below. This macro generates a stub that is links the Rust code to the OrbiterSDK. For example, in &lt;code&gt;lib.rs&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;orbiter_rs::{
&lt;&#x2F;span&gt;&lt;span&gt;    ODebug, OrbiterVessel, VesselContext, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;_V&lt;&#x2F;span&gt;&lt;span&gt;, init_vessel, FileHandle
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span&gt;(Default, Debug)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;pub struct &lt;&#x2F;span&gt;&lt;span&gt;ShuttlePB {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;_some_param&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;i32
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;impl &lt;&#x2F;span&gt;&lt;span&gt;OrbiterVessel &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;ShuttlePB {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;set_class_caps&lt;&#x2F;span&gt;&lt;span&gt;(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;mut &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;context&lt;&#x2F;span&gt;&lt;span&gt;: &amp;amp;VesselContext, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;_cfg&lt;&#x2F;span&gt;&lt;span&gt;: FileHandle) {
&lt;&#x2F;span&gt;&lt;span&gt;        context.SetSize(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        context.SetPMI(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;_V&lt;&#x2F;span&gt;&lt;span&gt;!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.50&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.50&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;0.50&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;        context.AddMesh(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;ShuttlePB&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;to_string&lt;&#x2F;span&gt;&lt;span&gt;());
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;init_vessel!(
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;init&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;_h_vessel&lt;&#x2F;span&gt;&lt;span&gt;: OBJHANDLE, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;_flight_model&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; ShuttlePB
&lt;&#x2F;span&gt;&lt;span&gt;    {
&lt;&#x2F;span&gt;&lt;span&gt;        ShuttlePB::default()
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;exit&lt;&#x2F;span&gt;&lt;span&gt;() {}
&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The addon may use any of the wrapped functions currently available. Any other Orbiter SDK functions will require wrappers to be generated for them. An automated tool like &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;autocxx&quot;&gt;autocxx&lt;&#x2F;a&gt; may be worth investigating for this purpose.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;building-and-installing&quot;&gt;Building and Installing&lt;&#x2F;h2&gt;
&lt;p&gt;The addon can be built using &lt;code&gt;cargo build&lt;&#x2F;code&gt; assuming that Visual Studio 2019 is available. Other C++ compilers may or may not work. Deploying the addon also requires a config file and any meshes and other dependencies. An example can be seen in &lt;code&gt;Config&#x2F;Surveyor.cfg&lt;&#x2F;code&gt;. Once you build the addon, the DLL will be available in the &lt;code&gt;target&#x2F;i686-pc-windows-msvc&#x2F;debug&lt;&#x2F;code&gt; folder. This will need to be renamed to match whatever module name you haev in the configuration file.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h2&gt;
&lt;p&gt;This proof-of-concept gives a basic framework for building Orbiter addons in Rust. It is not a complete system by any metric and will require significant amounts of work before it can be considered that.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Transparent Rust bindings for C++ structs</title>
        <published>2022-01-11T03:28:20.283+00:00</published>
        <updated>2022-01-11T03:28:20.283+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202200102128-transparent-rust-bindings-for-c-structs/"/>
        <id>https://www.thomasantony.com/notes/202200102128-transparent-rust-bindings-for-c-structs/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202200102128-transparent-rust-bindings-for-c-structs/">&lt;p&gt;This is a short note about the things I discovered about creating transparent bindings for C++ structs into Rust using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cxx.rs&quot;&gt;cxx&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;c-types&quot;&gt;C types&lt;&#x2F;h2&gt;
&lt;p&gt;For scalar types like DWORD, and pointer types that reslve down to void*, a ctype wrapper macro can be used to generate a “new-type” that transparently resolves to the underlying type on the C++ side without having to use &lt;code&gt;Box&lt;&#x2F;code&gt; or &lt;code&gt;unique_ptr&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This is can be further simplified using a macro adapted from the one at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dtolnay&#x2F;cxx&#x2F;issues&#x2F;254#issuecomment-747860504&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;dtolnay&#x2F;cxx&#x2F;issues&#x2F;254#issuecomment-747860504&lt;&#x2F;a&gt;. The macro looks something like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;macro_export&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;macro_rules! &lt;&#x2F;span&gt;&lt;span&gt;ctype_wrapper {
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$r&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;ident&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$c&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;ty&lt;&#x2F;span&gt;&lt;span&gt;) =&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F; Newtype wrapper for a `&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$c&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;` 
&lt;&#x2F;span&gt;&lt;span&gt;        #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span&gt;(Debug, Eq, Clone, PartialEq, Hash, Default, Copy)]
&lt;&#x2F;span&gt;&lt;span&gt;        #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;allow&lt;&#x2F;span&gt;&lt;span&gt;(non_camel_case_types)]
&lt;&#x2F;span&gt;&lt;span&gt;        #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;repr&lt;&#x2F;span&gt;&lt;span&gt;(transparent)]
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;pub struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$r&lt;&#x2F;span&gt;&lt;span&gt;(pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$c&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe impl &lt;&#x2F;span&gt;&lt;span&gt;cxx::ExternType &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$r &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span&gt;Id = cxx::type_id!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$r&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span&gt;Kind = cxx::kind::Trivial;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;    };
&lt;&#x2F;span&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$r&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;ident&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$c&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;ty&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$nice_name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;ident&lt;&#x2F;span&gt;&lt;span&gt;) =&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F;&#x2F; Newtype wrapper for a `&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$c&lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;`
&lt;&#x2F;span&gt;&lt;span&gt;        #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span&gt;(Debug, Eq, Clone, PartialEq, Hash, Default, Copy)]
&lt;&#x2F;span&gt;&lt;span&gt;        #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;allow&lt;&#x2F;span&gt;&lt;span&gt;(non_camel_case_types)]
&lt;&#x2F;span&gt;&lt;span&gt;        #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;repr&lt;&#x2F;span&gt;&lt;span&gt;(transparent)]
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;pub struct &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$r&lt;&#x2F;span&gt;&lt;span&gt;(pub &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$c&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe impl &lt;&#x2F;span&gt;&lt;span&gt;cxx::ExternType &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$r &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span&gt;Id = cxx::type_id!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$r&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span&gt;Kind = cxx::kind::Trivial;
&lt;&#x2F;span&gt;&lt;span&gt;        }
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$nice_name &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;$r&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    };
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The macro has two variants that are almost the same. They generate a newtype wrapping the given underling type and also implements the &lt;code&gt;cxx::ExternType&lt;&#x2F;code&gt; trait for it allowing to pass it by value to&#x2F;from C++ code. The variant with 3 arguments can be used to create a type alias for at the same time. For example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;ctype_wrapper!(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;THRUSTER_HANDLE&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, ThrusterHandle);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;will generate a new-type called &lt;code&gt;THRUSTER_HANDLE&lt;&#x2F;code&gt; wrapping &lt;code&gt;usize&lt;&#x2F;code&gt; as well as an alias called &lt;code&gt;ThrusterHandle&lt;&#x2F;code&gt;. Eithe the type or its alias now be used within an &lt;code&gt;extern &quot;C++&quot;&lt;&#x2F;code&gt; section as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;extern &lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;C++&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span&gt;THRUSTER_HANDLE = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;crate&lt;&#x2F;span&gt;&lt;span&gt;::ThrusterHandle;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;structs&quot;&gt;Structs&lt;&#x2F;h3&gt;
&lt;p&gt;It is possible to define a struct in Rust (outside of the FFI module), with all of the fields (assuming they are all compatible with CXX’s restrictions). A simple example is shown below for a 3-element vector type.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span&gt;(Debug, Default)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;pub struct &lt;&#x2F;span&gt;&lt;span&gt;VECTOR3([&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;f64&lt;&#x2F;span&gt;&lt;span&gt;; 3]);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;impl &lt;&#x2F;span&gt;&lt;span&gt;VECTOR3 {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;f64&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;y&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;f64&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;z&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;f64&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;Self &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;Self&lt;&#x2F;span&gt;&lt;span&gt;([x, y, z])
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;unsafe impl &lt;&#x2F;span&gt;&lt;span&gt;cxx::ExternType &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;VECTOR3 {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span&gt;Id = cxx::type_id!(&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;VECTOR3&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span&gt;Kind = cxx::kind::Trivial;
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span&gt;Vector3 = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;VECTOR3&lt;&#x2F;span&gt;&lt;span&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&#x2F;&#x2F; Alias
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This wraps an underlying &lt;code&gt;VECTOR3&lt;&#x2F;code&gt; struct on the C++ side as&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;c++&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-c++ &quot;&gt;&lt;code class=&quot;language-c++&quot; data-lang=&quot;c++&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;typedef union &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;double&lt;&#x2F;span&gt;&lt;span&gt; data[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#d08770;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;];
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;struct &lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;double&lt;&#x2F;span&gt;&lt;span&gt; x, y, z;};
&lt;&#x2F;span&gt;&lt;span&gt;} VECTOR3;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This type can also now be passed by value to&#x2F;from C++ code without requiring any other wrapper around it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What is the Gamma Function?</title>
        <published>2021-12-13T03:06:04.286+00:00</published>
        <updated>2021-12-13T03:06:04.286+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/notes/202111122106-what-is-the-gamma-function/"/>
        <id>https://www.thomasantony.com/notes/202111122106-what-is-the-gamma-function/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/notes/202111122106-what-is-the-gamma-function/">&lt;p&gt;The gamma function is a generalization of the factorial to complex numbers. The factorial is function defined for positive natural numbers as the product of all the positive numbers preceding it.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
n! = n (n-1) (n-2) ...
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The factorial is also defined by the recurrent relation: $n! = n (n-1)!$. The gamma function is based on this recurrent relation. The gamma function is a complex valued function that also has this same feature, i.e.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\Gamma(z) = z \Gamma(z - 1)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This was derived by Daneil Bernoulli to be the improper integeral:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\Gamma(z) = \int_0^\infty \frac{x^{z-1}}{e^x} dx \quad\text{ for all } \Re(z) &amp;gt; 0
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The function has some interesting structure when evaluated over the complex plane and this is examined in the referenced video.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=dGnIJFzkLI4&quot;&gt;The Gamma Function&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Deriving the MSL&#x2F;Apollo Entry Guidance Algorithm</title>
        <published>2021-08-19T15:05:51-05:00</published>
        <updated>2021-08-19T15:05:51-05:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/posts/2021/msl-apollo-guidance/"/>
        <id>https://www.thomasantony.com/posts/2021/msl-apollo-guidance/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/posts/2021/msl-apollo-guidance/">&lt;p&gt;&lt;div class=&quot;video-wrapper&quot; data-streaming=&quot;youtube&quot; data-videoid=3hf2--gw4Xk&quot; style=&quot;display: flex; justify-content: center;&quot;&gt;
	&lt;a href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;3hf2--gw4Xk&quot;&gt;
		&lt;img alt=&quot;YouTube Thumbnail&quot; src=&quot;https:&#x2F;&#x2F;img.youtube.com&#x2F;vi&#x2F;3hf2--gw4Xk&#x2F;0.jpg&quot; &#x2F;&gt;
	&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;

This post is a companion to the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;3hf2--gw4Xk&quot;&gt;video&lt;&#x2F;a&gt; linked above and includes a full derivation of the Apollo entry guidance longitudinal control algorithm. Please watch the video for more context. Full source code of Jupyter notebooks implementing the algorithm can be found at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;msl-apollo-entry-guidance&quot;&gt;&lt;strong&gt;thomasantony&#x2F;msl-apollo-entry-guidance&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;NASA’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mars.nasa.gov&#x2F;mars-exploration&#x2F;missions&#x2F;mars-science-laboratory&#x2F;&quot;&gt;Mars Science Laboratory&lt;&#x2F;a&gt; mission showcased an advancement in entry technology that allowed it to land much closer to its designated landing site than previous missions. It used with great success, the same guidance algorithm originally used by the Apollo Command Module when returning from the moon. By modulating its lift vector, MSL was able to counteract errors in its trajectory during hypersonic flight and combined with the famous &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.nasa.gov&#x2F;mission_pages&#x2F;msl&#x2F;multimedia&#x2F;gallery&#x2F;pia14839.html&quot;&gt;“sky-crane” maneuver&lt;&#x2F;a&gt;, deliver the Curiosity rover to within 2.5 km of its targeted landing site next to Gale Crater. Last year’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mars.nasa.gov&#x2F;mars-exploration&#x2F;missions&#x2F;mars2020&#x2F;&quot;&gt;Mars 2020&lt;&#x2F;a&gt; mission used the same guidance system to successfully land the Perseverance rover within Jezero crater.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;apollo-guidance-algorithm-overview&quot;&gt;Apollo Guidance Algorithm Overview&lt;&#x2F;h2&gt;
&lt;p&gt;The goal of the Apollo guidance algorithm is to minimize the error in “range” along the ground when compared to that of a pre-computed reference trajectory. It does not try to exactly match the reference trajectory, but instead computes a constant bank angle that is supposed to minimize the downrange distance error at the point where the vehicle reaches terminal altitude. This computation is repeated several times a second in the same manner as a closed-loop control system to correct for deviations in the trajectory due to external or internal factors.&lt;&#x2F;p&gt;
&lt;p&gt;The guidance algorithm uses bank angle to control the amount of vertical lift. This has the side-effect of causing lateral motion that takes the spacecraft away from the desired path. In order to account for this, the bank angle commanded is reversed when the predicted cross-range error exceeds a certain amount, effectively creating a series of S-turns. This is similar to the S-turns performed by the Space Shuttle during its re-entry.&lt;&#x2F;p&gt;
&lt;p&gt;This article focuses on the downrange error control.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2dof-dynamic-model&quot;&gt;2DOF Dynamic Model&lt;&#x2F;h2&gt;
&lt;p&gt;The MSL entry vehicle is modeled in two-dimensions using a vehicle-centric polar coordinate system. The state variables in the model are altidude ($h$), downrange distance ($s$), speed ($v$) and flight path angle($\gamma$). Their equations of motion are as follows:&lt;&#x2F;p&gt;
&lt;!-- Figure 1 source : https:&#x2F;&#x2F;ntrs.nasa.gov&#x2F;api&#x2F;citations&#x2F;20170001619&#x2F;downloads&#x2F;20170001619.pdf --&gt;
&lt;div&gt;
    $$
\begin{align*}
    \frac{d h}{dt} &amp;amp;= v \sin{\gamma} \nonumber \\
    \frac{d s}{dt} &amp;amp;= v \cos{\gamma}  \\
    \frac{d v}{dt} &amp;amp;= -{{D&amp;#x2F;m}} - {{g}} \sin(\gamma)  \\
    \frac{d \gamma}{dt} &amp;amp;= \frac{1}{v} \left(\frac{v^2 \cos(\gamma)}{{{R_M}} + h} + \frac{L \cos{u}}{m} - {{g}}\cos(\gamma)\right) \\
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align*}
\frac{D}{m} &amp;amp;= \frac{\rho v^2}{2 \beta} &amp;amp;;&amp;amp; \text{ Drag Acceleration}\\
\frac{L}{m} &amp;amp;= \frac{D}{m}\enspace (L&amp;#x2F;D) &amp;amp;;&amp;amp;\text{ Lift Acceleration}\\
\nonumber\\
\rho &amp;amp;= \rho_0 e^{-h&amp;#x2F;H} &amp;amp;;&amp;amp; \text{ Atmosphere Model}\\
\nonumber\\
\beta &amp;amp;= 120 \text{kg&amp;#x2F;m$^2$} &amp;amp;;&amp;amp; \text{ Ballistic Coefficient} \\
(L&amp;#x2F;D) &amp;amp;= 0.24 &amp;amp;;&amp;amp;\text{ Lift-to-Drag Ratio}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Surface atmospheric density, $\rho_0$ and scale height, $H$ define the exponential atmospheric model. $g$ is a constant value for acceleration due to gravity. $u$ is the bank angle of the vehicle. The states are collectively referred to as $\mathbf{x}$. The equations of motions may be collectively referred to as $\mathbf{f}(\mathbf{x}, u, t)$.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;deriving-the-apollo-entry-guidance-algorithm&quot;&gt;Deriving the Apollo Entry Guidance Algorithm&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;note-on-the-variation-operator&quot;&gt;Note on the Variation Operator&lt;&#x2F;h3&gt;
&lt;p&gt;This derivation requires the use of the “variation operator”, denoted by $\delta$, sometimes called a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Functional_derivative&quot;&gt;functional derivative&lt;&#x2F;a&gt; or variational derivative. A functional is a function that acts on functions. For example, $J(y(t))$ is a functional because $y$ is itself a function of time. Here $J$ is a scalar quantity derived from a function $y(t)$, that essentially consists of an infinite number of points.&lt;&#x2F;p&gt;
&lt;p&gt;The variational operator is to functionals, what derivatives are to functions. Similar to how a stationary point of a function can be found by setting its derivative to zero, the stationary point of a functional can be found by setting its variation to zero.&lt;&#x2F;p&gt;
&lt;p&gt;Please check the following links if you want to learn more:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=vqDHO2eKXcs&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=vqDHO2eKXcs&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;canvas.vt.edu&#x2F;files&#x2F;1315932&#x2F;download?download_frd=1&quot;&gt;https:&#x2F;&#x2F;canvas.vt.edu&#x2F;files&#x2F;1315932&#x2F;download?download_frd=1&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deriving-bank-angle-policy&quot;&gt;Deriving bank angle policy&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;msl-apollo-guidance&#x2F;Rf_derivation_plot.png&quot; alt=&quot;Reference Trajectory and Perturbed Trajectory&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The goal is to find the constant bank angle $u$ that will guide the spacecraft from the perturbed starting state $\mathbf{x_0}$ to the same range as the reference trajectory. Let’s call this function $J$. Any variable with an “f” in the suffix denotes that it is evaluated at the terminal point of the trajectory and the ‘*’ denotes that it is part of the reference trajectory.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
J = R_f &amp;amp;= s_f + \dot{s_f} dt_f = s_f + v_f \cos(\gamma_f)  dt_f \label{eqn:J_1}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;From the equations of motion,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\dot{h_f} &amp;amp;= \frac{dh_f}{dt_f} \implies dt_f = \frac{dh_f}{\dot{h_f}} \label{eqn:h_f_expr}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Substituting $\eqref{eqn:h_f_expr}$ in $\eqref{eqn:J_1}$,&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div&gt;
    $$
\begin{align}
J &amp;amp;= s_f + \frac{v_f \cos(\gamma_f) }{\dot{h_f}} dh_f \\ 
 &amp;amp;= s_f + \frac{v_f \cos(\gamma_f)}{v_f \sin(\gamma_f)} dh_f
\end{align}
$$
&lt;&#x2F;div&gt;

Assuming that the reference trajectory terminates at the ground, we get $dh_f = 0 - h_f = -h_f$&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\implies J = s_f - cot(\gamma_f) h_f = \Phi(\mathbf{x}_f)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;We want to now find a constant value of $u$ that will keep J constant at $J = R_f = R_f^*$ even with perturbations. We are able to control the trajectory by influencing $u$ and are constrained by physics i.e. equations of motion, $\dot{\mathbf{x}} = \mathbf{f}(\mathbf{x},u,t)$. These constraints can be adjoined to $J$ using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Costate_equation&quot;&gt;co-states&lt;&#x2F;a&gt; $\mathbf{\lambda}^\intercal = \left[\lambda_h\enspace\lambda_s\enspace\lambda_v\enspace\lambda_\gamma\right]$, one for each state. This is very similar to Lagrange multipliers used in function optimization. In this case, each costate is a function that has its own equation of motion which will be derived here.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
J&amp;#x27; =  \Phi(\mathbf{x}_f) + \int_{t_0}^{t_f} \mathbf{\lambda}^\intercal(t) \left\{ \mathbf{f}(\mathbf{x},u, t) - \dot{\mathbf{x}}\right\} dt
$$
&lt;&#x2F;div&gt;
&lt;p&gt;To find the stationary point of $J$ we apply the variation operator. We also shorten $\mathbf{f}(\mathbf{x},u, t)$ to just $\mathbf{f}$.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\delta J&amp;#x27; &amp;amp;= \frac{\partial \Phi}{\partial \mathbf{x}}\delta \mathbf{x}\bigg|_{t=t_f}  + \delta \left[ \int_{t_0}^{t_f} \mathbf{\lambda}^\intercal(t) \left\{ \mathbf{f} - \dot{\mathbf{x}}) \right\} dt \right] \nonumber\\
&amp;amp;= \frac{\partial \Phi}{\partial \mathbf{x}}\delta \mathbf{x}\bigg|_{t=t_f}  + \delta \int_{t_0}^{t_f} \bigg[ \mathbf{\lambda}^\intercal(t) \mathbf{f} - \mathbf{\lambda}^\intercal(t)\dot{\mathbf{x}}\bigg] dt \nonumber\\
&amp;amp;= \frac{\partial \Phi}{\partial \mathbf{x}}\delta \mathbf{x}\bigg|_{t=t_f}  + \int_{t_0}^{t_f} \delta \big[ \mathbf{\lambda}^\intercal(t) \mathbf{f} \big] - \delta\big[\mathbf{\lambda}^\intercal(t)\dot{\mathbf{x}}\big] dt  \nonumber\\
&amp;amp;= \frac{\partial \Phi}{\partial \mathbf{x}}\delta \mathbf{x}\bigg|_{t=t_f}  + \int_{t_0}^{t_f} \delta \big[ \mathbf{\lambda}^\intercal(t) \mathbf{f} \big] - \delta\big[\mathbf{\lambda}^\intercal\dot{\mathbf{x}}\big] dt 

\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Applying the chain rule to the variation operator&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\delta J&amp;#x27; &amp;amp;= \frac{\partial \Phi}{\partial \mathbf{x}}\delta \mathbf{x}\bigg|_{t=t_f}  + \int_{t_0}^{t_f} \mathbf{\lambda}^\intercal \delta \mathbf{f} + \delta\mathbf{\lambda}^\intercal \mathbf{f} - \delta\mathbf{\lambda}^\intercal(t)\dot{\mathbf{x}} - \mathbf{\lambda}^\intercal\delta\dot{\mathbf{x}} \enspace\enspace dt  \label{eqn:Jprime_1}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Applying &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Leibniz_integral_rule&quot;&gt;Leibniz Rule&lt;&#x2F;a&gt; to the first term of the integral in ${\eqref{eqn:Jprime_1}}$,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\int_{t_0}^{t_f} \mathbf{\lambda}^\intercal \delta \mathbf{f}(\mathbf{x}, u, t)\enspace dt = \int_{t_0}^{t_f} \mathbf{\lambda^\intercal} \frac{\partial \mathbf{f}}{\partial \mathbf{x}} \delta\mathbf{x} + \mathbf{\lambda^\intercal} \frac{\partial \mathbf{f}}{\partial \mathbf{u}} \delta\mathbf{u}\enspace dt \label{eqn:Jprime_int_term1}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Integration_by_parts&quot;&gt;Integrating by parts&lt;&#x2F;a&gt;, the fourth term of the integral in ${\eqref{eqn:Jprime_1}}$,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\int_{t_0}^{t_f} \mathbf{\lambda}^\intercal(t)\enspace\delta\dot{\mathbf{x}}\enspace dt &amp;amp;= \int_{t_0}^{t_f} \frac{d}{dt}\big( \mathbf{\lambda}^\intercal \delta \mathbf{x} \big) dt - \int_{t_0}^{t_f} \dot{\mathbf{\lambda}}(t)\enspace\delta x \enspace dt \\
&amp;amp;= \bigg[ {\lambda}^\intercal \delta \mathbf{x} \bigg]_{t_0}^{t_f} - \int_{t_0}^{t_f} \dot{\mathbf{\lambda}}(t)\enspace\delta x \enspace dt \label{eqn:Jprime_int_term4}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Substituting $\eqref{eqn:Jprime_int_term1}$ and $\eqref{eqn:Jprime_int_term4}$ in ${\eqref{eqn:Jprime_1}}$,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\delta J&amp;#x27; &amp;amp;= \frac{\partial \Phi}{\partial \mathbf{x}}\delta \mathbf{x}\bigg|_{t=t_f}  + \int_{t_0}^{t_f} \mathbf{\lambda^\intercal} \frac{\partial \mathbf{f}}{\partial \mathbf{x}} \delta\mathbf{x} + \mathbf{\lambda^\intercal} \frac{\partial \mathbf{f}}{\partial \mathbf{u}} \delta\mathbf{u}  + \delta\mathbf{\lambda}^\intercal \overbrace{\left(\mathbf{f} - \dot{\mathbf{x}}\right)}^{= 0} \enspace dt - \bigg[ {\lambda}^\intercal \delta \mathbf{x} \bigg]_{t_0}^{t_f} + \int_{t_0}^{t_f} \dot{\mathbf{\lambda}}(t)\enspace\delta x \enspace dt \\

\delta J&amp;#x27; &amp;amp;= \bigg[\bigg(\frac{\partial \Phi}{\partial \mathbf{x}} - \mathbf{\lambda}^\intercal\bigg)\delta \mathbf{x}\bigg]_{t=t_f}  + \left( \mathbf{\lambda}^\intercal \delta \mathbf{x} \right)\bigg|_{t=t_0}+ \int_{t_0}^{t_f} \delta\mathbf{x}(\mathbf{\lambda}^\intercal\frac{\partial \mathbf{f}}{\partial \mathbf{x}}  + \dot{\mathbf{\lambda}}) \enspace dt + \int_{t_0}^{t_f} \mathbf{\lambda}^\intercal \frac{\partial \mathbf{f}}{\partial \mathbf{u}} \delta\mathbf{u} \enspace dt\label{eqn:Jprime_2}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Set $\delta J’ = 0$ to find the stationary point of $J’$. We choose co-states to have the following equations of motion so that they cancel out the third term in $\eqref{eqn:Jprime_2}$:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\mathbf{\dot{\lambda}} = -\mathbf{\lambda}^\intercal\frac{\partial \mathbf{f}}{\partial \mathbf{x}} \label{eqn:costate_eom}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Now focusing on the first term of $\eqref{eqn:Jprime_2}$,&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\text{Let }\bigg[\bigg(\frac{\partial \Phi}{\partial \mathbf{x}} - \mathbf{\lambda}^\intercal\bigg)\delta \mathbf{x}\bigg]_{t=t_f} &amp;amp;= 0 \nonumber \\
\implies \mathbf{\lambda}^\intercal(t_f) &amp;amp;= \frac{\partial \Phi(t_f)}{\partial \mathbf{x}(t_f)} \label{eqn:costate_bc_vec}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This gives us the boundary conditions on the costates as follows:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\lambda_h(t_f) &amp;amp;= \frac{\partial \Phi}{\partial h_f} =  - \cot{\gamma_f} \\
\lambda_s(t_f) &amp;amp;= \frac{\partial \Phi}{\partial s_f} =  1 \\
\lambda_v(v_f) &amp;amp;= \frac{\partial \Phi}{\partial v_f} =  0 \\
\lambda_\gamma(t_f) &amp;amp;= \frac{\partial \Phi}{\partial \gamma_f} =  0 \\
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Therefore, assuming the conditions in $\eqref{eqn:costate_eom}$ and $\eqref{eqn:costate_bc_vec}$ hold for the costates, the condition for the stationary point of $J’$ is given by:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\delta J&amp;#x27; = \mathbf{\lambda}^\intercal(t_0) \delta \mathbf{x}(t_0) + \int_{t_0}^{t_f} \mathbf{\lambda^\intercal}\frac{\partial \mathbf{f}}{\partial \mathbf{u}} \delta u\enspace dt = 0\\
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Apollo guidance assumes that the bank angle correction, $\delta u$ is constant for the whole trajectory.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\mathbf{\lambda}^\intercal(t_0) \delta \mathbf{x}(t_0) &amp;amp;= - \delta u \int_{t_0}^{t_f} \mathbf{\lambda^\intercal}\frac{\partial \mathbf{f}}{\partial \mathbf{u}}\enspace dt \\
\delta u &amp;amp;= -\frac{\mathbf{\lambda}^\intercal(t_0) \delta \mathbf{x}(t_0)}{\int_{t_0}^{t_f} \mathbf{\lambda^\intercal}\frac{\partial \mathbf{f}}{\partial \mathbf{u}}\enspace dt} \label{eqn:delu_1}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Eq. $\eqref{eqn:delu_1}$ is giving us a “correction factor” for the bank angle $u$ that should minimize the range error at the terminal point if applied over the entire trajectory. This needs to be simplified into something that can be computed on-board the flight computers.&lt;&#x2F;p&gt;
&lt;p&gt;Looking at just the numerator of $\eqref{eqn:delu_1}$.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\mathbf{\lambda}^\intercal(t_0) \delta\mathbf{x}(t_0) = \lambda_h(t_0) \delta h(t_0) + \lambda_s(t_0) \delta s(t_0) + \lambda_v(t_0) \delta v(t_0) + \lambda_\gamma(t_0) \delta \gamma(t_0)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Since we are trying to keep $J$ stationary about the reference trajectory, all of the terms here must be evaluated w.r.t the reference trajectory (denoted by the $^*$). We also change the independent variable to the velocity, $v$ as that is a better value for matching up the current state of the vehicle to the reference state (for computing the $\delta$’s).&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\mathbf{\lambda^*}^\intercal(v_0) \delta\mathbf{x}(v_0) = \lambda_h^*(v_0) \delta h(v_0) + \lambda_s^*(v_0) \delta s(v_0) + \lambda_v^*(v_0) \underbrace{\delta v(v_0)}_{ = 0} + \lambda_\gamma^*(v_0) \delta \gamma(v_0) \label{eqn:delu_numerator}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Also, the altitude rate $\dot{h}$ and drag acceleration $D&#x2F;m$ are more accurately estimated by sensors on board the spacecraft than the altitude or flight-path angle.&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\dot{h} &amp;amp;= v \sin{\gamma} \nonumber\\
\implies \delta \dot{h} &amp;amp;= \sin{\gamma} \overbrace{\delta v}^{=0} + v \cos{\gamma} \delta \gamma \nonumber\\
\implies \delta \dot{\gamma} &amp;amp;= \frac{\delta\dot{h}}{v \cos{\gamma}} \label{eqn:delgam_to_delhdot}\\
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Assuming exponential atmospheric model with scale height $H$,
&lt;div&gt;
    $$
\begin{align}
\frac{D}{m} &amp;amp;= \frac{\rho_0 e^{-h&amp;#x2F;H} v^2 C_d A_{ref}}{2m}\nonumber\\
\delta(\frac{D}{m}) &amp;amp;= \frac{\rho_0 e^{-h&amp;#x2F;H} C_d A_{ref}}{2m} (v^2 \frac{\delta h}{H} + 2v\overbrace{\delta v}^{=0})\nonumber\\
\implies \delta(\frac{D}{m}) &amp;amp;= -\frac{(D&amp;#x2F;m)}{H} \delta h \label{eqn:delh_to_deldm}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Substituting $\eqref{eqn:delgam_to_delhdot}$ and $\eqref{eqn:delh_to_deldm}$ into $\eqref{eqn:delu_numerator}$&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\mathbf{\lambda^*}^\intercal(v_0) \delta\mathbf{x}^*(v_0) &amp;amp;= \frac{-H\lambda_h^*(v_0) }{\frac{D}{m}^*(v_0)} \delta(\frac{D}{m} (v_0))  + \lambda_s^*(v_0) \delta s(v_0) + \frac{\lambda_\gamma^*(v_0)}{v_0^* \cos{(\gamma^*(v_0))}}\delta\dot{h}^*(v_0)
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;For denominator of $\eqref{eqn:delu_1}$, introduce new state $\lambda_u(t)$ such that&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\lambda_u &amp;amp;= \int_{t_0}^{t_f}-\frac{\partial \mathbf{f}}{\partial \mathbf{u}}^\intercal \mathbf{\lambda}\enspace dt 
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;One option we have is to compute this integral on board the vehicle in every guidance cycle. However this can be very expensive (especially considering the hardware this was originally designed for). So we differentiate (34) w.r.t $t_0$ and apply Leibniz Rule to get&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\frac{\partial \lambda_u}{\partial t_0} &amp;amp;= -\frac{\partial \mathbf{f}}{\partial \mathbf{u}}^\intercal \mathbf{\lambda}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The boundary condition for $\lambda_u$ can be obtained as :&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\lambda_u(t_0=t_f) = \int_{t_f}^{t_f}-\frac{\partial \mathbf{f}}{\partial \mathbf{u}}^\intercal \mathbf{\lambda}\enspace dt = 0
$$
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;apollo-guidance-bank-angle-policy&quot;&gt;Apollo Guidance Bank Angle Policy&lt;&#x2F;h2&gt;
&lt;p&gt;When we actually implement this guidance algorithm, $t_0$ and $\mathbf{\mathbf{x}_0}$ corresponds to the “current” time and state of the spacecraft. All the $\delta{\mathbf{x}}$ values are therefore computed by comparing the current trajectory to the reference trajectory. For example,&lt;&#x2F;p&gt;
&lt;p&gt;$\delta h(v_0) = h(v_0) - h^{*}(v_0)$&lt;&#x2F;p&gt;
&lt;p&gt;where $h(v_0)$ is the current altitude and $h^*(v_0)$ is the altitude on the reference trajectory corresponding to the current speed.&lt;&#x2F;p&gt;
&lt;p&gt;Putting it all together, $\eqref{eqn:delu_1}$ becomes&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\delta u =  -\frac{\frac{-H\lambda_h^*(v_0)}{(D&amp;#x2F;m)^*(v_0)}\delta((D&amp;#x2F;m) (v_0)) + \lambda_s^*(v_0) \delta s(v_0) +  \frac{\lambda_\gamma^*(v_0)}{v_0^* \cos{(\gamma(v_0))}}\delta\dot{h}(v_0)}{\lambda_u^*(v_0)}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;The terms containing $*$ can be pre-computed on the ground along with teh reference trajectory. These terms can therefore be substituted by:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
F_1(v_0) &amp;amp;= \frac{H \lambda_h^*(v_0)}{\frac{D}{m}^*(v_0)}\\
F_2(v_0) &amp;amp;= \frac{\lambda_\gamma^*(v_0)}{v_0^* \cos{\gamma^*(v_0)}} \\
F_3(v_0) &amp;amp;= \lambda_u^*(v_0)
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Also, it can be found that $\lambda_s$ has a constant value of 1 since $\frac{\partial \mathbf{s}}{\partial s} = 0$ and $\lambda_s(t_f) = 1$.&lt;&#x2F;p&gt;
&lt;p&gt;So the final expression for $\delta u$ becomes:&lt;&#x2F;p&gt;
&lt;div&gt;
    $$
\begin{align}
\delta u =  \frac{- \delta s(v_0) -F_1(v_0) \delta(\frac{D}{m} (v_0))  - F_2 (v_0) \delta\dot{h}(v_0)}{F_3(v_0)}
\end{align}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;$\delta u$ is added to the reference bank angle $u$ to obtain the bank angle to be commanded in each guidance cycle.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;some-notes-on-implementation&quot;&gt;Some Notes on Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;One key bottleneck that I found during implementation was the data-lookup within the reference trajectory data. Right now, the reference trajectory data is stored in a 2D numpy array. In every guidance cycle, we do a lookup within this array to find the data row with the closest value of velocity to the vehicle’s current velocity. This &lt;em&gt;could&lt;&#x2F;em&gt; be made much more efficient with a better data structure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;msl-apollo-entry-guidance&#x2F;tree&#x2F;master&#x2F;notebooks&quot;&gt;Jupyter notebooks&lt;&#x2F;a&gt; implement the algorithm as well as a Monte Carlo simulation system for testing it. I will be updating them to add more notes and details on the implementation to clarify things further.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;[1] R.D.Braun and R.M. Manning, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;smartech.gatech.edu&#x2F;bitstream&#x2F;handle&#x2F;1853&#x2F;8390&#x2F;IEEEPaper06ID0076FINAL.pdf&quot;&gt;Mars Exploration Entry, Descent and Landing Challenges&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[2] M. Pajola, et. al., &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.researchgate.net&#x2F;publication&#x2F;331289183_Planetary_Mapping_for_Landing_Sites_Selection_The_Mars_Case_Study&quot;&gt;Planetary Mapping for Landing Sites Selection: The Mars Case Study&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[3] L. Blackmore, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;larsblackmore.com&#x2F;nae_bridge_2016.pdf&quot;&gt;Autonomous Precision Landing of Space Rockets&lt;&#x2F;a&gt;, Page 15&lt;&#x2F;p&gt;
&lt;p&gt;[4] C.R. Heidrich, E. Roelke, S.W. Albert and R.D. Braun, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.researchgate.net&#x2F;publication&#x2F;344238595_Comparative_Study_Of_Lift-And_Drag-Modulation_Control_Strategies_For_Aerocapture&quot;&gt;Comparative Study Of Lift And Drag Modulation Control Strategies For Aerocapture&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[5] &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ntrs.nasa.gov&#x2F;api&#x2F;citations&#x2F;20010038142&#x2F;downloads&#x2F;20010038142.pdf&quot;&gt;Entry System Design Considerations for Mars Landers&lt;&#x2F;a&gt;“ - includes more details about the Apollo Guidance Algorithm on Page 12&lt;&#x2F;p&gt;
&lt;p&gt;[6] P.D. Burkhart et. al., &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.researchgate.net&#x2F;publication&#x2F;4333698_Mars_Science_Laboratory_Entry_Descent_and_Landing_System_Overview&quot;&gt;Mars Science Laboratory Entry, Descent, and Landing System Overview&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[7] G.F. Mendeck, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ntrs.nasa.gov&#x2F;api&#x2F;citations&#x2F;20110003649&#x2F;downloads&#x2F;20110003649.pdf&quot;&gt;Mars Science Laboratory Entry Guidance&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[8] D.G. Ives, D.K. Geller and G.L. Carman, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;arc.aiaa.org&#x2F;doi&#x2F;10.2514&#x2F;6.1998-4570&quot;&gt;Apollo-derived Mars precision lander guidance&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;[9] G.F. Mendeck and G.L. Carman, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;arc.aiaa.org&#x2F;doi&#x2F;10.2514&#x2F;6.2002-4502&quot;&gt;Guidance Design for Mars Smart Landers Using the Entry Terminal Point Controller&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Publications</title>
        <published>2020-11-13T20:10:00-05:00</published>
        <updated>2020-11-13T20:10:00-05:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/publications/"/>
        <id>https://www.thomasantony.com/publications/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/publications/">&lt;h3 id=&quot;journal-articles-and-conference-proceedings&quot;&gt;Journal Articles and Conference Proceedings&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;pdf&#x2F;tantony_rapid_2017.pdf&quot;&gt;Rapid Indirect Trajectory Optimization on Highly Parallel Computing Architectures&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
Antony, T., and Grant, M. J.&lt;br &#x2F;&gt;
&lt;em&gt;Journal of Spacecraft and Rockets&lt;&#x2F;em&gt;, Vol. 54, No. 5 (2017), pp. 1081-1091, &lt;a href=https:&#x2F;&#x2F;doi.org&#x2F;10.2514&amp;#x2F;1.A33755&gt;doi:10.2514&amp;#x2F;1.A33755&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;pdf&#x2F;tantony_qcpi_2019.pdf&quot;&gt;Quasilinear Chebyshev-Picard Iteration Method for Indirect Trajectory Optimization&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
Antony, T. and Grant, M. J.&lt;br &#x2F;&gt;
&lt;em&gt;2019 AIAA Atmospheric Flight Mechanics Conference&lt;&#x2F;em&gt;, &lt;a href=https:&#x2F;&#x2F;doi.org&#x2F;10.2514&amp;#x2F;6.2019-0260&gt;doi:10.2514&amp;#x2F;6.2019-0260&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;pdf&#x2F;tantony_satfcn_2018.pdf&quot;&gt;Path Constraint Regularization in Optimal Control Problems using Saturation Functions&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
Antony, T. and Grant, M. J.&lt;br &#x2F;&gt;
&lt;em&gt;2018 AIAA Atmospheric Flight Mechanics Conference&lt;&#x2F;em&gt;, &lt;a href=https:&#x2F;&#x2F;doi.org&#x2F;10.2514&amp;#x2F;6.2018-0018&gt;doi:10.2514&amp;#x2F;6.2018-0018&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;pdf&#x2F;grant_longrange_2016.pdf&quot;&gt;Rapid Indirect Trajectory Optimization of a Hypothetical Long Range Weapon System&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
Grant M. J. and Antony, T.&lt;br &#x2F;&gt;
&lt;em&gt;2016 AIAA Atmospheric Flight Mechanics Conference&lt;&#x2F;em&gt;, &lt;a href=https:&#x2F;&#x2F;doi.org&#x2F;10.2514&amp;#x2F;6.2016-0276&gt;doi:10.2514&amp;#x2F;6.2016-0276&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;pdf&#x2F;ipaddles_2016.pdf&quot;&gt;Enabling Mars Exploration Using inflatable Purdue Aerodynamic Decelerator with Deployable Entry Systems (“iPADDLES”) Technology&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
Sparapany, M., Antony, T., Saranathan, H., Klug, L., Libben,B., Shibata, E., Williams, J., Grant, M. J. and Saikia, S. J.&lt;br &#x2F;&gt;
&lt;em&gt;2016 Big Idea Challenge&lt;&#x2F;em&gt;, NASA Langley Research Center&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;pdf&#x2F;tantony_ipcost_2015.pdf&quot;&gt;Optimization of Interior Point Cost Functionals Using Indirect Methods&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
Antony, T., Grant, M. J. and Bolender, M. A.&lt;br &#x2F;&gt;
&lt;em&gt;2015 AIAA Atmospheric Flight Mechanics Conference&lt;&#x2F;em&gt;, &lt;a href=https:&#x2F;&#x2F;doi.org&#x2F;10.2514&amp;#x2F;6.2015-2399&gt;doi:10.2514&amp;#x2F;6.2015-2399&lt;&#x2F;a&gt;
&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;ui.adsabs.harvard.edu&#x2F;abs&#x2F;2014acm..conf..461S&#x2F;abstract&quot;&gt;Voyage to Troy: A Mission Concept For The Exploration Of The Trojan Asteroids&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
Saikia, S., Das, A., Laipert, F., Dapkus, C., Kendall, J., Bowling, T., Steckloff, J., Holbert, S., Graves, K., Antony, T., Bobick, R., Huang, Y., Stuart, J., Longuski, J., Minton, D.&lt;br &#x2F;&gt;
&lt;em&gt;Asteroids, Comets, Meteors (ACM) 2014&lt;&#x2F;em&gt;, Helsinki, FI&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;!-- * &quot;A Generalized Adaptive Chebyshev-Picard Iteration Method for Solution to Two-Point Boundary Value Problems&quot;, Antony, T. and Grant, M.J., *3rd Annual Meeting of the AFRL Mathematical Modeling and Optimization Institute*, Shalimar FL, 27-31 Jul. 2015 --&gt;
&lt;h3 id=&quot;theses-and-dissertations&quot;&gt;Theses and Dissertations&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;pdf&#x2F;tantony_phdthesis.pdf&quot;&gt;Large Scale Constrained Trajectory Optimization using Indirect Methods&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
&lt;em&gt;PhD Aeronautics and Astronautics&lt;&#x2F;em&gt;, Purdue University, May 2018&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;pdf&#x2F;tantony_msthesis.pdf&quot;&gt;Rapid Indirect Trajectory Optimization on Highly Parallel Computing Architectures&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
&lt;em&gt;Master of Science in Aeronautics and Astronautics&lt;&#x2F;em&gt;, Purdue University, December 2014&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;patents&quot;&gt;Patents&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;patents.google.com&#x2F;patent&#x2F;US10788835B2&#x2F;en&quot;&gt;U.S. Patent 10788835B2&lt;&#x2F;a&gt;: &lt;em&gt;Safety system for autonomous operation of off-road and agricultural vehicles using machine learning for detection and identification of obstacles&lt;&#x2F;em&gt;, September 29, 2020&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Also on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;scholar.google.com&#x2F;citations?hl=en&amp;amp;user=UxT0v5MAAAAJ&quot;&gt;Google Scholar&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setting up the Orbiter 2016 SDK in Visual Studio 2019</title>
        <published>2020-08-08T12:39:52-05:00</published>
        <updated>2020-08-08T12:39:52-05:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/posts/2020/orbiter-sdk-vs-2019/"/>
        <id>https://www.thomasantony.com/posts/2020/orbiter-sdk-vs-2019/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/posts/2020/orbiter-sdk-vs-2019/">&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;orbit.medphys.ucl.ac.uk&#x2F;&quot;&gt;Orbiter&lt;&#x2F;a&gt; is to space flight, what X-Plane is to aviation. Orbiter has been around since the early 2000s and it seems like some of the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.orbiterwiki.org&#x2F;wiki&#x2F;Category:OrbiterSDK&quot;&gt;documentation&lt;&#x2F;a&gt; for add-on development is a bit out-dated. This post documents how to get an Orbiter 2016 addon development environment set-up on Windows 10, using tools available today (in 2020).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;download-orbiter-2016&quot;&gt;Download Orbiter 2016&lt;&#x2F;h2&gt;
&lt;p&gt;Download and install Orbiter following instructions at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;orbit.medphys.ucl.ac.uk&#x2F;download.html&quot;&gt;http:&#x2F;&#x2F;orbit.medphys.ucl.ac.uk&#x2F;download.html&lt;&#x2F;a&gt;. “TexFilms” on Youtube has a very &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtube.com&#x2F;watch?v=BzcPO8rtLDQ&quot;&gt;good video&lt;&#x2F;a&gt; detailing how to install Orbiter 2016 along with some essential add-ons. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.orbiter-forum.com&quot;&gt;Orbiter-Forum&lt;&#x2F;a&gt; is also a great resource. The rest of the post assumes that Orbiter 2016 is installed in &lt;strong&gt;C:\Orbiter&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;download-visual-studio-2019&quot;&gt;Download Visual Studio 2019&lt;&#x2F;h2&gt;
&lt;p&gt;Download the Visual Studio 2019 Community Edition web installer from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;visualstudio.microsoft.com&#x2F;downloads&#x2F;&quot;&gt;Visual Studio Download Center&lt;&#x2F;a&gt;. Run the installer and you will eventually see a window with something similar to this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;orbiter-sdk-vs-2019&#x2F;vs-installer-01.png&quot; alt=&quot;Visual Studio Installer&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Check the option that says “Desktop Development with C++”. You may also modify the install location for the compiler. Continue with the installation and wait for it to complete.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;build-a-sample-project&quot;&gt;Build a sample project&lt;&#x2F;h2&gt;
&lt;p&gt;The Orbiter SDK is installed in &lt;strong&gt;C:\Orbiter\OrbiterSdk&lt;&#x2F;strong&gt;. The SDK includes some sample projects including custom vehicles and Multi-Functional Displays (MFDs). Open &lt;strong&gt;OrbiterSdk\CustomMFD\CustomMFD.vcproj&lt;&#x2F;strong&gt; in Visual Studio 2019. You will get a prompt asking you if you want to convert the project to make it compatible.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;orbiter-sdk-vs-2019&#x2F;vs-01.png&quot; alt=&quot;Visual Studio Project Conversion&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Click “OK” to continue. Switch to the “Property Manager” tab at the bottom of “Solution Explorer”.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;orbiter-sdk-vs-2019&#x2F;vs-property-manager.png&quot; alt=&quot;Visual Studio Property Manager Tab&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Within Property Manager, expand “CustomMFD” to show two options “Debug | WIn32” and “Release | Win32”. Expand both of these until you get an opton called “Orbiterroot”. Right click this and select Properties.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;orbiter-sdk-vs-2019&#x2F;vs-orbiterroot.png&quot; alt=&quot;Visual Studio Orbiter Root Property Sheet&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Select “User Macros”. Ensure that the “OrbiterDir” variable is set to the correct Orbiter installation path.
&lt;img src=&quot;&#x2F;images&#x2F;orbiter-sdk-vs-2019&#x2F;vs-orbiterroot-window.png&quot; alt=&quot;Visual Studio OrbiterDir&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Select “VC++ Directories”. Change the “Include Directories” and “Library Directories” settings as shown in the screenshow below. This will ensure that the compiler can find the Orbiter SDK header files and libraries.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;orbiter-sdk-vs-2019&#x2F;vs-directories.png&quot; alt=&quot;Visual Studio VC++ Directories&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Click “OK” to close the property pages window. Right click on “CustomMFD” in Property Manager and select “Properties”. This should give you a window with an additional setting called “Debugging”. Change the settings as shown in the screenshot below. Please note that I use &lt;strong&gt;C:\Orbiter\Orbiter_ng.exe&lt;&#x2F;strong&gt; as the “Command” setting because I have the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;users.kymp.net&#x2F;~p501474a&#x2F;D3D9Client&#x2F;&quot;&gt;Orbiter D3D9Client&lt;&#x2F;a&gt; installed. If you are running a vanilla Orbiter installation, set this to &lt;strong&gt;C:\Orbiter\Orbiter.exe&lt;&#x2F;strong&gt; instead.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;orbiter-sdk-vs-2019&#x2F;vs-debugging.png&quot; alt=&quot;Visual Studio Debugging Property Sheet&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I got this handy tip from Andrew Stokes’ &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=knftMag1qc8&quot;&gt;video&lt;&#x2F;a&gt;. Go to &lt;strong&gt;C++ &amp;gt; Code Generation&lt;&#x2F;strong&gt; in the Property Sheet. Change Runtime Library to “&lt;strong&gt;Multithreaded (&#x2F;MT)&lt;&#x2F;strong&gt;” for your “Release” configuration and “&lt;strong&gt;Multithreaded Debug (&#x2F;MTd)&lt;&#x2F;strong&gt;” for your “Debug” configuration. This removes an external dependency on Visual Studio Runtime DLL.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;orbiter-sdk-vs-2019&#x2F;vs-runtime-debug.png&quot; alt=&quot;Visual Studio Runtime Debug Configuration&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;images&#x2F;orbiter-sdk-vs-2019&#x2F;vs-runtime-release.png&quot; alt=&quot;Visual Studio Runtime Release Configuration&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;At this point, if you hit Build (F7), you may get an error saying:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;RC : fatal error RC1110: could not open CustomMFD.rc
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If this happens, switch back to “Solution Explorer” and delete the &lt;strong&gt;CustomMFD.rc&lt;&#x2F;strong&gt; file. Now the project should build successfully. It should be noted that the compiler places the output in the &lt;strong&gt;C:\Orbiter\Modules\Plugin&lt;&#x2F;strong&gt; directory by default. This can be verified by deleting &lt;strong&gt;C:\Orbiter\Modules\Plugin\CustomMFD.dll&lt;&#x2F;strong&gt; and rebuilding the project. Ensure that &lt;strong&gt;CustomMFD.dll&lt;&#x2F;strong&gt; appears in the folder after you build the project. You can now run Orbiter as usual or have Visual Studio start it for you by hitting “Debug”. Activate the Module within Orbiter Launcher as shown below to test it in the simulator.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;orbiter-sdk-vs-2019&#x2F;orbiter-modules.png&quot; alt=&quot;Enable CustomMFD in Orbiter Launcher’s Modules page&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Your development environment is now ready.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hello World!</title>
        <published>2019-10-16T20:47:55-05:00</published>
        <updated>2019-10-16T20:47:55-05:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/posts/2019/hello-world/"/>
        <id>https://www.thomasantony.com/posts/2019/hello-world/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/posts/2019/hello-world/">&lt;p&gt;&lt;strong&gt;8&#x2F;8&#x2F;2020 update&lt;&#x2F;strong&gt;: I have imported some of my older articles from Medium to this blog to consolidate everything in one spot. So this particular “hello world” appearing in the middle of other posts may look a bit weird.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;10&#x2F;16&#x2F;2019&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;Yes. I have started a blog … again. This is probably my fourth attempt at creating a personal website. And as usual, I spent several hours looking at themes&#x2F;templates before finally settling on this one.&lt;&#x2F;p&gt;
&lt;p&gt;The intention of this blog is to share my thoughts and ideas on programming, engineering, spaceflight, and pretty much anything that catches my fancy. To whoever is reading this, welcome!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>About Me</title>
        <published>2019-10-16T20:45:02-05:00</published>
        <updated>2019-10-16T20:45:02-05:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/about/"/>
        <id>https://www.thomasantony.com/about/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/about/">&lt;p&gt;I’ll write this later. Here’s my LinkedIn for now: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;linkedin.com&#x2F;in&#x2F;thomasantony&quot;&gt;https:&#x2F;&#x2F;linkedin.com&#x2F;in&#x2F;thomasantony&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using VirtualCAN inside docker on macOS</title>
        <published>2018-02-09T03:42:31.359+00:00</published>
        <updated>2018-02-09T03:42:31.359+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/posts/2018/tantony-using-virtualcan-inside-docker-on-macos-cfa10f7e75d6/"/>
        <id>https://www.thomasantony.com/posts/2018/tantony-using-virtualcan-inside-docker-on-macos-cfa10f7e75d6/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/posts/2018/tantony-using-virtualcan-inside-docker-on-macos-cfa10f7e75d6/">&lt;p&gt;At &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.smart-ag.com&#x2F;&quot;&gt;SmartAg&lt;&#x2F;a&gt;, we use Docker to manage the development and runtime environments for our embedded software. For performing full-system integrated tests, we have built comprehensive simulators that mimic the behavior of the hardware that we automate. Since most of the hardware communication happens over CAN, VirtualCAN is a great way of faking the hardware signals.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;medium&#x2F;1__xk974__nijAtuCTMhs7B0__w.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Until now, any code that required a CAN interface could not run on my Macbook Pro. This was primarily because the linux kernel used by &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.docker.com&#x2F;docker-mac&quot;&gt;Docker for Mac&lt;&#x2F;a&gt; lacks support for &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SocketCAN&quot;&gt;SocketCAN&lt;&#x2F;a&gt; or VirtualCAN. After much &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;docker&#x2F;for-mac&#x2F;issues&#x2F;2580&quot;&gt;head-bashing&lt;&#x2F;a&gt;, I realized that a better option would be &lt;code&gt;[docker-machine](https:&#x2F;&#x2F;docs.docker.com&#x2F;machine&#x2F;overview&#x2F;)&lt;&#x2F;code&gt; , which is how docker was originally run on macOS before the official “Docker for Mac” release.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;setting-up-a-can-enabled-docker-machine-vm&quot;&gt;Setting up a CAN-enabled docker-machine VM&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;brew.sh&#x2F;&quot;&gt;Homebrew&lt;&#x2F;a&gt; if you don’t already have it.&lt;&#x2F;li&gt;
&lt;li&gt;Install &lt;code&gt;docker&lt;&#x2F;code&gt;, &lt;code&gt;docker-machine&lt;&#x2F;code&gt; and some associated software&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;brew install docker docker-compose docker-machine docker-credential-helper docker-machine-driver-xhyve&lt;&#x2F;p&gt;
&lt;p&gt;3. Clone the repo from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;boot2docker&#x2F;boot2docker&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;boot2docker&#x2F;boot2docker&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;4. Edit &lt;code&gt;kernel_config&lt;&#x2F;code&gt; in the &lt;code&gt;boot2docker&lt;&#x2F;code&gt; repo and add the following at the bottom:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;CONFIG\_CAN=y  
&lt;&#x2F;span&gt;&lt;span&gt;CONFIG\_CAN\_RAW=y  
&lt;&#x2F;span&gt;&lt;span&gt;CONFIG\_CAN\_VCAN=y  
&lt;&#x2F;span&gt;&lt;span&gt;CONFIG\_CAN\_DEV=y  
&lt;&#x2F;span&gt;&lt;span&gt;CAN\_SLCAN=y  
&lt;&#x2F;span&gt;&lt;span&gt;CAN\_BCM=y
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;5. Follow the instructions at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;boot2docker&#x2F;boot2docker&#x2F;blob&#x2F;master&#x2F;doc&#x2F;BUILD.md&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;boot2docker&#x2F;boot2docker&#x2F;blob&#x2F;master&#x2F;doc&#x2F;BUILD.md&lt;&#x2F;a&gt; to build your custom &lt;code&gt;boot2docker&lt;&#x2F;code&gt; image. This basically boils down to:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;docker build -t boot2docker .  
&lt;&#x2F;span&gt;&lt;span&gt;docker run --rm boot2docker &amp;gt; boot2docker-can.iso
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;6. Fix some permissions required by the &lt;code&gt;xhyve&lt;&#x2F;code&gt; docker-machine driver.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;sudo chown root:wheel $(brew --prefix)&#x2F;opt&#x2F;docker-machine-driver-xhyve&#x2F;bin&#x2F;docker-machine-driver-xhyve  
&lt;&#x2F;span&gt;&lt;span&gt;sudo chmod u+s $(brew --prefix)&#x2F;opt&#x2F;docker-machine-driver-xhyve&#x2F;bin&#x2F;docker-machine-driver-xhyve
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;7. Create your new &lt;code&gt;docker-machine&lt;&#x2F;code&gt; VM with the following command. Change the command appropriately to allocate the desired number of CPUs, amount of RAM and disk space to the VM.&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;docker-machine create default --driver xhyve --xhyve-experimental-nfs-share --xhyve-cpu-count=4 --xhyve-memory-size=4096 --xhyve-disk-size=40000 --xhyve-boot2docker-url boot2docker-can.iso
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;8. Your &lt;code&gt;docker-machine&lt;&#x2F;code&gt; VM is now ready. It should already be running. If you restart your machine, you can start the VM by typing &lt;code&gt;docker-machine start default&lt;&#x2F;code&gt; or stop it with &lt;code&gt;docker-machine stop default&lt;&#x2F;code&gt; .&lt;&#x2F;p&gt;
&lt;p&gt;9. Set the environment parameters to use docker with your new VM by running &lt;code&gt;eval $(docker-machine env default)&lt;&#x2F;code&gt; . This command has to be run every time you are in a new terminal. You can also add this to your &lt;code&gt;.bashrc&lt;&#x2F;code&gt; to make it automatic.&lt;&#x2F;p&gt;
&lt;p&gt;10. Check that it all works:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;docker run -it --rm --privileged alpine &#x2F;bin&#x2F;sh
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Inside the docker container, run:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#2b303b;color:#c0c5ce;&quot;&gt;&lt;code&gt;&lt;span&gt;zcat &#x2F;proc&#x2F;config.gz | grep CAN
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The command should display the CAN flags that you set while compiling the kernel. SocketCAN&#x2F;VirtualCAN is now enabled in any docker container that you start on this VM.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;caveats&quot;&gt;Caveats&lt;&#x2F;h3&gt;
&lt;p&gt;Running &lt;code&gt;docker&lt;&#x2F;code&gt; using &lt;code&gt;docker-machine&lt;&#x2F;code&gt; means that some things, such as port-forwarding does not work as you expect. A handy script for exposing any ports you want from your VM to &lt;code&gt;localhost&lt;&#x2F;code&gt; can be found here: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;johanhaleby&#x2F;docker-machine-port-forwarder&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;johanhaleby&#x2F;docker-machine-port-forwarder&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Training a neural network in real-time to control a self-driving car</title>
        <published>2016-12-11T05:02:01.849+00:00</published>
        <updated>2016-12-11T05:02:01.849+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/posts/2016/tantony-training-a-neural-network-in-real-time-to-control-a-self-driving-car-9ee5654978b7/"/>
        <id>https://www.thomasantony.com/posts/2016/tantony-training-a-neural-network-in-real-time-to-control-a-self-driving-car-9ee5654978b7/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/posts/2016/tantony-training-a-neural-network-in-real-time-to-control-a-self-driving-car-9ee5654978b7/">&lt;p&gt;I was lucky enough to be accepted into the first cohort of Udacity’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.udacity.com&#x2F;drive&quot;&gt;Self Driving Car NanoDegree&lt;&#x2F;a&gt; program back in October. Though I have been thinking of blogging about my experience since the start, it didn’t really happen till now. I am currently wrapping up Project #3 — “Behavioral Cloning”. This one was considerably tougher than the first two. However, it has been very fulfilling to finally complete it and here I will describe the approach I used for training a neural network to drive a car (in a simulator).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;medium&#x2F;1__0ahKkWS__pXY6ktIJMLptgg.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The project description makes it looks easy (relatively). In the first project, we detected lanes using some basic Computer Vision methods and in the second, we classified traffic signs from the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;benchmark.ini.rub.de&#x2F;?section=gtsdb&amp;amp;subsection=news&quot;&gt;German Traffic Signs dataset&lt;&#x2F;a&gt;. The third one seemed like an extension of the second, where instead of classifying traffic signs, we had to predict steering angles based on a camera feed, using a neural network.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;collecting-training-data&quot;&gt;Collecting Training Data&lt;&#x2F;h3&gt;
&lt;p&gt;Unlike Project#2, this time we had to collect our own training data. This was more challenging than expected. As it turned out, controlling Udacity’s SDC simulator with a keyboard is not a simple task. Feedback from other students on Slack seemed to indicate that it also gave bad, jittery steering angle data. Fortunately, I have a friend who is crazy about car racing games and owns a Logitech G27 Racing wheel.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;medium&#x2F;1__HPYURL9VsoLEBJ68iYK__xg.png&quot; alt=&quot;Udacity’s SDC Simulator&quot; &#x2F;&gt;
Udacity’s SDC Simulator&lt;&#x2F;p&gt;
&lt;p&gt;For training data, I recorded data (“camera” images + steering angle and other telemetry) where I drove through the two tracks a couple of times. I also recorded data while recovering from deliberate perturbations to the sides of the lane to make sure the neural net also learned how to recover from such situations.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;picking-the-architecture-and-training-the-nn&quot;&gt;Picking the Architecture and Training the NN&lt;&#x2F;h3&gt;
&lt;p&gt;I spent a lot of time experimenting with different convolutional neural network architectures, with varying levels of success. I also tried taking existing trained models like VGG16 and Google’s Inception v3 and adapting them to this purpose. Eventually, I settled upon NVIDIA’s End-to-End Deep Learning architecture described in this &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;images.nvidia.com&#x2F;content&#x2F;tegra&#x2F;automotive&#x2F;images&#x2F;2016&#x2F;solutions&#x2F;pdf&#x2F;end-to-end-dl-using-px.pdf&quot;&gt;paper&lt;&#x2F;a&gt;. It was relatively small in size and hence added very little latency when running it. I proceeded to use my gaming desktop with GTX 1070 GPU to train the model on ~32000 images.&lt;&#x2F;p&gt;
&lt;p&gt;What I learned is that “mean square error” was not at all a predictor of the performance of the network in the actual simulator. Another big issue was the turnaround time between collecting data, training the network and then testing it. Also, the ‘remote driving’ script provided by Udacity set the car’s throttle to a constant value with no way to control the speed.&lt;&#x2F;p&gt;
&lt;p&gt;That is when I came across &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;u&#x2F;8a1f0a75e0b5&quot;&gt;John Chen&lt;&#x2F;a&gt;’s post on our Slack channel about how he developed an “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;diyjac&#x2F;AgileTrainer&quot;&gt;Agile Trainer&lt;&#x2F;a&gt;” to reduce the turnaround time between data-collection and testing. His program uses PyGame and Joystick input to manually takeover control from the neural network whenever it deviated too much and also allowed to train the network at the same time.&lt;&#x2F;p&gt;
&lt;p&gt;I wrote my own live trainer based on this idea, which instead used keyboard input. It turned out that my keyboard based “remote driver” was able to control the simulator more reliably than the simulator’s “Training mode”.&lt;&#x2F;p&gt;
&lt;p&gt;Best of all, it allowed me to fine-tune the model from my bed with my Macbook Pro by “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.nomachine.com&#x2F;&quot;&gt;NoMachine&lt;&#x2F;a&gt;”-ing into my desktop (which would be difficult with a joystick&#x2F;racing wheel).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-it-works&quot;&gt;&lt;strong&gt;How it works&lt;&#x2F;strong&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;The live trainer has a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;tk.html&quot;&gt;Tkinter&lt;&#x2F;a&gt;-based UI and a few simple keyboard controls.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;medium&#x2F;1__kW5kXDzFkn4DCDoIn4hZsg.png&quot; alt=&quot;SDC Live Trainer interface&quot; &#x2F;&gt;
SDC Live Trainer interface&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Up&#x2F;Down&lt;&#x2F;strong&gt;: Control cruise speed&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Left&#x2F;Right&lt;&#x2F;strong&gt;: Steering&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;x&lt;&#x2F;strong&gt;: Toggle between autonomous and manual override modes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;c&lt;&#x2F;strong&gt;: Center steering (only in manual override mode)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;z&lt;&#x2F;strong&gt;: Toggle real-time training (only in manual override mode)&lt;&#x2F;p&gt;
&lt;p&gt;The speed of the car is controlled by a proportional-gain controller. It modulates the throttle based on speed feedback. This rudimentary “cruise control” gets the speed within +&#x2F;- 1 mph of the target speed, which is good enough in this case.&lt;&#x2F;p&gt;
&lt;p&gt;The arrow keys increase&#x2F;decrease the steering angle. The steering also has some slow auto re-centering dynamics added by the trainer. So the steering angle will keep “decaying” towards zero if you don’t press any key. The “autonomous rating” measures what percentage of the current session was spent in fully autonomous mode.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;real-time-training&quot;&gt;Real-time training&lt;&#x2F;h3&gt;
&lt;p&gt;The process of training itself is pretty simple. You can do one of two things:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Deliberately perturb the car’s motion while in manual override and engage training mode once you have started the recovery process&lt;&#x2F;li&gt;
&lt;li&gt;At any spots that the model has trouble with, engage training mode while driving through the spot manually to fine-tune the model.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The GIF below shows an example of the first case. I purposely drive the car towards the right edge using manual override and then start training the model once I have it recovering and returning to the center of the lane.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;evaluating-model-performance&quot;&gt;Evaluating model performance&lt;&#x2F;h3&gt;
&lt;p&gt;My initial model had some trouble navigating a couple of turns on track#1 in the simulator. I was able to successfully tune these spots using live training and finally get this result:&lt;&#x2F;p&gt;
&lt;p&gt;Track 2 was a little more difficult, with more sharp gradients and curves. However, I found that decreasing the speed down to 20 mph helped it navigate that track as well!&lt;&#x2F;p&gt;
&lt;p&gt;The live trainer code is on Github at: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;sdc-live-trainer&quot;&gt;&lt;strong&gt;thomasantony&#x2F;sdc-live-trainer&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;possibilities&quot;&gt;Possibilities&lt;&#x2F;h3&gt;
&lt;p&gt;A live trainer can also probably be used to perform the initial training of the network, though that would involve a lot more baby-sitting during the training process. The good thing is that you can immediately start seeing results as the model converges toward the right weights.&lt;&#x2F;p&gt;
&lt;p&gt;Is such an architecture extendable to real-world SDCs? It can definitely be done with scale models on scale tracks. On real cars it is probably a little more difficult (though there are probably ways to do it). NVIDIA’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;images.nvidia.com&#x2F;content&#x2F;tegra&#x2F;automotive&#x2F;images&#x2F;2016&#x2F;solutions&#x2F;pdf&#x2F;end-to-end-dl-using-px.pdf&quot;&gt;paper&lt;&#x2F;a&gt; mentions using real-world data to make a simulator. A live training methodology like the one described here can possibly be incorporated into such a simulator as well!&lt;&#x2F;p&gt;
&lt;p&gt;Let me know if you have any comments&#x2F;suggestions!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>flybywire — Declarative GUIs for Python inspired by React</title>
        <published>2016-09-04T05:26:46.557+00:00</published>
        <updated>2016-09-04T05:26:46.557+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://www.thomasantony.com/posts/2016/tantony-flybywire-declarative-guis-for-python-inspired-by-react-ad2131d4cbc1/"/>
        <id>https://www.thomasantony.com/posts/2016/tantony-flybywire-declarative-guis-for-python-inspired-by-react-ad2131d4cbc1/</id>
        
        <content type="html" xml:base="https://www.thomasantony.com/posts/2016/tantony-flybywire-declarative-guis-for-python-inspired-by-react-ad2131d4cbc1/">&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;medium&#x2F;1__Ql7p4__Wua5eSiZB41oAAlg.png&quot; alt=&quot;Source: xkcd#970&quot; &#x2F;&gt; by Randall Monroe
Source: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;xkcd.com&#x2F;970&#x2F;&quot;&gt;xkcd#970&lt;&#x2F;a&gt; by Randall Monroe&lt;&#x2F;p&gt;
&lt;p&gt;Python is amazing. I love the flexibility, the clean and readable syntax and its huge ecosystem of libraries. However, when it comes to making modern GUIs, it comes up sort in many ways.&lt;&#x2F;p&gt;
&lt;p&gt;There are libraries like &lt;em&gt;PyQT&lt;&#x2F;em&gt; and &lt;em&gt;Kivy&lt;&#x2F;em&gt; to create GUIs for your Python application. However, each of them come with their &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@tryexceptpass&#x2F;a-python-ate-my-gui-971f2326ce59#.lpb3pnf2d&quot;&gt;own problems&lt;&#x2F;a&gt;. Many modern UI solutions like Electron and React-Native looks to the web to avoid the problems of dealing with multiple platforms. After all, the web is one platform that DOES have it’s share of great (and at times awful) UIs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;thomasantony&#x2F;flybywire&quot;&gt;&lt;em&gt;flybywire&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; is my ongoing experiment to develop a declarative UI library, based off some great work by &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;u&#x2F;138c0eb26be5&quot;&gt;Cristian Medina&lt;&#x2F;a&gt;. So, what is &lt;em&gt;flybywire&lt;&#x2F;em&gt; all about? Well, you need a bit of background before I can go into that.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;react-es6-and-the-endless-abyss&quot;&gt;React, ES6 and the Endless Abyss&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;facebook.github.io&#x2F;react&quot;&gt;React&lt;&#x2F;a&gt; caught my interest sometime late last year when I was trying to build a desktop frontend for a Python project using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;electron.atom.io&quot;&gt;Electron&lt;&#x2F;a&gt;. I was coming back to web development after a gap of nearly six years and my last experience in the field was with jQuery and PHP.&lt;&#x2F;p&gt;
&lt;p&gt;After finishing a basic &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;reactfordesigners.com&#x2F;labs&#x2F;reactjs-introduction-for-people-who-know-just-enough-jquery-to-get-by&#x2F;&quot;&gt;tutorial&lt;&#x2F;a&gt;, I was really excited about the possibilities of React. However, that excitement was a little dulled once I discovered the wonderful world of node-based tools that seemed almost mandatory if you wanted to create anything serious. I found that javascript is no longer the innocent, interpreted language I knew it as. ES6, CoffeeScript, TypeScript, transpilers, &lt;em&gt;webpack&lt;&#x2F;em&gt;, the endless abyss that is &lt;strong&gt;node-packages&lt;&#x2F;strong&gt; … it is easy to get lost just trying to get a hang of all these tools and frameworks.&lt;&#x2F;p&gt;
&lt;p&gt;So where am I going with all this? Well, my (mis?)adventures with React, Redux etc. can be summarized as:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;React seems to have zeroed in on a really good way of defining UIs without much clutter. I especially loved the concept of one-way binding and views defined as pure functions of state which redraws the whole page when updated.&lt;&#x2F;li&gt;
&lt;li&gt;I found redux to be a great addition to the React ecosystem that provides clean and predictable state management along with some very fancy debugging features.&lt;&#x2F;li&gt;
&lt;li&gt;A Python programmer who wants to use React or Electron still has to navigate through the very confusing tooling (&lt;em&gt;npm&lt;&#x2F;em&gt;, &lt;em&gt;webpack&lt;&#x2F;em&gt;, &lt;em&gt;babel&lt;&#x2F;em&gt; etc.) before they can even start to create anything useful.&lt;&#x2F;li&gt;
&lt;li&gt;I don’t want to deal with Javascript to design my UI.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There has to be a way to do all this in Python!&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-magic-of-websockets&quot;&gt;The Magic of Websockets&lt;&#x2F;h4&gt;
&lt;p&gt;Last week, I came across this &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@tryexceptpass&#x2F;a-python-ate-my-gui-971f2326ce59#.lpb3pnf2d&quot;&gt;article&lt;&#x2F;a&gt; which seemed to reflect many of the problems that I had faced when it came to Python GUIs. The article is part of a 3-part (so far) series that ends with the creation of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;github.com&#x2F;tryexceptpass&#x2F;sofi&quot;&gt;Sofi&lt;&#x2F;a&gt; (Cheers &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;u&#x2F;138c0eb26be5&quot;&gt;Cristian&lt;&#x2F;a&gt;!). As described in the article, Sofi is:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;a system that will generate the necessary HTML and JavaScript code typically needed to produce a single-page application and serve it up through WebSockets&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Though it is at a very early stage in its design, Sofi seems to do what it is supposed to. It allows you to design UIs in Python while leveraging web technologies like Bootstrap to render them. One thing I did not like about Sofi was the imperative nature of the UI design which reminded me of jQuery (and maybe a bit of Java AWT). After my experience with React, I wanted something declarative and functional.&lt;&#x2F;p&gt;
&lt;p&gt;So, is it possible to leverage websockets to implement something that keeps the general idea behind Sofi, but is declarative and functional like React?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;flybywire&quot;&gt;flybywire&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;em&gt;flybywire&lt;&#x2F;em&gt; is my ongoing experiment based on Sofi to create a more declarative UI library. It re-renders the page every time the state changes. It uses a virtual-dom system similar to that used by React, to only update those parts of the page that have actually changed. The coding style in &lt;em&gt;flybywire&lt;&#x2F;em&gt; applications was modeled after that of React. The library includes a helper function that allows components to be defined in a syntax inspired by JSX.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;usage&quot;&gt;Usage&lt;&#x2F;h4&gt;
&lt;p&gt;Below is a really simple demo app that is included with the library:&lt;&#x2F;p&gt;
&lt;p&gt;A simple counter app made using &lt;strong&gt;flybywire&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And this is &lt;strong&gt;counter.py.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#2b303b;color:#c0c5ce;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;flybywire.core &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;App  
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;flybywire.dom &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;h
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;CounterView&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;count&lt;&#x2F;span&gt;&lt;span&gt;):  
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;A simple functional stateless component.&amp;quot;&amp;quot;&amp;quot;  
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;h&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;h1&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;(count))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;class &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ebcb8b;&quot;&gt;CounterApp&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eff1f5;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;App&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eff1f5;&quot;&gt;):  
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span&gt;\&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#bf616a;color:#2b303b;&quot;&gt;_\_init\_\_(self):  &lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;Initialize the application.&lt;&#x2F;span&gt;&lt;span&gt;&amp;quot;&amp;quot;&amp;quot;  
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#96b5b4;&quot;&gt;super&lt;&#x2F;span&gt;&lt;span&gt;().\&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#bf616a;color:#2b303b;&quot;&gt;_\_init\_\_()  &lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.set\&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#bf616a;color:#2b303b;&quot;&gt;_initial\_state(0)&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;render&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):  
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Renders view given application state.&amp;quot;&amp;quot;&amp;quot;  
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;h&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;div&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;,  
&lt;&#x2F;span&gt;&lt;span&gt;                    \&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#bf616a;color:#2b303b;&quot;&gt;[CounterView(count=self.state),  &lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;                     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;h&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;button&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;onclick &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.increment),  
&lt;&#x2F;span&gt;&lt;span&gt;                     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;h&lt;&#x2F;span&gt;&lt;span&gt;(&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;button&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#a3be8c;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;&amp;#39;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;onclick &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.decrement)\&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#bf616a;color:#2b303b;&quot;&gt;]  &lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;                )
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;increment&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span&gt;):  
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Increments counter.&amp;quot;&amp;quot;&amp;quot;  
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.set\&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#bf616a;color:#2b303b;&quot;&gt;_state(self.state + 1)&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b48ead;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8fa1b3;&quot;&gt;decrement&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span&gt;):  
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#65737e;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Decrements counter.&amp;quot;&amp;quot;&amp;quot;  
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;.set\&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#bf616a;color:#2b303b;&quot;&gt;_state(self.state - 1)&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;app = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;CounterApp&lt;&#x2F;span&gt;&lt;span&gt;()  
&lt;&#x2F;span&gt;&lt;span&gt;app.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#bf616a;&quot;&gt;start&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;how-it-works&quot;&gt;How it Works&lt;&#x2F;h4&gt;
&lt;p&gt;The structure of the code above should be very familiar to anyone who has worked with React before. &lt;em&gt;flybywire&lt;&#x2F;em&gt; provides a helper function for building DOM structures. It is also possible to compose the UI out of stateless, functional components (like &lt;strong&gt;CounterView&lt;&#x2F;strong&gt; in the above example). This DOM structure is then converted into JSON format and sent to the browser over websockets using the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.autobahn.ws&#x2F;python&#x2F;&quot;&gt;autobahn&lt;&#x2F;a&gt; library. The javascript part of the library parses the virtual-DOM structure out of the JSON data and patches the existing DOM wherever it has changed. Any DOM event callbacks are also setup to be passed back to the Python app over websockets.&lt;&#x2F;p&gt;
&lt;p&gt;Some of the core parts of this library such as the event server and event processor were directly taken from Sofi with a few modifications. Instead of Bootstrap-based widgets, &lt;em&gt;flybywire&lt;&#x2F;em&gt; allows you to define your own components that can be composed to form whatever widget you need.&lt;&#x2F;p&gt;
&lt;p&gt;It is now possible to make some really simple apps using &lt;em&gt;flybywire&lt;&#x2F;em&gt;. However, the library is at a very early stage, given that the First Commit in the repository was only three days ago!&lt;&#x2F;p&gt;
&lt;h4 id=&quot;what-doesn-t-work&quot;&gt;What doesn’t work&lt;&#x2F;h4&gt;
&lt;p&gt;Here’s some things that are missing and&#x2F;or acts weird:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Some basic manipulations of the DOM elements such as focusing a particular input box or clearing the input box after a certain action is completed are currently not possible. This will probably require putting back some of the command system from Sofi that I had removed when making &lt;em&gt;flybywire&lt;&#x2F;em&gt;. This can also possibly be fixed by moving to a platform like Electron which may give greater control over the rendering process.&lt;&#x2F;li&gt;
&lt;li&gt;The server shuts down as soon as you close the browser window. This is done on purpose as there is currently no way to reset the application state without restarting the server. The shared state also results in weird behavior if you open multiple windows. Once we move to a platform like Electron, &lt;em&gt;flybywire&lt;&#x2F;em&gt; will have hopefully have more fine control over the life cycle of the application.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;coming-soon&quot;&gt;&lt;strong&gt;Coming Soon&lt;&#x2F;strong&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;I will probably add a few more features over the weekend, particularly a better Component class for creating stateful components. Any suggestions&#x2F;comments&#x2F;ideas and constructive criticism are welcome!&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
