Esempio n. 1
0
def SoP(R, u_bar, w_txyu, w_z, latex=None):

    # FPF of t, x, u and y
    zeta_bar = R.Hzeta.WCPG() * u_bar
    FPF_txy = array([Constant(value=z[0, 0], wl=w_txyu).FPF for z in zeta_bar])
    FPF_txu = r_[FPF_txy[:-1], Constant(value=u_bar, wl=w_txyu).FPF]

    # Coefficients
    FPF_Z = vectorize(lambda x: Constant(value=x, wl=w_z).FPF)(R.Zcomp)
    # print(FPF_Z)

    # var Names
    varT = [v.toStr() for v in R._varNameT]
    varX = [v.toStr() for v in R._varNameX]
    varU = [v.toStr() for v in R._varNameU]
    varTXU = varT + varX + varU
    varXp1 = [v.toStr(suffix='p' if R.isPnut() else '') for v in R._varNameX]
    varY = [v.toStr() for v in R._varNameY]
    varTXY = varT + varXp1 + varY

    # SoP
    for i in range(R.Z.shape[0]):
        str, fsop = strSOP(varTXY[i], FPF_txy[i], R.Zcomp[i, :].tolist()[0],
                           FPF_Z[i, :].tolist()[0], varTXU, FPF_txu)
        print(str)
        print('\n'.join(f.ParenthesisNotation() for f in fsop))
Esempio n. 2
0
def testZero():
	""" Check value zero. """
	c = Constant(value=0, wl=8)
	assert(c.FPF == FPF(msb=7, lsb=0))

	c = Constant(value=0.0, wl=8)
	assert (c.FPF == FPF(msb=7, lsb=0))

	c = Constant(value="0", wl=8)
	assert (c.FPF == FPF(msb=7, lsb=0))

	c = Constant(value=mpf(0), wl=8)
	assert (c.FPF == FPF(msb=7, lsb=0))

	# with FPF:
	f = FPF(msb=7, lsb=-1)
	c = Constant(value=0, fpf=f)
	assert (c.FPF == f)

	c = Constant(value=0.0, fpf=f)
	assert (c.FPF == f)

	c = Constant(value="0", fpf=f)
	assert (c.FPF == f)

	c = Constant(value=mpf(0), fpf=f)
	assert (c.FPF == f)
Esempio n. 3
0
def checkConstantInit(val, st, signed, wl, fpf):
	"""Check the constant init, by comparing the three methods"""
	methods = ('', 'log','Benoit','threshold')
	c = [Constant(val, wl=wl, signed=signed, method=method, fpf=fpf, name=st) for method in methods]

	# check the mantissa range
	for cst in c:
		if signed:
			assert((-2 ** (wl - 1) <= cst.mantissa < -2 ** (wl - 2)) or (2 ** (wl-2) <= cst.mantissa < 2 ** (wl-1)))
		else:
			assert(2 ** (wl-1) <= cst.mantissa < 2 ** wl)
		# check str and value method
		str(c)
		repr(c)
		assert(cst.value == val)

	# compare the three constants (compare their FPF, mantissa and approx)
	cst = c[0]
	for i in range(1,len(c)):
		assert(cst.FPF == c[i].FPF)
		assert(cst.mantissa == c[i].mantissa)
		assert(cst.approx == c[i].approx)

	# check if |c - c_FxP| < 2 ^(l-1)
	for cst in c:
		if cst.mantissa == -2**(cst.FPF.wl-1):
			assert(almosteq(cst.approx, val, abs_eps=ldexp(1, cst.FPF.lsb)))
		else:
			assert (almosteq(cst.approx, val, abs_eps=ldexp(1, cst.FPF.lsb - 1)))

	# check relative and absolute error
	cst = c[0]
Esempio n. 4
0
def aSoP_submit():
	"""Manage the aSoP data"""
	# get data
	constants = request.forms.get('constants').split("\r\n")
	var_FPF = request.forms.get('var_FPF').split("\r\n")
	var_wi = request.forms.get('var_wi').split("\r\n")
	beta_final = request.forms.get('beta_final')
	# conversion
	try:
		beta_final = float(beta_final)
	except ValueError:
		return "the beta final is not valid"

	cons = []
	for c in constants:
		try:
			c_v, c_w = c.split(',')
			cons.append(Constant(float(c_v), int(c_w)))
		except ValueError:
			return "The constants cannot be converted to float"

	try:
		_ = [FPF(formatStr=f) for f in var_FPF]
	except ValueError:
		return "Invalid FPF format"

	var_w = []  # variable wordlength
	var_i = []  # variable interval
	for wi in var_wi:
		try:
			w, i1, i2 = wi.split(',')
			var_w.append(int(w))
			var_i.append((float(i1), float(i2)))
		except ValueError:
			return "Invalid wordlength,inteval format"
	# now call Benoit's function to do the aSoP...
	interval_var = []
	for w, i in zip(var_w, var_i):
		interval_var.append(Variable(value_inf=i[0], value_sup=i[1], wl=w))  # beta=w changed in wl=w
	return simple_cleaned_SoP(cons, interval_var, beta_final)
Esempio n. 5
0
def Sum_service(outputFormat):
	"""Generate Sum of FPF image (or LaTeX)"""
	try:
		# get data
		formats = request.query.sum.split(":")
		# build each FPF
		F = [FPF(formatStr=f.replace('_', '.')) for f in formats]
		resultFPF = FPF(formatStr=request.query.result.replace('_', '.'))
	except ValueError:
		return "Invalid Fixed-Point Formats"  # TODO: message d'erreur plus explicite ?
	# process the options
	options = optionManager(request.query)
	options.addOptionalOption("colors", colorThemes, "YG")  # color theme
	options.addOptionalOption("width", lambda x: int(x), '500')  # used for jpg, png, tiff only
	options.addOptionalOption("height", lambda x: int(x), '1300')  # used for jpg, png, tiff only (default value is very large, to let the user specify width=2000 without being blocked by the height:300)
	options.addOptionalOption("axis", {"yes": True, "no": False}, "no")  # display a vertical axis on bit=0
	options.addOptionalOption("sort", ("no", "lsb", "msb"), "no")
	options.addOptionalOption("hatches", {"yes": True, "no": False}, "no")  # display hatches for the bits outside the FPF of the result
	options.addOptionalOption("xshift", lambda x: float(x), '0')
	options.addOptionalOption("yshift", lambda x: float(x), '0')
	# build the LaTeX from the FxP SoP (fake SoP with constant equal to 1 and variable with msb decreased by 1)
	sop = FxPSoP([Constant(1, wl=2) for _ in F], ["" for _ in F], [FPF(msb=f.msb-1, lsb=f.lsb) for f in F], ["" for _ in F], resultFPF)
	latexFPF = sop.sumLaTeX(**options.getValues())
	# generate the files
	sumName = "-".join([f.Qnotation() for f in F + [resultFPF]])
	if outputFormat != 'tex':
		# prepare the conversion argument (in the LaTeX class 'standalone')
		if outputFormat != "pdf":
			convert = "convert={size=%dx%d,outext=.%s}," % (options['width'], options['height'], outputFormat)
		else:
			convert = ""
		# encompass it into a complete latex file
		latexStr = template("latex-FPF.tex",
		                    options.getValues({"FPF": latexFPF, "format": outputFormat, "convert": convert}))
		# create the image from the latex
		return createImageFromLaTeX(sumName + "?" + str(options), latexStr, outputFormat)
	else:
		return "\t%Generated from " + Config.baseURL + "Sum.tex?" + request.query_string + "\n" + latexFPF
Esempio n. 6
0
def Constant_service(constantsInter):
	"""Service that generates all the information for the transformation of a constant
	It returns a JSON object, containing dictionaries of: the FPF, the integer associated, the errors, etc. of the constants and intervals given in constantsInter.
	Ex: answer to /Constant/zzzz?option1=xxx&option2=yyy
	where zzzz is string of constants or a intervals seperated by @
	
	Possible options:
		FPF: string describing the FPF (Q-notation or parenthesis notation) 
		WL: word-length
			-> only one of these two options should be given !
		signed: (bool) indicates if the constant is represented with a signed constant

	It returns a json object containing dictionaries related to each constant or interval with the following fields
		error: (string) indicates if there is an error
		FPF: (string) the FPF used for the conversion (usefull if the WL was given)
		FPF_image: (url) the url used for the image of the FPF
	and for a constant (not for an interval)	
		integer: the associated Fixed-Point integer
		bits: 2's complement binary of the integer
		approx: the approximated value
		error_abs: absolute error
		error_rel: relative error"""
	# get the FPF
	q = request.query
	if "FPF" in q:
		try:
			F = FPF(formatStr=q["FPF"])
			WL = None
		except ValueError:
			return {"error": "invalid FPF"}
	# or get the word-length
	elif "WL" not in q:
		# return {'error':"At least one option 'FPF' or 'WL' must be given"}
		WL = 8
		F = None
	else:
		try:
			WL = int(q["WL"])
		except ValueError:
			return {"error": " The Word-length must be an integer"}
		F = None
	# and get the signedness
	if "signed" in q:
		signed = q["signed"] != 'no'
	else:
		signed = True

	returningJson = {}


	exps = []   # List containing input constants / intervals / their evaluation.

	# Treating the raw input from client:
	for i in range(0, len(constantsInter.split("@"))):
		line = constantsInter.split("@")[i].replace("div", "/")  # replacing div with the real division sign
		line = line.strip()
		if len(line) > 0:  # empty strings shouldn't be treated
			try:    # if it's a normal constant then it should simply be added to exps
				Constant(value=line, wl=100, signed=signed)
				exps.append({'exp': line, 'val': line, 'const': True})
			except ValueError:     # it's either an interval or a mathematical expression that needs to be evaluated
				if line[0] == '[':  # Since the input format is once validated in client side, we can simply use this condition to determine whether it's an interval or not
					if WL:
						exps.append({'exp': line, 'val': get_interval_inf(line, WL), 'const': False})
					else:
						exps.append({'exp': line, 'val': get_interval_inf(line, F.wl), 'const': False})
				else:   # Not an interval but a mathematical expression that needs to be evaluated
					if WL:
						exps.append({'exp': line, 'val': evaluate_exp(line, WL), 'const': True})
					else:
						exps.append({'exp': line, 'val': evaluate_exp(line, F.wl), 'const': True})

	counter = 0
	for expression in exps:
		constInter = expression['val']
		if len(constInter) != 0:
			inter = reobj_interval.match(constInter)  # is it an interval ?

			# get the constant
			if expression['const'] and expression['val'] != "NaN":
				try:
					C = Constant(value=expression['val'], wl=WL, signed=signed, fpf=F)
					dico = return_dictionary_constant(C)
					dico['value'] = expression['exp']
					returningJson[counter] = dico
				except ValueError:
					Cs = Constant(value=expression['val'], wl=F.wl, signed=signed)
					dico = return_dictionary_constant(Cs)
					dico['value'] = expression['exp']
					errStr = "Not possible with the asked FPF; suggestion: " + str(Cs.FPF)
					dico["error"] = errStr
					returningJson[counter] = dico
			elif inter:
				try:
					val_inf = float(inter.group(1))
					val_sup = float(inter.group(2))
				# TODO: conversion str->float... faire avec GMP?
				except ValueError:
					returningJson[counter] = {'value': expression['exp'], 'error': 'The interval must be of the form [xxx;yyy] where xxx and yyy are litteral'}
				try:
					if WL:
						C = Constant(value=val_sup, wl=WL)
						if float(Constant(value=val_inf, wl=WL).FPF.msb) > float(C.FPF.msb):
							C = Constant(value=val_inf, wl=WL)
					else:
						C = Constant(value=val_sup, fpf=F)
						if float(Constant(value=val_inf, fpf=F).FPF.msb) > float(C.FPF.msb):
							C = Constant(value=val_inf, fpf=F)
					dico = return_dictionary_constant(C)
					dico["value"] = expression['exp']
					returningJson[counter] = dico
				except ValueError:  # None of the interval values could be represented with the given format
					Cs = Constant(value=val_sup, wl=F.wl, signed=signed)
					if float(Constant(value=val_inf, wl=F.wl).FPF.msb) > float(Cs.FPF.msb):
						Cs = Constant(value=val_inf, wl=F.wl)
					dico = return_dictionary_constant(Cs)
					dico["value"] = expression['exp']
					errStr = "Not possible with the asked FPF; suggestion: " + str(Cs.FPF)
					dico["error"] = errStr
					returningJson[counter] = dico
			else:
				if expression["val"] != "NaN":
					returningJson[counter] = {
						'value': expression['exp'],
						'error': "The url should contain the constant or the interval (ex '/Constant/12.44' or '/Constant/[-120;10])'"
					}  # General Error
				else:
					returningJson[counter] = {
						'value': expression['exp'],
						'error': "Arithmetic problem"
					}
			counter += 1
	return returningJson
Esempio n. 7
0
		def quant(x, wl):
			"""Simple function to quantized x with w bits (fixed-point style)"""
			return Constant(x, wl=wl, signed=True).approx if x else 0
Esempio n. 8
0
def test_construct(method):
	"""
	Test the Constant constructor
	"""
	c = Constant(value=127, wl=8, signed=False, method=method)
	assert(c.FPF.wml() == (8, 6, -1))
	assert(c.mantissa == 254)

	c = Constant(value=127, wl=8, signed=True, method=method)
	assert(c.FPF.wml() == (8, 7, 0))
	assert(c.mantissa == 127)
	
	c = Constant(value=-127, wl=8, signed=True, method=method)
	assert(c.FPF.wml() == (8, 7, 0))
	assert(c.mantissa == -127)
	
	c = Constant(value=0.36567, wl=8, signed=True, method=method)
	assert(c.FPF.wml() == (8, -1, -8))
	assert(c.mantissa == 94)
	assert(c.approx == 94*2**-8)
	
	with pytest.raises(ValueError):
		Constant(value=-12, wl=12, signed=False, method=method)

	with pytest.raises(ValueError):
		Constant(value=42, wl=1)

	# particular cases
	c = Constant(value=127.78, wl=8, signed=False, method=method)
	assert(c.FPF.wml() == (8, 7, 0))
	assert(c.mantissa == 128)
	c = Constant(value=-128.1, wl=8, signed=True, method=method)
	assert(c.FPF.wml() == (8, 7, 0))
	assert(c.mantissa == -128)
	c = Constant(value=127.7, wl=8, signed=True, method=method)
	assert(c.FPF.wml() == (8, 8, 1))
	assert(c.mantissa == 64)
	
	c = Constant(value=-128.25, wl=8, signed=True, method=method)
	assert(c.FPF.wml() == (8, 7, 0))
	assert(c.mantissa == -128)
	c = Constant(value=-128.5, wl=8, signed=True, method=method)
	assert(c.FPF.wml() == (8, 7, 0))
	assert(c.mantissa == -128)
	c = Constant(value=-128.6, wl=8, signed=True, method=method)
	assert(c.FPF.wml() == (8, 7, 0))
	assert(c.mantissa == -128)
	c = Constant(value=-129, wl=8, signed=True, method=method)
	assert(c.FPF.wml() == (8, 7, 0))        # tie to even (otherwise, with ties to away, it should be (8,8,1), and mantissa=-65
	assert(c.mantissa == -128)
	c = Constant(value=-129.01, wl=8, signed=True, method=method)
	assert(c.FPF.wml() == (8, 8, 1))
	assert(c.mantissa == -65)


	# wrong combination of arguments
	with pytest.raises(ValueError):
		Constant(value=12)
	with pytest.raises(ValueError):
		Constant(value=12, signed=True)
	with pytest.raises(ValueError):
		Constant(value=12, wl=5, fpf=FPF(8, 7, 0))

	# construct with a given FPF
	with pytest.raises(ValueError):
		Constant(value=258.54, wl=8, fpf=FPF(8, 7, 0))
	c = Constant(value=127.1, fpf=FPF(8, 7, 0))
	assert(c.FPF.wml() == (8, 7, 0))
	with pytest.raises(ValueError):
		Constant(value=132, fpf=FPF(8, 7, 0, signed=True))
	with pytest.raises(ValueError):
		Constant(value=300,  fpf=FPF(8, 7, 0, signed=False))
	with pytest.raises(ValueError):
		Constant(value=0.123, fpf=FPF(8, 7, 0))