/* File: gen.c Generate a random matrix. Result is delivered to standard output. Usage: gen rows columns entries Example: To produce a 5x10 matrix with 12 non-zero entries, use the command: gen 5 10 12 >test.txt */ #include #include #include #include typedef struct { int row ; int col ; } entry ; main(int argc, char *argv[]) { int rows, columns, entries ; int i, j, k, n, r, repeated ; long int seed ; double value ; entry *previous ; /* Sanity check */ if (argc != 4) { fprintf(stderr, "Usage: gen rows columns entries\n") ; exit(1) ; } /* Get arguments */ r = sscanf(argv[1],"%d", &rows) ; if (r != 1) { fprintf(stderr, "%s not an integer!\n", argv[1]) ; exit(1) ; } r = sscanf(argv[2],"%d", &columns) ; if (r != 1) { fprintf(stderr, "%s not an integer!\n", argv[1]) ; exit(1) ; } r = sscanf(argv[3],"%d", &entries) ; if (r != 1) { fprintf(stderr, "%s not an integer!\n", argv[1]) ; exit(1) ; } fprintf(stderr, "Rows: %d Columns: %d Entires: %d\n", rows, columns, entries) ; /* Does the input make sense? */ if (rows < 1 || columns < 1) { fprintf(stderr, "Number of rows and columns must be positive\n") ; exit(1) ; } if (entries > rows * columns) { fprintf(stderr, "Error: Too many entries!\n") ; exit(1) ; } if (entries > 0.3*rows*columns) { fprintf(stderr, "Warning: this matrix is not very sparse!\n") ; } if (entries > 20000) { fprintf(stderr, "Warning: this could take a while...\n") ; } /* Set random seed to time in seconds since 01/01/70 */ seed = (long) time(NULL) ; fprintf(stderr, "Set random seed to %ld\n", seed) ; srand48(seed) ; /* Initialization for main loop */ n = 0 ; previous = malloc(entries * sizeof(entry)) ; if (previous == NULL) { fprintf(stderr, "Could not allocate that much memory\n!") ; exit(1) ; } /* Print row and column info */ printf("%d %d\n", rows, columns) ; /* Main loop */ while (n < entries) { /* Make a random entry with 0.01 <= value <= 200.01 */ i = ( (int) lrand48() ) % rows ; j = ( (int) lrand48() ) % columns ; value = ( ( ( (int) lrand48() ) % 20000 ) + 1.0) / 100.0 ; /* Make sure we don't generate two values for the same entry */ repeated = 0 ; for (k = 0 ; k < n ; k++) { if ( (previous[k].row == i) && (previous[k].col == j) ) { repeated = 1 ; break ; } } if (repeated) continue ; /* output random entry */ printf("%d %d %lf\n", i, j, value) ; /* remember that this entry was used */ previous[n].row = i ; previous[n].col = j ; n++ ; } }