RsBundle  Artifact [84f3034757]

Artifact 84f3034757d72de77dfcc31cbed6657376984e75:

  • File examples/quadratic.rs — part of check-in [2d05075c29] at 2019-07-17 19:21:47 on branch async — Add `MasterProblem::Err` type variable (user: fifr size: 2637)

/*
 * 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
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * 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 std::error::Error;

use bundle::{self, dvec};
use env_logger;
use log::debug;

use bundle::{DVector, DefaultSolver, FirstOrderProblem, Minorant, Real, SimpleEvaluation, SolverParams};

struct QuadraticProblem {
    a: [[Real; 2]; 2],
    b: [Real; 2],
    c: Real,
}

impl QuadraticProblem {
    fn new() -> QuadraticProblem {
        QuadraticProblem {
            a: [[5.0, 1.0], [1.0, 4.0]],
            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
    }

    #[allow(unused_variables)]
    fn evaluate(
        &mut self,
        fidx: usize,
        x: &[Real],
        nullstep_bnd: Real,
        relprec: Real,
    ) -> Result<Self::EvalResult, Self::Err> {
        assert_eq!(fidx, 0);
        let mut objective = self.c;
        let mut g = dvec![0.0; 2];

        for i in 0..2 {
            g[i] += (0..2).map(|j| self.a[i][j] * x[j]).sum::<Real>();
            objective += x[i] * (g[i] + self.b[i]);
            g[i] = 2.0 * g[i] + self.b[i];
        }

        debug!("Evaluation at {:?}", x);
        debug!("  objective={}", objective);
        debug!("  subgradient={}", g);

        Ok(SimpleEvaluation {
            objective: objective,
            minorants: vec![(
                Minorant {
                    constant: objective,
                    linear: g,
                },
                (),
            )],
        })
    }
}

fn main() {
    env_logger::init();

    let f = QuadraticProblem::new();
    let mut solver = DefaultSolver::new_params(
        f,
        SolverParams {
            min_weight: 1.0,
            max_weight: 1.0,
            ..Default::default()
        },
    )
    .unwrap();
    solver.solve().unwrap();
}