using Xunit; using SynorCompute; namespace SynorCompute.Tests; public class TensorTests { [Fact] public void Constructor_WithShapeAndData_CreatesTensor() { var tensor = new Tensor([2, 3], [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]); Assert.Equal([2, 3], tensor.Shape); Assert.Equal(6, tensor.Size); Assert.Equal(2, tensor.Ndim); } [Fact] public void Zeros_CreatesZeroTensor() { var tensor = Tensor.Zeros([3, 4]); Assert.Equal([3, 4], tensor.Shape); Assert.Equal(12, tensor.Size); Assert.All(tensor.Data, v => Assert.Equal(0.0, v)); } [Fact] public void Ones_CreatesOnesTensor() { var tensor = Tensor.Ones([2, 2]); Assert.All(tensor.Data, v => Assert.Equal(1.0, v)); } [Fact] public void Random_CreatesRandomTensor() { var tensor = Tensor.Random([10, 10]); Assert.Equal([10, 10], tensor.Shape); Assert.All(tensor.Data, v => Assert.InRange(v, 0.0, 1.0)); } [Fact] public void Randn_CreatesNormalDistributionTensor() { var tensor = Tensor.Randn([1000]); var mean = tensor.Mean(); var std = tensor.Std(); Assert.InRange(Math.Abs(mean), 0, 0.2); Assert.InRange(std, 0.8, 1.2); } [Fact] public void Eye_CreatesIdentityMatrix() { var tensor = Tensor.Eye(3); Assert.Equal([3, 3], tensor.Shape); Assert.Equal(1.0, tensor[0, 0]); Assert.Equal(1.0, tensor[1, 1]); Assert.Equal(1.0, tensor[2, 2]); Assert.Equal(0.0, tensor[0, 1]); } [Fact] public void Arange_CreatesRangeTensor() { var tensor = Tensor.Arange(0, 5, 1); Assert.Equal([5], tensor.Shape); Assert.Equal(0.0, tensor[0]); Assert.Equal(4.0, tensor[4]); } [Fact] public void Linspace_CreatesLinearlySpacedTensor() { var tensor = Tensor.Linspace(0, 10, 11); Assert.Equal([11], tensor.Shape); Assert.Equal(0.0, tensor[0], 4); Assert.Equal(10.0, tensor[10], 4); Assert.Equal(5.0, tensor[5], 4); } [Fact] public void Reshape_ChangesShape() { var tensor = new Tensor([6], [1, 2, 3, 4, 5, 6]); var reshaped = tensor.Reshape([2, 3]); Assert.Equal([2, 3], reshaped.Shape); Assert.Equal(6, reshaped.Size); } [Fact] public void Reshape_ThrowsOnInvalidShape() { var tensor = Tensor.Zeros([4]); Assert.Throws(() => tensor.Reshape([2, 3])); } [Fact] public void Transpose_Transposes2DTensor() { var tensor = new Tensor([2, 3], [1, 2, 3, 4, 5, 6]); var transposed = tensor.Transpose(); Assert.Equal([3, 2], transposed.Shape); Assert.Equal(1.0, transposed[0, 0]); Assert.Equal(4.0, transposed[0, 1]); } [Fact] public void Sum_CalculatesSum() { var tensor = new Tensor([4], [1, 2, 3, 4]); Assert.Equal(10.0, tensor.Sum()); } [Fact] public void Mean_CalculatesMean() { var tensor = new Tensor([4], [1, 2, 3, 4]); Assert.Equal(2.5, tensor.Mean()); } [Fact] public void Std_CalculatesStandardDeviation() { var tensor = new Tensor([4], [1, 2, 3, 4]); Assert.Equal(1.118, tensor.Std(), 3); } [Fact] public void Min_FindsMinimum() { var tensor = new Tensor([4], [3, 1, 4, 2]); Assert.Equal(1.0, tensor.Min()); } [Fact] public void Max_FindsMaximum() { var tensor = new Tensor([4], [3, 1, 4, 2]); Assert.Equal(4.0, tensor.Max()); } [Fact] public void ReLU_AppliesActivation() { var tensor = new Tensor([5], [-2, -1, 0, 1, 2]); var result = tensor.ReLU(); Assert.Equal([0.0, 0.0, 0.0, 1.0, 2.0], result.Data); } [Fact] public void Sigmoid_AppliesActivation() { var tensor = new Tensor([1], [0]); var result = tensor.Sigmoid(); Assert.Equal(0.5, result[0], 4); } [Fact] public void Softmax_AppliesActivation() { var tensor = new Tensor([3], [1, 2, 3]); var result = tensor.Softmax(); Assert.Equal(1.0, result.Sum(), 4); Assert.True(result[2] > result[1]); Assert.True(result[1] > result[0]); } [Fact] public void Serialization_RoundTrip() { var original = new Tensor([2, 3], [1, 2, 3, 4, 5, 6]); var json = original.ToJson(); var restored = Tensor.FromJson(json); Assert.Equal(original.Shape, restored.Shape); Assert.Equal(original.Data, restored.Data); } }