/** * Initializes the receiver. * * @param initialCapacity the initial capacity of the receiver. * @param minLoadFactor the minLoadFactor of the receiver. * @param maxLoadFactor the maxLoadFactor of the receiver. * @throws IllegalArgumentException if <tt>initialCapacity < 0 || (minLoadFactor < 0.0 || * minLoadFactor >= 1.0) || (maxLoadFactor <= 0.0 || maxLoadFactor >= 1.0) || (minLoadFactor * >= maxLoadFactor)</tt>. */ protected void setUp(int initialCapacity, double minLoadFactor, double maxLoadFactor) { int capacity = initialCapacity; super.setUp(capacity, minLoadFactor, maxLoadFactor); capacity = nextPrime(capacity); if (capacity == 0) capacity = 1; // open addressing needs at least one FREE slot at any time. this.table = new int[capacity]; this.values = new double[capacity]; this.state = new byte[capacity]; // memory will be exhausted long before this pathological case happens, anyway. this.minLoadFactor = minLoadFactor; if (capacity == PrimeFinder.largestPrime) this.maxLoadFactor = 1.0; else this.maxLoadFactor = maxLoadFactor; this.distinct = 0; this.freeEntries = capacity; // delta // lowWaterMark will be established upon first expansion. // establishing it now (upon instance construction) would immediately make the table shrink upon // first put(...). // After all the idea of an "initialCapacity" implies violating lowWaterMarks when an object is // young. // See ensureCapacity(...) this.lowWaterMark = 0; this.highWaterMark = chooseHighWaterMark(capacity, this.maxLoadFactor); }
/** * Clears the receiver, then adds all (key,value) pairs of <tt>other</tt>values to it. * * @param other the other map to be copied into the receiver. */ public void assign(AbstractIntDoubleMap other) { if (!(other instanceof OpenIntDoubleHashMap)) { super.assign(other); return; } OpenIntDoubleHashMap source = (OpenIntDoubleHashMap) other; OpenIntDoubleHashMap copy = (OpenIntDoubleHashMap) source.copy(); this.values = copy.values; this.table = copy.table; this.state = copy.state; this.freeEntries = copy.freeEntries; this.distinct = copy.distinct; this.lowWaterMark = copy.lowWaterMark; this.highWaterMark = copy.highWaterMark; this.minLoadFactor = copy.minLoadFactor; this.maxLoadFactor = copy.maxLoadFactor; }
/** * Returns the best cut of a graph w.r.t. the degree of dissimilarity between points of different * partitions and the degree of similarity between points of the same partition. * * @param W the weight matrix of the graph * @return an array of two elements, each of these contains the points of a partition */ protected static int[][] bestCut(DoubleMatrix2D W) { int n = W.columns(); // Builds the diagonal matrices D and D^(-1/2) (represented as their diagonals) DoubleMatrix1D d = DoubleFactory1D.dense.make(n); DoubleMatrix1D d_minus_1_2 = DoubleFactory1D.dense.make(n); for (int i = 0; i < n; i++) { double d_i = W.viewRow(i).zSum(); d.set(i, d_i); d_minus_1_2.set(i, 1 / Math.sqrt(d_i)); } DoubleMatrix2D D = DoubleFactory2D.sparse.diagonal(d); // System.out.println("DoubleMatrix2D :\n"+D.toString()); DoubleMatrix2D X = D.copy(); // System.out.println("DoubleMatrix2D copy :\n"+X.toString()); // X = D^(-1/2) * (D - W) * D^(-1/2) X.assign(W, Functions.minus); // System.out.println("DoubleMatrix2D X: (D-W) :\n"+X.toString()); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) X.set(i, j, X.get(i, j) * d_minus_1_2.get(i) * d_minus_1_2.get(j)); // Computes the eigenvalues and the eigenvectors of X EigenvalueDecomposition e = new EigenvalueDecomposition(X); DoubleMatrix1D lambda = e.getRealEigenvalues(); // Selects the eigenvector z_2 associated with the second smallest eigenvalue // Creates a map that contains the pairs <index, eigenvalue> AbstractIntDoubleMap map = new OpenIntDoubleHashMap(n); for (int i = 0; i < n; i++) map.put(i, Math.abs(lambda.get(i))); IntArrayList list = new IntArrayList(); // Sorts the map on the value map.keysSortedByValue(list); // Gets the index of the second smallest element int i_2 = list.get(1); // y_2 = D^(-1/2) * z_2 DoubleMatrix1D y_2 = e.getV().viewColumn(i_2).copy(); y_2.assign(d_minus_1_2, Functions.mult); // Creates a map that contains the pairs <i, y_2[i]> map.clear(); for (int i = 0; i < n; i++) map.put(i, y_2.get(i)); // Sorts the map on the value map.keysSortedByValue(list); // Search the element in the map previuosly ordered that minimizes the cut // of the partition double best_cut = Double.POSITIVE_INFINITY; int[][] partition = new int[2][]; // The array v contains all the elements of the graph ordered by their // projection on vector y_2 int[] v = list.elements(); // For each admissible splitting point i for (int i = 1; i < n; i++) { // The array a contains all the elements that have a projection on vector // y_2 less or equal to the one of i-th element // The array b contains the remaining elements int[] a = new int[i]; int[] b = new int[n - i]; System.arraycopy(v, 0, a, 0, i); System.arraycopy(v, i, b, 0, n - i); double cut = Ncut(W, a, b, v); if (cut < best_cut) { best_cut = cut; partition[0] = a; partition[1] = b; } } // System.out.println("Partition:"); // UtilsJS.printMatrix(partition); return partition; }