A short comparison of Pythagorean Means: the arithmetic mean (\(\AM\)), the geometric mean (\(\GM\)), and the harmonic mean (\(\HM\)).
This is an experimental post for the mathjax-tooltips script to illustrate the possible benefits by including annotations for mathematical equations that appears on mouse hover.
Type | Value Property | Application | Example |
---|---|---|---|
Arithmetic mean | linear | average | statistics mean |
Geometric mean | multiplicative, exponential | growth | proportional growth |
Harmonic mean | reciprocal | rate, ratio | speed, density, resistance |
Type | First Value | Second Value | Mean | Note |
---|---|---|---|---|
Arithmetic mean | \(x\) | \(y\) | \(\displaystyle\frac{x+y}{2}\) | |
Geometric mean | \(e^x\) | \(e^y\) | \(\displaystyle(e^xe^y)^{\frac{1}{2}}\) | \(\displaystyle=\sqrt{e^xe^y}=e^{\frac{x+y}{2}}\) |
Harmonic mean | \(x^{-1}\) | \(y^{-1}\) | \(\displaystyle(\frac{x^{-1}+y^{-1}}{2})^{-1}\) | \(\displaystyle=\frac{2}{\frac{1}{x}+\frac{1}{y}}=\frac{2xy}{x+y}\) |
Type | General form | Note |
---|---|---|
Arithmetic mean | \(\displaystyle\frac{1}{n}\sum_{i=1}^nx_i\) | \(=\displaystyle\frac{x_1+x_2+\cdots+x_n}{n}\) |
Geometric mean | \(\displaystyle(\prod_{i=1}^nx_i)^{\frac{1}{n}}\) | \(=\displaystyle\sqrt[n]{x_1x_2\cdots x_n}\) |
Harmonic mean | \(\displaystyle\left(\frac{\displaystyle\sum_{i=1}^nx_i^{-1}}{n}\right)^{-1}\) | \(=\displaystyle\frac{n}{\displaystyle\sum_{i=1}^nx_i^{-1}}=\frac{n}{\frac{1}{x_1}+\frac{1}{x_2}+\cdots+\frac{1}{x_n}}\) |
Assuming all values are positive, the following relationship holds:
\[\min\le \HM\le \GM\le \AM\le\max\]Statistics mean:
Three people with monthly income: \(1000\), \(2000\), \(3000\)
The arithmetic mean is \(\frac{1000+2000+3000}{3}=\tip{am}{2000}\)
Proportional growth:
An orange tree yields \(\tip{initial}{100}\), \(180\), \(210\), \(300\) in each year within a 4 year time frame.
The growth factors are: \(\frac{180}{\tip{initial}{100}}=180\%\), \(\frac{210}{180}\approx116.67\%\), \(\frac{300}{210}\approx142.86\%\).
The arithmetic mean is \(\frac{180\%+116.67\%+142.86\%}{3}\approx\tip{am}{146.51\%}\)
Simulate an orange tree that grows \(\tip{am}{146.51\%}\) for 3 years:
Initial | \(\tip{initial}{100}\) |
\(1^{st}\) Year | \(\tip{initial}{100}\cdot\tip{am}{146.51\%}\approx147\) |
\(2^{nd}\) Year | \(\tip{initial}{100}\cdot(\tip{am}{146.51\%})^2\approx215\) |
\(3^{rd}\) Year | \(\tip{initial}{100}\cdot(\tip{am}{146.51\%})^3\approx314\) |
The result \(314\) has \(\vert\frac{314-300}{300}\vert=4.67\%\) overestimation.
The geometric mean is \(\sqrt[3]{180\%\cdot 116.66\%\cdot 142.86\%}\approx\tip{gm}{144.22\%}\)
Simulate an orange tree that grows \(\tip{gm}{144.22\%}\) for 3 years:
Initial | \(\tip{initial}{100}\) |
\(1^{st}\) Year | \(\tip{initial}{100}\cdot\tip{gm}{144.22\%}\approx144\) |
\(2^{nd}\) Year | \(\tip{initial}{100}\cdot(\tip{gm}{144.22\%})^2\approx208\) |
\(3^{rd}\) Year | \(\tip{initial}{100}\cdot(\tip{gm}{144.22\%})^3\approx300\) |
The result \(300\) accurately describes the final yield.
The intuition behind this is that the growth factors are multiplied together: \(180\%\cdot116.67\%\cdot142.86\%\approx300\%\), and the final yield is calculated as exponential growth \(f(\tip{time_elapsed}{t})=\tip{initial}{a}(\tip{growth_factor}{1+\tip{growth_rate}{r}})^\tip{time_elapsed}{t}\).
Your goal is to find \(x\) in \(\tip{initial}{100}\cdot(x)^3=\tip{initial}{100}\cdot(180\%\cdot116.67\%\cdot142.86\%)\), therefore \(x=\GM\) is the natural fit.
Speed:
\[\mathrm{Speed}\SpeedUnit=\frac{\mathrm{Distance}\DistanceUnit}{\mathrm{Time}\TimeUnit}\]Starting at home, you travel with \(60\SpeedUnit\) to a location and return with \(20\SpeedUnit\). We denote the travel distance as \(d\DistanceUnit\).
Assume \(d=120\DistanceUnit\), the total time spent is \(\frac{120\DistanceUnit}{60\SpeedUnit}+\frac{120\DistanceUnit}{20\SpeedUnit}=2\TimeUnit+6\TimeUnit=8\TimeUnit\).
The arithmetic mean is \(\frac{60+20}{2}=\tip{am}{40\SpeedUnit}\). However, this also overestimates the mean.
The overestimation of speed causes underestimation of time \(\frac{120\cdot2\DistanceUnit}{\tip{am}{40\SpeedUnit}}=6\TimeUnit\).
The harmonic mean is \((\frac{60^{-1}+20^{-1}}{2})^{-1}=\frac{2}{\frac{1}{60\SpeedUnit}+\frac{1}{20\SpeedUnit}}=\tip{hm}{30\SpeedUnit}\).
The estimation \(\frac{120\cdot2\DistanceUnit}{\tip{hm}{30\SpeedUnit}}=8\TimeUnit\) accurately describes the total time spent.
The intuition behind this is that the speeds are ratios, and the total time is calculated as \(t\TimeUnit=\frac{d\DistanceUnit}{s_1\SpeedUnit}+\frac{d\DistanceUnit}{s_2\SpeedUnit}\). The multiplicative inverse of speed can be interpreted as “slowness”.
Your goal is to find \(x\) in \(\frac{2d\DistanceUnit}{x\SpeedUnit}=\frac{d\DistanceUnit}{60\SpeedUnit}+\frac{d\DistanceUnit}{20\SpeedUnit}\), therefore \(x=\HM\) is the natural fit.
Side Note: If the problem is modified to traveling with two speeds given the same elapsed time. Then arithmetic mean is the correct method to use.
Density:
\[\mathrm{Density}\DensityUnit=\frac{\mathrm{Mass}\MassUnit}{\mathrm{Volume}\VolumeUnit}\]Assume we combine 2 objects with the same mass, and the volume will add up (does not hold in most cases). We can use \(x=\HM\) to find the combined density \(x\) in \(\frac{2m}{x}=\frac{m}{d_1}+\frac{m}{d_2}\).
Side Note: If the problem is modified to combining two objects with the same volume. Then arithmetic mean is the correct method to use.
Resistance:
To calculate the equivalent resistance of two resistors connect in parallel (Same voltage difference), we can use \(x=\HM\) to find the equivalent resistance \(\frac{2V}{x}=\frac{V}{x}+\frac{V}{x}=\frac{V}{R_1}+\frac{V}{R_2}\). The equivalent resistance \(2x\) indicates that if we replace the resistors with 2 new resistors with resistance \(x\), the resulting resistance will be equivalent.
Side Note: If the problem is modified to connect two resistors in serial. Then arithmetic mean is the correct method to use.
Using an example file, we’ll explain the meaning of each byte and how the MIDI file is constructed. After understanding the basics, we should be able to manually build a MIDI file with a simple HEX Editor or by writing a program.
However, not all topics and usages will be covered. Only the minimum information we need to complete this example project will be introduced.
This is the “music” that we are going to create:
The result is a .mid
file with its content written in hexadecimal notation:
4D 54 68 64 00 00 00 06 00 00 00 01 00 60 4D 54 72 6B 00 00 00 0C 00 90 3C 64 60 80 3C 64 00 FF 2F 00
Let’s break it down and explain each section in detail.
The first 14 bytes of the sample file is the header chunk.
Data(hex) | Meaning | |
---|---|---|
1. | 4D 54 68 64 | identifier, ascii chars ‘MThd’ |
2. | 00 00 00 06 | chunklen, 6 bytes follow |
3. | 00 00 | format = 0 |
4. | 00 01 | ntracks = 1 |
5. | 00 60 | tickdiv = 96 ppqn |
MThd
’.chunklen
represents the number of data bytes in this chunk.format
type set to 0
for single MTrk chunk.ntracks
must be 1
for format 0.tickdiv
is the number of divisions for one quarter note. 96
is commonly used. (ppqn = pulses per quarter note)Right after the header chunk is the track chunk, which is 20 bytes long in our example.
Data(hex) | Meaning |
---|---|
4D 54 72 6B | identifier, ascii chars ‘MTrk’ |
00 00 00 0C | chunklen, 12 bytes of data follow |
00 90 3C 64 | Note On event |
60 80 3C 64 | Note Off event |
00 FF 2F 00 | End of Track event |
identifier
and chunklen
respectively, same as those in a header track.delta-time/event
pairs, which are introduced below.chunklen
should be updated accordingly.Delta time/event pairs are used to represent MIDI events and the distance relative to its former event. The basic structure of the data pair is illustrated below:
Delta-time is the number of tickdiv
after the previous event. It’s specified using variable-length representation with 1 to 4 bytes. The most significant bit of each byte is occupied for determining whether that byte is the last one in the data sequence.
Some of the eligible numbers before and after carrying are shown in the table below:
Decimal | Binary | Hexadecimal |
---|---|---|
0 | 00000000 | 00 |
127 | 01111111 | 7F |
128 | 10000001 00000000 | 81 00 |
16383 | 11111111 01111111 | FF 7F |
16384 | 10000001 10000000 00000000 | 81 80 00 |
Note that only the last byte has a prefix of 0
, and the other bytes before it are all 1xxxxxxx
. Thus, a delta-time of 81 00
represents 128
in decimal instead of 33024.
More examples, as well as detailed explanations, can be found here.
Only three types of events are used in this sample. Other events including pitch bend, tempo, and instrument name are listed on the website here.
9n + note + velocity (3 bytes)
In our example: 90 3C 64
9
: for Note On0
: MIDI channel number 03C
: starting note is 3C (see note number chart below)64
: press velocity is 100 (0~127)8n + note + velocity (3 bytes)
In our example: 80 3C 64
8
: for Note Off0
: MIDI channel number 03C
: ending note key is 3C (range: 00~7F)64
: release velocity is 100 (0~127)In our example: FF 2F 00
Therefore, the data 00 90 3C 64
means “At delta-time 0 from the beginning of MIDI channel 0, press down middle C with velocity 100.” Similarly, 60 80 3C 64
means “At delta-time 96 from the previous event at MIDI channel 0, release middle C with velocity 100.”
This chart displays all note numbers corresponding to each key and octave. The middle C is 3C
in hex, which is especially easy to remember.
Note \ Octave | -2 | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|---|---|---|
C | 00 | 0C | 18 | 24 | 30 | 3C |
48 | 54 | 60 | 6C | 78 |
C# / Db | 01 | 0D | 19 | 25 | 31 | 3D | 49 | 55 | 61 | 6D | 79 |
D | 02 | 0E | 1A | 26 | 32 | 3E | 4A | 56 | 62 | 6E | 7A |
D# / Eb | 03 | 0F | 1B | 27 | 33 | 3F | 4B | 57 | 63 | 6F | 7B |
E | 04 | 10 | 1C | 28 | 34 | 40 | 4C | 58 | 64 | 70 | 7C |
F | 05 | 11 | 1D | 29 | 35 | 41 | 4D | 59 | 65 | 71 | 7D |
F# / Gb | 06 | 12 | 1E | 2A | 36 | 42 | 4E | 5A | 66 | 72 | 7E |
G | 07 | 13 | 1F | 2B | 37 | 43 | 4F | 5B | 67 | 73 | 7F |
G# / Ab | 08 | 14 | 20 | 2C | 38 | 44 | 50 | 5C | 68 | 74 | - |
A | 09 | 15 | 21 | 2D | 39 | 45 | 51 | 5D | 69 | 75 | - |
A# / Bb | 0A | 16 | 22 | 2E | 3A | 46 | 52 | 5E | 6A | 76 | - |
B | 0B | 17 | 23 | 2F | 3B | 47 | 53 | 5F | 6B | 77 | - |
The same chart in decimal notation can be found here.
Files with the extension .mid
can be read by various software and be viewed or edited in different notations. The following are two examples:
Our example project is converted into a quarter note on a standard five-line staff using MuseScore.
Notes can also be shown on a MIDI piano roll editor in FL Studio.
This tutorial is based on the information of MIDI Flies Specification from Somascape.
]]>This is a guest post written by @J1soon.
I haven’t seen someone writing about this algorithm on the internet and only see some extremely high-level concept of it on some lecture slides.
Let’s dive into its details and think about the unsolvable conditions.
📄 Source:
📜 Hightower, 1969, A solution to line-routing problems on the continuous plane, DAC 1969.
In a 2D map, we have a source and a target point. We want to find a path that connects those 2 points, but there are obstacles on the map.
Previously, Mikami & Tabuchi’s Algorithm can be applied to solve these problems, but it is restricted to grid maps and have a lot of computation overhead.
Hightower’s Algorithm is an enhanced version of Mikami & Tabuchi’s Algorithm, and can work on continuous 2D maps.
Let \(S\), \(T\) be the source and target point.
For \(S\) and \(T\) simultaneously, construct a vertical or horizontal escape line where \(S\), \(T\) is an object point.
When a new escape line is constructed, an escape point is added under one of the 2 conditions:
The escape points are found by moving a unit away from the object point, along the line. The process stops if an escape point is found, or meeting a previously created escape point. (The new escape point won’t cross an old escape point to avoid falling into an infinite loop)
When a new escape point is found, set that escape point to be the new object point.
If no escape point is found, that means there exists a previously created escape point on the line. Set the escape point to be one unit nearer the object point starting from the previously created escape point. If there are no such points, exit and report no route found.
Repeat until one of \(S\)’s escape line meets one of \(T\)’s escape line.
Photo Credit: Prof. David Pan, Lecture 18. Global Routing (II)
The algorithm does not use the same escape line more than once. This means that if the algorithm used an escape line to get into a box that had a very narrow opening, it could not get out again. – Hightower, 1969
If the unit is infinitely small, the algorithm won’t fail to find an existing path.
But since discretizing the 2D map is necessary for practical uses, we can construct counterexamples that illustrates that how can Hightower’s Algorithm fail to find an existing path.
A visualization of the counterexample mentioned in the conclusion of the original paper can be seen as:
The same structure should be used for both the source \(S\) and the target \(T\), while ensuring there exists a route between them. Since the Point-3 in the image blocks the only exit of the box and the unit size isn’t small enough for other escape lines to go past it, Hightower’s algorithm fails and cannot find an existing route in this map.
✏️ Author’s Note
This issue is a trade off between efficiency and accuracy. The unit size should be chosen depending on the size of the map and available computation resources.
Disclaimers: The views and opinions expressed in this website are those of my own and do not represent those of my employer.
]]>