4
4
5
5
# ## basic definitions (types, aliases, constructors, abstractarray interface, sundry similar)
6
6
7
- # note that Adjoint and Transpose must be able to wrap not only vectors and matrices
7
+ # note that QuasiAdjoint and QuasiTranspose must be able to wrap not only vectors and matrices
8
8
# but also factorizations, rotations, and other linear algebra objects, including
9
9
# user-defined such objects. so do not restrict the wrapped type.
10
- struct Adjoint {T,S} <: AbstractQuasiMatrix{T}
10
+ struct QuasiAdjoint {T,S} <: AbstractQuasiMatrix{T}
11
11
parent:: S
12
- function Adjoint {T,S} (A:: S ) where {T,S}
12
+ function QuasiAdjoint {T,S} (A:: S ) where {T,S}
13
13
checkeltype_adjoint (T, eltype (A))
14
14
new (A)
15
15
end
16
16
end
17
- struct Transpose {T,S} <: AbstractQuasiMatrix{T}
17
+ struct QuasiTranspose {T,S} <: AbstractQuasiMatrix{T}
18
18
parent:: S
19
- function Transpose {T,S} (A:: S ) where {T,S}
19
+ function QuasiTranspose {T,S} (A:: S ) where {T,S}
20
20
checkeltype_transpose (T, eltype (A))
21
21
new (A)
22
22
end
23
23
end
24
24
25
25
# basic outer constructors
26
- Adjoint (A) = Adjoint {Base.promote_op(adjoint,eltype(A)),typeof(A)} (A)
27
- Transpose (A) = Transpose {Base.promote_op(transpose,eltype(A)),typeof(A)} (A)
26
+ QuasiAdjoint (A) = QuasiAdjoint {Base.promote_op(adjoint,eltype(A)),typeof(A)} (A)
27
+ QuasiTranspose (A) = QuasiTranspose {Base.promote_op(transpose,eltype(A)),typeof(A)} (A)
28
28
29
- Base. dataids (A:: Union{Adjoint, Transpose } ) = Base. dataids (A. parent)
30
- Base. unaliascopy (A:: Union{Adjoint,Transpose } ) = typeof (A)(Base. unaliascopy (A. parent))
29
+ Base. dataids (A:: Union{QuasiAdjoint, QuasiTranspose } ) = Base. dataids (A. parent)
30
+ Base. unaliascopy (A:: Union{QuasiAdjoint,QuasiTranspose } ) = typeof (A)(Base. unaliascopy (A. parent))
31
31
32
32
# wrapping lowercase quasi-constructors
33
33
"""
@@ -47,18 +47,18 @@ julia> A = [3+2im 9+2im; 8+7im 4+6im]
47
47
8+7im 4+6im
48
48
49
49
julia> adjoint(A)
50
- 2×2 Adjoint {Complex{Int64},Array{Complex{Int64},2}}:
50
+ 2×2 QuasiAdjoint {Complex{Int64},Array{Complex{Int64},2}}:
51
51
3-2im 8-7im
52
52
9-2im 4-6im
53
53
```
54
54
"""
55
- adjoint (A:: AbstractQuasiVecOrMat ) = Adjoint (A)
55
+ adjoint (A:: AbstractQuasiVecOrMat ) = QuasiAdjoint (A)
56
56
57
57
"""
58
58
transpose(A)
59
59
60
60
Lazy transpose. Mutating the returned object should appropriately mutate `A`. Often,
61
- but not always, yields `Transpose (A)`, where `Transpose ` is a lazy transpose wrapper. Note
61
+ but not always, yields `QuasiTranspose (A)`, where `QuasiTranspose ` is a lazy transpose wrapper. Note
62
62
that this operation is recursive.
63
63
64
64
This operation is intended for linear algebra usage - for general data manipulation see
@@ -72,30 +72,30 @@ julia> A = [3+2im 9+2im; 8+7im 4+6im]
72
72
8+7im 4+6im
73
73
74
74
julia> transpose(A)
75
- 2×2 Transpose {Complex{Int64},Array{Complex{Int64},2}}:
75
+ 2×2 QuasiTranspose {Complex{Int64},Array{Complex{Int64},2}}:
76
76
3+2im 8+7im
77
77
9+2im 4+6im
78
78
```
79
79
"""
80
- transpose (A:: AbstractQuasiVecOrMat ) = Transpose (A)
80
+ transpose (A:: AbstractQuasiVecOrMat ) = QuasiTranspose (A)
81
81
82
82
# unwrapping lowercase quasi-constructors
83
- adjoint (A:: Adjoint ) = A. parent
84
- transpose (A:: Transpose ) = A. parent
85
- adjoint (A:: Transpose {<:Real} ) = A. parent
86
- transpose (A:: Adjoint {<:Real} ) = A. parent
83
+ adjoint (A:: QuasiAdjoint ) = A. parent
84
+ transpose (A:: QuasiTranspose ) = A. parent
85
+ adjoint (A:: QuasiTranspose {<:Real} ) = A. parent
86
+ transpose (A:: QuasiAdjoint {<:Real} ) = A. parent
87
87
88
88
89
89
# some aliases for internal convenience use
90
- const AdjOrTrans{T,S} = Union{Adjoint {T,S},Transpose {T,S}} where {T,S}
91
- const AdjointAbsVec {T} = Adjoint {T,<: AbstractQuasiVector }
92
- const TransposeAbsVec {T} = Transpose {T,<: AbstractQuasiVector }
90
+ const AdjOrTrans{T,S} = Union{QuasiAdjoint {T,S},QuasiTranspose {T,S}} where {T,S}
91
+ const QuasiAdjointAbsVec {T} = QuasiAdjoint {T,<: AbstractQuasiVector }
92
+ const QuasiTransposeAbsVec {T} = QuasiTranspose {T,<: AbstractQuasiVector }
93
93
const AdjOrTransAbsVec{T} = AdjOrTrans{T,<: AbstractQuasiVector }
94
94
const AdjOrTransAbsMat{T} = AdjOrTrans{T,<: AbstractQuasiMatrix }
95
95
96
96
# for internal use below
97
- wrapperop (A:: Adjoint ) = adjoint
98
- wrapperop (A:: Transpose ) = transpose
97
+ wrapperop (A:: QuasiAdjoint ) = adjoint
98
+ wrapperop (A:: QuasiTranspose ) = transpose
99
99
100
100
# AbstractQuasiArray interface, basic definitions
101
101
length (A:: AdjOrTrans ) = length (A. parent)
@@ -114,8 +114,8 @@ IndexStyle(::Type{<:AdjOrTransAbsMat}) = IndexCartesian()
114
114
@propagate_inbounds getindex (v:: AdjOrTransAbsVec , :: Colon , :: Colon ) = wrapperop (v)(v. parent[:])
115
115
116
116
# conversion of underlying storage
117
- convert (:: Type{Adjoint {T,S}} , A:: Adjoint ) where {T,S} = Adjoint {T,S} (convert (S, A. parent))
118
- convert (:: Type{Transpose {T,S}} , A:: Transpose ) where {T,S} = Transpose {T,S} (convert (S, A. parent))
117
+ convert (:: Type{QuasiAdjoint {T,S}} , A:: QuasiAdjoint ) where {T,S} = QuasiAdjoint {T,S} (convert (S, A. parent))
118
+ convert (:: Type{QuasiTranspose {T,S}} , A:: QuasiTranspose ) where {T,S} = QuasiTranspose {T,S} (convert (S, A. parent))
119
119
120
120
# for vectors, the semantics of the wrapped and unwrapped types differ
121
121
# so attempt to maintain both the parent and wrapper type insofar as possible
@@ -135,82 +135,82 @@ cmp(A::AdjOrTransAbsVec, B::AdjOrTransAbsVec) = cmp(parent(A), parent(B))
135
135
isless (A:: AdjOrTransAbsVec , B:: AdjOrTransAbsVec ) = isless (parent (A), parent (B))
136
136
137
137
# ## concatenation
138
- # preserve Adjoint/Transpose wrapper around vectors
138
+ # preserve QuasiAdjoint/QuasiTranspose wrapper around vectors
139
139
# to retain the associated semantics post-concatenation
140
- hcat (avs:: Union{Number,AdjointAbsVec } ...) = _adjoint_hcat (avs... )
141
- hcat (tvs:: Union{Number,TransposeAbsVec } ...) = _transpose_hcat (tvs... )
142
- _adjoint_hcat (avs:: Union{Number,AdjointAbsVec } ...) = adjoint (vcat (map (adjoint, avs)... ))
143
- _transpose_hcat (tvs:: Union{Number,TransposeAbsVec } ...) = transpose (vcat (map (transpose, tvs)... ))
144
- typed_hcat (:: Type{T} , avs:: Union{Number,AdjointAbsVec } ...) where {T} = adjoint (typed_vcat (T, map (adjoint, avs)... ))
145
- typed_hcat (:: Type{T} , tvs:: Union{Number,TransposeAbsVec } ...) where {T} = transpose (typed_vcat (T, map (transpose, tvs)... ))
140
+ hcat (avs:: Union{Number,QuasiAdjointAbsVec } ...) = _adjoint_hcat (avs... )
141
+ hcat (tvs:: Union{Number,QuasiTransposeAbsVec } ...) = _transpose_hcat (tvs... )
142
+ _adjoint_hcat (avs:: Union{Number,QuasiAdjointAbsVec } ...) = adjoint (vcat (map (adjoint, avs)... ))
143
+ _transpose_hcat (tvs:: Union{Number,QuasiTransposeAbsVec } ...) = transpose (vcat (map (transpose, tvs)... ))
144
+ typed_hcat (:: Type{T} , avs:: Union{Number,QuasiAdjointAbsVec } ...) where {T} = adjoint (typed_vcat (T, map (adjoint, avs)... ))
145
+ typed_hcat (:: Type{T} , tvs:: Union{Number,QuasiTransposeAbsVec } ...) where {T} = transpose (typed_vcat (T, map (transpose, tvs)... ))
146
146
# otherwise-redundant definitions necessary to prevent hitting the concat methods in sparse/sparsevector.jl
147
- hcat (avs:: Adjoint {<:Any,<:Vector} ...) = _adjoint_hcat (avs... )
148
- hcat (tvs:: Transpose {<:Any,<:Vector} ...) = _transpose_hcat (tvs... )
149
- hcat (avs:: Adjoint {T,Vector{T}} ...) where {T} = _adjoint_hcat (avs... )
150
- hcat (tvs:: Transpose {T,Vector{T}} ...) where {T} = _transpose_hcat (tvs... )
147
+ hcat (avs:: QuasiAdjoint {<:Any,<:Vector} ...) = _adjoint_hcat (avs... )
148
+ hcat (tvs:: QuasiTranspose {<:Any,<:Vector} ...) = _transpose_hcat (tvs... )
149
+ hcat (avs:: QuasiAdjoint {T,Vector{T}} ...) where {T} = _adjoint_hcat (avs... )
150
+ hcat (tvs:: QuasiTranspose {T,Vector{T}} ...) where {T} = _transpose_hcat (tvs... )
151
151
# TODO unify and allow mixed combinations
152
152
153
153
154
154
# ## higher order functions
155
- # preserve Adjoint/Transpose wrapper around vectors
155
+ # preserve QuasiAdjoint/QuasiTranspose wrapper around vectors
156
156
# to retain the associated semantics post-map/broadcast
157
157
#
158
158
# note that the caller's operation f operates in the domain of the wrapped vectors' entries.
159
159
# hence the adjoint->f->adjoint shenanigans applied to the parent vectors' entries.
160
- map (f, avs:: AdjointAbsVec ... ) = adjoint (map ((xs... ) -> adjoint (f (adjoint .(xs)... )), parent .(avs)... ))
161
- map (f, tvs:: TransposeAbsVec ... ) = transpose (map ((xs... ) -> transpose (f (transpose .(xs)... )), parent .(tvs)... ))
160
+ map (f, avs:: QuasiAdjointAbsVec ... ) = adjoint (map ((xs... ) -> adjoint (f (adjoint .(xs)... )), parent .(avs)... ))
161
+ map (f, tvs:: QuasiTransposeAbsVec ... ) = transpose (map ((xs... ) -> transpose (f (transpose .(xs)... )), parent .(tvs)... ))
162
162
163
163
164
164
# ## linear algebra
165
165
166
- (- )(A:: Adjoint ) = Adjoint ( - A. parent)
167
- (- )(A:: Transpose ) = Transpose (- A. parent)
166
+ (- )(A:: QuasiAdjoint ) = QuasiAdjoint ( - A. parent)
167
+ (- )(A:: QuasiTranspose ) = QuasiTranspose (- A. parent)
168
168
169
169
# # multiplication *
170
170
171
- # Adjoint/Transpose -vector * vector
172
- * (u:: AdjointAbsVec , v:: AbstractQuasiVector ) = dot (u. parent, v)
173
- * (u:: TransposeAbsVec {T} , v:: AbstractQuasiVector{T} ) where {T<: Real } = dot (u. parent, v)
174
- function * (u:: TransposeAbsVec , v:: AbstractQuasiVector )
171
+ # QuasiAdjoint/QuasiTranspose -vector * vector
172
+ * (u:: QuasiAdjointAbsVec , v:: AbstractQuasiVector ) = dot (u. parent, v)
173
+ * (u:: QuasiTransposeAbsVec {T} , v:: AbstractQuasiVector{T} ) where {T<: Real } = dot (u. parent, v)
174
+ function * (u:: QuasiTransposeAbsVec , v:: AbstractQuasiVector )
175
175
@assert ! has_offset_axes (u, v)
176
176
@boundscheck length (u) == length (v) || throw (DimensionMismatch ())
177
177
return sum (@inbounds (u[k]* v[k]) for k in 1 : length (u))
178
178
end
179
- # vector * Adjoint/Transpose -vector
179
+ # vector * QuasiAdjoint/QuasiTranspose -vector
180
180
* (u:: AbstractQuasiVector , v:: AdjOrTransAbsVec ) = broadcast (* , u, v)
181
- # Adjoint/Transpose -vector * Adjoint/Transpose -vector
181
+ # QuasiAdjoint/QuasiTranspose -vector * QuasiAdjoint/QuasiTranspose -vector
182
182
# (necessary for disambiguation with fallback methods in linalg/matmul)
183
- * (u:: AdjointAbsVec , v:: AdjointAbsVec ) = throw (MethodError (* , (u, v)))
184
- * (u:: TransposeAbsVec , v:: TransposeAbsVec ) = throw (MethodError (* , (u, v)))
183
+ * (u:: QuasiAdjointAbsVec , v:: QuasiAdjointAbsVec ) = throw (MethodError (* , (u, v)))
184
+ * (u:: QuasiTransposeAbsVec , v:: QuasiTransposeAbsVec ) = throw (MethodError (* , (u, v)))
185
185
186
186
# AdjOrTransAbsVec{<:Any,<:AdjOrTransAbsVec} is a lazy conj vectors
187
187
# We need to expand the combinations to avoid ambiguities
188
- (* )(u:: TransposeAbsVec , v:: AdjointAbsVec {<:Any,<:TransposeAbsVec } ) =
188
+ (* )(u:: QuasiTransposeAbsVec , v:: QuasiAdjointAbsVec {<:Any,<:QuasiTransposeAbsVec } ) =
189
189
sum (uu* vv for (uu, vv) in zip (u, v))
190
- (* )(u:: AdjointAbsVec , v:: AdjointAbsVec {<:Any,<:TransposeAbsVec } ) =
190
+ (* )(u:: QuasiAdjointAbsVec , v:: QuasiAdjointAbsVec {<:Any,<:QuasiTransposeAbsVec } ) =
191
191
sum (uu* vv for (uu, vv) in zip (u, v))
192
- (* )(u:: TransposeAbsVec , v:: TransposeAbsVec {<:Any,<:AdjointAbsVec } ) =
192
+ (* )(u:: QuasiTransposeAbsVec , v:: QuasiTransposeAbsVec {<:Any,<:QuasiAdjointAbsVec } ) =
193
193
sum (uu* vv for (uu, vv) in zip (u, v))
194
- (* )(u:: AdjointAbsVec , v:: TransposeAbsVec {<:Any,<:AdjointAbsVec } ) =
194
+ (* )(u:: QuasiAdjointAbsVec , v:: QuasiTransposeAbsVec {<:Any,<:QuasiAdjointAbsVec } ) =
195
195
sum (uu* vv for (uu, vv) in zip (u, v))
196
196
197
197
# # pseudoinversion
198
- pinv (v:: AdjointAbsVec , tol:: Real = 0 ) = pinv (v. parent, tol). parent
199
- pinv (v:: TransposeAbsVec , tol:: Real = 0 ) = pinv (conj (v. parent)). parent
198
+ pinv (v:: QuasiAdjointAbsVec , tol:: Real = 0 ) = pinv (v. parent, tol). parent
199
+ pinv (v:: QuasiTransposeAbsVec , tol:: Real = 0 ) = pinv (conj (v. parent)). parent
200
200
201
201
202
202
# # left-division \
203
203
\ (u:: AdjOrTransAbsVec , v:: AdjOrTransAbsVec ) = pinv (u) * v
204
204
205
205
206
206
# # right-division \
207
- / (u:: AdjointAbsVec , A:: AbstractQuasiMatrix ) = adjoint (adjoint (A) \ u. parent)
208
- / (u:: TransposeAbsVec , A:: AbstractQuasiMatrix ) = transpose (transpose (A) \ u. parent)
209
- / (u:: AdjointAbsVec , A:: Transpose {<:Any,<:AbstractQuasiMatrix} ) = adjoint (conj (A. parent) \ u. parent) # technically should be adjoint(copy(adjoint(copy(A))) \ u.parent)
210
- / (u:: TransposeAbsVec , A:: Adjoint {<:Any,<:AbstractQuasiMatrix} ) = transpose (conj (A. parent) \ u. parent) # technically should be transpose(copy(transpose(copy(A))) \ u.parent)
207
+ / (u:: QuasiAdjointAbsVec , A:: AbstractQuasiMatrix ) = adjoint (adjoint (A) \ u. parent)
208
+ / (u:: QuasiTransposeAbsVec , A:: AbstractQuasiMatrix ) = transpose (transpose (A) \ u. parent)
209
+ / (u:: QuasiAdjointAbsVec , A:: QuasiTranspose {<:Any,<:AbstractQuasiMatrix} ) = adjoint (conj (A. parent) \ u. parent) # technically should be adjoint(copy(adjoint(copy(A))) \ u.parent)
210
+ / (u:: QuasiTransposeAbsVec , A:: QuasiAdjoint {<:Any,<:AbstractQuasiMatrix} ) = transpose (conj (A. parent) \ u. parent) # technically should be transpose(copy(transpose(copy(A))) \ u.parent)
211
211
212
212
213
- function materialize (M:: Mul2{<:Any,<:Any,<:Adjoint ,<:Adjoint } )
213
+ function materialize (M:: Mul2{<:Any,<:Any,<:QuasiAdjoint ,<:QuasiAdjoint } )
214
214
Ac,Bc = M. factors
215
215
materialize (Mul (parent (Bc),parent (Ac)))'
216
216
end
@@ -219,4 +219,4 @@ function adjoint(M::Mul)
219
219
Mul (reverse (adjoint .(M. factors))... )
220
220
end
221
221
222
- == (A:: Adjoint , B:: Adjoint ) = parent (A) == parent (B)
222
+ == (A:: QuasiAdjoint , B:: QuasiAdjoint ) = parent (A) == parent (B)
0 commit comments