Kronecker product

You are encouraged to solve this task according to the task description, using any language you may know.


Task

Implement the   Kronecker product   of two matrices (arbitrary sized) resulting in a block matrix. 




Test cases

Show results for each of the following two samples:




Sample 1 (from Wikipedia):



          ┌   ┐     ┌   ┐     ┌           ┐
          │1 2│     │0 5│     │ 0  5  0 10│
          │3 4│  x  │6 7│  =  │ 6  7 12 14│
	  └   ┘     └   ┘     │ 0 15  0 20│
	                      │18 21 24 28│
                              └           ┘ 

Sample 2:

          ┌     ┐     ┌       ┐     ┌                       ┐       
          │0 1 0│     │1 1 1 1│     │0 0 0 0 1 1 1 1 0 0 0 0│
          │1 1 1│  x  │1 0 0 1│  =  │0 0 0 0 1 0 0 1 0 0 0 0│
          │0 1 0│     │1 1 1 1│     │0 0 0 0 1 1 1 1 0 0 0 0│
	  └     ┘     └       ┘     │1 1 1 1 1 1 1 1 1 1 1 1│
                                    │1 0 0 1 1 0 0 1 1 0 0 1│
                                    │1 1 1 1 1 1 1 1 1 1 1 1│
                                    │0 0 0 0 1 1 1 1 0 0 0 0│
                                    │0 0 0 0 1 0 0 1 0 0 0 0│
                                    │0 0 0 0 1 1 1 1 0 0 0 0│
                                    └                       ┘



See implementations and results below in JavaScript and PARI/GP languages.



Related task

  Kronecker product based fractals. 


#lang typed/racket/base
 
(require math/array
         math/matrix
         racket/match)
 
(define-type (M A) (Matrix A))
 
(define #:forall (A B C) (general-⊗ [m1 : (M A)] [m2 : (M B)] [× : (A B -> C)]) : (M C)
  (match-let* ((`(#(,rs1 ,cs1) . #(,rs2 ,cs2)) (cons (array-shape m1) (array-shape m2)))
               (rs (* rs1 rs2))
               (cs (* cs1 cs2)))
    (for*/matrix: rs cs ((r (in-range rs)) (c (in-range cs))) : C
      (let-values (((rq rr) (quotient/remainder r rs2))
                   ((cq cr) (quotient/remainder c cs2)))
        (× (array-ref m1 (vector rq cq)) (array-ref m2 (vector rr cr)))))))
 
;; Narrow to Number
(define (Kronecker-product [m1 : (M Number)] [m2 : (M Number)]) (general-⊗ m1 m2 *))
 
;; ---------------------------------------------------------------------------------------------------
(module+ test
  (Kronecker-product (matrix [[1 2]
                              [3 4]])
                     (matrix [[0 5]
                              [6 7]]))
 
  (Kronecker-product (matrix [[0 1 0]
                              [1 1 1]
                              [0 1 0]])
                     (matrix [[1 1 1 1]
                              [1 0 0 1]
                              [1 1 1 1]])))