44 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
55"""
66mutable struct LimitedMemoryMatrix{T, V<: AbstractMatrix{T} } <: AbstractMatrix{T}
7- value :: V
7+ data :: V
88 memory:: Int
99 hsize:: Int
1010
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)
1414 end
1515end
1616
1717function 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 ))
2121end
2222function 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 )
2626end
2727
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)
3131Base. isempty (A:: LimitedMemoryMatrix ) = size (A, 1 ) == 0 || size (A, 2 ) == 0
3232
3333Base. @propagate_inbounds function Base. setindex! (A:: LimitedMemoryMatrix , v, i:: Integer , j:: Integer )
34+ @boundscheck checkbounds (A, i, j)
3435 lowest_stored_index = size (A, 2 ) - A. memory + 1
3536 if j < lowest_stored_index || j > size (A, 2 )
3637 throw (
@@ -40,12 +41,13 @@ Base.@propagate_inbounds function Base.setindex!(A::LimitedMemoryMatrix, v, i::I
4041 )
4142 else
4243 jj = j - lowest_stored_index + 1
43- A. value [i, jj] = v
44+ A. data [i, jj] = v
4445 end
4546 return v
4647end
4748
4849Base. @propagate_inbounds function Base. getindex (A:: LimitedMemoryMatrix , i:: Integer , j:: Integer )
50+ @boundscheck checkbounds (A, i, j)
4951 lowest_stored_index = size (A, 2 ) - A. memory + 1
5052 if j < lowest_stored_index || j > size (A, 2 )
5153 throw (
@@ -54,19 +56,19 @@ Base.@propagate_inbounds function Base.getindex(A::LimitedMemoryMatrix, i::Integ
5456 )
5557 )
5658 else
57- @inbounds v = A. value [i, j - lowest_stored_index + 1 ]
59+ @inbounds v = A. data [i, j - lowest_stored_index + 1 ]
5860 end
5961 return v
6062end
6163
6264function Base. show (io:: IO , :: MIME"text/plain" , A:: LimitedMemoryMatrix ) where {T}
6365 print (io, Base. dims2string (size (A)), " " )
64- Base. showarg (io, A. value , true )
66+ Base. showarg (io, A. data , true )
6567end
6668
6769function Base. show (io:: IO , A:: LimitedMemoryMatrix ) where {T}
6870 print (io, Base. dims2string (size (A)), " " )
69- Base. showarg (io, A. value , true )
71+ Base. showarg (io, A. data , true )
7072end
7173
7274"""
@@ -78,22 +80,152 @@ size of `A`
7880function hcat! (A:: LimitedMemoryMatrix , B:: AbstractVector )
7981 @assert size (B, 1 ) == size (A, 1 )
8082 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
8385 return A
8486end
8587
88+
8689"""
87- LimitedMemoryBandedMatrix
90+ LimitedMemoryUpperTriangularMatrix
8891
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.
9294"""
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
9597 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
99231end
0 commit comments