예제 #1
0
        private void ComputeKernelTilde()
        {
            //Evaluate the kernel at the interpolation nodes and form the embedded generating kernel vector for a circulant matrix
            int n_fft_coeffs = 2 * n_interpolation_points_1d;

            for (int i = 0; i < n_interpolation_points_1d; i++)
            {
                for (int j = 0; j < n_interpolation_points_1d; j++)
                {
                    for (int k = 0; k < n_interpolation_points_1d; k++)
                    {
                        fft[((n_interpolation_points_1d + i) * n_fft_coeffs + n_interpolation_points_1d + j) * n_fft_coeffs + n_interpolation_points_1d + k]
                                          = fft[((n_interpolation_points_1d - i) * n_fft_coeffs + n_interpolation_points_1d + j) * n_fft_coeffs + n_interpolation_points_1d + k]
                                          = fft[((n_interpolation_points_1d + i) * n_fft_coeffs + n_interpolation_points_1d - j) * n_fft_coeffs + n_interpolation_points_1d + k]
                                          = fft[((n_interpolation_points_1d - i) * n_fft_coeffs + n_interpolation_points_1d - j) * n_fft_coeffs + n_interpolation_points_1d + k]
                                          = fft[((n_interpolation_points_1d + i) * n_fft_coeffs + n_interpolation_points_1d + j) * n_fft_coeffs + n_interpolation_points_1d - k]
                                          = fft[((n_interpolation_points_1d - i) * n_fft_coeffs + n_interpolation_points_1d + j) * n_fft_coeffs + n_interpolation_points_1d - k]
                                          = fft[((n_interpolation_points_1d + i) * n_fft_coeffs + n_interpolation_points_1d - j) * n_fft_coeffs + n_interpolation_points_1d - k]
                                          = fft[((n_interpolation_points_1d - i) * n_fft_coeffs + n_interpolation_points_1d - j) * n_fft_coeffs + n_interpolation_points_1d - k]
                                          = SquaredCauchy(tilde[0], tilde[i], tilde[j], tilde[k]);
                    }
                }
            }

            // Precompute the FFT of the kernel generating matrix
            Fourier.ForwardMultiDim(fft, new int[] { n_fft_coeffs, n_fft_coeffs, n_fft_coeffs }, FourierOptions.NoScaling);
            for (int i = fft.Length - 1; i >= 0; i--)
            {
                kernel_tilde[i] = fft[i].Real;
            }
        }
예제 #2
0
        private void NBodyFFT()
        {
            //Compute the values v_{m, n} at the equispaced nodes, multiply the kernel matrix with the coefficients w
            int n_fft_coeffs = 2 * n_interpolation_points_1d;

            for (int d = 0; d < n_terms; d += 2)
            {
                Array.Clear(fft, 0, fft.Length);
                for (int i = 0; i < n_interpolation_points_1d; i++)
                {
                    for (int j = 0; j < n_interpolation_points_1d; j++)
                    {
                        for (int k = 0; k < n_interpolation_points_1d; k++)
                        {
                            fft[(i * n_fft_coeffs + j) * n_fft_coeffs + k] = new Complex(tilde_values[((i * n_interpolation_points_1d + j) * n_interpolation_points_1d + k) * n_terms + d],
                                                                                         (d == n_terms - 1) ? 0 : tilde_values[((i * n_interpolation_points_1d + j) * n_interpolation_points_1d + k) * n_terms + d + 1]);
                        }
                    }
                }

                Fourier.ForwardMultiDim(fft, new int[] { n_fft_coeffs, n_fft_coeffs, n_fft_coeffs });

                // Take the Hadamard product of two complex vectors
                for (int i = kernel_tilde.Length - 1; i >= 0; i--)
                {
                    fft[i] *= kernel_tilde[i];
                }

                // Invert the computed values at the interpolated nodes
                Fourier.InverseMultiDim(fft, new int[] { n_fft_coeffs, n_fft_coeffs, n_fft_coeffs });

                for (int i = 0; i < n_interpolation_points_1d; i++)
                {
                    for (int j = 0; j < n_interpolation_points_1d; j++)
                    {
                        for (int k = 0; k < n_interpolation_points_1d; k++)
                        {
                            tilde_values[((i * n_interpolation_points_1d + j) * n_interpolation_points_1d + k) * n_terms + d] = fft[((n_interpolation_points_1d + i) * n_fft_coeffs + n_interpolation_points_1d + j) * n_fft_coeffs + n_interpolation_points_1d + k].Real;
                            if (d != n_terms - 1)
                            {
                                tilde_values[((i * n_interpolation_points_1d + j) * n_interpolation_points_1d + k) * n_terms + d + 1] = fft[((n_interpolation_points_1d + i) * n_fft_coeffs + n_interpolation_points_1d + j) * n_fft_coeffs + n_interpolation_points_1d + k].Imaginary;
                            }
                        }
                    }
                }
            }
        }