func_ret_t create_matrix_from_random_float(float **mp, int size) { float *l, *u, *m; int i,j,k; float sum; l = (float*)malloc(size*size*sizeof(float)); if ( l == NULL) return RET_FAILURE; u = (float*)malloc(size*size*sizeof(float)); if ( u == NULL) { free(l); return RET_FAILURE; } m = (float *)malloc(size*size*sizeof(float)); if ( m == NULL) { free(l); free(u); return RET_FAILURE; } for (i = 0; i < size; i++) { for (j=0; j < size; j++) { if (i>j) { l[i*size+j] = common_randJS(); } else if (i == j) { l[i*size+j] = 1; } else { l[i*size+j] = 0; } } } // The u matrix is transposed to facilitate indexing // during matrix multiplication for (j=0; j < size; j++) { for (i=0; i < size; i++) { if (i>j) { u[j*size+i] = 0; } else { u[j*size+i] = common_randJS(); } } } for (i=0; i < size; i++) { for (j=0; j < size; j++) { sum = 0; for (k=0; k <= MIN(i,j); k++) { sum += l[i*size+k] * u[j*size+k]; } m[i*size+j] = sum; } } free(l); free(u); *mp = m; return RET_SUCCESS; }
// This function creates a matrix that is guaranteed to have a // LUD solution by creating the upper and lower trangular matrices // and then multiplying them together. func_ret_t create_matrix_from_random(double **mp, int size) { double *l, *u, *m; int i,j,k; double sum; l = (double*)malloc(size*size*sizeof(double)); if ( l == NULL) return RET_FAILURE; u = (double*)malloc(size*size*sizeof(double)); if ( u == NULL) { free(l); return RET_FAILURE; } m = (double *)malloc(size*size*sizeof(double)); if ( m == NULL) { free(l); free(u); return RET_FAILURE; } for (i = 0; i < size; i++) { for (j=0; j < size; j++) { if (i>j) { l[i*size+j] = common_randJS(); } else if (i == j) { l[i*size+j] = 1; } else { l[i*size+j] = 0; } } } // The u matrix is transposed to facilitate indexing // during matrix multiplication for (j=0; j < size; j++) { for (i=0; i < size; i++) { if (i>j) { u[j*size+i] = 0; } else { u[j*size+i] = common_randJS(); } } } // For debugging purposes, change to '1' to print // intermediary matrices if (DEBUG) { fprintf(stderr,"l:\n"); for (i=0; i < size; i++) { for (j=0; j < size; j++) { fprintf(stderr, "%f ", l[i*size+j]); } fprintf(stderr, "\n"); } fprintf(stderr, "\n"); fprintf(stderr,"u:\n"); for (i=0; i < size; i++) { for (j=0; j < size; j++) { fprintf(stderr, "%f ", u[i*size+j]); } fprintf(stderr, "\n"); } fprintf(stderr, "\n"); } for (i=0; i < size; i++) { for (j=0; j < size; j++) { sum = 0; for (k=0; k <= MIN(i,j); k++) { sum += l[i*size+k] * u[j*size+k]; } m[i*size+j] = sum; } } free(l); free(u); *mp = m; return RET_SUCCESS; }
csr_matrix rand_csr(const unsigned int N,const unsigned int density, const double normal_stddev,unsigned long* seed,FILE* log) { unsigned int i,j,nnz_ith_row,nnz,update_interval,rand_col; double nnz_ith_row_double,nz_error,nz_per_row_doubled,high_bound; int kn[128]; float fn[128],wn[128]; char* used_cols; csr_matrix csr; csr.num_rows = N; csr.num_cols = N; csr.density_perc = (((double)(density))/10000.0); csr.nz_per_row = (((double)N)*((double)density))/1000000.0; csr.num_nonzeros = round(csr.nz_per_row*N); csr.stddev = normal_stddev * csr.nz_per_row; //scale normalized standard deviation by average NZ/row fprintf(log,"Average NZ/Row: %-8.3f\n",csr.nz_per_row); fprintf(log,"Standard Deviation: %-8.3f\n",csr.stddev); fprintf(log,"Target Density: %u ppm = %g%%\n",density,csr.density_perc); fprintf(log,"Approximate NUM_nonzeros: %d\n",csr.num_nonzeros); csr.Ap = (unsigned int *) int_new_array(csr.num_rows+1,"rand_csr() - Heap Overflow! Cannot Allocate Space for csr.Ap"); csr.Aj = (unsigned int *) int_new_array(csr.num_nonzeros,"rand_csr() - Heap Overflow! Cannot Allocate Space for csr.Aj"); csr.Ap[0] = 0; nnz = 0; nz_per_row_doubled = 2*csr.nz_per_row; //limit nnz_ith_row to double the average because negative values are rounded up to 0. This high_bound = MINIMUM(csr.num_cols,nz_per_row_doubled); //limitation ensures the distribution will be symmetric about the mean, albeit not truly normal. used_cols = (char *) malloc(csr.num_cols*sizeof(char)); check(used_cols != NULL,"rand_csr() - Heap Overflow! Cannot allocate space for used_cols"); r4_nor_setup(kn,fn,wn); srand(*seed); update_interval = round(csr.num_rows / 10.0); if(!update_interval) update_interval = csr.num_rows; for(i=0; i<csr.num_rows; i++) { if(i % update_interval == 0) fprintf(log,"\t%d of %d (%5.1f%%) Rows Generated. Continuing...\n",i,csr.num_rows,((double)(i))/csr.num_rows*100); nnz_ith_row_double = r4_nor(seed,kn,fn,wn); //random, normally-distributed value for # of nz elements in ith row, NORMALIZED nnz_ith_row_double *= csr.stddev; //scale by standard deviation nnz_ith_row_double += csr.nz_per_row; //add average nz/row if(nnz_ith_row_double < 0) nnz_ith_row = 0; else if(nnz_ith_row_double > high_bound) nnz_ith_row = high_bound; else nnz_ith_row = (unsigned int) round(nnz_ith_row_double); csr.Ap[i+1] = csr.Ap[i] + nnz_ith_row; if(csr.Ap[i+1] > csr.num_nonzeros) csr.Aj = (unsigned int *) realloc(csr.Aj,sizeof(unsigned int)*csr.Ap[i+1]); for(j=0; j<csr.num_cols; j++) used_cols[j] = 0; for(j=0; j<nnz_ith_row; j++) { rand_col = abs(gen_rand(0,csr.num_cols - 1)); //unsigned long is always non-negative if(used_cols[rand_col]) { j--; } else { csr.Aj[csr.Ap[i]+j] = rand_col; used_cols[rand_col] = 1; } } qsort((&(csr.Aj[csr.Ap[i]])),nnz_ith_row,sizeof(unsigned int),unsigned_int_comparator); } nz_error = ((double)abs((signed int)(csr.num_nonzeros - csr.Ap[csr.num_rows]))) / ((double)csr.num_nonzeros); if(nz_error >= .05) fprintf(stderr,"WARNING: Actual NNZ differs from Theoretical NNZ by %5.2f%%!\n",nz_error*100); csr.num_nonzeros = csr.Ap[csr.num_rows]; fprintf(log,"Actual NUM_nonzeros: %d\n",csr.num_nonzeros); csr.density_perc = (((double)csr.num_nonzeros)*100.0)/((double)csr.num_cols)/((double)csr.num_rows); csr.density_ppm = (unsigned int)round(csr.density_perc * 10000.0); fprintf(log,"Actual Density: %u ppm = %g%%\n",csr.density_ppm,csr.density_perc); free(used_cols); csr.Ax = (float *) float_new_array(csr.num_nonzeros,"rand_csr() - Heap Overflow! Cannot Allocate Space for csr.Ax"); for(i=0; i<csr.num_nonzeros; i++) { csr.Ax[i] = 1.0 - 2.0 * common_randJS(); while(csr.Ax[i] == 0.0) csr.Ax[i] = 1.0 - 2.0 * common_randJS(); } return csr; }