RsBundle  Check-in [a5c90ab126]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Implement `Update::ModifyPrimals`
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | modifyprimals
Files: files | file ages | folders
SHA1: a5c90ab1267b1f408ec6c487fe948f3d47a57872
User & Date: fifr 2018-08-30 11:07:51.573
Context
2018-12-12
15:41
Merge trunk check-in: e1f5bd7920 user: fifr tags: modifyprimals
2018-08-30
11:07
Implement `Update::ModifyPrimals` check-in: a5c90ab126 user: fifr tags: modifyprimals
09:04
Add `Update::ModifyPrimal` update information check-in: ee9e94be2a user: fifr tags: modifyprimals
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/firstorderproblem.rs.
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
}

/// Problem update information.
///
/// The solver calls the `update` method of the problem regularly.
/// This method can modify the problem by adding (or removing)
/// variables. The possible updates are encoded in this type.



pub enum Update<P> {
    /// Add a variable with bounds.
    ///
    /// The initial value of the variable will be the feasible value
    /// closest to 0.
    AddVariable { lower: Real, upper: Real },
    /// Add a variable with bounds and initial value.
    AddVariableValue { lower: Real, upper: Real, value: Real },
    /// Change the current value of a variable. The bounds remain
    /// unchanged.
    MoveVariable { index: usize, value: Real },
    /// Update primal variables.
    ModifyPrimal(Box<Fn(&mut P)>),



}

/**
 * Trait for implementing a first-order problem description.
 *
 */
pub trait FirstOrderProblem {







>
>
>
|










|
|
>
>
>







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
94
95
}

/// Problem update information.
///
/// The solver calls the `update` method of the problem regularly.
/// This method can modify the problem by adding (or removing)
/// variables. The possible updates are encoded in this type.
///
/// - `P` is the type of primals
/// - `E` is the error type
pub enum Update<P, E> {
    /// Add a variable with bounds.
    ///
    /// The initial value of the variable will be the feasible value
    /// closest to 0.
    AddVariable { lower: Real, upper: Real },
    /// Add a variable with bounds and initial value.
    AddVariableValue { lower: Real, upper: Real, value: Real },
    /// Change the current value of a variable. The bounds remain
    /// unchanged.
    MoveVariable { index: usize, value: Real },
    /// Update primal variables of a subproblem.
    ModifyPrimals {
        subproblem: usize,
        modify: Box<Fn(&mut P) -> Result<(), E>>,
    },
}

/**
 * Trait for implementing a first-order problem description.
 *
 */
pub trait FirstOrderProblem {
174
175
176
177
178
179
180


181

182
183
184
185
186
187
188
        let mut primals = primals;
        primals.pop().unwrap().1
    }

    /// Return updates of the problem.
    ///
    /// The default implementation returns no updates.


    fn update(&mut self, _state: &UpdateState<Self::Primal>) -> Result<Vec<Update<Self::Primal>>, Self::Err> {

        Ok(vec![])
    }

    /// Return new components for a subgradient.
    ///
    /// The components are typically generated by some primal
    /// information. The corresponding primal is passed as a







>
>
|
>







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
        let mut primals = primals;
        primals.pop().unwrap().1
    }

    /// Return updates of the problem.
    ///
    /// The default implementation returns no updates.
    fn update(
        &mut self,
        _state: &UpdateState<Self::Primal>,
    ) -> Result<Vec<Update<Self::Primal, Self::Err>>, Self::Err> {
        Ok(vec![])
    }

    /// Return new components for a subgradient.
    ///
    /// The components are typically generated by some primal
    /// information. The corresponding primal is passed as a
Changes to src/solver.rs.
46
47
48
49
50
51
52


53
54
55
56
57
58
59
    Parameter(ParameterError),
    /// The lower bound of a variable is larger than the upper bound.
    InvalidBounds { lower: Real, upper: Real },
    /// The value of a variable is outside its bounds.
    ViolatedBounds { lower: Real, upper: Real, value: Real },
    /// The variable index is out of bounds.
    InvalidVariable { index: usize, nvars: usize },


    /// Iteration limit has been reached.
    IterationLimit { limit: usize },
}

impl<E: fmt::Display> fmt::Display for SolverError<E> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        use self::SolverError::*;







>
>







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    Parameter(ParameterError),
    /// The lower bound of a variable is larger than the upper bound.
    InvalidBounds { lower: Real, upper: Real },
    /// The value of a variable is outside its bounds.
    ViolatedBounds { lower: Real, upper: Real, value: Real },
    /// The variable index is out of bounds.
    InvalidVariable { index: usize, nvars: usize },
    /// A subproblem index is out of bounds.
    InvalidSubproblem { subproblem: usize, nsubs: usize },
    /// Iteration limit has been reached.
    IterationLimit { limit: usize },
}

impl<E: fmt::Display> fmt::Display for SolverError<E> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        use self::SolverError::*;
69
70
71
72
73
74
75





76
77
78
79
80
81
82
                fmt,
                "Violated bounds, lower:{}, upper:{}, value:{}",
                lower, upper, value
            ),
            InvalidVariable { index, nvars } => {
                write!(fmt, "Variable index out of bounds, got:{} must be < {}", index, nvars)
            }





            IterationLimit { limit } => write!(fmt, "The iteration limit of {} has been reached.", limit),
        }
    }
}

impl<E: Error> Error for SolverError<E> {
    fn cause(&self) -> Option<&Error> {







>
>
>
>
>







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
                fmt,
                "Violated bounds, lower:{}, upper:{}, value:{}",
                lower, upper, value
            ),
            InvalidVariable { index, nvars } => {
                write!(fmt, "Variable index out of bounds, got:{} must be < {}", index, nvars)
            }
            InvalidSubproblem { subproblem, nsubs } => write!(
                fmt,
                "Subproblem index out of bounds, got:{} must be < {}",
                subproblem, nsubs
            ),
            IterationLimit { limit } => write!(fmt, "The iteration limit of {} has been reached.", limit),
        }
    }
}

impl<E: Error> Error for SolverError<E> {
    fn cause(&self) -> Option<&Error> {
675
676
677
678
679
680
681
682














683
684
685
686
687
688
689
                    }
                    let (lower, upper) = self.bounds[index];
                    if value < lower || value > upper {
                        return Err(SolverError::ViolatedBounds { lower, upper, value });
                    }
                    newvars.push((Some(index), lower - value, upper - value, value));
                }
                Update::ModifyPrimal(_modify) => unimplemented!(),














            }
        }

        if !newvars.is_empty() {
            let problem = &mut self.problem;
            let minorants = &self.minorants;
            self.master







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>







682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
                    }
                    let (lower, upper) = self.bounds[index];
                    if value < lower || value > upper {
                        return Err(SolverError::ViolatedBounds { lower, upper, value });
                    }
                    newvars.push((Some(index), lower - value, upper - value, value));
                }
                Update::ModifyPrimals { subproblem, modify } => {
                    if subproblem >= self.minorants.len() {
                        return Err(SolverError::InvalidSubproblem {
                            subproblem: subproblem,
                            nsubs: self.minorants.len(),
                        });
                    }
                    for m in &mut self.minorants[subproblem] {
                        if let Some(ref mut p) = m.primal {
                            if let Err(err) = modify(p) {
                                return Err(SolverError::Update(err));;
                            }
                        }
                    }
                }
            }
        }

        if !newvars.is_empty() {
            let problem = &mut self.problem;
            let minorants = &self.minorants;
            self.master