<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>~/ on Max's blog</title><link>http://max-amb.com/</link><description>Recent content in ~/ on Max's blog</description><generator>Hugo</generator><language>en-gb</language><lastBuildDate>Wed, 23 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="http://max-amb.com/index.xml" rel="self" type="application/rss+xml"/><item><title>~/about-me/</title><link>http://max-amb.com/about-me/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>http://max-amb.com/about-me/</guid><description>&lt;p>Hi! I am Max Ambaum, a student at the &lt;a href="https://warwick.ac.uk/">University of Warwick&lt;/a> in the UK where I study discrete mathematics (mathematics, computer science and the large intersection) and I am just starting second year.
I love pure mathematics as well as most things software (including Nix and Rust), which I suppose makes my university course a good fit?
Also, I play trumpet and violin, and I enjoy classical music (perhaps by extension).&lt;/p></description></item><item><title>Your type checker may be wrong - an introduction to formal proof verification and the Curry-Howard Correspondence</title><link>http://max-amb.com/blog/your_type_checker_may_be_wrong/</link><pubDate>Sat, 25 Jul 2026 09:50:01 +0100</pubDate><guid>http://max-amb.com/blog/your_type_checker_may_be_wrong/</guid><description>&lt;details>
 &lt;summary>Contents&lt;/summary>
 
&lt;nav id="TableOfContents">
 &lt;ul>
 &lt;li>&lt;a href="#the-curry-howard-correspondence">The Curry-Howard correspondence&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#how-do-proof-assistants-use-the-ch-correspondence">How do proof assistants use the CH correspondence&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#a-theorem">A theorem&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#a-proof-of-the-theorem">A proof of the theorem&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#the-type-checker">The type checker&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#limitations-of-the-type-checker">Limitations of the type checker&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#mathematical-consequences-and-proof">Mathematical consequences (and proof)&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#your-type-checker-maybe-wrong">Your type checker maybe wrong&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#conclusion">Conclusion&lt;/a>&lt;/li>
 &lt;/ul>
&lt;/nav>


&lt;/details>

&lt;p>When writing code many of us have been saved time and time again by type checkers: the useful piece of software that ensures you aren&amp;rsquo;t adding a string to an integer &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> or returning a reference to a value instead of the owned value. However, while useful, and sometimes annoying, it seems that the humble type checker has limited capability beyond its noble task of saving our asses&amp;hellip;&lt;/p></description></item><item><title>Zero knowledge Tolstoyan art</title><link>http://max-amb.com/blog/zero_knowledge_tolstoyan_art/</link><pubDate>Sat, 11 Jul 2026 00:00:00 +0000</pubDate><guid>http://max-amb.com/blog/zero_knowledge_tolstoyan_art/</guid><description>&lt;details>
 &lt;summary>Contents&lt;/summary>
 
&lt;nav id="TableOfContents">
 &lt;ul>
 &lt;li>&lt;a href="#tolstoyan-art">Tolstoyan art&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#zero-knowledge-proof">Zero-knowledge proof&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#a-marriage-of-or-casual-relationship-between-the-two">A marriage of (or casual relationship between) the two&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#conclusion">Conclusion&lt;/a>&lt;/li>
 &lt;/ul>
&lt;/nav>


&lt;/details>

&lt;p>In this post I hope to &lt;em>prove to you&lt;/em> (get it 😉) in rather uncertain terms, that:&lt;/p>
&lt;blockquote>
&lt;p>Tolstoyan art has the structure of a zero knowledge proof.&lt;/p>&lt;/blockquote>
&lt;p>Currently, this statement is a big nothing-burger, so first we will discuss the high level ideas of Tolstoyan art and zero knowledge proofs.&lt;/p>
&lt;h2 id="tolstoyan-art">Tolstoyan art&lt;/h2>
&lt;p>In Tolstoy&amp;rsquo;s 1897 book, what is art? &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>, he discusses what it means for some piece of work to be art. In chapter V, he states that the activity of art is&lt;/p></description></item><item><title>Some intuition behind the contrapositive</title><link>http://max-amb.com/blog/some_intuition_behind_the_contrapositive/</link><pubDate>Sat, 27 Jun 2026 00:00:00 +0000</pubDate><guid>http://max-amb.com/blog/some_intuition_behind_the_contrapositive/</guid><description>&lt;details>
 &lt;summary>Contents&lt;/summary>
 
&lt;nav id="TableOfContents">
 &lt;ul>
 &lt;li>&lt;a href="#introduction">Introduction&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#the-explanation">The explanation&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#conclusion">Conclusion&lt;/a>&lt;/li>
 &lt;/ul>
&lt;/nav>


&lt;/details>

&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>While quite a fundamental law in logic, the contrapositive is certainly not immediately intuitive (or at least it was not to me).
After someone else expressed a similar feeling, I decided to try and derive some intuition to explain the rule, the results of which can be found here!
This blog could also be treated as an introduction to the contrapositive.&lt;/p>
&lt;p>Before we begin, I would like to show how the formal definition of the contrapositive looks.
I like to think that definitions codify intuition, but it only goes one way.
That is, we can turn intuition into definitions, but trying to gain intuition from a definition is a faux pas.
Towards the end of this post we will revisit it, and hopefully, you will see your newfound intuition reflected in the definition.&lt;/p></description></item><item><title>An introduction to Turing machines and computation</title><link>http://max-amb.com/blog/an_introduction_to_turing_machines_and_computation/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><guid>http://max-amb.com/blog/an_introduction_to_turing_machines_and_computation/</guid><description>&lt;details>
 &lt;summary>Contents&lt;/summary>
 
&lt;nav id="TableOfContents">
 &lt;ul>
 &lt;li>&lt;a href="#introduction">Introduction&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#should-you-read-this">Should you read this?&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#the-turing-machine">The Turing machine&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#the-intuitive-approach">The intuitive approach&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#a-mathematical-approach">A mathematical approach&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#languages">Languages&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#wordsstrings">Words/Strings&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#languages-from-words">Languages from words&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#distinguishing-turing-machines-with-respect-to-a-language">Distinguishing Turing machines with respect to a language&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#a-recogniser">A recogniser&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#a-decider">A decider&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#distinguishing-languages">Distinguishing languages&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#a-first-result">A first result&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#proof-of-turing-recognisability">Proof of Turing-recognisability&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#a-second-more-exciting-result">A second, more exciting result&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#proof-of-non-decidability">Proof of non-decidability&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#a-discussion-of-the-proof">A discussion of the proof&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#the-halting-problem-and-conclusion">The halting problem? (and conclusion)&lt;/a>&lt;/li>
 &lt;/ul>
&lt;/nav>


&lt;/details>

&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>This blog aims to provide a short (but slightly longer than intended), and potentially useful, introduction to Turing machines.
Turing machines are so fundamental to Computer Science and the study of computability (i.e. can this thing be computed? In finite time?), that an understanding of the key elements and results can only further one&amp;rsquo;s appreciation for the field.&lt;/p></description></item><item><title>Minimising the product of sums chosen from intervals</title><link>http://max-amb.com/blog/minimising_the_product_of_sums_chosen_from_intervals/</link><pubDate>Sun, 07 Sep 2025 00:00:00 +0100</pubDate><guid>http://max-amb.com/blog/minimising_the_product_of_sums_chosen_from_intervals/</guid><description>&lt;details>
 &lt;summary>Contents&lt;/summary>
 
&lt;nav id="TableOfContents">
 &lt;ul>
 &lt;li>&lt;a href="#the-problem">The problem&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#an-example">An example&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#the-solution">The solution&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#lemma-one">Lemma one&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#lemma-two">Lemma two&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#conclusion">Conclusion&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#generalisation">Generalisation&lt;/a>&lt;/li>
 &lt;/ul>
&lt;/nav>


&lt;/details>

&lt;p>What a catchy name!
I&amp;rsquo;d like to explain this problem, and then provide a wordy proof for a general case.
All the proofs are hidden in drop downs to motivate you to try them yourself and to make the blog less dense, if you have any questions about the proofs (or anything else), please leave them below!&lt;/p></description></item><item><title>The main components of the MLP</title><link>http://max-amb.com/blog/the_main_components_of_the_mlp/</link><pubDate>Sun, 17 Aug 2025 00:00:00 +0100</pubDate><guid>http://max-amb.com/blog/the_main_components_of_the_mlp/</guid><description>&lt;details>
 &lt;summary>Contents&lt;/summary>
 
&lt;nav id="TableOfContents">
 &lt;ul>
 &lt;li>&lt;a href="#the-structure-of-the-network">The structure of the network&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#the-new-function">The new function&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#arguments">Arguments&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#network-setup">Network setup&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#weight-initialisation">Weight initialisation&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#initialisation-options">Initialisation options&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#bias-initialisation">Bias initialisation&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#returning">Returning&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#the-forward-pass-function">The forward pass function&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#arguments-1">Arguments&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#return-value">Return value&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#initialisation">Initialisation&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#all-layers-but-one">All layers but one&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#the-one-layer">The one layer&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#conclusion">Conclusion&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#appendix">Appendix&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#the-rng-tangent">The RNG tangent&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;/ul>
&lt;/nav>


&lt;/details>

&lt;p>This is the second iteration in the &lt;a href="http://max-amb.com/series/the-making-of-a-mlp/">series&lt;/a> where we are building a Multi-Layer-Perceptron (MLP) from scratch!
This post will consider the main sections of the code in the MLP, which are the:&lt;/p></description></item><item><title>The maths behind the MLP</title><link>http://max-amb.com/blog/the_maths_behind_the_mlp/</link><pubDate>Wed, 13 Aug 2025 00:00:00 +0000</pubDate><guid>http://max-amb.com/blog/the_maths_behind_the_mlp/</guid><description>&lt;details>
 &lt;summary>Contents&lt;/summary>
 
&lt;nav id="TableOfContents">
 &lt;ul>
 &lt;li>&lt;a href="#why-from-scratch">Why from scratch&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#intuition">Intuition?&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#notation">Notation&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#forward-pass">Forward pass&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#matrix-notation">Matrix notation&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#vector-of-z-values">Vector of z values&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#vector-of-neuron-values">Vector of neuron values&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#non-linearity">Non-linearity&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#conclusion">Conclusion&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#backpropagation">Backpropagation&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#output-layer-derivatives">Output layer derivatives&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#bias-derivative">Bias derivative&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#weight-derivative">Weight derivative&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#delta">Delta&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#representation-of-output-layer-backpropagation-as-a-matrix-operation">Representation of output layer backpropagation as a matrix operation&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#added-notation">Added notation&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#conclusion-of-the-output-layer-derivatives">Conclusion of the output layer derivatives&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#hidden-layer-derivatives">Hidden layer derivatives&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#intuition-behind-the-derivative-sum">Intuition behind the derivative sum&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#derivative-of-the-bias">Derivative of the bias&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#derivative-of-the-weight">Derivative of the weight&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#deltas-again">Delta&amp;rsquo;s again&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#representation-of-hidden-layer-backpropagation-as-a-matrix-operation">Representation of hidden layer backpropagation as a matrix operation&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#conclusion-of-the-hidden-layer-derivatives">Conclusion of the hidden layer derivatives&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#summary">Summary&lt;/a>&lt;/li>
 &lt;/ul>
&lt;/nav>


&lt;/details>

&lt;p>This blog(/tutorial maybe?) is the first part in a walk-through of the process I followed to build a multi-layer-perceptron (MLP) from scratch in rust. Followed by using it to classify the &lt;a href="https://en.wikipedia.org/wiki/MNIST_database">MNIST dataset&lt;/a>. The source code for the MLP can be found &lt;a href="https://github.com/max-amb/number_recognition">here&lt;/a>.&lt;/p></description></item></channel></rss>