use std::fs;
use std::path::Path;
pub fn write_csv(path: &str, headers: &[&str], rows: &[Vec<f64>]) -> std::io::Result<()> {
let mut content = headers.join(",") + "\n";
for row in rows {
let line: Vec<String> = row.iter().map(|v| format!("{:.6e}", v)).collect();
content += &(line.join(",") + "\n");
}
if let Some(parent) = Path::new(path).parent() {
fs::create_dir_all(parent)?;
}
fs::write(path, content)
}
pub fn write_dat(path: &str, data: &[(f64, f64)]) -> std::io::Result<()> {
let content: String = data
.iter()
.map(|(x, y)| format!("{:.6e}\t{:.6e}\n", x, y))
.collect();
if let Some(parent) = Path::new(path).parent() {
fs::create_dir_all(parent)?;
}
fs::write(path, content)
}
pub fn ensure_dir(path: &str) -> std::io::Result<()> {
fs::create_dir_all(path)
}
pub fn format_si(value: f64) -> String {
let prefixes = [
(1e24, "Y"),
(1e21, "Z"),
(1e18, "E"),
(1e15, "P"),
(1e12, "T"),
(1e9, "G"),
(1e6, "M"),
(1e3, "k"),
(1.0, ""),
(1e-3, "m"),
(1e-6, "µ"),
(1e-9, "n"),
(1e-12, "p"),
];
let abs = value.abs();
for (threshold, prefix) in prefixes {
if abs >= threshold {
return format!("{:.3}{}", value / threshold, prefix);
}
}
format!("{:.3e}", value)
}