def __init__(self, value, denominator=1):
"""
:param value: either an integer numerator, a
float/rational/other number, or an IFDRational
:param denominator: Optional integer denominator
"""
self._denominator = denominator
self._numerator = value
self._val = float(1)
if isinstance(value, Fraction):
self._numerator = value.numerator
self._denominator = value.denominator
self._val = value
if isinstance(value, IFDRational):
self._denominator = value.denominator
self._numerator = value.numerator
self._val = value._val
return
if denominator == 0:
self._val = float('nan')
return
elif denominator == 1:
self._val = Fraction(value)
else:
self._val = Fraction(value, denominator)
python类Fraction()的实例源码
def fraction(self, terms=None):
"Convert to a Fraction."
if terms is None or terms >= len(self):
terms = len(self) - 1
frac = Fraction(1, self[terms])
for t in reversed(self[1:terms]):
frac = 1 / (frac + t)
frac += self[0]
return frac
def addVar (self, ve):
assert(isinstance(ve, tft_expr.VariableExpr))
if (ve.label().startswith(tft_expr.GROUP_ERR_VAR_PREFIX) or ve.label().startswith(tft_expr.ERR_VAR_PREFIX)):
assert(ve.type() == int)
if (ve in self.var_expr_2_gurobi_var.keys()):
return
# add variable
var = ""
if (ve.type() == int):
var = self.solver.addVar(vtype=GRB.INTEGER, name=ve.label())
elif (ve.type() == Fraction):
var = self.solver.addVar(name=ve.label())
else:
sys.exit("ERROR: invalid type of VariableExpr found when asking gurobi for OptimizeExpr")
self.var_expr_2_gurobi_var[ve] = var
self.solver.update()
# write range
if (ve.hasBounds()):
# check lower bound
if (ve.lb().value() < Fraction(0, 1)):
sys.exit("ERROR: variable's (" + ve.label() +") lower bound must be greater than 0")
# add constraint
self.addConstraint("linear", "<=", ve.lb(), ve)
self.addConstraint("linear", "<=", ve, ve.ub())
def Eps2CtypeString (eps):
assert(isinstance(eps, Fraction))
if (eps == tft_alloc.EPSILON_32):
return "float"
elif (eps == tft_alloc.EPSILON_64):
return "double"
elif (eps == tft_alloc.EPSILON_128):
return "__float128"
else:
sys.exit("Error: invalid bit-width: " + str(bw))
def refVar (self):
return tft_expr.VariableExpr(self.refVarName(), Fraction, -1, False)
def absexpr (self):
if (self.stored_absexpr is not None):
return self.stored_absexpr
if (self.expr.hasLB() and self.expr.lb().value() >= Fraction(0, 1)):
self.stored_absexpr = self.expr
elif (isinstance(self.expr, tft_expr.UnaryExpr) and (self.expr.operator.label == "abs")):
self.stored_absexpr = self.expr
else:
self.stored_absexpr = IR.MakeUnaryExpr("abs", -1, self.expr, True)
return self.stored_absexpr
def scalingUpFactor (self):
if (IR.PREC_CANDIDATES == ["e32", "e64"]):
return tft_expr.ConstantExpr(math.pow(2, 21))
elif (IR.PREC_CANDIDATES == ["e64", "e128"]):
return tft_expr.ConstantExpr(math.pow(2, 50))
elif (IR.PREC_CANDIDATES == ["e32", "e64", "e128"]):
return tft_expr.ConstantExpr(math.pow(2, 48))
else:
sys.exit("Error: invalid setting of IR.PREC_CANDIDATES: " + str(IR.PREC_CANDIDATES))
# scaling_eps = Fraction(0.0)
scaling_eps = Fraction(1.0)
for gid,epss in self.gid2epsilons.items():
for eps in epss:
assert(eps.value() >= 0.0)
if (eps.value() == 0.0):
continue
# if (scaling_eps < eps.value()):
if (scaling_eps > eps.value()):
scaling_eps = eps.value()
up_fac = Fraction(scaling_eps.denominator, scaling_eps.numerator)
# return tft_expr.ConstantExpr(up_fac)
# return tft_expr.ConstantExpr(up_fac * 512.0)
return tft_expr.ConstantExpr(up_fac / 8.0 ) # It is just a heuristic to divide by 8.0
def FreshErrorSumVar ():
global ID_ERROR_SUM
var_es = tft_expr.VariableExpr(tft_expr.ERR_SUM_PREFIX+str(ID_ERROR_SUM), Fraction, -1, False)
ID_ERROR_SUM = ID_ERROR_SUM + 1
return var_es
def rational_value (self):
if (self.type() == int):
return Fraction(self.value(), 1)
elif (self.type() == Fraction):
return self.value()
else:
sys.exit("ERROR: invalid value type for ConstantExpr")
def __str__ (self):
if (self.type() == int):
return "([Const:int] " + str(self.value()) + ")"
elif (self.type() == Fraction):
return "([Const:Fraction] " + str(float(self.value())) + ")"
else:
sys.exit("ERROR: invalid type of ConstantExpr found in __str__")
def __eq__ (self, rhs):
if (not isinstance(rhs, ConstantExpr)):
return False
if (self.type() == rhs.type()):
return (self.value() == rhs.value())
elif (self.type() == int and rhs.type() == Fraction):
return (Fraction(self.value(), 1) == rhs.value())
elif (self.type() == Fraction and rhs.type() == int):
return (self.value() == Fraction(rhs.value(), 1))
else:
sys.exit("ERROR: invlaid __eq__ scenario of ConstExpr")
def __gt__ (self, rhs):
if (not isinstance(rhs, ConstantExpr)):
return False
if (self.type() == rhs.type()):
return (self.value() > rhs.value())
elif (self.type() == int and rhs.type() == Fraction):
return (Fraction(self.value(), 1) > rhs.value())
elif (self.type() == Fraction and rhs.type() == int):
return (self.value() > Fraction(rhs.value(), 1))
else:
sys.exit("ERROR: invlaid __gt__ scenario of ConstExpr")
def __lt__ (self, rhs):
if (not isinstance(rhs, ConstantExpr)):
return False
if (self.type() == rhs.type()):
return (self.value() < rhs.value())
elif (self.type() == int and rhs.type() == Fraction):
return (Fraction(self.value(), 1) < rhs.value())
elif (self.type() == Fraction and rhs.type() == int):
return (self.value() < Fraction(rhs.value(), 1))
else:
sys.exit("ERROR: invlaid __lt__ scenario of ConstExpr")
def concEval (self, vmap = {}):
retv = self.value()
assert((type(retv) is int) or (type(retv) is float) or (isinstance(retv, Fraction)))
return retv
def __init__ (self, label, vtype, gid, check_prefix=True):
assert(isinstance(label, str))
assert(vtype == int or vtype == Fraction)
assert(type(gid) is int)
if (sys.version_info.major == 2):
sys.exit("Error: FPTuner is currently based on Python3 only...")
super(VariableExpr, self).__init__()
elif (sys.version_info.major == 3):
super().__init__()
else:
sys.exit("ERROR: not supported python version: " + str(sys.version_info))
if (gid == PRESERVED_CONST_GID):
assert(label.startswith(PRESERVED_CONST_VPREFIX))
self.vtype = vtype
self.operands.append(label)
self.gid = gid
if (check_prefix):
if (self.isPreservedVar()):
print("ERROR: the given label \"" + label + "\" has a preserved prefix...")
assert(False)
RegisterVariableExpr(self)
def concEval (self, vmap = {}):
assert(self in vmap.keys())
retv = vmap[self]
assert((type(retv) is int) or (type(retv) is float) or (isinstance(retv, Fraction)))
return retv
def setLB (self, lb):
assert(isinstance(lb, ConstantExpr))
if (self.operator.label in ["abs", "sqrt"]):
assert(lb.value() >= Fraction(0, 1))
self.lower_bound = lb
def setUB (self, ub):
assert(isinstance(ub, ConstantExpr))
if (self.operator.label in ["abs", "sqrt"]):
assert(ub.value() >= Fraction(0, 1))
self.upper_bound = ub
def EPS2HDLValue (eps):
assert(isinstance(eps, Fraction))
try:
i = tft_alloc.EpsValues().index(eps)
return i
except ValueError:
sys.exit("ERROR: not supporting argument for EPS2FID: " + str(eps))
def computeConstBinaryExpr (op, opd0, opd1):
assert(isinstance(op, EXPR.BinaryOp))
assert(isinstance(opd0, EXPR.ConstantExpr))
assert(isinstance(opd1, EXPR.ConstantExpr))
v0 = opd0.value()
v1 = opd1.value()
assert((type(v0) is int) or (type(v0) is float) or isinstance(v0, Fraction))
assert((type(v1) is int) or (type(v1) is float) or isinstance(v1, Fraction))
if (op.label == "+"):
return EXPR.ConstantExpr(v0 + v1)
elif (op.label == "-"):
return EXPR.ConstantExpr(v0 - v1)
elif (op.label == "*"):
return EXPR.ConstantExpr(v0 * v1)
elif (op.label == "/"):
return EXPR.ConstantExpr(v0 / v1)
elif (op.label == "^"):
return EXPR.ConstantExpr(v0 ** v1)
else:
assert(False)
# ========
# string to operator
# ========