Case 889
The hues were averaged across the wrap
the_hues_were_averaged_across_the_wrap.eml - A palette tool picks an image's representative colour by averaging the hue of every pixel, and the average is exact over every pixel. What the mean of two hues near the seam of the colour wheel is, is computed below.
ok: true — round-trip fixpoint reached (python1 == python2)updated 2026-09-17
EML
eml# Self-authored for the EML case corpus (no external origin). A palette tool
# picks an image's representative colour by averaging the hue of every pixel,
# and the average is exact over every pixel. What the mean of two hues near the
# seam of the colour wheel is, is computed below.
#
# The pick is careful. It reads the real hue of every pixel, not a sample; it
# uses the engine's own arithmetic mean; it weights every pixel equally; and the
# intent is exactly 'the hue that represents the image'.
#
# Hue is an angle on a circle that wraps at 360, and two reds - 350 and 10 -
# average arithmetically to 180, which is cyan, the one hue farthest from both.
350 => hue_a_degrees
10 => hue_b_degrees
0 => circular_mean_degrees
hue_a_degrees + hue_b_degrees => hue_sum
int(hue_sum / 2) => arithmetic_mean_degrees
arithmetic_mean_degrees - circular_mean_degrees => degrees_from_the_true_mean
int(degrees_from_the_true_mean * 10000 / 180) => share_of_the_farthest_possible_error_per_myriad
"hue A : " + str(hue_a_degrees) + " degrees, a red" ^0
"hue B : " + str(hue_b_degrees) + " degrees, a red" ^0
"arithmetic mean : " + str(arithmetic_mean_degrees) + " degrees, cyan" ^0
"circular mean : " + str(circular_mean_degrees) + " degrees, red" ^0
"error of the arithmetic mean : " + str(degrees_from_the_true_mean) + " degrees" ^0
"of the farthest possible error : " + str(share_of_the_farthest_possible_error_per_myriad) + " per ten thousand" ^0
"" ^0
# ---- what the pick verified ----
"the representative-hue pick" ^0
" reads : the real hue of every pixel" ^0
" mean : the engine's own arithmetic mean" ^0
" weighting : every pixel equal" ^0
" intent : the hue that represents the image" ^0
" pixels omitted : 0" ^0
" verdict : MEAN HUE IS 180" ^0
"" ^0
" taking the exact arithmetic mean of every pixel's real hue" ^0
" is the part done right here, and it is why 180 is" ^0
" precisely the mean of the numbers" ^0
"" ^0
# ---- what hue is ----
"hue as a number" ^0
" what hue is : an angle around a wheel, 0 and 360 the same" ^0
" colour" ^0
" where 350 and 10 sit : 20 degrees apart, across the seam" ^0
" what the arithmetic mean does : treats 350 and 10 as 340" ^0
" apart and lands halfway, at 180" ^0
" what 180 is : the hue opposite both inputs" ^0
" so the representative hue of a red image : cyan" ^0
"" ^0
# ---- what the caller got ----
"the palette" ^0
" image : reds, 350 and 10" ^0
" representative hue chosen : " + str(arithmetic_mean_degrees) + ", cyan" ^0
" is the mean miscomputed : no; it is exact" ^0
" is a mean of angles the same as a mean of numbers : no;" ^0
" across the seam it is the opposite" ^0
"" ^0
# ---- null control ----
# The same hues averaged as directions (mean of the unit vectors, then the angle
# of the result), which has no seam.
180 => nc_mean_as_numbers
0 => nc_mean_as_directions
180 => nc_degrees_the_circular_mean_corrects
"null control - average the directions, not the numbers" ^0
" mean as numbers : " + str(nc_mean_as_numbers) + " degrees" ^0
" mean as directions : " + str(nc_mean_as_directions) + " degrees" ^0
" degrees the circular mean corrects : " + str(nc_degrees_the_circular_mean_corrects) ^0
" no pixel and no hue changed; the mean stopped crossing" ^0
" the seam" ^0
"" ^0
# ---- the rule ----
"what an arithmetic mean of hues guarantees" ^0
" the result is the mean of the hue numbers : exactly, every" ^0
" pixel, the engine's own mean" ^0
" the result is a hue between the inputs : not addressed;" ^0
" hue wraps at 360, and two reds at " + str(hue_a_degrees) + " and " + str(hue_b_degrees) + " average to " + str(arithmetic_mean_degrees) + "," ^0
" the hue opposite both - " + str(share_of_the_farthest_possible_error_per_myriad) + " per ten thousand of the worst" ^0
" possible error" ^0
"" ^0
"a circle has no smallest number, and a mean that assumes one puts the middle" ^0
"of two neighbours on the far side of the wheel; the same seam that broke" ^0
"longitude at 180 breaks hue at 360, for the same reason" ^0
"" ^0
"It takes the exact arithmetic mean of every pixel's real hue - 180 is the mean" ^0
"of the numbers. But hue is an angle, and " + str(hue_a_degrees) + " and " + str(hue_b_degrees) + " are two reds 20 degrees" ^0
"apart across the seam; their arithmetic mean is " + str(arithmetic_mean_degrees) + ", cyan, " + str(degrees_from_the_true_mean) + " degrees off, until" ^0
"the hues are averaged as directions." ^0Python (deterministic transpilation)
pythonhue_a_degrees = 350
hue_b_degrees = 10
circular_mean_degrees = 0
hue_sum = hue_a_degrees + hue_b_degrees
arithmetic_mean_degrees = int(hue_sum / 2)
degrees_from_the_true_mean = arithmetic_mean_degrees - circular_mean_degrees
share_of_the_farthest_possible_error_per_myriad = int(degrees_from_the_true_mean * 10000 / 180)
print("hue A : " + str(hue_a_degrees) + " degrees, a red")
print("hue B : " + str(hue_b_degrees) + " degrees, a red")
print("arithmetic mean : " + str(arithmetic_mean_degrees) + " degrees, cyan")
print("circular mean : " + str(circular_mean_degrees) + " degrees, red")
print("error of the arithmetic mean : " + str(degrees_from_the_true_mean) + " degrees")
print("of the farthest possible error : " + str(share_of_the_farthest_possible_error_per_myriad) + " per ten thousand")
print("")
print("the representative-hue pick")
print(" reads : the real hue of every pixel")
print(" mean : the engine's own arithmetic mean")
print(" weighting : every pixel equal")
print(" intent : the hue that represents the image")
print(" pixels omitted : 0")
print(" verdict : MEAN HUE IS 180")
print("")
print(" taking the exact arithmetic mean of every pixel's real hue")
print(" is the part done right here, and it is why 180 is")
print(" precisely the mean of the numbers")
print("")
print("hue as a number")
print(" what hue is : an angle around a wheel, 0 and 360 the same")
print(" colour")
print(" where 350 and 10 sit : 20 degrees apart, across the seam")
print(" what the arithmetic mean does : treats 350 and 10 as 340")
print(" apart and lands halfway, at 180")
print(" what 180 is : the hue opposite both inputs")
print(" so the representative hue of a red image : cyan")
print("")
print("the palette")
print(" image : reds, 350 and 10")
print(" representative hue chosen : " + str(arithmetic_mean_degrees) + ", cyan")
print(" is the mean miscomputed : no; it is exact")
print(" is a mean of angles the same as a mean of numbers : no;")
print(" across the seam it is the opposite")
print("")
nc_mean_as_numbers = 180
nc_mean_as_directions = 0
nc_degrees_the_circular_mean_corrects = 180
print("null control - average the directions, not the numbers")
print(" mean as numbers : " + str(nc_mean_as_numbers) + " degrees")
print(" mean as directions : " + str(nc_mean_as_directions) + " degrees")
print(" degrees the circular mean corrects : " + str(nc_degrees_the_circular_mean_corrects))
print(" no pixel and no hue changed; the mean stopped crossing")
print(" the seam")
print("")
print("what an arithmetic mean of hues guarantees")
print(" the result is the mean of the hue numbers : exactly, every")
print(" pixel, the engine's own mean")
print(" the result is a hue between the inputs : not addressed;")
print(" hue wraps at 360, and two reds at " + str(hue_a_degrees) + " and " + str(hue_b_degrees) + " average to " + str(arithmetic_mean_degrees) + ",")
print(" the hue opposite both - " + str(share_of_the_farthest_possible_error_per_myriad) + " per ten thousand of the worst")
print(" possible error")
print("")
print("a circle has no smallest number, and a mean that assumes one puts the middle")
print("of two neighbours on the far side of the wheel; the same seam that broke")
print("longitude at 180 breaks hue at 360, for the same reason")
print("")
print("It takes the exact arithmetic mean of every pixel's real hue - 180 is the mean")
print("of the numbers. But hue is an angle, and " + str(hue_a_degrees) + " and " + str(hue_b_degrees) + " are two reds 20 degrees")
print("apart across the seam; their arithmetic mean is " + str(arithmetic_mean_degrees) + ", cyan, " + str(degrees_from_the_true_mean) + " degrees off, until")
print("the hues are averaged as directions.")stdout (executed)
texthue A : 350 degrees, a red
hue B : 10 degrees, a red
arithmetic mean : 180 degrees, cyan
circular mean : 0 degrees, red
error of the arithmetic mean : 180 degrees
of the farthest possible error : 10000 per ten thousand
the representative-hue pick
reads : the real hue of every pixel
mean : the engine's own arithmetic mean
weighting : every pixel equal
intent : the hue that represents the image
pixels omitted : 0
verdict : MEAN HUE IS 180
taking the exact arithmetic mean of every pixel's real hue
is the part done right here, and it is why 180 is
precisely the mean of the numbers
hue as a number
what hue is : an angle around a wheel, 0 and 360 the same
colour
where 350 and 10 sit : 20 degrees apart, across the seam
what the arithmetic mean does : treats 350 and 10 as 340
apart and lands halfway, at 180
what 180 is : the hue opposite both inputs
so the representative hue of a red image : cyan
the palette
image : reds, 350 and 10
representative hue chosen : 180, cyan
is the mean miscomputed : no; it is exact
is a mean of angles the same as a mean of numbers : no;
across the seam it is the opposite
null control - average the directions, not the numbers
mean as numbers : 180 degrees
mean as directions : 0 degrees
degrees the circular mean corrects : 180
no pixel and no hue changed; the mean stopped crossing
the seam
what an arithmetic mean of hues guarantees
the result is the mean of the hue numbers : exactly, every
pixel, the engine's own mean
the result is a hue between the inputs : not addressed;
hue wraps at 360, and two reds at 350 and 10 average to 180,
the hue opposite both - 10000 per ten thousand of the worst
possible error
a circle has no smallest number, and a mean that assumes one puts the middle
of two neighbours on the far side of the wheel; the same seam that broke
longitude at 180 breaks hue at 360, for the same reason
It takes the exact arithmetic mean of every pixel's real hue - 180 is the mean
of the numbers. But hue is an angle, and 350 and 10 are two reds 20 degrees
apart across the seam; their arithmetic mean is 180, cyan, 180 degrees off, until
the hues are averaged as directions.Trace event types
eml:run:starteml:assigneml:outputeml:run:done