/* * Copyright (C) 2015 Information Retrieval Group at Universidad Autónoma * de Madrid, http://ir.ii.uam.es * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package es.uam.eps.ir.ranksys.fast.preference; import es.uam.eps.ir.ranksys.core.preference.IdPref; import it.unimi.dsi.fastutil.doubles.DoubleIterator; import it.unimi.dsi.fastutil.ints.IntIterator; import java.util.Optional; import java.util.stream.IntStream; import java.util.stream.Stream; import org.jooq.lambda.function.Function2; import org.ranksys.fast.preference.FastPointWisePreferenceData; /** * Transposed preferences, where users and items change roles. This class is useful to simplify the implementation of many algorithms that work user or item-wise, such as similarities or matrix factorization. * * @author Saúl Vargas (saul.vargas@uam.es) * * @param <I> type of the items * @param <U> type of the users */ public class TransposedPreferenceData<I, U> implements FastPreferenceData<I, U>, FastPointWisePreferenceData<I, U> { private final FastPreferenceData<U, I> d; private final Function2<U, IdPref<I>, IdPref<U>> idPrefFun; private final Function2<Integer, IdxPref, IdxPref> idxPrefFun; /** * Constructor with default converters between IdxPref and IdPref. * * @param recommenderData preference data to be transposed */ public TransposedPreferenceData(FastPreferenceData<U, I> recommenderData) { this(recommenderData, (u, p) -> new IdPref<>(u, p.v2), (uidx, p) -> new IdxPref(uidx, p.v2)); } /** * Constructor with custom converters between IdxPref and IdPref. * * @param recommenderData preference data to be transposed * @param idPrefFun converter from item IdPref to user IdPref * @param idxPrefFun converter from item IdxPref to item IdxPref */ public TransposedPreferenceData(FastPreferenceData<U, I> recommenderData, Function2<U, IdPref<I>, IdPref<U>> idPrefFun, Function2<Integer, IdxPref, IdxPref> idxPrefFun) { this.d = recommenderData; this.idPrefFun = idPrefFun; this.idxPrefFun = idxPrefFun; } @Override public int user2uidx(I u) { return d.item2iidx(u); } @Override public I uidx2user(int uidx) { return d.iidx2item(uidx); } @Override public int item2iidx(U i) { return d.user2uidx(i); } @Override public U iidx2item(int iidx) { return d.uidx2user(iidx); } @Override public int numUsers(int iidx) { return d.numItems(iidx); } @Override public int numItems(int uidx) { return d.numUsers(uidx); } @Override public Stream<? extends IdxPref> getUidxPreferences(int uidx) { return d.getIidxPreferences(uidx); } @Override public Stream<? extends IdxPref> getIidxPreferences(int iidx) { return d.getUidxPreferences(iidx); } @Override public int numUsers() { return d.numItems(); } @Override public int numUsers(U i) { return d.numItems(i); } @Override public int numItems() { return d.numUsers(); } @Override public int numItems(I u) { return d.numUsers(u); } @Override public int numPreferences() { return d.numPreferences(); } @Override public Stream<I> getAllUsers() { return d.getAllItems(); } @Override public Stream<U> getAllItems() { return d.getAllUsers(); } @Override public Stream<? extends IdPref<U>> getUserPreferences(I u) { return d.getItemPreferences(u); } @Override public Stream<? extends IdPref<I>> getItemPreferences(U i) { return d.getUserPreferences(i); } @Override public IntStream getAllUidx() { return d.getAllIidx(); } @Override public IntStream getAllIidx() { return d.getAllUidx(); } @Override public IntStream getUidxWithPreferences() { return d.getIidxWithPreferences(); } @Override public IntStream getIidxWithPreferences() { return d.getUidxWithPreferences(); } @Override public int numUsersWithPreferences() { return d.numItemsWithPreferences(); } @Override public int numItemsWithPreferences() { return d.numUsersWithPreferences(); } @Override public Stream<I> getUsersWithPreferences() { return d.getItemsWithPreferences(); } @Override public Stream<U> getItemsWithPreferences() { return d.getUsersWithPreferences(); } @Override public IntIterator getUidxIidxs(int uidx) { return d.getIidxUidxs(uidx); } @Override public DoubleIterator getUidxVs(int uidx) { return d.getIidxVs(uidx); } @Override public IntIterator getIidxUidxs(int iidx) { return d.getUidxIidxs(iidx); } @Override public DoubleIterator getIidxVs(int iidx) { return d.getUidxVs(iidx); } @Override public Optional<IdxPref> getPreference(int uidx, int iidx) { Optional<? extends IdxPref> pref = ((FastPointWisePreferenceData<U, I>) d).getPreference(iidx, uidx); if (pref.isPresent()) { return Optional.of(idxPrefFun.apply(iidx, pref.get())); } else { return Optional.empty(); } } @Override public Optional<IdPref<U>> getPreference(I u, U i) { Optional<? extends IdPref<I>> pref = ((FastPointWisePreferenceData<U, I>) d).getPreference(i, u); if (pref.isPresent()) { return Optional.of(idPrefFun.apply(i, pref.get())); } else { return Optional.empty(); } } @Override public boolean useIteratorsPreferentially() { return d.useIteratorsPreferentially(); } }