Reputation: 1057
I looked through core.matrix searching for a block diagonal matrix function and searched Google, but have found no such function. Does such a function exist? If it does not could someone point me in the right direction to writing such a function.
Sample inputs would be nested vectors which would output along the diagonals of a larger nested vector.
Symbolic example: Let a,b,c,d be matrices (nested vectors). An example output would then look like
[[a 0 0 0] [0 b 0 0] [0 0 c 0] [0 0 0 d]]
where d might be [[0 1] [1 0]].
Upvotes: 2
Views: 720
Reputation: 106351
The library Vectorz (which provides the underlying types for vectorz-clj) includes a BlockDiagonalMatrix
class:
You'll have to use Java interop to instantiate it right now, but it offers a couple of advangtages:
Longer term, it probably makes sense to add a block-diagonal-matrix
function to core.matrix
itself. In fact, I've just created an issue to do this:
Upvotes: 0
Reputation: 10789
First of all you need a function to generate vector of size n with element m injected into i th position.
(defn vec-i [m i n]
(-> (repeat n 0)
(vec)
(assoc-in [i] m)))
(vec-i 'a 0 10) => [a 0 0 0 0 0 0 0 0 0]
(vec-i 'b 2 7) => [0 0 b 0 0 0 0]
Then just combine results for every i (assuming matrices
are list of your diagonal elements)
(defn block-diag [matrices]
(let [n (count matrices)]
(vec (map-indexed #(vec-i %2 %1 n) matrices))))
(block-diag ['a 'b 'c 'd]) => [[a 0 0 0] [0 b 0 0] [0 0 c 0] [0 0 0 d]]
Of course, symbols abcd can be replaced to matrix.
Upvotes: 4