在Pyomo中我想解决以下最小化问题,它与两个音频文件的播放速率和时间相匹配:
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)
问题是以下错误:
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.
除非numpy的/ s&s的sinc和floor函数发生变化,否则解算器无法正常工作。但是,在Pyomo的文档中没有提到Pyomo提供的函数。我如何更改标准sinc / floor函数以便创建没有错误的模型对象?
此外,我想知道是否有更智能的方法将数据读入模型。截至目前,它在目标函数的每次传递中都会被不必要地读取。
答案 0 :(得分:1)
Pyomo提供的内部函数(sin,log等)会自动导入行from pyomo.environ import *
。问题是您在该行之后导入数学,该数字用数学库中的函数覆盖Pyomo的内部函数。解决方案是完全删除math import语句或将math import语句移到pyomo import语句之上。