This commit is contained in:
William Ball 2021-07-21 13:57:44 -04:00
parent cc906992cd
commit f7c30b2b54
2 changed files with 24 additions and 52 deletions

View file

@ -1,10 +1,13 @@
use ansi_term::Color::Yellow; use ansi_term::Color::Yellow;
use linregress::{FormulaRegressionBuilder, RegressionDataBuilder}; use linregress::{FormulaRegressionBuilder, RegressionDataBuilder};
use nalgebra::{DMatrix, DVector}; use nalgebra::{DMatrix, DVector};
use f128::f128;
type F = f128;
pub fn fractal_dimension( pub fn fractal_dimension(
generators: Vec<DMatrix<f64>>, generators: Vec<DMatrix<F>>,
root: DVector<f64>, root: DVector<F>,
faces: Vec<Vec<usize>>, faces: Vec<Vec<usize>>,
upper_bound: f64, upper_bound: f64,
n: usize, n: usize,
@ -18,7 +21,7 @@ pub fn fractal_dimension(
let mut nodes: u64 = 1; let mut nodes: u64 = 1;
let xs: Vec<f64> = (1..=n) let xs: Vec<f64> = (1..=n)
.map(|x| (x as f64 * upper_bound / (2.0 * n as f64) + upper_bound / 2.0)) .map(|x| ((x as f64) * upper_bound / ((2 * n) as f64) + upper_bound / f64::from(2.0)))
.collect(); .collect();
let mut i = 0; let mut i = 0;
@ -54,7 +57,7 @@ pub fn fractal_dimension(
continue; continue;
} }
for (k, max) in xs.iter().enumerate() { for (k, max) in xs.iter().enumerate() {
if curvature <= max { if curvature <= &F::from(*max) {
add_children = true; add_children = true;
too_big = false; too_big = false;
totals[k] += 1; totals[k] += 1;

View file

@ -1,8 +1,11 @@
use std::fs; use std::fs;
use f128::f128;
use nalgebra::{DMatrix, DVector}; use nalgebra::{DMatrix, DVector};
use ansi_term::Color::Red; use ansi_term::Color::Red;
type F = f128;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
enum TokenType { enum TokenType {
OpenBracket, OpenBracket,
@ -163,13 +166,13 @@ fn eval(data: &mut std::iter::Peekable<TokenIterator>) -> Result<Value, String>
} }
} }
fn vector_to_rust_value(value: &Value) -> Result<Vec<f64>, String> { fn vector_to_rust_value(value: &Value) -> Result<Vec<F>, String> {
let mut result = vec![]; let mut result: Vec<F> = vec![];
if let Value::List(data) = value { if let Value::List(data) = value {
for datapoint in data { for datapoint in data {
if let Value::Number(num) = datapoint { if let Value::Number(num) = datapoint {
result.push(*num); result.push(F::from(*num));
} else { } else {
return Err(format!("Expected a number, got {:?}", datapoint)); return Err(format!("Expected a number, got {:?}", datapoint));
} }
@ -181,8 +184,8 @@ fn vector_to_rust_value(value: &Value) -> Result<Vec<f64>, String> {
Ok(result) Ok(result)
} }
fn matrix_to_rust_value(value: &Value) -> Result<Vec<Vec<f64>>, String> { fn matrix_to_rust_value(value: &Value) -> Result<Vec<Vec<F>>, String> {
let mut result = vec![]; let mut result: Vec<Vec<F>> = vec![];
if let Value::List(data) = value { if let Value::List(data) = value {
for row in data { for row in data {
@ -197,8 +200,8 @@ fn matrix_to_rust_value(value: &Value) -> Result<Vec<Vec<f64>>, String> {
Ok(result) Ok(result)
} }
fn matrix_to_rust_value_flat(value: &Value) -> Result<Vec<f64>, String> { fn matrix_to_rust_value_flat(value: &Value) -> Result<Vec<F>, String> {
let mut result = vec![]; let mut result: Vec<F> = vec![];
if let Value::List(data) = value { if let Value::List(data) = value {
for row in data { for row in data {
@ -213,8 +216,8 @@ fn matrix_to_rust_value_flat(value: &Value) -> Result<Vec<f64>, String> {
Ok(result) Ok(result)
} }
pub type Generator = DMatrix<f64>; pub type Generator = DMatrix<F>;
pub type Root = DVector<f64>; pub type Root = DVector<F>;
pub type FaceList = Vec<Vec<usize>>; pub type FaceList = Vec<Vec<usize>>;
pub type OrthogonalGenerators = Vec<Vec<usize>>; pub type OrthogonalGenerators = Vec<Vec<usize>>;
pub type Data = (Vec<Generator>, Root, FaceList, OrthogonalGenerators); pub type Data = (Vec<Generator>, Root, FaceList, OrthogonalGenerators);
@ -226,7 +229,7 @@ pub fn read_file(filename: &str) -> Result<Data, String> {
let results = eval_full(contents)?; let results = eval_full(contents)?;
let mut generators = vec![]; let mut generators: Vec<Generator> = vec![];
if let Value::List(gens) = &results[0] { if let Value::List(gens) = &results[0] {
for val in gens { for val in gens {
let mat = matrix_to_rust_value(val)?; let mat = matrix_to_rust_value(val)?;
@ -244,7 +247,9 @@ pub fn read_file(filename: &str) -> Result<Data, String> {
let faces = matrix_to_rust_value(&results[2])?; let faces = matrix_to_rust_value(&results[2])?;
let faces = faces let faces = faces
.iter() .iter()
.map(|v| v.iter().map(|x| x.round() as usize).collect()) .map(|v| -> Vec<usize> {
v.iter().map(|x| -> usize { (*x).into() }).collect()
})
.collect(); .collect();
let orthogonal_generators: Vec<Vec<usize>> = if results.len() < 4 { let orthogonal_generators: Vec<Vec<usize>> = if results.len() < 4 {
@ -252,7 +257,7 @@ pub fn read_file(filename: &str) -> Result<Data, String> {
} else { } else {
matrix_to_rust_value(&results[3])? matrix_to_rust_value(&results[3])?
.iter() .iter()
.map(|v| v.iter().map(|x| x.round() as usize).collect()) .map(|v| v.iter().map(|x| -> usize { (*x).into() }).collect())
.collect() .collect()
}; };
@ -372,40 +377,4 @@ mod test {
])] ])]
); );
} }
#[test]
fn vector() {
let test = Value::List(vec![Value::Number(1.0), Value::Number(2.0)]);
assert_eq!(vector_to_rust_value(&test).unwrap(), vec![1.0, 2.0]);
}
#[test]
fn matrix() {
let val = Value::List(vec![
Value::List(vec![
Value::Number(1.0),
Value::Number(0.0),
Value::Number(0.0),
]),
Value::List(vec![
Value::Number(0.0),
Value::Number(1.0),
Value::Number(0.0),
]),
Value::List(vec![
Value::Number(0.0),
Value::Number(0.0),
Value::Number(1.0),
]),
]);
let res = matrix_to_rust_value(&val).unwrap();
assert_eq!(
res,
vec![
vec![1.0, 0.0, 0.0],
vec![0.0, 1.0, 0.0],
vec![0.0, 0.0, 1.0]
]
);
}
} }