Ir al contenido principal

Matriz dodecafónica

Como se explica en Create a Twelve-Tone Melody With a Twelve-Tone Matrix una matriz dodecafónica es una matriz de 12 filas y 12 columnas construidas siguiendo los siguientes pasos:

  • Se escribe en la primera fila una permutación de los números del 1 al 12. Por ejemplo,
(  3  1  9  5  4  6  8  7 12 10 11  2 )
(                                     )
(                                     )
(                                     )
(                                     )
(                                     )
(                                     )
(                                     )
(                                     )
(                                     )
(                                     )
(                                     )
  • Escribir la primera columna de forma que, para todo i (entre 2 y 12), a(i,1) es el número entre 1 y 12 que verifica la siguiente condición
(a(1,1) - a(i,1)) = (a(1,i) - a(1,1)) (módulo 12)

Siguiendo con el ejemplo anterior, la matriz con la 1ª fila y la 1ª columna es

(  3  1  9  5  4  6  8  7 12 10 11  2 )
(  5                                  )
(  9                                  )
(  1                                  )
(  2                                  )
( 12                                  )
( 10                                  )
( 11                                  )
(  6                                  )
(  8                                  )
(  7                                  )
(  4                                  )
  • Escribir la segunda fila de forma que, para todo j (entre 2 y 12), a(j,2) es el número entre 1 y 12 que verifica la siguiente condición
(a(2,j) - a(1,j)) = (a(2,1) - a(1,1)) (módulo 12)

Siguiendo con el ejemplo anterior, la matriz con la 1ª fila, 1ª columna y 2ª fila es

(  3  1  9  5  4  6  8  7 12 10 11  2 )
(  5  3 11  7  6  8 10  9  2 12  1  4 )
(  9                                  )
(  1                                  )
(  2                                  )
( 12                                  )
( 10                                  )
( 11                                  )
(  6                                  )
(  8                                  )
(  7                                  )
(  4                                  )
  • Las restantes filas se completan como la 2ª; es decir, para todo i (entre 3 y 12) y todo j (entre 2 y 12), a(i,j) es el número entre 1 y 12 que verifica la siguiente relación.
(a(i,j) - a(1,j)) = (a(i,1) - a(1,1)) (módulo 12)

Siguiendo con el ejemplo anterior, la matriz dodecafónica es

(  3  1  9  5  4  6  8  7 12 10 11  2 )
(  5  3 11  7  6  8 10  9  2 12  1  4 )
(  9  7  3 11 10 12  2  1  6  4  5  8 )
(  1 11  7  3  2  4  6  5 10  8  9 12 )
(  2 12  8  4  3  5  7  6 11  9 10  1 )
( 12 10  6  2  1  3  5  4  9  7  8 11 )
( 10  8  4 12 11  1  3  2  7  5  6  9 )
( 11  9  5  1 12  2  4  3  8  6  7 10 )
(  6  4 12  8  7  9 11 10  3  1  2  5 )
(  8  6  2 10  9 11  1 12  5  3  4  7 )
(  7  5  1  9  8 10 12 11  4  2  3  6 )
(  4  2 10  6  5  7  9  8  1 11 12  3 )

Definir la función

matrizDodecafonica :: [Int] -> Matrix Int

tal que (matrizDodecafonica xs) es la matriz dodecafónica cuya primera fila es xs (que se supone que es una permutación de los números del 1 al 12). Por ejemplo,

λ> matrizDodecafonica [3,1,9,5,4,6,8,7,12,10,11,2]
(  3  1  9  5  4  6  8  7 12 10 11  2 )
(  5  3 11  7  6  8 10  9  2 12  1  4 )
(  9  7  3 11 10 12  2  1  6  4  5  8 )
(  1 11  7  3  2  4  6  5 10  8  9 12 )
(  2 12  8  4  3  5  7  6 11  9 10  1 )
( 12 10  6  2  1  3  5  4  9  7  8 11 )
( 10  8  4 12 11  1  3  2  7  5  6  9 )
( 11  9  5  1 12  2  4  3  8  6  7 10 )
(  6  4 12  8  7  9 11 10  3  1  2  5 )
(  8  6  2 10  9 11  1 12  5  3  4  7 )
(  7  5  1  9  8 10 12 11  4  2  3  6 )
(  4  2 10  6  5  7  9  8  1 11 12  3 )

Comprobar con QuickCheck para toda matriz dodecafónica D se verifican las siguientes propiedades:

  • todas las filas de D son permutaciones de los números 1 a 12,
  • todos los elementos de la diagonal de D son iguales y
  • la suma de todos los elementos de D es 936.

Soluciones

import Data.List
import Test.QuickCheck
import Data.Matrix

-- 1ª solución
-- ===========

matrizDodecafonica :: [Int] -> Matrix Int
matrizDodecafonica xs = matrix 12 12 f
  where f (1,j) = xs !! (j-1)
        f (i,1) = modulo12 (2 * f (1,1) - f (1,i))
        f (i,j) = modulo12 (f (1,j) + f (i,1) - f (1,1))
        modulo12 0  = 12
        modulo12 12 = 12
        modulo12 x  = x `mod` 12

-- 2ª solución
-- ===========

matrizDodecafonica2 :: [Int] -> Matrix Int
matrizDodecafonica2 xs = fromLists (secuencias xs)

secuencias :: [Int] -> [[Int]]
secuencias xs = [secuencia a xs | a <- inversa xs]

inversa :: [Int] -> [Int]
inversa xs = map conv (map (\x -> (-x) + 2* (abs a)) xs)
  where a = head xs

secuencia :: Int -> [Int] -> [Int]
secuencia n xs = [conv (a+(n-b)) | a <- xs]
  where b = head xs

conv :: Int -> Int
conv n | n == 0 = 12
       | n < 0 = conv (n+12)
       | n > 11 = conv (mod n 12)
       | otherwise = n

-- Propiedades
-- ===========

-- Las propiedades son
prop_dodecafonica :: Int -> Property
prop_dodecafonica n =
  n >= 0 ==>
  all esPermutacion (toLists d)
  && all (== d!(1,1)) [d!(i,i) | i <- [2..12]]
  && sum d == 936
  where xss = permutations [1..12]
        k   = n `mod` product [1..12]
        d   = matrizDodecafonica (xss !! k)
        esPermutacion ys = sort ys == [1..12]

-- La comprobación es
--    λ> quickCheck prop_dodecafonica
--    +++ OK, passed 100 tests.