@@ -46,45 +46,73 @@ for T in (:AbstractVector, :AbstractMatrix)
4646end
4747
4848# quad
49- quad (A:: Cholesky , x:: AbstractVector ) = sum (abs2, chol_upper (A) * x)
49+ function quad (A:: Cholesky , x:: AbstractVector )
50+ @check_argdims size (A, 1 ) == length (x)
51+ return sum (abs2, chol_upper (A) * x)
52+ end
5053function quad (A:: Cholesky , X:: AbstractMatrix )
54+ @check_argdims size (A, 1 ) == size (X, 1 )
5155 Z = chol_upper (A) * X
5256 return vec (sum (abs2, Z; dims= 1 ))
5357end
5458function quad! (r:: AbstractArray , A:: Cholesky , X:: AbstractMatrix )
55- Z = chol_upper (A) * X
56- return map! (Base. Fix1 (sum, abs2), r, eachcol (Z))
59+ @check_argdims eachindex (r) == axes (X, 2 )
60+ @check_argdims size (A, 1 ) == size (X, 1 )
61+ aU = chol_upper (A)
62+ z = similar (r, size (A, 1 )) # buffer to save allocations
63+ @inbounds for i in axes (X, 2 )
64+ copyto! (z, view (X, :, i))
65+ lmul! (aU, z)
66+ r[i] = sum (abs2, z)
67+ end
68+ return r
5769end
5870
5971# invquad
60- invquad (A:: Cholesky , x:: AbstractVector ) = sum (abs2, chol_lower (A) \ x)
61- function invquad (A:: Cholesky , X:: AbstractMatrix )
72+ function invquad (A:: Cholesky , x:: AbstractVector )
73+ @check_argdims size (A, 1 ) == size (x, 1 )
74+ return sum (abs2, chol_lower (A) \ x)
75+ end
76+ function invquad (A:: Cholesky , X:: AbstractMatrix )
77+ @check_argdims size (A, 1 ) == size (X, 1 )
6278 Z = chol_lower (A) \ X
6379 return vec (sum (abs2, Z; dims= 1 ))
6480end
6581function invquad! (r:: AbstractArray , A:: Cholesky , X:: AbstractMatrix )
66- Z = chol_lower (A) * X
67- return map! (Base. Fix1 (sum, abs2), r, eachcol (Z))
82+ @check_argdims eachindex (r) == axes (X, 2 )
83+ @check_argdims size (A, 1 ) == size (X, 1 )
84+ aL = chol_lower (A)
85+ z = similar (r, size (A, 1 )) # buffer to save allocations
86+ @inbounds for i in axes (X, 2 )
87+ copyto! (z, view (X, :, i))
88+ ldiv! (aL, z)
89+ r[i] = sum (abs2, z)
90+ end
91+ return r
6892end
6993
7094# tri products
7195
7296function X_A_Xt (A:: Cholesky , X:: AbstractMatrix )
97+ @check_argdims size (A, 1 ) == size (X, 2 )
7398 Z = X * chol_lower (A)
7499 return Z * transpose (Z)
75100end
76101
77102function Xt_A_X (A:: Cholesky , X:: AbstractMatrix )
103+ @check_argdims size (A, 1 ) == size (X, 1 )
78104 Z = chol_upper (A) * X
79105 return transpose (Z) * Z
80106end
81107
82108function X_invA_Xt (A:: Cholesky , X:: AbstractMatrix )
109+ @check_argdims size (A, 1 ) == size (X, 2 )
83110 Z = X / chol_upper (A)
84111 return Z * transpose (Z)
85112end
86113
87114function Xt_invA_X (A:: Cholesky , X:: AbstractMatrix )
115+ @check_argdims size (A, 1 ) == size (X, 1 )
88116 Z = chol_lower (A) \ X
89117 return transpose (Z) * Z
90118end
0 commit comments