git diff against previous

March 30, 2025 Linux No comments , , , ,

I’ve been using a simple home grown script (gitdiffc) to generate git diffs against the previous version for all files in a given commit.  It would run something like:

# git diff \
$(git log --pretty=format:%h -2 --reverse d86cc4b38db | tr "\n" " ")

The git log part, just gives two commit IDs. Example:

# git log --pretty=format:%h -2 --reverse d86cc4b38db
38aeb009b21
d86cc4b38db

I have a few files that I have to manually merge, as there are two many cherry-pick conflicts, so I was collecting information for that merge.  That included extracting the version that I would have wanted to cherry-pick, since :

git show d86cc4b38db:foo.cc > foo.cc.show

I also wanted a diff, of just that file, in the branch I am trying to pick from, but wasn’t sure how to get that easily without looking up the log, like I did in my ‘gitdiffc’ script that ran the log and diff command above.

I figured there had to be an easier way. Shout out to Grok, which pointed out that I can just use:

git diff d86cc4b38db^ d86cc4b38db -- foo.cc

This also means that I can simplify my ‘gitdiffc’ script so that it just runs:

# git diff d86cc4b38db^..d86cc4b38db

eliminating the nested git log command. That is simple enough that I don’t even need a script to remember how to do it. This should have been obvious, since I’ve used HEAD^ just like that so many times (i.e.: git reset HEAD^, to break up the last commit.)

Weighted geometric series

March 23, 2025 math and physics play No comments , , ,

[Click here for a PDF version of this post]

Karl needed to evaluate the sum:

\begin{equation}\label{eqn:weightedGeometric:20}
S = \sum_{k = 0}^9 \frac{a + b k}{\lr{ 1 + i }^k}
\end{equation}

He ended up using a spreadsheet, which was a quick and effective way to deal with the problem. I was curious about this sum, since he asked me how to sum it symbolically, and I didn’t know.

Mathematica doesn’t have any problem with it, as seen in fig. 1.

fig. 1. A funky sum.

How can we figure this out?

Let’s write \( r = 1/(1+i) \) to start with, and break up the sum into constituent parts
\begin{equation}\label{eqn:weightedGeometric:40}
\begin{aligned}
S_n
&= \sum_{k = 0}^n \frac{a + b k}{\lr{ 1 + i }^k} \\
&= a \sum_{k = 0}^n r^k + b \sum_{k = 0}^n k r^k.
\end{aligned}
\end{equation}
We can evaluate the geometric part of this easily using the usual trick. Let
\begin{equation}\label{eqn:weightedGeometric:60}
T_n = \sum_{k = 0}^n r^k,
\end{equation}
then
\begin{equation}\label{eqn:weightedGeometric:80}
r T_n – T_n = r^{n+1} – 1,
\end{equation}
so
\begin{equation}\label{eqn:weightedGeometric:100}
T_n = \frac{r^{n+1} – 1}{r – 1}.
\end{equation}
Now we just have to figure out how to sum
\begin{equation}\label{eqn:weightedGeometric:120}
G_n = \sum_{k = 0}^n k r^k = \sum_{k = 1}^n k r^k.
\end{equation}
This looks suspiciously like the derivative of a geometric series. Let’s evaluate such a derivative, as a function of r:
\begin{equation}\label{eqn:weightedGeometric:140}
\begin{aligned}
\frac{d T_n(r)}{dr}
&= \sum_{k = 0}^n \frac{d}{dr} r^k \\
&= \sum_{k = 0}^n k r^{k-1} \\
&= \sum_{k = 1}^n k r^{k-1} \\
&= \inv{r} \sum_{k = 1}^n k r^k.
\end{aligned}
\end{equation}
Having summed the geometric series, we may also take the derivative of that summed result
\begin{equation}\label{eqn:weightedGeometric:160}
\begin{aligned}
\frac{d T_n(r)}{dr}
&= \frac{d}{dr} \lr{ \frac{r^{n+1} – 1}{r – 1} } \\
&= \frac{(n+1)r^n}{r – 1} – \frac{r^{n+1} – 1}{\lr{r -1}^2} \\
&= \frac{(n+1)r^n(r-1) – \lr{r^{n+1} – 1}}{\lr{r -1}^2}.
\end{aligned}
\end{equation}
Putting the pieces together, we have
\begin{equation}\label{eqn:weightedGeometric:180}
T_n = \frac{r}{\lr{r -1}^2} \lr{ (n+1)r^n(r-1) – \lr{r^{n+1} – 1} }.
\end{equation}

This means that our sum is
\begin{equation}\label{eqn:weightedGeometric:200}
S_n = a \frac{r^{n+1} – 1}{r – 1} + b \frac{r}{\lr{r -1}^2} \lr{ (n+1)r^n(r-1) – \lr{r^{n+1} – 1} }.
\end{equation}
Putting back \( r = 1/(1+i) \), and subsequent simplification, gives the Mathematica result. It’s not pretty, but at least we can do it if we want to.

Shout out to Grok that pointed out the derivative trick for the second series.  I’d forgotten that one.

Wonderful Life=Giving Radium

March 22, 2025 Incoherent ramblings No comments

From “The Wide World” Magazine, June 1905 edition

“This remarkable substance is absolute and quick death to the germs of cancer, tumor, consumption, malaria, blood poison, ulcers and all forms of existing disease.  When it enters the system every vestige of disease is driven out, as no germ can live in its presence.”

The amusing thing is that the idea of this advertisement has a close analogue in modern medicine, as chemotherapy is essentially the same idea.  Chemotherapy is also a gross system wide attack on the body, a desperate hope that it can be used to kill off the cancer cells faster than the rest of the cellular structure of the body.  It’s the kind of treatment that future Bones, in Star Trek IV, will eventually be describing as “What is this, the dark ages?”

I have three of these “Wide World” magazines that I got in a “unknown” box of pulp fiction magazines from a second hand store when I was a kid (Argosy, Blue Boy, …).  The ads from these magazines are the best part.  I think I’ve posted a few more of them on my old blog, but I should systematically go through them for archival purposes, and share them all.

Impedance refresher.

March 21, 2025 math and physics play No comments , , , , , , , , , , , ,

[Click here for a PDF version of this post]

Karl is taking his circuits course right now, which means that I get a chance to field some questions. I don’t get an excuse to think about this stuff any more. It’s fun material, since most of the ideas are all really simple, and you can figure out everything from first principles.

Karl just started sinusoidal circuits, which I think is a bit exciting. They are such a nice special case, as complex calculations are all effectively reduced to \( V = I R \) style computations.

Solving RLC circuits for general time dependent sources.

To contrast the simple case of sinusoidal sources, let’s consider what we have to do in order to solve a general case RLC circuit. The simple basic RC circuit sketched in fig. 1 provides a good illustrative example, even though it does not include any inductance.

With \( v \) as the voltage at the capacitor, the equations that describe the circuit are
\begin{equation}\label{eqn:impedance:20}
\begin{aligned}
v_s – v &= i R \\
i &= C \frac{dv}{dt}.
\end{aligned}
\end{equation}

We can combine these into one equation for \( v \). Letting \( \tau = RC \), that is
\begin{equation}\label{eqn:impedance:40}
v + \tau \frac{dv}{dt} = v_s.
\end{equation}
Here \( v_s = v_s(t) \) can be an arbitrary function of time. This is a simple enough differential equation, and can probably be solved in various ways (integrating factors, Fourier transforms, Laplace transforms, …)

For illustration purposes, let’s tackle this little equation with Fourier transforms, a method logically equivalent to the computation of the Green’s function for the system.

Let’s use a symmetric representation of the Fourier transform
\begin{equation}\label{eqn:impedance:60}
\begin{aligned}
F(\omega) &= \inv{\sqrt{2 \pi}} \int_{-\infty}^\infty e^{-j\omega t} f(t) dt \\
f(t) &= \inv{\sqrt{2 \pi}} \int_{-\infty}^\infty e^{j\omega t} F(\omega) d\omega \\
\end{aligned}
\end{equation}
Recall that the Fourier transform of the derivative is just a \( j \omega \) scaled frequency domain function, which we show with integration by parts
\begin{equation}\label{eqn:impedance:80}
\begin{aligned}
\inv{\sqrt{2 \pi}} \int_{-\infty}^\infty e^{-j\omega t} \frac{df}{dt} dt
&= \inv{\sqrt{2 \pi}} \int_{-\infty}^\infty \lr{ \frac{d}{dt} \lr{ f(t) e^{-j \omega t} } – f(t) \frac{d}{dt}\lr{ e^{-j\omega t}} } dt \\
&= j \omega F(\omega).
\end{aligned}
\end{equation}
That means that the frequency domain equivalent of our system is
\begin{equation}\label{eqn:impedance:100}
V + j \omega \tau V = V_s,
\end{equation}
or
\begin{equation}\label{eqn:impedance:120}
V(\omega) = \frac{V_s(\omega)}{1 + j \omega \tau}.
\end{equation}
Inverse transformation yields
\begin{equation}\label{eqn:impedance:140}
\begin{aligned}
v(t)
&= \inv{\sqrt{2 \pi}} \int_{-\infty}^\infty e^{j\omega t} \frac{V_s(\omega)}{1 + j \omega \tau} d\omega \\
&= \inv{2 \pi} \iint_{-\infty}^\infty e^{j\omega t} \frac{1}{1 + j \omega \tau} d\omega e^{-j\omega t’} v_s(t’) dt’ \\
&= \int_{-\infty}^\infty dt’ v_s(t’) \inv{2\pi} \int_{-\infty}^\infty \frac{e^{j\omega(t-t’)}}{1 + j \omega \tau} d\omega,
\end{aligned}
\end{equation}
or with
\begin{equation}\label{eqn:impedance:160}
G(u) = \inv{2\pi} \int_{-\infty}^\infty \frac{e^{j\omega u}}{1 + j \omega \tau} d\omega,
\end{equation}
\begin{equation}\label{eqn:impedance:180}
v(t) = \int_{-\infty}^\infty v_s(t’) G(t – t’) dt’.
\end{equation}
We just need to evaluate the Green’s function \( G(u) \) to proceed, which we can do with standard contour integration, first writing:

\begin{equation}\label{eqn:impedance:200}
\begin{aligned}
G(u)
&= \inv{2\pi j \tau} \int_{-\infty}^\infty \frac{e^{j\omega u}}{\inv{j\tau} + \omega} d\omega \\
&= \inv{2\pi j \tau} \oint \frac{e^{j z u}}{\inv{j\tau} + z} dz.
\end{aligned}
\end{equation}
This has a single pole at \( z = j/\tau \). We need an infinite semicircular contour in the lower half plane for \( u < 0 \), and can use the upper half plane infinite semicircular contour (surrounding the pole) for \( u > 0 \). That gives
\begin{equation}\label{eqn:impedance:220}
\begin{aligned}
G(u)
&= \Theta(u) \frac{2 \pi j}{2\pi j \tau} \evalbar{e^{j z u}}{z = j/\tau} \\
&= \frac{\Theta(u)}{\tau} e^{- u/\tau}.
\end{aligned}
\end{equation}

The solution to the problem, for any Fourier integrable source \( v_s(t) \), is
\begin{equation}\label{eqn:impedance:240}
\boxed{
v(t) = \int_{-\infty}^t v_s(t’) \frac{e^{- \lr{t – t’}/\tau}}{\tau} dt’.
}
\end{equation}

As a check, let’s evaluate this convolution integral for a step source \( v_s(t) = V \Theta(t) \), to find
\begin{equation}\label{eqn:impedance:260}
\begin{aligned}
v(t)
&= \frac{V e^{-t/tau}}{\tau} \int_0^t e^{t’/\tau} dt’ \\
&= V e^{-t/tau} \evalrange{e^{t’/\tau} }{0}{t} \\
&= V e^{-t/tau} \lr{ e^{t/\tau} – 1 } \\
&= V \lr{ 1 – e^{-t/\tau} }.
\end{aligned}
\end{equation}
This is the damped time domain response that we remember for an RC circuit. In Karl’s first year engineering notes, this was presented as a given (without the step factor), and he had to verify that it worked by differentiation (for \( t > 0 \).)

Solving this exactly, even for arbitrary sources, as we’ve done above, is not strictly hard, if you have all the required tools. But the first year engineering student doesn’t have all those tools to start with. This is where the beauty of the phasor techniques for sinusoidal sources comes in. Let’s now see how that works.

Phasor approach.

Let’s consider the three simplest RLC circuits, each with just a single element, and a variable voltage source. I’ll depict that element with a box as in fig. 2.

Resistor case.

If the element is a resistor with value \( R \), our equations are simple
\begin{equation}\label{eqn:impedance:280}
v_s = i R.
\end{equation}
Clearly \( i \) is directly proportional to the source voltage. In particular, if \( v_s(t) \) has a sinusoidal character, such as
\begin{equation}\label{eqn:impedance:300}
v_s(t) = V \cos(\omega t),
\end{equation}
then
\begin{equation}\label{eqn:impedance:320}
i(t) = \frac{V}{R} \cos\lr{ \omega t }.
\end{equation}
In particular, if we let \( i(t) = I \cos\lr{ \omega t } \), then we have
\begin{equation}\label{eqn:impedance:340}
I = \frac{V}{R},
\end{equation}
or \( V = I R \).

Capacitor case.

If the load element is a capacitor with capacitance \( C \), then the equation for the system is
\begin{equation}\label{eqn:impedance:360}
i = C \frac{dv_s(t)}{dt}.
\end{equation}
If we just plug in \( v_s(t) = V \cos(\omega t) \), as before, we get a bit of a mess
\begin{equation}\label{eqn:impedance:380}
i = -C \omega V \sin\lr{ \omega t }.
\end{equation}
We no longer have a nice simple proportionality relationship between the current and the voltage source, as the capacitor has introduced a phase shift into the mix.
We can figure out that phase factor by solving the equation
\begin{equation}\label{eqn:impedance:400}
-\sin x = \cos\lr{ x + \phi }.
\end{equation}
The easiest way to solve this is to express the sinusoids in complex exponential form
\begin{equation}\label{eqn:impedance:420}
\textrm{Re} \lr{ e^{j + \phi} } = \Real \lr{ j e^{j x} } = \Real \lr{ e^{j \pi/2} e^{j x} }.
\end{equation}
We see that the phase factor is a \( \pi/2 \) shift. However, even better, we have a strong hint that working with complex exponentials may be a better approach to formulating the problem.

Let’s write
\begin{equation}\label{eqn:impedance:440}
v_s(t) = V \cos\lr{ \omega t } = \textrm{Re} \lr{ V e^{j \omega t} }.
\end{equation}
Then we have
\begin{equation}\label{eqn:impedance:460}
i(t) = C V \textrm{Re} \lr{ \frac{d}{dt} e^{j \omega t} }.
\end{equation}
If we also assume that we can write
\begin{equation}\label{eqn:impedance:480}
i(t) = \textrm{Re} \lr{ I e^{j \omega t} },
\end{equation}
then if the real parts are equal, we must also have
\begin{equation}\label{eqn:impedance:500}
I e^{j \omega t} = j \omega C V e^{j \omega t},
\end{equation}
or
\begin{equation}\label{eqn:impedance:520}
I = j \omega C V.
\end{equation}
We have a \( V = I R \) relationship, which we write as
\begin{equation}\label{eqn:impedance:540}
V = I Z,
\end{equation}
where
\begin{equation}\label{eqn:impedance:560}
Z = \inv{j \omega C}.
\end{equation}
This is the phasor description of the circuit.

Inductive case.

If the circuit has an inductive load, then the system equation is
\begin{equation}\label{eqn:impedance:580}
v_s(t) = L \frac{di}{dt}.
\end{equation}
Again, we can write \( v_s(t) = \textrm{Re} \lr{ V e^{j\omega t} } \), and assume that \( i = \Real \lr{ I e^{j\omega t} } \). We then require
\begin{equation}\label{eqn:impedance:600}
V e^{j \omega t} = L \frac{d}{dt} \lr{ I e^{j \omega t} },
\end{equation}
or
\begin{equation}\label{eqn:impedance:620}
V = j \omega L I.
\end{equation}
We write
\begin{equation}\label{eqn:impedance:640}
Z = j \omega L,
\end{equation}
so once again \( V = I Z \).

Solving a more complex RLC configuration.

An example of a more complicated RLC circuit is sketched in fig. 3.

Here we have two impedances in parallel
\begin{equation}\label{eqn:impedance:660}
\begin{aligned}
Z_C &= \inv{j \omega C} \\
Z_L &= j \omega L.
\end{aligned}
\end{equation}
The parallel impedance through that reactive load is
\begin{equation}\label{eqn:impedance:680}
\begin{aligned}
Z
&= \lr{ \inv{Z_C} + \inv{Z_L} }^{-1} \\
&= \lr{ j \omega C + \inv{ j \omega L } }^{-1}.
\end{aligned}
\end{equation}
We can compute the current through \( R \) now
\begin{equation}\label{eqn:impedance:700}
I = \frac{V_s}{ R + \lr{ j \omega C + \inv{ j \omega L } }^{-1} }.
\end{equation}
We also have
\begin{equation}\label{eqn:impedance:720}
\frac{V_s – V}{R} = I,
\end{equation}
or
\begin{equation}\label{eqn:impedance:740}
\begin{aligned}
V
&= V_s – I R \\
&= V_s \lr{ 1 – \frac{R}{ R + \lr{ j \omega C + \inv{ j \omega L } }^{-1} } } \\
&= V_s \frac{\lr{ j \omega C + \inv{ j \omega L } }^{-1} }{ R + \lr{ j \omega C + \inv{ j \omega L } }^{-1} } \\
&= \frac{V_s}{ R \lr{ j \omega C + \inv{ j \omega L } } + 1 }.
\end{aligned}
\end{equation}
The complicated time response for this system is reduced to a trivial voltage divider calculation. We see that it was kind of pointless to run an inductor and capacitor in parallel, as they are both purely reactive (imaginary). That’s a detail that I didn’t remember, since it’s been decades since I did any practical circuits applications. However, the point is, by using a complex exponential source representation, these types of systems are reduced from systems of coupled differential equations to simple linear systems. Imagine how messy it would be to try to solve this system using the Green’s function methods that we used above!

What stocks to buy as part of my retirement savings?

February 20, 2025 Investing , , , , ,

As part of my RRSP, I recently opened a stock trading account.  I’m in the process of seeding this account with a relatively small percentage of my total combined RRSP+LIRA.  It’s a small enough number that it is noise in the big picture, but still enough that it satisfies the minimum amounts for high fee avoidance.
I like to spend my time thinking about math, physics, coding, and building stuff, and don’t find investing intrinsically interesting whatsoever.  Because of that lack of interest, mutual funds have made a lot of sense for my retirement savings.  I can use dollar cost averaging to buy into those funds, and forget about them after that.  However, in the interest of diversification, I thought I should finally bite the bullet and at least set myself up to buy some stocks should I want to.
Having done so, I am left with the annoying problem of figuring out what specific stocks to include in my retirement savings.
Considering what I might potentially buy, it makes sense not to buy stuff that I already own indirectly through various mutual funds.  It’s slightly non-trivial to figure out what those indirect holdings actually are, but I downloaded the end of year “holdings CSVs” for all the funds I own, and did some data manipulation after that.  I determined that (not counting crypto, nor real estate equity) these are my current effective top holdings, as percentages of total:
Microsoft Corp 3.06
NVIDIA Corp 2.99
Apple Inc 2.44
Agnico Eagle Mines Ltd 1.90
Royal Bank of Canada 1.62
Amazon.com Inc 1.51
Alphabet Inc – Class A Shares 1.35
Broadcom Inc 1.30
Enbridge Inc 1.27
Wheaton Precious Metals Corp 1.25
Shopify Inc 1.22
Exxon Mobil Corp 1.11
Meta Platforms Inc – Class A Shares 1.09
Kinross Gold Corp 1.00
Barrick Gold Corp 1.00
Canadian Natural Resources Ltd 0.96
Taiwan Semiconductor Manufacturing Co Ltd 0.94
Toronto-Dominion Bank 0.90
Unknown 0.89
Shell PLC 0.83
Chevron Corp 0.82
Brookfield Corp 0.79
TC Energy Corp 0.70
Netflix Inc 0.70
Alamos Gold Inc 0.68
Suncor Energy Inc 0.68
Bank of Montreal 0.67
ConocoPhillips 0.67
Canadian Pacific Kansas City Ltd 0.65
Bank of Nova Scotia 0.63
TotalEnergies SE 0.58
Constellation Software Inc/Canada 0.58
Canadian Imperial Bank of Commerce 0.58
Franco-Nevada Corp 0.57
Salesforce Inc 0.53
Canadian National Railway Co 0.53
JPMorgan Chase & Co 0.52
Procter & Gamble Co 0.52
Manulife Financial Corp 0.52
Home Depot Inc 0.51
K92 Mining Inc 0.51
Intuit Inc 0.51
RBC Canadian Short-Term Income Fund – Series O 0.50
The full list is about 1000 rows long, with non-zero dollar amounts going as low as $2.30 per holding.  The data manipulation and visualization possibilities are much more interesting than the investments themselves, and I’d like to play with that more.
As for what to incorporate into the stock account, I think that I’m heavy on the equity side of the story, so some stable dividend producers might be a good way to round things out.