From ab6fd51db3550fab3a15fe264f54cbe273f88d45 Mon Sep 17 00:00:00 2001 From: Rubens <91782701+tibetsou@users.noreply.github.com> Date: Wed, 15 Mar 2023 18:04:41 +0900 Subject: [PATCH 1/6] feat: symcbolize lib, add, mul --- .vscode/settings.json | 5 +- Cargo.toml | 1 + src/add.rs | 171 +++++++++++++-------------- src/lib.rs | 8 +- src/mul.rs | 157 +++++++++++-------------- src/rbf.rs | 262 ++++++++++++++++++++++++------------------ 6 files changed, 308 insertions(+), 296 deletions(-) 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..6cd7924 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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.1.3" 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..74d2bbf 100644 --- a/src/add.rs +++ b/src/add.rs @@ -1,54 +1,41 @@ -use crate::KernelError; -use crate::ParamsDifferentiableKernel; -use crate::Value; -use crate::ValueDifferentiableKernel; use crate::{KernelMul, PositiveDefiniteKernel}; -use opensrdk_linear_algebra::Vector; +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]) -> Expression { 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(¶ms[..lhs_params_len], x, x_prime)?; + let gx = self.rhs.expression(¶ms[lhs_params_len..], x, x_prime)?; let hx = fx + gx; @@ -56,86 +43,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/lib.rs b/src/lib.rs index 59b1ead..e6b63bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,7 @@ 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::*; @@ -38,13 +39,10 @@ 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]) -> Expression; } #[derive(thiserror::Error, Debug)] diff --git a/src/mul.rs b/src/mul.rs index 0cf04a3..1138506 100644 --- a/src/mul.rs +++ b/src/mul.rs @@ -1,55 +1,40 @@ -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 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]) -> Expression { 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(¶ms[..lhs_params_len], x, x_prime)?; + let gx = self.rhs.expression(¶ms[lhs_params_len..], x, x_prime)?; let hx = fx * gx; @@ -57,78 +42,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/rbf.rs b/src/rbf.rs index b1231e8..43f32b1 100644 --- a/src/rbf.rs +++ b/src/rbf.rs @@ -1,137 +1,179 @@ -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 super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; #[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 expression(&self, x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { + let diff = x - x_prime; -impl PositiveDefiniteKernel> for RBF { - fn params_len(&self) -> usize { - PARAMS_LEN + (-diff.clone().dot(diff, &[[0, 0]]) / (2.0 * params[0].clone().pow(2.0.into()))).exp() } - 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) + fn params_len(&self) -> usize { + 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) - } -} - -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) + KernelMul::new(self, rhs) } } -#[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 (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); +// } +// } From 8287e1c679b9ad396828d2c9cf8f0af40f689878 Mon Sep 17 00:00:00 2001 From: Rubens <91782701+tibetsou@users.noreply.github.com> Date: Thu, 16 Mar 2023 17:04:07 +0900 Subject: [PATCH 2/6] feat: symcbolize periodic, linear, constant, instant --- src/constant.rs | 160 ++++++++++++++++++++------------ src/instant.rs | 191 ++++++++++++++++++++++++-------------- src/linear.rs | 174 +++++++++++++++++++++-------------- src/periodic.rs | 238 ++++++++++++++++++++++++++++-------------------- src/rbf.rs | 2 +- 5 files changed, 470 insertions(+), 295 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index e14e123..ea9c106 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -1,90 +1,130 @@ -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}; -const PARAMS_LEN: usize = 1; +use super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; #[derive(Clone, Debug)] pub struct Constant; -impl PositiveDefiniteKernel for Constant -where - T: Value, -{ - fn params_len(&self) -> usize { - PARAMS_LEN +impl PositiveDefiniteKernel for Constant { + fn expression(&self, x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { + params[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) + 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/instant.rs b/src/instant.rs index c971013..46dbc62 100644 --- a/src/instant.rs +++ b/src/instant.rs @@ -1,103 +1,156 @@ -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}; - -#[derive(Clone)] +use std::ops::{Add, Mul}; + +use super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; + +#[derive(Clone, Debug)] pub struct InstantKernel where T: Value, - F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, + F: Fn(&[f64], &T, &T) -> 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, - } - } -} - -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) +impl PositiveDefiniteKernel for InstantKernel { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { + (self.value_function)(params, x, x_prime) } -} -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 +impl Add for InstantKernel where - T: Value, - R: PositiveDefiniteKernel, - F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, + 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 InstantKernel +impl Mul for InstantKernel where - T: Value, - R: PositiveDefiniteKernel, - F: Fn(&[f64], &T, &T) -> 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/linear.rs b/src/linear.rs index 24ef343..81a79da 100644 --- a/src/linear.rs +++ b/src/linear.rs @@ -1,97 +1,137 @@ -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 super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; #[derive(Clone, Debug)] pub struct Linear; -impl PositiveDefiniteKernel> for Linear { - fn params_len(&self) -> usize { - PARAMS_LEN +impl PositiveDefiniteKernel for Linear { + fn expression(&self, x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { + x.clone().dot(x_prime, &[[0, 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) + 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/periodic.rs b/src/periodic.rs index 78e15b5..64028a1 100644 --- a/src/periodic.rs +++ b/src/periodic.rs @@ -1,125 +1,167 @@ -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 super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; +use opensrdk_symbolic_computation::Expression; #[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 expression(&self, x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { + let diff = x - x_prime; -impl PositiveDefiniteKernel> for Periodic { - fn params_len(&self) -> usize { - PARAMS_LEN + (params[0] * (diff.clone().dot(diff, &[[0, 0]]).sqrt() / params[1]).cos()).exp() } - 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) + fn params_len(&self) -> usize { + 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) - } -} - -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) + KernelMul::new(self, rhs) } } -#[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 43f32b1..0e52bb4 100644 --- a/src/rbf.rs +++ b/src/rbf.rs @@ -10,7 +10,7 @@ impl PositiveDefiniteKernel for RBF { fn expression(&self, x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { let diff = x - x_prime; - (-diff.clone().dot(diff, &[[0, 0]]) / (2.0 * params[0].clone().pow(2.0.into()))).exp() + (-diff.clone().dot(diff, &[[0, 0]]) / params[0]).exp() } fn params_len(&self) -> usize { From ff989e32024dcf218156d2a129680a602ef0b369 Mon Sep 17 00:00:00 2001 From: Rubens <91782701+tibetsou@users.noreply.github.com> Date: Mon, 20 Mar 2023 23:07:11 +0900 Subject: [PATCH 3/6] feat: symcbolize instant, exponential, and so on --- src/add.rs | 9 +- src/ard/mod.rs | 121 ++++++------ src/constant.rs | 19 +- src/convolutional.rs | 63 ++++--- src/exponential.rs | 204 +++++++++++++-------- src/instant.rs | 23 ++- src/lib.rs | 12 +- src/linear.rs | 18 +- src/mul.rs | 9 +- src/periodic.rs | 19 +- src/rbf.rs | 20 +- src/spectral_mixture.rs | 274 ++++++++++++++-------------- src/traits/mod.rs | 5 - src/traits/params_differentiable.rs | 8 - src/traits/value_differentiable.rs | 8 - 15 files changed, 469 insertions(+), 343 deletions(-) delete mode 100644 src/traits/mod.rs delete mode 100644 src/traits/params_differentiable.rs delete mode 100644 src/traits/value_differentiable.rs diff --git a/src/add.rs b/src/add.rs index 74d2bbf..0c03cf9 100644 --- a/src/add.rs +++ b/src/add.rs @@ -1,4 +1,4 @@ -use crate::{KernelMul, PositiveDefiniteKernel}; +use crate::{KernelError, KernelMul, PositiveDefiniteKernel}; use opensrdk_symbolic_computation::Expression; use std::fmt::Debug; use std::{ops::Add, ops::Mul}; @@ -32,7 +32,12 @@ where self.lhs.params_len() + self.rhs.params_len() } - fn expression(&self, x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { let lhs_params_len = self.lhs.params_len(); let fx = self.lhs.expression(¶ms[..lhs_params_len], x, x_prime)?; let gx = self.rhs.expression(¶ms[lhs_params_len..], x, x_prime)?; diff --git a/src/ard/mod.rs b/src/ard/mod.rs index 415ae36..32a51cc 100644 --- a/src/ard/mod.rs +++ b/src/ard/mod.rs @@ -1,36 +1,41 @@ 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 { +fn weighted_norm_pow(x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { params .par_iter() .zip(x.par_iter()) - .zip(xprime.par_iter()) - .map(|((relevance, xi), xprimei)| relevance * (xi - xprimei).powi(2)) + .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 { + if x.len() != self.0 || x_prime.len() != self.0 { return Err(KernelError::InvalidArgument.into()); } - let fx = (-weighted_norm_pow(¶ms, x, xprime)).exp(); + let fx = (-weighted_norm_pow(¶ms, x, x_prime)).exp(); Ok(fx) } @@ -38,9 +43,9 @@ impl PositiveDefiniteKernel> for ARD { 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 +54,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 ea9c106..bf66b24 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -1,14 +1,29 @@ 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 { - fn expression(&self, x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { - params[0] + 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]) } fn params_len(&self) -> usize { diff --git a/src/convolutional.rs b/src/convolutional.rs index 9a51bed..b2dd84e 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,49 @@ 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::>()?; + .map(|pi| self.kernel.expression(x.part(pi), x_prime.part(pi), params)) + .sum::>()?; 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..b2b3f1f 100644 --- a/src/exponential.rs +++ b/src/exponential.rs @@ -1,108 +1,166 @@ -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() { + if x.len() != x_prime.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(); + let diff = x - x_prime; - Ok(v) + Ok((-diff.clone().dot(diff, &[[0, 0]]).sqrt() / params[0]).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 46dbc62..7ba5371 100644 --- a/src/instant.rs +++ b/src/instant.rs @@ -1,20 +1,27 @@ -use std::ops::{Add, Mul}; +use std::{ + marker::PhantomData, + ops::{Add, Mul}, +}; + +use crate::KernelError; use super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; use opensrdk_symbolic_computation::Expression; #[derive(Clone, Debug)] -pub struct InstantKernel +pub struct InstantKernel where - T: Value, - F: Fn(&[f64], &T, &T) -> Result + Clone + Send + Sync, + F: Fn(&[f64], &Expression, &Expression) -> Result + + Clone + + Send + + Sync, { params_len: usize, value_function: F, - phantom: PhantomData, + phantom: PhantomData, } -impl PositiveDefiniteKernel for InstantKernel { +impl PositiveDefiniteKernel for InstantKernel { fn expression( &self, x: Expression, @@ -29,7 +36,7 @@ impl PositiveDefiniteKernel for InstantKernel { } } -impl Add for InstantKernel +impl Add for InstantKernel where R: PositiveDefiniteKernel, { @@ -40,7 +47,7 @@ where } } -impl Mul for InstantKernel +impl Mul for InstantKernel where R: PositiveDefiniteKernel, { diff --git a/src/lib.rs b/src/lib.rs index e6b63bd..7f7b04b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,10 +15,6 @@ 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; @@ -34,7 +30,6 @@ 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 {} @@ -42,7 +37,12 @@ impl Value for T where T: Clone + Debug + Send + Sync {} pub trait PositiveDefiniteKernel: Clone + Debug + Send + Sync { fn params_len(&self) -> usize; - fn expression(&self, x: Expression, x_prime: Expression, params: &[Expression]) -> Expression; + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result; } #[derive(thiserror::Error, Debug)] diff --git a/src/linear.rs b/src/linear.rs index 81a79da..c0faaa5 100644 --- a/src/linear.rs +++ b/src/linear.rs @@ -1,14 +1,28 @@ use std::ops::{Add, Mul}; +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 expression(&self, x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { - x.clone().dot(x_prime, &[[0, 0]]) + 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(x.clone().dot(x_prime, &[[0, 0]])) } fn params_len(&self) -> usize { diff --git a/src/mul.rs b/src/mul.rs index 1138506..bce1313 100644 --- a/src/mul.rs +++ b/src/mul.rs @@ -1,4 +1,4 @@ -use crate::{KernelAdd, PositiveDefiniteKernel}; +use crate::{KernelAdd, KernelError, PositiveDefiniteKernel}; use opensrdk_symbolic_computation::Expression; use std::ops::Add; use std::{fmt::Debug, ops::Mul}; @@ -31,7 +31,12 @@ where fn params_len(&self) -> usize { self.lhs.params_len() + self.rhs.params_len() } - fn expression(&self, x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> Result { let lhs_params_len = self.lhs.params_len(); let fx = self.lhs.expression(¶ms[..lhs_params_len], x, x_prime)?; let gx = self.rhs.expression(¶ms[lhs_params_len..], x, x_prime)?; diff --git a/src/periodic.rs b/src/periodic.rs index 64028a1..a828665 100644 --- a/src/periodic.rs +++ b/src/periodic.rs @@ -1,16 +1,31 @@ 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 PositiveDefiniteKernel for Periodic { - fn expression(&self, x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { + 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()); + } let diff = x - x_prime; - (params[0] * (diff.clone().dot(diff, &[[0, 0]]).sqrt() / params[1]).cos()).exp() + Ok((params[0] * (diff.clone().dot(diff, &[[0, 0]]).sqrt() / params[1]).cos()).exp()) } fn params_len(&self) -> usize { diff --git a/src/rbf.rs b/src/rbf.rs index 0e52bb4..5967bb2 100644 --- a/src/rbf.rs +++ b/src/rbf.rs @@ -1,16 +1,32 @@ 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 RBF; impl PositiveDefiniteKernel for RBF { - fn expression(&self, x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { + 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()); + } + let diff = x - x_prime; - (-diff.clone().dot(diff, &[[0, 0]]) / params[0]).exp() + Ok((-diff.clone().dot(diff, &[[0, 0]]) / params[0]).exp()) } fn params_len(&self) -> usize { diff --git a/src/spectral_mixture.rs b/src/spectral_mixture.rs index b304f4f..c955c79 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,19 +17,24 @@ 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 { + fn expression( + &self, + x: Expression, + x_prime: Expression, + params: &[Expression], + ) -> 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() { + if x.len() != x_prime.len() { return Err(KernelError::InvalidArgument.into()); } @@ -44,8 +48,8 @@ impl PositiveDefiniteKernel> for SpectralMixture { 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() + (-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::() }) @@ -57,9 +61,9 @@ impl PositiveDefiniteKernel> for SpectralMixture { 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,135 +72,135 @@ 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) - } -} +// 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 { @@ -205,7 +209,11 @@ mod tests { 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]); + 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) => (), 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>; -} From d098e77d7216b57c5d89e8a44476222561713f69 Mon Sep 17 00:00:00 2001 From: Rubens <91782701+tibetsou@users.noreply.github.com> Date: Tue, 21 Mar 2023 23:06:06 +0900 Subject: [PATCH 4/6] feat: resolute some errors --- src/add.rs | 4 +- src/ard/mod.rs | 6 +- src/constant.rs | 6 +- src/convolutional.rs | 9 +- src/exponential.rs | 13 +- src/instant.rs | 38 ++++- src/lib.rs | 32 ++--- src/linear.rs | 6 +- src/mul.rs | 4 +- src/neural_network/deep_neural_network.rs | 164 ++++++++++------------ src/periodic.rs | 8 +- src/rbf.rs | 6 +- 12 files changed, 162 insertions(+), 134 deletions(-) diff --git a/src/add.rs b/src/add.rs index 0c03cf9..d7bcbfa 100644 --- a/src/add.rs +++ b/src/add.rs @@ -39,8 +39,8 @@ where params: &[Expression], ) -> Result { let lhs_params_len = self.lhs.params_len(); - let fx = self.lhs.expression(¶ms[..lhs_params_len], x, x_prime)?; - let gx = self.rhs.expression(¶ms[lhs_params_len..], x, x_prime)?; + let fx = self.lhs.expression(x, x_prime, ¶ms[..lhs_params_len])?; + let gx = self.rhs.expression(x, x_prime, ¶ms[lhs_params_len..])?; let hx = fx + gx; diff --git a/src/ard/mod.rs b/src/ard/mod.rs index 32a51cc..509d145 100644 --- a/src/ard/mod.rs +++ b/src/ard/mod.rs @@ -31,9 +31,9 @@ impl PositiveDefiniteKernel for ARD { if params.len() != self.0 { return Err(KernelError::ParametersLengthMismatch.into()); } - if x.len() != self.0 || x_prime.len() != self.0 { - return Err(KernelError::InvalidArgument.into()); - } + // if x.len() != self.0 || x_prime.len() != self.0 { + // return Err(KernelError::InvalidArgument.into()); + // } let fx = (-weighted_norm_pow(¶ms, x, x_prime)).exp(); diff --git a/src/constant.rs b/src/constant.rs index bf66b24..587fbfd 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -20,9 +20,9 @@ impl PositiveDefiniteKernel for Constant { if params.len() != PARAMS_LEN { return Err(KernelError::ParametersLengthMismatch.into()); } - if x.len() != x_prime.len() { - return Err(KernelError::InvalidArgument.into()); - } + // if x.len() != x_prime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } Ok(params[0]) } diff --git a/src/convolutional.rs b/src/convolutional.rs index b2dd84e..b701523 100644 --- a/src/convolutional.rs +++ b/src/convolutional.rs @@ -49,8 +49,8 @@ where fn expression( &self, - x: &Expression, - x_prime: &Expression, + x: Expression, + x_prime: Expression, params: &[Expression], ) -> Result { if params.len() != self.kernel.params_len() { @@ -63,7 +63,10 @@ where let fx = (0..p) .into_par_iter() - .map(|pi| self.kernel.expression(x.part(pi), x_prime.part(pi), params)) + .map(|pi| { + self.kernel + .expression(x.part(pi).clone(), x_prime.part(pi).clone(), params) + }) .sum::>()?; Ok(fx) diff --git a/src/exponential.rs b/src/exponential.rs index b2b3f1f..91d4c07 100644 --- a/src/exponential.rs +++ b/src/exponential.rs @@ -20,13 +20,18 @@ impl PositiveDefiniteKernel for Exponential { if params.len() != PARAMS_LEN { return Err(KernelError::ParametersLengthMismatch.into()); } - if x.len() != x_prime.len() { - return Err(KernelError::InvalidArgument.into()); - } + // if x.len() != x_prime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } let diff = x - x_prime; - Ok((-diff.clone().dot(diff, &[[0, 0]]).sqrt() / params[0]).exp()) + Ok((-diff + .clone() + .dot(diff, &[[0, 0]]) + .pow(Expression::from(1.0 / 2.0)) + / params[0]) + .exp()) } fn params_len(&self) -> usize { diff --git a/src/instant.rs b/src/instant.rs index 7ba5371..a5b5f40 100644 --- a/src/instant.rs +++ b/src/instant.rs @@ -5,30 +5,50 @@ use std::{ use crate::KernelError; +use std::fmt::Debug; + use super::{KernelAdd, KernelMul, PositiveDefiniteKernel}; use opensrdk_symbolic_computation::Expression; -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct InstantKernel where - F: Fn(&[f64], &Expression, &Expression) -> Result + F: Fn(&Expression, &Expression, &[Expression]) -> Result + Clone + Send + Sync, { params_len: usize, - value_function: F, + function: F, phantom: PhantomData, } -impl PositiveDefiniteKernel for InstantKernel { +impl Debug for InstantKernel +where + 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 +where + F: Fn(&Expression, &Expression, &[Expression]) -> Result + + Clone + + Send + + Sync, +{ fn expression( &self, x: Expression, x_prime: Expression, params: &[Expression], ) -> Result { - (self.value_function)(params, x, x_prime) + (self.function)(&x, &x_prime, params) } fn params_len(&self) -> usize { @@ -39,6 +59,10 @@ impl PositiveDefiniteKernel for InstantKernel { impl Add for InstantKernel where R: PositiveDefiniteKernel, + F: Fn(&Expression, &Expression, &[Expression]) -> Result + + Clone + + Send + + Sync, { type Output = KernelAdd; @@ -49,6 +73,10 @@ where impl Mul for InstantKernel where + F: Fn(&Expression, &Expression, &[Expression]) -> Result + + Clone + + Send + + Sync, R: PositiveDefiniteKernel, { type Output = KernelMul; diff --git a/src/lib.rs b/src/lib.rs index 7f7b04b..e470639 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,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 c0faaa5..744ccbd 100644 --- a/src/linear.rs +++ b/src/linear.rs @@ -19,9 +19,9 @@ impl PositiveDefiniteKernel for Linear { if params.len() != PARAMS_LEN { return Err(KernelError::ParametersLengthMismatch.into()); } - if x.len() != x_prime.len() { - return Err(KernelError::InvalidArgument.into()); - } + // if x.len() != x_prime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } Ok(x.clone().dot(x_prime, &[[0, 0]])) } diff --git a/src/mul.rs b/src/mul.rs index bce1313..0db39de 100644 --- a/src/mul.rs +++ b/src/mul.rs @@ -38,8 +38,8 @@ where params: &[Expression], ) -> Result { let lhs_params_len = self.lhs.params_len(); - let fx = self.lhs.expression(¶ms[..lhs_params_len], x, x_prime)?; - let gx = self.rhs.expression(¶ms[lhs_params_len..], x, x_prime)?; + let fx = self.lhs.expression(x, x_prime, ¶ms[..lhs_params_len])?; + let gx = self.rhs.expression(x, x_prime, ¶ms[lhs_params_len..])?; let hx = fx * gx; 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 a828665..7dcb577 100644 --- a/src/periodic.rs +++ b/src/periodic.rs @@ -20,12 +20,12 @@ impl PositiveDefiniteKernel for Periodic { if params.len() != PARAMS_LEN { return Err(KernelError::ParametersLengthMismatch.into()); } - if x.len() != x_prime.len() { - return Err(KernelError::InvalidArgument.into()); - } + // if x.len() != x_prime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } let diff = x - x_prime; - Ok((params[0] * (diff.clone().dot(diff, &[[0, 0]]).sqrt() / params[1]).cos()).exp()) + Ok((params[0] * (diff.clone().dot(diff, &[[0, 0]]).pow(Expression::from(1.0 / 2.0)) / params[1]).cos()).exp()) } fn params_len(&self) -> usize { diff --git a/src/rbf.rs b/src/rbf.rs index 5967bb2..016338f 100644 --- a/src/rbf.rs +++ b/src/rbf.rs @@ -20,9 +20,9 @@ impl PositiveDefiniteKernel for RBF { if params.len() != PARAMS_LEN { return Err(KernelError::ParametersLengthMismatch.into()); } - if x.len() != x_prime.len() { - return Err(KernelError::InvalidArgument.into()); - } + // if x.len() != x_prime.len() { + // return Err(KernelError::InvalidArgument.into()); + // } let diff = x - x_prime; From 60668c475cb10c76d7c0f7c87c3165ecc91a16cc Mon Sep 17 00:00:00 2001 From: Rubens <91782701+tibetsou@users.noreply.github.com> Date: Thu, 23 Mar 2023 20:44:31 +0900 Subject: [PATCH 5/6] feat: change to todo!() in ard, convolutional, spectral_mixture --- Cargo.toml | 2 +- src/add.rs | 4 +- src/ard/mod.rs | 18 ++++---- src/constant.rs | 2 +- src/convolutional.rs | 21 +++++---- src/exponential.rs | 4 +- src/mul.rs | 4 +- src/periodic.rs | 9 +++- src/rbf.rs | 2 +- src/spectral_mixture.rs | 97 +++++++++++++++++++++-------------------- 10 files changed, 91 insertions(+), 72 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6cd7924..6cd6cdb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "opensrdk-kernel-method" -version = "0.2.3" +version = "0.2.4" authors = ["Kimura Yu <33382781+KimuraYu45z@users.noreply.github.com>"] edition = "2018" description = "Standard Kernel Method library for OpenSRDK toolchain." diff --git a/src/add.rs b/src/add.rs index d7bcbfa..d351470 100644 --- a/src/add.rs +++ b/src/add.rs @@ -39,7 +39,9 @@ where params: &[Expression], ) -> Result { let lhs_params_len = self.lhs.params_len(); - let fx = self.lhs.expression(x, x_prime, ¶ms[..lhs_params_len])?; + 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; diff --git a/src/ard/mod.rs b/src/ard/mod.rs index 509d145..80fd13e 100644 --- a/src/ard/mod.rs +++ b/src/ard/mod.rs @@ -5,12 +5,13 @@ use rayon::prelude::*; use std::{ops::Add, ops::Mul}; fn weighted_norm_pow(x: Expression, x_prime: Expression, params: &[Expression]) -> Expression { - params - .par_iter() - .zip(x.par_iter()) - .zip(x_prime.par_iter()) - .map(|((relevance, xi), x_primei)| relevance * (xi - x_primei).powi(2)) - .sum() + 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! @@ -34,10 +35,11 @@ impl PositiveDefiniteKernel for ARD { // if x.len() != self.0 || x_prime.len() != self.0 { // return Err(KernelError::InvalidArgument.into()); // } + todo!() - let fx = (-weighted_norm_pow(¶ms, x, x_prime)).exp(); + // let fx = (-weighted_norm_pow(¶ms, x, x_prime)).exp(); - Ok(fx) + // Ok(fx) } } diff --git a/src/constant.rs b/src/constant.rs index 587fbfd..ee5f005 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -23,7 +23,7 @@ impl PositiveDefiniteKernel for Constant { // if x.len() != x_prime.len() { // return Err(KernelError::InvalidArgument.into()); // } - Ok(params[0]) + Ok(params[0].clone()) } fn params_len(&self) -> usize { diff --git a/src/convolutional.rs b/src/convolutional.rs index b701523..1ade6b6 100644 --- a/src/convolutional.rs +++ b/src/convolutional.rs @@ -61,15 +61,20 @@ where return Err(KernelError::InvalidArgument.into()); } - let fx = (0..p) - .into_par_iter() - .map(|pi| { - self.kernel - .expression(x.part(pi).clone(), x_prime.part(pi).clone(), params) - }) - .sum::>()?; + todo!() - Ok(fx) + // 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) } } diff --git a/src/exponential.rs b/src/exponential.rs index 91d4c07..5b976d1 100644 --- a/src/exponential.rs +++ b/src/exponential.rs @@ -30,8 +30,8 @@ impl PositiveDefiniteKernel for Exponential { .clone() .dot(diff, &[[0, 0]]) .pow(Expression::from(1.0 / 2.0)) - / params[0]) - .exp()) + / params[0].clone()) + .exp()) } fn params_len(&self) -> usize { diff --git a/src/mul.rs b/src/mul.rs index 0db39de..77744bf 100644 --- a/src/mul.rs +++ b/src/mul.rs @@ -38,7 +38,9 @@ where params: &[Expression], ) -> Result { let lhs_params_len = self.lhs.params_len(); - let fx = self.lhs.expression(x, x_prime, ¶ms[..lhs_params_len])?; + 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; diff --git a/src/periodic.rs b/src/periodic.rs index 7dcb577..0da9bcd 100644 --- a/src/periodic.rs +++ b/src/periodic.rs @@ -25,7 +25,14 @@ impl PositiveDefiniteKernel for Periodic { // } let diff = x - x_prime; - Ok((params[0] * (diff.clone().dot(diff, &[[0, 0]]).pow(Expression::from(1.0 / 2.0)) / params[1]).cos()).exp()) + Ok((params[0].clone() + * (diff + .clone() + .dot(diff, &[[0, 0]]) + .pow(Expression::from(1.0 / 2.0)) + / params[1].clone()) + .cos()) + .exp()) } fn params_len(&self) -> usize { diff --git a/src/rbf.rs b/src/rbf.rs index 016338f..dc4645d 100644 --- a/src/rbf.rs +++ b/src/rbf.rs @@ -26,7 +26,7 @@ impl PositiveDefiniteKernel for RBF { let diff = x - x_prime; - Ok((-diff.clone().dot(diff, &[[0, 0]]) / params[0]).exp()) + Ok((-diff.clone().dot(diff, &[[0, 0]]) / params[0].clone()).exp()) } fn params_len(&self) -> usize { diff --git a/src/spectral_mixture.rs b/src/spectral_mixture.rs index c955c79..8c2c7ca 100644 --- a/src/spectral_mixture.rs +++ b/src/spectral_mixture.rs @@ -28,34 +28,35 @@ impl PositiveDefiniteKernel for SpectralMixture { x_prime: Expression, params: &[Expression], ) -> 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() != 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) + 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) } } @@ -200,24 +201,24 @@ where // 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!(), +// }; +// } // } - -#[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!(), - }; - } -} From 0c428b05d4aa6e97a76fb0669d83a5c26effde40 Mon Sep 17 00:00:00 2001 From: tibetsou Date: Wed, 17 May 2023 21:59:18 +0900 Subject: [PATCH 6/6] feat: change version of symbolic --- Cargo.toml | 4 ++-- src/rbf.rs | 15 ++++----------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6cd6cdb..8ba7b3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "opensrdk-kernel-method" -version = "0.2.4" +version = "0.2.5" authors = ["Kimura Yu <33382781+KimuraYu45z@users.noreply.github.com>"] edition = "2018" description = "Standard Kernel Method library for OpenSRDK toolchain." @@ -12,7 +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.1.3" +opensrdk-symbolic-computation = "0.2.0" rayon = "1.5.1" thiserror = "1.0.28" opensrdk-linear-algebra = "0.8.2" diff --git a/src/rbf.rs b/src/rbf.rs index dc4645d..62419d0 100644 --- a/src/rbf.rs +++ b/src/rbf.rs @@ -161,17 +161,10 @@ where // #[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(); +// let kernel_diff = kernel +// .expression(theta_array, samples_array, &kernel_params_expression) +// .unwrap() +// .ln(); // assert_eq!(test_value, (-1f64).exp()); // }