1818
1919Base. size (P:: PlusOperator ,k:: Integer ) = size (first (P. ops),k)
2020
21+ bandwidthsmax (ops) = mapreduce (bandwidths, (t1,t2) -> max .(t1, t2), ops, init = (- 720 , - 720 ) #= approximate (-∞,-∞) =# )
2122
22- PlusOperator (opsin:: Vector{Operator{T}} ,bi:: Tuple{UT,VT} ) where {T,UT,VT } =
23+ PlusOperator (opsin:: Vector{Operator{T}} ,bi:: Tuple{Any,Any} = bandwidthsmax (opsin)) where {T} =
2324 PlusOperator {T,typeof(bi)} (opsin,bi)
2425
2526bandwidths (P:: PlusOperator ) = P. bandwidths
@@ -37,14 +38,6 @@ for (OP,mn) in ((:colstart,:min),(:colstop,:max),(:rowstart,:min),(:rowstop,:max
3738 end
3839end
3940
40- function PlusOperator (ops:: Vector )
41- # calculate bandwidths
42- almostneginf= - 720 # approximates -∞
43- b1 = mapreduce (first ∘ bandwidths, max, ops, init = almostneginf)
44- b2 = mapreduce (last ∘ bandwidths, max, ops, init = almostneginf)
45- PlusOperator (ops,(b1,b2))
46- end
47-
4841function convert (:: Type{Operator{T}} ,P:: PlusOperator ) where T
4942 if T== eltype (P)
5043 P
@@ -69,25 +62,18 @@ domain(P::PlusOperator) = commondomain(P.ops)
6962_promote_eltypeof (As... ) = _promote_eltypeof (As)
7063_promote_eltypeof (As:: Union{Vector, Tuple} ) = mapreduce (eltype, promote_type, As)
7164
72- + (A:: PlusOperator ,B:: PlusOperator ) =
73- promoteplus (Operator{_promote_eltypeof (A,B)}[A. ops; B. ops])
74- + (A:: PlusOperator ,B:: PlusOperator ,C:: PlusOperator ) =
75- promoteplus (Operator{_promote_eltypeof (A,B,C)}[A. ops; B. ops; C. ops])
76- + (A:: PlusOperator ,B:: Operator ) =
77- promoteplus (Operator{_promote_eltypeof (A,B)}[A. ops; B])
78- + (A:: PlusOperator ,B:: ZeroOperator ) = A
79- + (A:: PlusOperator ,B:: Operator ,C:: Operator ) =
80- promoteplus (Operator{_promote_eltypeof (A,B,C)}[A. ops; B; C])
81- + (A:: Operator ,B:: PlusOperator ) =
82- promoteplus (Operator{_promote_eltypeof (A,B)}[A; B. ops])
83- + (A:: ZeroOperator ,B:: PlusOperator ) = B
84- + (A:: Operator ,B:: Operator ) =
85- promoteplus (Operator{_promote_eltypeof (A,B)}[A,B])
86- + (A:: Operator ,B:: Operator ,C:: Operator ) =
87- promoteplus (Operator{_promote_eltypeof (A,B,C)}[A,B,C])
88-
89-
65+ _extractops (A, :: Any ) = [A]
66+ _extractops (A:: PlusOperator , :: typeof (+ )) = A. ops
9067
68+ function + (A:: Operator ,B:: Operator )
69+ v = Operator{_promote_eltypeof (A,B)}[_extractops (A, + ); _extractops (B, + )]
70+ promoteplus (v)
71+ end
72+ # Optimization for 3-term sum
73+ function + (A:: Operator ,B:: Operator ,C:: Operator )
74+ v = Operator{_promote_eltypeof (A,B,C)}[_extractops (A,+ ); _extractops (B, + ); _extractops (C, + )]
75+ promoteplus (v)
76+ end
9177
9278Base. stride (P:: PlusOperator )= mapreduce (stride,gcd,P. ops)
9379
@@ -137,7 +123,7 @@ for TYP in (:ZeroOperator,:Operator)
137123 end
138124end
139125+ (A:: ZeroOperator ,B:: Operator ) = B+ A
140-
126+ + (Z1 :: ZeroOperator , Z2 :: ZeroOperator , Z3 :: ZeroOperator ) = (Z1 + Z2) + Z3
141127
142128
143129
@@ -257,14 +243,12 @@ TimesOperator(ops::Vector{Operator{T}}) where {T} = TimesOperator(ops,bandwidths
257243TimesOperator (ops:: Vector{OT} ) where {OT<: Operator } =
258244 TimesOperator (convert (Vector{Operator{eltype (OT)}},ops),bandwidthssum (ops))
259245
260- TimesOperator (A:: TimesOperator ,B:: TimesOperator ) =
261- TimesOperator (Operator{_promote_eltypeof (A,B)}[A. ops; B. ops], _bandwidthssum (A, B))
262- TimesOperator (A:: TimesOperator ,B:: Operator ) =
263- TimesOperator (Operator{_promote_eltypeof (A,B)}[A. ops; B], _bandwidthssum (A, B))
264- TimesOperator (A:: Operator ,B:: TimesOperator ) =
265- TimesOperator (Operator{_promote_eltypeof (A,B)}[A; B. ops], _bandwidthssum (A, B))
266- TimesOperator (A:: Operator ,B:: Operator ) =
267- TimesOperator (Operator{_promote_eltypeof (A,B)}[A,B], _bandwidthssum (A, B))
246+ _extractops (A:: TimesOperator , :: typeof (* )) = A. ops
247+
248+ function TimesOperator (A:: Operator ,B:: Operator )
249+ v = Operator{_promote_eltypeof (A,B)}[_extractops (A, * ); _extractops (B, * )]
250+ TimesOperator (v, _bandwidthssum (A, B))
251+ end
268252
269253
270254== (A:: TimesOperator ,B:: TimesOperator )= A. ops== B. ops
@@ -492,29 +476,13 @@ for OP in (:(adjoint),:(transpose))
492476 @eval $ OP (A:: TimesOperator )= TimesOperator (reverse! (map ($ OP,A. ops)))
493477end
494478
495- * (A:: TimesOperator ,B:: TimesOperator ) =
496- promotetimes (Operator{_promote_eltypeof (A, B)}[A. ops; B. ops])
497- function * (A:: TimesOperator ,B:: Operator )
498- if isconstop (B)
499- promotedomainspace (convert (Number,B)* A,domainspace (B))
500- else
501- promotetimes (Operator{_promote_eltypeof (A, B)}[A. ops; B])
502- end
503- end
504- function * (A:: Operator ,B:: TimesOperator )
505- if isconstop (A)
506- promoterangespace (convert (Number,A)* B,rangespace (A))
507- else
508- promotetimes (Operator{_promote_eltypeof (A, B)}[A; B. ops])
509- end
510- end
511479function * (A:: Operator ,B:: Operator )
512480 if isconstop (A)
513481 promoterangespace (convert (Number,A)* B,rangespace (A))
514482 elseif isconstop (B)
515483 promotedomainspace (convert (Number,B)* A,domainspace (B))
516484 else
517- promotetimes (Operator{_promote_eltypeof (A, B)}[A,B ])
485+ promotetimes (Operator{_promote_eltypeof (A, B)}[_extractops (A, * ); _extractops (B, * ) ])
518486 end
519487end
520488
0 commit comments