use linalg::vector::Vector;
use linalg::utils;
use linalg::Metric;
use libnum::Float;
pub trait Kernel {
fn kernel(&self, x1: &[f64], x2: &[f64]) -> f64;
}
pub struct Linear {
pub c: f64,
}
impl Linear {
pub fn new(c: f64) -> Linear {
Linear {
c : c,
}
}
}
impl Default for Linear {
fn default() -> Linear {
Linear {
c: 0f64,
}
}
}
impl Kernel for Linear {
fn kernel(&self, x1: &[f64], x2: &[f64]) -> f64 {
utils::dot(x1, x2) + self.c
}
}
pub struct Polynomial {
pub alpha: f64,
pub c: f64,
pub d: f64,
}
impl Polynomial {
pub fn new(alpha: f64, c: f64, d: f64) -> Polynomial {
Polynomial {
alpha: alpha,
c : c,
d: d,
}
}
}
impl Default for Polynomial {
fn default() -> Polynomial {
Polynomial {
alpha: 1f64,
c: 0f64,
d: 1f64,
}
}
}
impl Kernel for Polynomial {
fn kernel(&self, x1: &[f64], x2: &[f64]) -> f64 {
(self.alpha * utils::dot(x1, x2) + self.c).powf(self.d)
}
}
pub struct SquaredExp {
pub ls: f64,
pub ampl: f64,
}
impl SquaredExp {
pub fn new(ls: f64, ampl: f64) -> SquaredExp {
SquaredExp {
ls: ls,
ampl: ampl,
}
}
}
impl Default for SquaredExp {
fn default() -> SquaredExp {
SquaredExp {
ls: 1f64,
ampl: 1f64,
}
}
}
impl Kernel for SquaredExp {
fn kernel(&self, x1: &[f64], x2: &[f64]) -> f64 {
assert_eq!(x1.len(), x2.len());
let diff = Vector::new(x1.to_vec()) - Vector::new(x2.to_vec());
let x = -diff.dot(&diff) / (2f64 * self.ls * self.ls);
(self.ampl * x.exp())
}
}
pub struct Exponential {
pub ls: f64,
pub ampl: f64,
}
impl Exponential {
pub fn new(ls: f64, ampl: f64) -> Exponential {
Exponential {
ls: ls,
ampl: ampl,
}
}
}
impl Default for Exponential {
fn default() -> Exponential {
Exponential {
ls: 1f64,
ampl: 1f64,
}
}
}
impl Kernel for Exponential {
fn kernel(&self, x1: &[f64], x2: &[f64]) -> f64 {
assert_eq!(x1.len(), x2.len());
let diff = Vector::new(x1.to_vec()) - Vector::new(x2.to_vec());
let x = -diff.norm() / (2f64 * self.ls * self.ls);
(self.ampl * x.exp())
}
}
pub struct HyperTan {
pub alpha: f64,
pub c: f64,
}
impl HyperTan {
pub fn new(alpha: f64, c: f64) -> HyperTan {
HyperTan {
alpha: alpha,
c : c,
}
}
}
impl Default for HyperTan {
fn default() -> HyperTan {
HyperTan {
alpha: 1f64,
c: 0f64,
}
}
}
impl Kernel for HyperTan {
fn kernel(&self, x1: &[f64], x2: &[f64]) -> f64 {
(self.alpha * utils::dot(x1, x2) + self.c).tanh()
}
}
pub struct Multiquadric {
pub c: f64,
}
impl Multiquadric {
pub fn new(c: f64) -> Multiquadric {
Multiquadric {
c : c,
}
}
}
impl Default for Multiquadric {
fn default() -> Multiquadric {
Multiquadric {
c: 0f64,
}
}
}
impl Kernel for Multiquadric {
fn kernel(&self, x1: &[f64], x2: &[f64]) -> f64 {
assert_eq!(x1.len(), x2.len());
let diff = Vector::new(x1.to_vec()) - Vector::new(x2.to_vec());
diff.norm().hypot(self.c)
}
}
pub struct RationalQuadratic {
pub alpha: f64,
pub ls: f64,
}
impl RationalQuadratic {
pub fn new(alpha: f64, ls: f64) -> RationalQuadratic {
RationalQuadratic {
alpha: alpha,
ls: ls,
}
}
}
impl Default for RationalQuadratic {
fn default() -> RationalQuadratic {
RationalQuadratic {
alpha: 1f64,
ls: 1f64,
}
}
}
impl Kernel for RationalQuadratic {
fn kernel(&self, x1: &[f64], x2: &[f64]) -> f64 {
let diff = Vector::new(x1.to_vec()) - Vector::new(x2.to_vec());
(1f64 + diff.dot(&diff) / (2f64 * self.alpha * self.ls * self.ls)).powf(-self.alpha)
}
}