Using the function Gradual(Omap())

The function of Mapped Opposite enables the musician to choose among sets of series sensitive to their permutational properties (Cf. J.Palfi et al., 2008, Le dodécaphonisme comme outil d’analyse – in French).

To say things quickly, the mapped opposite uses what group theory calls an invariant, in order to have a suite transposed permutationnally. If you do the gradual suite of the opposite of any series S, mapped onto S, you get a suite G that is the same for each transposition of S. Now if you unmap each element of G from S+1 you get a transposed suite Q+1, and you can get Q+2 by unmapping G from S+2. Capisce?

(the command lines below can be sent from the Series tab)

print Csgrouper::Gradual(Csgrouper::Omap(“32014″),’a’)
   12340 23401 34012 40123
# The gradual suite made upon the mapped opposite of 32014.

print Csgrouper::Gradual(Csgrouper::Omap(Csgrouper::Transpose("32014","00000",1,5,'')),'a')
   12340 23401 34012 40123 
# We see that however transposed, the result is the same.

print Csgrouper::Gradomap("32014",'a')
   20143 01432 14320 43201 
# This is the gradual suite made of the mapped opposite, where each row has been unmapped from 32014.

print Csgrouper::Gradomap(Csgrouper::Transpose("32014","00000",1,5,''),'a')
   31204 12043 20431 04312
# Here each row from the previous suite is transposed, permutationally.

The only thing to care about is that these gradual suites – as they are produced by Gradomap() in the Csgrouper sequence creation process (and not as in here with the command line) – will contain an additionnal row in the beggining, which is  the original row S itself, or S+n if transposed. This allows us to keep in touch with our starting point musically, and it is not unsound permutationally, since S is the last element in the cyclic suite (we could have made it last too). The difference, with normal, not unmapped, Gradual suites – which contain one row less – comes from the fact that in normal Gradual suites, as in the above example, Csgrouper does not add the last element which is always equivalent to Natural(S) i.e. the chromatic scale (for this has rarely a nice effect in music).


In the preceding example Gradual(Omap(S)) is the original function without unmapping, unlike Gradomap(S) which proceeds to the unmapping. However, in Csgrouper’s Sequence Details tab, where one can choose functions by menu, the menu item Gradual(Omap(S)) implies automatic unmapping and in fact calls internally Gradomap(). This is due to the fact that musically speaking, Gradomap() is much more interesting as it yields transposed suites. If a user wants to create a bare Gradual(Omap(S)) as above, she will have to do it through command line from the Series tab and then paste the result as a Suite() into the chosen Sequence window. So all this naming is fallacious, and I should have named the menu item Unmap(Gradual(Omap(A)),A) and Gradomap() Ugradomap() or something. 


Non permutational serialism (3): What about Schoenberg ?

According to Milton Babbitt [1], Schoenberg’s twelve tone musical system is permutational. However Babbitt’s maths are so hard to understand for me that I seem condemned to believe this claim because of my ignorance. Even in religion this wouldn’t be the right way to believe, so we are going to ask the question about the permutational nature of Schoenberg’s musical theory in a way that makes sense to us (non mathematicians).

The basic schoenbergian material is quite narrow, it is made of 4 expressions, or instances, of the same twelve tone row. If we call S one series of notes chosen among the 479001600 rows made of 12 distinct digits, then Schoenberg admits also the same row read from right to left and he calls this instance of the row its retrograde form, or sometimes also its recurrence. We are going to choose the term ‘reverse’ to name this instance of S, and choose the letter R to design it. The third form used by Schoenberg was called a reversal but consisted in taking the inversion of each interval in the row, so we are going to call it ‘inverse’ and abbreviate it ‘I’. The last traditional form in twelve tone music was sometimes called recurrence of the reversal, but it will be clearer to describe it reverse of the inverse, according to the previous naming since it is only the inverse read from right to left, and we will call it ‘opposite’ or simply ‘O’.

Let’s take a random example:

S : 87925361A04B
R : B40A16352978
I : 453A796B2081
O : 1802B697A354

We can verify that R is S read from right to left, as well as O for I. And this reverse form is indubitably permutational because it is obtained easily  by composing S (or I) with the last element of the well ordered permutational set which is BA9876543210. [2]

Now if we look at I, things are not so clear, we can obtain it by taking the inverse value of each note, for example if the first note is 8 (G#) then we take 8 steps down starting at 0 (C) and that is 4 (E), etc. for each other note. But this way of doing is not permutational, it’s arithmetic. In fact for each possible S, there is one precise composed row that will get I, and many different rows will get their inverse by being composed with the same row so there is a whole subset of the total group of permutations that play for I the role BA9876543210 was playing for R .

This set of 10395  inverting rows in base 12 separates the total set of permutations in subsets of 46080 rows. All the 10395 share a common type [3], which is the type of their most remarkable – and last – element : 0BA987654321. [4] We see that having 0 on its index has the result of setting the axis on this note. I don’t know if Schoenberg always chose that note as axis, but if he did then it was an undue priviledge; in Csgrouper one can choose any index as axis by setting the ‘x’ field.

Which further permutational means can make us select the correct row to compose with S in order to obtain I, that’s what I’d like to know; it is perhaps also something Babbitt had explained to the graduates, who knows?


[1] Milton Babbitt, 2003, Collected Essays, Princeton University Press.

[2] See the definition of a composition of rows in the ‘code’ section.

[3] See the definition of the type of a row in the ‘code’ section.

[4] There are for instance 46080 rows whose Inverse can be produced by composing them with  0BA987654321, and 10394 other inverting rows like 0BA987654321 with their 0 in indexical position. If we agree to have each note in turn in indexical position and produce this way 12 different inverses for each row, we obtain a set of 124740  inverting rows, among 479 millions.

Update 130607:

Addition and correction

We don’t have to check 479 millions permutations to catch those values; as many results about permutations they come from induction:

a)- note that in many bases (B+1) many inverses are produced by the inverting row 0B..1 and call this row T[B+1];
b)- check the small bases first to see how many inverses are produced by T[B] and call this number N[B];
c)- remark that B!/N[B] = the total number of inverting rows, call it R[B];
d)- for the same value of R, bases go by pairs (even then odd), the other mentionned values always differ in a higher base;
e)- observe that B*R[B] = R[B+1] but only when B is odd;
f)- so  N[B+1] = (B+1)!/(B*R[B]) =  (B+1)!/(B*R[B-1]); when B is odd;
g)- and R[B] = (B-1)*R[B-1] = (B-1)*R[B-2]; when B is even;

For example:

e) 3*1 = 3 = R[4]; 
f) 4!/3 = 8 = N[4]; 
e) 5*3 = 15 = R[6]; 
f) 6!/15 = 48 = N[6]; 
e) 7*15 = 105 = R[8];
f) 8!/105 = 384 = N[8];
e) 9*105 = 945 = R[10];
f) 10!/945 = 3840 = N[10];
e) 11*945 = 10395 = R[12]; 
f) 12!/10395 = 46080 = N[12];


Non permutational serialism (2): Static and dynamic intervals

Though it is permuting notes, the function Train() is not ‘permutational’ because it does not compose permutations but only iterate through the notes of some series in order to modify the corresponding values in another one. This could certainly be done ‘permutationally’ but with much more computation and it’d be useless in this context, since the goal of this set of functions is precisely to obtain sequences different from typical permutational ones. With Trainsposition() we had an already interesting example since each modifying note was given two parameters (in addition to its index): an integer value and a sign. The amount of strictly permutational manipulations needed to perform such a computation would be fairly large.

Static intervals

Now instead of applying one modification to each note in a series and take a picture of the result after each step in the process, we want to have a sequence of intervals (they can be represented by a series too) that will run through our original series and stop at some stage. Each interval will be applied to a gradually decreasing number of notes in the original row. Let’s name ‘origin’ the series to be modified. The number of concerned notes in the origin is decreasing because each time an interval has reached the last available note, is remains as a permanent modification. So for a twelve-tone origin, as soon as the first interval has reached the last note, it remains there and this note index is not available anymore for further modification. Then the second interval only touches eleven notes in the origin, and so on till the last change which only concerns one note. This is a train of static intervals.

These schoenbergian examples are taken from a 2008 Etude for clarinet.

Series S:   05814B62793A
Reverse R:  A39726B41850
Inverse I:  074B816A5392
0pposite O: 2935A618B470

Ex. 1:

*** DESCR: seq_obj: Seq_2 after Build_tree: object tree: 
funt: Static(A=05814B62793A,oct,B=A39726B41850,oct,ord=05814B62793A) ready: 1 ***
*** seq_proc : Tkrow_2 Sequence object: recorded

In this sequence we reach at step 12 the schoenbergian Reverse of Series S. The notes are modified following the order given by the same Series S. Now we could be interessed by the series of intervals that is applied in this case. To acquire this knowledge, Csgrouper provides – on the ‘Series’ tab – an analytic function called Statana(). Putting our origin (05814B62793A) into fields A and ord and our target (A39726B41850) into field B and applying function Statana() we obtain the resulting series (261215A2265A) and a sequence of signs (++-+++—–+) that have to be applied to S in order to get R under the static intervals sequential method. You can verify that the first value (2) has to be added (+) to note index (A=10, i.e. the eleventh note in S = 3) in order to get (5) which is the eleventh note in R. To get there, (2) had first to change the value of each other note in S. This knowledge isn’t required to run Static() though, but the same sequence of values can then be devoted to another role somewhere else in a work for instance.

Dynamic intervals

Now we can also have our origin modified permanently by each interval. Instead of falling back to the original value when a note has been modified, we keep the modified value. Then next time the interval changes this note, it is no more the value that was shown in the origin. This is a train of dynamic intervals, and it almost makes melodies sound like random sequences. However, the ultimate state of the series is completely determined too. Thus sequences of dynamic intervals are useful in music because from an original pattern they create complications leading to other defined musical patterns. The complication itself shows properties that the ear may perhaps sometimes apprehend or recognize, most of all when this form is used in several places in a piece. Again the internal parameters of Dynamic() can be known by feeding the same fields and appying Dynana() (checking the box ‘exp’ will further expand the results).

Ex. 2:

Now we start from where we left off in Static(), i.e. R (A39726B41850) and we want to reach O (2935A618B470) according to order (A39726B41850):

*** DESCR: seq_obj: Seq_2 after Build_tree: object tree: 
funt: Dynamic(A=A39726B41850,oct,B=2935A618B470,oct,ord=A39726B41850) ready: 1 ***
*** seq_proc : Tkrow_2 Sequence object: recorded

Non permutational serialism (1): Trainsposition()

Aside from what is explained in the ‘code’ section, Csgrouper offers non permutational functions, that were the origin of the whole program back in 2008. Their purpose is to transform gradually one series to another by arithmetic means.


While mere ‘Transposition’ is easily replaced by setting the correct ‘tone’ value for a ‘Suite’ in the corresponding row (and could therefore be removed from the function menu if it wasn’t for the possibility of giving a negative interval value to the field ‘n’),  ‘Trainsposition’ represents the first in a set of non permutational functions I wish to describe here. However there is a last semi-permutational function to describe before, because it makes the link between permutational and non permutational functions by giving to the latter ones a general action scheme.


The Train function is quite simple, provided you give it two Series, no matter whether they are made of distinct elements, and one Order Series, all three in the same base, it will yield a gradual replacement of the values of the first one by the values of the second one following the indexical order given as third series.

The Order Series (ord) must be made of distinct elements, and that feature is shared by all Train-like functions explained from now on.


*** DESCR: seq_obj: Seq_1 after Build_tree: 
object tree: 102145 112145 111145 111145 111115 111111
funt: Train(A=302145,oct,B=111111,oct,ord=012345) [n=1] ready: 1 
*** seq_proc : Tkrow_1 Sequence object: recorded

This last example taken from the output in Csgrouper’s terminal after row validation, shows well the process that will be shared by all non permutational functions. The original Series sees its first element replaced by the corresponding element in B, and so on till the whole Series is replaced (here the repetitions come from the fact that we have chosen a replacing Series made of one sole element) . Now if we had put 3 into field ‘n’ we’d have obtained:

object tree: 111145 111110

And this is a (small) bug since last sign should be one! But we see that the number of intermediary series made by the train is different. This feature will be further described below.


This function will take a Series (A) as first argument (a twelve-tone row in our example) and transpose each of its notes according to the values in a second Series (B) in the same base. This transposition will however not be done at once but note by note, so if the Series has twelve notes, it will then be repeated twelve times, each time showing a new differing note till reaching a totally different Series, possibly with non-distinct signs. This behaviour makes the ear gradually used to a different note pattern.

To make things a little less predictable, we add three factors to our transformation: first, the order in which the notes are taken for transposition is not necessarily ascending but represented by any Series in the same base put into field ‘ord’. Second, unlike normal transposition, the  value combined with the original note is not necessarily unique, i.e. you can have a different transposition value for each note of your base Series. This is the content of field (B). Of course you can also choose to have the transpositions done with a sole value, then your field (B) should be filled with 12 times that value, for example, ‘111111111111’ will transpose all your original row one semitone higher. The third factor is the sense of transposition, and it will define whether you’d like to have your transposition value added or subtracted from your original note. This is the content of field ‘signs’ and it be filled with signs corresponding to the values in field (B). For example ‘-+++++++++++’ will make the function subtract from your initial note, and then add to the other ones.

Another way of modifying the behaviour of this function is to change the value of the field ‘n’ to one of the divisors of your Series base. For a twelve-tone row we see that this value can be set to 1, 2, 3, 4 or 6. Each one of these choices will have the effect of grouping together as many changes or steps in the gradual process. Having 3 in ‘n’ for instance, will limit the repetitions of a twelve-tone row to 4, each one containing 3 notes transposed. This value is also set as a global fallback value for each row by meta-field ‘Steps’, but the utility of this field raises a question: to be efficient in each possible case, it should always be set to one (because a series base can be a prime number) and thus it isn’t requiring an independant field.

Unfortunately – unlike what exists for the Static and Dynamic trains of intervals we’ll examine later –  Csgrouper doesn’t provide any analytic tool to tell quickly which Series of transpositions (B) you have to use in order to obtain a certain Series as last output of this function, but this is not very difficult to calculate.

Finally as with any Series manipulation in Csgrouper, one has to be aware of the octavial range attributed jointly (correlative fields ‘Aoct’ and ‘Boct’).