NAME
Math::PlanePath::FractionsTree  fractions by tree
SYNOPSIS
use Math::PlanePath::FractionsTree;
my $path = Math::PlanePath::FractionsTree>new (tree_type => 'Kepler');
my ($x, $y) = $path>n_to_xy (123);
DESCRIPTION
This path enumerates fractions X/Y in the range 0 < X/Y < 1 and in reduced form, ie. X and Y having no common factor, using a method by Johannes Kepler.
Fractions are traversed by rows of a binary tree which effectively represents a coprime pair X,Y by subtraction steps of a subtractiononly form of Euclid's greatest common divisor algorithm which would prove X,Y coprime. The steps left or right are encoded/decoded as an N value.
Kepler Tree
The default and only tree currently is by Kepler.
Johannes Kepler, "Harmonices Mundi", Book III. Excerpt of translation by Aiton, Duncan and Field at http://ndirty.cute.fi/~karttu/Kepler/a086592.htm
In principle similar bit reversal etc variations as in RationalsTree
would be possible.
N=1 1/2
 
N=2 to N=3 1/3 2/3
/ \ / \
N=4 to N=7 1/4 3/4 2/5 3/5
       
N=8 to N=15 1/5 4/5 3/7 4/7 2/7 5/7 3/8 5/8
A node descends as
X/Y
/ \
X/(X+Y) Y/(X+Y)
Kepler described the tree as starting at 1, ie. 1/1, which descends to two identical 1/2 and 1/2. For the code here a single copy starting from 1/2 is used.
Plotting the N values by X,Y is as follows. Since it's only fractions X/Y<1, ie. X<Y, all points are above the X=Y diagonal. The unused X,Y positions are where X and Y have a common factor. For example X=2,Y=6 have common factor 2 so is never reached.
12  1024 26 27 1025
11  512 48 28 22 34 35 23 29 49 513
10  256 20 21 257
9  128 24 18 19 25 129
8  64 14 15 65
7  32 12 10 11 13 33
6  16 17
5  8 6 7 9
4  4 5
3  2 3
2  1
1 
Y=0 

X=0 1 2 3 4 5 6 7 8 9 10 11
The X=1 vertical is the fractions 1/Y at the left end of each tree row, which is
Nstart=2^level
The diagonal X=Y1, fraction K/(K+1), is the second in each row, at N=Nstart+1. That's the maximum X/Y in each level.
The N values in the upper octant, ie. above the line Y=2*X, are even and those below that line are odd. This arises since X<Y so the left leg X/(X+Y) < 1/2 and the right leg Y/(X+Y) > 1/2. The left is an even N and the right an odd N.
FUNCTIONS
See "FUNCTIONS" in Math::PlanePath for behaviour common to all path classes.
$path = Math::PlanePath::FractionsTree>new ()

Create and return a new path object.
$n = $path>n_start()

Return 1, the first N in the path.
($n_lo, $n_hi) = $path>rect_to_n_range ($x1,$y1, $x2,$y2)

Return a range of N values which occur in a rectangle with corners at
$x1
,$y1
and$x2
,$y2
. The range is inclusive.For reference,
$n_hi
can be quite large because within each row there's only one new 1/Y fraction. So if X=1 is included then roughly$n_hi = 2**max(x,y)
.
Tree Methods
Each point has 2 children, so the path is a complete binary tree.
@n_children = $path>tree_n_children($n)

Return the two children of
$n
, or an empty list if$n < 1
(before the start of the path).This is simply
2*$n, 2*$n+1
. The children are$n
with an extra bit appended, either a 0bit or a 1bit. $num = $path>tree_n_num_children($n)

Return 2, since every node has two children, or return
undef
if$n<1
(before the start of the path). $n_parent = $path>tree_n_parent($n)

Return the parent node of
$n
, orundef
if$n <= 1
(the top of the tree).This is simply
floor($n/2)
, stripping the least significant bit from$n
(undoing whattree_n_children()
appends). $depth = $path>tree_n_to_depth($n)

Return the depth of node
$n
, orundef
if there's no point$n
. The top of the tree at N=1 is depth=0, then its children depth=1, etc.The structure of the tree with 2 nodes per point means the depth is simply floor(log2(N)), so for example N=4 through N=7 are all depth=2.
Tree Descriptive Methods
$num = $path>tree_num_children_minimum()
$num = $path>tree_num_children_maximum()

Return 2 since every node has 2 children, making that both the minimum and maximum.
$bool = $path>tree_any_leaf()

Return false, since there are no leaf nodes in the tree.
OEIS
The trees are in Sloane's Online Encyclopedia of Integer Sequences in the following forms
http://oeis.org/A020651 (etc)
tree_type=Kepler
A020651 X numerator (RationalsTree AYT denominators)
A086592 Y denominators
A086593 X+Y sum, and every second denominator
A020650 YX difference (RationalsTree AYT numerators)
The tree descends as X/(X+Y) and Y/(X+Y) so the denominators are two copies of X+Y time after the initial 1/2. A086593 is every second, starting at 2, eliminating the duplication. This is also the sum X+Y, from value 3 onwards, as can be seen by thinking of writing a node as the X+Y which would be the denominators it descends to.
SEE ALSO
Math::PlanePath, Math::PlanePath::RationalsTree, Math::PlanePath::CoprimeColumns, Math::PlanePath::PythagoreanTree
Math::NumSeq::SternDiatomic, Math::ContinuedFraction
HOME PAGE
http://user42.tuxfamily.org/mathplanepath/index.html
LICENSE
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Kevin Ryde
This file is part of MathPlanePath.
MathPlanePath is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
MathPlanePath is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with MathPlanePath. If not, see <http://www.gnu.org/licenses/>.