[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