/** * @file gensvm_sparse.c * @author G.J.J. van den Burg * @date 2016-10-11 * @brief Functions for dealing with sparse data matrices * * @copyright Copyright 2016, G.J.J. van den Burg. This file is part of GenSVM. GenSVM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GenSVM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GenSVM. If not, see . */ #include "gensvm_sparse.h" /** * @brief Initialize a GenSparse structure * * @details * A GenSparse structure is used to hold a sparse data matrix. We work with * Compressed Row Storage (CSR) storage, also known as old Yale format. * * @return initialized GenSparse instance */ struct GenSparse *gensvm_init_sparse(void) { struct GenSparse *sp = Malloc(struct GenSparse, 1); sp->nnz = 0; sp->n_row = 0; sp->n_col = 0; sp->values = NULL; sp->ia = NULL; sp->ja = NULL; return sp; } /** * @brief Free an allocated GenSparse structure * * @details * Simply free a previously allocated GenSparse structure by freeing all of * its components. Finally, the structure itself is freed, and the pointer is * set to NULL for safety. * * @param[in] sp GenSparse structure to free */ void gensvm_free_sparse(struct GenSparse *sp) { free(sp->values); free(sp->ia); free(sp->ja); free(sp); sp = NULL; } /** * @brief Count the number of nonzeros in a matrix * * @details * This is a utility function to count the number of nonzeros in a dense * matrix. This is simply done by comparing with 0.0. * * @param[in] A a dense matrix (RowMajor order) * @param[in] rows the number of rows of A * @param[in] cols the number of columns of A * * @return the number of nonzeros in A */ long gensvm_count_nnz(double *A, long rows, long cols) { long i, nnz = 0; for (i=0; innz = nnz; spA->n_row = rows; spA->n_col = cols; spA->values = Calloc(double, nnz); spA->ia = Calloc(long, rows+1); spA->ja = Calloc(long, nnz); cnt = 0; spA->ia[0] = 0; for (i=0; ivalues[cnt] = value; spA->ja[cnt] = j; cnt++; } } spA->ia[i+1] = spA->ia[i] + row_cnt; } return spA; } /** * @brief Convert a GenSparse structure to a dense matrix * * @details * This function converts a GenSparse structure back to a normal dense matrix * in RowMajor order. Note that the allocated memory must be freed by the * caller. * * @param[in] A a GenSparse structure * * @return a dense matrix */ double *gensvm_sparse_to_dense(struct GenSparse *A) { double value; long i, j, jj; double *B = Calloc(double, (A->n_row)*(A->n_col)); for (i=0; in_row; i++) { for (jj=A->ia[i]; jjia[i+1]; jj++) { j = A->ja[jj]; value = A->values[jj]; matrix_set(B, A->n_col, i, j, value); } } return B; }