molpack/constraints/
container.rs1use crate::context::PackContext;
4use crate::objective::{compute_f, compute_fg, compute_g};
5use molrs::types::F;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum EvalMode {
10 FOnly,
12 GradientOnly,
14 FAndGradient,
16 RestMol,
18}
19
20#[derive(Debug, Clone, Copy, Default)]
22pub struct EvalOutput {
23 pub f_total: F,
24 pub fdist_max: F,
25 pub frest_max: F,
26}
27
28#[derive(Debug, Clone, Copy, Default)]
32pub struct Constraints;
33
34impl Constraints {
35 #[allow(clippy::needless_pass_by_value)]
36 pub fn evaluate(
37 self,
38 x: &[F],
39 ctx: &mut PackContext,
40 mode: EvalMode,
41 gradient: Option<&mut [F]>,
42 ) -> EvalOutput {
43 let mut f_total = 0.0;
44
45 match mode {
46 EvalMode::FOnly => {
47 f_total = compute_f(x, ctx);
48 }
49 EvalMode::GradientOnly => {
50 if let Some(g) = gradient {
51 compute_g(x, ctx, g);
52 } else {
53 debug_assert!(false, "GradientOnly mode requires gradient buffer");
54 }
55 }
56 EvalMode::FAndGradient | EvalMode::RestMol => {
57 if let Some(g) = gradient {
58 f_total = compute_fg(x, ctx, g);
59 } else {
60 debug_assert!(false, "FAndGradient/RestMol mode requires gradient buffer");
61 }
62 }
63 }
64
65 EvalOutput {
66 f_total,
67 fdist_max: ctx.fdist,
68 frest_max: ctx.frest,
69 }
70 }
71
72 #[inline]
73 pub fn violation(self, x: &[F], ctx: &mut PackContext) -> EvalOutput {
74 self.evaluate(x, ctx, EvalMode::FOnly, None)
75 }
76}