36 #ifndef VIGRA_NUMPY_ARRAY_TRAITS_HXX 
   37 #define VIGRA_NUMPY_ARRAY_TRAITS_HXX 
   39 #ifndef NPY_NO_DEPRECATED_API 
   40 # define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 
   43 #include "numerictraits.hxx" 
   44 #include "multi_array.hxx" 
   45 #include "numpy_array_taggedshape.hxx" 
   54 template<
class ValueType>
 
   55 struct ERROR_NumpyArrayValuetypeTraits_not_specialized_for_ { };
 
   57 template<
class ValueType>
 
   58 struct NumpyArrayValuetypeTraits
 
   60     static bool isValuetypeCompatible(PyArrayObject 
const *)
 
   62         return ERROR_NumpyArrayValuetypeTraits_not_specialized_for_<ValueType>();
 
   65     static ERROR_NumpyArrayValuetypeTraits_not_specialized_for_<ValueType> typeCode;
 
   67     static std::string typeName()
 
   69         return std::string(
"ERROR: NumpyArrayValuetypeTraits not specialized for this case");
 
   72     static std::string typeNameImpex()
 
   74         return std::string(
"ERROR: NumpyArrayValuetypeTraits not specialized for this case");
 
   77     static PyObject * typeObject()
 
   83 template<
class ValueType>
 
   84 ERROR_NumpyArrayValuetypeTraits_not_specialized_for_<ValueType> NumpyArrayValuetypeTraits<ValueType>::typeCode;
 
   86 #define VIGRA_NUMPY_VALUETYPE_TRAITS(type, typeID, numpyTypeName, impexTypeName) \ 
   88 struct NumpyArrayValuetypeTraits<type > \ 
   90     static bool isValuetypeCompatible(PyArrayObject const * obj)  \ 
   92         return PyArray_EquivTypenums(typeID, PyArray_DESCR((PyArrayObject *)obj)->type_num) && \ 
   93                PyArray_ITEMSIZE((PyArrayObject *)obj) == sizeof(type); \ 
   96     static NPY_TYPES const typeCode = typeID; \ 
   98     static std::string typeName() \ 
  100         return #numpyTypeName; \ 
  103     static std::string typeNameImpex() \ 
  105         return impexTypeName; \ 
  108     static PyObject * typeObject() \ 
  110         return PyArray_TypeObjectFromType(typeID); \ 
  115 VIGRA_NUMPY_VALUETYPE_TRAITS(
bool,           NPY_BOOL, 
bool, 
"UINT8")
 
  116 VIGRA_NUMPY_VALUETYPE_TRAITS(
signed char,    NPY_INT8, int8, "INT16")
 
  117 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned char,  NPY_UINT8, uint8, "UINT8")
 
  118 VIGRA_NUMPY_VALUETYPE_TRAITS(
short,          NPY_INT16, int16, "INT16")
 
  119 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned short, NPY_UINT16, uint16, "UINT16")
 
  121 #if VIGRA_BITSOF_LONG == 32 
  122 VIGRA_NUMPY_VALUETYPE_TRAITS(
long,           NPY_INT32, int32, 
"INT32")
 
  123 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned long,  NPY_UINT32, uint32, "UINT32")
 
  124 #elif VIGRA_BITSOF_LONG == 64 
  125 VIGRA_NUMPY_VALUETYPE_TRAITS(
long,           NPY_INT64, int64, 
"DOUBLE")
 
  126 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned long,  NPY_UINT64, uint64, "DOUBLE")
 
  129 #if VIGRA_BITSOF_INT == 32 
  130 VIGRA_NUMPY_VALUETYPE_TRAITS(
int,            NPY_INT32, int32, 
"INT32")
 
  131 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned int,   NPY_UINT32, uint32, "UINT32")
 
  132 #elif VIGRA_BITSOF_INT == 64 
  133 VIGRA_NUMPY_VALUETYPE_TRAITS(
int,            NPY_INT64, int64, 
"DOUBLE")
 
  134 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned int,   NPY_UINT64, uint64, "DOUBLE")
 
  138 # if VIGRA_BITSOF_LONG_LONG == 32 
  139 VIGRA_NUMPY_VALUETYPE_TRAITS(
long long,            NPY_INT32, int32, 
"INT32")
 
  140 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned long long,   NPY_UINT32, uint32, "UINT32")
 
  141 # elif VIGRA_BITSOF_LONG_LONG == 64 
  142 VIGRA_NUMPY_VALUETYPE_TRAITS(
long long,          NPY_INT64, int64, 
"DOUBLE")
 
  143 VIGRA_NUMPY_VALUETYPE_TRAITS(
unsigned long long, NPY_UINT64, uint64, "DOUBLE")
 
  147 VIGRA_NUMPY_VALUETYPE_TRAITS(npy_float32, NPY_FLOAT32, float32, 
"FLOAT")
 
  148 VIGRA_NUMPY_VALUETYPE_TRAITS(npy_float64, NPY_FLOAT64, float64, "DOUBLE")
 
  149 #if NPY_SIZEOF_LONGDOUBLE != NPY_SIZEOF_DOUBLE 
  150 VIGRA_NUMPY_VALUETYPE_TRAITS(npy_longdouble, NPY_LONGDOUBLE, longdouble, 
"")
 
  152 VIGRA_NUMPY_VALUETYPE_TRAITS(npy_cfloat, NPY_CFLOAT, complex64, 
"")
 
  153 VIGRA_NUMPY_VALUETYPE_TRAITS(std::complex<npy_float>, NPY_CFLOAT, complex64, "")
 
  154 VIGRA_NUMPY_VALUETYPE_TRAITS(npy_cdouble, NPY_CDOUBLE, complex128, "")
 
  155 VIGRA_NUMPY_VALUETYPE_TRAITS(std::complex<npy_double>, NPY_CDOUBLE, complex128, "")
 
  156 VIGRA_NUMPY_VALUETYPE_TRAITS(npy_clongdouble, NPY_CLONGDOUBLE, clongdouble, "")
 
  157 #if NPY_SIZEOF_LONGDOUBLE != NPY_SIZEOF_DOUBLE 
  158 VIGRA_NUMPY_VALUETYPE_TRAITS(std::complex<npy_longdouble>, NPY_CLONGDOUBLE, clongdouble, 
"")
 
  161 #undef VIGRA_NUMPY_VALUETYPE_TRAITS 
  169 template<
unsigned int N, 
class T, 
class Str
ide>
 
  170 struct NumpyArrayTraits;
 
  174 template<
unsigned int N, 
class T>
 
  175 struct NumpyArrayTraits<N, T, StridedArrayTag>
 
  178     typedef T value_type;
 
  179     typedef NumpyArrayValuetypeTraits<T> ValuetypeTraits;
 
  180     static NPY_TYPES 
const typeCode = ValuetypeTraits::typeCode;
 
  182     static bool isArray(PyObject * obj)
 
  184         return obj && PyArray_Check(obj);
 
  187     static bool isValuetypeCompatible(PyArrayObject * obj)  
 
  189         return ValuetypeTraits::isValuetypeCompatible(obj);
 
  192     static bool isShapeCompatible(PyArrayObject * array) 
 
  194         int ndim = PyArray_NDIM(array);
 
  203     static bool isPropertyCompatible(PyArrayObject * obj) 
 
  205         return isShapeCompatible(obj) && isValuetypeCompatible(obj);
 
  211     static TaggedShape taggedShape(TinyVector<U, N> 
const & shape, PyAxisTags axistags)
 
  213         return TaggedShape(shape, axistags);
 
  220     static TaggedShape taggedShape(TinyVector<U, N> 
const & shape,
 
  221                                    std::string 
const &  = 
"")
 
  227         return TaggedShape(shape, PyAxisTags());
 
  232     static void finalizeTaggedShape(TaggedShape & tagged_shape)
 
  234         vigra_precondition(tagged_shape.size() == N,
 
  235                   "reshapeIfEmpty(): tagged_shape has wrong size.");
 
  243     template <
class ARRAY>
 
  244     static void permuteLikewise(python_ptr array, ARRAY 
const & data, ARRAY & res)
 
  246         vigra_precondition((
int)data.size() == N,
 
  247             "NumpyArray::permuteLikewise(): size mismatch.");
 
  249         ArrayVector<npy_intp> permute;
 
  250         detail::getAxisPermutationImpl(permute, array, 
"permutationToNormalOrder",
 
  251                                        AxisInfo::AllAxes, 
true);
 
  253         if(permute.size() != 0)
 
  255             applyPermutation(permute.begin(), permute.end(), data.begin(), res.begin());
 
  262     static void permutationToSetupOrder(python_ptr array, ArrayVector<U> & permute)
 
  264         detail::getAxisPermutationImpl(permute, array, 
"permutationToNormalOrder",
 
  265                                        AxisInfo::AllAxes, 
true);
 
  267         if(permute.size() == 0)
 
  279     static python_ptr unsafeConstructorFromData(TinyVector<U, N> 
const & shape,
 
  280                                                 T *data, TinyVector<U, N> 
const & stride)
 
  282         TinyVector<npy_intp, N> npyStride(stride * 
sizeof(T));
 
  283         return constructNumpyArrayFromData(shape, npyStride.begin(),
 
  284                                                     ValuetypeTraits::typeCode, data);
 
  290 template<
unsigned int N, 
class T>
 
  291 struct NumpyArrayTraits<N, T, UnstridedArrayTag>
 
  292 : 
public NumpyArrayTraits<N, T, StridedArrayTag>
 
  294     typedef NumpyArrayTraits<N, T, StridedArrayTag> BaseType;
 
  295     typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
 
  297     static bool isShapeCompatible(PyArrayObject * array) 
 
  299         PyObject * obj = (PyObject *)array;
 
  300         int ndim = PyArray_NDIM(array);
 
  301         long channelIndex = pythonGetAttr(obj, 
"channelIndex", ndim);
 
  302         long majorIndex = pythonGetAttr(obj, 
"innerNonchannelIndex", ndim);
 
  303         npy_intp * strides = PyArray_STRIDES(array);
 
  305         if(channelIndex < ndim)
 
  308             return (ndim == N && strides[channelIndex] == 
sizeof(T));
 
  310         else if(majorIndex < ndim)
 
  314             return (ndim == N && strides[majorIndex] == 
sizeof(T));
 
  319             return (ndim == N && strides[0] == 
sizeof(T));
 
  323     static bool isPropertyCompatible(PyArrayObject * obj) 
 
  325         return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
 
  331 template<
unsigned int N, 
class T>
 
  332 struct NumpyArrayTraits<N, Singleband<T>, StridedArrayTag>
 
  333 : 
public NumpyArrayTraits<N, T, StridedArrayTag>
 
  335     typedef NumpyArrayTraits<N, T, StridedArrayTag> BaseType;
 
  336     typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
 
  338     static bool isShapeCompatible(PyArrayObject * array) 
 
  340         PyObject * obj = (PyObject *)array;
 
  341         int ndim = PyArray_NDIM(array);
 
  342         long channelIndex = pythonGetAttr(obj, 
"channelIndex", ndim);
 
  346         if(channelIndex == ndim)
 
  350         return ndim == N+1 && PyArray_DIM(array, channelIndex) == 1;
 
  353     static bool isPropertyCompatible(PyArrayObject * obj) 
 
  355         return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
 
  359     static TaggedShape taggedShape(TinyVector<U, N> 
const & shape, PyAxisTags axistags)
 
  361         return TaggedShape(shape, axistags).setChannelCount(1);
 
  365     static TaggedShape taggedShape(TinyVector<U, N> 
const & shape, std::string 
const & order = 
"")
 
  367         return TaggedShape(shape,
 
  368                   PyAxisTags(detail::defaultAxistags(shape.size()+1, order))).setChannelCount(1);
 
  371     static void finalizeTaggedShape(TaggedShape & tagged_shape)
 
  373         if(tagged_shape.axistags.hasChannelAxis())
 
  375             tagged_shape.setChannelCount(1);
 
  376             vigra_precondition(tagged_shape.size() == N+1,
 
  377                      "reshapeIfEmpty(): tagged_shape has wrong size.");
 
  381             tagged_shape.setChannelCount(0);
 
  382             vigra_precondition(tagged_shape.size() == N,
 
  383                      "reshapeIfEmpty(): tagged_shape has wrong size.");
 
  387     template <
class ARRAY>
 
  388     static void permuteLikewise(python_ptr array, ARRAY 
const & data, ARRAY & res)
 
  390         vigra_precondition((
int)data.size() == N,
 
  391             "NumpyArray::permuteLikewise(): size mismatch.");
 
  393         ArrayVector<npy_intp> permute;
 
  394         detail::getAxisPermutationImpl(permute, array, 
"permutationToNormalOrder",
 
  395                                        AxisInfo::NonChannel, 
true);
 
  397         if(permute.size() == 0)
 
  403         applyPermutation(permute.begin(), permute.end(), data.begin(), res.begin());
 
  407     static void permutationToSetupOrder(python_ptr array, ArrayVector<U> & permute)
 
  409         detail::getAxisPermutationImpl(permute, array, 
"permutationToNormalOrder",
 
  410                                        AxisInfo::AllAxes, 
true);
 
  411         if(permute.size() == 0)
 
  416         else if(permute.size() == N+1)
 
  418             permute.erase(permute.begin());
 
  425 template<
unsigned int N, 
class T>
 
  426 struct NumpyArrayTraits<N, Singleband<T>, UnstridedArrayTag>
 
  427 : 
public NumpyArrayTraits<N, Singleband<T>, StridedArrayTag>
 
  429     typedef NumpyArrayTraits<N, T, UnstridedArrayTag> UnstridedTraits;
 
  430     typedef NumpyArrayTraits<N, Singleband<T>, StridedArrayTag> BaseType;
 
  431     typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
 
  433     static bool isShapeCompatible(PyArrayObject * array) 
 
  435         PyObject * obj = (PyObject *)array;
 
  436         int ndim = PyArray_NDIM(array);
 
  437         long channelIndex = pythonGetAttr(obj, 
"channelIndex", ndim);
 
  438         long majorIndex = pythonGetAttr(obj, 
"innerNonchannelIndex", ndim);
 
  439         npy_intp * strides = PyArray_STRIDES(array);
 
  442         if(majorIndex == ndim)
 
  443             return N == ndim && strides[0] == 
sizeof(T);
 
  447         if(channelIndex == ndim)
 
  448             return N == ndim && strides[majorIndex] == 
sizeof(T);
 
  452         return ndim == N+1 && PyArray_DIM(array, channelIndex) == 1 &&
 
  453                 strides[majorIndex] == 
sizeof(T);
 
  456     static bool isPropertyCompatible(PyArrayObject * obj) 
 
  458         return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
 
  464 template<
unsigned int N, 
class T>
 
  465 struct NumpyArrayTraits<N, Multiband<T>, StridedArrayTag>
 
  466 : 
public NumpyArrayTraits<N, T, StridedArrayTag>
 
  468     typedef NumpyArrayTraits<N, T, StridedArrayTag> BaseType;
 
  469     typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
 
  471     static bool isShapeCompatible(PyArrayObject * array) 
 
  473         PyObject * obj = (PyObject*)array;
 
  474         int ndim = PyArray_NDIM(array);
 
  475         long channelIndex = pythonGetAttr(obj, 
"channelIndex", ndim);
 
  476         long majorIndex = pythonGetAttr(obj, 
"innerNonchannelIndex", ndim);
 
  478         if(channelIndex < ndim)
 
  483         else if(majorIndex < ndim)
 
  491             return ndim == N || ndim == N-1;
 
  495     static bool isPropertyCompatible(PyArrayObject * obj) 
 
  497         return isShapeCompatible(obj) && ValuetypeTraits::isValuetypeCompatible(obj);
 
  501     static TaggedShape taggedShape(TinyVector<U, N> 
const & shape, PyAxisTags axistags)
 
  503         return TaggedShape(shape, axistags).setChannelIndexLast();
 
  507     static TaggedShape taggedShape(TinyVector<U, N> 
const & shape, std::string 
const & order = 
"")
 
  509         return TaggedShape(shape,
 
  510                     PyAxisTags(detail::defaultAxistags(shape.size(), order))).setChannelIndexLast();
 
  513     static void finalizeTaggedShape(TaggedShape & tagged_shape)
 
  517         if(tagged_shape.channelCount() == 1 && !tagged_shape.axistags.hasChannelAxis())
 
  519             tagged_shape.setChannelCount(0);
 
  520             vigra_precondition(tagged_shape.size() == N-1,
 
  521                   "reshapeIfEmpty(): tagged_shape has wrong size.");
 
  525             vigra_precondition(tagged_shape.size() == N,
 
  526                   "reshapeIfEmpty(): tagged_shape has wrong size.");
 
  530     template <
class ARRAY>
 
  531     static void permuteLikewise(python_ptr array, ARRAY 
const & data, ARRAY & res)
 
  533         ArrayVector<npy_intp> permute;
 
  535         if((
int)data.size() == N)
 
  537             vigra_precondition(PyArray_NDIM((PyArrayObject*)array.get()) == N,
 
  538                 "NumpyArray::permuteLikewise(): input array has no channel axis.");
 
  540             detail::getAxisPermutationImpl(permute, array, 
"permutationToNormalOrder",
 
  541                                            AxisInfo::AllAxes, 
true);
 
  543             if(permute.size() == 0)
 
  551                 int channelIndex = permute[0];
 
  552                 for(
unsigned k=1; k<N; ++k)
 
  553                     permute[k-1] = permute[k];
 
  554                 permute[N-1] = channelIndex;
 
  559             vigra_precondition((
int)data.size() == N-1,
 
  560                 "NumpyArray::permuteLikewise(): size mismatch.");
 
  562             detail::getAxisPermutationImpl(permute, array, 
"permutationToNormalOrder",
 
  563                                            AxisInfo::NonChannel, 
true);
 
  565             if(permute.size() == 0)
 
  572         applyPermutation(permute.begin(), permute.end(), data.begin(), res.begin());
 
  576     static void permutationToSetupOrder(python_ptr array, ArrayVector<U> & permute)
 
  578         detail::getAxisPermutationImpl(permute, array, 
"permutationToNormalOrder",
 
  579                                        AxisInfo::AllAxes, 
true);
 
  581         if(permute.size() == 0)
 
  583             permute.resize(PyArray_NDIM((PyArrayObject*)array.get()));
 
  586         else if(permute.size() == N)
 
  589             int channelIndex = permute[0];
 
  590             for(decltype(permute.size()) k=1; k<N; ++k)
 
  591                 permute[k-1] = permute[k];
 
  592             permute[N-1] = channelIndex;
 
  599 template<
unsigned int N, 
class T>
 
  600 struct NumpyArrayTraits<N, Multiband<T>, UnstridedArrayTag>
 
  601 : 
public NumpyArrayTraits<N, Multiband<T>, StridedArrayTag>
 
  603     typedef NumpyArrayTraits<N, Multiband<T>, StridedArrayTag> BaseType;
 
  604     typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
 
  606     static bool isShapeCompatible(PyArrayObject * array) 
 
  608         PyObject * obj = (PyObject *)array;
 
  609         int ndim = PyArray_NDIM(array);
 
  610         long channelIndex = pythonGetAttr(obj, 
"channelIndex", ndim);
 
  611         long majorIndex = pythonGetAttr(obj, 
"innerNonchannelIndex", ndim);
 
  612         npy_intp * strides = PyArray_STRIDES(array);
 
  614         if(channelIndex < ndim)
 
  618             return ndim == N && strides[majorIndex] == 
sizeof(T);
 
  620         else if(majorIndex < ndim)
 
  624             return ndim == N-1 && strides[majorIndex] == 
sizeof(T);
 
  630             return (ndim == N || ndim == N-1) && strides[0] == 
sizeof(T);
 
  634     static bool isPropertyCompatible(PyArrayObject * obj) 
 
  636         return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
 
  642 template<
unsigned int N, 
int M, 
class T>
 
  643 struct NumpyArrayTraits<N, TinyVector<T, M>, StridedArrayTag>
 
  646     typedef TinyVector<T, M> value_type;
 
  647     typedef NumpyArrayValuetypeTraits<T> ValuetypeTraits;
 
  648     static NPY_TYPES 
const typeCode = ValuetypeTraits::typeCode;
 
  650     static bool isArray(PyObject * obj)
 
  652         return obj && PyArray_Check(obj);
 
  655     static bool isValuetypeCompatible(PyArrayObject * obj)  
 
  657         return ValuetypeTraits::isValuetypeCompatible(obj);
 
  660     static bool isShapeCompatible(PyArrayObject * array) 
 
  662         PyObject * obj = (PyObject *)array;
 
  665          if(PyArray_NDIM(array) != N+1)
 
  669         long channelIndex = pythonGetAttr(obj, 
"channelIndex", N);
 
  670         npy_intp * strides = PyArray_STRIDES(array);
 
  673         long majorIndex = pythonGetAttr(obj, 
"innerNonchannelIndex", N+1);
 
  674         if(majorIndex >= N+1)
 
  676             npy_intp smallest = NumericTraits<npy_intp>::max();
 
  677             for(
unsigned int k=0; k<N+1; ++k)
 
  679                 if(k == channelIndex)
 
  681                 if(strides[k] < smallest)
 
  683                     smallest = strides[k];
 
  689         return PyArray_DIM(array, channelIndex) == M &&
 
  690                strides[channelIndex] == 
sizeof(T) &&
 
  691                strides[majorIndex] % (M*
sizeof(T)) == 0;
 
  694     static bool isPropertyCompatible(PyArrayObject * obj) 
 
  696         return isShapeCompatible(obj) && ValuetypeTraits::isValuetypeCompatible(obj);
 
  700     static TaggedShape taggedShape(TinyVector<U, N> 
const & shape, PyAxisTags axistags)
 
  702         return TaggedShape(shape, axistags).setChannelCount(M);
 
  706     static TaggedShape taggedShape(TinyVector<U, N> 
const & shape, std::string 
const & order = 
"")
 
  708         return TaggedShape(shape,
 
  709                      PyAxisTags(detail::defaultAxistags(shape.size()+1, order))).setChannelCount(M);
 
  712     static void finalizeTaggedShape(TaggedShape & tagged_shape)
 
  714         tagged_shape.setChannelCount(M);
 
  715         vigra_precondition(tagged_shape.size() == N+1,
 
  716               "reshapeIfEmpty(): tagged_shape has wrong size.");
 
  719     template <
class ARRAY>
 
  720     static void permuteLikewise(python_ptr array, ARRAY 
const & data, ARRAY & res)
 
  722         vigra_precondition((
int)data.size() == N,
 
  723             "NumpyArray::permuteLikewise(): size mismatch.");
 
  725         ArrayVector<npy_intp> permute;
 
  726         detail::getAxisPermutationImpl(permute, array, 
"permutationToNormalOrder",
 
  727                                        AxisInfo::NonChannel, 
true);
 
  729         if(permute.size() == 0)
 
  735         applyPermutation(permute.begin(), permute.end(), data.begin(), res.begin());
 
  739     static void permutationToSetupOrder(python_ptr array, ArrayVector<U> & permute)
 
  741         detail::getAxisPermutationImpl(permute, array, 
"permutationToNormalOrder",
 
  742                                        AxisInfo::AllAxes, 
true);
 
  743         if(permute.size() == 0)
 
  748         else if(permute.size() == N+1)
 
  750             permute.erase(permute.begin());
 
  755     static python_ptr unsafeConstructorFromData(TinyVector<U, N> 
const & shape,
 
  756                                                 value_type *data, TinyVector<U, N> 
const & stride)
 
  758         TinyVector<npy_intp, N+1> npyShape;
 
  759         std::copy(shape.begin(), shape.end(), npyShape.begin());
 
  762         TinyVector<npy_intp, N+1> npyStride;
 
  764             stride.begin(), stride.end(), npyStride.begin(),
 
  765             std::bind2nd(std::multiplies<npy_intp>(), 
sizeof(value_type)));
 
  766         npyStride[N] = 
sizeof(T);
 
  768         return constructNumpyArrayFromData(npyShape, npyStride.begin(),
 
  769                                                     ValuetypeTraits::typeCode, data);
 
  775 template<
unsigned int N, 
int M, 
class T>
 
  776 struct NumpyArrayTraits<N, TinyVector<T, M>, UnstridedArrayTag>
 
  777 : 
public NumpyArrayTraits<N, TinyVector<T, M>, StridedArrayTag>
 
  779     typedef NumpyArrayTraits<N, TinyVector<T, M>, StridedArrayTag> BaseType;
 
  780     typedef typename BaseType::value_type value_type;
 
  781     typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
 
  783     static bool isShapeCompatible(PyArrayObject * array) 
 
  785         PyObject * obj = (PyObject *)array;
 
  786         int ndim = PyArray_NDIM(array);
 
  792         long channelIndex = pythonGetAttr(obj, 
"channelIndex", ndim);
 
  793         long majorIndex = pythonGetAttr(obj, 
"innerNonchannelIndex", ndim);
 
  794         npy_intp * strides = PyArray_STRIDES(array);
 
  796         if(majorIndex < ndim)
 
  799             if(channelIndex == ndim)
 
  803             return PyArray_DIM(array, channelIndex) == M &&
 
  804                    strides[channelIndex] == 
sizeof(T) &&
 
  805                    strides[majorIndex] == 
sizeof(TinyVector<T, M>);
 
  812             return PyArray_DIM(array, N) == M &&
 
  813                    strides[N] == 
sizeof(T) &&
 
  814                    strides[0] == 
sizeof(TinyVector<T, M>);
 
  818     static bool isPropertyCompatible(PyArrayObject * obj) 
 
  820         return isShapeCompatible(obj) && BaseType::isValuetypeCompatible(obj);
 
  826 template<
unsigned int N, 
class T>
 
  827 struct NumpyArrayTraits<N, RGBValue<T>, StridedArrayTag>
 
  828 : 
public NumpyArrayTraits<N, TinyVector<T, 3>, StridedArrayTag>
 
  831     typedef RGBValue<T> value_type;
 
  832     typedef NumpyArrayValuetypeTraits<T> ValuetypeTraits;
 
  837 template<
unsigned int N, 
class T>
 
  838 struct NumpyArrayTraits<N, RGBValue<T>, UnstridedArrayTag>
 
  839 : 
public NumpyArrayTraits<N, RGBValue<T>, StridedArrayTag>
 
  841     typedef NumpyArrayTraits<N, TinyVector<T, 3>, UnstridedArrayTag> UnstridedTraits;
 
  842     typedef NumpyArrayTraits<N, RGBValue<T>, StridedArrayTag> BaseType;
 
  843     typedef typename BaseType::value_type value_type;
 
  844     typedef typename BaseType::ValuetypeTraits ValuetypeTraits;
 
  846     static bool isShapeCompatible(PyArrayObject * obj) 
 
  848         return UnstridedTraits::isShapeCompatible(obj);
 
  851     static bool isPropertyCompatible(PyArrayObject * obj) 
 
  853         return UnstridedTraits::isPropertyCompatible(obj);
 
  859 #endif // VIGRA_NUMPY_ARRAY_TRAITS_HXX 
void applyPermutation(IndexIterator index_first, IndexIterator index_last, InIterator in, OutIterator out)
Sort an array according to the given index permutation. 
Definition: algorithm.hxx:456
void linearSequence(Iterator first, Iterator last, Value start, Value step)
Fill an array with a sequence of numbers. 
Definition: algorithm.hxx:208