/*******************************************************************************
* Copyright (c) 2010 Haifeng Li
*
* 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 smile.math.kernel;
import java.lang.Math;
import java.io.Serializable;
/**
* The hyperbolic tangent kernel.
* k(u, v) = tanh(γ uTv - λ), where γ is the scale
* of the used inner product and λ is the offset of the used inner
* product. If the offset is negative the likelihood of obtaining a kernel
* matrix that is not positive definite is much higher (since then even some
* diagonal elements may be negative), hence if this kernel has to be used,
* the offset should always be positive. Note, however, that this is no
* guarantee that the kernel will be positive.
*
* The hyperbolic tangent kernel was quite popular for support vector machines
* due to its origin from neural networks. However, it should be used carefully
* since the kernel matrix may not be positive semi-definite. Besides, it was
* reported the hyperbolic tangent kernel is not better than the Gaussian kernel
* in general.
*
* The kernel works sparse binary array as int[], which are the indices of
* nonzero elements.
*
* @author Haifeng Li
*/
public class BinarySparseHyperbolicTangentKernel implements MercerKernel, Serializable {
private static final long serialVersionUID = 1L;
private double scale;
private double offset;
/**
* Constructor with scale 1.0 and offset 0.0.
*/
public BinarySparseHyperbolicTangentKernel() {
this(1, 0);
}
/**
* Constructor.
*/
public BinarySparseHyperbolicTangentKernel(double scale, double offset) {
this.scale = scale;
this.offset = offset;
}
@Override
public String toString() {
return String.format("Sparse Binary Hyperbolic Tangent Kernel (scale = %.4f, offset = %.4f)", scale, offset);
}
@Override
public double k(int[] x, int[] y) {
double dot = 0.0;
for (int p1 = 0, p2 = 0; p1 < x.length && p2 < y.length; ) {
int i1 = x[p1];
int i2 = y[p2];
if (i1 == i2) {
dot++;
p1++;
p2++;
} else if (i1 > i2) {
p2++;
} else {
p1++;
}
}
return Math.tanh(scale * dot + offset);
}
}
Ads help maintain this website.