protected double ProbS(int u, int j) {

		if (!userItemRanks.containsRow(u)) {

			userItemRanks.clear();

			SparseVector uv = trainMatrix.row(u);
			List<Integer> items = Lists.toList(uv.getIndex());

			// distribute resources to users, including user u
			Map<Integer, Double> userResources = new HashMap<>();
			for (int v = 0; v < numUsers; v++) {
				SparseVector vv = trainMatrix.row(v);
				double sum = 0;
				for (int item : vv.getIndex()) {
					if (items.contains(item))
						sum += 1.0 / itemDegrees.get(item);
				}

				userResources.put(v, sum);
			}

			// redistribute resources to items
			for (int i = 0; i < numItems; i++) {
				if (items.contains(i))
					continue;

				SparseVector iv = trainMatrix.column(i);
				double sum = 0;
				for (int user : iv.getIndex())
					sum += userResources.get(user) / userDegrees.get(user);

				double score = sum;
				userItemRanks.put(u, i, score);
			}
		}

		return userItemRanks.contains(u, j) ? userItemRanks.get(u, j) : 0.0;
	}