在Cython中使用qsort获取排序索引/排列

时间:2018-02-15 09:42:15

标签: sorting cython qsort

概述

有一些问题与此类似,但它们都略有不同。要明确的是,如果values是一个整数数组,我想找到perm,使sorted_valuesvalues按某个比较运算符排序),由

sorted_values[i] = values[perm[i]]

第1步

如何在C中执行此操作?好qsort需要声明一个比较函数来告诉你一个值是否大于另一个值。如果我们使values成为全局变量,那么我们可以利用这个比较函数对最初设置为perm的数组0:N-1进行排序(其中N是{{1}的长度不比较valuesperm[i],而是比较perm[j]values[perm[i]]。见link。一些示例C代码:

values[perm[j]]

当然,诀窍在于全局定义// sort_test.c #include <stdio.h> #include <stdlib.h> int *values; int cmpfunc (const void * a, const void * b) { return ( values[*(int*)a] - values[*(int*)b] ); } int main () { int i; int n = 5; int *perm; // Assign memory values = (int *) malloc(n*sizeof(int)); perm = (int *) malloc(n*sizeof(int)); // Set values to random values between 0 and 99 for (i=0; i<n; i++) values[i] = rand() % 100; // Set perm initially to 0:n-1 for (i=0; i<n; i++) perm[i] = i; printf("Before sorting the list is: \n"); for (i=0; i<n; i++) printf("%d ", values[i]); qsort(perm, n, sizeof(int), cmpfunc); printf("\nThe sorting permutation is: \n"); for (i=0; i<n; i++) printf("%d ", perm[i]); free(values); free(perm); printf("\n"); return(0); } ,因此values可以看到它。

第2步

如何在Cython中完成?不幸的是,我不能让Cython使用与全局声明的值相同的技巧。我最好的尝试是基于答案here的以下内容,但不同之处在于它们只是排序他们不需要获取索引/排列的数组。

cmpfunc

可以使用

编译
# sort_test_c.pyx
cimport cython
from libc.stdlib cimport qsort

# Try declaring global variable for the sort function
cpdef long[:] values

cdef int cmpfunc (const void *a , const void *b) nogil:
    cdef long a_v = (<long *> a)[0] 
    cdef long b_v = (<long *> b)[0]
    return (values[a_v] - values[b_v]);

def sort(long[:] py_values, long[:] perm, int N):
    # Assign to global
    values = py_values

    # Make sure perm is 0:N-1
    for i in range(N):
        perm[i] = i

    # Perform sort
    qsort(&perm[0], N, perm.strides[0], &cmpfunc)

并使用脚本进行测试

cythonize -i sort_test_c.pyx

然而,这引起了我们的全局变量# sort_test.py from sort_test_c import sort import numpy as np n = 5 values = np.random.randint(0, 100, n).astype(int) perm = np.empty(n).astype(int) sort(values, perm, n) ,即

values

并且排序排列不正确(除非UnboundLocalError: local variable 'values' referenced before assignment Exception ignored in: 'sort_test_c.cmpfunc 已经被排序,在这种情况下幸运,因为values总是返回数组perm)。我该如何解决这个问题?

0 个答案:

没有答案