public Correlate2d(Tensor <float> x, Tensor <float> y, ConvMode mode = ConvMode.Valid) : base("Correlate2d", x, y, mode.Named("mode")) { if (x.NDim != 2 && y.NDim != 2) { throw new RankException("Expect inputs of dim 2"); } this.mode = mode; _shape = new[] { GetConvolveDim(x.Shape[0], y.Shape[0], mode) }; }
public Correlate(Tensor <float> x, Tensor <float> kernel, ConvMode mode = ConvMode.Valid) : base("Correlate", x, kernel, mode.Named("mode")) { if (x.NDim != 1 && kernel.NDim != 1) { throw new RankException("Expect inputs of dim 1"); } this.mode = mode; _shape = new[] { GetConvolveDim(x.Shape[0], kernel.Shape[0], mode) }; }
/// <summary> /// Allows to create a custom convolution (ie replace the multiplication with any a custom op) /// </summary> /// <remarks> /// The generic case of convolution requiers Jacobian computation. /// As this not implemented in TheaNet, the user as to provide himself the "Jacobian". /// This operator make the following assumptions: /// if: /// z = ConvolveCustom(x, y, f) /// then: /// dx = CorrelateCustom(dz, y, g) /// dy = CorrelateCustom(dz, x, h) /// </remarks> public static Tensor <float> Create( Tensor <float> x, Tensor <float> y, Func <Tensor <float>, Tensor <float>, Tensor <float> > f, Func <Tensor <float>, Tensor <float>, Tensor <float> > g, Func <Tensor <float>, Tensor <float>, Tensor <float> > h, ConvMode mode = ConvMode.Full, string description = null ) => Create(x, y, f, g, h, GetConvolveDim(x.Shape[0], y.Shape[0], mode), description);
public static ConvMode Reverse(ConvMode mode) { switch (mode) { case ConvMode.Full: return(ConvMode.Valid); case ConvMode.Same: return(ConvMode.Same); case ConvMode.Valid: return(ConvMode.Full); default: throw new ArgumentException(); } }
public static Dim GetConvolveDim(Dim xDim, Dim kDim, ConvMode mode) { switch (mode) { case ConvMode.Full: return(xDim + kDim - 1); case ConvMode.Same: return(Op.Max(xDim, kDim)); case ConvMode.Valid: return(Op.Max(xDim, kDim) - Op.Min(xDim, kDim) + 1); default: throw new ArgumentException("Mode not supported", nameof(mode)); } }
public static Tensor <float> Correlate2d(Tensor <float> x, Tensor <float> y, ConvMode mode = ConvMode.Valid) { return(new Correlate(x, y, mode)); }
public static Tensor <float> Convolve2d(Tensor <float> x, Tensor <float> y, ConvMode mode = ConvMode.Full) { return(new Convolve2d(x, y, mode)); }
public static Array <Real> Convolve(this Array <Real> a, Array <Real> kernel, Array <Real> result = null, ConvMode mode = ConvMode.Full) { a.AssertOfDim(1); kernel.AssertOfDim(1); int na = a.Shape[0], nk = kernel.Shape[0]; if (nk > na) { return(kernel.Convolve(a, result: result, mode: mode)); } int nr, nFull = na + nk - 1; if (mode == ConvMode.Full) { nr = nFull; } else if (mode == ConvMode.Same) { nr = na; } else /* if (mode == Mode.Valid) */ nr {
public static Array <Real> Convolve(this Array <Real> a, Array <Real> kernel, Array <Real> result = null, ConvMode mode = ConvMode.Full) { a.AssertOfDim(1); kernel.AssertOfDim(1); int na = a.Shape[0], nk = kernel.Shape[0]; if (nk > na) { return(kernel.Convolve(a, result: result, mode: mode)); } int nr = GetConvolveDim(na, nk, mode); int nFull = GetConvolveDim(na, nk, ConvMode.Full); if (result == null) { result = NN.Zeros <Real>(nr); } else { result.Clear(); } if (mode == ConvMode.Full) { for (int k = 0; k < nk; ++k) { result[(k, k + na)].Acc(a, alpha: kernel.Item[k]);