@@ -1409,13 +1409,78 @@ function selfloop_feedback_cycle(rng::AbstractRNG, ::Type{T}, dims::Integer...;
14091409 return return_init_as (Val (return_sparse), reservoir_matrix)
14101410end
14111411
1412+ """
1413+ selfloop_delayline_backward([rng], [T], dims...;
1414+ cycle_weight=0.1, selfloop_weight=0.1,
1415+ return_sparse=false)
1416+
1417+ Creates a reservoir based on a delay line with the addition of self loops and
1418+ backward connections shifted by one [^elsarraj2019].
1419+
1420+ This architecture is referred to as TP3 in the original paper.
1421+
1422+ # Arguments
1423+
1424+ - `rng`: Random number generator. Default is `Utils.default_rng()`
1425+ from WeightInitializers.
1426+ - `T`: Type of the elements in the reservoir matrix. Default is `Float32`.
1427+ - `dims`: Dimensions of the reservoir matrix.
1428+
1429+ # Keyword arguments
1430+
1431+ - `weight`: Weight of the cycle connections in the reservoir matrix.
1432+ Default is 0.1.
1433+ - `selfloop_weight`: Weight of the self loops in the reservoir matrix.
1434+ Default is 0.1.
1435+ - `return_sparse`: flag for returning a `sparse` matrix.
1436+ Default is `false`.
1437+
1438+ # Examples
1439+
1440+ ```jldoctest
1441+ julia> reservoir_matrix = selfloop_delayline_backward(5, 5)
1442+ 5×5 Matrix{Float32}:
1443+ 0.1 0.0 0.1 0.0 0.0
1444+ 0.1 0.1 0.0 0.1 0.0
1445+ 0.0 0.1 0.1 0.0 0.1
1446+ 0.0 0.0 0.1 0.1 0.0
1447+ 0.0 0.0 0.0 0.1 0.1
1448+
1449+ julia> reservoir_matrix = selfloop_delayline_backward(5, 5; weight=0.3)
1450+ 5×5 Matrix{Float32}:
1451+ 0.1 0.0 0.3 0.0 0.0
1452+ 0.3 0.1 0.0 0.3 0.0
1453+ 0.0 0.3 0.1 0.0 0.3
1454+ 0.0 0.0 0.3 0.1 0.0
1455+ 0.0 0.0 0.0 0.3 0.1
1456+ ```
1457+
1458+ [^elsarraj2019]: Elsarraj, Duaa, et al.
1459+ "Demystifying echo state network with deterministic simple topologies."
1460+ International Journal of Computational Science and Engineering 19.3 (2019): 407-417.
1461+ """
1462+ function selfloop_delayline_backward (rng:: AbstractRNG , :: Type{T} , dims:: Integer... ;
1463+ weight= T (0.1f0 ), selfloop_weight= T (0.1f0 ),
1464+ return_sparse:: Bool = false ) where {T <: Number }
1465+ throw_sparse_error (return_sparse)
1466+ reservoir_matrix = DeviceAgnostic. zeros (rng, T, dims... )
1467+ reservoir_matrix += T (selfloop_weight) .* I (dims[1 ])
1468+ for idx in first (axes (reservoir_matrix, 1 )): (last (axes (reservoir_matrix, 1 )) - 1 )
1469+ reservoir_matrix[idx + 1 , idx] = T (weight)
1470+ end
1471+ for idx in (first (axes (reservoir_matrix, 1 ))): (last (axes (reservoir_matrix, 1 )) - 2 )
1472+ reservoir_matrix[idx, idx + 2 ] = T (weight)
1473+ end
1474+ return return_init_as (Val (return_sparse), reservoir_matrix)
1475+ end
1476+
14121477# ## fallbacks
14131478# fallbacks for initializers #eventually to remove once migrated to WeightInitializers.jl
14141479for initializer in (:rand_sparse , :delay_line , :delay_line_backward , :cycle_jumps ,
14151480 :simple_cycle , :pseudo_svd , :chaotic_init ,
14161481 :scaled_rand , :weighted_init , :informed_init , :minimal_init , :chebyshev_mapping ,
14171482 :logistic_mapping , :modified_lm , :low_connectivity , :double_cycle , :self_loop_cycle ,
1418- :selfloop_feedback_cycle )
1483+ :selfloop_feedback_cycle , :selfloop_delayline_backward )
14191484 @eval begin
14201485 function ($ initializer)(dims:: Integer... ; kwargs... )
14211486 return $ initializer (Utils. default_rng (), Float32, dims... ; kwargs... )
0 commit comments