Markov Matrix (Part 2)

If Markov matrices were limited to a single state per seed then their musical usefulness would be limited (as I am sure you have realised from playing around with the example in part 1). Luckily, there are no such limits and seeds can in fact be any length you like.

Let's look back again at the set of numbers we used in part 1. {64,62,60,62,64,64,64,62,62,62,64,67,67,64,62,60,62,64,64,64,64,62,62,64,62,60} To produce a Markov matrix of a depth of more than 1 (1 was the depth for the matrix in the previous example) we use seeds of more than one element. Let us build a matrix based on a seed of two elements instead of one (i.e. a Markov depth of 2). We calculate a matrix with a depth of 2 in the same way we calculate a matrix with a depth of 1. The only difference is that we base all our calculations on any two numbers being followed by another number. Remember our seed is now 2. Output is always 1 regardless of the Markov depth. Our primary matrix now looks like this.


60

62

64

67

64,62

0.6

0.4

0.0

0.0

62,60

0.0

1.0

0.0

0.0

60,62

0.0

0.0

1.0

0.0

62,64

0.0

0.25

0.50

0.25

64,64

0.0

0.4

0.6

0.0

62,62

0.0

0.3333333

0.6666666

0.0

67,67

0.0

0.0

1.0

0.0

64,67

0.0

0.0

0.0

1.0

67,64

0.0

1.0

0.0

0.0

The obvious change is that the far left hand column now contains 2 numbers (prior states) as the seed rather than 1. Two more obvious changes have occurred. There are more rows than there were previously and there are more 1.0 (100%) weighings than there were before. These last two points seem obvious, but they point to the most important feature of Markov chains; the ability to maintain local context and provide for more discriminatory, therefore musically coherent, output. The output of the matrix maintains the 'character' of the data used to construct it. Musically we might say it stores a sense of 'style'.

A Markov chain can be of any depth (any seed length) but there are a number of important considerations when regarding depth. As the depth of the Markov chain approaches the length of the phrase (data) the novelty (randomness) of the output decreases. Take the above matrix as an example. When we calculated the matrix for a Markov chain of depth 1, then 25% of the rows had a 100% (no randomness) chance of selecting a particular note. Now in our matrix of depth 2 more than 50% of rows have a 100% chance of selecting a particular note. This is the tradeoff with Markov chains. The guarantee of a particular sequence introduces stability and thematic coherence but also introduces the chance of a very similar and even identical arrangement. The resulting melody might be too close to the original.

To test this matrix we are not going to write another engine but instead make use of another of jMusic's in built classes. This class is called PhraseMatrix and it will calculate a matrix and generate a phrase of any length based on the calculated matrix. It will also do this for you for any depth level and calculates matrices for pitch, rhythm and volume (yes, of course you can create matrices for characteristics other than pitch, for example rhythms value, dynamic, or position in the bar). Here is an example class which uses the PhraseMatrix.

Click here to view/download the source.

  1: import jm.JMC;
  2: import jm.music.data.*;
  3: import jm.music.tools.*;
  4: import jm.util.*;
 
  6: public class MarkovTest implements JMC{
 
8: public static void main(String[] args){
9: Phrase marysLamb = new Phrase();
10: int[] p = {64,62,60,62,64,64,64,62,62,62,64,
67,67,64,62,60,62,64,64,64,64,62,62,64,62,60};
11: double[] r = {C,C,C,C,C,C,M,C,C,M,C,C,M,C,
C,C,C,C,C,C,C,C,C,C,C,M};
12: int[] d = {80,70,60,70,80,80,80,70,70,70,80,
100,100,80,70,60,70,80,80,80,80,70,70,80,70,60};
13: marysLamb.addNoteList(p,r,d);
14: int markovDepth = 2;
15: PhraseMatrix matrix = new PhraseMatrix(marysLamb,markovDepth);
16: Phrase myLamb = matrix.generate(true,true,true,20);
17: Score scr = new Score("MarysLamb");
18: Part part = new Part();
19: part.addPhrase(myLamb);
20: scr.addPart(part);
21: Write.midi(scr);
22: }
23: }

Markov Matrix (Part 1)

jMusic Tutorial Index