- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我将一些使用 NumPy 的代码移植到 Cython 中以获得一些性能提升。我取得了相当大的进步,但我遇到了一个问题。
Cython 得到的结果与Python 得到的结果不同。我不知道为什么会这样,所以我决定查看将什么推送到 Cython 模块。
在到达 Cython 之前,数据如下所示:
azimuth = 0.000349065850399
rawDistance = [ 2.682 7.234 2.8 7.2 2.912 7.19 3.048 7.174 3.182 7.162
3.33 7.164 3.506 7.158 3.706 7.154 3.942 7.158 4.192 7.158
4.476 7.186 4.826 7.19 5.218 7.204 5.704 7.224 6.256 7.248
6.97 7.284]
intensity = [19 34 25 28 26 48 21 56 21 60 31 49 24 37 26 37 34 37 23 84 15 59 23 45
18 47 20 55 18 36 15 39]
一旦它进入 Cython,同样的数据看起来像:
azimuth = 0.000349065850399
rawDistance = [2.686, 7.23, 2.7960000000000003, 7.204, 2.91, 7.188, 3.044, 7.174, 3.19,
7.16, 3.3280000000000003, 7.16, 3.5, 7.154, 3.704, 7.144, 3.936, 7.158,
4.196, 7.156000000000001, 4.478, 7.19, 4.8260000000000005, 7.192, 5.22,
7.204, 5.708, 7.22, 6.256, 7.252, 6.97, 7.282]
intensity = [19, 34, 27, 28, 26, 48, 22, 52, 21, 60, 31, 49, 24, 37, 28, 34, 32, 37,
23, 84, 15, 59, 23, 45, 18, 47, 20, 58, 18, 36, 15, 36]
这就解释了为什么结果与纯Python方法计算的结果不完全一样。
这是信息被传输到的 Cython 模块:
from libc.math cimport sin, cos
import numpy as np
cimport numpy as np
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
def calculateXYZ(list frames, double[:] cosVertCorrection, double[:] sinVertCorrection):
cdef long numberFrames = len(frames)
cdef long i, j, k, numberBlocks
cdef list finalResults = []
cdef list intensities = []
cdef list frameXYZ = []
cdef double azimuth, xy, x, y, z, sinRotational, cosRotational
cdef double[32] rawDistance
cdef int[32] intensity
cdef double[:] tempX
cdef double[:] tempY
cdef double[:] tempZ
cdef int positionsFilled = 0
for i in xrange(numberFrames):
numberBlocks = len(frames[i])
tempX = np.zeros(numberBlocks * 32, dtype=np.double)
tempY = np.zeros(numberBlocks * 32, dtype=np.double)
tempZ = np.zeros(numberBlocks * 32, dtype=np.double)
frameXYZ = [[] for i in range(3)]
positionsFilled = 0
for j in xrange(numberBlocks):
# This is where I tested for the data in Cython
# This is the information that is different.
# It is reading from what was passed to it from python.
azimuth = frames[i][j][0]
rawDistance = frames[i][j][1]
intensity = frames[i][j][2]
sinRotational, cosRotational = sin(azimuth), cos(azimuth)
for k in xrange(32):
xy = rawDistance[k] * cosVertCorrection[k]
x, y = xy * sinRotational, xy * cosRotational
z = rawDistance[k] * sinVertCorrection[k]
if x != 0 or y != 0 or z != 0:
tempX[positionsFilled] = x
tempY[positionsFilled] = y
tempZ[positionsFilled] = z
intensities.append(intensity[k])
positionsFilled = positionsFilled + 1
frameXYZ[0].append(np.asarray(tempX[0:positionsFilled].copy()).tolist())
frameXYZ[1].append(np.asarray(tempY[0:positionsFilled].copy()).tolist())
frameXYZ[2].append(np.asarray(tempZ[0:positionsFilled].copy()).tolist())
finalResults.append(frameXYZ)
return finalResults, intensities
这是它的纯 Python 版本:
documentXYZ = []
intensities = []
# I tested to see what the original data was in here adding prints
for frame in frames:
frameXYZ = [[] for i in range(3)]
frameX, frameY, frameZ = [], [], []
for block in frame:
sinRotational, cosRotational = np.math.sin(block[0]), np.math.cos(block[0])
rawDistance, intensity = np.array(block[1]), np.array(block[2])
xy = np.multiply(rawDistance, cosVertCorrection)
x, y, z = np.multiply(xy, sinRotational), np.multiply(xy, cosRotational), np.multiply(rawDistance, sinVertCorrection)
maskXYZ = np.logical_and(np.logical_and(x, x != 0), np.logical_and(y, y != 0), np.logical_and(z, z != 0))
frameX += x[maskXYZ].tolist()
frameY += y[maskXYZ].tolist()
frameZ += z[maskXYZ].tolist()
intensities += intensity[maskXYZ].tolist()
frameXYZ[0].append(frameX), frameXYZ[1].append(frameY), frameXYZ[2].append(frameZ)
documentXYZ.append(frameXYZ)
我知道浮点值的精度可能存在差异(尽管我认为不应该存在,因为我在所有结构中都使用了 doubles
),但我不明白为什么作为整数的 intensity
值也被更改。我希望精度与 Python 中的精度相同。
关于如何改进这个的任何想法?
谢谢。
最佳答案
解决问题的前两个步骤是:
确定 NumPy 在您的平台上使用的特定整数类型(例如 int32
、int64
...),例如检查 dtype
整数数组的属性或其值之一。
确定int
的位宽在您的平台上使用您选择的 C 实现。通常它是 32 位,但并非总是如此(例如使用 sizeof
检查)。
一旦了解了这两个细节,您就可以确定以何种方式进行普通 (C) int
无法匹配 NumPy 一直使用的整数精度。一个常见的猜测是 NumPy 使用的是 int64
但在 C 中你使用的是 int
这可能是 int32
为您的平台/实现。另一个常见的情况是 NumPy 使用无符号整数,而在 C 中 int
将被签名,即使具有相同的位数也会导致不同的表示。
在Cython中可以很方便的引用定宽整数,至少有以下三种方式:
自从您使用了cimport numpy as np
可以引用NumPy的定宽整数类型,比如np.int64_t
或 np.uint8_t
. “_t”类型定义在 NumPy 的 Cython 支持中可用。
您可以尝试从您的 C 实现和平台中找出标准类型名称,例如 cython.longlong
对于 64 位整数或 cython.uchar
对于一个无符号的 8 位整数,它恰好对应于整数的正确位数和正确的符号性,以匹配 NumPy 使用的任何类型的精度和符号性。
也可以从C标准库导入,比如from libc.stdint import int64_t, uint8_t
如果您更喜欢将 C 的标准头文件用于指定大小的固定宽度整数。
假设您选择了合适的整数类型,然后您可以声明您的 intensity
具有正确类型的数组,例如以下任何一种,具体取决于您选择用于表达正确整数类型的方法:
cdef np.uint8_t[32] intensity # If using NumPy integer types
cdef uint8_t[32] intensity # If importing from libc.stdint
cdef cython.uchar[32] intensity # If using Cython integer types
最后一点,最好记住常规 Python 整数是无限精度的,所以如果您设法获得 int
的 NumPy 数组类型(不是 C int
,而是 Python int
),在 Cython 中工作时,您必须决定不同的固定精度表示,或者使用包含 Python int
的数组或类型化内存 View 。类型(这通常违背了首先使用 Cython 的目的)。
关于python - 一旦数据进入 Cython 模块,精度就会丢失/更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37625628/
我在 Ubuntu 10.04 LTS 上运行 Eclipse Galileo。今天 Ubuntu 在我身上崩溃了,重新启动后,我发现 Eclipse 已经完全失去了 Java Perspective
我使用配置了 sonata_user 的 SonataAdminBundle在 config.yml : sonata_user: impersonating: route:
我有 ubuntu 14.04 但它不见了 docker exec sudo docker exec -it ubuntu_bash bash 我希望在现有正在运行的 docker 容器中运行交互式
我正在使用 Ubuntu 8.04/32 位(作为虚拟机)。在一个不是 min 的项目上执行一些 make 时,我得到了错误: g++:/usr/lib/libstdc++.a: 没有这样的文件或目录
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许在 Stack Overflow 上提出有关通用计算硬件和软件的问题。您可以编辑问题,使其成为
我正在尝试获取有关我在 UIImagePicker 中选择的视频的一些数据。 因此,当它进入 UIImagePicker 委托(delegate)方法(如下)时,我知道我需要使用信息字典中的 UIIm
我的网站最近被可能的黑客行为删除了。我上传了备份的文件夹和数据库,但现在我的 View 没有显示。其他一切都有效。我想不出有什么变化,只是上传了几天前的备份。 这些字段在 admin/build/vi
我执行以下操作来设置我的 session ,这是有效的,因为 echo 出现了。但是当我转到下一页或另一页时, session 不存在吗?我做错了什么? $session_start(); if ($
我试图在 BigQuery 中使用这段代码,显然是从 GA 中获取数据,但 _TABLE_SUFFIX 似乎有问题。错误显示“错误:无法识别的名称:_TABLE_SUFFIX at [12:3]”您能
输入:8(2 5 6 9 10 2 7 4)预期输出:(2 7 9 9 12 5 7 6)实际输出:(2 7 9 9) 这是我的大学作业,也是我第一次在这里提问。我不知道为什么,但 10 没有扫描,有
$('div'); // 我在上面的代码中遇到错误。在检查 .js 代码时,我找不到名为 $ 的函数,但根据文档,应该有一个。 最佳答案 试试 http://ajax.googleapis.co
以下简单代码的输出对我来说有点奇怪。它错过了在控制台上打印的 0 到 100 之间的一些数字。 谁能解释一下为什么省略打印?我对并发编程完全陌生。 import java.util.concurren
我正在学习 xamarin 以构建移动应用程序,但我对 Xamarin 和移动应用程序一无所知。我打开了一个空白的移动应用程序,其中有“Hello world”示例并编辑了一些文本,但我的应用程序图标
我正在将一些值存储到 sqlite 数据库中。因此,数据是作为字符串从文本字段收集的,然后转换为 double 并持久化。 这是我试过的 NSDecimalNumber 答案; value.answe
我有一个奇怪的案例。突然,其中一个表中的一些记录(这么多记录)丢失了。首先,我认为这是由我的 PHP 脚本中的错误引起的。但是,我检查了一下,我的脚本中没有DELETE操作,只有UPDATE。有谁知道
我正在复制 NSString来自 NSDictionary进入本地NSString使用 [[NSString alloc] initWithString:] ,对其进行处理(删除一些字符),然后将其发
当保存在根文件夹中时,我的非常基本的 html 页面保持样式。为一个组创建了一个新文件夹,但是当我将页面移动到该文件夹时,它们似乎失去了与 css 文件的连接。 认为问题可能出在链接上,因为它现在
我需要使用 OpenCV 训练一些图像。但问题是,我找不到 opencv_createsamples 程序。我以正常方式安装了 OpenCV,因为我使用的是 Windows 7。这个 opencv_c
我有一个绑定(bind)到 JTable 的 ArrayList。之后 bindingGroup.unbind(); bindingGroup.bind(); (完成刷新数据)我丢失了表格单元格渲
所以基本上我们只是丢失了一个 keystore 和备份 keystore 。但是我们可能知道原始 keystore 的密码。 我的问题是,如果我们知道原始 keystore 的密码,我们可以重新生成
我是一名优秀的程序员,十分优秀!