Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何加快计算速度以找到表格N/2**M的最接近表示形式_Python_Performance_Minimization - Fatal编程技术网

Python 如何加快计算速度以找到表格N/2**M的最接近表示形式

Python 如何加快计算速度以找到表格N/2**M的最接近表示形式,python,performance,minimization,Python,Performance,Minimization,我想在python中以N/2**M的形式找到最接近的浮点数表示形式,其中N和M是整数。我试图使用scipy.optimize中的最小化函数,但它不能局限于N和M为整数的情况 我最终使用了一个简单的实现,它迭代M和N的值并找到最小值,但是对于许多数字的数组来说,这在计算上是昂贵和耗时的,有什么更好的方法呢 我的简单实现如下所示: import numpy as np def ValueRepresentation(X): M, Dp = X return M/(2**Dp) d

我想在python中以N/2**M的形式找到最接近的浮点数表示形式,其中N和M是整数。我试图使用scipy.optimize中的最小化函数,但它不能局限于N和M为整数的情况

我最终使用了一个简单的实现,它迭代M和N的值并找到最小值,但是对于许多数字的数组来说,这在计算上是昂贵和耗时的,有什么更好的方法呢

我的简单实现如下所示:

import numpy as np

def ValueRepresentation(X):
    M, Dp = X
    return M/(2**Dp)

def Diff(X, value):
    return abs(ValueRepresentation(X) - value)

def BestApprox(value):
    mindiff = 1000000000
    for i in np.arange(0, 1000, 1):
        for j in np.arange(0, 60, 1):
            diff = Diff([i, j], value)            
            if diff < mindiff:
                mindiff = diff
                M = i
                Dp = j
    return M, Dp
def BestApprox_fast(value):
    mindiff = 1000000000
    for Dp in np.arange(0, 32, 1):
        M = round(value*2**Dp)
        if abs(M) < 1000:
            diff = Diff([M, Dp], value)
            if diff < mindiff:
                mindiff = diff
                M_best = M
                Dp_best = Dp
    return M_best, Dp_best
将numpy导入为np
def值表示法(X):
M、 Dp=X
返回M/(2**Dp)
def差异(X,值):
返回abs(值表示法(X)-值)
def最佳近似值(值):
mindiff=100000000
对于np.arange中的i(0,1000,1):
对于np.arange(0,60,1)中的j:
diff=diff([i,j],值)
如果差异
多亏了jasonharper,我意识到我的实现效率低得离谱,可以简单得多

他的方法的实现如下所示:

import numpy as np

def ValueRepresentation(X):
    M, Dp = X
    return M/(2**Dp)

def Diff(X, value):
    return abs(ValueRepresentation(X) - value)

def BestApprox(value):
    mindiff = 1000000000
    for i in np.arange(0, 1000, 1):
        for j in np.arange(0, 60, 1):
            diff = Diff([i, j], value)            
            if diff < mindiff:
                mindiff = diff
                M = i
                Dp = j
    return M, Dp
def BestApprox_fast(value):
    mindiff = 1000000000
    for Dp in np.arange(0, 32, 1):
        M = round(value*2**Dp)
        if abs(M) < 1000:
            diff = Diff([M, Dp], value)
            if diff < mindiff:
                mindiff = diff
                M_best = M
                Dp_best = Dp
    return M_best, Dp_best
def最佳近似值(值):
mindiff=100000000
对于np.arange(0,32,1)中的Dp:
M=四舍五入(值*2**Dp)
如果abs(M)<1000:
差异=差异([M,Dp],值)
如果差异

这大约快了200倍。

多亏了jasonharper,我意识到我的实现效率低得离谱,可能会简单得多

他的方法的实现如下所示:

import numpy as np

def ValueRepresentation(X):
    M, Dp = X
    return M/(2**Dp)

def Diff(X, value):
    return abs(ValueRepresentation(X) - value)

def BestApprox(value):
    mindiff = 1000000000
    for i in np.arange(0, 1000, 1):
        for j in np.arange(0, 60, 1):
            diff = Diff([i, j], value)            
            if diff < mindiff:
                mindiff = diff
                M = i
                Dp = j
    return M, Dp
def BestApprox_fast(value):
    mindiff = 1000000000
    for Dp in np.arange(0, 32, 1):
        M = round(value*2**Dp)
        if abs(M) < 1000:
            diff = Diff([M, Dp], value)
            if diff < mindiff:
                mindiff = diff
                M_best = M
                Dp_best = Dp
    return M_best, Dp_best
def最佳近似值(值):
mindiff=100000000
对于np.arange(0,32,1)中的Dp:
M=四舍五入(值*2**Dp)
如果abs(M)<1000:
差异=差异([M,Dp],值)
如果差异

速度大约快200倍。

只需使用内置功能即可:

In [10]: 2.5.as_integer_ratio()  # get representation as fraction
Out[10]: (5, 2)

In [11]: (2).bit_length() - 1    # convert 2**M to M
Out[11]: 1

请注意,所有非无限、非NaN浮点都是并矢有理数,因此我们可以依赖分母为2的精确幂。

只需使用内置功能:

In [10]: 2.5.as_integer_ratio()  # get representation as fraction
Out[10]: (5, 2)

In [11]: (2).bit_length() - 1    # convert 2**M to M
Out[11]: 1

请注意,所有非无限、非NaN浮点都是并矢有理数,因此我们可以依赖分母为2的精确幂。

给定M和N的限制后,N/2**M的范围是一个定义良好的离散数标度:

[0-1000/2^26501-1000/2^25501-1000/2^24,…501-1000/2^11501-1000/2^0]

在这个给定的离散集合中,不同的子集具有不同的精度/分辨率。第一个子集[0-1000/2^26]的精度为2^-26或26二进制位分辨率。因此,当给定的数字落在相应的连续域[01000/2^26]中时,可达到的最佳精度为2^-26。依次地,当给定数字超出第一个域但落在域[500/2^251000/2^25]中时,最佳精度为2^25,该域对应于第二个子集[501-1000/2^25]。(注意离散集和连续域之间的区别。)

根据上述逻辑,我们知道由M定义的最佳精度取决于给定数字在刻度上的位置。因此,我们可以按照以下python代码实现它:

import numpy as np

limits = 1000.0/2**np.arange(0,61)

a = 103.23    # test value
for i in range(60,-1,-1):
    if a <= limits[i]:
        N = i
        M = round(a * 2**N)
        r = [M, N]
        break

if a > 1000:
    r = [round(a), 0]
将numpy导入为np
限值=1000.0/2**np.arange(0,61)
a=103.23#测试值
对于范围(60,-1,-1)内的i:
如果是1000:
r=[第(a)轮,0]

此解决方案的执行时间为O(c),因此非常适合多次调用。

给定M和N的限制后,N/2**M的范围是一个定义良好的离散数字范围:

[0-1000/2^26501-1000/2^25501-1000/2^24,…501-1000/2^11501-1000/2^0]

在这个给定的离散集合中,不同的子集具有不同的精度/分辨率。第一个子集[0-1000/2^26]的精度为2^-26或26二进制位分辨率。因此,当给定的数字落在相应的连续域[01000/2^26]中时,可达到的最佳精度为2^-26。依次地,当给定数字超出第一个域但落在域[500/2^251000/2^25]中时,最佳精度为2^25,该域对应于第二个子集[501-1000/2^25]。(注意离散集和连续域之间的区别。)

根据上述逻辑,我们知道由M定义的最佳精度取决于给定数字在刻度上的位置。因此,我们可以按照以下python代码实现它:

import numpy as np

limits = 1000.0/2**np.arange(0,61)

a = 103.23    # test value
for i in range(60,-1,-1):
    if a <= limits[i]:
        N = i
        M = round(a * 2**N)
        r = [M, N]
        break

if a > 1000:
    r = [round(a), 0]
将numpy导入为np
限值=1000.0/2**np.arange(0,61)
a=103.23#测试值
对于范围(60,-1,-1)内的i:
如果是1000:
r=[第(a)轮,0]

此解决方案具有O(c)执行时间,因此非常适合多次调用。

在N和M上循环效率极低。仅在M上循环(因为这是一个具有较小的可能值集的循环),计算相应的N,如果它超出了N的允许范围,则拒绝它。此外,您正在使用numpy,但仍在单独使用它进行迭代,因此,您根本没有从它可能提供的数组/矩阵优化中获益。我忽略了一些东西,但因为您已经有了一个特定的浮点值,并且它的二进制表示形式已经将指数和尾数存储在基数2中,难道你就不能提取这些值吗?在N和M上循环是非常低效的。仅在M上循环(因为这是一个具有较小的可能值集的循环),计算相应的N,如果它超出了N的允许范围,则拒绝它。此外,您正在使用numpy,但仍在单独使用它进行迭代,因此,您根本没有从它可能提供的数组/矩阵优化中获益。我忽略了一些东西,但是因为您已经有了一个特定的浮点值,而且它的二进制表示形式