Skip to content
Snippets Groups Projects
Commit 73bcb539 authored by Aaron Councilman's avatar Aaron Councilman
Browse files

Clean-up Juno's dynamic constant generation

parent 3af4013e
No related branches found
No related tags found
2 merge requests!139Edge detection,!137Dynamic Constant Normalization
Pipeline #201278 passed
...@@ -291,16 +291,16 @@ impl DynConst { ...@@ -291,16 +291,16 @@ impl DynConst {
.map(|(d, c)| self.build_mono(builder, d, c)) .map(|(d, c)| self.build_mono(builder, d, c))
.partition(|(_, neg)| !*neg); .partition(|(_, neg)| !*neg);
let pos_sum = pos let pos_sum =
.into_iter() builder.create_dynamic_constant_add_many(pos.into_iter().map(|(t, _)| t).collect());
.map(|(t, _)| t)
.reduce(|x, y| builder.create_dynamic_constant_add(x, y))
.unwrap_or_else(|| builder.create_dynamic_constant_constant(0));
let neg_sum = neg let neg_sum = if neg.is_empty() {
.into_iter() None
.map(|(t, _)| t) } else {
.reduce(|x, y| builder.create_dynamic_constant_add(x, y)); Some(
builder.create_dynamic_constant_add_many(neg.into_iter().map(|(t, _)| t).collect()),
)
};
match neg_sum { match neg_sum {
None => pos_sum, None => pos_sum,
...@@ -317,72 +317,61 @@ impl DynConst { ...@@ -317,72 +317,61 @@ impl DynConst {
term: &Vec<i64>, term: &Vec<i64>,
coeff: &Ratio<i64>, coeff: &Ratio<i64>,
) -> (DynamicConstantID, bool) { ) -> (DynamicConstantID, bool) {
let term_id = term let (pos, neg): (Vec<_>, Vec<_>) = term
.iter() .iter()
.enumerate() .enumerate()
.filter(|(_, p)| **p != 0) .filter(|(_, p)| **p != 0)
.map(|(v, p)| self.build_power(builder, v, *p)) .map(|(v, p)| self.build_power(builder, v, *p))
.collect::<Vec<_>>() .partition(|(_, neg)| !*neg);
.into_iter() let mut pos: Vec<_> = pos.into_iter().map(|(t, _)| t).collect();
.reduce(|x, y| builder.create_dynamic_constant_mul(x, y)); let mut neg: Vec<_> = neg.into_iter().map(|(t, _)| t).collect();
match term_id { let numerator = {
None => { let numer: i64 = coeff.numer().abs();
// This means all powers of the term are 0, so we just let numer_dc = builder.create_dynamic_constant_constant(numer as usize);
// output the coefficient pos.push(numer_dc);
if !coeff.is_integer() { builder.create_dynamic_constant_mul_many(pos)
panic!("Dynamic constant is a non-integer constant") };
} else {
let val: i64 = coeff.to_integer(); let denominator = {
( let denom: i64 = *coeff.denom();
builder.create_dynamic_constant_constant(val.abs() as usize), assert!(denom > 0);
val < 0,
) if neg.is_empty() && denom == 1 {
} None
} } else {
Some(term) => { let denom_dc = builder.create_dynamic_constant_constant(denom as usize);
if coeff.is_one() { neg.push(denom_dc);
(term, false) Some(builder.create_dynamic_constant_mul_many(neg))
} else {
let numer: i64 = coeff.numer().abs();
let denom: i64 = *coeff.denom(); // > 0
let with_numer = if numer == 1 {
term
} else {
let numer_id = builder.create_dynamic_constant_constant(numer as usize);
builder.create_dynamic_constant_mul(numer_id, term)
};
let with_denom = if denom == 1 {
with_numer
} else {
let denom_id = builder.create_dynamic_constant_constant(denom as usize);
builder.create_dynamic_constant_div(with_numer, denom_id)
};
(with_denom, numer < 0)
}
} }
};
if let Some(denominator) = denominator {
(
builder.create_dynamic_constant_div(numerator, denominator),
*coeff.numer() < 0,
)
} else {
(numerator, *coeff.numer() < 0)
} }
} }
// Build's a dynamic constant that is a certain power of a specific variable // Build's a dynamic constant that is a certain power of a specific variable
fn build_power(&self, builder: &mut Builder, v: usize, power: i64) -> DynamicConstantID { // Returns the dynamic constant id of variable raised to the absolute value of the power and a
// boolean indicating whether the power is actually negative
fn build_power(
&self,
builder: &mut Builder,
v: usize,
power: i64,
) -> (DynamicConstantID, bool) {
assert!(power != 0); assert!(power != 0);
let power_pos = power.abs() as usize; let power_pos = power.abs() as usize;
let var_id = builder.create_dynamic_constant_parameter(v); let var_id = builder.create_dynamic_constant_parameter(v);
let power_id = iter::repeat(var_id) let power_id =
.take(power_pos) builder.create_dynamic_constant_mul_many((0..power_pos).map(|_| var_id).collect());
.map(|_| var_id)
.reduce(|x, y| builder.create_dynamic_constant_mul(x, y))
.expect("Power is non-zero");
if power > 0 { (power_id, power < 0)
power_id
} else {
let one_id = builder.create_dynamic_constant_constant(1);
builder.create_dynamic_constant_div(one_id, power_id)
}
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment