Skip to content

Commit

Permalink
Impl vec_fmt_scientific
Browse files Browse the repository at this point in the history
  • Loading branch information
cpmech committed Jun 26, 2024
1 parent c9af9b1 commit 6252cec
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 24 deletions.
29 changes: 16 additions & 13 deletions russell_lab/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -500,13 +500,14 @@ roots =
│ 0.5162732673126048 │
└ ┘
f @ roots =
1.84e-8
-1.51e-8
-2.40e-8
9.53e-9
-1.16e-8
-5.80e-9
┌ ┐
│ 1.84E-08 │
│ -1.51E-08 │
│ -2.40E-08 │
│ 9.53E-09 │
│ -1.16E-08 │
│ -5.80E-09 │
└ ┘
refined roots =
┌ ┐
│ 0.04109147155278252 │
Expand All @@ -517,12 +518,14 @@ refined roots =
│ 0.5162732665558162 │
└ ┘
f @ refined roots =
6.66e-16
-2.22e-16
-2.22e-16
1.33e-15
4.44e-16
-2.22e-16
┌ ┐
│ 6.66E-16 │
│ -2.22E-16 │
│ -2.22E-16 │
│ 1.33E-15 │
│ 4.44E-16 │
│ -2.22E-16 │
└ ┘
```

The function and the roots are illustrated in the figure below.
Expand Down
13 changes: 2 additions & 11 deletions russell_lab/examples/algo_multi_root_solver_cheby.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use plotpy::{Curve, Legend, Plot};
use russell_lab::math::PI;
use russell_lab::*;
use std::fmt::Write;

fn main() -> Result<(), StrError> {
// function
Expand All @@ -22,14 +21,14 @@ fn main() -> Result<(), StrError> {
let roots = Vector::from(&solver.chebyshev(&interp)?);
let f_at_roots = roots.get_mapped(|x| f(x, args).unwrap());
println!("roots =\n{}", roots);
println!("f @ roots =\n{}", print_vec_exp(&f_at_roots));
println!("f @ roots =\n{}", vec_fmt_scientific(&f_at_roots, 2));

// polish the roots
let mut roots_refined = roots.clone();
solver.refine(roots_refined.as_mut_data(), xa, xb, args, f)?;
let f_at_roots_refined = roots_refined.get_mapped(|x| f(x, args).unwrap());
println!("refined roots =\n{}", roots_refined);
println!("f @ refined roots =\n{}", print_vec_exp(&f_at_roots_refined));
println!("f @ refined roots =\n{}", vec_fmt_scientific(&f_at_roots_refined, 2));

// plot the results
let nstation = 301;
Expand Down Expand Up @@ -81,11 +80,3 @@ fn main() -> Result<(), StrError> {
.unwrap();
Ok(())
}

fn print_vec_exp(v: &Vector) -> String {
let mut buf = String::new();
for x in v {
writeln!(&mut buf, "{:>9.2e}", x).unwrap();
}
buf
}
2 changes: 2 additions & 0 deletions russell_lab/src/vector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod vec_add;
mod vec_all_finite;
mod vec_approx_eq;
mod vec_copy;
mod vec_fmt_scientific;
mod vec_inner;
mod vec_max_abs_diff;
mod vec_max_scaled;
Expand All @@ -35,6 +36,7 @@ pub use crate::vector::vec_add::*;
pub use crate::vector::vec_all_finite::*;
pub use crate::vector::vec_approx_eq::*;
pub use crate::vector::vec_copy::*;
pub use crate::vector::vec_fmt_scientific::*;
pub use crate::vector::vec_inner::*;
pub use crate::vector::vec_max_abs_diff::*;
pub use crate::vector::vec_max_scaled::*;
Expand Down
70 changes: 70 additions & 0 deletions russell_lab/src/vector/vec_fmt_scientific.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use super::Vector;
use crate::format_scientific;
use std::cmp;
use std::fmt::Write;

pub fn vec_fmt_scientific(u: &Vector, precision: usize) -> String {
let mut result = String::new();
let f = &mut result;
// handle empty vector
if u.dim() == 0 {
write!(f, "[]").unwrap();
return result;
}
// find largest width
let mut width = 0;
let mut buf = String::new();
for i in 0..u.dim() {
write!(&mut buf, "{:.1$e}", u[i], precision).unwrap();
let _ = buf.split_off(buf.find('e').unwrap());
width = cmp::max(buf.chars().count(), width);
buf.clear();
}
width += 4;
// draw vector
width += 1;
write!(f, "┌{:1$}┐\n", " ", width + 1).unwrap();
for i in 0..u.dim() {
if i > 0 {
write!(f, " │\n").unwrap();
}
write!(f, "│").unwrap();
write!(f, "{}", format_scientific(u[i], width, precision)).unwrap();
}
write!(f, " │\n").unwrap();
write!(f, "└{:1$}┘", " ", width + 1).unwrap();
result
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#[cfg(test)]
mod tests {
use super::vec_fmt_scientific;
use crate::Vector;

#[test]
fn vec_fmt_scientific_works() {
let u = Vector::from(&[1.012444, 200.034123, 1e-8]);
println!("{}", vec_fmt_scientific(&u, 3));
assert_eq!(
vec_fmt_scientific(&u, 3),
"┌ ┐\n\
│ 1.012E+00 │\n\
│ 2.000E+02 │\n\
│ 1.000E-08 │\n\
└ ┘"
);

let u = Vector::from(&[1.012444, 200.034123, 1e+8]);
println!("{}", vec_fmt_scientific(&u, 4));
assert_eq!(
vec_fmt_scientific(&u, 4),
"┌ ┐\n\
│ 1.0124E+00 │\n\
│ 2.0003E+02 │\n\
│ 1.0000E+08 │\n\
└ ┘"
);
}
}

0 comments on commit 6252cec

Please sign in to comment.