90 lines
2.8 KiB
Rust
90 lines
2.8 KiB
Rust
//! 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<f64>, Vec<f64>)>) -> 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<R: Read + Seek>(
|
|
reader: &mut R,
|
|
filter: impl Fn(u64) -> bool,
|
|
) -> io::Result<Vec<(Vec<f64>, Vec<f64>)>> {
|
|
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<u64>) -> 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(())
|
|
}
|