pounce_algorithm/output/
orig.rs1use crate::ipopt_cq::IpoptCqHandle;
8use crate::ipopt_data::IpoptDataHandle;
9use crate::output::r#trait::IterationOutput;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum PrintInfoString {
13 Yes,
14 No,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum InfPrTag {
19 Internal,
20 Original,
21}
22
23pub struct OrigIterationOutput {
24 pub print_info_string: PrintInfoString,
25 pub inf_pr_output: InfPrTag,
26 pub print_frequency_iter: i32,
27 pub print_frequency_time: f64,
28 last_header_iter: i32,
31}
32
33impl Default for OrigIterationOutput {
34 fn default() -> Self {
35 Self {
36 print_info_string: PrintInfoString::No,
37 inf_pr_output: InfPrTag::Original,
38 print_frequency_iter: 1,
39 print_frequency_time: 0.0,
40 last_header_iter: -1,
41 }
42 }
43}
44
45impl OrigIterationOutput {
46 pub fn new() -> Self {
47 Self::default()
48 }
49
50 pub const HEADER: &'static str =
53 "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n";
54}
55
56impl IterationOutput for OrigIterationOutput {
57 fn write_output(&mut self) {
58 self.last_header_iter = 0;
61 }
62
63 fn format_row(&mut self, data: &IpoptDataHandle, cq: &IpoptCqHandle) -> String {
67 let d = data.borrow();
68 let c = cq.borrow();
69
70 let iter = d.iter_count;
71 let unscaled_f = c.unscaled_curr_f();
72 let inf_pr = match self.inf_pr_output {
73 InfPrTag::Internal => c.curr_primal_infeasibility_max(),
74 InfPrTag::Original => c.curr_primal_infeasibility_max(),
78 };
79 let inf_du = c.curr_dual_infeasibility_max();
80 let mu = d.curr_mu;
81 let lg_mu = mu.log10();
82
83 let dnrm = match &d.delta {
85 Some(delta) => delta.x.amax().max(delta.s.amax()),
86 None => 0.0,
87 };
88
89 let regu_x = d.info_regu_x;
90 let regu_str: String = if regu_x == 0.0 {
91 " - ".to_string()
92 } else {
93 format_field_5_1(regu_x.log10())
94 };
95
96 let alpha_dual = d.info_alpha_dual;
97 let alpha_primal = d.info_alpha_primal;
98 let alpha_char = d.info_alpha_primal_char;
99 let ls_count = d.info_ls_count;
100
101 let mut row = format!(
102 "{:>4} {:14.7e} {:7.2e} {:7.2e} {:5.1} {:7.2e} {:>5} {:7.2e} {:7.2e}{}{:>3}",
103 iter,
104 unscaled_f,
105 inf_pr,
106 inf_du,
107 lg_mu,
108 dnrm,
109 regu_str,
110 alpha_dual,
111 alpha_primal,
112 alpha_char,
113 ls_count,
114 );
115 if self.print_info_string == PrintInfoString::Yes && !d.info_string.is_empty() {
122 row.push(' ');
123 row.push_str(&d.info_string);
124 }
125 row
126 }
127}
128
129fn format_field_5_1(x: f64) -> String {
133 format!("{:5.1}", x)
134}
135
136#[cfg(test)]
137mod tests {
138 use super::*;
139
140 #[test]
141 fn header_matches_upstream_literal() {
142 assert_eq!(
143 OrigIterationOutput::HEADER,
144 "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n"
145 );
146 }
147
148 #[test]
149 fn regu_field_dashes_when_zero() {
150 assert_eq!(format_field_5_1(-1.0), " -1.0");
152 }
153}