<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://leorfe.me//feed.xml" rel="self" type="application/atom+xml" /><link href="https://leorfe.me//" rel="alternate" type="text/html" /><updated>2026-08-27T04:42:33+00:00</updated><id>https://leorfe.me//feed.xml</id><title type="html">Leon’s Blog</title><subtitle>Here I upload the things that I (consider interesting) do</subtitle><author><name>Fernando Leon</name></author><entry><title type="html">Multilayer perceptrons, deep learning and number recognition</title><link href="https://leorfe.me//multilayer-perceptrons-and-deep-learning/" rel="alternate" type="text/html" title="Multilayer perceptrons, deep learning and number recognition" /><published>2023-01-09T00:00:00+00:00</published><updated>2023-01-09T00:00:00+00:00</updated><id>https://leorfe.me//multilayer-perceptrons-and-deep-learning</id><content type="html" xml:base="https://leorfe.me//multilayer-perceptrons-and-deep-learning/"><![CDATA[<script type="text/x-mathjax-config">

MathJax.Hub.Config({
tex2jax: { inlineMath: [["$","$"],["\\(","\\)"]] },
"HTML-CSS": {
  linebreaks: { automatic: true, width: "container" }          
}              
});

</script>

<p>New year, new post. Here I am again with a new topic that I found interesting to read after watching the videos of 3Blue1Brown on deep learning. It seems like the “Hello world!” of machine learning is making a neural network that recognizes handwritten digits, so today’s post will be about that.</p>

<h2 id="the-multilayer-perceptron">The multilayer perceptron</h2>
<p>An MLP (Multilayer perceptron) is a network of “neurons” connected in a forward manner from input neurons to the outputs.</p>

<p><img src="/images/2023-01-09-multilayer-perceptrons-and-deep-learning/mlp_1.png" width="80%" height="80%" /></p>

<p>The value of the neurons on each layer after the input is just a weighted sum of the values of the previous neurons passed through an activation function plus a bias. In this case for a perceptron:</p>

<p><img src="/images/2023-01-09-multilayer-perceptrons-and-deep-learning/perceptron.png" width="80%" height="80%" /></p>

<p>The term “MLP” seems to be used to generalize any neural network that not necessarily uses that activation function. Later I’ll show an interesting activation function that’s pretty similar to this one of a perceptron</p>

<h2 id="feedfowarding-to-the-outputs">Feedfowarding to the outputs</h2>

<p>The beauty of this topic is that everything is basically linear algebra and calculus. If we represent every weight, bias, and the value of a neuron per layer using a matrix, then we can use simple matrix operations to work our way to the outputs. For this, I’ll use the superscript as the layer and the subscript as the output \(a\) of the neuron and bias \(b\)</p>

\[\begin{bmatrix}
a^0_1 \\
a^0_2 \\
a^0_3 \\
a^0_4 \\
a^0_5
\end{bmatrix} \space\begin{bmatrix}
a^1_1 \\
a^1_2 \\
a^1_3
\end{bmatrix}
\space\begin{bmatrix}
a^2_1 \\
a^2_2 \\
a^2_3
\end{bmatrix}
\space\begin{bmatrix}
a^3_1 \\
a^3_2
\end{bmatrix}\]

\[\begin{bmatrix}
b^1_1 \\
b^1_2 \\
b^1_3
\end{bmatrix}
\space\begin{bmatrix}
b^2_1 \\
b^2_2 \\
b^2_3
\end{bmatrix}
\space\begin{bmatrix}
b^3_1 \\
b^3_2
\end{bmatrix}\]

<p>For the weights, the superscript will indicate to which layer they are connecting, and the subscript will show the connection of the neuron n to the neuron m of the previous layer</p>

\[\begin{bmatrix}
w^1_{11} &amp; w^1_{12} &amp; w^1_{13} &amp; w^1_{14} &amp; w^1_{15} \\
w^1_{21} &amp; w^1_{22} &amp; w^1_{23} &amp; w^1_{24} &amp; w^1_{25} \\
w^1_{31} &amp; w^1_{32} &amp; w^1_{33} &amp; w^1_{34} &amp; w^1_{35}
\end{bmatrix}

\space

\begin{bmatrix}
w^2_{11} &amp;w^2_{12}  &amp;w^2_{13}  \\
w^2_{21} &amp;w^2_{22}  &amp;w^2_{23}  \\
w^2_{31} &amp;w^2_{32}  &amp;w^2_{33} 
\end{bmatrix}

\space

\begin{bmatrix}
w^2{11} &amp; w^2{12} &amp; w^2{13} \\
 w^2{21}&amp; w^2{22} &amp;w^2{23} 
\end{bmatrix}\]

<p>Given the rules of matrix multiplication, for example, we multiply the inputs by the weights that connect to the next layer then we will get a matrix of size 3x1, the same number of neurons of our next layer.</p>

\[\begin{bmatrix}
w^1_{11} &amp; w^1_{12} &amp; w^1_{13} &amp; w^1_{14} &amp; w^1_{15} \\
w^1_{21} &amp; w^1_{22} &amp; w^1_{23} &amp; w^1_{24} &amp; w^1_{25} \\
w^1_{31} &amp; w^1_{32} &amp; w^1_{33} &amp; w^1_{34} &amp; w^1_{35}
\end{bmatrix}
\begin{bmatrix}
a^0_1 \\
a^0_2 \\
a^0_3 \\
a^0_4 \\
a^0_5
\end{bmatrix}=\begin{bmatrix}
a^0_1w^1_{11} + a^0_2w^1_{12} + a^0_3w^1_{13} + a^0_4w^1_{14} + a^0_5w^1_{15} \\
a^0_1w^1_{21} + a^0_2w^1_{12} + a^0_3w^1_{23} + a^0_4w^1_{24} + a^0_5w^1_{25} \\
a^0_1w^1_{31} + a^0_2w^1_{32} + a^0_3w^1_{33} + a^0_4w^1_{34} + a^0_5w^1_{35}
\end{bmatrix}\]

<p>Then adding the bias and applying our activation function \(f\) element-wise to the resulting vector will give us the value of the neurons for our first hidden layer.</p>

\[f\left(  \begin{bmatrix}
a^0_1w^1_{11} + a^0_2w^1_{12} + a^0_3w^1_{13} + a^0_4w^1_{14} + a^0_5w^1_{15} \\
a^0_1w^1_{21} + a^0_2w^1_{12} + a^0_3w^1_{23} + a^0_4w^1_{24} + a^0_5w^1_{25} \\
a^0_1w^1_{31} + a^0_2w^1_{32} + a^0_3w^1_{33} + a^0_4w^1_{34} + a^0_5w^1_{35}
\end{bmatrix}+\begin{bmatrix}
b^1_1 \\
b^1_2 \\
b^1_3
\end{bmatrix} \right)=\begin{bmatrix}
a^1_1 \\
a^1_2 \\
a^1_3
\end{bmatrix}\]

<p>Doing this all the way to the outputs will give you the prediction of the network with its current weights and biases. It could be right, or it could be wrong.</p>

<h2 id="deep-learning-with-backpropagation">Deep learning (with backpropagation)</h2>

<p>Deep learning is a set of rules defining how our network will “learn” to give the best possible output. We can see our network as a function that takes X inputs, N biases and M weights, process them and gives out an output vector. In order to train it, we need to have a large set of data that will have a series of inputs and the expected output, from here finding how far the predictions are from the expected outputs will allow us to tune the weights and biases until we start getting the predictions we want. Backpropagation does this by finding how much each parameter of the network affects the value of some cost function and reducing it. For this example our cost function will be:</p>

\[C_o=\frac{1}{2}\sum_{i}^{n}(y_i-a_i)^2\]

<!-- 87 score -->
<p>By using calculus we can create a gradient of our function that will allow us to tune each weight and bias in order to get each output \(a_i\) closer to those expected \(y_i\) outputs. Let’s see how is done for the weights and biases that go from the first neuron of the second-last layer to the first neuron of our last layer:</p>

<p><img src="/images/2023-01-09-multilayer-perceptrons-and-deep-learning/backprop_1.png" width="80%" height="80%" /></p>

<p>Using the multivariable chain rule will allow us to find how much one bias and weight affects the cost</p>

<p><img src="/images/2023-01-09-multilayer-perceptrons-and-deep-learning/backprop_2.png" width="50%" height="50%" /></p>

<p>Let’s say we want to find how much that bias affects the cost. This can done by computing the derivative of the cost with respect to the bias.</p>

\[\frac{\partial C_o}{\partial b^3_1}\]

<p>The chain rule tells us that this derivative will be equal to the products of all those derivatives with respect to the element that follows them from bottom to top</p>

\[\frac{\partial C_o}{\partial b^3_1}=\frac{\partial C_o}{\partial a^3_1}\cdot\frac{\partial a^3_1}{\partial z^3_1}\cdot \frac{\partial z^3_1}{\partial b^3_1}\]

<p>We know that</p>

\[\begin{matrix}
C_o=\frac{1}{2}[(y_1-a^3_1)^2+(y_2-a^3_2)^2]\\
z^3_1=(a^2_1w^3_{11}+a^2_2w^3_{12}+a^2_3w^3_{13})+b^3_1\\
a^3_1=f(z^3_1)
\end{matrix}\]

<p>So the derivatives of those functions with respect to what’s needed end up being:</p>

\[\begin{matrix}
\frac{\partial C_o}{\partial a^3_1}=(y_1-a^3_1),\space
\frac{\partial a^3_1}{\partial z^3_1}=f'(z^3_1),\space
\frac{\partial z^3_1}{\partial b^3_1}=1
\\ \Rightarrow \frac{\partial C_o}{\partial b^3_1}=(y_1-a^3_1)f'(z^3_1)
\end{matrix}\]

<p>We do this for the rest of functions at the top of the chain</p>

\[\begin{matrix}
\frac{\partial C_o}{\partial w^3_{11}}=\frac{\partial C_o}{\partial a^3_1}\cdot\frac{\partial a^3_1}{\partial z^3_1}\cdot \frac{\partial z^3_1}{\partial w^3_{11}}=\frac{\partial C_o}{\partial b^3_1}\cdot\frac{\partial z^3_1}{\partial w^3_{11}}
\\

\frac{\partial C_o}{\partial a^2_{1}}=\frac{\partial C_o}{\partial a^3_1}\cdot\frac{\partial a^3_1}{\partial z^3_1}\cdot \frac{\partial z^3_1}{\partial a^2_{1}}=\frac{\partial C_o}{\partial b^3_1}\cdot\frac{\partial z^3_1}{\partial a^2_{1}}
\\

\Rightarrow \frac{\partial z^3_1}{\partial w^3_{11}}=a^2_1,\space \frac{\partial z^3_1}{\partial a^3_{2}}=w^3_{11}
\\

\Rightarrow \frac{\partial C_o}{\partial w^3_{11}}=a^2_1(y_1-a^3_1)f'(z^3_1), \space \frac{\partial C_o}{\partial a^2_{1}}=w^3_{11}(y_1-a^3_1)f'(z^3_1)
\end{matrix}\]

<p>And just like this, work your way up to the inputs with each neuron, bias and weight</p>

<p><img src="/images/2023-01-09-multilayer-perceptrons-and-deep-learning/backprop_3.png" width="50%" height="50%" /></p>

<p>Since a network will usually deal with a lot of possible results, we need to average these derivatives over all training samples and only then, subtract to the weight or  bias that averaged derivative multiplied by some factor \(\gamma\)</p>

\[\begin{matrix}
b^L_k=b^L_k-\gamma \cdot \frac{1}{s}\sum_{}^{s} \frac{\partial C_o}{\partial b^L_k}\\

w^L_{kn}=w^L_{kn}-\gamma \cdot \frac{1}{s}\sum_{}^{s} \frac{\partial C_o}{\partial w^L_{kn}}
\end{matrix}\]

<h2 id="computing-with-matrices">Computing with matrices</h2>

<p>Once again, these operations for all weights and biases can be done “all at once” per layer using matrices, allowing us to use libraries optimized for matrix operations and linear algebra. So now we will make matrices/vectors to do these layer operations. As you have seen, to compute the derivative of weight and previous neuron, multiply the derivative of the bias by the value of the previous neuron or weight, this way we create a new vector \(\delta^l\) that will be composed of the bias derivatives of each neuron in the layer \(l\)</p>

\[\delta^3=\begin{bmatrix}
b^3_1 \\
b^3_2
\end{bmatrix}\]

<p>To compute this \(\delta^3\) we do the same thing as if it were a single bias, with the difference that we’ll be doing element-wise operations with vectors/matrices.</p>

\[\begin{matrix}
\Delta C_o=\begin{bmatrix}
y_1-a^3_1 \\
y_2-a^3_2
\end{bmatrix}=y-a^3, \space z^3=\begin{bmatrix}
w^3_{11}a^2_1+w^3_{12}a^2_2 \\
w^3_{21}a^2_1+w^3_{21}a^2_2
\end{bmatrix}+\begin{bmatrix}
b^3_1 \\
b^3_2
\end{bmatrix}=w^3a^2+b^3
\\
\Rightarrow \delta³=\Delta C_o\odot f'(z^3)
\\
\odot \space is\space elementwise\space multiplication
\end{matrix}\]

<p>From here we compute \(\Delta w^3\) and \(\delta^2\) for it to be used on the previous layer</p>

\[\begin{matrix}
\Delta w^3=\delta^3(a^2)^T
\\
\delta^2=(w^3)^T\delta^3 \odot f'(z^2)
\end{matrix}\]

<p>And we work our way to the inputs</p>

\[\begin{matrix}
\Delta w^2=\delta^3(a^1)^T\\
\delta^1=(w^2)^T\delta^2 \odot f'(z^1)\\
\Delta w^1=\delta^1i^T
\end{matrix}\]

<p>Then (after averaging those vectors) we subtract by our deltas many times as necessary to bring the loss to a minimum</p>

\[\begin{matrix}

b^1 = b^1-\gamma\delta^1
\\
w^1 = w^1-\gamma\Delta w^1
\\
b^2 = b^2-\gamma\delta^2
\\
w^2 = w^2-\gamma\Delta w^2
\\
b^3 = b^3-\gamma\delta^3
\\
w^3 = w^3-\gamma\Delta w^3

\end{matrix}\]

<p>It’s very important to note that since we initialize the weights and biases with random values it’s possible that we won’t find the global minima of the loss.</p>

<h1 id="handwritten-number-recognition">Handwritten number recognition</h1>

<p>The apparent “Hello world!” of machine learning. The idea is to take a 28x28 image of some written number and make a network that can classify the number from 0 to 9</p>

<p><img src="https://upload.wikimedia.org/wikipedia/commons/2/27/MnistExamples.png" width="95%" height="50%" /></p>

<p>This network will have four layers: 784 inputs (flattened 28x28 image matrix), two 16 neuron hidden layers, and 10 neurons output.</p>

<p><img src="/images/2023-01-09-multilayer-perceptrons-and-deep-learning/network.svg" width="85%" height="50%" /></p>

<p>The activation function for the hidden layers will be the \(ReLU\). This function and its derivative are easy to compute:</p>

\[\begin{matrix}
ReLU(x)=\left\{ \begin{array}{cl}
x &amp; : \ x \geq 0 \\
0 &amp; : \ x &lt; 0
\end{array} \right.

\\

ReLU'(x)=\left\{ \begin{array}{cl}
1 &amp; : \ x \geq 0 \\
0 &amp; : \ x &lt; 0
\end{array} \right.
\end{matrix}\]

<p>Since this is a classifier I’ll be using the softmax function at the outputs, this will turn the values of the output to a way that everything adds to 1, so each value of the output is a probability of the image being that number</p>

\[\sigma(\overrightarrow{z})_i = \frac{e^{z_i}}{\sum^{K}_{j}e^{z_j}}\]

<p>The derivative of this function is quite interesting to compute, to make it easier let’s start by computing the derivative of the first element in a 2x1 matrix</p>

\[\begin{matrix}
z=\begin{bmatrix}
v_1 \\
v_2
\end{bmatrix},\space \sigma(z)_1=\frac{e^{v_1}}{e^{v_1}+e^{v_2}}
\\

\frac{d}{dx}\frac{f}{g}=\frac{f'g-g'f}{g^2}\Rightarrow \frac{\partial \sigma(z)_1}{v_1}=\frac{e^{v_1}(e^{v_1}+e^{v_2})-e^{2v_1}}{(e^{v_1}+e^{v_2})^2}
\\
=\frac{e^{v_1}}{e^{v_1}+e^{v_2}}-\frac{e^{2v_1}}{(e^{v_1}+e^{v_2})^2}=\sigma(z)_1-\sigma^2(z)_1
\end{matrix}\]

<p>Try doing this for more elements, and you’ll find that:</p>

\[\frac{\partial\sigma(\overrightarrow{z})_i}{\partial z_i}=\sigma(\overrightarrow{z})_i-\sigma^2(\overrightarrow{z})_i=\sigma(\overrightarrow{z})_i(1-\sigma(\overrightarrow{z})_i)\]

<p>Then for the cost function I’ll be using Cross-entropy loss:</p>

\[C_o(a)=-\sum^{}_{i}y_iln(a_i)\]

<p>Using this function as the cost function will give us a short expression for \(\delta^4\). To explain this I’ll go back to a network that has two outputs</p>

\[a=\begin{bmatrix}
a_1 \\
a_2
\end{bmatrix},\space
y=\begin{bmatrix}
y_1 \\
y_2
\end{bmatrix},\space C_o(a)=-y_1ln(a_1)-y_2ln(a_2)\]

<p>We know that for the ouputs \(\delta=\Delta C_o\odot f'(z)\), so we compute:</p>

\[\Delta C_o=\begin{bmatrix}
-\frac{y_1}{a_1} \\
-\frac{y_2}{a_2}
\end{bmatrix},\space \delta=\begin{bmatrix}
y_1a_1-y_1 \\
y_2a_2-y_2
\end{bmatrix}=y\odot\begin{bmatrix}
a_1-y_1 \\
a_2-y_2
\end{bmatrix}\]

<p>I don’t know the best way to explain this, but by abusing the fact that this is a classification problem \(y\) will always be a matrix where only one element is equal to 1 and the rest are zeros, the sum is always one so we can simplify \(\delta\) to (a more detailed explanation <a href="https://deepnotes.io/softmax-crossentropy">here</a>):</p>

\[\delta=a-y\]

<h2 id="implementation">Implementation</h2>

<p>Once again I’ll be using GNU Octave because libBLAS is a thing and there’s no need to reinvent the wheel. I got the training and test dataset from <a href="https://pjreddie.com/projects/mnist-in-csv/">here</a>.</p>

<div class="language-m highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">old_state</span> <span class="o">=</span> <span class="nb">warning</span> <span class="p">(</span><span class="s2">"off"</span><span class="p">,</span> <span class="s2">"Octave:shadowed-function"</span><span class="p">);</span>
<span class="n">pkg</span> <span class="nb">load</span> <span class="n">statistics</span>
<span class="n">pkg</span> <span class="nb">load</span> <span class="n">io</span>
<span class="nb">warning</span> <span class="p">(</span><span class="n">old_state</span><span class="p">);</span>

<span class="c1">%A_1=[784 1] </span>
<span class="k">global</span> <span class="n">A_2</span><span class="o">=</span><span class="nb">double</span><span class="p">(</span><span class="n">unifrnd</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,[</span><span class="mi">16</span> <span class="mi">1</span><span class="p">]));</span>
<span class="k">global</span> <span class="n">A_3</span><span class="o">=</span><span class="nb">double</span><span class="p">(</span><span class="n">unifrnd</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,[</span><span class="mi">16</span> <span class="mi">1</span><span class="p">]));</span>
<span class="k">global</span> <span class="n">A_4</span><span class="o">=</span><span class="nb">double</span><span class="p">(</span><span class="n">unifrnd</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,[</span><span class="mi">10</span> <span class="mi">1</span><span class="p">]));</span>


<span class="k">global</span> <span class="n">W_12</span> <span class="o">=</span> <span class="nb">double</span><span class="p">(</span><span class="n">unifrnd</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,[</span><span class="mi">16</span> <span class="mi">784</span><span class="p">]));</span>
<span class="k">global</span> <span class="n">B_2</span>  <span class="o">=</span> <span class="nb">double</span><span class="p">(</span><span class="n">unifrnd</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,[</span><span class="mi">16</span> <span class="mi">1</span><span class="p">]));</span>

<span class="k">global</span> <span class="n">W_23</span> <span class="o">=</span> <span class="nb">double</span><span class="p">(</span><span class="n">unifrnd</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,[</span><span class="mi">16</span> <span class="mi">16</span><span class="p">]));</span>
<span class="k">global</span> <span class="n">B_3</span>  <span class="o">=</span> <span class="nb">double</span><span class="p">(</span><span class="n">unifrnd</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,[</span><span class="mi">16</span> <span class="mi">1</span><span class="p">]));</span>

<span class="k">global</span> <span class="n">W_34</span> <span class="o">=</span> <span class="nb">double</span><span class="p">(</span><span class="n">unifrnd</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,[</span><span class="mi">10</span> <span class="mi">16</span><span class="p">]));</span>
<span class="k">global</span> <span class="n">B_4</span>  <span class="o">=</span> <span class="nb">double</span><span class="p">(</span><span class="n">unifrnd</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,[</span><span class="mi">10</span> <span class="mi">1</span><span class="p">]));</span>

<span class="c1">%Activations</span>
<span class="k">function</span> <span class="n">y</span> <span class="o">=</span> <span class="n">relu</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
    <span class="n">y</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">x</span><span class="p">);</span>
<span class="k">end</span>

<span class="k">function</span> <span class="n">y</span> <span class="o">=</span> <span class="n">relu_derivative</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
    <span class="n">y</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">);</span>
<span class="k">end</span>

<span class="k">function</span> <span class="n">y</span> <span class="o">=</span> <span class="n">softmax</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
    <span class="n">s</span><span class="o">=</span><span class="n">x</span><span class="o">-</span><span class="nb">max</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
    <span class="n">y</span> <span class="o">=</span> <span class="nb">exp</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">.</span><span class="p">/</span> <span class="nb">sum</span><span class="p">(</span><span class="nb">exp</span><span class="p">(</span><span class="n">s</span><span class="p">));</span>
<span class="k">end</span>

<span class="c1">%Backpropagation</span>
<span class="k">function</span> <span class="p">[</span><span class="n">d_bias_4</span><span class="p">,</span><span class="n">d_weight_4</span><span class="p">,</span> <span class="n">d_bias_3</span><span class="p">,</span><span class="n">d_weight_3</span><span class="p">,</span> <span class="n">d_bias_2</span><span class="p">,</span><span class="n">d_weight_2</span><span class="p">]</span><span class="o">=</span><span class="n">backpropagate</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span><span class="n">outputs</span><span class="p">)</span>
    <span class="k">global</span> <span class="n">A_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_4</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_12</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_23</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_34</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_4</span><span class="p">;</span>

    <span class="n">z_2</span><span class="o">=</span><span class="p">(</span><span class="n">W_12</span><span class="o">*</span><span class="n">inputs</span><span class="p">)</span><span class="o">+</span><span class="n">B_2</span><span class="p">;</span>
    <span class="n">A_2</span><span class="o">=</span><span class="n">relu</span><span class="p">(</span><span class="n">z_2</span><span class="p">);</span>

    <span class="n">z_3</span><span class="o">=</span><span class="p">(</span><span class="n">W_23</span><span class="o">*</span><span class="n">A_2</span><span class="p">)</span><span class="o">+</span><span class="n">B_3</span><span class="p">;</span>
    <span class="n">A_3</span><span class="o">=</span><span class="n">relu</span><span class="p">(</span><span class="n">z_3</span><span class="p">);</span>
    
    <span class="n">z_4</span><span class="o">=</span><span class="p">(</span><span class="n">W_34</span><span class="o">*</span><span class="n">A_3</span><span class="p">)</span><span class="o">+</span><span class="n">B_4</span><span class="p">;</span>
    <span class="n">A_4</span><span class="o">=</span><span class="n">softmax</span><span class="p">(</span><span class="n">z_4</span><span class="p">);</span>

    <span class="c1">%1 / size(inputs, 2) is just to scale the gradient</span>
    <span class="n">d_cost</span> <span class="o">=</span> <span class="n">A_4</span> <span class="o">-</span> <span class="n">outputs</span><span class="p">;</span>
    <span class="n">d_weight_4</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="p">/</span> <span class="nb">size</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span> <span class="o">*</span> <span class="n">d_cost</span> <span class="o">*</span> <span class="n">A_3</span><span class="o">'</span><span class="p">;</span>
    <span class="n">d_bias_4</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="p">/</span> <span class="nb">size</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span><span class="o">*</span><span class="n">d_cost</span><span class="p">;</span>

    <span class="n">d_cost</span> <span class="o">=</span> <span class="p">(</span><span class="n">W_34</span><span class="o">'</span> <span class="o">*</span> <span class="n">d_cost</span><span class="p">)</span> <span class="o">.*</span> <span class="n">relu_derivative</span><span class="p">(</span><span class="n">z_3</span><span class="p">);</span>
    <span class="n">d_weight_3</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="p">/</span> <span class="nb">size</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span><span class="o">*</span><span class="n">d_cost</span> <span class="o">*</span> <span class="n">A_2</span><span class="o">'</span><span class="p">;</span>
    <span class="n">d_bias_3</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="p">/</span> <span class="nb">size</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span><span class="o">*</span><span class="n">d_cost</span><span class="p">;</span>

    <span class="n">d_cost</span> <span class="o">=</span> <span class="p">(</span><span class="n">W_23</span><span class="o">'</span> <span class="o">*</span> <span class="n">d_cost</span><span class="p">)</span> <span class="o">.*</span> <span class="n">relu_derivative</span><span class="p">(</span><span class="n">z_2</span><span class="p">);</span>
    <span class="n">d_weight_2</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="p">/</span> <span class="nb">size</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span><span class="o">*</span><span class="n">d_cost</span> <span class="o">*</span> <span class="n">inputs</span><span class="o">'</span><span class="p">;</span>
    <span class="n">d_bias_2</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="p">/</span> <span class="nb">size</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span><span class="o">*</span><span class="n">d_cost</span><span class="p">;</span>

<span class="n">endfunction</span>

<span class="k">function</span> <span class="p">[</span><span class="n">d_b4</span><span class="p">,</span><span class="n">d_w4</span><span class="p">,</span> <span class="n">d_b3</span><span class="p">,</span><span class="n">d_w3</span><span class="p">,</span> <span class="n">d_b2</span><span class="p">,</span><span class="n">d_w2</span><span class="p">]</span> <span class="o">=</span> <span class="n">GradientDescent</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span><span class="n">outputs</span><span class="p">,</span><span class="n">learning_rate</span><span class="p">)</span>
    <span class="k">global</span> <span class="n">A_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_4</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_12</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_23</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_34</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_4</span><span class="p">;</span>

    <span class="n">d_b4</span> <span class="o">=</span> <span class="nb">zeros</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">B_4</span><span class="p">));</span>
    <span class="n">d_w4</span> <span class="o">=</span> <span class="nb">zeros</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">W_34</span><span class="p">));</span>
    <span class="n">d_b3</span> <span class="o">=</span> <span class="nb">zeros</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">B_3</span><span class="p">));</span>
    <span class="n">d_w3</span> <span class="o">=</span> <span class="nb">zeros</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">W_23</span><span class="p">));</span>
    <span class="n">d_b2</span> <span class="o">=</span> <span class="nb">zeros</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">B_2</span><span class="p">));</span>
    <span class="n">d_w2</span> <span class="o">=</span> <span class="nb">zeros</span><span class="p">(</span><span class="nb">size</span><span class="p">(</span><span class="n">W_12</span><span class="p">));</span>

    <span class="n">batch_size</span><span class="o">=</span><span class="nb">size</span><span class="p">(</span><span class="n">outputs</span><span class="p">,</span><span class="mi">2</span><span class="p">);</span>
    <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">:</span><span class="n">batch_size</span>
        <span class="p">[</span><span class="n">d_b4_</span><span class="p">,</span><span class="n">d_w4_</span><span class="p">,</span> <span class="n">d_b3_</span><span class="p">,</span><span class="n">d_w3_</span><span class="p">,</span> <span class="n">d_b2_</span><span class="p">,</span><span class="n">d_w2_</span><span class="p">]</span> <span class="o">=</span> <span class="n">backpropagate</span><span class="p">(</span><span class="n">inputs</span><span class="p">(:,</span><span class="n">i</span><span class="p">),</span><span class="n">outputs</span><span class="p">(:,</span><span class="n">i</span><span class="p">));</span>
        <span class="n">d_b4</span> <span class="o">=</span> <span class="n">d_b4</span> <span class="o">+</span> <span class="n">d_b4_</span><span class="p">;</span>
        <span class="n">d_w4</span> <span class="o">=</span> <span class="n">d_w4</span> <span class="o">+</span> <span class="n">d_w4_</span><span class="p">;</span>
        <span class="n">d_b3</span> <span class="o">=</span> <span class="n">d_b3</span> <span class="o">+</span> <span class="n">d_b3_</span><span class="p">;</span>
        <span class="n">d_w3</span> <span class="o">=</span> <span class="n">d_w3</span> <span class="o">+</span> <span class="n">d_w3_</span><span class="p">;</span>
        <span class="n">d_b2</span> <span class="o">=</span> <span class="n">d_b2</span> <span class="o">+</span> <span class="n">d_b2_</span><span class="p">;</span>
        <span class="n">d_w2</span> <span class="o">=</span> <span class="n">d_w2</span> <span class="o">+</span> <span class="n">d_w2_</span><span class="p">;</span>
    <span class="k">end</span>

    <span class="c1">%average deltas</span>
    <span class="n">d_b4</span> <span class="o">=</span> <span class="n">d_b4</span> <span class="p">/</span> <span class="n">batch_size</span><span class="p">;</span>
    <span class="n">d_w4</span> <span class="o">=</span> <span class="n">d_w4</span> <span class="p">/</span> <span class="n">batch_size</span><span class="p">;</span>
    <span class="n">d_b3</span> <span class="o">=</span> <span class="n">d_b3</span> <span class="p">/</span> <span class="n">batch_size</span><span class="p">;</span>
    <span class="n">d_w3</span> <span class="o">=</span> <span class="n">d_w3</span> <span class="p">/</span> <span class="n">batch_size</span><span class="p">;</span>
    <span class="n">d_b2</span> <span class="o">=</span> <span class="n">d_b2</span> <span class="p">/</span> <span class="n">batch_size</span><span class="p">;</span>
    <span class="n">d_w2</span> <span class="o">=</span> <span class="n">d_w2</span> <span class="p">/</span> <span class="n">batch_size</span><span class="p">;</span>

    <span class="c1">%update parameters</span>
    <span class="n">W_34</span> <span class="o">=</span> <span class="n">W_34</span> <span class="o">-</span> <span class="p">(</span><span class="n">learning_rate</span><span class="p">)</span> <span class="o">*</span> <span class="n">d_w4</span><span class="p">;</span>
    <span class="n">B_4</span> <span class="o">=</span> <span class="n">B_4</span> <span class="o">-</span> <span class="p">(</span><span class="n">learning_rate</span><span class="p">)</span> <span class="o">*</span> <span class="n">d_b4</span><span class="p">;</span>
    <span class="n">W_23</span> <span class="o">=</span> <span class="n">W_23</span> <span class="o">-</span> <span class="p">(</span><span class="n">learning_rate</span><span class="p">)</span> <span class="o">*</span> <span class="n">d_w3</span><span class="p">;</span>
    <span class="n">B_3</span> <span class="o">=</span> <span class="n">B_3</span> <span class="o">-</span> <span class="p">(</span><span class="n">learning_rate</span><span class="p">)</span> <span class="o">*</span> <span class="n">d_b3</span><span class="p">;</span>
    <span class="n">W_12</span> <span class="o">=</span> <span class="n">W_12</span> <span class="o">-</span> <span class="p">(</span><span class="n">learning_rate</span><span class="p">)</span> <span class="o">*</span> <span class="n">d_w2</span><span class="p">;</span>
    <span class="n">B_2</span> <span class="o">=</span> <span class="n">B_2</span> <span class="o">-</span> <span class="p">(</span><span class="n">learning_rate</span><span class="p">)</span> <span class="o">*</span> <span class="n">d_b2</span><span class="p">;</span>
<span class="k">end</span>

<span class="c1">%Utility</span>
<span class="k">global</span> <span class="n">last_acc</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>

<span class="k">function</span> <span class="n">save_network</span><span class="p">()</span>
    <span class="k">global</span> <span class="n">A_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_4</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_12</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_23</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_34</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_4</span><span class="p">;</span>
    <span class="nb">save</span><span class="p">(</span><span class="s2">"network.mat"</span><span class="p">,</span> <span class="s2">"A_2"</span><span class="p">,</span> <span class="s2">"A_3"</span><span class="p">,</span> <span class="s2">"A_4"</span><span class="p">,</span> <span class="s2">"W_12"</span><span class="p">,</span> <span class="s2">"B_2"</span><span class="p">,</span> <span class="s2">"W_23"</span><span class="p">,</span> <span class="s2">"B_3"</span><span class="p">,</span> <span class="s2">"W_34"</span><span class="p">,</span> <span class="s2">"B_4"</span><span class="p">);</span>
<span class="k">end</span>

<span class="k">function</span> <span class="n">load_network</span><span class="p">()</span>
    <span class="k">global</span> <span class="n">A_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_4</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_12</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_23</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_34</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_4</span><span class="p">;</span>
    <span class="nb">load</span><span class="p">(</span><span class="s2">"network.mat"</span><span class="p">,</span> <span class="s2">"A_2"</span><span class="p">,</span> <span class="s2">"A_3"</span><span class="p">,</span> <span class="s2">"A_4"</span><span class="p">,</span> <span class="s2">"W_12"</span><span class="p">,</span> <span class="s2">"B_2"</span><span class="p">,</span> <span class="s2">"W_23"</span><span class="p">,</span> <span class="s2">"B_3"</span><span class="p">,</span> <span class="s2">"W_34"</span><span class="p">,</span> <span class="s2">"B_4"</span><span class="p">);</span>
<span class="k">end</span>

<span class="k">function</span> <span class="p">[</span><span class="n">images</span><span class="p">,</span> <span class="n">outputs</span><span class="p">]</span> <span class="o">=</span> <span class="n">load_mnist_data</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
    <span class="n">data</span> <span class="o">=</span> <span class="nb">csvread</span><span class="p">(</span><span class="n">filename</span><span class="p">);</span>
    <span class="n">outputs</span> <span class="o">=</span> <span class="nb">zeros</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="nb">size</span><span class="p">(</span><span class="n">data</span><span class="p">,</span><span class="mi">1</span><span class="p">));</span>
    <span class="n">labels</span> <span class="o">=</span> <span class="n">data</span><span class="p">(:,</span><span class="mi">1</span><span class="p">);</span>
    <span class="n">images</span> <span class="o">=</span> <span class="n">data</span><span class="p">(:,</span><span class="mi">2</span><span class="p">:</span><span class="k">end</span><span class="p">);</span>
    <span class="n">labels</span> <span class="o">=</span> <span class="n">labels</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
    <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">:</span><span class="nb">size</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
        <span class="n">outputs</span><span class="p">(</span><span class="n">labels</span><span class="p">(</span><span class="n">i</span><span class="p">),</span><span class="n">i</span><span class="p">)</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="k">end</span>
<span class="k">end</span>

<span class="c1">%Evaluation</span>
<span class="k">function</span> <span class="n">feed_foward</span><span class="p">(</span><span class="n">inputs</span><span class="p">)</span>
    <span class="k">global</span> <span class="n">A_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_4</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_12</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_23</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_34</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_4</span><span class="p">;</span>

    <span class="n">z_2</span><span class="o">=</span><span class="p">(</span><span class="n">W_12</span><span class="o">*</span><span class="n">inputs</span><span class="p">)</span><span class="o">+</span><span class="n">B_2</span><span class="p">;</span>
    <span class="n">A_2</span><span class="o">=</span><span class="n">relu</span><span class="p">(</span><span class="n">z_2</span><span class="p">);</span>

    <span class="n">z_3</span><span class="o">=</span><span class="p">(</span><span class="n">W_23</span><span class="o">*</span><span class="n">A_2</span><span class="p">)</span><span class="o">+</span><span class="n">B_3</span><span class="p">;</span>
    <span class="n">A_3</span><span class="o">=</span><span class="n">relu</span><span class="p">(</span><span class="n">z_3</span><span class="p">);</span>
    
    <span class="n">z_4</span><span class="o">=</span><span class="p">(</span><span class="n">W_34</span><span class="o">*</span><span class="n">A_3</span><span class="p">)</span><span class="o">+</span><span class="n">B_4</span><span class="p">;</span>
    <span class="n">A_4</span><span class="o">=</span><span class="n">softmax</span><span class="p">(</span><span class="n">z_4</span><span class="p">);</span>
<span class="n">endfunction</span>

<span class="c1">%Test accuracy and save network parameters if it improved</span>
<span class="k">function</span> <span class="n">y</span><span class="o">=</span><span class="n">test</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span><span class="n">outputs</span><span class="p">)</span>
    <span class="k">global</span> <span class="n">A_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_4</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_12</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_23</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_34</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_4</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">last_acc</span><span class="p">;</span>

    <span class="n">correct</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">:</span><span class="mi">10000</span>
        <span class="n">feed_foward</span><span class="p">(</span><span class="n">inputs</span><span class="p">(:,</span><span class="n">i</span><span class="p">));</span>
        <span class="p">[</span><span class="err">_</span><span class="p">,</span><span class="n">AID</span><span class="p">]</span><span class="o">=</span><span class="nb">max</span><span class="p">(</span><span class="n">A_4</span><span class="p">);</span>
        <span class="p">[</span><span class="err">_</span><span class="p">,</span><span class="n">OID</span><span class="p">]</span><span class="o">=</span><span class="nb">max</span><span class="p">(</span><span class="n">outputs</span><span class="p">(:,</span><span class="n">i</span><span class="p">));</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">AID</span><span class="o">==</span><span class="n">OID</span><span class="p">)</span>
            <span class="n">correct</span> <span class="o">=</span> <span class="n">correct</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
        <span class="k">end</span>
    <span class="k">end</span>
    <span class="n">acc</span><span class="o">=</span><span class="n">correct</span> <span class="p">/</span> <span class="mi">10000</span><span class="p">;</span>
    <span class="nb">disp</span><span class="p">(</span><span class="n">acc</span><span class="p">);</span>

    <span class="k">if</span><span class="p">(</span><span class="n">acc</span><span class="o">&gt;</span><span class="n">last_acc</span><span class="p">)</span>
        <span class="n">last_acc</span> <span class="o">=</span> <span class="n">correct</span> <span class="p">/</span> <span class="mi">10000</span><span class="p">;</span>
        <span class="n">save_network</span><span class="p">();</span>
    <span class="k">end</span>
    <span class="n">y</span><span class="o">=</span><span class="n">acc</span><span class="p">;</span>
<span class="k">end</span>

<span class="c1">%Training</span>
<span class="n">train</span><span class="o">=</span><span class="nb">true</span><span class="p">;</span>
<span class="n">epochs</span><span class="o">=</span><span class="mi">10000</span><span class="p">;</span>

<span class="k">if</span><span class="p">(</span><span class="n">train</span><span class="p">)</span>
    <span class="c1">%load the data (0-255 to 0-1)</span>
    <span class="p">[</span><span class="n">images</span><span class="p">,</span> <span class="n">labels</span><span class="p">]</span> <span class="o">=</span> <span class="n">load_mnist_data</span><span class="p">(</span><span class="s2">"mnist_train.csv"</span><span class="p">);</span>
    <span class="n">images</span> <span class="o">=</span> <span class="n">images</span> <span class="p">/</span> <span class="mi">255</span><span class="p">;</span>

    <span class="c1">%load test data (0-255 to 0-1)</span>
    <span class="p">[</span><span class="n">test_images</span><span class="p">,</span> <span class="n">test_labels</span><span class="p">]</span> <span class="o">=</span> <span class="n">load_mnist_data</span><span class="p">(</span><span class="s2">"mnist_test.csv"</span><span class="p">);</span>
    <span class="n">test_images</span> <span class="o">=</span> <span class="n">test_images</span> <span class="p">/</span> <span class="mi">255</span><span class="p">;</span>
    <span class="n">test</span><span class="p">(</span><span class="n">test_images</span><span class="o">'</span><span class="p">,</span> <span class="n">test_labels</span><span class="p">);</span>

    <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">:</span><span class="n">epochs</span>
        <span class="nb">disp</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
        <span class="n">GradientDescent</span><span class="p">(</span><span class="n">images</span><span class="o">'</span><span class="p">,</span><span class="n">labels</span><span class="p">,</span><span class="mf">0.001</span><span class="p">);</span>
        <span class="n">test</span><span class="p">(</span><span class="n">test_images</span><span class="o">'</span><span class="p">,</span> <span class="n">test_labels</span><span class="p">);</span>
    <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p>After ~4h of training the accuracy capped at 93.2%</p>

<p><img src="/images/2023-01-09-multilayer-perceptrons-and-deep-learning/accuracy.png" width="100%" height="100%" /></p>

<p>From here I wanted to see how it would do with numbers made by me, so I wrote a function to load an image and feed it to the network (I had to rotate the image since the images in the dataset were rotated 270°).</p>

<div class="language-m highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">y</span> <span class="o">=</span> <span class="n">load_and_feed_foward</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
    <span class="k">global</span> <span class="n">A_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">A_4</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_12</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_2</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_23</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_3</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">W_34</span><span class="p">;</span>
    <span class="k">global</span> <span class="n">B_4</span><span class="p">;</span>

    <span class="n">img</span> <span class="o">=</span> <span class="nb">imread</span><span class="p">(</span><span class="n">filename</span><span class="p">);</span>
    <span class="n">img</span> <span class="o">=</span> <span class="nb">rot90</span><span class="p">(</span><span class="n">img</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span>
    <span class="n">img</span> <span class="o">=</span> <span class="nb">fliplr</span><span class="p">(</span><span class="n">img</span><span class="p">);</span>

    <span class="n">image_data</span> <span class="o">=</span> <span class="nb">reshape</span><span class="p">(</span><span class="n">img</span><span class="p">,</span> <span class="p">[</span><span class="mi">784</span> <span class="mi">1</span><span class="p">]);</span>
    <span class="n">image_data</span><span class="o">=</span> <span class="nb">double</span><span class="p">(</span><span class="n">image_data</span><span class="p">)</span> <span class="o">.</span><span class="p">/</span> <span class="mi">255</span><span class="p">;</span>
    <span class="nb">imagesc</span><span class="p">(</span><span class="n">img</span><span class="p">);</span>
    <span class="nb">colormap</span><span class="p">(</span><span class="nb">gray</span><span class="p">);</span>
    <span class="n">feed_foward</span><span class="p">(</span><span class="n">image_data</span><span class="p">);</span>
    <span class="n">y</span> <span class="o">=</span> <span class="nb">find</span><span class="p">(</span><span class="n">A_4</span> <span class="o">&gt;</span> <span class="mf">0.5</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">end</span>

<span class="n">load_network</span><span class="p">();</span>
<span class="nb">disp</span><span class="p">(</span><span class="n">load_and_feed_foward</span><span class="p">(</span><span class="s2">"number.jpg"</span><span class="p">))</span>
</code></pre></div></div>

<p>For the images I created a 28x28 grayscale canvas in GIMP and then whenever I wanted to test another drawing I just re-exported it as number.jpg</p>

<p><img src="/images/2023-01-09-multilayer-perceptrons-and-deep-learning/gimp.png" width="80%" height="80%" /></p>

<p>After playing with it a bit I noticed that the network classified numbers better if they were drawn below (0,5), also it has the tendency to mark 8’s as 5’s for some reason. That’s it for this post and I hope you find this topic interesting.
(Get the tuned weights and biases <a href="https://raw.githubusercontent.com/l1g4v/l1g4v.github.io/master/images/2023-01-09-multilayer-perceptrons-and-deep-learning/network.mat">here</a>).</p>]]></content><author><name>Fernando Leon</name></author><category term="Calculus" /><category term="Machine Learning" /><category term="Linear Algebra" /><summary type="html"><![CDATA[New year, new post. Here I am again with a new topic that I found interesting to read after watching the videos of 3Blue1Brown on deep learning. It seems like the "Hello world!" of machine learning is making a neural network that recognizes handwritten digits, so today's post will be about that.]]></summary></entry><entry><title type="html">Equipotential lines</title><link href="https://leorfe.me//equipotential-lines/" rel="alternate" type="text/html" title="Equipotential lines" /><published>2022-05-28T00:00:00+00:00</published><updated>2022-05-28T00:00:00+00:00</updated><id>https://leorfe.me//equipotential-lines</id><content type="html" xml:base="https://leorfe.me//equipotential-lines/"><![CDATA[<p>Equipotential lines are a way to represent that the electric potential will be the same everywhere along that line. In other words, if we take a voltmeter and start to make measurements along the equipotential line, all the values will be the same (or will differ by very small values since we don’t live in a perfect world)</p>

<p><img src="/images/2022-05-28-equipotential-lines/pointequi.png" width="50%" height="50%" /></p>

<p>Since the electric potential is the same all across some equipotential (\(\Delta V=0\)), moving a charge across it requires no work whatsoever. Also, these equipotential lines are perpendicular to the electric field vectors meaning we can give an numeric proof that \(W=0\)</p>

\[W=q|\overrightarrow{E}|r\cos\pi=0\]

<h2 id="visualizing-the-equipotential">Visualizing the equipotential</h2>

<p>The formula to obtain the electric potential is:</p>

\[V=\frac{kQ}{r}\]

<p>We can use this value as a sort of \(z\) axis for the vector plot of the previous post, other way of seeing it is by imagining this value V will be the weight of that vector, the further away from the charge, the lighter it is. For this we need to add a new global variable \(V\) and add some code to the function that creates point charges. This will create the matrix of values for the z axis.</p>
<div class="language-m highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">V</span> <span class="o">=</span> <span class="n">V</span> <span class="o">+</span> <span class="n">k</span><span class="o">.*</span><span class="n">q</span><span class="o">.</span><span class="p">/(</span><span class="nb">sqrt</span><span class="p">(</span><span class="n">Cx</span><span class="o">.^</span><span class="mi">2</span> <span class="o">+</span> <span class="n">Cy</span><span class="o">.^</span><span class="mi">2</span><span class="p">));</span>
</code></pre></div></div>
<p>After that, using the contour function we can plot these values as lines that will have a color depending on their weight.</p>
<div class="language-m highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">hold</span> <span class="n">on</span>
<span class="nb">contour</span><span class="p">(</span><span class="n">xS</span><span class="p">,</span><span class="n">yS</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">line_amount</span><span class="p">);</span>
</code></pre></div></div>
<p>These are the results with 300 lines of density<br />
<img src="/images/2022-05-28-equipotential-lines/dipole.png" /><br />
<img src="/images/2022-05-28-equipotential-lines/cap.png" /><br />
<img src="/images/2022-05-28-equipotential-lines/shapes.png" /><br />
If we do a surface plot of this \(V\) matrix, we get something similar to those gravity force plots that we see solar system videos :P   <br />
<img src="/images/2022-05-28-equipotential-lines/3dplot.png" /></p>

<h2 id="an-experiment-you-can-try">An experiment you can try</h2>

<p>Using the same setup as the previous post, change the oil for water and try to simulate the shapes you want to recreate, then print that graphic and put it on your tray while trying to align the center of your shapes with the ones in the graphic. Then take your voltmeter and verify if the measurements along different equipotential lines has little to no difference.</p>

<p>Here is all the code so far to visualize electric fields in GNU Octave (this should work in Matlab too)</p>
<div class="language-m highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">clear</span><span class="p">;</span> <span class="nb">close</span> <span class="nb">all</span><span class="p">;</span> <span class="nb">clc</span><span class="p">;</span>
<span class="c1">%grid</span>
<span class="n">N</span><span class="o">=</span><span class="mi">60</span><span class="p">;</span> <span class="c1">%density</span>
<span class="n">Vd</span><span class="o">=</span><span class="mi">300</span><span class="p">;</span> <span class="c1">%equipotential lines</span>
<span class="n">minX</span><span class="o">=-</span><span class="mi">20</span><span class="p">;</span><span class="n">maxX</span><span class="o">=+</span><span class="mi">20</span><span class="p">;</span> <span class="c1">%grid size</span>
<span class="n">minY</span><span class="o">=-</span><span class="mi">20</span><span class="p">;</span><span class="n">maxY</span><span class="o">=+</span><span class="mi">20</span><span class="p">;</span>
<span class="n">xl</span><span class="o">=</span><span class="nb">linspace</span><span class="p">(</span><span class="n">minX</span><span class="p">,</span><span class="n">maxX</span><span class="p">,</span><span class="n">N</span><span class="p">);</span> <span class="c1">%evenly spaced N vectors per row</span>
<span class="n">yl</span><span class="o">=</span><span class="nb">linspace</span><span class="p">(</span><span class="n">minY</span><span class="p">,</span><span class="n">maxY</span><span class="p">,</span><span class="n">N</span><span class="p">);</span>
<span class="k">global</span> <span class="n">xS</span><span class="p">;</span>
<span class="k">global</span> <span class="n">yS</span><span class="p">;</span>
<span class="k">global</span> <span class="n">Ex</span><span class="p">;</span>
<span class="k">global</span> <span class="n">Ey</span><span class="p">;</span>
<span class="k">global</span> <span class="n">V</span><span class="p">;</span>
<span class="p">[</span><span class="n">xS</span><span class="p">,</span><span class="n">yS</span><span class="p">]</span><span class="o">=</span><span class="nb">meshgrid</span><span class="p">(</span><span class="n">xl</span><span class="p">,</span><span class="n">yl</span><span class="p">);</span> <span class="c1">%vector grid</span>

<span class="c1">%electric field components</span>
<span class="n">Ex</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
<span class="n">Ey</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
<span class="n">V</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>

<span class="c1">%q=charge x,y=position in the grid</span>
<span class="k">function</span> <span class="n">efield</span> <span class="o">=</span> <span class="n">place_charge</span><span class="p">(</span><span class="n">q</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">)</span>
  <span class="k">global</span> <span class="n">xS</span><span class="p">;</span>
  <span class="k">global</span> <span class="n">yS</span><span class="p">;</span>
  <span class="k">global</span> <span class="n">Ex</span><span class="p">;</span>
  <span class="k">global</span> <span class="n">Ey</span><span class="p">;</span>
  <span class="k">global</span> <span class="n">V</span><span class="p">;</span>
  <span class="c1">%constants</span>
  <span class="n">eps0</span> <span class="o">=</span> <span class="mf">8.854e-12</span><span class="p">;</span>
  <span class="n">k</span> <span class="o">=</span> <span class="mi">1</span><span class="p">/(</span><span class="mi">4</span><span class="o">*</span><span class="nb">pi</span><span class="o">*</span><span class="n">eps0</span><span class="p">);</span>
  <span class="c1">%vector coordinates in the spaces where the point charge is placed</span>
  <span class="n">Cx</span> <span class="o">=</span> <span class="n">xS</span><span class="o">-</span><span class="n">x</span><span class="p">;</span>
  <span class="n">Cy</span> <span class="o">=</span> <span class="n">yS</span><span class="o">-</span><span class="n">y</span><span class="p">;</span>
  <span class="n">C</span> <span class="o">=</span> <span class="nb">sqrt</span><span class="p">(</span><span class="n">Cx</span><span class="o">.^</span><span class="mi">2</span> <span class="o">+</span> <span class="n">Cy</span><span class="o">.^</span><span class="mi">2</span><span class="p">)</span><span class="o">.^</span><span class="mi">3</span><span class="p">;</span>
  <span class="c1">%electric field calculation</span>
  <span class="n">Ex</span> <span class="o">=</span> <span class="n">Ex</span> <span class="o">+</span> <span class="n">k</span> <span class="o">.*</span> <span class="n">q</span> <span class="o">.*</span> <span class="n">Cx</span> <span class="o">.</span><span class="p">/</span> <span class="n">C</span><span class="p">;</span>
  <span class="n">Ey</span> <span class="o">=</span> <span class="n">Ey</span> <span class="o">+</span> <span class="n">k</span> <span class="o">.*</span> <span class="n">q</span> <span class="o">.*</span> <span class="n">Cy</span> <span class="o">.</span><span class="p">/</span> <span class="n">C</span><span class="p">;</span>
  <span class="c1">%electric potential calculation</span>
  <span class="n">V</span> <span class="o">=</span> <span class="n">V</span> <span class="o">+</span> <span class="n">k</span><span class="o">.*</span><span class="n">q</span><span class="o">.</span><span class="p">/(</span><span class="nb">sqrt</span><span class="p">(</span><span class="n">Cx</span><span class="o">.^</span><span class="mi">2</span> <span class="o">+</span> <span class="n">Cy</span><span class="o">.^</span><span class="mi">2</span><span class="p">));</span>
  <span class="nb">hold</span> <span class="n">on</span><span class="p">;</span>
  <span class="k">if</span><span class="p">(</span><span class="n">q</span><span class="o">&lt;</span><span class="mi">0</span><span class="p">)</span>
  <span class="nb">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">,</span> <span class="s1">'MarkerSize'</span><span class="p">,</span> <span class="mi">80</span><span class="p">);</span>
<span class="k">else</span>
  <span class="nb">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">,</span> <span class="s1">'MarkerSize'</span><span class="p">,</span> <span class="mi">80</span><span class="p">);</span>
  <span class="k">end</span>

<span class="k">end</span>

<span class="k">function</span> <span class="n">linefi</span> <span class="o">=</span> <span class="n">place_line</span><span class="p">(</span><span class="n">q</span><span class="p">,</span><span class="n">x0</span><span class="p">,</span><span class="n">y0</span><span class="p">,</span><span class="n">x1</span><span class="p">,</span><span class="n">y1</span><span class="p">)</span>
  <span class="n">lambda</span> <span class="o">=</span> <span class="n">q</span> <span class="o">.</span><span class="p">/</span> <span class="nb">sqrt</span><span class="p">(</span> <span class="p">(</span><span class="n">x1</span><span class="o">-</span><span class="n">x0</span><span class="p">)</span><span class="o">.^</span><span class="mi">2</span> <span class="o">+</span> <span class="p">(</span><span class="n">y1</span><span class="o">-</span><span class="n">y0</span><span class="p">)</span><span class="o">.^</span><span class="mi">2</span><span class="p">);</span>
  <span class="nb">step</span><span class="o">=</span><span class="nb">abs</span><span class="p">(</span><span class="n">lambda</span><span class="p">);</span>
  <span class="n">dx</span><span class="o">=</span><span class="n">x1</span> <span class="o">-</span> <span class="n">x0</span><span class="p">;</span>
  <span class="n">dy</span><span class="o">=</span><span class="n">y1</span> <span class="o">-</span> <span class="n">y0</span><span class="p">;</span>
  <span class="n">m</span><span class="o">=</span><span class="n">dy</span> <span class="o">.</span><span class="p">/</span> <span class="n">dx</span><span class="p">;</span>
  <span class="n">b</span><span class="o">=</span><span class="n">y0</span> <span class="o">-</span> <span class="n">m</span> <span class="o">.*</span> <span class="n">x0</span><span class="p">;</span>
  <span class="k">if</span> <span class="n">x1</span><span class="o">==</span><span class="n">x0</span>
    <span class="c1">%Do sweep across y axis</span>
    <span class="k">if</span><span class="p">(</span><span class="n">y0</span><span class="o">&gt;</span><span class="n">y1</span><span class="p">)</span>
    <span class="nb">step</span><span class="o">*=-</span><span class="mi">1</span><span class="p">;</span>
  <span class="n">endif</span>
  <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="n">y0</span><span class="p">:</span><span class="nb">step</span><span class="p">:</span><span class="n">y1</span>
    <span class="n">place_charge</span><span class="p">(</span><span class="n">lambda</span><span class="p">,</span><span class="n">x0</span><span class="p">,</span><span class="n">i</span><span class="p">);</span>
  <span class="k">end</span>
  <span class="k">else</span>
    <span class="c1">%Do sweep across x axis</span>
    <span class="k">if</span><span class="p">(</span><span class="n">x0</span><span class="o">&gt;</span><span class="n">x1</span><span class="p">)</span>
      <span class="nb">step</span><span class="o">*=-</span><span class="mi">1</span><span class="p">;</span>
    <span class="n">endif</span>
    <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="n">x0</span><span class="p">:</span><span class="nb">step</span><span class="p">:</span><span class="n">x1</span>
      <span class="n">place_charge</span><span class="p">(</span><span class="n">lambda</span><span class="p">,</span><span class="n">i</span><span class="p">,</span><span class="n">m</span><span class="o">.*</span><span class="n">i</span> <span class="o">+</span> <span class="n">b</span><span class="p">);</span> <span class="c1">%y = mx+b</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="k">function</span> <span class="n">ringfi</span> <span class="o">=</span> <span class="n">place_ring</span><span class="p">(</span><span class="n">q</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="n">r</span><span class="p">)</span>
  <span class="n">lambda</span> <span class="o">=</span> <span class="n">q</span> <span class="o">.</span><span class="p">/</span> <span class="p">(</span><span class="mf">6.28318530717958647693</span><span class="o">.*</span><span class="n">r</span><span class="p">);</span>
  <span class="nb">step</span><span class="o">=</span><span class="nb">abs</span><span class="p">(</span><span class="n">lambda</span><span class="p">);</span>
  <span class="k">for</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">:</span><span class="nb">step</span><span class="p">:</span><span class="mf">6.28318530717958647693</span>
    <span class="n">place_charge</span><span class="p">(</span><span class="n">lambda</span><span class="p">,</span><span class="n">x</span><span class="o">+</span><span class="n">r</span><span class="o">*</span><span class="nb">cos</span><span class="p">(</span><span class="n">i</span><span class="p">),</span><span class="n">y</span><span class="o">+</span><span class="n">r</span><span class="o">*</span><span class="nb">sin</span><span class="p">(</span><span class="n">i</span><span class="p">));</span>
  <span class="n">endfor</span>
<span class="k">end</span>

<span class="c1">%shapes</span>
<span class="n">place_ring</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">5</span><span class="p">);</span>
<span class="n">place_line</span><span class="p">(</span><span class="o">-</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="o">-</span><span class="mi">4</span><span class="p">);</span>
<span class="n">place_charge</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span><span class="mi">15</span><span class="p">,</span><span class="o">-</span><span class="mi">10</span><span class="p">);</span>
<span class="n">place_line</span><span class="p">(</span><span class="o">-</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">17</span><span class="p">,</span><span class="o">-</span><span class="mi">14</span><span class="p">,</span><span class="mi">9</span><span class="p">);</span>
<span class="n">place_charge</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="o">-</span><span class="mi">11</span><span class="p">,</span><span class="o">-</span><span class="mi">15</span><span class="p">);</span>
<span class="c1">%shapes</span>

<span class="c1">%normalize transforms</span>
<span class="n">E</span> <span class="o">=</span> <span class="nb">sqrt</span><span class="p">(</span><span class="n">Ex</span><span class="o">.^</span><span class="mi">2</span> <span class="o">+</span> <span class="n">Ey</span><span class="o">.^</span><span class="mi">2</span><span class="p">);</span>
<span class="n">u</span> <span class="o">=</span> <span class="n">Ex</span><span class="o">.</span><span class="p">/</span><span class="n">E</span><span class="p">;</span>
<span class="n">v</span> <span class="o">=</span> <span class="n">Ey</span><span class="o">.</span><span class="p">/</span><span class="n">E</span><span class="p">;</span>
<span class="c1">%plot electric field</span>
<span class="nb">quiver</span><span class="p">(</span><span class="n">xS</span><span class="p">,</span><span class="n">yS</span><span class="p">,</span><span class="n">u</span><span class="p">,</span><span class="n">v</span><span class="p">,</span><span class="s1">'autoscalefactor'</span><span class="p">,</span><span class="mf">0.6</span><span class="p">);</span>
<span class="nb">hold</span> <span class="n">on</span>
<span class="c1">%plot equipotential</span>
<span class="nb">contour</span><span class="p">(</span><span class="n">xS</span><span class="p">,</span><span class="n">yS</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span><span class="n">Vd</span><span class="p">);</span>
<span class="nb">axis</span><span class="p">([</span><span class="o">-</span><span class="mi">20</span> <span class="mi">20</span> <span class="o">-</span><span class="mi">20</span> <span class="mi">20</span><span class="p">]);</span>
<span class="nb">axis</span> <span class="n">equal</span><span class="p">;</span>
<span class="c1">%3d plot</span>
<span class="nb">figure</span><span class="p">();</span>
<span class="nb">surf</span><span class="p">(</span><span class="n">xS</span><span class="p">,</span><span class="n">yS</span><span class="p">,</span><span class="n">V</span><span class="p">);</span>
</code></pre></div></div>]]></content><author><name>Fernando Leon</name></author><category term="Physics" /><category term="Simulation" /><summary type="html"><![CDATA[Equipotential lines are a way to represent that the electric potential will be the same everywhere along that line. In other words, if we take a voltmeter and start to make measurements along the equipotential line, all the values will be the same (or will differ by very small values since we don't live in a perfect world)]]></summary></entry><entry><title type="html">Visualizing electric fields</title><link href="https://leorfe.me//visualizing-electric-fields/" rel="alternate" type="text/html" title="Visualizing electric fields" /><published>2022-05-25T00:00:00+00:00</published><updated>2022-05-25T00:00:00+00:00</updated><id>https://leorfe.me//visualizing-electric-fields</id><content type="html" xml:base="https://leorfe.me//visualizing-electric-fields/"><![CDATA[<p>An electric field \(\overrightarrow{E}\) is defined as \(\frac{\overrightarrow{F}}{q}\) where \(\overrightarrow{F}\) is the electric force and \(q\) is the charge. The shape of the force lines in an electric field changes depending on the shape and interactions that an object goes through, this means that for a point charge such as an electron or a proton, the direction of the electric field is set by the charge. For a positive point charge, the electric field has the same direction as the electric force, pointing outwards.</p>

<p><img src="/images/2022-05-25-visualizing-electric-fields/positivepoint.png" width="50%" height="50%" /></p>

<p>And for a negative charge, the electric field goes in the opposite direction of the electric force, pointing inwards to the charge</p>

<p><img src="/images/2022-05-25-visualizing-electric-fields/negativepoint.png" width="50%" height="50%" /></p>

<p>The magnitude of these point charges is calculated by using Coulomb’s law, which states that the electric force magnitude between two point charges is equal to:</p>

\[|\overrightarrow{F}|=k\frac{Qq}{r^{2}}\]

<p>where \(Q\) is the first charge, \(q\) the second charge, \(r\) the distance between them, and \(k\) is the Coulomb’s constants that is equal to \(\frac{1}{4\pi \epsilon_0}=9\cdot10^{9}\frac{N\cdot m^{2}}{C^2}\) where \(\epsilon_0\) is the permittivity of space.<br />
Solving the electric field for a point charge by replacing \(\overrightarrow{F}\) in \(|\overrightarrow{E}|\) we get:</p>

\[|\overrightarrow{E}|=\frac{|\overrightarrow{F}|}{q}=\frac{kQq}{r^{2}}\cdot\frac{1}{q}=k\frac{Q}{r^2}\]

<h1 id="line-charge">Line charge</h1>
<p>We can calculate the electric field of any shape by representing it as the continuous distribution of point charges across the surface of that shape even though the charge is quantized, the total number of charges on the surface can be so large that we could consider it to be continuous. For example, if we want to know what is the magnitude of an electric field of a line at some point in the space, we need to represent that line with charge \(q\) as a group of almost infinite \(\lambda\) point charges across its length.</p>

<p><img src="/images/2022-05-25-visualizing-electric-fields/linecharge1.jpg" width="50%" height="50%" /></p>

<p>This \(\lambda\) is the value of the charge density, how many \(C\) are there per unit length \(\lambda=\frac{q}{L}\), by this we can say the charge \(dl\) of the segment is equal to \(\lambda dl\), and then we can define the electric field magnitude \(dE\) of the \(dQ\) point charge as:</p>

\[dE=k\frac{\lambda dl}{r^{2}}\]

<p>Where \(r\) is the distance from that particular point charge. In order to obtain that full vector we make use of the superposition principle which states: “Every charge in space creates an electric field at point independent of the presence of other charges in that medium. The resultant electric field is a vector sum of the electric field due to individual charges.” basically what we need to do here is add up every \(dQ\)’s electric field forming the following expression:</p>

\[E=k\int_{a}^{b}\frac{\lambda dl}{r^{2}}\]

<p>Okay, we got the expression, but something is missing. Electric field changes according to the distance, so how do we add up almost infinite different distance dependent values? Well if we want to take a measure of the electric field from a point \(P\)</p>

<p><img src="/images/2022-05-25-visualizing-electric-fields/linechargep.jpg" width="50%" height="50%" /></p>

<p>If we draw lines from the point \(P\) towards some \(dL\) charges and it forms an angle from the start and the end of the line charge</p>

<p><img src="/images/2022-05-25-visualizing-electric-fields/linechargepline.jpg" width="50%" height="50%" /></p>

<p>But wait, what if we split it from the middle? This way a right triangle will form, and we will be able to use trig identities to form a new integral</p>

<p><img src="/images/2022-05-25-visualizing-electric-fields/linechargetrig.jpg" width="50%" height="50%" /></p>

<p>Via trigonometric substitution we change \(dl\) in terms of the angle \(d\theta\) by first finding what’s the value of \(l\)</p>

\[cos\space\theta=\frac{z}{r}\Rightarrow r=z\frac{1}{cos\space\theta}=z\space sec\space\theta\Rightarrow r^{2}=z^2sec^2\space\theta\\
tan\space\theta=\frac{l}{z}\Rightarrow l=z\space tan\space\theta\]

<p>Derivating \(l\) in terms of \(\theta\) gives us:</p>

\[dl=z\space sec^{2}\space\theta\space d\theta\]

<p>After doing the substitution for \(dl\) and \(r\) we get:</p>

\[\frac{dl}{r^{2}}=\frac{z\space sec^{2}\space\theta\space}{z^2sec^2\space\theta}d\theta = \frac{1}{z}d\theta\]

<p>Going back to the integral we can form an expression that sweeps the whole line across the angle</p>

\[k\int_{-\theta}^{\theta} \frac{\lambda}{z}\space\cos\theta\space d\theta\]

<p>By this aproach we can find the electric field at the \(z\) axis of the symmetry point of any shape, even thought that is not the goal this time, it is important to know as a basis for the following.</p>

<h1 id="simulating-electric-field-lines">Simulating electric field lines</h1>

<p>For the lab report of this class, we were asked to put a simulation of what kinds of electric field lines with different shapes of charges like line, point, and a ring would have, at the time no one on my team would know how to do that and luckily I found a page that did that and a teammate just did some photoshop magic to form the ring charge(https://static.bcheng.me/electric-fields/). Fortunately, the less-idiot-me of today finally understands how the superposition principle can be used for this problem (also the even lesser-idiot-me knows that just a drawing that shows for example the ring electric field would be like a point charge on the outside and a -point charge on the inside ).<br />
According to the sources I’ve read, we can represent an empty electric field space with vectors that point outwards from the origin, these vectors will suffer a transformation by adding all-electric fields surrounding it. For this simulation I’ll be using GNU Octave, first I wrote the code to create that space:</p>
<div class="language-m highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">clear</span><span class="p">;</span> <span class="nb">close</span> <span class="nb">all</span><span class="p">;</span> <span class="nb">clc</span><span class="p">;</span>
<span class="c1">%grid</span>
<span class="n">N</span><span class="o">=</span><span class="mi">30</span><span class="p">;</span> <span class="c1">%density</span>
<span class="n">minX</span><span class="o">=-</span><span class="mi">20</span><span class="p">;</span><span class="n">maxX</span><span class="o">=+</span><span class="mi">20</span><span class="p">;</span> <span class="c1">%grid size</span>
<span class="n">minY</span><span class="o">=-</span><span class="mi">20</span><span class="p">;</span><span class="n">maxY</span><span class="o">=+</span><span class="mi">20</span><span class="p">;</span>
<span class="n">xl</span><span class="o">=</span><span class="nb">linspace</span><span class="p">(</span><span class="n">minX</span><span class="p">,</span><span class="n">maxX</span><span class="p">,</span><span class="n">N</span><span class="p">);</span> <span class="c1">%evenly spaced N vectors per row</span>
<span class="n">yl</span><span class="o">=</span><span class="nb">linspace</span><span class="p">(</span><span class="n">minY</span><span class="p">,</span><span class="n">maxY</span><span class="p">,</span><span class="n">N</span><span class="p">);</span>
<span class="k">global</span> <span class="n">xS</span><span class="p">;</span>
<span class="k">global</span> <span class="n">yS</span><span class="p">;</span>
<span class="k">global</span> <span class="n">Ex</span><span class="p">;</span>
<span class="k">global</span> <span class="n">Ey</span><span class="p">;</span>
<span class="p">[</span><span class="n">xS</span><span class="p">,</span><span class="n">yS</span><span class="p">]</span><span class="o">=</span><span class="nb">meshgrid</span><span class="p">(</span><span class="n">xl</span><span class="p">,</span><span class="n">yl</span><span class="p">);</span> <span class="c1">%vector grid</span>

<span class="n">u</span><span class="o">=</span><span class="n">xS</span><span class="p">;</span>
<span class="n">v</span><span class="o">=</span><span class="n">yS</span><span class="p">;</span>

<span class="n">h</span><span class="o">=</span><span class="nb">quiver</span><span class="p">(</span><span class="n">xS</span><span class="p">,</span><span class="n">yS</span><span class="p">,</span><span class="n">u</span><span class="p">,</span><span class="n">v</span><span class="p">,</span><span class="s1">'autoscalefactor'</span><span class="p">,</span><span class="mf">0.6</span><span class="p">);</span>
</code></pre></div></div>
<p><img src="/images/2022-05-25-visualizing-electric-fields/emptyfield.jpg" /></p>

<p>By using the dipole moment formula \(\overrightarrow{E}_{dipole}=k\frac{\overrightarrow{p}}{z^{3}}\) we can compute an electric field by just adding up the electric fields of point charges, for this I just made a function that calculates the electric field at some point (x,y)</p>
<div class="language-m highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">%electric field components</span>
<span class="n">Ex</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
<span class="n">Ey</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>

<span class="c1">%q=charge x,y=position in the grid</span>
<span class="k">function</span> <span class="n">efield</span> <span class="o">=</span> <span class="n">place_charge</span><span class="p">(</span><span class="n">q</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">)</span>
  <span class="k">global</span> <span class="n">xS</span><span class="p">;</span>
  <span class="k">global</span> <span class="n">yS</span><span class="p">;</span>
  <span class="k">global</span> <span class="n">Ex</span><span class="p">;</span>
  <span class="k">global</span> <span class="n">Ey</span><span class="p">;</span>
  <span class="c1">%constants</span>
  <span class="n">eps0</span> <span class="o">=</span> <span class="mf">8.854e-12</span><span class="p">;</span>
  <span class="n">k</span> <span class="o">=</span> <span class="mi">1</span><span class="p">/(</span><span class="mi">4</span><span class="o">*</span><span class="nb">pi</span><span class="o">*</span><span class="n">eps0</span><span class="p">);</span>
  <span class="c1">%vector coordinates in the spaces where the point charge is placed</span>
  <span class="n">Cx</span> <span class="o">=</span> <span class="n">xS</span><span class="o">-</span><span class="n">x</span><span class="p">;</span>
  <span class="n">Cy</span> <span class="o">=</span> <span class="n">yS</span><span class="o">-</span><span class="n">y</span><span class="p">;</span>
  <span class="n">C</span> <span class="o">=</span> <span class="nb">sqrt</span><span class="p">(</span><span class="n">Cx</span><span class="o">.^</span><span class="mi">2</span> <span class="o">+</span> <span class="n">Cy</span><span class="o">.^</span><span class="mi">2</span><span class="p">)</span><span class="o">.^</span><span class="mi">3</span><span class="p">;</span>
  <span class="c1">%electric field calculation</span>
  <span class="n">Ex</span> <span class="o">=</span> <span class="n">Ex</span> <span class="o">+</span> <span class="n">k</span> <span class="o">.*</span> <span class="n">q</span> <span class="o">.*</span> <span class="n">Cx</span> <span class="o">.</span><span class="p">/</span> <span class="n">C</span><span class="p">;</span>
  <span class="n">Ey</span> <span class="o">=</span> <span class="n">Ey</span> <span class="o">+</span> <span class="n">k</span> <span class="o">.*</span> <span class="n">q</span> <span class="o">.*</span> <span class="n">Cy</span> <span class="o">.</span><span class="p">/</span> <span class="n">C</span><span class="p">;</span>
<span class="k">end</span>
</code></pre></div></div>
<p>This is the result with some charges added to the grid (after changing u and v to the normalized components of Ex and Ey)<br />
<img src="/images/2022-05-25-visualizing-electric-fields/randomfield.jpg" /></p>

<h2 id="shaped-charges">Shaped charges</h2>

<p>Now that we know that \(\overrightarrow{E}_{final}\) is just the sum of all point charge electric fields, for the simulation we can make new functions that keep adding point charges across the desired shape. This new function places point charges across a line from two points (I forgot to implement when y0=y1 lol).</p>
<div class="language-m highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">linefi</span> <span class="o">=</span> <span class="n">place_line</span><span class="p">(</span><span class="n">q</span><span class="p">,</span><span class="n">x0</span><span class="p">,</span><span class="n">y0</span><span class="p">,</span><span class="n">x1</span><span class="p">,</span><span class="n">y1</span><span class="p">)</span>
  <span class="c1">%calculate the steps and the charge of each element</span>
  <span class="n">lambda</span> <span class="o">=</span> <span class="n">q</span> <span class="o">.</span><span class="p">/</span> <span class="nb">sqrt</span><span class="p">(</span> <span class="p">(</span><span class="n">x1</span><span class="o">-</span><span class="n">x0</span><span class="p">)</span><span class="o">.^</span><span class="mi">2</span> <span class="o">+</span> <span class="p">(</span><span class="n">y1</span><span class="o">-</span><span class="n">y0</span><span class="p">)</span><span class="o">.^</span><span class="mi">2</span><span class="p">);</span>
  <span class="nb">step</span><span class="o">=</span><span class="nb">abs</span><span class="p">(</span><span class="n">lambda</span><span class="p">);</span>

  <span class="c1">%slope</span>
  <span class="n">dx</span><span class="o">=</span><span class="n">x1</span> <span class="o">-</span> <span class="n">x0</span><span class="p">;</span>
  <span class="n">dy</span><span class="o">=</span><span class="n">y1</span> <span class="o">-</span> <span class="n">y0</span><span class="p">;</span>
  <span class="n">m</span><span class="o">=</span><span class="n">dy</span> <span class="o">.</span><span class="p">/</span> <span class="n">dx</span><span class="p">;</span>
  <span class="n">b</span><span class="o">=</span><span class="n">y0</span> <span class="o">-</span> <span class="n">m</span> <span class="o">.*</span> <span class="n">x0</span><span class="p">;</span>

  <span class="k">if</span> <span class="n">x1</span><span class="o">==</span><span class="n">x0</span>
    <span class="c1">%Do sweep across y axis only</span>
    <span class="k">if</span><span class="p">(</span><span class="n">y0</span><span class="o">&gt;</span><span class="n">y1</span><span class="p">)</span>
    <span class="nb">step</span><span class="o">*=-</span><span class="mi">1</span><span class="p">;</span>
  <span class="n">endif</span>
  <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="n">y0</span><span class="p">:</span><span class="nb">step</span><span class="p">:</span><span class="n">y1</span>
    <span class="nb">disp</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
    <span class="n">place_charge</span><span class="p">(</span><span class="n">lambda</span><span class="p">,</span><span class="n">x0</span><span class="p">,</span><span class="n">i</span><span class="p">);</span>
  <span class="k">end</span>
  <span class="k">else</span>
    <span class="c1">%Do sweep across xy axis</span>
    <span class="k">if</span><span class="p">(</span><span class="n">x0</span><span class="o">&gt;</span><span class="n">x1</span><span class="p">)</span>
      <span class="nb">step</span><span class="o">*=-</span><span class="mi">1</span><span class="p">;</span>
    <span class="n">endif</span>
    <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="n">x0</span><span class="p">:</span><span class="nb">step</span><span class="p">:</span><span class="n">x1</span>
      <span class="nb">disp</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
      <span class="n">place_charge</span><span class="p">(</span><span class="n">lambda</span><span class="p">,</span><span class="n">i</span><span class="p">,</span><span class="n">m</span><span class="o">.*</span><span class="n">i</span> <span class="o">+</span> <span class="n">b</span><span class="p">);</span> <span class="c1">%y = mx+b</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<p>This is what two parallel lines electric fields look like:<br />
<img src="/images/2022-05-25-visualizing-electric-fields/linefield.jpg" /><br />
Now, for the final shape we were asked how its electric field would look like, the ring. For this one I just need to place \(\frac{q}{2\pi r}\) charges around a circle at \(r\) distance from a point that will be our center (\((x_0+r\space\cos\space\theta,y_0+r\space\sin\theta)\) basically)</p>
<div class="language-m highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">ringfi</span> <span class="o">=</span> <span class="n">place_ring</span><span class="p">(</span><span class="n">q</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="n">r</span><span class="p">)</span>
  <span class="n">lambda</span> <span class="o">=</span> <span class="n">q</span> <span class="o">.</span><span class="p">/</span> <span class="p">(</span><span class="mf">6.28318530717958647693</span><span class="o">.*</span><span class="n">r</span><span class="p">);</span>
  <span class="n">lambda</span>
  <span class="nb">step</span><span class="o">=</span><span class="nb">abs</span><span class="p">(</span><span class="n">lambda</span><span class="p">);</span>
  <span class="k">for</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">:</span><span class="nb">step</span><span class="p">:</span><span class="mf">6.28318530717958647693</span>
    <span class="nb">disp</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
    <span class="n">place_charge</span><span class="p">(</span><span class="n">lambda</span><span class="p">,</span><span class="n">x</span><span class="o">+</span><span class="n">r</span><span class="o">*</span><span class="nb">cos</span><span class="p">(</span><span class="n">i</span><span class="p">),</span><span class="n">y</span><span class="o">+</span><span class="n">r</span><span class="o">*</span><span class="nb">sin</span><span class="p">(</span><span class="n">i</span><span class="p">));</span>
  <span class="n">endfor</span>
<span class="k">end</span>
</code></pre></div></div>
<p>This is what it looks like (also at this point I added a visual aid to the place_charge function)<br />
<img src="/images/2022-05-25-visualizing-electric-fields/ringfield.jpg" /><br />
Here is the full code for those who want to play with it</p>
<div class="language-m highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">clear</span><span class="p">;</span> <span class="nb">close</span> <span class="nb">all</span><span class="p">;</span> <span class="nb">clc</span><span class="p">;</span>
<span class="c1">%grid</span>
<span class="n">N</span><span class="o">=</span><span class="mi">20</span><span class="p">;</span> <span class="c1">%density</span>
<span class="n">minX</span><span class="o">=-</span><span class="mi">20</span><span class="p">;</span><span class="n">maxX</span><span class="o">=+</span><span class="mi">20</span><span class="p">;</span> <span class="c1">%grid size</span>
<span class="n">minY</span><span class="o">=-</span><span class="mi">20</span><span class="p">;</span><span class="n">maxY</span><span class="o">=+</span><span class="mi">20</span><span class="p">;</span>
<span class="n">xl</span><span class="o">=</span><span class="nb">linspace</span><span class="p">(</span><span class="n">minX</span><span class="p">,</span><span class="n">maxX</span><span class="p">,</span><span class="n">N</span><span class="p">);</span> <span class="c1">%evenly spaced N vectors per row</span>
<span class="n">yl</span><span class="o">=</span><span class="nb">linspace</span><span class="p">(</span><span class="n">minY</span><span class="p">,</span><span class="n">maxY</span><span class="p">,</span><span class="n">N</span><span class="p">);</span>
<span class="k">global</span> <span class="n">xS</span><span class="p">;</span>
<span class="k">global</span> <span class="n">yS</span><span class="p">;</span>
<span class="k">global</span> <span class="n">Ex</span><span class="p">;</span>
<span class="k">global</span> <span class="n">Ey</span><span class="p">;</span>
<span class="p">[</span><span class="n">xS</span><span class="p">,</span><span class="n">yS</span><span class="p">]</span><span class="o">=</span><span class="nb">meshgrid</span><span class="p">(</span><span class="n">xl</span><span class="p">,</span><span class="n">yl</span><span class="p">);</span> <span class="c1">%vector grid</span>

<span class="c1">%electric field components</span>
<span class="n">Ex</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
<span class="n">Ey</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
<span class="c1">%q=charge x,y=position in the grid</span>
<span class="k">function</span> <span class="n">efield</span> <span class="o">=</span> <span class="n">place_charge</span><span class="p">(</span><span class="n">q</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">)</span>
  <span class="k">global</span> <span class="n">xS</span><span class="p">;</span>
  <span class="k">global</span> <span class="n">yS</span><span class="p">;</span>
  <span class="k">global</span> <span class="n">Ex</span><span class="p">;</span>
  <span class="k">global</span> <span class="n">Ey</span><span class="p">;</span>
  <span class="c1">%constants</span>
  <span class="n">eps0</span> <span class="o">=</span> <span class="mf">8.854e-12</span><span class="p">;</span>
  <span class="n">k</span> <span class="o">=</span> <span class="mi">1</span><span class="p">/(</span><span class="mi">4</span><span class="o">*</span><span class="nb">pi</span><span class="o">*</span><span class="n">eps0</span><span class="p">);</span>
  <span class="c1">%vector coordinates in the spaces where the point charge is placed</span>
  <span class="n">Cx</span> <span class="o">=</span> <span class="n">xS</span><span class="o">-</span><span class="n">x</span><span class="p">;</span>
  <span class="n">Cy</span> <span class="o">=</span> <span class="n">yS</span><span class="o">-</span><span class="n">y</span><span class="p">;</span>
  <span class="n">C</span> <span class="o">=</span> <span class="nb">sqrt</span><span class="p">(</span><span class="n">Cx</span><span class="o">.^</span><span class="mi">2</span> <span class="o">+</span> <span class="n">Cy</span><span class="o">.^</span><span class="mi">2</span><span class="p">)</span><span class="o">.^</span><span class="mi">3</span><span class="p">;</span>
  <span class="c1">%electric field calculation</span>
  <span class="n">Ex</span> <span class="o">=</span> <span class="n">Ex</span> <span class="o">+</span> <span class="n">k</span> <span class="o">.*</span> <span class="n">q</span> <span class="o">.*</span> <span class="n">Cx</span> <span class="o">.</span><span class="p">/</span> <span class="n">C</span><span class="p">;</span>
  <span class="n">Ey</span> <span class="o">=</span> <span class="n">Ey</span> <span class="o">+</span> <span class="n">k</span> <span class="o">.*</span> <span class="n">q</span> <span class="o">.*</span> <span class="n">Cy</span> <span class="o">.</span><span class="p">/</span> <span class="n">C</span><span class="p">;</span>

  <span class="nb">hold</span> <span class="n">on</span><span class="p">;</span>
  <span class="k">if</span><span class="p">(</span><span class="n">q</span><span class="o">&lt;</span><span class="mi">0</span><span class="p">)</span>
  <span class="nb">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">,</span> <span class="s1">'MarkerSize'</span><span class="p">,</span> <span class="mi">80</span><span class="p">);</span>
<span class="k">else</span>
  <span class="nb">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">,</span> <span class="s1">'MarkerSize'</span><span class="p">,</span> <span class="mi">80</span><span class="p">);</span>
  <span class="k">end</span>

<span class="k">end</span>

<span class="k">function</span> <span class="n">linefi</span> <span class="o">=</span> <span class="n">place_line</span><span class="p">(</span><span class="n">q</span><span class="p">,</span><span class="n">x0</span><span class="p">,</span><span class="n">y0</span><span class="p">,</span><span class="n">x1</span><span class="p">,</span><span class="n">y1</span><span class="p">)</span>
  <span class="n">lambda</span> <span class="o">=</span> <span class="n">q</span> <span class="o">.</span><span class="p">/</span> <span class="nb">sqrt</span><span class="p">(</span> <span class="p">(</span><span class="n">x1</span><span class="o">-</span><span class="n">x0</span><span class="p">)</span><span class="o">.^</span><span class="mi">2</span> <span class="o">+</span> <span class="p">(</span><span class="n">y1</span><span class="o">-</span><span class="n">y0</span><span class="p">)</span><span class="o">.^</span><span class="mi">2</span><span class="p">);</span>
  <span class="nb">step</span><span class="o">=</span><span class="nb">abs</span><span class="p">(</span><span class="n">lambda</span><span class="p">);</span>
  <span class="n">dx</span><span class="o">=</span><span class="n">x1</span> <span class="o">-</span> <span class="n">x0</span><span class="p">;</span>
  <span class="n">dy</span><span class="o">=</span><span class="n">y1</span> <span class="o">-</span> <span class="n">y0</span><span class="p">;</span>
  <span class="n">m</span><span class="o">=</span><span class="n">dy</span> <span class="o">.</span><span class="p">/</span> <span class="n">dx</span><span class="p">;</span>
  <span class="n">b</span><span class="o">=</span><span class="n">y0</span> <span class="o">-</span> <span class="n">m</span> <span class="o">.*</span> <span class="n">x0</span><span class="p">;</span>
  <span class="k">if</span> <span class="n">x1</span><span class="o">==</span><span class="n">x0</span>
    <span class="c1">%Do sweep across y axis</span>
    <span class="k">if</span><span class="p">(</span><span class="n">y0</span><span class="o">&gt;</span><span class="n">y1</span><span class="p">)</span>
    <span class="nb">step</span><span class="o">*=-</span><span class="mi">1</span><span class="p">;</span>
  <span class="n">endif</span>
  <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="n">y0</span><span class="p">:</span><span class="nb">step</span><span class="p">:</span><span class="n">y1</span>
    <span class="n">place_charge</span><span class="p">(</span><span class="n">lambda</span><span class="p">,</span><span class="n">x0</span><span class="p">,</span><span class="n">i</span><span class="p">);</span>
  <span class="k">end</span>
  <span class="k">else</span>
    <span class="c1">%Do sweep across x axis</span>
    <span class="k">if</span><span class="p">(</span><span class="n">x0</span><span class="o">&gt;</span><span class="n">x1</span><span class="p">)</span>
      <span class="nb">step</span><span class="o">*=-</span><span class="mi">1</span><span class="p">;</span>
    <span class="n">endif</span>
    <span class="k">for</span> <span class="n">i</span> <span class="o">=</span> <span class="n">x0</span><span class="p">:</span><span class="nb">step</span><span class="p">:</span><span class="n">x1</span>
      <span class="n">place_charge</span><span class="p">(</span><span class="n">lambda</span><span class="p">,</span><span class="n">i</span><span class="p">,</span><span class="n">m</span><span class="o">.*</span><span class="n">i</span> <span class="o">+</span> <span class="n">b</span><span class="p">);</span> <span class="c1">%y = mx+b</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="k">function</span> <span class="n">ringfi</span> <span class="o">=</span> <span class="n">place_ring</span><span class="p">(</span><span class="n">q</span><span class="p">,</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="n">r</span><span class="p">)</span>
  <span class="n">lambda</span> <span class="o">=</span> <span class="n">q</span> <span class="o">.</span><span class="p">/</span> <span class="p">(</span><span class="mf">6.28318530717958647693</span><span class="o">.*</span><span class="n">r</span><span class="p">);</span>
  <span class="n">lambda</span>
  <span class="nb">step</span><span class="o">=</span><span class="nb">abs</span><span class="p">(</span><span class="n">lambda</span><span class="p">);</span>
  <span class="k">for</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">:</span><span class="nb">step</span><span class="p">:</span><span class="mf">6.28318530717958647693</span>
    <span class="nb">disp</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
    <span class="n">place_charge</span><span class="p">(</span><span class="n">lambda</span><span class="p">,</span><span class="n">x</span><span class="o">+</span><span class="n">r</span><span class="o">*</span><span class="nb">cos</span><span class="p">(</span><span class="n">i</span><span class="p">),</span><span class="n">y</span><span class="o">+</span><span class="n">r</span><span class="o">*</span><span class="nb">sin</span><span class="p">(</span><span class="n">i</span><span class="p">));</span>
  <span class="n">endfor</span>
<span class="k">end</span>

<span class="n">place_ring</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">5</span><span class="p">);</span>
<span class="n">place_line</span><span class="p">(</span><span class="o">-</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="o">-</span><span class="mi">4</span><span class="p">);</span>
<span class="n">place_charge</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span><span class="mi">15</span><span class="p">,</span><span class="o">-</span><span class="mi">10</span><span class="p">);</span>
<span class="n">place_line</span><span class="p">(</span><span class="o">-</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">17</span><span class="p">,</span><span class="o">-</span><span class="mi">14</span><span class="p">,</span><span class="mi">9</span><span class="p">);</span>
<span class="n">place_charge</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="o">-</span><span class="mi">11</span><span class="p">,</span><span class="o">-</span><span class="mi">15</span><span class="p">);</span>

<span class="c1">%normalize transforms</span>
<span class="n">E</span> <span class="o">=</span> <span class="nb">sqrt</span><span class="p">(</span><span class="n">Ex</span><span class="o">.^</span><span class="mi">2</span> <span class="o">+</span> <span class="n">Ey</span><span class="o">.^</span><span class="mi">2</span><span class="p">);</span>
<span class="n">u</span> <span class="o">=</span> <span class="n">Ex</span><span class="o">.</span><span class="p">/</span><span class="n">E</span><span class="p">;</span>
<span class="n">v</span> <span class="o">=</span> <span class="n">Ey</span><span class="o">.</span><span class="p">/</span><span class="n">E</span><span class="p">;</span>

<span class="nb">quiver</span><span class="p">(</span><span class="n">xS</span><span class="p">,</span><span class="n">yS</span><span class="p">,</span><span class="n">u</span><span class="p">,</span><span class="n">v</span><span class="p">,</span><span class="s1">'autoscalefactor'</span><span class="p">,</span><span class="mf">0.6</span><span class="p">);</span>
<span class="nb">hold</span> <span class="n">on</span>
<span class="nb">axis</span><span class="p">([</span><span class="o">-</span><span class="mi">20</span> <span class="mi">20</span> <span class="o">-</span><span class="mi">20</span> <span class="mi">20</span><span class="p">]);</span>
<span class="nb">axis</span> <span class="n">equal</span>
</code></pre></div></div>
<p><img src="/images/2022-05-25-visualizing-electric-fields/randombs.jpg" /></p>

<h2 id="visualizing-the-field-in-the-real-life">Visualizing the field in the real life</h2>
<p>There is a experiment everyone can try to visualize the electric field of any shape without having to solve boring integrals or things like that, for this you will need:</p>

<ul>
  <li>A power supply of at least 12v</li>
  <li>Cooking oil</li>
  <li>Canary grass</li>
  <li>A tray</li>
  <li>Thick wires that you will shape however you want</li>
  <li>Thiner wires to connect the thicker ones to your power supply</li>
</ul>

<p>In class we had a Wimshurst machine as our power supply because before doing this we were calculating the charge of two electrostatic charged pendulums (and testing if condoms are truly nonporous lol)<br />
<img src="/images/2022-05-25-visualizing-electric-fields/xdd.jpg" /></p>

<p>Put the oil on your tray, shape your wires, connect them to your power supply, sprinkle some canary grass and crank the voltage up</p>

<table>
<tbody>
      <tr>
				<td><video width="100%" height="100%" autoplay="" loop="">
  <source src="/images/2022-05-25-visualizing-electric-fields/dipole.webm" type="video/webm" />
Your browser does not support the video tag.
</video>   </td>
				<td><video width="100%" height="100%" autoplay="" loop="">
  <source src="/images/2022-05-25-visualizing-electric-fields/samepole.webm" type="video/webm" />
Your browser does not support the video tag.
</video>  </td>
			</tr>
</tbody>
</table>

<p>And that’s it. They actually look like the simulations (with the difference that we didn’t have to solve math for this one hehe). For the next post, I’ll continue this topic with equipotential lines.</p>]]></content><author><name>Fernando Leon</name></author><category term="Physics" /><category term="Simulation" /><category term="Experiment" /><category term="Calculus" /><summary type="html"><![CDATA[An electric field E is defined as F/q where F is the electric force and q is the charge. The shape of the force lines in an electric field change depending on the shape and interactions that an object goes through, by this definition it means that for a point charge such as an electron or a proton, the direction of the electric field is defined by the charge]]></summary></entry><entry><title type="html">Ohm’s law</title><link href="https://leorfe.me//ohms-law/" rel="alternate" type="text/html" title="Ohm’s law" /><published>2022-05-10T00:00:00+00:00</published><updated>2022-05-10T00:00:00+00:00</updated><id>https://leorfe.me//ohms-law</id><content type="html" xml:base="https://leorfe.me//ohms-law/"><![CDATA[<p>The semester is almost finished, so I finally get a change to upload something to this blog, I’ll begin with the first things we saw on the “Laboratory of electromagnetic devices” class.<br />
For this class session we were asked “How does the electric resistance of a wire depends on its length and cross-sectional area?” and then we were given three nichrome wires of 1 mm diameter each, a rule and a multimeter, then I started to take resistance measurements in steps of 5 cm for one, two and three threaded wires</p>

<table class="centerfy">
<tr><th>1mm diameter </th><th>2mm diameter</th><th>3mm diameter</th></tr>
<tr><td>

<table class="centerfy">
		<thead>
			<tr>
				<th>Length</th>
				<th>Resistance</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td>5</td>
				<td>2.3</td>
			</tr>
			<tr>
				<td>10</td>
				<td>3.1</td>
			</tr>
            <tr>
				<td>15</td>
				<td>4.0</td>
			</tr>
			<tr>
				<td>20</td>
				<td>4.9</td>
			</tr>
            <tr>
				<td>25</td>
				<td>5.8</td>
			</tr>
			<tr>
				<td>30</td>
				<td>6.4</td>
			</tr>
            <tr>
				<td>35</td>
				<td>7.3</td>
			</tr>
			<tr>
				<td>40</td>
				<td>8.1</td>
			</tr>
		</tbody>
	</table>
</td>
<td>

<table>
		<thead>
			<tr>
				<th>Length</th>
				<th>Resistance</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td>5</td>
				<td>1.7</td>
			</tr>
			<tr>
				<td>10</td>
				<td>2.1</td>
			</tr>
            <tr>
				<td>15</td>
				<td>2.7</td>
			</tr>
			<tr>
				<td>20</td>
				<td>3.1</td>
			</tr>
            <tr>
				<td>25</td>
				<td>3.4</td>
			</tr>
			<tr>
				<td>30</td>
				<td>3.8</td>
			</tr>
            <tr>
				<td>35</td>
				<td>4.3</td>
			</tr>
			<tr>
				<td>40</td>
				<td>4.8</td>
			</tr>
		</tbody>
	</table>
</td>
<td>
<table>
		<thead>
			<tr>
				<th>Length</th>
				<th>Resistance</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td>5</td>
				<td>1.5</td>
			</tr>
			<tr>
				<td>10</td>
				<td>2.0</td>
			</tr>
            <tr>
				<td>15</td>
				<td>2.2</td>
			</tr>
			<tr>
				<td>20</td>
				<td>2.4</td>
			</tr>
            <tr>
				<td>25</td>
				<td>2.8</td>
			</tr>
			<tr>
				<td>30</td>
				<td>3.1</td>
			</tr>
            <tr>
				<td>35</td>
				<td>3.5</td>
			</tr>
			<tr>
				<td>40</td>
				<td>3.8</td>
			</tr>
		</tbody>
	</table>
</td></tr> 
</table>

<p>After that I did four scatter plots of the data, three of length vs resistance for each threaded wire and one of cross-sectional area vs resistance at 20 cm of length</p>

<table>
<tbody>
			<tr>
				<td>Length vs resistance with one 1mm wire</td>
				<td>Length vs resistance with two 1mm wires</td>
			</tr>
            <tr>
				<td><img src="/images/2022-05-10-ohms-law/1mmplot.png" /></td>
				<td><img src="/images/2022-05-10-ohms-law/2mmplot.png" /></td>
			</tr>
            <tr>
				<td>Length vs resistance with three 1mm wire</td>
				<td>Area vs resistance at 20cm</td>
			</tr>
            <tr>
				<td><img src="/images/2022-05-10-ohms-law/3mmplot.png" /></td>
				<td><img src="/images/2022-05-10-ohms-law/123plot.png" /></td>
			</tr>
            <tr>
            </tr>
</tbody>
</table>

<p>As we can see from the plots, each of them has at least a 92% relation with a linear trend, we can also see that if we take measurements from a greater distance, the resistance goes up, and when we add more wires to the thread the resistance goes down meaning that the resistance of a material is directly proportional to its length and inversely proportional to its cross-sectional area.</p>

<h1 id="why">Why?</h1>
<p>Ok, we got the answer to the question, but why is it that way and not the other way around? To explain this behavior we’ll have to look at Ohm’s law from the physics side.<br />
Everyone knows a little about Ohm’s law but from an electric analysis perspective on a “macroscopic” scale</p>

\[I=\frac{V}{R}\Rightarrow V=IR\Rightarrow R=\frac{V}{I}\]

<p>From the physics perspective, we analyze the electric field \(\overrightarrow{E}\) as it is composed of the scalar product of resistivity in ohm/meter \(\rho\) and the current density vector per m² \(\overrightarrow{J}\)</p>

\[\overrightarrow{E}=\rho\overrightarrow{J}\]

<p>Then using the definition of voltage between two points of the electric field:</p>

\[\Delta V=-\int_{}^{}\overrightarrow{E}\cdot dl\]

<p>Where \(dl\) is the path along the conductor. If the electric field is uniform along the length of the material as it happens with a wire:</p>

<p><img src="/images/2022-05-10-ohms-law/wire.jpg" alt="from https://phys.libretexts.org/Bookshelves/University_Physics/Book%3A_University_Physics_(OpenStax)/Book%3A_University_Physics_II_-_Thermodynamics_Electricity_and_Magnetism_(OpenStax)/09%3A_Current_and_Resistance/9.04%3A_Resistivity_and_Resistance" /></p>

<p>Then we can drop the \(\Delta\) and define voltage \(V\) and the magnitude \(E\) as:</p>

\[V=lE \rightarrow E=\frac{V}{l}\]

<p>And since the electric field is uniform, so is the current density too, which means we can define the magnitude \(J\) as:</p>

\[J=\frac{I}{a}\]

<p>Replacing the values of \(\overrightarrow{E}\) and \(\overrightarrow{J}\) with these new ones we get:</p>

\[\overrightarrow{E}=\rho\overrightarrow{J} \rightarrow \frac{V}{l}=\rho\frac{I}{a}\]

<p>Solving for \(V\):</p>

\[\frac{V}{l}=\rho\frac{I}{a} \rightarrow V=\frac{\rho I l}{a}\]

<p>If we remove \(I\) from the right side we get</p>

\[\frac{V}{I}=\rho\frac{l}{a}\]

<p>And since \(R=\frac{V}{I}\) it means that the resistance of a wire is</p>

\[R=\rho\frac{l}{a}\]

<p>Proving that there exists a formula that shows the resistivity is proportional to the length and inversely proportional to the cross-sectional area.</p>]]></content><author><name>Fernando Leon</name></author><category term="Physics" /><category term="Data gathering" /><category term="Experiment" /><summary type="html"><![CDATA[The semester is almost finished, so I finally get a change to upload something to this blog, I'll begin with the first things we saw on the "Laboratory of electromagnetic devices" class. For this class session we were asked]]></summary></entry><entry><title type="html">ADC Board PCB</title><link href="https://leorfe.me//adc-board/" rel="alternate" type="text/html" title="ADC Board PCB" /><published>2001-01-01T00:00:00+00:00</published><updated>2001-01-01T00:00:00+00:00</updated><id>https://leorfe.me//adc-board</id><content type="html" xml:base="https://leorfe.me//adc-board/"><![CDATA[<p>This is an ADC board PCB designed in KiCad. The main goal of this project was to create a high-speed data acquisition system that can be used for measuring fast signals as part of a bigger project involving signal processing. Since I had coupon for six layer PCBs I decided to design this ADC board with a six layer design to ensure proper signal integrity, minimize noise, small form factor and the use of in-pad vias.</p>
<h2 id="design">Design</h2>

<p>The PCB was designed using KiCad using the HMCAD1511TR ADC chip as the main component for data acquisition and the AD8132 differential amplifier for signal conditioning.
<img src="/images/adc-board/design.png" /></p>

<h2 id="manufacturing">Manufacturing</h2>
<p>The PCB was manufactured using a professional PCB manufacturing service. The components were soldered using a reflow soldering process to ensure proper connections and reliability also done by the manufacturer since some of the components were pretty much exotic and was a lot cheaper than having to order them separately.</p>

<p><img src="/images/adc-board/man1.png" /></p>

<p><img src="/images/adc-board/preview.png" /></p>]]></content><author><name>Fernando Leon</name></author><category term="PCB" /><summary type="html"><![CDATA[This is an ADC board PCB designed in KiCad. It allows for high-speed data acquisition using an external ADC chip.]]></summary></entry><entry><title type="html">Differential Probe PCB</title><link href="https://leorfe.me//differential-probe/" rel="alternate" type="text/html" title="Differential Probe PCB" /><published>2001-01-01T00:00:00+00:00</published><updated>2001-01-01T00:00:00+00:00</updated><id>https://leorfe.me//differential-probe</id><content type="html" xml:base="https://leorfe.me//differential-probe/"><![CDATA[<p>This is a differential probe PCB designed in KiCad. The main goal of this project was to create a high-precision differential probe that can be used for measuring high voltage signals safely by having different ground references. Also in my power electronics class there werent enough differential probes available for students to use, so I decided to design my own making this project born out of necessity.</p>
<h2 id="design">Design</h2>

<p>The PCB was designed using KiCad using the INA-128 instrumentation amplifier as the main component for signal conditioning.
<img src="/images/differential-probe/design.png" /></p>

<h2 id="manufacturing">Manufacturing</h2>
<p>The PCB was manufactured using a professional PCB manufacturing service. The components were soldered using a reflow soldering process to ensure proper connections and reliability also done by the manufacturer since some of the components were somewhat exotic and was cheaper than having to order them separately.</p>

<p><img src="/images/differential-probe/man1.png" /></p>

<p><img src="/images/differential-probe/preview.png" /></p>

<h2 id="testing">Testing</h2>
<p>The differential probe was tested with a classic SRC light bulb brightness control circuit. The results showed that the probe was able to accurately measure the differential voltage across the load, allowing for safe and precise measurements of high voltage signals.</p>

<p><img src="/images/differential-probe/test1.png" />
<img src="/images/differential-probe/test2.png" /></p>]]></content><author><name>Fernando Leon</name></author><category term="PCB" /><summary type="html"><![CDATA[This is a differential probe PCB designed in KiCad. It allows for measurements of high voltage signals.]]></summary></entry><entry><title type="html">ESP32 DIY Relay PCB</title><link href="https://leorfe.me//esp32-diy-relay/" rel="alternate" type="text/html" title="ESP32 DIY Relay PCB" /><published>2001-01-01T00:00:00+00:00</published><updated>2001-01-01T00:00:00+00:00</updated><id>https://leorfe.me//esp32-diy-relay</id><content type="html" xml:base="https://leorfe.me//esp32-diy-relay/"><![CDATA[<p>This is a relay PCB based on ESP32 manufactured in DIY way. The main goal of this project was to create a low-cost and easy-to-assemble relay PCB that can be used for home automation. Also during this time (Circa 2016) PCB manufacturing services were quite expensive, so I decided to make it myself.</p>

<h2 id="design">Design</h2>

<p>The PCB was designed using KiCad.
<img src="/images/esp32-diy-relay/design.png" /></p>

<h2 id="manufacturing">Manufacturing</h2>

<p>The manufacturing process involved painting a copper-clad board black, then using a laser to burn the design onto the board. After that, the board was etched using a ferric chloride solution to remove the unwanted copper. Then, the board was drilled and components were soldered onto it. Finally, the board was coated with a protective layer to prevent oxidation using “liquid tin”.</p>

<video width="100%" height="100%" autoplay="" loop="" muted="">
  <source src="/images/esp32-diy-relay/laser.mp4" type="video/mp4" />
Your browser does not support the video tag.
</video>

<p><img src="/images/esp32-diy-relay/etch1.png" /></p>

<p><img src="/images/esp32-diy-relay/etch2.png" /></p>

<p><img src="/images/esp32-diy-relay/preview.png" /></p>]]></content><author><name>Fernando Leon</name></author><category term="PCB" /><summary type="html"><![CDATA[This is a relay PCB based on ESP32 designed in KiCad and manufactured in DIY way using laser, ferric chloride etching and liquid tin for oxidation prevention.]]></summary></entry><entry><title type="html">Universal HeNe power supply</title><link href="https://leorfe.me//hene-supply/" rel="alternate" type="text/html" title="Universal HeNe power supply" /><published>2001-01-01T00:00:00+00:00</published><updated>2001-01-01T00:00:00+00:00</updated><id>https://leorfe.me//hene-supply</id><content type="html" xml:base="https://leorfe.me//hene-supply/"><![CDATA[<p>This is a universal HeNe power supply designed in KiCad. The main goal of this project was to create a high-voltage power supply that can be used for driving HeNe lasers since manufacturer’s power supplies are often expensive and hard to repair. This design includes multiple boards to handle different aspects of the power supply, including high-voltage generation, regulation, and control.</p>

<h2 id="design">Design</h2>

<h3 id="controller-board">Controller Board</h3>
<p>The controller board is responsible for managing the overall operation of the power supply, including voltage regulation and safety features. It uses an RP2350 microcontroller for control and monitoring, along with various gate drivers, amplifiers and mosfets to handle DC-DC and AC-DC conversion.
<img src="/images/hene-supply/controller-design.png" /></p>

<h3 id="hv-board">HV Board</h3>
<p>The high-voltage board is responsible for generating the high voltage required to drive the HeNe laser. It uses a combination of transformers, rectifiers, and voltage multipliers to achieve the necessary voltage levels.
<img src="/images/hene-supply/hv-design.png" /></p>

<h3 id="user-interface-board">User Interface Board</h3>
<p>The user interface board provides a way for the user to interact with the power supply, including buttons and a display.
<img src="/images/hene-supply/ui-design.png" /></p>

<h2 id="manufacturing">Manufacturing</h2>
<p>The PCBs were manufactured using a professional PCB manufacturing service. The components were soldered using a reflow soldering process to ensure proper connections and reliability also done by the manufacturer.</p>

<p><img src="/images/hene-supply/man1.png" />
<img src="/images/hene-supply/man2.png" />
<img src="/images/hene-supply/man3.png" /></p>

<h2 id="testing">Testing</h2>
<p>The power supply was tested with a Melles Griot 15mW HeNe laser tube. The results showed that the power supply was able to drive the laser tube successfully.</p>

<p><img src="/images/hene-supply/test1.png" />
<img src="/images/hene-supply/test2.png" /></p>

<p>On a side note, the results of this project were presented at the LXVIII Congreso Nacional de Física in Toluca, México. Since this project was born out of a collaborative effort of the Electronics Faculty and Physics Faculty of the Benemérita Universidad Autónoma de Puebla (BUAP), the presentation highlighted the interdisciplinary nature of the work and its potential applications in both educational and research settings.</p>]]></content><author><name>Fernando Leon</name></author><category term="PCB" /><category term="Project" /><summary type="html"><![CDATA[This is a universal HeNe power supply with multiple boards designed in KiCad. It allows for high-voltage operation and control of the laser.]]></summary></entry><entry><title type="html">LR1121 Transceiver PCB</title><link href="https://leorfe.me//lr1121-transceiver/" rel="alternate" type="text/html" title="LR1121 Transceiver PCB" /><published>2001-01-01T00:00:00+00:00</published><updated>2001-01-01T00:00:00+00:00</updated><id>https://leorfe.me//lr1121-transceiver</id><content type="html" xml:base="https://leorfe.me//lr1121-transceiver/"><![CDATA[<p>This is an LR1121 transceiver PCB designed in KiCad for long-range low-power communication applications with an integrated antenna. The main goal of this project was to create a compact and efficient transceiver module that can be easily integrated into various IoT devices. Initially this design was meant to use the LR2021 chip but Semtech did not release the chip on time for the project deadline so I had to switch to the LR1121 which was available at the time (and cheaper since there were premade modules out there). Because of that the board design was kept in 6 layers but also because of the antenna geometry requirements of a flat surface.</p>
<h2 id="design">Design</h2>

<p>The PCB was designed using KiCad using the LR1121 transceiver chip as the main component for long-range communication and the AD8132 differential amplifier for signal conditioning.
<img src="/images/lr1121-transceiver/design.png" /></p>

<h2 id="antenna">Antenna</h2>
<p>The PCB features an integrated inverted-F antenna designed to operate in the 2400 MHz frequency band. The antenna was simulated and optimized using the electromagnetic solver software Sonnet to ensure optimal performance and efficiency.
<img src="/images/lr1121-transceiver/sim.png" /></p>

<h2 id="manufacturing">Manufacturing</h2>
<p>The PCB was manufactured using a professional PCB manufacturing service. The components were soldered using a reflow soldering process to ensure proper connections and reliability also done by the manufacturer since some of the components were pretty much exotic and was a lot cheaper than having to order them separately.</p>

<p><img src="/images/lr1121-transceiver/man1.png" /></p>

<p><img src="/images/lr1121-transceiver/preview.png" /></p>

<h2 id="testing">Testing</h2>
<p>The PCB antenna was tested using a network analyzer to measure its performance and ensure it met the design specifications. The transceiver functionality was verified by establishing communication with another LR1121 module and measuring the signal strength and data transfer rates.</p>

<video width="100%" height="100%" autoplay="" loop="" muted="">
  <source src="/images/lr1121-transceiver/test.mp4" type="video/mp4" />
Your browser does not support the video tag.
</video>]]></content><author><name>Fernando Leon</name></author><category term="PCB" /><summary type="html"><![CDATA[This is an LR1121 transceiver PCB designed in KiCad for long-range low-power communication applications with an integrated antenna.]]></summary></entry><entry><title type="html">Planar Magnetics</title><link href="https://leorfe.me//planar-magnetics/" rel="alternate" type="text/html" title="Planar Magnetics" /><published>2001-01-01T00:00:00+00:00</published><updated>2001-01-01T00:00:00+00:00</updated><id>https://leorfe.me//planar-magnetics</id><content type="html" xml:base="https://leorfe.me//planar-magnetics/"><![CDATA[<p>This is a six layer 2:1 planar transformer PCB designed in KiCad for use in 1MHz - 5MHz frequencies. The main goal of this project was to create a small transformer that can be used in a variety of applications, including power supplies and RF circuits. The design was driven by the need for a compact and efficient transformer that could operate at high frequencies without excessive losses. Also I had a coupon with the manufacturer that allowed me to create a six layer PCB at a very low cost, so I decided to take advantage of that to create this planar transformer with some “unordinary” design choices like 2oz copper on all layers.</p>

<h2 id="design">Design</h2>

<p>The PCB was designed using KiCad with the help of this website: https://webench.ti.com/wb5/LDC/#/spirals in order to calculate the spirals.
<img src="/images/planar-magnetics/design.png" /></p>

<h2 id="manufacturing">Manufacturing</h2>
<p>The PCB was manufactured using a professional PCB manufacturing service. six layer PCB with 2oz copper on all layers.</p>

<p><img src="/images/planar-magnetics/preview.png" /></p>

<h2 id="testing">Testing</h2>

<p>A 1.5MHz sine wave is applied to the primary side of the transformer and the output is measured on the secondary side. The results show that the transformer is able to step up the voltage as expected, with a measured output voltage of approximately 3.8 times the input.</p>

<p><img src="/images/planar-magnetics/test1.png" />
<img src="/images/planar-magnetics/test2.png" />
<img src="/images/planar-magnetics/test3.png" /></p>]]></content><author><name>Fernando Leon</name></author><category term="PCB" /><summary type="html"><![CDATA[This is a six layer planar transformer PCB designed in KiCad for use in 1MHz - 5MHz frequencies.]]></summary></entry></feed>