/**
* @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;
}