Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Replace `extern crate` with `use` |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
32372fda04e9dcc1c7f87e33f0954d02 |
| User & Date: | fifr 2018-12-12 15:38:03.747 |
Context
|
2018-12-12
| ||
| 15:38 | Update version to 0.5.1 check-in: 393791e563 user: fifr tags: trunk, v0.5.1 | |
| 15:38 | Replace `extern crate` with `use` check-in: 32372fda04 user: fifr tags: trunk | |
| 15:30 | Update to 2018 edition check-in: 80cbe311ac user: fifr tags: trunk | |
Changes
Changes to Cargo.toml.
1 2 3 4 5 6 7 8 9 10 | [package] name = "bundle" version = "0.5.0" authors = ["Frank Fischer <frank-fischer@shadow-soft.de>"] [dependencies] itertools = "^0.7.2" libc = "^0.2.6" log = "^0.4" c_str_macro = "^1.0" | > | 1 2 3 4 5 6 7 8 9 10 11 | [package] name = "bundle" version = "0.5.0" edition = "2018" authors = ["Frank Fischer <frank-fischer@shadow-soft.de>"] [dependencies] itertools = "^0.7.2" libc = "^0.2.6" log = "^0.4" c_str_macro = "^1.0" |
| ︙ | ︙ |
Changes to examples/mmcf.rs.
| ︙ | ︙ | |||
11 12 13 14 15 16 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ | | | < | > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
use bundle;
use env_logger;
use log::info;
use bundle::mcf;
use bundle::{FirstOrderProblem, Solver, SolverParams, StandardTerminator};
use std::env;
fn main() {
env_logger::init();
let mut args = env::args();
let program = args.next().unwrap();
|
| ︙ | ︙ | |||
39 40 41 42 43 44 45 |
mmcf,
SolverParams {
max_bundle_size: 25,
min_weight: 1e-3,
max_weight: 100.0,
..Default::default()
},
| > | > | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
mmcf,
SolverParams {
max_bundle_size: 25,
min_weight: 1e-3,
max_weight: 100.0,
..Default::default()
},
)
.unwrap();
solver.terminator = Box::new(StandardTerminator {
termination_precision: 1e-6,
});
solver.solve().unwrap();
let costs: f64 = (0..solver.problem().num_subproblems())
.map(|i| {
let primals = solver.aggregated_primals(i);
let aggr_primals = solver.problem().aggregate_primals_ref(&primals);
solver.problem().get_primal_costs(i, &aggr_primals)
})
.sum();
info!("Primal costs: {}", costs);
} else {
panic!("Usage: {} FILENAME", program);
}
}
|
Changes to examples/quadratic.rs.
| ︙ | ︙ | |||
13 14 15 16 17 18 19 | * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ use std::error::Error; | < | | < | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
use std::error::Error;
use bundle::{self, dvec};
use env_logger;
use log::debug;
use bundle::{DVector, FirstOrderProblem, Minorant, Real, SimpleEvaluation, Solver, SolverParams};
struct QuadraticProblem {
a: [[Real; 2]; 2],
b: [Real; 2],
c: Real,
|
| ︙ | ︙ | |||
92 93 94 95 96 97 98 |
let mut solver = Solver::new_params(
f,
SolverParams {
min_weight: 1.0,
max_weight: 1.0,
..Default::default()
},
| > | | 90 91 92 93 94 95 96 97 98 99 100 |
let mut solver = Solver::new_params(
f,
SolverParams {
min_weight: 1.0,
max_weight: 1.0,
..Default::default()
},
)
.unwrap();
solver.solve().unwrap();
}
|
Changes to src/hkweighter.rs.
| ︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
//!
//! > Helmberg, C. and Kiwiel, K.C. (2002): A spectral bundle method
//! > with bounds, Math. Programming A 93, 173--194
//!
use crate::Real;
use crate::{BundleState, SolverParams, Step, Weighter};
use std::cmp::{max, min};
use std::f64::NEG_INFINITY;
const FACTOR: Real = 2.0;
/**
| > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
//!
//! > Helmberg, C. and Kiwiel, K.C. (2002): A spectral bundle method
//! > with bounds, Math. Programming A 93, 173--194
//!
use crate::Real;
use crate::{BundleState, SolverParams, Step, Weighter};
use log::debug;
use std::cmp::{max, min};
use std::f64::NEG_INFINITY;
const FACTOR: Real = 2.0;
/**
|
| ︙ | ︙ | |||
79 80 81 82 83 84 85 |
if state.step == Step::Term {
self.eps_weight = 1e30;
self.iter = 0;
return if state.cur_y.len() == 0 || state.sgnorm < state.cur_y.len() as Real * 1e-10 {
1.0
} else {
state.sgnorm.max(1e-4)
| > | > | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
if state.step == Step::Term {
self.eps_weight = 1e30;
self.iter = 0;
return if state.cur_y.len() == 0 || state.sgnorm < state.cur_y.len() as Real * 1e-10 {
1.0
} else {
state.sgnorm.max(1e-4)
}
.max(params.min_weight)
.min(params.max_weight);
}
let cur_nxt = state.cur_val - state.nxt_val;
let cur_mod = state.cur_val - state.nxt_mod;
let w = 2.0 * state.weight * (1.0 - cur_nxt / cur_mod);
debug!(" cur_nxt={} cur_mod={} w={}", cur_nxt, cur_mod, w);
if state.step == Step::Null {
let sgnorm = state.sgnorm;
let lin_err = state.cur_val - state.new_cutval;
self.eps_weight = self.eps_weight.min(sgnorm + cur_mod - sgnorm * sgnorm / state.weight);
let new_weight = if self.iter < -3 && lin_err > self.eps_weight.max(FACTOR * cur_mod) {
w
} else {
state.weight
}
.min(FACTOR * state.weight)
.min(params.max_weight);
if new_weight > state.weight {
self.iter = -1
} else {
self.iter = min(self.iter - 1, -1);
}
|
| ︙ | ︙ | |||
120 121 122 123 124 125 126 |
self.model_max = self.model_max.max(state.nxt_mod);
let new_weight = if self.iter > 0 && cur_nxt > self.m_r * cur_mod {
w
} else if self.iter > 3 || state.nxt_val < self.model_max {
state.weight / 2.0
} else {
state.weight
| > | | 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
self.model_max = self.model_max.max(state.nxt_mod);
let new_weight = if self.iter > 0 && cur_nxt > self.m_r * cur_mod {
w
} else if self.iter > 3 || state.nxt_val < self.model_max {
state.weight / 2.0
} else {
state.weight
}
.max(state.weight / FACTOR)
.max(params.min_weight);
self.eps_weight = self.eps_weight.max(2.0 * cur_mod);
if new_weight < state.weight {
self.iter = 1;
self.model_max = NEG_INFINITY;
} else {
self.iter = max(self.iter + 1, 1);
|
| ︙ | ︙ |
Changes to src/lib.rs.
| ︙ | ︙ | |||
12 13 14 15 16 17 18 | // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/> // //! Proximal bundle method implementation. | < < < < < < < < < < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>
//
//! Proximal bundle method implementation.
/// Type used for real numbers throughout the library.
pub type Real = f64;
#[macro_export]
macro_rules! dvec {
( $ elem : expr ; $ n : expr ) => { DVector(vec![$elem; $n]) };
( $ ( $ x : expr ) , * ) => { DVector(vec![$($x),*]) };
( $ ( $ x : expr , ) * ) => { DVector(vec![$($x,)*]) };
}
pub mod vector;
pub use crate::vector::{DVector, Vector};
pub mod minorant;
pub use crate::minorant::Minorant;
pub mod firstorderproblem;
|
| ︙ | ︙ |
Changes to src/master/boxed.rs.
| ︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
//
use crate::master::MasterProblem;
use crate::master::UnconstrainedMasterProblem;
use crate::{DVector, Minorant, Real};
use super::Result;
use itertools::multizip;
use std::error::Error;
use std::f64::{EPSILON, INFINITY, NEG_INFINITY};
use std::result;
/**
* Turn unconstrained master problem into box-constrained one.
*
| > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
//
use crate::master::MasterProblem;
use crate::master::UnconstrainedMasterProblem;
use crate::{DVector, Minorant, Real};
use super::Result;
use itertools::multizip;
use log::debug;
use std::error::Error;
use std::f64::{EPSILON, INFINITY, NEG_INFINITY};
use std::result;
/**
* Turn unconstrained master problem into box-constrained one.
*
|
| ︙ | ︙ | |||
157 158 159 160 161 162 163 |
0.0
}
} else if ub < INFINITY {
ub * eta
} else {
0.0
}
| > | | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
0.0
}
} else if ub < INFINITY {
ub * eta
} else {
0.0
}
})
.sum()
}
/**
* Return $\\|G \alpha - \eta\\|_2\^2$.
*
* This is the norm-square of the dual optimal solution including
* the current box-multipliers $\eta$.
|
| ︙ | ︙ |
Changes to src/master/cpx.rs.
| ︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 |
//! Master problem implementation using CPLEX.
#![allow(unused_unsafe)]
use crate::master::{Error as MasterProblemError, UnconstrainedMasterProblem};
use crate::{DVector, Minorant, Real};
use cplex_sys as cpx;
| > > > > > < | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
//! Master problem implementation using CPLEX.
#![allow(unused_unsafe)]
use crate::master::{Error as MasterProblemError, UnconstrainedMasterProblem};
use crate::{DVector, Minorant, Real};
use super::Result;
use c_str_macro::c_str;
use cplex_sys as cpx;
use cplex_sys::trycpx;
use log::debug;
use std;
use std::error::Error;
use std::f64::{self, NEG_INFINITY};
use std::os::raw::{c_char, c_int};
use std::ptr;
use std::result;
|
| ︙ | ︙ |
Changes to src/master/minimal.rs.
| ︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// along with this program. If not, see <http://www.gnu.org/licenses/>
//
use crate::master::{Error as MasterProblemError, UnconstrainedMasterProblem};
use crate::{DVector, Minorant, Real};
use super::Result;
use std::error::Error;
use std::f64::NEG_INFINITY;
use std::fmt;
use std::result;
/// Minimal master problem error.
#[derive(Debug)]
| > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// along with this program. If not, see <http://www.gnu.org/licenses/>
//
use crate::master::{Error as MasterProblemError, UnconstrainedMasterProblem};
use crate::{DVector, Minorant, Real};
use super::Result;
use log::debug;
use std::error::Error;
use std::f64::NEG_INFINITY;
use std::fmt;
use std::result;
/// Minimal master problem error.
#[derive(Debug)]
|
| ︙ | ︙ |
Changes to src/mcf/problem.rs.
| ︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>
//
use crate::mcf;
use crate::{DVector, FirstOrderProblem, Minorant, Real, SimpleEvaluation};
use std::error::Error;
use std::f64::INFINITY;
use std::fmt;
use std::fs::File;
use std::io::Read;
use std::result;
| > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>
//
use crate::mcf;
use crate::{DVector, FirstOrderProblem, Minorant, Real, SimpleEvaluation};
use log::debug;
use std::error::Error;
use std::f64::INFINITY;
use std::fmt;
use std::fs::File;
use std::io::Read;
use std::result;
|
| ︙ | ︙ |
Changes to src/mcf/solver.rs.
| ︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// along with this program. If not, see <http://www.gnu.org/licenses/>
//
#![allow(unused_unsafe)]
use crate::{DVector, Real};
use cplex_sys as cpx;
use std;
use std::error::Error;
use std::ffi::CString;
use std::ptr;
use std::result;
| > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// along with this program. If not, see <http://www.gnu.org/licenses/>
//
#![allow(unused_unsafe)]
use crate::{DVector, Real};
use c_str_macro::c_str;
use cplex_sys as cpx;
use cplex_sys::trycpx;
use std;
use std::error::Error;
use std::ffi::CString;
use std::ptr;
use std::result;
|
| ︙ | ︙ | |||
73 74 75 76 77 78 79 |
if status != 0 {
let msg = CString::new(vec![0; cpx::MESSAGE_BUF_SIZE]).unwrap().into_raw();
cpx::geterrorstring(cpx::env(), status, msg);
cpx::NETfreeprob(cpx::env(), &mut net);
return Err(cpx::CplexError {
code: status,
msg: CString::from_raw(msg).to_string_lossy().into_owned(),
| > | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
if status != 0 {
let msg = CString::new(vec![0; cpx::MESSAGE_BUF_SIZE]).unwrap().into_raw();
cpx::geterrorstring(cpx::env(), status, msg);
cpx::NETfreeprob(cpx::env(), &mut net);
return Err(cpx::CplexError {
code: status,
msg: CString::from_raw(msg).to_string_lossy().into_owned(),
}
.into());
}
}
Ok(Solver { net })
}
pub fn num_nodes(&self) -> usize {
|
| ︙ | ︙ |
Changes to src/solver.rs.
| ︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
use crate::{DVector, Real};
use crate::{Evaluation, FirstOrderProblem, HKWeighter, Update};
use crate::master::{BoxedMasterProblem, Error as MasterProblemError, MasterProblem, UnconstrainedMasterProblem};
use crate::master::{CplexMaster, MinimalMaster};
use std::error::Error;
use std::f64::{INFINITY, NEG_INFINITY};
use std::fmt;
use std::mem::swap;
use std::result::Result;
use std::time::Instant;
| > > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
use crate::{DVector, Real};
use crate::{Evaluation, FirstOrderProblem, HKWeighter, Update};
use crate::master::{BoxedMasterProblem, Error as MasterProblemError, MasterProblem, UnconstrainedMasterProblem};
use crate::master::{CplexMaster, MinimalMaster};
use log::{debug, info, warn};
use std::error::Error;
use std::f64::{INFINITY, NEG_INFINITY};
use std::fmt;
use std::mem::swap;
use std::result::Result;
use std::time::Instant;
|
| ︙ | ︙ | |||
690 691 692 693 694 695 696 |
&newvars.iter().map(|v| (v.0, v.1, v.2)).collect::<Vec<_>>(),
&mut |fidx, minidx, vars| {
problem
.extend_subgradient(minorants[fidx][minidx].primal.as_ref().unwrap(), vars)
.map(DVector)
.map_err(|e| e.into())
},
| > | | 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 |
&newvars.iter().map(|v| (v.0, v.1, v.2)).collect::<Vec<_>>(),
&mut |fidx, minidx, vars| {
problem
.extend_subgradient(minorants[fidx][minidx].primal.as_ref().unwrap(), vars)
.map(DVector)
.map_err(|e| e.into())
},
)
.map_err(SolverError::Master)?;
// modify moved variables
for (index, val) in newvars.iter().filter_map(|v| v.0.map(|i| (i, v.3))) {
self.cur_y[index] = val;
self.nxt_y[index] = val;
self.nxt_d[index] = 0.0;
}
// add new variables
|
| ︙ | ︙ |