The geothmetic meandian, $G_{MDN}$ is defined in this XKCD as
$$F(x_1, x_2, ..., x_n) = \left(\frac{x_1 +x_2+\cdots+x_n}{n}, \sqrt[n]{x_1 x_2 \cdots x_n}, x_{\frac{n+1}{2}} \right)$$
$$G_{MDN}(x_1, x_2, \ldots, x_n) = F(F(F(\ldots F(x_1, x_2, \ldots, x_n)\ldots)))$$
The comic also (correctly) claims that $G_{MDN}(1, 1, 2, 3, 5) \approx 2.089$
There are two convergence questions I'm interested in:
For what values of $(x_1, x_2, \ldots, x_n)$ does $G_{MDN}$ converge to a single number?
For what values of $(x_1, x_2, \ldots, x_n)$ does $G_{MDN}$ converge, but not to a single number?
I've written up Python 3 code so that you can test out numbers yourself by changing the values at the bottom of the code. If the code never seems to stop running, then $G_{MDN}$ does not converge for your input. (In these situations, you can set verbose=True to see what's happening.)
# assumes Python 3 because I assume that "/" always means float division
from typing import Iterable, Tuple, Union
from decimal import Decimal
import math
from functools import reduce # Required in Python 3
import operator
from https://stackoverflow.com/a/48648756
def prod(iterable):
return reduce(operator.mul, iterable, 1)
def geothmetic_meandian(nums: Iterable[float], verbose=False) -> Tuple[bool, Tuple[float, float, float]]:
def inner_geothmetic_meandian(nums: Iterable[float]) -> Tuple[float]:
arithmetic_mean = sum(nums)/len(nums)
geometric_mean = prod(nums)**(1 / len(nums))
sorted_nums = sorted(list(nums))
if len(nums) % 2 == 0:
# even number of numbers
higher_median_index = int(len(nums) / 2)
lower_median_index = higher_median_index - 1
median = (sorted_nums[higher_median_index] + sorted_nums[lower_median_index]) / 2
else:
# odd number of numbers
median = sorted_nums[int((len(nums) - 1) / 2)]
return (arithmetic_mean, geometric_mean, median)
last_ans = None
ans = inner_geothmetic_meandian(nums)
converged = True
while not (ans[0] == ans[1] == ans[2]):
if ans == last_ans:
converged = False
break
last_ans = ans
ans = inner_geothmetic_meandian(ans)
if verbose:
print(ans)
return converged, ans
if name == "main":
verbose = False
values = (1, 1, 3, 2, 5)
converged, results = geothmetic_meandian(values, verbose=verbose)
if converged:
print(f"The geothmetic meandian of {values} converged to: {results[0]}")
else:
print(f"The geothmetic meandian of {values} did not converge to a single value:\nArithmetic Mean: {results[0]}\nGeometric Mean: {results[1]}\nMedian: {results[2]}")
I've tested this code to verify that $G_{MDN}(1, 1, 2, 3, 5) \approx 2.089$.
I have also not found any inputs that cause the program to not converge at all.
However, I have found that $G_{MDN}(1, 2, 3, 4, 5) = (2.8993696858822964, 2.899369685882296, 2.8993696858822964)$ which would mean that $(1, 2, 3, 4, 5)$ is in the second convergence class, where it converged, just not all to the same number. But I'm worried that this result is due to a rounding error in Python itself. (I quickly tried and failed to use the Decimal class due to the nth root operation.)
Thus, my hunch is that all inputs converge to a single number, but I have not been able to prove this yet. It looks like an epsilon-delta proof.
using Statistics, StatsBase; F(x) = (mean(x), geomean(x), median(x)); Fn(x, n) = ∘(fill(F, n)...)(x); Fn(BigFloat[1,2,3,4,5], 100)shows convergence of the three values to the same number up to the 48th decimal after 100 iterations (using the default BigFloat precision of 256 bits). – sijo Mar 12 '21 at 13:18