1. Preface to the recent parallel computing work when there is a problem is to let the parallel way to the inverse of a matrix, the approximate step of this experiment is to write a well-written matrix file (a certain format) as input, using a certain algorithm to find the inverse matrix and then output in the form of a file. Because it is difficult to realize the superiority of parallel mode when using parallel method for numerical calculation, if data size is not large enough, it becomes one of the key points of this experiment to have a large data set. About datasets This matter, the great gods have used matlab to create a random two-dimensional array file, but for me who will not use MATLAB (a mathematical slag), want to get a large-scale matrix file is really very difficult ah! 2. Key issues and solutions some of the same shoes may say: Randomly generated a two-dimensional array is not simple, a few lines of code things. However, please note that the matrices we need here must be random and reversible! The matrix reversibility is to satisfy certain conditions, but the randomly generated matrix may not be a invertible matrix at all, resulting in an inverse matrix that cannot be calculated: The input is this:
After it is reversed, it becomes this:
can see my inverse program error, display not a number, this is because this randomly generated array is irreversible. So I wanted to write a program that would generate a square of any size. First we want to generate a reversible square of any size, and then write it to the file in a certain format. In fact, there is only one difficulty, that is how to construct a reversible matrix. I found two solutions on the Internet: (1) after generating the random number matrix, it is determined whether it is reversible according to the determinant value or rank condition. (2) First, the unit matrix is given a finite number of elementary line transformations. With bad luck, the first way is expensive, so we choose the second way. However, in the second way, there are the following problems: (1) How to make the elementary line transformation to get the final result right (2) How to make the matrix after the elementary transformation look more symmetrical below I'll explain what the two points mean. The so-called correct is not in the calculation of cross-border, overflow, etc., because when the number in the matrix is relatively large, the result of elementary row transformation may make some numbers too large to exceed the accuracy of the computer can be caused by overflow The so-called symmetry means that a large matrix does not appear to be full of 0 or a large crowd is 0 another part nonzero. Of course, for the matrix inversion, the 1th is to be satisfied, the 2nd we take for a moment as a function of demand. Well, let me introduce my ideas. When we get the unit matrix, we have to consider the elementary line transformation, nothing more than to exchange two lines of position, all the elements in a row multiplied by a number, there is a row of all the elements of the same multiply one number and then add to another line, my idea is to randomly select a main row (the number of lines of course to 0~n-1 between , n is the number of rows of a square, and then a random number of row transformations, but the row transformation I only take "multiply all the elements in a row by one count and then add to another line" this way, in each elementary row transformation to perform multiplication and addition to detect whether the results will overflow. 3. Code implementation of the overall framework of the 3.1 program this program, the user will be prompted to enter the number of rows of the matrix, and then will be for matrices (two-dimensional array) to apply for memory, here I use a dynamic array of the way to store, it is important to note that the array itself is a int** type, that is, pointer pointers, In the first dimension of the array is a series of int pointers, variables of type int*, and variables of type int stored in their second dimension. After the memory request for the matrix is complete, the user can choose to generate only the unit matrix (input 0) or the invertible matrix of the non-unit matrix (input 1), because the logic of generating the invertible matrix of a non-unit matrix contains the logic to generate the unit matrix, So we briefly describe the process of generating a invertible matrix of a non-unit matrix: (1) Generating a unit matrix (2) generating a matrix of non-unit matrices based on the unit matrix (3) Writing the generated matrices to a file these steps are described in detail in the following subsections.
int main (int argc, char* argv[]) {int k = 0; int n = 0; int flag = 0; int** Array; printf ("Please input the line and row number of the matrix:\n"); scanf ("%d", &n);//create matrix printf ("Start Create a%d *%d matrix.\n", n,n); Array = (int**) malloc (sizeof (int*) *n); for (k = 0; k < n; ++k) {array[k] = (int*) malloc (sizeof (int) *n); } printf ("If you want get a identity matrix, please input 0, and if want an invertible matrix, just input 1. \ n "); scanf ("%d", &flag), if (flag = = 0) {printf ("Your input word is%d, so you want an identity matrix: \ n ", flag); Get indentity Matrix Getidentitymatrix (n, array); Put indentity matrix into file Putidentitymatrixintofile (n, array); Print identity matrix Printidentitymatrix (n, array); }else if (flag = = 1) { printf ("Your input word is%d, so-want an invertible matrix:\n", flag); Get indentity Matrix Getidentitymatrix (n, array); Get invertible matrix Getinvertiblematrix (n, array); Put invertible matrix into file Putinvertiblematrixintofile (n, array); Print invertible matrix Printinvertiblematrix (n, array); }else {printf ("error:you input a wrong number!\n"); return-1; }//free Matrix printf ("Free matrix.\n"); Freematrix (n, array); return 1;}
Note: The last Freematrix function in the code is the one I wrote specifically in order to free up the array memory, the code is as follows:
void Freematrix (int n, int** array) { int k = 0; for (k = 0, k < n; ++k) {free (array[k]); } Free (array);}
Since the memory allocation is in the form of a dynamic array, coupled with a two-dimensional array, it is slightly more complex to reclaim memory.
3.2 Generating the unit matrix the Code logic for generating the unit matrix is simple, that is, the number of rows and columns equal to the position of 1, the rest of the 0 is OK.
void Getidentitymatrix (int n, int** array) { int r = 0; int c = 0; for (r = 0, r < N; ++r) {for (c = 0; c < n; ++c) { if (r = = c) array[r][c] = 1; else array[r][c] = 0;}} }
3.3 The steps to generate a reversible matrix are relatively complex, and there are two points to note: (1) The number of elementary line transformations is random (but not unlimited) (2) The addition operation of the elementary line transformation can not overflow (so to judge the legitimacy of the calculation result) due to the need to use random numbers in the program, We first use the Srand function to set the seed of the random number, and then use the RAND function to generate the number of times I want to make an elementary line transformation (here I set it to 1000, if you want to know something about more random numbers, see this article: Click to open the link); In order to achieve the addition in the Elementary line transformation , I need a mediation array to store the elements in a row in the matrix, so I used a dynamic approach to build a one-dimensional array of quota day temparray. The next play begins with some loops, and you crossing and listen to me slowly. The circle of the outer ring controls the number of times the primary line transforms, and the main loop is covered by two small loops: (1) There is a sentence before the first cycle begins:
Mainrownum = (int) (rand ()% (n-1));
This sentence is random. Select a primary row in the Matrix 0~n-1 row for the elementary row transformation, and the first loop is to handle the elements in the main row in some way
ARRAY[MAINROWNUM][K]) * ((int) (rand ()%5-10)
After depositing into the intermediary array Temparray (the processing method is I casually write, also can be another operation mode). And this sentence:
((Uint16_max-(Array[mainrownum][k]) * ((int) (rand ()%5-10))) < 0) | | ((uint16_max* ( -1))-(Array[mainrownum][k]) * ((int) (rand ()%5-10)) > Temparray[k])
is to determine whether the value of the element will overflow after the operation of the matrix element using the above processing method. (If you want to learn more, see here: Click to open the link) The second loop is to iterate through all the rows in the matrix, then add the processed rows and all the other rows sequentially, and the overflow is judged. Finally, don't forget to release the memory yo ~
void Getinvertiblematrix (int n, int** array) {int i = 0; int j = 0; int k = 0;int mainrownum = 0; int* Temparray = Null;srand ((int) time (NULL)), int transformtime = (int) (rand ()%1000);p rintf ("We'll do%d times Tansforma Tion.\n ", transformtime); Temparray = (int*) malloc (sizeof (int) *n); for (i = 0; i < transformtime; ++i) {mainrownum = (int) (rand ()% (n-1)); for (k = 0; k < n; ++k) if (((Uint16_max-(Array[mainrownum][k]) * ((int) (rand ()%5-10)) < 0) | | ((uint16_max* ( -1))-(Array[mainrownum][k]) * ((int) (rand ()%5-10)) > Temparray[k])) Temparray[k] = (array[mainrownum][k]); else temparray[k] = (Array[mainrownum][k]) * ((int) (rand ()%5- 10)); for (j = 0; J < N; ++j) if (mainrownum! = j) for (k = 0; k < n; + +k) {if ((Uint16_max-array[j][k) < temparray[k]) | | ((uint16_max* ( -1))-array[j][k] > Temparray[k])) Array[j][k] = arrAY[J][K]/4;ELSEARRAY[J][K] = Array[j][k] + temparray[k];} } free (temparray);}
3.4 After the reversible matrix is written to the reversible matrix in the file, the final step is to save it to the file, here is mainly related to the file operation, in fact, the matrix output, but this is the output of the element to the file.
int putinvertiblematrixintofile (int n, int** array) { file* fp = NULL; int i = 0; int j = 0; if (fp = fopen ("Input", "W")) {==null) { printf ("error:writing file error!\n"); return-1; } for (i = 0; l < n; ++i) { for (j = 0; J < N; ++j) { if (j! = (n-1)) fprintf (FP, "%d\t", Array[i] [j]); else fprintf (FP, "%d", array[i][j]); } Fputs ("\ n", FP); } Fclose (FP); return 1;}
Note that there should be no whitespace or tab-like segmentation after the last element of the line at output, so make a decision. It is best to use \ t for the element at the end of each line, and if you use only spaces, it will look messy when the numbers are large and both negative and positive. 4. Experimental results I did on 64-bit Ubuntu 14.04, so use GCC to compile
Gcc-o invertible invertiblematrix.c
Let's try the 5*5 matrix for example.
Select 1 to generate a non-unit matrix invertible matrix
As you can see, there are 780 times the line transformation, but the matrix has a list of a lot of 0, it does not look perfect.
Use Vim to look at the files we get (called input):
Initial success. Summary as a mathematical slag, this blog is a bit of my humble opinion, the algorithm is not perfect, there are many flaws, but also ask the great gods to correct, if there is a better way to discuss and share with more people. Finally, I have uploaded the source of this program to my resources: http://download.csdn.net/detail/liu1075538266/9529058. Thank you for reading my blog ~
C language generating random invertible matrices