saptak = ['Sa','Re','Ga','Ma','Pa','Dha','Ni']
saptak = ['Sa','Re_', 'Re',"Ga_", "Ga", "Ma", "Ma__", "Pa", "Dha_", "Dha", "Ni_", "Ni"]
len(saptak)
12
mandra_sptak = [s.lower() for s in saptak]
mandra_sptak
['sa', 're_', 're', 'ga_', 'ga', 'ma', 'ma__', 'pa', 'dha_', 'dha', 'ni_', 'ni']
tar_saptak = [s.upper() for s in saptak]
tar_saptak
['SA', 'RE_', 'RE', 'GA_', 'GA', 'MA', 'MA__', 'PA', 'DHA_', 'DHA', 'NI_', 'NI']
We will represent our composition in csv file format as given below
SA,SA,Dha,Pa,Ga,Re,Sa,Re,Ga$,Pa,Ga,Dha,Pa,Ga$
Ga,Pa,Dha,SA,RE,SA,Dha,Pa,SA,Pa,Dha,Pa,Ga,Re,Sa$
Ga,Ga,Pa,Dha,Pa,SA,SA$,Dha,Dha,SA,RE,GA,RE,SA,Dha
GA,GA,RE,SA,RE,RE,SA,Dha,SA,Pa,Dha,Pa,Ga,Re,Sa$
____ Pa (0.1) ____ Ga (0.5)
/ ___ Ga (0.1) /
/ / __ Re (0.3)--------- Sa (0.4)
/ / / \____ dha (0.1)
/ / /
Sa ------- Sa (0.2)
\ \ \
\ \ \__ dha (0.25)
\ \___ pa (0.04)
\____ ga (0.01)
%%file bhoop.csv
SA,SA,Dha,Pa,Ga,Re,Sa,Re,Ga$,Pa,Ga,Dha,Pa,Ga$
Ga,Pa,Dha,SA,RE,SA,Dha,Pa,SA,Pa,Dha,Pa,Ga,Re,Sa$
Ga,Ga,Pa,Dha,Pa,SA,SA$,Dha,Dha,SA,RE,GA,RE,SA,Dha
GA,GA,RE,SA,RE,RE,SA,Dha,SA,Pa,Dha,Pa,Ga,Re,Sa$
Ga,Re,Ga$,Sa,Re,Sa,Sa,Sa,Sa,Sa,dha,Sa,Re,Ga$
Pa,Ga,Pa,Pa,Dha,Dha,Pa,Pa,Ga,Pa,Dha,SA,Dha,Pa,Ga,Sa
Pa,Ga$,Re,Ga,Pa,SA,Dha,SA$$,SA,Dha,RE,SA$
Dha,Dha,Dha,Dha,SA,RE,GA,RE,SA,SA,Dha,Pa,Dha,SA,Dha,Pa
Ga,Re,Ga,Ga,Ga,Re,Pa,Ga,Dha,Pa,Dha,SA,Dha,Pa,Ga,Sa
Sa,Re,Ga,Pa,GaRe,Sa$,Re,Pa$$,Re,Ga$,Re$
Ga,GaPa,Ga,Re,Ga,Pa,Dha,SA,SA$,SA,Dha$,Pa,Ga,Pa
DhaRE,SA$,Dha$,Pa,Ga,Re,GaPa,DhaSA,PaDha,SA,DhaSA,DhaPa,GaRe,Sa
Pa,Ga,Ga,Ga,Pa$,SA,Dha,SA$,SA,SA,SARE,GARE,SA$
SA,Dha,Dha,SA$,SA,RE$,DhaSA,PaDha,SA$,Dha$,Pa$
Ga,GaPa,Ga,Re,Ga,Pa,Dha,SA,SARE,GARE,SA,DhaPa,DhaSA,DhaPa,GaRe,GaPa,GaRe,Sa
Writing bhoop.csv
def read_notations(filename):
with open(filename) as f:
return [line.strip().split(",") for line in f]
read_notations("bhoop.csv")[:1]
[['SA', 'SA', 'Dha', 'Pa', 'Ga', 'Re', 'Sa', 'Re', 'Ga$', 'Pa', 'Ga', 'Dha', 'Pa', 'Ga$']]
def histogram(data):
"""notations are given as a list of notes.
its a list of lists. every list is one line from composition
{"Sa":{"Pa":5, "Re":10, "Ga":3},
"Re": {"Ga":4, "Sa":"3"}
}
SA,SA,Dha,Pa,Ga,Re,Sa,Re,Ga$,Pa,Ga,Dha,Pa,Ga$
"""
hist = {}
for line in data:
for i, item in enumerate(line[:-1]):
nextnote = hist.get(item, {}) # get will return empty dict if item is not found
nextnote[line[i+1]] = nextnote.get(line[i+1], 0) + 1
hist[item] = nextnote
return hist
def transition_prabability(hist):
prob = {}
for k in hist:
total = sum(hist[k].values())
prob[k] = {note: freq/total for note, freq in hist[k].items()}
return prob
bhoopdata = read_notations("bhoop.csv")
histogram(bhoopdata)
{'SA': {'SA': 3,
'Dha': 12,
'RE': 4,
'Pa': 2,
'SA$': 2,
'Dha$': 1,
'DhaSA': 1,
'SARE': 2,
'RE$': 1,
'DhaPa': 1},
'Dha': {'Pa': 12, 'SA': 9, 'Dha': 6, 'SA$$': 1, 'RE': 1, 'SA$': 2},
'Pa': {'Ga': 12, 'Ga$': 2, 'Dha': 10, 'SA': 3, 'Pa': 2, 'GaRe': 1},
'Ga': {'Re': 9, 'Dha': 2, 'Pa': 9, 'Ga': 5, 'Sa': 2, 'GaPa': 2, 'Pa$': 1},
'Re': {'Sa': 2, 'Ga$': 4, 'Sa$': 2, 'Ga': 5, 'Pa': 1, 'Pa$$': 1, 'GaPa': 1},
'Sa': {'Re': 4, 'Sa': 4, 'dha': 1},
'Ga$': {'Pa': 1, 'Sa': 1, 'Re': 1, 'Re$': 1},
'RE': {'SA': 5, 'GA': 2, 'RE': 1, 'SA$': 1},
'SA$': {'Dha': 1, 'SA': 3, 'Dha$': 2},
'GA': {'RE': 3, 'GA': 1},
'dha': {'Sa': 1},
'SA$$': {'SA': 1},
'GaRe': {'Sa$': 1, 'Sa': 2, 'GaPa': 1},
'Sa$': {'Re': 1},
'Pa$$': {'Re': 1},
'GaPa': {'Ga': 2, 'DhaSA': 1, 'GaRe': 1},
'Dha$': {'Pa': 2, 'Pa$': 1},
'DhaRE': {'SA$': 1},
'DhaSA': {'PaDha': 2, 'DhaPa': 2},
'PaDha': {'SA': 1, 'SA$': 1},
'DhaPa': {'GaRe': 2, 'DhaSA': 1},
'Pa$': {'SA': 1},
'SARE': {'GARE': 2},
'GARE': {'SA$': 1, 'SA': 1},
'RE$': {'DhaSA': 1}}
hist = histogram(bhoopdata)
prob = transition_prabability(hist)
prob
{'SA': {'SA': 0.10344827586206896,
'Dha': 0.41379310344827586,
'RE': 0.13793103448275862,
'Pa': 0.06896551724137931,
'SA$': 0.06896551724137931,
'Dha$': 0.034482758620689655,
'DhaSA': 0.034482758620689655,
'SARE': 0.06896551724137931,
'RE$': 0.034482758620689655,
'DhaPa': 0.034482758620689655},
'Dha': {'Pa': 0.3870967741935484,
'SA': 0.2903225806451613,
'Dha': 0.1935483870967742,
'SA$$': 0.03225806451612903,
'RE': 0.03225806451612903,
'SA$': 0.06451612903225806},
'Pa': {'Ga': 0.4,
'Ga$': 0.06666666666666667,
'Dha': 0.3333333333333333,
'SA': 0.1,
'Pa': 0.06666666666666667,
'GaRe': 0.03333333333333333},
'Ga': {'Re': 0.3,
'Dha': 0.06666666666666667,
'Pa': 0.3,
'Ga': 0.16666666666666666,
'Sa': 0.06666666666666667,
'GaPa': 0.06666666666666667,
'Pa$': 0.03333333333333333},
'Re': {'Sa': 0.125,
'Ga$': 0.25,
'Sa$': 0.125,
'Ga': 0.3125,
'Pa': 0.0625,
'Pa$$': 0.0625,
'GaPa': 0.0625},
'Sa': {'Re': 0.4444444444444444,
'Sa': 0.4444444444444444,
'dha': 0.1111111111111111},
'Ga$': {'Pa': 0.25, 'Sa': 0.25, 'Re': 0.25, 'Re$': 0.25},
'RE': {'SA': 0.5555555555555556,
'GA': 0.2222222222222222,
'RE': 0.1111111111111111,
'SA$': 0.1111111111111111},
'SA$': {'Dha': 0.16666666666666666, 'SA': 0.5, 'Dha$': 0.3333333333333333},
'GA': {'RE': 0.75, 'GA': 0.25},
'dha': {'Sa': 1.0},
'SA$$': {'SA': 1.0},
'GaRe': {'Sa$': 0.25, 'Sa': 0.5, 'GaPa': 0.25},
'Sa$': {'Re': 1.0},
'Pa$$': {'Re': 1.0},
'GaPa': {'Ga': 0.5, 'DhaSA': 0.25, 'GaRe': 0.25},
'Dha$': {'Pa': 0.6666666666666666, 'Pa$': 0.3333333333333333},
'DhaRE': {'SA$': 1.0},
'DhaSA': {'PaDha': 0.5, 'DhaPa': 0.5},
'PaDha': {'SA': 0.5, 'SA$': 0.5},
'DhaPa': {'GaRe': 0.6666666666666666, 'DhaSA': 0.3333333333333333},
'Pa$': {'SA': 1.0},
'SARE': {'GARE': 1.0},
'GARE': {'SA$': 0.5, 'SA': 0.5},
'RE$': {'DhaSA': 1.0}}
to generate new notations from probabiities we will need a reverse function which can find notations given the probabilities
import random
def sample(items, probs):
r = random.random()
index = 0
while(r >=0 and index <len(probs)):
r -= probs[index]
index +=1
return items[index-1]
prob['Pa']
{'Ga': 0.4,
'Ga$': 0.06666666666666667,
'Dha': 0.3333333333333333,
'SA': 0.1,
'Pa': 0.06666666666666667,
'GaRe': 0.03333333333333333}
def test_samples():
"""a testing function which has data included in it
"""
probs = {'Ga': 0.4,
'Ga$': 0.06666666666666667,
'Dha': 0.3333333333333333,
'SA': 0.1,
'Pa': 0.06666666666666667,
'GaRe': 0.03333333333333333}
keys = [i for i in probs.keys()]
pvalues = [probs[i] for i in keys]
samples = [sample(keys, pvalues) for i in range(100000)]
for item in probs:
print(item, samples.count(item)/10000)
assert abs(probs['Pa'] - samples.count('Pa')/100000)<0.001
test_samples()
Ga 4.023 Ga$ 0.6677 Dha 3.3097 SA 0.9916 Pa 0.6725 GaRe 0.3355
bhoop_probs = transition_prabability(histogram(read_notations("bhoop.csv")))
def aalap(transition_prab, initial='Sa'):
current = initial
while True:
if current not in transition_prab:
current = random.choice(list(transition_prab.keys()))
yield current
probs = transition_prab[current]
items = [i for i in probs.keys()]
pvalues = [probs[item] for item in items]
current = sample(items, pvalues)
def take(seq, n):
"""take first n items
"""
return [next(seq) for i in range(n)]
bhoop = aalap(bhoop_probs, 'Sa')
take(bhoop, 32)
['Sa', 'Re', 'Pa', 'Ga', 'Re', 'Ga', 'Ga', 'Pa', 'Ga', 'Re', 'Pa', 'Ga', 'Pa', 'SA', 'Dha', 'Pa', 'Ga', 'GaPa', 'DhaSA', 'DhaPa', 'DhaSA', 'PaDha', 'SA', 'Dha', 'Dha', 'Dha', 'Pa', 'GaRe', 'Sa', 'Sa', 'Re', 'Sa$']
pakad for bhoop raag is
pakad = (('dha', 'dha', 'Sa'),('Ga','Re','Pa','Ga'),('Dha','Pa','Ga','Re'))
we will search for it
from collections import deque
def search(seq, subseq, end=100):
def compare(source, dest):
return any(["".join(item).lower() in "".join(source).lower().replace("$","") for item in dest])
n = len(max(subseq, key=len)) # will find a subseq of max length
window = deque(take(seq, n), n)
for i in range(n, end):
if compare(window, subseq):
yield i-n
window = deque(take(seq, n), n)
else:
window.append(next(seq))
def count(seq):
return sum(1 for i in seq)
bhoop = aalap(bhoop_probs)
pakad = (('dha', 'dha', 'Sa'),('Ga','Re','Pa','Ga'),('Dha','Pa','Ga','Re'))
print("beats", "pakad_count")
for i in range(8, 100, 8):
s = 0
for j in range(1000):
s += count(search(bhoop, pakad, i))
print("{:5} {:11}".format(i, s/1000))
beats pakad_count
8 0.183
16 0.418
24 0.741
32 0.972
40 1.249
48 1.507
56 1.796
64 2.076
72 2.351
80 2.649
88 2.913
96 3.237
def to_seq(data):
for line in data:
yield from line
sum([len(line) for line in bhoopdata])
214
count(search(to_seq(bhoopdata), pakad, 200))
--------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-39-de7168e894da> in search(seq, subseq, end) 12 yield i-n ---> 13 window = deque(take(seq, n), n) 14 else: <ipython-input-35-ae8835f98777> in take(seq, n) 19 """ ---> 20 return [next(seq) for i in range(n)] <ipython-input-35-ae8835f98777> in <listcomp>(.0) 19 """ ---> 20 return [next(seq) for i in range(n)] StopIteration: The above exception was the direct cause of the following exception: RuntimeError Traceback (most recent call last) <ipython-input-56-4f9c6b4a9222> in <module> ----> 1 count(search(to_seq(bhoopdata), pakad, 200)) <ipython-input-39-de7168e894da> in count(seq) 16 17 def count(seq): ---> 18 return sum(1 for i in seq) 19 <ipython-input-39-de7168e894da> in <genexpr>(.0) 16 17 def count(seq): ---> 18 return sum(1 for i in seq) 19 RuntimeError: generator raised StopIteration