Newton’s Method for Polynomial Square Roots is an algorithm that computes for a formal power series such that in time and space.

Tip

This problem can also be solved by Newton’s Method for Polynomial Powers in time and space.

Algorithm

Lemma

Let , then

For , find in the following way:

  1. Let . Apply Newton’s Method for Polynomial Inversion to find .
  2. Let . Apply the Fast Fourier Transform to find and .
  3. Use the results from 1 to find .
  4. Apply the Inverse Fast Fourier Transform to find .
  5. Apply the lemma to find .

This algorithm solves the problem in time and space.

std::vector<std::complex<double>> newton_sqrt(const std::vector<std::complex<double>> &a, int n) {
	std::vector x = {std::sqrt(a[0])};
	for (int m = 1; m < n; m *= 2) {
		std::vector y(a.begin(), a.begin() + std::min(2 * m, int(a.size())));
		auto z = newton_inv(x, 2 * m);
 
		y.resize(4 * m, 0), z.resize(4 * m, 0);
		fft(4 * m, y), fft(4 * m, z);
		for (int i = 0; i < 4 * m; i++) {
			y[i] *= z[i];
		}
		ifft(4 * m, y);
 
		x.resize(2 * m, 0);
		for (int i = 0; i < 2 * m; i++) {
			x[i] = (x[i] + y[i]) / (1. * 2);
		}
	}
	x.resize(n);
 
	return x;
}