3

I know there is already this question answered but I can't seem to make it work.

I'm currently trying to use a PriorityQueue of pair[double,pair[int,int]] and use the double of the pair (pair.first) to sort itself. Incase this helps, the method is this one: pathfind(pair[int,int] start, pair[int,int] goal, np.ndarray grid), the 1st and 2nd arguments are passed from a tuple in a normal python method and the grid is just a 2D array. So... what's the best way to create a PriorityQueue of pair[double,pair[int,int]] in Cython and make it so it compares the first thing in the pair (the double)?

The error it outputs is this: error C2955: 'cpp_pq': use of alias template requires template argument list

The cpp_priority_queue.hpp code is this:

#include <functional>
#include <queue>
template <class T> //Had to use this since pair wasn't getting imported correctly with <utilities>

using cpp_pq = std::priority_queue<T,std::vector<T>,std::function<bool(T,T)>>;

And part of the .pyx code is this:

cdef extern from "cpp_priority_queue.hpp":
    cdef cppclass cpp_pq:
        cpp_pq(...) except +
        void push(pair[double,pair[int,int]])
        pair[double,pair[int,int]] top()
        void pop()
        bool empty()

cdef bool compare_element(pair[double,pair[int,int]] a, pair[double,pair[int,int]] b):
    return a.first < b.first

cpdef int pathfind(pair[int,int] start, pair[int,int] goal, np.ndarray grid): # it supposed to output a 
                                                                              # list of tupples, but its 
                                                                              # an int for now until this 
                                                                              # works
    cdef cpp_pq queue = cpp_pq(compare_element)
    cdef pair[double,pair[int,int]] p = (05.7,start) # some random stuff here for testing....
    queue.push(p)
    ##nothing here till this works...
    return 0
GSR
  • 49
  • 3
  • 1
    Not answering your question, but... Any reason you couldn't just use the `_heapq` module? – Amadan Dec 24 '19 at 05:01
  • @Amadan, Hi!, I used the builtin heappq in my code when it was pure python and it worked pretty well, but once I started creating large grids or using multiple objects, I noticed it was getting slow, therefore I decided to start using Cython and implement as much as possible in C++ to speed things up, until this issue appeared. – GSR Dec 24 '19 at 05:36
  • 2
    `heapq` is written in Python. `_heapq` (notice the underscore) is written in C. They have exactly the same API. You should be able to use your old code by simply switching `import heapq` with `import _heapq as heapq`. – Amadan Dec 24 '19 at 05:37
  • 2
    @Amadan Thank you, but... the timing is almost the same using _heap, I'm pretty sure is because of the for loops I've got in the code, which were the primary reason for me to switch to Cython. – GSR Dec 24 '19 at 06:05
  • Fair enough.... – Amadan Dec 24 '19 at 06:06
  • 1
    Not sure, what you expect: you try use a template class without providing the template argument. So just replace T by the type you use in the typedef. – ead Dec 24 '19 at 06:22

1 Answers1

1

I finally fixed the issue, I restarted the project and instead of copying .hpp file I rewrote it and It worked like a charm. For some reason at first the utility library was showing errors (red underlined words) so I kept rewriting the code until I managed to break it myself and added the unnecessary template . It wasn't until I gave up and restarted everything that It worked.

The final cpp_priority_queue.hpp file is this:

#include <functional>
#include <queue>
#include <utility>

using cpp_pq = std::priority_queue<std::pair<double,std::pair<int,int>>,std::vector<std::pair<double,std::pair<int,int>>>,std::function<bool(std::pair<double,std::pair<int,int>>,std::pair<double,std::pair<int,int>>)>>;

The .pyx file format is correct, the issue was just with the .hpp file.

GSR
  • 49
  • 3