4
4
A matrix which keeps only the last `memory` columns. Access outside these columns throws an error. Thus, the underlying storage is a matrix of size `(N, memory)` where `N` is the size of the first dimension
5
5
"""
6
6
mutable struct LimitedMemoryMatrix{T, V<: AbstractMatrix{T} } <: AbstractMatrix{T}
7
- value :: V
7
+ data :: V
8
8
memory:: Int
9
9
hsize:: Int
10
10
11
- function LimitedMemoryMatrix {T, V} (value :: V , memory, hsize) where {T, V<: AbstractMatrix{T} }
12
- @assert Base. require_one_based_indexing (value )
13
- return new {T, V} (value , memory, hsize)
11
+ function LimitedMemoryMatrix {T, V} (data :: V , memory, hsize) where {T, V<: AbstractMatrix{T} }
12
+ @assert Base. require_one_based_indexing (data )
13
+ return new {T, V} (data , memory, hsize)
14
14
end
15
15
end
16
16
17
17
function LimitedMemoryMatrix (mat:: AbstractMatrix{T} , memory) where T
18
- value = similar (mat, size (mat, 1 ), memory)
19
- value [:, end - size (mat, 2 )+ 1 : end ] .= mat
20
- return LimitedMemoryMatrix {T, typeof(value )} (value , memory, size (mat, 2 ))
18
+ data = similar (mat, size (mat, 1 ), memory)
19
+ data [:, end - size (mat, 2 )+ 1 : end ] .= mat
20
+ return LimitedMemoryMatrix {T, typeof(data )} (data , memory, size (mat, 2 ))
21
21
end
22
22
function LimitedMemoryMatrix (vec:: AbstractVector{T} , memory) where T
23
- value = similar (vec, size (vec, 1 ), memory)
24
- value [:, end ] .= vec
25
- return LimitedMemoryMatrix {T, typeof(value )} (value , memory, 1 )
23
+ data = similar (vec, size (vec, 1 ), memory)
24
+ data [:, end ] .= vec
25
+ return LimitedMemoryMatrix {T, typeof(data )} (data , memory, 1 )
26
26
end
27
27
28
- Base. size (A:: LimitedMemoryMatrix ) = (size (A. value , 1 ), A. hsize)
29
- Base. similar (A:: LimitedMemoryMatrix ) = LimitedMemoryMatrix (similar (A. value ), A. memory, A. hsize)
30
- Base. similar (A:: LimitedMemoryMatrix , :: Type{T} ) where T = LimitedMemoryMatrix (similar (A. value , T), A. memory, A. hsize)
28
+ Base. size (A:: LimitedMemoryMatrix ) = (size (A. data , 1 ), A. hsize)
29
+ Base. similar (A:: LimitedMemoryMatrix ) = LimitedMemoryMatrix (similar (A. data ), A. memory, A. hsize)
30
+ Base. similar (A:: LimitedMemoryMatrix , :: Type{T} ) where T = LimitedMemoryMatrix (similar (A. data , T), A. memory, A. hsize)
31
31
Base. isempty (A:: LimitedMemoryMatrix ) = size (A, 1 ) == 0 || size (A, 2 ) == 0
32
32
33
33
Base. @propagate_inbounds function Base. setindex! (A:: LimitedMemoryMatrix , v, i:: Integer , j:: Integer )
34
+ @boundscheck checkbounds (A, i, j)
34
35
lowest_stored_index = size (A, 2 ) - A. memory + 1
35
36
if j < lowest_stored_index || j > size (A, 2 )
36
37
throw (
@@ -40,12 +41,13 @@ Base.@propagate_inbounds function Base.setindex!(A::LimitedMemoryMatrix, v, i::I
40
41
)
41
42
else
42
43
jj = j - lowest_stored_index + 1
43
- A. value [i, jj] = v
44
+ A. data [i, jj] = v
44
45
end
45
46
return v
46
47
end
47
48
48
49
Base. @propagate_inbounds function Base. getindex (A:: LimitedMemoryMatrix , i:: Integer , j:: Integer )
50
+ @boundscheck checkbounds (A, i, j)
49
51
lowest_stored_index = size (A, 2 ) - A. memory + 1
50
52
if j < lowest_stored_index || j > size (A, 2 )
51
53
throw (
@@ -54,19 +56,19 @@ Base.@propagate_inbounds function Base.getindex(A::LimitedMemoryMatrix, i::Integ
54
56
)
55
57
)
56
58
else
57
- @inbounds v = A. value [i, j - lowest_stored_index + 1 ]
59
+ @inbounds v = A. data [i, j - lowest_stored_index + 1 ]
58
60
end
59
61
return v
60
62
end
61
63
62
64
function Base. show (io:: IO , :: MIME"text/plain" , A:: LimitedMemoryMatrix ) where {T}
63
65
print (io, Base. dims2string (size (A)), " " )
64
- Base. showarg (io, A. value , true )
66
+ Base. showarg (io, A. data , true )
65
67
end
66
68
67
69
function Base. show (io:: IO , A:: LimitedMemoryMatrix ) where {T}
68
70
print (io, Base. dims2string (size (A)), " " )
69
- Base. showarg (io, A. value , true )
71
+ Base. showarg (io, A. data , true )
70
72
end
71
73
72
74
"""
@@ -78,22 +80,152 @@ size of `A`
78
80
function hcat! (A:: LimitedMemoryMatrix , B:: AbstractVector )
79
81
@assert size (B, 1 ) == size (A, 1 )
80
82
A. hsize += 1
81
- A. value [:, 1 : end - 1 ] .= A. value [:, 2 : end ]
82
- A. value [:, end ] .= B
83
+ A. data [:, 1 : end - 1 ] .= A. data [:, 2 : end ]
84
+ A. data [:, end ] .= B
83
85
return A
84
86
end
85
87
88
+
86
89
"""
87
- LimitedMemoryBandedMatrix
90
+ LimitedMemoryUpperTriangularMatrix
88
91
89
- A matrix which keeps only the last `memory` columns. Access outside these columns throws an
90
- error. Additionally, the matrix is understood to be banded, such that only values
91
- `band_offset` from the diagonal are non-zero, where the band is of width `band_width`. Thus, the underlying storage is a matrix of size `(band_width, memory)`
92
+ A matrix which keeps only the last `memory` columns. `setindex!` outside these columns
93
+ throws an error, otherwise entries are set to 0.
92
94
"""
93
- mutable struct LimitedMemoryBandedMatrix {T, V<: AbstractMatrix{T} } <: AbstractMatrix{T}
94
- value :: V
95
+ mutable struct LimitedMemoryUpperTriangular {T, V<: AbstractMatrix{T} } <: AbstractMatrix{T}
96
+ data :: V
95
97
memory:: Int
96
- size:: Tuple{Int, Int}
97
- band_offset:: Int
98
- band_width:: Int
98
+ hsize:: Int
99
+
100
+ function LimitedMemoryUpperTriangular {T, V} (data:: AbstractMatrix{T} , memory, hsize) where {T, V<: AbstractMatrix{T} }
101
+ @assert Base. require_one_based_indexing (data)
102
+ return new {T, typeof(data)} (data, memory, hsize)
103
+ end
104
+ end
105
+
106
+ Base. size (A:: LimitedMemoryUpperTriangular ) = (A. hsize, A. hsize)
107
+ function LimitedMemoryUpperTriangular (mat:: AbstractMatrix{T} , memory) where T
108
+ data = similar (mat, memory, memory)
109
+ fill! (data, 0 )
110
+ data[:, end - size (mat, 2 )+ 1 : end ] .= mat
111
+ return LimitedMemoryUpperTriangular {T, typeof(data)} (data, memory, size (mat, 2 ))
112
+ end
113
+ function LimitedMemoryUpperTriangular (vec:: AbstractVector{T} , memory) where T
114
+ data = similar (vec, memory, memory)
115
+ fill! (data, 0 )
116
+ data[:, end ] .= vec
117
+ return LimitedMemoryUpperTriangular {T, typeof(data)} (data, memory, 1 )
118
+ end
119
+ function LimitedMemoryUpperTriangular {T, V} (memory) where {T, V<: AbstractMatrix{T} }
120
+ data = V (undef, memory, memory)
121
+ fill! (data, 0 )
122
+ return LimitedMemoryUpperTriangular {T, typeof(data)} (data, memory, 0 )
123
+ end
124
+
125
+ Base. @propagate_inbounds function Base. setindex! (A:: LimitedMemoryUpperTriangular , v, i:: Integer , j:: Integer )
126
+ @boundscheck checkbounds (A, i, j)
127
+ lowest_stored_index = size (A, 2 ) - A. memory + 1
128
+ if j < lowest_stored_index || (i > j) || (j- A. memory) >= i
129
+ throw (
130
+ ArgumentError (
131
+ " Cannot set index ($i , $j ) out of memory range, memory kept from $(max (1 , lowest_stored_index)) to $(size (A, 2 )) )"
132
+ )
133
+ )
134
+ else
135
+ jj = j - lowest_stored_index + 1
136
+ ii = i - lowest_stored_index + 1 - (size (A, 2 ) - j)
137
+ A. data[ii, jj] = v
138
+ end
139
+ return v
140
+ end
141
+
142
+ Base. @propagate_inbounds function Base. getindex (A:: LimitedMemoryUpperTriangular , i:: Integer , j:: Integer )
143
+ @boundscheck checkbounds (A, i, j)
144
+ lowest_stored_index_j = size (A, 2 ) - A. memory + 1
145
+ if j < lowest_stored_index_j || (i > j) || (j- A. memory) >= i
146
+ v = zero (eltype (A))
147
+ else
148
+ jj = j - lowest_stored_index_j + 1
149
+ ii = i - lowest_stored_index_j + 1 + (size (A, 2 ) - j)
150
+ @inbounds v = A. data[ii, jj]
151
+ end
152
+ return v
153
+ end
154
+
155
+ """
156
+ LimitedMemoryUpperHessenberg
157
+
158
+ A matrix which keeps only the last `memory` columns. `setindex!` outside these columns
159
+ throws an error, otherwise entries are set to 0.
160
+ """
161
+ mutable struct LimitedMemoryUpperHessenberg{T, V<: AbstractMatrix{T} } <: AbstractMatrix{T}
162
+ data:: V
163
+ memory:: Int
164
+ hsize:: Int
165
+
166
+ function LimitedMemoryUpperHessenberg {T, V} (data:: AbstractMatrix{T} , memory, hsize) where {T, V<: AbstractMatrix{T} }
167
+ @assert Base. require_one_based_indexing (data)
168
+ return new {T, typeof(data)} (data, memory, hsize)
169
+ end
170
+ end
171
+
172
+ Base. size (A:: LimitedMemoryUpperHessenberg ) = (A. hsize+ 1 , A. hsize)
173
+ function LimitedMemoryUpperHessenberg (mat:: AbstractMatrix{T} , memory) where T
174
+ data = similar (mat, memory, memory)
175
+ fill! (data, 0 )
176
+ data[end - memory+ 1 : end , end - size (mat, 2 )+ 1 : end ] .= mat
177
+ return LimitedMemoryUpperHessenberg {T, typeof(data)} (data, memory, size (mat, 2 ))
178
+ end
179
+ function LimitedMemoryUpperHessenberg (vec:: AbstractVector{T} , memory) where T
180
+ data = similar (vec, memory, memory)
181
+ fill! (data, 0 )
182
+ data[:, end ] .= vec[end - memory+ 1 : end ]
183
+ return LimitedMemoryUpperHessenberg {T, typeof(data)} (data, memory, 1 )
184
+ end
185
+ function LimitedMemoryUpperHessenberg {T, V} (memory) where {T, V<: AbstractMatrix{T} }
186
+ data = V (undef, memory, memory)
187
+ fill! (data, 0 )
188
+ return LimitedMemoryUpperHessenberg {T, typeof(data)} (data, memory, 0 )
189
+ end
190
+
191
+ Base. @propagate_inbounds function Base. setindex! (A:: LimitedMemoryUpperHessenberg , v, i:: Integer , j:: Integer )
192
+ @boundscheck checkbounds (A, i, j)
193
+ lowest_stored_index = size (A, 2 ) - A. memory + 1
194
+ if j < lowest_stored_index || (i > j+ 1 ) || (j+ 1 - A. memory) >= i
195
+ throw (
196
+ ArgumentError (
197
+ " Cannot set index ($i , $j ) out of memory range, memory kept from $(max (1 , lowest_stored_index)) to $(size (A, 2 )) )"
198
+ )
199
+ )
200
+ else
201
+ jj = j - lowest_stored_index + 1
202
+ ii = i - lowest_stored_index - (size (A, 2 ) - j)
203
+ A. data[ii, jj] = v
204
+ end
205
+ return v
206
+ end
207
+
208
+ Base. @propagate_inbounds function Base. getindex (A:: LimitedMemoryUpperHessenberg , i:: Integer , j:: Integer )
209
+ @boundscheck checkbounds (A, i, j)
210
+ lowest_stored_index_j = size (A, 2 ) - A. memory + 1
211
+ if j < lowest_stored_index_j || (i > j+ 1 ) || (j+ 1 - A. memory) >= i
212
+ v = zero (eltype (A))
213
+ else
214
+ jj = j - lowest_stored_index_j + 1
215
+ ii = i - lowest_stored_index_j + (size (A, 2 ) - j)
216
+ @inbounds v = A. data[ii, jj]
217
+ end
218
+ return v
219
+ end
220
+
221
+ function _grow_hcat! (A, v)
222
+ if ! isempty (A)
223
+ @assert size (v, 1 ) == size (A, 1 )+ 1
224
+ end
225
+ @assert sum (abs, v[1 : end - A. memory]) < eps (real (eltype (A)))
226
+ mem = min (A. memory, length (v))
227
+ A. hsize += 1
228
+ A. data[:, 1 : end - 1 ] .= A. data[:, 2 : end ]
229
+ A. data[end - mem+ 1 : end , end ] .= v[end - mem+ 1 : end ]
230
+ return A
99
231
end
0 commit comments