Commit 3e531c22 authored by Manuel Günther's avatar Manuel Günther
Browse files

Added rudimentary C++ implementation of array sorting, including test

parent 0e46138a
......@@ -11,8 +11,10 @@
#endif
#include <bob.blitz/cppapi.h>
#include <bob.blitz/cleanup.h>
#include <bob.extension/documentation.h>
#include <bob.core/array_convert.h>
#include <bob.core/array_sort.h>
template <typename Tdst, typename Tsrc, int N>
PyObject* inner_convert (PyBlitzArrayObject* src,
......@@ -229,6 +231,40 @@ with its element type as indicated by the user.\n\
"
);
static auto sort_doc = bob::extension::FunctionDoc(
"_sort",
"Sorts a blitz::Array.",
"This function should only be used in the C++ code. "
"The binding is only for test purposes."
)
.add_prototype("array")
.add_parameter("array", "array_like(float,1D)", "The unsorted array, which will be sorted afterwards")
;
static PyObject* sort(PyObject*, PyObject* args, PyObject* kwds) {
BOB_TRY
/* Parses input arguments in a single shot */
char** kwlist = sort_doc.kwlist();
PyBlitzArrayObject* array;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&", kwlist, &PyBlitzArray_OutputConverter, &array)) return 0;
auto array_ = make_safe(array);
if (array->ndim != 1 || array->type_num != NPY_FLOAT64){
PyErr_SetString(PyExc_TypeError, "Invalid input");
return 0;
}
bob::core::array::sort(*PyBlitzArrayCxx_AsBlitz<double,1>(array));
Py_RETURN_NONE;
BOB_CATCH_FUNCTION("sort", 0)
}
static PyMethodDef module_methods[] = {
{
s_convert_str,
......@@ -236,6 +272,12 @@ static PyMethodDef module_methods[] = {
METH_VARARGS|METH_KEYWORDS,
s_convert__doc__
},
{
sort_doc.name(),
(PyCFunction)sort,
METH_VARARGS|METH_KEYWORDS,
sort_doc.doc()
},
{0} /* Sentinel */
};
......
/**
* @date Thu Oct 20 11:25:46 2011 +0200
* @author Laurent El Shafey <Laurent.El-Shafey@idiap.ch>
*
* @brief This file defines deep copy functions for blitz++ arrays
*
* Copyright (C) Idiap Research Institute, Martigny, Switzerland
*/
#ifndef BOB_CORE_ARRAY_SORT_H
#define BOB_CORE_ARRAY_SORT_H
#include <blitz/array.h>
#include <vector>
#include <algorithm>
namespace bob {
namespace core { namespace array {
/**
* @ingroup CORE_ARRAY
* @{
*/
/**
* @brief Sorts an array.
* By default, the array is sorted ascendantly.
* If you wish a different sort order, please select a different predicate, which must be a functor that implements an order over T.
* For an example, have a look at the documentation of std::less<T> (the default in this function)
*
* @warning: The array sort is performed out of place, which means that the data is copied, sorted and copied back.
*/
template <typename T, typename predicate = std::less<T>>
void sort(blitz::Array<T,1>& a)
{
std::vector<T> b(a.extent(0));
std::copy(a.begin(), a.end(), b.begin());
std::sort(b.begin(), b.end(), predicate());
std::copy(b.begin(), b.end(), a.begin());
}
/**
* @}
*/
}}
}
#endif /* BOB_CORE_ARRAY_SORT_H */
......@@ -32,3 +32,12 @@ def test_from_and_to_range():
x = numpy.array(range(6), 'uint8').reshape(2,3)
c = convert(x, 'float64', source_range=(0,255), dest_range=(0.,255.))
assert numpy.array_equal(x.astype('float64'), c)
def test_sorting():
# tests the sorting functionality implemented in C++
from ._convert import _sort
unsorted = numpy.random.random((100))
py = numpy.sort(unsorted)
_sort(unsorted)
assert (py==unsorted).all()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment