/*
* Apache License
* Version 2.0, January 2004
* http://www.apache.org/licenses/
*
* Copyright 2013 Aurelian Tutuianu
* Copyright 2014 Aurelian Tutuianu
* Copyright 2015 Aurelian Tutuianu
* Copyright 2016 Aurelian Tutuianu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package rapaio.ml.classifier.svm.kernel;
import rapaio.math.MathTools;
import rapaio.data.Frame;
import static rapaio.sys.WS.formatFlex;
/**
* The Polynomial kernel is a non-stationary kernel. Polynomial kernels
* are well suited for problems where all the training data is normalized.
* <p>
* k(x, y) = (\alpha x^T y + c)^d
* <p>
* Adjustable parameters are the slope alpha, the constant term c and the
* polynomial degree d.
* <p>
* A special case is the linear kernel (d=1).
* <p>
* The Linear kernel is the simplest kernel function. It is given by the
* inner product <x,y> plus an optional constant c. Kernel algorithms
* using a linear kernel are often equivalent to their non-kernel
* counterparts, i.e. KPCA with linear kernel is the same as standard PCA.
* <p>
* Created by <a href="mailto:padreati@yahoo.com">Aurelian Tutuianu</a> at 1/16/15.
*/
public class PolyKernel extends AbstractKernel {
private static final long serialVersionUID = 7520286921201342580L;
private final double exponent;
private final double bias;
private final double slope;
@Override
public boolean isLinear() {
return MathTools.eq(exponent, 1.0);
}
@Override
public Kernel newInstance() {
return new PolyKernel(exponent, bias, slope);
}
public PolyKernel(double exponent) {
this(exponent, 1.0, 1.0);
}
public PolyKernel(double exponent, double bias) {
this(exponent, bias, 1.0);
}
@Override
public String name() {
return "PolyKernel(" +
"exp=" + formatFlex(exponent) + "," +
"bias=" + formatFlex(bias) + "," +
"slope=" + formatFlex(slope) +
")";
}
public PolyKernel(double exponent, double bias, double slope) {
this.exponent = exponent;
this.slope = slope;
this.bias = bias;
}
@Override
public double eval(Frame df1, int row1, Frame df2, int row2) {
if (varNames == null) {
throw new IllegalArgumentException("This kernel is not build with var names");
}
double result = dotProd(df1, row1, df2, row2);
if (exponent != 1.0) {
result = Math.pow(slope * result + bias, exponent);
}
return result;
}
}