Roots Of Unity - Is It Primitive?

Click For Summary

Discussion Overview

The discussion revolves around the determination of primitive nth roots of unity, particularly focusing on the algorithmic approach to identify these roots for both odd and even values of n. Participants explore the conditions under which roots are considered primitive and share Python code to illustrate their points.

Discussion Character

  • Technical explanation
  • Mathematical reasoning
  • Debate/contested

Main Points Raised

  • One participant suggests that for odd n, testing if (n, k) are coprime is sufficient for determining primitive roots, but questions arise regarding even n.
  • Another participant challenges the validity of using (n-k-1, n) for even n, stating that the code outputs incorrect results.
  • A participant proposes moving the coprime function call to test (k, n) first, indicating that this approach yields correct results for n=4.
  • There is a discussion about whether only the first rotation needs to be calculated for a primitive nth root, suggesting an O(1) time complexity, which is later contested.
  • Concerns are raised about the correctness of the algorithm when n=2, where the expected primitive root is -1, but the algorithm yields +1.
  • Participants discuss the implications of removing certain checks in the code and how it affects the output of primitive roots.
  • One participant simplifies the algorithm significantly, leading to a simpler function for calculating a primitive nth root.
  • There is a debate about the time complexity of the operations involved, particularly regarding division and multiplication in the context of algorithm efficiency.

Areas of Agreement / Disagreement

Participants express differing views on the correctness of the algorithm for even values of n and the conditions for determining primitive roots. There is no consensus on the optimal approach or the validity of the proposed methods.

Contextual Notes

Some participants note that the algorithm's performance and correctness may depend on specific assumptions about the values of n and the definitions used in the coprimality tests.

Who May Find This Useful

Readers interested in computational mathematics, algorithm design, and the properties of roots of unity may find this discussion relevant.

Sane
Messages
220
Reaction score
0
All right, thanks to everybody's help, I've got the algorithm for determining the nth roots of unity.

However, for determining which ones are primitive, I'm still having a little trouble.

If n is odd, I can test if (n, k) are coprime. However, for even values of n, it seems that it doesn't work.

I took a guess and tried to see if (n-k-1, n) are coprime, to determine if the nth root of unity is primitive. It seems to work for all known examples I've tried.

Is that guess of mine incorrect? If not, what should I do for even values of n?

Here's some Python code, demonstrating that an even value of n, 4, yields only primitive roots of unity, by testing if (n-k-1, n) are coprime. Highlighted in blue.[/color]

Code:
import math

def resolve_limit (value):
    if value < 0.00001 and value > - 0.00001:
        return 0
    if value > 0.49999 and value < 0.50001:
        return 0.5
    if value < -0.49999 and value > -0.50001:
        return -0.5
    return value

def polar_to_complex (r, theta):
    a = math.cos (theta) * r
    b = math.sin (theta) * r
    a = resolve_limit (a)
    b = resolve_limit (b)
    return (a, b)

def gcd (a, b):
    while b:
        a, b = b, a % b
    return a

def coprime (a, b):
    if a == 0 or b == 0:
        return False
    return gcd (a, b) == 1

def prime_nth_roots (n):
    is_even = (n%2 == 0)

    for k in range (n):

        if is_even:
            [b]if coprime (n-k-1, n)[/color][/b]:
                angle = k * 2 * math.pi / float(n)
                yield polar_to_complex (-1, angle)

        else:
            if coprime (k, n):
                angle = k * 2 * math.pi / float(n)
                yield polar_to_complex (1, angle)

print [root for root in prime_nth_roots (4)]
 
Last edited:
Mathematics news on Phys.org
Sane said:
If n is odd, I can test if (n, k) are coprime. However, for even values of n, it seems that it doesn't work.
Why do you think that?


Here's some Python code, demonstrating that an even value of n, 4, yields only primitive roots of unity, by testing if (n-k-1, n) are coprime.
This code gives wrong answers.
 
Hurkyl said:
Why do you think that?

I think that because it wasn't outputting the correct answers, as suggested for certain situations. If you move my coprime function call test to the first dimension of the conditional statements, using the call "coprime (k, n)", and let n=4, it does not get the right answers.

Hurkyl said:
This code gives wrong answers.

Are you positive? The code outputs:

>>>[/color]
[(-1.0, 0), (1.0, 0)][/color]

Which translates to +i and -i.

According to Wikipedia, these are the correct primitive nth roots of unity where n = 4.

Wikipedia said:
The fourth roots of unity are

\left\{ 1, +i, -1, -i \right\} ,

of which +i and -i are primitive.
 
Traditionally, and how you've written your code,

(a, b)

corresponds to

a + bi.
 
Yeah, I smacked my forehead right after I made that post. No sooner than I made that statement, I made the connection that my conclusion wasn't even correct in the first place. :-p

Oh geez. Hahah. So was it correct to only test coprime(n, k)?

Furthermore, if I only need "a primitive nth root of unity", do I only need to calculate and return the first rotation, since (1, n) will always be coprime? Which reduces the algorithm to O(1) time? :biggrin:
 
I was hoping you'd see it just before you made your post. :wink:


Furthermore, if I only need "a primitive nth root of unity", do I only need to calculate and return the first rotation, since (1, n) will always be coprime? Which reduces the algorithm to O(n) time?
Why wouldn't it work?

Incidentally, isn't it much faster than O(n) time? You're just doing a couple multiplies and computing one sine and one cosine.
 
Last edited:
this programmed approach seems silly to me. just think about it.
 
I assume computing the primitive 4-th roots was merely a test of his program, not the end goal.
 
Hahaha, yes. I actually immediately edited it to O(1) after I made the post. I'm surprised that you managed to catch my original post. You must have been close by at the time I posted.

It's O(1) because generally mathematical computations are expressed as a constant, even though they may themselves, take linear (or even polynomial) time.

Hurkyl said:
Why wouldn't it work?
Just checking. That's great then! I just did not want to make a catastrophic mistake that could ressonate throughout my entire program!

Hurkyl said:
I assume computing the primitive 4-th roots was merely a test of his program, not the end goal.

Precisely. The "Discrete Weighted Transform With An Irrational Base" (DWTIB) requires a primitive nth root of unity in the appropriate domain, where n is the chosen run time for the Algorithm W variant of the DWT.
 
Last edited:
  • #10
I believe I found out why I figured my algorithm to be incorrect (yet used a wrong example in my first post)...

If n = 2, the only supposed primitive root is -1, yet my algorithm yields +1.

Code:
import math

def resolve_limit (value):
    if value < 0.00001 and value > - 0.00001:
        return 0
    if value > 0.49999 and value < 0.50001:
        return 0.5
    if value < -0.49999 and value > -0.50001:
        return -0.5
    return value

def deg_to_rad (deg):
    return deg * math.pi / 180.0

def complex_to_polar (a, b):
    r = (a**2.0 + b**2.0)**0.5
    theta = math.acos (a / r)
    return (r, theta)

def polar_to_complex (r, theta):
    a = math.cos (theta) * r
    b = math.sin (theta) * r
    a = resolve_limit (a)
    b = resolve_limit (b)
    return (a, b)

def gcd (a, b):
    while b:
        a, b = b, a % b
    return a

def coprime (a, b):
    if a == 0 or b == 0:
        return False
    return gcd (a, b) == 1

def prime_nth_roots (n):
    is_even = n%2 == 0
    for k in range (n):
        if coprime (k, n):
            angle = k * 2 * math.pi / float(n)
            yield polar_to_complex ((1, -1)[is_even], angle)

def a_prime_nth_root (n):
    is_even = n%2 == 0
    angle = 2 * math.pi / float(n)
    return polar_to_complex ((1, -1)[is_even], angle)

if __name__ == '__main__':
    n = 2
    
    print [root for root in prime_nth_roots (n)]
    print a_prime_nth_root (n)
 
  • #11
When I ran your original algorithm on 2 (after removing the "is_even" check), it gives me -1 is the only primitive root of 1.

When I run this new code, it says 1 is a primitive square root of 1.
 
  • #12
In my second code I used a length of negative 1 for an even value of n. While in the first code, if you removed the "is_even" check, it would have used positive 1.

If a value of n is even, you need to either add pi to the angle, or set the length to negative 1.

That's not for something else is it?
 
  • #13
That's not for something else is it?
I think you're thinking of the trick to turn a primitive n-th root into a primitive (2n)-th root. (with n odd)
 
  • #14
Oh my... so the algorithm dumbs down to something as little as...

Code:
def a_prime_nth_root (n):
    return polar_to_complex (1, 2 * math.pi / float(n))

Jesus christ, that's a lot simpler. Heh. Thanks for the help.
 
  • #15
Sane said:
Hahaha, yes. I actually immediately edited it to O(1) after I made the post. I'm surprised that you managed to catch my original post. You must have been close by at the time I posted.

There's no way it's O(1). You're doing a division, which takes O(log(n)) absolute minimum -- and probably more like O(log(n)2).
 
  • #16
Division and multiplication of 16-32 bit numbers is often only one operation for most 32-64 bit processors. n will never be more than 2 bytes.
 
Last edited:

Similar threads

  • · Replies 22 ·
Replies
22
Views
2K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
Replies
0
Views
2K
  • · Replies 8 ·
Replies
8
Views
7K
  • · Replies 17 ·
Replies
17
Views
4K
Replies
1
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
Replies
8
Views
3K