问题
In Pyomo I want to solve the following minimization problem, which matches the playback rate and timing of two audio files:
import pyomo
from pyomo.environ import *
from pyomo.opt import SolverFactory
import soundfile as sf
import math
import numpy
#Create Model:
model = ConcreteModel()
#Declare Variables:
model.P = Var(initialize = 1, within=PositiveReals, bounds = (0.5,2))
model.T = Var(initialize = 0, within=Reals, bounds = (-500,500))
#Objective function:
def shift(data,rate,t,point):
Y=numpy.zeros(len(data))
for i in range(len(data)):
for j in range(point):
if math.floor(i*rate+t-j+point/2)>=0 and math.floor(i*rate+t-j+point/2)<=len(data)-1:
Y[i]+=data[math.floor(i*rate+t-j+point/2)]*numpy.sinc((math.floor(i*rate+t)-i*rate-t)-(j-point/2))
return Y
def obj_fun(model):
#Read data from audiofile:
Audio1, samplerate = sf.read('C:/Audio1.wav')
Audio2, samplerate = sf.read('C:/Audio2.wav')
Audio1=Audio1[:,0]
Audio2=Audio2[:,0]
Audio2= numpy.pad(Audio2,(0,len(Audio1)-len(Audio2)),'constant', constant_values=(0, 0))
return -1*numpy.sum(shift(Audio2,model.P,model.T,4)*Audio1)
#Create obj function:
model.obj = Objective(rule=obj_fun, sense=1)
The problem is the following error:
TypeError: Implicit conversion of Pyomo NumericValue type `<class 'pyomo.core.base.expr_coopr3._SumExpression'>' to a float is
disabled. This error is often the result of using Pyomo components as
arguments to one of the Python built-in math module functions when
defining expressions. Avoid this error by using Pyomo-provided math
functions.
The solver can't function unless numpy's/math's sinc and floor functions are changed. However, in Pyomo's documentation there is no reference to Pyomo-provided functions. What do I change the standard sinc/floor functions with in order to get the model object created without errors?
Also I am wondering whether there is a smarter way to read the data into the model. As of now, it's unnecessarily read on every pass of the objective function.
回答1:
Pyomo provided intrinsic functions (sin, log, etc.) are automatically imported with the line from pyomo.environ import *
. The problem is that you are importing math after that line which overwrites Pyomo's intrinsic functions with the ones from the math library. The solution is to remove the math import statement entirely or to move the math import statement above the pyomo import statement.
来源:https://stackoverflow.com/questions/48171498/finding-pyomo-provided-math-functions