You’re an expert programmer with a expert understanding of best coding practices and numerical computing.  this is a class library for neural networks for real world applications, the library must be able to handle small networks like simple classifiers and large networks like LLMs . so you must always consider for best possible answer with best performance, optimizations and least memory footprint,  use Tensor<T>.ParallelizationThreshold static property when preferred or required for best practices. you will produce fully complete and working code. 
When I ask you for code improvements or bug fix, you will only generate new code or code changes, don't re-generate unchanged or old code, also with the changes you provide code copy paste explanation so I can avoid any copy paste errors and to avoid human confusion.
Please note this class library is on multiply file and large code base, so If you want to know about certain implementation to provide complete answer then assume it is already implemented and well optimized, also you can ask for code snippets and I will provide to you my current up-to-date implementation.

Programming language : c#
Application Type: class library
public async Task<Tensor<T>> ElementWiseOperationAsync(Tensor<T> other, Func<T, T, T> operation) { return await Task.Run(() => ElementWiseOperation(other, operation)); } public Tensor<T> ElementWiseOperation(Tensor<T> other, Func<T, T, T> operation) { EnsureNotDisposed(); other.EnsureNotDisposed(); var broadcastInfo = GetOrAddBroadcastCache(shape, other.shape, other.strides); int[] resultShape = broadcastInfo.ResultShape; int resultSize = resultShape.Aggregate(1, (a, b) => a * b); Tensor<T> result = new Tensor<T>(resultShape); var dataResult = result.data; var stridesA = broadcastInfo.BroadcastStridesA; var stridesB = broadcastInfo.BroadcastStridesB; bool isContiguousA = IsContiguous(stridesA, shape); bool isContiguousB = IsContiguous(stridesB, other.shape); bool isContiguousResult = result.IsContiguous(); bool shapesAreEqual = shape.SequenceEqual(other.shape); bool stridesAreEqual = strides.SequenceEqual(other.strides); bool operationIsSupported = operation.Method == ((Func<T, T, T>)((x, y) => x + y)).Method || operation.Method == ((Func<T, T, T>)((x, y) => x - y)).Method || operation.Method == ((Func<T, T, T>)((x, y) => x * y)).Method || operation.Method == ((Func<T, T, T>)((x, y) => x / y)).Method; bool canUseSIMD = ( (typeof(T) == typeof(float) || typeof(T) == typeof(double)) && isContiguousA && isContiguousB && isContiguousResult && shapesAreEqual && stridesAreEqual && operationIsSupported ); if (canUseSIMD) { int vectorSize = Vector<T>.Count; int vectorizableLength = resultSize - (resultSize % vectorSize); if (resultSize >= ParallelizationThreshold) { Parallel.For(0, vectorizableLength / vectorSize, index => { int baseIndex = index * vectorSize; int indexA = offset + baseIndex; int indexB = other.offset + baseIndex; int indexResult = result.offset + baseIndex; var vectorA = new Vector<T>(data, indexA); var vectorB = new Vector<T>(other.data, indexB); var vectorResult = PerformVectorOperation(vectorA, vectorB, operation); vectorResult.CopyTo(dataResult, indexResult); }); for (int i = vectorizableLength; i < resultSize; i++) { int indexA = offset + i; int indexB = other.offset + i; int indexResult = result.offset + i; dataResult[indexResult] = operation(data[indexA], other.data[indexB]); } } else { int i = 0; for (; i <= vectorizableLength - vectorSize; i += vectorSize) { int indexA = offset + i; int indexB = other.offset + i; int indexResult = result.offset + i; var vectorA = new Vector<T>(data, indexA); var vectorB = new Vector<T>(other.data, indexB); var vectorResult = PerformVectorOperation(vectorA, vectorB, operation); vectorResult.CopyTo(dataResult, indexResult); } for (; i < resultSize; i++) { int indexA = offset + i; int indexB = other.offset + i; int indexResult = result.offset + i; dataResult[indexResult] = operation(data[indexA], other.data[indexB]); } } } else { if (resultSize >= ParallelizationThreshold) { Parallel.For(0, resultSize, i => { int[] multiIndex = GetIndicesFromRawIndex(i, resultShape); int indexA = GetFlatIndex(multiIndex, stridesA, offset); int indexB = GetFlatIndex(multiIndex, stridesB, other.offset); int indexResult = GetFlatIndex(multiIndex, result.strides, result.offset); dataResult[indexResult] = operation(data[indexA], other.data[indexB]); }); } else { for (int i = 0; i < resultSize; i++) { int[] multiIndex = GetIndicesFromRawIndex(i, resultShape); int indexA = GetFlatIndex(multiIndex, stridesA, offset); int indexB = GetFlatIndex(multiIndex, stridesB, other.offset); int indexResult = GetFlatIndex(multiIndex, result.strides, result.offset); dataResult[indexResult] = operation(data[indexA], other.data[indexB]); } } } return result; } private Vector<T> PerformVectorOperation(Vector<T> vectorA, Vector<T> vectorB, Func<T, T, T> operation) { if (operation.Method == ((Func<T, T, T>)((x, y) => x + y)).Method) { return vectorA + vectorB; } else if (operation.Method == ((Func<T, T, T>)((x, y) => x - y)).Method) { return vectorA - vectorB; } else if (operation.Method == ((Func<T, T, T>)((x, y) => x * y)).Method) { return vectorA * vectorB; } else if (operation.Method == ((Func<T, T, T>)((x, y) => x / y)).Method) { return vectorA / vectorB; } else { T[] resultArray = new T[Vector<T>.Count]; for (int i = 0; i < Vector<T>.Count; i++) { resultArray[i] = operation(vectorA[i], vectorB[i]); } return new Vector<T>(resultArray); } } public async Task<Tensor<T>> ScalarOperationAsync(Func<T, T> operation) { return await Task.Run(() => ScalarOperation(operation)); } public Tensor<T> ScalarOperation(Func<T, T> operation) { EnsureNotDisposed(); T[] resultData = new T[totalSize]; var offsetResult = 0; bool isContiguous = IsContiguous(); bool canUseSIMD = (typeof(T) == typeof(float) || typeof(T) == typeof(double)) && isContiguous && operation.Method == ((Func<T, T>)(x => -x)).Method; if (canUseSIMD) { int vectorSize = Vector<T>.Count; int vectorizableLength = totalSize - (totalSize % vectorSize); if (totalSize >= ParallelizationThreshold) { Parallel.For(0, vectorizableLength / vectorSize, index => { int baseIndex = index * vectorSize; int indexData = offset + baseIndex; int indexResult = offsetResult + baseIndex; var vectorData = new Vector<T>(data, indexData); var vectorResult = PerformVectorOperation(vectorData, operation); vectorResult.CopyTo(resultData, indexResult); }); for (int i = vectorizableLength; i < totalSize; i++) { int indexData = offset + i; resultData[offsetResult + i] = operation(data[indexData]); } } else { int i = 0; for (; i <= vectorizableLength - vectorSize; i += vectorSize) { int indexData = offset + i; int indexResult = offsetResult + i; var vectorData = new Vector<T>(data, indexData); var vectorResult = PerformVectorOperation(vectorData, operation); vectorResult.CopyTo(resultData, indexResult); } for (; i < totalSize; i++) { int indexData = offset + i; resultData[offsetResult + i] = operation(data[indexData]); } } } else { if (totalSize >= ParallelizationThreshold) { Parallel.For(0, totalSize, i => { int[] multiIndex = GetIndicesFromRawIndex(i, shape); int indexData = GetFlatIndex(multiIndex, strides, offset); resultData[offsetResult + i] = operation(data[indexData]); }); } else { for (int i = 0; i < totalSize; i++) { int[] multiIndex = GetIndicesFromRawIndex(i, shape); int indexData = GetFlatIndex(multiIndex, strides, offset); resultData[offsetResult + i] = operation(data[indexData]); } } } return new Tensor<T>(resultData, (int[])shape.Clone(), (int[])strides.Clone(), totalSize, isRowMajor, disposed: false, offset: offsetResult); } private Vector<T> PerformVectorOperation(Vector<T> vectorData, Func<T, T> operation) { if (operation.Method == ((Func<T, T>)(x => -x)).Method) { return -vectorData; } else { T[] resultArray = new T[Vector<T>.Count]; for (int i = 0; i < Vector<T>.Count; i++) { resultArray[i] = operation(vectorData[i]); } return new Vector<T>(resultArray); } } public static Tensor<T> operator /(T scalar, Tensor<T> a) { return a.Reciprocal().MultiplyScalar(scalar); } public void ElementWiseInPlaceOperation(Tensor<T> other, Func<T, T, T> operation) { EnsureNotDisposed(); other.EnsureNotDisposed(); var broadcastInfo = GetOrAddBroadcastCache(this.shape, other.shape, other.strides); int[] resultShape = broadcastInfo.ResultShape.ToArray(); if (!this.shape.SequenceEqual(resultShape)) throw new InvalidOperationException("Result shape after broadcasting must match the shape of the tensor being modified."); var stridesA = broadcastInfo.BroadcastStridesA.ToArray(); var stridesB = broadcastInfo.BroadcastStridesB.ToArray(); int resultSize = resultShape.Aggregate(1, (a, b) => a * b); var dataA = data; var dataB = other.data; var offsetA = offset; var offsetB = other.offset; if (resultSize >= ParallelizationThreshold) { Parallel.For(0, resultSize, i => { int indexA = offsetA; int indexB = offsetB; int idx = i; for (int dim = resultShape.Length - 1; dim >= 0; dim--) { int currentIndex = idx % resultShape[dim]; idx /= resultShape[dim]; indexA += stridesA[dim] * currentIndex; indexB += stridesB[dim] * currentIndex; } dataA[indexA] = operation(dataA[indexA], dataB[indexB]); }); } else { for (int i = 0; i < resultSize; i++) { int indexA = offsetA; int indexB = offsetB; int idx = i; for (int dim = resultShape.Length - 1; dim >= 0; dim--) { int currentIndex = idx % resultShape[dim]; idx /= resultShape[dim]; indexA += stridesA[dim] * currentIndex; indexB += stridesB[dim] * currentIndex; } dataA[indexA] = operation(dataA[indexA], dataB[indexB]); } } } public void ScalarInPlaceOperation(Func<T, T> operation) { EnsureNotDisposed(); bool isContiguous = IsContiguous(); if ((typeof(T) == typeof(float) || typeof(T) == typeof(double)) && isContiguous && operation.Method == ((Func<T, T>)(x => -x)).Method) { int vectorSize = Vector<T>.Count; int vectorizableLength = totalSize - (totalSize % vectorSize); if (totalSize >= ParallelizationThreshold) { Parallel.For(0, vectorizableLength / vectorSize, index => { int baseIndex = index * vectorSize; int indexData = offset + baseIndex; var vectorData = new Vector<T>(data, indexData); var vectorResult = PerformVectorOperation(vectorData, operation); vectorResult.CopyTo(data, indexData); }); for (int i = vectorizableLength; i < totalSize; i++) { int indexData = offset + i; data[indexData] = operation(data[indexData]); } } else { int i = 0; for (; i <= vectorizableLength - vectorSize; i += vectorSize) { int indexData = offset + i; var vectorData = new Vector<T>(data, indexData); var vectorResult = PerformVectorOperation(vectorData, operation); vectorResult.CopyTo(data, indexData); } for (; i < totalSize; i++) { int indexData = offset + i; data[indexData] = operation(data[indexData]); } } } else { if (totalSize >= ParallelizationThreshold) { Parallel.For(0, totalSize, i => { data[offset + i] = operation(data[offset + i]); }); } else { for (int i = 0; i < totalSize; i++) { data[offset + i] = operation(data[offset + i]); } } } } public void SubtractScalarInPlace(T scalar) { ScalarInPlaceOperation(x => x - scalar); } public void DivideScalarInPlace(T scalar) { ScalarInPlaceOperation(x => x / scalar); } private void PerformBatchMatMul(int batchIndex, int m, int n, int p, int[] resultBatchShape, Tensor<T> result, Tensor<T> a, Tensor<T> b) { var batchIndices = GetIndicesFromRawIndex(batchIndex, resultBatchShape); int aBatchOffset = a.GetBatchOffset(batchIndices, a.strides); int bBatchOffset = b.GetBatchOffset(batchIndices, b.strides); int resultBatchOffset = result.GetBatchOffset(batchIndices, result.strides); for (int i = 0; i < m; i++) { for (int j = 0; j < p; j++) { T sum = T.Zero; for (int k = 0; k < n; k++) { int aIndex = aBatchOffset + i * a.strides[a.Rank - 2] + k * a.strides[a.Rank - 1]; int bIndex = bBatchOffset + k * b.strides[b.Rank - 2] + j * b.strides[b.Rank - 1]; sum += a.data[aIndex] * b.data[bIndex]; } int resultIndex = resultBatchOffset + i * result.strides[result.Rank - 2] + j * result.strides[result.Rank - 1]; result.data[resultIndex] = sum; } } } public Tensor<T> MatMulBatchOffset(Tensor<T> other) { EnsureNotDisposed(); other.EnsureNotDisposed(); if (this.Rank < 2 || other.Rank < 2) throw new InvalidOperationException("MatMul requires tensors with at least 2 dimensions."); int[] batchShapeA = this.shape.Take(this.Rank - 2).ToArray(); int[] batchShapeB = other.shape.Take(other.Rank - 2).ToArray(); int[] resultBatchShape = BroadcastShapes(batchShapeA, batchShapeB); int aLastDim = this.shape[this.Rank - 1]; int bSecondLastDim = other.shape[other.Rank - 2]; if (aLastDim != bSecondLastDim) throw new InvalidOperationException($"Inner dimensions do not match: {aLastDim} != {bSecondLastDim}"); int m = this.shape[this.Rank - 2]; int n = other.shape[other.Rank - 1]; int[] resultShape = resultBatchShape.Concat(new int[] { m, n }).ToArray(); Tensor<T> result = new Tensor<T>(resultShape); int batchSize = resultBatchShape.Aggregate(1, (x, y) => x * y); for (int batchIndex = 0; batchIndex < batchSize; batchIndex++) { var batchIndices = UnflattenIndex(batchIndex, resultBatchShape); int batchOffsetA = ComputeBatchOffset(batchIndices, batchShapeA, this.strides); int batchOffsetB = ComputeBatchOffset(batchIndices, batchShapeB, other.strides); int batchOffsetResult = ComputeBatchOffset(batchIndices, resultBatchShape, result.strides); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { T sum = T.Zero; for (int l = 0; l < aLastDim; l++) { int aIndex = this.offset + batchOffsetA + i * this.strides[this.Rank - 2] + l * this.strides[this.Rank - 1]; int bIndex = other.offset + batchOffsetB + l * other.strides[other.Rank - 2] + j * other.strides[other.Rank - 1]; sum += this.data[aIndex] * other.data[bIndex]; } int resultIndex = result.offset + batchOffsetResult + i * result.strides[result.Rank - 2] + j * result.strides[result.Rank - 1]; result.data[resultIndex] = sum; } } } return result; } private int ComputeBatchOffset(int[] batchIndices, int[] batchShape, int[] strides) { int offset = 0; int rankDiff = strides.Length - batchShape.Length; for (int i = 0; i < batchShape.Length; i++) { int index = (batchShape[i] == 1) ? 0 : batchIndices[i]; offset += index * strides[i + rankDiff]; } return offset; } private int GetBatchOffset(int[] batchIndices, int[] strides) { int offset = 0; for (int i = 0; i < batchIndices.Length; i++) { offset += batchIndices[i] * strides[i]; } return offset; } public Tensor<T> MatMulStrassen(Tensor<T> other) { EnsureNotDisposed(); other.EnsureNotDisposed(); if (Rank != 2 || other.Rank != 2) throw new InvalidOperationException("MatMulStrassen requires both tensors to be 2D."); int m = shape[0]; int n = shape[1]; int p = other.shape[1]; if (n != other.shape[0]) throw new InvalidOperationException("Inner dimensions must match for MatMulStrassen."); int maxSize = Math.Max(Math.Max(m, n), p); int newSize = NextPowerOfTwo(maxSize); Tensor<T> A = PadMatrix(this, newSize, newSize); Tensor<T> B = PadMatrix(other, newSize, newSize); Tensor<T> C = A.StrassenMultiply(B); Tensor<T> result = C.Slice((Start:0, End:m, Step: null), (Start: 0, End:p, Step: null)); return result; } private int NextPowerOfTwo(int n) { int p = 1; while (p < n) p <<= 1; return p; } private Tensor<T> PadMatrix(Tensor<T> matrix, int rows, int cols) { var padded = new Tensor<T>(rows, cols); int originalRows = matrix.shape[0]; int originalCols = matrix.shape[1]; for (int i = 0; i < originalRows; i++) { Array.Copy( sourceArray: matrix.data, sourceIndex: matrix.offset + i * matrix.strides[0], destinationArray: padded.data, destinationIndex: padded.offset + i * padded.strides[0], length: originalCols ); } return padded; } private Tensor<T> StrassenMultiply(Tensor<T> other) { int n = shape[0]; Tensor<T> C = new Tensor<T>(n, n); if (n <= 64) { return this.MatMul(other); } int k = n / 2; Tensor<T> A11 = Slice((Start: 0, End: k, Step: null), (Start: 0, End: k, Step: null)); Tensor<T> A12 = Slice((Start: 0, End: k, Step: null), (Start: k, End: n, Step: null)); Tensor<T> A21 = Slice((Start: k, End: n, Step: null), (Start: 0, End: k, Step: null)); Tensor<T> A22 = Slice((Start: k, End: n, Step: null), (Start: k, End: n, Step: null)); Tensor<T> B11 = other.Slice((Start: 0, End: k, Step: null), (Start: 0, End: k, Step: null)); Tensor<T> B12 = other.Slice((Start: 0, End: k, Step: null), (Start: k, End: n, Step: null)); Tensor<T> B21 = other.Slice((Start: k, End: n, Step: null), (Start: 0, End: k, Step: null)); Tensor<T> B22 = other.Slice((Start: k, End: n, Step: null), (Start: k, End: n, Step: null)); Tensor<T> M1 = null, M2 = null, M3 = null, M4 = null, M5 = null, M6 = null, M7 = null; Parallel.Invoke( () => { M1 = (A11.Add(A22)).StrassenMultiply(B11.Add(B22)); }, () => { M2 = (A21.Add(A22)).StrassenMultiply(B11); }, () => { M3 = A11.StrassenMultiply(B12.Subtract(B22)); }, () => { M4 = A22.StrassenMultiply(B21.Subtract(B11)); }, () => { M5 = (A11.Add(A12)).StrassenMultiply(B22); }, () => { M6 = (A21.Subtract(A11)).StrassenMultiply(B11.Add(B12)); }, () => { M7 = (A12.Subtract(A22)).StrassenMultiply(B21.Add(B22)); } ); Tensor<T> C11 = M1.Add(M4).Subtract(M5).Add(M7); Tensor<T> C12 = M3.Add(M5); Tensor<T> C21 = M2.Add(M4); Tensor<T> C22 = M1.Subtract(M2).Add(M3).Add(M6); C.SetSubMatrix(0, 0, C11); C.SetSubMatrix(0, k, C12); C.SetSubMatrix(k, 0, C21); C.SetSubMatrix(k, k, C22); return C; } private void SetSubMatrix(int rowOffset, int colOffset, Tensor<T> subMatrix) { int subRows = subMatrix.shape[0]; int subCols = subMatrix.shape[1]; for (int i = 0; i < subRows; i++) { Array.Copy( sourceArray: subMatrix.data, sourceIndex: subMatrix.offset + i * subMatrix.strides[0], destinationArray: data, destinationIndex: offset + (rowOffset + i) * strides[0] + colOffset * strides[1], length: subCols ); } } public (Tensor<T> Q, Tensor<T> R) QRDecomposition() { EnsureNotDisposed(); if (Rank != 2) throw new InvalidOperationException("QR Decomposition requires a 2D tensor."); int m = shape[0]; int n = shape[1]; var Q = new Tensor<T>(m, n); var R = new Tensor<T>(n, n); var AColumns = new Tensor<T>[n]; for (int k = 0; k < n; k++) { AColumns[k] = GetColumn(k); } var QColumns = new Tensor<T>[n]; for (int k = 0; k < n; k++) { var v = AColumns[k].Copy(); for (int j = 0; j < k; j++) { R[j, k] = QColumns[j].DotProduct(AColumns[k]); v.SubtractInPlace(QColumns[j].MultiplyScalar(R[j, k])); } R[k, k] = v.Norm(); QColumns[k] = v.DivideScalar(R[k, k]); Q.SetColumn(k, QColumns[k]); } return (Q, R); } private Tensor<T> GetColumn(int columnIndex) { var column = new Tensor<T>(shape[0]); for (int i = 0; i < shape[0]; i++) { column[i] = this[i, columnIndex]; } return column; } private void SetColumn(int columnIndex, Tensor<T> column) { for (int i = 0; i < shape[0]; i++) { this[i, columnIndex] = column[i]; } } private T DotProduct(Tensor<T> other) { EnsureNotDisposed(); if (totalSize != other.totalSize) throw new InvalidOperationException("Vectors must be the same size for dot product."); T sum = T.Zero; for (int i = 0; i < totalSize; i++) { sum += data[offset + i] * other.data[other.offset + i]; } return sum; } private T Norm() { EnsureNotDisposed(); T sum = T.Zero; for (int i = 0; i < totalSize; i++) { sum += data[offset + i] * data[offset + i]; } return T.Sqrt(sum); } public async Task<Tensor<T>> ConvolveAsync(Tensor<T> kernel, PaddingType padding = PaddingType.Valid) { return await Task.Run(() => Convolve(kernel, padding)); } public Tensor<T> Convolve(Tensor<T> kernel, PaddingType padding = PaddingType.Valid) { EnsureNotDisposed(); kernel.EnsureNotDisposed(); if (Rank != 2 || kernel.Rank != 2) throw new InvalidOperationException("Convolution requires both tensors to be 2D."); int padHeight = 0, padWidth = 0; int outputHeight, outputWidth; if (padding == PaddingType.Same) { padHeight = (kernel.shape[0] - 1) / 2; padWidth = (kernel.shape[1] - 1) / 2; outputHeight = shape[0]; outputWidth = shape[1]; } else { outputHeight = shape[0] - kernel.shape[0] + 1; outputWidth = shape[1] - kernel.shape[1] + 1; } var result = new Tensor<T>(outputHeight, outputWidth); for (int i = 0; i < outputHeight; i++) { for (int j = 0; j < outputWidth; j++) { T sum = T.Zero; for (int ki = 0; ki < kernel.shape[0]; ki++) { for (int kj = 0; kj < kernel.shape[1]; kj++) { int xi = i + ki - padHeight; int yj = j + kj - padWidth; if (xi >= 0 && xi < shape[0] && yj >= 0 && yj < shape[1]) { sum += this[xi, yj] * kernel[ki, kj]; } } } result[i, j] = sum; } } return result; } public Tensor<T> ElementWiseUnaryWithAlpha(T alpha, Func<T, T, T> operation) { EnsureNotDisposed(); T[] resultData = new T[totalSize]; var offsetResult = 0; if (totalSize >= ParallelizationThreshold) { Parallel.For(0, totalSize, i => { int indexData = offset + i; resultData[offsetResult + i] = operation(data[indexData], alpha); }); } else { for (int i = 0; i < totalSize; i++) { int indexData = offset + i; resultData[offsetResult + i] = operation(data[indexData], alpha); } } return new Tensor<T>(resultData, (int[])shape.Clone(), (int[])strides.Clone(), totalSize, isRowMajor, false, offsetResult); } public Tensor<T> ElementWiseBinaryWithAlpha(Tensor<T> other, T alpha, Func<T, T, T, T> operation) { EnsureNotDisposed(); other.EnsureNotDisposed(); var broadcastInfo = GetOrAddBroadcastCache(shape, other.shape, other.strides); int[] resultShape = broadcastInfo.ResultShape; int resultSize = resultShape.Aggregate(1, (a, b) => a * b); Tensor<T> result = new Tensor<T>(resultShape); var stridesA = broadcastInfo.BroadcastStridesA; var stridesB = broadcastInfo.BroadcastStridesB; var dataResult = result.data; if (resultSize >= ParallelizationThreshold) { Parallel.For(0, resultSize, i => { int[] multiIndex = GetIndicesFromRawIndex(i, resultShape); int indexA = GetFlatIndex(multiIndex, stridesA, offset); int indexB = GetFlatIndex(multiIndex, stridesB, other.offset); int indexResult = GetFlatIndex(multiIndex, result.strides, result.offset); dataResult[indexResult] = operation(data[indexA], other.data[indexB], alpha); }); } else { for (int i = 0; i < resultSize; i++) { int[] multiIndex = GetIndicesFromRawIndex(i, resultShape); int indexA = GetFlatIndex(multiIndex, stridesA, offset); int indexB = GetFlatIndex(multiIndex, stridesB, other.offset); int indexResult = GetFlatIndex(multiIndex, result.strides, result.offset); dataResult[indexResult] = operation(data[indexA], other.data[indexB], alpha); } } return result; } public Tensor<T> LogSumExp(int axis, bool keepDims = false) { EnsureNotDisposed(); int ndim = shape.Length; if (ndim == 0) throw new InvalidOperationException("Cannot perform LogSumExp on a scalar tensor."); if (axis < 0) axis += ndim; if (axis < 0 || axis >= ndim) throw new ArgumentOutOfRangeException(nameof(axis), $"Axis {axis} is out of range for tensor of rank {ndim}."); Tensor<T> maxTensor = Max(axis, keepDims: true); Tensor<T> shiftedInput = Subtract(maxTensor); Tensor<T> expShifted = shiftedInput.ScalarOperation(x => T.Exp(x)); Tensor<T> sumExp = expShifted.Sum(axis, keepDims: true); Tensor<T> logSumExp = sumExp.ScalarOperation(x => T.Log(x)); return maxTensor.Add(logSumExp); } public Tensor<T> Softmax(int axis) { EnsureNotDisposed(); int ndim = shape.Length; if (ndim == 0) throw new InvalidOperationException("Softmax cannot be applied on a scalar tensor."); if (axis < 0) axis += ndim; if (axis < 0 || axis >= ndim) throw new ArgumentOutOfRangeException(nameof(axis), $"Axis {axis} is out of range for tensor of rank {ndim}."); Tensor<T> maxTensor = Max(axis, keepDims: true); Tensor<T> shiftedInput = Subtract(maxTensor); Tensor<T> expShifted = shiftedInput.ScalarOperation(x => T.Exp(x)); Tensor<T> sumExp = expShifted.Sum(axis, keepDims: true); Tensor<T> softmaxResult = expShifted.Divide(sumExp); return softmaxResult; }

write mstest for these methods