Python中是否有类似于Matlab numerictype/reinterpretcast的功能?

8
在Matlab中,有一个命令可以定义一个新的数字类型,例如:
numerictype(0,16,8) 

请查看文档:https://www.mathworks.com/help/fixedpoint/ref/embedded.numerictype.html

NumPy或其他库中是否有等价物?我能否使用类似的命令创建自己的dtype?


编辑:

由于被要求提供更多信息,这里有一个关于matlab中固定点数值类型如何工作的参考资料:https://www.mathworks.com/help/dsp/ug/concepts-and-terminology.html 基本上,您设置有符号/无符号属性,然后设置一个字的长度和小数位数。因此,例如在我给出的示例中,您将拥有一个带有16字长和10分数长度的有符号数。

从我阅读的关于结构化数组的文章中,似乎类似表示可能是以下内容之一:

dtype=[('signed', np.bool_), ('word', np.int16), ('frac', np.int16)]) 

我的终极目标是实现三个不同的重新解释转换语句,分别为:

reinterpretcast(EVMacq,numerictype(0,16,8))
reinterpretcast(Payload16c,numerictype(1,16,16))
reinterpretcast(Payload32,numerictype(1,32,32))

如果有更简单的方法,我很乐意用不同的方式完成。
以下是我在评论中添加的信息的转录:mathworks.com/help/fixedpoint/ref/reinterpretcast.html 这是来自Matlab的reinterpretcast的文档。实际上,您传入一个整数或定点数,该函数将会移动小数点周围。这使得即使二进制数据没有改变,变量的数值也不同。
偶尔,您可以通过普通除法在某些数字范围内实现类似的效果,但这并不是可靠的解决方案,也不是理想的解决方案。
我可能可以自己写一些东西来做到这一点,但我希望比我聪明的人已经做过了。考虑到大多数Matlab功能都包含在numpy中,我认为这也应该是如此。结构化数组可能是一个不错的选择,但我不确定转换成它们的工作方式。
编辑:
我现在意识到我真的只想关注一个单一的命令,如果有人告诉我如何做到与此转换完全等价的事情,我将非常高兴,因为我仍然无法弄清楚它。速度不是问题,它只需要运行即可。
这是命令:reinterpretcast(Payload16c,numerictype(1,16,16)) 其中Payload16c是由np.complex(real,imag)定义的复数数组。提前感谢您。
我尝试了类似这样的东西,但它不起作用,但可能正在正确的轨道上,我看起来比MatLab中发生的要少一些比例因子,但不是每次都是相同的比例因子。
    i = 0
    result = []

    #first generate a binary number that is a one in the highest spot and zero elsewhere
    comp = 2**wordlength
    #next iterate through entire array
    while i < array.size:

        #check to see if the value of the item is near the largest value it can be
        #if so its likely that it is just negative and thats why that bit is high
        if(array[i:i+1] < ((2**fracbits)-1000)):
            #if it is not near the largest number simply convert divide to move decimal place
            real = array[i:i+1] * (2**-fracbits) 
        else:
            #else we subtract comp so that we get the negative number this binary string was supposed to represent.
            # print(np.binary_repr(np.uint16(array[i:i+1])))
            real = double(array[i:i+1]) - comp 

            #then we divide it to move the decimal point properly
            real = real * (2**-fracbits)

        #same for the next number in the array which is the imaginary component
        if(array[i+1:i+2] < ((2**fracbits)-2000)):
            imag = array[i+1:i+2] * (2**-fracbits)
        else:
            imag = double(array[i+1:i+2]) - comp
            imag = imag * (2**-fracbits)

        result.append(np.complex(real,imag))
        i+=2
    return result

3
你能否为那些最近没有使用过MATLAB的人解释一下你试图实现什么?请注意,不要改变原意,尽量让语言通俗易懂。 - hpaulj
虽然复合数据类型易于构建和使用(请参见“结构化数组”),但任何更定制化的内容都需要一定程度的C编程(https://numpy.org/doc/stable/reference/c-api/dtype.html),这并不是我推荐给相对Python / NumPy初学者的东西(我甚至没有尝试过)。 - hpaulj
1
注意:这是关于Matlab的Fixed Point Designer的内容,它是一个专业应用程序(我会说是高级应用程序),而不是一般的Matlab类型。如果您在其他语言中寻找定点数学库,您可能会在那里找到相应的库。尽管从简短的谷歌搜索来看,目前似乎没有针对NumPy的定点库。 - Andrew Janke
我们已经重新开放了您的问题,但您仍然应该多说几句关于您期望的行为。reinterpretcast(...)并没有告诉我们您需要什么,除非我们特别熟悉Fixed Point工具箱,而我们大多数人(尤其是Python用户)并不熟悉。您想要实现什么功能?hpaulj建议的结构化数组是否涵盖了您的需求? - Andras Deak -- Слава Україні
1
快速的numpy代码使用标准的 c 数值类型 - int,float,double。它们的使用被编译代码所固定。用户定义的 dtypes 不太可能具有类似的性能 - 除非他们重写并重新编译 numpy。复合 dtypes 对于从文件加载混合数据很方便,但不允许您跨字段进行计算。如果需要特殊结构和良好的速度,则自定义 “c” 代码加上 “cython” 粘合剂可能是最佳选择。 - hpaulj
为什么不使用ndarray的最后一个维度,然后您可以将该最后维度视为一个单位,并且可以在其中拥有所需数量的整数。 - RichieV
2个回答

2
从Python程序员的角度来看,深入研究数据类型与Python语言本身的性质相悖。Python 是动态类型的,这意味着它缺乏效率,但易于编程。为了解决这个问题,许多流行的库都是用C语言编写的,因此你可能需要使用像numpy这样的库来实现你的类型转换。这里有一个在numpy中设置数据类型的例子。但据我所知,这些只适用于预定义的C类型。
理论上,你可能可以定义一个特殊的类来包含你的数据,实现__add____subtract__和其他必要的关键函数。然而,由于Python是动态类型的,这在实践中可能有限的回报。
另一个选择可能是Cython,它允许您在Python中定义C类型,但如果您只想要快速定义一种类型的函数,则Python的基本特性会与您相抗衡。

0
您可以使用np.dtype。我在以下片段中使用了您的dtype表示:
import numpy as np
dtype=[('signed', np.bool_), ('word', np.int16), ('frac', np.int16)] 
mytype = np.dtype(dtype)

你可以像这样在数组中使用它:

np.array([True,1,1],dtype=mytype)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接