// TODO: Scalar preference relations based on Bradley-Terry model public static PrefRelations CreateScalar(DataMatrix R) { int userCount = R.UserCount; int itemCount = R.ItemCount; PrefRelations PR = new PrefRelations(itemCount); // Create a preference matrix for each user Object lockMe = new Object(); Parallel.ForEach(R.Users, user => { int userIndex = user.Item1; RatingVector userRatings = new RatingVector(user.Item2); Utils.PrintEpoch("Doing user/total", userIndex, userCount); // The diagonal refer to the i-i item pair SparseMatrix userPreferences = new SparseMatrix(itemCount); // The diagonal is left empty! //SparseMatrix.OfMatrix(Matrix.Build.SparseDiagonal(itemCount, Config.Preferences.EquallyPreferred)); // TODO: Use Vector.Map2 to replace the following two foreach loops // Here we need to compare each pair of items rated by this user foreach (Tuple <int, double> left in userRatings.Ratings) { int leftItemIndex = left.Item1; double leftItemRating = left.Item2; foreach (Tuple <int, double> right in userRatings.Ratings) { int rightItemIndex = right.Item1; // TODO: We could compute only the lower triangular, // and uppwer will be a negative mirror // Let's do it directly at this stage double rightItemRating = right.Item2; Debug.Assert(rightItemRating != 0 && leftItemRating != 0); // Skip the diagonal if (leftItemIndex == rightItemIndex) { continue; } userPreferences[leftItemIndex, rightItemIndex] = 0.1 * (leftItemRating - rightItemRating + 5);//(double)leftItemRating / (leftItemRating + rightItemRating); } } // Because pr's upper triangular should be a mirror of the lower triangular Debug.Assert((userPreferences.NonZerosCount).IsEven()); double debug1 = (Math.Pow(((SparseVector)R.GetRow(userIndex)).NonZerosCount, 2) - ((SparseVector)R.GetRow(userIndex)).NonZerosCount); double debug2 = userPreferences.NonZerosCount; Debug.Assert(debug1 == debug2); lock (lockMe) { // Copy similarity values from lower triangular to upper triangular //pr_uid = DenseMatrix.OfMatrix(pr_uid + pr_uid.Transpose() - DenseMatrix.CreateIdentity(pr_uid.RowCount)); PR[userIndex] = userPreferences; } }); return(PR); }