Tue, 22 Oct 2024 08:27:45 -0500
Save log to a CSV file
| 4 | 1 | |
| 2 | // We use unicode. We would like to use much more of it than Rust allows. | |
| 3 | // Live with it. Embrace it. | |
| 4 | #![allow(uncommon_codepoints)] | |
| 5 | #![allow(mixed_script_confusables)] | |
| 6 | #![allow(confusable_idents)] | |
| 1 | 7 | |
| 12 | 8 | use serde::Serialize; | 
| 7 | 9 | use dist::DistToSquaredDiv2; | 
| 12 | 10 | use fb::{forward_backward, IterInfo}; | 
| 7 | 11 | use manifold::EmbeddedManifoldPoint; | 
| 12 | 12 | use alg_tools::logger::Logger; | 
| 13 | use alg_tools::tabledump::TableDump; | |
| 14 | use alg_tools::error::DynError; | |
| 11 | 15 | use cube::*; | 
| 16 | use image::{ | |
| 17 | ImageFormat, | |
| 18 | ImageBuffer, | |
| 19 | Rgb | |
| 20 | }; | |
| 7 | 21 | |
| 1 | 22 | mod manifold; | 
| 4 | 23 | mod fb; | 
| 1 | 24 | mod cube; | 
| 5 | 25 | mod dist; | 
| 6 
df9628092285
Add a zero function on manifolds
 Tuomo Valkonen <tuomov@iki.fi> parents: 
5diff
changeset | 26 | mod zero; | 
| 1 | 27 | |
| 28 | fn main() { | |
| 12 | 29 | simple_cube_test().unwrap() | 
| 7 | 30 | } | 
| 1 | 31 | |
| 12 | 32 | /// Helper structure for saving the log into a CSV file | 
| 33 | #[derive(Serialize)] | |
| 34 | struct CSVLog { | |
| 35 | iter : usize, | |
| 36 | value : f64, | |
| 37 | face : Face, | |
| 38 | x : f64, | |
| 39 | y : f64, | |
| 40 | z : f64 | |
| 41 | } | |
| 42 | ||
| 43 | static PREFIX : &str = "res"; | |
| 44 | ||
| 45 | /// A simple test on the cube | |
| 46 | fn simple_cube_test() -> DynError { | |
| 7 | 47 | use alg_tools::loc::Loc; | 
| 48 | use Face::*; | |
| 49 | use zero::ZeroFn; | |
| 11 | 50 | use alg_tools::mapping::{Sum, Apply}; | 
| 12 | 51 | use alg_tools::iterate::{AlgIteratorOptions, AlgIteratorFactory, Verbose}; | 
| 7 | 52 | |
| 53 | let points = [ | |
| 9 | 54 | //OnCube::new(F1, Loc([0.5, 0.5])), | 
| 55 | //OnCube::new(F2, Loc([0.5, 0.5])), | |
| 56 | //OnCube::new(F4, Loc([0.1, 0.1])), | |
| 7 | 57 | OnCube::new(F1, Loc([0.5, 0.5])), | 
| 9 | 58 | OnCube::new(F3, Loc([0.5, 0.5])), | 
| 7 | 59 | OnCube::new(F2, Loc([0.5, 0.5])), | 
| 60 | ]; | |
| 61 | ||
| 62 | //let x = points[0].clone(); | |
| 9 | 63 | // OnCube::new(F3, Loc([0.5, 0.5])); goes to opposite side | 
| 64 | let x = OnCube::new(F3, Loc([0.5, 0.4])); | |
| 7 | 65 | let f = Sum::new(points.into_iter().map(DistToSquaredDiv2)); | 
| 66 | let g = ZeroFn::new(); | |
| 67 | let τ = 0.1; | |
| 12 | 68 | |
| 69 | let mut logger = Logger::new(); | |
| 70 | let logmap = |iter, IterInfo { value, point } : IterInfo<OnCube>| { | |
| 71 | let Loc([x,y,z]) = point.embedded_coords(); | |
| 72 | let face = point.face(); | |
| 73 | CSVLog { iter, value, face, x, y, z } | |
| 74 | }; | |
| 7 | 75 | let iter = AlgIteratorOptions{ | 
| 76 | max_iter : 100, | |
| 77 | verbose_iter : Verbose::Every(1), | |
| 78 | .. Default::default() | |
| 12 | 79 | }.mapped(logmap) | 
| 80 | .into_log(&mut logger); | |
| 7 | 81 | |
| 82 | let x̂ = forward_backward(&f, &g, x, τ, iter); | |
| 83 | println!("result = {}\n{:?}", x̂.embedded_coords(), &x̂); | |
| 11 | 84 | |
| 12 | 85 | std::fs::create_dir_all(PREFIX)?; | 
| 86 | ||
| 87 | logger.write_csv(format!("{PREFIX}/log.txt"))?; | |
| 88 | ||
| 11 | 89 | for face in Face::all() { | 
| 12 | 90 | write_face(format!("{PREFIX}/{face}"), face, 128, |x| f.apply(x) + g.apply(x))?; | 
| 11 | 91 | } | 
| 12 | 92 | |
| 93 | Ok(()) | |
| 1 | 94 | } | 
| 11 | 95 | |
| 12 | 96 | /// Writes the values of `f` on `face` of a [`OnCube`] into a PNG file | 
| 97 | /// with resolution `n × n`. | |
| 98 | fn write_face(filename : String, face : Face, n : usize, mut f : impl FnMut(&OnCube) -> f64) -> DynError { | |
| 11 | 99 | use alg_tools::lingrid::LinSpace; | 
| 100 | use alg_tools::loc::Loc; | |
| 101 | use alg_tools::types::*; | |
| 102 | ||
| 103 | let mut img = ImageBuffer::new(n as u32, n as u32); | |
| 104 | let grid = LinSpace { | |
| 105 | start : Loc([0.0, 0.0]), | |
| 106 | end : Loc([1.0, 1.0]), | |
| 107 | count : [n, n] | |
| 108 | }; | |
| 109 | let rawdata : Vec<_> = grid.into_iter() | |
| 110 | .map(|x| f(&OnCube::new(face, x))) | |
| 111 | .collect(); | |
| 112 | let a = rawdata.iter().copied().reduce(f64::max).unwrap(); | |
| 113 | img.pixels_mut() | |
| 114 | .zip(rawdata) | |
| 115 | .for_each(|(p, v)| { | |
| 116 | let t = v/a; | |
| 117 | let rgb = [1.0-t, 1.0-t, 1.0]; | |
| 118 | *p = Rgb(rgb.map(|v| (v*(u8::RANGE_MAX as f64)) as u8)) | |
| 119 | }); | |
| 120 | ||
| 12 | 121 | img.save_with_format(format!("{filename}.png"), ImageFormat::Png)?; | 
| 122 | ||
| 123 | Ok(()) | |
| 11 | 124 | } |