diff --git a/src/inits/inits_reservoir.jl b/src/inits/inits_reservoir.jl index 90a9715f..a1fbd226 100644 --- a/src/inits/inits_reservoir.jl +++ b/src/inits/inits_reservoir.jl @@ -2533,3 +2533,56 @@ for initializer in ( end end end + + + +function wigner_init( + rng::AbstractRNG, ::Type{T}, dims::Integer...; + radius::Number = T(1.0), diagonal_std::Number, off_diagonal_std::Number, + return_symmetric::Bool = true + ) where {T <: Number} + # 1. Dimension check : Reservoir has to be a square matrix + check_res_size(dims...) + res_size = dims[1] + + # 2. Initialise the zeros matrix with type T + reservoir_matrix = zeros(T, res_size, res_size) + + # 3. Populating the matrix + # Diagonal elements sampled from N(0, diagonal_std^2) + # Off-diagonal elements sampled from N(0, off_diagonal_std^2) + + # Default symmetric case + if return_symmetric + # Efficient upper-triangle fill for symmetric matrices + for i in 1:res_size + for j in i:res_size + if i == j + reservoir_matrix[i, j] = DeviceAgnostic.randn(rng, T) * T(diag_std) + else + reservoir_matrix[i, j] = DeviceAgnostic.randn(rng, T) * T(off_diag_std) + end + end + end + # Mirror the matrix + reservoir_matrix = Symmetric(reservoir_matrix) + + # User sets return_symmetric=false + else + for i in 1:res_size + for j in 1:res_size + if i == j + W[i, j] = DeviceAgnostic.randn(rng, T) * T(diag_std) + else + W[i, j] = DeviceAgnostic.randn(rng, T) * T(off_diag_std) + end + end + end + end + + #3. Scale the spectral radius + reservoir_matrix = scale_radius!(reservoir_matrix, T(radius)) + + + return reservoir_matrix +end \ No newline at end of file diff --git a/test/test_inits.jl b/test/test_inits.jl index 4db5c46c..f8034463 100644 --- a/test/test_inits.jl +++ b/test/test_inits.jl @@ -105,3 +105,23 @@ end @test sort(unique(dl)) == Float32.([-0.1, 0.1]) end end + +@testset "Wigner_matrix_init.jl" begin + #rng = Random.default_rng() + #res_size = 10 + + # Test for symmetric case (default) + symmetric_reservoir = wigner_init(rng, Float32, res_size; radius=1.2, diag_std=1.414, off_diag_std=1.0) + + @test size(symm) == (res_size, res_size) + @test eltype(symmetric_reservoir) == Float32 + @test issymmetric(symmetric_reservoir) + + # Test for asymmetric case + # We explicitly turn off symmetry + asymmetric_reservoir = wigner_init(rng, Float32, res_size; radius=1.2, diag_std=1.414, off_diag_std=1.0, return_symmetric=false) + + @test size(asymmetric_reservoir) == (res_size, res_size) + @test eltype(asymmetric_reservoir) == Float32 + @test !issymmetric(asymmetric_reservoir) +end \ No newline at end of file