use crate::core::{
CostFunction, Error, Gradient, Hessian, IterState, Jacobian, Operator, Problem, Solver, KV,
};
#[cfg(feature = "rand")]
use crate::solver::simulatedannealing::Anneal;
#[cfg(feature = "serde1")]
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
#[derive(Clone, Copy, Default, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub struct TestProblem {}
impl TestProblem {
#[allow(dead_code)]
pub fn new() -> Self {
TestProblem {}
}
}
impl Operator for TestProblem {
type Param = Vec<f64>;
type Output = Vec<f64>;
fn apply(&self, p: &Self::Param) -> Result<Self::Output, Error> {
Ok(p.clone())
}
}
impl CostFunction for TestProblem {
type Param = Vec<f64>;
type Output = f64;
fn cost(&self, _p: &Self::Param) -> Result<Self::Output, Error> {
Ok(1.0f64)
}
}
impl Gradient for TestProblem {
type Param = Vec<f64>;
type Gradient = Vec<f64>;
fn gradient(&self, p: &Self::Param) -> Result<Self::Param, Error> {
Ok(p.clone())
}
}
impl Hessian for TestProblem {
type Param = Vec<f64>;
type Hessian = Vec<Vec<f64>>;
fn hessian(&self, p: &Self::Param) -> Result<Self::Hessian, Error> {
Ok(vec![p.clone(), p.clone()])
}
}
impl Jacobian for TestProblem {
type Param = Vec<f64>;
type Jacobian = Vec<Vec<f64>>;
fn jacobian(&self, p: &Self::Param) -> Result<Self::Jacobian, Error> {
Ok(vec![p.clone(), p.clone()])
}
}
#[cfg(feature = "rand")]
impl Anneal for TestProblem {
type Param = Vec<f64>;
type Output = Vec<f64>;
type Float = f64;
fn anneal(&self, p: &Self::Param, _t: Self::Float) -> Result<Self::Output, Error> {
Ok(p.clone())
}
}
#[derive(Clone, Copy, Default, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub struct TestSparseProblem {}
impl TestSparseProblem {
#[allow(dead_code)]
pub fn new() -> Self {
TestSparseProblem {}
}
}
impl CostFunction for TestSparseProblem {
type Param = Vec<f64>;
type Output = f64;
fn cost(&self, param: &Self::Param) -> Result<Self::Output, Error> {
let err1 = (param[0] + param[1] - 1.0).powi(2);
let err2 = (param[2] + param[3] + 1.0).powi(2);
let err3 = (param[0] - 1.0).powi(2);
let err4 = (param[2] + 1.0).powi(2);
Ok(err1 + err2 + err3 + err4)
}
}
impl Gradient for TestSparseProblem {
type Param = Vec<f64>;
type Gradient = Vec<f64>;
fn gradient(&self, param: &Self::Param) -> Result<Self::Gradient, Error> {
let mut g = vec![0.0; 4];
g[0] = 4.0 * param[0] + 2.0 * param[1] - 4.0;
g[1] = 2.0 * param[0] + 2.0 * param[1] - 2.0;
g[2] = 4.0 * param[2] + 2.0 * param[3] + 4.0;
g[3] = 2.0 * param[2] + 2.0 * param[3] + 2.0;
Ok(g)
}
}
#[derive(Clone, Copy, Default, Eq, PartialEq, Debug)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub struct TestSolver {}
impl TestSolver {
pub fn new() -> TestSolver {
TestSolver {}
}
}
impl<O> Solver<O, IterState<Vec<f64>, (), (), (), (), f64>> for TestSolver {
fn name(&self) -> &str {
"TestSolver"
}
fn next_iter(
&mut self,
_problem: &mut Problem<O>,
state: IterState<Vec<f64>, (), (), (), (), f64>,
) -> Result<(IterState<Vec<f64>, (), (), (), (), f64>, Option<KV>), Error> {
Ok((state, None))
}
}