func zero(x *fftw.Array2) { m, n := x.Dims() for i := 0; i < m; i++ { for j := 0; j < n; j++ { x.Set(i, j, 0) } } }
// ai <- k ai func scale(k complex128, c *fftw.Array2) { m, n := c.Dims() for i := 0; i < m; i++ { for j := 0; j < n; j++ { c.Set(i, j, k*c.At(i, j)) } } }
// ci <- k conj(ai) bi func scaleMul(c *fftw.Array2, k complex128, a, b *fftw.Array2) { m, n := a.Dims() for i := 0; i < m; i++ { for j := 0; j < n; j++ { ax := cmplx.Conj(a.At(i, j)) bx := b.At(i, j) c.Set(i, j, k*ax*bx) } } }
// ci <- ci + conj(ai) bi func addMul(c *fftw.Array2, a, b *fftw.Array2) { m, n := a.Dims() for i := 0; i < m; i++ { for j := 0; j < n; j++ { ax := cmplx.Conj(a.At(i, j)) bx := b.At(i, j) cx := c.At(i, j) c.Set(i, j, cx+ax*bx) } } }
// Assumes that f is no smaller than x. // Pads with zeros. func copyChannelTo(x *fftw.Array2, f *rimg64.Multi, p int) { w, h := x.Dims() for u := 0; u < w; u++ { for v := 0; v < h; v++ { if u < f.Width && v < f.Height { x.Set(u, v, complex(f.At(u, v, p), 0)) } else { x.Set(u, v, 0) } } } }
func copyImageTo(x *fftw.Array2, f *rimg64.Image) { w, h := x.Dims() for u := 0; u < w; u++ { for v := 0; v < h; v++ { if u < f.Width && v < f.Height { x.Set(u, v, complex(f.At(u, v), 0)) } else { x.Set(u, v, 0) } } } }
// dst[i, j] = src[i*stride + offset.X, j*stride + offset.Y], // or zero if this is outside the boundary. func copyChannelStrideTo(dst *fftw.Array2, src *rimg64.Multi, channel, stride int, offset image.Point) { m, n := dst.Dims() bnds := image.Rect(0, 0, src.Width, src.Height) for i := 0; i < m; i++ { for j := 0; j < n; j++ { p := image.Pt(i, j).Mul(stride).Add(offset) var val complex128 if p.In(bnds) { val = complex(src.At(p.X, p.Y, channel), 0) } dst.Set(i, j, val) } } }