Skip to content

Commit

Permalink
Added so panoc and fbs have a max duration parameter
Browse files Browse the repository at this point in the history
Now the solving can be stopped based on time, which is really useful
in case of real-time implementation where a max time maps better to
the use-case
  • Loading branch information
korken89 committed May 7, 2019
1 parent d73d47a commit 27e456c
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 11 deletions.
28 changes: 24 additions & 4 deletions src/core/fbs/fbs_optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use super::super::SolverStatus;
use super::FBSEngine;
use super::FBSOptimizer;
use crate::constraints;
use std::time;

const MAX_ITER: usize = 100_usize;

Expand All @@ -22,6 +23,7 @@ where
FBSOptimizer {
fbs_engine: fbs_engine,
max_iter: MAX_ITER,
max_duration: None,
}
}

Expand All @@ -48,20 +50,37 @@ where
self.max_iter = max_iter;
self
}

/// Sets the maximum number of iterations
pub fn with_max_duration(
&mut self,
max_duration: time::Duration,
) -> &mut FBSOptimizer<'a, GradientType, ConstraintType, CostType> {
self.max_duration = Some(max_duration);
self
}
}

impl<'life, GradientType, ConstraintType, CostType> Optimizer
for FBSOptimizer<'life, GradientType, ConstraintType, CostType>
where
GradientType: Fn(&[f64], &mut [f64]) -> i32 + 'life,
GradientType: Fn(&[f64], &mut [f64]) -> i32,
CostType: Fn(&[f64], &mut f64) -> i32,
ConstraintType: constraints::Constraint + 'life,
ConstraintType: constraints::Constraint,
{
fn solve(&mut self, u: &mut [f64]) -> SolverStatus {
let now = time::Instant::now();

self.fbs_engine.init(u);
let mut num_iter: usize = 0;
while self.fbs_engine.step(u) && num_iter < self.max_iter {
num_iter += 1;
if let Some(dur) = self.max_duration {
while self.fbs_engine.step(u) && num_iter < self.max_iter && dur <= now.elapsed() {
num_iter += 1;
}
} else {
while self.fbs_engine.step(u) && num_iter < self.max_iter {
num_iter += 1;
}
}

// cost at the solution
Expand All @@ -77,6 +96,7 @@ where
SolverStatus::new(
num_iter < self.max_iter,
num_iter,
now.elapsed(),
self.fbs_engine.cache.norm_fpr,
cost_value,
)
Expand Down
2 changes: 2 additions & 0 deletions src/core/fbs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ mod fbs_optimizer;

use super::Problem;
use crate::constraints;
use std::time;

/// Cache for the forward-backward splitting (FBS), or projected gradient, algorithm
///
Expand Down Expand Up @@ -90,6 +91,7 @@ where
{
fbs_engine: &'a mut FBSEngine<'a, GradientType, ConstraintType, CostType>,
max_iter: usize,
max_duration: Option<time::Duration>,
}

/* --------------------------------------------------------------------------------------------- */
Expand Down
3 changes: 3 additions & 0 deletions src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//!
//!
use crate::constraints;
use std::time;

pub mod fbs;
pub mod panoc;
Expand All @@ -18,6 +19,8 @@ pub struct SolverStatus {
converged: bool,
/// number of iterations for convergence
num_iter: usize,
/// time it took to solve
solve_time: time::Duration,
/// norm of the fixed-point residual (FPR)
fpr_norm: f64,
/// cost value at the candidate solution
Expand Down
2 changes: 2 additions & 0 deletions src/core/panoc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! PANOC super-fast algorithm
use super::Problem;
use crate::constraints;
use std::time;

mod panoc_cache;
mod panoc_engine;
Expand Down Expand Up @@ -55,6 +56,7 @@ where
{
panoc_engine: &'a mut PANOCEngine<'a, GradientType, ConstraintType, CostType>,
max_iter: usize,
max_duration: Option<time::Duration>,
}

#[cfg(test)]
Expand Down
26 changes: 24 additions & 2 deletions src/core/panoc/panoc_optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use super::super::SolverStatus;
use super::PANOCEngine;
use super::PANOCOptimizer;
use crate::constraints;
use std::time;

const MAX_ITER: usize = 100_usize;

Expand All @@ -22,6 +23,7 @@ where
PANOCOptimizer {
panoc_engine: panoc_engine,
max_iter: MAX_ITER,
max_duration: None,
}
}

Expand All @@ -48,6 +50,15 @@ where
self.max_iter = max_iter;
self
}

/// Sets the maximum solution time, useful in real-time applications
pub fn with_max_duration(
&mut self,
max_duation: time::Duration,
) -> &mut PANOCOptimizer<'a, GradientType, ConstraintType, CostType> {
self.max_duration = Some(max_duation);
self
}
}

impl<'life, GradientType, ConstraintType, CostType> Optimizer
Expand All @@ -58,16 +69,27 @@ where
ConstraintType: constraints::Constraint + 'life,
{
fn solve(&mut self, u: &mut [f64]) -> SolverStatus {
let now = time::Instant::now();

self.panoc_engine.init(u);

let mut num_iter: usize = 0;
while self.panoc_engine.step(u) && num_iter < self.max_iter {
num_iter += 1;

if let Some(dur) = self.max_duration {
while self.panoc_engine.step(u) && num_iter < self.max_iter && now.elapsed() <= dur {
num_iter += 1;
}
} else {
while self.panoc_engine.step(u) && num_iter < self.max_iter {
num_iter += 1;
}
}

// export solution status
SolverStatus::new(
num_iter < self.max_iter,
num_iter,
now.elapsed(),
self.panoc_engine.cache.norm_gamma_fpr,
self.panoc_engine.cache.cost_value,
)
Expand Down
23 changes: 18 additions & 5 deletions src/core/solver_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//!
//!
pub use crate::core::SolverStatus;
use std::time;

impl SolverStatus {
/// Constructs a new instance of SolverStatus
Expand All @@ -15,12 +16,19 @@ impl SolverStatus {
/// quality
/// - `cost_value` the value of the cost function at the solution
///
pub fn new(converged: bool, num_iter: usize, fpr_norm: f64, cost_value: f64) -> SolverStatus {
pub fn new(
converged: bool,
num_iter: usize,
solve_time: time::Duration,
fpr_norm: f64,
cost_value: f64,
) -> SolverStatus {
SolverStatus {
converged: converged,
num_iter: num_iter,
fpr_norm: fpr_norm,
cost_value: cost_value,
converged,
num_iter,
solve_time,
fpr_norm,
cost_value,
}
}

Expand All @@ -34,6 +42,11 @@ impl SolverStatus {
self.num_iter
}

/// number of iterations taken by the algorithm
pub fn get_solve_time(&self) -> time::Duration {
self.solve_time
}

/// norm of the fixed point residual
pub fn get_norm_fpr(&self) -> f64 {
self.fpr_norm
Expand Down

0 comments on commit 27e456c

Please sign in to comment.