【发布时间】:2020-08-07 00:14:35
【问题描述】:
在 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)])
我的最终目标是实现三个独立的 reinterpertcast 语句,即:
reinterpretcast(EVMacq,numerictype(0,16,8))
reinterpretcast(Payload16c,numerictype(1,16,16))
reinterpretcast(Payload32,numerictype(1,32,32))
如果有更简单的方法来做这些,我很乐意用不同的方式来做。
这是我在 cmets 中添加的信息的转录:
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
【问题讨论】:
-
对于我们这些最近没有使用过 MATLAB 的人,请解释一下您想要实现的目标,
-
虽然复合 dtypes 易于构建和使用(参见
structured arrays),但任何更多的定制都需要一定程度的C编程(numpy.org/doc/stable/reference/c-api/dtype.html),这不是我推荐给亲戚的东西python/numpy 初学者(我还没试过)。 -
注意:这是专门关于 Matlab 的定点设计器的,它是一个专门的应用程序(我会说是一个高级应用程序),而不是一般的 Matlab 类型。如果您寻找其他语言的定点数学库,您可能会在那里找到等价物。虽然从简短的 Google 搜索来看,目前似乎没有 NumPy 的定点库。
-
我们已重新提出您的问题,但您仍应就您所期望的行为多说几句。
reinterpretcast(...)并没有真正告诉我们您需要什么,除非我们特别熟悉定点工具箱,而我们大多数人(尤其是 python 用户)并不熟悉。您想实现什么功能,hpaulj 建议的结构化数组是否涵盖了这一点? -
快速 numpy 代码使用标准的
c数字类型 - int、float、double。它们的用途是“嵌入”已编译的代码。用户定义的dtypes不太可能有类似的性能——除非他们重写和重新编译numpy。复合数据类型对于从文件加载混合数据很方便,但不允许您跨字段进行计算。如果您需要特殊的结构和不错的速度,自定义 'c' 代码加上 'cython' 胶水可能是最佳选择。