11""" 
2-     Λc_mul_B!(A::AbstractTerm, B::AbstractArray) 
32    A_mul_Λ!(A::AbstractArray, B::AbstractTerm) 
43
5- In-place products w.r.t. blocks of Λ or Λ′  
4+ In-place product of `A` with a repeated block diagonal expansion of `B.Λ``  
65
76An [`AbstractTerm`]{@ref} of size n×k includes a description of a lower triangular 
87k×k matrix determined by the θ parameter vector.  These matrices are, at most, repeated 
@@ -12,94 +11,64 @@ with a [`MatrixTerm`]{@ref} is the identity.
1211See also [`scaleinflate!`]{@ref} which performs two such multiplications plus inflation of 
1312the diagonal plus a copy! operation in one step. 
1413""" 
15- function  Λc_mul_B! end 
1614function  A_mul_Λ! end 
17- 
18- Λc_mul_B! (A:: MatrixTerm , B) =  B
1915A_mul_Λ! (A, B:: MatrixTerm ) =  A
20- 
2116A_mul_Λ! (A, B:: ScalarFactorReTerm ) =  scale! (A, B. Λ)
22- Λc_mul_B! (A:: ScalarFactorReTerm , B) =  scale! (A. Λ, B)
23- 
24- function  A_mul_Λ! (A:: SparseMatrixCSC{T,S} , B:: VectorFactorReTerm{T} ) where  {T,S}
25-     k =  vsize (B)
26-     nz =  nonzeros (A)
27-     λ =  LowerTriangular (B. Λ)
28-     m, n =  size (A)
29-     cp =  A. colptr
30-     rv =  rowvals (A)
31-     blkstart =  1 
32-     while  blkstart ≤  n
33-         i1 =  nzrange (A, blkstart)
34-         r =  length (i1)
35-         if  (cp[blkstart +  k] -  cp[blkstart]) ≠  length (i1) *  k
36-             throw (ArgumentError (" A is not compatible with B" 
37-         end 
38-         # # consider using a pointer here to cut down on allocation (~ 1GB for d3 fit)
39-         a =  reshape (view (nz, cp[blkstart]: (cp[blkstart +  k] -  1 )), (r, k))
40-         A_mul_B! (a, a, λ)
41-         blkstart +=  k
17+ function  A_mul_Λ! (A:: BlockedSparse{T} , B:: VectorFactorReTerm{T} ) where  T
18+     λ =  B. Λ
19+     for  blk in  A. colblocks
20+         A_mul_B! (blk, λ)
4221    end 
4322    A
4423end 
45- 
46- function  Λ_mul_B! (A:: VectorFactorReTerm{T} , B:: StridedVector{T} ) where  T
47-     @argcheck  (k =  vsize (A)) >  1 
48-     λ =  LowerTriangular (A. Λ)
49-     A_mul_B! (λ, reshape (B, (k, div (length (B), k))))
50-     B
51- end 
52- 
53- Λ_mul_B! (A:: ScalarFactorReTerm{T} , B:: StridedVecOrMat{T} ) where  T =  scale! (B, A. Λ)
54- 
55- function  A_mul_Λ! (A:: Matrix{T} , B:: VectorFactorReTerm{T} ) where  T<: AbstractFloat 
56-     @argcheck  (k =  vsize (B)) >  1 
57-     λ =  LowerTriangular (B. Λ)
24+ function  A_mul_Λ! (A:: Matrix{T} , B:: VectorFactorReTerm{T,V,R,S} ) where  {T,V,R,S}
25+     λ =  B. Λ
5826    m, n =  size (A)
59-     q, r =  divrem (n, k)
60-     if  r ≠  0 
61-         throw (DimensionMismatch (" size(A, 2) = $n  is not a multiple of size(B.λ, 1) = $k " 
62-     end 
63-     offset =  0 
64-     onetok =  1 : k
65-     for  blk in  1 : q
66-         # # another place where ~ 1GB is allocated in d3 fit
67-         A_mul_B! (view (A, :, onetok +  offset), λ)
68-         offset +=  k
27+     q, r =  divrem (n, S)
28+     iszero (r) ||  throw (DimensionMismatch (" size(A, 2) = $n  is not a multiple of S = $S " 
29+     A3 =  reshape (A, (m, S, q))
30+     for  k in  1 : q
31+         A_mul_B! (view (A3, :, :, k), λ)
6932    end 
7033    A
7134end 
7235
73- Λ_mul_B! (C:: AbstractArray{T} , A:: ScalarFactorReTerm{T} , B:: AbstractArray{T} ) where  T =  scale! (C, A. Λ, B)
36+ """ 
37+     Λc_mul_B!(A::AbstractTerm, B::AbstractArray) 
38+ 
39+ In-place product of a repeated block diagonal expansion of `A.Λ'` with `B` 
7440
75- function  Λ_mul_B! (C:: StridedVecOrMat{T} , A:: VectorFactorReTerm{T} ,
76-                   B:: StridedVecOrMat{T} ) where  T
77-     @argcheck (size (C) ==  size (B), DimensionMismatch)
78-     k =  vsize (A)
79-     q, r =  divrem (size (C, 1 ), k)
80-     iszero (r) ||  throw (ArgumentError (" size(C, 1) = $(size (C,1 ))  is not a multiple of $k  = vsize(A)" 
81-     A_mul_B! (LowerTriangular (A. Λ), reshape (copy! (C, B), (k, size (C, 2 ) *  q)))
82-     C
41+ See also [`scaleinflate!`]{@ref} which performs two such multiplications plus inflation of 
42+ the diagonal plus a copy! operation in one step. 
43+ """ 
44+ function  Λc_mul_B! end 
45+ Λc_mul_B! (A:: MatrixTerm , B) =  B
46+ Λc_mul_B! (A:: ScalarFactorReTerm , B) =  scale! (A. Λ, B)
47+ function  Λc_mul_B! (A:: VectorFactorReTerm{T,V,R,S} , B:: Matrix{T} ) where  {T,V,R,S}
48+     m, n =  size (B)
49+     Ac_mul_B! (A. Λ, reshape (B, (S, div (m, S) *  n)))
50+     B
8351end 
8452
85- function  Λc_mul_B! (A:: VectorFactorReTerm{T} , B:: StridedVecOrMat{T} ) where  T
86-     @argcheck  (k =  vsize (A)) >  1 
87-     λ =  LowerTriangular (A. Λ)
88-     m, n =  size (B, 1 ), size (B, 2 )
89-     Ac_mul_B! (λ, reshape (B, (k, div (m, k) *  n)))
53+ function  Λc_mul_B! (A:: VectorFactorReTerm{T} , B:: BlockedSparse{T} ) where  T
54+     Ac_mul_B! (A. Λ, B. nzsasmat)
9055    B
9156end 
9257
93- function  Λc_mul_B! (A:: VectorFactorReTerm{T} , B:: SparseMatrixCSC{T} ) where  {T}
94-     @argcheck  (k =  vsize (A)) >  1 
95-     nz =  nonzeros (B)
96-     λ =  LowerTriangular (A. Λ)
97-     for  j in  1 : B. n
98-         # # third place with over 1 GB allocation in d3 fit
99-         # # probably call BLAS.trmm directly here
100-         bnz =  view (nz, nzrange (B, j))
101-         mbj =  reshape (bnz, (k, div (length (bnz), k)))
102-         Ac_mul_B! (mbj, λ, mbj)
103-     end 
104-     B
58+ """ 
59+     Λ_mul_B!(C::Matrix, A::AbstractFactorReTerm, B::Matrix) 
60+ 
61+ Mutating product of the repeated block-diagonal expansion of `A` and `B` into `C` 
62+ This multiplication is used to convert "spherical" random effects to the original scale. 
63+ """ 
64+ function  Λ_mul_B! (C:: Matrix , A:: AbstractFactorReTerm , B:: Matrix ) end 
65+ 
66+ function  Λ_mul_B! (C:: Matrix{T} , A:: ScalarFactorReTerm{T} , B:: Matrix{T} ) where  T
67+     @argcheck (size (C) ==  size (B) ==  (1 , size (A, 2 )), DimensionMismatch)
68+     scale! (C, A. Λ, B)
69+ end 
70+ 
71+ function  Λ_mul_B! (C:: Matrix{T} , A:: VectorFactorReTerm{T,V,R,S} , B:: Matrix{T} ) where  {T,V,R,S}
72+     @argcheck (size (C) ==  size (B) ==  (S, div (size (A, 2 ), S)), DimensionMismatch)
73+     A_mul_B! (A. Λ, copy! (C, B))
10574end 
0 commit comments