Add else statement to conditional formulas

This commit is contained in:
thepaperpilot 2023-04-18 20:13:12 -05:00
parent ba67ff4fe9
commit 0f2cc45a7e
2 changed files with 36 additions and 3 deletions

View file

@ -364,21 +364,30 @@ export default class Formula<T extends [FormulaSource] | FormulaSource[]> {
* @param value The incoming formula value
* @param condition Whether or not to apply the modifier
* @param formulaModifier The modifier to apply to the incoming formula if the condition is true
* @param elseFormulaModifier An optional modifier to apply to the incoming formula if the condition is false
*/
public static if(
value: FormulaSource,
condition: Computable<boolean>,
formulaModifier: (
value: InvertibleFormula & IntegrableFormula & InvertibleIntegralFormula
) => GenericFormula,
elseFormulaModifier?: (
value: InvertibleFormula & IntegrableFormula & InvertibleIntegralFormula
) => GenericFormula
): GenericFormula {
const lhsRef = ref<DecimalSource>(0);
const formula = formulaModifier(Formula.variable(lhsRef));
const variable = Formula.variable(lhsRef);
const formula = formulaModifier(variable);
const elseFormula = elseFormulaModifier?.(variable);
const processedCondition = convertComputable(condition);
function evalStep(lhs: DecimalSource) {
if (unref(processedCondition)) {
lhsRef.value = lhs;
return formula.evaluate();
} else if (elseFormula) {
lhsRef.value = lhs;
return elseFormula.evaluate();
} else {
return lhs;
}
@ -389,6 +398,8 @@ export default class Formula<T extends [FormulaSource] | FormulaSource[]> {
}
if (unref(processedCondition)) {
return lhs.invert(formula.invert(value));
} else if (elseFormula) {
return lhs.invert(elseFormula.invert(value));
} else {
return lhs.invert(value);
}
@ -399,15 +410,17 @@ export default class Formula<T extends [FormulaSource] | FormulaSource[]> {
invert: formula.isInvertible() && formula.hasVariable() ? invertStep : undefined
});
}
/** @see {@link if} */
public static conditional(
value: FormulaSource,
condition: Computable<boolean>,
formulaModifier: (
value: InvertibleFormula & IntegrableFormula & InvertibleIntegralFormula
) => GenericFormula,
elseFormulaModifier?: (
value: InvertibleFormula & IntegrableFormula & InvertibleIntegralFormula
) => GenericFormula
) {
return Formula.if(value, condition, formulaModifier);
return Formula.if(value, condition, formulaModifier, elseFormulaModifier);
}
public static abs(value: FormulaSource): GenericFormula {

View file

@ -868,6 +868,26 @@ describe("Conditionals", () => {
Formula.if(variable, false, value => Formula.sqrt(value)).invert(10)
).compare_tolerance(10));
});
describe("Evaluates correctly with condition false and else statement", () => {
test("Evaluates correctly", () =>
expect(
Formula.if(
constant,
false,
value => Formula.sqrt(value),
value => value.times(2)
).evaluate()
).compare_tolerance(20));
test("Inverts correctly with variable in input", () =>
expect(
Formula.if(
variable,
false,
value => Formula.sqrt(value),
value => value.times(2)
).invert(20)
).compare_tolerance(10));
});
describe("Evaluates correctly with condition true", () => {
test("Evaluates correctly", () =>