Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added multidimensional Rosenbrock derivative and Hessian #411

Merged
merged 1 commit into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions argmin/src/core/checkpointing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
//! use argmin_checkpointing_file::FileCheckpoint;
//! # use argmin_observer_slog::SlogLogger;
//! # use argmin::solver::landweber::Landweber;
//! # use argmin_testfunctions::{rosenbrock_2d, rosenbrock_2d_derivative};
//! # use argmin_testfunctions::{rosenbrock, rosenbrock_derivative};
//! #
//! # #[derive(Default)]
//! # struct Rosenbrock {}
Expand All @@ -49,7 +49,7 @@
//! #
//! # /// Apply the cost function to a parameter `p`
//! # fn cost(&self, p: &Self::Param) -> Result<Self::Output, Error> {
//! # Ok(rosenbrock_2d(&[p[0], p[1]], 1.0, 100.0))
//! # Ok(rosenbrock(p, 1.0, 100.0))
//! # }
//! # }
//! #
Expand All @@ -62,7 +62,7 @@
//! #
//! # /// Compute the gradient at parameter `p`.
//! # fn gradient(&self, p: &Self::Param) -> Result<Self::Gradient, Error> {
//! # Ok(rosenbrock_2d_derivative(&[p[0], p[1]], 1.0, 100.0).to_vec())
//! # Ok(rosenbrock_derivative(p, 1.0, 100.0))
//! # }
//! # }
//! #
Expand Down
6 changes: 3 additions & 3 deletions argmin/src/core/observers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
//! # use argmin_observer_paramwriter::{ParamWriter, ParamWriterFormat};
//! # use argmin::solver::gradientdescent::SteepestDescent;
//! # use argmin::solver::linesearch::MoreThuenteLineSearch;
//! # use argmin_testfunctions::{rosenbrock_2d, rosenbrock_2d_derivative};
//! # use argmin_testfunctions::{rosenbrock, rosenbrock_derivative};
//! #
//! # struct Rosenbrock {
//! # a: f64,
Expand All @@ -52,7 +52,7 @@
//! #
//! # /// Apply the cost function to a parameter `p`
//! # fn cost(&self, p: &Self::Param) -> Result<Self::Output, Error> {
//! # Ok(rosenbrock_2d(&[p[0], p[1]], 1.0, 100.0))
//! # Ok(rosenbrock(p, 1.0, 100.0))
//! # }
//! # }
//! #
Expand All @@ -65,7 +65,7 @@
//! #
//! # /// Compute the gradient at parameter `p`.
//! # fn gradient(&self, p: &Self::Param) -> Result<Self::Gradient, Error> {
//! # Ok(rosenbrock_2d_derivative(&[p[0], p[1]], 1.0, 100.0).to_vec())
//! # Ok(rosenbrock_derivative(p, 1.0, 100.0))
//! # }
//! # }
//! #
Expand Down
6 changes: 3 additions & 3 deletions examples/checkpoint/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use argmin::{
};
use argmin_checkpointing_file::FileCheckpoint;
use argmin_observer_slog::SlogLogger;
use argmin_testfunctions::{rosenbrock_2d, rosenbrock_2d_derivative};
use argmin_testfunctions::{rosenbrock, rosenbrock_derivative};

#[derive(Default)]
struct Rosenbrock {}
Expand All @@ -24,7 +24,7 @@ impl CostFunction for Rosenbrock {
type Output = f64;

fn cost(&self, p: &Self::Param) -> Result<Self::Output, Error> {
Ok(rosenbrock_2d(&[p[0], p[1]], 1.0, 100.0))
Ok(rosenbrock(p, 1.0, 100.0))
}
}

Expand All @@ -33,7 +33,7 @@ impl Gradient for Rosenbrock {
type Gradient = Vec<f64>;

fn gradient(&self, p: &Self::Param) -> Result<Self::Gradient, Error> {
Ok(rosenbrock_2d_derivative(&[p[0], p[1]], 1.0, 100.0).to_vec())
Ok(rosenbrock_derivative(p, 1.0, 100.0))
}
}

Expand Down
4 changes: 2 additions & 2 deletions examples/landweber/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use argmin::{
solver::landweber::Landweber,
};
use argmin_observer_slog::SlogLogger;
use argmin_testfunctions::rosenbrock_2d_derivative;
use argmin_testfunctions::rosenbrock_derivative;

struct Rosenbrock {}

Expand All @@ -19,7 +19,7 @@ impl Gradient for Rosenbrock {
type Gradient = Vec<f64>;

fn gradient(&self, p: &Self::Param) -> Result<Self::Gradient, Error> {
Ok(rosenbrock_2d_derivative(&[p[0], p[1]], 1.0, 100.0).to_vec())
Ok(rosenbrock_derivative(p, 1.0, 100.0))
}
}

Expand Down
13 changes: 8 additions & 5 deletions examples/lbfgs/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ use argmin::{
solver::{linesearch::MoreThuenteLineSearch, quasinewton::LBFGS},
};
use argmin_observer_slog::SlogLogger;
use argmin_testfunctions::rosenbrock;
use finitediff::FiniteDiff;
use argmin_testfunctions::{rosenbrock, rosenbrock_derivative};
use ndarray::{array, Array1};

struct Rosenbrock {
Expand All @@ -24,15 +23,19 @@ impl CostFunction for Rosenbrock {
type Output = f64;

fn cost(&self, p: &Self::Param) -> Result<Self::Output, Error> {
Ok(rosenbrock(&p.to_vec(), self.a, self.b))
Ok(rosenbrock(p.as_slice().unwrap(), self.a, self.b))
}
}
impl Gradient for Rosenbrock {
type Param = Array1<f64>;
type Gradient = Array1<f64>;

fn gradient(&self, p: &Self::Param) -> Result<Self::Gradient, Error> {
Ok((*p).forward_diff(&|x| rosenbrock(&x.to_vec(), self.a, self.b)))
Ok(Array1::from(rosenbrock_derivative(
p.as_slice().unwrap(),
self.a,
self.b,
)))
}
}

Expand All @@ -42,7 +45,7 @@ fn run() -> Result<(), Error> {

// Define initial parameter vector
let init_param: Array1<f64> = array![-1.2, 1.0];
// let init_param: Array1<f64> = array![-1.2, 1.0, -10.0, 2.0, 3.0, 2.0, 4.0, 10.0];
// let init_param: Array1<f64> = array![-1.2, 1.0, -10.0, 2.0, 3.0, 2.0, 4.0, 9.0];

// set up a line search
let linesearch = MoreThuenteLineSearch::new().with_c(1e-4, 0.9)?;
Expand Down
12 changes: 7 additions & 5 deletions examples/lbfgs_nalgebra/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use argmin::{
solver::{linesearch::MoreThuenteLineSearch, quasinewton::LBFGS},
};
use argmin_observer_slog::SlogLogger;
use argmin_testfunctions::{rosenbrock_2d, rosenbrock_2d_derivative};
use argmin_testfunctions::{rosenbrock, rosenbrock_derivative};
use nalgebra::DVector;

struct Rosenbrock {
Expand All @@ -23,7 +23,7 @@ impl CostFunction for Rosenbrock {
type Output = f64;

fn cost(&self, p: &Self::Param) -> Result<Self::Output, Error> {
Ok(rosenbrock_2d(&[p[0], p[1]], self.a, self.b))
Ok(rosenbrock(p.as_slice(), self.a, self.b))
}
}

Expand All @@ -32,9 +32,11 @@ impl Gradient for Rosenbrock {
type Gradient = DVector<f64>;

fn gradient(&self, p: &Self::Param) -> Result<Self::Gradient, Error> {
Ok(DVector::from(
rosenbrock_2d_derivative(&[p[0], p[1]], self.a, self.b).to_vec(),
))
Ok(DVector::from(rosenbrock_derivative(
p.as_slice(),
self.a,
self.b,
)))
}
}

Expand Down
22 changes: 11 additions & 11 deletions examples/newton/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use argmin::{
solver::newton::Newton,
};
use argmin_observer_slog::SlogLogger;
use argmin_testfunctions::{rosenbrock_2d_derivative, rosenbrock_2d_hessian};
use argmin_testfunctions::{rosenbrock_derivative, rosenbrock_hessian};
use ndarray::{Array, Array1, Array2};

struct Rosenbrock {
Expand All @@ -23,9 +23,11 @@ impl Gradient for Rosenbrock {
type Gradient = Array1<f64>;

fn gradient(&self, p: &Self::Param) -> Result<Self::Gradient, Error> {
Ok(Array1::from(
rosenbrock_2d_derivative(&[p[0], p[1]], self.a, self.b).to_vec(),
))
Ok(Array1::from(rosenbrock_derivative(
p.as_slice().unwrap(),
self.a,
self.b,
)))
}
}

Expand All @@ -34,12 +36,11 @@ impl Hessian for Rosenbrock {
type Hessian = Array2<f64>;

fn hessian(&self, p: &Self::Param) -> Result<Self::Hessian, Error> {
let h = rosenbrock_2d_hessian(&[p[0], p[1]], self.a, self.b)
.iter()
let h = rosenbrock_hessian(p.as_slice().unwrap(), self.a, self.b)
.into_iter()
.flatten()
.cloned()
.collect();
Ok(Array::from_shape_vec((2, 2), h)?)
Ok(Array::from_shape_vec((p.len(), p.len()), h)?)
}
}

Expand All @@ -48,15 +49,14 @@ fn run() -> Result<(), Error> {
let cost = Rosenbrock { a: 1.0, b: 100.0 };

// Define initial parameter vector
// let init_param: Array1<f64> = Array1::from(vec![1.2, 1.2]);
let init_param: Array1<f64> = Array1::from(vec![-1.2, 1.0]);
let init_param: Array1<f64> = Array1::from(vec![1.2, 1.2]);

// Set up solver
let solver: Newton<f64> = Newton::new();

// Run solver
let res = Executor::new(cost, solver)
.configure(|state| state.param(init_param).max_iters(8))
.configure(|state| state.param(init_param).max_iters(10))
.add_observer(SlogLogger::term(), ObserverMode::Always)
.run()?;

Expand Down
14 changes: 6 additions & 8 deletions examples/newton_cg/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use argmin::{
solver::{linesearch::MoreThuenteLineSearch, newton::NewtonCG},
};
use argmin_observer_slog::SlogLogger;
use argmin_testfunctions::{rosenbrock_2d, rosenbrock_2d_derivative, rosenbrock_2d_hessian};
use argmin_testfunctions::{rosenbrock, rosenbrock_derivative, rosenbrock_hessian};
use ndarray::{Array, Array1, Array2};

struct Rosenbrock {
Expand All @@ -23,7 +23,7 @@ impl CostFunction for Rosenbrock {
type Output = f64;

fn cost(&self, p: &Self::Param) -> Result<Self::Output, Error> {
Ok(rosenbrock_2d(&[p[0], p[1]], self.a, self.b))
Ok(rosenbrock(p.as_slice().unwrap(), self.a, self.b))
}
}

Expand All @@ -33,7 +33,7 @@ impl Gradient for Rosenbrock {

fn gradient(&self, p: &Self::Param) -> Result<Self::Gradient, Error> {
Ok(Array1::from(
rosenbrock_2d_derivative(&[p[0], p[1]], self.a, self.b).to_vec(),
rosenbrock_derivative(p.as_slice().unwrap(), self.a, self.b).to_vec(),
))
}
}
Expand All @@ -43,12 +43,11 @@ impl Hessian for Rosenbrock {
type Hessian = Array2<f64>;

fn hessian(&self, p: &Self::Param) -> Result<Self::Hessian, Error> {
let h = rosenbrock_2d_hessian(&[p[0], p[1]], self.a, self.b)
.iter()
let h = rosenbrock_hessian(p.as_slice().unwrap(), self.a, self.b)
.into_iter()
.flatten()
.cloned()
.collect();
Ok(Array::from_shape_vec((2, 2), h)?)
Ok(Array::from_shape_vec((p.len(), p.len()), h)?)
}
}

Expand All @@ -57,7 +56,6 @@ fn run() -> Result<(), Error> {
let cost = Rosenbrock { a: 1.0, b: 100.0 };

// Define initial parameter vector
// let init_param: Array1<f64> = Array1::from(vec![1.2, 1.2]);
let init_param: Array1<f64> = Array1::from(vec![-1.2, 1.0]);

// set up line search
Expand Down
6 changes: 3 additions & 3 deletions examples/nonlinear_cg/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use argmin::{
},
};
use argmin_observer_slog::SlogLogger;
use argmin_testfunctions::{rosenbrock_2d, rosenbrock_2d_derivative};
use argmin_testfunctions::{rosenbrock, rosenbrock_derivative};

struct Rosenbrock {}

Expand All @@ -22,7 +22,7 @@ impl CostFunction for Rosenbrock {
type Output = f64;

fn cost(&self, p: &Self::Param) -> Result<Self::Output, Error> {
Ok(rosenbrock_2d(&[p[0], p[1]], 1.0, 100.0))
Ok(rosenbrock(p, 1.0, 100.0))
}
}

Expand All @@ -31,7 +31,7 @@ impl Gradient for Rosenbrock {
type Gradient = Vec<f64>;

fn gradient(&self, p: &Self::Param) -> Result<Self::Gradient, Error> {
Ok(rosenbrock_2d_derivative(&[p[0], p[1]], 1.0, 100.0).to_vec())
Ok(rosenbrock_derivative(p, 1.0, 100.0))
}
}

Expand Down
6 changes: 3 additions & 3 deletions examples/paramwriter/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use argmin::{
solver::{gradientdescent::SteepestDescent, linesearch::MoreThuenteLineSearch},
};
use argmin_observer_paramwriter::{ParamWriter, ParamWriterFormat};
use argmin_testfunctions::{rosenbrock_2d, rosenbrock_2d_derivative};
use argmin_testfunctions::{rosenbrock, rosenbrock_derivative};

struct Rosenbrock {
a: f64,
Expand All @@ -22,7 +22,7 @@ impl CostFunction for Rosenbrock {
type Output = f64;

fn cost(&self, p: &Self::Param) -> Result<Self::Output, Error> {
Ok(rosenbrock_2d(&[p[0], p[1]], self.a, self.b))
Ok(rosenbrock(p, self.a, self.b))
}
}

Expand All @@ -31,7 +31,7 @@ impl Gradient for Rosenbrock {
type Gradient = Vec<f64>;

fn gradient(&self, p: &Self::Param) -> Result<Self::Gradient, Error> {
Ok(rosenbrock_2d_derivative(&[p[0], p[1]], self.a, self.b).to_vec())
Ok(rosenbrock_derivative(p, self.a, self.b))
}
}

Expand Down
8 changes: 4 additions & 4 deletions examples/steepestdescent/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use argmin::{
},
};
use argmin_observer_slog::SlogLogger;
use argmin_testfunctions::{rosenbrock_2d, rosenbrock_2d_derivative};
use argmin_testfunctions::{rosenbrock, rosenbrock_derivative};

struct Rosenbrock {
a: f64,
Expand All @@ -26,7 +26,7 @@ impl CostFunction for Rosenbrock {
type Output = f64;

fn cost(&self, p: &Self::Param) -> Result<Self::Output, Error> {
Ok(rosenbrock_2d(&[p[0], p[1]], self.a, self.b))
Ok(rosenbrock(p, self.a, self.b))
}
}

Expand All @@ -35,7 +35,7 @@ impl Gradient for Rosenbrock {
type Gradient = Vec<f64>;

fn gradient(&self, p: &Self::Param) -> Result<Self::Gradient, Error> {
Ok(rosenbrock_2d_derivative(&[p[0], p[1]], self.a, self.b).to_vec())
Ok(rosenbrock_derivative(p, self.a, self.b))
}
}

Expand All @@ -58,7 +58,7 @@ fn run() -> Result<(), Error> {

// Run solver
let res = Executor::new(cost, solver)
.configure(|state| state.param(init_param).max_iters(10))
.configure(|state| state.param(init_param).max_iters(100))
.add_observer(SlogLogger::term(), ObserverMode::Always)
.run()?;

Expand Down
3 changes: 2 additions & 1 deletion examples/trustregion/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ publish = false

[dependencies]
argmin = { version = "*", path = "../../argmin" }
argmin-math = { version = "*", features = ["ndarray_latest-nolinalg"], path = "../../argmin-math" }
argmin-math = { version = "*", features = ["ndarray_latest"], path = "../../argmin-math" }
argmin-observer-slog = { version = "*", path = "../../observers/slog/" }
argmin_testfunctions = { version = "*", path = "../../tools/testfunctions/" }
ndarray = "0.15.6"
ndarray-linalg = { version = "0.16.0", features = ["intel-mkl-static"] }
Loading