使用iminuit时,python程序的输入等于输入的不同输出:未定义行为?

问题描述

我遇到了这些错误,这些错误使iminuit无法在纯朴的线性模型上收敛。但是,真正的问题是,如果我取消注释“ #bins = np.linspace(0,4,25)”行,则该程序的结果将有所不同,并且可以收敛。

如果“相同输入”不产生“相同输出”,则表示存在未定义的行为或分段错误。有什么想法吗?

import numpy as np
import scipy as sp
import scipy.special
import probfit
import pandas as pd
data = pd.read_feather('test.feather').rho2.to_numpy()
print(data)
N,bins = np.histogram(data,bins=24,range=(0,4))
#bins = np.linspace(0,25)
print(bins)
x = (bins[:-1]+bins[1:])/2

exposure = 3.8061025098100147
def cost(y0,k):
    global x,exposure,N
    T = (y0+k*x)*exposure
    return -2*np.sum(N*np.log(T)-T-sp.special.loggamma(N+1))

import iminuit
minimizer = iminuit.Minuit(cost,errordef=1,y0=11,k=3,limit_y0=(0,None),limit_k=(0.1,None))
minimizer.migrad()
minimizer.hesse()
minimizer.minos()
display(minimizer.fmin,minimizer.params,minimizer.merrors)
minimizer.draw_mncontour("y0","k")

输出output

测试输入

test.feather.zip

解决方法

该错误已解决。尽管使用print 看起来相同,但类型却不同:

data = pd.read_feather('test.feather').rho2.to_numpy()
N,bins = np.histogram(data,bins=24,range=(0,4))

vs

bins = np.linspace(0,4,25)

第一个返回float32,第二个返回float64iminuit需要使用数值方法来计算梯度,因此cost函数的输出精度必须至少为float64

最佳解决方案是

data = pd.read_feather('test.feather').rho2.to_numpy().astype('float64')