/*----------------------------------------------------------------- cvDlsDenseDQJac ----------------------------------------------------------------- This routine generates a dense difference quotient approximation to the Jacobian of f(t,y). It assumes that a dense SUNMatrix is stored column-wise, and that elements within each column are contiguous. The address of the jth column of J is obtained via the accessor function SUNDenseMatrix_Column, and this pointer is associated with an N_Vector using the N_VSetArrayPointer function. Finally, the actual computation of the jth column of the Jacobian is done with a call to N_VLinearSum. -----------------------------------------------------------------*/ int cvDlsDenseDQJac(realtype t, N_Vector y, N_Vector fy, SUNMatrix Jac, CVodeMem cv_mem, N_Vector tmp1) { realtype fnorm, minInc, inc, inc_inv, yjsaved, srur; realtype *y_data, *ewt_data; N_Vector ftemp, jthCol; sunindextype j, N; int retval = 0; CVDlsMem cvdls_mem; /* access DlsMem interface structure */ cvdls_mem = (CVDlsMem) cv_mem->cv_lmem; /* access matrix dimension */ N = SUNDenseMatrix_Rows(Jac); /* Rename work vector for readibility */ ftemp = tmp1; /* Create an empty vector for matrix column calculations */ jthCol = N_VCloneEmpty(tmp1); /* Obtain pointers to the data for ewt, y */ ewt_data = N_VGetArrayPointer(cv_mem->cv_ewt); y_data = N_VGetArrayPointer(y); /* Set minimum increment based on uround and norm of f */ srur = SUNRsqrt(cv_mem->cv_uround); fnorm = N_VWrmsNorm(fy, cv_mem->cv_ewt); minInc = (fnorm != ZERO) ? (MIN_INC_MULT * SUNRabs(cv_mem->cv_h) * cv_mem->cv_uround * N * fnorm) : ONE; for (j = 0; j < N; j++) { /* Generate the jth col of J(tn,y) */ N_VSetArrayPointer(SUNDenseMatrix_Column(Jac,j), jthCol); yjsaved = y_data[j]; inc = SUNMAX(srur*SUNRabs(yjsaved), minInc/ewt_data[j]); y_data[j] += inc; retval = cv_mem->cv_f(t, y, ftemp, cv_mem->cv_user_data); cvdls_mem->nfeDQ++; if (retval != 0) break; y_data[j] = yjsaved; inc_inv = ONE/inc; N_VLinearSum(inc_inv, ftemp, -inc_inv, fy, jthCol); /* DENSE_COL(Jac,j) = N_VGetArrayPointer(jthCol); /\*UNNECESSARY?? *\/ */ } /* Destroy jthCol vector */ N_VSetArrayPointer(NULL, jthCol); /* SHOULDN'T BE NEEDED */ N_VDestroy(jthCol); return(retval); }
/* ---------------------------------------------------------------------- * Main SUNMatrix Testing Routine * --------------------------------------------------------------------*/ int main(int argc, char *argv[]) { int fails=0; /* counter for test failures */ sunindextype matrows, matcols; /* matrix dims */ int mattype; /* matrix storage type */ N_Vector x, y, z; /* test vectors */ realtype* vecdata; /* pointers to vector data */ SUNMatrix A, B, C, D, I; /* test matrices */ realtype* matdata; /* pointer to matrix data */ sunindextype i, j, k, kstart, kend, N, uband, lband; sunindextype *colptrs, *rowindices; sunindextype *rowptrs, *colindices; int print_timing, square; /* check input and set vector length */ if (argc < 5){ printf("ERROR: FOUR (4) Input required: matrix rows, matrix cols, matrix type (0/1), print timing \n"); return(-1); } matrows = atol(argv[1]); if (matrows < 1) { printf("ERROR: number of rows must be a positive integer\n"); return(-1); } matcols = atol(argv[2]); if (matcols < 1) { printf("ERROR: number of cols must be a positive integer\n"); return(-1); } k = atol(argv[3]); if ((k != 0) && (k != 1)) { printf("ERROR: matrix type must be 0 or 1\n"); return(-1); } mattype = (k == 0) ? CSC_MAT : CSR_MAT; print_timing = atoi(argv[4]); SetTiming(print_timing); square = (matrows == matcols) ? 1 : 0; printf("\nSparse matrix test: size %ld by %ld, type = %i\n\n", (long int) matrows, (long int) matcols, mattype); /* Initialize vectors and matrices to NULL */ x = NULL; y = NULL; z = NULL; A = NULL; B = NULL; C = NULL; D = NULL; I = NULL; /* check creating sparse matrix from dense matrix */ B = SUNDenseMatrix(5,6); matdata = SUNDenseMatrix_Data(B); matdata[2] = RCONST(1.0); /* [ 0 2 0 0 7 0 ] */ matdata[5] = RCONST(2.0); /* [ 0 0 4 0 8 0 ] */ matdata[9] = RCONST(3.0); /* [ 1 0 0 0 0 0 ] */ matdata[11] = RCONST(4.0); /* [ 0 0 5 6 0 0 ] */ matdata[13] = RCONST(5.0); /* [ 0 3 0 0 0 9 ] */ matdata[18] = RCONST(6.0); matdata[20] = RCONST(7.0); matdata[21] = RCONST(8.0); matdata[29] = RCONST(9.0); if (mattype == CSR_MAT) { /* Check CSR */ C = SUNSparseMatrix(5, 6, 9, CSR_MAT); rowptrs = SUNSparseMatrix_IndexPointers(C); colindices = SUNSparseMatrix_IndexValues(C); matdata = SUNSparseMatrix_Data(C); rowptrs[0] = 0; matdata[0] = RCONST(2.0); colindices[0] = 1; matdata[1] = RCONST(7.0); colindices[1] = 4; rowptrs[1] = 2; matdata[2] = RCONST(4.0); colindices[2] = 2; matdata[3] = RCONST(8.0); colindices[3] = 4; rowptrs[2] = 4; matdata[4] = RCONST(1.0); colindices[4] = 0; rowptrs[3] = 5; matdata[5] = RCONST(5.0); colindices[5] = 2; matdata[6] = RCONST(6.0); colindices[6] = 3; rowptrs[4] = 7; matdata[7] = RCONST(3.0); colindices[7] = 1; matdata[8] = RCONST(9.0); colindices[8] = 5; rowptrs[5] = 9; A = SUNSparseFromDenseMatrix(B, ZERO, CSR_MAT); fails += check_matrix(A, C, 1e-15); if (fails) { printf("FAIL: SUNMatrix SparseFromDense CSR conversion failed\n"); return(1); } SUNMatDestroy(A); SUNMatDestroy(C); } else { /* Check CSC */ D = SUNSparseMatrix(5, 6, 9, CSC_MAT); colptrs = SUNSparseMatrix_IndexPointers(D); rowindices = SUNSparseMatrix_IndexValues(D); matdata = SUNSparseMatrix_Data(D); colptrs[0] = 0; matdata[0] = RCONST(1.0); rowindices[0] = 2; colptrs[1] = 1; matdata[1] = RCONST(2.0); rowindices[1] = 0; matdata[2] = RCONST(3.0); rowindices[2] = 4; colptrs[2] = 3; matdata[3] = RCONST(4.0); rowindices[3] = 1; matdata[4] = RCONST(5.0); rowindices[4] = 3; colptrs[3] = 5; matdata[5] = RCONST(6.0); rowindices[5] = 3; colptrs[4] = 6; matdata[6] = RCONST(7.0); rowindices[6] = 0; matdata[7] = RCONST(8.0); rowindices[7] = 1; colptrs[5] = 8; matdata[8] = RCONST(9.0); rowindices[8] = 4; colptrs[6] = 9; A = SUNSparseFromDenseMatrix(B, 1e-15, CSC_MAT); fails += check_matrix(A, D, 1e-15); if (fails) { printf("FAIL: SUNMatrix SparseFromDense CSC conversion failed\n"); return(1); } SUNMatDestroy(A); SUNMatDestroy(D); } SUNMatDestroy(B); /* check creating sparse matrix from banded matrix */ N = 7; uband = 1; lband = 2; /* B(i,j) = j + (j-i) */ B = SUNBandMatrix(N, uband, lband); /* B = [ 0 2 0 0 0 0 0 ] */ for (j=0; j<N; j++) { /* [ -1 1 3 0 0 0 0 ] */ matdata = SUNBandMatrix_Column(B, j); /* [ -2 0 2 4 0 0 0 ] */ kstart = (j<uband) ? -j : -uband; /* [ 0 -1 1 3 5 0 0 ] */ kend = (j>N-1-lband) ? N-1-j: lband; /* [ 0 0 0 2 4 6 0 ] */ for (k=kstart; k<=kend; k++) /* [ 0 0 0 1 3 5 7 ] */ matdata[k] = j - k; /* [ 0 0 0 0 2 4 6 ] */ } if (mattype == CSR_MAT) { /* CSR */ C = SUNSparseMatrix(7, 7, 21, CSR_MAT); rowptrs = SUNSparseMatrix_IndexPointers(C); colindices = SUNSparseMatrix_IndexValues(C); matdata = SUNSparseMatrix_Data(C); rowptrs[ 0] = 0; matdata[ 0] = RCONST(2.0); colindices[ 0] = 1; rowptrs[ 1] = 1; matdata[ 1] = RCONST(-1.0); colindices[ 1] = 0; matdata[ 2] = RCONST(1.0); colindices[ 2] = 1; matdata[ 3] = RCONST(3.0); colindices[ 3] = 2; rowptrs[ 2] = 4; matdata[ 4] = RCONST(-2.0); colindices[ 4] = 0; matdata[ 5] = RCONST(2.0); colindices[ 5] = 2; matdata[ 6] = RCONST(4.0); colindices[ 6] = 3; rowptrs[ 3] = 7; matdata[ 7] = RCONST(-1.0); colindices[ 7] = 1; matdata[ 8] = RCONST(1.0); colindices[ 8] = 2; matdata[ 9] = RCONST(3.0); colindices[ 9] = 3; matdata[10] = RCONST(5.0); colindices[10] = 4; rowptrs[ 4] = 11; matdata[11] = RCONST(2.0); colindices[11] = 3; matdata[12] = RCONST(4.0); colindices[12] = 4; matdata[13] = RCONST(6.0); colindices[13] = 5; rowptrs[ 5] = 14; matdata[14] = RCONST(1.0); colindices[14] = 3; matdata[15] = RCONST(3.0); colindices[15] = 4; matdata[16] = RCONST(5.0); colindices[16] = 5; matdata[17] = RCONST(7.0); colindices[17] = 6; rowptrs[ 6] = 18; matdata[18] = RCONST(2.0); colindices[18] = 4; matdata[19] = RCONST(4.0); colindices[19] = 5; matdata[20] = RCONST(6.0); colindices[20] = 6; rowptrs[ 7] = 21; A = SUNSparseFromBandMatrix(B, ZERO, CSR_MAT); fails += check_matrix(A, C, 1e-15); if (fails) { printf("FAIL: SUNMatrix SparseFromBand CSR conversion failed\n"); return(1); } SUNMatDestroy(A); SUNMatDestroy(C); } else { /* Check CSC */ D = SUNSparseMatrix(7, 7, 21, CSC_MAT); colptrs = SUNSparseMatrix_IndexPointers(D); rowindices = SUNSparseMatrix_IndexValues(D); matdata = SUNSparseMatrix_Data(D); colptrs[ 0] = 0; matdata[ 0] = RCONST(-1.0); rowindices[ 0] = 1; matdata[ 1] = RCONST(-2.0); rowindices[ 1] = 2; colptrs[ 1] = 2; matdata[ 2] = RCONST(2.0); rowindices[ 2] = 0; matdata[ 3] = RCONST(1.0); rowindices[ 3] = 1; matdata[ 4] = RCONST(-1.0); rowindices[ 4] = 3; colptrs[ 2] = 5; matdata[ 5] = RCONST(3.0); rowindices[ 5] = 1; matdata[ 6] = RCONST(2.0); rowindices[ 6] = 2; matdata[ 7] = RCONST(1.0); rowindices[ 7] = 3; colptrs[ 3] = 8; matdata[ 8] = RCONST(4.0); rowindices[ 8] = 2; matdata[ 9] = RCONST(3.0); rowindices[ 9] = 3; matdata[10] = RCONST(2.0); rowindices[10] = 4; matdata[11] = RCONST(1.0); rowindices[11] = 5; colptrs[ 4] = 12; matdata[12] = RCONST(5.0); rowindices[12] = 3; matdata[13] = RCONST(4.0); rowindices[13] = 4; matdata[14] = RCONST(3.0); rowindices[14] = 5; matdata[15] = RCONST(2.0); rowindices[15] = 6; colptrs[ 5] = 16; matdata[16] = RCONST(6.0); rowindices[16] = 4; matdata[17] = RCONST(5.0); rowindices[17] = 5; matdata[18] = RCONST(4.0); rowindices[18] = 6; colptrs[ 6] = 19; matdata[19] = RCONST(7.0); rowindices[19] = 5; matdata[20] = RCONST(6.0); rowindices[20] = 6; colptrs[ 7] = 21; A = SUNSparseFromBandMatrix(B, 1e-15, CSC_MAT); fails += check_matrix(A, D, 1e-15); if (fails) { printf("FAIL: SUNMatrix SparseFromBand CSC conversion failed\n"); return(1); } SUNMatDestroy(A); SUNMatDestroy(D); } SUNMatDestroy(B); /* Create/fill I matrix */ I = NULL; if (square) { I = SUNSparseMatrix(matrows, matcols, matcols, mattype); matdata = SUNSparseMatrix_Data(I); colindices = SUNSparseMatrix_IndexValues(I); rowptrs = SUNSparseMatrix_IndexPointers(I); for(i=0; i<matrows; i++) { matdata[i] = ONE; colindices[i] = i; rowptrs[i] = i; } rowptrs[matrows] = matrows; } /* Create/fill random dense matrices, create sparse from them */ C = SUNDenseMatrix(matrows, matcols); D = SUNDenseMatrix(matrows, matcols); for (k=0; k<3*matrows; k++) { i = rand() % matrows; j = rand() % matcols; matdata = SUNDenseMatrix_Column(D,j); matdata[i] = (realtype) rand() / (realtype) RAND_MAX; } for (k=0; k<matrows; k++) { i = rand() % matrows; j = rand() % matcols; matdata = SUNDenseMatrix_Column(C,j); matdata[i] = (realtype) rand() / (realtype) RAND_MAX; } A = SUNSparseFromDenseMatrix(C, ZERO, mattype); B = SUNSparseFromDenseMatrix(D, ZERO, mattype); /* Create vectors and fill */ x = N_VNew_Serial(matcols); y = N_VNew_Serial(matrows); z = N_VNew_Serial(matrows); vecdata = N_VGetArrayPointer(x); for(i=0; i<matcols; i++) vecdata[i] = (realtype) rand() / (realtype) RAND_MAX; if (SUNMatMatvec(C, x, y) != 0) { printf("FAIL: SUNMatrix module Dense matvec failure \n \n"); SUNMatDestroy(A); SUNMatDestroy(B); SUNMatDestroy(C); SUNMatDestroy(D); N_VDestroy(x); N_VDestroy(y); N_VDestroy(z); if (square) SUNMatDestroy(I); return(1); } if (SUNMatMatvec(D, x, z) != 0) { printf("FAIL: SUNMatrix module Dense matvec failure \n \n"); SUNMatDestroy(A); SUNMatDestroy(B); SUNMatDestroy(C); SUNMatDestroy(D); N_VDestroy(x); N_VDestroy(y); N_VDestroy(z); if (square) SUNMatDestroy(I); return(1); } /* SUNMatrix Tests */ fails += Test_SUNMatGetID(A, SUNMATRIX_SPARSE, 0); fails += Test_SUNMatClone(A, 0); fails += Test_SUNMatCopy(A, 0); fails += Test_SUNMatZero(A, 0); fails += Test_SUNMatScaleAdd(A, I, 0); fails += Test_SUNMatScaleAdd2(A, B, x, y, z); if (square) { fails += Test_SUNMatScaleAddI(A, I, 0); fails += Test_SUNMatScaleAddI2(A, x, y); } fails += Test_SUNMatMatvec(A, x, y, 0); fails += Test_SUNMatSpace(A, 0); /* Print result */ if (fails) { printf("FAIL: SUNMatrix module failed %i tests \n \n", fails); printf("\nA =\n"); SUNSparseMatrix_Print(A,stdout); printf("\nB =\n"); SUNSparseMatrix_Print(B,stdout); if (square) { printf("\nI =\n"); SUNSparseMatrix_Print(I,stdout); } printf("\nx =\n"); N_VPrint_Serial(x); printf("\ny =\n"); N_VPrint_Serial(y); printf("\nz =\n"); N_VPrint_Serial(z); } else { printf("SUCCESS: SUNMatrix module passed all tests \n \n"); } /* Free vectors and matrices */ N_VDestroy(x); N_VDestroy(y); N_VDestroy(z); SUNMatDestroy(A); SUNMatDestroy(B); SUNMatDestroy(C); SUNMatDestroy(D); if (square) SUNMatDestroy(I); return(fails); }
/* ---------------------------------------------------------------------- * SUNLinSol_Dense Testing Routine * --------------------------------------------------------------------*/ int main(int argc, char *argv[]) { int fails = 0; /* counter for test failures */ sunindextype cols, rows; /* matrix columns, rows */ SUNLinearSolver LS; /* solver object */ SUNMatrix A, B, I; /* test matrices */ N_Vector x, y, b; /* test vectors */ int print_timing; sunindextype j, k; realtype *colj, *xdata, *colIj; /* check input and set matrix dimensions */ if (argc < 3){ printf("ERROR: TWO (2) Inputs required: matrix cols, print timing \n"); return(-1); } cols = atol(argv[1]); if (cols <= 0) { printf("ERROR: number of matrix columns must be a positive integer \n"); return(-1); } rows = cols; print_timing = atoi(argv[2]); SetTiming(print_timing); printf("\nDense linear solver test: size %ld\n\n", (long int) cols); /* Create matrices and vectors */ A = SUNDenseMatrix(rows, cols); B = SUNDenseMatrix(rows, cols); I = SUNDenseMatrix(rows, cols); x = N_VNew_Serial(cols); y = N_VNew_Serial(cols); b = N_VNew_Serial(cols); /* Fill A matrix with uniform random data in [0,1/cols] */ for (j=0; j<cols; j++) { colj = SUNDenseMatrix_Column(A, j); for (k=0; k<rows; k++) colj[k] = (realtype) rand() / (realtype) RAND_MAX / cols; } /* Create anti-identity matrix */ j=cols-1; for (k=0; k<rows; k++) { colj = SUNDenseMatrix_Column(I,j); colj[k] = 1; j = j-1; } /* Add anti-identity to ensure the solver needs to do row-swapping */ for (k=0; k<rows; k++){ for(j=0; j<cols; j++){ colj = SUNDenseMatrix_Column(A,j); colIj = SUNDenseMatrix_Column(I,j); colj[k] = colj[k] + colIj[k]; } } /* Fill x vector with uniform random data in [0,1] */ xdata = N_VGetArrayPointer(x); for (j=0; j<cols; j++) { xdata[j] = (realtype) rand() / (realtype) RAND_MAX; } /* copy A and x into B and y to print in case of solver failure */ SUNMatCopy(A, B); N_VScale(ONE, x, y); /* create right-hand side vector for linear solve */ fails = SUNMatMatvec(A, x, b); if (fails) { printf("FAIL: SUNLinSol SUNMatMatvec failure\n"); /* Free matrices and vectors */ SUNMatDestroy(A); SUNMatDestroy(B); SUNMatDestroy(I); N_VDestroy(x); N_VDestroy(y); N_VDestroy(b); return(1); } /* Create dense linear solver */ LS = SUNLinSol_Dense(x, A); /* Run Tests */ fails += Test_SUNLinSolInitialize(LS, 0); fails += Test_SUNLinSolSetup(LS, A, 0); fails += Test_SUNLinSolSolve(LS, A, x, b, 10*UNIT_ROUNDOFF, 0); fails += Test_SUNLinSolGetType(LS, SUNLINEARSOLVER_DIRECT, 0); fails += Test_SUNLinSolLastFlag(LS, 0); fails += Test_SUNLinSolSpace(LS, 0); /* Print result */ if (fails) { printf("FAIL: SUNLinSol module failed %i tests \n \n", fails); printf("\nA (original) =\n"); SUNDenseMatrix_Print(B,stdout); printf("\nA (factored) =\n"); SUNDenseMatrix_Print(A,stdout); printf("\nx (original) =\n"); N_VPrint_Serial(y); printf("\nx (computed) =\n"); N_VPrint_Serial(x); } else { printf("SUCCESS: SUNLinSol module passed all tests \n \n"); } /* Free solver, matrix and vectors */ SUNLinSolFree(LS); SUNMatDestroy(A); SUNMatDestroy(B); SUNMatDestroy(I); N_VDestroy(x); N_VDestroy(y); N_VDestroy(b); return(fails); }