mirror of https://github.com/rm-dr/daisy
Fixed unit matching
parent
7fb0e0274c
commit
7b77c49ba4
|
@ -111,7 +111,6 @@ impl Quantity {
|
||||||
return Some(n.mul_no_convert(fa).div_no_convert(fb))
|
return Some(n.mul_no_convert(fa).div_no_convert(fb))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn match_units(&mut self, other: &Quantity) {
|
pub fn match_units(&mut self, other: &Quantity) {
|
||||||
|
|
||||||
let mut new_units = Quantity::new_rational_from_string("1").unwrap();
|
let mut new_units = Quantity::new_rational_from_string("1").unwrap();
|
||||||
|
@ -123,14 +122,15 @@ impl Quantity {
|
||||||
|
|
||||||
// Check if `us` matches some unit in `other`
|
// Check if `us` matches some unit in `other`
|
||||||
for (uo, _) in other.unit.get_val() {
|
for (uo, _) in other.unit.get_val() {
|
||||||
if {
|
// Use generalized compatible_with check to match reciprocal units
|
||||||
uo.to_base().unit.compatible_with(&us.to_base().unit)
|
// (for example, 1Hz * 1 sec.)
|
||||||
} {
|
let f = uo.to_base().unit.compatible_with_power(&us.to_base().unit);
|
||||||
// If it does, convert `us` to `uo`
|
if f.is_none() { continue; }
|
||||||
new_units.insert_unit(uo.clone(), ps.clone());
|
let f = f.unwrap();
|
||||||
flag = true;
|
|
||||||
break;
|
new_units.insert_unit(uo.clone(), ps.clone() * f);
|
||||||
}
|
flag = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if !flag {
|
if !flag {
|
||||||
// If no unit in `other` matches `us`, don't convert `us`
|
// If no unit in `other` matches `us`, don't convert `us`
|
||||||
|
|
|
@ -162,6 +162,55 @@ impl Unit {
|
||||||
return o == s;
|
return o == s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// True if all base units are the same AND there is a constant factor between their powers.
|
||||||
|
// This is a generalization of `compatible_with`. `compatible_with` is true iff
|
||||||
|
// `compatible_with_power` is one.
|
||||||
|
pub fn compatible_with_power(&self, other: &Unit) -> Option<Scalar> {
|
||||||
|
let mut flag;
|
||||||
|
let mut pow_factor: Option<Scalar> = None;
|
||||||
|
|
||||||
|
let sbu = self.to_base().unit;
|
||||||
|
let obu = other.to_base().unit;
|
||||||
|
|
||||||
|
for (us, ps) in sbu.get_val() {
|
||||||
|
flag = false;
|
||||||
|
for (uo, po) in obu.get_val() {
|
||||||
|
if uo.whole == us.whole {
|
||||||
|
if pow_factor.is_none() {
|
||||||
|
pow_factor = Some(po.clone() / ps.clone());
|
||||||
|
} else if let Some(ref f) = pow_factor {
|
||||||
|
if *f != po.clone() / ps.clone() { return None; }
|
||||||
|
}
|
||||||
|
|
||||||
|
flag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !flag { return None; }
|
||||||
|
}
|
||||||
|
|
||||||
|
pow_factor = None;
|
||||||
|
for (uo, po) in obu.get_val() {
|
||||||
|
flag = false;
|
||||||
|
for (us, ps) in sbu.get_val() {
|
||||||
|
if uo.whole == us.whole {
|
||||||
|
if pow_factor.is_none() {
|
||||||
|
pow_factor = Some(po.clone() / ps.clone());
|
||||||
|
} else if let Some(ref f) = pow_factor {
|
||||||
|
if *f != po.clone() / ps.clone() { return None; }
|
||||||
|
}
|
||||||
|
|
||||||
|
flag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !flag { return None; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return pow_factor;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, u: FreeUnit, p: Scalar) {
|
pub fn insert(&mut self, u: FreeUnit, p: Scalar) {
|
||||||
let v = self.get_val_mut();
|
let v = self.get_val_mut();
|
||||||
match v.get_mut(&u) {
|
match v.get_mut(&u) {
|
||||||
|
|
|
@ -211,4 +211,6 @@ fn complex_units() {
|
||||||
good_expr("20 mi", "10 mph * 2 hours");
|
good_expr("20 mi", "10 mph * 2 hours");
|
||||||
good_expr("120 m", "1 (m/s) * 2 min");
|
good_expr("120 m", "1 (m/s) * 2 min");
|
||||||
good_expr("120 m", "(2 min) * (1 m/s)");
|
good_expr("120 m", "(2 min) * (1 m/s)");
|
||||||
|
good_expr("180", "1 Hz * 3 min");
|
||||||
|
good_expr("3600", "1 hour * 1 Hz");
|
||||||
}
|
}
|
Loading…
Reference in New Issue