Function Repository Resource:

SternBrocotTree

Source Notebook

Generate a complete binary search tree of positive fractions

Contributed by: Ian Ford (Wolfram Research)

ResourceFunction["SternBrocotTree"][n]

generates a complete binary search tree of the positive fractions down to level n.

Details and Options

The fractions on level d are those for which the total of the terms in its continued fraction representation is d+1.
In ResourceFunction["SternBrocotTree"][n], n can be any non-negative machine integer.
ResourceFunction["SternBrocotTree"] takes the same options as Tree.

Examples

Basic Examples (1) 

Generate a complete binary search tree of the positive fractions down to level 4:

In[1]:=
ResourceFunction["SternBrocotTree"][4]
Out[1]=

Applications (1) 

Approximate Pi as a rational number with a continued fraction representation with terms totalling 10:

In[2]:=
approximate[x_, n_] := search[ResourceFunction["SternBrocotTree"][n], x]
In[3]:=
search[tree_, x_] := Module[{data = TreeData[tree], left, right}, If[TreeLeafQ[tree], data, {left, right} = TreeChildren[tree]; Switch[NumericalOrder[data, x], 1, search[right, x], -1, search[left, x], 0, data]]]
In[4]:=
approximate[Pi, 9]
Out[4]=
In[5]:=
ContinuedFraction[22/7]
Out[5]=

Properties and Relations (7) 

FareySequence[n] gives the list of fractions in SternBrocotTree[n-1] between 0 and 1 with denominators not exceeding n:

In[6]:=
FareySequence[5]
Out[6]=
In[7]:=
ResourceFunction["SternBrocotTree"][4, TreeElementStyle -> TreeCases[Alternatives @@ %] -> LightRed]
Out[7]=

SternBrocotTree gives a sorted binary tree, also known as a search tree:

In[8]:=
inorder[q_, {q1_, q2_}] /; q1 < q < q2 := q
inorder[_, _] := "not sorted"
In[9]:=
ResourceFunction["SternBrocotTree"][3]
Out[9]=
In[10]:=
TreeFold[inorder, %]
Out[10]=

A fraction with a continued fraction representation {a1,,ak} has children with continued fraction representations {a1,,ak-1,2} and {a1,,ak+1}:

In[11]:=
NestTree[
 Replace[{as___, a_} :> SortBy[{{as, a - 1, 2}, {as, a + 1}}, FromContinuedFraction]], {1},
  3]
Out[11]=
In[12]:=
% === TreeMap[ContinuedFraction, ResourceFunction["SternBrocotTree"][3]]
Out[12]=

The fractions on level d are those for which the total of the terms in its continued fraction representation is d+1:

In[13]:=
TreeMap[Total@*ContinuedFraction, ResourceFunction["SternBrocotTree"][3]]
Out[13]=

The fractions given by SternBrocotTree can be obtained by successively taking the sums of the numerators and denominators of consecutive pairs of fractions starting with 0 and Infinity:

In[14]:=
ResourceFunction["SternBrocotTree"][3]
Out[14]=
In[15]:=
mediant[{q1_, Infinity}] := Apply[Divide, NumeratorDenominator[q1] + {1, 0}]
mediant[{q1_, q2_}] := Divide @@ Total[NumeratorDenominator[{q1, q2}]]
In[16]:=
split[{q1_, q2_}] := Splice[{mediant[{q1, q2}], q2}]
In[17]:=
{0, Infinity}
Out[17]=
In[18]:=
Prepend[split /@ Partition[%, 2, 1], 0]
Out[18]=
In[19]:=
Prepend[split /@ Partition[%, 2, 1], 0]
Out[19]=
In[20]:=
Prepend[split /@ Partition[%, 2, 1], 0]
Out[20]=
In[21]:=
Prepend[split /@ Partition[%, 2, 1], 0]
Out[21]=

The convergents of a positive fraction are a subset of its ancestors in the Stern-Brocot tree:

In[22]:=
Convergents[7/5]
Out[22]=
In[23]:=
ResourceFunction["SternBrocotTree"][4, TreeElementStyle -> TreeCases[Alternatives @@ %] -> LightRed]
Out[23]=
In[24]:=
ContinuedFraction[{1, 2, 3/2, 4/3, 7/5}]
Out[24]=

If , , , are the fractions at level d, then :

In[25]:=
ResourceFunction["SternBrocotTree"][4]
Out[25]=
In[26]:=
TreeLevel[ResourceFunction["SternBrocotTree"][4], {3} -> "Data"]
Out[26]=
In[27]:=
Total[1/Times @@@ NumeratorDenominator[%]]
Out[27]=

Define a function that permutes the positions on level d by reversing the corresponding binary integers with d digits:

In[28]:=
bitreverse[pos_] := IntegerDigits[IntegerReverse[FromDigits[pos - 1, 2], 2, Length[pos]],
    2, Length[pos]] + 1

Permute the fractions on each level of a Stern-Brocot tree:

In[29]:=
tree = ResourceFunction["SternBrocotTree"][3];
In[30]:=
TreeMap[First[TreeExtract[tree, {bitreverse[#]}, TreeData]] &, tree, All -> {"Position"}]
Out[30]=

The result is a Calkin-Wilf tree:

In[31]:=
% === ResourceFunction["CalkinWilfTree"][3]
Out[32]=

Version History

  • 1.0.0 – 06 January 2023

Source Metadata

Related Resources

License Information