Saturday, January 9, 2016

Composing T and I operations


Almost four years ago to this day I submitted a simple assignment to a Transformational Theory course I was attending at college. The task was to compose different combinations of two of the so-called Twelve-Tone Operators (T and I) into just one operation. The Tn operation is transposition by the value of n, whereas the In operation is inversion followed by a transposition by the value of n. Note that this is all done within a given modulo universe; in music, we operate within mod 12.

Back to the task at hand: If you apply, for example, T4 and then I7 to a set of pitch-classes, is there an alternate way to reach the same state the set is in but with just one operation? Undoubtedly there is. The previous example can be more simply done with just one stroke of an I3 operation. But how can one confidently generate that singular operation given any two operators T and I in any order? The following set of rules is exactly how:


Tm · Tn = Tm+n
Im · Tn = Im+n
Tm · In = In-m
Im · In = Tn-m

NB All resulting values from the above operations on n and m must be mod 12, e.g. I9 · I1 = T-8 mod12 = T4

My assignment was to generate all possible combinations, which results in a 24x24 sized matrix. At the time I wasn't quite the computer wizard I am now, so I painstakingly plugged in more or less each value into an Excel file. This was slow and also harboured the ominous risk of inputting an inaccuracy by mistake. It also wasn't very flexible in the event that I want to compose T and I operators in a universe of a different size (as unlikely as that may be); I'd have to rewrite a ton of it!

Looking back now on the assignment from the perspective of a programmer made me rethink how I would've done it at the time. Any programmer knows that solving repetitive tasks and programming are happily married. Below I complete the assignment with some C# code. The (admittedly crude in format, but complete) output follows it. 


namespace TransformationalTheory.Assignment1 {
    class Program {
        // Music is in modulo 12
        public const int ModUniverse = 12;
        // Two twelve-tone operators: T and I
        public const int NumTTOperators = 2;
        // Set dimensions of the matrix based on the above values
        public const int Rows = ModUniverse * NumTTOperators;
        public const int Columns = Rows;
        public const int Halfway = Rows / 2;

        public enum Operator {
            T, I
        }

        static void Main(string[] args) {
            // Create and set the matrix
            string[,] matrix = new string[Rows, Columns];

            for (int m = 0; m < Rows; m++) {
                for (int n = 0; n < Columns; n++) {
                    if (m < Halfway) {
                        if (n < Halfway) {
                            matrix[m, n] = TmTn(m, n);
                        } else {
                            matrix[m, n] = TmIn(m, n);
                        }
                    } else {
                        if (n < Halfway) {
                            matrix[m, n] = ImTn(m, n);
                        } else {
                            matrix[m, n] = ImIn(m, n);
                        }
                    }
                }
            }

            // Write to a file
            using (System.IO.StreamWriter file =
                    new System.IO.StreamWriter(@"C:\Users\Nick\Desktop\Assignment1.html")) {
                file.WriteLine("<table>");
                for (int m = 0; m < Rows; m++) {
                    file.Write("<tr>");
                    for (int n = 0; n < Columns; n++) {
                        file.Write("<td>" + matrix[m, n] + "</td>");
                    }
                    file.WriteLine("</tr>");
                }
                file.Write("</table>");
            }
        }

        public static string TmTn(int m, int n) {
            return Compose(Operator.T, AddMod(m, n));
        }

        public static string ImTn(int m, int n) {
            return Compose(Operator.I, AddMod(m, n));
        }

        public static string TmIn(int m, int n) {
            return Compose(Operator.I, SubtractMod(n, m));
        }

        public static string ImIn(int m, int n) {
            return Compose(Operator.T, SubtractMod(n, m));
        }

        public static string Compose(Operator a, int b) {
            return string.Format("{0}<sub>{1}</sub>", a, b);
        }

        public static int AddMod(int m, int n) {
            return (m + n) % ModUniverse;
        }

        public static int SubtractMod(int n, int m) {
            return ((n - m) + ModUniverse) % ModUniverse;
        }
    }
}


File output
To navigate the matrix, firstly take any one value from the leftmost column and secondly any one value from the top rowWhere they meet in the matrix is the value of their composition with respect to the aforementioned chosen order, e.g. T2 on row 3 (leftmost column) can be composed with I4 on column 17 (top row) to make I2 (which is therefore living in cell 3, 17). I've bolded these rows for clarity. NB that the matrix logic only works with these directions; if you choose to start with values from the rightmost column or bottom row, or pick the top row first then the leftmost column second, you'll likely end up with an incorrect composition.

You might also be wondering why it isn't possible to compose any operation with T0 in this matrix. T0 is the identity operation; i.e. T0 composed with x will always result in x. It's inclusion would therefore be quite trivial!

T0T1T2T3T4T5T6T7T8T9T10T11I0I1I2I3I4I5I6I7I8I9I10I11
T1T2T3T4T5T6T7T8T9T10T11T0I11I0I1I2I3I4I5I6I7I8I9I10
T2T3T4T5T6T7T8T9T10T11T0T1I10I11I0I1I2I3I4I5I6I7I8I9
T3T4T5T6T7T8T9T10T11T0T1T2I9I10I11I0I1I2I3I4I5I6I7I8
T4T5T6T7T8T9T10T11T0T1T2T3I8I9I10I11I0I1I2I3I4I5I6I7
T5T6T7T8T9T10T11T0T1T2T3T4I7I8I9I10I11I0I1I2I3I4I5I6
T6T7T8T9T10T11T0T1T2T3T4T5I6I7I8I9I10I11I0I1I2I3I4I5
T7T8T9T10T11T0T1T2T3T4T5T6I5I6I7I8I9I10I11I0I1I2I3I4
T8T9T10T11T0T1T2T3T4T5T6T7I4I5I6I7I8I9I10I11I0I1I2I3
T9T10T11T0T1T2T3T4T5T6T7T8I3I4I5I6I7I8I9I10I11I0I1I2
T10T11T0T1T2T3T4T5T6T7T8T9I2I3I4I5I6I7I8I9I10I11I0I1
T11T0T1T2T3T4T5T6T7T8T9T10I1I2I3I4I5I6I7I8I9I10I11I0
I0I1I2I3I4I5I6I7I8I9I10I11T0T1T2T3T4T5T6T7T8T9T10T11
I1I2I3I4I5I6I7I8I9I10I11I0T11T0T1T2T3T4T5T6T7T8T9T10
I2I3I4I5I6I7I8I9I10I11I0I1T10T11T0T1T2T3T4T5T6T7T8T9
I3I4I5I6I7I8I9I10I11I0I1I2T9T10T11T0T1T2T3T4T5T6T7T8
I4I5I6I7I8I9I10I11I0I1I2I3T8T9T10T11T0T1T2T3T4T5T6T7
I5I6I7I8I9I10I11I0I1I2I3I4T7T8T9T10T11T0T1T2T3T4T5T6
I6I7I8I9I10I11I0I1I2I3I4I5T6T7T8T9T10T11T0T1T2T3T4T5
I7I8I9I10I11I0I1I2I3I4I5I6T5T6T7T8T9T10T11T0T1T2T3T4
I8I9I10I11I0I1I2I3I4I5I6I7T4T5T6T7T8T9T10T11T0T1T2T3
I9I10I11I0I1I2I3I4I5I6I7I8T3T4T5T6T7T8T9T10T11T0T1T2
I10I11I0I1I2I3I4I5I6I7I8I9T2T3T4T5T6T7T8T9T10T11T0T1
I11I0I1I2I3I4I5I6I7I8I9I10T1T2T3T4T5T6T7T8T9T10T11T0

No comments:

Post a Comment