Sophie

Sophie

distrib > Fedora > 15 > i386 > by-pkgid > 62356126073ffa0ee9bd0f6e1f269f30 > files > 172

igraph-devel-0.5.4-3.fc15.i686.rpm

/* -*- mode: C -*-  */
/* 
   IGraph library.
   Copyright (C) 2006  Gabor Csardi <csardi@rmki.kfki.hu>
   MTA RMKI, Konkoly-Thege Miklos st. 29-33, Budapest 1121, Hungary
   
   This program 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 2 of the License, or
   (at your option) any later version.
   
   This program 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 this program; if not, write to the Free Software
   Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA 
   02110-1301 USA

*/

#include <igraph.h>
#include <stdio.h>
#include <stdlib.h>

void print_matrix(igraph_matrix_t* m) {
  long int nr=igraph_matrix_nrow(m);
  long int nc=igraph_matrix_ncol(m);
  long int i, j;
  for (i=0; i<nr; i++) {
    for (j=0; j<nc; j++) {
      if (j!=0) { putchar(' '); }
      printf("%d", (int)MATRIX(*m, i, j));
    }
    printf("\n");
  }
}

igraph_bool_t check_laplacian(igraph_t* graph, igraph_matrix_t* matrix) {
  igraph_vector_t vec, res;
  long int i, j;

  igraph_vector_init(&vec, 0);
  igraph_vector_init(&res, igraph_vcount(graph));

  igraph_degree(graph, &vec, igraph_vss_all(), IGRAPH_OUT, IGRAPH_NO_LOOPS);

  for (i = 0; i < igraph_vcount(graph); i++) {
    VECTOR(vec)[i] = sqrt(VECTOR(vec)[i]);
  }

  for (i = 0; i < igraph_vcount(graph); i++) {
    for (j = 0; j < igraph_vcount(graph); j++) {
      VECTOR(res)[i] += MATRIX(*matrix, i, j) * VECTOR(vec)[j];
    }
  }

  if (igraph_vector_min(&res) > 1e-7) {
    printf("Invalid Laplacian matrix:\n");
    print_matrix(matrix);
    return 0;
  }

  igraph_vector_destroy(&vec);
  igraph_vector_destroy(&res);

  return 1;
}

int test_unnormalized_laplacian(igraph_bool_t dir) {
  igraph_t g;
  igraph_matrix_t m;
  igraph_vector_t vec;
  igraph_matrix_init(&m, 1, 1);

  /* No loop or multiple edges */
  igraph_ring(&g, 5, dir, 0, 1);
  igraph_laplacian(&g, &m, 0);
  print_matrix(&m);
  printf("===\n");

  /* Add some loop edges */
  igraph_vector_init_real(&vec, 4, 1.0, 1.0, 2.0, 2.0);
  igraph_add_edges(&g, &vec, 0);
  igraph_vector_destroy(&vec);

  igraph_laplacian(&g, &m, 0);
  print_matrix(&m);
  printf("===\n");

  /* Duplicate some edges */
  igraph_vector_init_real(&vec, 4, 1.0, 2.0, 3.0, 4.0);
  igraph_add_edges(&g, &vec, 0);
  igraph_vector_destroy(&vec);

  igraph_laplacian(&g, &m, 0);
  print_matrix(&m);

  igraph_destroy(&g);

  igraph_matrix_destroy(&m);

  return 0;
}

int test_normalized_laplacian(igraph_bool_t dir) {
  igraph_t g;
  igraph_matrix_t m;
  igraph_vector_t vec;
  igraph_matrix_init(&m, 1, 1);
  igraph_bool_t ok = 1;

  /* Undirected graph, no loop or multiple edges */
  igraph_ring(&g, 5, dir, 0, 1);
  igraph_laplacian(&g, &m, 1);
  ok = ok && check_laplacian(&g, &m);

  /* Add some loop edges */
  igraph_vector_init_real(&vec, 4, 1.0, 1.0, 2.0, 2.0);
  igraph_add_edges(&g, &vec, 0);
  igraph_vector_destroy(&vec);

  igraph_laplacian(&g, &m, 1);
  ok = ok && check_laplacian(&g, &m);

  /* Duplicate some edges */
  igraph_vector_init_real(&vec, 4, 1.0, 2.0, 3.0, 4.0);
  igraph_add_edges(&g, &vec, 0);
  igraph_vector_destroy(&vec);

  igraph_laplacian(&g, &m, 1);
  ok = ok && check_laplacian(&g, &m);

  igraph_destroy(&g);

  igraph_matrix_destroy(&m);

  if (ok)
    printf("OK\n");

  return !ok;
}

int main() {
  int res;
  int i;

  for (i = 0; i < 4; i++) {
    igraph_bool_t is_normalized = i / 2;
    igraph_bool_t dir = (i % 2 ? IGRAPH_DIRECTED : IGRAPH_UNDIRECTED);

    printf("=== %sormalized, unweighted, %sdirected\n",
      (is_normalized ? "N" : "Unn"),
      (dir == IGRAPH_DIRECTED ? "" : "un")
    );

    if (is_normalized)
      res = test_normalized_laplacian(dir);
    else
      res = test_unnormalized_laplacian(dir);

    if (res)
      return i+1;
  }

  return 0;
}