int main() { gsl_spmatrix *A = gsl_spmatrix_alloc(5, 4); /* triplet format */ gsl_spmatrix *C; size_t i, j; /* build the sparse matrix */ gsl_spmatrix_set(A, 0, 2, 3.1); gsl_spmatrix_set(A, 0, 3, 4.6); gsl_spmatrix_set(A, 1, 0, 1.0); gsl_spmatrix_set(A, 1, 2, 7.2); gsl_spmatrix_set(A, 3, 0, 2.1); gsl_spmatrix_set(A, 3, 1, 2.9); gsl_spmatrix_set(A, 3, 3, 8.5); gsl_spmatrix_set(A, 4, 0, 4.1); printf("printing all matrix elements:\n"); for (i = 0; i < 5; ++i) for (j = 0; j < 4; ++j) printf("A(%zu,%zu) = %g\n", i, j, gsl_spmatrix_get(A, i, j)); /* print out elements in triplet format */ printf("matrix in triplet format (i,j,Aij):\n"); for (i = 0; i < A->nz; ++i) printf("(%zu, %zu, %.1f)\n", A->i[i], A->p[i], A->data[i]); /* convert to compressed column format */ C = gsl_spmatrix_compcol(A); printf("matrix in compressed column format:\n"); printf("i = [ "); for (i = 0; i < C->nz; ++i) printf("%zu, ", C->i[i]); printf("]\n"); printf("p = [ "); for (i = 0; i < C->size2 + 1; ++i) printf("%zu, ", C->p[i]); printf("]\n"); printf("d = [ "); for (i = 0; i < C->nz; ++i) printf("%g, ", C->data[i]); printf("]\n"); gsl_spmatrix_free(A); gsl_spmatrix_free(C); return 0; }
static void test_random(const size_t N, const gsl_rng *r, const int compress) { const gsl_splinalg_itersolve_type *T = gsl_splinalg_itersolve_gmres; const double tol = 1.0e-8; int status; gsl_spmatrix *A = create_random_sparse(N, N, 0.3, r); gsl_spmatrix *B; gsl_vector *b = gsl_vector_alloc(N); gsl_vector *x = gsl_vector_calloc(N); /* these random matrices require all N iterations to converge */ gsl_splinalg_itersolve *w = gsl_splinalg_itersolve_alloc(T, N, N); const char *desc = gsl_splinalg_itersolve_name(w); create_random_vector(b, r); if (compress) B = gsl_spmatrix_compcol(A); else B = A; status = gsl_splinalg_itersolve_iterate(B, b, tol, x, w); gsl_test(status, "%s random status s=%d N=%zu", desc, status, N); /* check that the residual satisfies ||r|| <= tol*||b|| */ { gsl_vector *res = gsl_vector_alloc(N); double normr, normb; gsl_vector_memcpy(res, b); gsl_spblas_dgemv(CblasNoTrans, -1.0, A, x, 1.0, res); normr = gsl_blas_dnrm2(res); normb = gsl_blas_dnrm2(b); status = (normr <= tol*normb) != 1; gsl_test(status, "%s random residual N=%zu normr=%.12e normb=%.12e", desc, N, normr, normb); gsl_vector_free(res); } gsl_spmatrix_free(A); gsl_vector_free(b); gsl_vector_free(x); gsl_splinalg_itersolve_free(w); if (compress) gsl_spmatrix_free(B); } /* test_random() */
void test_compress(const size_t M, const size_t N, const double density, const gsl_rng *r) { int status; size_t i, j; gsl_spmatrix *m, *ccs, *crs, *ccstr; m = create_random_sparse(M, N, density, r); // Compress column sum duplicates ccs = gsl_spmatrix_compress(m, GSL_SPMATRIX_CCS); // Compress row sum duplicates crs = gsl_spmatrix_compress(m, GSL_SPMATRIX_CRS); status = 0; for (i = 0; i < ccs->size1; i++) for (j = 0; j < ccs->size2; j++) if (gsl_spmatrix_get(crs, i, j) != gsl_spmatrix_get(ccs, i, j)) status = 1; gsl_test(status, "test_compress: _compress at M=%zu, N=%zu", M, N); return; // Transpose in place by changing major gsl_spmatrix_transpose(crs); status = 0; for (i = 0; i < crs->size1; i++) for (j = 0; j < crs->size2; j++) if (gsl_spmatrix_get(crs, i, j) != gsl_spmatrix_get(ccs, j, i)) status = 1; gsl_test(status, "test_compress: transpose inplace at M=%zu, N=%zu", M, N); gsl_spmatrix_transpose(crs); // Convert by transpose copy gsl_spmatrix_switch_major(crs, ccs); status = 0; for (i = 0; i < ccs->size1; i++) for (j = 0; j < ccs->size2; j++) if (gsl_spmatrix_get(crs, i, j) != gsl_spmatrix_get(ccs, i, j)) status = 1; gsl_test(status, "test_compress: _switch_major at M=%zu, N=%zu", M, N); gsl_spmatrix_free(m); gsl_spmatrix_free(ccs); gsl_spmatrix_free(crs); gsl_spmatrix_free(ccstr); return; }
static void test_ops(const size_t M, const size_t N, const double density, const gsl_rng *r) { size_t i, j; int status; /* test gsl_spmatrix_add */ { gsl_spmatrix *A = create_random_sparse(M, N, density, r); gsl_spmatrix *B = create_random_sparse(M, N, density, r); gsl_spmatrix *A_ccs = gsl_spmatrix_ccs(A); gsl_spmatrix *B_ccs = gsl_spmatrix_ccs(B); gsl_spmatrix *C_ccs = gsl_spmatrix_alloc_nzmax(M, N, 1, GSL_SPMATRIX_CCS); gsl_spmatrix *A_crs = gsl_spmatrix_crs(A); gsl_spmatrix *B_crs = gsl_spmatrix_crs(B); gsl_spmatrix *C_crs = gsl_spmatrix_alloc_nzmax(M, N, 1, GSL_SPMATRIX_CRS); gsl_spmatrix_add(C_ccs, A_ccs, B_ccs); gsl_spmatrix_add(C_crs, A_crs, B_crs); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double aij, bij, cij; aij = gsl_spmatrix_get(A_ccs, i, j); bij = gsl_spmatrix_get(B_ccs, i, j); cij = gsl_spmatrix_get(C_ccs, i, j); if (aij + bij != cij) status = 1; aij = gsl_spmatrix_get(A_crs, i, j); bij = gsl_spmatrix_get(B_crs, i, j); cij = gsl_spmatrix_get(C_crs, i, j); if (aij + bij != cij) status = 2; } } gsl_test(status == 1, "test_ops: add M="F_ZU" N="F_ZU" CCS", M, N); gsl_test(status == 2, "test_ops: add M="F_ZU" N="F_ZU" CRS", M, N); gsl_spmatrix_free(A); gsl_spmatrix_free(B); gsl_spmatrix_free(A_ccs); gsl_spmatrix_free(B_ccs); gsl_spmatrix_free(C_ccs); gsl_spmatrix_free(A_crs); gsl_spmatrix_free(B_crs); gsl_spmatrix_free(C_crs); } } /* test_ops() */
static void test_ops(const size_t M, const size_t N, const gsl_rng *r) { size_t i, j; int status; /* test gsl_spmatrix_add */ { gsl_spmatrix *Ta = create_random_sparse(M, N, 0.2, r); gsl_spmatrix *Tb = create_random_sparse(M, N, 0.2, r); gsl_spmatrix *a = gsl_spmatrix_compcol(Ta); gsl_spmatrix *b = gsl_spmatrix_compcol(Tb); gsl_spmatrix *c = gsl_spmatrix_alloc_nzmax(M, N, 1, GSL_SPMATRIX_CCS); gsl_spmatrix_add(c, a, b); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double aij = gsl_spmatrix_get(a, i, j); double bij = gsl_spmatrix_get(b, i, j); double cij = gsl_spmatrix_get(c, i, j); if (aij + bij != cij) status = 1; } } gsl_test(status, "test_ops: _add M=%zu N=%zu compressed format", M, N); gsl_spmatrix_free(Ta); gsl_spmatrix_free(Tb); gsl_spmatrix_free(a); gsl_spmatrix_free(b); gsl_spmatrix_free(c); } } /* test_ops() */
void test_io(FILE *inStream, FILE *outStream) { gsl_spmatrix *m; int status; m = gsl_spmatrix_fscanf(inStream, 1); status = gsl_spmatrix_fprintf(outStream, m, "%.3lf"); gsl_spmatrix_free(m); return; }
gsl_spmatrix * gsl_spmatrix_alloc_nzmax(const size_t n1, const size_t n2, const size_t nzmax, const size_t sptype) { gsl_spmatrix *m; if (n1 == 0) { GSL_ERROR_VAL ("matrix dimension n1 must be positive integer", GSL_EINVAL, 0); } else if (n2 == 0) { GSL_ERROR_VAL ("matrix dimension n2 must be positive integer", GSL_EINVAL, 0); } m = calloc(1, sizeof(gsl_spmatrix)); if (!m) { GSL_ERROR_VAL("failed to allocate space for spmatrix struct", GSL_ENOMEM, 0); } m->size1 = n1; m->size2 = n2; m->nz = 0; m->nzmax = GSL_MAX(nzmax, 1); m->sptype = sptype; m->i = malloc(m->nzmax * sizeof(size_t)); if (!m->i) { gsl_spmatrix_free(m); GSL_ERROR_VAL("failed to allocate space for row indices", GSL_ENOMEM, 0); } if (sptype == GSL_SPMATRIX_TRIPLET) { m->p = malloc(m->nzmax * sizeof(size_t)); if (!m->p) { gsl_spmatrix_free(m); GSL_ERROR_VAL("failed to allocate space for column indices", GSL_ENOMEM, 0); } } else if (sptype == GSL_SPMATRIX_CCS) { m->p = malloc((n2 + 1) * sizeof(size_t)); m->work = malloc(GSL_MAX(n1, n2) * GSL_MAX(sizeof(size_t), sizeof(double))); if (!m->p || !m->work) { gsl_spmatrix_free(m); GSL_ERROR_VAL("failed to allocate space for column pointers", GSL_ENOMEM, 0); } } m->data = malloc(m->nzmax * sizeof(double)); if (!m->data) { gsl_spmatrix_free(m); GSL_ERROR_VAL("failed to allocate space for data", GSL_ENOMEM, 0); } return m; } /* gsl_spmatrix_alloc_nzmax() */
static void test_toeplitz(const size_t N, const double a, const double b, const double c) { int status; const double tol = 1.0e-10; const size_t max_iter = 10; const gsl_splinalg_itersolve_type *T = gsl_splinalg_itersolve_gmres; const char *desc; gsl_spmatrix *A; gsl_vector *rhs, *x; gsl_splinalg_itersolve *w; size_t i, iter = 0; if (N <= 1) return; A = gsl_spmatrix_alloc(N ,N); rhs = gsl_vector_alloc(N); x = gsl_vector_calloc(N); w = gsl_splinalg_itersolve_alloc(T, N, 0); desc = gsl_splinalg_itersolve_name(w); /* first row */ gsl_spmatrix_set(A, 0, 0, b); gsl_spmatrix_set(A, 0, 1, c); /* interior rows */ for (i = 1; i < N - 1; ++i) { gsl_spmatrix_set(A, i, i - 1, a); gsl_spmatrix_set(A, i, i, b); gsl_spmatrix_set(A, i, i + 1, c); } /* last row */ gsl_spmatrix_set(A, N - 1, N - 2, a); gsl_spmatrix_set(A, N - 1, N - 1, b); /* set rhs vector */ gsl_vector_set_all(rhs, 1.0); /* solve the system */ do { status = gsl_splinalg_itersolve_iterate(A, rhs, tol, x, w); } while (status == GSL_CONTINUE && ++iter < max_iter); gsl_test(status, "%s toeplitz status s=%d N=%zu a=%f b=%f c=%f", desc, status, N, a, b, c); /* check that the residual satisfies ||r|| <= tol*||b|| */ { gsl_vector *r = gsl_vector_alloc(N); double normr, normb; gsl_vector_memcpy(r, rhs); gsl_spblas_dgemv(CblasNoTrans, -1.0, A, x, 1.0, r); normr = gsl_blas_dnrm2(r); normb = gsl_blas_dnrm2(rhs); status = (normr <= tol*normb) != 1; gsl_test(status, "%s toeplitz residual N=%zu a=%f b=%f c=%f normr=%.12e normb=%.12e", desc, N, a, b, c, normr, normb); gsl_vector_free(r); } gsl_vector_free(x); gsl_vector_free(rhs); gsl_spmatrix_free(A); gsl_splinalg_itersolve_free(w); } /* test_toeplitz() */
/* test_poisson() Solve u''(x) = -pi^2 sin(pi*x), u(x) = sin(pi*x) epsrel is the relative error threshold with the exact solution */ static void test_poisson(const size_t N, const double epsrel, const int compress) { const gsl_splinalg_itersolve_type *T = gsl_splinalg_itersolve_gmres; const size_t n = N - 2; /* subtract 2 to exclude boundaries */ const double h = 1.0 / (N - 1.0); /* grid spacing */ const double tol = 1.0e-9; const size_t max_iter = 10; size_t iter = 0; gsl_spmatrix *A = gsl_spmatrix_alloc(n ,n); /* triplet format */ gsl_spmatrix *B; gsl_vector *b = gsl_vector_alloc(n); /* right hand side vector */ gsl_vector *u = gsl_vector_calloc(n); /* solution vector, u0 = 0 */ gsl_splinalg_itersolve *w = gsl_splinalg_itersolve_alloc(T, n, 0); const char *desc = gsl_splinalg_itersolve_name(w); size_t i; int status; /* construct the sparse matrix for the finite difference equation */ /* first row of matrix */ gsl_spmatrix_set(A, 0, 0, -2.0); gsl_spmatrix_set(A, 0, 1, 1.0); /* loop over interior grid points */ for (i = 1; i < n - 1; ++i) { gsl_spmatrix_set(A, i, i + 1, 1.0); gsl_spmatrix_set(A, i, i, -2.0); gsl_spmatrix_set(A, i, i - 1, 1.0); } /* last row of matrix */ gsl_spmatrix_set(A, n - 1, n - 1, -2.0); gsl_spmatrix_set(A, n - 1, n - 2, 1.0); /* scale by h^2 */ gsl_spmatrix_scale(A, 1.0 / (h * h)); /* construct right hand side vector */ for (i = 0; i < n; ++i) { double xi = (i + 1) * h; double bi = -M_PI * M_PI * sin(M_PI * xi); gsl_vector_set(b, i, bi); } if (compress) B = gsl_spmatrix_compcol(A); else B = A; /* solve the system */ do { status = gsl_splinalg_itersolve_iterate(B, b, tol, u, w); } while (status == GSL_CONTINUE && ++iter < max_iter); gsl_test(status, "%s poisson status s=%d N=%zu", desc, status, N); /* check solution against analytic */ for (i = 0; i < n; ++i) { double xi = (i + 1) * h; double u_gsl = gsl_vector_get(u, i); double u_exact = sin(M_PI * xi); gsl_test_rel(u_gsl, u_exact, epsrel, "%s poisson N=%zu i=%zu", desc, N, i); } /* check that the residual satisfies ||r|| <= tol*||b|| */ { gsl_vector *r = gsl_vector_alloc(n); double normr, normb; gsl_vector_memcpy(r, b); gsl_spblas_dgemv(CblasNoTrans, -1.0, A, u, 1.0, r); normr = gsl_blas_dnrm2(r); normb = gsl_blas_dnrm2(b); status = (normr <= tol*normb) != 1; gsl_test(status, "%s poisson residual N=%zu normr=%.12e normb=%.12e", desc, N, normr, normb); gsl_vector_free(r); } gsl_splinalg_itersolve_free(w); gsl_spmatrix_free(A); gsl_vector_free(b); gsl_vector_free(u); if (compress) gsl_spmatrix_free(B); } /* test_poisson() */
int main() { const size_t N = 100; /* number of grid points */ const size_t n = N - 2; /* subtract 2 to exclude boundaries */ const double h = 1.0 / (N - 1.0); /* grid spacing */ gsl_spmatrix *A = gsl_spmatrix_alloc(n ,n); /* triplet format */ gsl_spmatrix *C; /* compressed format */ gsl_vector *f = gsl_vector_alloc(n); /* right hand side vector */ gsl_vector *u = gsl_vector_alloc(n); /* solution vector */ size_t i; /* construct the sparse matrix for the finite difference equation */ /* construct first row */ gsl_spmatrix_set(A, 0, 0, -2.0); gsl_spmatrix_set(A, 0, 1, 1.0); /* construct rows [1:n-2] */ for (i = 1; i < n - 1; ++i) { gsl_spmatrix_set(A, i, i + 1, 1.0); gsl_spmatrix_set(A, i, i, -2.0); gsl_spmatrix_set(A, i, i - 1, 1.0); } /* construct last row */ gsl_spmatrix_set(A, n - 1, n - 1, -2.0); gsl_spmatrix_set(A, n - 1, n - 2, 1.0); /* scale by h^2 */ gsl_spmatrix_scale(A, 1.0 / (h * h)); /* construct right hand side vector */ for (i = 0; i < n; ++i) { double xi = (i + 1) * h; double fi = -M_PI * M_PI * sin(M_PI * xi); gsl_vector_set(f, i, fi); } /* convert to compressed column format */ C = gsl_spmatrix_ccs(A); /* now solve the system with the GMRES iterative solver */ { const double tol = 1.0e-6; /* solution relative tolerance */ const size_t max_iter = 10; /* maximum iterations */ const gsl_splinalg_itersolve_type *T = gsl_splinalg_itersolve_gmres; gsl_splinalg_itersolve *work = gsl_splinalg_itersolve_alloc(T, n, 0); size_t iter = 0; double residual; int status; /* initial guess u = 0 */ gsl_vector_set_zero(u); /* solve the system A u = f */ do { status = gsl_splinalg_itersolve_iterate(C, f, tol, u, work); /* print out residual norm ||A*u - f|| */ residual = gsl_splinalg_itersolve_normr(work); fprintf(stderr, "iter "F_ZU" residual = %.12e\n", iter, residual); if (status == GSL_SUCCESS) fprintf(stderr, "Converged\n"); } while (status == GSL_CONTINUE && ++iter < max_iter); /* output solution */ for (i = 0; i < n; ++i) { double xi = (i + 1) * h; double u_exact = sin(M_PI * xi); double u_gsl = gsl_vector_get(u, i); printf("%f %.12e %.12e\n", xi, u_gsl, u_exact); } gsl_splinalg_itersolve_free(work); } gsl_spmatrix_free(A); gsl_spmatrix_free(C); gsl_vector_free(f); gsl_vector_free(u); return 0; } /* main() */
int main (void) { const size_t p = 2000; const size_t n = p + 1; gsl_vector *f = gsl_vector_alloc(n); gsl_vector *x = gsl_vector_alloc(p); /* allocate sparse Jacobian matrix with 2*p non-zero elements in triplet format */ gsl_spmatrix *J = gsl_spmatrix_alloc_nzmax(n, p, 2 * p, GSL_SPMATRIX_TRIPLET); gsl_multilarge_nlinear_fdf fdf; gsl_multilarge_nlinear_parameters fdf_params = gsl_multilarge_nlinear_default_parameters(); struct model_params params; size_t i; params.alpha = 1.0e-5; params.J = J; /* define function to be minimized */ fdf.f = penalty_f; fdf.df = penalty_df; fdf.fvv = penalty_fvv; fdf.n = n; fdf.p = p; fdf.params = ¶ms; for (i = 0; i < p; ++i) { /* starting point */ gsl_vector_set(x, i, i + 1.0); /* store sqrt(alpha)*I_p in upper p-by-p block of J */ gsl_spmatrix_set(J, i, i, sqrt(params.alpha)); } fprintf(stderr, "%-25s %-4s %-4s %-5s %-6s %-4s %-10s %-10s %-7s %-11s %-10s\n", "Method", "NITER", "NFEV", "NJUEV", "NJTJEV", "NAEV", "Init Cost", "Final cost", "cond(J)", "Final |x|^2", "Time (s)"); fdf_params.scale = gsl_multilarge_nlinear_scale_levenberg; fdf_params.trs = gsl_multilarge_nlinear_trs_lm; solve_system(x, &fdf, &fdf_params); fdf_params.trs = gsl_multilarge_nlinear_trs_lmaccel; solve_system(x, &fdf, &fdf_params); fdf_params.trs = gsl_multilarge_nlinear_trs_dogleg; solve_system(x, &fdf, &fdf_params); fdf_params.trs = gsl_multilarge_nlinear_trs_ddogleg; solve_system(x, &fdf, &fdf_params); fdf_params.trs = gsl_multilarge_nlinear_trs_cgst; solve_system(x, &fdf, &fdf_params); gsl_vector_free(f); gsl_vector_free(x); gsl_spmatrix_free(J); return 0; }
static void test_getset(const size_t M, const size_t N, const gsl_rng *r) { int status; size_t i, j; /* test triplet versions of _get and _set */ { size_t k = 0; gsl_spmatrix *m = gsl_spmatrix_alloc(M, N); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double x = (double) ++k; double y; gsl_spmatrix_set(m, i, j, x, 0); y = gsl_spmatrix_get(m, i, j); if (x != y) status = 1; } } gsl_test(status, "test_getset: M=%zu N=%zu _get != _set", M, N); /* test setting an element to 0 */ gsl_spmatrix_set(m, 0, 0, 1.0, 0); gsl_spmatrix_set(m, 0, 0, 0.0, 0); status = gsl_spmatrix_get(m, 0, 0) != 0.0; gsl_test(status, "test_getset: M=%zu N=%zu m(0,0) = %f", M, N, gsl_spmatrix_get(m, 0, 0)); /* test gsl_spmatrix_set_zero() */ gsl_spmatrix_set(m, 0, 0, 1.0, 0); gsl_spmatrix_set_zero(m); status = gsl_spmatrix_get(m, 0, 0) != 0.0; gsl_test(status, "test_getset: M=%zu N=%zu set_zero m(0,0) = %f", M, N, gsl_spmatrix_get(m, 0, 0)); /* resassemble matrix to ensure nz is calculated correctly */ k = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double x = (double) ++k; gsl_spmatrix_set(m, i, j, x, 0); } } status = gsl_spmatrix_nnz(m) != M * N; gsl_test(status, "test_getset: M=%zu N=%zu set_zero nz = %zu", M, N, gsl_spmatrix_nnz(m)); gsl_spmatrix_free(m); } /* test duplicate values are handled correctly */ { size_t min = GSL_MIN(M, N); size_t expected_nnz = min; size_t nnz; size_t k = 0; gsl_spmatrix *m = gsl_spmatrix_alloc(M, N); status = 0; for (i = 0; i < min; ++i) { for (j = 0; j < 5; ++j) { double x = (double) ++k; double y; gsl_spmatrix_set(m, i, i, x, 0); y = gsl_spmatrix_get(m, i, i); if (x != y) status = 1; } } gsl_test(status, "test_getset: duplicate test M=%zu N=%zu _get != _set", M, N); nnz = gsl_spmatrix_nnz(m); status = nnz != expected_nnz; gsl_test(status, "test_getset: duplicate test M=%zu N=%zu nnz=%zu, expected=%zu", M, N, nnz, expected_nnz); gsl_spmatrix_free(m); } /* test compressed version of gsl_spmatrix_get() */ { gsl_spmatrix *T = create_random_sparse(M, N, 0.3, r); gsl_spmatrix *C = gsl_spmatrix_compress(T, GSL_SPMATRIX_CCS); gsl_spmatrix *CR = gsl_spmatrix_compress(T, GSL_SPMATRIX_CRS); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Tij = gsl_spmatrix_get(T, i, j); double Cij = gsl_spmatrix_get(C, i, j); if (Tij != Cij) status = 1; } } gsl_test(status, "test_getset: M=%zu N=%zu compressed column _get", M, N); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Tij = gsl_spmatrix_get(T, i, j); double Cij = gsl_spmatrix_get(CR, i, j); if (Tij != Cij) status = 1; } } gsl_test(status, "test_getset: M=%zu N=%zu compressed row _get", M, N); gsl_spmatrix_free(T); gsl_spmatrix_free(C); gsl_spmatrix_free(CR); } } /* test_getset() */
void test_prop(const size_t M, const size_t N, const double density, const double d, const gsl_rng *r) { gsl_spmatrix *m, *test, *ccs, *crs; size_t n, p, outerIdx; int status, any; m = create_random_sparse(M, N, density, r); ccs = gsl_spmatrix_compress(m, GSL_SPMATRIX_CCS); crs = gsl_spmatrix_compress(m, GSL_SPMATRIX_CRS); // For triplet /** Test greater than */ test = gsl_spmatrix_gt_elements(m, d); status = 0; for (n = 0; n < m->nz; n++) { if ((m->data[n] > d) != (gsl_spmatrix_get(test, m->i[n], m->p[n]))) status = 1; } gsl_test(status, "test_prop: M=%zu N=%zu _gt_elements triplet", M, N); gsl_spmatrix_free(test); /** Test greater or equal than */ test = gsl_spmatrix_ge_elements(m, d); status = 0; for (n = 0; n < m->nz; n++) { if ((m->data[n] >= d) != (gsl_spmatrix_get(test, m->i[n], m->p[n]))) status = 1; } gsl_test(status, "test_prop: M=%zu N=%zu _ge_elements triplet", M, N); gsl_spmatrix_free(test); /** Test lower than */ test = gsl_spmatrix_lt_elements(m, d); status = 0; for (n = 0; n < m->nz; n++) { if ((m->data[n] < d) != (gsl_spmatrix_get(test, m->i[n], m->p[n]))) status = 1; } gsl_test(status, "test_prop: M=%zu N=%zu _lt_elements triplet", M, N); gsl_spmatrix_free(test); /** Test lower or equal than */ test = gsl_spmatrix_le_elements(m, d); status = 0; any = 0; for (n = 0; n < m->nz; n++) { if ((m->data[n] <= d) != (gsl_spmatrix_get(test, m->i[n], m->p[n]))) status = 1; if (m->data[n] <= d) any = 1; } gsl_test(status, "test_prop: M=%zu N=%zu _le_elements triplet", M, N); gsl_spmatrix_free(test); /** Test any */ status = !(any == (int) gsl_spmatrix_any(test)); gsl_test(status, "test_prop: M=%zu N=%zu _any triplet", M, N); // For CCS /** Test greater than */ test = gsl_spmatrix_gt_elements(ccs, d); status = 0; for (outerIdx = 0; outerIdx < ccs->outerSize; outerIdx++) { for (p = ccs->p[outerIdx]; p < ccs->p[outerIdx + 1]; p++) { if (((int) gsl_spmatrix_get(test, ccs->i[p], outerIdx)) != (ccs->data[p] > d)) status = 1; } } gsl_test(status, "test_prop: M=%zu N=%zu _gt_elements CCS", M, N); gsl_spmatrix_free(test); /** Test greater or equal than */ test = gsl_spmatrix_ge_elements(ccs, d); status = 0; for (outerIdx = 0; outerIdx < ccs->outerSize; outerIdx++) { for (p = ccs->p[outerIdx]; p < ccs->p[outerIdx + 1]; p++) { if (((int) gsl_spmatrix_get(test, ccs->i[p], outerIdx)) != (ccs->data[p] >= d)) status = 1; } } gsl_test(status, "test_prop: M=%zu N=%zu _ge_elements CCS", M, N); gsl_spmatrix_free(test); /** Test lower than */ test = gsl_spmatrix_lt_elements(ccs, d); status = 0; for (outerIdx = 0; outerIdx < ccs->outerSize; outerIdx++) { for (p = ccs->p[outerIdx]; p < ccs->p[outerIdx + 1]; p++) { if (((int) gsl_spmatrix_get(test, ccs->i[p], outerIdx)) != (ccs->data[p] < d)) status = 1; } } gsl_test(status, "test_prop: M=%zu N=%zu _lt_elements CCS", M, N); gsl_spmatrix_free(test); /** Test lower or equal than */ test = gsl_spmatrix_le_elements(ccs, d); status = 0; any = 0; for (outerIdx = 0; outerIdx < ccs->outerSize; outerIdx++) { for (p = ccs->p[outerIdx]; p < ccs->p[outerIdx + 1]; p++) { if (((int) gsl_spmatrix_get(test, ccs->i[p], outerIdx)) != (ccs->data[p] <= d)) status = 1; if (ccs->data[p] <= d) any = 1; } } gsl_test(status, "test_prop: M=%zu N=%zu _le_elements CCS", M, N); gsl_spmatrix_free(test); /** Test any */ status = !(any == (int) gsl_spmatrix_any(test)); gsl_test(status, "test_prop: M=%zu N=%zu _any CCS", M, N); // For CRS /** Test greater than */ test = gsl_spmatrix_gt_elements(crs, d); status = 0; for (outerIdx = 0; outerIdx < crs->outerSize; outerIdx++) { for (p = crs->p[outerIdx]; p < crs->p[outerIdx + 1]; p++) { if (((int) gsl_spmatrix_get(test, outerIdx, crs->i[p])) != (crs->data[p] > d)) status = 1; } } gsl_test(status, "test_prop: M=%zu N=%zu _gt_elements CRS", M, N); gsl_spmatrix_free(test); /** Test greater or equal than */ test = gsl_spmatrix_ge_elements(crs, d); status = 0; for (outerIdx = 0; outerIdx < crs->outerSize; outerIdx++) { for (p = crs->p[outerIdx]; p < crs->p[outerIdx + 1]; p++) { if (((int) gsl_spmatrix_get(test, outerIdx, crs->i[p])) != (crs->data[p] >= d)) status = 1; } } gsl_test(status, "test_prop: M=%zu N=%zu _ge_elements CRS", M, N); gsl_spmatrix_free(test); /** Test lower than */ test = gsl_spmatrix_lt_elements(crs, d); status = 0; for (outerIdx = 0; outerIdx < crs->outerSize; outerIdx++) { for (p = crs->p[outerIdx]; p < crs->p[outerIdx + 1]; p++) { if (((int) gsl_spmatrix_get(test, outerIdx, crs->i[p])) != (crs->data[p] < d)) status = 1; } } gsl_test(status, "test_prop: M=%zu N=%zu _lt_elements CRS", M, N); gsl_spmatrix_free(test); /** Test lower or equal than */ test = gsl_spmatrix_le_elements(crs, d); status = 0; any = 0; for (outerIdx = 0; outerIdx < crs->outerSize; outerIdx++) { for (p = crs->p[outerIdx]; p < crs->p[outerIdx + 1]; p++) { if (((int) gsl_spmatrix_get(test, outerIdx, crs->i[p])) != (crs->data[p] <= d)) status = 1; if (crs->data[p] <= d) any = 1; } } gsl_test(status, "test_prop: M=%zu N=%zu _le_elements CRS", M, N); gsl_spmatrix_free(test); /** Test any */ status = !(any == (int) gsl_spmatrix_any(test)); gsl_test(status, "test_prop: M=%zu N=%zu _any CRS", M, N); gsl_spmatrix_free(m); gsl_spmatrix_free(ccs); gsl_spmatrix_free(crs); return; }
void test_manip(const size_t M, const size_t N, const double density, const gsl_rng *r) { int status; gsl_spmatrix *tri, *ccs, *crs, *test; gsl_matrix *dense, *denseDivRows, *denseDivCols; double sum, sumDense; gsl_vector *v; gsl_vector *denseRowSum, *denseColSum; size_t i, j; tri = create_random_sparse(M, N, density, r); dense = gsl_matrix_alloc(M, N); gsl_spmatrix_sp2d(dense, tri); /** Get row sum and col sum aswell as divided matrices for dense */ denseDivRows = gsl_matrix_calloc(M, N); denseDivCols = gsl_matrix_calloc(M, N); denseRowSum = gsl_vector_calloc(M); denseColSum = gsl_vector_calloc(N); sumDense = 0.; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { denseRowSum->data[i * denseRowSum->stride] += gsl_matrix_get(dense, i, j); denseColSum->data[j * denseColSum->stride] += gsl_matrix_get(dense, i, j); sumDense += gsl_matrix_get(dense, i, j); } } for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { if (gsl_pow_2(denseRowSum->data[i * denseRowSum->stride]) > 1.e-12) { gsl_matrix_set(denseDivRows, i, j, gsl_matrix_get(dense, i, j) / denseRowSum->data[i * denseRowSum->stride]); } else { gsl_matrix_set(denseDivRows, i, j, gsl_matrix_get(dense, i, j)); } if (gsl_pow_2(denseColSum->data[j * denseColSum->stride]) > 1.e-12) { gsl_matrix_set(denseDivCols, i, j, gsl_matrix_get(dense, i, j) / denseColSum->data[j * denseColSum->stride]); } else { gsl_matrix_set(denseDivCols, i, j, gsl_matrix_get(dense, i, j)); } } } // Compress ccs = gsl_spmatrix_compress(tri, GSL_SPMATRIX_CCS); crs = gsl_spmatrix_compress(tri, GSL_SPMATRIX_CRS); /** TOTAL SUM */ /** Triplet */ sum = gsl_spmatrix_get_sum(tri); status = !(sum == sumDense); gsl_test(status, "test_manip: M=%zu N=%zu _get != _get_sum triplet", M, N); /** CCS */ sum = gsl_spmatrix_get_sum(ccs); status = !(sum == sumDense); gsl_test(status, "test_manip: M=%zu N=%zu _get != _get_sum CCS", M, N); /** CRS */ sum = gsl_spmatrix_get_sum(crs); status = !(sum == sumDense); gsl_test(status, "test_manip: M=%zu N=%zu _get != _get_sum CRS", M, N); /** COLUMN SUM AND DIVIDE */ /** Triplet */ /* Sum */ v = gsl_vector_alloc(M); gsl_spmatrix_get_rowsum(v, tri); status = 0; for (i = 0; i < M; i++) if (v->data[i * v->stride] != denseRowSum->data[i * denseRowSum->stride]) status = 1; gsl_test(status, "test_manip: M=%zu N=%zu _get != _get_rowsum triplet", M, N); /* Div */ test = gsl_spmatrix_alloc_nzmax(crs->size1, crs->size2, 0, GSL_SPMATRIX_TRIPLET); gsl_spmatrix_memcpy(test, tri); gsl_spmatrix_div_rows(test, v); status = 0; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { if (gsl_matrix_get(denseDivRows, i, j) != gsl_spmatrix_get(test, i, j)) status = 1; } } gsl_test(status, "test_manip: M=%zu N=%zu _get != _div_rows triplet", M, N); gsl_vector_free(v); gsl_spmatrix_free(test); /** CCS */ /* Sum */ v = gsl_vector_alloc(M); gsl_spmatrix_get_rowsum(v, ccs); status = 0; for (i = 0; i < M; i++) if (v->data[i * v->stride] != denseRowSum->data[i * denseRowSum->stride]) status = 1; gsl_test(status, "test_manip: M=%zu N=%zu _get != _get_rowsum CCS", M, N); /* Div */ test = gsl_spmatrix_alloc_nzmax(ccs->size1, ccs->size2, 0, GSL_SPMATRIX_CCS); gsl_spmatrix_memcpy(test, ccs); gsl_spmatrix_div_rows(test, v); status = 0; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { if (gsl_matrix_get(denseDivRows, i, j) != gsl_spmatrix_get(test, i, j)) status = 1; } } gsl_test(status, "test_manip: M=%zu N=%zu _get != _div_rows CCS", M, N); gsl_vector_free(v); gsl_spmatrix_free(test); /* CRS */ /* Sum */ v = gsl_vector_alloc(M); gsl_spmatrix_get_rowsum(v, crs); status = 0; for (i = 0; i < M; i++) if (v->data[i * v->stride] != denseRowSum->data[i * denseRowSum->stride]) status = 1; gsl_test(status, "test_manip: M=%zu N=%zu _get != _get_rowsum CRS", M, N); /* Div */ test = gsl_spmatrix_alloc_nzmax(crs->size1, crs->size2, 0, GSL_SPMATRIX_CRS); gsl_spmatrix_memcpy(test, crs); gsl_spmatrix_div_rows(test, v); status = 0; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { if (gsl_matrix_get(denseDivRows, i, j) != gsl_spmatrix_get(test, i, j)) status = 1; } } gsl_test(status, "test_manip: M=%zu N=%zu _get != _div_rows CRS", M, N); gsl_vector_free(v); gsl_spmatrix_free(test); /** COLUMN SUM AND DIVIDE */ /** Triplet */ /* Sum */ v = gsl_vector_alloc(N); gsl_spmatrix_get_colsum(v, tri); status = 0; for (j = 0; j < N; j++) if (v->data[j * v->stride] != denseColSum->data[j * denseColSum->stride]) status = 1; gsl_test(status, "test_manip: M=%zu N=%zu _get != _get_colsum triplet", M, N); /* Div */ test = gsl_spmatrix_alloc_nzmax(tri->size1, tri->size2, 0, GSL_SPMATRIX_TRIPLET); gsl_spmatrix_memcpy(test, tri); gsl_spmatrix_div_cols(test, v); status = 0; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { if (gsl_fcmp(gsl_matrix_get(denseDivCols, i, j), gsl_spmatrix_get(test, i, j), 1.e-12)) { fprintf(stdout, "mismatch: (%zu, %zu) %lf != %lf\n", i, j, gsl_matrix_get(denseDivCols, i, j), gsl_spmatrix_get(test, i, j)); status = 1; } } } gsl_test(status, "test_manip: M=%zu N=%zu _get != _div_cols triplet", M, N); gsl_vector_free(v); gsl_spmatrix_free(test); /** CCS */ /** Sum */ v = gsl_vector_alloc(N); gsl_spmatrix_get_colsum(v, ccs); status = 0; for (j = 0; j < N; j++) if (v->data[j * v->stride] != denseColSum->data[j * denseColSum->stride]) status = 1; gsl_test(status, "test_manip: M=%zu N=%zu _get != _get_colsum CCS", M, N); /** Div */ test = gsl_spmatrix_alloc_nzmax(ccs->size1, ccs->size2, 0, GSL_SPMATRIX_CCS); gsl_spmatrix_memcpy(test, ccs); gsl_spmatrix_div_cols(test, v); status = 0; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { if (gsl_matrix_get(denseDivCols, i, j) != gsl_spmatrix_get(test, i, j)) status = 1; } } gsl_test(status, "test_manip: M=%zu N=%zu _get != _div_cols CCS", M, N); gsl_vector_free(v); gsl_spmatrix_free(test); /** CRS */ /* Sum */ v = gsl_vector_alloc(N); gsl_spmatrix_get_colsum(v, crs); status = 0; for (j = 0; j < N; j++) if (v->data[j * v->stride] != denseColSum->data[j * denseColSum->stride]) status = 1; gsl_test(status, "test_manip: M=%zu N=%zu _get != _get_colsum CRS", M, N); /* Div */ test = gsl_spmatrix_alloc_nzmax(crs->size1, crs->size2, 0, GSL_SPMATRIX_CRS); gsl_spmatrix_memcpy(test, crs); gsl_spmatrix_div_cols(test, v); status = 0; for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { if (gsl_matrix_get(denseDivCols, i, j) != gsl_spmatrix_get(test, i, j)) status = 1; } } gsl_test(status, "test_manip: M=%zu N=%zu _get != _div_cols CRS", M, N); gsl_vector_free(v); gsl_spmatrix_free(test); /** Free */ gsl_spmatrix_free(tri); gsl_spmatrix_free(ccs); gsl_spmatrix_free(crs); gsl_matrix_free(dense); gsl_matrix_free(denseDivRows); gsl_matrix_free(denseDivCols); gsl_vector_free(denseRowSum); gsl_vector_free(denseColSum); return; }
gsl_spmatrix * gsl_spmatrix_alloc_nzmax(const size_t n1, const size_t n2, const size_t nzmax, const size_t sptype) { gsl_spmatrix *m; if (n1 == 0) { GSL_ERROR_VAL ("matrix dimension n1 must be positive integer", GSL_EINVAL, 0); } else if (n2 == 0) { GSL_ERROR_VAL ("matrix dimension n2 must be positive integer", GSL_EINVAL, 0); } m = calloc(1, sizeof(gsl_spmatrix)); if (!m) { GSL_ERROR_VAL("failed to allocate space for spmatrix struct", GSL_ENOMEM, 0); } m->size1 = n1; m->size2 = n2; m->nz = 0; m->nzmax = GSL_MAX(nzmax, 1); m->sptype = sptype; m->i = malloc(m->nzmax * sizeof(size_t)); if (!m->i) { gsl_spmatrix_free(m); GSL_ERROR_VAL("failed to allocate space for row indices", GSL_ENOMEM, 0); } if (sptype == GSL_SPMATRIX_TRIPLET) { m->tree_data = malloc(sizeof(gsl_spmatrix_tree)); if (!m->tree_data) { gsl_spmatrix_free(m); GSL_ERROR_VAL("failed to allocate space for AVL tree struct", GSL_ENOMEM, 0); } m->tree_data->n = 0; /* allocate tree data structure */ m->tree_data->tree = avl_create(compare_triplet, (void *) m, &avl_allocator_spmatrix); if (!m->tree_data->tree) { gsl_spmatrix_free(m); GSL_ERROR_VAL("failed to allocate space for AVL tree", GSL_ENOMEM, 0); } /* preallocate nzmax tree nodes */ m->tree_data->node_array = malloc(m->nzmax * sizeof(struct avl_node)); if (!m->tree_data->node_array) { gsl_spmatrix_free(m); GSL_ERROR_VAL("failed to allocate space for AVL tree nodes", GSL_ENOMEM, 0); } m->p = malloc(m->nzmax * sizeof(size_t)); if (!m->p) { gsl_spmatrix_free(m); GSL_ERROR_VAL("failed to allocate space for column indices", GSL_ENOMEM, 0); } } else if (sptype == GSL_SPMATRIX_CCS) { m->p = malloc((n2 + 1) * sizeof(size_t)); m->work = malloc(GSL_MAX(n1, n2) * GSL_MAX(sizeof(size_t), sizeof(double))); if (!m->p || !m->work) { gsl_spmatrix_free(m); GSL_ERROR_VAL("failed to allocate space for column pointers", GSL_ENOMEM, 0); } } m->data = malloc(m->nzmax * sizeof(double)); if (!m->data) { gsl_spmatrix_free(m); GSL_ERROR_VAL("failed to allocate space for data", GSL_ENOMEM, 0); } return m; } /* gsl_spmatrix_alloc_nzmax() */
static void test_memcpy(const size_t M, const size_t N, const gsl_rng *r) { int status; { gsl_spmatrix *at = create_random_sparse(M, N, 0.2, r); gsl_spmatrix *ac = gsl_spmatrix_compress(at, GSL_SPMATRIX_CCS); gsl_spmatrix *ar = gsl_spmatrix_compress(at, GSL_SPMATRIX_CRS); gsl_spmatrix *bt, *bc, *br; bt = gsl_spmatrix_alloc(M, N); gsl_spmatrix_memcpy(bt, at); status = gsl_spmatrix_equal(at, bt) != 1; gsl_test(status, "test_memcpy: _memcpy M=%zu N=%zu triplet format", M, N); bc = gsl_spmatrix_alloc_nzmax(M, N, ac->nzmax, GSL_SPMATRIX_CCS); gsl_spmatrix_memcpy(bc, ac); status = gsl_spmatrix_equal(ac, bc) != 1; gsl_test(status, "test_memcpy: _memcpy M=%zu N=%zu compressed column format", M, N); br = gsl_spmatrix_alloc_nzmax(M, N, ar->nzmax, GSL_SPMATRIX_CRS); gsl_spmatrix_memcpy(br, ar); status = gsl_spmatrix_equal(ar, br) != 1; gsl_test(status, "test_memcpy: _memcpy M=%zu N=%zu compressed row format", M, N); gsl_spmatrix_free(at); gsl_spmatrix_free(ac); gsl_spmatrix_free(ar); gsl_spmatrix_free(bt); gsl_spmatrix_free(bc); gsl_spmatrix_free(br); } /* test transpose_memcpy */ { gsl_spmatrix *A = create_random_sparse(M, N, 0.3, r); gsl_spmatrix *B = gsl_spmatrix_compress(A, GSL_SPMATRIX_CCS); gsl_spmatrix *BR = gsl_spmatrix_compress(A, GSL_SPMATRIX_CRS); gsl_spmatrix *AT = gsl_spmatrix_alloc(N, M); gsl_spmatrix *BT = gsl_spmatrix_alloc_nzmax(N, M, 1, GSL_SPMATRIX_CCS); gsl_spmatrix *BTR = gsl_spmatrix_alloc_nzmax(N, M, 1, GSL_SPMATRIX_CRS); size_t i, j; gsl_spmatrix_transpose_memcpy(AT, A); gsl_spmatrix_transpose_memcpy(BT, B); gsl_spmatrix_transpose_memcpy(BTR, BR); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Aij = gsl_spmatrix_get(A, i, j); double ATji = gsl_spmatrix_get(AT, j, i); if (Aij != ATji) status = 1; } } gsl_test(status, "test_memcpy: _transpose_memcpy M=%zu N=%zu triplet format", M, N); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Aij = gsl_spmatrix_get(A, i, j); double Bij = gsl_spmatrix_get(B, i, j); double BTji = gsl_spmatrix_get(BT, j, i); if ((Bij != BTji) || (Aij != Bij)) status = 1; } } gsl_test(status, "test_memcpy: _transpose_memcpy M=%zu N=%zu column format", M, N); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Aij = gsl_spmatrix_get(A, i, j); double BRij = gsl_spmatrix_get(BR, i, j); double BTRji = gsl_spmatrix_get(BTR, j, i); if ((Aij != BRij) || (BRij != BTRji)) status = 1; } } gsl_test(status, "test_memcpy: _transpose_memcpy M=%zu N=%zu row format", M, N); gsl_spmatrix_free(A); gsl_spmatrix_free(AT); gsl_spmatrix_free(B); gsl_spmatrix_free(BT); gsl_spmatrix_free(BR); gsl_spmatrix_free(BTR); } } /* test_memcpy() */
static void test_getset(const size_t M, const size_t N, const double density, const gsl_rng *r) { int status; size_t i, j; /* test triplet versions of _get and _set */ { const double val = 0.75; size_t k = 0; gsl_spmatrix *m = gsl_spmatrix_alloc(M, N); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double x = (double) ++k; double y; gsl_spmatrix_set(m, i, j, x); y = gsl_spmatrix_get(m, i, j); if (x != y) status = 1; } } gsl_test(status, "test_getset: M="F_ZU" N="F_ZU" _get != _set", M, N); /* test setting an element to 0 */ gsl_spmatrix_set(m, 0, 0, 1.0); gsl_spmatrix_set(m, 0, 0, 0.0); status = gsl_spmatrix_get(m, 0, 0) != 0.0; gsl_test(status, "test_getset: M="F_ZU" N="F_ZU" m(0,0) = %f", M, N, gsl_spmatrix_get(m, 0, 0)); /* test gsl_spmatrix_set_zero() */ gsl_spmatrix_set(m, 0, 0, 1.0); gsl_spmatrix_set_zero(m); status = gsl_spmatrix_get(m, 0, 0) != 0.0; gsl_test(status, "test_getset: M="F_ZU" N="F_ZU" set_zero m(0,0) = %f", M, N, gsl_spmatrix_get(m, 0, 0)); /* resassemble matrix to ensure nz is calculated correctly */ k = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double x = (double) ++k; gsl_spmatrix_set(m, i, j, x); } } status = gsl_spmatrix_nnz(m) != M * N; gsl_test(status, "test_getset: M="F_ZU" N="F_ZU" set_zero nz = "F_ZU, M, N, gsl_spmatrix_nnz(m)); /* test gsl_spmatrix_ptr() */ status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double mij = gsl_spmatrix_get(m, i, j); double *ptr = gsl_spmatrix_ptr(m, i, j); *ptr += val; if (gsl_spmatrix_get(m, i, j) != mij + val) status = 2; } } gsl_test(status == 2, "test_getset: M="F_ZU" N="F_ZU" triplet ptr", M, N); gsl_spmatrix_free(m); } /* test duplicate values are handled correctly */ { size_t min = GSL_MIN(M, N); size_t expected_nnz = min; size_t nnz; size_t k = 0; gsl_spmatrix *m = gsl_spmatrix_alloc(M, N); status = 0; for (i = 0; i < min; ++i) { for (j = 0; j < 5; ++j) { double x = (double) ++k; double y; gsl_spmatrix_set(m, i, i, x); y = gsl_spmatrix_get(m, i, i); if (x != y) status = 1; } } gsl_test(status, "test_getset: duplicate test M="F_ZU" N="F_ZU" _get != _set", M, N); nnz = gsl_spmatrix_nnz(m); status = nnz != expected_nnz; gsl_test(status, "test_getset: duplicate test M="F_ZU" N="F_ZU" nnz="F_ZU", expected="F_ZU, M, N, nnz, expected_nnz); gsl_spmatrix_free(m); } /* test CCS version of gsl_spmatrix_get() */ { const double val = 0.75; gsl_spmatrix *T = create_random_sparse(M, N, density, r); gsl_spmatrix *C = gsl_spmatrix_ccs(T); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Tij = gsl_spmatrix_get(T, i, j); double Cij = gsl_spmatrix_get(C, i, j); double *ptr = gsl_spmatrix_ptr(C, i, j); if (Tij != Cij) status = 1; if (ptr) { *ptr += val; Cij = gsl_spmatrix_get(C, i, j); if (Tij + val != Cij) status = 2; } } } gsl_test(status == 1, "test_getset: M="F_ZU" N="F_ZU" CCS get", M, N); gsl_test(status == 2, "test_getset: M="F_ZU" N="F_ZU" CCS ptr", M, N); gsl_spmatrix_free(T); gsl_spmatrix_free(C); } /* test CRS version of gsl_spmatrix_get() */ { const double val = 0.75; gsl_spmatrix *T = create_random_sparse(M, N, density, r); gsl_spmatrix *C = gsl_spmatrix_crs(T); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Tij = gsl_spmatrix_get(T, i, j); double Cij = gsl_spmatrix_get(C, i, j); double *ptr = gsl_spmatrix_ptr(C, i, j); if (Tij != Cij) status = 1; if (ptr) { *ptr += val; Cij = gsl_spmatrix_get(C, i, j); if (Tij + val != Cij) status = 2; } } } gsl_test(status == 1, "test_getset: M="F_ZU" N="F_ZU" CRS get", M, N); gsl_test(status == 2, "test_getset: M="F_ZU" N="F_ZU" CRS ptr", M, N); gsl_spmatrix_free(T); gsl_spmatrix_free(C); } } /* test_getset() */
static void test_io_binary(const size_t M, const size_t N, const double density, const gsl_rng *r) { int status; gsl_spmatrix *A = create_random_sparse(M, N, density, r); gsl_spmatrix *A_ccs, *A_crs; char filename[] = "test.XXXXXX"; #if !defined( _WIN32 ) int fd = mkstemp(filename); #else char * fd = _mktemp(filename); # define fdopen fopen #endif /* test triplet I/O */ { FILE *f = fdopen(fd, "wb"); gsl_spmatrix_fwrite(f, A); fclose(f); } { FILE *f = fopen(filename, "rb"); gsl_spmatrix *B = gsl_spmatrix_alloc_nzmax(M, N, A->nz, A->sptype); gsl_spmatrix_fread(f, B); status = gsl_spmatrix_equal(A, B) != 1; gsl_test(status, "test_io_binary: fwrite/fread M="F_ZU" N="F_ZU" triplet format", M, N); fclose(f); gsl_spmatrix_free(B); } /* test CCS I/O */ A_ccs = gsl_spmatrix_ccs(A); { FILE *f = fopen(filename, "wb"); gsl_spmatrix_fwrite(f, A_ccs); fclose(f); } { FILE *f = fopen(filename, "rb"); gsl_spmatrix *B = gsl_spmatrix_alloc_nzmax(M, N, A->nz, GSL_SPMATRIX_CCS); gsl_spmatrix_fread(f, B); status = gsl_spmatrix_equal(A_ccs, B) != 1; gsl_test(status, "test_io_binary: fwrite/fread M="F_ZU" N="F_ZU" CCS format", M, N); fclose(f); gsl_spmatrix_free(B); } /* test CRS I/O */ A_crs = gsl_spmatrix_crs(A); { FILE *f = fopen(filename, "wb"); gsl_spmatrix_fwrite(f, A_crs); fclose(f); } { FILE *f = fopen(filename, "rb"); gsl_spmatrix *B = gsl_spmatrix_alloc_nzmax(M, N, A->nz, GSL_SPMATRIX_CRS); gsl_spmatrix_fread(f, B); status = gsl_spmatrix_equal(A_crs, B) != 1; gsl_test(status, "test_io_binary: fwrite/fread M="F_ZU" N="F_ZU" CRS format", M, N); fclose(f); gsl_spmatrix_free(B); } unlink(filename); gsl_spmatrix_free(A); gsl_spmatrix_free(A_ccs); gsl_spmatrix_free(A_crs); }
static void test_io_ascii(const size_t M, const size_t N, const double density, const gsl_rng *r) { int status; gsl_spmatrix *A = create_random_sparse_int(M, N, density, r); char filename[] = "test.XXXXXX"; #if !defined( _WIN32 ) int fd = mkstemp(filename); #else char * fd = _mktemp(filename); # define fdopen fopen #endif /* test triplet I/O */ { FILE *f = fdopen(fd, "w"); gsl_spmatrix_fprintf(f, A, "%lg"); fclose(f); } { FILE *f = fopen(filename, "r"); gsl_spmatrix *B = gsl_spmatrix_fscanf(f); status = gsl_spmatrix_equal(A, B) != 1; gsl_test(status, "test_io_ascii: fprintf/fscanf M="F_ZU" N="F_ZU" triplet format", M, N); fclose(f); gsl_spmatrix_free(B); } /* test CCS I/O */ { FILE *f = fopen(filename, "w"); gsl_spmatrix *A_ccs = gsl_spmatrix_ccs(A); gsl_spmatrix_fprintf(f, A_ccs, "%lg"); fclose(f); gsl_spmatrix_free(A_ccs); } { FILE *f = fopen(filename, "r"); gsl_spmatrix *B = gsl_spmatrix_fscanf(f); status = gsl_spmatrix_equal(A, B) != 1; gsl_test(status, "test_io_ascii: fprintf/fscanf M="F_ZU" N="F_ZU" CCS format", M, N); fclose(f); gsl_spmatrix_free(B); } /* test CRS I/O */ { FILE *f = fopen(filename, "w"); gsl_spmatrix *A_crs = gsl_spmatrix_crs(A); gsl_spmatrix_fprintf(f, A_crs, "%lg"); fclose(f); gsl_spmatrix_free(A_crs); } { FILE *f = fopen(filename, "r"); gsl_spmatrix *B = gsl_spmatrix_fscanf(f); status = gsl_spmatrix_equal(A, B) != 1; gsl_test(status, "test_io_ascii: fprintf/fscanf M="F_ZU" N="F_ZU" CRS format", M, N); fclose(f); gsl_spmatrix_free(B); } unlink(filename); gsl_spmatrix_free(A); }
static void test_memcpy(const size_t M, const size_t N, const double density, const gsl_rng *r) { int status; { gsl_spmatrix *A = create_random_sparse(M, N, density, r); gsl_spmatrix *A_ccs = gsl_spmatrix_ccs(A); gsl_spmatrix *A_crs = gsl_spmatrix_crs(A); gsl_spmatrix *B_t, *B_ccs, *B_crs; B_t = gsl_spmatrix_alloc(M, N); gsl_spmatrix_memcpy(B_t, A); status = gsl_spmatrix_equal(A, B_t) != 1; gsl_test(status, "test_memcpy: _memcpy M="F_ZU" N="F_ZU" triplet format", M, N); B_ccs = gsl_spmatrix_alloc_nzmax(M, N, A_ccs->nzmax, GSL_SPMATRIX_CCS); B_crs = gsl_spmatrix_alloc_nzmax(M, N, A_ccs->nzmax, GSL_SPMATRIX_CRS); gsl_spmatrix_memcpy(B_ccs, A_ccs); gsl_spmatrix_memcpy(B_crs, A_crs); status = gsl_spmatrix_equal(A_ccs, B_ccs) != 1; gsl_test(status, "test_memcpy: _memcpy M="F_ZU" N="F_ZU" CCS", M, N); status = gsl_spmatrix_equal(A_crs, B_crs) != 1; gsl_test(status, "test_memcpy: _memcpy M="F_ZU" N="F_ZU" CRS", M, N); gsl_spmatrix_free(A); gsl_spmatrix_free(A_ccs); gsl_spmatrix_free(A_crs); gsl_spmatrix_free(B_t); gsl_spmatrix_free(B_ccs); gsl_spmatrix_free(B_crs); } /* test transpose_memcpy */ { gsl_spmatrix *A = create_random_sparse(M, N, density, r); gsl_spmatrix *AT = gsl_spmatrix_alloc(N, M); gsl_spmatrix *B = gsl_spmatrix_ccs(A); gsl_spmatrix *BT = gsl_spmatrix_alloc_nzmax(N, M, 1, GSL_SPMATRIX_CCS); gsl_spmatrix *C = gsl_spmatrix_crs(A); gsl_spmatrix *CT = gsl_spmatrix_alloc_nzmax(N, M, 1, GSL_SPMATRIX_CRS); size_t i, j; gsl_spmatrix_transpose_memcpy(AT, A); gsl_spmatrix_transpose_memcpy(BT, B); gsl_spmatrix_transpose_memcpy(CT, C); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Aij = gsl_spmatrix_get(A, i, j); double ATji = gsl_spmatrix_get(AT, j, i); if (Aij != ATji) status = 1; } } gsl_test(status, "test_memcpy: _transpose_memcpy M="F_ZU" N="F_ZU" triplet format", M, N); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Aij = gsl_spmatrix_get(A, i, j); double Bij = gsl_spmatrix_get(B, i, j); double BTji = gsl_spmatrix_get(BT, j, i); if ((Bij != BTji) || (Aij != Bij)) status = 1; } } gsl_test(status, "test_memcpy: _transpose_memcpy M="F_ZU" N="F_ZU" CCS format", M, N); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Aij = gsl_spmatrix_get(A, i, j); double Cij = gsl_spmatrix_get(C, i, j); double CTji = gsl_spmatrix_get(CT, j, i); if ((Cij != CTji) || (Aij != Cij)) status = 1; } } gsl_test(status, "test_memcpy: _transpose_memcpy M="F_ZU" N="F_ZU" CRS format", M, N); gsl_spmatrix_free(A); gsl_spmatrix_free(AT); gsl_spmatrix_free(B); gsl_spmatrix_free(BT); gsl_spmatrix_free(C); gsl_spmatrix_free(CT); } } /* test_memcpy() */
static void test_transpose(const size_t M, const size_t N, const double density, const gsl_rng *r) { int status; gsl_spmatrix *A = create_random_sparse(M, N, density, r); gsl_spmatrix *AT = gsl_spmatrix_alloc_nzmax(M, N, A->nz, A->sptype); gsl_spmatrix *AT2 = gsl_spmatrix_alloc_nzmax(M, N, A->nz, A->sptype); gsl_spmatrix *AT2_ccs, *AT2_crs; size_t i, j; /* test triplet transpose */ gsl_spmatrix_memcpy(AT, A); gsl_spmatrix_memcpy(AT2, A); gsl_spmatrix_transpose(AT); gsl_spmatrix_transpose2(AT2); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Aij = gsl_spmatrix_get(A, i, j); double ATji = gsl_spmatrix_get(AT, j, i); double AT2ji = gsl_spmatrix_get(AT2, j, i); if (Aij != ATji) status = 1; if (Aij != AT2ji) status = 2; } } gsl_test(status == 1, "test_transpose: transpose M="F_ZU" N="F_ZU" triplet format", M, N); gsl_test(status == 2, "test_transpose: transpose2 M="F_ZU" N="F_ZU" triplet format", M, N); /* test CCS transpose */ AT2_ccs = gsl_spmatrix_ccs(A); gsl_spmatrix_transpose2(AT2_ccs); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Aij = gsl_spmatrix_get(A, i, j); double AT2ji = gsl_spmatrix_get(AT2_ccs, j, i); if (Aij != AT2ji) status = 2; } } gsl_test(status == 2, "test_transpose: transpose2 M="F_ZU" N="F_ZU" CCS format", M, N); /* test CRS transpose */ AT2_crs = gsl_spmatrix_crs(A); gsl_spmatrix_transpose2(AT2_crs); status = 0; for (i = 0; i < M; ++i) { for (j = 0; j < N; ++j) { double Aij = gsl_spmatrix_get(A, i, j); double AT2ji = gsl_spmatrix_get(AT2_crs, j, i); if (Aij != AT2ji) status = 2; } } gsl_test(status == 2, "test_transpose: transpose2 M="F_ZU" N="F_ZU" CRS format", M, N); gsl_spmatrix_free(A); gsl_spmatrix_free(AT); gsl_spmatrix_free(AT2); gsl_spmatrix_free(AT2_ccs); gsl_spmatrix_free(AT2_crs); }