Menu Close

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.

Nota: Este ejercicio ha sido propuesto por Francisco J. Hidalgo.

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.

Pensamiento

Como el olivar,
mucho fruto lleva,
poca sombra da.

Antonio Machado

Medio

3 soluciones de “Matriz dodecafónica

  1. adogargon
    import Data.Matrix 
     
    matrizDodecafonica :: [Int] -> Matrix Int
    matrizDodecafonica xs =
      fromLists (map (map (x -> if x == 0 then 12 else x))
                          (toLists (auxiliar xs)))
     
    auxiliar :: [Int] -> Matrix Int 
    auxiliar xs = m
      where
        m = matrix 12 12
                   ((i,j) -> if i == 1
                              then xs !!(j-1)
                              else if j == 1
                                   then (2*m!(1,1) - m!(1,i)) `mod` 12
                                   else (m!(i,1) - m!(1,1) + m!(1,j)) `mod` 12)
  2. luipromor
    import Data.Matrix 
    import Test.QuickCheck
    import Data.List
     
    matrizDodecafonica :: [Int] -> Matrix Int
    matrizDodecafonica xs = v
      where v = matrix 12 12 f
            f (1,j) = xs !! (j-1)
            f (i,1) | n == 0    = 12
                    | otherwise = n
              where n = mod (2 * v ! (1,1) - v ! (1,i)) 12
            f (i,j) | n == 0    = 12
                    | otherwise = n
              where n =  mod ( v ! (i,1) -v !(1,1) + v !(1,j) ) 12
     
    prop_permutaciones :: [Int] -> Property
    prop_permutaciones xs =
      length xs == 12 && and [ elem k xs | k <- [1..12]] ==>
      all (ys -> elem ys $ permutations xs) $ toLists $ matrizDodecafonica xs
     
    prop_diagonal :: [Int] -> Property
    prop_diagonal xs =
      length xs == 12 && and [elem k xs | k <- [1..12]] ==>
      aux $ matrizDodecafonica xs
      where aux v = 1 == length (nub [ v ! (i,i) | i <- [1..12]])
     
    prop_suma :: [Int] -> Property
    prop_suma xs =
      length xs == 12 && and [elem k xs | k <- [1..12]] ==>
      aux $ matrizDodecafonica xs
      where aux v = 936 == sum [v ! (i,j) | i <- [1..12] , j <- [1..12]]
  3. javmarcha1
    import Data.Matrix
    import Test.QuickCheck
    import Data.List
     
    matrizDodecafonica :: [Int] -> Matrix Int
    matrizDodecafonica xs = q
      where q = matrix 12 12 ((i,j) -> f i j)
            f 1 j = xs !! (j-1)
            f i 1 | mod (f 1 1 + f 1 1 - f 1 i) 12 == 0 = 12
                  | otherwise = mod (f 1 1 + f 1 1 - f 1 i) 12
            f i j | mod (f 1 j + f i 1 - f 1 1) 12 == 0 = 12
                  | otherwise = mod (f 1 j + f i 1 - f 1 1) 12
     
    prop_permutaciones :: [Int] -> Property
    prop_permutaciones xs =
      length xs == 12 && and [elem k xs | k <- [1..12]] ==>
      all (ys -> elem ys $ permutations xs) $ toLists $ matrizDodecafonica xs
     
    prop_diagonal :: [Int] -> Property
    prop_diagonal xs =
      length xs == 12 && and [elem k xs | k <- [1..12]] ==>
      aux $ matrizDodecafonica xs
      where aux v = 1 == length (nub [v ! (i,i) | i <- [1..12]])
     
    prop_suma :: [Int] -> Property
    prop_suma xs =
      length xs == 12 && and [elem k xs | k <- [1..12]] ==>
      aux $ matrizDodecafonica xs
      where aux v = 936 == sum [v ! (i,j) | i <- [1..12] , j <- [1..12]]

Escribe tu solución

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.