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 {
.map(|(d, c)| self.build_mono(builder, d, c))
.partition(|(_, neg)| !*neg);
let pos_sum = pos
.into_iter()
.map(|(t, _)| t)
.reduce(|x, y| builder.create_dynamic_constant_add(x, y))
.unwrap_or_else(|| builder.create_dynamic_constant_constant(0));
let pos_sum =
builder.create_dynamic_constant_add_many(pos.into_iter().map(|(t, _)| t).collect());
let neg_sum = neg
.into_iter()
.map(|(t, _)| t)
.reduce(|x, y| builder.create_dynamic_constant_add(x, y));
let neg_sum = if neg.is_empty() {
None
} else {
Some(
builder.create_dynamic_constant_add_many(neg.into_iter().map(|(t, _)| t).collect()),
)
};
match neg_sum {
None => pos_sum,
......@@ -317,72 +317,61 @@ impl DynConst {
term: &Vec<i64>,
coeff: &Ratio<i64>,
) -> (DynamicConstantID, bool) {
let term_id = term
let (pos, neg): (Vec<_>, Vec<_>) = term
.iter()
.enumerate()
.filter(|(_, p)| **p != 0)
.map(|(v, p)| self.build_power(builder, v, *p))
.collect::<Vec<_>>()
.into_iter()
.reduce(|x, y| builder.create_dynamic_constant_mul(x, y));
match term_id {
None => {
// This means all powers of the term are 0, so we just
// output the coefficient
if !coeff.is_integer() {
panic!("Dynamic constant is a non-integer constant")
} else {
let val: i64 = coeff.to_integer();
(
builder.create_dynamic_constant_constant(val.abs() as usize),
val < 0,
)
}
}
Some(term) => {
if coeff.is_one() {
(term, false)
} 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)
}
.partition(|(_, neg)| !*neg);
let mut pos: Vec<_> = pos.into_iter().map(|(t, _)| t).collect();
let mut neg: Vec<_> = neg.into_iter().map(|(t, _)| t).collect();
let numerator = {
let numer: i64 = coeff.numer().abs();
let numer_dc = builder.create_dynamic_constant_constant(numer as usize);
pos.push(numer_dc);
builder.create_dynamic_constant_mul_many(pos)
};
let denominator = {
let denom: i64 = *coeff.denom();
assert!(denom > 0);
if neg.is_empty() && denom == 1 {
None
} else {
let denom_dc = builder.create_dynamic_constant_constant(denom as usize);
neg.push(denom_dc);
Some(builder.create_dynamic_constant_mul_many(neg))
}
};
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
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);
let power_pos = power.abs() as usize;
let var_id = builder.create_dynamic_constant_parameter(v);
let power_id = iter::repeat(var_id)
.take(power_pos)
.map(|_| var_id)
.reduce(|x, y| builder.create_dynamic_constant_mul(x, y))
.expect("Power is non-zero");
let power_id =
builder.create_dynamic_constant_mul_many((0..power_pos).map(|_| var_id).collect());
if power > 0 {
power_id
} else {
let one_id = builder.create_dynamic_constant_constant(1);
builder.create_dynamic_constant_div(one_id, power_id)
}
(power_id, power < 0)
}
}
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