Starting with section A||B the primary tree is grown in a depth first manner and each node can have up to 16 children each of which is generated by a different function based upon Φ and φ. The tree is constructed using a template where each row is composed of 16 bits whose states determine whether the function that corresponds with each index is applied to a given node whose depth matches the row number in the template. The template is used to limit the number of possible children and keep the tree to a reasonable size. The tree is stored as it's created in a mysql database using a nested set representation so that searches are fast. A and B are stored as strings and only evaluated when determining their frequency or assigning them a color and not when the tree is constructed. This makes it possible to determine whether two endpoints are equal and also whether an endpoint is rational. For example, Φ (1/2 + 1/2√5) and its inverse, φ (-1/2 + 1/2√5) are represented as 1:1:1:2 and -1:2:1:2, respectively. Note that since the √5 is implicit any endpoint where the 3rd term equals zero is rational. The endpoint representing an octave would simply be represented as 2:1:0:1.

If the endpoints of a section are considered in relation to each other and also with respect to zero we can identify three lengths. (B − A, A − 0, B − 0) which can be multiplied by Φ and φ, This results in the following 16 children.

  • A || A ± (B−A)×Φ
  • A || A ± (B−A)×φ
  • B || B ± (B−A)×Φ
  • B || B ± (B−A)×φ
  • A || A ± (A−0)×Φ
  • A || A ± (A−0)×φ
  • B || B ± (B−0)×Φ
  • B || B ± (B−0)×φ

  • Note that when the starting_section A||B = A||A×Φ, the following children are duplicated and so 13 and not 16 unique children are produced.
    B || B + (B−A)×Φ ≡ B || B + (B−0)×φ
    B || B − (B−A)×Φ ≡ B || B − (B−0)×φ
    A || A + (A−0)×φ ≡ A||B (clone of parent)

    Generally speaking, nodes can have identical values for A||B but have different parents. This type of potential cycle is ignored by the use of a tree which greatly simplifies searches. It is handled, instead, by leaving it to the user to manually choose between different cycles. All nodes that share the same pick coordinates are represented in the picked window where they can be selected and then added to the composition or where the information displayed can be used in further searches.

    If the primary tree is built starting with section A||B =1||Φ then all the integers will be generated with just the use of three of the functions. To get the ratios of just intonation to show up we can simply start with A||B = 1/360||(1/360×Φ) or, since all just ratios are greater then 1, with A||B = 1/360×Φ11 || 1/360×Φ12. However, for all the just ratios to be generated requires that the primary tree be grown to great depth which still causes the database to become too large, so as a workaround an optional stopping case (juststop) was introduced. Whether a child should be grown using a given function is determined both by the template and, if juststop = true, by whether it remains possible to generate one of the just ratios that remains marked as unfound by following that branch. Though determining whether it is "possible" only looks one step ahead this was found to be sufficient to keep the database to a manageable size as well as generate all the just ratios in the given list.

    In order to create a composition the primarytree can be searched and the resulting subtrees displayed in a 3D graph where their nodes can be played and, if selected, transfered to a composition panel. Subtrees can be saved to the database and, like the primary tree, be the source of future subtrees. A composition can utilize more then one tree and any trees it uses are loaded when it is. However, it may not use nodes from more then one primary tree and can therefore not span databases. Each database can have only one primary tree. Most of the compositions here utilize the same database, where the primary tree was grown with juststop = true and a template where 0010100100000000 was repeated 498 times.
    In this database, the just ratio with the greatest depth (d = 376) is 1152/5 (9/5) and the maximum nodeid is 190057. Note that if juststop was set to false, then the full tree would have to be grown to a depth of 376 and the number of nodes in the resulting tree would have been prohibitively large.

    just ratios Database: template = 0010100100000000 x 498; juststop = true; starting_section = 1/360×Φ11 || 1/360×Φ12.
    Search: @d400%1:1:0:1 + @d400%16:15:0:1 + @d400%9:8:0:1 + ... etc.
    Searches the primary tree for all just ratios in the given list. The subtrees (one for each just ratio) were then combined after the search into one connected subtree.
    This could have also been accomplished with @d400%1:1:0:1 > @d400%16:15:0:1 > @d400%9:8:0:1 + ... etc.
    The white cones represent the justly intoned ratios.

    just ratios Same as the above graph, except uses a different mapping to display nodes and the cones representing just ratios are colored.

    14 functions
    Database: template = 1111111111111111 x 3; juststop = false; starting_section = 1||Φ
    Search: @d2$1 (all nodes from nodeid = 1 to a depth of 2). Only 14 nodes are visible since 3 are identical when the starting section is A || A×Φ. In this case A=1; and B=Φ. There are seventeen notes in the audio, one for the root node and one for each child node.

    16 functions
    Database: template = 1111111111111111 x 3; juststop = false; starting_section = 1||Φ.
    Search: @d2$1 (all nodes from nodeid = 1 to a depth of 2). All 16 nodes are visible since the starting_section A||B ≠ A || A×Φ.

    Database: template = 1111111111111111 x 4; juststop = false; starting_section = 1||Φ.
    Search: @$38453 > @$64667
    Both nodes have same A||B and can thus be thought of as representing a cycle. The picked window shows 4 nodes that have this A||B (lower right), the path between two of them is shown here.

    Same as the above graph, except as seperate tree rather then as overlay. Notice that the picked window only shows the two nodes searched for.

    Database: template = 1111111111111111 x 4; juststop = false; starting_section = 1||Φ.
    Search: @d4$1 (all nodes from nodeid=1 to a depth of 4).