adding script dump of jupyter notebook

dev
mwinter 2 months ago
parent 91f68f3066
commit 1be96953b8

@ -0,0 +1,577 @@
#!/usr/bin/env python
# coding: utf-8
# In[2]:
import itertools as it
import networkx as nx
from collections import Counter
import copy
import matplotlib.pyplot as plt
import random
from fractions import Fraction
import math
def collapse(fraction):
if fraction < 1:
while fraction < 1:
fraction *= Fraction(2, 1)
elif fraction >= 2:
while fraction >= 2:
fraction *= Fraction(1, 2)
return fraction
def hsPointToFR(point):
fraction = Fraction(1, 1)
for dim in point:
if dim > 0:
fraction = fraction * dim
else:
fraction = fraction * 1/abs(dim)
return fraction
def pitches(iterable, r):
for base in it.combinations_with_replacement(iterable, r - 1):
split = tuple(list(g) for k, g in it.groupby(tuple(b for b in base if b != 1)))
mults = list(it.product([-1, 1], repeat = len(split)))
for mult in mults:
yield tuple(it.chain(*[[val * mult[idx] for val in g] for idx, g in enumerate(split)]))
def expandPitch(pitch):
num = 1;
den = 1;
expandedPitch = list(pitch)
for dim in pitch:
if dim > 0:
num *= dim
else:
den *= abs(dim)
fraction = num/den
if fraction < 1:
while fraction < 1:
fraction *= 2
expandedPitch = [2] + expandedPitch
elif fraction >= 2:
while fraction >= 2:
fraction *= 1/2
expandedPitch = [-2] + expandedPitch
return tuple(expandedPitch)
def expandChord(chord):
return tuple([expandPitch(p) for p in chord])
def transposePitch(pitch, trans):
transposedPitch = list(pitch)
for t in trans:
if (t * -1) in transposedPitch:
transposedPitch.remove(t * -1)
else:
transposedPitch.append(t)
transposedPitch.sort(key=lambda val: abs(val))
return transposedPitch
def transposeChord(chord, trans):
transposedChord = list(chord)
for pdx, pitch in enumerate(chord):
transposedPitch = transposePitch(pitch, trans)
transposedChord[pdx] = tuple(transposedPitch)
return tuple(transposedChord)
def chords(pitches, r):
def is_connected(iterable):
points = comparitors = list(iterable)
connectedPoints = []
base = points[0]
bIdxScroll = 0
while True:
for comp in comparitors:
comps = sorted([base, comp], key=len, reverse=True)
if ((Counter(comps[0]) - Counter(comps[1])).total() == 1) and (len(comps[0]) - len(comps[1]) == 1):
comparitors = connectedPoints = connectedPoints + comps
points.remove(base)
if comp in points:
points.remove(comp)
if(len(points) == 0):
return True
else:
base = points[0]
bIdxScroll = 0
break
else:
if bIdxScroll < (len(points) - 1):
bIdxScroll += 1
base = points[bIdxScroll]
else:
return False
def is_centered(iterable):
return len(list(iterable)[0]) == 0
#return filter(is_connected, it.takewhile(is_centered, it.combinations(pitches, r)))
return {c for c in it.takewhile(is_centered, it.combinations(pitches, r)) if is_connected(c)}
def pitchDifference(frs):
cents1 = (1200 * math.log(hsPointToFR(frs[0]), 2))
cents2 = (1200 * math.log(hsPointToFR(frs[1]), 2))
return abs(cents2 - cents1)
def difference(p1, p2):
return transposePitch(p1, [p * -1 for p in p2])
def edges(chords):
def edgeDict(transposition, symDiff):
dict = {}
dict['melodic_movement'] = pitchDifference(symDiff)
dict['transposition'] = transposition
return dict
def reverseDict(dict):
revDict = copy.deepcopy(dict)
if revDict['transposition'] != ():
revDict['transposition'] = tuple(t * -1 for t in revDict['transposition'])
return revDict
def edgeData(iterable):
[base, comp] = list(iterable)
expandedBase = expandChord(base)
expandedComp = expandChord(comp)
transpositions = set([tuple(difference(pair[0], pair[1])) for pair in set(it.product(expandedBase, expandedComp))])
edges = [(expandedBase, expandedComp, edgeDict(t, symDiff)) for t in transpositions if len(symDiff := list(set(expandedBase) ^ set(tChord := transposeChord(expandedComp, t)))) == 2]
edges = edges + [(e[1], e[0], reverseDict(e[2])) for e in edges]
if edges != []:
return edges
else:
return None
return list(it.chain(*[e for c in it.combinations(chords, 2) if (e := edgeData(c)) is not None]))
def graph(edges):
G = nx.MultiDiGraph()
G.add_edges_from(edges)
return G
def hamiltonian(G):
F = [(G,[list(G.nodes())[0]])]
n = G.number_of_nodes()
while F:
graph,path = F.pop()
confs = []
neighbors = (node for node in graph.neighbors(path[-1])
if node != path[-1]) #exclude self loops
for neighbor in neighbors:
conf_p = path[:]
conf_p.append(neighbor)
conf_g = nx.Graph(graph)
conf_g.remove_node(path[-1])
confs.append((conf_g,conf_p))
for g,p in confs:
if len(p)==n:
return p
else:
F.append((g,p))
return None
def stochastic_hamiltonian(graph):
check_graph = graph.copy()
#next_node = random.choice(list(graph.nodes()))
next_node = list(graph.nodes())[0]
check_graph.remove_node(next_node)
path = [next_node]
while (nx.number_of_nodes(check_graph) > 0) and (len(path) < 5000):
neighbors = graph[next_node]
nd_list = list(graph.degree(list(neighbors)))
neighbors, weights = zip(*[[n, 1/pow(d, 2) if n not in path else 0.0000001] for n, d in nd_list])
next_node = random.choices(neighbors, weights=weights)[0]
path.append(next_node)
if next_node in check_graph.nodes:
check_graph.remove_node(next_node)
return [path, check_graph]
def stochastic_hamiltonian(graph):
check_graph = graph.copy()
#next_node = random.choice(list(graph.nodes()))
next_node = list(graph.nodes())[0]
check_graph.remove_node(next_node)
path = []
while (nx.number_of_nodes(check_graph) > 0) and (len(path) < 5000):
outEdges = list(graph.out_edges(next_node, data=True))
weights = [(1 if e[2]['melodic_movement'] < 200 else 0.001) * (1 if e[1] not in [pE[0] for pE in path] else 0.0000001) for e in outEdges]
edge = random.choices(outEdges, weights=weights)[0]
next_node = edge[1]
path.append(edge)
if next_node in check_graph.nodes:
check_graph.remove_node(next_node)
return path
# In[3]:
pSet = pitches([1, 3, 5], 4)
#print(len(list(pSet)))
cSet = chords(pSet, 4)
#print(cSet)
eSet = edges(cSet)
#for e in eSet:
# print(e)
testGraph = graph(eSet)
# In[4]:
len(testGraph.nodes)
# In[5]:
len(testGraph.edges)
# In[6]:
sGraph = nx.Graph(testGraph)
pos = nx.draw_spring(sGraph, node_size=5, width=0.1)
# larger figure size
plt.figure(1, figsize=(12,12))
nx.draw(sGraph, pos, node_size=5, width=0.1)
#plt.show()
plt.savefig('compact_sets.png', dpi=150)
# In[7]:
def reconcilePath(ham):
def sortByOther(c1, c2, trans):
indices = list(range(len(c1)))
sortedChord = copy.deepcopy(c2)
for pitch in c2:
transposedPitch = tuple(transposePitch(pitch, trans))
if transposedPitch in c1:
index = c1.index(transposedPitch)
sortedChord[index] = pitch
indices.remove(index)
else:
diff = pitch
sortedChord[indices[0]] = diff
return sortedChord
rPath = [[[], [list(p) for p in ham[0][0]]]]
for cdx in range(len(ham)-1):
c1 = list(ham[cdx][0])
c2 = list(ham[cdx][1])
trans = list(ham[cdx][2]['transposition'])
c2 = sortByOther(c1, c2, trans)
ham[cdx+1][0] = c2
rPath.append([trans, [list(p) for p in c2]])
return rPath
ham = stochastic_hamiltonian(testGraph)
ham = [list(e) for e in ham]
print(len(ham))
for e in ham:
print(e)
rPath = reconcilePath(ham)
rPath
# In[8]:
def pathToChords(path):
curRoot = Fraction(1, 1)
chords = []
for trans, points in path:
curRoot = curRoot * hsPointToFR(trans)
chord = [float(curRoot * hsPointToFR(p)) for p in points]
chords.append(chord)
return chords
fPath = pathToChords(rPath)
len(set([tuple(p) for p in fPath]))
fPath
# In[284]:
# Opening a file in write mode{
file = open("seq.txt", "w+")
# Converting the array to a string and writing to the file
content = str(fPath)
file.write(content)
# Closing the file
file.close()
# In[279]:
for edge in list(testGraph.edges(data=True))[:1000]:
print(edge)
# In[161]:
import networkx as nx
from matplotlib import pyplot as plt
import math
G = nx.grid_graph(dim=(range(-3, 4), range(-3, 4)))
def getLabel(x, y):
num = 1
den = 1
if x >= 0:
num *= math.pow(3, x)
else:
den *= math.pow(3, abs(x))
if y >= 0:
num *= math.pow(2, y)
else:
den *= math.pow(2, abs(y))
return str(int(num)) + "/" + str(int(den))
plt.figure(figsize=(10 * math.log2(3), 10 * math.log2(2)))
#plt.figure(figsize=(10, 10))
pos = {(x, y):(x * math.log2(3), y * math.log2(2)) for x,y in G.nodes()}
labels = {(x, y):getLabel(x, y) for x,y in G.nodes()}
nx.draw_networkx_labels(G, pos, labels=labels)
nx.draw(G, pos=pos,
node_color='white',
with_labels=False,
node_size=1000)
# In[160]:
import networkx as nx
from matplotlib import pyplot as plt
import math
G = nx.grid_graph(dim=(range(-2, 3), range(-2, 3)))
def collapseLabel(fraction):
if fraction < 1:
while fraction < 1:
fraction *= Fraction(2, 1)
elif fraction >= 2:
while fraction >= 2:
fraction *= Fraction(1, 2)
return fraction
def getLabel(x, y):
num = 1
den = 1
if x >= 0:
num *= math.pow(5, x)
else:
den *= math.pow(5, abs(x))
if y >= 0:
num *= math.pow(3, y)
else:
den *= math.pow(3, abs(y))
fraction = collapse(Fraction(int(num), int(den)))
num = fraction.numerator
den = fraction.denominator
return str(int(num)) + "/" + str(int(den))
plt.figure(figsize=(5 * math.log2(5), 5 * math.log2(3)))
#plt.figure(figsize=(10, 10))
pos = {(x, y):(x, y) for x,y in G.nodes()}
labels = {(x, y):getLabel(x, y) for x,y in G.nodes()}
nx.draw_networkx_labels(G, pos, labels=labels)
nx.draw(G, pos=pos,
node_color='white',
with_labels=False,
node_size=2000)
# In[44]:
for node in list(testGraph.nodes)[2:3]:
edges = list(testGraph.out_edges(node, data=True))
for edge in edges:
if list(edge)[2]['transposition'] != ():
print(edge)
# In[251]:
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# The graph to visualize
G = nx.grid_graph(dim=(range(-1, 2), range(-1, 2), range(-1, 2)))
# 3d spring layout
#pos = nx.spring_layout(G, dim=3, seed=779)
pos = {(x, y, z):(math.log2(2) * x, math.log2(3) * y, math.log2(5) * z) for x,y,z in G.nodes()}
# Extract node and edge positions from the layout
node_xyz = np.array([pos[v] for v in sorted(G)])
edge_xyz = np.array([(pos[u], pos[v]) for u, v in G.edges()])
# Create the 3D figure
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, projection="3d")
# Plot the nodes - alpha is scaled by "depth" automatically
ax.scatter(*node_xyz.T, s=100, ec="w")
ax.view_init(elev=30, azim=45, roll=15)
ax.axis('equal')
# Plot the edges
for vizedge in edge_xyz:
ax.plot(*vizedge.T, color="tab:gray")
def _format_axes(ax):
"""Visualization options for the 3D axes."""
# Turn gridlines off
ax.grid(False)
# Suppress tick labels
for dim in (ax.xaxis, ax.yaxis, ax.zaxis):
dim.set_ticks([])
# Set axes labels
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_zlabel("z")
_format_axes(ax)
fig.tight_layout()
plt.show()
# In[31]:
from tikzpy import TikzPicture
def collapseLabel(fraction):
if fraction < 1:
while fraction < 1:
fraction *= Fraction(2, 1)
elif fraction >= 2:
while fraction >= 2:
fraction *= Fraction(1, 2)
return fraction
def getLabel(x, y, z, collapse = False):
num = 1
den = 1
if x >= 0:
num *= math.pow(3, x)
else:
den *= math.pow(3, abs(x))
if y >= 0:
num *= math.pow(5, y)
else:
den *= math.pow(5, abs(y))
if z >= 0:
num *= math.pow(2, z)
else:
den *= math.pow(2, abs(z))
if collapse:
fraction = collapseLabel(Fraction(int(num), int(den)))
else:
fraction = Fraction(int(num), int(den))
num = fraction.numerator
den = fraction.denominator
return str(int(num)) + "/" + str(int(den))
def chord2Points(chord):
points = []
for n in chord:
counter = Counter(n)
points.append(tuple([counter[d] - counter[-d] for d in [2, 3, 5]]))
return tuple(points)
def genLattice(chord = None, ranges = None, filename = "tikz", collapse = False, scale = 1):
dx = math.log2(3) * scale
dy = math.log2(5) * scale
dz = math.log2(2) * scale
if chord:
set = chord2Points(chord)
if ranges:
rz,rx,ry = ranges
else:
rz,rx,ry = [[min(t), max(t) + 1] for t in list(zip(*set))]
if collapse:
rz = [0, 1]
tikz = TikzPicture(center=True)
tikz.set_tdplotsetmaincoords(30, -30)
tikz.options = "tdplot_main_coords"
for x in range(*rx):
for y in range(*ry):
for z in range(*rz):
line = tikz.line((x * dx - dx / 2, y * dy, z * dz), (x * dx + dx / 2, y * dy, z * dz), options="thick, black, -")
line = tikz.line((x * dx, y * dy - dy / 2, z * dz), (x * dx, y * dy + dy / 2, z * dz), options="thick, black, -")
if not collapse:
line = tikz.line((x * dx, y * dy, z * dz - dz / 2), (x * dx, y * dy, z * dz + dz / 2), options="thick, black, -")
node = tikz.node((x * dx, y * dy, z * dz), options="draw, fill=white, scale=0.5", text=getLabel(x,y,z, collapse))
if chord:
for e in set:
z,x,y = e
if collapse:
z = 0
line = tikz.line((x * dx - dx / 2, y * dy, z * dz), (x * dx + dx / 2, y * dy, z * dz), options="thick, black, -")
line = tikz.line((x * dx, y * dy - dy / 2, z * dz), (x * dx, y * dy + dy / 2, z * dz), options="thick, black, -")
if not collapse:
line = tikz.line((x * dx, y * dy, z * dz - dz / 2), (x * dx, y * dy, z * dz + dz / 2), options="thick, black, -")
node = tikz.node((x * dx, y * dy, z * dz), options="draw, fill=yellow, scale=0.5", text=getLabel(x,y,z, collapse))
tikz.compile(filename + ".pdf", True)
texFile = open(filename + ".tex", "w+")
texFile.write(tikz.code())
texFile.close()
# In[72]:
edge = (((), (-2, 3), (2, 3, -5), (3, 3, -5)), ((), (2, 2, -3), (-2, 3), (-2, -2, 5)), {'melodic_movement': 813.6862861351653, 'transposition': (2, 3, -5)})
chord = transposeChord(edge[0], (-2, -3, 5))
#genLattice(chord, path="figure.pdf", collapse=False)
genLattice(chord, ranges=[[-2, 2], [-2, 2], [-2, 2]], filename="compact_set_1_transposed_expanded_padded", collapse=False, scale=2)
# In[79]:
edge = (((), (-2, 3), (2, 3, -5), (3, 3, -5)), ((), (2, 2, -3), (-2, 3), (-2, -2, 5)), {'melodic_movement': 813.6862861351653, 'transposition': (2, 3, -5)})
chord = transposeChord(edge[0], (-2, -3, 5))
#genLattice(chord, path="figure.pdf", collapse=False)
genLattice(chord, ranges=[[-2, 2], [-1, 3], [-1, 2]], filename="compact_set_1_transposed_expanded_padded", collapse=False, scale=2)
# In[80]:
edge = (((), (-2, 3), (2, 3, -5), (3, 3, -5)), ((), (2, 2, -3), (-2, 3), (-2, -2, 5)), {'melodic_movement': 813.6862861351653, 'transposition': (2, 3, -5)})
chord = edge[0]
#genLattice(chord, path="figure.pdf", collapse=False)
genLattice(chord, ranges=[[-2, 2], [-1, 3], [-1, 2]], filename="compact_set_1_expanded_padded", collapse=False, scale=2)
Loading…
Cancel
Save