Java matrix class

This is an improved version of the Java matrix classes previously described and given in:

https://kyaw.xyz/2017/12/10/comprehensive-pure-java-matrix-classes-especially-computer-vision-machine-learning-ai-applications/

and

https://github.com/Kyaw-Kyaw-Htike/Comprehensive-pure-Java-matrix-classes-for-Computer-Vision-Machine-Learning-and-AI-applications

The code for the improved version can be found at:

https://github.com/Kyaw-Kyaw-Htike/Java-matrix-class

The documentation for some of the constructors can be found below. The rest of the documentation may follow later if time permits.

Code:

int nrows = 8;
int ncols = 6;
int nchannels = 3;
double[] arr = new double[nrows*ncols*nchannels];
int count = 0;
for(int i=0; i<nrows; i++)
 for(int j=0; j<ncols; j++)
  for(int k=0; k<nchannels; k++)
 arr[count++] = count;
 
Matk m = new Matk(arr, true, nrows, ncols, nchannels);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 9.0, 17.0, 25.0, 33.0, 41.0;
2.0, 10.0, 18.0, 26.0, 34.0, 42.0;
3.0, 11.0, 19.0, 27.0, 35.0, 43.0;
4.0, 12.0, 20.0, 28.0, 36.0, 44.0;
5.0, 13.0, 21.0, 29.0, 37.0, 45.0;
6.0, 14.0, 22.0, 30.0, 38.0, 46.0;
7.0, 15.0, 23.0, 31.0, 39.0, 47.0;
8.0, 16.0, 24.0, 32.0, 40.0, 48.0;
];
mat(:,:,2)=[
49.0, 57.0, 65.0, 73.0, 81.0, 89.0;
50.0, 58.0, 66.0, 74.0, 82.0, 90.0;
51.0, 59.0, 67.0, 75.0, 83.0, 91.0;
52.0, 60.0, 68.0, 76.0, 84.0, 92.0;
53.0, 61.0, 69.0, 77.0, 85.0, 93.0;
54.0, 62.0, 70.0, 78.0, 86.0, 94.0;
55.0, 63.0, 71.0, 79.0, 87.0, 95.0;
56.0, 64.0, 72.0, 80.0, 88.0, 96.0;
];
mat(:,:,3)=[
97.0, 105.0, 113.0, 121.0, 129.0, 137.0;
98.0, 106.0, 114.0, 122.0, 130.0, 138.0;
99.0, 107.0, 115.0, 123.0, 131.0, 139.0;
100.0, 108.0, 116.0, 124.0, 132.0, 140.0;
101.0, 109.0, 117.0, 125.0, 133.0, 141.0;
102.0, 110.0, 118.0, 126.0, 134.0, 142.0;
103.0, 111.0, 119.0, 127.0, 135.0, 143.0;
104.0, 112.0, 120.0, 128.0, 136.0, 144.0;
];
=========== Matrix printed ===========

Code:

 int nrows = 8;
 int ncols = 6;
 int nchannels = 3;
 double[] arr = new double[nrows*ncols*nchannels];
 int count = 0;
 for(int i=0; i<nrows; i++)
  for(int j=0; j<ncols; j++)
   for(int k=0; k<nchannels; k++)
 arr[count++] = count;
 
 Matk m = new Matk(arr, false, nrows, ncols, nchannels);
 m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 4.0, 7.0, 10.0, 13.0, 16.0;
19.0, 22.0, 25.0, 28.0, 31.0, 34.0;
37.0, 40.0, 43.0, 46.0, 49.0, 52.0;
55.0, 58.0, 61.0, 64.0, 67.0, 70.0;
73.0, 76.0, 79.0, 82.0, 85.0, 88.0;
91.0, 94.0, 97.0, 100.0, 103.0, 106.0;
109.0, 112.0, 115.0, 118.0, 121.0, 124.0;
127.0, 130.0, 133.0, 136.0, 139.0, 142.0;
];
mat(:,:,2)=[
2.0, 5.0, 8.0, 11.0, 14.0, 17.0;
20.0, 23.0, 26.0, 29.0, 32.0, 35.0;
38.0, 41.0, 44.0, 47.0, 50.0, 53.0;
56.0, 59.0, 62.0, 65.0, 68.0, 71.0;
74.0, 77.0, 80.0, 83.0, 86.0, 89.0;
92.0, 95.0, 98.0, 101.0, 104.0, 107.0;
110.0, 113.0, 116.0, 119.0, 122.0, 125.0;
128.0, 131.0, 134.0, 137.0, 140.0, 143.0;
];
mat(:,:,3)=[
3.0, 6.0, 9.0, 12.0, 15.0, 18.0;
21.0, 24.0, 27.0, 30.0, 33.0, 36.0;
39.0, 42.0, 45.0, 48.0, 51.0, 54.0;
57.0, 60.0, 63.0, 66.0, 69.0, 72.0;
75.0, 78.0, 81.0, 84.0, 87.0, 90.0;
93.0, 96.0, 99.0, 102.0, 105.0, 108.0;
111.0, 114.0, 117.0, 120.0, 123.0, 126.0;
129.0, 132.0, 135.0, 138.0, 141.0, 144.0;
];
=========== Matrix printed ===========

Code:

double[] arr = new double[] {1,2,3,4,5,6};
Matk m = new Matk(arr, true, 2, 3, 1);
m.print();

Output:


=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 3.0, 5.0;
2.0, 4.0, 6.0;
];
=========== Matrix printed ===========

Code:

double[] arr = new double[] {1,2,3,4,5,6};
Matk m = new Matk(arr, false, 2, 3, 1);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 2.0, 3.0;
4.0, 5.0, 6.0;
];
=========== Matrix printed ===========

Code:

double[] arr = new double[] {1,2,3,4,5,6,7,8};
Matk m = new Matk(arr, false, 2, 2, 2);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 3.0;
5.0, 7.0;
];
mat(:,:,2)=[
2.0, 4.0;
6.0, 8.0;
];
=========== Matrix printed ===========

Code:

double[] arr = new double[] {1,2,3,4,5,6,7,8};
Matk m = new Matk(arr, true, 2, 2, 2);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 3.0;
2.0, 4.0;
];
mat(:,:,2)=[
5.0, 7.0;
6.0, 8.0;
];
=========== Matrix printed ===========

Code:

int nrows = 8;
int ncols = 6;
int nchannels = 3;
float[] arr = new float[nrows*ncols*nchannels];
int count = 0;
for(int i=0; i<nrows; i++)
 for(int j=0; j<ncols; j++)
 for(int k=0; k<nchannels; k++)
 arr[count++] = count;
 
Matk m = new Matk(arr, true, nrows, ncols, nchannels);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 9.0, 17.0, 25.0, 33.0, 41.0;
2.0, 10.0, 18.0, 26.0, 34.0, 42.0;
3.0, 11.0, 19.0, 27.0, 35.0, 43.0;
4.0, 12.0, 20.0, 28.0, 36.0, 44.0;
5.0, 13.0, 21.0, 29.0, 37.0, 45.0;
6.0, 14.0, 22.0, 30.0, 38.0, 46.0;
7.0, 15.0, 23.0, 31.0, 39.0, 47.0;
8.0, 16.0, 24.0, 32.0, 40.0, 48.0;
];
mat(:,:,2)=[
49.0, 57.0, 65.0, 73.0, 81.0, 89.0;
50.0, 58.0, 66.0, 74.0, 82.0, 90.0;
51.0, 59.0, 67.0, 75.0, 83.0, 91.0;
52.0, 60.0, 68.0, 76.0, 84.0, 92.0;
53.0, 61.0, 69.0, 77.0, 85.0, 93.0;
54.0, 62.0, 70.0, 78.0, 86.0, 94.0;
55.0, 63.0, 71.0, 79.0, 87.0, 95.0;
56.0, 64.0, 72.0, 80.0, 88.0, 96.0;
];
mat(:,:,3)=[
97.0, 105.0, 113.0, 121.0, 129.0, 137.0;
98.0, 106.0, 114.0, 122.0, 130.0, 138.0;
99.0, 107.0, 115.0, 123.0, 131.0, 139.0;
100.0, 108.0, 116.0, 124.0, 132.0, 140.0;
101.0, 109.0, 117.0, 125.0, 133.0, 141.0;
102.0, 110.0, 118.0, 126.0, 134.0, 142.0;
103.0, 111.0, 119.0, 127.0, 135.0, 143.0;
104.0, 112.0, 120.0, 128.0, 136.0, 144.0;
];
=========== Matrix printed ===========

Code:

int nrows = 3;
int ncols = 4;
int nchannels = 1;
int[] arr = new int[nrows*ncols*nchannels];
int count = 0;
for(int i=0; i<nrows; i++)
 for(int j=0; j<ncols; j++)
 for(int k=0; k<nchannels; k++)
 arr[count++] = count;
 
Matk m = new Matk(arr, true, nrows, ncols, nchannels);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 4.0, 7.0, 10.0;
2.0, 5.0, 8.0, 11.0;
3.0, 6.0, 9.0, 12.0;
];
=========== Matrix printed ===========

Code:

int nrows = 2;
int ncols = 4;
int nchannels = 1;
byte[] arr = new byte[nrows*ncols*nchannels];
int count = 0;
for(int i=0; i<nrows; i++)
 for(int j=0; j<ncols; j++)
 for(int k=0; k<nchannels; k++)
 arr[count++] = (byte)count;
 
Matk m = new Matk(arr, false, nrows, ncols, nchannels);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 2.0, 3.0, 4.0;
5.0, 6.0, 7.0, 8.0;
];
=========== Matrix printed ===========

Code:

int nrows = 2;
int ncols = 3;
int nchannels = 1;
double[] arr = new double[nrows*ncols*nchannels];
int count = 0;
for(int i=0; i<nrows; i++)
 for(int j=0; j<ncols; j++)
 for(int k=0; k<nchannels; k++)
 arr[count++] = count;
 
Matk m = new Matk(arr);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0;
2.0;
3.0;
4.0;
5.0;
6.0;
];
=========== Matrix printed ===========

Code:

int nrows = 2;
int ncols = 2;
int nchannels = 1;
float[] arr = new float[nrows*ncols*nchannels];
int count = 0;
for(int i=0; i<nrows; i++)
 for(int j=0; j<ncols; j++)
 for(int k=0; k<nchannels; k++)
 arr[count++] = count;
 
Matk m = new Matk(arr);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0;
2.0;
3.0;
4.0;
];
=========== Matrix printed ===========

Code:

int nrows = 1;
int ncols = 4;
int nchannels = 2;
int[] arr = new int[nrows*ncols*nchannels];
int count = 0;
for(int i=0; i<nrows; i++)
 for(int j=0; j<ncols; j++)
 for(int k=0; k<nchannels; k++)
 arr[count++] = count;
 
Matk m = new Matk(arr);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0;
2.0;
3.0;
4.0;
5.0;
6.0;
7.0;
8.0;
];
=========== Matrix printed ===========

Code:

int nrows = 2;
int ncols = 3;
int nchannels = 1;
byte[] arr = new byte[nrows*ncols*nchannels];
int count = 0;
for(int i=0; i<nrows; i++)
 for(int j=0; j<ncols; j++)
 for(int k=0; k<nchannels; k++)
 arr[count++] = (byte)count;
 
Matk m = new Matk(arr);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0;
2.0;
3.0;
4.0;
5.0;
6.0;
];
=========== Matrix printed ===========

Code:

Create a matrix of zeros with 2 channels.

Matk m = new Matk(2, 3, 2);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
0.0, 0.0, 0.0;
0.0, 0.0, 0.0;
];
mat(:,:,2)=[
0.0, 0.0, 0.0;
0.0, 0.0, 0.0;
];
=========== Matrix printed ===========

Create a matrix of zeros (1 channel).

Code:

Matk m = new Matk(3, 2);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
0.0, 0.0;
0.0, 0.0;
0.0, 0.0;
];
=========== Matrix printed ===========

Create a matrix of zeros (1 channel) with channel information being explicitly specified.

Code:

Matk m = new Matk(3, 2, 1);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
0.0, 0.0;
0.0, 0.0;
0.0, 0.0;
];
=========== Matrix printed ===========

Create a column vector of zeros with length equal to 3.

Code:

Matk m = new Matk(3);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
0.0;
0.0;
0.0;
];
=========== Matrix printed ===========

Create a matrix from Java 2D double array.

Code:

double[][] arr = new double[][] {{1,2},{3,4}}; 
Matk m = new Matk(arr);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 2.0;
3.0, 4.0;
];
=========== Matrix printed ===========

Create a matrix from Java 3D double array.

Code:

double[][][] arr = new double[][][] {{{1,2},{3,4}}, {{5,6},{7,8}}}; 
Matk m = new Matk(arr);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 2.0;
3.0, 4.0;
];
mat(:,:,2)=[
5.0, 6.0;
7.0, 8.0;
];
=========== Matrix printed ===========

Create a matrix from Java 3D float array.

Code:

float[][][] arr = new float[][][] {{{1,2},{3,4}}, {{5,6},{7,8}}}; 
Matk m = new Matk(arr);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 2.0;
3.0, 4.0;
];
mat(:,:,2)=[
5.0, 6.0;
7.0, 8.0;
];
=========== Matrix printed ===========

Create a matrix from Java 3D int array.

Code:

int[][][] arr = new int[][][] {{{1,2},{3,4}}, {{5,6},{7,8}}}; 
Matk m = new Matk(arr);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 2.0;
3.0, 4.0;
];
mat(:,:,2)=[
5.0, 6.0;
7.0, 8.0;
];
=========== Matrix printed ===========

Create a matrix using Java 2D int array.

Code:

int[][] arr = new int[][] {{1,2},{3,4}}; 
Matk m = new Matk(arr);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 2.0;
3.0, 4.0;
];
=========== Matrix printed ===========

Create a matrix using Java 2D float array.

Code:

float[][] arr = new float[][] {{1,2},{3,4}}; 
Matk m = new Matk(arr);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 2.0;
3.0, 4.0;
];
=========== Matrix printed ===========

Create a matrix from Java List of Floats.

Code:

List<Float&gt; data = new ArrayList<&gt;();
for(int i=0; i<12; i++) data.add((float)i);
Matk m = new Matk(data, true, 3, 4, 1);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
0.0, 3.0, 6.0, 9.0;
1.0, 4.0, 7.0, 10.0;
2.0, 5.0, 8.0, 11.0;
];
=========== Matrix printed ===========

Create a matrix from Java List of Integers.

Code:

List<Integer&gt; data = new ArrayList<&gt;();
for(int i=0; i<12; i++) data.add(i);
Matk m = new Matk(data, false, 3, 4, 1);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
0.0, 1.0, 2.0, 3.0;
4.0, 5.0, 6.0, 7.0;
8.0, 9.0, 10.0, 11.0;
];
=========== Matrix printed ===========

Create a column vector from a Java List.

Code:

List<Integer&gt; data = new ArrayList<&gt;();
for(int i=0; i<4; i++) data.add(i);
Matk m = new Matk(data);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
0.0;
1.0;
2.0;
3.0;
];
=========== Matrix printed ===========

Create a matrix from Number array.

Code:

Integer[] data = new Integer[6];
for(int i=0; i<6; i++) data[i] = i;
Matk m = new Matk(data, false, 2, 3, 1);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
0.0, 1.0, 2.0;
3.0, 4.0, 5.0;
];
=========== Matrix printed ===========

Create a matrix from Number array.

Code:

Float[] data = new Float[6];
for(int i=0; i<6; i++) data[i] = (float)i;
Matk m = new Matk(data, true, 2, 3, 1);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
0.0, 2.0, 4.0;
1.0, 3.0, 5.0;
];
=========== Matrix printed ===========

Create a column vector from Number Array.

Code:

Double[] data = new Double[3];
for(int i=0; i<3; i++) data[i] = (double)i;
Matk m = new Matk(data);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
0.0;
1.0;
2.0;
];
=========== Matrix printed ===========

Create a matrix from Apache Common Math RealMatrix matrix.

Code:

double data[][] = new double[][] {{1,2,3},{4,5,6}};
RealMatrix mat = MatrixUtils.createRealMatrix(data);
Matk m = new Matk(mat);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 2.0, 3.0;
4.0, 5.0, 6.0;
];
=========== Matrix printed ===========

Creating a multi-channel matrix from an array of Apache Common Math RealMatrix matrices.

Code:

double data[][] = new double[][] {{1,2,3},{4,5,6}};
RealMatrix mat = MatrixUtils.createRealMatrix(data);
Matk m = new Matk(new RealMatrix[] {mat, mat, mat});
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 2.0, 3.0;
4.0, 5.0, 6.0;
];
mat(:,:,2)=[
1.0, 2.0, 3.0;
4.0, 5.0, 6.0;
];
mat(:,:,3)=[
1.0, 2.0, 3.0;
4.0, 5.0, 6.0;
];
=========== Matrix printed ===========

Creating a multi-channel matrix from a List of Apache Common Math RealMatrix matrices.

Code:

double data[][] = new double[][] {{1,2,3},{4,5,6}};
RealMatrix mat = MatrixUtils.createRealMatrix(data);
List<RealMatrix&gt; matList = new ArrayList<&gt;();
matList.add(mat);
matList.add(mat.add(mat));
matList.add(mat.scalarMultiply(4));
Matk m = new Matk(matList, true);
m.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
1.0, 2.0, 3.0;
4.0, 5.0, 6.0;
];
mat(:,:,2)=[
2.0, 4.0, 6.0;
8.0, 10.0, 12.0;
];
mat(:,:,3)=[
4.0, 8.0, 12.0;
16.0, 20.0, 24.0;
];
=========== Matrix printed ===========

Creating a matrix (representing an image) from a BufferedImage object.

Code:

BufferedImage bimg;
try {
 bimg = ImageIO.read(new File("somePicture.png"));
} catch (IOException e) {
 throw new IllegalArgumentException("ERROR: Could not read image file.");
} 
Matk img = new Matk(bimg);
img.imshow();

Output:

The image is shown on a Jframe.

Creating a matrix (representing an image) from a BufferedImage object.

Code:

BufferedImage bimg = Matk.load_image_file_as_BufferedImage("Some_picture.png");
Matk img = new Matk(bimg);
img.imshow();

Output:

The image is shown on a Jframe.

Creating a matrix (representing an image) from an image file path.

Code:

Matk img = new Matk("some_picture.png");
img.imshow();

Output:

The image is shown on a Jframe.

Serializing and deserializing the matrix.

Code:

Matk m = Matk.randi(2, 3, 1, 5, 10);
m.print();
m.save("my_file.dat");
Matk m2 = Matk.load("my_file.dat");
m2.print();

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
6.0, 6.0, 7.0;
9.0, 9.0, 8.0;
];
=========== Matrix printed ===========
=========== Printing matrix ===========
mat(:,:,1)=[
6.0, 6.0, 7.0;
9.0, 9.0, 8.0;
];
=========== Matrix printed ===========

Saving the matrix as a linear array in a text file.

Code:

Matk m = Matk.randi(2, 3, 2, 5, 10);
m.print();
m.save_data_txt("theArray.txt");

Output:

=========== Printing matrix ===========
mat(:,:,1)=[
9.0, 8.0, 9.0;
9.0, 7.0, 10.0;
];
mat(:,:,2)=[
9.0, 6.0, 8.0;
10.0, 6.0, 6.0;
];
=========== Matrix printed ===========

Inside the text file "theArray.txt":

Matkc matrix: nrows = 2, ncols = 3, nchannels = 2
9.0
9.0
8.0
7.0
9.0
10.0
9.0
10.0
6.0
6.0
8.0
6.0