Motif sequence generation
Страница в процессе перевода. |
#
MotifSequenceGenerator
— Module
MotifSequenceGenerator
This module generates random sequences of motifs, under the constrain that the sequence has some total length ℓ so that q - δq ≤ ℓ ≤ q + δq
. All main functionality is given by the function random_sequence
.
#
MotifSequenceGenerator.random_sequence
— Function
random_sequence(motifs::Vector{M}, q, limits, translate, δq = 0; kwargs...)
Create a random sequence of motifs of type M
, under the constraint that the sequence has "length" ℓ
exactly within q - δq ≤ ℓ ≤ q + δq
. Return the sequence itself as well as the sequence of indices of motifs
used to create it. A vector of probabilities weights
can be given as a keyword argument, which then dictates the sampling probability for each entry of motifs
for the initial sequence created.
"length" here means an abstracted length defined by the struct M
, based on the limits
and translate
functions. It does not refer to the amount of elements!
M
can be anything, given the two functions
-
limits(motif)
: Some function that given themotif
it returns the(start, fine)
of the the motif in the same units asq
. This function establishes a measure of length, which simply isfine - start
. -
translate(motif, t)
: Some function that given themotif
it returns a new motif which is translated byt
(either negative or positive), with respect to the same units asq
.
Other Keywords
Please see the source code (use @which
) for a full description of the algorithm.
-
tries = 5
: Up to how many initial random sequences are accepted. -
taulcut = 2
: Up to how times an element is dropped from the initial guess. -
summands = 3
: Up to how many motifs may be combined as a sum to complete a sequence.
Simple Example
This example illustrates how the module MotifSequenceGenerator
works using a simple struct
. For a more realistic, and much more complex example, see the example using music notes.
Let’s say that we want to create a random sequence of "shouts", which are described by the struct
struct Shout
shout::String
start::Int
end
Let’s first create a vector of shouts that will be used as the pool of possible motifs that will create the random sequence:
using Random
shouts = [Shout(uppercase(randstring(rand(3:5))), rand(1:100)) for k in 1:5]
5-element Vector{Main.Shout}:
Main.Shout("W0C", 15)
Main.Shout("LL5XW", 59)
Main.Shout("YVHOF", 8)
Main.Shout("PEJVC", 9)
Main.Shout("HX03", 73)
Notice that at the moment the values of the .start
field of Shout
are irrelevant. MotifSequenceGenerator
will translate all motifs to start point 0 while operating.
Now, to create a random sequence, we need to define two concepts:
shoutlimits(s::Shout) = (s.start, s.start + length(s.shout) + 1);
shouttranslate(s::Shout, n) = Shout(s.shout, s.start + n);
shouttranslate (generic function with 1 method)
This means that we accept that the temporal length of a Shout
is length(s.shout) + 1
.
We can now create random sequences of shouts that have total length of exactly q
:
using MotifSequenceGenerator
q = 30
sequence, idxs = random_sequence(shouts, q, shoutlimits, shouttranslate)
sequence
6-element Vector{Main.Shout}:
Main.Shout("W0C", 0)
Main.Shout("LL5XW", 4)
Main.Shout("W0C", 10)
Main.Shout("W0C", 14)
Main.Shout("YVHOF", 18)
Main.Shout("LL5XW", 24)
sequence, idxs = random_sequence(shouts, q, shoutlimits, shouttranslate)
sequence
5-element Vector{Main.Shout}:
Main.Shout("LL5XW", 0)
Main.Shout("YVHOF", 6)
Main.Shout("YVHOF", 12)
Main.Shout("PEJVC", 18)
Main.Shout("LL5XW", 24)
Notice that it is impossible to create a sequence of length e.g. 7
with the above pool. Doing random_sequence(shouts, 7, shoutlimits, shouttranslate)
would throw an error.
Floating point lengths
The lengths of the motifs do not have to be integers. When using motifs with floating lengths, it is advised to give a non-0 δq
to random_sequence
. The following example modifies the Shout
struct and shows how it can be done with floating length.
struct FloatShout
shout::String
dur::Float64
start::Float64
end
rs(x) = uppercase(randstring(x))
shouts = [FloatShout(rs(rand(3:5)), rand()+1, rand()) for k in 1:5]
shoutlimits(s::FloatShout) = (s.start, s.start + s.dur);
shouttranslate(s::FloatShout, n) = FloatShout(s.shout, s.dur, s.start + n);
q = 10.0
δq = 1.0
r, s = random_sequence(shouts, q, shoutlimits, shouttranslate, δq)
r
6-element Vector{Main.FloatShout}:
Main.FloatShout("KVTW", 1.1276816927320024, 0.0)
Main.FloatShout("TTYJ", 1.5868177186878274, 1.1276816927320024)
Main.FloatShout("A1LSJ", 1.916592554483628, 2.7144994114198298)
Main.FloatShout("KVTW", 1.1276816927320024, 4.631091965903458)
Main.FloatShout("XXG", 1.7047743456209954, 5.7587736586354605)
Main.FloatShout("TTYJ", 1.5868177186878274, 7.463548004256456)
s
6-element Vector{Int64}:
3
1
4
3
2
1