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