lcsim/src/org/lcsim/event/base
diff -u -r1.2 -r1.3
--- BaseRelationalTable.java 16 Jul 2007 20:11:19 -0000 1.2
+++ BaseRelationalTable.java 10 Sep 2007 23:45:49 -0000 1.3
@@ -317,7 +317,14 @@
{
double w1 = weightFromTo(from,o1);
double w2 = weightFromTo(from,o2);
- return (int) Math.signum(w2 - w1);
+ if (w1 == w2)
+ {
+ // FIXME: TreeSet bases equality on the return code from the comparator, with equal
+ // elements being eliminated. Thus we only want to return 0 for object which are really equal.
+ // Using hashcode is not strictly correct, since unequal object can have the same hashcode.
+ return o1.hashCode() - o2.hashCode();
+ }
+ else return (int) Math.signum(w2 - w1);
}
}
private class ToWeightComparator implements Comparator<F>
@@ -331,7 +338,14 @@
{
double w1 = weightFromTo(o1,to);
double w2 = weightFromTo(o2,to);
- return (int) Math.signum(w2 - w1);
+ if (w1 == w2)
+ {
+ // FIXME: TreeSet bases equality on the return code from the comparator, with equal
+ // elements being eliminated. Thus we only want to return 0 for object which are really equal.
+ // Using hashcode is not strictly correct, since unequal object can have the same hashcode.
+ return o1.hashCode() - o2.hashCode();
+ }
+ else return (int) Math.signum(w2 - w1);
}
}
}
\ No newline at end of file
lcsim/test/org/lcsim/event/base
diff -N BaseRelationalTableTest.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ BaseRelationalTableTest.java 10 Sep 2007 23:45:49 -0000 1.1
@@ -0,0 +1,257 @@
+package org.lcsim.event.base;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.List;
+import junit.framework.*;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author tonyj
+ */
+public class BaseRelationalTableTest extends TestCase
+{
+ public void testOneToOne()
+ {
+ BaseRelationalTable<Integer,Integer> squares = new BaseRelationalTable<Integer,Integer>(BaseRelationalTable.Mode.ONE_TO_ONE,BaseRelationalTable.Weighting.UNWEIGHTED);
+ assertEquals(BaseRelationalTable.Mode.ONE_TO_ONE,squares.getMode());
+ assertEquals(BaseRelationalTable.Weighting.UNWEIGHTED,squares.getWeighting());
+
+ for (int i=0; i<1000; i++)
+ {
+ assertFalse(squares.add(i,i*i));
+ }
+ assertEquals(1000,squares.size());
+
+ assertEquals(Integer.valueOf(100),squares.to(10));
+ assertEquals(Integer.valueOf(100),squares.from(10000));
+
+ Set<Integer> list = squares.allFrom(10);
+ assertEquals(1,list.size());
+ assertEquals(Integer.valueOf(100),list.iterator().next());
+
+ list = squares.allTo(100);
+ assertEquals(1,list.size());
+ assertEquals(Integer.valueOf(10),list.iterator().next());
+
+ list = squares.allTo(99);
+ assertEquals(0,list.size());
+
+ Map<Integer,Double> map = squares.allFromWithWeights(10);
+ assertEquals(1,map.size());
+ assertEquals(1.0,map.get(100),1e-16);
+
+ map = squares.allToWithWeights(100);
+ assertEquals(1,map.size());
+ assertEquals(1.0,map.get(10),1e-16);
+
+ map = squares.allToWithWeights(99);
+ assertEquals(0,map.size());
+
+ assertEquals(1.0,squares.weightFromTo(10,100),1e-16);
+ assertEquals(0.0,squares.weightFromTo(10,99),1e-16);
+
+ assertNull(squares.from(99));
+
+ assertTrue(squares.add(10,99));
+ assertEquals(1000,squares.size());
+ assertEquals(Integer.valueOf(99),squares.to(10));
+ assertEquals(Integer.valueOf(10),squares.from(99));
+
+ list = squares.allTo(99);
+ assertEquals(1,list.size());
+ assertEquals(Integer.valueOf(10),list.iterator().next());
+
+ assertTrue(squares.remove(10,99));
+ assertEquals(999,squares.size());
+
+ assertFalse(squares.remove(10,99));
+ assertEquals(999,squares.size());
+ }
+ public void testManyToMany()
+ {
+ BaseRelationalTable<Integer,Integer> diffs = new BaseRelationalTable<Integer,Integer>(BaseRelationalTable.Mode.MANY_TO_MANY,BaseRelationalTable.Weighting.WEIGHTED);
+ assertEquals(BaseRelationalTable.Mode.MANY_TO_MANY,diffs.getMode());
+ assertEquals(BaseRelationalTable.Weighting.WEIGHTED,diffs.getWeighting());
+
+ for (int i=0; i<100; i++)
+ {
+ for (int j=0; j<100; j++)
+ {
+ assertFalse(diffs.add(i,j,i-j));
+ }
+ }
+ assertEquals(10000,diffs.size());
+
+ try
+ {
+ diffs.to(10);
+ fail("Should have thrown an exception");
+ }
+ catch (IllegalArgumentException x)
+ {
+ // OK
+ }
+ try
+ {
+ diffs.from(10);
+ fail("Should have thrown an exception");
+ }
+ catch (IllegalArgumentException x)
+ {
+ // OK
+ }
+
+ Set<Integer> list = diffs.allFrom(10);
+ assertEquals(100,list.size());
+ assertEquals(Integer.valueOf(0),list.iterator().next());
+
+ list = diffs.allTo(10);
+ assertEquals(100,list.size());
+ assertEquals(Integer.valueOf(99),list.iterator().next());
+
+ list = diffs.allTo(100);
+ assertEquals(0,list.size());
+
+ Map<Integer,Double> map = diffs.allFromWithWeights(10);
+ assertEquals(100,map.size());
+ assertEquals(10-90,map.get(90),1e-16);
+
+ map = diffs.allToWithWeights(10);
+ assertEquals(100,map.size());
+ assertEquals(90-10,map.get(90),1e-16);
+
+ map = diffs.allToWithWeights(100);
+ assertEquals(0,map.size());
+
+ assertEquals(0.0,diffs.weightFromTo(10,100),1e-16);
+ assertEquals(10-99,diffs.weightFromTo(10,99),1e-16);
+
+ assertNull(diffs.from(100));
+
+ assertTrue(diffs.add(10,99));
+ assertEquals(10000,diffs.size());
+
+ list = diffs.allTo(99);
+ assertEquals(101,list.size());
+ assertEquals(Integer.valueOf(10),list.iterator().next());
+
+ diffs.remove(10,99);
+ assertEquals(9999,diffs.size());
+ }
+
+ public void testFactors()
+ {
+ BaseRelationalTable<Integer,Integer> factors = new BaseRelationalTable<Integer,Integer>(BaseRelationalTable.Mode.MANY_TO_MANY,BaseRelationalTable.Weighting.WEIGHTED);
+ assertEquals(BaseRelationalTable.Mode.MANY_TO_MANY,factors.getMode());
+ assertEquals(BaseRelationalTable.Weighting.WEIGHTED,factors.getWeighting());
+
+ List<Integer> primes = getPrimes(1000);
+ for (int i=1; i<=1000; i++)
+ {
+ List<Integer> primeFactors = getPrimeFactors(primes,i);
+ for (int factor : primeFactors)
+ {
+ double w = factors.weightFromTo(i,factor) + 1;
+ boolean rc = factors.add(i,factor,w);
+ }
+ }
+
+ for (int i=1; i<=1000; i++)
+ {
+ Map<Integer,Double> primeFactors = factors.allFromWithWeights(i);
+ int j=1;
+ for (Map.Entry<Integer,Double> e : primeFactors.entrySet())
+ {
+ j *= Math.pow(e.getKey(),e.getValue());
+ }
+ assertEquals(i,j);
+ }
+
+ }
+ private List<Integer> getPrimeFactors(List<Integer> primes, int n)
+ {
+ List<Integer> factors = new ArrayList<Integer>();
+
+ // Step 1
+ int k = 0;
+ int divisor;
+ int quotient;
+ int remainder;
+
+ // Step 2
+ while (n > 1)
+ {
+
+ // Step 3
+ divisor = primes.get(k);
+ quotient = n / divisor;
+ remainder = n % divisor;
+
+ // Step 4
+ if (remainder == 0)
+ {
+
+ // Step 5
+ factors.add(divisor);
+ n = quotient;
+
+ }
+ else
+ {
+
+ // Step 6
+ if (quotient > divisor)
+ {
+ k++;
+ }
+ else
+ {
+ // Step 7
+ factors.add(n);
+ break;
+ }
+ }
+ }
+ return factors;
+ }
+ private List<Integer> getPrimes(int upTo)
+ {
+ int size = upTo + 1;
+ BitSet flags = new BitSet(size);
+ List<Integer> primes = new ArrayList<Integer>();
+ double limit = Math.sqrt(size);
+
+ // Cross out multiples of 2
+ int j = 2;
+ for (int i = j + j; i < size; i = i + j)
+ {
+ flags.set(i);
+ }
+
+ // Cross out multiples of odd numbers
+ for (j = 3; j <= limit; j = j + 2)
+ {
+ if (!flags.get(j))
+ {
+ for (int i = j + j; i < size; i = i + j)
+ {
+ flags.set(i);
+ }
+ }
+ }
+
+ // Build list of primes from what is left
+ for (int i = 2; i < size; i++)
+ {
+ if (!flags.get(i))
+ {
+ primes.add(i);
+ }
+ }
+
+ return primes;
+ }
+}