Skip to content

Commit b1ba131

Browse files
added cycle reservoir with self loops
1 parent 17fbc38 commit b1ba131

File tree

4 files changed

+65
-5
lines changed

4 files changed

+65
-5
lines changed

docs/src/api/inits.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@
2424
chaotic_init
2525
low_connectivity
2626
double_cycle
27+
self_loop_cycle
2728
```

src/ReservoirComputing.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ export StandardRidge
3939
export scaled_rand, weighted_init, informed_init, minimal_init, chebyshev_mapping,
4040
logistic_mapping, modified_lm
4141
export rand_sparse, delay_line, delay_line_backward, cycle_jumps,
42-
simple_cycle, pseudo_svd, chaotic_init, low_connectivity, double_cycle
42+
simple_cycle, pseudo_svd, chaotic_init, low_connectivity, double_cycle,
43+
self_loop_cycle
4344
export RNN, MRNN, GRU, GRUParams, FullyGated, Minimal
4445
export train
4546
export ESN, HybridESN, KnowledgeModel, DeepESN

src/esn/esn_inits.jl

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -886,10 +886,10 @@ function simple_cycle(rng::AbstractRNG, ::Type{T}, dims::Integer...;
886886
reservoir_matrix = DeviceAgnostic.zeros(rng, T, dims...)
887887

888888
for idx in first(axes(reservoir_matrix, 1)):(last(axes(reservoir_matrix, 1)) - 1)
889-
reservoir_matrix[idx + 1, idx] = weight
889+
reservoir_matrix[idx + 1, idx] = T(weight)
890890
end
891891

892-
reservoir_matrix[1, dims[1]] = weight
892+
reservoir_matrix[1, dims[1]] = T(weight)
893893
return return_init_as(Val(return_sparse), reservoir_matrix)
894894
end
895895

@@ -1281,12 +1281,69 @@ function double_cycle(rng::AbstractRNG, ::Type{T}, dims::Integer...;
12811281
return return_init_as(Val(return_sparse), reservoir_matrix)
12821282
end
12831283

1284+
"""
1285+
self_loop_cycle([rng], [T], dims...;
1286+
cycle_weight=0.1, self_loop_weight=0.1,
1287+
return_sparse=false)
1288+
1289+
Creates a simple cycle reservoir with the addition of self loops [^elsarraj2019].
1290+
1291+
# Arguments
1292+
1293+
- `rng`: Random number generator. Default is `Utils.default_rng()`
1294+
from WeightInitializers.
1295+
- `T`: Type of the elements in the reservoir matrix. Default is `Float32`.
1296+
- `dims`: Dimensions of the reservoir matrix.
1297+
1298+
# Keyword arguments
1299+
1300+
- `cycle_weight`: Weight of the upper cycle connections in the reservoir matrix.
1301+
Default is 0.1.
1302+
- `self_loop_weight`: Weight of the self loops in the reservoir matrix.
1303+
Default is 0.1.
1304+
- `return_sparse`: flag for returning a `sparse` matrix.
1305+
Default is `false`.
1306+
1307+
# Examples
1308+
1309+
```jldoctest
1310+
julia> reservoir_matrix = self_loop_cycle(5, 5)
1311+
5×5 Matrix{Float32}:
1312+
0.1 0.0 0.0 0.0 0.1
1313+
0.1 0.1 0.0 0.0 0.0
1314+
0.0 0.1 0.1 0.0 0.0
1315+
0.0 0.0 0.1 0.1 0.0
1316+
0.0 0.0 0.0 0.1 0.1
1317+
1318+
julia> reservoir_matrix = self_loop_cycle(5, 5; weight=0.2, self_loop_weight=0.5)
1319+
5×5 Matrix{Float32}:
1320+
0.5 0.0 0.0 0.0 0.2
1321+
0.2 0.5 0.0 0.0 0.0
1322+
0.0 0.2 0.5 0.0 0.0
1323+
0.0 0.0 0.2 0.5 0.0
1324+
0.0 0.0 0.0 0.2 0.5
1325+
```
1326+
1327+
[^elsarraj2019]: Elsarraj, Duaa, et al.
1328+
"Demystifying echo state network with deterministic simple topologies."
1329+
International Journal of Computational Science and Engineering 19.3 (2019): 407-417.
1330+
"""
1331+
function self_loop_cycle(rng::AbstractRNG, ::Type{T}, dims::Integer...;
1332+
weight=T(0.1f0), self_loop_weight=T(0.1f0),
1333+
return_sparse::Bool=false) where {T <: Number}
1334+
throw_sparse_error(return_sparse)
1335+
reservoir_matrix = simple_cycle(rng, T, dims...;
1336+
weight=weight, return_sparse=false)
1337+
reservoir_matrix += T(self_loop_weight) .* I(dims[1])
1338+
return return_init_as(Val(return_sparse), reservoir_matrix)
1339+
end
1340+
12841341
### fallbacks
12851342
#fallbacks for initializers #eventually to remove once migrated to WeightInitializers.jl
12861343
for initializer in (:rand_sparse, :delay_line, :delay_line_backward, :cycle_jumps,
12871344
:simple_cycle, :pseudo_svd, :chaotic_init,
12881345
:scaled_rand, :weighted_init, :informed_init, :minimal_init, :chebyshev_mapping,
1289-
:logistic_mapping, :modified_lm, :low_connectivity, :double_cycle)
1346+
:logistic_mapping, :modified_lm, :low_connectivity, :double_cycle, :self_loop_cycle)
12901347
@eval begin
12911348
function ($initializer)(dims::Integer...; kwargs...)
12921349
return $initializer(Utils.default_rng(), Float32, dims...; kwargs...)

test/esn/test_inits.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ reservoir_inits = [
2727
pseudo_svd,
2828
chaotic_init,
2929
low_connectivity,
30-
double_cycle
30+
double_cycle,
31+
self_loop_cycle
3132
]
3233
input_inits = [
3334
scaled_rand,

0 commit comments

Comments
 (0)