I need pulp or pyomo to do ALL arithmetic operations exclusively using float32.
It seems that the default they use is float64.
The following are 2 examples from both pulp and pyomo for the sum operation.
import pulp
import pyomo.environ as pyo
import numpy as np
def pulp_example(values, target_float):
variables = pulp.LpVariable.dicts("x", range(len(values)), 0, 1, pulp.LpBinary)
problem = pulp.LpProblem("Problem", pulp.LpMinimize)
problem += 0
problem += pulp.lpSum([variables[i] for i in range(len(values))]) == 2
sum_exp = pulp.lpSum([variables[i] * float(values[i]) for i in range(len(values))])
problem += sum_exp == target_float
status = problem.solve()
return status
def pyomo_example(values, target_float):
model = pyo.ConcreteModel()
model.I = pyo.RangeSet(0, len(values) - 1)
model.x = pyo.Var(model.I, within=pyo.Binary)
model.selection_constraint = pyo.Constraint(expr=sum(model.x[i] for i in model.I) == 2)
def sum_expr_rule(model):
return sum(model.x[i] * values[i] for i in model.I)
model.eq_expr = pyo.Expression(rule=sum_expr_rule)
model.constraint = pyo.Constraint(expr=model.eq_expr == target_float)
model.objective = pyo.Objective(expr=0, sense=pyo.minimize)
solver = pyo.SolverFactory('cbc')
result = solver.solve(model, tee=False)
return result.solver.status
input_values = [90.2743351459503174, 4.8144315292034]
# As expected, summation of same input values results in different outputs depending on float data type
float32_target = 95.0887680053711 # float32 arithmetic
float64_target = 95.08876667515372 # float64 arithmetic
assert np.sum([input_values], dtype=np.float32) == float32_target
assert np.sum([input_values], dtype=np.float64) == float64_target
pulp_res = pulp_example(input_values, float32_target) # 'Infeasible
pyomo_res = pyomo_example(input_values, float32_target) # 'warning'
pulp_res = pulp_example(input_values, float64_target) # 'Optimal'
pyomo_res = pyomo_example(input_values, float64_target) # 'ok'
pulpnorpyomo"does the math". They formulate a problem and turn it over to a solver, in this casecbc. Solvers have tolerances for all kinds of things, and you appear to be seeking floating point accuracy beyond 7 significant digits, which isn't really the forte of this approachlen(input_values) >= 100