/*
 * LensKit, an open source recommender systems toolkit.
 * Copyright 2010-2012 Regents of the University of Minnesota and contributors
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package org.grouplens.lenskit.svd;

import java.io.Serializable;

import org.grouplens.grapht.annotation.DefaultProvider;
import org.grouplens.lenskit.baseline.BaselinePredictor;
import org.grouplens.lenskit.transform.clamp.ClampingFunction;
import org.grouplens.lenskit.util.Index;

@DefaultProvider(FunkSVDModelProvider.class)
public class FunkSVDModel implements Serializable {
    private static final long serialVersionUID = -5797099617512506185L;

    public final int featureCount;
    public final double itemFeatures[][];
    public final double userFeatures[][];
    public final ClampingFunction clampingFunction;

    public final Index itemIndex;
    public final Index userIndex;
    public final BaselinePredictor baseline;

    public FunkSVDModel(int nfeatures, double[][] ifeats, double[][] ufeats,
                        ClampingFunction clamp, Index iidx, Index uidx,
                        BaselinePredictor baseline) {
        featureCount = nfeatures;
        itemFeatures = ifeats;
        userFeatures = ufeats;
        clampingFunction = clamp;
        itemIndex = iidx;
        userIndex = uidx;
        this.baseline = baseline;
    }

    public double getItemFeatureValue(int item, int feature) {
        return itemFeatures[feature][item];
    }

    public int getItemIndex(long item) {
        return itemIndex.getIndex(item);
    }
}

@@ -1604,16 +1604,198 @@
 eline;%0A%0A
+    //Added%0A    public final double%5B%5D averUserFeatures;%0A    public final double%5B%5D averItemFeatures;%0A    public final int numUser;%0A    public final int numItem;%0A    //End Adding%0A    %0A
     publ
@@ -2204,23 +2204,943 @@
 aseline;
+ %0A        %0A        //Added%0A        numItem = iidx.getIds().size();%0A        numUser = uidx.getIds().size();%0A        averItemFeatures = getAverageFeatureVector(ifeats, numItem, featureCount);%0A        averUserFeatures = getAverageFeatureVector(ufeats, numUser, featureCount);%0A        //End Adding%0A        %0A    %7D%0A%0A    //Add%0A    %0A    private double%5B%5D getAverageFeatureVector(double%5B%5D%5B%5D twoDimMatrix, int dimension, int feature)%7B%0A    %09double%5B%5D outputVector = new double%5Bfeature%5D;%0A    %09for (int i = 0; i %3C feature; i++)%7B%0A    %09%09for (int j = 0; j %3C dimension; j++)%7B%0A    %09%09%09outputVector%5Bi%5D += twoDimMatrix%5Bi%5D%5Bj%5D;%0A    %09%09%7D%0A    %09%09outputVector%5Bi%5D = outputVector%5Bi%5D / dimension;%0A    %09%7D%0A    %09return outputVector;%0A    %7D%0A    %0A    public double getUserFeatureValue(int user, int feature)%7B%0A    %09return userFeatures%5Bfeature%5D%5Buser%5D;%0A    %7D%0A    %0A    public int getUserIndex(long user)%7B%0A    %09return userIndex.getIndex(user);%0A    %7D%0A    //End Adding
 %0A    
-%7D%0A
 %0A    pub

modify FunkSVDModel to cooperate with predictor (ref# 174)