Normal forms

From Xenharmonic Wiki
Jump to navigation Jump to search

Since a regular temperament can be represented by multiple equivalent val lists (aka mappings) or monzo lists (aka comma-bases), it can be helpful — e.g. when comparing or cataloguing temperaments — to choose a single one of these equivalent lists to use as its unique identifier. A set of rules that are consistently able to narrow the full set of equivalent lists down to a single list for each temperament may be called a normal form, and accordingly, a list which uniquely identifies a temperament in this way may be called a normal list.

Because several different normal forms have been developed, each temperament has several different normal lists: one for each form. These normal lists are not all necessarily different; sometimes some or all of them may be the same.

Hermite normal form

Hermite normal form, or HNF for short, is an important normal form that was defined for integer matrices in the mathematical field of linear algebra. An integer matrix is simply a 2D array of integers, and so we can easily think of lists of vals or commas as integer matrices and therefore leverage HNF in regular temperament theory.

HNF by itself is not used as a normal form for regular temperament theory. However, it is part of the definition of every normal form here, so it is important to have a basic understanding of it.

There are slightly different definitions of HNF in use, and if you are using a computer program to compute it, you should take care that the same normal monzo or val list is finally achieved. The definition used by the Wikipedia article on Hermite form, probably the most standard, works as follows.

An n by m integral matrix H is in HNF if when we define a function F such that F (i) = 0 if all of the entries in the i-th column of H are 0, and otherwise F (i) is equal to the row number of the first nonzero entry in the i-th column, checking up from the bottom, i.e. from the n-th row, we have

  1. If i > j, H[i, j] = 0 (H is upper triangular.)
  2. F (i) is a function of the column number i.
  3. F (i) = 0 if and only if all of the entries in the i-th column are 0.
  4. F is an increasing function of the column number i, and becomes strictly increasing after F (i) becomes positive.
  5. If k > F (i) > 0 then H[k, i] = 0; that is, F (i) is the row of the first nonzero entry in the i-th column, counting up from the bottom.
  6. If F (i) > 0 then H[F (i), i] > 0; that is, the first nonzero entry in the i-th column, counting up from the bottom, is positive.
  7. If F (i) > 0 and i < j then H[F (i), i] > H[F (i), j] ≥ 0; that is, the first nonzero entry in the i-th column, counting up from the bottom, is greater than any of the rest along that row, which however are all non-negative.

There is some redundancy in the statement of these conditions, but that does no harm.

For more information, diagrams, an alternative articulation of the same definition, and comparisons with related integer matrix forms, see: Canonical_form#HNF.

Normal val lists

First we will review the set of normal forms that are defined for val lists.

Canonical form

If A is a list of n vals, we may write it as an n×m matrix, where the rows of the matrix are the vals, and m = π (p), where p is the prime limit. To get the canonical form, we do the following:

  1. First, defactor it.
  2. Then, put it into HNF.
  3. Throw away all rows which consist of nothing but zeros, resulting in a k×m matrix.

For example, septimal meantone has the canonical form of [1 0 -4 -13], 0 1 4 10]], corresponding to generators of ~2/1 and ~3/1.

Positive generator form

Even though by using the HNF the canonical form ensures that the pivot (first nonzero entry) of each mapping row is a positive number, this does not necessarily mean that the corresponding generators are all positive in pitch. For example, the canonical form of porcupine is the matrix [1 2 3] 0 3 5]. The second column of this matrix tells us it takes 2 of the first generator and 3 of the second generator to reach its approximation of 3/1. But as we can tell from the first column of this matrix, it takes only 1 of the first generator and nothing else to reach its approximation of 2/1. Therefore, if we move by 2 of the first generator, we are already at this temperament's approximation of 4/1, and so if we still need to move by 3 of the second generator to reach its approximation of 3/1, then the second generator must be negative. Indeed, it is about 163 cents downward in pitch. Negative generators like this can be surprising and confusing, and so the positive generator form was developed to address this concern.

To obtain this form, we first need to know whether each generator is positive or negative in pitch. Many methods are available for finding this information, but the one which is the easiest (and therefore the one this form is defined as using) is to find the Frobenius generators of the temperament. To break this down, we find the Moore–Penrose pseudoinverse of the k×m matrix, A+, and multiply this from the left by the row vector of JIP, J0 = [1 log23 log25 … log2p].

[math]\displaystyle{ G_\text{F} = J_0 A^+ }[/math]

If the i-th entry in the result is negative, change the signs of every entry in the corresponding row of the mapping.

The "mapping" (though not the "map to lattice") listed on temperament pages of this wiki are in this form. The generators in canonical form of septimal meantone is positive already, so its positive generator form is the same as its canonical form, [1 0 -4 -13], 0 1 4 10]], corresponding to generators of ~2/1 and ~3/1. An example of positive generator form that is different from the canonical form is the porcupine temperament, elaborated below.

The canonical mapping for porcupine is

[math]\displaystyle{ \left[ \begin{array} {rrr} 1 & 2 & 3 \\ 0 & 3 & 5 \\ \end{array} \right] }[/math]

Its pseudoinverse is

[math]\displaystyle{ \left[ \begin{array} {rrr} \frac{34}{35} & -\frac{3}{5} \\ \frac{1}{7} & 0 \\ -\frac{3}{35} & \frac{1}{5} \\ \end{array} \right] }[/math]

Since we're in the 5-limit here, we want the 5-limit JIP:

[math]\displaystyle{ \left[ \begin{array} {rrr} log_2{2} & log_2{3} & log_2{5} \\ \end{array} \right] }[/math]

Multiplying those:

[math]\displaystyle{ \begin{array} {l} \left[ \begin{array} {rrr} log_2{2} & log_2{3} & log_2{5} \\ \end{array} \right] & × & \left[ \begin{array} {rrr} \frac{34}{35} & -\frac{3}{5} \\ \frac{1}{7} & 0 \\ -\frac{3}{35} & \frac{1}{5} \\ \end{array} \right] & = & \left[ \begin{array} {rrr} 0.998829 & -0.135614 \\ \end{array} \right] \end{array} }[/math]

Those results are in octaves. Multiplying by 1200 gives them in cents: 1198.5948 and -162.7368. So we can recognize these two values as porcupine's octave period and its neutral second generator. The concern here is that this mapping form results in the generator being a neutral second downward, i.e. it has a negative value when measured logarithmically such as in octaves or cents as seen here.

The solution is simply to change the signs of the corresponding row of the matrix, like so:

[math]\displaystyle{ \begin{array} {lllllllll} \left[ \begin{array} {rrr} 1 & 2 & 3 \\ 0 & 3 & 5 \\ \end{array} \right] & \begin{array} {rrr} +1198.5948 \\ \colorbox{pink}{-}162.7368 \\ \end{array} & → & \left[ \begin{array} {rrr} 1 & 2 & 3 \\ 0 & \colorbox{yellow}{-}3 & \colorbox{yellow}{-}5 \\ \end{array} \right] & \begin{array} {rrr} +1198.5948 \\ \colorbox{yellow}{+}162.7368 \\ \end{array} \end{array} }[/math]

And the cents value of the generator flips accordingly.

Equave-reduced generator form

The equave-reduced generator form is similar to the positive generator form, but the matrix is further normalized such that each generator is equave-reduced, where the equave can be found as the formal prime represented by the first column of the matrix (which is usually the octave). For more information, see: Octave reduction#Generalization

Consider the case of septimal meantone. As we know, its positive generator form is [1 0 -4 -13] 0 1 4 10] which corresponds to generators of ~2/1 and ~3/1. In this case, as is typical, the formal prime represented by the first column of the matrix is 2, and so the equave is the octave. Therefore, all generators must be octave-reduced. But our second generator is ~3/1, which is not octave-reduced. We must alter the mapping in such a way that this row represents a generator of ~3/2 instead. We can do that here by adding the second row of the mapping to the first: [1 1 0 -3] 0 1 4 10]. So that is septimal meantone's equave-reduced generator form, corresponding to generators of ~2/1 and ~3/2.

For a general discussion of how to manipulate the sizes of generators in this way, see generator size manipulation.

Minimal generator form

The minimal generator form (or mingen form) is a form specific to rank-2 temperaments, where the matrix is normalized such that the generator is positive and no greater than half the period.

Graham Breed's temperament finder uses this form for all rank-2 temperaments. Septimal meantone in minimal generator form is [1 2 4 7], 0 -1 -4 -10]], corresponding to generators of ~2/1 and ~4/3.

For more information, see mingen.

Normal interval lists

A similar set of normal forms are defined for interval lists.

Canonical form

Given a list of p-limit intervals, we can convert it to a canonical list by the following procedure:

  1. Convert the list to a list of monzos
  2. Reverse the order of the elements of the monzos
  3. Form a matrix whose rows are these reversed monzos
  4. Defactor and Hermite reduce this matrix to HNF
  5. Reverse (once again) the entries in each row of the HNF matrix, and use these re-reversed rows to form a new list of monzos
  6. Discard all of the all-zero monzos, corresponding to the unison 1/1
  7. Reverse the whole list (not the entries) of the remaining monzos
  8. Convert this list back to a list of p-limit rational numbers

The result is the canonical form of the interval list. The set of elements of the original list generates a finitely generated free abelian subgroup of the positive rationals under multiplication, and therefore of any p-limit group it lives inside. The normalized list contains a minimal set of ratios, in an ordering of nondecreasing prime limit which is parsimonious in its use of higher limits. For example, if we normalize [81/80, 126/125] we obtain [80/81, 57344/59049]. The first interval is 5-limit, which is as small as possible. The second is 7-limit, which must be the case because the group these two generate is 7-limit. However, it uses only 2, 3 and 7 in its prime factorization, parsimoniously rejecting 5 as the next highest prime limit. Because regular temperaments, where the prime mappings are known but not the specific tuning of the generators, are fully characterized by their kernel, the group of intervals they map to the unison, they can also be characterized by the regular interval list of a set of generators (called commas or unison vectors) for the kernel. The above normal interval list, for example, characterizes septimal meantone, defining the normal comma list of septimal meantone.

Note that the canonical form of the comma list requires the list to be defactored. For example, both [25/27, 35/36] and [25/27, 49/48] characterize Beep. But the latter is enfactored, so the former is Beep's canonical form.

Normal interval lists can also be used to characterize the just intonation subgroups on which subgroup temperaments are defined and using which subgroup scales may be constructed. On the pages chromatic pairs, subgroup temperaments and just intonation subgroups can be found many examples; the subgroup lists are given in a form where generators of the subgroup are separated by periods so as to flag the fact that the list defines a subgroup. An example would be the Barbados subgroup, 2.3.13/5.

Positive ratio form

Similar to the situation with mappings, even though by using the HNF the canonical form ensures that the first nonzero entry of each comma's prime count vector is a positive number, this does not necessarily mean that the corresponding commas are all positive in pitch.

For example, the canonical form of meantone's comma-basis is [4 -4 1]. HNF has ensured that the first number is positive. But the vector [4 -4 1 represents the ratio 80/81, which is less than unity; it is still the meantone comma, but it is the meantone comma downward in pitch.

Having negative commas like this can be surprising or confusing, and so the positive ratio form addresses this concern. To correct any negative comma, simply replace it with its reciprocal, by changing the signs on every number in its vector; meantone can be put into positive ratio form as [-4 4 -1].

The positive ratio form of septimal meantone is [81/80, 59049/57344]

Minimal ratio form

The minimal ratio form shows ratio-wise the simplest comma list sufficient to define the temperament, where the ratios are rated by the product of the numerator and the denominator, i.e. the Benedetti height.

This is the form shown in the "comma lists" of each temperament on this wiki.

Maple code

Below is Maple code for finding the normal interval and val list, given an interval list or a val list. Note that this code does not defactor, so it assumes your lists have already been defactored.

Code
log2 := proc(x) evalf(ln(x) / ln(2)) end:

# transpose of listlist w
transpos := proc(w)
    local u;
    u := Matrix(w);
    u := LinearAlgebra[Transpose](u);
    convert(u, listlist)
end:

# pseudoinverse of listlist w
pseudo := proc(w)
    local u;
    u := Matrix(w);
    u := LinearAlgebra[MatrixInverse](u, method='pseudo');
    convert(u, listlist)
end:

psu := proc(w) transpos(pseudo(w)) end:

# log2 of first n primes
pril := proc(n)
    local i, u;
    u := NULL;
    for i from 1 to n do
        u := u, log2(ithprime(i))
    od;
    [u]
end:

# reverse of list
revlist := proc(l)
    local i, v, e;
    e := nops(l);
    for i from 1 to e do
        v[i] := l[e - i + 1]
    od;
    convert(convert(v, array), list)
end:

orp := proc(w, p) padic[ordp](w, p) end:

# rank of p-limit of q
pim := proc(q)
    local r, i, p;
    r := 1;
    i := 0;
    while not (r = q) do
        i := i + 1;
        p := ithprime(i);
        r := r * p ^ orp(q, p)
    od;
    if i = 0 then RETURN(0) fi;
    i
end:

# prime limit of rational number q
plim := proc(q)
    ithprime(pim(q))
end:

# converts rational number q to monzo of length n
rat2monz := proc(q, n)
    local v, i;
    for i from 1 to n do
        v[i] := ordp(q, ithprime(i))
    od;
    convert(convert(v, array), list)
end:

# converts monzo to rational number
monz2rat := proc(m)
    local i, t;
    t := 1;
    for i from 1 to nops(m) do
        t := t * ithprime(i) ^ m[i]
    od;
    t
end:

# hermite normal form of listlist l
herm := proc(l)
    local M;
    M := Matrix(l);
    convert(convert(HermiteForm[Z](M), array), listlist)
end:

# normal interval list from list of intervals l
nori := proc(l)
    local i, p, u, v, w;
    p := 1;
    for i from 1 to nops(l) do
        p := max(p, plim(l[i]))
    od;
    u := [];
    for i from 1 to nops(l) do
        u := [op(u), revlist(rat2monz(l[i], p))]
    od;
    v := herm(u);
    for i from 1 to nops(l) do
        u := revlist(v[i]);
        u := monz2rat(u);
        w[i] := u
    od;
    u := [];
    for i from 1 to nops(l) do
        v := w[i];
        if v < 1 then v := 1 / v fi;
        if not v=1 then u := [op(u), v] fi
    od;
    revlist(u)
end:

norv := proc(l)
    # normal val list from list of vals l
    local u, v, w, i, n, a;
    u := herm(l);
    n := rnk(u);
    v := NULL:
    for i from 1 to n do
        v := v, u[i]
    od;
    v := [v];
    u := pseudo(v);
    w := pril(nops(l[1]));
    a := op(matmul(w, u));
    u := NULL;
    for i from 1 to n do
        if a[i] < 0 then u := u, -v[i] fi;
        if a[i] >= 0 then u := u, v[i] fi
    od;
    [u]
end: