private IVariable MakeLongMultiplication(IMilpManager baseMilpManager, Domain domain, IVariable zero, IVariable second, IVariable first) { var result = zero; var secondDigits = second.CompositeOperation(CompositeOperationType.UnsignedMagnitudeDecomposition).ToArray(); for (int index = 0, power = 1; index < secondDigits.Length; ++index, power = power * 2) { result = result.Operation(OperationType.Addition, MultipleByBinaryDigit(baseMilpManager, first, secondDigits[index]) .ChangeDomain(domain) .Operation(OperationType.Multiplication, baseMilpManager.FromConstant(power)) ); } return(result); }
private static IVariable CalculatePower(IVariable number, IVariable power, IMilpManager milpManager, IVariable isEdgeCase) { var digits = (int)Math.Ceiling(Math.Log(milpManager.IntegerWidth, 2.0)); var infinity = milpManager.FromConstant(milpManager.MaximumIntegerValue); var currentPower = milpManager.Operation(OperationType.Minimum, number, isEdgeCase.Operation(OperationType.BinaryNegation).Operation(OperationType.Multiplication, infinity)); var decomposition = power.CompositeOperation(CompositeOperationType.UnsignedMagnitudeDecomposition).Take(digits).ToArray(); var one = milpManager.FromConstant(1); var result = one; for (int i = 0; i < digits; ++i) { if (i > 0) { var isAnyNonzeroDigitLater = milpManager.Operation(OperationType.Disjunction, decomposition.Skip(i).ToArray()); var numberToMultiply = milpManager.Operation(OperationType.Minimum, currentPower, isAnyNonzeroDigitLater.Operation(OperationType.Multiplication, infinity)); currentPower = numberToMultiply.Operation(OperationType.Multiplication, numberToMultiply); } result = result.Operation(OperationType.Multiplication, one.Operation(OperationType.Maximum, currentPower.Operation(OperationType.Multiplication, decomposition[i]))); } return(result); }
private static IVariable CalculatePower(IVariable number, IVariable power, IMilpManager milpManager, IVariable isEdgeCase) { var digits = (int)Math.Ceiling(Math.Log(milpManager.IntegerWidth, 2.0)); var infinity = milpManager.FromConstant(milpManager.MaximumIntegerValue); var currentPower = milpManager.Operation(OperationType.Minimum, number, isEdgeCase.Operation(OperationType.BinaryNegation).Operation(OperationType.Multiplication, infinity)); var decomposition = power.CompositeOperation(CompositeOperationType.UnsignedMagnitudeDecomposition).Take(digits).ToArray(); var one = milpManager.FromConstant(1); var result = one; for (int i = 0; i < digits; ++i) { if (i > 0) { var isAnyNonzeroDigitLater = milpManager.Operation(OperationType.Disjunction, decomposition.Skip(i).ToArray()); var numberToMultiply = milpManager.Operation(OperationType.Minimum, currentPower, isAnyNonzeroDigitLater.Operation(OperationType.Multiplication, infinity)); currentPower = numberToMultiply.Operation(OperationType.Multiplication, numberToMultiply); } result = result.Operation(OperationType.Multiplication, one.Operation(OperationType.Maximum, currentPower.Operation(OperationType.Multiplication, decomposition[i]))); } return result; }
private IVariable MakeLongMultiplication(IMilpManager baseMilpManager, Domain domain, IVariable zero, IVariable second, IVariable first) { var result = zero; var secondDigits = second.CompositeOperation(CompositeOperationType.UnsignedMagnitudeDecomposition).ToArray(); for (int index = 0, power = 1; index < secondDigits.Length; ++index, power = power*2) { result = result.Operation(OperationType.Addition, MultipleByBinaryDigit(baseMilpManager, first, secondDigits[index]) .ChangeDomain(domain) .Operation(OperationType.Multiplication, baseMilpManager.FromConstant(power)) ); } return result; }