forked from StudioInfinity/dyna3
Improve naming in realization output structures
This commit is contained in:
parent
477d6a5064
commit
f1865f85a1
7 changed files with 53 additions and 47 deletions
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
use nalgebra::DMatrix;
|
use nalgebra::DMatrix;
|
||||||
|
|
||||||
use dyna3::engine::{Q, DescentHistory, RealizationResult};
|
use dyna3::engine::{Q, DescentHistory, Realization};
|
||||||
|
|
||||||
pub fn title(title: &str) {
|
pub fn title(title: &str) {
|
||||||
println!("─── {title} ───");
|
println!("─── {title} ───");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn realization_diagnostics(realization_result: &RealizationResult) {
|
pub fn realization_diagnostics(realization: &Realization) {
|
||||||
let RealizationResult { result, history } = realization_result;
|
let Realization { result, history } = realization;
|
||||||
println!();
|
println!();
|
||||||
if let Err(ref message) = result {
|
if let Err(ref message) = result {
|
||||||
println!("❌️ {message}");
|
println!("❌️ {message}");
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
#[path = "common/print.rs"]
|
#[path = "common/print.rs"]
|
||||||
mod print;
|
mod print;
|
||||||
|
|
||||||
use dyna3::engine::{Realization, examples::realize_irisawa_hexlet};
|
use dyna3::engine::{ConfigNeighborhood, examples::realize_irisawa_hexlet};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
const SCALED_TOL: f64 = 1.0e-12;
|
const SCALED_TOL: f64 = 1.0e-12;
|
||||||
let realization_result = realize_irisawa_hexlet(SCALED_TOL);
|
let realization = realize_irisawa_hexlet(SCALED_TOL);
|
||||||
print::title("Irisawa hexlet");
|
print::title("Irisawa hexlet");
|
||||||
print::realization_diagnostics(&realization_result);
|
print::realization_diagnostics(&realization);
|
||||||
if let Ok(Realization { config, .. }) = realization_result.result {
|
if let Ok(ConfigNeighborhood { config, .. }) = realization.result {
|
||||||
// print the diameters of the chain spheres
|
// print the diameters of the chain spheres
|
||||||
println!("\nChain diameters:");
|
println!("\nChain diameters:");
|
||||||
println!(" {} sun (given)", 1.0 / config[(3, 3)]);
|
println!(" {} sun (given)", 1.0 / config[(3, 3)]);
|
||||||
|
@ -19,5 +19,5 @@ fn main() {
|
||||||
// print the completed Gram matrix
|
// print the completed Gram matrix
|
||||||
print::gram_matrix(&config);
|
print::gram_matrix(&config);
|
||||||
}
|
}
|
||||||
print::loss_history(&realization_result.history);
|
print::loss_history(&realization.history);
|
||||||
}
|
}
|
|
@ -3,14 +3,14 @@ mod print;
|
||||||
|
|
||||||
use nalgebra::{DMatrix, DVector};
|
use nalgebra::{DMatrix, DVector};
|
||||||
|
|
||||||
use dyna3::engine::{Realization, examples::realize_kaleidocycle};
|
use dyna3::engine::{ConfigNeighborhood, examples::realize_kaleidocycle};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
const SCALED_TOL: f64 = 1.0e-12;
|
const SCALED_TOL: f64 = 1.0e-12;
|
||||||
let realization_result = realize_kaleidocycle(SCALED_TOL);
|
let realization = realize_kaleidocycle(SCALED_TOL);
|
||||||
print::title("Kaleidocycle");
|
print::title("Kaleidocycle");
|
||||||
print::realization_diagnostics(&realization_result);
|
print::realization_diagnostics(&realization);
|
||||||
if let Ok(Realization { config, tangent }) = realization_result.result {
|
if let Ok(ConfigNeighborhood { config, nbhd: tangent }) = realization.result {
|
||||||
// print the completed Gram matrix and the realized configuration
|
// print the completed Gram matrix and the realized configuration
|
||||||
print::gram_matrix(&config);
|
print::gram_matrix(&config);
|
||||||
print::config(&config);
|
print::config(&config);
|
||||||
|
|
|
@ -5,8 +5,8 @@ use dyna3::engine::{
|
||||||
point,
|
point,
|
||||||
realize_gram,
|
realize_gram,
|
||||||
sphere,
|
sphere,
|
||||||
ConstraintProblem,
|
ConfigNeighborhood,
|
||||||
Realization
|
ConstraintProblem
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -20,14 +20,14 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
problem.frozen.push(3, 0, problem.guess[(3, 0)]);
|
problem.frozen.push(3, 0, problem.guess[(3, 0)]);
|
||||||
let realization_result = realize_gram(
|
let realization = realize_gram(
|
||||||
&problem, 1.0e-12, 0.5, 0.9, 1.1, 200, 110
|
&problem, 1.0e-12, 0.5, 0.9, 1.1, 200, 110
|
||||||
);
|
);
|
||||||
print::title("Point on a sphere");
|
print::title("Point on a sphere");
|
||||||
print::realization_diagnostics(&realization_result);
|
print::realization_diagnostics(&realization);
|
||||||
if let Ok(Realization{ config, .. }) = realization_result.result {
|
if let Ok(ConfigNeighborhood{ config, .. }) = realization.result {
|
||||||
print::gram_matrix(&config);
|
print::gram_matrix(&config);
|
||||||
print::config(&config);
|
print::config(&config);
|
||||||
}
|
}
|
||||||
print::loss_history(&realization_result.history);
|
print::loss_history(&realization.history);
|
||||||
}
|
}
|
|
@ -1,7 +1,12 @@
|
||||||
#[path = "common/print.rs"]
|
#[path = "common/print.rs"]
|
||||||
mod print;
|
mod print;
|
||||||
|
|
||||||
use dyna3::engine::{realize_gram, sphere, ConstraintProblem, Realization};
|
use dyna3::engine::{
|
||||||
|
realize_gram,
|
||||||
|
sphere,
|
||||||
|
ConfigNeighborhood,
|
||||||
|
ConstraintProblem
|
||||||
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut problem = ConstraintProblem::from_guess({
|
let mut problem = ConstraintProblem::from_guess({
|
||||||
|
@ -17,13 +22,13 @@ fn main() {
|
||||||
problem.gram.push_sym(j, k, if j == k { 1.0 } else { -1.0 });
|
problem.gram.push_sym(j, k, if j == k { 1.0 } else { -1.0 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let realization_result = realize_gram(
|
let realization = realize_gram(
|
||||||
&problem, 1.0e-12, 0.5, 0.9, 1.1, 200, 110
|
&problem, 1.0e-12, 0.5, 0.9, 1.1, 200, 110
|
||||||
);
|
);
|
||||||
print::title("Three spheres");
|
print::title("Three spheres");
|
||||||
print::realization_diagnostics(&realization_result);
|
print::realization_diagnostics(&realization);
|
||||||
if let Ok(Realization{ config, .. }) = realization_result.result {
|
if let Ok(ConfigNeighborhood{ config, .. }) = realization.result {
|
||||||
print::gram_matrix(&config);
|
print::gram_matrix(&config);
|
||||||
}
|
}
|
||||||
print::loss_history(&realization_result.history);
|
print::loss_history(&realization.history);
|
||||||
}
|
}
|
|
@ -23,11 +23,11 @@ use crate::{
|
||||||
project_sphere_to_normalized,
|
project_sphere_to_normalized,
|
||||||
realize_gram,
|
realize_gram,
|
||||||
sphere,
|
sphere,
|
||||||
|
ConfigNeighborhood,
|
||||||
ConfigSubspace,
|
ConfigSubspace,
|
||||||
ConstraintProblem,
|
ConstraintProblem,
|
||||||
DescentHistory,
|
DescentHistory,
|
||||||
Realization,
|
Realization
|
||||||
RealizationResult
|
|
||||||
},
|
},
|
||||||
outline::OutlineItem,
|
outline::OutlineItem,
|
||||||
specified::SpecifiedValue
|
specified::SpecifiedValue
|
||||||
|
@ -696,7 +696,7 @@ impl Assembly {
|
||||||
console_log!("Old configuration:{:>8.3}", problem.guess);
|
console_log!("Old configuration:{:>8.3}", problem.guess);
|
||||||
|
|
||||||
// look for a configuration with the given Gram matrix
|
// look for a configuration with the given Gram matrix
|
||||||
let RealizationResult { result, history } = realize_gram(
|
let Realization { result, history } = realize_gram(
|
||||||
&problem, 1.0e-12, 0.5, 0.9, 1.1, 200, 110
|
&problem, 1.0e-12, 0.5, 0.9, 1.1, 200, 110
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -714,7 +714,7 @@ impl Assembly {
|
||||||
self.descent_history.set(history);
|
self.descent_history.set(history);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(Realization { config, tangent }) => {
|
Ok(ConfigNeighborhood { config, nbhd: tangent }) => {
|
||||||
/* DEBUG */
|
/* DEBUG */
|
||||||
// report the tangent dimension
|
// report the tangent dimension
|
||||||
console_log!("Tangent dimension: {}", tangent.dim());
|
console_log!("Tangent dimension: {}", tangent.dim());
|
||||||
|
|
|
@ -393,13 +393,14 @@ fn seek_better_config(
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Realization {
|
// a first-order neighborhood of a configuration
|
||||||
|
pub struct ConfigNeighborhood {
|
||||||
pub config: DMatrix<f64>,
|
pub config: DMatrix<f64>,
|
||||||
pub tangent: ConfigSubspace
|
pub nbhd: ConfigSubspace
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RealizationResult {
|
pub struct Realization {
|
||||||
pub result: Result<Realization, String>,
|
pub result: Result<ConfigNeighborhood, String>,
|
||||||
pub history: DescentHistory
|
pub history: DescentHistory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +416,7 @@ pub fn realize_gram(
|
||||||
reg_scale: f64,
|
reg_scale: f64,
|
||||||
max_descent_steps: i32,
|
max_descent_steps: i32,
|
||||||
max_backoff_steps: i32
|
max_backoff_steps: i32
|
||||||
) -> RealizationResult {
|
) -> Realization {
|
||||||
// destructure the problem data
|
// destructure the problem data
|
||||||
let ConstraintProblem {
|
let ConstraintProblem {
|
||||||
gram, guess, frozen
|
gram, guess, frozen
|
||||||
|
@ -501,7 +502,7 @@ pub fn realize_gram(
|
||||||
*/
|
*/
|
||||||
let hess_cholesky = match hess.clone().cholesky() {
|
let hess_cholesky = match hess.clone().cholesky() {
|
||||||
Some(cholesky) => cholesky,
|
Some(cholesky) => cholesky,
|
||||||
None => return RealizationResult {
|
None => return Realization {
|
||||||
result: Err("Cholesky decomposition failed".to_string()),
|
result: Err("Cholesky decomposition failed".to_string()),
|
||||||
history
|
history
|
||||||
}
|
}
|
||||||
|
@ -518,7 +519,7 @@ pub fn realize_gram(
|
||||||
state = better_state;
|
state = better_state;
|
||||||
history.backoff_steps.push(backoff_steps);
|
history.backoff_steps.push(backoff_steps);
|
||||||
} else {
|
} else {
|
||||||
return RealizationResult {
|
return Realization {
|
||||||
result: Err("Line search failed".to_string()),
|
result: Err("Line search failed".to_string()),
|
||||||
history
|
history
|
||||||
}
|
}
|
||||||
|
@ -539,11 +540,11 @@ pub fn realize_gram(
|
||||||
// find the kernel of the Hessian. give it the uniform inner product
|
// find the kernel of the Hessian. give it the uniform inner product
|
||||||
let tangent = ConfigSubspace::symmetric_kernel(hess, unif_to_std, assembly_dim);
|
let tangent = ConfigSubspace::symmetric_kernel(hess, unif_to_std, assembly_dim);
|
||||||
|
|
||||||
Ok(Realization { config: state.config, tangent })
|
Ok(ConfigNeighborhood { config: state.config, nbhd: tangent })
|
||||||
} else {
|
} else {
|
||||||
Err("Failed to reach target accuracy".to_string())
|
Err("Failed to reach target accuracy".to_string())
|
||||||
};
|
};
|
||||||
RealizationResult{ result, history }
|
Realization { result, history }
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- tests ---
|
// --- tests ---
|
||||||
|
@ -562,7 +563,7 @@ pub mod examples {
|
||||||
// "Japan's 'Wasan' Mathematical Tradition", by Abe Haruki
|
// "Japan's 'Wasan' Mathematical Tradition", by Abe Haruki
|
||||||
// https://www.nippon.com/en/japan-topics/c12801/
|
// https://www.nippon.com/en/japan-topics/c12801/
|
||||||
//
|
//
|
||||||
pub fn realize_irisawa_hexlet(scaled_tol: f64) -> RealizationResult {
|
pub fn realize_irisawa_hexlet(scaled_tol: f64) -> Realization {
|
||||||
let mut problem = ConstraintProblem::from_guess(
|
let mut problem = ConstraintProblem::from_guess(
|
||||||
[
|
[
|
||||||
sphere(0.0, 0.0, 0.0, 15.0),
|
sphere(0.0, 0.0, 0.0, 15.0),
|
||||||
|
@ -613,7 +614,7 @@ pub mod examples {
|
||||||
|
|
||||||
// set up a kaleidocycle, made of points with fixed distances between them,
|
// set up a kaleidocycle, made of points with fixed distances between them,
|
||||||
// and find its tangent space
|
// and find its tangent space
|
||||||
pub fn realize_kaleidocycle(scaled_tol: f64) -> RealizationResult {
|
pub fn realize_kaleidocycle(scaled_tol: f64) -> Realization {
|
||||||
const N_HINGES: usize = 6;
|
const N_HINGES: usize = 6;
|
||||||
let mut problem = ConstraintProblem::from_guess(
|
let mut problem = ConstraintProblem::from_guess(
|
||||||
(0..N_HINGES).step_by(2).flat_map(
|
(0..N_HINGES).step_by(2).flat_map(
|
||||||
|
@ -737,7 +738,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
problem.frozen.push(3, 0, problem.guess[(3, 0)]);
|
problem.frozen.push(3, 0, problem.guess[(3, 0)]);
|
||||||
problem.frozen.push(3, 1, 0.5);
|
problem.frozen.push(3, 1, 0.5);
|
||||||
let RealizationResult { result, history } = realize_gram(
|
let Realization { result, history } = realize_gram(
|
||||||
&problem, 1.0e-12, 0.5, 0.9, 1.1, 200, 110
|
&problem, 1.0e-12, 0.5, 0.9, 1.1, 200, 110
|
||||||
);
|
);
|
||||||
let config = result.unwrap().config;
|
let config = result.unwrap().config;
|
||||||
|
@ -782,10 +783,10 @@ mod tests {
|
||||||
for n in 0..ELEMENT_DIM {
|
for n in 0..ELEMENT_DIM {
|
||||||
problem.frozen.push(n, 0, problem.guess[(n, 0)]);
|
problem.frozen.push(n, 0, problem.guess[(n, 0)]);
|
||||||
}
|
}
|
||||||
let RealizationResult { result, history } = realize_gram(
|
let Realization { result, history } = realize_gram(
|
||||||
&problem, SCALED_TOL, 0.5, 0.9, 1.1, 200, 110
|
&problem, SCALED_TOL, 0.5, 0.9, 1.1, 200, 110
|
||||||
);
|
);
|
||||||
let Realization { config, tangent } = result.unwrap();
|
let ConfigNeighborhood { config, nbhd: tangent } = result.unwrap();
|
||||||
assert_eq!(config, problem.guess);
|
assert_eq!(config, problem.guess);
|
||||||
assert_eq!(history.scaled_loss.len(), 1);
|
assert_eq!(history.scaled_loss.len(), 1);
|
||||||
|
|
||||||
|
@ -854,8 +855,8 @@ mod tests {
|
||||||
fn tangent_test_kaleidocycle() {
|
fn tangent_test_kaleidocycle() {
|
||||||
// set up a kaleidocycle and find its tangent space
|
// set up a kaleidocycle and find its tangent space
|
||||||
const SCALED_TOL: f64 = 1.0e-12;
|
const SCALED_TOL: f64 = 1.0e-12;
|
||||||
let RealizationResult { result, history } = realize_kaleidocycle(SCALED_TOL);
|
let Realization { result, history } = realize_kaleidocycle(SCALED_TOL);
|
||||||
let Realization { config, tangent } = result.unwrap();
|
let ConfigNeighborhood { config, nbhd: tangent } = result.unwrap();
|
||||||
assert_eq!(history.scaled_loss.len(), 1);
|
assert_eq!(history.scaled_loss.len(), 1);
|
||||||
|
|
||||||
// list some motions that should form a basis for the tangent space of
|
// list some motions that should form a basis for the tangent space of
|
||||||
|
@ -943,10 +944,10 @@ mod tests {
|
||||||
problem_orig.gram.push_sym(0, 0, 1.0);
|
problem_orig.gram.push_sym(0, 0, 1.0);
|
||||||
problem_orig.gram.push_sym(1, 1, 1.0);
|
problem_orig.gram.push_sym(1, 1, 1.0);
|
||||||
problem_orig.gram.push_sym(0, 1, 0.5);
|
problem_orig.gram.push_sym(0, 1, 0.5);
|
||||||
let RealizationResult { result: result_orig, history: history_orig } = realize_gram(
|
let Realization { result: result_orig, history: history_orig } = realize_gram(
|
||||||
&problem_orig, SCALED_TOL, 0.5, 0.9, 1.1, 200, 110
|
&problem_orig, SCALED_TOL, 0.5, 0.9, 1.1, 200, 110
|
||||||
);
|
);
|
||||||
let Realization { config: config_orig, tangent: tangent_orig } = result_orig.unwrap();
|
let ConfigNeighborhood { config: config_orig, nbhd: tangent_orig } = result_orig.unwrap();
|
||||||
assert_eq!(config_orig, problem_orig.guess);
|
assert_eq!(config_orig, problem_orig.guess);
|
||||||
assert_eq!(history_orig.scaled_loss.len(), 1);
|
assert_eq!(history_orig.scaled_loss.len(), 1);
|
||||||
|
|
||||||
|
@ -964,10 +965,10 @@ mod tests {
|
||||||
guess: guess_tfm,
|
guess: guess_tfm,
|
||||||
frozen: problem_orig.frozen
|
frozen: problem_orig.frozen
|
||||||
};
|
};
|
||||||
let RealizationResult { result: result_tfm, history: history_tfm } = realize_gram(
|
let Realization { result: result_tfm, history: history_tfm } = realize_gram(
|
||||||
&problem_tfm, SCALED_TOL, 0.5, 0.9, 1.1, 200, 110
|
&problem_tfm, SCALED_TOL, 0.5, 0.9, 1.1, 200, 110
|
||||||
);
|
);
|
||||||
let Realization { config: config_tfm, tangent: tangent_tfm } = result_tfm.unwrap();
|
let ConfigNeighborhood { config: config_tfm, nbhd: tangent_tfm } = result_tfm.unwrap();
|
||||||
assert_eq!(config_tfm, problem_tfm.guess);
|
assert_eq!(config_tfm, problem_tfm.guess);
|
||||||
assert_eq!(history_tfm.scaled_loss.len(), 1);
|
assert_eq!(history_tfm.scaled_loss.len(), 1);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue