首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在cython中声明列表

如何在cython中声明列表
EN

Stack Overflow用户
提问于 2018-04-22 10:07:50
回答 2查看 3.7K关注 0票数 3

我有以下.pyx代码:

代码语言:javascript
复制
import cython
@cython.boundscheck(False)
@cython.cdivision(True)
@cython.wraparound(False)
def f(m):
  cdef int n = len(m)/2
  cdef int j, k
  z = [[0]*(n+1) for _ in range(n*(2*n-1))]
  for j in range(1, 2*n):
    for k in range(j):
      z[j*(j-1)/2+k][0] = m[j][k]
  return solve(z, 2*n, 1, [1] + [0]*n, n)


cdef solve(b, int s, int w, g, int n):
  cdef complex h
  cdef int u,v,j,k
  if s == 0:
    return w*g[n]
  c = [b[(j+1)*(j+2)/2+k+2][:] for j in range(1, s-2) for k in range(j)]
  h = solve(c, s-2, -w, g, n)
  e = g[:]
  for u in range(n):
    for v in range(n-u):
      e[u+v+1] += g[u]*b[0][v]
  for j in range(1, s-2):
    for k in range(j):
      for u in range(n):
        for v in range(n-u):
          c[j*(j-1)/2+k][u+v+1] += b[(j+1)*(j+2)/2][u]*b[(k+1)*(k+2)/2+1][v] + b[(k+1)*(k+2)/2][u]*b[(j+1)*(j+2)/2+1][v]
  return h + solve(c, s-2, w, e, n)

我不知道如何在cython中声明列表以加快代码的速度。

例如,变量m是一个矩阵,表示为浮点数列表。变量z也是浮点数列表。例如,def f(m)行应该是什么样的?

按照@DavidW在回答中的建议,这里是我的最新版本。

代码语言:javascript
复制
import cython
import numpy as np
def f(complex[:,:] m):
  cdef int n = len(m)/2
  cdef int j, k
  cdef complex[:,:] z = np.zeros((n*(2*n-1), n+1), dtype = complex)
  for j in range(1, 2*n):
    for k in range(j):
      z[j*(j-1)/2+k, 0] = m[j, k]
  return solve(z, 2*n, 1, [1] + [0]*n, n)


cdef solve(complex[:,:] b, int s, int w, g, int n):
  cdef complex h
  cdef int u,v,j,k
  cdef complex[:,:] c
  if s == 0:
    return w*g[n]
  c = [b[(j+1)*(j+2)/2+k+2][:] for j in range(1, s-2) for k in range(j)]
  print("c stats:", len(c), [len(c[i]) for i in len(c)]) 
  h = solve(c, s-2, -w, g, n)
  e = g[:]
  for u in range(n):
    for v in range(n-u):
      e[u+v+1] = e[u+v+1] + g[u]*b[0][v]
  for j in range(1, s-2):
    for k in range(j):
      for u in range(n):
        for v in range(n-u):
          c[j*(j-1)/2+k][u+v+1] = c[j*(j-1)/2+k][u+v+1] + b[(j+1)*(j+2)/2][u]*b[(k+1)*(k+2)/2+1][v] + b[(k+1)*(k+2)/2][u]*b[(j+1)*(j+2)/2+1][v]
  return h + solve(c, s-2, w, e, n)

现在的主要问题是如何声明c,因为它目前是一个列表列表。

EN

回答 2

Stack Overflow用户

发布于 2018-04-23 16:41:17

列表列表并不是一个可以从Cython获得更快速度的结构。应该使用的结构是一个2D 类型化内存视图

代码语言:javascript
复制
def f(double[:,:] m):
    # ...

它们被索引为m[j,k]而不是m[j][k]。您可以向它们传递任何公开Python缓冲区协议的适当形状的对象。大多数频率这将是一个Numpy数组。

您还应该避免使用像@cython.boundscheck(False)@cython.wraparound(False)这样的装饰器,除非您了解它们所做的事情,并考虑它们是否适合您的功能。对于您的当前版本(您使用的是list),它们实际上什么也不做,并且建议您在不理解的情况下复制它们。它们确实加快了内存视图的索引(代价是一些安全的)。

编辑:在初始化c方面,您有两个选项。

  1. 使用列表列表初始化numpy数组。这可能不是非常快(但如果其他步骤较慢,那么这可能并不重要): C= np.array([b(j+1)*(j+2)/2+k+2,:对于j在范围(1,s-2)对于k在范围(J)],dtype=complex) #注意,我稍微改变了b的索引
  2. 使用适当大小的c数组设置np.zeros。将列表理解转换为两个循环。对我来说,这并不是百分之百明显的翻译,但它有点像 对于范围(J)中的k(J):对于j在范围(1,s-2):c“j和k的某些函数”,:=b“j和k的某些函数”,:

您还希望用len(c)替换为c.shape[0]等。

票数 6
EN

Stack Overflow用户

发布于 2018-04-22 10:14:57

就像C:

代码语言:javascript
复制
cdef float z[100][100]

有关更多细节,请参阅链接。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49964757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档