Blame spmatrix/test.c

Packit 67cb25
/* test.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 <stdio.h>
Packit 67cb25
#include <stdlib.h>
Packit 67cb25
#include <math.h>
Packit 67cb25
#include <unistd.h>
Packit 67cb25
Packit 67cb25
#include <gsl/gsl_math.h>
Packit 67cb25
#include <gsl/gsl_errno.h>
Packit 67cb25
#include <gsl/gsl_randist.h>
Packit 67cb25
#include <gsl/gsl_rng.h>
Packit 67cb25
#include <gsl/gsl_matrix.h>
Packit 67cb25
#include <gsl/gsl_vector.h>
Packit 67cb25
#include <gsl/gsl_test.h>
Packit 67cb25
#include <gsl/gsl_blas.h>
Packit 67cb25
#include <gsl/gsl_spmatrix.h>
Packit 67cb25
Packit 67cb25
/*
Packit 67cb25
create_random_sparse()
Packit 67cb25
  Create a random sparse matrix with approximately
Packit 67cb25
M*N*density non-zero entries
Packit 67cb25
Packit 67cb25
Inputs: M       - number of rows
Packit 67cb25
        N       - number of columns
Packit 67cb25
        density - sparse density \in [0,1]
Packit 67cb25
                  0 = no non-zero entries
Packit 67cb25
                  1 = all m*n entries are filled
Packit 67cb25
        r       - random number generator
Packit 67cb25
Packit 67cb25
Return: pointer to sparse matrix in triplet format (must be freed by caller)
Packit 67cb25
Packit 67cb25
Notes:
Packit 67cb25
1) non-zero matrix entries are uniformly distributed in [0,1]
Packit 67cb25
*/
Packit 67cb25
Packit 67cb25
static gsl_spmatrix *
Packit 67cb25
create_random_sparse(const size_t M, const size_t N, const double density,
Packit 67cb25
                     const gsl_rng *r)
Packit 67cb25
{
Packit 67cb25
  size_t nnzwanted = (size_t) floor(M * N * GSL_MIN(density, 1.0));
Packit 67cb25
  gsl_spmatrix *m = gsl_spmatrix_alloc_nzmax(M, N,
Packit 67cb25
                                             nnzwanted,
Packit 67cb25
                                             GSL_SPMATRIX_TRIPLET);
Packit 67cb25
Packit 67cb25
  while (gsl_spmatrix_nnz(m) < nnzwanted)
Packit 67cb25
    {
Packit 67cb25
      /* generate a random row and column */
Packit 67cb25
      size_t i = gsl_rng_uniform(r) * M;
Packit 67cb25
      size_t j = gsl_rng_uniform(r) * N;
Packit 67cb25
Packit 67cb25
      /* generate random m_{ij} and add it */
Packit 67cb25
      double x = gsl_rng_uniform(r);
Packit 67cb25
      gsl_spmatrix_set(m, i, j, x);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  return m;
Packit 67cb25
} /* create_random_sparse() */
Packit 67cb25
Packit 67cb25
static gsl_spmatrix *
Packit 67cb25
create_random_sparse_int(const size_t M, const size_t N, const double density,
Packit 67cb25
                         const gsl_rng *r)
Packit 67cb25
{
Packit 67cb25
  const double lower = 1.0;
Packit 67cb25
  const double upper = 10.0;
Packit 67cb25
  size_t nnzwanted = (size_t) floor(M * N * GSL_MIN(density, 1.0));
Packit 67cb25
  gsl_spmatrix *m = gsl_spmatrix_alloc_nzmax(M, N,
Packit 67cb25
                                             nnzwanted,
Packit 67cb25
                                             GSL_SPMATRIX_TRIPLET);
Packit 67cb25
Packit 67cb25
  while (gsl_spmatrix_nnz(m) < nnzwanted)
Packit 67cb25
    {
Packit 67cb25
      /* generate a random row and column */
Packit 67cb25
      size_t i = gsl_rng_uniform(r) * M;
Packit 67cb25
      size_t j = gsl_rng_uniform(r) * N;
Packit 67cb25
Packit 67cb25
      /* generate random m_{ij} and add it */
Packit 67cb25
      int x = (int) (gsl_rng_uniform(r) * (upper - lower) + lower);
Packit 67cb25
      gsl_spmatrix_set(m, i, j, (double) x);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  return m;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
static void
Packit 67cb25
test_getset(const size_t M, const size_t N,
Packit 67cb25
            const double density, const gsl_rng *r)
Packit 67cb25
{
Packit 67cb25
  int status;
Packit 67cb25
  size_t i, j;
Packit 67cb25
Packit 67cb25
  /* test that a newly allocated matrix is initialized to zero */
Packit 67cb25
  {
Packit 67cb25
    size_t nzmax = (size_t) (0.5 * M * N);
Packit 67cb25
    gsl_spmatrix *mt = gsl_spmatrix_alloc_nzmax(M, N, nzmax, GSL_SPMATRIX_TRIPLET);
Packit 67cb25
    gsl_spmatrix *mccs = gsl_spmatrix_alloc_nzmax(M, N, nzmax, GSL_SPMATRIX_CCS);
Packit 67cb25
    gsl_spmatrix *mcrs = gsl_spmatrix_alloc_nzmax(M, N, nzmax, GSL_SPMATRIX_CRS);
Packit 67cb25
Packit 67cb25
    status = 0;
Packit 67cb25
    for (i = 0; i < M; ++i)
Packit 67cb25
      {
Packit 67cb25
        for (j = 0; j < N; ++j)
Packit 67cb25
          {
Packit 67cb25
            double mtij = gsl_spmatrix_get(mt, i, j);
Packit 67cb25
            double mcij = gsl_spmatrix_get(mccs, i, j);
Packit 67cb25
            double mrij = gsl_spmatrix_get(mcrs, i, j);
Packit 67cb25
Packit 67cb25
            if (mtij != 0.0)
Packit 67cb25
              status = 1;
Packit 67cb25
Packit 67cb25
            if (mcij != 0.0)
Packit 67cb25
              status = 2;
Packit 67cb25
Packit 67cb25
            if (mrij != 0.0)
Packit 67cb25
              status = 3;
Packit 67cb25
          }
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    gsl_test(status == 1, "test_getset: triplet M=%zu N=%zu not initialized to zero", M, N);
Packit 67cb25
    gsl_test(status == 2, "test_getset: CCS M=%zu N=%zu not initialized to zero", M, N);
Packit 67cb25
    gsl_test(status == 3, "test_getset: CRS M=%zu N=%zu not initialized to zero", M, N);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_free(mt);
Packit 67cb25
    gsl_spmatrix_free(mccs);
Packit 67cb25
    gsl_spmatrix_free(mcrs);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  /* test triplet versions of _get and _set */
Packit 67cb25
  {
Packit 67cb25
    const double val = 0.75;
Packit 67cb25
    size_t k = 0;
Packit 67cb25
    gsl_spmatrix *m = gsl_spmatrix_alloc(M, N);
Packit 67cb25
Packit 67cb25
    status = 0;
Packit 67cb25
    for (i = 0; i < M; ++i)
Packit 67cb25
      {
Packit 67cb25
        for (j = 0; j < N; ++j)
Packit 67cb25
          {
Packit 67cb25
            double x = (double) ++k;
Packit 67cb25
            double y;
Packit 67cb25
Packit 67cb25
            gsl_spmatrix_set(m, i, j, x);
Packit 67cb25
            y = gsl_spmatrix_get(m, i, j);
Packit 67cb25
            if (x != y)
Packit 67cb25
              status = 1;
Packit 67cb25
          }
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    gsl_test(status, "test_getset: M=%zu N=%zu _get != _set", M, N);
Packit 67cb25
Packit 67cb25
    /* test setting an element to 0 */
Packit 67cb25
    gsl_spmatrix_set(m, 0, 0, 1.0);
Packit 67cb25
    gsl_spmatrix_set(m, 0, 0, 0.0);
Packit 67cb25
Packit 67cb25
    status = gsl_spmatrix_get(m, 0, 0) != 0.0;
Packit 67cb25
    gsl_test(status, "test_getset: M=%zu N=%zu m(0,0) = %f",
Packit 67cb25
             M, N, gsl_spmatrix_get(m, 0, 0));
Packit 67cb25
Packit 67cb25
    /* test gsl_spmatrix_set_zero() */
Packit 67cb25
    gsl_spmatrix_set(m, 0, 0, 1.0);
Packit 67cb25
    gsl_spmatrix_set_zero(m);
Packit 67cb25
    status = gsl_spmatrix_get(m, 0, 0) != 0.0;
Packit 67cb25
    gsl_test(status, "test_getset: M=%zu N=%zu set_zero m(0,0) = %f",
Packit 67cb25
             M, N, gsl_spmatrix_get(m, 0, 0));
Packit 67cb25
Packit 67cb25
    /* resassemble matrix to ensure nz is calculated correctly */
Packit 67cb25
    k = 0;
Packit 67cb25
    for (i = 0; i < M; ++i)
Packit 67cb25
      {
Packit 67cb25
        for (j = 0; j < N; ++j)
Packit 67cb25
          {
Packit 67cb25
            double x = (double) ++k;
Packit 67cb25
            gsl_spmatrix_set(m, i, j, x);
Packit 67cb25
          }
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    status = gsl_spmatrix_nnz(m) != M * N;
Packit 67cb25
    gsl_test(status, "test_getset: M=%zu N=%zu set_zero nz = %zu",
Packit 67cb25
             M, N, gsl_spmatrix_nnz(m));
Packit 67cb25
Packit 67cb25
    /* test gsl_spmatrix_ptr() */
Packit 67cb25
    status = 0;
Packit 67cb25
    for (i = 0; i < M; ++i)
Packit 67cb25
      {
Packit 67cb25
        for (j = 0; j < N; ++j)
Packit 67cb25
          {
Packit 67cb25
            double mij = gsl_spmatrix_get(m, i, j);
Packit 67cb25
            double *ptr = gsl_spmatrix_ptr(m, i, j);
Packit 67cb25
Packit 67cb25
            *ptr += val;
Packit 67cb25
            if (gsl_spmatrix_get(m, i, j) != mij + val)
Packit 67cb25
              status = 2;
Packit 67cb25
          }
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    gsl_test(status == 2, "test_getset: M=%zu N=%zu triplet ptr", M, N);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_free(m);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  /* test duplicate values are handled correctly */
Packit 67cb25
  {
Packit 67cb25
    size_t min = GSL_MIN(M, N);
Packit 67cb25
    size_t expected_nnz = min;
Packit 67cb25
    size_t nnz;
Packit 67cb25
    size_t k = 0;
Packit 67cb25
    gsl_spmatrix *m = gsl_spmatrix_alloc(M, N);
Packit 67cb25
Packit 67cb25
    status = 0;
Packit 67cb25
    for (i = 0; i < min; ++i)
Packit 67cb25
      {
Packit 67cb25
        for (j = 0; j < 5; ++j)
Packit 67cb25
          {
Packit 67cb25
            double x = (double) ++k;
Packit 67cb25
            double y;
Packit 67cb25
Packit 67cb25
            gsl_spmatrix_set(m, i, i, x);
Packit 67cb25
            y = gsl_spmatrix_get(m, i, i);
Packit 67cb25
            if (x != y)
Packit 67cb25
              status = 1;
Packit 67cb25
          }
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    gsl_test(status, "test_getset: duplicate test M=%zu N=%zu _get != _set", M, N);
Packit 67cb25
Packit 67cb25
    nnz = gsl_spmatrix_nnz(m);
Packit 67cb25
    status = nnz != expected_nnz;
Packit 67cb25
    gsl_test(status, "test_getset: duplicate test M=%zu N=%zu nnz=%zu, expected=%zu",
Packit 67cb25
             M, N, nnz, expected_nnz);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_free(m);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  /* test CCS version of gsl_spmatrix_get() */
Packit 67cb25
  {
Packit 67cb25
    const double val = 0.75;
Packit 67cb25
    gsl_spmatrix *T = create_random_sparse(M, N, density, r);
Packit 67cb25
    gsl_spmatrix *C = gsl_spmatrix_ccs(T);
Packit 67cb25
Packit 67cb25
    status = 0;
Packit 67cb25
    for (i = 0; i < M; ++i)
Packit 67cb25
      {
Packit 67cb25
        for (j = 0; j < N; ++j)
Packit 67cb25
          {
Packit 67cb25
            double Tij = gsl_spmatrix_get(T, i, j);
Packit 67cb25
            double Cij = gsl_spmatrix_get(C, i, j);
Packit 67cb25
            double *ptr = gsl_spmatrix_ptr(C, i, j);
Packit 67cb25
Packit 67cb25
            if (Tij != Cij)
Packit 67cb25
              status = 1;
Packit 67cb25
Packit 67cb25
            if (ptr)
Packit 67cb25
              {
Packit 67cb25
                *ptr += val;
Packit 67cb25
                Cij = gsl_spmatrix_get(C, i, j);
Packit 67cb25
                if (Tij + val != Cij)
Packit 67cb25
                  status = 2;
Packit 67cb25
              }
Packit 67cb25
          }
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    gsl_test(status == 1, "test_getset: M=%zu N=%zu CCS get", M, N);
Packit 67cb25
    gsl_test(status == 2, "test_getset: M=%zu N=%zu CCS ptr", M, N);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_free(T);
Packit 67cb25
    gsl_spmatrix_free(C);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  /* test CRS version of gsl_spmatrix_get() */
Packit 67cb25
  {
Packit 67cb25
    const double val = 0.75;
Packit 67cb25
    gsl_spmatrix *T = create_random_sparse(M, N, density, r);
Packit 67cb25
    gsl_spmatrix *C = gsl_spmatrix_crs(T);
Packit 67cb25
Packit 67cb25
    status = 0;
Packit 67cb25
    for (i = 0; i < M; ++i)
Packit 67cb25
      {
Packit 67cb25
        for (j = 0; j < N; ++j)
Packit 67cb25
          {
Packit 67cb25
            double Tij = gsl_spmatrix_get(T, i, j);
Packit 67cb25
            double Cij = gsl_spmatrix_get(C, i, j);
Packit 67cb25
            double *ptr = gsl_spmatrix_ptr(C, i, j);
Packit 67cb25
Packit 67cb25
            if (Tij != Cij)
Packit 67cb25
              status = 1;
Packit 67cb25
Packit 67cb25
            if (ptr)
Packit 67cb25
              {
Packit 67cb25
                *ptr += val;
Packit 67cb25
                Cij = gsl_spmatrix_get(C, i, j);
Packit 67cb25
                if (Tij + val != Cij)
Packit 67cb25
                  status = 2;
Packit 67cb25
              }
Packit 67cb25
          }
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    gsl_test(status == 1, "test_getset: M=%zu N=%zu CRS get", M, N);
Packit 67cb25
    gsl_test(status == 2, "test_getset: M=%zu N=%zu CRS ptr", M, N);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_free(T);
Packit 67cb25
    gsl_spmatrix_free(C);
Packit 67cb25
  }
Packit 67cb25
} /* test_getset() */
Packit 67cb25
Packit 67cb25
static void
Packit 67cb25
test_memcpy(const size_t M, const size_t N,
Packit 67cb25
            const double density, const gsl_rng *r)
Packit 67cb25
{
Packit 67cb25
  int status;
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    gsl_spmatrix *A = create_random_sparse(M, N, density, r);
Packit 67cb25
    gsl_spmatrix *A_ccs = gsl_spmatrix_ccs(A);
Packit 67cb25
    gsl_spmatrix *A_crs = gsl_spmatrix_crs(A);
Packit 67cb25
    gsl_spmatrix *B_t, *B_ccs, *B_crs;
Packit 67cb25
  
Packit 67cb25
    B_t = gsl_spmatrix_alloc(M, N);
Packit 67cb25
    gsl_spmatrix_memcpy(B_t, A);
Packit 67cb25
Packit 67cb25
    status = gsl_spmatrix_equal(A, B_t) != 1;
Packit 67cb25
    gsl_test(status, "test_memcpy: _memcpy M=%zu N=%zu triplet format", M, N);
Packit 67cb25
Packit 67cb25
    B_ccs = gsl_spmatrix_alloc_nzmax(M, N, A_ccs->nzmax, GSL_SPMATRIX_CCS);
Packit 67cb25
    B_crs = gsl_spmatrix_alloc_nzmax(M, N, A_ccs->nzmax, GSL_SPMATRIX_CRS);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_memcpy(B_ccs, A_ccs);
Packit 67cb25
    gsl_spmatrix_memcpy(B_crs, A_crs);
Packit 67cb25
Packit 67cb25
    status = gsl_spmatrix_equal(A_ccs, B_ccs) != 1;
Packit 67cb25
    gsl_test(status, "test_memcpy: _memcpy M=%zu N=%zu CCS", M, N);
Packit 67cb25
Packit 67cb25
    status = gsl_spmatrix_equal(A_crs, B_crs) != 1;
Packit 67cb25
    gsl_test(status, "test_memcpy: _memcpy M=%zu N=%zu CRS", M, N);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_free(A);
Packit 67cb25
    gsl_spmatrix_free(A_ccs);
Packit 67cb25
    gsl_spmatrix_free(A_crs);
Packit 67cb25
    gsl_spmatrix_free(B_t);
Packit 67cb25
    gsl_spmatrix_free(B_ccs);
Packit 67cb25
    gsl_spmatrix_free(B_crs);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  /* test transpose_memcpy */
Packit 67cb25
  {
Packit 67cb25
    gsl_spmatrix *A = create_random_sparse(M, N, density, r);
Packit 67cb25
    gsl_spmatrix *AT = gsl_spmatrix_alloc(N, M);
Packit 67cb25
    gsl_spmatrix *B = gsl_spmatrix_ccs(A);
Packit 67cb25
    gsl_spmatrix *BT = gsl_spmatrix_alloc_nzmax(N, M, 1, GSL_SPMATRIX_CCS);
Packit 67cb25
    gsl_spmatrix *C = gsl_spmatrix_crs(A);
Packit 67cb25
    gsl_spmatrix *CT = gsl_spmatrix_alloc_nzmax(N, M, 1, GSL_SPMATRIX_CRS);
Packit 67cb25
    size_t i, j;
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_transpose_memcpy(AT, A);
Packit 67cb25
    gsl_spmatrix_transpose_memcpy(BT, B);
Packit 67cb25
    gsl_spmatrix_transpose_memcpy(CT, C);
Packit 67cb25
Packit 67cb25
    status = 0;
Packit 67cb25
    for (i = 0; i < M; ++i)
Packit 67cb25
      {
Packit 67cb25
        for (j = 0; j < N; ++j)
Packit 67cb25
          {
Packit 67cb25
            double Aij = gsl_spmatrix_get(A, i, j);
Packit 67cb25
            double ATji = gsl_spmatrix_get(AT, j, i);
Packit 67cb25
Packit 67cb25
            if (Aij != ATji)
Packit 67cb25
              status = 1;
Packit 67cb25
          }
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    gsl_test(status, "test_memcpy: _transpose_memcpy M=%zu N=%zu triplet format", M, N);
Packit 67cb25
Packit 67cb25
    status = 0;
Packit 67cb25
    for (i = 0; i < M; ++i)
Packit 67cb25
      {
Packit 67cb25
        for (j = 0; j < N; ++j)
Packit 67cb25
          {
Packit 67cb25
            double Aij = gsl_spmatrix_get(A, i, j);
Packit 67cb25
            double Bij = gsl_spmatrix_get(B, i, j);
Packit 67cb25
            double BTji = gsl_spmatrix_get(BT, j, i);
Packit 67cb25
Packit 67cb25
            if ((Bij != BTji) || (Aij != Bij))
Packit 67cb25
              status = 1;
Packit 67cb25
          }
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    gsl_test(status, "test_memcpy: _transpose_memcpy M=%zu N=%zu CCS format", M, N);
Packit 67cb25
Packit 67cb25
    status = 0;
Packit 67cb25
    for (i = 0; i < M; ++i)
Packit 67cb25
      {
Packit 67cb25
        for (j = 0; j < N; ++j)
Packit 67cb25
          {
Packit 67cb25
            double Aij = gsl_spmatrix_get(A, i, j);
Packit 67cb25
            double Cij = gsl_spmatrix_get(C, i, j);
Packit 67cb25
            double CTji = gsl_spmatrix_get(CT, j, i);
Packit 67cb25
Packit 67cb25
            if ((Cij != CTji) || (Aij != Cij))
Packit 67cb25
              status = 1;
Packit 67cb25
          }
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    gsl_test(status, "test_memcpy: _transpose_memcpy M=%zu N=%zu CRS format", M, N);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_free(A);
Packit 67cb25
    gsl_spmatrix_free(AT);
Packit 67cb25
    gsl_spmatrix_free(B);
Packit 67cb25
    gsl_spmatrix_free(BT);
Packit 67cb25
    gsl_spmatrix_free(C);
Packit 67cb25
    gsl_spmatrix_free(CT);
Packit 67cb25
  }
Packit 67cb25
} /* test_memcpy() */
Packit 67cb25
Packit 67cb25
static void
Packit 67cb25
test_transpose(const size_t M, const size_t N,
Packit 67cb25
               const double density, const gsl_rng *r)
Packit 67cb25
{
Packit 67cb25
  int status;
Packit 67cb25
  gsl_spmatrix *A = create_random_sparse(M, N, density, r);
Packit 67cb25
  gsl_spmatrix *AT = gsl_spmatrix_alloc_nzmax(M, N, A->nz, A->sptype);
Packit 67cb25
  gsl_spmatrix *AT2 = gsl_spmatrix_alloc_nzmax(M, N, A->nz, A->sptype);
Packit 67cb25
  gsl_spmatrix *AT2_ccs, *AT2_crs;
Packit 67cb25
  size_t i, j;
Packit 67cb25
Packit 67cb25
  /* test triplet transpose */
Packit 67cb25
Packit 67cb25
  gsl_spmatrix_memcpy(AT, A);
Packit 67cb25
  gsl_spmatrix_memcpy(AT2, A);
Packit 67cb25
Packit 67cb25
  gsl_spmatrix_transpose(AT);
Packit 67cb25
  gsl_spmatrix_transpose2(AT2);
Packit 67cb25
Packit 67cb25
  status = 0;
Packit 67cb25
  for (i = 0; i < M; ++i)
Packit 67cb25
    {
Packit 67cb25
      for (j = 0; j < N; ++j)
Packit 67cb25
        {
Packit 67cb25
          double Aij = gsl_spmatrix_get(A, i, j);
Packit 67cb25
          double ATji = gsl_spmatrix_get(AT, j, i);
Packit 67cb25
          double AT2ji = gsl_spmatrix_get(AT2, j, i);
Packit 67cb25
Packit 67cb25
          if (Aij != ATji)
Packit 67cb25
            status = 1;
Packit 67cb25
Packit 67cb25
          if (Aij != AT2ji)
Packit 67cb25
            status = 2;
Packit 67cb25
        }
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  gsl_test(status == 1, "test_transpose: transpose M=%zu N=%zu triplet format",
Packit 67cb25
           M, N);
Packit 67cb25
  gsl_test(status == 2, "test_transpose: transpose2 M=%zu N=%zu triplet format",
Packit 67cb25
           M, N);
Packit 67cb25
Packit 67cb25
  /* test CCS transpose */
Packit 67cb25
Packit 67cb25
  AT2_ccs = gsl_spmatrix_ccs(A);
Packit 67cb25
  gsl_spmatrix_transpose2(AT2_ccs);
Packit 67cb25
Packit 67cb25
  status = 0;
Packit 67cb25
  for (i = 0; i < M; ++i)
Packit 67cb25
    {
Packit 67cb25
      for (j = 0; j < N; ++j)
Packit 67cb25
        {
Packit 67cb25
          double Aij = gsl_spmatrix_get(A, i, j);
Packit 67cb25
          double AT2ji = gsl_spmatrix_get(AT2_ccs, j, i);
Packit 67cb25
Packit 67cb25
          if (Aij != AT2ji)
Packit 67cb25
            status = 2;
Packit 67cb25
        }
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  gsl_test(status == 2, "test_transpose: transpose2 M=%zu N=%zu CCS format",
Packit 67cb25
           M, N);
Packit 67cb25
Packit 67cb25
  /* test CRS transpose */
Packit 67cb25
Packit 67cb25
  AT2_crs = gsl_spmatrix_crs(A);
Packit 67cb25
  gsl_spmatrix_transpose2(AT2_crs);
Packit 67cb25
Packit 67cb25
  status = 0;
Packit 67cb25
  for (i = 0; i < M; ++i)
Packit 67cb25
    {
Packit 67cb25
      for (j = 0; j < N; ++j)
Packit 67cb25
        {
Packit 67cb25
          double Aij = gsl_spmatrix_get(A, i, j);
Packit 67cb25
          double AT2ji = gsl_spmatrix_get(AT2_crs, j, i);
Packit 67cb25
Packit 67cb25
          if (Aij != AT2ji)
Packit 67cb25
            status = 2;
Packit 67cb25
        }
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  gsl_test(status == 2, "test_transpose: transpose2 M=%zu N=%zu CRS format",
Packit 67cb25
           M, N);
Packit 67cb25
Packit 67cb25
  gsl_spmatrix_free(A);
Packit 67cb25
  gsl_spmatrix_free(AT);
Packit 67cb25
  gsl_spmatrix_free(AT2);
Packit 67cb25
  gsl_spmatrix_free(AT2_ccs);
Packit 67cb25
  gsl_spmatrix_free(AT2_crs);
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
static void
Packit 67cb25
test_ops(const size_t M, const size_t N,
Packit 67cb25
         const double density, const gsl_rng *r)
Packit 67cb25
{
Packit 67cb25
  size_t i, j;
Packit 67cb25
  int status;
Packit 67cb25
Packit 67cb25
  /* test gsl_spmatrix_add */
Packit 67cb25
  {
Packit 67cb25
    gsl_spmatrix *A = create_random_sparse(M, N, density, r);
Packit 67cb25
    gsl_spmatrix *B = create_random_sparse(M, N, density, r);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix *A_ccs = gsl_spmatrix_ccs(A);
Packit 67cb25
    gsl_spmatrix *B_ccs = gsl_spmatrix_ccs(B);
Packit 67cb25
    gsl_spmatrix *C_ccs = gsl_spmatrix_alloc_nzmax(M, N, 1, GSL_SPMATRIX_CCS);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix *A_crs = gsl_spmatrix_crs(A);
Packit 67cb25
    gsl_spmatrix *B_crs = gsl_spmatrix_crs(B);
Packit 67cb25
    gsl_spmatrix *C_crs = gsl_spmatrix_alloc_nzmax(M, N, 1, GSL_SPMATRIX_CRS);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_add(C_ccs, A_ccs, B_ccs);
Packit 67cb25
    gsl_spmatrix_add(C_crs, A_crs, B_crs);
Packit 67cb25
Packit 67cb25
    status = 0;
Packit 67cb25
    for (i = 0; i < M; ++i)
Packit 67cb25
      {
Packit 67cb25
        for (j = 0; j < N; ++j)
Packit 67cb25
          {
Packit 67cb25
            double aij, bij, cij;
Packit 67cb25
Packit 67cb25
            aij = gsl_spmatrix_get(A_ccs, i, j);
Packit 67cb25
            bij = gsl_spmatrix_get(B_ccs, i, j);
Packit 67cb25
            cij = gsl_spmatrix_get(C_ccs, i, j);
Packit 67cb25
            if (aij + bij != cij)
Packit 67cb25
              status = 1;
Packit 67cb25
Packit 67cb25
            aij = gsl_spmatrix_get(A_crs, i, j);
Packit 67cb25
            bij = gsl_spmatrix_get(B_crs, i, j);
Packit 67cb25
            cij = gsl_spmatrix_get(C_crs, i, j);
Packit 67cb25
            if (aij + bij != cij)
Packit 67cb25
              status = 2;
Packit 67cb25
          }
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    gsl_test(status == 1, "test_ops: add M=%zu N=%zu CCS", M, N);
Packit 67cb25
    gsl_test(status == 2, "test_ops: add M=%zu N=%zu CRS", M, N);
Packit 67cb25
Packit 67cb25
    /* test again with C = 2*A */
Packit 67cb25
    gsl_spmatrix_add(C_ccs, A_ccs, A_ccs);
Packit 67cb25
    gsl_spmatrix_add(C_crs, A_crs, A_crs);
Packit 67cb25
Packit 67cb25
    status = 0;
Packit 67cb25
    for (i = 0; i < M; ++i)
Packit 67cb25
      {
Packit 67cb25
        for (j = 0; j < N; ++j)
Packit 67cb25
          {
Packit 67cb25
            double aij, bij, cij;
Packit 67cb25
Packit 67cb25
            aij = gsl_spmatrix_get(A_ccs, i, j);
Packit 67cb25
            cij = gsl_spmatrix_get(C_ccs, i, j);
Packit 67cb25
            if (aij + aij != cij)
Packit 67cb25
              status = 1;
Packit 67cb25
Packit 67cb25
            aij = gsl_spmatrix_get(A_crs, i, j);
Packit 67cb25
            cij = gsl_spmatrix_get(C_crs, i, j);
Packit 67cb25
            if (aij + aij != cij)
Packit 67cb25
              status = 2;
Packit 67cb25
          }
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    gsl_test(status == 1, "test_ops: add duplicate M=%zu N=%zu CCS", M, N);
Packit 67cb25
    gsl_test(status == 2, "test_ops: add duplicate M=%zu N=%zu CRS", M, N);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_free(A);
Packit 67cb25
    gsl_spmatrix_free(B);
Packit 67cb25
    gsl_spmatrix_free(A_ccs);
Packit 67cb25
    gsl_spmatrix_free(B_ccs);
Packit 67cb25
    gsl_spmatrix_free(C_ccs);
Packit 67cb25
    gsl_spmatrix_free(A_crs);
Packit 67cb25
    gsl_spmatrix_free(B_crs);
Packit 67cb25
    gsl_spmatrix_free(C_crs);
Packit 67cb25
  }
Packit 67cb25
} /* test_ops() */
Packit 67cb25
Packit 67cb25
static void
Packit 67cb25
test_io_ascii(const size_t M, const size_t N,
Packit 67cb25
              const double density, const gsl_rng *r)
Packit 67cb25
{
Packit 67cb25
  int status;
Packit 67cb25
  gsl_spmatrix *A = create_random_sparse_int(M, N, density, r);
Packit 67cb25
Packit 67cb25
  char filename[] = "test.dat";
Packit 67cb25
Packit 67cb25
  /* test triplet I/O */
Packit 67cb25
  {
Packit 67cb25
    FILE *f = fopen(filename, "w");
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_fprintf(f, A, "%g");
Packit 67cb25
Packit 67cb25
    fclose(f);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    FILE *f = fopen(filename, "r");
Packit 67cb25
    gsl_spmatrix *B = gsl_spmatrix_fscanf(f);
Packit 67cb25
Packit 67cb25
    status = gsl_spmatrix_equal(A, B) != 1;
Packit 67cb25
    gsl_test(status, "test_io_ascii: fprintf/fscanf M=%zu N=%zu triplet format", M, N);
Packit 67cb25
Packit 67cb25
    fclose(f);
Packit 67cb25
    gsl_spmatrix_free(B);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  /* test CCS I/O */
Packit 67cb25
  {
Packit 67cb25
    FILE *f = fopen(filename, "w");
Packit 67cb25
    gsl_spmatrix *A_ccs = gsl_spmatrix_ccs(A);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_fprintf(f, A_ccs, "%g");
Packit 67cb25
Packit 67cb25
    fclose(f);
Packit 67cb25
    gsl_spmatrix_free(A_ccs);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    FILE *f = fopen(filename, "r");
Packit 67cb25
    gsl_spmatrix *B = gsl_spmatrix_fscanf(f);
Packit 67cb25
Packit 67cb25
    status = gsl_spmatrix_equal(A, B) != 1;
Packit 67cb25
    gsl_test(status, "test_io_ascii: fprintf/fscanf M=%zu N=%zu CCS format", M, N);
Packit 67cb25
Packit 67cb25
    fclose(f);
Packit 67cb25
    gsl_spmatrix_free(B);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  /* test CRS I/O */
Packit 67cb25
  {
Packit 67cb25
    FILE *f = fopen(filename, "w");
Packit 67cb25
    gsl_spmatrix *A_crs = gsl_spmatrix_crs(A);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_fprintf(f, A_crs, "%g");
Packit 67cb25
Packit 67cb25
    fclose(f);
Packit 67cb25
    gsl_spmatrix_free(A_crs);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    FILE *f = fopen(filename, "r");
Packit 67cb25
    gsl_spmatrix *B = gsl_spmatrix_fscanf(f);
Packit 67cb25
Packit 67cb25
    status = gsl_spmatrix_equal(A, B) != 1;
Packit 67cb25
    gsl_test(status, "test_io_ascii: fprintf/fscanf M=%zu N=%zu CRS format", M, N);
Packit 67cb25
Packit 67cb25
    fclose(f);
Packit 67cb25
    gsl_spmatrix_free(B);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  unlink(filename);
Packit 67cb25
Packit 67cb25
  gsl_spmatrix_free(A);
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
static void
Packit 67cb25
test_io_binary(const size_t M, const size_t N,
Packit 67cb25
               const double density, const gsl_rng *r)
Packit 67cb25
{
Packit 67cb25
  int status;
Packit 67cb25
  gsl_spmatrix *A = create_random_sparse(M, N, density, r);
Packit 67cb25
  gsl_spmatrix *A_ccs, *A_crs;
Packit 67cb25
Packit 67cb25
  char filename[] = "test.dat";
Packit 67cb25
Packit 67cb25
  /* test triplet I/O */
Packit 67cb25
  {
Packit 67cb25
    FILE *f = fopen(filename, "wb");
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_fwrite(f, A);
Packit 67cb25
Packit 67cb25
    fclose(f);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    FILE *f = fopen(filename, "rb");
Packit 67cb25
    gsl_spmatrix *B = gsl_spmatrix_alloc_nzmax(M, N, A->nz, A->sptype);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_fread(f, B);
Packit 67cb25
Packit 67cb25
    status = gsl_spmatrix_equal(A, B) != 1;
Packit 67cb25
    gsl_test(status, "test_io_binary: fwrite/fread M=%zu N=%zu triplet format", M, N);
Packit 67cb25
Packit 67cb25
    fclose(f);
Packit 67cb25
    gsl_spmatrix_free(B);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  /* test CCS I/O */
Packit 67cb25
  A_ccs = gsl_spmatrix_ccs(A);
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    FILE *f = fopen(filename, "wb");
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_fwrite(f, A_ccs);
Packit 67cb25
Packit 67cb25
    fclose(f);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    FILE *f = fopen(filename, "rb");
Packit 67cb25
    gsl_spmatrix *B = gsl_spmatrix_alloc_nzmax(M, N, A->nz, GSL_SPMATRIX_CCS);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_fread(f, B);
Packit 67cb25
Packit 67cb25
    status = gsl_spmatrix_equal(A_ccs, B) != 1;
Packit 67cb25
    gsl_test(status, "test_io_binary: fwrite/fread M=%zu N=%zu CCS format", M, N);
Packit 67cb25
Packit 67cb25
    fclose(f);
Packit 67cb25
    gsl_spmatrix_free(B);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  /* test CRS I/O */
Packit 67cb25
  A_crs = gsl_spmatrix_crs(A);
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    FILE *f = fopen(filename, "wb");
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_fwrite(f, A_crs);
Packit 67cb25
Packit 67cb25
    fclose(f);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    FILE *f = fopen(filename, "rb");
Packit 67cb25
    gsl_spmatrix *B = gsl_spmatrix_alloc_nzmax(M, N, A->nz, GSL_SPMATRIX_CRS);
Packit 67cb25
Packit 67cb25
    gsl_spmatrix_fread(f, B);
Packit 67cb25
Packit 67cb25
    status = gsl_spmatrix_equal(A_crs, B) != 1;
Packit 67cb25
    gsl_test(status, "test_io_binary: fwrite/fread M=%zu N=%zu CRS format", M, N);
Packit 67cb25
Packit 67cb25
    fclose(f);
Packit 67cb25
    gsl_spmatrix_free(B);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  unlink(filename);
Packit 67cb25
Packit 67cb25
  gsl_spmatrix_free(A);
Packit 67cb25
  gsl_spmatrix_free(A_ccs);
Packit 67cb25
  gsl_spmatrix_free(A_crs);
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
int
Packit 67cb25
main()
Packit 67cb25
{
Packit 67cb25
  gsl_rng *r = gsl_rng_alloc(gsl_rng_default);
Packit 67cb25
Packit 67cb25
  test_memcpy(10, 10, 0.2, r);
Packit 67cb25
  test_memcpy(10, 15, 0.3, r);
Packit 67cb25
  test_memcpy(53, 213, 0.4, r);
Packit 67cb25
  test_memcpy(920, 2, 0.2, r);
Packit 67cb25
  test_memcpy(2, 920, 0.3, r);
Packit 67cb25
Packit 67cb25
  test_getset(20, 20, 0.3, r);
Packit 67cb25
  test_getset(30, 20, 0.3, r);
Packit 67cb25
  test_getset(15, 210, 0.3, r);
Packit 67cb25
Packit 67cb25
  test_transpose(50, 50, 0.5, r);
Packit 67cb25
  test_transpose(10, 40, 0.3, r);
Packit 67cb25
  test_transpose(40, 10, 0.3, r);
Packit 67cb25
  test_transpose(57, 13, 0.2, r);
Packit 67cb25
Packit 67cb25
  test_ops(20, 20, 0.2, r);
Packit 67cb25
  test_ops(50, 20, 0.3, r);
Packit 67cb25
  test_ops(20, 50, 0.3, r);
Packit 67cb25
  test_ops(76, 43, 0.4, r);
Packit 67cb25
Packit 67cb25
  test_io_ascii(30, 30, 0.3, r);
Packit 67cb25
  test_io_ascii(20, 10, 0.2, r);
Packit 67cb25
  test_io_ascii(10, 20, 0.2, r);
Packit 67cb25
  test_io_ascii(34, 78, 0.3, r);
Packit 67cb25
Packit 67cb25
  test_io_binary(50, 50, 0.3, r);
Packit 67cb25
  test_io_binary(25, 10, 0.2, r);
Packit 67cb25
  test_io_binary(10, 25, 0.2, r);
Packit 67cb25
  test_io_binary(101, 253, 0.3, r);
Packit 67cb25
Packit 67cb25
  gsl_rng_free(r);
Packit 67cb25
Packit 67cb25
  exit (gsl_test_summary());
Packit 67cb25
} /* main() */