Method: NMatrix.block_diagonal
- Defined in:
- lib/nmatrix/shortcuts.rb
.block_diagonal(*params) ⇒ Object Also known as: block_diag
Generate a block-diagonal NMatrix from the supplied 2D square matrices.
-
Arguments
-
*params -> An array that collects all arguments passed to the method. The method
can receive any number of arguments. Optionally, the last entry of +params+ is a hash of from NMatrix#initialize. All other entries of +params+ are the blocks of the desired block-diagonal matrix. Each such matrix block can be supplied as a square 2D NMatrix object, or alternatively as an array of arrays (with dimensions corresponding to a square matrix), or alternatively as a number.
-
-
Returns
-
NMatrix of block-diagonal form filled with specified matrices as the blocks along the diagonal.
-
-
Example
a = NMatrix.new([2,2], [1,2,3,4])
b = NMatrix.new([1,1], [123], dtype: :float64)
c = Array.new(2) { [[10,10], [10,10]] }
d = Array[[1,2,3], [4,5,6], [7,8,9]]
m = NMatrix.block_diagonal(a, b, *c, d, 10.0, 11, dtype: :int64, stype: :yale)
=>
[
[1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11]
]
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/nmatrix/shortcuts.rb', line 313 def block_diagonal(*params) = params.last.is_a?(Hash) ? params.pop : {} params.each_index do |i| params[i] = params[i].to_nm if params[i].is_a?(Array) # Convert Array to NMatrix params[i] = NMatrix.new([1,1], [params[i]]) if params[i].is_a?(Numeric) # Convert number to NMatrix end block_sizes = [] #holds the size of each matrix block params.each do |b| unless b.is_a?(NMatrix) raise(ArgumentError, "Only NMatrix or appropriate Array objects or single numbers allowed") end raise(ArgumentError, "Only 2D matrices or 2D arrays allowed") unless b.shape.size == 2 raise(ArgumentError, "Only square-shaped blocks allowed") unless b.shape[0] == b.shape[1] block_sizes << b.shape[0] end block_diag_mat = NMatrix.zeros(block_sizes.sum, ) (0...params.length).each do |n| # First determine the size and position of the n'th block in the block-diagonal matrix block_size = block_sizes[n] block_pos = block_sizes[0...n].sum # populate the n'th block in the block-diagonal matrix (0...block_size).each do |i| (0...block_size).each do |j| block_diag_mat[block_pos+i,block_pos+j] = params[n][i,j] end end end return block_diag_mat end |