Public Documentation
Documentation for BlockArrays.jl
's public interface.
See Internal Documentation for internal package docs covering all submodules.
Contents
Index
BlockArrays.undef_blocks
BlockArrays.AbstractBlockArray
BlockArrays.Block
BlockArrays.BlockArray
BlockArrays.BlockArray
BlockArrays.BlockArray
BlockArrays.BlockArray
BlockArrays.BlockBoundsError
BlockArrays.BlockIndex
BlockArrays.BlockKron
BlockArrays.BlockedArray
BlockArrays.BlockedMatrix
BlockArrays.BlockedVector
BlockArrays.UndefBlocksInitializer
Base.append!
Base.pop!
Base.popfirst!
Base.push!
Base.pushfirst!
Base.resize!
BlockArrays.blockappend!
BlockArrays.blockaxes
BlockArrays.blockcheckbounds
BlockArrays.blockfirsts
BlockArrays.blockisequal
BlockArrays.blockkron
BlockArrays.blocklasts
BlockArrays.blocklengths
BlockArrays.blockpop!
BlockArrays.blockpopfirst!
BlockArrays.blockpush!
BlockArrays.blockpushfirst!
BlockArrays.blocks
BlockArrays.blocksize
BlockArrays.blocksizes
BlockArrays.blockvec
BlockArrays.eachblock
BlockArrays.khatri_rao
BlockArrays.mortar
AbstractBlockArray interface
This sections defines the functions a subtype of AbstractBlockArray
should define to be a part of the AbstractBlockArray
interface. An AbstractBlockArray{T, N}
is a subtype of AbstractArray{T,N}
and should therefore also fulfill the AbstractArray
interface.
BlockArrays.AbstractBlockArray
— Typeabstract AbstractBlockArray{T, N} <: AbstractArray{T, N}
The abstract type that represents a blocked array. Types that implement the AbstractBlockArray
interface should subtype from this type.
** Typealiases **
AbstractBlockMatrix{T}
->AbstractBlockArray{T, 2}
AbstractBlockVector{T}
->AbstractBlockArray{T, 1}
AbstractBlockVecOrMat{T}
->Union{AbstractBlockMatrix{T}, AbstractBlockVector{T}}
BlockArrays.BlockBoundsError
— TypeBlockBoundsError([A], [inds...])
Thrown when a block indexing operation into a block array, A
, tried to access an out-of-bounds block, inds
.
BlockArrays.Block
— TypeBlock(inds...)
A Block
is simply a wrapper around a set of indices or enums so that it can be used to dispatch on. By indexing a AbstractBlockArray
with a Block
the a block at that block index will be returned instead of a single element.
julia> A = BlockArray(ones(2,3), [1, 1], [2, 1])
2×2-blocked 2×3 BlockMatrix{Float64}:
1.0 1.0 │ 1.0
──────────┼─────
1.0 1.0 │ 1.0
julia> A[Block(1, 1)]
1×2 Matrix{Float64}:
1.0 1.0
BlockArrays.BlockIndex
— TypeBlockIndex{N}
A BlockIndex
is an index which stores a global index in two parts: the block and the offset index into the block.
It can be used to index into BlockArrays
in the following manner:
julia> arr = Array(reshape(1:25, (5,5)));
julia> a = BlockedArray(arr, [3,2], [1,4])
2×2-blocked 5×5 BlockedMatrix{Int64}:
1 │ 6 11 16 21
2 │ 7 12 17 22
3 │ 8 13 18 23
───┼────────────────
4 │ 9 14 19 24
5 │ 10 15 20 25
julia> a[BlockIndex((1,2), (1,2))]
11
julia> a[BlockIndex((2,2), (2,3))]
20
BlockArrays.blockaxes
— Functionblockaxes(A::AbstractArray)
Return the tuple of valid block indices for array A
.
Examples
julia> A = BlockArray([1,2,3],[2,1])
2-blocked 3-element BlockVector{Int64}:
1
2
─
3
julia> blockaxes(A)
(BlockRange(Base.OneTo(2)),)
julia> B = BlockArray(zeros(3,4), [1,2], [1,2,1])
2×3-blocked 3×4 BlockMatrix{Float64}:
0.0 │ 0.0 0.0 │ 0.0
─────┼────────────┼─────
0.0 │ 0.0 0.0 │ 0.0
0.0 │ 0.0 0.0 │ 0.0
julia> blockaxes(B)
(BlockRange(Base.OneTo(2)), BlockRange(Base.OneTo(3)))
blockaxes(A::AbstractArray, d::Int)
Return the valid range of block indices for array A
along dimension d
.
Examples
julia> A = BlockArray([1,2,3], [2,1])
2-blocked 3-element BlockVector{Int64}:
1
2
─
3
julia> blockaxes(A,1)
BlockRange(Base.OneTo(2))
julia> blockaxes(A,1) |> collect
2-element Vector{Block{1, Int64}}:
Block(1)
Block(2)
BlockArrays.blockisequal
— Functionblockisequal(a::AbstractUnitRange{<:Integer}, b::AbstractUnitRange{<:Integer})
Check if a
and b
have the same block structure.
Examples
julia> b1 = blockedrange([1,2])
2-blocked 3-element BlockedOneTo{Int64, Vector{Int64}}:
1
─
2
3
julia> b2 = blockedrange([1,1,1])
3-blocked 3-element BlockedOneTo{Int64, Vector{Int64}}:
1
─
2
─
3
julia> blockisequal(b1, b1)
true
julia> blockisequal(b1, b2)
false
blockisequal(a::Tuple, b::Tuple)
Return if the tuples satisfy blockisequal
elementwise.
BlockArrays.blocksize
— Functionblocksize(A::AbstractArray)
blocksize(A::AbstractArray, i::Int)
Return the tuple of the number of blocks along each dimension. See also size and blocksizes.
Examples
julia> A = BlockArray(ones(3,3),[2,1],[1,1,1])
2×3-blocked 3×3 BlockMatrix{Float64}:
1.0 │ 1.0 │ 1.0
1.0 │ 1.0 │ 1.0
─────┼───────┼─────
1.0 │ 1.0 │ 1.0
julia> blocksize(A)
(2, 3)
julia> blocksize(A,2)
3
BlockArrays.blockfirsts
— Functionblockfirsts(a::AbstractUnitRange{<:Integer})
Return the first index of each block of a
.
Examples
julia> b = blockedrange([1,2,3])
3-blocked 6-element BlockedOneTo{Int64, Vector{Int64}}:
1
─
2
3
─
4
5
6
julia> blockfirsts(b)
3-element Vector{Int64}:
1
2
4
BlockArrays.blocklasts
— Functionblocklasts(a::AbstractUnitRange{<:Integer})
Return the last index of each block of a
.
Examples
julia> b = blockedrange([1,2,3])
3-blocked 6-element BlockedOneTo{Int64, Vector{Int64}}:
1
─
2
3
─
4
5
6
julia> blocklasts(b)
3-element Vector{Int64}:
1
3
6
BlockArrays.blocklengths
— Functionblocklengths(a::AbstractUnitRange{<:Integer})
Return the length of each block of a
.
Examples
julia> b = blockedrange([1,2,3])
3-blocked 6-element BlockedOneTo{Int64, Vector{Int64}}:
1
─
2
3
─
4
5
6
julia> blocklengths(b)
3-element Vector{Int64}:
1
2
3
BlockArrays.blocksizes
— Functionblocksizes(A::AbstractArray)
blocksizes(A::AbstractArray, d::Integer)
Return an iterator over the sizes of each block. See also size and blocksize.
Examples
julia> A = BlockArray(ones(3,3),[2,1],[1,1,1])
2×3-blocked 3×3 BlockMatrix{Float64}:
1.0 │ 1.0 │ 1.0
1.0 │ 1.0 │ 1.0
─────┼───────┼─────
1.0 │ 1.0 │ 1.0
julia> blocksizes(A)
2×3 BlockArrays.BlockSizes{Tuple{Int64, Int64}, 2, BlockMatrix{Float64, Matrix{Matrix{Float64}}, Tuple{BlockedOneTo{Int64, Vector{Int64}}, BlockedOneTo{Int64, Vector{Int64}}}}}:
(2, 1) (2, 1) (2, 1)
(1, 1) (1, 1) (1, 1)
julia> blocksizes(A)[1,2]
(2, 1)
julia> blocksizes(A,2)
3-element Vector{Int64}:
1
1
1
BlockArrays.blocks
— Functionblocks(a::AbstractArray{T,N}) :: AbstractArray{<:AbstractArray{T,N},N}
Return the array-of-arrays view to a
such that
blocks(a)[i₁, i₂, ..., iₙ] == a[Block(i₁), Block(i₂), ..., Block(iₙ)]
This function does not copy the blocks and give a mutable viwe to the original array. This is an "inverse" of mortar
.
Examples
julia> bs1 = permutedims(reshape([
1ones(1, 3), 2ones(1, 2),
3ones(2, 3), 4ones(2, 2),
], (2, 2)))
2×2 Matrix{Matrix{Float64}}:
[1.0 1.0 1.0] [2.0 2.0]
[3.0 3.0 3.0; 3.0 3.0 3.0] [4.0 4.0; 4.0 4.0]
julia> a = mortar(bs1)
2×2-blocked 3×5 BlockMatrix{Float64}:
1.0 1.0 1.0 │ 2.0 2.0
───────────────┼──────────
3.0 3.0 3.0 │ 4.0 4.0
3.0 3.0 3.0 │ 4.0 4.0
julia> bs2 = blocks(a)
2×2 Matrix{Matrix{Float64}}:
[1.0 1.0 1.0] [2.0 2.0]
[3.0 3.0 3.0; 3.0 3.0 3.0] [4.0 4.0; 4.0 4.0]
julia> bs1 == bs2
true
julia> bs2[1, 1] .*= 100;
julia> a # in-place mutation is reflected to the block array
2×2-blocked 3×5 BlockMatrix{Float64}:
100.0 100.0 100.0 │ 2.0 2.0
─────────────────────┼──────────
3.0 3.0 3.0 │ 4.0 4.0
3.0 3.0 3.0 │ 4.0 4.0
BlockArrays.eachblock
— Functioneachblock(A::AbstractBlockArray)
Create a generator that iterates over each block of an AbstractBlockArray
returning views.
julia> v = Array(reshape(1:6, (2, 3)))
2×3 Matrix{Int64}:
1 3 5
2 4 6
julia> A = BlockArray(v, [1,1], [2,1])
2×2-blocked 2×3 BlockMatrix{Int64}:
1 3 │ 5
──────┼───
2 4 │ 6
julia> sum.(eachblock(A))
2×2 Matrix{Int64}:
4 5
6 6
BlockArrays.blockcheckbounds
— Functionblockcheckbounds(A, inds...)
Throw a BlockBoundsError
if the specified block indexes are not in bounds for the given block array. Subtypes of AbstractBlockArray
should specialize this method if they need to provide custom block bounds checking behaviors.
julia> A = BlockArray(rand(2,3), [1,1], [2,1]);
julia> blockcheckbounds(A, 3, 2)
ERROR: BlockBoundsError: attempt to access 2×2-blocked 2×3 BlockMatrix{Float64} at block index [3,2]
[...]
BlockArray
BlockArrays.BlockArray
— TypeBlockArray{T, N, R<:AbstractArray{<:AbstractArray{T,N},N}, BS<:Tuple{Vararg{AbstractUnitRange{<:Integer},N}}} <: AbstractBlockArray{T, N}
A BlockArray
is an array where each block is stored contiguously. This means that insertions and retrieval of blocks can be very fast and non allocating since no copying of data is needed.
In the type definition, R
defines the array type that holds the blocks, for example Matrix{Matrix{Float64}}
.
BlockArrays.BlockArray
— MethodBlockArray(::UndefBlocksInitializer, ::Type{R}, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {N,R<:AbstractArray{<:Any,N}}
Construct a N
-dim BlockArray
with uninitialized blocks from a block type R
, with sizes defined by block_sizes
. Each block must be allocated before being accessed.
Examples
julia> B = BlockArray(undef_blocks, Matrix{Float64}, [1,3], [2,2])
2×2-blocked 4×4 BlockMatrix{Float64}:
#undef #undef │ #undef #undef
────────────────┼────────────────
#undef #undef │ #undef #undef
#undef #undef │ #undef #undef
#undef #undef │ #undef #undef
julia> typeof(blocks(B))
Matrix{Matrix{Float64}} (alias for Array{Array{Float64, 2}, 2})
julia> using SparseArrays
julia> B = BlockArray(undef_blocks, SparseMatrixCSC{Float64,Int}, [1,3], [2,2]);
julia> typeof(blocks(B))
Matrix{SparseMatrixCSC{Float64, Int64}} (alias for Array{SparseMatrixCSC{Float64, Int64}, 2})
See also undef_blocks
, UndefBlocksInitializer
BlockArrays.BlockArray
— MethodBlockArray{T}(::UndefBlocksInitializer, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T,N}
Construct a N
-dim BlockArray
with uninitialized blocks of type Array{T,N}
, with sizes defined by block_sizes
. Each block must be allocated before being accessed.
Examples
julia> B = BlockArray{Float64}(undef_blocks, [1,2], [1,2])
2×2-blocked 3×3 BlockMatrix{Float64}:
#undef │ #undef #undef
────────┼────────────────
#undef │ #undef #undef
#undef │ #undef #undef
julia> typeof(blocks(B))
Matrix{Matrix{Float64}} (alias for Array{Array{Float64, 2}, 2})
julia> B = BlockArray{Int8}(undef_blocks, [1,2])
2-blocked 3-element BlockVector{Int8}:
#undef
──────
#undef
#undef
julia> typeof(blocks(B))
Vector{Vector{Int8}} (alias for Array{Array{Int8, 1}, 1})
julia> B[Block(1)] .= 2 # errors, as the block is not allocated yet
ERROR: UndefRefError: access to undefined reference
[...]
julia> B[Block(1)] = [1]; # assign an array to the block
julia> B[Block(2)] = [2,3];
julia> B
2-blocked 3-element BlockVector{Int8}:
1
─
2
3
See also undef_blocks
, UndefBlocksInitializer
BlockArrays.BlockArray
— MethodBlockArray{T}(::UndefInitializer, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N}
Construct a N
-dim BlockArray
with blocks of type Array{T,N}
, with sizes defined by block_sizes
. The blocks are allocated using similar
, and the elements in each block are therefore unitialized.
Examples
julia> B = BlockArray{Int8}(undef, [1,2]);
julia> B[Block(1)] .= 2;
julia> B[Block(2)] .= 3;
julia> B
2-blocked 3-element BlockVector{Int8}:
2
─
3
3
BlockArrays.undef_blocks
— Constantundef_blocks
Alias for UndefBlocksInitializer()
, which constructs an instance of the singleton type UndefBlocksInitializer
, used in block array initialization to indicate the array-constructor-caller would like an uninitialized block array.
Examples
julia> BlockArray(undef_blocks, Matrix{Float32}, [1,2], [3,2])
2×2-blocked 3×5 BlockMatrix{Float32}:
#undef #undef #undef │ #undef #undef
────────────────────────┼────────────────
#undef #undef #undef │ #undef #undef
#undef #undef #undef │ #undef #undef
BlockArrays.UndefBlocksInitializer
— TypeUndefBlocksInitializer
Singleton type used in block array initialization, indicating the array-constructor-caller would like an uninitialized block array. See also undef_blocks
, an alias for UndefBlocksInitializer()
.
Examples
julia> BlockArray(undef_blocks, Matrix{Float32}, [1,2], [3,2])
2×2-blocked 3×5 BlockMatrix{Float32}:
#undef #undef #undef │ #undef #undef
────────────────────────┼────────────────
#undef #undef #undef │ #undef #undef
#undef #undef #undef │ #undef #undef
BlockArrays.mortar
— Functionmortar(blocks::AbstractArray)
mortar(blocks::AbstractArray{R, N}, sizes_1, sizes_2, ..., sizes_N)
mortar(blocks::AbstractArray{R, N}, block_sizes::Tuple{Vararg{AbstractUnitRange{<:Integer},N}})
Construct a BlockArray
from blocks
. block_sizes
is computed from blocks
if it is not given.
This is an "inverse" of blocks
.
Examples
julia> arrays = permutedims(reshape([
fill(1.0, 1, 3), fill(2.0, 1, 2),
fill(3.0, 2, 3), fill(4.0, 2, 2),
], (2, 2)))
2×2 Matrix{Matrix{Float64}}:
[1.0 1.0 1.0] [2.0 2.0]
[3.0 3.0 3.0; 3.0 3.0 3.0] [4.0 4.0; 4.0 4.0]
julia> M = mortar(arrays)
2×2-blocked 3×5 BlockMatrix{Float64}:
1.0 1.0 1.0 │ 2.0 2.0
───────────────┼──────────
3.0 3.0 3.0 │ 4.0 4.0
3.0 3.0 3.0 │ 4.0 4.0
julia> M == mortar(
(fill(1.0, 1, 3), fill(2.0, 1, 2)),
(fill(3.0, 2, 3), fill(4.0, 2, 2)),
)
true
mortar((block_11, ..., block_1m), ... (block_n1, ..., block_nm))
Construct a BlockMatrix
with n * m
blocks. Each block_ij
must be an AbstractMatrix
.
BlockArrays.blockappend!
— Functionblockappend!(dest::BlockVector, sources...) -> dest
Append blocks from sources
to dest
. The number of blocks in dest
are increased by sum(blocklength, sources)
.
This function avoids copying the elements of the blocks in sources
when these blocks are compatible with dest
. Importantly, this means that mutating sources
afterwards alters the items in dest
and it may even break the invariance of dest
if the length of sources
are changed.
The blocks in dest
must not alias with sources
or components of them. For example, the result of blockappend!(x, x)
is undefined.
Examples
julia> using BlockArrays
julia> blockappend!(mortar([[1], [2, 3]]), mortar([[4, 5]]))
3-blocked 5-element BlockVector{Int64}:
1
─
2
3
─
4
5
BlockArrays.blockpush!
— Functionblockpush!(dest::BlockVector, blocks...) -> dest
Push blocks
to the end of dest
.
This function avoids copying the elements of the blocks
when these blocks are compatible with dest
. Importantly, this means that mutating blocks
afterwards alters the items in dest
and it may even break the invariance of dest
if the length of blocks
are changed.
Examples
julia> using BlockArrays
julia> blockpush!(mortar([[1], [2, 3]]), [4, 5], [6])
4-blocked 6-element BlockVector{Int64}:
1
─
2
3
─
4
5
─
6
BlockArrays.blockpushfirst!
— Functionblockpushfirst!(dest::BlockVector, blocks...) -> dest
Push blocks
to the beginning of dest
. See also blockpush!
.
This function avoids copying the elements of the blocks
when these blocks are compatible with dest
. Importantly, this means that mutating blocks
afterwards alters the items in dest
and it may even break the invariance of dest
if the length of blocks
are changed.
Examples
julia> using BlockArrays
julia> blockpushfirst!(mortar([[1], [2, 3]]), [4, 5], [6])
4-blocked 6-element BlockVector{Int64}:
4
5
─
6
─
1
─
2
3
BlockArrays.blockpop!
— Functionblockpop!(A::BlockVector) -> block
Pop a block
from the end of dest
.
Examples
julia> using BlockArrays
julia> A = mortar([[1], [2, 3]]);
julia> blockpop!(A)
2-element Vector{Int64}:
2
3
julia> A
1-blocked 1-element BlockVector{Int64}:
1
BlockArrays.blockpopfirst!
— Functionblockpopfirst!(dest::BlockVector) -> block
Pop a block
from the beginning of dest
.
Examples
julia> using BlockArrays
julia> A = mortar([[1], [2, 3]]);
julia> blockpopfirst!(A)
1-element Vector{Int64}:
1
julia> A
1-blocked 2-element BlockVector{Int64}:
2
3
Base.append!
— Functionappend!(dest::BlockVector, sources...)
Append items from sources
to the last block of dest
.
The blocks in dest
must not alias with sources
or components of them. For example, the result of append!(x, x)
is undefined.
Examples
julia> using BlockArrays
julia> append!(mortar([[1], [2, 3]]), mortar([[4], [5]]))
2-blocked 5-element BlockVector{Int64}:
1
─
2
3
4
5
Base.push!
— Functionpush!(dest::BlockVector, items...)
Push items to the end of the last block.
Base.pushfirst!
— Functionpushfirst!(A::BlockVector, items...)
Push items to the beginning of the first block.
Base.pop!
— Functionpop!(A::BlockVector)
Pop the last element from the last non-empty block. Remove all empty blocks at the end.
Base.popfirst!
— Functionpopfirst!(A::BlockVector)
Pop the first element from the first non-empty block. Remove all empty blocks at the beginning.
BlockedArray
BlockArrays.BlockedArray
— TypeBlockedArray{T, N, R} <: AbstractBlockArray{T, N}
A BlockedArray
is similar to a BlockArray
except the full array is stored contiguously instead of block by block. This means that is not possible to insert and retrieve blocks without copying data. On the other hand parent
on a BlockedArray
is instead instant since it just returns the wrapped array.
When iteratively solving a set of equations with a gradient method the Jacobian typically has a block structure. It can be convenient to use a BlockedArray
to build up the Jacobian block by block and then pass the resulting matrix to a direct solver using parent
.
Examples
julia> A = zeros(Int, 2, 3);
julia> B = BlockedArray(A, [1,1], [2,1])
2×2-blocked 2×3 BlockedMatrix{Int64}:
0 0 │ 0
──────┼───
0 0 │ 0
julia> parent(B) === A
true
julia> B[Block(1,1)] .= 4
1×2 view(::Matrix{Int64}, 1:1, 1:2) with eltype Int64:
4 4
julia> A
2×3 Matrix{Int64}:
4 4 0
0 0 0
BlockArrays.BlockedVector
— TypeBlockedVector{T}
Alias for BlockedArray{T, 1}
julia> A = [1:6;]
6-element Vector{Int64}:
1
2
3
4
5
6
julia> BlockedVector(A, [3,2,1])
3-blocked 6-element BlockedVector{Int64}:
1
2
3
─
4
5
─
6
BlockArrays.BlockedMatrix
— TypeBlockedMatrix{T}
Alias for BlockedArray{T, 2}
julia> A = reshape([1:6;], 2, 3)
2×3 Matrix{Int64}:
1 3 5
2 4 6
julia> BlockedMatrix(A, [1,1], [1,2])
2×2-blocked 2×3 BlockedMatrix{Int64}:
1 │ 3 5
───┼──────
2 │ 4 6
Base.resize!
— Functionresize!(a::BlockVector, N::Block) -> BlockedVector
Resize a
to contain the first N
blocks, returning a new BlockVector
sharing memory with a
. If N
is smaller than the current collection block length, the first N
blocks will be retained. N
is not allowed to be larger.
resize!(a::BlockedVector, N::Block) -> BlockedVector
Resize a
to contain the first N
blocks, returning a new BlockedVector
sharing memory with a
. If N
is smaller than the current collection block length, the first N
blocks will be retained. N
is not allowed to be larger.
Kronecker products
BlockArrays.blockkron
— Functionblockkron(A...)
Return a blocked version of kron(A...) with the natural block-structure imposed.
Examples
julia> A = reshape(1:9, 3, 3)
3×3 reshape(::UnitRange{Int64}, 3, 3) with eltype Int64:
1 4 7
2 5 8
3 6 9
julia> BlockArrays.blockkron(A, A)
3×3-blocked 9×9 BlockMatrix{Int64}:
1 4 7 │ 4 16 28 │ 7 28 49
2 5 8 │ 8 20 32 │ 14 35 56
3 6 9 │ 12 24 36 │ 21 42 63
───────────┼──────────────┼────────────
2 8 14 │ 5 20 35 │ 8 32 56
4 10 16 │ 10 25 40 │ 16 40 64
6 12 18 │ 15 30 45 │ 24 48 72
───────────┼──────────────┼────────────
3 12 21 │ 6 24 42 │ 9 36 63
6 15 24 │ 12 30 48 │ 18 45 72
9 18 27 │ 18 36 54 │ 27 54 81
BlockArrays.BlockKron
— TypeBlockKron(A...)
Create a lazy representation of kron(A...) with the natural block-structure imposed. This is a component in blockkron(A...)
.
BlockArrays.blockvec
— Functionblockvec(A::AbstractMatrix)
creates a blocked version of vec(A)
, with the block structure used to represent the columns.
Examples
julia> A = reshape(1:9, 3, 3)
3×3 reshape(::UnitRange{Int64}, 3, 3) with eltype Int64:
1 4 7
2 5 8
3 6 9
julia> BlockArrays.blockvec(A)
3-blocked 9-element BlockedVector{Int64, UnitRange{Int64}, Tuple{BlockedOneTo{Int64, StepRangeLen{Int64, Int64, Int64, Int64}}}}:
1
2
3
─
4
5
6
─
7
8
9
BlockArrays.khatri_rao
— Functionkhatri_rao(A, B)
References
- Liu, Shuangzhe, and Gõtz Trenkler (2008) Hadamard, Khatri-Rao, Kronecker and Other Matrix Products. International J. Information and Systems Sciences 4, 160–177.
- 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.