Пример #1
0
func FFT3dSpec(c gospec.Context) {
	signal := Alloc3d(32, 16, 8)
	for i := range signal {
		for j := range signal[i] {
			for k := range signal[i][j] {
				signal[i][j][k] = complex(float64(i+j+k), float64(-i-j-k))
			}
		}
	}
	forward := PlanDft3d(signal, signal, Forward, Estimate)
	c.Specify("Creating a plan doesn't overwrite an existing array if fftw.Estimate is used.", func() {
		for i := range signal {
			for j := range signal[i] {
				for k := range signal[i][j] {
					c.Expect(signal[i][j][k], gospec.Equals, complex(float64(i+j+k), float64(-i-j-k)))
				}
			}
		}
	})

	// As long as fx < dx/2, fy < dy/2, and fz < dz/2, where dx,dy,dz  are the lengths in
	// each dimension, there will be 2^n spikes, where n is the number of dimensions.
	// Each spike will be real and have magnitude equal to dx*dy*dz / 2^n
	dx := len(signal)
	fx := float64(dx) / 4
	dy := len(signal[0])
	fy := float64(dy) / 4
	dz := len(signal[0][0])
	fz := float64(dz) / 4
	for i := range signal {
		for j := range signal[i] {
			for k := range signal[i][j] {
				cosx := math.Cos(float64(i) / float64(dx) * fx * math.Pi * 2)
				cosy := math.Cos(float64(j) / float64(dy) * fy * math.Pi * 2)
				cosz := math.Cos(float64(k) / float64(dz) * fz * math.Pi * 2)
				signal[i][j][k] = complex(cosx*cosy*cosz, 0)
			}
		}
	}
	forward.Execute()
	c.Specify("Forward 3d FFT works properly.", func() {
		for i := range signal {
			for j := range signal[i] {
				for k := range signal[i][j] {
					if (i == int(fx) || i == dx-int(fx)) &&
						(j == int(fy) || j == dy-int(fy)) &&
						(k == int(fz) || k == dz-int(fz)) {
						c.Expect(real(signal[i][j][k]), gospec.IsWithin(1e-7), float64(dx*dy*dz/8))
						c.Expect(imag(signal[i][j][k]), gospec.IsWithin(1e-7), 0.0)
					} else {
						c.Expect(real(signal[i][j][k]), gospec.IsWithin(1e-7), 0.0)
						c.Expect(imag(signal[i][j][k]), gospec.IsWithin(1e-7), 0.0)
					}
				}
			}
		}
	})
}
Пример #2
0
func FFT1dSpec(c gospec.Context) {
	signal := Alloc1d(16)
	for i := range signal {
		signal[i] = complex(float64(i), float64(-i))
	}
	forward := PlanDft1d(signal, signal, Forward, Estimate)
	c.Specify("Creating a plan doesn't overwrite an existing array if fftw.Estimate is used.", func() {
		for i := range signal {
			c.Expect(signal[i], gospec.Equals, complex(float64(i), float64(-i)))
		}
	})

	// A simple real cosine should result in transform with two spikes, one at S[1] and one at S[-1]
	// The spikes should be real and have amplitude equal to len(S)/2 (because fftw doesn't normalize)
	for i := range signal {
		signal[i] = complex(math.Cos(float64(i)/float64(len(signal))*math.Pi*2), 0)
	}
	forward.Execute()
	c.Specify("Forward 1d FFT works properly.", func() {
		c.Expect(real(signal[0]), gospec.IsWithin(1e-9), 0.0)
		c.Expect(imag(signal[0]), gospec.IsWithin(1e-9), 0.0)
		c.Expect(real(signal[1]), gospec.IsWithin(1e-9), float64(len(signal))/2)
		c.Expect(imag(signal[1]), gospec.IsWithin(1e-9), 0.0)
		for i := 2; i < len(signal)-1; i++ {
			c.Expect(real(signal[i]), gospec.IsWithin(1e-9), 0.0)
			c.Expect(imag(signal[i]), gospec.IsWithin(1e-9), 0.0)
		}
		c.Expect(real(signal[len(signal)-1]), gospec.IsWithin(1e-9), float64(len(signal))/2)
		c.Expect(imag(signal[len(signal)-1]), gospec.IsWithin(1e-9), 0.0)
	})
}
Пример #3
0
func FFT3Spec(c gospec.Context) {
	signal := NewArray3(32, 16, 8)

	n0, n1, n2 := signal.Dims()
	for i := 0; i < n0; i++ {
		for j := 0; j < n1; j++ {
			for k := 0; k < n2; k++ {
				signal.Set(i, j, k, complex(float32(i+j+k), float32(-i-j-k)))
			}
		}
	}

	// As long as fx < dx/2, fy < dy/2, and fz < dz/2, where dx,dy,dz  are the lengths in
	// each dimension, there will be 2^n spikes, where n is the number of dimensions.
	// Each spike will be real and have magnitude equal to dx*dy*dz / 2^n
	dx := n0
	fx := float64(dx) / 4
	dy := n1
	fy := float64(dy) / 4
	dz := n2
	fz := float64(dz) / 4
	for i := 0; i < n0; i++ {
		for j := 0; j < n1; j++ {
			for k := 0; k < n2; k++ {
				cosx := math.Cos(float64(i) / float64(dx) * fx * math.Pi * 2)
				cosy := math.Cos(float64(j) / float64(dy) * fy * math.Pi * 2)
				cosz := math.Cos(float64(k) / float64(dz) * fz * math.Pi * 2)
				signal.Set(i, j, k, complex(float32(cosx*cosy*cosz), 0))
			}
		}
	}
	NewPlan3(signal, signal, Forward, Estimate).Execute().Destroy()
	c.Specify("Forward 3D FFT works properly.", func() {
		for i := 0; i < n0; i++ {
			for j := 0; j < n1; j++ {
				for k := 0; k < n2; k++ {
					if (i == int(fx) || i == dx-int(fx)) &&
						(j == int(fy) || j == dy-int(fy)) &&
						(k == int(fz) || k == dz-int(fz)) {
						c.Expect(real(signal.At(i, j, k)), gospec.IsWithin(1e-7), float32(dx*dy*dz/8))
						c.Expect(imag(signal.At(i, j, k)), gospec.IsWithin(1e-7), 0.0)
					} else {
						c.Expect(real(signal.At(i, j, k)), gospec.IsWithin(1e-7), 0.0)
						c.Expect(imag(signal.At(i, j, k)), gospec.IsWithin(1e-7), 0.0)
					}
				}
			}
		}
	})
}
Пример #4
0
func FFT2dSpec(c gospec.Context) {
	signal := Alloc2d(64, 8)
	for i := range signal {
		for j := range signal[i] {
			signal[i][j] = complex(float64(i+j), float64(-i-j))
		}
	}
	forward := PlanDft2d(signal, signal, Forward, Estimate)
	c.Specify("Creating a plan doesn't overwrite an existing array if fftw.Estimate is used.", func() {
		for i := range signal {
			for j := range signal[i] {
				c.Expect(signal[i][j], gospec.Equals, complex(float64(i+j), float64(-i-j)))
			}
		}
	})

	// As long as fx < dx/2 and fy < dy/2, where dx and dy are the lengths in each dimension,
	// there will be 2^n spikes, where n is the number of dimensions.  Each spike will be
	// real and have magnitude equal to dx*dy / 2^n
	dx := len(signal)
	fx := float64(dx) / 4
	dy := len(signal[0])
	fy := float64(dy) / 4
	for i := range signal {
		for j := range signal[i] {
			cosx := math.Cos(float64(i) / float64(dx) * fx * math.Pi * 2)
			cosy := math.Cos(float64(j) / float64(dy) * fy * math.Pi * 2)
			signal[i][j] = complex(cosx*cosy, 0)
		}
	}
	forward.Execute()
	c.Specify("Forward 2d FFT works properly.", func() {
		for i := range signal {
			for j := range signal[i] {
				if (i == int(fx) || i == dx-int(fx)) &&
					(j == int(fy) || j == dy-int(fy)) {
					c.Expect(real(signal[i][j]), gospec.IsWithin(1e-7), float64(dx*dy/4))
					c.Expect(imag(signal[i][j]), gospec.IsWithin(1e-7), 0.0)
				} else {
					c.Expect(real(signal[i][j]), gospec.IsWithin(1e-7), 0.0)
					c.Expect(imag(signal[i][j]), gospec.IsWithin(1e-7), 0.0)
				}
			}
		}
	})
}
Пример #5
0
func peakVerifier(s []complex64, c gospec.Context) {
	c.Expect(real(s[0]), gospec.IsWithin(1e-6), 0.0)
	c.Expect(imag(s[0]), gospec.IsWithin(1e-6), 0.0)
	c.Expect(real(s[1]), gospec.IsWithin(1e-6), float32(len(s))/2)
	c.Expect(imag(s[1]), gospec.IsWithin(1e-6), 0.0)
	for i := 2; i < len(s)-1; i++ {
		c.Expect(real(s[i]), gospec.IsWithin(1e-6), 0.0)
		c.Expect(imag(s[i]), gospec.IsWithin(1e-6), 0.0)
	}
	c.Expect(real(s[len(s)-1]), gospec.IsWithin(1e-6), float32(len(s))/2)
	c.Expect(imag(s[len(s)-1]), gospec.IsWithin(1e-6), 0.0)
}
Пример #6
0
func FFTR2CSpec(c gospec.Context) {
	signal := make([]float64, 16)
	F_signal := make([]complex128, 9)

	for i := range signal {
		signal[i] = math.Sin(float64(i) / float64(len(signal)) * math.Pi * 2)
	}
	forward := PlanDftR2C1d(signal, F_signal, Estimate)
	forward.Execute()
	c.Specify("Running a R2C transform doesn't destroy the input.", func() {
		for i := range signal {
			c.Expect(signal[i], gospec.Equals, math.Sin(float64(i)/float64(len(signal))*math.Pi*2))
		}
	})

	c.Specify("Forward 1d Real to Complex FFT  works properly.", func() {
		c.Expect(real(F_signal[0]), gospec.IsWithin(1e-9), 0.0)
		c.Expect(imag(F_signal[0]), gospec.IsWithin(1e-9), 0.0)
		c.Expect(real(F_signal[1]), gospec.IsWithin(1e-9), 0.0)
		c.Expect(imag(F_signal[1]), gospec.IsWithin(1e-9), -float64(len(signal))/2)
		for i := 2; i < len(F_signal)-1; i++ {
			c.Expect(real(F_signal[i]), gospec.IsWithin(1e-9), 0.0)
			c.Expect(imag(F_signal[i]), gospec.IsWithin(1e-9), 0.0)
		}
	})
}
Пример #7
0
func FFT2Spec(c gospec.Context) {
	signal := NewArray2(64, 8)
	n0, n1 := signal.Dims()
	for i := 0; i < n0; i++ {
		for j := 0; j < n1; j++ {
			signal.Set(i, j, complex(float32(i+j), float32(-i-j)))
		}
	}

	// As long as fx < dx/2 and fy < dy/2, where dx and dy are the lengths in each dimension,
	// there will be 2^n spikes, where n is the number of dimensions.  Each spike will be
	// real and have magnitude equal to dx*dy / 2^n
	dx := n0
	fx := float64(dx) / 4
	dy := n1
	fy := float64(dy) / 4
	for i := 0; i < n0; i++ {
		for j := 0; j < n1; j++ {
			cosx := math.Cos(float64(i) / float64(dx) * fx * math.Pi * 2)
			cosy := math.Cos(float64(j) / float64(dy) * fy * math.Pi * 2)
			signal.Set(i, j, complex(float32(cosx*cosy), 0))
		}
	}
	NewPlan2(signal, signal, Forward, Estimate).Execute().Destroy()
	c.Specify("Forward 2D FFT works properly.", func() {
		for i := 0; i < n0; i++ {
			for j := 0; j < n1; j++ {
				if (i == int(fx) || i == dx-int(fx)) &&
					(j == int(fy) || j == dy-int(fy)) {
					c.Expect(real(signal.At(i, j)), gospec.IsWithin(1e-7), float32(dx*dy/4))
					c.Expect(imag(signal.At(i, j)), gospec.IsWithin(1e-7), 0.0)
				} else {
					c.Expect(real(signal.At(i, j)), gospec.IsWithin(1e-7), 0.0)
					c.Expect(imag(signal.At(i, j)), gospec.IsWithin(1e-7), 0.0)
				}
			}
		}
	})
}
Пример #8
0
func FFTC2RSpec(c gospec.Context) {
	signal := make([]float64, 16)
	F_signal := make([]complex128, 9)

	forward := PlanDftR2C1d(signal, F_signal, Estimate)
	backward := PlanDftC2R1d(F_signal, signal, Estimate)
	for i := range signal {
		signal[i] = float64(i)
	}
	forward.Execute()
	backward.Execute()

	c.Specify("Forward 1d Complx to Real FFT  works properly.", func() {
		for i := 0; i < len(signal); i++ {
			c.Expect(signal[i], gospec.IsWithin(1e-7), float64(i*len(signal)))
		}
	})
}