Three hundred lines of Java per day (08 days, code implementation of matrix multiplication)
Note: here are the synchronous notes and records of JAVA self-study and understanding. If you have any questions, please correct them
1, Connotation of matrix multiplication
First, we need to have a basic understanding of matrix multiplication. Although we may have learned this very basic content in the online generation at the undergraduate stage, we might as well say a few more words for code implementation today.
The so-called matrix multiplication is an operation of the relationship between the rows and columns of two matrices with a certain relationship. Generally speaking, the number of columns of the left multiplication matrix is equal to the number of rows of the right multiplication matrix. Then, during the operation, the left matrix is extracted row by row, multiplied column by column with the right multiplication matrix, and then added. We use the expression of the graph to illustrate the oral cavity:
Here we define a matrix as M × N matrix, B matrix is n × A matrix of p, naturally C is m × Matrix of p. The calculation of each element in the C matrix can be defined as follows:
The elements in each individual C are obtained by the interaction of a row and column determined in matrix A and matrix B.
C[1][1] in the figure can be written according to this theory:
C[1][1] = A[1][0]*B[0][1] + A[1][1]*B[1][1] + A[1][2]*B[2][1] + A[1][3]*B[3][1] + A[1][4]*B[4][1]
It can be seen that row i of matrix A and column j of matrix B can jointly determine the (i,j) elements of matrix C, as shown in the following figure (from the Internet):
2, Code logic
·Overhead analysis
Because the set constructed by all rows of matrix A and the set composed of all columns of matrix B are calculated one by one, the natural matching overhead is O(n2). Moreover, the operation is the summation of several products, and the process of this product also needs a loop in the code. Therefore, intuitively, we need three-layer loops to complete the program, and the basic complexity is O(n3)
·Core code
After the above analysis, it is basically determined that the core code is a three-tier for loop, but the difficulty in thinking is to clear the upper limit of the loop and the distinction between rows and columns.
At present, it is assumed that the A matrix is m × N, B matrix is n × p
Through for (int i = 0; I < m; I + +) {A [i] [...]} Get A line by line
By for (int j = 0; I < p; I + +) {B [...] [j] } get column by column of B
The product of these rows and columns requires n times of sum, so the sum is completed through for (int k = 0; K < n; K + +) {}
To sum up, complete the core code:
int[][] resultMatrix = new int[m][p]; for (int i = 0; i < m; i++) { for (int j = 0; j < p; j++) { for (int k = 0; k < n; k++) { resultMatrix[i][j] += paraFirstMatrix[i][k] * paraSecondMatrix[k][j]; } // Of for k } // Of for j } // Of for i
3, Data test
This time, we will test the multiplication of any two matrices and the operation of matrix self multiplication. Of course, because matrix multiplication has certain row and column restrictions, we need to add the judgment of illegal cases to improve the robustness of the function.
The code is as follows:
package basic; import java.util.Arrays; /** * This is the eighth code. Names and comments should follow my style strictly. * * @author Xingyi Zhang 1328365276@qq.com */ public class MatrixMultiplication { /** ********************* * The entrance of the program. * * @param args Not used now. ********************* */ public static void main(String args[]) { matrixMultiplicationTest(); }// Of main /** ********************* * Matrix multiplication. The columns of the first matrix should be equal to the * rows of the second one. * * @param paraFirstMatrix The first matrix. * @param paraSecondMatrix The second matrix. * @return The result matrix. ********************* */ public static int[][] multiplication(int[][] paraFirstMatrix, int[][] paraSecondMatrix) { int m = paraFirstMatrix.length; int n = paraFirstMatrix[0].length; int p = paraSecondMatrix[0].length; // Step 1. Dimension check. if (paraSecondMatrix.length != n) { System.out.println("The two matrices cannot be multiplied."); return null; } // Of if // Step 2. The loop. int[][] resultMatrix = new int[m][p]; for (int i = 0; i < m; i++) { for (int j = 0; j < p; j++) { for (int k = 0; k < n; k++) { resultMatrix[i][j] += paraFirstMatrix[i][k] * paraSecondMatrix[k][j]; } // Of for k } // Of for j } // Of for i return resultMatrix; }// Of multiplication /** ********************* * Unit test for respective method. ********************* */ public static void matrixMultiplicationTest() { int[][] tempFirstMatrix = new int[2][3]; for (int i = 0; i < tempFirstMatrix.length; i++) { for (int j = 0; j < tempFirstMatrix[0].length; j++) { tempFirstMatrix[i][j] = i + j; } // Of for j } // Of for i System.out.println("The first matrix is: \r\n" + Arrays.deepToString(tempFirstMatrix)); int[][] tempSecondMatrix = new int[3][2]; for (int i = 0; i < tempSecondMatrix.length; i++) { for (int j = 0; j < tempSecondMatrix[0].length; j++) { tempSecondMatrix[i][j] = i + j; } // Of for j } // Of for i System.out.println("The second matrix is: \r\n" + Arrays.deepToString(tempSecondMatrix)); int[][] tempThirdMatrix = multiplication(tempFirstMatrix, tempSecondMatrix); System.out.println("The third matrix is: \r\n" + Arrays.deepToString(tempThirdMatrix)); System.out.println("Trying to multiply the first matrix with itself.\r\n"); tempThirdMatrix = multiplication(tempFirstMatrix, tempFirstMatrix); System.out.println("The result matrix is: \r\n" + Arrays.deepToString(tempThirdMatrix)); }// Of matrixMultiplicationTest }// Of matrixMultiplication
The results are shown as follows:
At the beginning, the expected result is obtained by multiplying the two matrices, but matrix 1 cannot multiply itself because it is not a square matrix, so an error prompt is thrown.
Summary and feelings
The operation of matrix is very rich. In the follow-up study of computer, we will still see matrix in many places. However, since this article is mainly the basic notes for individuals to learn java, there is no more in-depth entanglement with various other applications of matrix.
Compared with yesterday's basic matrix application, the difficulty of matrix multiplication has been slightly improved today. Perhaps when we calculate matrix multiplication by hand, because the image of the matrix is intuitive and the positional relationship between the two matrices is clear at a glance, we will not think it is a very difficult process by using people's basic spatial ability.
However, when the actual application is in code simulation, it will fall into "how does my for loop loop loop? How many times does it loop? How does this for loop iterate? Is it row or column now?" In many questions.
Therefore, in order to correctly connect mathematical problems with code problems, we need to deeply deconstruct the contents that are usually simple, and use mathematical methods to model and analyze the problems. For example, according to the source of each element of C matrix, which row and column are determined; The matrix multiplication formula is constructed to analyze how many cycles there are, so as to determine the iterative scheme and complexity of the for cycle; Or just take a case and reconstruct the code from special to general through the particularity of the case.
In short, to really use code to solve a practical problem, it is not enough to have a flexible mathematical thinking mind, but also to have the ability to use code to simulate mathematical solutions. Naturally, if you only have perfect code thinking, if you don't know how to solve mathematical problems, you belong to a person who knows all kinds of traffic rules, but doesn't even know how to start the car.
[for example, DP: dynamic programming, one of my most troublesome algorithms, is very easy to program as long as a mathematical model of state transformation of dynamic programming is correctly established, but this is really... Very difficult to build]