pub struct Problem<O> {
pub problem: Option<O>,
pub counts: HashMap<&'static str, u64>,
}Expand description
Wrapper around problems defined by users.
Keeps track of how many times methods such as apply, cost, gradient, jacobian,
hessian, anneal and so on are called. It is used to pass the problem from one iteration of
a solver to the next.
Fields§
§problem: Option<O>Problem defined by user
counts: HashMap<&'static str, u64>Keeps track of how often methods of problem have been called.
Implementations§
Source§impl<O> Problem<O>
impl<O> Problem<O>
Sourcepub fn new(problem: O) -> Self
pub fn new(problem: O) -> Self
Wraps a problem into an instance of Problem.
§Example
let wrapped_problem = Problem::new(UserDefinedProblem {});Sourcepub fn problem<T, F: FnOnce(&O) -> Result<T, Error>>(
&mut self,
counts_string: &'static str,
func: F,
) -> Result<T, Error>
pub fn problem<T, F: FnOnce(&O) -> Result<T, Error>>( &mut self, counts_string: &'static str, func: F, ) -> Result<T, Error>
Gives access to the stored problem via the closure func and keeps track of how many
times the function has been called. The function counts will be passed to observers labeled
with counts_string. Per convention, counts_string is chosen as <something>_count.
§Example
let cost = problem.problem("cost_count", |problem| problem.cost(¶m));This is typically used when designing a trait which optimization problems need to implement
for certain solvers. For instance, for a trait Anneal used in Simulated Annealing, one
would write the following to enable the solver to call .anneal(...) on an Problem
directly:
pub trait Anneal {
type Param;
type Output;
type Float;
fn anneal(&self, param: &Self::Param, extent: Self::Float) -> Result<Self::Output, Error>;
}
impl<O: Anneal> Problem<O> {
pub fn anneal(&mut self, param: &O::Param, extent: O::Float) -> Result<O::Output, Error> {
self.problem("anneal_count", |problem| problem.anneal(param, extent))
}
}
// ...
let new_param = problem.anneal(¶m, 1.0f64);Note that this will unfortunately only work inside the argmin crate itself due to the fact
that it is not possible to impl a type from another crate. Therefore if one implements a
solver outside of argmin, .problem(...) has to be called directly as shown in the first
example.
Sourcepub fn bulk_problem<T, F: FnOnce(&O) -> Result<T, Error>>(
&mut self,
counts_string: &'static str,
num_param_vecs: usize,
func: F,
) -> Result<T, Error>
pub fn bulk_problem<T, F: FnOnce(&O) -> Result<T, Error>>( &mut self, counts_string: &'static str, num_param_vecs: usize, func: F, ) -> Result<T, Error>
Gives access to the stored problem via the closure func and keeps track of how many
times the function has been called. In contrast to the problem method, this also allows
to pass the number of parameter vectors which will be processed by the underlying problem.
This is used by the bulk_* methods, which process multiple parameters at once.
The function counts will be passed to observers labeled with counts_string.
Per convention, counts_string is chosen as <something>_count.
Sourcepub fn take_problem(&mut self) -> Option<O>
pub fn take_problem(&mut self) -> Option<O>
Returns the internally stored problem and replaces it with None.
§Example
let mut problem = Problem::new(UserDefinedProblem {});
let user_problem: Option<UserDefinedProblem> = problem.take_problem();
assert_eq!(user_problem.unwrap(), UserDefinedProblem {});
assert!(problem.problem.is_none());Sourcepub fn consume_problem(&mut self, other: Problem<O>)
pub fn consume_problem(&mut self, other: Problem<O>)
Consumes another instance of Problem. The internally stored user defined problem of the
passed Problem instance is moved to Self. The function evaluation counts are
merged/summed up.
§Example
let mut problem1 = Problem::new(UserDefinedProblem {});
// Simulate function evaluation counts in `problem1`
problem1.counts.insert("cost_count", 2);
// Take the internally stored problem such that `None` remains in its place.
let _ = problem1.take_problem();
assert!(problem1.problem.is_none());
let mut problem2 = Problem::new(UserDefinedProblem {});
// Simulate function evaluation counts in `problem2`
problem2.counts.insert("cost_count", 1);
problem2.counts.insert("gradient_count", 4);
// `problem1` consumes `problem2` by moving its internally stored user defined problem and
// by merging the function evaluation counts
problem1.consume_problem(problem2);
// `problem1` now holds a problem of type `UserDefinedProblem` (taken from `problem2`)
assert_eq!(problem1.problem.unwrap(), UserDefinedProblem {});
// The function evaluation counts have been merged
assert_eq!(problem1.counts["cost_count"], 3);
assert_eq!(problem1.counts["gradient_count"], 4);Sourcepub fn consume_func_counts<O2>(&mut self, other: Problem<O2>)
pub fn consume_func_counts<O2>(&mut self, other: Problem<O2>)
Consumes another instance of Problem by summing ob the function evaluation counts.
In contrast to consume_problem, the internally stored problem remains untouched.
Therefore the two internally stored problems do not need to be of the same type.
§Example
let mut problem1 = Problem::new(UserDefinedProblem1 {});
// Simulate function evaluation counts in `problem1`.
problem1.counts.insert("cost_count", 2);
// Take the internally stored problem such that `None` remains in its place.
let _ = problem1.take_problem();
assert!(problem1.problem.is_none());
let mut problem2 = Problem::new(UserDefinedProblem2 {});
// Simulate function evaluation counts in `problem2`
problem2.counts.insert("cost_count", 1);
problem2.counts.insert("gradient_count", 4);
// `problem1` consumes `problem2` by merging the function evaluation counts.
problem1.consume_func_counts(problem2);
// The internally stored problem remains being `None` (in contrast to `consume_problem`).
assert!(problem1.problem.is_none());
// The function evaluation counts have been merged.
assert_eq!(problem1.counts["cost_count"], 3);
assert_eq!(problem1.counts["gradient_count"], 4);Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Resets the function evaluation counts to zero.
§Example
let mut problem = Problem::new(UserDefinedProblem {});
// Simulate function evaluation counts in `problem1`.
problem.counts.insert("cost_count", 2);
problem.counts.insert("gradient_count", 4);
assert_eq!(problem.counts["cost_count"], 2);
assert_eq!(problem.counts["gradient_count"], 4);
// Set function evaluation counts to 0
problem.reset();
assert_eq!(problem.counts["cost_count"], 0);
assert_eq!(problem.counts["gradient_count"], 0);Sourcepub fn get_problem(self) -> Option<O>
pub fn get_problem(self) -> Option<O>
Returns the internally stored user defined problem by consuming Self.
§Example
let problem = Problem::new(UserDefinedProblem {});
let user_problem = problem.get_problem();
assert_eq!(user_problem.unwrap(), UserDefinedProblem {});Source§impl<O: Operator> Problem<O>
Wraps a call to apply defined in the Operator trait and as such allows to call apply on
an instance of Problem. Internally, the number of evaluations of apply is counted.
impl<O: Operator> Problem<O>
Wraps a call to apply defined in the Operator trait and as such allows to call apply on
an instance of Problem. Internally, the number of evaluations of apply is counted.
Sourcepub fn apply(&mut self, param: &O::Param) -> Result<O::Output, Error>
pub fn apply(&mut self, param: &O::Param) -> Result<O::Output, Error>
Calls apply defined in the Operator trait and keeps track of the number of evaluations.
§Example
// `UserDefinedProblem` implements `Operator`.
let mut problem1 = Problem::new(UserDefinedProblem {});
let param = vec![2.0f64, 1.0f64];
let res = problem1.apply(¶m);
assert_eq!(problem1.counts["operator_count"], 1);Sourcepub fn bulk_apply<P>(&mut self, params: &[P]) -> Result<Vec<O::Output>, Error>
pub fn bulk_apply<P>(&mut self, params: &[P]) -> Result<Vec<O::Output>, Error>
Calls bulk_apply defined in the Operator trait and keeps track of the number of
evaluations.
§Example
// `UserDefinedProblem` implements `Operator`.
let mut problem1 = Problem::new(UserDefinedProblem {});
let param1 = vec![2.0f64, 1.0f64];
let param2 = vec![3.0f64, 5.0f64];
let params = vec![¶m1, ¶m2];
let res = problem1.bulk_apply(¶ms);
assert_eq!(problem1.counts["operator_count"], 2);Source§impl<O: CostFunction> Problem<O>
Wraps a call to cost defined in the CostFunction trait and as such allows to call cost on
an instance of Problem. Internally, the number of evaluations of cost is counted.
impl<O: CostFunction> Problem<O>
Wraps a call to cost defined in the CostFunction trait and as such allows to call cost on
an instance of Problem. Internally, the number of evaluations of cost is counted.
Sourcepub fn cost(&mut self, param: &O::Param) -> Result<O::Output, Error>
pub fn cost(&mut self, param: &O::Param) -> Result<O::Output, Error>
Calls cost defined in the CostFunction trait and keeps track of the number of
evaluations.
§Example
// `UserDefinedProblem` implements `CostFunction`.
let mut problem1 = Problem::new(UserDefinedProblem {});
let param = vec![2.0f64, 1.0f64];
let res = problem1.cost(¶m);
assert_eq!(problem1.counts["cost_count"], 1);Sourcepub fn bulk_cost<P>(&mut self, params: &[P]) -> Result<Vec<O::Output>, Error>
pub fn bulk_cost<P>(&mut self, params: &[P]) -> Result<Vec<O::Output>, Error>
Calls bulk_cost defined in the CostFunction trait and keeps track of the number of
evaluations.
§Example
// `UserDefinedProblem` implements `CostFunction`.
let mut problem1 = Problem::new(UserDefinedProblem {});
let param1 = vec![2.0f64, 1.0f64];
let param2 = vec![3.0f64, 5.0f64];
let params = vec![¶m1, ¶m2];
let res = problem1.bulk_cost(¶ms);
assert_eq!(problem1.counts["cost_count"], 2);Source§impl<O: Gradient> Problem<O>
Wraps a call to gradient defined in the Gradient trait and as such allows to call gradient on
an instance of Problem. Internally, the number of evaluations of gradient is counted.
impl<O: Gradient> Problem<O>
Wraps a call to gradient defined in the Gradient trait and as such allows to call gradient on
an instance of Problem. Internally, the number of evaluations of gradient is counted.
Sourcepub fn gradient(&mut self, param: &O::Param) -> Result<O::Gradient, Error>
pub fn gradient(&mut self, param: &O::Param) -> Result<O::Gradient, Error>
Calls gradient defined in the Gradient trait and keeps track of the number of
evaluations.
§Example
// `UserDefinedProblem` implements `Gradient`.
let mut problem1 = Problem::new(UserDefinedProblem {});
let param = vec![2.0f64, 1.0f64];
let res = problem1.gradient(¶m);
assert_eq!(problem1.counts["gradient_count"], 1);Sourcepub fn bulk_gradient<P>(
&mut self,
params: &[P],
) -> Result<Vec<O::Gradient>, Error>
pub fn bulk_gradient<P>( &mut self, params: &[P], ) -> Result<Vec<O::Gradient>, Error>
Calls bulk_gradient defined in the Gradient trait and keeps track of the number of
evaluations.
§Example
// `UserDefinedProblem` implements `Gradient`.
let mut problem1 = Problem::new(UserDefinedProblem {});
let param1 = vec![2.0f64, 1.0f64];
let param2 = vec![3.0f64, 5.0f64];
let params = vec![¶m1, ¶m2];
let res = problem1.bulk_gradient(¶ms);
assert_eq!(problem1.counts["gradient_count"], 2);Source§impl<O: Hessian> Problem<O>
Wraps a call to hessian defined in the Hessian trait and as such allows to call hessian on
an instance of Problem. Internally, the number of evaluations of hessian is counted.
impl<O: Hessian> Problem<O>
Wraps a call to hessian defined in the Hessian trait and as such allows to call hessian on
an instance of Problem. Internally, the number of evaluations of hessian is counted.
Sourcepub fn hessian(&mut self, param: &O::Param) -> Result<O::Hessian, Error>
pub fn hessian(&mut self, param: &O::Param) -> Result<O::Hessian, Error>
Calls hessian defined in the Hessian trait and keeps track of the number of evaluations.
§Example
// `UserDefinedProblem` implements `Hessian`.
let mut problem1 = Problem::new(UserDefinedProblem {});
let param = vec![2.0f64, 1.0f64];
let res = problem1.hessian(¶m);
assert_eq!(problem1.counts["hessian_count"], 1);Sourcepub fn bulk_hessian<P>(
&mut self,
params: &[P],
) -> Result<Vec<O::Hessian>, Error>
pub fn bulk_hessian<P>( &mut self, params: &[P], ) -> Result<Vec<O::Hessian>, Error>
Calls bulk_hessian defined in the Hessian trait and keeps track of the number of
evaluations.
§Example
// `UserDefinedProblem` implements `Hessian`.
let mut problem1 = Problem::new(UserDefinedProblem {});
let param1 = vec![2.0f64, 1.0f64];
let param2 = vec![3.0f64, 5.0f64];
let params = vec![¶m1, ¶m2];
let res = problem1.bulk_hessian(¶ms);
assert_eq!(problem1.counts["hessian_count"], 2);Source§impl<O: Jacobian> Problem<O>
Wraps a call to jacobian defined in the Jacobian trait and as such allows to call jacobian
on an instance of Problem. Internally, the number of evaluations of jacobian is counted.
impl<O: Jacobian> Problem<O>
Wraps a call to jacobian defined in the Jacobian trait and as such allows to call jacobian
on an instance of Problem. Internally, the number of evaluations of jacobian is counted.
Sourcepub fn jacobian(&mut self, param: &O::Param) -> Result<O::Jacobian, Error>
pub fn jacobian(&mut self, param: &O::Param) -> Result<O::Jacobian, Error>
Calls jacobian defined in the Jacobian trait and keeps track of the number of
evaluations.
§Example
// `UserDefinedProblem` implements `Jacobian`.
let mut problem1 = Problem::new(UserDefinedProblem {});
let param = vec![2.0f64, 1.0f64];
let res = problem1.jacobian(¶m);
assert_eq!(problem1.counts["jacobian_count"], 1);Sourcepub fn bulk_jacobian<P>(
&mut self,
params: &[P],
) -> Result<Vec<O::Jacobian>, Error>
pub fn bulk_jacobian<P>( &mut self, params: &[P], ) -> Result<Vec<O::Jacobian>, Error>
Calls bulk_jacobian defined in the Jacobian trait and keeps track of the number of
evaluations.
§Example
// `UserDefinedProblem` implements `Jacobian`.
let mut problem1 = Problem::new(UserDefinedProblem {});
let params = vec![vec![2.0f64, 1.0f64], vec![3.0f64, 5.0f64]];
let res = problem1.bulk_jacobian(¶ms);
assert_eq!(problem1.counts["jacobian_count"], 2);Source§impl<O: LinearProgram> Problem<O>
Wraps a calls to c, b and A defined in the LinearProgram trait and as such allows to
call those methods on an instance of Problem.
impl<O: LinearProgram> Problem<O>
Wraps a calls to c, b and A defined in the LinearProgram trait and as such allows to
call those methods on an instance of Problem.
Sourcepub fn c(&self) -> Result<Vec<O::Float>, Error>
pub fn c(&self) -> Result<Vec<O::Float>, Error>
Calls c defined in the LinearProgram trait.
§Example
// `UserDefinedProblem` implements `LinearProgram`.
let mut problem1 = Problem::new(UserDefinedProblem {});
let c = problem1.c();
let b = problem1.b();
Source§impl<O: Anneal> Problem<O>
Wraps a call to anneal defined in the Anneal trait and as such allows to call anneal on
an instance of Problem. Internally, the number of evaluations of anneal is counted.
impl<O: Anneal> Problem<O>
Wraps a call to anneal defined in the Anneal trait and as such allows to call anneal on
an instance of Problem. Internally, the number of evaluations of anneal is counted.
Sourcepub fn anneal(
&mut self,
param: &O::Param,
extent: O::Float,
) -> Result<O::Output, Error>
pub fn anneal( &mut self, param: &O::Param, extent: O::Float, ) -> Result<O::Output, Error>
Calls anneal defined in the Anneal trait and keeps track of the number of evaluations.
§Example
// `UserDefinedProblem` implements `Anneal`.
let mut problem1 = Problem::new(UserDefinedProblem {});
let param = vec![2.0f64, 1.0f64];
let res = problem1.anneal(¶m, 1.0);
assert_eq!(problem1.counts["anneal_count"], 1);Trait Implementations§
Auto Trait Implementations§
impl<O> Freeze for Problem<O>where
O: Freeze,
impl<O> RefUnwindSafe for Problem<O>where
O: RefUnwindSafe,
impl<O> Send for Problem<O>where
O: Send,
impl<O> Sync for Problem<O>where
O: Sync,
impl<O> Unpin for Problem<O>where
O: Unpin,
impl<O> UnwindSafe for Problem<O>where
O: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read more§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.