double gsl_spmatrix_get(const gsl_spmatrix *m, const size_t i, const size_t j) { if (i >= m->size1) { GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0.0); } else if (j >= m->size2) { GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0.0); } else { if (GSL_SPMATRIX_ISTRIPLET(m)) { /* traverse binary tree to search for (i,j) element */ void *ptr = tree_find(m, i, j); double x = ptr ? *(double *) ptr : 0.0; return x; } else if (GSL_SPMATRIX_ISCCS(m)) { const size_t *mi = m->i; const size_t *mp = m->p; size_t p; /* loop over column j and search for row index i */ for (p = mp[j]; p < mp[j + 1]; ++p) { if (mi[p] == i) return m->data[p]; } } else if (GSL_SPMATRIX_ISCRS(m)) { const size_t *mi = m->i; const size_t *mp = m->p; size_t p; /* loop over row i and search for column index j */ for (p = mp[i]; p < mp[i + 1]; ++p) { if (mi[p] == j) return m->data[p]; } } else { GSL_ERROR_VAL("unknown sparse matrix type", GSL_EINVAL, 0.0); } /* element not found; return 0 */ return 0.0; } } /* gsl_spmatrix_get() */
/** * \brief Divide each column of a compressed matrix by a vector. * * Divide each column of a compressed matrix by the corresponding vector element. * \param[in] m compressed matrix to divide. * \param[in] v vector to divide the columns of the sparse matrix. * \param[in] tol threshold under which to avoid division by zero. * \return Exit status. */ int gsl_spmatrix_div_cols(gsl_spmatrix *m, const gsl_vector *v, const double tol) { size_t outerIdx, p, n; if (GSL_SPMATRIX_ISTRIPLET(m)) { for (n = 0; n < m->nz; n++) { if (gsl_pow_2(v->data[m->p[n] * v->stride]) > tol) { m->data[n] = m->data[n] / v->data[m->p[n] * v->stride]; } } } else if (GSL_SPMATRIX_ISCCS(m)) { for (outerIdx = 0; outerIdx < m->outerSize; outerIdx++) { for (p = m->p[outerIdx]; p < m->p[outerIdx + 1]; ++p) { if (gsl_pow_2(v->data[outerIdx * v->stride]) > tol) { m->data[p] /= v->data[outerIdx * v->stride]; } } } } else if (GSL_SPMATRIX_ISCRS(m)) { for (outerIdx = 0; outerIdx < m->outerSize; outerIdx++) { for (p = m->p[outerIdx]; p < m->p[outerIdx + 1]; ++p) { if (gsl_pow_2(v->data[m->i[p] * v->stride]) > tol) { m->data[p] /= v->data[m->i[p] * v->stride]; } } } } else { GSL_ERROR("unknown sparse matrix type", GSL_EINVAL); } return GSL_SUCCESS; }
/** \brief Get the sum of the elements of a compressed matrix over each column. * * Get the sum of the elements of a compressed matrix over each column. * \param[out] sum Resulting vector of the sum of the columns. * \param[in] m Compressed matrix over which to sum. * \return Exit status. */ int gsl_spmatrix_get_colsum(gsl_vector *sum, const gsl_spmatrix *m) { size_t outerIdx, p, n; if (GSL_SPMATRIX_ISTRIPLET(m)) { for (n = 0; n < m->nz; n++) { sum->data[m->p[n] * sum->stride] += m->data[n]; } } else if (GSL_SPMATRIX_ISCCS(m)) { for (outerIdx = 0; outerIdx < m->outerSize; outerIdx++) { for (p = m->p[outerIdx]; p < m->p[outerIdx + 1]; ++p) { sum->data[outerIdx * sum->stride] += m->data[p]; } } } else if (GSL_SPMATRIX_ISCRS(m)) { for (outerIdx = 0; outerIdx < m->outerSize; outerIdx++) { for (p = m->p[outerIdx]; p < m->p[outerIdx + 1]; ++p) { sum->data[m->i[p] * sum->stride] += m->data[p]; } } } else { GSL_ERROR("unknown sparse matrix type", GSL_EINVAL); } return GSL_SUCCESS; }
int gsl_spblas_dgemv(const CBLAS_TRANSPOSE_t TransA, const double alpha, const gsl_spmatrix *A, const gsl_vector *x, const double beta, gsl_vector *y) { const size_t M = A->size1; const size_t N = A->size2; if ((TransA == CblasNoTrans && N != x->size) || (TransA == CblasTrans && M != x->size)) { GSL_ERROR("invalid length of x vector", GSL_EBADLEN); } else if ((TransA == CblasNoTrans && M != y->size) || (TransA == CblasTrans && N != y->size)) { GSL_ERROR("invalid length of y vector", GSL_EBADLEN); } else { size_t j, p; size_t incX, incY; size_t lenX, lenY; double *X, *Y; double *Ad; size_t *Ap, *Ai, *Aj; if (TransA == CblasNoTrans) { lenX = N; lenY = M; } else { lenX = M; lenY = N; } /* form y := beta*y */ Y = y->data; incY = y->stride; if (beta == 0.0) { size_t jy = 0; for (j = 0; j < lenY; ++j) { Y[jy] = 0.0; jy += incY; } } else if (beta != 1.0) { size_t jy = 0; for (j = 0; j < lenY; ++j) { Y[jy] *= beta; jy += incY; } } if (alpha == 0.0) return GSL_SUCCESS; /* form y := alpha*op(A)*x + y */ Ap = A->p; Ad = A->data; X = x->data; incX = x->stride; if ((GSL_SPMATRIX_ISCCS(A) && (TransA == CblasNoTrans)) || (GSL_SPMATRIX_ISCRS(A) && (TransA == CblasTrans))) { Ai = A->i; for (j = 0; j < lenX; ++j) { for (p = Ap[j]; p < Ap[j + 1]; ++p) { Y[Ai[p] * incY] += alpha * Ad[p] * X[j * incX]; } } } else if ((GSL_SPMATRIX_ISCCS(A) && (TransA == CblasTrans)) || (GSL_SPMATRIX_ISCRS(A) && (TransA == CblasNoTrans))) { Ai = A->i; for (j = 0; j < lenY; ++j) { for (p = Ap[j]; p < Ap[j + 1]; ++p) { Y[j * incY] += alpha * Ad[p] * X[Ai[p] * incX]; } } } else if (GSL_SPMATRIX_ISTRIPLET(A)) { if (TransA == CblasNoTrans) { Ai = A->i; Aj = A->p; } else { Ai = A->p; Aj = A->i; } for (p = 0; p < A->nz; ++p) { Y[Ai[p] * incY] += alpha * Ad[p] * X[Aj[p] * incX]; } } else { GSL_ERROR("unsupported matrix type", GSL_EINVAL); } return GSL_SUCCESS; } } /* gsl_spblas_dgemv() */