/// <summary> /// Setup function for shaping the input and output arrays to broadcast compatible shapes. /// If no output array is given, a compatible output array is created /// </summary> /// <typeparam name="Ta">The type of input data to operate on</typeparam> /// <typeparam name="Tb">The type of output data to operate on</typeparam> /// <param name="in1">The left-hand-side input argument</param> /// <param name="in2">The right-hand-side input argument</param> /// <param name="out">The output target</param> /// <returns>A tupple with broadcast compatible shapes for the inputs, and an output array</returns> private static Tuple <NdArray <Ta>, NdArray <Ta>, NdArray <Tb> > SetupApplyHelper <Ta, Tb>(NdArray <Ta> in1, NdArray <Ta> in2, NdArray <Tb> @out) { Tuple <Shape, Shape> broadcastshapes = Shape.ToBroadcastShapes(in1.Shape, in2.Shape); if (@out == null) { //We allocate a new array @out = new NdArray <Tb>(broadcastshapes.Item1.Plain); } else { if (@out.Shape.Dimensions.Length != broadcastshapes.Item1.Dimensions.Length) { throw new Exception("Target array does not have the right number of dimensions"); } for (long i = 0; i < @out.Shape.Dimensions.Length; i++) { if (@out.Shape.Dimensions[i].Length != broadcastshapes.Item1.Dimensions[i].Length) { throw new Exception("Dimension size of target array is incorrect"); } } } var op1 = in1.Reshape(broadcastshapes.Item1); var op2 = in2.Reshape(broadcastshapes.Item2); return(new Tuple <NdArray <Ta>, NdArray <Ta>, NdArray <Tb> >(op1, op2, @out)); }