|
Packit |
67cb25 |
/* spcompress.c
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* Copyright (C) 2012-2014, 2016 Patrick Alken
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
67cb25 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
67cb25 |
* the Free Software Foundation; either version 3 of the License, or (at
|
|
Packit |
67cb25 |
* your option) any later version.
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
67cb25 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
67cb25 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
67cb25 |
* General Public License for more details.
|
|
Packit |
67cb25 |
*
|
|
Packit |
67cb25 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
67cb25 |
* along with this program; if not, write to the Free Software
|
|
Packit |
67cb25 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
#include <config.h>
|
|
Packit |
67cb25 |
#include <stdlib.h>
|
|
Packit |
67cb25 |
#include <math.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_math.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_errno.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_spmatrix.h>
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/*
|
|
Packit |
67cb25 |
gsl_spmatrix_ccs()
|
|
Packit |
67cb25 |
Create a sparse matrix in compressed column format
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Inputs: T - sparse matrix in triplet format
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Return: pointer to new matrix (should be freed when finished with it)
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_spmatrix *
|
|
Packit |
67cb25 |
gsl_spmatrix_ccs(const gsl_spmatrix *T)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (!GSL_SPMATRIX_ISTRIPLET(T))
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_ERROR_NULL("matrix must be in triplet format", GSL_EINVAL);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const size_t *Tj; /* column indices of triplet matrix */
|
|
Packit |
67cb25 |
size_t *Cp; /* column pointers of compressed column matrix */
|
|
Packit |
67cb25 |
size_t *w; /* copy of column pointers */
|
|
Packit |
67cb25 |
gsl_spmatrix *m;
|
|
Packit |
67cb25 |
size_t n;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
m = gsl_spmatrix_alloc_nzmax(T->size1, T->size2, T->nz,
|
|
Packit |
67cb25 |
GSL_SPMATRIX_CCS);
|
|
Packit |
67cb25 |
if (!m)
|
|
Packit |
67cb25 |
return NULL;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Tj = T->p;
|
|
Packit |
67cb25 |
Cp = m->p;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* initialize column pointers to 0 */
|
|
Packit |
67cb25 |
for (n = 0; n < m->size2 + 1; ++n)
|
|
Packit |
67cb25 |
Cp[n] = 0;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/*
|
|
Packit |
67cb25 |
* compute the number of elements in each column:
|
|
Packit |
67cb25 |
* Cp[j] = # non-zero elements in column j
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
for (n = 0; n < T->nz; ++n)
|
|
Packit |
67cb25 |
Cp[Tj[n]]++;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* compute column pointers: p[j] = p[j-1] + nnz[j-1] */
|
|
Packit |
67cb25 |
gsl_spmatrix_cumsum(m->size2, Cp);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* make a copy of the column pointers */
|
|
Packit |
67cb25 |
w = m->work_sze;
|
|
Packit |
67cb25 |
for (n = 0; n < m->size2; ++n)
|
|
Packit |
67cb25 |
w[n] = Cp[n];
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* transfer data from triplet format to CCS */
|
|
Packit |
67cb25 |
for (n = 0; n < T->nz; ++n)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t k = w[Tj[n]]++;
|
|
Packit |
67cb25 |
m->i[k] = T->i[n];
|
|
Packit |
67cb25 |
m->data[k] = T->data[n];
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
m->nz = T->nz;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return m;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_spmatrix *
|
|
Packit |
67cb25 |
gsl_spmatrix_compcol(const gsl_spmatrix *T)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
return gsl_spmatrix_ccs(T);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/*
|
|
Packit |
67cb25 |
gsl_spmatrix_crs()
|
|
Packit |
67cb25 |
Create a sparse matrix in compressed row format
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Inputs: T - sparse matrix in triplet format
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Return: pointer to new matrix (should be freed when finished with it)
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_spmatrix *
|
|
Packit |
67cb25 |
gsl_spmatrix_crs(const gsl_spmatrix *T)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
if (!GSL_SPMATRIX_ISTRIPLET(T))
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
GSL_ERROR_NULL("matrix must be in triplet format", GSL_EINVAL);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const size_t *Ti; /* row indices of triplet matrix */
|
|
Packit |
67cb25 |
size_t *Cp; /* row pointers of compressed row matrix */
|
|
Packit |
67cb25 |
size_t *w; /* copy of column pointers */
|
|
Packit |
67cb25 |
gsl_spmatrix *m;
|
|
Packit |
67cb25 |
size_t n;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
m = gsl_spmatrix_alloc_nzmax(T->size1, T->size2, T->nz,
|
|
Packit |
67cb25 |
GSL_SPMATRIX_CRS);
|
|
Packit |
67cb25 |
if (!m)
|
|
Packit |
67cb25 |
return NULL;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Ti = T->i;
|
|
Packit |
67cb25 |
Cp = m->p;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* initialize row pointers to 0 */
|
|
Packit |
67cb25 |
for (n = 0; n < m->size1 + 1; ++n)
|
|
Packit |
67cb25 |
Cp[n] = 0;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/*
|
|
Packit |
67cb25 |
* compute the number of elements in each row:
|
|
Packit |
67cb25 |
* Cp[i] = # non-zero elements in row i
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
for (n = 0; n < T->nz; ++n)
|
|
Packit |
67cb25 |
Cp[Ti[n]]++;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* compute row pointers: p[i] = p[i-1] + nnz[i-1] */
|
|
Packit |
67cb25 |
gsl_spmatrix_cumsum(m->size1, Cp);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* make a copy of the row pointers */
|
|
Packit |
67cb25 |
w = m->work_sze;
|
|
Packit |
67cb25 |
for (n = 0; n < m->size1; ++n)
|
|
Packit |
67cb25 |
w[n] = Cp[n];
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* transfer data from triplet format to CRS */
|
|
Packit |
67cb25 |
for (n = 0; n < T->nz; ++n)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t k = w[Ti[n]]++;
|
|
Packit |
67cb25 |
m->i[k] = T->p[n];
|
|
Packit |
67cb25 |
m->data[k] = T->data[n];
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
m->nz = T->nz;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return m;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/*
|
|
Packit |
67cb25 |
gsl_spmatrix_cumsum()
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Compute the cumulative sum:
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
p[j] = Sum_{k=0...j-1} c[k]
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
0 <= j < n + 1
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Alternatively,
|
|
Packit |
67cb25 |
p[0] = 0
|
|
Packit |
67cb25 |
p[j] = p[j - 1] + c[j - 1]
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Inputs: n - length of input array
|
|
Packit |
67cb25 |
c - (input/output) array of size n + 1
|
|
Packit |
67cb25 |
on input, contains the n values c[k]
|
|
Packit |
67cb25 |
on output, contains the n + 1 values p[j]
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
Return: success or error
|
|
Packit |
67cb25 |
*/
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
void
|
|
Packit |
67cb25 |
gsl_spmatrix_cumsum(const size_t n, size_t *c)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t sum = 0;
|
|
Packit |
67cb25 |
size_t k;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (k = 0; k < n; ++k)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t ck = c[k];
|
|
Packit |
67cb25 |
c[k] = sum;
|
|
Packit |
67cb25 |
sum += ck;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
c[n] = sum;
|
|
Packit |
67cb25 |
} /* gsl_spmatrix_cumsum() */
|