Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Discrete Fourier Transform example #150

Merged
merged 18 commits into from
Dec 11, 2023
Merged

Add Discrete Fourier Transform example #150

merged 18 commits into from
Dec 11, 2023

Conversation

plafer
Copy link
Contributor

@plafer plafer commented Oct 5, 2023

Implements the Discrete Fourier Transform over the input list. Basically, this is the non-efficient version of the Number Theoretic Transform (NTT).

You can verify the correctness of the program by comparing with the Python implementation:

# Adapted from https://www.geeksforgeeks.org/python-number-theoretic-transformation/
from sympy import ntt 
  
seq = [15, 21, 13, 44] 
  
prime_no = 2**64 - 2**32 + 1
  
# ntt 
transform = ntt(seq, prime_no) 
print ("NTT : ", transform)

# NTT :  [93, 18440270144950239235, 18446744069414584284, 6473924464345090]

Conceptually though, this Miden implementation is closer to

from math import log2

PRIME = 2**64 - 2**32 + 1
TWO_ADIC_ROOT_OF_UNITY = 7277203076849721926

def get_root_of_unity(n):
    power = (1 << (32 - n)) % PRIME
    return pow(TWO_ADIC_ROOT_OF_UNITY, power, PRIME)

def f_k(seq, k, alpha):
    alpha_k = pow(alpha, k, PRIME)
    return sum([(seq[i] * pow(alpha_k, i, PRIME)) for i in range(len(seq))]) % PRIME

def ntt(seq, alpha):
    return [f_k(seq, k, alpha) for k in range(len(seq))]

seq = [15, 21, 13, 44]
alpha = get_root_of_unity(int(log2(len(seq))))

print(ntt(seq, alpha))

Copy link
Contributor

@Dominik1999 Dominik1999 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is amazing, thanks a lot.

I did a first round, but I need more time to wrap my head around it

examples/dft.masm Outdated Show resolved Hide resolved
Copy link
Contributor

@Dominik1999 Dominik1999 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nice example. I left a few comments but overall, its really nice. And I learned some things about the Discrete Fourier Transform (DFT).

One general comment, we now try to follow a common commenting style in MASM, see https://github.com/0xPolygonMiden/miden-base/blob/main/miden-lib/asm/faucets/basic.masm#L39C1-L39C1 where we always

  • explain a function or line of instructions above it, i.e. # get max supply of this faucet. We assume it is stored at pos 3 of slot 1
  • indicate the new stack below it, i.e., # => [max_supply, amount, tag, RECIPIENT, ...]

examples/dft.masm Outdated Show resolved Hide resolved
examples/dft.masm Outdated Show resolved Hide resolved
examples/dft.masm Show resolved Hide resolved
# Input: [n, v0, ..., v{n-1}, ...]
# Output: [...]
proc.store_array
# Store n
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to store n again here? Looks like you did that already in procedure main?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This store_array procedure was written to be self-contained (modulo the fact that it uses the global INPUT_ARR_LOC instead of receiving that address on the stack, but I got lazy); i.e. it can be used to store array of any length. So you could do (pseudocode)

# Storing arrays of different lengths
exec.store_array([4,1,2,3,4])
exec.store_array([3,1,2,3])

Basically, an array is [length, ele_0, ..., ele_{length-1}], and this mem_store stores the length (which could be different from call to call).

examples/dft.masm Outdated Show resolved Hide resolved
examples/dft.masm Show resolved Hide resolved
Copy link

sonarcloud bot commented Nov 17, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@plafer
Copy link
Contributor Author

plafer commented Nov 17, 2023

@Dominik1999 Changed the code to follow the comment convention

Copy link
Contributor

@Dominik1999 Dominik1999 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thanks!

@Dominik1999 Dominik1999 merged commit b38e5f5 into main Dec 11, 2023
4 checks passed
@Dominik1999 Dominik1999 deleted the plafer/dft-example branch December 11, 2023 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants