Related
from sympy import Sum, Eq
from sympy.abc import n,x
import random
def polynomial(x):
i = 0
def random_value(i):
return random.choice([i for i in range(-10,10) if i not in [0]])
eq = Sum(random_value(i)*x**n, (n,0,random_value(i)))
display(Eq(eq,eq.doit(), evaluate=False))
polynomial(x)
polynomial(x)
With this code, the coefficients are always the same.
Also, I am not sure if the algebra evaluations are correct for b < 0 .
One way is to use IndexedBase to generate symbolic-placeholder coefficients, and then substitute them with numerical coefficients.
from sympy import Sum, Eq, Matrix, IndexedBase
from sympy.abc import n, x
import random
def polynomial(x):
# n will go from zero to this positive value
to = random.randint(0, 10)
# generate random coefficients
# It is important for them to be a sympy Matrix or Tuple,
# otherwise the substitution (later step) won't work
coeff = Matrix([random.randint(-10, 10) for i in range(to + 1)])
c = IndexedBase("c")
eq = Sum(c[n]*x**n, (n, 0, to)).doit()
eq = eq.subs(c, coeff)
return eq
display(polynomial(x))
display(polynomial(x))
Another ways is to avoid using Sum, relying instead on list-comprehension syntax and builtin sum:
def polynomial(x):
to = random.randint(0, 10)
coeff = [random.randint(-10, 10) for i in range(to + 1)]
return sum([c * x**n for c, n in zip(coeff, range(to + 1))])
display(polynomial(x))
display(polynomial(x))
You can pass a list of coefficients (with highest order coefficient first and constant last) directly to Poly and then convert that to an expression:
>>> from sympy import Poly
>>> from sympy.abc import x
>>> Poly([1,2,3,4], x)
Poly(x**3 + 2*x**2 + 3*x + 4, x, domain='ZZ')
>>> _.as_expr()
x**3 + 2*x**2 + 3*x + 4
>>> from random import randint, choice
>>> Poly([choice((-1,1))*randint(1,10) for i in range(randint(0, 10))], x).as_expr()
-3*x**4 + 3*x**3 - x**2 - 6*x + 2
How to model the following problem with pyomo and Gurobi solver?
This is a non-convex problem, and can not model as a QCQP problem. So I want to solve it with pyomo and Gurobi solver. The most difficult part is matrix algebra (pyomo do not support yet).
Many thanks!
Here is my own answer. Please let me know if there are any mistakes. Thanks!
import pyomo.environ as pyo
## get your param
L, Delta =
K, P =
O, l =
ones3 = np.ones((3, 1))
model = pyo.ConcreteModel()
model.r = pyo.RangeSet(0,2) # 3
model.s = pyo.RangeSet(0,0) # 1
model.n = pyo.RangeSet(0,len(L)-1) # n
model.m = pyo.RangeSet(0,len(K)-1) # m
model.q = pyo.RangeSet(0,len(O)-1) # q
def param_rule(I, J, mat):
return dict(((i,j), mat[i,j]) for i in I for j in J)
model.L = pyo.Param(model.n, model.n, initialize=param_rule(model.n, model.n, L)) # L
model.Delta = pyo.Param(model.n, model.r, initialize=param_rule(model.n, model.r, Delta)) # Delta
model.K = pyo.Param(model.m, model.n, initialize=param_rule(model.m, model.n, K)) # K
model.P = pyo.Param(model.m, model.r, initialize=param_rule(model.m, model.r, P)) # P
model.O = pyo.Param(model.q, model.n, initialize=param_rule(model.q, model.n, O)) # O
model.ones3 = pyo.Param(model.r, model.s, initialize=param_rule(model.r, model.s, ones3)) # ones3
model.l = pyo.Param(model.q, initialize=dict(((i),l[i,0]) for i in model.q)) # l
model.V = pyo.Var(model.n, model.r, initialize=param_rule(model.n, model.r, Delta)) # V
def ObjRule(model):
return 0.5*sum((sum(model.L[i,k]*model.V[k,j] for k in model.n) - model.Delta[i,j])**2 for i in model.n for j in model.r)
model.obj = pyo.Objective(rule=ObjRule, sense=pyo.minimize)
model.constraints = pyo.ConstraintList()
# constraints 1
[model.constraints.add(sum(model.K[i,k] * model.V[k,j] for k in model.n) == model.P[i,j]) for i in model.m for j in model.r]
# constraint 2
for i in model.q:
model.constraints.add(sum(sum(model.O[i,k] * model.V[k,j] for k in model.n)**2 for j in model.r) == model.l[i])
opt = pyo.SolverFactory('gurobi')
opt.options['nonconvex'] = 2
solution = opt.solve(model)
V_opt = np.array([pyo.value(model.V[i,j]) for i in model.n for j in model.r]).reshape(len(model.n),len(model.r))
obj_values = pyo.value(model.obj)
print("optimum point: \n {} ".format(V_opt))
print("optimal objective: {}".format(obj_values))
I'm trying to plot and compare the frequency spectrum of two .wav files. I wrote the following in python for that:
import pylab
import time
from scipy import fft, arange
from numpy import linspace
from scipy.io.wavfile import read
import gc
import sys
params = {'figure.figsize': (20, 15)}
pylab.rcParams.update(params)
def plotSpec(y, Fs):
n = len(y) # lungime semnal
k = arange(n)
T = n / Fs
frq = k / T # two sides frequency range
frq = frq[range(n / 2)] # one side frequency range
ff_valu = fft(y) / n # fft computing and normalization
ff_valu = ff_valu[range(n / 2)]
pylab.plot(frq, abs(ff_valu), 'r') # plotting the spectrum
pylab.tick_params(axis='x', labelsize=8)
pylab.tick_params(axis='y', labelsize=8)
pylab.tick_params()
pylab.xticks(rotation=45)
pylab.xlabel('Frequency')
pylab.ylabel('Power')
del frq, ff_valu, n, k, T, y
gc.collect()
return
def graph_plot(in_file, graph_loc, output_folder, count, func_type):
graph_loc = int(graph_loc)
rate = 0
data = 0
rate, data = read(in_file)
dlen = len(data)
print "dlen=", dlen
lungime = dlen
timp = dlen / rate
print "timp=", timp
t = linspace(0, timp, dlen)
pylab.subplot(3, 2, graph_loc)
pylab.plot(t, data)
fl = in_file.split('/')
file_name = fl[len(fl) - 1]
pylab.title(file_name)
pylab.tick_params(axis='x', labelsize=8)
pylab.tick_params(axis='y', labelsize=8)
pylab.xticks(rotation=45)
pylab.xlabel('Time')
pylab.ylabel('Numerical level')
pylab.subplot(3, 2, graph_loc + 2)
plotSpec(data, rate)
pylab.subplot(3, 2, graph_loc + 4)
if rate == 16000:
frq = 16
else:
frq = 8
pylab.specgram(data, NFFT=128, noverlap=0, Fs=frq)
pylab.tick_params(axis='x', labelsize=8)
pylab.tick_params(axis='y', labelsize=8)
pylab.xticks(rotation=45)
pylab.xlabel('Time')
pylab.ylabel('Frequency')
if graph_loc == 2:
name = in_file.split("/")
lnth = len(name)
name = in_file.split("/")[lnth - 1].split(".")[0]
print "File=", name
if func_type == 'a':
save_file = output_folder + 'RESULT_' + name + '.png'
else:
save_file = output_folder + 'RESULT_graph.png'
pylab.savefig(save_file)
pylab.gcf()
pylab.gca()
pylab.close('all')
del in_file, graph_loc, output_folder, count, t, rate, data, dlen, timp
gc.get_referrers()
gc.collect()
def result_plot(orig_file, rec_file, output_folder, seq):
graph_loc = 1
graph_plot(orig_file, graph_loc, output_folder, seq, 'a')
graph_loc = 2
graph_plot(rec_file, graph_loc, output_folder, seq, 'a')
sys.exit()
save_file="~/Documents/Output/"
o_file='~/Documents/audio/orig_8sec.wav'
#o_file='~/Documents/audio/orig_4sec.wav'
r_file='~/Documents/audio/rec_8sec.wav'
#r_file='~/Documents/audio/rec_4sec.wav'
print 10*"#"+"Start"+10*"#"
result_plot(o_file, r_file,save_file, 'a')
print 10*"#"+"End"+10*"#"
pylab.close('all')
With the above code, I see that the scale of y-axis appear different:
It clearly shows an automatically assigned scale. With this any amplification or attenuation with respect to the original file is difficult to be made obvious unless the person looks up the values.
Since I cannot really predict what would be the max amplitude among either files when I use multiple samples, how can I make both y-axis on each subplot set to the max of either so that the scale is the same and amplification is more clear?
I am adding my explanation you asked for in the comments above as an answer below. The idea is to selectively modify the x-axis limits for some particular subplots
fig, axes = plt.subplots(2,3,figsize=(16,8))
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
for i, row in enumerate(axes):
for j, col in enumerate(row):
col.plot(x, y)
col.set_title("Title here", fontsize=18)
if i == 1 and (j == 1 or j == 2):
col.set_xlim(0, np.pi)
plt.tight_layout()
Output
An alternative to setting the limits yourself is to create the figure and axes first using
fig, axes = plt.subplots(3, 2)
This has an optional argument sharex. From the docs
sharex, sharey : bool or {'none', 'all', 'row', 'col'}, default: False
Controls sharing of properties among x (sharex) or y (sharey) axes:
True or 'all': x- or y-axis will be shared among all subplots.
False or 'none': each subplot x- or y-axis will be independent.
'row': each subplot row will share an x- or y-axis.
'col': each subplot column will share an x- or y-axis.
Therefore, we can make sure the rows share the same x axis values as each other by using the argument sharex="row":
fig, axes = plt.subplots(3, 2, sharex="row")
If you want the y axis to be shared you can use sharey="row" instead/aswell.
Taking cues from other answers, I happened to make it work the following way:
import matplotlib.pyplot as pl
import time
from scipy import fft, arange
from numpy import linspace
from scipy.io.wavfile import read
import gc
import sys
def plotWavAmplLev(in_file, sub_graph):
print "Printing Signal graph (amplitude vs seconds)...."
rate, data = read(in_file)
dlen = len(data)
timp = dlen / rate
t = linspace(0,timp,dlen)
sub_graph.plot(t, data)
fl = in_file.split('/')
file_name = fl[len(fl) - 1]
sub_graph.set_title(file_name)
sub_graph.tick_params(axis='x', labelsize=10)
sub_graph.tick_params(axis='y', labelsize=10)
sub_graph.set_xlabel('Time')
sub_graph.set_ylabel('Numerical level')
def plotSpectralDensity(y, fs, sub_graph):
print "Printing Power Spectral Density (dB vs Hz)...."
n = len(y) # lungime semnal
k = arange(n)
T = n / fs
frq = k / T # two sides frequency range
frq = frq[range(n / 2)] # one side frequency range
ff_valu = fft(y) / n # fft computing and normalization
ff_valu = ff_valu[range(n / 2)]
sub_graph.plot(frq, abs(ff_valu), 'r') # plotting the spectrum
sub_graph.tick_params(axis='x', labelsize=10)
sub_graph.tick_params(axis='y', labelsize=10)
sub_graph.tick_params()
sub_graph.set_xlabel('Frequency')
sub_graph.set_ylabel('Power')
del frq, ff_valu, n, k, T, y
gc.collect()
return
def plotSpectrogram(rate, data, sub_graph):
print "Plotting Spectrogram (kHz vs seconds)...."
if rate == 16000:
frq = 16
else:
frq = 8
sub_graph.specgram(data, NFFT=128, noverlap=0, Fs=frq)
sub_graph.tick_params(axis='x', labelsize=10)
sub_graph.tick_params(axis='y', labelsize=10)
sub_graph.set_xlabel('Time')
sub_graph.set_ylabel('Frequency')
def graph_plot(in_file_list, output_folder, func_type):
orig_file = in_file_list[0]
rec_file = in_file_list[1]
g_index = 1
g_rows = 3
g_cols = 2
fig, axes = pl.subplots(g_rows, g_cols, figsize=(20,15), sharex="row", sharey="row")
for i, row in enumerate(axes):
for j, col in enumerate(row):
if i == 0 :
if j == 0:
print "Source file waveform is being plotted...."
rate, data = read(orig_file)
plotWavAmplLev(orig_file, col)
continue
elif j == 1:
print "Recorded file waveform is being plotted...."
rate, data = read(rec_file)
plotWavAmplLev(rec_file, col)
continue
elif i == 1:
if j == 0:
print "Source file PSD is being plotted...."
rate, data = read(orig_file)
plotSpectralDensity(data, rate, col)
continue
elif j == 1:
print "Recorded file PSD is being plotted...."
rate, data = read(rec_file)
plotSpectralDensity(data, rate, col)
continue
elif i == 2:
if j == 0:
print "Source file Spectrogram is being plotted...."
rate, data = read(orig_file)
plotSpectrogram(rate, data, col)
continue
elif j == 1:
print "Recorded file Spectrogram is being plotted...."
rate, data = read(rec_file)
plotSpectrogram(rate, data, col)
continue
pl.tight_layout()
name = in_file_list[1].split("/")
lnth = len(name)
name = in_file_list[1].split("/")[lnth - 1].split(".")[0]
print "File=", name
if func_type == 'a':
save_file = output_folder + 'RESULT_' + name + '.png'
else:
save_file = output_folder + 'RESULT_graph.png'
pl.savefig(save_file)
pl.gcf()
pl.gca()
pl.close('all')
del in_file_list, output_folder, rate, data
gc.get_referrers()
gc.collect()
def result_plot(orig_file, rec_file, output_folder, seq):
flist = [orig_file, rec_file]
graph_plot(flist, output_folder, 'a')
s_file="/<path>/Output/"
#o_file='/<path>/short_orig.wav'
o_file='/<path>/orig.wav'
#r_file='/<path>/short_rec.wav'
r_file='/<path>/rec.wav'
print 10*"#"+"Start"+10*"#"
result_plot(o_file, r_file,s_file, 'a')
print 10*"#"+"End"+10*"#"
pl.close('all')
Now, I got the y-axis scales fixed and get the output as follows:
This makes comparison a lot easier now.
I have a script as follows:
import numpy as np
import pandas as pd
import pdb
# conventions: W = fitness, A = affinity ; sex: 1=M, 0=F; alien: 1=alien,
# 0=native
# pop array order: W, A, sex, alien
def mkpop(n):
W = np.repeat(a=1, repeats=n)
A = np.random.normal(1, 0.1, size=n)
A[A < 0] = 0
alien = np.repeat(a=False, repeats=n)
sex = np.random.randint(0, 2, n)
pop = np.array([W, A, sex, alien])
pop = np.transpose(pop)
return pop
def migrate(pop, n=10, gParams=[1, 0.1]):
W = np.random.gamma(shape=gParams[0], scale=gParams[1], size=n)
A = np.repeat(1, n)
# 0 is native; 1 is alien
alien = np.repeat(True, n)
# 0 is female
sex = np.random.randint(0, 2, n)
popAlien = np.array([W, A, sex, alien])
popAlien = np.transpose(popAlien)
pop = np.vstack((pop, popAlien))
return pop
def mate(pop):
# split into male and female
f = pop[pop[:, 2] == 0]
m = pop[pop[:, 2] == 1]
# create transition matricies for native and alien mates
# m with native = m.!alien.transpose * f.alien
# negate alien
naLog = list(np.asarray(m[:, 3]) == False)
naPdMat = np.outer(naLog, f[:, 1])
# mate with alien = m.alien.transpose * affinity
alPdMat = np.outer(m[:, 3], f[:, 1])
# add transition matrices for probability density matrix
pdMat = alPdMat + naPdMat
# transition matrix is equal to the pd matrix / column sumso
colSums = np.sum(pdMat, axis=0)
pMat = pdMat / colSums
# select mates
def choice(x):
ch = np.random.choice(a=range(0, len(x)), p=x)
return ch
mCh = np.apply_along_axis(choice, 0, pMat)
mCh = m[mCh, :]
WMid = (f[:, 0] + mCh[:, 0]) / 2
AMid = (f[:, 1] + mCh[:, 1]) / 2
# assign fitness based on group affiliation; only native/alien matings have
# modified fitness
# reassign fitness and affinity based on group id and midparent vals
W1 = np.where(
(f[:, 3] == mCh[:, 3]) |
((f[:, 3] == 1) & (mCh[:, 3] == 0))
)
WMid[W1] = 1
# number of offspring is a poisson-distributed variable with lambda=2W
nOff = map(lambda x: np.random.poisson(lam=x), 2 * WMid)
# generate offspring
# expand list of nOff to numbers of offspring per pair
# realized offspring is index posisions of W and A vals to be replicated
# for offspring
# this can be rewritten to return a matrix of the appropriate length. This
# should work
midVals = np.array([WMid, AMid]).T
realOff = np.array([0, 0])
for i in range(0, len(nOff)):
sibs = np.repeat([np.array(midVals[i])], [nOff[i]], axis=0)
realOff = np.vstack((realOff, sibs))
offspring = np.delete(realOff, 0, 0)
sex = np.random.randint(0, 2, len(offspring))
alien = np.repeat(0, len(offspring))
otherStats = np.array([sex, alien]).T
offspring = np.hstack([offspring, otherStats])
return offspring # should return offspring
def sim(nInit, nGen=100, nAlien=10, gParams=[1, 0.1]):
gen = 0
pop = mkpop
stats = pd.DataFrame(columns=('gen', 'W', 'WMean', 'AMean', 'WVar', 'AVar'))
while gen < nGen:
pop = migrate(pop, nAlien, gParams)
offspring = mate(pop)
var = np.var(offspring, axis=0)
mean = np.mean(offspring, axis=0)
N = len(offspring)
W = N / nInit
genStats = N.append(W, gen, mean, var)
stats = stats.append(genStats)
print(N, gen)
gen = gen + 1
return stats
print mkpop(100)
print mate(mkpop(100))
#
sim(100, 100, 10, [1, 0.1])
Running this script, outputs NameError: name 'sim' is not defined. It is apparent from the commands before the final one that all the other functions defined within this script work without a hitch. I'm not sure what is going on here, and there is probably some very easy fix that I'm overlooking. Ctags recognizes this function just fine. It's entirely possibe that sim() doesn't actually work yet, as I haven't been able to debug it.
Your sim function defined in mate function scope so it's invisible to global scope. You need to fix your indentation for sim function
I have an elliptic curve plotted. I want to draw a line along a P,Q,R (where P and Q will be determined independent of this question). The main problem with the P is that sympy solve() returns another equation and it needs to instead return a value so it can be used to plot the x-value for P. As I understood it, solve() should return a value, so I'm clearly doing something wrong here that I'm just totally not seeing. For reference, here's how P+Q=R should look:
I've been going over the docs and other material and this is as far as I've been able to get myself into trouble:
from mpl_toolkits.axes_grid.axislines import SubplotZero
from pylab import *
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
import matplotlib.patches as patches
from matplotlib import rc
import random
from sympy.solvers import solve
from sympy import *
def plotGraph():
fig = plt.figure(1)
#ax = SubplotZero(fig, 111)
#fig.add_subplot(ax)
#for direction in ["xzero", "yzero"]:
#ax.axis[direction].set_axisline_style("-|>")
#ax.axis[direction].set_visible(True)
#ax.axis([-10,10,-10,10])
a = -2; b = 1
y, x = np.ogrid[-10:10:100j, -10:10:100j]
xlist = x.ravel(); ylist = y.ravel()
elliptic_curve = pow(y, 2) - pow(x, 3) - x * a - b
plt.contour(xlist, ylist, elliptic_curve, [0])
#rand = random.uniform(-5,5)
randmid = random.randint(30,70)
#y = ylist[randmid]; x = xlist[randmid]
xsym, ysym = symbols('x ylist[randmid]')
x_result = solve(pow(ysym, 2) - pow(xsym, 3) - xsym * a - b, xsym) # 11/5/13 needs to return a value
plt.plot([-1.5,5], [-1,8], color = "c", linewidth=1) # plot([x1,x2,x3,...],[y1,y2,y3,...])
plt.plot([xlist[randmid],5], [ylist[randmid],8], color = "m", linewidth=1)
#rc('text', usetex=True)
text(-9,6,' size of xlist: %s \n size of ylist: %s \n x_coord: %s \n random_y: %s'
%(len(xlist),len(ylist),x_result,ylist[randmid]),
fontsize=10, color = 'blue',bbox=dict(facecolor='tan', alpha=0.5))
plt.annotate('$P+Q=R$', xy=(2, 1), xytext=(3, 1.5),arrowprops=dict(facecolor='black', shrink=0.05))
## verts = [(-5, -10),(5, 10)] # [(x,y)startpoint,(x,y)endpoint] #,(0, 0)]
## codes = [Path.MOVETO,Path.LINETO] # related to verts[] #,Path.STOP]
## path = Path(verts, codes)
## patch = patches.PathPatch(path, facecolor='none', lw=2)
## ax.add_patch(patch)
plt.grid(True)
plt.show()
def main():
plotGraph()
if __name__ == '__main__':
main()
Ultimately, I'd like to draw a line to show P+Q=R, so if someone also has something to add on how to code to get the Q that would be greatly appreciated. I'm teaching myself about Python and elliptic curves so I'm sure that any entry-level programmer can figure out in 2 minutes what I've been on for some time already.
I don't know what are you calculating, but here is the code that can plot the graph:
import numpy as np
import pylab as pl
Y, X = np.mgrid[-10:10:100j, -10:10:100j]
def f(x):
return x**3 -3*x + 5
px = -2.0
py = -np.sqrt(f(px))
qx = 0.5
qy = np.sqrt(f(qx))
k = (qy - py)/(qx - px)
b = -px*k + py
poly = np.poly1d([-1, k**2, 2*k*b+3, b**2-5])
x = np.roots(poly)
y = np.sqrt(f(x))
pl.contour(X, Y, Y**2 - f(X), levels=[0])
pl.plot(x, y, "o")
pl.plot(x, -y, "o")
x = np.linspace(-5, 5)
pl.plot(x, k*x+b)
graph:
based on HYRY's answer, I just update some details to make it better:
import numpy as np
import pylab as pl
Y, X = np.mgrid[-10:10:100j, -10:10:100j]
def f(x, a, b):
return x**3 + a*x + b
a = -2
b = 4
# the 1st point: 0, -2
x1 = 0
y1 = -np.sqrt(f(x1, a, b))
print(x1, y1)
# the second point
x2 = 3
y2 = np.sqrt(f(x2, a, b))
print(x2, y2)
# line: y=kl*x+bl
kl = (y2 - y1)/(x2 - x1)
bl = -x1*kl + y1 # bl = -x2*kl + y2
# y^2=x^3+ax+b , y=kl*x+bl => [-1, kl^2, 2*kl*bl, bl^2-b]
poly = np.poly1d([-1, kl**2, 2*kl*bl-a, bl**2-b])
# the roots of the poly
x = np.roots(poly)
y = np.sqrt(f(x, a, b))
print(x, y)
pl.contour(X, Y, Y**2 - f(X, a, b), levels=[0])
pl.plot(x, y, "o")
pl.plot(x, -y, "o")
x = np.linspace(-5, 5)
pl.plot(x, kl*x+bl)
And we got the roots of this poly:
[3. 2.44444444 0. ] [5. 3.7037037 2. ]