/// <summary> /// Calculates the difference between adjoining elements along the specified axes. /// </summary> /// <param name="axis">The axis to operate along.</param> /// <param name="source">The NdArray containing the source values.</param> /// <returns>The differences NdArray. It has one element less in dimension <paramref name="axis"/> as the source NdArray.</returns> public static NdArray <T> DiffAxis(int axis, NdArray <T> source) { NdArray <T> .CheckAxis(axis, source); var shiftRanges = new List <IRange>(); var cutRanges = new List <IRange>(); for (var index = 0; index < source.NumDimensions; index++) { if (index == axis) { shiftRanges.Add(RangeFactory.Range(1, SpecialIdx.None)); cutRanges.Add(RangeFactory.Range(SpecialIdx.None, source.Shape[index] - 2)); } else { shiftRanges.Add(RangeFactory.All); cutRanges.Add(RangeFactory.All); } } var shiftArray = source[shiftRanges.ToArray()]; var cutArray = source[cutRanges.ToArray()]; return(shiftArray - cutArray); }
/// <summary /// >Creates a NdArray with the specified diagonal along the given axes. /// </summary> /// <param name="axis1">The first dimension of the diagonal.</param> /// <param name="axis2">The seconds dimension of the diagonal.</param> /// <param name="source">The values for the diagonal.</param> /// <returns>A NdArray having the values <paramref name="a"/> on the diagonal specified by the axes public static NdArray <T> DiagMatAxis(int axis1, int axis2, NdArray <T> source) { if (axis1 == axis2) { var errorMessage = string.Format("axes [axis1={0}, axis2={1}] to use for diagonal must be different", axis1, axis2); throw new ArgumentException(errorMessage, "axis2"); } var ax1 = axis1 < axis2 ? axis1 : axis2; var ax2 = axis1 < axis2 ? axis2 : axis1; NdArray <T> .CheckAxis(ax1, source); if (!(ax2 >= 0 && ax2 <= source.NumDimensions)) { var errorMessage = string.Format("Cannot insert axis at position {0} into array of shape {1}.", ax2, ErrorMessage.ShapeToString(source.Shape)); throw new ArgumentException(errorMessage, "axis2"); } var shape = List.Insert(ax2, source.Shape[ax1], source.Shape); var result = NdArray <T> .Zeros(source.Storage.Device, shape); var diag = DiagAxis(ax1, ax2, result); FillFrom(diag, source); return(result); }
/// <summary> /// Repeats the NdArray along an axis. /// </summary> /// <param name="axis">The axis to repeat along.</param> /// <param name="repeats">The number of repetitions.</param> /// <param name="source">The NdArray to repeat.</param> /// <returns>The repeated NdArray.</returns> public static NdArray <T> Replicate(int axis, int repeats, NdArray <T> source) { NdArray <T> .CheckAxis(axis, source); if (repeats < 0) { throw new ArgumentException("Number of repetitions cannot be negative.", "repeats"); } // 1. insert axis of size one left to repetition axis // 2. broadcast along the new axis to number of repetitions // 3. reshape to result shape var step1 = source.Reshape(List.Insert(axis, 1, source.Shape)); var step2 = NdArray <T> .BraodcastDim(axis, repeats, step1); var step3 = step2.Reshape(List.Set(axis, repeats * source.Shape[axis], source.Shape)); return(step3); }