mutwo.common_generators¶
Object |
Documentation |
---|---|
Generate an instance of Brownian motion (i.e. the Wiener process). |
|
|
Make generator which runs Bruns adaption of the Euclidean algorithm. |
Can be used as a Mixin to define context-free grammar. |
|
Can be used as a Mixin to define context-free grammar. |
|
Describe a context_free_grammar_rule for a |
|
Describe a context-free grammar and resolve non-terminals |
|
Python implementation of Michael Edwards activity level algorithm. |
|
Weighted random choices with dynamically changing weights. |
|
Make gray code where each tuple has length items with modulus different numbers. |
|
Tendency offers an interface for dynamically changing minima / maxima areas. |
|
Abstract base class to implement a backtracking algorithm |
|
Abstract base class for index based backtracking algorithms |
|
Return euclidean rhythm as described in a 2005 paper by G. T. Toussaint. |
|
Generates rhythm using the paradiddle method described by G. T. Toussaint. |
|
Generates rhythm using the alternating hands method described by G. T. Toussaint. |
- random_walk_noise(x0, n, dt, delta, out=None, random_state=None)[source]¶
Generate an instance of Brownian motion (i.e. the Wiener process).
- Parameters:
x0 (float) – the initial condition(s) (i.e. position(s)) of the Brownian motion.
n (int) – the number of steps to take
dt (float) – the time step
delta (float) – delta determines the “speed” of the Brownian motion. The random variable of the position at time t, X(t), has a normal distribution whose mean is the position at time t=0 and whose variance is delta**2*t.
out (Optional[array]) – If out is not None, it specifies the array in which to put the result. If out is None, a new numpy array is created and returned.
random_state (Optional[int]) – set the random seed of the pseudo-random generator.
- Returns:
A numpy array of floats with shape x0.shape + (n,).
- Return type:
array
X(t) = X(0) + N(0, delta**2 * t; 0, t)
where N(a,b; t0, t1) is a normally distributed random variable with mean a and variance b. The parameters t0 and t1 make explicit the statistical independence of N on different time intervals; that is, if [t0, t1) and [t2, t3) are disjoint intervals, then N(a, b; t0, t1) and N(a, b; t2, t3) are independent.
Written as an iteration scheme,
X(t + dt) = X(t) + N(0, delta**2 * dt; t, t+dt)
If x0 is an array (or array-like), each value in x0 is treated as an initial condition, and the value returned is a numpy array with one more dimension than x0.
Note that the initial value x0 is not included in the returned array.
- This code has been copied from the scipy cookbook:
https://scipy-cookbook.readthedocs.io/items/BrownianMotion.html
- make_bruns_euclidean_algorithm_generator(element_tuple, matrix=array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]), subtraction_index=1)[source]¶
Make generator which runs Bruns adaption of the Euclidean algorithm.
- Parameters:
element_tuple (tuple[_BrunEuclideanElement, _BrunEuclideanElement, _BrunEuclideanElement]) – The initial elements which gets re-calculated after each step. Type doesn’t matter; objects only need to have the following magic methods: __sub__, __lt__ and __gt__.
matrix (np.array) – The initial matrix.
subtraction_index (Literal[1, 2]) – This parameter has been added for the adaption of the function in
make_wilsons_brun_euclidean_algorithm_generator()
and is not part of Bruns original algorithm. It describes whether in each step the first element gets subtracted by the second (original) or by the third (Wilson adaption) element.
- Return type:
Generator
This algorithm has been described by V. Brun in his paper “EUCLIDEAN ALGORITHMS AND MUSICAL THEORY” (1964).
Example:
>>> import fractions >>> from mutwo import common_generators >>> b = common_generators.make_bruns_euclidean_algorithm_generator( ... ( ... fractions.Fraction(2, 1), ... fractions.Fraction(3, 2), ... fractions.Fraction(5, 4), ... ) ... ) >>> next(b) ((Fraction(2, 1), Fraction(3, 2), Fraction(5, 4)), array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]), Fraction(2, 1))
- reflected_binary_code(length, modulus)[source]¶
Make gray code where each tuple has length items with modulus different numbers.
- Parameters:
length (int) – how long one code is
modulus (int) – how many different numbers are included
- Return type:
tuple[tuple[int, …], …]
Example:
>>> from mutwo import common_generators >>> common_generators.reflected_binary_code(2, 2) ((0, 0), (0, 1), (1, 1), (1, 0)) >>> common_generators.reflected_binary_code(3, 2) ((0, 0, 0), (0, 0, 1), (0, 1, 1), (0, 1, 0), (1, 1, 0), (1, 1, 1), (1, 0, 1), (1, 0, 0)) >>> common_generators.reflected_binary_code(2, 3) ((0, 0), (0, 1), (0, 2), (1, 2), (1, 1), (1, 0), (2, 0), (2, 1), (2, 2))
- Basic code has been copied from:
- euclidean(size, distribution)[source]¶
Return euclidean rhythm as described in a 2005 paper by G. T. Toussaint.
- Parameters:
size (int) – how many beats the rhythm contains
distribution (int) – how many beats are played
- Returns:
The rhythm in relative time.
- Return type:
tuple[int, …]
Example:
>>> from mutwo import common_generators >>> common_generators.euclidean(8, 4) (2, 2, 2, 2) >>> common_generators.euclidean(7, 5) (2, 1, 1, 2, 1)
The title of Toussaints paper is “The Euclidean Algorithm Generates Traditional Musical Rhythms”.
- paradiddle(size)[source]¶
Generates rhythm using the paradiddle method described by G. T. Toussaint.
- Parameters:
size (int) – how many beats the resulting rhythm shall last. ‘Size’ has to be divisible by 2 because of the symmetrical structure of the generated rhythm.
- Returns:
Return nested tuple that contains two tuple where each tuple represents one rhythm (both rhythms are complementary to each other). The rhythms are encoded in absolute time values.
- Return type:
tuple[tuple[int, …], …]
Example:
>>> from mutwo import common_generators >>> common_generators.paradiddle(8) ((0, 2, 3, 5), (1, 4, 6, 7)) >>> common_generators.paradiddle(6) ((0, 4, 5), (1, 2, 3))
The paradiddle algorithm has been described by Godfried T. Toussaint in his paper ‘Generating “Good” Musical Rhythms Algorithmically’.
- alternating_hands(seed_rhythm)[source]¶
Generates rhythm using the alternating hands method described by G. T. Toussaint.
- Parameters:
seed_rhythm (tuple[int, ...]) – rhythm that shall be distributed on two hands.
- Returns:
Return nested tuple that contains two tuple where each tuple represents one rhythm (both rhythms are complementary to each other). The rhythms are encoded in absolute time values.
- Return type:
tuple[tuple[int, …], …]
Example:
>>> from mutwo import common_generators >>> common_generators.alternating_hands((2, 2)) ((0, 6), (2, 4)) >>> common_generators.alternating_hands((3, 2, 2)) ((0, 5, 10), (3, 7, 12))
The alternating hands algorithm has been described by Godfried T. Toussaint in his paper ‘Generating “Good” Musical Rhythms Algorithmically’.
- class ContextFreeGrammarRule(left_side, right_side)[source]¶
Bases:
object
Describe a context_free_grammar_rule for a
ContextFreeGrammar
Public Data Attributes:
left_side
right_side
- Parameters:
left_side (NonTerminal) –
right_side (tuple[Union[mutwo.common_generators.chomksy.NonTerminal, mutwo.common_generators.chomksy.Terminal], ...]) –
- left_side: NonTerminal¶
- right_side: tuple[Union[mutwo.common_generators.chomksy.NonTerminal, mutwo.common_generators.chomksy.Terminal], ...]¶
- class ContextFreeGrammar(context_free_grammar_rule_sequence)[source]¶
Bases:
object
Describe a context-free grammar and resolve non-terminals
- Parameters:
context_free_grammar_rule_sequence (Sequence[ContextFreeGrammarRule]) – A sequence of
ContextFreeGrammarRule
objects. It is allowed to provide multiple context_free_grammar_rules with the same :attribute:`left_side`.
This is a very reduced implementation of a context-free grammar which only provides the most basic functions. It is not made for the purpose of parsing text but rather as a technique to generate algorithmic data (for the sake of art creation). Therefore it is all about the resolution of start objects to variants of this start.
Public Data Attributes:
non_terminal_tuple
terminal_tuple
context_free_grammar_rule_tuple
Get all defined rules
Public Methods:
get_context_free_grammar_rule_tuple
(non_terminal)Find all defined context_free_grammar_rules for the provided
NonTerminal
.resolve_one_layer
(tree)Resolve all leaves of the tree.
resolve
(start[, limit])Resolve until only
Terminal
are left or the limit is reached.
- get_context_free_grammar_rule_tuple(non_terminal)[source]¶
Find all defined context_free_grammar_rules for the provided
NonTerminal
.- Parameters:
non_terminal (NonTerminal) – The left side element of the
ContextFreeGrammarRule
.- Return type:
tuple[mutwo.common_generators.chomksy.ContextFreeGrammarRule, …]
- resolve(start, limit=None)[source]¶
Resolve until only
Terminal
are left or the limit is reached.- Parameters:
start (NonTerminal) – The start value.
limit (Optional[int]) – The maximum node levels until the function returns a tree. If it is set to None it will only stop once all nodes are
Terminal
.
- Return type:
Tree
- resolve_one_layer(tree)[source]¶
Resolve all leaves of the tree.
- Parameters:
tree (treelib.Tree) – The tree from which all leaves should be resolved.
- Returns:
True if any leaf has been resolved and False if no resolution has happened (e.g. if there are only
Terminal
left).- Return type:
bool
- property context_free_grammar_rule_tuple: tuple[mutwo.common_generators.chomksy.ContextFreeGrammarRule, ...]¶
Get all defined rules
- property non_terminal_tuple: tuple[mutwo.common_generators.chomksy.NonTerminal, ...]¶
- property terminal_tuple: tuple[mutwo.common_generators.chomksy.Terminal, ...]¶
- class ActivityLevel(start_at=0)[source]¶
Bases:
object
Python implementation of Michael Edwards activity level algorithm.
- Parameters:
start_at (int) – from which pattern per level shall be started (can be either 0, 1 or 2)
Activity Levels is a concept derived from Michael Edwards. Quoting Michael Edwards, Activity Levels are an “object for determining (deterministically) on a call-by-call basis whether a process is active or not (boolean). This is determined by nine 10-element lists (actually three versions of each) of hand-coded 1s and 0s, each list representing an ‘activity-level’ (how active the process should be). The first three 10-element lists have only one 1 in them, the rest being zeros. The second three have two 1s, etc. Activity-levels of 0 and 10 would return never active and always active respectively.”.
Example:
>>> from mutwo import common_generators >>> activity_levels = common_generators.ActivityLevel() >>> activity_levels(0) # activity level 0 will always return False False >>> activity_levels(10) # activity level 10 will always return True True >>> activity_levels(7) # activity level 7 will mostly return True True >>> tuple(activity_levels(7) for _ in range(10)) (True, False, True, True, False, True, True, False, True, True)
- class DynamicChoice(value_sequence, curve_sequence, random_seed=100)[source]¶
Bases:
object
Weighted random choices with dynamically changing weights.
- Parameters:
value_sequence (Sequence[Any]) – The items to choose from.
curve_sequence (Sequence[core_events.Envelope]) – The dynamically changing weight for each value.
random_seed (int) – The seed which shall be set at class initialisation.
Example:
>>> from mutwo import core_events >>> from mutwo import common_generators >>> dynamic_choice = common_generators.DynamicChoice( ... [0, 1, 2], ... [ ... core_events.Envelope([(0, 0), (0.5, 1), (1, 0)]), ... core_events.Envelope([(0, 0.5), (0.5, 0), (1, 0.5)]), ... core_events.Envelope([(0, 0.5), (1, 1)]), ... ], ... ) >>> dynamic_choice.gamble_at(0.3) 0 >>> dynamic_choice.gamble_at(0.3) 1 >>> dynamic_choice.gamble_at(0.3) 2
Public Methods:
items
()gamble_at
(time)Return value at requested time.
- gamble_at(time)[source]¶
Return value at requested time.
- Parameters:
time (numbers.Real) – At which position on the x-Axis shall be gambled.
- Returns:
The chosen value.
- Return type:
Any
- items()[source]¶
- Return type:
tuple[tuple[Any, mutwo.core_events.envelopes.Envelope]]
- class Tendency(minima_curve, maxima_curve, random_seed=100)[source]¶
Bases:
object
Tendency offers an interface for dynamically changing minima / maxima areas.
- Parameters:
minima_curve (core_events.Envelope) – The curve which describes the smallest allowed value over the time axis.
maxima_curve (core_events.Envelope) – The curve which describes the biggest allowed value over the time axis.
random_seed (int) – The random seed which shall be set.
The class is based on Gottfried Michael Koenigs algorithm of “Tendenz-Masken” in his program “Projekt 2” where those minima / maxima areas represent probability fields.
Example:
>>> from mutwo import core_events >>> from mutwo import common_generators >>> minima_curve = core_events.Envelope([(0, 0), (1, 1), (2, 0)]) >>> maxima_curve = core_events.Envelope([(0, 1), (1, 2), (2, 3)]) >>> my_tendency = common_generators.Tendency(minima_curve, maxima_curve) >>> my_tendency.value_at(0.5) 1.3349816305020088 >>> my_tendency.value_at(0.5) 1.0965540269678873
Public Data Attributes:
minima_curve
maxima_curve
Public Methods:
range_at
(time)Get minima / maxima range at requested time.
value_at
(time)Get value at requested time.
- class Backtracking[source]¶
Bases:
ABC
Abstract base class to implement a backtracking algorithm
By inheriting from this class, various backtracking algorithms can be implemented. In order to do so the user has to override a set of abstract methods. The abstract methods include:
Furthermore it may be helpful to override the following method (even though there is a valid working implementation):
Please see the methods documentation for more details.
The implementation of this backtracking algorithm makes a distinction between an element list and a solution. A solution is created by an element list. A solution is the output a user wants to get, but an element list is an object which is used internally in order to solve the problem. When implementing a backtracking algorithm by using this interface the user doesn’t have to make the distinction between both (and in this case treat both in the same way).
The most common use case for this distinction is by having a set of items which can appear in the solution and a list of indices which item of set shall be used. In this case the element_list is actually a list of indices. This use case is implemented in the
IndexBasedBacktracking
class.Bitner and Reingold [2] credit Derrick H. Lehmer with first using the term ‘backtrack’ in the 1950s..
Public Data Attributes:
solution_count
Return expected solution size
Public Methods:
is_valid
(element_list)Checks if an element list provides an acceptable solution.
append_new_element
(element_list)Append new element to element list.
update_last_element
(element_list)Increments value of the last element in an element_list.
can_last_element_be_updated
(element_list)Checks if the last element of the list can be incremented.
element_list_to_solution
(element_list)Converts an element list to the final solution
solve
([return_element_list])Apply backtracking algorithm.
- abstract append_new_element(element_list)[source]¶
Append new element to element list.
- Parameters:
element_list (list[Any]) – The element list to which a new element shall be appended.
- abstract can_last_element_be_updated(element_list)[source]¶
Checks if the last element of the list can be incremented.
- Parameters:
element_list (list[Any]) – The element list which last value shall be checked.
- Return type:
bool
- element_list_to_solution(element_list)[source]¶
Converts an element list to the final solution
- Parameters:
element_list (list[Any]) – The element list to be converted.
- Return type:
tuple[Any, …]
- abstract is_valid(element_list)[source]¶
Checks if an element list provides an acceptable solution.
- Returns:
True if the solution is acceptable and False if the solution is rejected.
- Parameters:
element_list (list[Any]) –
- Return type:
bool
- solve(return_element_list=False)[source]¶
Apply backtracking algorithm.
- Parameters:
return_element_list (bool) – If set to True the function will not only return the solution, but also the element list.
- Return type:
Union[tuple[Any, …], tuple[tuple[Any, …], list[Any]]]
- abstract update_last_element(element_list)[source]¶
Increments value of the last element in an element_list.
- Parameters:
element_list (list[Any]) – The element list which last value shall be updated.
This function should raise an Exception in case the last element can’t be updated.
- abstract property solution_count: int¶
Return expected solution size
- class IndexBasedBacktracking[source]¶
Bases:
Backtracking
Abstract base class for index based backtracking algorithms
This class implements concrete solutions for the following methods which are inherited from the parent class
Backtracking
:The following methods still have to be implemented:
(Please consult for more information the documentation of
Backtracking
).Furthermore the class adds new abstract methods to be implemented by child classes:
Example:
>>> import itertools >>> from mutwo import common_generators >>> class QueenProblem8(common_generators.IndexBasedBacktracking): ... queen_count = 8 ... point_list = list(itertools.combinations_with_replacement(range(queen_count), 2)) ... point_list.extend( ... [tuple(reversed(point)) for point in point_list if len(set(point)) == 2] ... ) ... def element_index_to_item_sequence(self, element_index, element_list): ... return self.point_list ... @property ... def solution_count(self): ... # 8 queens problem! ... return 8 ... def is_valid(self, element_list): ... solution = self.element_list_to_solution(element_list) ... for q0, q1 in itertools.combinations(solution, 2): ... # x != x, y != y ... is_valid = all(v0 != v1 for v0, v1 in zip(q0, q1)) ... diff_x, diff_y = (v0 - v1 for v0, v1 in zip(q0, q1)) ... is_valid = is_valid and (diff_x != diff_y) ... if not is_valid: return False ... return True >>> queen_problem_8 = QueenProblem8() >>> queen_problem_8.solve() ((0, 0), (1, 2), (2, 5), (3, 7), (4, 6), (6, 1), (5, 3), (7, 4))
Public Data Attributes:
Inherited from
Backtracking
solution_count
Return expected solution size
Public Methods:
element_index_to_item_sequence
(...)Get a sequence of items to choose from for a specific element
append_new_element
(element_list)Append new element to element list.
update_last_element
(element_list)Increments value of the last element in an element_list.
can_last_element_be_updated
(element_list)Checks if the last element of the list can be incremented.
element_list_to_solution
(element_list)Converts an element list to the final solution
Inherited from
Backtracking
is_valid
(element_list)Checks if an element list provides an acceptable solution.
append_new_element
(element_list)Append new element to element list.
update_last_element
(element_list)Increments value of the last element in an element_list.
can_last_element_be_updated
(element_list)Checks if the last element of the list can be incremented.
element_list_to_solution
(element_list)Converts an element list to the final solution
solve
([return_element_list])Apply backtracking algorithm.
- append_new_element(element_list)[source]¶
Append new element to element list.
- Parameters:
element_list (list[Any]) – The element list to which a new element shall be appended.
- can_last_element_be_updated(element_list)[source]¶
Checks if the last element of the list can be incremented.
- Parameters:
element_list (list[Any]) – The element list which last value shall be checked.
- Return type:
bool
- abstract element_index_to_item_sequence(element_index, element_list)[source]¶
Get a sequence of items to choose from for a specific element
- Parameters:
element_index (int) – The index of the element for which a sequence of solutions shall be returned.
element_list (list[Any]) – The current element list
- Return type:
Sequence[Any]
mutwo.common_generators.constants¶
Constants which are used in mutwo.common_generators
.
- ACTIVITY_LEVEL_TUPLE = (((0,), (0,), (0,)), ((1, 0, 0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 1, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 1, 0, 0, 0)), ((1, 0, 0, 0, 0, 0, 1, 0, 0, 0), (0, 0, 0, 1, 0, 1, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 1, 1, 0, 0)), ((1, 0, 0, 0, 1, 0, 1, 0, 0, 0), (0, 0, 0, 1, 0, 1, 1, 0, 0, 0), (0, 0, 1, 0, 0, 0, 1, 1, 0, 0)), ((1, 0, 0, 0, 1, 0, 1, 1, 0, 0), (0, 1, 0, 1, 0, 1, 1, 0, 0, 0), (0, 0, 1, 0, 0, 0, 1, 1, 0, 1)), ((1, 1, 0, 0, 1, 0, 1, 1, 0, 0), (0, 1, 0, 1, 0, 1, 1, 0, 0, 1), (0, 0, 1, 0, 1, 0, 1, 1, 0, 1)), ((1, 1, 0, 1, 1, 0, 1, 1, 0, 0), (0, 1, 0, 1, 0, 1, 1, 0, 1, 1), (0, 1, 1, 0, 1, 0, 1, 1, 0, 1)), ((1, 1, 0, 1, 1, 0, 1, 1, 0, 1), (1, 1, 0, 1, 0, 1, 1, 0, 1, 1), (1, 1, 1, 0, 1, 0, 1, 1, 0, 1)), ((1, 1, 0, 1, 1, 1, 1, 1, 0, 1), (1, 1, 1, 1, 0, 1, 1, 0, 1, 1), (1, 1, 1, 0, 1, 1, 1, 1, 0, 1)), ((1, 1, 0, 1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 0, 1, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 1, 1, 0, 1)), ((1,), (1,), (1,)))¶
Definition of activity level pattern. Pattern are copied from Michael Edwards Common Lisp composition software ‘slippery-chicken’.