Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Make all errors Send + Sync |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | async |
| Files: | files | file ages | folders |
| SHA1: |
1e94fdd305a81cbd26bd41aed88e4c16 |
| User & Date: | fifr 2019-07-17 11:23:44.240 |
Context
|
2019-07-17
| ||
| 14:14 | master: add error type parameter for subgradient extension callback check-in: f6352834ce user: fifr tags: async | |
| 11:23 | Make all errors Send + Sync check-in: 1e94fdd305 user: fifr tags: async | |
| 07:40 | examples/cflp: improve error handling check-in: eae47a6415 user: fifr tags: async | |
Changes
Changes to examples/quadratic.rs.
1 | /* | | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2016, 2017, 2018, 2019 Frank Fischer <frank-fischer@shadow-soft.de> * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but |
| ︙ | ︙ | |||
36 37 38 39 40 41 42 |
b: [-12.0, -10.0],
c: 3.0,
}
}
}
impl FirstOrderProblem for QuadraticProblem {
| | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
b: [-12.0, -10.0],
c: 3.0,
}
}
}
impl FirstOrderProblem for QuadraticProblem {
type Err = Box<dyn Error + Send + Sync>;
type Primal = ();
type EvalResult = SimpleEvaluation<()>;
fn num_variables(&self) -> usize {
2
}
|
| ︙ | ︙ |
Changes to src/master/base.rs.
|
| | | 1 2 3 4 5 6 7 8 | // Copyright (c) 2016, 2017, 2019 Frank Fischer <frank-fischer@shadow-soft.de> // // This program is free software: you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but |
| ︙ | ︙ | |||
20 21 22 23 24 25 26 |
use std::fmt;
use std::result;
/// Error type for master problems.
#[derive(Debug)]
pub enum MasterProblemError {
/// Extension of the subgradient failed with some user error.
| | | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
use std::fmt;
use std::result;
/// Error type for master problems.
#[derive(Debug)]
pub enum MasterProblemError {
/// Extension of the subgradient failed with some user error.
SubgradientExtension(Box<dyn Error + Send + Sync>),
/// No minorants available when solving the master problem
NoMinorants,
/// An error in the solver backend occurred.
Solver(Box<dyn Error + Send + Sync>),
/// A custom error (specific to the master problem solver) occurred.
Custom(Box<dyn Error + Send + Sync>),
}
impl fmt::Display for MasterProblemError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
use self::MasterProblemError::*;
match self {
SubgradientExtension(err) => write!(fmt, "Subgradient extension failed: {}", err),
|
| ︙ | ︙ | |||
55 56 57 58 59 60 61 |
}
}
/// Result type of master problems.
pub type Result<T> = result::Result<T, MasterProblemError>;
/// Callback for subgradient extensions.
| | > | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
}
}
/// Result type of master problems.
pub type Result<T> = result::Result<T, MasterProblemError>;
/// Callback for subgradient extensions.
pub type SubgradientExtension<'a, I> =
FnMut(usize, I, &[usize]) -> result::Result<DVector, Box<dyn Error + Send + Sync>> + 'a;
pub trait MasterProblem {
/// Unique index for a minorant.
type MinorantIndex: Copy + Eq;
/// Set the number of subproblems.
fn set_num_subproblems(&mut self, n: usize) -> Result<()>;
|
| ︙ | ︙ |
Changes to src/master/cpx.rs.
| ︙ | ︙ | |||
31 32 33 34 35 36 37 |
use std;
use std::f64::{self, NEG_INFINITY};
use std::os::raw::{c_char, c_int};
use std::ptr;
impl From<cpx::CplexError> for MasterProblemError {
fn from(err: cpx::CplexError) -> MasterProblemError {
| | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
use std;
use std::f64::{self, NEG_INFINITY};
use std::os::raw::{c_char, c_int};
use std::ptr;
impl From<cpx::CplexError> for MasterProblemError {
fn from(err: cpx::CplexError) -> MasterProblemError {
MasterProblemError::Solver(Box::new(err))
}
}
pub struct CplexMaster {
lp: *mut cpx::Lp,
/// True if the QP must be updated.
|
| ︙ | ︙ |
Changes to src/master/minimal.rs.
| ︙ | ︙ | |||
41 42 43 44 45 46 47 |
MaxMinorants => write!(fmt, "The minimal master problem allows at most two minorants"),
}
}
}
impl Error for MinimalMasterError {}
| | | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
MaxMinorants => write!(fmt, "The minimal master problem allows at most two minorants"),
}
}
}
impl Error for MinimalMasterError {}
impl From<MinimalMasterError> for MasterProblemError {
fn from(err: MinimalMasterError) -> MasterProblemError {
MasterProblemError::Custom(Box::new(err))
}
}
/**
* A minimal master problem with only two minorants.
*
* This is the simplest possible master problem for bundle methods. It
|
| ︙ | ︙ |
Changes to src/mcf/problem.rs.
| ︙ | ︙ | |||
15 16 17 18 19 20 21 |
//
use crate::mcf;
use crate::{Aggregatable, DVector, FirstOrderProblem, Minorant, Real, SimpleEvaluation};
use log::debug;
| < | | > > | > > | > > | | | > | > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
//
use crate::mcf;
use crate::{Aggregatable, DVector, FirstOrderProblem, Minorant, Real, SimpleEvaluation};
use log::debug;
use std::f64::INFINITY;
use std::fmt;
use std::fs::File;
use std::io::Read;
use std::result;
/// An error in the mmcf file format.
#[derive(Debug)]
pub enum MMCFReadError {
Format(String),
Solver(mcf::solver::Error),
Io(std::io::Error),
}
impl fmt::Display for MMCFReadError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
use MMCFReadError::*;
match self {
Format(msg) => write!(fmt, "Format error: {}", msg),
Solver(err) => err.fmt(fmt),
Io(err) => err.fmt(fmt),
}
}
}
impl std::error::Error for MMCFReadError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use MMCFReadError::*;
match self {
Solver(err) => Some(err),
Io(err) => Some(err),
_ => None,
}
}
}
impl From<mcf::solver::Error> for MMCFReadError {
fn from(err: mcf::solver::Error) -> MMCFReadError {
MMCFReadError::Solver(err)
}
}
impl From<std::io::Error> for MMCFReadError {
fn from(err: std::io::Error) -> MMCFReadError {
MMCFReadError::Io(err)
}
}
impl From<std::num::ParseIntError> for MMCFReadError {
fn from(err: std::num::ParseIntError) -> MMCFReadError {
MMCFReadError::Format(format!("Parse error: {}", err))
}
}
impl From<std::num::ParseFloatError> for MMCFReadError {
fn from(err: std::num::ParseFloatError) -> MMCFReadError {
MMCFReadError::Format(format!("Parse error: {}", err))
}
}
/// Type of errors of the MMCFProblem.
pub type Error = crate::mcf::solver::Error;
/// Result type of the MMCFProblem.
pub type Result<T> = result::Result<T, Error>;
#[derive(Clone, Copy, Debug)]
struct ArcInfo {
arc: usize,
src: usize,
snk: usize,
}
|
| ︙ | ︙ | |||
64 65 66 67 68 69 70 |
rhs: DVector,
rhsval: Real,
cbase: Vec<DVector>,
c: Vec<DVector>,
}
impl MMCFProblem {
| | | | < > > | | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
rhs: DVector,
rhsval: Real,
cbase: Vec<DVector>,
c: Vec<DVector>,
}
impl MMCFProblem {
pub fn read_mnetgen(basename: &str) -> std::result::Result<MMCFProblem, MMCFReadError> {
let mut buffer = String::new();
{
let mut f = File::open(&format!("{}.nod", basename))?;
f.read_to_string(&mut buffer)?;
}
let fnod = buffer
.split_whitespace()
.map(|x| x.parse::<usize>().unwrap())
.collect::<Vec<_>>();
if fnod.len() != 4 {
return Err(MMCFReadError::Format(format!(
"Expected 4 numbers in {}.nod, but got {}",
basename,
fnod.len()
)));
}
let ncom = fnod[0];
let nnodes = fnod[1];
let narcs = fnod[2];
let ncaps = fnod[3];
|
| ︙ | ︙ | |||
245 246 247 248 249 250 251 |
}
x
}
}
impl FirstOrderProblem for MMCFProblem {
| | | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
}
x
}
}
impl FirstOrderProblem for MMCFProblem {
type Err = Error;
type Primal = Vec<DVector>;
type EvalResult = SimpleEvaluation<Vec<DVector>>;
fn num_variables(&self) -> usize {
self.lhs.len()
|
| ︙ | ︙ |
Changes to src/mcf/solver.rs.
| ︙ | ︙ | |||
19 20 21 22 23 24 25 |
use crate::{DVector, Real};
use c_str_macro::c_str;
use cplex_sys as cpx;
use cplex_sys::trycpx;
use std;
| < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 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 65 66 67 68 |
use crate::{DVector, Real};
use c_str_macro::c_str;
use cplex_sys as cpx;
use cplex_sys::trycpx;
use std;
use std::ffi::CString;
use std::ptr;
use std::result;
use std::os::raw::{c_char, c_double, c_int};
#[derive(Debug)]
pub enum Error {
Solver(cpx::CplexError),
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use Error::*;
match self {
Solver(err) => Some(err),
}
}
}
impl std::fmt::Display for Error {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
use Error::*;
match self {
Solver(err) => err.fmt(fmt),
}
}
}
impl From<cpx::CplexError> for Error {
fn from(err: cpx::CplexError) -> Error {
Error::Solver(err)
}
}
pub type Result<T> = result::Result<T, Error>;
pub struct Solver {
net: *mut cpx::Net,
}
impl Drop for Solver {
fn drop(&mut self) {
|
| ︙ | ︙ |
Changes to src/solver.rs.
| ︙ | ︙ | |||
30 31 32 33 34 35 36 |
use std::mem::swap;
use std::result::Result;
use std::time::Instant;
/// A solver error.
#[derive(Debug)]
pub enum SolverError<E> {
| | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
use std::mem::swap;
use std::result::Result;
use std::time::Instant;
/// A solver error.
#[derive(Debug)]
pub enum SolverError<E> {
/// An error occurred during oracle evaluation.
Evaluation(E),
/// An error occurred during oracle update.
Update(E),
/// An error has been raised by the master problem.
Master(MasterProblemError),
/// The oracle did not return a minorant.
NoMinorant,
/// The dimension of some data is wrong.
Dimension,
|
| ︙ | ︙ | |||
470 471 472 473 474 475 476 |
/// Accumulated information about the last iteration.
iterinfos: Vec<IterationInfo>,
}
impl<P: FirstOrderProblem> Solver<P>
where
| | | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 |
/// Accumulated information about the last iteration.
iterinfos: Vec<IterationInfo>,
}
impl<P: FirstOrderProblem> Solver<P>
where
P::Err: Into<Box<dyn Error + Send + Sync>>,
{
/**
* Create a new solver for the given problem.
*
* Note that the solver owns the problem, so you cannot use the
* same problem description elsewhere as long as it is assigned to
* the solver. However, it is possible to get a reference to the
|
| ︙ | ︙ |