Lab 2
Get the code
Find the Lab 2 code in the class repository.
$ ls
README.md classes/ labs/ scripts/
$ ls labs/lab2
README cpp/ julia/ python/ rust/
$ ls labs/lab2/cpp
curves.cpp makefile triples.cpp view-trip.gp
The instructions here focus on C++, but you may carry out the comparable steps in Julia, Python, or Rust. You only need to submit your solutions for a single programming language.
Ordered tuples
The lab2
directory contains a short C++ program named
triples.cpp
that outputs all strictly ordered triples of the
integers 0 to 6 (inclusive). The make
command invokes the compiler,
which creates an executable named triples
.
$ make triples
g++ -o triples triples.cpp -O -ansi -pedantic -Wall
$ ./triples
(0,1,2)
(0,1,3)
(0,2,3)
(1,2,3)
.
.
.
(1,5,6)
(2,5,6)
(3,5,6)
(4,5,6)
Modify the program so that instead it counts the number of such triples. Generalize to integers \(\mathsf{0}, \mathsf{1}, \ldots, \mathsf{N}\), and output the results in two-column format for all values of \(\mathsf{N}\) from 2 to 10. You should be able to reproduce the following.
$ make triples
g++ -o triples triples.cpp -O -ansi -pedantic -Wall
$ ./triples
2 1
3 4
4 10
5 20
6 35
7 56
8 84
9 120
10 165
$ ./triples > trip.dat
$ gnuplot view-trip.gp
(If your plot doesn’t persist, you may have to type
gnuplot -p view-trip.gp
. Whether the -p
flag is required
depends on which operating system you’re running. Alternatively, you
can add pause -1
as the last line of your gnuplot script.)
Redirection from stdout
to a file via > trip.dat
is a shell feature
and not specific to C++, which is to say that you can do all of the
following:
$ cd ../julia
$ julia triples.jl > trip.dat
$ cd ../python
$ python3 triples.py > trip.dat
$ cd ../rust
$ rustc triples.rs
$ ./triples > trip.dat
$ cd ../cpp
Using your solution to triples.cpp
as a template, create a program
file quadruples.cpp
that writes three columns of data:
\(\mathsf{N}\) from 0 to 99, the number of weakly ordered
quadruples \(\mathsf{(i,j,k,l)}\) formed from the integers
\(\mathsf{0}\) through \(\mathsf{N}\), and how many of the sums
\(\mathsf{i^2 + j^2 + k^2 + l^2}\) are perfect squares.
(Strict ordering of \(\mathsf{i}\), \(\mathsf{j}\),
\(\mathsf{k}\), and \(\mathsf{l}\) implies that
\(\mathsf{i < j < k < l}\). Weak ordering implies
that \(\mathsf{i \le j \le k \le l}\).)
$ make quadruples
g++ -o quadruples quadruples.cpp -O -ansi -pedantic -Wall
$ ./quadruples
0 1 1
1 5 3
2 15 6
3 35 8
4 70 14
5 126 18
. . .
. . .
. . .
97 4082925 15689
98 4249575 16213
99 4421275 16462
Determine whether an integer is a perfect square by whatever means. You
may want to use std::sqrt
from the cmath
library in combination
with integer casting.
Following view-trip.gp
, compose a gnuplot script file view-quad.gp
that plots the number of perfect squares alongside the 3rd- and
4th-order polynomial fits to the data.
Selection rules
The hydrogen atom consists of a single electron orbiting a positively charged nucleus. The electron can exist only in discrete orbitals characterized by the radial quantum number \(\mathsf{n} = \mathsf{1}, \mathsf{2}, \mathsf{3}, \ldots\) and the angular momentum quantum numbers \(\mathsf{l} = \mathsf{0}, \mathsf{1}, \mathsf{2}, \ldots, \mathsf{n-1}\) and \(\mathsf{m} = \mathsf{-l}, \ldots, \mathsf{-1}, \mathsf{0}, \mathsf{1}, \ldots, \mathsf{l}\). The energy of each orbital, \(\mathsf{E_n} = \mathsf{-(13.6\,\textsf{eV})/n^2}\), is a function of the radial quantum number alone. Hence, each energy level is \(\mathsf{g_n}\)-fold degenerate, where \(\mathsf{g_n} = \mathsf{\sum_{l=0}^{n-1} (2l+1)} = \mathsf{n^2}\). (In other words, there are \(\mathsf{g_n} = \mathsf{n^2}\) states having the same energy \(\mathsf{E_n}\).)
Transitions between orbitals can occur if the electron absorbs or emits a photon. But since a quantum of light has intrinsic angular momentum (1 in units of \(\mathsf{\hbar}\)), conservation laws put a strict limit on which atomic transitions are possible. This leads to the famous electric dipole selection rules: \(\mathsf{\Delta l} = \pm \mathsf{1}\) and \(\mathsf{\Delta m} = \mathsf{0}, \pm \mathsf{1}\). Allowed transitions between the various states with \(\mathsf{n} = \mathsf{1}, \mathsf{2}, \mathsf{3}\) are shown in the following diagram.
Complete the program selection.cpp
so that it computes all possible
transitions of the form \(\mathsf{n_2} \to \mathsf{n_1}\) with
\(\mathsf{n_1} < \mathsf{n_2} \le \mathsf{20}\). Have the program
output the results in four columns indicating the initial and final
radial quantum numbers, the number of allowed pathways, the energy of
the emitted photon \(\mathsf{\Delta E} = \mathsf{E_2}
- \mathsf{E_1}\), and its wavelength \(\lambda = \mathsf{hc/\Delta
E}\) in nanometers. (Recall that \(\mathsf{hc}
= \mathsf{1240}\,\textsf{eV}\cdot\textsf{nm}\).)
$ make selection
g++ -o selection selection.cpp -O2 -ansi -pedantic -Wall -lm
$ ./selection | head -n5
2->1 3 10.2 121.569
3->1 3 12.0889 102.574
3->2 15 1.88889 656.471
4->1 3 12.75 97.2549
4->2 15 2.55 486.275
Modify selection.cpp
so that the spectral lines in the visible
spectrum, \(\mathsf{380}\,\textsf{nm} < \mathsf{\lambda}
< \mathsf{750}\,\textsf{nm}\), are marked with a lowercase v
.
$ make selection
g++ -o selection selection.cpp -O2 -ansi -pedantic -Wall -lm
$ ./selection | head -n5
2->1 3 10.2 121.569
3->1 3 12.0889 102.574
3->2v 15 1.88889 656.471
4->1 3 12.75 97.2549
4->2v 15 2.55 486.275
$ ./selection | grep v
3->2v 15 1.88889 656.471
4->2v 15 2.55 486.275
5->2v 15 2.856 434.174
6->2v 15 3.02222 410.294
7->2v 15 3.12245 397.124
8->2v 15 3.1875 389.02
9->2v 15 3.2321 383.652
Spin sectors
Quantum particles have a property called spin, which is an intrinsic angular momentum. The spin of a particle is restricted to be a multiple of \(\mathsf{\hbar/2}\). In units where \(\mathsf{\hbar} = \mathsf{1}\), the spin is either an integer or an odd multiple of one half. Electrons have spin \(\mathsf{s=1/2}\).
The total spin \(S\) of a collection of electrons is determined by the angular momentum summation rule \(\mathsf{\tfrac{1}{2}} \otimes \mathsf{S} = \mathsf{(S-\tfrac{1}{2})} \oplus \mathsf{(S + \tfrac{1}{2})}\). The possible spin sectors for two, three, and four electrons are shown below.
The final line shows the general result for \(\mathsf{N}\) electrons. The coefficient \(\mathsf{C_S^{(N)}}\) denotes the number of states in a given spin sector. One can show that the total number of states in the singlet (\(\mathsf{S=0}\)) sector is
and that the total number of states—counting the \((\mathsf{2S+1})\)-fold degeracy—is
The \(\mathsf{2^N}\) result is just the number of ways to orient \(\mathsf{N}\) electrons either spin-up or spin-down.
Read over the file moments.cpp
. It provides the skeleton of
a program that computes the coefficients \(\mathsf{C_S^{(N)}}\) and
displays them in a table. Determine how elements of the array
current
(indexed by the integer \(\mathsf{2S}\)) should be
incremented in terms of the values in last
. Accumulate the total
number of states into the variable num_states
. The output of your
program should be identical to the following.
$ make moments
g++ -o moments moments.cpp -O2 -ansi -pedantic -Wall -lm
$ ./moments
0 0.5 1 1.5 2 2.5 3 num
+-------------------------------------------------+-------
1| 1 | 2
2| 1 1 | 4
3| 2 1 | 8
4| 2 3 1 | 16
5| 5 4 1 | 32
6| 5 9 5 1 | 64
7| 14 14 6 | 128
8| 14 28 20 7 | 256
9| 42 48 27 | 512
10| 42 90 75 35 | 1024
11| 132 165 110 | 2048
12| 132 297 275 154 | 4096
13| 429 572 429 | 8192
14| 429 1001 1001 637 | 16384
15| 1430 2002 1638 | 32768
16| 1430 3432 3640 2548 | 65536
+-------------------------------------------------+-------
Write a function verify_singlet
that computes
\(\mathsf{C_0^{(N)}}\) explicitly. Check its result against
last[0]
for each even value of n
from 2
to Nmax
.