/* Copyright (C) 2006 Univ. of Massachusetts Amherst, Computer Science Dept. This file is part of "MALLET" (MAchine Learning for LanguagE Toolkit). http://www.cs.umass.edu/~mccallum/mallet This software is provided under the terms of the Common Public License, version 1.0, as published by http://www.opensource.org. For further information, see the file `LICENSE' included with this distribution. */ package cc.mallet.grmm.types; import gnu.trove.THashSet; import gnu.trove.TIntArrayList; import java.util.AbstractSet; import java.util.BitSet; import java.util.Collection; import java.util.Set; import java.io.ObjectOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; import cc.mallet.grmm.inference.Utils; /** * A clique that uses very little time and memory based on the flyweight * pattern, in the same way as BitVarSet. This implementation uses an * ArrayList of indices, and is likely to be more memory-efficient when the * Universe is very, very large. * * @author Charles Sutton * @version $Id: ListVarSet.java,v 1.1 2007/10/22 21:37:44 mccallum Exp $ */ public class ListVarSet extends AbstractSet implements VarSet, Serializable { transient private Universe universe; transient private TIntArrayList included; public ListVarSet (Universe universe, Collection included) { this.universe = universe; this.included = new TIntArrayList (included.size ()); java.util.Iterator it = included.iterator(); while (it.hasNext()) { this.included.add (universe.getIndex ((Variable) it.next ())); } this.included.sort (); } public ListVarSet (VarSet vsOld) { this (vsOld.get(0).getUniverse (), vsOld); } public boolean add (Object o) { int idx = universe.getIndex ((Variable) o); if (idx == -1) throw new UnsupportedOperationException(); included.add (idx); included.sort (); return true; } public Variable get(int idx) { int gidx = included.get (idx); return universe.get (gidx); } public Variable[] toVariableArray() { return (Variable[]) toArray (new Variable[0]); } // FIXME cache not updated on changes to the clique private int cachedWeight = -1; public int weight() { if (cachedWeight == -1) { int weight = 1; ListVarSet.Iterator it = new ListVarSet.Iterator (); while (it.hasNext()) { Variable var = (Variable) it.next(); weight *= var.getNumOutcomes(); } cachedWeight = weight; } return cachedWeight; } public AssignmentIterator assignmentIterator() { return new DenseAssignmentIterator (this); } public int size() { return included.size (); } public boolean isEmpty() { return included.isEmpty(); } public boolean contains(Object o) { return included.contains (universe.getIndex ((Variable) o)); } private class Iterator implements java.util.Iterator { int nextIdx; public Iterator () { nextIdx = 0; } public boolean hasNext() { return (nextIdx < included.size ()); } public Object next() { int thisIdx = nextIdx; nextIdx++; return universe.get (included.get (thisIdx)); } public void remove() { throw new UnsupportedOperationException("Removal from BitSetClique not permitted"); } } public java.util.Iterator iterator() { return new ListVarSet.Iterator (); } public boolean equals (Object o) { if (this == o) return true; if (!(o instanceof VarSet)) return false; VarSet vs = (VarSet) o; return (vs.size () == size()) && containsAll (vs); } public int hashCode () { int result = 39; for (int vi = 0; vi < size(); vi++) { result = 59 * result + get(vi).hashCode (); } return result; } public VarSet intersection (VarSet c) { return Utils.defaultIntersection (this, c); } public void clear() { included.clear(); } public String toString () { String foo = "(C"; ListVarSet.Iterator it = new ListVarSet.Iterator (); while (it.hasNext()) { Variable var = (Variable) it.next(); foo = foo + " " + var; } foo = foo + ")"; return foo; } // Serialization garbage private static final long serialVersionUID = 1; private static final int CURRENT_SERIAL_VERSION = 1; private void writeObject (ObjectOutputStream out) throws IOException { out.defaultWriteObject (); out.writeInt (CURRENT_SERIAL_VERSION); out.writeObject (universe); out.writeObject (included.toNativeArray ()); } private void readObject (ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject (); int version = in.readInt (); universe = (Universe) in.readObject (); int[] vals = (int[]) in.readObject (); included = new TIntArrayList (vals); } }