1+ # ##
2+ # sum/cumsum
3+ # ##
4+
5+ # support overloading sum by MemoryLayout
6+ _sum (V:: AbstractQuasiArray , dims) = sum_layout (MemoryLayout (V), V, dims)
7+ _sum (V:: AbstractQuasiArray , :: Colon ) = sum_layout (MemoryLayout (V), V, :)
8+
9+ _cumsum (A, dims) = cumsum_layout (MemoryLayout (A), A, dims)
10+ cumsum (A:: AbstractQuasiArray ; dims:: Integer ) = _cumsum (A, dims)
11+ cumsum (x:: AbstractQuasiVector ) = cumsum (x, dims= 1 )
12+
13+ # sum is equivalent to hitting by ones(n) on the left or right
14+
15+ cumsum_layout (:: QuasiArrayLayout , A, d:: Int ) = QuasiArray (cumsum (parent (A),dims= d), axes (A))
16+
17+ for Sum in (:sum , :cumsum )
18+ Sum_Lay = Symbol (Sum, " _layout" )
19+ @eval function $Sum_Lay (LAY:: ApplyLayout{typeof(*)} , V:: AbstractQuasiMatrix , d:: Int )
20+ a = arguments (LAY, V)
21+ if d == 1
22+ * ($ Sum (first (a); dims= 1 ), tail (a)... )
23+ else
24+ @assert d == 2
25+ * (Base. front (a)... , $ Sum (last (a); dims= 2 ))
26+ end
27+ end
28+ end
29+
30+ function cumsum_layout (LAY:: ApplyLayout{typeof(*)} , V:: AbstractQuasiVector , dims)
31+ a = arguments (LAY, V)
32+ apply (* , cumsum (a[1 ]; dims= dims), tail (a)... )
33+ end
34+
35+ function sum_layout (LAY:: ApplyLayout{typeof(*)} , V:: AbstractQuasiVector , :: Colon )
36+ a = arguments (LAY, V)
37+ first (apply (* , sum (a[1 ]; dims= 1 ), tail (a)... ))
38+ end
39+
40+ sum_layout (:: MemoryLayout , A, dims) = sum_size (size (A), A, dims)
41+ sum_size (:: NTuple{N,Integer} , A, dims) where N = _sum (identity, A, dims)
42+ cumsum_layout (:: MemoryLayout , A, dims) = cumsum_size (size (A), A, dims)
43+ cumsum_size (:: NTuple{N,Integer} , A, dims) where N = error (" Not implemented" )
44+
45+
46+ # ###
47+ # diff
48+ # ###
49+
50+ @inline diff (a:: AbstractQuasiArray ; dims:: Integer = 1 ) = diff_layout (MemoryLayout (a), a, dims)
51+ function diff_layout (LAY:: ApplyLayout{typeof(*)} , V:: AbstractQuasiVector , dims... )
52+ a = arguments (LAY, V)
53+ * (diff (a[1 ]), tail (a)... )
54+ end
55+
56+ function diff_layout (LAY:: ApplyLayout{typeof(*)} , V:: AbstractQuasiMatrix , dims= 1 )
57+ a = arguments (LAY, V)
58+ @assert dims == 1 # for type stability, for now
59+ # if dims == 1
60+ * (diff (a[1 ]), tail (a)... )
61+ # else
62+ # *(front(a)..., diff(a[end]; dims=dims))
63+ # end
64+ end
65+
66+ diff_layout (:: MemoryLayout , A, dims... ) = diff_size (size (A), A, dims... )
67+ diff_size (sz, a, dims... ) = error (" diff not implemented for $(typeof (a)) " )
68+
69+ diff (x:: Inclusion ; dims:: Integer = 1 ) = ones (eltype (x), diffaxes (x))
70+ diff (c:: AbstractQuasiFill{<:Any,1} ; dims:: Integer = 1 ) = zeros (eltype (c), diffaxes (axes (c,1 )))
71+ function diff (c:: AbstractQuasiFill{<:Any,2} ; dims:: Integer = 1 )
72+ a,b = axes (c)
73+ if dims == 1
74+ zeros (eltype (c), diffaxes (a), b)
75+ else
76+ zeros (eltype (c), a, diffaxes (b))
77+ end
78+ end
79+
80+
81+ diffaxes (a:: Inclusion{<:Any,<:AbstractVector} ) = Inclusion (a. domain[1 : end - 1 ])
82+ diffaxes (a:: OneTo ) = oneto (length (a)- 1 )
83+ diffaxes (a) = a # default is differentiation does not change axes
84+
85+ diff (b:: QuasiVector ; dims:: Integer = 1 ) = QuasiVector (diff (b. parent) ./ diff (b. axes[1 ]), (diffaxes (axes (b,1 )),))
86+ function diff (A:: QuasiMatrix ; dims:: Integer = 1 )
87+ D = diff (A. parent; dims= dims)
88+ a,b = axes (A)
89+ if dims == 1
90+ QuasiMatrix (D ./ diff (a. domain), (diffaxes (a), b))
91+ else
92+ QuasiMatrix (D ./ permutedims (diff (b. domain)), (a, diffaxes (b)))
93+ end
94+ end
0 commit comments