How to replace pitches in a music21 Score - music21

I'm trying to replace one pitch in a score with another pitch (the end goal being to generate harmony parts).
>>> from music21 import *
>>> score = converter.parse('test.mid')
>>> type(score)
<class 'music21.stream.Score'>
>>> p0 = score.parts[0].pitches[0]
>>> p0sharp = p0.transpose(1)
>>> print p0
A3
>>> print p0sharp
B-3
>>> score.replace(p0, p0sharp)
>>> print score.parts[0].pitches[0]
A3
How should I be going about this?
Update: I posted my "test.mid" file here.

I have just checked the code for transpose. Just pass inPlace=True and it will work like magic. Hope it helps!
from music21 import *
score = converter.parse('test.mid')
p0 = score.parts[0].pitches[0]
print(p0)
p0.transpose(1, inPlace=True)
print(score.parts[0].pitches[0])
And for those who want a complete working example without loading an existing midi file:
from music21 import stream, instrument, meter
from music21.note import Note
from music21.stream import Score
# Creating the example score
n = Note("A2", type='quarter')
part = stream.Part()
measure = stream.Measure()
measure.append(n)
part.append(measure)
score = Score()
score.append(part)
p0 = score.parts[0].pitches[0]
print(p0)
p0.transpose(1, inPlace=True)
print(score.parts[0].pitches[0])

Related

Computing the Pearson Correlation coefficient between a set of model weights trained in Keras

I am training an ImageNet-pretrained VGG-16 model in Keras with two different hyperparameter settings. I prefer to see if there exists a linear relationship between the two sets of model weights. For simplicity, I have taken two VGG-16 models just to check if my approach works. I have computed the layer weights for each model and stored them as a 1-dimensional array, each having a shape of (1, 512). I wish to measure the Pearson Correlation coefficient between these two model weights as used in this study https://arxiv.org/pdf/1910.08475v2.pdf. My code is as shown below:
import os
from tensorflow import keras
from tensorflow.keras import backend as K
from tensorflow.keras.layers import *
from tensorflow.keras import applications
from tensorflow.keras.models import Model
from scipy.stats import pearsonr
from numpy import array
model_input = (224,224,3)
model1 = applications.VGG16(include_top=False,
weights='imagenet',
input_shape=model_input)
model1.summary()
n_layers1 = len(model1.get_weights())
for layer1 in range(n_layers1):
layer_weights1 = array([model1.get_weights()[layer1]]) # shape [1 x 512]
model2 = applications.VGG16(include_top=False,
weights='imagenet',
input_shape=model_input)
model2.summary()
n_layers2 = len(model2.get_weights())
for layer2 in range(n_layers2):
layer_weights2 = array([model2.get_weights()[layer2]]) # shape [1 x 512]
# calculate Pearson's correlation
corr, _ = pearsonr(layer_weights1, layer_weights2)
print('Pearsons correlation: %.3f' % corr)
I am getting the following error:
File "C:\Users\AppData\Local\Temp\2/ipykernel_16136/1139308701.py", line 1, in <module>
corr, _ = pearsonr(layer_weights1, layer_weights2)
File "C:\Users\AppData\Local\Continuum\anaconda3\envs\tf2.7\lib\site-packages\scipy\stats\stats.py", line 4016, in pearsonr
raise ValueError('x and y must have length at least 2.')
ValueError: x and y must have length at least 2.
Is my approach correct?
I found a solution to my problem. It is the shape mismatch error due to the syntax for the computation of the Pearson correlation coefficient. The revised code is as shown below:
import os
from tensorflow import keras
from tensorflow.keras import backend as K
from tensorflow.keras.layers import *
from tensorflow.keras import applications
from tensorflow.keras.models import Model
from scipy.stats import pearsonr
from numpy import array
import numpy as np
model_input = (224,224,3)
model1 = applications.VGG16(include_top=False,
weights='imagenet',
input_shape=model_input)
model1.summary()
n_layers1 = len(model1.get_weights())
for layer1 in range(n_layers1):
layer_weights1 = array([model1.get_weights()[layer1]])
model2 = applications.VGG16(include_top=False,
weights='imagenet',
input_shape=model_input)
model2.summary()
n_layers2 = len(model2.get_weights())
for layer2 in range(n_layers2):
layer_weights2 = array([model2.get_weights()[layer2]])
# calculate Pearson's correlation
x1 = layer_weights1.transpose()
x2 = layer_weights1.transpose()
x11 = x1.reshape(-1)
x22 = x2.reshape(-1)
corr, sig = pearsonr(x11, x22)
print('Pearsons correlation: %.4f' % corr)

only size-1 arrays can be converted to Python scalars / Rasterio

I have this code and my aim to calculate the sin of my raster in the power of 0.8.
import os
os.chdir('D:/NOA/Soil_Erosion/test_Project/Workspace/Input_Data_LS_Factor')
import rasterio
import math
data = rasterio.open('Slope_degrees_clipped.tif')
band = data.read(1) # array of float32 with size (3297,2537)
w = band.shape[0]
print(w)
h = band.shape[1]
print(h)
dtypes =data.dtypes[0]
band_calc = math.sin(band)**0.8 # the formula I would like to calculate
However, the following error pops up:
only size-1 arrays can be converted to Python scalars / Rasterio
May you know how I should fix this?
P.S. I tried to vectorize it (np.vectorize()) but it does not work as it needs a real number.
When I use the np.ndarray.flatten(band) the same error occurs.
I found the solution on Geographic Information Systems:
import os
os.chdir('D:/NOA/Soil_Erosion/test_Project/Workspace/Input_Data_LS_Factor')
import rasterio
import math
data = rasterio.open('Slope_degrees_clipped.tif')
from rasterio.plot import show
show(data)
band = data.read(1) # array of float32 with size (3297,2537)
w = band.shape[0]
print(w)
h = band.shape[1]
print(h)
dtypes =data.dtypes[0]
Calculate the sine of the raster in the power of 0.8
import numpy as np
band_calc2 = np.sin(band)**0.8 # the formula I would like to calculate
"""
another way to do it
band_calc = [ [] for i in range(len(band)) ]
for i,row in enumerate(band):
for element in row:
band_calc[i].append(math.sin(element*math.pi/180)**0.8)
"""

Coloring entries in an Matrix/2D-numpy array?

I'm learning python3 and I'd like to print a matrix/2d-array which is color-coded (CLI). So let's say I'd like to assign each of these integers a certain background color, creating a mosaic-style look.
I've figured out how to fill a matrix of a given size with random integers, but I can't wrap my head around on how to continue from here on to achieve background coloring for each individual entry in the matrix, depending on its value. This is how far I've come:
from random import randint
import numpy as np
def generate():
n = 10
m = 0
map = np.random.randint(4 + 1, size=(n, n))
print(map)
for element in np.nditer(map):
# iterating over each column is probably not the way to go...
generate()
Is there a way to do this? I was thinking of iterating through every column of the matrix and check by several if conditions whether the entry is 0,1,2,3 or 4 and, based on the condition, append that value with a certain background color to a new matrix, but I assume there is a far more elegant way to do this...
The following will print a colored output on console...
>>> map = np.random.randint(4 + 1, size=(10, 10))
>>> def get_color_coded_str(i):
... return "\033[3{}m{}\033[0m".format(i+1, i)
...
>>> map_modified = np.vectorize(get_color_coded_str)(map)
>>> print("\n".join([" ".join(["{}"]*10)]*10).format(*[x for y in map_modified.tolist() for x in y]))
>>>
To add background color use following fn
>>> def get_color_coded_str(i):
... return "\033[4{}m{}\033[0m".format(i+1, i)
from random import randint
import numpy as np
def get_color_coded_str(i):
return "\033[3{}m{}\033[0m".format(i+1, i)
def get_color_coded_background(i):
return "\033[4{}m {} \033[0m".format(i+1, i)
def print_a_ndarray(map, row_sep=" "):
n, m = map.shape
fmt_str = "\n".join([row_sep.join(["{}"]*m)]*n)
print(fmt_str.format(*map.ravel()))
n = 10
m = 20
map = np.random.randint(4 + 1, size=(n, m))
map_modified = np.vectorize(get_color_coded_str)(map)
print_a_ndarray(map_modified)
back_map_modified = np.vectorize(get_color_coded_background)(map)
print("-------------------------------------------------------")
print_a_ndarray(back_map_modified, row_sep="")
PS: print function modified as suggested by #hpaulj

IndexError: list assignment index out of range in python 2.7.11

I was just solving a problem using python, and my codes are:
from math import sin,pi
import numpy
import numpy as np
import pylab
N=20
x = np.linspace(0,1, N)
def v(x):
return 100*sin(pi*x)
#set up initial condition
u0 = [0.0] # Boundary conditions at t= 0
for i in range(1,N):
u0[i] = v(x[i])
And I would want to plot the results by updating v(x) in range(0, N) after. it looks simple but perhaps you guys could help since it gives me an error, like
Traceback (most recent call last):
File "/home/universe/Desktop/Python/sample.py", line 13, in <module>
u0[i] = v(x[i])
IndexError: list assignment index out of range
You could change u0[i] = v(x[i]) to u0.append(v(x[i])). But you should write more elegantly as
u0 = [v(xi) for xi in x]
Indices i are bug magnets.
Since you are using numpy, I'd suggest using np.vectorize. That way you can pass the array x directly to the function and the function will return an array of the same size with the function applied on each element of the input array.
from math import sin,pi
import numpy
import numpy as np
import pylab
N=20
x = np.linspace(0,1, N)
def v(x):
return 100*sin(pi*x)
vectorized_v = np.vectorize(v) #so that the function takes an array of x's and returns an array again
u0 = vectorized_v(x)
Out:
array([ 0.00000000e+00, 1.64594590e+01, 3.24699469e+01,
4.75947393e+01, 6.14212713e+01, 7.35723911e+01,
8.37166478e+01, 9.15773327e+01, 9.69400266e+01,
9.96584493e+01, 9.96584493e+01, 9.69400266e+01,
9.15773327e+01, 8.37166478e+01, 7.35723911e+01,
6.14212713e+01, 4.75947393e+01, 3.24699469e+01,
1.64594590e+01, 1.22464680e-14])
u is a list with one element, so you can't assign values to indices that don't exist. Instead make u a dictionary
u = {}
u[0] = 0.0
for i in range(1,N):
u[i] = v(x[i])

objects not aligned error

I'm using python 2.7
And trying to get this code to work and keep receiving an error
nsample = 50
sig = 0.25
x1 = np.linspace(0,20, nsample)
X = np.c_[x1, np.sin(x1), (x1-5)**2, np.ones(nsample)]
beta = masterAverageList
y_true = np.dot(X, beta)
y = y_true + sig * np.random.normal(size=nsample)
However I keep getting objects are not aligned error
I think it has something to do with master average list being a list?
I forgot to mention the master array list has 196 items in it if it matters. They are all floats
How can I correct this?
Thanks for any sugguestions
You should read up on numpy broadcasting here and here. You are trying to take the dot product between two arrays which have incompatible shapes.
>>> import numpy as np
>>> x1 = np.linspace(0,20,50)
>>> X = np.c_[x1,np.sin(x1),(x1-5)**2,np.ones(50)]
>>> beta = np.ones(196)
>>> y_true = np.dot(X,beta)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: matrices are not aligned
>>> X.shape
(50, 4)
>>> beta.shape
(196,)
I'm not sure what to recommend, since I don't know what you were expecting by taking the dot product between these arrays.

Resources