//! This module writes and reads roots and weights of gauss-quad into files, using a dedicated file format. //! The format works as follows: One u64 is written, indicating the n of the roots and weights that follow //! (thereby hinting at the number of floats that are following before the next u64, which is 2*n). This is repeated for //! arbitrary n. #![allow(dead_code)] use std::{ fs::File, io::{self, BufReader, BufWriter, Read, Seek, SeekFrom, Write}, }; use gauss_quad::GaussLegendre; /// Writes roots and weights of gauss-quad into a file at `filepath`. params contains roots and weights for multiple n. pub fn serialize(filepath: &str, params: Vec<(Vec, Vec)>) -> io::Result<()> { let file = File::create(filepath)?; let mut file = BufWriter::new(file); for (roots, weights) in params.iter() { file.write_all(&u64::try_from(roots.len()).unwrap().to_le_bytes())?; for root in roots { file.write_all(&root.to_bits().to_le_bytes())?; } for weight in weights { file.write_all(&weight.to_bits().to_le_bytes())?; } } Ok(()) } pub fn deserialize( reader: &mut R, filter: impl Fn(u64) -> bool, ) -> io::Result, Vec)>> { let mut buf = [0u8; 8]; let mut values = Vec::new(); 'outer: loop { let res = reader.read(&mut buf)?; if res < 8 { break; } let n = u64::from_le_bytes(buf); // skips stored floats for n that should not be stored if !filter(n) { reader .seek(SeekFrom::Current(i64::try_from(2 * n * 8).unwrap())) .unwrap(); continue; } // Stores roots and weights into values Vec let mut roots = Vec::new(); for _ in 0..n { let res = reader.read(&mut buf)?; if res < 8 { break 'outer; } roots.push(f64::from_bits(u64::from_le_bytes(buf))); } let mut weights = Vec::new(); for _ in 0..n { let res = reader.read(&mut buf)?; if res < 8 { break 'outer; } weights.push(f64::from_bits(u64::from_le_bytes(buf))); } values.push((roots, weights)); } Ok(values) } pub fn fill_with_gauss_quad(n_values: Vec) -> std::io::Result<()> { let mut params = Vec::new(); for i in n_values { let gq = GaussLegendre::init(usize::try_from(i).unwrap()); params.push((gq.nodes, gq.weights)); } serialize("./gauss_quad_lut.morello", params).unwrap(); let file = File::open("./gauss_quad_lut.morello")?; let mut file = BufReader::new(file); let res = deserialize(&mut file, |_| true); println!("{:?}", res); Ok(()) }