Wednesday, January 4, 2012

KRON: Calculating Kronecker Products of Two Matrices with C++ and Fortran 90


Purpose
  • The library "kron" provides generic C++ and Fortran 90 codes for calculating the Kronecker product of two matrices of any size. It does not require any installation of other libraries. In C++, matrices are stored as 'column major ordered' vectors. In Fortran 90, matrices are stored as 2-D arrays.

Specifications
  • Name: kron.
  • Author: Feng Chen.
  • Version: 2.8
  • Language: C++ and Fortran 90.

Simple Example
  • Given matrices: \begin{equation} A = \left[ \begin{array}{ccc} 1 & 2 & 3 \\ 2 & 4 & 6 \end{array} \right], \quad B = \left[ \begin{array}{cc} 2 & 3 \\ 3 & 4 \end{array} \right] \end{equation}
  • Results: \begin{equation} C = A \otimes B = \left[ \begin{array}{cccccc} 2 & 3 & 4 & 6 & 6 & 9 \\ 3 & 4 & 6 & 8 & 9 & 12 \\ 4 & 6 & 8 & 12 & 12 & 18 \\ 6 & 8 & 12 & 16 & 18 & 24 \end{array} \right] \end{equation}

Quick Start
  • Compiling and running:
    gfortran tst_Kronecker.f90 Kronecker.f90
    
  • Output:
     
     ---A---
     1.0     2.0     3.0    
     2.0     4.0     6.0    
     ---B---
     2.0     3.0    
     3.0     4.0    
     ---C---
     2.0     3.0     4.0     6.0     6.0     9.0    
     3.0     4.0     6.0     8.0     9.0     12.    
     4.0     6.0     8.0     12.     12.     18.    
     6.0     8.0     12.     16.     18.     24.    
    
  • CPU: Genuine Intel(R) CPU T2060 @ 1.60GHz.
  • OS: Ubuntu 10.10.
  • Release: gcc version 4.4.5.

References
  • Kronecker product. Link.

Code Highlights
    
    //
    // calculate the Kronecker product of two matrices of any size:
    //     C = a*C + b*(A kron B);
    //
    // PARAMETERS:
    //    ma - number of rows of A.
    //    na - number of columns of A.
    //    mb - number of rows of B.
    //    nb - number of columns of B.
    //    A - matrix 'A', column major ordering, stored as a 1-D vector.
    //    B - matrix 'B', column major ordering, stored as a 1-D vector.
    //    C - matrix 'a*C + b*(A kron B)', column major ordering, stored as a 1-D vector.
    //
    // WARNINGS:
    //    1. Every matrix is stored in a column major fashion, in order to be compatible with Fortran.
    //       For row major ordering vectors, users have to switch the row and column indicies.
    //    2. Every matrix is stored as a 1-D vector instead of a pointer to pointers.
    //
    
    void Kronecker(const int ma, const int na, const int mb, const int nb,
     const double a, const double b, const double *A, const double *B, double *C){
    
     int i, j, I, J, M, N;
     double c;
     M = ma*mb;
     N = na*nb;
     for(j=0; j < na; j++){
      for(i=0; i < ma; i++){
       I = i*mb;
       J = j*nb;
       c = b*A[cm(i,j,ma)];
       assign_matrix_block(I, J, mb, nb, M, N, a, c, B, C);
      }
     }
    }