Adds unit tests covering tensor operations, type enums, client functionality, and serialization for all 12 SDK implementations: - JavaScript (Vitest): tensor, types, client tests - Python (pytest): tensor, types, client tests - Go: standard library tests with httptest - Flutter (flutter_test): tensor, types tests - Java (JUnit 5): tensor, types tests - Rust: embedded module tests - Ruby (minitest): tensor, types tests - C# (xUnit): tensor, types tests Tests cover: - Tensor creation (zeros, ones, random, randn, eye, arange, linspace) - Tensor operations (reshape, transpose, indexing) - Reductions (sum, mean, std, min, max) - Activations (relu, sigmoid, softmax) - Serialization/deserialization - Type enums and configuration - Client request building - Error handling
198 lines
4.6 KiB
C#
198 lines
4.6 KiB
C#
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<ArgumentException>(() => 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);
|
|
}
|
|
}
|