| 1 | //
|
|---|
| 2 | // utils.h
|
|---|
| 3 | // cg
|
|---|
| 4 | //
|
|---|
| 5 | // Created by Sri Hari Krishna Narayanan on 9/02/15.
|
|---|
| 6 | //
|
|---|
| 7 | //
|
|---|
| 8 |
|
|---|
| 9 | #ifndef __cg__utils__
|
|---|
| 10 | #define __cg__utils__
|
|---|
| 11 | /** @brief slow matrix copy. Should be reduced to a memcpy()
|
|---|
| 12 | * @param X src matrix.
|
|---|
| 13 | * @param n #rows.
|
|---|
| 14 | * @param m #columns.
|
|---|
| 15 | * @param result output matrix.
|
|---|
| 16 | * @return Void.
|
|---|
| 17 | */
|
|---|
| 18 | void matrixCopy (double **X, int n, int m, double **result);
|
|---|
| 19 |
|
|---|
| 20 | /** @brief result_{ij} = X_{ij} -Y_{ij}
|
|---|
| 21 | * @param X src matrix.
|
|---|
| 22 | * @param Y src matrix.
|
|---|
| 23 | * @param n #rows.
|
|---|
| 24 | * @param m #columns.
|
|---|
| 25 | * @param result output matrix.
|
|---|
| 26 | * @return Void.
|
|---|
| 27 | */
|
|---|
| 28 | void matrixDifference (double **X, double **Y, int n, int m, double **result);
|
|---|
| 29 |
|
|---|
| 30 | /** @brief matrix matrix multiply.
|
|---|
| 31 | * @param X src matrix (n*m).
|
|---|
| 32 | * @param Y src matrix. (m*ensemblecount)
|
|---|
| 33 | * @param n #rows in X.
|
|---|
| 34 | * @param m #columns in X and rows in Y.
|
|---|
| 35 | * @param ensemblecount #columns in Y.
|
|---|
| 36 | * @param result output matrix.
|
|---|
| 37 | * @return Void.
|
|---|
| 38 | */
|
|---|
| 39 | void matrixMatrixProduct (double **X, double **Y, int n, int m, int ensemblecount, double **result);
|
|---|
| 40 |
|
|---|
| 41 | /** @brief computes matrix times vector result_i = \sigma_j{x_{ij}*v_j}.
|
|---|
| 42 | * @param X src matrix (n*m).
|
|---|
| 43 | * @param v src vector. (m)
|
|---|
| 44 | * @param n #rows in X.
|
|---|
| 45 | * @param m #columns in X.
|
|---|
| 46 | * @param result output vector.
|
|---|
| 47 | * @return Void.
|
|---|
| 48 | */
|
|---|
| 49 | void matrixVectorProduct (double **X, double *v, int n, int m, double *result);
|
|---|
| 50 |
|
|---|
| 51 | /** @brief result_e = \sigma_j{X_{ie}*Y_{ie}}.
|
|---|
| 52 | * @param X src matrix (n*ensemblecount).
|
|---|
| 53 | * @param Y src matrix. (n*ensemblecount)
|
|---|
| 54 | * @param n #rows in X and Y.
|
|---|
| 55 | * @param ensemblecount #columns in X and Y.
|
|---|
| 56 | * @param result output vector.
|
|---|
| 57 | * @return Void.
|
|---|
| 58 | */
|
|---|
| 59 | void vectorTransposeVectorProductInsideMatrix(double **X, double **Y, int n, int ensemblecount, double *result);
|
|---|
| 60 |
|
|---|
| 61 | /** @brief result_e = \sigma_j{X_{ei}*Y_{ei}}.
|
|---|
| 62 | * @param X src matrix (ensemblecount*n).
|
|---|
| 63 | * @param Y src matrix. (ensemblecount*n)
|
|---|
| 64 | * @param ensemblecount #rows in X and Y.
|
|---|
| 65 | * @param n #columns in X and Y.
|
|---|
| 66 | * @param result output vector.
|
|---|
| 67 | * @return Void.
|
|---|
| 68 | */
|
|---|
| 69 | void vectorVectorTransposeProductInsideMatrix(double **X, double **Y, int ensemblecount, int n, double *result);
|
|---|
| 70 |
|
|---|
| 71 | /** @brief result_i = v1_i-v2_i.
|
|---|
| 72 | * @param v1 src vector (n).
|
|---|
| 73 | * @param v2 src vector. (n)
|
|---|
| 74 | * @param n length of v1 and v2.
|
|---|
| 75 | * @param result output vector.
|
|---|
| 76 | * @return Void.
|
|---|
| 77 | */
|
|---|
| 78 | void vectorDifference (double *v1, double *v2, int n, double *result);
|
|---|
| 79 |
|
|---|
| 80 | /** @brief result_i = v1_i.
|
|---|
| 81 | * @param v1 src vector (n).
|
|---|
| 82 | * @param n length of v1.
|
|---|
| 83 | * @param result output vector.
|
|---|
| 84 | * @return Void.
|
|---|
| 85 | */
|
|---|
| 86 | void vectorCopy (double *v1, int n, double *result);
|
|---|
| 87 |
|
|---|
| 88 | /** @brief result = \sigma_i{v1_i*v2_i}.
|
|---|
| 89 | * @param v1 src vector (n).
|
|---|
| 90 | * @param v2 src vector. (n)
|
|---|
| 91 | * @param n length of v1 and v2.
|
|---|
| 92 | * @param result output scalar.
|
|---|
| 93 | * @return scalar variable result.
|
|---|
| 94 | */
|
|---|
| 95 | double vectorTransposeVectorProduct (double *v1, double *v2, int n);
|
|---|
| 96 |
|
|---|
| 97 | /** @brief In place diagonal preconditioner of matrix A.
|
|---|
| 98 | * @param A src and output matrix (n*m).
|
|---|
| 99 | * @param n #rows.
|
|---|
| 100 | * @param m #columns.
|
|---|
| 101 | * @return Void.
|
|---|
| 102 | */
|
|---|
| 103 | void diagonalPreconditioner( double **A, int n, int m);
|
|---|
| 104 |
|
|---|
| 105 | /** @brief Computes the Euclidean norm for each row in the matrix.
|
|---|
| 106 | * @param mat src matrix (emsemblecount*n).
|
|---|
| 107 | * @param emsemblecount #rows.
|
|---|
| 108 | * @param n #columns.
|
|---|
| 109 | * @param sum output vector of norms.
|
|---|
| 110 | * @return Void.
|
|---|
| 111 | */
|
|---|
| 112 | void norm2PerRow(double **const mat, size_t ensemblecount, size_t n, double *sum);
|
|---|
| 113 |
|
|---|
| 114 | /** @brief Computes the Euclidean norm for each column in the matrix.
|
|---|
| 115 | * @param mat src matrix (n*emsemblecount).
|
|---|
| 116 | * @param n #rows.
|
|---|
| 117 | * @param emsemblecount #columns.
|
|---|
| 118 | * @param sum output vector of norms.
|
|---|
| 119 | * @return Void.
|
|---|
| 120 | */
|
|---|
| 121 | void norm2PerColumn(double **const mat, size_t n, size_t ensemblecount, double *sum);
|
|---|
| 122 |
|
|---|
| 123 | /** @brief If the Euclidean norm of a row in the matrix1 divided by the norm of vector1 is less than tolerance, the ensemble corresponding to that row has converged. Based on the convergence policyt, the total number of converged ensembles is used to decide if overall convergence has been reached.
|
|---|
| 124 | * @param matrix1 src matrix (emsemblecount*n).
|
|---|
| 125 | * @param vector1 src vector (emsemblecount*n).
|
|---|
| 126 | * @param emsemblecount #rows of matrix1.
|
|---|
| 127 | * @param n #columns of matrix1 and length of vector1.
|
|---|
| 128 | * @param policy (allconverge=0, anyconverge=1, halfconverge=2).
|
|---|
| 129 | * @param tolerance value that decides whether an ensemble has conerged.
|
|---|
| 130 | * @param iteration current iteration.
|
|---|
| 131 | * @param converged integer vector (length e) containing the iteration at which the ensemble converged.
|
|---|
| 132 | * @return tolerance.
|
|---|
| 133 | */
|
|---|
| 134 | int haveConvergedPerRow(double **matrix1, double *vector1, int ensemblecount, int n, int policy, double tolerance, int iteration, int *converged);
|
|---|
| 135 |
|
|---|
| 136 | /** @brief If the quotient of the Euclidean norm of a column in the matrix1 divided by the norm of corresponging column in matrix2 vector2 is less than tolerance, the ensemble corresponding to that column in matrix1 has converged. Based on the convergence policy, the total number of converged ensembles is used to decide if overall convergence has been reached.
|
|---|
| 137 | * @param matrix1 src matrix (n*emsemblecount).
|
|---|
| 138 | * @param matrix2 src metrix (n*emsemblecount).
|
|---|
| 139 | * @param n #rows of matrix1 and matrix2.
|
|---|
| 140 | * @param emsemblecount #cols of matrix1 and matrix2.
|
|---|
| 141 | * @param policy (allconverge=0, anyconverge=1, halfconverge=2).
|
|---|
| 142 | * @param tolerance value that decides whether an ensemble has conerged.
|
|---|
| 143 | * @param iteration current iteration.
|
|---|
| 144 | * @param converged integer vector (length e) containing the iteration at which the ensemble converged.
|
|---|
| 145 | * @return tolerance.
|
|---|
| 146 | */
|
|---|
| 147 | int haveConvergedPerColumn(double **matrix1, double **matrix2, int n, int ensemblecount, int policy, double tolerance, int iteration, int *converged);
|
|---|
| 148 |
|
|---|
| 149 | /** @brief Computes the Euclidean norm of a vector.
|
|---|
| 150 | * @param v src vector .
|
|---|
| 151 | * @param n length of v.
|
|---|
| 152 | * @return Euclidean norm of v.
|
|---|
| 153 | */
|
|---|
| 154 | double norm2(const double *const v, const size_t n);
|
|---|
| 155 |
|
|---|
| 156 | /** @brief Function to return postive and negative random numbers in the half-open interval [-max/2, max/2]
|
|---|
| 157 | *
|
|---|
| 158 | * Original copied from:
|
|---|
| 159 | * http://stackoverflow.com/questions/2509679/how-to-generate-a-random-number-from-within-a-range
|
|---|
| 160 | * Adapted to return -ve numbers as well
|
|---|
| 161 | * Assumes 0 <= max <= RAND_MAX
|
|---|
| 162 | * @return a random number in the half-open interval [0, max]
|
|---|
| 163 | */
|
|---|
| 164 | long random_at_most(long max);
|
|---|
| 165 |
|
|---|
| 166 | /** @brief naively create an n*m matrix and initialize its entries to 0.0
|
|---|
| 167 | * @param n #rows.
|
|---|
| 168 | * @param m #columns.
|
|---|
| 169 | * @return matrix
|
|---|
| 170 | */
|
|---|
| 171 | double ** createMatrix( int n, int m);
|
|---|
| 172 |
|
|---|
| 173 | /** @brief deallocate matrix
|
|---|
| 174 | * @param A src matrix (n rows).
|
|---|
| 175 | * @param n #rows.
|
|---|
| 176 | * @return Void
|
|---|
| 177 | */
|
|---|
| 178 | void destroyMatrix( double **A, int n);
|
|---|
| 179 |
|
|---|
| 180 | /** @brief if directionfilename is not NULL, read a direction vector from a file, else create it
|
|---|
| 181 | * @param M #rows that the direction vector should have.
|
|---|
| 182 | * @param directionfilename file containing an input direction vector (can be NULL).
|
|---|
| 183 | * @param direction output direction vector.
|
|---|
| 184 | * @return 0 on success -1 on failure
|
|---|
| 185 | */
|
|---|
| 186 | int createDirectionVector(int M, const char * directionfilename, double **direction);
|
|---|
| 187 |
|
|---|
| 188 | /** @brief if rhsfilename is not NULL, read a basis RHS vector from a file, create a direction vector and create a matrix ((b_{ij} = vector_j+ i*scalingfactor*direction_j). Otherwise create an (ensemblecount*M) matrix with all entries 0.0.
|
|---|
| 189 | * @param b output RHS matrix.
|
|---|
| 190 | * @param M #cols in RHS matrix.
|
|---|
| 191 | * @param ensemblecount #rows in RHS matrix.
|
|---|
| 192 | * @param rhsfilename file containing a single RHS vector can be NULL).
|
|---|
| 193 | * @param directionfilename file containing an input direction vector (can be NULL).
|
|---|
| 194 | * @param scalingfactor value used to scale entries of the RHS matrix.
|
|---|
| 195 | * @return 0 on success -1 on failure
|
|---|
| 196 | */
|
|---|
| 197 | int createRHSMatrix(double ***b, int *M, int *ensemblecount, const char * rhsfilename, const char * directionfilename, double scalingfactor);
|
|---|
| 198 |
|
|---|
| 199 | /** @brief if rhsfilename is not NULL, read a basis RHS vector from a file, create a direction vector and create a matrix ((b_{ji} = vector_j+ i*scalingfactor*direction_j). Otherwise create an (M*ensemblecount) matrix with all entries 0.0.
|
|---|
| 200 | * @param b output RHS matrix.
|
|---|
| 201 | * @param M #rows in RHS matrix.
|
|---|
| 202 | * @param ensemblecount #cols in RHS matrix.
|
|---|
| 203 | * @param rhsfilename file containing a single RHS vector can be NULL).
|
|---|
| 204 | * @param directionfilename file containing an input direction vector (can be NULL).
|
|---|
| 205 | * @param scalingfactor value used to scale entries of the RHS matrix.
|
|---|
| 206 | * @return 0 on success -1 on failure
|
|---|
| 207 | */
|
|---|
| 208 | int createRHSMatrixTranspose(double ***b, int *M, int *ensemblecount, const char * rhsfilename, const char * directionfilename, double scalingfactor);
|
|---|
| 209 |
|
|---|
| 210 | /** @brief interface to mm_read_symmetric_sparse() which reads a sparse matrix from a file.
|
|---|
| 211 | * @param filename file containing a matrix in matrix market format).
|
|---|
| 212 | * @param M output #rows in the matrix.
|
|---|
| 213 | * @param N output #cols in the matrix.
|
|---|
| 214 | * @param NZ output #nonzeroes in the matrix.
|
|---|
| 215 | * @param val output values the matrix.
|
|---|
| 216 | * @param I output row coordinates of entries of val.
|
|---|
| 217 | * @param J output col coordinates of entires of val.
|
|---|
| 218 | * @return 0 on success -1 on failure
|
|---|
| 219 | */
|
|---|
| 220 | int readMatrixFile(const char * filename, int *M, int *N, int *NZ, double**val, int **I, int **J);
|
|---|
| 221 |
|
|---|
| 222 | /** @brief Copy matrix A to create a matrix ensemble. Then scale the diagonal entries of each matrix Aensemble_{ijj} += i*scalingfactor*direction[j];
|
|---|
| 223 | * @param A src matrix (M*M).
|
|---|
| 224 | * @param M #rows and #cols in A.
|
|---|
| 225 | * @param ensemblecount #entires in the ensemble.
|
|---|
| 226 | * @param directionfilename file containing an input direction vector (can be NULL).
|
|---|
| 227 | * @param scalingfactor value used to scale entries of the RHS matrix.
|
|---|
| 228 | * @param Aensemble output ensemble.
|
|---|
| 229 | * @return 0 on success -1 on failure
|
|---|
| 230 | */
|
|---|
| 231 | int createMatrixEmsemble(double **A, int M, int ensemblecount, const char * directionfilename, double scalingfactor, double ****Aensemble);
|
|---|
| 232 |
|
|---|
| 233 | /** @brief Copy CSR matrix to create a matrix ensemble. Then scale the diagonal entries of each CSR matrix The dense version of this will be: Aensemble_{ijj} += i*scalingfactor*direction[j];
|
|---|
| 234 | * @param NZ #nonzeroes in the CSR matrix.
|
|---|
| 235 | * @param row rows of the CSR matrix.
|
|---|
| 236 | * @param col_idx cols of the CSR matrix.
|
|---|
| 237 | * @param val values of CSR matrix (size: NZ).
|
|---|
| 238 | * @param ensemblecount #entires in the ensemble.
|
|---|
| 239 | * @param directionfilename file containing an input direction vector (can be NULL).
|
|---|
| 240 | * @param scalingfactor value used to scale entries of the RHS matrix.
|
|---|
| 241 | * @param valensemble output ensemble(enmblecount *NZ).
|
|---|
| 242 | * @return 0 on success -1 on failure
|
|---|
| 243 | */
|
|---|
| 244 | int createMatrixEmsembleCSR(int NZ, int *row, int *col_idx, double *val, int M, int ensemblecount, const char * directionfilename, double scalingfactor, double ***valensemble);
|
|---|
| 245 |
|
|---|
| 246 | /** @brief Scale the diagonal elements of a CSR matrix inplace. The dense version of this will be: Aensemble_{ii} += e*scalingfactor*direction[i];
|
|---|
| 247 | * @param numrows #rows of the CSR matrix.
|
|---|
| 248 | * @param row rows of the CSR matrix.
|
|---|
| 249 | * @param col cols of the CSR matrix.
|
|---|
| 250 | * @param val values of CSR matrix (size: NZ).
|
|---|
| 251 | * @param scalingfactor value used to scale entries of the RHS matrix.
|
|---|
| 252 | * @param direction direction vector used in scaling (size: numrows).
|
|---|
| 253 | * @return Void
|
|---|
| 254 | */
|
|---|
| 255 | void diagonalDirectionIncrementCSR(int numrows, int *row, int*col, double* val, int e, double scalingfactor, double *direction);
|
|---|
| 256 |
|
|---|
| 257 | /** @brief In place diagonal preconditioner of CSR matrix.
|
|---|
| 258 | * @param I row coordinates of entries of val.
|
|---|
| 259 | * @param J col coordinates of entires of val.
|
|---|
| 260 | * @param val input and output values the matrix.
|
|---|
| 261 | * @return Void.
|
|---|
| 262 | */
|
|---|
| 263 | void diagonalPreconditionerCSR(int nz, int *I, int*J, double* val);
|
|---|
| 264 |
|
|---|
| 265 | /** @brief Matrix vector product of CSR matrix and vector.
|
|---|
| 266 | * @param NZ #nonzeroes in the CSR matrix.
|
|---|
| 267 | * @param row rows of the CSR matrix.
|
|---|
| 268 | * @param col_idx cols of the CSR matrix.
|
|---|
| 269 | * @param val values the matrix.
|
|---|
| 270 | * @param v src vector of lenght n
|
|---|
| 271 | * @param n #rows in v and matrix.
|
|---|
| 272 | * @param result output vector.
|
|---|
| 273 | * @return Void.
|
|---|
| 274 | */
|
|---|
| 275 | void matrixVectorProductCSR (int NZ, int *row, int *col_idx, double *val, double *v, int n, double *result);
|
|---|
| 276 |
|
|---|
| 277 | /** @brief Extract the diagonal elments of the CSR matrix.
|
|---|
| 278 | * @param n #rows in matrix.
|
|---|
| 279 | * @param row rows of the CSR matrix.
|
|---|
| 280 | * @param col cols of the CSR matrix.
|
|---|
| 281 | * @param val values the matrix.
|
|---|
| 282 | * @param result output vector of length n.
|
|---|
| 283 | * @return Void.
|
|---|
| 284 | */
|
|---|
| 285 | void getDiagonalFromCSR (int n, int *row, int *col, double *val, double *result);
|
|---|
| 286 |
|
|---|
| 287 | /** @brief Use a CSR matrix and a random x to create an ensemble of RHS vector that is ensemblecount in size.
|
|---|
| 288 | * @param NZ #nonzeroes in the CSR matrix.
|
|---|
| 289 | * @param row rows of the CSR matrix.
|
|---|
| 290 | * @param col cols of the CSR matrix.
|
|---|
| 291 | * @param val values the matrix.
|
|---|
| 292 | * @param M #rows in the matrix.
|
|---|
| 293 | * @param N #cols in the matrix.
|
|---|
| 294 | * @param ensemblecount #entires in the ensemble.
|
|---|
| 295 | * @param wantindependentensemble <0|1>. If true, create a new x vector for each ensemble.
|
|---|
| 296 | * @param b output RHS ensemble (ensemblecount*M).
|
|---|
| 297 | * @return Void.
|
|---|
| 298 | */
|
|---|
| 299 | void formRHSCSR(int NZ, int *row, int *col, double *val, int M, int N, int ensemblecount, int wantindependentensemble ,double **b);
|
|---|
| 300 |
|
|---|
| 301 | /** @brief Use a CSR matrix and a random x to create an ensemble of RHS vector that is ensemblecount in size.
|
|---|
| 302 | * @param NZ #nonzeroes in the CSR matrix.
|
|---|
| 303 | * @param row rows of the CSR matrix.
|
|---|
| 304 | * @param col cols of the CSR matrix.
|
|---|
| 305 | * @param val values the matrix.
|
|---|
| 306 | * @param M #rows in the matrix.
|
|---|
| 307 | * @param N #cols in the matrix.
|
|---|
| 308 | * @param ensemblecount #entires in the ensemble.
|
|---|
| 309 | * @param wantindependentensemble <0|1>. If true, create a new x vector for each ensemble.
|
|---|
| 310 | * @param b output RHS ensemble (M*ensemblecount).
|
|---|
| 311 | * @return Void.
|
|---|
| 312 | */
|
|---|
| 313 | void formRHSTransposeCSR(int NZ, int *row, int *col, double *val, int M, int N, int ensemblecount, int wantindependentensemble ,double **b);
|
|---|
| 314 |
|
|---|
| 315 | /** @brief Matrix matrix product of two CSR matrices.
|
|---|
| 316 | * @param NZ #nonzeroes in the CSR matrix.
|
|---|
| 317 | * @param row rows of the CSR matrix.
|
|---|
| 318 | * @param col_idx cols of the CSR matrix.
|
|---|
| 319 | * @param val values the CSR matrix1.
|
|---|
| 320 | * @param Y values the CSR matrix2.
|
|---|
| 321 | * @param result output vector of length n.
|
|---|
| 322 | * @return Void.
|
|---|
| 323 | */
|
|---|
| 324 | void matrixMatrixProductCSR (int NZ, int *row, int *col_idx, double *val, double **Y, int n, int m, int ensemblecount, double **result);
|
|---|
| 325 |
|
|---|
| 326 | /** @brief Use A and a random x to create an ensemble of RHS vector that is ensemblecount in size.
|
|---|
| 327 | * @param A src matrix (M*N) CSR matrix.
|
|---|
| 328 | * @param M #rows in the matrix.
|
|---|
| 329 | * @param N #cols in the matrix.
|
|---|
| 330 | * @param ensemblecount #entires in the ensemble.
|
|---|
| 331 | * @param wantindependentensemble <0|1>. If true, create a new x vector for each ensemble.
|
|---|
| 332 | * @param b output RHS ensemble (ensemblecount*M).
|
|---|
| 333 | * @return Void.
|
|---|
| 334 | */
|
|---|
| 335 | void formRHS(double** A, int M, int N, int ensemblecount, int wantindependentensemble ,double **b);
|
|---|
| 336 |
|
|---|
| 337 | /** @brief Use A and a random x to create an ensemble of RHS vector that is ensemblecount in size.
|
|---|
| 338 | * @param A src matrix (M*N) CSR matrix.
|
|---|
| 339 | * @param M #rows in the matrix.
|
|---|
| 340 | * @param N #cols in the matrix.
|
|---|
| 341 | * @param ensemblecount #entires in the ensemble.
|
|---|
| 342 | * @param wantindependentensemble <0|1>. If true, create a new x vector for each ensemble.
|
|---|
| 343 | * @param b output RHS ensemble (M*ensemblecount).
|
|---|
| 344 | * @return Void.
|
|---|
| 345 | */
|
|---|
| 346 | void formRHSTranspose(double** A, int M, int N, int ensemblecount, int wantindependentensemble ,double **b);
|
|---|
| 347 |
|
|---|
| 348 | /** @brief Printout the output.
|
|---|
| 349 | * @param converged .
|
|---|
| 350 | * @param normval.
|
|---|
| 351 | * @param ensemblecount.
|
|---|
| 352 | * @return Void.
|
|---|
| 353 | */
|
|---|
| 354 | void output(int *converged, double * normval, int ensemblecount);
|
|---|
| 355 | #endif
|
|---|