diff --git a/.vscode/settings.json b/.vscode/settings.json index 2163812..12a24e2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,4 +2,7 @@ "editor.tabSize": 2, "editor.detectIndentation": false, "editor.formatOnSave": true, -} + "rust-analyzer.diagnostics.disabled": [ + "unresolved-proc-macro" + ], +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 5d0dea3..8ba7b3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "opensrdk-kernel-method" -version = "0.2.3" +version = "0.2.5" authors = ["Kimura Yu <33382781+KimuraYu45z@users.noreply.github.com>"] edition = "2018" description = "Standard Kernel Method library for OpenSRDK toolchain." @@ -12,6 +12,7 @@ categories = ["mathematics", "science"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +opensrdk-symbolic-computation = "0.2.0" rayon = "1.5.1" thiserror = "1.0.28" opensrdk-linear-algebra = "0.8.2" diff --git a/src/add.rs b/src/add.rs index 93e42cd..d351470 100644 --- a/src/add.rs +++ b/src/add.rs @@ -1,54 +1,48 @@ -use crate::KernelError; -use crate::ParamsDifferentiableKernel; -use crate::Value; -use crate::ValueDifferentiableKernel; -use crate::{KernelMul, PositiveDefiniteKernel}; -use opensrdk_linear_algebra::Vector; +use crate::{KernelError, KernelMul, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; use std::fmt::Debug; -use std::marker::PhantomData; use std::{ops::Add, ops::Mul}; #[derive(Clone, Debug)] -pub struct KernelAdd +pub struct KernelAdd where - L: PositiveDefiniteKernel, - R: PositiveDefiniteKernel, - T: Value, + L: PositiveDefiniteKernel, + R: PositiveDefiniteKernel, { lhs: L, rhs: R, - phantom: PhantomData, } -impl KernelAdd +impl KernelAdd where - L: PositiveDefiniteKernel, - R: PositiveDefiniteKernel, - T: Value, + L: PositiveDefiniteKernel, + R: PositiveDefiniteKernel, { pub fn new(lhs: L, rhs: R) -> Self { - Self { - lhs, - rhs, - phantom: PhantomData, - } + Self { lhs, rhs } } } -impl PositiveDefiniteKernel for KernelAdd +impl PositiveDefiniteKernel for KernelAdd where - L: PositiveDefiniteKernel, - R: PositiveDefiniteKernel, - T: Value, + L: PositiveDefiniteKernel, + R: PositiveDefiniteKernel, { fn params_len(&self) -> usize { self.lhs.params_len() + self.rhs.params_len() } - fn value(&self, params: &[f64], x: &T, xprime: &T) -> Result { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { let lhs_params_len = self.lhs.params_len(); - let fx = self.lhs.value(¶ms[..lhs_params_len], x, xprime)?; - let gx = self.rhs.value(¶ms[lhs_params_len..], x, xprime)?; + let fx = self + .lhs + .expression(x.clone(), x_prime.clone(), ¶ms[..lhs_params_len])?; + let gx = self.rhs.expression(x, x_prime, ¶ms[lhs_params_len..])?; let hx = fx + gx; @@ -56,86 +50,84 @@ where } } -impl Add for KernelAdd +impl Add for KernelAdd where - Rhs: PositiveDefiniteKernel, - L: PositiveDefiniteKernel, - R: PositiveDefiniteKernel, - T: Value, + Rhs: PositiveDefiniteKernel, + L: PositiveDefiniteKernel, + R: PositiveDefiniteKernel, { - type Output = KernelAdd; + type Output = KernelAdd; fn add(self, rhs: Rhs) -> Self::Output { Self::Output::new(self, rhs) } } -impl Mul for KernelAdd +impl Mul for KernelAdd where - Rhs: PositiveDefiniteKernel, - L: PositiveDefiniteKernel, - R: PositiveDefiniteKernel, - T: Value, + Rhs: PositiveDefiniteKernel, + L: PositiveDefiniteKernel, + R: PositiveDefiniteKernel, { - type Output = KernelMul; + type Output = KernelMul; fn mul(self, rhs: Rhs) -> Self::Output { Self::Output::new(self, rhs) } } -impl ValueDifferentiableKernel for KernelAdd -where - L: ValueDifferentiableKernel, - R: ValueDifferentiableKernel, - T: Value, -{ - fn ln_diff_value(&self, params: &[f64], x: &T, xprime: &T) -> Result, KernelError> { - let diff_rhs = &self - .rhs - .ln_diff_value(params, x, xprime) - .unwrap() - .clone() - .col_mat(); - let diff_lhs = &self - .lhs - .ln_diff_value(params, x, xprime) - .unwrap() - .clone() - .col_mat(); - let value_rhs = vec![self.rhs.value(params, x, xprime).unwrap()].col_mat(); - let value_lhs = vec![self.lhs.value(params, x, xprime).unwrap()].col_mat(); - let diff = ((&value_rhs * diff_rhs + &value_lhs * diff_lhs) - * (&value_rhs + value_lhs)[(0, 0)].powi(-1)) - .vec(); - Ok(diff) - } -} +// impl ValueDifferentiableKernel for KernelAdd +// where +// L: ValueDifferentiableKernel, +// R: ValueDifferentiableKernel, +// T: Value, +// { +// fn ln_diff_value(&self, params: &[f64], x: &T, xprime: &T) -> Result, KernelError> { +// let diff_rhs = &self +// .rhs +// .ln_diff_value(params, x, xprime) +// .unwrap() +// .clone() +// .col_mat(); +// let diff_lhs = &self +// .lhs +// .ln_diff_value(params, x, xprime) +// .unwrap() +// .clone() +// .col_mat(); +// let value_rhs = vec![self.rhs.value(params, x, xprime).unwrap()].col_mat(); +// let value_lhs = vec![self.lhs.value(params, x, xprime).unwrap()].col_mat(); +// let diff = ((&value_rhs * diff_rhs + &value_lhs * diff_lhs) +// * (&value_rhs + value_lhs)[(0, 0)].powi(-1)) +// .vec(); +// Ok(diff) +// } +// } -impl ParamsDifferentiableKernel for KernelAdd -where - L: ParamsDifferentiableKernel, - R: ParamsDifferentiableKernel, - T: Value, -{ - fn ln_diff_params(&self, params: &[f64], x: &T, xprime: &T) -> Result, KernelError> { - let diff_rhs = &self - .rhs - .ln_diff_params(params, x, xprime) - .unwrap() - .clone() - .col_mat(); - let diff_lhs = &self - .lhs - .ln_diff_params(params, x, xprime) - .unwrap() - .clone() - .col_mat(); - let value_rhs = vec![self.rhs.value(params, x, xprime).unwrap()].col_mat(); - let value_lhs = vec![self.lhs.value(params, x, xprime).unwrap()].col_mat(); - let diff = ((&value_rhs * diff_rhs + &value_lhs * diff_lhs) - * (&value_rhs + value_lhs)[(0, 0)].powi(-1)) - .vec(); - Ok(diff) - } -} +// impl ParamsDifferentiableKernel for KernelAdd +// where +// L: ParamsDifferentiableKernel, +// R: ParamsDifferentiableKernel, +// T: Value, +// { +// fn ln_diff_params(&self, params: &[f64], x: &T, xprime: &T) -> Result, KernelError> { +// let diff_rhs = &self +// .rhs +// .ln_diff_params(params, x, xprime) +// .unwrap() +// .clone() +// .col_mat(); +// let diff_lhs = &self +// .lhs +// .ln_diff_params(params, x, xprime) +// .unwrap() +// .clone() +// .col_mat(); +// let value_rhs = vec![self.rhs.value(params, x, xprime).unwrap()].col_mat(); +// let value_lhs = vec![self.lhs.value(params, x, xprime).unwrap()].col_mat(); +// let diff = ((&value_rhs * diff_rhs + &value_lhs * diff_lhs) +// * (&value_rhs + value_lhs)[(0, 0)].powi(-1)) +// .vec(); +// Ok(diff) +// } +// } diff --git a/src/ard/mod.rs b/src/ard/mod.rs index 415ae36..80fd13e 100644 --- a/src/ard/mod.rs +++ b/src/ard/mod.rs @@ -1,46 +1,53 @@ use super::PositiveDefiniteKernel; -use crate::{ - KernelAdd, KernelError, KernelMul, ParamsDifferentiableKernel, ValueDifferentiableKernel, -}; +use crate::{KernelAdd, KernelError, KernelMul}; +use opensrdk_symbolic_computation::Expression; use rayon::prelude::*; use std::{ops::Add, ops::Mul}; -fn weighted_norm_pow(params: &[f64], x: &Vec, xprime: &Vec) -> f64 { - params - .par_iter() - .zip(x.par_iter()) - .zip(xprime.par_iter()) - .map(|((relevance, xi), xprimei)| relevance * (xi - xprimei).powi(2)) - .sum() +fn weighted_norm_pow(x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { + todo!() + // params + // .par_iter() + // .zip(x.par_iter()) + // .zip(x_prime.par_iter()) + // .map(|((relevance, xi), x_primei)| relevance * (xi - x_primei).powi(2)) + // .sum() } +//must rewite this function! #[derive(Clone, Debug)] pub struct ARD(pub usize); -impl PositiveDefiniteKernel> for ARD { +impl PositiveDefiniteKernel for ARD { fn params_len(&self) -> usize { self.0 } - fn value(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { if params.len() != self.0 { return Err(KernelError::ParametersLengthMismatch.into()); } - if x.len() != self.0 || xprime.len() != self.0 { - return Err(KernelError::InvalidArgument.into()); - } + // if x.len() != self.0 || x_prime.len() != self.0 { + // return Err(KernelError::InvalidArgument.into()); + // } + todo!() - let fx = (-weighted_norm_pow(¶ms, x, xprime)).exp(); + // let fx = (-weighted_norm_pow(¶ms, x, x_prime)).exp(); - Ok(fx) + // Ok(fx) } } impl Add for ARD where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelAdd>; + type Output = KernelAdd; fn add(self, rhs: R) -> Self::Output { Self::Output::new(self, rhs) @@ -49,60 +56,60 @@ where impl Mul for ARD where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelMul>; + type Output = KernelMul; fn mul(self, rhs: R) -> Self::Output { Self::Output::new(self, rhs) } } -impl ValueDifferentiableKernel> for ARD { - fn ln_diff_value( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { - let diff = params - .par_iter() - .zip(x.par_iter()) - .zip(xprime.par_iter()) - .map(|((relevance, xi), xprimei)| -2.0 * relevance * (xi - xprimei)) - .collect::>(); - Ok(diff) - } -} +// impl ValueDifferentiableKernel> for ARD { +// fn ln_diff_value( +// &self, +// params: &[f64], +// x: &Vec, +// xprime: &Vec, +// ) -> Result, KernelError> { +// let diff = params +// .par_iter() +// .zip(x.par_iter()) +// .zip(xprime.par_iter()) +// .map(|((relevance, xi), xprimei)| -2.0 * relevance * (xi - xprimei)) +// .collect::>(); +// Ok(diff) +// } +// } -impl ParamsDifferentiableKernel> for ARD { - fn ln_diff_params( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { - let diff = params - .par_iter() - .zip(x.par_iter()) - .zip(xprime.par_iter()) - .map(|((_relevance, xi), xprimei)| -(xi - xprimei).powi(2)) - .collect::>(); - Ok(diff) - } -} +// impl ParamsDifferentiableKernel> for ARD { +// fn ln_diff_params( +// &self, +// params: &[f64], +// x: &Vec, +// xprime: &Vec, +// ) -> Result, KernelError> { +// let diff = params +// .par_iter() +// .zip(x.par_iter()) +// .zip(xprime.par_iter()) +// .map(|((_relevance, xi), xprimei)| -(xi - xprimei).powi(2)) +// .collect::>(); +// Ok(diff) +// } +// } -#[cfg(test)] -mod tests { - use crate::*; - #[test] - fn it_works() { - let kernel = ARD(3); +// #[cfg(test)] +// mod tests { +// use crate::*; +// #[test] +// fn it_works() { +// let kernel = ARD(3); - let test_value = kernel - .value(&[1.0, 0.0, 0.0], &vec![1.0, 2.0, 3.0], &vec![0.0, 2.0, 1.0]) - .unwrap(); +// let test_value = kernel +// .value(&[1.0, 0.0, 0.0], &vec![1.0, 2.0, 3.0], &vec![0.0, 2.0, 1.0]) +// .unwrap(); - assert_eq!(test_value, (-1f64).exp()); - } -} +// assert_eq!(test_value, (-1f64).exp()); +// } +// } diff --git a/src/constant.rs b/src/constant.rs index e14e123..ee5f005 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -1,90 +1,145 @@ -use super::PositiveDefiniteKernel; -use crate::{KernelAdd, KernelError, KernelMul}; -use crate::{ParamsDifferentiableKernel, Value, ValueDifferentiableKernel}; -use std::fmt::Debug; -use std::{ops::Add, ops::Mul}; +use std::ops::{Add, Mul}; + +use crate::KernelError; + +use super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; const PARAMS_LEN: usize = 1; #[derive(Clone, Debug)] pub struct Constant; -impl PositiveDefiniteKernel for Constant -where - T: Value, -{ - fn params_len(&self) -> usize { - PARAMS_LEN - } - - fn value(&self, params: &[f64], _: &T, _: &T) -> Result { +impl PositiveDefiniteKernel for Constant { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { if params.len() != PARAMS_LEN { return Err(KernelError::ParametersLengthMismatch.into()); } + // if x.len() != x_prime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } + Ok(params[0].clone()) + } - let fx = params[0]; - - Ok(fx) + fn params_len(&self) -> usize { + 1 } } impl Add for Constant where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelAdd>; + type Output = KernelAdd; fn add(self, rhs: R) -> Self::Output { - Self::Output::new(self, rhs) + KernelAdd::new(self, rhs) } } impl Mul for Constant where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelMul>; + type Output = KernelMul; fn mul(self, rhs: R) -> Self::Output { - Self::Output::new(self, rhs) + KernelMul::new(self, rhs) } } -impl ValueDifferentiableKernel> for Constant { - fn ln_diff_value( - &self, - _params: &[f64], - x: &Vec, - _xprime: &Vec, - ) -> Result, KernelError> { - let diff = vec![0.0; x.len()]; - Ok(diff) - } -} +// use super::PositiveDefiniteKernel; +// use crate::{KernelAdd, KernelError, KernelMul}; +// use crate::{ParamsDifferentiableKernel, Value, ValueDifferentiableKernel}; +// use std::fmt::Debug; +// use std::{ops::Add, ops::Mul}; -impl ParamsDifferentiableKernel> for Constant { - fn ln_diff_params( - &self, - _params: &[f64], - _x: &Vec, - _xprime: &Vec, - ) -> Result, KernelError> { - let diff = vec![1.0]; - Ok(diff) - } -} +// const PARAMS_LEN: usize = 1; -#[cfg(test)] -mod tests { - use crate::*; - #[test] - fn it_works() { - let kernel = Constant; +// #[derive(Clone, Debug)] +// pub struct Constant; - let test_value = kernel - .value(&[1.0], &vec![1.0, 2.0, 3.0], &vec![3.0, 2.0, 1.0]) - .unwrap(); +// impl PositiveDefiniteKernel for Constant +// where +// T: Value, +// { +// fn params_len(&self) -> usize { +// PARAMS_LEN +// } - assert_eq!(test_value, 1.0); - } -} +// fn value(&self, params: &[f64], _: &T, _: &T) -> Result { +// if params.len() != PARAMS_LEN { +// return Err(KernelError::ParametersLengthMismatch.into()); +// } + +// let fx = params[0]; + +// Ok(fx) +// } +// } + +// impl Add for Constant +// where +// R: PositiveDefiniteKernel>, +// { +// type Output = KernelAdd>; + +// fn add(self, rhs: R) -> Self::Output { +// Self::Output::new(self, rhs) +// } +// } + +// impl Mul for Constant +// where +// R: PositiveDefiniteKernel>, +// { +// type Output = KernelMul>; + +// fn mul(self, rhs: R) -> Self::Output { +// Self::Output::new(self, rhs) +// } +// } + +// impl ValueDifferentiableKernel> for Constant { +// fn ln_diff_value( +// &self, +// _params: &[f64], +// x: &Vec, +// _xprime: &Vec, +// ) -> Result, KernelError> { +// let diff = vec![0.0; x.len()]; +// Ok(diff) +// } +// } + +// impl ParamsDifferentiableKernel> for Constant { +// fn ln_diff_params( +// &self, +// _params: &[f64], +// _x: &Vec, +// _xprime: &Vec, +// ) -> Result, KernelError> { +// let diff = vec![1.0]; +// Ok(diff) +// } +// } + +// #[cfg(test)] +// mod tests { +// use crate::*; +// #[test] +// fn it_works() { +// let kernel = Constant; + +// let test_value = kernel +// .value(&[1.0], &vec![1.0, 2.0, 3.0], &vec![3.0, 2.0, 1.0]) +// .unwrap(); + +// assert_eq!(test_value, 1.0); +// } +// } diff --git a/src/convolutional.rs b/src/convolutional.rs index 9a51bed..1ade6b6 100644 --- a/src/convolutional.rs +++ b/src/convolutional.rs @@ -1,39 +1,34 @@ -use crate::Value; use crate::{KernelError, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; use rayon::prelude::*; use std::fmt::Debug; -pub trait Convolutable: Value { +pub trait Convolutable { fn parts_len(&self) -> usize; - fn part(&self, index: usize) -> &Vec; - fn data_len(&self) -> usize; + fn part(&self, index: usize) -> &Expression; } -impl Convolutable for Vec { +impl Convolutable for Expression { fn parts_len(&self) -> usize { 1 } - fn part(&self, _: usize) -> &Vec { + fn part(&self, _: usize) -> &Expression { self } - - fn data_len(&self) -> usize { - self.len() - } } #[derive(Clone, Debug)] pub struct Convolutional where - K: PositiveDefiniteKernel>, + K: PositiveDefiniteKernel, { kernel: K, } impl Convolutional where - K: PositiveDefiniteKernel>, + K: PositiveDefiniteKernel, { pub fn new(kernel: K) -> Self { Self { kernel } @@ -44,45 +39,57 @@ where } } -impl PositiveDefiniteKernel for Convolutional +impl PositiveDefiniteKernel for Convolutional where - T: Convolutable, - K: PositiveDefiniteKernel>, + K: PositiveDefiniteKernel, { fn params_len(&self) -> usize { self.kernel.params_len() } - fn value(&self, params: &[f64], x: &T, xprime: &T) -> Result { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { if params.len() != self.kernel.params_len() { return Err(KernelError::ParametersLengthMismatch.into()); } let p = x.parts_len(); - if p != xprime.parts_len() { + if p != x_prime.parts_len() { return Err(KernelError::InvalidArgument.into()); } - let fx = (0..p) - .into_par_iter() - .map(|pi| self.kernel.value(params, x.part(pi), xprime.part(pi))) - .sum::>()?; + todo!() + + // let fx = (0..p) + // .into_par_iter() + // .map(|pi| { + // let expression = self + // .kernel + // .expression(x.part(pi).clone(), x_prime.part(pi).clone(), params) + // .unwrap(); + // expression + // }) + // .sum::>()?; - Ok(fx) + // Ok(fx) } } -#[cfg(test)] -mod tests { - use crate::*; - #[test] - fn it_works() { - let kernel = Convolutional::new(RBF); +// #[cfg(test)] +// mod tests { +// use crate::*; +// #[test] +// fn it_works() { +// let kernel = Convolutional::new(RBF); - let test_value = kernel.value(&[1.0], &vec![0.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0]); +// let test_value = kernel.value(&[1.0], &vec![0.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0]); - match test_value { - Err(KernelError::ParametersLengthMismatch) => (), - _ => panic!(), - }; - } -} +// match test_value { +// Err(KernelError::ParametersLengthMismatch) => (), +// _ => panic!(), +// }; +// } +// } diff --git a/src/exponential.rs b/src/exponential.rs index 044e6b5..5b976d1 100644 --- a/src/exponential.rs +++ b/src/exponential.rs @@ -1,108 +1,171 @@ -use super::PositiveDefiniteKernel; -use crate::{ - KernelAdd, KernelError, KernelMul, ParamsDifferentiableKernel, ValueDifferentiableKernel, -}; -use opensrdk_linear_algebra::Vector; -use rayon::prelude::*; -use std::{ops::Add, ops::Mul}; +use std::ops::{Add, Mul}; + +use crate::KernelError; + +use super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; const PARAMS_LEN: usize = 1; #[derive(Clone, Debug)] pub struct Exponential; -impl Exponential { - fn norm(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { +impl PositiveDefiniteKernel for Exponential { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { if params.len() != PARAMS_LEN { return Err(KernelError::ParametersLengthMismatch.into()); } - if x.len() != xprime.len() { - return Err(KernelError::InvalidArgument.into()); - } - - let v = x - .par_iter() - .zip(xprime.par_iter()) - .map(|(x_i, xprime_i)| (x_i - xprime_i).powi(2)) - .sum::() - .sqrt(); - - Ok(v) + // if x.len() != x_prime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } + + let diff = x - x_prime; + + Ok((-diff + .clone() + .dot(diff, &[[0, 0]]) + .pow(Expression::from(1.0 / 2.0)) + / params[0].clone()) + .exp()) } -} -impl PositiveDefiniteKernel> for Exponential { fn params_len(&self) -> usize { - PARAMS_LEN - } - - fn value(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { - let norm = self.norm(params, x, xprime)?; - - let fx = (-norm / params[0]).exp(); - - Ok(fx) - } -} - -impl ValueDifferentiableKernel> for Exponential { - fn ln_diff_value( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { - let diff = (-2.0 / params[0] * (x.clone().col_mat() - xprime.clone().col_mat())).vec(); - Ok(diff) - } -} - -impl ParamsDifferentiableKernel> for Exponential { - fn ln_diff_params( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { - let diff1 = 2.0 * params[0].powi(-2) * &self.norm(params, x, xprime).unwrap(); - let diff = vec![diff1]; - Ok(diff) + 1 } } impl Add for Exponential where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelAdd>; + type Output = KernelAdd; fn add(self, rhs: R) -> Self::Output { - Self::Output::new(self, rhs) + KernelAdd::new(self, rhs) } } impl Mul for Exponential where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelMul>; + type Output = KernelMul; fn mul(self, rhs: R) -> Self::Output { - Self::Output::new(self, rhs) + KernelMul::new(self, rhs) } } -#[cfg(test)] -mod tests { - use crate::*; - #[test] - fn it_works() { - let kernel = Exponential; - - let test_value = kernel - .value(&[1.0], &vec![1.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0]) - .unwrap(); - - assert_eq!(test_value, (-1f64).exp()); - } -} +// use super::PositiveDefiniteKernel; +// use crate::{ +// KernelAdd, KernelError, KernelMul, ParamsDifferentiableKernel, ValueDifferentiableKernel, +// }; +// use opensrdk_linear_algebra::Vector; +// use rayon::prelude::*; +// use std::{ops::Add, ops::Mul}; + +// const PARAMS_LEN: usize = 1; + +// #[derive(Clone, Debug)] +// pub struct Exponential; + +// impl Exponential { +// fn norm(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { +// if params.len() != PARAMS_LEN { +// return Err(KernelError::ParametersLengthMismatch.into()); +// } +// if x.len() != xprime.len() { +// return Err(KernelError::InvalidArgument.into()); +// } + +// let v = x +// .par_iter() +// .zip(xprime.par_iter()) +// .map(|(x_i, xprime_i)| (x_i - xprime_i).powi(2)) +// .sum::() +// .sqrt(); + +// Ok(v) +// } +// } + +// impl PositiveDefiniteKernel> for Exponential { +// fn params_len(&self) -> usize { +// PARAMS_LEN +// } + +// fn value(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { +// let norm = self.norm(params, x, xprime)?; + +// let fx = (-norm / params[0]).exp(); + +// Ok(fx) +// } +// } + +// impl ValueDifferentiableKernel> for Exponential { +// fn ln_diff_value( +// &self, +// params: &[f64], +// x: &Vec, +// xprime: &Vec, +// ) -> Result, KernelError> { +// let diff = (-2.0 / params[0] * (x.clone().col_mat() - xprime.clone().col_mat())).vec(); +// Ok(diff) +// } +// } + +// impl ParamsDifferentiableKernel> for Exponential { +// fn ln_diff_params( +// &self, +// params: &[f64], +// x: &Vec, +// xprime: &Vec, +// ) -> Result, KernelError> { +// let diff1 = 2.0 * params[0].powi(-2) * &self.norm(params, x, xprime).unwrap(); +// let diff = vec![diff1]; +// Ok(diff) +// } +// } + +// impl Add for Exponential +// where +// R: PositiveDefiniteKernel>, +// { +// type Output = KernelAdd>; + +// fn add(self, rhs: R) -> Self::Output { +// Self::Output::new(self, rhs) +// } +// } + +// impl Mul for Exponential +// where +// R: PositiveDefiniteKernel>, +// { +// type Output = KernelMul>; + +// fn mul(self, rhs: R) -> Self::Output { +// Self::Output::new(self, rhs) +// } +// } + +// #[cfg(test)] +// mod tests { +// use crate::*; +// #[test] +// fn it_works() { +// let kernel = Exponential; + +// let test_value = kernel +// .value(&[1.0], &vec![1.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0]) +// .unwrap(); + +// assert_eq!(test_value, (-1f64).exp()); +// } +// } diff --git a/src/instant.rs b/src/instant.rs index c971013..a5b5f40 100644 --- a/src/instant.rs +++ b/src/instant.rs @@ -1,103 +1,191 @@ -use super::PositiveDefiniteKernel; +use std::{ + marker::PhantomData, + ops::{Add, Mul}, +}; + use crate::KernelError; -use crate::Value; -use crate::{KernelAdd, KernelMul}; -use std::marker::PhantomData; -use std::{fmt::Debug, ops::Add, ops::Mul}; + +use std::fmt::Debug; + +use super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; #[derive(Clone)] -pub struct InstantKernel +pub struct InstantKernel where - T: Value, - F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, + F: Fn(&Expression, &Expression, &[Expression]) -> Result + + Clone + + Send + + Sync, { params_len: usize, - value_function: F, - phantom: PhantomData, -} - -impl InstantKernel -where - T: Value, - F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, -{ - pub fn new(params_len: usize, value_function: F) -> Self { - Self { - params_len, - value_function, - phantom: PhantomData, - } - } + function: F, + phantom: PhantomData, } -impl Debug for InstantKernel +impl Debug for InstantKernel where - T: Value, - F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, + F: Fn(&Expression, &Expression, &[Expression]) -> Result + + Clone + + Send + + Sync, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "InstantKernel {{ params_len: {} }}", self.params_len) } } -impl PositiveDefiniteKernel for InstantKernel +impl PositiveDefiniteKernel for InstantKernel where - T: Value, - F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, + F: Fn(&Expression, &Expression, &[Expression]) -> Result + + Clone + + Send + + Sync, { - fn params_len(&self) -> usize { - self.params_len + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { + (self.function)(&x, &x_prime, params) } - fn value(&self, params: &[f64], x: &T, xprime: &T) -> Result { - (self.value_function)(params, x, xprime) + fn params_len(&self) -> usize { + self.params_len } } -impl Add for InstantKernel +impl Add for InstantKernel where - T: Value, - R: PositiveDefiniteKernel, - F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, + R: PositiveDefiniteKernel, + F: Fn(&Expression, &Expression, &[Expression]) -> Result + + Clone + + Send + + Sync, { - type Output = KernelAdd; + type Output = KernelAdd; fn add(self, rhs: R) -> Self::Output { - Self::Output::new(self, rhs) + KernelAdd::new(self, rhs) } } -impl Mul for InstantKernel +impl Mul for InstantKernel where - T: Value, - R: PositiveDefiniteKernel, - F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, + F: Fn(&Expression, &Expression, &[Expression]) -> Result + + Clone + + Send + + Sync, + R: PositiveDefiniteKernel, { - type Output = KernelMul; + type Output = KernelMul; fn mul(self, rhs: R) -> Self::Output { - Self::Output::new(self, rhs) + KernelMul::new(self, rhs) } } -#[cfg(test)] -mod tests { - use crate::*; - #[test] - fn it_works() { - let kernel = RBF + InstantKernel::new(0, |_, _, _| Ok(0.0)); +// use super::PositiveDefiniteKernel; +// use crate::KernelError; +// use crate::Value; +// use crate::{KernelAdd, KernelMul}; +// use std::marker::PhantomData; +// use std::{fmt::Debug, ops::Add, ops::Mul}; - //let (func, grad) = kernel - // .value_with_grad(&[1.0, 1.0], &vec![1.0, 2.0, 3.0], &vec![3.0, 2.0, 1.0]) - // .unwrap(); +// #[derive(Clone)] +// pub struct InstantKernel +// where +// T: Value, +// F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, +// { +// params_len: usize, +// value_function: F, +// phantom: PhantomData, +// } - //println!("{}", func); - //println!("{:#?}", grad); +// impl InstantKernel +// where +// T: Value, +// F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, +// { +// pub fn new(params_len: usize, value_function: F) -> Self { +// Self { +// params_len, +// value_function, +// phantom: PhantomData, +// } +// } +// } - let test_value = kernel - .value(&[1.0, 1.0], &vec![1.0, 2.0, 3.0], &vec![3.0, 2.0, 1.0]) - .unwrap(); +// impl Debug for InstantKernel +// where +// T: Value, +// F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, +// { +// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +// write!(f, "InstantKernel {{ params_len: {} }}", self.params_len) +// } +// } - println!("{}", test_value); - } -} +// impl PositiveDefiniteKernel for InstantKernel +// where +// T: Value, +// F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, +// { +// fn params_len(&self) -> usize { +// self.params_len +// } + +// fn value(&self, params: &[f64], x: &T, xprime: &T) -> Result { +// (self.value_function)(params, x, xprime) +// } +// } + +// impl Add for InstantKernel +// where +// T: Value, +// R: PositiveDefiniteKernel, +// F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, +// { +// type Output = KernelAdd; + +// fn add(self, rhs: R) -> Self::Output { +// Self::Output::new(self, rhs) +// } +// } + +// impl Mul for InstantKernel +// where +// T: Value, +// R: PositiveDefiniteKernel, +// F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, +// { +// type Output = KernelMul; + +// fn mul(self, rhs: R) -> Self::Output { +// Self::Output::new(self, rhs) +// } +// } + +// #[cfg(test)] +// mod tests { +// use crate::*; +// #[test] +// fn it_works() { +// let kernel = RBF + InstantKernel::new(0, |_, _, _| Ok(0.0)); + +// //let (func, grad) = kernel +// // .value_with_grad(&[1.0, 1.0], &vec![1.0, 2.0, 3.0], &vec![3.0, 2.0, 1.0]) +// // .unwrap(); + +// //println!("{}", func); +// //println!("{:#?}", grad); + +// let test_value = kernel +// .value(&[1.0, 1.0], &vec![1.0, 2.0, 3.0], &vec![3.0, 2.0, 1.0]) +// .unwrap(); + +// println!("{}", test_value); +// } +// } diff --git a/src/lib.rs b/src/lib.rs index 59b1ead..e470639 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,13 +11,10 @@ pub use instant::*; pub use linear::*; pub use mul::*; pub use neural_network::{deep_neural_network::*, relu::*}; +use opensrdk_symbolic_computation::Expression; pub use periodic::*; pub use rbf::*; pub use spectral_mixture::*; -pub use traits::{ - params_differentiable::*, params_differentiable::*, value_differentiable::*, - value_differentiable::*, -}; use std::fmt::Debug; @@ -33,18 +30,19 @@ pub mod neural_network; pub mod periodic; pub mod rbf; pub mod spectral_mixture; -pub mod traits; pub trait Value: Clone + Debug + Send + Sync {} impl Value for T where T: Clone + Debug + Send + Sync {} -pub trait PositiveDefiniteKernel: Clone + Debug + Send + Sync -where - T: Value, -{ +pub trait PositiveDefiniteKernel: Clone + Debug + Send + Sync { fn params_len(&self) -> usize; - fn value(&self, params: &[f64], x: &T, xprime: &T) -> Result; + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result; } #[derive(thiserror::Error, Debug)] @@ -57,20 +55,20 @@ pub enum KernelError { InvalidArgument, } -#[cfg(test)] -mod tests { - use crate::*; - #[test] - fn it_works() { - let kernel = RBF + Constant * Linear + Constant * Periodic + Constant * ARD(3); - let test_value = kernel - .value( - &vec![1.0; kernel.params_len()], - &vec![1.0, 2.0, 3.0], - &vec![30.0, 20.0, 10.0], - ) - .unwrap(); +// #[cfg(test)] +// mod tests { +// use crate::*; +// #[test] +// fn it_works() { +// let kernel = RBF + Constant * Linear + Constant * Periodic + Constant * ARD(3); +// let test_value = kernel +// .value( +// &vec![1.0; kernel.params_len()], +// &vec![1.0, 2.0, 3.0], +// &vec![30.0, 20.0, 10.0], +// ) +// .unwrap(); - println!("{}", test_value); - } -} +// println!("{}", test_value); +// } +// } diff --git a/src/linear.rs b/src/linear.rs index 24ef343..744ccbd 100644 --- a/src/linear.rs +++ b/src/linear.rs @@ -1,97 +1,151 @@ -use super::PositiveDefiniteKernel; -use crate::{ - KernelAdd, KernelError, KernelMul, ParamsDifferentiableKernel, ValueDifferentiableKernel, -}; -use opensrdk_linear_algebra::*; -use rayon::prelude::*; -use std::{ops::Add, ops::Mul}; +use std::ops::{Add, Mul}; -const PARAMS_LEN: usize = 0; +use crate::KernelError; + +use super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; +const PARAMS_LEN: usize = 0; #[derive(Clone, Debug)] pub struct Linear; -impl PositiveDefiniteKernel> for Linear { - fn params_len(&self) -> usize { - PARAMS_LEN - } - - fn value(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { +impl PositiveDefiniteKernel for Linear { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { if params.len() != PARAMS_LEN { return Err(KernelError::ParametersLengthMismatch.into()); } - if x.len() != xprime.len() { - return Err(KernelError::InvalidArgument.into()); - } - - let fx = x - .par_iter() - .zip(xprime.par_iter()) - .map(|(x_i, xprime_i)| x_i * xprime_i) - .sum(); + // if x.len() != x_prime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } + Ok(x.clone().dot(x_prime, &[[0, 0]])) + } - Ok(fx) + fn params_len(&self) -> usize { + 0 } } impl Add for Linear where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelAdd>; + type Output = KernelAdd; fn add(self, rhs: R) -> Self::Output { - Self::Output::new(self, rhs) + KernelAdd::new(self, rhs) } } impl Mul for Linear where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelMul>; + type Output = KernelMul; fn mul(self, rhs: R) -> Self::Output { - Self::Output::new(self, rhs) + KernelMul::new(self, rhs) } } -impl ValueDifferentiableKernel> for Linear { - fn ln_diff_value( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { - let value = &self.value(params, x, xprime)?; - let diff = (2.0 / value * x.clone().col_mat()).vec(); - Ok(diff) - } -} +// use super::PositiveDefiniteKernel; +// use crate::{ +// KernelAdd, KernelError, KernelMul, ParamsDifferentiableKernel, ValueDifferentiableKernel, +// }; +// use opensrdk_linear_algebra::*; +// use rayon::prelude::*; +// use std::{ops::Add, ops::Mul}; -impl ParamsDifferentiableKernel> for Linear { - fn ln_diff_params( - &self, - _params: &[f64], - _x: &Vec, - _xprime: &Vec, - ) -> Result, KernelError> { - let diff = vec![]; - Ok(diff) - } -} +// const PARAMS_LEN: usize = 0; -#[cfg(test)] -mod tests { - use crate::*; - #[test] - fn it_works() { - let kernel = Linear; +// #[derive(Clone, Debug)] +// pub struct Linear; - let test_value = kernel - .value(&[], &vec![1.0, 2.0, 3.0], &vec![3.0, 2.0, 1.0]) - .unwrap(); +// impl PositiveDefiniteKernel> for Linear { +// fn params_len(&self) -> usize { +// PARAMS_LEN +// } - assert_eq!(test_value, 10.0); - } -} +// fn value(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { +// if params.len() != PARAMS_LEN { +// return Err(KernelError::ParametersLengthMismatch.into()); +// } +// if x.len() != xprime.len() { +// return Err(KernelError::InvalidArgument.into()); +// } + +// let fx = x +// .par_iter() +// .zip(xprime.par_iter()) +// .map(|(x_i, xprime_i)| x_i * xprime_i) +// .sum(); + +// Ok(fx) +// } +// } + +// impl Add for Linear +// where +// R: PositiveDefiniteKernel>, +// { +// type Output = KernelAdd>; + +// fn add(self, rhs: R) -> Self::Output { +// Self::Output::new(self, rhs) +// } +// } + +// impl Mul for Linear +// where +// R: PositiveDefiniteKernel>, +// { +// type Output = KernelMul>; + +// fn mul(self, rhs: R) -> Self::Output { +// Self::Output::new(self, rhs) +// } +// } + +// impl ValueDifferentiableKernel> for Linear { +// fn ln_diff_value( +// &self, +// params: &[f64], +// x: &Vec, +// xprime: &Vec, +// ) -> Result, KernelError> { +// let value = &self.value(params, x, xprime)?; +// let diff = (2.0 / value * x.clone().col_mat()).vec(); +// Ok(diff) +// } +// } + +// impl ParamsDifferentiableKernel> for Linear { +// fn ln_diff_params( +// &self, +// _params: &[f64], +// _x: &Vec, +// _xprime: &Vec, +// ) -> Result, KernelError> { +// let diff = vec![]; +// Ok(diff) +// } +// } + +// #[cfg(test)] +// mod tests { +// use crate::*; +// #[test] +// fn it_works() { +// let kernel = Linear; + +// let test_value = kernel +// .value(&[], &vec![1.0, 2.0, 3.0], &vec![3.0, 2.0, 1.0]) +// .unwrap(); + +// assert_eq!(test_value, 10.0); +// } +// } diff --git a/src/mul.rs b/src/mul.rs index 0cf04a3..77744bf 100644 --- a/src/mul.rs +++ b/src/mul.rs @@ -1,55 +1,47 @@ -use opensrdk_linear_algebra::Vector; - -use crate::KernelError; -use crate::ParamsDifferentiableKernel; -use crate::Value; -use crate::ValueDifferentiableKernel; -use crate::{KernelAdd, PositiveDefiniteKernel}; -use std::marker::PhantomData; +use crate::{KernelAdd, KernelError, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; use std::ops::Add; use std::{fmt::Debug, ops::Mul}; #[derive(Clone, Debug)] -pub struct KernelMul +pub struct KernelMul where - L: PositiveDefiniteKernel, - R: PositiveDefiniteKernel, - T: Value, + L: PositiveDefiniteKernel, + R: PositiveDefiniteKernel, { lhs: L, rhs: R, - phantom: PhantomData, } -impl KernelMul +impl KernelMul where - L: PositiveDefiniteKernel, - R: PositiveDefiniteKernel, - T: Value, + L: PositiveDefiniteKernel, + R: PositiveDefiniteKernel, { pub fn new(lhs: L, rhs: R) -> Self { - Self { - lhs, - rhs, - phantom: PhantomData, - } + Self { lhs, rhs } } } -impl PositiveDefiniteKernel for KernelMul +impl PositiveDefiniteKernel for KernelMul where - L: PositiveDefiniteKernel, - R: PositiveDefiniteKernel, - T: Value, + L: PositiveDefiniteKernel, + R: PositiveDefiniteKernel, { fn params_len(&self) -> usize { self.lhs.params_len() + self.rhs.params_len() } - - fn value(&self, params: &[f64], x: &T, xprime: &T) -> Result { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { let lhs_params_len = self.lhs.params_len(); - let fx = self.lhs.value(¶ms[..lhs_params_len], x, xprime)?; - let gx = self.rhs.value(¶ms[lhs_params_len..], x, xprime)?; + let fx = self + .lhs + .expression(x.clone(), x_prime.clone(), ¶ms[..lhs_params_len])?; + let gx = self.rhs.expression(x, x_prime, ¶ms[lhs_params_len..])?; let hx = fx * gx; @@ -57,78 +49,76 @@ where } } -impl Add for KernelMul +impl Add for KernelMul where - Rhs: PositiveDefiniteKernel, - L: PositiveDefiniteKernel, - R: PositiveDefiniteKernel, - T: Value, + Rhs: PositiveDefiniteKernel, + L: PositiveDefiniteKernel, + R: PositiveDefiniteKernel, { - type Output = KernelAdd; + type Output = KernelAdd; fn add(self, rhs: Rhs) -> Self::Output { Self::Output::new(self, rhs) } } -impl Mul for KernelMul +impl Mul for KernelMul where - Rhs: PositiveDefiniteKernel, - L: PositiveDefiniteKernel, - R: PositiveDefiniteKernel, - T: Value, + Rhs: PositiveDefiniteKernel, + L: PositiveDefiniteKernel, + R: PositiveDefiniteKernel, { - type Output = KernelMul; + type Output = KernelMul; fn mul(self, rhs: Rhs) -> Self::Output { Self::Output::new(self, rhs) } } -impl ValueDifferentiableKernel for KernelMul -where - L: ValueDifferentiableKernel, - R: ValueDifferentiableKernel, - T: Value, -{ - fn ln_diff_value(&self, params: &[f64], x: &T, xprime: &T) -> Result, KernelError> { - let diff_rhs = &self - .rhs - .ln_diff_value(params, x, xprime) - .unwrap() - .clone() - .col_mat(); - let diff_lhs = &self - .lhs - .ln_diff_value(params, x, xprime) - .unwrap() - .clone() - .col_mat(); - let diff = (diff_rhs + diff_lhs.clone()).vec(); - Ok(diff) - } -} +// impl ValueDifferentiableKernel for KernelMul +// where +// L: ValueDifferentiableKernel, +// R: ValueDifferentiableKernel, +// T: Value, +// { +// fn ln_diff_value(&self, params: &[f64], x: &T, xprime: &T) -> Result, KernelError> { +// let diff_rhs = &self +// .rhs +// .ln_diff_value(params, x, xprime) +// .unwrap() +// .clone() +// .col_mat(); +// let diff_lhs = &self +// .lhs +// .ln_diff_value(params, x, xprime) +// .unwrap() +// .clone() +// .col_mat(); +// let diff = (diff_rhs + diff_lhs.clone()).vec(); +// Ok(diff) +// } +// } -impl ParamsDifferentiableKernel for KernelMul -where - L: ParamsDifferentiableKernel, - R: ParamsDifferentiableKernel, - T: Value, -{ - fn ln_diff_params(&self, params: &[f64], x: &T, xprime: &T) -> Result, KernelError> { - let diff_rhs = &self - .rhs - .ln_diff_params(params, x, xprime) - .unwrap() - .clone() - .col_mat(); - let diff_lhs = &self - .lhs - .ln_diff_params(params, x, xprime) - .unwrap() - .clone() - .col_mat(); - let diff = (diff_rhs + diff_lhs.clone()).vec(); - Ok(diff) - } -} +// impl ParamsDifferentiableKernel for KernelMul +// where +// L: ParamsDifferentiableKernel, +// R: ParamsDifferentiableKernel, +// T: Value, +// { +// fn ln_diff_params(&self, params: &[f64], x: &T, xprime: &T) -> Result, KernelError> { +// let diff_rhs = &self +// .rhs +// .ln_diff_params(params, x, xprime) +// .unwrap() +// .clone() +// .col_mat(); +// let diff_lhs = &self +// .lhs +// .ln_diff_params(params, x, xprime) +// .unwrap() +// .clone() +// .col_mat(); +// let diff = (diff_rhs + diff_lhs.clone()).vec(); +// Ok(diff) +// } +// } diff --git a/src/neural_network/deep_neural_network.rs b/src/neural_network/deep_neural_network.rs index 04110df..cf43466 100644 --- a/src/neural_network/deep_neural_network.rs +++ b/src/neural_network/deep_neural_network.rs @@ -1,8 +1,7 @@ +use opensrdk_symbolic_computation::Expression; + use super::ActivationFunction; -use crate::{ - Constant, KernelAdd, KernelError, KernelMul, Linear, ParamsDifferentiableKernel, - PositiveDefiniteKernel, ValueDifferentiableKernel, -}; +use crate::{KernelAdd, KernelError, KernelMul, PositiveDefiniteKernel}; use std::{ fmt::Debug, ops::{Add, Mul}, @@ -19,80 +18,73 @@ impl<'a> DeepNeuralNetwork<'a> { Self { layers } } } -impl<'a> PositiveDefiniteKernel> for DeepNeuralNetwork<'a> { +impl<'a> PositiveDefiniteKernel for DeepNeuralNetwork<'a> { fn params_len(&self) -> usize { 2 * (1 + self.layers.len()) } - fn value(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { if params.len() != self.params_len() { return Err(KernelError::ParametersLengthMismatch.into()); } - if x.len() != xprime.len() { - return Err(KernelError::InvalidArgument.into()); - } - - let layer0 = Constant + Constant * Linear; - let mut previous_layer_kernel = ( - layer0.value(¶ms[0..2], x, xprime)?, - layer0.value(¶ms[0..2], x, x)?, - layer0.value(¶ms[0..2], xprime, xprime)?, - ); - let params = ¶ms[2..]; - - for (i, &layer) in self.layers.iter().enumerate() { - let sigma_b = params[(i + 1) * 2]; - let sigma_w = params[(i + 1) * 2 + 1]; - let f = layer.f(previous_layer_kernel); - let fxx = layer.f(( - previous_layer_kernel.1, - previous_layer_kernel.1, - previous_layer_kernel.1, - )); - let fxpxp = layer.f(( - previous_layer_kernel.2, - previous_layer_kernel.2, - previous_layer_kernel.2, - )); - - previous_layer_kernel = ( - sigma_b + sigma_w * f, - sigma_b + sigma_w * fxx, - sigma_b + sigma_w * fxpxp, - ); - } - - Ok(previous_layer_kernel.0) - } -} - -impl<'a> ValueDifferentiableKernel> for DeepNeuralNetwork<'a> { - fn ln_diff_value( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { + // if x.len() != x_prime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } todo!() } -} -impl<'a> ParamsDifferentiableKernel> for DeepNeuralNetwork<'a> { - fn ln_diff_params( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { - todo!() - } + // fn value(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { + // if params.len() != self.params_len() { + // return Err(KernelError::ParametersLengthMismatch.into()); + // } + // if x.len() != xprime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } + + // let layer0 = Constant + Constant * Linear; + // let mut previous_layer_kernel = ( + // layer0.value(¶ms[0..2], x, xprime)?, + // layer0.value(¶ms[0..2], x, x)?, + // layer0.value(¶ms[0..2], xprime, xprime)?, + // ); + // let params = ¶ms[2..]; + + // for (i, &layer) in self.layers.iter().enumerate() { + // let sigma_b = params[(i + 1) * 2]; + // let sigma_w = params[(i + 1) * 2 + 1]; + // let f = layer.f(previous_layer_kernel); + // let fxx = layer.f(( + // previous_layer_kernel.1, + // previous_layer_kernel.1, + // previous_layer_kernel.1, + // )); + // let fxpxp = layer.f(( + // previous_layer_kernel.2, + // previous_layer_kernel.2, + // previous_layer_kernel.2, + // )); + + // previous_layer_kernel = ( + // sigma_b + sigma_w * f, + // sigma_b + sigma_w * fxx, + // sigma_b + sigma_w * fxpxp, + // ); + // } + + // Ok(previous_layer_kernel.0) + // } } impl<'a, R> Add for DeepNeuralNetwork<'a> where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelAdd>; + type Output = KernelAdd; fn add(self, rhs: R) -> Self::Output { Self::Output::new(self, rhs) } @@ -100,33 +92,33 @@ where impl<'a, R> Mul for DeepNeuralNetwork<'a> where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelMul>; + type Output = KernelMul; fn mul(self, rhs: R) -> Self::Output { Self::Output::new(self, rhs) } } -#[cfg(test)] -mod tests { - use crate::*; - - #[test] - fn it_works() { - let activfunc = ReLU; - let kernel = DeepNeuralNetwork::new(vec![&activfunc]); - - let test_value = kernel.value( - &[1.0, 1.0, 3.0, 4.0, 6.0], - &vec![0.0, 0.0, 0.0], - &vec![0.0, 0.0, 0.0], - ); - - match test_value { - Err(KernelError::ParametersLengthMismatch) => (), - _ => panic!(), - }; - } -} +// #[cfg(test)] +// mod tests { +// use crate::*; + +// #[test] +// fn it_works() { +// let activfunc = ReLU; +// let kernel = DeepNeuralNetwork::new(vec![&activfunc]); + +// let test_value = kernel.value( +// &[1.0, 1.0, 3.0, 4.0, 6.0], +// &vec![0.0, 0.0, 0.0], +// &vec![0.0, 0.0, 0.0], +// ); + +// match test_value { +// Err(KernelError::ParametersLengthMismatch) => (), +// _ => panic!(), +// }; +// } +// } diff --git a/src/periodic.rs b/src/periodic.rs index 78e15b5..0da9bcd 100644 --- a/src/periodic.rs +++ b/src/periodic.rs @@ -1,125 +1,189 @@ -use super::PositiveDefiniteKernel; -use crate::{ - KernelAdd, KernelError, KernelMul, ParamsDifferentiableKernel, ValueDifferentiableKernel, -}; -use opensrdk_linear_algebra::Vector; -use rayon::prelude::*; -use std::{ops::Add, ops::Mul}; +use std::ops::{Add, Mul}; + +use crate::KernelError; + +use super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; const PARAMS_LEN: usize = 2; #[derive(Clone, Debug)] pub struct Periodic; -impl Periodic { - fn norm(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { +impl PositiveDefiniteKernel for Periodic { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { if params.len() != PARAMS_LEN { return Err(KernelError::ParametersLengthMismatch.into()); } - if x.len() != xprime.len() { - return Err(KernelError::InvalidArgument.into()); - } - - let v = x - .par_iter() - .zip(xprime.par_iter()) - .map(|(x_i, xprime_i)| (x_i - xprime_i).powi(2)) - .sum::() - .sqrt(); - - Ok(v) + // if x.len() != x_prime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } + let diff = x - x_prime; + + Ok((params[0].clone() + * (diff + .clone() + .dot(diff, &[[0, 0]]) + .pow(Expression::from(1.0 / 2.0)) + / params[1].clone()) + .cos()) + .exp()) } -} -impl PositiveDefiniteKernel> for Periodic { fn params_len(&self) -> usize { - PARAMS_LEN - } - - fn value(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { - let norm = self.norm(params, x, xprime)?; - - let fx = (params[0] * (norm / params[1]).cos()).exp(); - - Ok(fx) + 2 } } impl Add for Periodic where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelAdd>; + type Output = KernelAdd; fn add(self, rhs: R) -> Self::Output { - Self::Output::new(self, rhs) + KernelAdd::new(self, rhs) } } impl Mul for Periodic where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelMul>; + type Output = KernelMul; fn mul(self, rhs: R) -> Self::Output { - Self::Output::new(self, rhs) + KernelMul::new(self, rhs) } } -impl ValueDifferentiableKernel> for Periodic { - fn ln_diff_value( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { - let value = &self.value(params, x, xprime)?; - let diff = (-value.sin() * 2.0 / params[1] - * (x.clone().col_mat() - xprime.clone().col_mat())) - .vec(); - Ok(diff) - } -} - -impl ParamsDifferentiableKernel> for Periodic { - fn ln_diff_params( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { - let value = &self.value(params, x, xprime)?; - let diff0 = 1.0 / params[0]; - let diff1 = value.sin() * 2.0 * params[1].powi(-2) * &self.norm(params, x, xprime)?; - let diff = vec![diff0, diff1]; - Ok(diff) - } -} - -#[cfg(test)] -mod tests { - use crate::*; - #[test] - fn it_works() { - let kernel = Periodic; - - let test_value = kernel.value(&[1.0], &vec![0.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0]); - - match test_value { - Err(KernelError::ParametersLengthMismatch) => (), - _ => panic!(), - }; - } - - #[test] - fn it_works2() { - let kernel = Periodic; - - let test_value = kernel - .value(&[1.0, 1.0], &vec![0.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0]) - .unwrap(); - - assert_eq!(test_value, 1f64.exp()); - } -} +// use super::PositiveDefiniteKernel; +// use crate::{ +// KernelAdd, KernelError, KernelMul, ParamsDifferentiableKernel, ValueDifferentiableKernel, +// }; +// use opensrdk_linear_algebra::Vector; +// use rayon::prelude::*; +// use std::{ops::Add, ops::Mul}; + +// const PARAMS_LEN: usize = 2; + +// #[derive(Clone, Debug)] +// pub struct Periodic; + +// impl Periodic { +// fn norm(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { +// if params.len() != PARAMS_LEN { +// return Err(KernelError::ParametersLengthMismatch.into()); +// } +// if x.len() != xprime.len() { +// return Err(KernelError::InvalidArgument.into()); +// } + +// let v = x +// .par_iter() +// .zip(xprime.par_iter()) +// .map(|(x_i, xprime_i)| (x_i - xprime_i).powi(2)) +// .sum::() +// .sqrt(); + +// Ok(v) +// } +// } + +// impl PositiveDefiniteKernel> for Periodic { +// fn params_len(&self) -> usize { +// PARAMS_LEN +// } + +// fn value(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { +// let norm = self.norm(params, x, xprime)?; + +// let fx = (params[0] * (norm / params[1]).cos()).exp(); + +// Ok(fx) +// } +// } + +// impl Add for Periodic +// where +// R: PositiveDefiniteKernel>, +// { +// type Output = KernelAdd>; + +// fn add(self, rhs: R) -> Self::Output { +// Self::Output::new(self, rhs) +// } +// } + +// impl Mul for Periodic +// where +// R: PositiveDefiniteKernel>, +// { +// type Output = KernelMul>; + +// fn mul(self, rhs: R) -> Self::Output { +// Self::Output::new(self, rhs) +// } +// } + +// impl ValueDifferentiableKernel> for Periodic { +// fn ln_diff_value( +// &self, +// params: &[f64], +// x: &Vec, +// xprime: &Vec, +// ) -> Result, KernelError> { +// let value = &self.value(params, x, xprime)?; +// let diff = (-value.sin() * 2.0 / params[1] +// * (x.clone().col_mat() - xprime.clone().col_mat())) +// .vec(); +// Ok(diff) +// } +// } + +// impl ParamsDifferentiableKernel> for Periodic { +// fn ln_diff_params( +// &self, +// params: &[f64], +// x: &Vec, +// xprime: &Vec, +// ) -> Result, KernelError> { +// let value = &self.value(params, x, xprime)?; +// let diff0 = 1.0 / params[0]; +// let diff1 = value.sin() * 2.0 * params[1].powi(-2) * &self.norm(params, x, xprime)?; +// let diff = vec![diff0, diff1]; +// Ok(diff) +// } +// } + +// #[cfg(test)] +// mod tests { +// use crate::*; +// #[test] +// fn it_works() { +// let kernel = Periodic; + +// let test_value = kernel.value(&[1.0], &vec![0.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0]); + +// match test_value { +// Err(KernelError::ParametersLengthMismatch) => (), +// _ => panic!(), +// }; +// } + +// #[test] +// fn it_works2() { +// let kernel = Periodic; + +// let test_value = kernel +// .value(&[1.0, 1.0], &vec![0.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0]) +// .unwrap(); + +// assert_eq!(test_value, 1f64.exp()); +// } +// } diff --git a/src/rbf.rs b/src/rbf.rs index b1231e8..62419d0 100644 --- a/src/rbf.rs +++ b/src/rbf.rs @@ -1,137 +1,188 @@ -use super::PositiveDefiniteKernel; -use crate::{ - KernelAdd, KernelError, KernelMul, ParamsDifferentiableKernel, ValueDifferentiableKernel, -}; -use opensrdk_linear_algebra::Vector; -use rayon::prelude::*; -use std::{ops::Add, ops::Mul}; +use std::ops::{Add, Mul}; -const PARAMS_LEN: usize = 2; +use crate::KernelError; + +use super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; + +const PARAMS_LEN: usize = 1; #[derive(Clone, Debug)] pub struct RBF; -impl RBF { - fn norm_pow( +impl PositiveDefiniteKernel for RBF { + fn expression( &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result { + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { if params.len() != PARAMS_LEN { return Err(KernelError::ParametersLengthMismatch.into()); } - if x.len() != xprime.len() { - return Err(KernelError::InvalidArgument.into()); - } + // if x.len() != x_prime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } - let norm_pow = x - .par_iter() - .zip(xprime.par_iter()) - .map(|(x_i, xprime_i)| (x_i - xprime_i).powi(2)) - .sum(); + let diff = x - x_prime; - Ok(norm_pow) + Ok((-diff.clone().dot(diff, &[[0, 0]]) / params[0].clone()).exp()) } -} -impl PositiveDefiniteKernel> for RBF { fn params_len(&self) -> usize { - PARAMS_LEN - } - - fn value(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { - let norm_pow = self.norm_pow(params, x, xprime)?; - - let fx = params[0] * (-norm_pow / params[1]).exp(); - - Ok(fx) + 1 } } impl Add for RBF where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelAdd>; + type Output = KernelAdd; fn add(self, rhs: R) -> Self::Output { - Self::Output::new(self, rhs) + KernelAdd::new(self, rhs) } } impl Mul for RBF where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelMul>; + type Output = KernelMul; fn mul(self, rhs: R) -> Self::Output { - Self::Output::new(self, rhs) + KernelMul::new(self, rhs) } } -impl ValueDifferentiableKernel> for RBF { - fn ln_diff_value( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { - let diff = (-2.0 / params[1] * (x.clone().col_mat() - xprime.clone().col_mat())).vec(); - Ok(diff) - } -} - -impl ParamsDifferentiableKernel> for RBF { - fn ln_diff_params( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { - let diff0 = 1.0 / params[0]; - let diff1 = 2.0 * params[1].powi(-2) * &self.norm_pow(params, x, xprime).unwrap(); - let diff = vec![diff0, diff1]; - Ok(diff) - } -} - -#[cfg(test)] -mod tests { - use crate::*; - #[test] - fn it_works() { - let kernel = RBF; - - //let (func, grad) = kernel - // .value_with_grad(&[1.0, 1.0], &vec![1.0, 2.0, 3.0], &vec![3.0, 2.0, 1.0]) - // .unwrap(); - - //println!("{}", func); - //println!("{:#?}", grad); - - let test_value = kernel - .value(&[1.0, 1.0], &vec![1.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0]) - .unwrap(); - - assert_eq!(test_value, (-1f64).exp()); - } - #[test] - fn it_works2() { - let kernel = RBF; - - //let (func, grad) = kernel - // .value_with_grad(&[1.0, 1.0], &vec![1.0, 2.0, 3.0], &vec![3.0, 2.0, 1.0]) - // .unwrap(); - - //println!("{}", func); - //println!("{:#?}", grad); - - let test_value = kernel - .ln_diff_value(&[1.0, 1.0], &vec![1.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0]) - .unwrap(); - - println!("{:?}", test_value); - } -} +// use super::PositiveDefiniteKernel; +// use crate::{ +// KernelAdd, KernelError, KernelMul, ParamsDifferentiableKernel, ValueDifferentiableKernel, +// }; +// use opensrdk_linear_algebra::Vector; +// use rayon::prelude::*; +// use std::{ops::Add, ops::Mul}; + +// const PARAMS_LEN: usize = 2; + +// #[derive(Clone, Debug)] +// pub struct RBF; + +// impl RBF { +// fn norm_pow( +// &self, +// params: &[f64], +// x: &Vec, +// xprime: &Vec, +// ) -> Result { +// if params.len() != PARAMS_LEN { +// return Err(KernelError::ParametersLengthMismatch.into()); +// } +// if x.len() != xprime.len() { +// return Err(KernelError::InvalidArgument.into()); +// } + +// let norm_pow = x +// .par_iter() +// .zip(xprime.par_iter()) +// .map(|(x_i, xprime_i)| (x_i - xprime_i).powi(2)) +// .sum(); + +// Ok(norm_pow) +// } +// } + +// impl PositiveDefiniteKernel> for RBF { +// fn params_len(&self) -> usize { +// PARAMS_LEN +// } + +// fn value(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { +// let norm_pow = self.norm_pow(params, x, xprime)?; + +// let fx = params[0] * (-norm_pow / params[1]).exp(); + +// Ok(fx) +// } +// } + +// impl Add for RBF +// where +// R: PositiveDefiniteKernel>, +// { +// type Output = KernelAdd>; + +// fn add(self, rhs: R) -> Self::Output { +// Self::Output::new(self, rhs) +// } +// } + +// impl Mul for RBF +// where +// R: PositiveDefiniteKernel>, +// { +// type Output = KernelMul>; + +// fn mul(self, rhs: R) -> Self::Output { +// Self::Output::new(self, rhs) +// } +// } + +// impl ValueDifferentiableKernel> for RBF { +// fn ln_diff_value( +// &self, +// params: &[f64], +// x: &Vec, +// xprime: &Vec, +// ) -> Result, KernelError> { +// let diff = (-2.0 / params[1] * (x.clone().col_mat() - xprime.clone().col_mat())).vec(); +// Ok(diff) +// } +// } + +// impl ParamsDifferentiableKernel> for RBF { +// fn ln_diff_params( +// &self, +// params: &[f64], +// x: &Vec, +// xprime: &Vec, +// ) -> Result, KernelError> { +// let diff0 = 1.0 / params[0]; +// let diff1 = 2.0 * params[1].powi(-2) * &self.norm_pow(params, x, xprime).unwrap(); +// let diff = vec![diff0, diff1]; +// Ok(diff) +// } +// } + +// #[cfg(test)] +// mod tests { +// use crate::*; +// #[test] +// fn it_works() { +// let kernel = RBF; +// let kernel_diff = kernel +// .expression(theta_array, samples_array, &kernel_params_expression) +// .unwrap() +// .ln(); + +// assert_eq!(test_value, (-1f64).exp()); +// } +// #[test] +// fn it_works2() { +// let kernel = RBF; + +// //let (func, grad) = kernel +// // .value_with_grad(&[1.0, 1.0], &vec![1.0, 2.0, 3.0], &vec![3.0, 2.0, 1.0]) +// // .unwrap(); + +// //println!("{}", func); +// //println!("{:#?}", grad); + +// let test_value = kernel +// .ln_diff_value(&[1.0, 1.0], &vec![1.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0]) +// .unwrap(); + +// println!("{:?}", test_value); +// } +// } diff --git a/src/spectral_mixture.rs b/src/spectral_mixture.rs index b304f4f..8c2c7ca 100644 --- a/src/spectral_mixture.rs +++ b/src/spectral_mixture.rs @@ -1,7 +1,6 @@ use super::PositiveDefiniteKernel; -use crate::{ - KernelAdd, KernelError, KernelMul, ParamsDifferentiableKernel, ValueDifferentiableKernel, -}; +use crate::{KernelAdd, KernelError, KernelMul}; +use opensrdk_symbolic_computation::Expression; use rayon::prelude::*; use std::{f64::consts::PI, ops::Add, ops::Mul}; @@ -18,48 +17,54 @@ impl SpectralMixture { } } -impl PositiveDefiniteKernel> for SpectralMixture { +impl PositiveDefiniteKernel for SpectralMixture { fn params_len(&self) -> usize { self.q + self.p * self.q + self.p * self.q } - fn value(&self, params: &[f64], x: &Vec, xprime: &Vec) -> Result { - if params.len() != self.params_len() { - return Err(KernelError::ParametersLengthMismatch.into()); - } - if self.p != x.len() { - return Err(KernelError::ParametersLengthMismatch.into()); - } - if x.len() != xprime.len() { - return Err(KernelError::InvalidArgument.into()); - } - - let w = ¶ms[0..self.q]; - let v = ¶ms[self.q..self.q + self.p * self.q]; - let mu = ¶ms[self.q + self.p * self.q..self.q + self.p * self.q + self.p * self.q]; - - let fx = (0..self.q) - .into_par_iter() - .map(|q| { - w[q] * (0..self.p) - .into_par_iter() - .map(|p| { - (-2.0 * PI.powi(2) * (x[p] - xprime[p]).powi(2) * v[self.p * p + q]).exp() - * (2.0 * PI * (x[p] - xprime[p]) * mu[self.p * p + q]).cos() - }) - .product::() - }) - .sum(); - - Ok(fx) + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { + todo!() + // if params.len() != self.params_len() { + // return Err(KernelError::ParametersLengthMismatch.into()); + // } + // if self.p != x.len() { + // return Err(KernelError::ParametersLengthMismatch.into()); + // } + // if x.len() != x_prime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } + + // let w = ¶ms[0..self.q]; + // let v = ¶ms[self.q..self.q + self.p * self.q]; + // let mu = ¶ms[self.q + self.p * self.q..self.q + self.p * self.q + self.p * self.q]; + + // let fx = (0..self.q) + // .into_par_iter() + // .map(|q| { + // w[q] * (0..self.p) + // .into_par_iter() + // .map(|p| { + // (-2.0 * PI.powi(2) * (x[p] - x_prime[p]).powi(2) * v[self.p * p + q]).exp() + // * (2.0 * PI * (x[p] - x_prime[p]) * mu[self.p * p + q]).cos() + // }) + // .product::() + // }) + // // .sum(); + + // Ok(fx) } } impl Add for SpectralMixture where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelAdd>; + type Output = KernelAdd; fn add(self, rhs: R) -> Self::Output { Self::Output::new(self, rhs) @@ -68,148 +73,152 @@ where impl Mul for SpectralMixture where - R: PositiveDefiniteKernel>, + R: PositiveDefiniteKernel, { - type Output = KernelMul>; + type Output = KernelMul; fn mul(self, rhs: R) -> Self::Output { Self::Output::new(self, rhs) } } -impl ValueDifferentiableKernel> for SpectralMixture { - fn ln_diff_value( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { - let value = self.value(params, x, xprime).unwrap(); - let w = ¶ms[0..self.q]; - let v = ¶ms[self.q..self.q + self.p * self.q]; - let mu = ¶ms[self.q + self.p * self.q..self.q + self.p * self.q + self.p * self.q]; - - let diff = (0..self.p) - .into_par_iter() - .map(|p| { - (0..self.q) - .into_par_iter() - .map(|q| { - let each_wd = w[q] - * (0..self.p) - .into_par_iter() - .map(|i| { - (-2.0 - * PI.powi(2) - * (x[i] - xprime[i]).powi(2) - * v[self.p * i + q]) - .exp() - * (2.0 * PI * (x[i] - xprime[i]) * mu[self.p * i + q]).cos() - }) - .product::(); - let diff_d = (4.0 * PI.powi(2) * (x[p] - xprime[p]) * v[self.p * p + q]) - + (2.0 * PI * (x[p] - xprime[p]) * mu[self.p * p + q]).tan() - * ((-2.0) * PI * (x[p] - xprime[p]) * mu[self.p * p + q]); - diff_d * each_wd / value - }) - .sum() - }) - .collect::>(); - - Ok(diff) - } -} - -impl ParamsDifferentiableKernel> for SpectralMixture { - fn ln_diff_params( - &self, - params: &[f64], - x: &Vec, - xprime: &Vec, - ) -> Result, KernelError> { - let value = self.value(params, x, xprime).unwrap(); - let w = ¶ms[0..self.q]; - let v = ¶ms[self.q..self.q + self.p * self.q]; - let mu = ¶ms[self.q + self.p * self.q..self.q + self.p * self.q + self.p * self.q]; - - let diff_w = (0..self.q) - .into_par_iter() - .map(|q| { - (0..self.p) - .into_par_iter() - .map(|i| { - (-2.0 * PI.powi(2) * (x[i] - xprime[i]).powi(2) * v[self.p * i + q]).exp() - * (2.0 * PI * (x[i] - xprime[i]) * mu[self.p * i + q]).cos() - }) - .product::() - }) - .collect::>(); - - let diff_mu = (0..self.q) - .into_par_iter() - .map(|q| { - let each_wd = w[q] - * (0..self.p) - .into_par_iter() - .map(|i| { - (-2.0 * PI.powi(2) * (x[i] - xprime[i]).powi(2) * v[self.p * i + q]) - .exp() - * (2.0 * PI * (x[i] - xprime[i]) * mu[self.p * i + q]).cos() - }) - .product::(); - (0..self.p) - .into_par_iter() - .map(|p| { - let diff_d = (2.0 * PI * (x[p] - xprime[p]) * mu[self.p * p + q]).tan() - * ((-2.0) * PI * (x[p] - xprime[p])); - diff_d * each_wd / value - }) - .collect::>() - }) - .collect::>>() - .concat(); - - let diff_v = (0..self.q) - .into_par_iter() - .map(|q| { - let each_wd = w[q] - * (0..self.p) - .into_par_iter() - .map(|i| { - (-2.0 * PI.powi(2) * (x[i] - xprime[i]).powi(2) * v[self.p * i + q]) - .exp() - * (2.0 * PI * (x[i] - xprime[i]) * mu[self.p * i + q]).cos() - }) - .product::(); - (0..self.p) - .into_par_iter() - .map(|p| { - let diff_d = 4.0 * PI.powi(2) * (x[p] - xprime[p]).powi(2); - diff_d * each_wd / value - }) - .collect::>() - }) - .collect::>>() - .concat(); - - let diff = [diff_w, diff_v, diff_mu].concat(); - - Ok(diff) - } -} - -#[cfg(test)] -mod tests { - use crate::*; - #[test] - fn it_works() { - let kernel = SpectralMixture::new(1, 2); - - let test_value = kernel.value(&[1.0, 1.0], &vec![0.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0]); - - match test_value { - Err(KernelError::ParametersLengthMismatch) => (), - _ => panic!(), - }; - } -} +// impl ValueDifferentiableKernel> for SpectralMixture { +// fn ln_diff_value( +// &self, +// params: &[f64], +// x: &Vec, +// xprime: &Vec, +// ) -> Result, KernelError> { +// let value = self.value(params, x, xprime).unwrap(); +// let w = ¶ms[0..self.q]; +// let v = ¶ms[self.q..self.q + self.p * self.q]; +// let mu = ¶ms[self.q + self.p * self.q..self.q + self.p * self.q + self.p * self.q]; + +// let diff = (0..self.p) +// .into_par_iter() +// .map(|p| { +// (0..self.q) +// .into_par_iter() +// .map(|q| { +// let each_wd = w[q] +// * (0..self.p) +// .into_par_iter() +// .map(|i| { +// (-2.0 +// * PI.powi(2) +// * (x[i] - xprime[i]).powi(2) +// * v[self.p * i + q]) +// .exp() +// * (2.0 * PI * (x[i] - xprime[i]) * mu[self.p * i + q]).cos() +// }) +// .product::(); +// let diff_d = (4.0 * PI.powi(2) * (x[p] - xprime[p]) * v[self.p * p + q]) +// + (2.0 * PI * (x[p] - xprime[p]) * mu[self.p * p + q]).tan() +// * ((-2.0) * PI * (x[p] - xprime[p]) * mu[self.p * p + q]); +// diff_d * each_wd / value +// }) +// .sum() +// }) +// .collect::>(); + +// Ok(diff) +// } +// } + +// impl ParamsDifferentiableKernel> for SpectralMixture { +// fn ln_diff_params( +// &self, +// params: &[f64], +// x: &Vec, +// xprime: &Vec, +// ) -> Result, KernelError> { +// let value = self.value(params, x, xprime).unwrap(); +// let w = ¶ms[0..self.q]; +// let v = ¶ms[self.q..self.q + self.p * self.q]; +// let mu = ¶ms[self.q + self.p * self.q..self.q + self.p * self.q + self.p * self.q]; + +// let diff_w = (0..self.q) +// .into_par_iter() +// .map(|q| { +// (0..self.p) +// .into_par_iter() +// .map(|i| { +// (-2.0 * PI.powi(2) * (x[i] - xprime[i]).powi(2) * v[self.p * i + q]).exp() +// * (2.0 * PI * (x[i] - xprime[i]) * mu[self.p * i + q]).cos() +// }) +// .product::() +// }) +// .collect::>(); + +// let diff_mu = (0..self.q) +// .into_par_iter() +// .map(|q| { +// let each_wd = w[q] +// * (0..self.p) +// .into_par_iter() +// .map(|i| { +// (-2.0 * PI.powi(2) * (x[i] - xprime[i]).powi(2) * v[self.p * i + q]) +// .exp() +// * (2.0 * PI * (x[i] - xprime[i]) * mu[self.p * i + q]).cos() +// }) +// .product::(); +// (0..self.p) +// .into_par_iter() +// .map(|p| { +// let diff_d = (2.0 * PI * (x[p] - xprime[p]) * mu[self.p * p + q]).tan() +// * ((-2.0) * PI * (x[p] - xprime[p])); +// diff_d * each_wd / value +// }) +// .collect::>() +// }) +// .collect::>>() +// .concat(); + +// let diff_v = (0..self.q) +// .into_par_iter() +// .map(|q| { +// let each_wd = w[q] +// * (0..self.p) +// .into_par_iter() +// .map(|i| { +// (-2.0 * PI.powi(2) * (x[i] - xprime[i]).powi(2) * v[self.p * i + q]) +// .exp() +// * (2.0 * PI * (x[i] - xprime[i]) * mu[self.p * i + q]).cos() +// }) +// .product::(); +// (0..self.p) +// .into_par_iter() +// .map(|p| { +// let diff_d = 4.0 * PI.powi(2) * (x[p] - xprime[p]).powi(2); +// diff_d * each_wd / value +// }) +// .collect::>() +// }) +// .collect::>>() +// .concat(); + +// let diff = [diff_w, diff_v, diff_mu].concat(); + +// Ok(diff) +// } +// // } + +// #[cfg(test)] +// mod tests { +// use crate::*; +// #[test] +// fn it_works() { +// let kernel = SpectralMixture::new(1, 2); + +// let test_value = kernel.expression( +// Expression::from(vec![0.0, 0.0, 0.0]), +// Expression::from(vec![0.0, 0.0, 0.0]), +// &[Expression::from([1.0]), Expression::from([1.0])], +// ); + +// match test_value { +// Err(KernelError::ParametersLengthMismatch) => (), +// _ => panic!(), +// }; +// } +// } diff --git a/src/traits/mod.rs b/src/traits/mod.rs deleted file mode 100644 index bce3d3e..0000000 --- a/src/traits/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod params_differentiable; -pub mod value_differentiable; - -pub use params_differentiable::*; -pub use params_differentiable::*; diff --git a/src/traits/params_differentiable.rs b/src/traits/params_differentiable.rs deleted file mode 100644 index e7aa13e..0000000 --- a/src/traits/params_differentiable.rs +++ /dev/null @@ -1,8 +0,0 @@ -use crate::{KernelError, PositiveDefiniteKernel, Value}; - -pub trait ParamsDifferentiableKernel: PositiveDefiniteKernel -where - T: Value, -{ - fn ln_diff_params(&self, params: &[f64], x: &T, xprime: &T) -> Result, KernelError>; -} diff --git a/src/traits/value_differentiable.rs b/src/traits/value_differentiable.rs deleted file mode 100644 index 75fd396..0000000 --- a/src/traits/value_differentiable.rs +++ /dev/null @@ -1,8 +0,0 @@ -use crate::{KernelError, PositiveDefiniteKernel, Value}; - -pub trait ValueDifferentiableKernel: PositiveDefiniteKernel -where - T: Value, -{ - fn ln_diff_value(&self, params: &[f64], x: &T, xprime: &T) -> Result, KernelError>; -}