/*
 * Regression.java
 * Created on Apr 11, 2005
 */
package kernel;

import javax.vecmath.GMatrix;
import javax.vecmath.GVector;
import javax.vecmath.MismatchedSizeException;

/**
 * A utility class for performing regression with kernels.
 */
public final class Regression {

    private Regression() {}
    
    public static Representer solve(GMatrix data, GVector values,
                             Kernel kernel, double lambda) {
        int numPoints = data.getNumCol();
        if (numPoints != values.getSize()) {
            throw new MismatchedSizeException();
        }
        
        // calculate the coefficients c
        GMatrix k = kernelMatrix(data, kernel);
        GMatrix l = new GMatrix(numPoints, numPoints);
        l.setScale(lambda);
        k.sub(l);
        k.invert();
        GVector c = new GVector(numPoints);
        c.mul(k, values);
        
        return new Representer(kernel, data, c);
    }
    
    public static GMatrix kernelMatrix(GMatrix data, Kernel kernel) {
        int rows = data.getNumRow(), cols = data.getNumCol();
        GMatrix k = new GMatrix(cols, cols);
        
        for(int i = 0; i < cols; i++) {
            GVector v1 = new GVector(rows);
            data.getColumn(i, v1);
            
            for(int j = 0; j < cols; j++) {
                GVector v2 = new GVector(rows);
                data.getColumn(j, v2);
                k.setElement(i, j, kernel.eval(v1, v2));
            }
        }
        
        return k;
    }
}
