opensrdk_kernel_method/
exponential.rs

1use std::ops::{Add, Mul};
2
3use crate::KernelError;
4
5use super::{KernelAdd, KernelMul, PositiveDefiniteKernel};
6use opensrdk_symbolic_computation::Expression;
7
8const PARAMS_LEN: usize = 1;
9
10#[derive(Clone, Debug)]
11pub struct Exponential;
12
13impl PositiveDefiniteKernel for Exponential {
14    fn expression(
15        &self,
16        x: Expression,
17        x_prime: Expression,
18        params: &[Expression],
19    ) -> Result<Expression, KernelError> {
20        if params.len() != PARAMS_LEN {
21            return Err(KernelError::ParametersLengthMismatch.into());
22        }
23        // if x.len() != x_prime.len() {
24        //     return Err(KernelError::InvalidArgument.into());
25        // }
26
27        let diff = x - x_prime;
28
29        Ok((-diff
30            .clone()
31            .dot(diff, &[[0, 0]])
32            .pow(Expression::from(1.0 / 2.0))
33            / params[0].clone())
34        .exp())
35    }
36
37    fn params_len(&self) -> usize {
38        1
39    }
40}
41
42impl<R> Add<R> for Exponential
43where
44    R: PositiveDefiniteKernel,
45{
46    type Output = KernelAdd<Self, R>;
47
48    fn add(self, rhs: R) -> Self::Output {
49        KernelAdd::new(self, rhs)
50    }
51}
52
53impl<R> Mul<R> for Exponential
54where
55    R: PositiveDefiniteKernel,
56{
57    type Output = KernelMul<Self, R>;
58
59    fn mul(self, rhs: R) -> Self::Output {
60        KernelMul::new(self, rhs)
61    }
62}
63
64// use super::PositiveDefiniteKernel;
65// use crate::{
66//     KernelAdd, KernelError, KernelMul, ParamsDifferentiableKernel, ValueDifferentiableKernel,
67// };
68// use opensrdk_linear_algebra::Vector;
69// use rayon::prelude::*;
70// use std::{ops::Add, ops::Mul};
71
72// const PARAMS_LEN: usize = 1;
73
74// #[derive(Clone, Debug)]
75// pub struct Exponential;
76
77// impl Exponential {
78//     fn norm(&self, params: &[f64], x: &Vec<f64>, xprime: &Vec<f64>) -> Result<f64, KernelError> {
79//         if params.len() != PARAMS_LEN {
80//             return Err(KernelError::ParametersLengthMismatch.into());
81//         }
82//         if x.len() != xprime.len() {
83//             return Err(KernelError::InvalidArgument.into());
84//         }
85
86//         let v = x
87//             .par_iter()
88//             .zip(xprime.par_iter())
89//             .map(|(x_i, xprime_i)| (x_i - xprime_i).powi(2))
90//             .sum::<f64>()
91//             .sqrt();
92
93//         Ok(v)
94//     }
95// }
96
97// impl PositiveDefiniteKernel<Vec<f64>> for Exponential {
98//     fn params_len(&self) -> usize {
99//         PARAMS_LEN
100//     }
101
102//     fn value(&self, params: &[f64], x: &Vec<f64>, xprime: &Vec<f64>) -> Result<f64, KernelError> {
103//         let norm = self.norm(params, x, xprime)?;
104
105//         let fx = (-norm / params[0]).exp();
106
107//         Ok(fx)
108//     }
109// }
110
111// impl ValueDifferentiableKernel<Vec<f64>> for Exponential {
112//     fn ln_diff_value(
113//         &self,
114//         params: &[f64],
115//         x: &Vec<f64>,
116//         xprime: &Vec<f64>,
117//     ) -> Result<Vec<f64>, KernelError> {
118//         let diff = (-2.0 / params[0] * (x.clone().col_mat() - xprime.clone().col_mat())).vec();
119//         Ok(diff)
120//     }
121// }
122
123// impl ParamsDifferentiableKernel<Vec<f64>> for Exponential {
124//     fn ln_diff_params(
125//         &self,
126//         params: &[f64],
127//         x: &Vec<f64>,
128//         xprime: &Vec<f64>,
129//     ) -> Result<Vec<f64>, KernelError> {
130//         let diff1 = 2.0 * params[0].powi(-2) * &self.norm(params, x, xprime).unwrap();
131//         let diff = vec![diff1];
132//         Ok(diff)
133//     }
134// }
135
136// impl<R> Add<R> for Exponential
137// where
138//     R: PositiveDefiniteKernel<Vec<f64>>,
139// {
140//     type Output = KernelAdd<Self, R, Vec<f64>>;
141
142//     fn add(self, rhs: R) -> Self::Output {
143//         Self::Output::new(self, rhs)
144//     }
145// }
146
147// impl<R> Mul<R> for Exponential
148// where
149//     R: PositiveDefiniteKernel<Vec<f64>>,
150// {
151//     type Output = KernelMul<Self, R, Vec<f64>>;
152
153//     fn mul(self, rhs: R) -> Self::Output {
154//         Self::Output::new(self, rhs)
155//     }
156// }
157
158// #[cfg(test)]
159// mod tests {
160//     use crate::*;
161//     #[test]
162//     fn it_works() {
163//         let kernel = Exponential;
164
165//         let test_value = kernel
166//             .value(&[1.0], &vec![1.0, 0.0, 0.0], &vec![0.0, 0.0, 0.0])
167//             .unwrap();
168
169//         assert_eq!(test_value, (-1f64).exp());
170//     }
171// }