The idea behind FluxEM

Where this comes from

On music theory, hidden structure, and why embeddings might matter more than we think

There's a story from early twentieth-century music that I keep coming back to: a group of composers who seemed to destroy tonality—and, in the process, revealed structure they didn't expect to find.

In Vienna, around 1908, Arnold Schoenberg began writing music that abandoned traditional keys: no more C major, no more resolution to the tonic—just twelve chromatic pitches treated as equals. His students—Berg, Webern—followed. Critics called it atonal, and they didn't mean it kindly.

Over the following decades, theorists developed a rigorous framework for analyzing this music. They called it pitch-class set theory. The idea was simple: forget about octaves, forget about note names. Reduce everything to numbers 0 through 11. C becomes 0, C♯ becomes 1, D becomes 2, and so on around the circle.

0 C 1 2 3 E♭ 4 E 5 6 7 G 8 A♭ 9 10 11
The pitch-class circle. C major triad (0, 4, 7) in solid burgundy. C minor (0, 3, 7) in dashed green. Same root, same fifth—different third.

A chord becomes a set of numbers. C major—C, E, G—becomes {0, 4, 7}. And once you have numbers, you can do mathematics.

The transformation

Here's where it gets interesting. Look at the two most fundamental chords in Western music:

C Major

C – E – G
{0, 4, 7}
intervals: 4, then 3

C Minor

C – E♭ – G
{0, 3, 7}
intervals: 3, then 4

Musicians have always known these chords are related. There's the parallel major and minor, the relative major and minor. We hear the kinship. But pitch-class set theory makes the relationship precise: major and minor are inversions of each other.

Inversion, in this context, means reflection. Take each pitch class n and map it to (12 − n) mod 12. You're flipping the circle. And when you flip {0, 4, 7}:

I({0, 4, 7}) = {12-0, 12-4, 12-7} mod 12
             = {0, 8, 5}
             = {0, 5, 8}  (reordered)

That's {0, 5, 8}—which, transposed down by 5 (or up by 7), gives you {0, 3, 7}. C minor.

The same intervals, reversed—not a metaphor or a feeling, but a mathematical identity.

The interval-class vector is a fingerprint of a chord's interval content. For both major and minor triads, it's identical:

(0, 0, 1, 1, 1, 0)
One each of interval classes 3, 4, and 5

Major and minor aren't just "related." In the mathematics of pitch-class sets, they're the same object under a group action.


Hindemith's turn

Now here's the part that matters for us.

Paul Hindemith was a German composer, born in 1895. A practical musician—he could play nearly every orchestral instrument—and a demanding theorist. In the 1930s and 40s, he wrote The Craft of Musical Composition, a treatise that proposed something counterintuitive.

Hindemith didn't reject Schoenberg's revolution. He absorbed it. He took the mathematical thinking that had emerged from atonality—the treatment of all twelve tones as structurally equal, the focus on interval relationships rather than key signatures—and used it to rebuild tonal theory from first principles.

His "Series 1" ranks the twelve tones by their acoustic relationship to a fundamental. His "Series 2" ranks intervals by consonance and dissonance. From these, he derives chord classification, harmonic tension, melodic direction—the whole apparatus of tonality, but now grounded in something more fundamental than convention.

Hindemith showed that tonality and atonality weren't opposites. They were the same underlying structure, viewed through different lenses.

The atonal composers thought they were escaping tradition. What they'd actually done was reveal the algebra that tradition had been using all along, without knowing it.


Structure as transformation

So what does this have to do with embeddings?

When you encode pitch-class sets into a vector space—properly, with the algebraic structure intact—something happens. The operations that music theorists defined abstractly become geometric:

The embedding doesn't just represent the structure; it makes the structure explicit. The move from major to minor becomes a rotation plus reflection in the embedding space, so things that once felt merely "related" collapse to the same object under transformation.

Across domains

And now we can ask a bigger question.

The cyclic group of pitch transposition—shifting notes around the circle of twelve—is mathematically identical to clock arithmetic. The lattice of propositional logic mirrors the algebra of set operations. Certain chemical reaction networks share structure with metabolic pathways.

If you embed these domains with their algebra intact, something becomes possible that wasn't before: a model could recognize when two problems share the same structure.

Not just similar or analogous—algebraically identical.

A pattern learned in music theory would apply directly when the model encounters the same structure in chemistry. A relationship between logical propositions would transfer to set operations, because in embedding space, they occupy the same geometry.

This is what Hindemith did with tonality. He saw that the tools developed for one purpose—analyzing atonal music—revealed truths about something seemingly different. The structure transferred because the algebra was the same.

FluxEM is an attempt to make that kind of transfer native to neural systems. Embed the algebra, and let the geometry do the work.

We don't know yet how far this goes. The eleven domains currently implemented—physics, chemistry, biology, mathematics, logic, music, geometry, graphs, sets, number theory, data—are existence proofs, not the final answer: they demonstrate that the embeddings can be constructed, and that the homomorphisms hold.

Whether this enables the cross-domain recognition we hope for—whether a model trained on these embeddings can discover structural kinships we haven't seen—that's the research question.

But the premise is Hindemith's: structure is structure, and when you encode it properly, it becomes visible.


Try it

pip install fluxem

from fluxem.domains.music import AtonalSetEncoder, prime_form
from fluxem.domains.music import interval_class_vector

enc = AtonalSetEncoder()

major = enc.encode([0, 4, 7])
minor = enc.encode([0, 3, 7])

# Same interval content
interval_class_vector([0, 4, 7])  # → (0, 0, 1, 1, 1, 0)
interval_class_vector([0, 3, 7])  # → (0, 0, 1, 1, 1, 0)

# Same prime form (the canonical representative)
prime_form([0, 4, 7])  # → (0, 3, 7)
prime_form([0, 3, 7])  # → (0, 3, 7)