@@ -223,22 +223,26 @@ axpy!(α, S::SubOperator{T,OP}, A::AbstractMatrix) where {T,OP<:ConstantTimesOpe
223
223
224
224
225
225
226
- struct TimesOperator{T,BW,SZ,O<: Operator{T} ,BBW,SBBW} <: Operator{T}
226
+ struct TimesOperator{T,BW,SZ,O<: Operator{T} ,BBW,SBBW,D } <: Operator{T}
227
227
ops:: Vector{O}
228
228
bandwidths:: BW
229
229
sz:: SZ
230
230
blockbandwidths:: BBW
231
231
subblockbandwidths:: SBBW
232
232
isbandedblockbanded:: Bool
233
233
israggedbelow:: Bool
234
+ domainspace:: D
234
235
235
236
function TimesOperator {T,BW,SZ,O,BBW,SBBW} (ops:: Vector{O} , bw:: BW ,
236
237
sz:: SZ , bbw:: BBW , sbbw:: SBBW ,
237
- ibbb:: Bool , irb:: Bool ) where {T,O<: Operator{T} ,BW,SZ,BBW,SBBW}
238
- # check compatible
238
+ ibbb:: Bool , irb:: Bool , dsp:: D ) where {T,O<: Operator{T} ,BW,SZ,BBW,SBBW,D}
239
+
240
+ dsp == domainspace (ops[end ]) || throw (ArgumentError (" incompatible domainspace" ))
241
+
242
+ # check compatibility
239
243
for k = 1 : length (ops)- 1
240
244
size (ops[k], 2 ) == size (ops[k+ 1 ], 1 ) || throw (ArgumentError (" incompatible operator sizes" ))
241
- spacescompatible (domainspace (ops[k]), rangespace (ops[k+ 1 ])) || throw (ArgumentError (" imcompatible spaces at index $k " ))
245
+ spacescompatible (domainspace (ops[k]), rangespace (ops[k+ 1 ])) || throw (ArgumentError (" incompatible spaces at index $k " ))
242
246
end
243
247
244
248
# remove TimesOperators buried inside ops
@@ -252,7 +256,7 @@ struct TimesOperator{T,BW,SZ,O<:Operator{T},BBW,SBBW} <: Operator{T}
252
256
newops = ops
253
257
end
254
258
255
- new {T,BW,SZ,O,BBW,SBBW} (newops, bw, sz, bbw, sbbw, ibbb, irb)
259
+ new {T,BW,SZ,O,BBW,SBBW,D } (newops, bw, sz, bbw, sbbw, ibbb, irb, dsp )
256
260
end
257
261
end
258
262
@@ -273,9 +277,10 @@ function TimesOperator(ops::AbstractVector{O},
273
277
sbbw:: Tuple{Any,Any} = bandwidthssum (ops, subblockbandwidths),
274
278
ibbb:: Bool = all (isbandedblockbanded, ops),
275
279
irb:: Bool = all (israggedbelow, ops),
280
+ dsp = domainspace (last (ops)),
276
281
) where {O<: Operator }
277
282
TimesOperator {eltype(O),typeof(bw),typeof(sz),O,typeof(bbw),typeof(sbbw)} (
278
- convert_vector (ops), bw, sz, bbw, sbbw, ibbb, irb)
283
+ convert_vector (ops), bw, sz, bbw, sbbw, ibbb, irb, dsp )
279
284
end
280
285
281
286
_extractops (A:: TimesOperator , :: typeof (* )) = A. ops
@@ -284,9 +289,10 @@ function TimesOperator(A::Operator, B::Operator)
284
289
v = collateops (* , A, B)
285
290
ibbb = all (isbandedblockbanded, (A, B))
286
291
irb = all (israggedbelow, (A, B))
292
+ dsp = domainspace (B)
287
293
TimesOperator (convert_vector (v), _bandwidthssum (A, B), _timessize ((A, B)),
288
294
_bandwidthssum (A, B, blockbandwidths),
289
- _bandwidthssum (A, B, subblockbandwidths), ibbb, irb)
295
+ _bandwidthssum (A, B, subblockbandwidths), ibbb, irb, dsp )
290
296
end
291
297
292
298
@@ -301,7 +307,7 @@ function convert(::Type{Operator{T}}, P::TimesOperator) where {T}
301
307
_convertops (Operator{T}, ops),
302
308
bandwidths (P), size (P), blockbandwidths (P),
303
309
subblockbandwidths (P), isbandedblockbanded (P),
304
- israggedbelow (P)):: Operator{T}
310
+ israggedbelow (P), domainspace (P) ):: Operator{T}
305
311
end
306
312
end
307
313
318
324
319
325
@assert length (opsin) > 1 " need at least 2 operators"
320
326
ops, bw, bbw, sbbw, ibbb, irb = __promotetimes (opsin, dsp, anytimesop)
321
- TimesOperator (ops, bw, sz, bbw, sbbw, ibbb, irb)
327
+ TimesOperator (ops, bw, sz, bbw, sbbw, ibbb, irb, dsp )
322
328
end
323
329
function __promotetimes (opsin, dsp, anytimesop)
324
330
ops = Vector {Operator{promote_eltypeof(opsin)}} (undef, 0 )
372
378
end
373
379
end
374
380
375
- domainspace (P:: PlusOrTimesOp ) = domainspace (last (P. ops))
381
+ domainspace (P:: PlusOperator ) = domainspace (last (P. ops))
382
+ domainspace (T:: TimesOperator ) = T. domainspace
376
383
rangespace (P:: PlusOrTimesOp ) = rangespace (first (P. ops))
377
384
378
385
domain (P:: TimesOperator ) = commondomain (P. ops)
0 commit comments