|      3 // Live with it. Embrace it. | 
     3 // Live with it. Embrace it. | 
|      4 #![allow(uncommon_codepoints)] | 
     4 #![allow(uncommon_codepoints)] | 
|      5 #![allow(mixed_script_confusables)] | 
     5 #![allow(mixed_script_confusables)] | 
|      6 #![allow(confusable_idents)] | 
     6 #![allow(confusable_idents)] | 
|      7  | 
     7  | 
|         | 
     8 use serde::Serialize; | 
|      8 use dist::DistToSquaredDiv2; | 
     9 use dist::DistToSquaredDiv2; | 
|      9 use fb::forward_backward; | 
    10 use fb::{forward_backward, IterInfo}; | 
|     10 use manifold::EmbeddedManifoldPoint; | 
    11 use manifold::EmbeddedManifoldPoint; | 
|         | 
    12 use alg_tools::logger::Logger; | 
|         | 
    13 use alg_tools::tabledump::TableDump; | 
|         | 
    14 use alg_tools::error::DynError; | 
|     11 use cube::*; | 
    15 use cube::*; | 
|     12 use image::{ | 
    16 use image::{ | 
|     13     ImageFormat, | 
    17     ImageFormat, | 
|     14     ImageBuffer, | 
    18     ImageBuffer, | 
|     15     Rgb | 
    19     Rgb | 
|     20 mod cube; | 
    24 mod cube; | 
|     21 mod dist; | 
    25 mod dist; | 
|     22 mod zero; | 
    26 mod zero; | 
|     23  | 
    27  | 
|     24 fn main() { | 
    28 fn main() { | 
|     25     simple_test() | 
    29     simple_cube_test().unwrap() | 
|     26 } | 
    30 } | 
|     27  | 
    31  | 
|     28 fn simple_test() { | 
    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 { | 
|     29     use alg_tools::loc::Loc; | 
    47     use alg_tools::loc::Loc; | 
|     30     use Face::*; | 
    48     use Face::*; | 
|     31     use zero::ZeroFn; | 
    49     use zero::ZeroFn; | 
|     32     use alg_tools::mapping::{Sum, Apply}; | 
    50     use alg_tools::mapping::{Sum, Apply}; | 
|     33     use alg_tools::iterate::{AlgIteratorOptions, Verbose}; | 
    51     use alg_tools::iterate::{AlgIteratorOptions, AlgIteratorFactory, Verbose}; | 
|     34      | 
    52      | 
|     35     let points = [ | 
    53     let points = [ | 
|     36         //OnCube::new(F1, Loc([0.5, 0.5])), | 
    54         //OnCube::new(F1, Loc([0.5, 0.5])), | 
|     37         //OnCube::new(F2, Loc([0.5, 0.5])), | 
    55         //OnCube::new(F2, Loc([0.5, 0.5])), | 
|     38         //OnCube::new(F4, Loc([0.1, 0.1])), | 
    56         //OnCube::new(F4, Loc([0.1, 0.1])), | 
|     45     // OnCube::new(F3, Loc([0.5, 0.5])); goes to opposite side | 
    63     // OnCube::new(F3, Loc([0.5, 0.5])); goes to opposite side | 
|     46     let x = OnCube::new(F3, Loc([0.5, 0.4])); | 
    64     let x = OnCube::new(F3, Loc([0.5, 0.4])); | 
|     47     let f = Sum::new(points.into_iter().map(DistToSquaredDiv2)); | 
    65     let f = Sum::new(points.into_iter().map(DistToSquaredDiv2)); | 
|     48     let g = ZeroFn::new(); | 
    66     let g = ZeroFn::new(); | 
|     49     let τ = 0.1; | 
    67     let τ = 0.1; | 
|         | 
    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     }; | 
|     50     let iter = AlgIteratorOptions{ | 
    75     let iter = AlgIteratorOptions{ | 
|     51         max_iter : 100, | 
    76         max_iter : 100, | 
|     52         verbose_iter : Verbose::Every(1), | 
    77         verbose_iter : Verbose::Every(1), | 
|     53         .. Default::default() | 
    78         .. Default::default() | 
|     54     }; | 
    79     }.mapped(logmap) | 
|         | 
    80      .into_log(&mut logger); | 
|     55  | 
    81  | 
|     56     let x̂ = forward_backward(&f, &g, x, τ, iter); | 
    82     let x̂ = forward_backward(&f, &g, x, τ, iter); | 
|     57     println!("result = {}\n{:?}", x̂.embedded_coords(), &x̂); | 
    83     println!("result = {}\n{:?}", x̂.embedded_coords(), &x̂); | 
|     58  | 
    84  | 
|         | 
    85     std::fs::create_dir_all(PREFIX)?; | 
|         | 
    86  | 
|         | 
    87     logger.write_csv(format!("{PREFIX}/log.txt"))?; | 
|         | 
    88  | 
|     59     for face in Face::all() { | 
    89     for face in Face::all() { | 
|     60         write_face(format!("{face}"), face, 128, |x| f.apply(x) + g.apply(x)) | 
    90         write_face(format!("{PREFIX}/{face}"), face, 128, |x| f.apply(x) + g.apply(x))?; | 
|     61     } | 
    91     } | 
|         | 
    92  | 
|         | 
    93     Ok(()) | 
|     62 } | 
    94 } | 
|     63  | 
    95  | 
|     64 fn write_face(filename : String, face : Face, n : usize, mut f : impl FnMut(&OnCube) -> f64) { | 
    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 { | 
|     65     use alg_tools::lingrid::LinSpace; | 
    99     use alg_tools::lingrid::LinSpace; | 
|     66     use alg_tools::loc::Loc; | 
   100     use alg_tools::loc::Loc; | 
|     67     use alg_tools::types::*; | 
   101     use alg_tools::types::*; | 
|     68  | 
   102  | 
|     69     let mut img = ImageBuffer::new(n as u32, n as u32); | 
   103     let mut img = ImageBuffer::new(n as u32, n as u32); |