Shell variable ~-

After writing the previous post, I poked around in the bash shell documentation and found a handy feature I’d never seen before, the shortcut ~-.

I frequently use the command cd - to return to the previous working directory, but didn’t know about ~- as a shotrcut for the shell variable $OLDPWD which contains the name of the previous working directory.

Here’s how I will be using this feature now that I know about it. Fairly often I work in two directories, and moving back and forth between them using cd -, and need to compare files in the two locations. If I have files in both directories with the same name, say notes.org, I can diff them by running

    diff notes.org ~-/notes.org

I was curious why I’d never run into ~- before. Maybe it’s a relatively recent bash feature? No, it’s been there since bash was released in 1989. The feature was part of C shell before that, though not part of Bourne shell.

Working with file extensions in bash scripts

I’ve never been good at shell scripting. I’d much rather write scripts in a general purpose language like Python. But occasionally a shell script can do something so simply that it’s worth writing a shell script.

Sometimes a shell scripting feature is terse and cryptic precisely because it solves a common problem succinctly. One example of this is working with file extensions.

For example, maybe you have a script that takes a source file name like foo.java and needs to do something with the class file foo.class. In my case, I had a script that takes a La TeX file name and needs to create the corresponding DVI and SVG file names.

Here’s a little script to create an SVG file from a LaTeX file.

    #!/bin/bash

    latex "$1"
    dvisvgm --no-fonts "${1%.tex}.dvi" -o "${1%.tex}.svg"

The pattern ${parameter%word} is a bash shell parameter expansion that removes the shortest match to the pattern word from the end of the expansion of parameter. So if $1 equals foo.tex, then

    ${1%.tex}

evaluates to

    foo

and so

${1%.tex}.dvi

and

${1%.tex}.svg

expand to foo.dvi and foo.svg.

You can get much fancier with shell parameter expansions if you’d like. See the documentation here.

Hyperbolic versions of latest posts

The post A curious trig identity contained the theorem that for real x and y,

|\sin(x + iy)| = |\sin x + \sin iy|

This theorem also holds when sine is replaced with hyperbolic sine.

The post Trig of inverse trig contained a table summarizing trig functions applied to inverse trig functions. You can make a very similar table for the hyperbolic counterparts.

\renewcommand{\arraystretch}{2.2} \begin{array}{c|c|c|c} & \sinh^{-1} & \cosh^{-1} & \tanh^{-1} \\ \hline \sinh & x & \sqrt{x^{2}-1} & \dfrac{x}{\sqrt{1-x^2}} \\ \hline \cosh & \sqrt{x^{2} + 1} & x & \dfrac{1}{\sqrt{1 - x^2}} \\ \hline \tanh & \dfrac{x}{\sqrt{x^{2}+1}} & \dfrac{\sqrt{x^{2}-1}}{x} & x \\ \end{array}

The following Python code doesn’t prove that the entries in the table are correct, but it likely would catch typos.

    from math import *

    def compare(x, y):
        print(abs(x - y) < 1e-12)

    for x in [2, 3]:
        compare(sinh(acosh(x)), sqrt(x**2 - 1))
        compare(cosh(asinh(x)), sqrt(x**2 + 1))
        compare(tanh(asinh(x)), x/sqrt(x**2 + 1))
        compare(tanh(acosh(x)), sqrt(x**2 - 1)/x)                
    for x in [0.1, -0.2]:
        compare(sinh(atanh(x)), x/sqrt(1 - x**2))
        compare(cosh(atanh(x)), 1/sqrt(1 - x**2)) 

Related post: Rule for converting trig identities into hyperbolic identities

Trig of inverse trig

I ran across an old article [1] that gave a sort of multiplication table for trig functions and inverse trig functions. Here’s my version of the table.

\renewcommand{\arraystretch}{2.2} \begin{array}{c|c|c|c} & \sin^{-1} & \cos^{-1} & \tan^{-1} \\ \hline \sin & x & \sqrt{1-x^{2}} & \dfrac{x}{\sqrt{1+x^2}} \\ \hline \cos & \sqrt{1-x^{2}} & x & \dfrac{1}{\sqrt{1 + x^2}} \\ \hline \tan & \dfrac{x}{\sqrt{1-x^{2}}} & \dfrac{\sqrt{1-x^{2}}}{x} & x \\ \end{array}

I made a few changes from the original. First, I used LaTeX, which didn’t exist when the article was written in 1957. Second, I only include sin, cos, and tan; the original also included csc, sec, and cot. Third, I reversed the labels of the rows and columns. Each cell represents a trig function applied to an inverse trig function.

The third point requires a little elaboration. The table represents function composition, not multiplication, but is expressed in the format of a multiplication table. For the composition fg(x) ), do you expect f to be on the side or top? It wouldn’t matter if the functions commuted under composition, but they don’t. I think it feels more conventional to put the outer function on the side; the author make the opposite choice.

The identities in the table are all easy to prove, so the results aren’t interesting so much as the arrangement. I’d never seen these identities arranged into a table before. The matrix of identities is not symmetric, but the 2 by 2 matrix in the upper left corner is because

sin(cos−1(x)) = cos(sin−1(x)).

The entries of the third row and third column are not symmetric, though they do have some similarities.

You can prove the identities in the sin, cos, and tan rows by focusing on the angles θ, φ, and ψ below respectively because θ = sin−1(x), φ = cos−1(x), and ψ = tan−1(x). This shows that the square roots in the table above all fall out of the Pythagorean theorem.

See the next post for the hyperbolic analog of the table above.

[1] G. A. Baker. Multiplication Tables for Trigonometric Operators. The American Mathematical Monthly, Vol. 64, No. 7 (Aug. – Sep., 1957), pp. 502–503.

A curious trig identity

Here is an identity that doesn’t look correct but it is. For real x and y,

|\sin(x + iy)| = |\sin x + \sin iy|

I found the identity in [1]. The author’s proof is short. First of all,

\begin{align*} \sin(x + iy) &= \sin x \cos iy + \cos x \sin iy \\ &= \sin x \cosh y + i \cos x \sinh y \end{align*}

Then

\begin{align*} |\sin(x + iy)|^2 &= \sin^2 x \cosh^2 y + \cos^2 x \sinh^2 y \\ &= \sin^2 x (1 + \sinh^2 y) + (1 -\sin^2x) \sinh^2 y \\ &= \sin^2 x + \sinh^2 y \\ &= |\sin x + i \sinh y|^2 \\ &= |\sin x + \sin iy|^2 \end{align*}

Taking square roots completes the proof.

Now note that the statement at the top assumed x and y are real. You can see that this assumption is necessary by, for example, setting x = 2 and yi.

Where does the proof use the assumption that x and y are real? Are there weaker assumptions on x and y that are sufficient?

 

[1] R. M. Robinson. A curious trigonometric identity. American Mathematical Monthly. Vol 64, No 2. (Feb. 1957). pp 83–85

Copy and paste law

I was doing some research today and ran into a couple instances where part of one law was copied and pasted verbatim into another law. I suppose this is not uncommon, but I’m not a lawyer, so I don’t have that much experience comparing laws. I do, however, consult for lawyers and have to look up laws from time to time.

Here’s an example from California Health and Safety Code § 1385.10 and the California Insurance Code § 10181.10.

The former says

The health care service plan shall obtain a formal determination from a qualified statistician that the data provided pursuant to this subdivision have been deidentified so that the data do not identify or do not provide a reasonable basis from which to identify an individual. If the statistician is unable to determine that the data has been deidentified, the health care service plan shall not provide the data that cannot be deidentified to the large group purchaser. The statistician shall document the formal determination in writing and shall, upon request, provide the protocol used for deidentification to the department.

The latter says the same thing, replacing “health care service plan” with “health insurer.”

The health insurer shall obtain a formal determination … health insurer shall not provide the data … for deidentification to the department.

I saved the former in a file cal1.txt and the latter in cal2.txt and verified that the files were the same, with a search and replace, using the following shell one-liner:

diff <(sed 's/care service plan/insurer/g' cal1.txt) cal2.txt

I ran into this because I often provide statistical determination of deidentification, though usually in the context of HIPAA rather than California safety or insurance codes.

Related posts

Giant Steps

John Coltrane’s song Giant Steps is known for its unusual and difficult chord changes. Although the chord progressions are complicated, there aren’t that many unique chords, only nine. And there is a simple pattern to the chords; the difficulty comes from the giant steps between the chords.

Giant Steps chords

If you wrap the chromatic scale around a circle like a clock, there is a three-fold symmetry. There is only one type of chord for each root, and the three notes not represented are evenly spaced. And the pattern of the chord types going around the circle is

minor 7th, dominant 7th, major 7th, skip
minor 7th, dominant 7th, major 7th, skip
minor 7th, dominant 7th, major 7th, skip

To be clear, this is not the order of the chords in Giant Steps. It’s the order of the sorted list of chords.

For more details see the video The simplest song that nobody can play.

Related posts

Tritone substitution

Big moves in roots can correspond to small moves in chords.

Imagine the 12 notes of a chromatic scale arranged around the hours of a clock: C at 12:00, C♯ at 1:00, D at 2:00, etc. The furthest apart two notes can be is 6 half steps, just as the furthest apart two times can be is 6 hours.

Musical clock

An interval of 6 half steps is called a tritone. That’s a common term in jazz. In classical music you’d likely say augmented fourth or diminished fifth. Same thing.

The largest possible movement in roots corresponds to almost the smallest possible movement between chords. Specifically, to go from a dominant seventh chord to another dominant seventh chord whose roots are a tritone apart only requires moving two notes of the chord a half step each.

For example, C and F♯ are a tritone apart, but a C7 chord and a F♯7 chord are very close together. To move from the former to the latter you only need to move two notes a half step.

Musical clock

Replacing a dominant seventh chord with one a tritone away is called a tritone substitution, or just tritone sub. It’s called this for two reasons. The root moves a tritone, but also the tritone inside the chord does not move. In the example above, the third and the seventh of the C7 chord become the seventh and third of the F♯7 chord. On the diagram, the dots at 4:00 and 10:00 don’t move.

Tritone substitutions are a common technique for making basic chord progressions more sophisticated. A common tritone sub is to replace the V of a ii-V-I chord progression, giving a nice chromatic progression in the bass line. For example, in the key of C, a D min – G7– C progression becomes D min – D♭7 – C.

Related posts

Bitcoin mining difficulty

The previous post looked at the Bitcoin network hash rate, currently around one zettahash per second, i.e. 1021 hashes per second. The difficulty of mining a Bitcoin block adjusts over time to keep the rate of block production relatively constant, around one block every 10 minutes. The plot below shows this in action.

Bitcoin hash rate, difficulty, and ratio of the two

Notice the difficulty graph is more quantized than the hash rate graph. This is because the difficulty changes every 2,016 blocks, or about every two weeks. The number 2016 was chosen to be the number of blocks that would be produced in two weeks if every block took exactly 10 minutes to create.

The ratio of the hash rate to difficulty is basically constant with noise. The noticeable dip in mid 2021 was due to China cracking down on Bitcoin mining. This caused the hash rate to drop suddenly, and it took a while for the difficulty level to be adjusted accordingly.

Mining difficulty

At the current difficulty level, how many hashes would it take to mine a Bitcoin block if there were no competition? How does this compare to the number of hashes the network computes during this time?

To answer these questions, we have to back up a bit. The current mining difficulty is around 1014, but what does that mean?

The original Bitcoin mining task was to produce a hash [1] with 32 leading zeros. On average, this would take 232 attempts. Mining difficulty is defined so that the original mining difficult was 1 and current mining difficulty is proportional to the expected number of hashes needed. So a difficulty of around 1014 means that the expected number of hashes is around

1014 × 232 = 4.3 × 1023.

At one zetahash per second, the number of hashes computed by the entire network over a 10 minute interval would be

1021 × 60 × 10 = 6 × 1023.

So the number of hashes computed by the entire network is only about 40% greater than what would be necessary to mine a block without competition.

Related posts

[1] The hash function used in Bitcoin’s proof of work is double SHA256, i.e. the Bitcoin hash of x is SHA256( SHA256( x ) ). So a single Bitcoin hash consists of two applications of the SHA256 hash function.

Exahash, Zettahash, Yottahash

When I first heard of cryptographic hash functions, they were called “one-way functions” and seemed like a mild curiosity. I had no idea that one day the world would compute a mind-boggling number of hashes every second.

Because Bitcoin mining requires computing hash functions to solve proof-of-work problems, the world currently computes around 1,000,000,000,000,000,000,000 hashes, one zettahash, per second. Other cryptocurrencies uses hash functions for proof-of-work as well, but they contribute a negligible amount of hashes per second compared to Bitcoin.

The hashrate varies over time because the difficulty of Bitcoin mining is continually adjusted to keep new blocks being produced at about one every ten minutes. As hardware has gotten faster, the difficulty level of mining has gotten higher. When the price of Bitcoin drops and mining becomes less profitable, the difficulty adjusts downward. There are other factors too, and hashrate is variable.

Bitcoin network hashes per second over time

The prefix giga- (109) wasn’t widely known until computer memory and storage entered the gigabyte range. Then the prefix tera- (1012) became familiar when disk drives entered terabyte territory. The prefixes for larger units such as peta- (1015) and exa- (1018) are still not widely known. The prefixes zetta- (1021) and  yotta- (1024) were adopted in 1991 and ronna- (1027) and quetta (1030) were adopted in 2022.

When the Bitcoin hashrate is relatively low, it’s in the range of hundreds of exahashes per second. At the time of writing the hashrate is 1.136 ZH/s, 1.136 × 1021 hashes per second. This puts the hashrate per day in the tens of yottahashes and the number of hashes per year in tens of ronnahashes.

Related posts