[Vegan-commits] r1850 - in pkg/vegan: inst src

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Thu Sep 15 15:03:31 CEST 2011


Author: jarioksa
Date: 2011-09-15 15:03:31 +0200 (Thu, 15 Sep 2011)
New Revision: 1850

Modified:
   pkg/vegan/inst/ChangeLog
   pkg/vegan/src/nestedness.c
Log:
nestedness.c is more specific and choicy for the tests it does for each 2x2 submatrix fill

Modified: pkg/vegan/inst/ChangeLog
===================================================================
--- pkg/vegan/inst/ChangeLog	2011-09-15 12:27:35 UTC (rev 1849)
+++ pkg/vegan/inst/ChangeLog	2011-09-15 13:03:31 UTC (rev 1850)
@@ -7,6 +7,17 @@
 	* New major version opened with the release of vegan_2.0-0 on
 	September 8, 2011.
 
+	* nestedness.c: isDiag* uses now switch(sX) where sX is the number
+	of non-empty cells. The code looks like it should be faster, but
+	measurable effects are hard to see. However, it is now much
+	clearer since it is obvious what kind of decisions are made with
+	each matrix fill. The swap and trialswap also find first the fill
+	of the 2x2 submatrix, and continue only if fill == 2. The
+	measurable effects are small again (perhaps 1%). 
+
+	* tests: added tests for commsimulator, permatswap1 and
+	permatfull1 before starting the adventures with nestedness.c.
+
 	* commsimulator: a bit less overhead -- all attributes set
 	simultaneously instead of setting separately dim, rownames and
 	colnames. The results should be identical(), running should be

Modified: pkg/vegan/src/nestedness.c
===================================================================
--- pkg/vegan/src/nestedness.c	2011-09-15 12:27:35 UTC (rev 1849)
+++ pkg/vegan/src/nestedness.c	2011-09-15 13:03:31 UTC (rev 1850)
@@ -90,7 +90,7 @@
 void trialswap(int *m, int *nr, int *nc, int *thin)
 {
 
-    int i, a, b, c, d, row[2], col[2];
+    int i, a, b, c, d, row[2], col[2], sX;
 
     GetRNGstate();
 
@@ -101,13 +101,16 @@
 	b = INDX(row[0], col[1], *nr);
 	c = INDX(row[1], col[0], *nr);
 	d = INDX(row[1], col[1], *nr);
-	if (m[a] == 1 && m[d] == 1 && m[b] == 0 && m[c] == 0) {
+        /* only two filled items can be swapped */
+	sX = m[a] + m[b] + m[c] + m[d];
+	if (sX != 2)
+	    continue;
+	if (m[a] == 1 && m[d] == 1) {
 	    m[a] = 0;
 	    m[d] = 0;
 	    m[b] = 1;
 	    m[c] = 1;
-	} else if (m[c] == 1 && m[b] == 1 && m[d] == 0 &&
-		   m[a] == 0) {
+	} else if (m[c] == 1 && m[b] == 1) {
 	    m[a] = 1;
 	    m[d] = 1;
 	    m[b] = 0;
@@ -126,7 +129,7 @@
 void swap(int *m, int *nr, int *nc, int *thin)
 {
 
-    int i, a, b, c, d, row[2], col[2];
+    int i, a, b, c, d, row[2], col[2], sX;
 
     GetRNGstate();
 
@@ -138,14 +141,17 @@
 	    b = INDX(row[0], col[1], *nr);
 	    c = INDX(row[1], col[0], *nr);
 	    d = INDX(row[1], col[1], *nr);
-	    if (m[a] == 1 && m[d] == 1 && m[b] == 0 && m[c] == 0) {
+	    sX = m[a] + m[b] + m[c] + m[d];
+	    if (sX != 2)
+		continue;
+	    if (m[a] == 1 && m[d] == 1) {
 		m[a] = 0;
 		m[d] = 0;
 		m[b] = 1;
 		m[c] = 1;
 		break;
 	    } 
-	    if (m[c] == 1 && m[b] == 1 && m[d] == 0 && m[a] == 0) {
+	    if (m[c] == 1 && m[b] == 1) {
 		m[a] = 1;
 		m[d] = 1;
 		m[b] = 0;
@@ -172,50 +178,50 @@
 double isDiag(double *sm)
 {
     int i, sX;
-    double choose[2];
+    double retval;
 
     /* sX: number of non-zero cells */
     for (i = 0, sX = 0; i < 4; i++)
 	    if (sm[i] > 0)
 		    sX++;
 
-    /* quick return: you cannot swap 0 or 1 items */
-    if (sX < 2)
-        return 0;
-
-    /* Smallest diagonal and antidiagonal element */
-    choose[0] = (sm[1] < sm[2]) ? sm[1] : sm[2];
-    choose[1] = (sm[0] < sm[3]) ? -sm[0] : -sm[3]; 
-
-    if (sX == 4) {
-	 /* Either choose could be returned, but RNG is not needed, 
-	 * because sm already is in random order, and we always return
-	 * choose[0] */
-	    return choose[0];
-    } 
-    if ((sm[0] == 0 && sm[1] > 0 && sm[2] > 0 && sm[3] == 0) ||
-	(sm[0] == 0 && sm[1] > 0 && sm[2] > 0 && sm[3] > 0) ||
-	(sm[0] > 0 && sm[1] > 0 && sm[2] > 0 && sm[3] == 0))
-	    return choose[0];
-    if ((sm[0] > 0 && sm[1] == 0 && sm[2] == 0 && sm[3] > 0) ||
-	(sm[0] > 0 && sm[1] == 0 && sm[2] > 0 && sm[3] > 0) ||
-	(sm[0] > 0 && sm[1] > 0 && sm[2] == 0 && sm[3] > 0))
-	    return choose[1];
- 
-   /* The following is unnecessary, because next 'else' will return 0
-     * even if this if(...) is false */
-
-/*
- *  if (sX < 2 ||
- *	(sm[0] == 0 && sm[1] == 0 && sm[2] > 0 && sm[3] > 0) ||
- *	(sm[0] > 0 && sm[1] > 0 && sm[2] == 0 && sm[3] == 0) ||
- *	(sm[0] == 0 && sm[1] > 0 && sm[2] == 0 && sm[3] > 0) ||
- *	(sm[0] > 0 && sm[1] == 0 && sm[2] > 0 && sm[3] == 0))
- *	    return 0;
- */ 
-
-    else
-	 return 0;
+    switch (sX) {
+    case 0:
+    case 1:
+	    /* nothing to swap*/
+	    return 0;
+	    break;
+    case 2:
+	    /* diagonal and antidiagonal swappable */
+	    if (sm[1] > 0 && sm[2] > 0) {
+		    retval = (sm[1] < sm[2]) ? sm[1] : sm[2];
+	    }
+	    else if (sm[0] > 0 && sm[3] > 0) { 
+		    retval = (sm[0] < sm[3]) ? -sm[0] : -sm[3];
+	    } else {
+		    retval = 0;
+	    }
+	    return retval;
+	    break;
+    case 3:
+	    /* always swappable: case depends on the empty corner */
+	    if (sm[0] == 0 || sm[3] == 0) {
+		    retval = (sm[1] < sm[2]) ? sm[1] : sm[2];
+	    } else {
+		    retval = (sm[0] < sm[3]) ? -sm[0] : -sm[3];
+	    }
+	    return retval;
+	    break;
+    case 4:
+	    /* always swappable: return diagonal case */
+	    retval = (sm[1] < sm[2]) ? sm[1] : sm[2];
+	    return retval;
+	    break;
+    default:
+            /* never reach this */
+	    return 0;
+	    break;
+    }
 }
 
 void swapcount(double *m, int *nr, int *nc, int *thin)
@@ -329,17 +335,29 @@
     for (i = 0, sX = 0; i < 4; i++)
 	if (sm[i] > 0)
 	    sX++;
-    /* quickly out: you cannot swap 0 or 1 items */
-    if (sX < 2)
-	return 0;
-    if (sX == 4) {
-	return 1;
+    
+    switch(sX) {
+    case 0:
+    case 1:
+	    /* never swappable */
+	    return 0;
+	    break;
+    case 2:
+	    /* diagonal and antidiagonal swappable */
+	    if ((sm[1] > 0 && sm[2] > 0) || (sm[0] > 0 && sm[3] > 0))
+		    return 1;
+	    else
+		    return 0;
+	    break;
+    case 3:
+	    /* never swappable */
+	    return 0;
+	    break;
+    case 4:
+	    /* always swappable */
+	    return 1;
+	    break;
     }
-    if ((sm[0] == 0 && sm[1] > 0 && sm[2] > 0 && sm[3] == 0) ||
-	(sm[0] > 0 && sm[1] == 0 && sm[2] == 0 && sm[3] > 0))
-	return 1;
-    else
-	return 0;
 }
 
 /* 'abuswap' to do Hardy 2008 J Ecol 96: 914-926 */



More information about the Vegan-commits mailing list