Serialism (ToneRow)

Twelve-tone serialism — tone rows and the row matrix.

A tone row is simply an ordering of all twelve pitch classes (C, C#, D, … B) in which each appears exactly once. It isn’t a melody — there’s no rhythm — it’s the raw pitch material a twelve-tone piece draws on. By always running through all twelve before repeating any, no single note can act as a tonal “home”, which is how Schoenberg’s method produces atonal music on purpose.

From one row you derive 48 forms via four operations, each at any of the twelve transpositions:

  • Prime (P) — the row as written.

  • Retrograde (R) — the row backwards.

  • Inversion (I) — every interval flipped upside-down.

  • Retrograde-Inversion (RI) — the inversion, backwards.

Everything here is plain arithmetic on the numbers 0–11 (mod 12), so the results are easy to verify: every form is still a permutation of all twelve pitch classes, and every row and column of the matrix contains each pitch class exactly once.

Example:

>>> row = ToneRow.from_names("C", "C#", "E", "D", "F", "D#",
...                          "F#", "A", "G#", "G", "B", "A#")
>>> row.P(0)[:4]          # prime starting on C
[0, 1, 4, 2]
>>> row.I(0)[:4]          # inversion starting on C — intervals mirrored
[0, 11, 8, 10]
>>> row.R(0) == row.P(0)[::-1]
True
class pytheory.serialism.ToneRow(pitches)[source]

Bases: object

A twelve-tone row and the 48 forms derived from it.

Construct from pitch-class numbers (0–11) or note names:

ToneRow([0, 1, 4, 2, 5, 3, 6, 9, 8, 7, 11, 10])
ToneRow.from_names("C", "C#", "E", "D", ...)

The transposition index n in P(), I(), R(), and RI() is the pitch class the form begins on (the common textbook convention). So P(0) starts on C, P(7) starts on G, and the row you passed in is P(row[0]).

__init__(pitches)[source]
classmethod from_names(*names: str) ToneRow[source]

Build a row from twelve note names, e.g. ToneRow.from_names("C", "C#", "E", ...).

P(n: int = 0) List[int][source]

Prime form beginning on pitch class n — the row, transposed.

I(n: int = 0) List[int][source]

Inversion beginning on pitch class n — every interval of the prime flipped upside-down.

R(n: int = 0) List[int][source]

Retrograde of P(n) — the prime form played backwards.

(It ends on pitch class n, since it’s P(n) reversed.)

RI(n: int = 0) List[int][source]

Retrograde-inversionI(n) played backwards.

form(label: str) List[int][source]

Look up a form by label, e.g. "P0", "I7", "R5", "RI11".

Example:

>>> ToneRow(range(12)).form("R0")
[11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
all_forms() dict[source]

Return all 48 forms as a {label: [pitch classes]} dict (P0P11, I0I11, R0R11, RI0RI11).

matrix() List[List[int]][source]

The 12×12 row matrix as a list of rows of pitch classes.

P0 runs along the top, I0 down the left, and the top-left to bottom-right diagonal is all zeros. Read a row left-to-right for a Prime form, right-to-left for a Retrograde; read a column top-to-bottom for an Inversion, bottom-to-top for a Retrograde-Inversion.

matrix_str(names: bool = True) str[source]

A printable matrix, labelled with the P/I/R/RI transpositions.

With names=True cells show note names; otherwise pitch-class numbers. The left edge labels each row’s Prime form and the right edge its Retrograde; the top labels each column’s Inversion and the bottom its Retrograde-Inversion.

note_names(form: str = 'P0') List[str][source]

Note names for a given form label (default "P0").

property interval_succession: List[int]

The eleven ordered intervals (1–11 semitones) between successive notes of the row.

property is_all_interval: bool

True if this is an all-interval row — its eleven successive intervals use each of the intervals 1–11 exactly once.

Example:

>>> ToneRow([0, 11, 1, 10, 2, 9, 3, 8, 4, 7, 5, 6]).is_all_interval
True
__repr__() str[source]

Return repr(self).

__eq__(other) bool[source]

Return self==value.

__len__() int[source]