@@ -6,7 +6,7 @@ References
6
6
* Khatri, C. G., and Rao, C. Radhakrishna (1968) Solutions to Some Functional Equations and Their Applications to Characterization of Probability Distributions. Sankhya: Indian J. Statistics, Series A 30, 167–180.
7
7
"""
8
8
function khatri_rao (A:: AbstractBlockMatrix , B:: AbstractBlockMatrix )
9
- #
9
+ #
10
10
Ablksize = blocksize (A)
11
11
Bblksize = blocksize (B)
12
12
27
27
28
28
function khatri_rao (A:: AbstractMatrix , B:: AbstractMatrix )
29
29
kron (A, B)
30
- end
30
+ end
31
+
32
+ """ "
33
+ BlockKron(A...)
34
+
35
+ creates a lazy representation of kron(A...) with the natural
36
+ block-structure imposed. This is a component in `blockkron(A...)`.
37
+ """
38
+ struct BlockKron{T,N,ARGS <: Tuple } <: AbstractBlockArray{T,N}
39
+ args:: ARGS
40
+ end
41
+
42
+ BlockKron {T,N} (A... ) where {T,N} = BlockKron {T,N,typeof(A)} (A)
43
+ BlockKron {T} (A:: AbstractVector , B:: AbstractVector , C:: AbstractVector... ) where {T} = BlockKron {T,1} (A, B, C... )
44
+ BlockKron {T} (A, B, C... ) where {T} = BlockKron {T,2} (A, B, C... )
45
+ BlockKron (A, B, C... ) = BlockKron {mapreduce(eltype,promote_type,(A,B,C...))} (A, B, C... )
46
+
47
+
48
+ size (B:: BlockKron ) = size (Kron (B))
49
+
50
+ size (K:: BlockKron , j:: Int ) = prod (size .(K. args, j))
51
+ size (a:: BlockKron{<:Any,1} ) = (size (a,1 ),)
52
+ size (a:: BlockKron{<:Any,2} ) = (size (a,1 ), size (a,2 ))
53
+
54
+ function axes (K:: BlockKron{<:Any,1} )
55
+ A,B = K. args
56
+ (blockedrange (fill (prod (size .(tail (K. args),1 )), size (K. args[1 ],1 ))),)
57
+ end
58
+
59
+ function axes (K:: BlockKron{<:Any,2} )
60
+ A,B = K. args
61
+ blockedrange .((fill (prod (size .(tail (K. args),1 )), size (K. args[1 ],1 )),
62
+ fill (prod (size .(tail (K. args),2 )), size (K. args[1 ],2 ))))
63
+ end
64
+
65
+ kron_getindex ((A,):: Tuple{AbstractVector} , k:: Integer ) = A[k]
66
+ function kron_getindex ((A,B):: NTuple{2,AbstractVector} , k:: Integer )
67
+ K,κ = divrem (k- 1 , length (B))
68
+ A[K+ 1 ]* B[κ+ 1 ]
69
+ end
70
+ kron_getindex ((A,):: Tuple{AbstractMatrix} , k:: Integer , j:: Integer ) = A[k,j]
71
+ function kron_getindex ((A,B):: NTuple{2,AbstractVecOrMat} , k:: Integer , j:: Integer )
72
+ K,κ = divrem (k- 1 , size (B,1 ))
73
+ J,ξ = divrem (j- 1 , size (B,2 ))
74
+ A[K+ 1 ,J+ 1 ]* B[κ+ 1 ,ξ+ 1 ]
75
+ end
76
+
77
+ kron_getindex (args:: Tuple , k:: Integer , j:: Integer ) = kron_getindex (tuple (BlockKron (args[1 : 2 ]. .. ), args[3 : end ]. .. ), k, j)
78
+ kron_getindex (args:: Tuple , k:: Integer ) = kron_getindex (tuple (BlockKron (args[1 : 2 ]. .. ), args[3 : end ]. .. ), k)
79
+
80
+ getindex (K:: BlockKron{<:Any,1} , k:: Integer ) = kron_getindex (K. args, k)
81
+ getindex (K:: BlockKron{<:Any,2} , k:: Integer , j:: Integer ) = kron_getindex (K. args, k, j)
82
+
83
+ kron_getblock ((a,b):: Tuple{Any,Any} , k:: Integer ) = a[k]* b
84
+ kron_getblock (args, k:: Integer ) = args[1 ][k]* BlockKron (tail (args)... )
85
+
86
+ kron_getblock ((a,b):: Tuple{Any,Any} , k:: Integer , j:: Integer ) = a[k,j]* b
87
+ kron_getblock (args, k:: Integer , j:: Integer ) = args[1 ][k,j]* BlockKron (tail (args)... )
88
+
89
+ getblock (K:: BlockKron{<:Any,1} , k:: Integer ) = kron_getblock (K. args, k)
90
+ getblock (K:: BlockKron{<:Any,2} , k:: Integer , j:: Integer ) = kron_getblock (K. args, k, j)
91
+
92
+ # const SubKron{T,M1,M2,R1,R2} = SubArray{T,2,<:BlockKron{T,M1,M2},<:Tuple{<:BlockSlice{R1},<:BlockSlice{R2}}}
93
+
94
+
95
+ # BroadcastStyle(::Type{<:SubKron{<:Any,<:Any,B,Block1,Block1}}) where B =
96
+ # BroadcastStyle(B)
97
+
98
+
99
+ # allow dispatch on memory layout
100
+ _blockkron (_, A) = BlockArray (BlockKron (A... ))
101
+
102
+
103
+ """ "
104
+ blockkron(A...)
105
+
106
+ creates a blocked version of kron(A...) with the natural
107
+ block-structure imposed.
108
+ """
109
+ blockkron (A... ) = _blockkron (map (MemoryLayout,A), A)
110
+
111
+ """
112
+ blockvec(A::AbstractMatrix)
113
+
114
+ creates a blocked version of `vec(A)`, with the block structure used to represent the columns.
115
+ """
116
+ blockvec (A:: AbstractMatrix ) = PseudoBlockVector (vec (A), Fill (size (A,1 ), size (A,2 )))
0 commit comments