Task: Kronecker product


C++: #include <cassert>
#include <iomanip>
#include <iostream>
#include <vector>

template <typename scalar_type> class matrix {
public:
    matrix(size_t rows, size_t columns)
        : rows_(rows), columns_(columns), elements_(rows * columns) {}
    matrix(size_t rows, size_t columns,
        const std::initializer_list<std::initializer_list<scalar_type>>& values)
        : rows_(rows), columns_(columns), elements_(rows * columns) {
        assert(values.size() <= rows_);
        size_t i = 0;
        for (const auto& row : values) {
            assert(row.size() <= columns_);
            std::copy(begin(row), end(row), &elements_[i]);
            i += columns_;
        }
    }
    size_t rows() const { return rows_; }
    size_t columns() const { return columns_; }

    const scalar_type& operator()(size_t row, size_t column) const {
        assert(row < rows_);
        assert(column < columns_);
        return elements_[row * columns_ + column];
    }
    scalar_type& operator()(size_t row, size_t column) {
        assert(row < rows_);
        assert(column < columns_);
        return elements_[row * columns_ + column];
    }
private:
    size_t rows_;
    size_t columns_;
    std::vector<scalar_type> elements_;
};


template <typename scalar_type>
matrix<scalar_type> kronecker_product(const matrix<scalar_type>& a,
                                      const matrix<scalar_type>& b) {
    size_t arows = a.rows();
    size_t acolumns = a.columns();
    size_t brows = b.rows();
    size_t bcolumns = b.columns();
    matrix<scalar_type> c(arows * brows, acolumns * bcolumns);
    for (size_t i = 0; i < arows; ++i)
        for (size_t j = 0; j < acolumns; ++j)
            for (size_t k = 0; k < brows; ++k)
                for (size_t l = 0; l < bcolumns; ++l)
                    c(i*brows + k, j*bcolumns + l) = a(i, j) * b(k, l);
    return c;
}

template <typename scalar_type>
void print(std::wostream& out, const matrix<scalar_type>& a) {
    const wchar_t* box_top_left = L"\x250c";
    const wchar_t* box_top_right = L"\x2510";
    const wchar_t* box_bottom_left = L"\x2514";
    const wchar_t* box_bottom_right = L"\x2518";
    const wchar_t* box_vertical = L"\x2502";
    const wchar_t nl = L'\n';
    const wchar_t space = L' ';
    const int width = 2;

    size_t rows = a.rows(), columns = a.columns();
    std::wstring spaces((width + 1) * columns, space);
    out << box_top_left << spaces << box_top_right << nl;
    for (size_t row = 0; row < rows; ++row) {
        out << box_vertical;
        for (size_t column = 0; column < columns; ++column)
            out << std::setw(width) << a(row, column) << space;
        out << box_vertical << nl;
    }
    out << box_bottom_left << spaces << box_bottom_right << nl;
}

void test1() {
    matrix<int> matrix1(2, 2, {{1,2}, {3,4}});
    matrix<int> matrix2(2, 2, {{0,5}, {6,7}});
    std::wcout << L"Test case 1:\n";
    print(std::wcout, kronecker_product(matrix1, matrix2));
}

void test2() {
    matrix<int> matrix1(3, 3, {{0,1,0}, {1,1,1}, {0,1,0}});
    matrix<int> matrix2(3, 4, {{1,1,1,1}, {1,0,0,1}, {1,1,1,1}});
    std::wcout << L"Test case 2:\n";
    print(std::wcout, kronecker_product(matrix1, matrix2));
}

int main() {
    std::wcout.imbue(std::locale(""));
    test1();
    test2();
    return 0;
}




Java: package kronecker;


public class Product {
  
  public static int[][] product(final int[][] a, final int[][] b) {
    
    
    final int[][] c = new int[a.length*b.length][];
    
    
    for (int ix = 0; ix < c.length; ix++) {
      final int num_cols = a[0].length*b[0].length;
      c[ix] = new int[num_cols];
    }
    
    
    for (int ia = 0; ia < a.length; ia++) {
      for (int ja = 0; ja < a[ia].length; ja++) {
        
        for (int ib = 0; ib < b.length; ib++) {
          for (int jb = 0; jb < b[ib].length; jb++) {
             c[b.length*ia+ib][b[ib].length*ja+jb] = a[ia][ja] * b[ib][jb];
          }
        }
      }
    }

    
    return c;
  }

  
  public static void print_matrix(final int[][] m) {
    
    
    
    
    final String[][] sts = new String[m.length][];
    int max_length = 0;  
    for (int im = 0; im < m.length; im++) {
      sts[im] = new String[m[im].length];
      for (int jm = 0; jm < m[im].length; jm++) {
        final String st = String.valueOf(m[im][jm]);
        if (st.length() > max_length) {
          max_length = st.length();
        }
        sts[im][jm] = st;
      }
    }

    
    
    
    final String format = String.format("%%%ds", max_length);
    for (int im = 0; im < m.length; im++) {
      System.out.print("|");
      
      for (int jm = 0; jm < m[im].length - 1; jm++) {
        System.out.format(format, m[im][jm]);
        System.out.print(" ");
      }
      System.out.format(format, m[im][m[im].length - 1]);
      System.out.println("|");
    }
  }

  
  private static void test(final int[][] a, final int[][] b) {
    
    System.out.println("Testing Kronecker product");
    System.out.println("Size of matrix a: " + a.length + " by " + a[0].length);
    System.out.println("Matrix a:");
    print_matrix(a);
    System.out.println("Size of matrix b: " + b.length + " by " + b[0].length);
    System.out.println("Matrix b:");
    print_matrix(b);
    System.out.println("Calculating matrix c as Kronecker product");
    final int[][] c = product(a, b);
    System.out.println("Size of matrix c: " + c.length + " by " + c[0].length);
    System.out.println("Matrix c:");
    print_matrix(c);
  }

  
  private static void test1() {
    
    final int[][] a = new int[2][];  
    a[0] = new int[]{1, 2};
    a[1] = new int[]{3, 4};
    final int[][] b = new int[2][];  
    b[0] = new int[]{0, 5};
    b[1] = new int[]{6, 7};
    
    test(a, b);
  }

  
  private static void test2() {
    
    final int[][] a = new int[3][];  
    a[0] = new int[]{0, 1, 0};
    a[1] = new int[]{1, 1, 1};
    a[2] = new int[]{0, 1, 0};
    final int[][] b = new int[3][];  
    b[0] = new int[]{1, 1, 1, 1};
    b[1] = new int[]{1, 0, 0, 1};
    b[2] = new int[]{1, 1, 1, 1};
    
    test(a, b);
  }

  
  public static void main(final String[] args) {
    
    test1();
    test2();
  }

}