3
$\begingroup$

OK, I'm working on some music theory stuff since that's my hobby. This is what I want to do:

deltas = Tuples[{3, 4, 5, -9, -8, -7}, 11]; (* Generate every possible permutation of a minor third, major third, a perfect forth, and their inversions, 11 intervals long*)

musicMod[n_] := Which[n > 0, Mod[n, 12], n < 0, Mod[n, -12], n == 0, 0]; (*This is useful to define for the next function *)

candidates = Table[musicMod /@ Accumulate[Prepend[deltas[[i]], 0]], {i, 1, 
Length[deltas]}]; (* This collects the deltas into sequences of 12 notes, that have the deltas as intervals between them*)

tonerows = Select[candidates, CountDistinct[Mod[#, 12]] == 12 &] (* Finally just select the sequences that have one instance of each pitch class (eg <5,-7>) once *)

The problem is I get a memory allocation error in the first line when I try to generate my tuples. I know it's a lot of tuples, 6^11 = 362,797,056, but that's not a ridiculous amount. My computer has 16GB=16,000,000,000 of RAM, so shouldn't it be able to handle it?

Anyway, since I'm just going to end up selecting a small amount of the generated tuples anyway, is there a more efficient way to do it?

(For the musically astute among you, what I'm trying to do is generate a comprehensive list of tone rows made just from minor 3rds, major 3rds, and perfect 4ths, but treating their inversions somewhat distinctly.*)

Edit: Code fixed. Sorry about that!

$\endgroup$
  • $\begingroup$ One of your tuples occupies 184 bytes on my system, so your set of $6^{11}$ tuples would require more than 62 GB of memory. Your system does not even come close to that. For the second part of your question, that's a harder question. Can you specify your selection conditions in mathematical terms? it may be possible to generate the set directly, rather than construct all tuples then filter them. $\endgroup$ – MarcoB Jun 10 '18 at 5:01
  • $\begingroup$ Your code doesn't work even when you reduce the number of Tuples. I am confused by your definition of musicMod as a function of one variable, but then your usage in candidates suggests that it should take two inputs. Also, something seems wrong with the CountDistinct impression. Can you check the code and make sure that it works when you use fewer tuples? $\endgroup$ – MarcoB Jun 10 '18 at 5:13
5
$\begingroup$

My laptop has only 16 GB of RAM but still manages to produce the list deltas within about 24 seconds with a lot of memory compression and swapping.

But for manipulating the $i$-th element, it is not necessary to have all elements in memory. You can directly access the $i$-th tuple of length $n$ with values from list with the following function.

ithTuple[list_, n_, i_Integer] := list[[1 + IntegerDigits[i - 1, Length[list], n]]];

Here is also a small test

n = 6;
list = RandomInteger[{1, 100}, 4];
a = ithTuple[list, n, #] & /@ Range[Length[list]^n];
b = Tuples[list, n];
a == b

True

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.