2

What would be an efficient algorithm to determine if $n \in \mathbb{N}$ can be written as $n = a^b$ for some $a,b \in \mathbb{N}, b>1$?

So far, I've tried:

def ispower(n):
    if n<=3:
        return False
    LIM = math.floor(math.log2(n))
    for b in range(2,LIM+1):
        a = math.pow(n, 1/b)
        a_floor = math.floor(a)
        print(a,a_floor)
        if a == a_floor:
            return True
    return False

That is, checking if the $b-th$ roots are integer, for $b$ from 2 to $LIM$, where $LIM$ stands for the ultimate limit of n being a power of 2.

Thanks for your comments.

MJD
  • 65,394
  • 39
  • 298
  • 580
Ricardo
  • 29
  • How large might $n$ be? When using Python floating point numbers (i.e., with a decimal point), you cannot count on reliably accurate results, especially for large numbers. By contrast, working only with the int (integer) data type, you will have accurate results until you overflow your computer. – paw88789 Mar 05 '22 at 20:41
  • 1
    This post cites a paper that gives a very efficient algorithm. – MJD Mar 05 '22 at 20:41

2 Answers2

1

If you restrict $b\geq 2$, then the most efficient way is probably simply testing each root $b = 2, 3, \ldots, \lfloor\log_2 n\rfloor$. This is of runtime $O(\log n)$ and can be implemented using the gmpy2 module efficiently:

import gmpy2

p = 197 e = 989 n = p ** e

b = 2 while 2 ** b <= n: root, exact = gmpy2.iroot(n, b) if exact: print(f"n is a {b}-th power") break b += 1 else: print(f"n is not a perfect power.") ```

Gareth Ma
  • 3,725
  • It's definitely not $O(\log n)$ because you can't extract a root in constant time. – MJD Mar 05 '22 at 20:46
  • 1
    @MJD My bad, I was referring to taking $O(\log n)$ roots. If we ignore the time complexity of multiplying large numbers then the algorithm is $O(\log^2 n)$ by binary search (I believe). – Gareth Ma Mar 05 '22 at 20:47
  • It's the same code, then. Thanks. – Ricardo Mar 05 '22 at 23:13
0

Since $n = n^1$, every number can be written in the required form. Thus an efficient algorithm is to always answer yes.

J.-E. Pin
  • 40,163