mirror of https://github.com/rm-dr/daisy
Compound unit foundation
parent
ad3ae83c66
commit
175261b5c0
|
@ -93,31 +93,30 @@ impl PreToken {
|
||||||
let c = match &s[..] {
|
let c = match &s[..] {
|
||||||
// Mathematical constants
|
// Mathematical constants
|
||||||
// 100 digits of each.
|
// 100 digits of each.
|
||||||
"π"|"pi" => { Some(Token::Constant(Quantity::new_float_from_string(
|
"π"|"pi" => { Some((Quantity::new_float_from_string(
|
||||||
"3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067"
|
"3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067"
|
||||||
).unwrap(), String::from("π")))},
|
).unwrap(), String::from("π")))},
|
||||||
|
|
||||||
"e" => { Some(Token::Constant(Quantity::new_float_from_string(
|
"e" => { Some((Quantity::new_float_from_string(
|
||||||
"2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427"
|
"2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427"
|
||||||
).unwrap(), String::from("e"))) },
|
).unwrap(), String::from("e"))) },
|
||||||
|
|
||||||
"phi"|"φ" => { Some(Token::Constant(Quantity::new_float_from_string(
|
"phi"|"φ" => { Some((Quantity::new_float_from_string(
|
||||||
"1.618033988749894848204586834365638117720309179805762862135448622705260462818902449707207204189391137"
|
"1.618033988749894848204586834365638117720309179805762862135448622705260462818902449707207204189391137"
|
||||||
).unwrap(), String::from("φ"))) },
|
).unwrap(), String::from("φ"))) },
|
||||||
|
|
||||||
_ => { None }
|
_ => { None }
|
||||||
};
|
};
|
||||||
|
|
||||||
if c.is_some() { return Ok(c.unwrap()); }
|
|
||||||
|
|
||||||
let c = Unit::from_string(&s);
|
|
||||||
|
|
||||||
if c.is_some() {
|
if c.is_some() {
|
||||||
let mut q = Quantity::new_rational(1f64).unwrap();
|
let (a, b) = c.unwrap();
|
||||||
q.set_unit(c.unwrap());
|
return Ok(Token::Constant(a, b));
|
||||||
return Ok(Token::Number(q));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let c = Quantity::from_unit_string(&s);
|
||||||
|
|
||||||
|
if c.is_some() { return Ok(Token::Number(c.unwrap())); }
|
||||||
|
|
||||||
return Err((l, ParserError::Undefined(s)));
|
return Err((l, ParserError::Undefined(s)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,11 @@ pub(in crate::quantity) use crate::quantity::scalar::Scalar;
|
||||||
mod unit;
|
mod unit;
|
||||||
pub use crate::quantity::unit::Unit;
|
pub use crate::quantity::unit::Unit;
|
||||||
pub use crate::quantity::unit::BaseUnit;
|
pub use crate::quantity::unit::BaseUnit;
|
||||||
|
pub(in crate::quantity) use crate::quantity::unit::CompoundUnit;
|
||||||
|
|
||||||
mod quantity;
|
mod quantity;
|
||||||
pub use crate::quantity::quantity::Quantity;
|
pub use crate::quantity::quantity::Quantity;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ use std::ops::{
|
||||||
};
|
};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
|
||||||
use crate::quantity::Unit;
|
use crate::quantity::Unit;
|
||||||
use crate::quantity::BaseUnit;
|
use crate::quantity::BaseUnit;
|
||||||
|
use crate::quantity::CompoundUnit;
|
||||||
|
|
||||||
|
|
||||||
use crate::quantity::Scalar;
|
use crate::quantity::Scalar;
|
||||||
|
@ -44,8 +44,6 @@ impl Quantity {
|
||||||
return format!("{n} {u}");
|
return format!("{n} {u}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn new_float(f: f64) -> Option<Quantity> {
|
pub fn new_float(f: f64) -> Option<Quantity> {
|
||||||
let v = Scalar::new_float(f);
|
let v = Scalar::new_float(f);
|
||||||
if v.is_none() { return None; }
|
if v.is_none() { return None; }
|
||||||
|
@ -88,6 +86,48 @@ impl Quantity {
|
||||||
|
|
||||||
pub fn insert_unit(&mut self, ui: BaseUnit, pi: f64) { self.u.insert(ui, pi) }
|
pub fn insert_unit(&mut self, ui: BaseUnit, pi: f64) { self.u.insert(ui, pi) }
|
||||||
pub fn set_unit(&mut self, u: Unit) { self.u = u; }
|
pub fn set_unit(&mut self, u: Unit) { self.u = u; }
|
||||||
|
|
||||||
|
pub fn from_unit_string(s: &str) -> Option<Quantity> {
|
||||||
|
// Base Units
|
||||||
|
let b = match s {
|
||||||
|
"m" => Some(BaseUnit::Meter),
|
||||||
|
"s" => Some(BaseUnit::Second),
|
||||||
|
"kg" => Some(BaseUnit::Kilogram),
|
||||||
|
"a" => Some(BaseUnit::Ampere),
|
||||||
|
"k" => Some(BaseUnit::Kelvin),
|
||||||
|
"mol" => Some(BaseUnit::Mole),
|
||||||
|
"c" => Some(BaseUnit::Candela),
|
||||||
|
_ => { None }
|
||||||
|
};
|
||||||
|
|
||||||
|
if b.is_some() {
|
||||||
|
let mut u = Unit::new();
|
||||||
|
u.insert(b.unwrap(), 1f64);
|
||||||
|
|
||||||
|
let mut q = Quantity::new_rational(1f64).unwrap();
|
||||||
|
q.set_unit(u);
|
||||||
|
|
||||||
|
return Some(q);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compound units
|
||||||
|
let b = match s {
|
||||||
|
"ft" => Some(CompoundUnit::FOOT),
|
||||||
|
_ => { None }
|
||||||
|
};
|
||||||
|
|
||||||
|
if b.is_some() {
|
||||||
|
let b = b.unwrap();
|
||||||
|
let q = Quantity{
|
||||||
|
v: b.coef(),
|
||||||
|
u: b.unit()
|
||||||
|
};
|
||||||
|
return Some(q);
|
||||||
|
};
|
||||||
|
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use std::{collections::HashMap, hash::Hash};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
|
||||||
use std::ops::{
|
use std::ops::{
|
||||||
Mul, Div,
|
Mul, Div,
|
||||||
MulAssign, DivAssign
|
MulAssign, DivAssign
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::quantity::Scalar;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[derive(Hash)]
|
#[derive(Hash)]
|
||||||
#[derive(Eq, PartialEq)]
|
#[derive(Eq, PartialEq)]
|
||||||
|
@ -20,6 +20,40 @@ pub enum BaseUnit {
|
||||||
Candela
|
Candela
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct CompoundUnit {
|
||||||
|
coef_str: &'static str,
|
||||||
|
rational: bool,
|
||||||
|
units: &'static[(BaseUnit, f64)],
|
||||||
|
pub str: &'static str
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CompoundUnit {
|
||||||
|
pub const FOOT: CompoundUnit = CompoundUnit {
|
||||||
|
coef_str: "0.3048",
|
||||||
|
rational: false,
|
||||||
|
units: &[(BaseUnit::Meter, 1f64)],
|
||||||
|
str: "ft"
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn unit(&self) -> Unit {
|
||||||
|
let mut n = Unit::new();
|
||||||
|
for (u, p) in self.units.iter() {
|
||||||
|
n.insert(*u, *p);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn coef(&self) -> Scalar {
|
||||||
|
if self.rational {
|
||||||
|
Scalar::new_rational_from_string(self.coef_str).unwrap()
|
||||||
|
} else {
|
||||||
|
Scalar::new_float_from_string(self.coef_str).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Unit {
|
pub struct Unit {
|
||||||
|
@ -117,23 +151,6 @@ impl Unit {
|
||||||
};
|
};
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_string(s: &str) -> Option<Unit> {
|
|
||||||
let b = match s {
|
|
||||||
"m" => BaseUnit::Meter,
|
|
||||||
"s" => BaseUnit::Second,
|
|
||||||
"kg" => BaseUnit::Kilogram,
|
|
||||||
"a" => BaseUnit::Ampere,
|
|
||||||
"k" => BaseUnit::Kelvin,
|
|
||||||
"mol" => BaseUnit::Mole,
|
|
||||||
"c" => BaseUnit::Candela,
|
|
||||||
_ => { return None; }
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut u = Unit::new();
|
|
||||||
u.insert(b, 1f64);
|
|
||||||
return Some(u);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue