this.dataModel = dataModel;
}
@Override
public double userSimilarity(long userID1, long userID2) throws TasteException {
PreferenceArray xPrefs = dataModel.getPreferencesFromUser(userID1);
PreferenceArray yPrefs = dataModel.getPreferencesFromUser(userID2);
int xLength = xPrefs.length();
int yLength = yPrefs.length();
if ((xLength <= 1) || (yLength <= 1)) {
return Double.NaN;
}
// Copy prefs since we need to modify pref values to ranks
xPrefs = xPrefs.clone();
yPrefs = yPrefs.clone();
// First sort by values from low to high
xPrefs.sortByValue();
yPrefs.sortByValue();
// Assign ranks from low to high
float nextRank = 1.0f;
for (int i = 0; i < xLength; i++) {
// ... but only for items that are common to both pref arrays
if (yPrefs.hasPrefWithItemID(xPrefs.getItemID(i))) {
xPrefs.setValue(i, nextRank);
nextRank += 1.0f;
}
// Other values are bogus but don't matter
}
nextRank = 1.0f;
for (int i = 0; i < yLength; i++) {
if (xPrefs.hasPrefWithItemID(yPrefs.getItemID(i))) {
yPrefs.setValue(i, nextRank);
nextRank += 1.0f;
}
}
xPrefs.sortByItem();
yPrefs.sortByItem();
long xIndex = xPrefs.getItemID(0);
long yIndex = yPrefs.getItemID(0);
int xPrefIndex = 0;
int yPrefIndex = 0;
double sumXYRankDiff2 = 0.0;
int count = 0;
while (true) {
int compare = xIndex < yIndex ? -1 : xIndex > yIndex ? 1 : 0;
if (compare == 0) {
double diff = xPrefs.getValue(xPrefIndex) - yPrefs.getValue(yPrefIndex);
sumXYRankDiff2 += diff * diff;
count++;
}
if (compare <= 0) {
if (++xPrefIndex >= xLength) {
break;
}
xIndex = xPrefs.getItemID(xPrefIndex);
}
if (compare >= 0) {
if (++yPrefIndex >= yLength) {
break;
}
yIndex = yPrefs.getItemID(yPrefIndex);
}
}
if (count <= 1) {
return Double.NaN;