%PDF- %PDF-
| Direktori : /proc/thread-self/root/lib/python3/dist-packages/pythran/pythonic/numpy/ |
| Current File : //proc/thread-self/root/lib/python3/dist-packages/pythran/pythonic/numpy/cross.hpp |
#ifndef PYTHONIC_NUMPY_CROSS_HPP
#define PYTHONIC_NUMPY_CROSS_HPP
#include "pythonic/include/numpy/cross.hpp"
#include "pythonic/utils/functor.hpp"
#include "pythonic/types/ndarray.hpp"
PYTHONIC_NS_BEGIN
namespace numpy
{
template <size_t N, size_t En, size_t Fn>
struct _cross {
template <class Out, class E, class F>
void operator()(Out obegin, Out oend, E ebegin, F fbegin)
{
while (obegin != oend) {
_cross<N - 1, En, Fn>{}((*obegin).begin(), (*obegin).end(),
(*ebegin).begin(), (*fbegin).begin());
++obegin, ++ebegin, ++fbegin;
}
}
};
template <>
struct _cross<1, 2, 2> {
template <class Out, class E, class F>
void operator()(Out obegin, Out oend, E ebegin, F fbegin)
{
auto e0 = *ebegin;
++ebegin;
auto e1 = *ebegin;
auto f0 = *fbegin;
++fbegin;
auto f1 = *fbegin;
*obegin = e0 *f1 - e1 *f0;
}
};
template <>
struct _cross<1, 2, 3> {
template <class Out, class E, class F>
void operator()(Out obegin, Out oend, E ebegin, F fbegin)
{
auto e0 = *ebegin;
++ebegin;
auto e1 = *ebegin;
decltype(e1) e2 = 0;
auto f0 = *fbegin;
++fbegin;
auto f1 = *fbegin;
++fbegin;
auto f2 = *fbegin;
*obegin = e1 *f2 - e2 *f1;
++obegin;
*obegin = e2 *f0 - e0 *f2;
++obegin;
*obegin = e0 *f1 - e1 *f0;
}
};
template <>
struct _cross<1, 3, 3> {
template <class Out, class E, class F>
void operator()(Out obegin, Out oend, E ebegin, F fbegin)
{
auto e0 = *ebegin;
++ebegin;
auto e1 = *ebegin;
++ebegin;
auto e2 = *ebegin;
auto f0 = *fbegin;
++fbegin;
auto f1 = *fbegin;
++fbegin;
auto f2 = *fbegin;
*obegin = e1 *f2 - e2 *f1;
++obegin;
*obegin = e2 *f0 - e0 *f2;
++obegin;
*obegin = e0 *f1 - e1 *f0;
}
};
template <>
struct _cross<1, 3, 2> {
template <class Out, class E, class F>
void operator()(Out obegin, Out oend, E ebegin, F fbegin)
{
auto e0 = *ebegin;
++ebegin;
auto e1 = *ebegin;
++ebegin;
auto e2 = *ebegin;
auto f0 = *fbegin;
++fbegin;
auto f1 = *fbegin;
decltype(f1) f2 = 0;
*obegin = e1 *f2 - e2 *f1;
++obegin;
*obegin = e2 *f0 - e0 *f2;
++obegin;
*obegin = e0 *f1 - e1 *f0;
}
};
template <class E, class F>
types::ndarray<
typename __combined<typename E::dtype, typename F::dtype>::type,
types::array<long, E::value>>
cross(E const &e, F const &f)
{
using dtype =
typename __combined<typename E::dtype, typename F::dtype>::type;
types::array<long, E::value> out_shape;
sutils::copy_shape<0, 0>(out_shape, e,
utils::make_index_sequence<E::value - 1>());
if (e.template shape<E::value - 1>() == 2) {
if (f.template shape<F::value - 1>() == 2) {
out_shape[E::value - 1] = 1;
types::ndarray<dtype, types::array<long, E::value>> out{
out_shape, types::none_type{}};
_cross<E::value, 2, 2>{}(out.begin(), out.end(), e.begin(), f.begin());
return out;
} else {
out_shape[E::value - 1] = 3;
types::ndarray<dtype, types::array<long, E::value>> out{
out_shape, types::none_type{}};
_cross<E::value, 2, 3>{}(out.begin(), out.end(), e.begin(), f.begin());
return out;
}
} else {
if (f.template shape<F::value - 1>() == 2) {
out_shape[E::value - 1] = 3;
types::ndarray<dtype, types::array<long, E::value>> out{
out_shape, types::none_type{}};
_cross<E::value, 3, 2>{}(out.begin(), out.end(), e.begin(), f.begin());
return out;
} else {
out_shape[E::value - 1] = 3;
types::ndarray<dtype, types::array<long, E::value>> out{
out_shape, types::none_type{}};
_cross<E::value, 3, 3>{}(out.begin(), out.end(), e.begin(), f.begin());
return out;
}
}
}
}
PYTHONIC_NS_END
#endif