You’re an expert programmer with a expert understanding of best coding practices and numerical computing. You always review the code I give to you before you answer to check if it would need improvements before proceeding with your answer.  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 partial class Tensor<T> : IDisposable, ICloneable, IEquatable<Tensor<T>>, IEnumerable<T> where T : INumber<T>, IExponentialFunctions<T>, ITrigonometricFunctions<T>, ILogarithmicFunctions<T>, IFloatingPointIeee754<T>, IRootFunctions<T> { public T this[params int[] indices] { get { EnsureNotDisposed(); int flatIndex = CalculateFlatIndex(indices); return data[flatIndex]; } set { EnsureNotDisposed(); int flatIndex = CalculateFlatIndex(indices); data[flatIndex] = value; } } public T ScalarValue { get { EnsureNotDisposed(); if (Rank != 0) throw new InvalidOperationException("ScalarValue can only be accessed on a 0-dimensional tensor."); return data[offset]; } set { EnsureNotDisposed(); if (Rank != 0) throw new InvalidOperationException("ScalarValue can only be set on a 0-dimensional tensor."); data[offset] = value; } } public int CalculateFlatIndex(int[] indices) { if (indices == null) throw new ArgumentNullException(nameof(indices)); if (indices.Length != shape.Length) throw new ArgumentException("Number of indices must match number of tensor dimensions.", nameof(indices)); int flatIndex = 0; if (isRowMajor) { for (int i = 0; i < indices.Length; i++) { int index = indices[i]; int dim = shape[i]; if (index < 0 || index >= dim) throw new ArgumentOutOfRangeException(nameof(indices), $"Index {index} out of bounds for dimension {i} of size {dim}."); int stride = strides[i]; if (stride == 0) index = 0; flatIndex += index * stride; } } else { for (int i = indices.Length - 1; i >= 0; i--) { int index = indices[i]; int dim = shape[i]; if (index < 0 || index >= dim) throw new ArgumentOutOfRangeException(nameof(indices), $"Index {index} out of bounds for dimension {i} of size {dim}."); int stride = strides[i]; if (stride == 0) index = 0; flatIndex += index * stride; } } return flatIndex + offset; } public (Tensor<T> MaxValues, Tensor<int> MaxIndices) MaxWithIndices(int axis) { EnsureNotDisposed(); if (axis < 0) axis += shape.Length; if (axis < 0 || axis >= shape.Length) throw new ArgumentOutOfRangeException(nameof(axis)); int[] resultShape = shape.ToArray(); resultShape[axis] = 1; int[] resultStrides = CalculateStrides(resultShape, isRowMajor); int resultTotalSize = resultShape.Aggregate(1, (a, b) => a * b); T[] maxValuesData = new T[resultTotalSize]; int[] maxIndicesData = new int[resultTotalSize]; int[] indices = new int[shape.Length]; Action<int> processElement = (resultIndex) => { int remaining = resultIndex; for (int i = 0; i < resultShape.Length; i++) { int size = shape[i]; indices[i] = remaining % size; remaining /= size; } T maxVal = default!; int maxIdx = 0; bool initialized = false; for (int idx = 0; idx < shape[axis]; idx++) { indices[axis] = idx; int flatIndex = GetFlatIndex(indices, strides, offset); T val = data[flatIndex]; if (!initialized || val.CompareTo(maxVal) > 0) { maxVal = val; maxIdx = idx; initialized = true; } } maxValuesData[resultIndex] = maxVal; maxIndicesData[resultIndex] = maxIdx; }; if (resultTotalSize >= ParallelizationThreshold) { Parallel.For(0, resultTotalSize, processElement); } else { for (int i = 0; i < resultTotalSize; i++) { processElement(i); } } Tensor<T> maxValues = new Tensor<T>(maxValuesData, resultShape, resultStrides); Tensor<int> maxIndices = new Tensor<int>(maxIndicesData, resultShape, resultStrides); return (maxValues, maxIndices); } private int[] UnflattenIndex(int flatIndex, int[] shape) { int[] indices = new int[shape.Length]; int remaining = flatIndex; for (int i = 0; i < shape.Length; i++) { int size = 1; for (int j = i + 1; j < shape.Length; j++) { size *= shape[j]; } indices[i] = remaining / size; remaining = remaining % size; } return indices; } private static int GetFlatIndex(int[] indices, int[] strides, bool isRowMajor) { int flatIndex = 0; if (isRowMajor) { for (int i = 0; i < indices.Length; i++) { flatIndex += indices[i] * strides[i]; } } else { for (int i = indices.Length - 1; i >= 0; i--) { flatIndex += indices[i] * strides[i]; } } return flatIndex; } private int CalculateResultIndex(int[] indices, int axis, int[] newStrides) { int resultIndex = 0; for (int j = 0; j < indices.Length; j++) { if (j == axis) continue; resultIndex += indices[j] * newStrides[j < axis ? j : j - 1]; } return resultIndex; } private static int[] CalculateStrides(int[] shape, bool isRowMajor) { int[] strides = new int[shape.Length]; int stride = 1; if (isRowMajor) { for (int i = shape.Length - 1; i >= 0; i--) { strides[i] = stride; stride *= shape[i]; } } else { for (int i = 0; i < shape.Length; i++) { strides[i] = stride; stride *= shape[i]; } } return strides; } private int[] GetIndicesFromRawIndex(int rawIndex, int[] shape) { int[] indices = new int[shape.Length]; for (int i = shape.Length - 1; i >= 0; i--) { indices[i] = rawIndex % shape[i]; rawIndex /= shape[i]; } return indices; } private int GetFlatIndex(int[] indices, int[] strides, int offset) { int flatIndex = offset; for (int i = 0; i < indices.Length; i++) { flatIndex += indices[i] * strides[i]; } return flatIndex; } }

solve the following errors 
Error (active)	CS0315	The type 'int' cannot be used as type parameter 'T' in the generic type or method 'Tensor<T>'. There is no boxing conversion from 'int' to 'System.Numerics.ITrigonometricFunctions<int>'.	Tensor.Indexer.cs	157	
Error (active)	CS0315	The type 'int' cannot be used as type parameter 'T' in the generic type or method 'Tensor<T>'. There is no boxing conversion from 'int' to 'System.Numerics.IRootFunctions<int>'.	Tensor.Indexer.cs	157	
Error (active)	CS0315	The type 'int' cannot be used as type parameter 'T' in the generic type or method 'Tensor<T>'. There is no boxing conversion from 'int' to 'System.Numerics.ILogarithmicFunctions<int>'.	Tensor.Indexer.cs	157	
Error (active)	CS0315	The type 'int' cannot be used as type parameter 'T' in the generic type or method 'Tensor<T>'. There is no boxing conversion from 'int' to 'System.Numerics.IFloatingPointIeee754<int>'.	Tensor.Indexer.cs	157	
Error (active)	CS0315	The type 'int' cannot be used as type parameter 'T' in the generic type or method 'Tensor<T>'. There is no boxing conversion from 'int' to 'System.Numerics.IExponentialFunctions<int>'.	Tensor.Indexer.cs	157	
then write mstest for MaxWithIndices and make sure to handle edge cases