Skip to main content

Algorithm

In this section, we will go through the Circle FFT algorithm specifically, to interpolate a bivariate polynomial given the evaluations over a circle domain. We will also go over a concrete example which will help us understand the algorithm. Circle FFT follows a divide-and-conquer strategy, as in the classical Cooley–Tukey FFT. We recursively reduce the task of interpolating a polynomial over some domain to interpolating a lower degree polynomial over a smaller domain. Thus at each recursive layer, we have “smaller” polynomials and their evaluations over “smaller” domains. Let us first go over this sequence of domains for the Circle FFT algorithm.

Sequence of Domains for Circle FFT

In Circle FFT, we use a 2-to-1 map to halve the domain size at each recursive layer. The domain used here is the circle domain DnD_n of size Dn=2n|D_n| = 2^n. Dn=q+gn1q+gn1D_n = q + \langle g_{n-1} \rangle \cup -q + \langle g_{n-1} \rangle This section describes two specific 2-to-1 maps that are central to the Circle FFT construction:
  1. Projection map πx\pi_x: The projection map πx\pi_x projects the points (x,y)(x,y) and (x,y)(x,-y) to the same xx-coordinate i.e. πx:DnSn,πx((x,y))=x\pi_x: D_n \rightarrow S_n, \quad \pi_x((x, y)) = x where SnS_n is the set containing all the xx-coordinates from DnD_n. This can be interpreted as saying that two points are considered equivalent if they differ only by sign. Since πx\pi_x maps two points from DnD_n to a single element in SnS_n, the size of SnS_n will be half the size of DnD_n.
  2. Squaring map π\pi: The squaring map π\pi is a 2-to-1 map defined by: π:SnSn1,π(x)=2x21\pi: S_n \rightarrow S_{n-1}, \quad \pi(x) = 2x^2 - 1 This is obtained using the doubling map and the equality y2=1x2y^2 = 1 - x^2 to compute the xx-coordinate: π(x,y)=(x,y)+(x,y)=(x2y2,2xy)=(2x21,2xy)\pi(x, y) = (x, y) + (x, y) = (x^2 - y^2, 2xy) = (2x^2-1, 2xy)
In Circle FFT, we use both the projection map πx\pi_x and the squaring map π\pi to construct the sequence of domains. The sequence of domains for Circle FFT is shown as follows: DnπxSnπSn1ππS1D_n \xrightarrow{\pi_x} S_n \xrightarrow{\pi} S_{n-1} \xrightarrow{\pi} \cdots \xrightarrow{\pi} S_1 Now that we know the sequence of domains, let us dive into the Circle FFT algorithm.

Circle FFT

The Circle FFT interpolates a bivariate polynomial p(x,y)p(x,y) from the polynomial space LN(F)L_N(F), given the evaluations over a circle domain DnD_n of size N=2nN=2^n. The algorithm is a three step process described as follows.

Step 1: Decompose p(x,y)p(x, y) into sub-polynomials

In the first step, we decompose the bivariate polynomial p(x,y)p(x, y) over DnD_n using the projection map πx\pi_x into two univariate polynomials p0(x)p_0(x) and p1(x)p_1(x) as follows: p(x,y)=p0(πx(x,y))+yp1(πx(x,y))=p0(x)+yp1(x)p(x, y) = p_0(\pi_x(x, y)) + y \cdot p_1(\pi_x(x, y)) = p_0(x) + y \cdot p_1(x) Now to continue with the FFT algorithm, we want to compute the evaluations of p0(x)p_0(x) and p1(x)p_1(x) over the smaller domain Sn=πx(Dn)S_n = \pi_x(D_n), given the evaluations of p(x,y)p(x, y) over DnD_n. This is done using the following equations: p0(x)=p(x,y)+p(x,y)2,p1(x)=p(x,y)p(x,y)2yp_0(x) = \frac{p(x, y) + p(x, -y)}{2}, \quad p_1(x) = \frac{p(x, y) - p(x, -y)}{2 \cdot y} Substituting all evaluations of p(x,y)p(x, y) over DnD_n in the above equations, gives the evaluations of p0(x)p_0(x) and p1(x)p_1(x) over the domain SnS_n.
To compute the evaluations of p1(x)p_1(x) over the domain SnS_n, we subtract the evaluations i.e. compute p(x,y)p(x,y)p(x, y) - p(x, -y) and then divide by 2y2 \cdot y. These values yy are the yy-coordinates of the points in the circle domain DnD_n. They are also referred to as circle twiddles and they only depend on the circle domain DnD_n. Therefore they can be precomputed before the start of the FFT algorithm. We will look into these in detail in the next section.
Example: To make all the calculations easier we will work on a concrete example over the Mersenne prime p=251=31p = 2^5 - 1 = 31. Thus all calculations are over F31\mathbb{F}_{31}, i.e, modulo 3131. We are given the evaluations v=[13,16,9,30,29,27,13,21]\vec{v} = [13, 16, 9, 30, 29, 27, 13, 21] of p(x,y)p(x, y) over the circle domain D3=[(7,18),(13,7),(24,13),(18,24),(7,13),(13,24),(24,18),(18,7)]D_3 = [(7, 18), (13, 7), (24, 13), (18, 24), (7, 13), (13, 24), (24, 18), (18, 7)] and we want to compute the coefficients of p(x,y)p(x, y) i.e. interpolate p(x,y)p(x, y) given its evaluations v\vec{v} over D3D_3. Step 1: . First, decompose the polynomial p(x,y)p(x, y) using the map πx(x,y)=x\pi_x(x, y) = x: p(x,y)=p0(πx(x,y))+yp1(πx(x,y))=p0(x)+yp1(x)p(x, y) = p_0(\pi_x(x, y)) + y \cdot p_1(\pi_x(x, y)) = p_0(x) + y \cdot p_1(x) Given the evaluations v\vec{v} of p(x,y)p(x, y) over the circle domain D3D_3 we aim to compute the evaluations of p0p_0 and p1p_1 over the smaller domain S3S_3: S3=πx(D3)=[7,13,24,18]S_3 = \pi_x(D_3) = [7, 13, 24, 18] For (x,y)=(7,18)(x, y)=(7, 18) and (x,y)=(7,13)(x, -y) = (7, 13) in D3D_3, substituting them into the following equations give: p0(x)=p(x,y)+p(x,y)2=p(7,18)+p(7,13)2=13+292=21p_0(x) = \frac{p(x, y) + p(x, -y)}{2} = \frac{p(7, 18) + p(7, 13)}{2} = \frac{13 + 29}{2} = 21 p1(x)=p(x,y)p(x,y)2y=p(7,18)p(7,13)218=1329218=3p_1(x) = \frac{p(x, y) - p(x, -y)}{2 \cdot y} = \frac{p(7, 18) - p(7, 13)}{2 \cdot 18} = \frac{13 - 29}{2 \cdot 18} = 3 Repeating this process for other pairs (x,y)(x, y) and (x,y)(x, -y) in D3D_3, we obtain: v0=[21,6,11,10],v1=[3,28,7,6]\vec{v_0} = [21, 6, 11, 10], \quad \vec{v_1} = [3, 28, 7, 6]

Step 2: Recursively apply FFT to sub-polynomials

Given the evaluations of p0(x)p_0(x) and p1(x)p_1(x) over SnS_n, we now compute their coefficients. This step mirrors the recursive structure of the Cooley–Tukey FFT. Each polynomial is recursively split using the squaring map π(x)=2x21\pi(x) = 2x^2 - 1, and the process continues over successively smaller domains. We begin by decomposing p0(x)p_0(x) using the squaring map π\pi as follows: p0(x)=p00(π(x))+xp01(π(x))p_0(x) = p_{00}(\pi(x)) + x \cdot p_{01}(\pi(x)) We compute the evaluations of p00(x)p_{00}(x) and p01(x)p_{01}(x) over Sn1=π(Sn)S_{n-1} = \pi(S_n) using the following equations. p00(π(x))=p0(x)+p0(x)2,p01(π(x))=p0(x)p0(x)2xp_{00}(\pi(x)) = \frac{p_0(x) + p_0(-x)}{2}, \quad p_{01}(\pi(x)) = \frac{p_0(x) - p_0(-x)}{2 \cdot x} This recursive process continues until we reach the base case: all evaluations of the polynomial over the domain are same. At that level, the coefficient is simply the evaluation of the constant polynomial. Finally, we reconstruct the coefficients of p0(x)p_0(x) by working backward through the recursive calls, using the decomposition equation at each level. The same process applies to compute the coefficients of p1(x)p_1(x).
Similar to circle twiddles, to compute the evaluations of p01(x)p_{01}(x) over Sn1S_{n-1} we divide by the values xx which are the values from the domain SnS_n. These values xx are referred to as line twiddles. For the next recursive layer, we divide by values from Sn1S_{n-1} i.e. π(x)\pi(x) and for the next recursive layer we divide by π2(x)\pi^2(x) and so on. Thus the line twiddles is a vector of values x,π(x),π2(x),x, \pi(x), \pi^2(x), \ldots and so on. These only depend on the initial domain DnD_n and thus can be precomputed before the start of the algorithm.
Step 2: Given the evaluations of p0p_0 and p1p_1 over S3=[7,13,24,18]S_3 = [7, 13, 24, 18]: v0=[21,6,11,10],v1=[3,28,7,6]\vec{v_0} = [21, 6, 11, 10], \quad \vec{v_1} = [3, 28, 7, 6] we recursively apply the FFT algorithm to compute the coefficients of p0p_0 and p1p_1. At each layer, we decompose the polynomial using the polynomial map π(x)\pi(x). For example, the decomposition of p0(x)p_0(x) is: p0(x)=p00(π(x))+xp01(π(x))p_0(x) = p_{00}(\pi(x)) + x \cdot p_{01}(\pi(x)) Omitting the intermediate steps of the recursive calls, we eventually obtain the coefficients of p0(x)p_0(x) and p1(x)p_1(x) as follows: p0(x)=12+26x+π(x)+28xπ(x)p_0(x) = 12 + 26 \cdot x + \pi(x) + 28 \cdot x \cdot \pi(x) p1(x)=11+26x+14π(x)+20xπ(x)p_1(x) = 11 + 26 \cdot x + 14 \cdot \pi(x) + 20 \cdot x \cdot \pi(x)

Step 3: Combine the coefficients

Finally, we combine the coefficients of p0(x)p_0(x) and p1(x)p_1(x) to compute the coefficients of the original bivariate polynomial p(x,y)p(x, y), using the decomposition: p(x,y)=p0(x)+yp1(x)p(x, y) = p_0(x) + y \cdot p_1(x)
Step 3: Given the coefficients of p0(x)p_0(x) and p1(x)p_1(x): p0(x)=12+26x+π(x)+28xπ(x)p_0(x) = 12 + 26 \cdot x + \pi(x) + 28 \cdot x \cdot \pi(x) p1(x)=11+26x+14π(x)+20xπ(x)p_1(x) = 11 + 26 \cdot x + 14 \cdot \pi(x) + 20 \cdot x \cdot \pi(x) we reconstruct the original polynomial p(x,y)p(x, y) using the decomposition: p(x,y)=p0(x)+yp1(x)p(x, y) = p_0(x) + y \cdot p_1(x) Substituting the expressions for p0p_0 and p1p_1, we get: p(x,y)=12+26x+π(x)+28xπ(x)+y(11+26x+14π(x)+20xπ(x))p(x, y) = 12 + 26 \cdot x + \pi(x) + 28 \cdot x \cdot \pi(x) + y \cdot (11 + 26 \cdot x + 14 \cdot \pi(x) + 20 \cdot x \cdot \pi(x)) p(x,y)=12+26x+π(x)+28xπ(x)+p(x, y) = 12 + 26 \cdot x + \pi(x) + 28 \cdot x \cdot \pi(x) + \quad \quad \quad \quad \quad \quad 11y+26xy+14yπ(x)+20xyπ(x)\quad \quad \quad \quad \quad \quad 11 \cdot y + 26 \cdot x \cdot y + 14 \cdot y \cdot \pi(x) + 20 \cdot x \cdot y \cdot \pi(x)
This completes an overview of the interpolation algorithm using Circle FFT. In the next section, we will see how the twiddle values are computed and stored for Circle FFT.