<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Posts on BlueHour</title>
    <link>https://keqing996.github.io/posts/</link>
    <description>Recent content in Posts on BlueHour</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Sat, 27 Sep 2025 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://keqing996.github.io/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Notes on Developing Vulkan on Mac</title>
      <link>https://keqing996.github.io/posts/programming/20250927_vulkanonapple/</link>
      <pubDate>Sat, 27 Sep 2025 00:00:00 +0000</pubDate>
      <guid>https://keqing996.github.io/posts/programming/20250927_vulkanonapple/</guid>
      <description>&lt;h1 id=&#34;setup-environment-on-macos&#34;&gt;Setup environment on MacOS&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;First, install the Vulkan SDK. I recommend downloading the latest version from the &lt;a href=&#34;https://vulkan.lunarg.com/sdk/home#mac&#34;&gt;LunarG website&lt;/a&gt;. The default install path is usually &lt;strong&gt;/Users/$USER/VulkanSDK/version-number&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The SDK includes a script named &lt;strong&gt;setup-env.sh&lt;/strong&gt; for setting environment variables, so you need to run it every time your shell starts.&lt;/li&gt;
&lt;li&gt;Open your shell config file, such as &lt;sub&gt;/.zshrc for zsh or &lt;/sub&gt;/.bash_profile for bash, and add the following line. This gives every new shell session the corresponding Vulkan environment variables, and CMake can also find Vulkan through find_package.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Note: replace this path with your actual VulkanSDK installation path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;source&lt;/span&gt; /Users/USER/VulkanSDK/1.3.xxx.x/setup-env.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;moltenvk&#34;&gt;MoltenVK&lt;/h1&gt;
&lt;p&gt;Apple&amp;rsquo;s native graphics API is Metal, and there is no native Vulkan implementation on macOS. So you need MoltenVK to translate Vulkan calls into Metal calls. If you installed the Vulkan SDK, MoltenVK is already included. One extra thing to watch out for: when creating Vulkan-related contexts, there are three places you need to configure.&lt;/p&gt;</description>
    </item>
    <item>
      <title>C#, Java, and Cpp Communication in Unity</title>
      <link>https://keqing996.github.io/posts/programming/20240912_unityjavaandjni/</link>
      <pubDate>Thu, 12 Sep 2024 00:00:00 +0000</pubDate>
      <guid>https://keqing996.github.io/posts/programming/20240912_unityjavaandjni/</guid>
      <description>&lt;p&gt;This post covers four things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How C# calls Java functions in Unity.&lt;/li&gt;
&lt;li&gt;How Java calls C++ through JNI.&lt;/li&gt;
&lt;li&gt;How C++ under JNI calls Java.&lt;/li&gt;
&lt;li&gt;How Java calls Unity&amp;rsquo;s C#.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;csharp-call-java&#34;&gt;CSharp Call Java&lt;/h2&gt;
&lt;p&gt;Use Unity&amp;rsquo;s &lt;code&gt;AndroidJavaObject&lt;/code&gt;, and pass the Java class object into the constructor. The format is the package name followed by the class name.&lt;/p&gt;
&lt;p&gt;For example, in Java:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;package&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nn&#34;&gt;com.example.jni&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;ExampleJavaClass&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Function with no return value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;TestFuncVoid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* ... */&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Function with a return value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;TestFuncInt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;cm&#34;&gt;/* ... */&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In CSharp, write it like this:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cross-Compiling C&#43;&#43; for Android Without Android Studio</title>
      <link>https://keqing996.github.io/posts/programming/20231217_crosscompileandroidcpp/</link>
      <pubDate>Sun, 17 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://keqing996.github.io/posts/programming/20231217_crosscompileandroidcpp/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/keqing996/AndroidCppCrossCompile&#34;&gt;AndroidCppCrossCompile&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Android Studio has quite a few bugs, and the C++ development experience is not exactly great. A lot of the time, when we need to do JNI development or pure C++ development, we do not really want to do it inside Android Studio. So we need an environment for cross-compiling C++ programs for Android without relying on Android Studio.&lt;/p&gt;
&lt;p&gt;Next, I will use CMake to build the whole workflow. First, the preparation: you must download the NDK, because we need to use the NDK toolchain. The version I use here is r23c.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Using Arm64 Assembly on Android</title>
      <link>https://keqing996.github.io/posts/programming/20231016_arm64onandroid/</link>
      <pubDate>Mon, 16 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://keqing996.github.io/posts/programming/20231016_arm64onandroid/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/keqing996/AndroidCppWithAsm&#34;&gt;AndroidAsm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;First, create an Android Studio JNI project. By default, the project will generate a C++ file that calls a native function from the Java side to display a string.&lt;/p&gt;
&lt;p&gt;The function generated on the Cpp side uses static binding, so the function name is extremely long and not very pleasant to look at. Let&amp;rsquo;s change it to dynamic binding first. Start by renaming that verbose function.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-C++&#34; data-lang=&#34;C++&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;JNIEXPORT&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;jstring&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JNICALL&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;StringFromJNI&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JNIEnv&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;jclass&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clazz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hello&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Hello World From JNI&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NewStringUTF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c_str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, implement dynamic binding. Add a function called JniOnLoad to the Cpp file, and load the native function from the Java side inside this function.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Lock-Free Programming</title>
      <link>https://keqing996.github.io/posts/programming/20230421_lockfree/</link>
      <pubDate>Fri, 21 Apr 2023 00:00:00 +0000</pubDate>
      <guid>https://keqing996.github.io/posts/programming/20230421_lockfree/</guid>
      <description>&lt;h1 id=&#34;lock-free-programming&#34;&gt;Lock-Free Programming&lt;/h1&gt;
&lt;p&gt;The goal of lock-free programming is not to make synchronization &amp;ldquo;free&amp;rdquo;. It is to avoid as much of the extra overhead of traditional locks as possible in highly concurrent scenarios.&lt;/p&gt;
&lt;p&gt;In a multithreaded environment, the most common and simplest synchronization tool is still a lock. For example, many implementations of &lt;code&gt;std::mutex&lt;/code&gt; try to stay in user space when there is no contention. But once contention becomes heavy, threads may block, wake up, and context switch, and performance can drop sharply. Even when the kernel is not involved, locks can still introduce cache synchronization, pipeline stalls, and scheduling overhead.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Getting Started with OpenGL Using SFML</title>
      <link>https://keqing996.github.io/posts/programming/20211022_openglwithsfml/</link>
      <pubDate>Fri, 22 Oct 2021 00:00:00 +0000</pubDate>
      <guid>https://keqing996.github.io/posts/programming/20211022_openglwithsfml/</guid>
      <description>&lt;p&gt;If you have ever taught yourself OpenGL, you probably remember the pain of pulling in a whole pile of libraries. GLEW and GLUT in particular are awkward to use. SFML makes opening a window very simple, and for anyone learning OpenGL, I think it can completely replace GLUT. So in this post I will use SFML to create the window, then write a casual OpenGL example: a simple forward renderer using the Phong model.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Differential Geometry</title>
      <link>https://keqing996.github.io/posts/math/differentialgeometry/20211007_differentialgeometry/</link>
      <pubDate>Thu, 07 Oct 2021 00:00:00 +0000</pubDate>
      <guid>https://keqing996.github.io/posts/math/differentialgeometry/20211007_differentialgeometry/</guid>
      <description>&lt;h1 id=&#34;theory-of-curves&#34;&gt;Theory of Curves&lt;/h1&gt;
&lt;h2 id=&#34;a-few-results-i-often-forget&#34;&gt;A Few Results I Often Forget&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Double cross product formula&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;math-display&#34;&gt;
$$

(\vec{a} \times \vec{b}) \times \vec{c} = 
\vec{b} (\vec{a} \cdot \vec{c}) - \vec{a} (\vec{b} \cdot \vec{c})

$$
&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Lagrange identity&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;math-display&#34;&gt;
$$

(\vec{a} \times \vec{b}) (\vec{c} \times \vec{d})=
(\vec{a}\cdot\vec{c})(\vec{b}\cdot\vec{d})-(\vec{a}\cdot\vec{d})(\vec{b}\cdot\vec{c})

$$
&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Suppose the vector-valued function &lt;span class=&#34;math-inline&#34;&gt;${a}(t)$&lt;/span&gt; is nowhere zero and continuously differentiable. Then the length of &lt;span class=&#34;math-inline&#34;&gt;${a}(t)$&lt;/span&gt; is constant if and only if:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;math-display&#34;&gt;
$$

\vec{a}^{\prime}(t) \cdot \vec{a}(t) \equiv 0

$$
&lt;/div&gt;&lt;h2 id=&#34;regular-parametric-curves&#34;&gt;Regular Parametric Curves&lt;/h2&gt;
&lt;p&gt;A parametric curve &lt;span class=&#34;math-inline&#34;&gt;${\textbf{r} }(t)$&lt;/span&gt; is a regular parametric curve if it satisfies the following conditions:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Topology 05 - Homogeneous Coordinates and Projective Geometry</title>
      <link>https://keqing996.github.io/posts/math/topology/20210905_homogeneouscoordinatesprojectivegeometry/</link>
      <pubDate>Sun, 05 Sep 2021 00:00:00 +0000</pubDate>
      <guid>https://keqing996.github.io/posts/math/topology/20210905_homogeneouscoordinatesprojectivegeometry/</guid>
      <description>&lt;h1 id=&#34;homogeneous-coordinates-and-projective-geometry&#34;&gt;Homogeneous Coordinates and Projective Geometry&lt;/h1&gt;
&lt;p&gt;If you work in computer graphics, you deal with the following operations every day:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A point in 3D space is written as a 4D vector &lt;span class=&#34;math-inline&#34;&gt;$(x,y,z,w)$&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;math-inline&#34;&gt;$(x,y,z,w)$&lt;/span&gt; and &lt;span class=&#34;math-inline&#34;&gt;$(kx,ky,kz,kw)\;(k \neq 0)$&lt;/span&gt; represent the same point.&lt;/li&gt;
&lt;li&gt;At render time, you perform a &amp;ldquo;perspective divide&amp;rdquo;: &lt;span class=&#34;math-inline&#34;&gt;$(x/w,\;y/w,\;z/w)$&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;&lt;span class=&#34;math-inline&#34;&gt;$w=0$&lt;/span&gt; is treated as a &amp;ldquo;direction&amp;rdquo;—a point at infinity.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This design is not a graphics programmer&amp;rsquo;s invention. Its roots lie in &lt;strong&gt;19th-century projective geometry&lt;/strong&gt;. Homogeneous coordinates are not an engineering hack; they are the most natural coordinate system for projective space.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Topology 04 - Quaternions</title>
      <link>https://keqing996.github.io/posts/math/topology/20210830_quaternion/</link>
      <pubDate>Mon, 30 Aug 2021 00:00:00 +0000</pubDate>
      <guid>https://keqing996.github.io/posts/math/topology/20210830_quaternion/</guid>
      <description>&lt;h1 id=&#34;quaternions&#34;&gt;Quaternions&lt;/h1&gt;
&lt;h2 id=&#34;algebraic-definition&#34;&gt;Algebraic Definition&lt;/h2&gt;
&lt;p&gt;Let &lt;span class=&#34;math-inline&#34;&gt;$\mathbb{H}=\lbrace a&amp;#43;bi&amp;#43;cj&amp;#43;dk \mid a,b,c,d \in \mathbb{R}\rbrace$&lt;/span&gt;. There is a vector-space structure on &lt;span class=&#34;math-inline&#34;&gt;$\mathbb{H}$&lt;/span&gt;:&lt;/p&gt;
&lt;div class=&#34;math-display&#34;&gt;
$$

\cdot: \mathbb{R} \times \mathbb{H} \rightarrow \mathbb{H}:
(\lambda, a&amp;#43;bi&amp;#43;cj&amp;#43;dk) \rightarrow (\lambda, \lambda a&amp;#43;\lambda bi&amp;#43;\lambda cj&amp;#43;\lambda dk)

$$
&lt;/div&gt;&lt;p&gt;
&lt;/p&gt;
&lt;div class=&#34;math-display&#34;&gt;
$$

\begin{aligned}
&amp;#43;:\mathbb{H} \times \mathbb{H} \rightarrow \mathbb{H}:
(a_1&amp;#43;b_1i&amp;#43;c_1j&amp;#43;d_1k, a_2&amp;#43;b_2i&amp;#43;c_2j&amp;#43;d_2k) \\
\rightarrow (a_1&amp;#43;a_2, (b_1&amp;#43;b_2)i,(c_1&amp;#43;c_2)j,(d_1&amp;#43;d_2)k)
\end{aligned}

$$
&lt;/div&gt;&lt;p&gt;Clearly &lt;span class=&#34;math-inline&#34;&gt;$(\mathbb{H},&amp;#43;)$&lt;/span&gt; is an abelian group, so &lt;span class=&#34;math-inline&#34;&gt;$(\mathbb{H},&amp;#43;,\cdot)$&lt;/span&gt; is an &lt;span class=&#34;math-inline&#34;&gt;$\mathbb{R}$&lt;/span&gt;-linear space.&lt;/p&gt;
&lt;p&gt;In addition, we define a multiplication operation on &lt;span class=&#34;math-inline&#34;&gt;$\mathbb{H}$&lt;/span&gt;. First set:&lt;/p&gt;
&lt;div class=&#34;math-display&#34;&gt;
$$

i^2=j^2=k^2=ijk=-1

$$
&lt;/div&gt;&lt;div class=&#34;math-display&#34;&gt;
$$

ij=k,jk=i,ki=j,ji=-k,kj=-i,ik=-j

$$
&lt;/div&gt;&lt;p&gt;Then multiplication is defined componentwise. To keep the notation lighter, the imaginary part can be written as a vector: &lt;span class=&#34;math-inline&#34;&gt;$\vec{v}=(b,c,d)$&lt;/span&gt;. A quaternion can then be written as &lt;span class=&#34;math-inline&#34;&gt;$x=[a,\vec{v}]=a&amp;#43;\vec{v}$&lt;/span&gt;; this is only notation, and does not mean we are adding a scalar and a vector.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Topology 03 - Quotient Sets</title>
      <link>https://keqing996.github.io/posts/math/topology/20210821_quotientset/</link>
      <pubDate>Sat, 21 Aug 2021 00:00:00 +0000</pubDate>
      <guid>https://keqing996.github.io/posts/math/topology/20210821_quotientset/</guid>
      <description>&lt;h1 id=&#34;quotients&#34;&gt;Quotients&lt;/h1&gt;
&lt;h2 id=&#34;quotient-sets&#34;&gt;Quotient Sets&lt;/h2&gt;
&lt;p&gt;Let &lt;span class=&#34;math-inline&#34;&gt;$X$&lt;/span&gt; be a set. An &lt;strong&gt;equivalence relation&lt;/strong&gt; on &lt;span class=&#34;math-inline&#34;&gt;$X$&lt;/span&gt; is a relation that is reflexive, symmetric, and transitive.&lt;/p&gt;
&lt;p&gt;Let &lt;span class=&#34;math-inline&#34;&gt;$X$&lt;/span&gt; be a set, and let &lt;span class=&#34;math-inline&#34;&gt;$\sim$&lt;/span&gt; be an equivalence relation on &lt;span class=&#34;math-inline&#34;&gt;$X$&lt;/span&gt;. For any &lt;span class=&#34;math-inline&#34;&gt;$a \in X$&lt;/span&gt;, the set &lt;span class=&#34;math-inline&#34;&gt;$\bar{a} =\lbrace b \in X | b \sim a \rbrace$&lt;/span&gt; is the &lt;strong&gt;equivalence class&lt;/strong&gt; containing &lt;span class=&#34;math-inline&#34;&gt;$a$&lt;/span&gt;. An equivalence class is a special kind of subset: if two equivalence classes intersect, then they must actually be the same class (by transitivity).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Topology 02 - Continuity, Compactness, and Connectedness</title>
      <link>https://keqing996.github.io/posts/math/topology/20210810_continuitycompactnessconnectedness/</link>
      <pubDate>Tue, 10 Aug 2021 00:00:00 +0000</pubDate>
      <guid>https://keqing996.github.io/posts/math/topology/20210810_continuitycompactnessconnectedness/</guid>
      <description>&lt;h1 id=&#34;continuitycompactnessconnectedness&#34;&gt;Continuity/Compactness/Connectedness&lt;/h1&gt;
&lt;h2 id=&#34;the-definition-of-continuity&#34;&gt;The Definition of Continuity&lt;/h2&gt;
&lt;p&gt;In mathematical analysis, we define continuity of a function like this: &lt;span class=&#34;math-inline&#34;&gt;$f$&lt;/span&gt; is continuous at &lt;span class=&#34;math-inline&#34;&gt;$x\_0$&lt;/span&gt; if for every &lt;span class=&#34;math-inline&#34;&gt;$\epsilon$&lt;/span&gt;, there exists a &lt;span class=&#34;math-inline&#34;&gt;$\delta$&lt;/span&gt; such that for every &lt;span class=&#34;math-inline&#34;&gt;$x \in R^n$&lt;/span&gt;, if &lt;span class=&#34;math-inline&#34;&gt;$\vert \vert x - x\_0 \vert \vert &amp;lt; \delta$&lt;/span&gt;, then &lt;span class=&#34;math-inline&#34;&gt;$\vert \vert f(x) - f(x\_0) \vert \vert &amp;lt; \epsilon$&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;And we define an open set in &lt;span class=&#34;math-inline&#34;&gt;$R^n$&lt;/span&gt; as follows: &lt;span class=&#34;math-inline&#34;&gt;$U \subset R^n$&lt;/span&gt; is called an open set in &lt;span class=&#34;math-inline&#34;&gt;$R^n$&lt;/span&gt; if for every &lt;span class=&#34;math-inline&#34;&gt;$x \in U$&lt;/span&gt;, there exists a &lt;span class=&#34;math-inline&#34;&gt;$\delta$&lt;/span&gt; such that &lt;span class=&#34;math-inline&#34;&gt;$B(x;\delta) \subset U$&lt;/span&gt;, where &lt;span class=&#34;math-inline&#34;&gt;$B(x;\delta)$&lt;/span&gt; is an open ball.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Topology 01 - Open Sets, Topologies, and Limit Points</title>
      <link>https://keqing996.github.io/posts/math/topology/20210801_opensettopologylimit/</link>
      <pubDate>Sun, 01 Aug 2021 00:00:00 +0000</pubDate>
      <guid>https://keqing996.github.io/posts/math/topology/20210801_opensettopologylimit/</guid>
      <description>&lt;p&gt;&lt;strong&gt;The ultimate goal of topology:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Classify spaces up to homeomorphism. This immediately leads to two questions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Given two spaces, how do we prove they are homeomorphic? This is often rather hard.&lt;/li&gt;
&lt;li&gt;Given two spaces, how do we prove they are not homeomorphic? This is relatively easier.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The effective tools for proving that two spaces are not homeomorphic are topological invariants.&lt;/p&gt;
&lt;h1 id=&#34;open-setstopologiescontinuity&#34;&gt;Open Sets/Topologies/Continuity&lt;/h1&gt;
&lt;h2 id=&#34;open-sets&#34;&gt;Open Sets&lt;/h2&gt;
&lt;p&gt;Let &lt;span class=&#34;math-inline&#34;&gt;$X$&lt;/span&gt; be a set, and let &lt;span class=&#34;math-inline&#34;&gt;$\mathscr{F}$&lt;/span&gt; be a family consisting of some subsets of &lt;span class=&#34;math-inline&#34;&gt;$X$&lt;/span&gt;. We call &lt;span class=&#34;math-inline&#34;&gt;$F$&lt;/span&gt; an open set in &lt;span class=&#34;math-inline&#34;&gt;$X$&lt;/span&gt; if:&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
