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")) {
                for (int m = 0; m < Rows; m++) {
                    for (int n = 0; n < Columns; n++) {
                        file.Write("<td>" + matrix[m, n] + "</td>");

        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!


No comments:

Post a Comment