| Server IP : 217.160.0.212 / Your IP : 216.73.216.141 Web Server : Apache System : Linux www 6.18.51-i1-ampere #1196 SMP Fri Sep 11 20:43:55 CEST 2026 aarch64 User : sws1073854427 ( 1073854427) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /lib/python3/dist-packages/pythran/pythonic/numpy/linalg/ |
Upload File : |
#ifndef PYTHONIC_NUMPY_LINALG_MATRIX_POWER_HPP
#define PYTHONIC_NUMPY_LINALG_MATRIX_POWER_HPP
#include "pythonic/include/numpy/linalg/matrix_power.hpp"
#include "pythonic/numpy/array.hpp"
#include "pythonic/numpy/asarray.hpp"
#include "pythonic/numpy/identity.hpp"
#include "pythonic/numpy/dot.hpp"
#include "pythonic/builtins/NotImplementedError.hpp"
PYTHONIC_NS_BEGIN
namespace numpy
{
namespace linalg
{
namespace details
{
template <class E>
E fast_pow(E const &base, long n)
{
if (n == 1)
return base;
if (n == 2)
return numpy::functor::dot{}(base, base);
if (n == 3) {
auto tmp = numpy::functor::dot{}(base, base);
return numpy::functor::dot{}(tmp, base);
}
// starting from here, we know for sure that tmp will point to newly
// allocated memory
// this is used to optimize in-place dot computation in the odd case
auto tmp = fast_pow(base, n / 2);
if (n & 1) {
auto next = numpy::functor::dot{}(tmp, tmp);
return numpy::functor::dot{}(base, next, tmp);
} else {
return numpy::functor::dot{}(tmp, tmp);
}
}
}
template <class E>
auto matrix_power(E const &expr, long n)
-> decltype(numpy::functor::array{}(expr))
{
if (n == 0)
return numpy::functor::identity{}(expr.template shape<0>(),
types::dtype_t<typename E::dtype>{});
if (n > 0) {
auto base = numpy::functor::asarray{}(expr);
return details::fast_pow(base, n);
}
throw pythonic::builtins::NotImplementedError("negative power");
}
}
}
PYTHONIC_NS_END
#endif