/** Computes the next step of the Power Method. */ public void step() throws IOException { double[] oldRank = rank, newRank = previousRank; DoubleArrays.fill(newRank, 0.0); // for each node, calculate its outdegree and redistribute its rank among pointed nodes double accum = 0.0; progressLogger.expectedUpdates = numNodes; progressLogger.start("Iteration " + (++iterationNumber) + "..."); final ArcLabelledNodeIterator nodeIterator = g.nodeIterator(); int i, outdegree, j, n = numNodes; int[] succ; Label[] lab; while (n-- != 0) { i = nodeIterator.nextInt(); outdegree = nodeIterator.outdegree(); if (outdegree == 0 || buckets != null && buckets.get(i)) accum += oldRank[i]; else { j = outdegree; succ = nodeIterator.successorArray(); lab = nodeIterator.labelArray(); while (j-- != 0) { newRank[succ[j]] += (oldRank[i] * lab[j].getFloat()) / sumoutweight[i]; } } progressLogger.update(); } progressLogger.done(); final double accumOverNumNodes = accum / numNodes; final double oneOverNumNodes = 1.0 / numNodes; if (preference != null) if (preferentialAdjustment == null) for (i = numNodes; i-- != 0; ) newRank[i] = alpha * newRank[i] + (1 - alpha) * preference.getDouble(i) + alpha * accumOverNumNodes; else for (i = numNodes; i-- != 0; ) newRank[i] = alpha * newRank[i] + (1 - alpha) * preference.getDouble(i) + alpha * accum * preferentialAdjustment.getDouble(i); else if (preferentialAdjustment == null) for (i = numNodes; i-- != 0; ) newRank[i] = alpha * newRank[i] + (1 - alpha) * oneOverNumNodes + alpha * accumOverNumNodes; else for (i = numNodes; i-- != 0; ) newRank[i] = alpha * newRank[i] + (1 - alpha) * oneOverNumNodes + alpha * accum * preferentialAdjustment.getDouble(i); // make the rank just computed the new rank rank = newRank; previousRank = oldRank; // Compute derivatives. n = iterationNumber; if (subset == null) { for (i = 0; i < order.length; i++) { final int k = order[i]; final double alphak = Math.pow(alpha, k); final double nFallingK = Util.falling(n, k); for (j = 0; j < numNodes; j++) derivative[i][j] += nFallingK * (rank[j] - previousRank[j]) / alphak; } } else { for (i = 0; i < order.length; i++) { final int k = order[i]; final double alphak = Math.pow(alpha, k); final double nFallingK = Util.falling(n, k); for (int t : subset) derivative[i][t] += nFallingK * (rank[t] - previousRank[t]) / alphak; } } // Compute coefficients, if required. if (coeffBasename != null) { final DataOutputStream coefficients = new DataOutputStream( new FastBufferedOutputStream( new FileOutputStream(coeffBasename + "-" + (iterationNumber)))); final double alphaN = Math.pow(alpha, n); for (i = 0; i < numNodes; i++) coefficients.writeDouble((rank[i] - previousRank[i]) / alphaN); coefficients.close(); } }