问题
Given a set of n particles electric charge carriers founds on the points (1,0), (2,0), .... (n,0) on a plane. The particle charge that found in point (i,0) is noted as Qi. the force that act on the particle is given by the formula:
C is a Coulomb's constant.Give an algorithm to calculate Fi, for all of the particles in total complexity O(nlgn). Hint: use FFT algorithm.
It seems that Fi is already divided to the even and odd points..
I thought about to divide each sum to calculate the FFT (but divide until what..?) and then sum always half of the points (cause this is what FFT cause) and then subtract the result of the sums that given on the formula..
any idea of how to do it better?
回答1:
looks like homework so no actual code for your case is provided instead some example and hints.
for FFT-like algorithms:
set the dataset size to power of
2
by zero paddingso the division to halves is simple (no remainders)
create recursive function to compute your FFT-like stuff
in it reorder the data set, divide it to two halves and recursively call it self 2 times (each with the different half of data) and add if statement to start. If dataset
size<=1
or2
then return directly computed value to ensure that recursion stops.After these two recursion calls reorder data back and combine them to result
remove zero padding from the result if needed
For example this is how mine NTT looks like (Number theoretic transform)
//---------------------------------------------------------------------------
void fourier_NTT:: NTT_fast(DWORD *dst,DWORD *src,DWORD n,DWORD w)
{
// recursion stop condition if the data is single number ...
if (n<=1) { if (n==1) dst[0]=src[0]; return; }
DWORD i,j,a0,a1,n2=n>>1,w2=modmul(w,w);
// reorder even,odd to dst array
for (i=0,j=0;i<n2;i++,j+=2) dst[i]=src[j];
for ( j=1;i<n ;i++,j+=2) dst[i]=src[j];
// recursion
NTT_fast(src ,dst ,n2,w2); // even
NTT_fast(src+n2,dst+n2,n2,w2); // odd
// restore results
for (w2=1,i=0,j=n2;i<n2;i++,j++,w2=modmul(w2,w))
{
a0=src[i];
a1=modmul(src[j],w2);
dst[i]=modadd(a0,a1);
dst[j]=modsub(a0,a1);
}
}
//---------------------------------------------------------------------------
Full source code and more info is here.
Always compare Fast implementation results with the slow implementation !!!
A small error in some coefficient or index can lead to huge differences in results with growing dataset size.
This is slow implementation for above NTT function:
//---------------------------------------------------------------------------
void fourier_NTT:: NTT_slow(DWORD *dst,DWORD *src,DWORD n,DWORD w)
{
DWORD i,j,wj,wi,a,n2=n>>1;
for (wj=1,j=0;j<n;j++)
{
a=0;
for (wi=1,i=0;i<n;i++)
{
a=modadd(a,modmul(wi,src[i]));
wi=modmul(wi,wj);
}
dst[j]=a;
wj=modmul(wj,w);
}
}
//---------------------------------------------------------------------------
[Notes]
now you have your separation equation
derive the coefficient difference between directly computed value and value computed by 2x half recursion call and restore your result accordingly so the output match the correct result.
来源:https://stackoverflow.com/questions/23627751/using-the-fft-algorithm-to-calculate