Example #1
0
def mpf_matrix_fadd(A, B):
	"""
	Given a m x n matrix A and m x n matrix B either in numpy.matrix
	or mpmath.matrix format,
	this function computes the sum C = A + B exactly.
	The output matrix C is always given in the MPMATH format.


	Parameters
	----------
	A - m x n matrix
	B - m x n matrix

	Returns
	-------
	C - m x n matrix
	"""

	if isinstance(A, numpy.matrix):
		try:
			A = python2mpf_matrix(A)
		except ValueError as e:
			raise ValueError('Cannot compute exact sum of two matrices. %s' % e)
	else:
		if not isinstance(A, mpmath.matrix):
			raise ValueError('Cannot compute exact sum of two matrices: unexpected input type, excpected numpy.matrix or mpmath.matrix but got %s') %type(A)

	if isinstance(B, numpy.matrix):
		try:
			B = python2mpf_matrix(B)
		except ValueError as e:
			raise ValueError('Cannot compute exact sum of two matrices. %s' % e)
	else:
		if not isinstance(B, mpmath.matrix):
			raise ValueError('Cannot compute exact sum of two matrices: unexpected input type, excpected numpy.matrix or mpmath.matrix but got %s') % type(B)


	#here both A and B are mpmath matrices
	#we consider that A and B are MPF matrices if their first elements are of type mpf, let's test it

	if not isinstance(A[0,0], mpmath.mpf) or not isinstance(B[0,0], mpmath.mpf):
		raise ValueError('Cannot compute exact product of two matrices: cannot sum complex matrices.')

	#test sizes
	if A.rows != B.rows or A.cols != B.cols:
		raise ValueError('Cannot compute exact sum of two matrices: incorrect sizes.')

	m = A.rows
	n = A.cols
	C = mp.zeros(m, n)
	for i in range(0, m):
		for j in range(0, n):
			C[i,j] = mpmath.fadd(A[i,j], B[i,j], exact=True)
			if mpmath.isnan(C[i,j]) or mpmath.isinf(C[i,j]):
				print('WARNING: in matrix sum an abnormal number (NaN/Inf) occured: %f' % C[i,j])


	return C
Example #2
0
File: dTFmp.py Project: fixif/fixif
	def __init__(self, b, a):
		"""
		define a discrete transfer function with multiple precision coefficients
		Parameters
		----------
		b -  deg_b x 1 matrix of filter coefficients
		a -  deg_a x 1 matrix of filter coefficients

		Returns
		-------

		"""

		if not isinstance(b, mpmath.matrix) or not isinstance(a, mpmath.matrix):
			if isinstance(b, numpy.matrix) and isinstance(a, numpy.matrix):
				b = python2mpf_matrix(b)
				a = python2mpf_matrix(a)
			else:
				raise ValueError('Cannot create a dTFmp object: expected mpmath.matrix or numpy.matrix arguments but instead got %s and %s' % (type(b), type(a)))

		# check if user gave transposed matrices
		if b.cols > 1 and b.rows == 1:
			b = b.transpose()
		if a.cols > 1 and a.rows == 1:
			a = a.transpose()

		if a.cols != 1 or b.cols != 1:  # or b.rows != a.rows :
			raise ValueError('Cannot create a dTFmp pbject: incorrect sizes')


		n = a.rows
		if a[0, 0] != mpmath.mp.one:
			for i in range(0, n):
				# division cannot be performed exactly but we do it with doubled precision
				a[i, 0] = mpmath.fdiv(a[i, 0], a[0, 0], prec=a[i, 0]._mpf_[3] * 2)
				b[i, 0] = mpmath.fdiv(b[i, 0], b[0, 0], prec=b[i, 0]._mpf_[3] * 2)

		self._order = n - 1
		self._num = b
		self._den = a

		# cached sollya numerator and denominator
		self._sollya = None
Example #3
0
def mpf_matrix_lt_inverse(L):
	"""
	For a lower-triangular n x n real matrix L with 1s on the main diagonal
	this function computes its inverse X exactly such that
				    L * X = I
	Matrix L must be in the numpy.matrix of mpmath.matrix formats.
	The function returns X as n x n real a mpmath.matrix


	Parameters
	----------
	L - n x n lower-triangular matrix

	Returns
	-------
	X - n x n matrix

	"""

	if isinstance(L, numpy.matrix):
		try:
			L = python2mpf_matrix(L)
		except ValueError as e:
			raise ValueError('Cannot compute exact difference of two matrices. %s') % e
	else:
		if not isinstance(L, mpmath.matrix):
			raise ValueError('Cannot compute exact difference of two matrices: unexpected input type, excpected numpy.matrix or mpmath.matrix but got %s') % type(L)


	#checking the size
	if L.rows != L.cols:
		raise ValueError('Cannot compute inverse: matrix must be square but istead is %s x %s' % L.rows, L.cols)
	else:
		n = L.rows

	#checking if the matrix is indeed lower-triangular with 1s on the main diagonal
	for i in range(0,n):
		if L[i,i] != mpmath.mp.one:
			raise ValueError('Cannot compute inverse: matrix must have 1s on the main diagonal.')
		for j in range(i+1, n):
			if L[i,j] != mpmath.mp.zero:
				raise ValueError('Cannot compute inverse: matrix must be lower triangular.')


	X = mp.zeros(n, n)
	for i in range(0,n):
		X[:, i] = my_forward_subst(L, i)


	return X
Example #4
0
def test_computeMSBSIF(nSimulations=1000):

    sollya.settings.display = sollya.binary
    nu = 1
    ny = 1
    nx = 5
    F = random_Filter(nx, ny, nu, seed=5)
    #F = Butter(5, 1.2)
    #SS = LWDF.makeRealization(F)
    SS = State_Space.makeRealization(F)

    #a hardcoded example
    #A = np.matrix([[-0.1721,  0.004845,    0.2187],[0.004845,  -0.08567,   -0.1096], [0.2187,   -0.1096,   -0.4978]])
    #B = np.matrix([[1.533], [0], [0]])
    #C = np.matrix([-0.2256,    1.117,   -1.089])
    #D = np.matrix([0.03256])
    #F = Filter(A=A,B=B,C=C,D=D)
    #SS = State_Space.makeRealization(F)

    u_bar = np.bmat([np.ones([1, nu])])
    l_y_out = -15
    #msb_u = np.bmat([np.zeros([1, SS.q])])
    #lsb_u = -15 * np.bmat([np.ones([1, SS.q])])
    msb_u = 0
    lsb_u = -15

    msb = SS._compute_MSB(u_bar)
    lsb, error_budget_y = SS._compute_LSB(l_y_out)
    Y, N = mpf_get_representation(mpmath.mpf(error_budget_y))
    error_budget_y = sollya.SollyaObject(Y) * 2**sollya.SollyaObject(N)

    lsb_t = [lsb[0, i] for i in range(0, SS.l)]
    lsb_x = [lsb[0, i] for i in range(SS.l, SS.l + SS.n)]
    lsb_y = [lsb[0, i] for i in range(SS.l + SS.n, SS.l + SS.n + SS.p)]

    msb_ext = SS.compute_MSB_allvar_extended(u_bar, lsb_t, lsb_x, lsb_y)
    if (msb != msb_ext).any():
        print(
            'MSB computed with taking into account the propagation of the error due to the format (msb, lsb) differs from the initial format. Changing MSBs.\n'
        )
        print('new MSBs:')
        msb = msb_ext
        print(msb)

    msb_t = [msb[0, i] for i in range(0, SS.l)]
    msb_x = [msb[0, i] for i in range(SS.l, SS.l + SS.n)]
    msb_y = [msb[0, i] for i in range(SS.l + SS.n, SS.l + SS.n + SS.p)]

    fileID = './SIF-' + time.strftime("%d%m%Y-%H%M%S")
    filename = fileID + '.txt'
    with open(filename, 'a') as f_handle:
        f_handle.write('%d\n%d\n%d\n%d\n' % (SS.q, SS.l, SS.n, SS.p))
        #for i in range(0, SS.q):
        f_handle.write('%d %d\n' % (msb_u, lsb_u))
        for i in range(0, SS.l):
            f_handle.write('%d %d\n' % (msb_t[i], lsb_t[i]))
        for i in range(0, SS.n):
            f_handle.write('%d %d\n' % (msb_x[i], lsb_x[i]))
        for i in range(0, SS.p):
            f_handle.write('%d %d %s\n' %
                           (msb_y[i], l_y_out, str(error_budget_y).replace(
                               " ", "").replace("\n", "")))
        #f_handle.write('%s\n' % str(error_budget_y))

        #write_matrix_hex(f_handle, SS.Z, ' ')
        Z_sollya, Zrows, Zcols = mpf_matrix_to_sollya(python2mpf_matrix(SS.Z))

        for i in range(0, Zrows):
            for j in range(0, Zcols):
                f_handle.write('%s' % str(Z_sollya[i + j * Zcols]).replace(
                    " ", "").replace("\n", ""))
                f_handle.write(' ')
            f_handle.write('\n')

    f_handle.close()

    print('Filter: \n')
    print(SS)
    print('y_out was initially set to: %d\n' % l_y_out)
    print('LSBs:\n')
    print(lsb)
    print('MSBs:\n')
    print(msb)

    u = np.random.rand(1, nSimulations)

    # quantize the simulations to the format lsb_u bits
    u_sollya = mpf_matrix_to_sollya(
        mpmath.matrix([
            mpmath.nint(mp.mpf(u[0, i]) * 2**-lsb_u) / 2**-lsb_u
            for i in range(0, nSimulations)
        ]))[0]
    u_quantized = sollya_matrix_to_numpy(u_sollya, 1, nSimulations)

    # perform simulations either in exact or rounded

    y_simulated_sollya_exact = SS.to_dSSexact().simulate_rounded(u_quantized,
                                                                 prec=53)
    y_simulated_sollya = mpf_matrix_to_sollya(SS.to_dSSexact().simulate(
        u_quantized, exact=True))[0]

    filename = fileID + 'simulation' + '.txt'
    with open(filename, 'a') as f_handle:
        f_handle.write('%d\n' % nSimulations)
        for i in range(0, nSimulations):
            #for j in range (0, nu):
            f_handle.write('%s' %
                           str(u_sollya[i]).replace(" ", "").replace("\n", ""))
            f_handle.write('\n')
            #for j in range(0,ny):
            f_handle.write(
                '%s ' %
                str(y_simulated_sollya[i]).replace(" ", "").replace("\n", ""))
            f_handle.write('\n')
            #f_handle.write(str(y_simulated_exact_sollya[i]) + ' ')
            #f_handle.write('\n')

    f_handle.close()

    return True
Example #5
0
	def simulate(self, u, exact=True, x0=None):
		"""
		Given a vector of inputs u this function simulates
		the output of the dSS system on these inputs.

		If the flag exact is set to True (default) then the simulation is performed
		exactly. Otherwise, on each iteration the SoPs are computed exactly and then the state variables
		are rounded to double precision.

		Parameters
		----------
		u - vector of inputs in the format numpy.matrix or mpmath.matrix of size q x T
		x0 - vector of inital states, if specified must be of size n x 1
		exact - a flag wether to perform simulations in exact (by default) or to perform

		Returns
		-------
		y -  p x T matrix of outputs

		"""

		if not isinstance(u, mpmath.matrix):
			if isinstance(u, numpy.matrix):
				u = python2mpf_matrix(u)
			else:
				raise ValueError('Cannot perform simulation: u must be either mpmath.matrix or numpy.matrix')

		if u.rows != self._q:
			raise ValueError('Cannot perform somulation: u is of incorrect size')

		xk = mpmath.mp.zeros(self._n, 1)
		if x0:
			if not isinstance(x0, mpmath.matrix):
				if isinstance(x0, numpy.matrix):
					xk = python2mpf_matrix(x0)
				else:
					raise ValueError('Cannot perform simulation: initial state specified in incorrect format')

		if xk.rows != self._n:
			raise ValueError('Cannot perform simulation: initial state is of incorrect size')

		T = u.cols
		yk = mpmath.mp.zeros(self._p, T)

		if exact:
			for i in range(0, T):
				xkp1 = mpf_matrix_fmul(self._A, xk)
				xkp1 = mpf_matrix_fadd(xkp1, mpf_matrix_fmul(self._B, u[:, i]))

				yk[:, i] = mpf_matrix_fmul(self._C, xk)
				yk[:, i] = mpf_matrix_fadd(yk[:, i], mpf_matrix_fmul(self._D, u[:, i]))

				xk = xkp1

		else:
			for i in range(0, T):
				xkp1 = mpf_matrix_fmul(self._A, xk)
				xkp1 = mpf_matrix_fadd(xkp1, mpf_matrix_fmul(self._B, u[:, i]))

				yk[:, i] = mpf_matrix_fmul(self._C, xk)
				yk[:, i] = mpf_matrix_fadd(yk[:, i], mpf_matrix_fmul(self._D, u[:, i]))

			for i in range(0, xk.rows):
				xk[i, 0] = mpmath.fadd(xkp1[i, 0], mpmath.mp.zero, prec=64, rounding='n')


		return yk
Example #6
0
	def __init__(self, A, B, C, D):
		"""
		The dSSmp class describes a discrete state space realization
		with coefficients in multiple precision

	A state space system :math:`(A,B,C,D)` is defined by

	.. math::

		\left\lbrace \begin{aligned}
		x(k+1) &= Ax(k) + Bu(k) \\
		y(k)   &= Cx(k) + Du(k)
		\end{aligned}\right.

	with :math:`A \in \mathbb{R}^{n \times n}, B \in \mathbb{R}^{n \times q}, C \in \mathbb{R}^{p \times n} \text{ and } D \in \mathbb{R}^{p \times q}`.

	**Dimensions of the state space :**

	.. math::
		:align: left
		n,p,q \in \mathbb{N}

	==  ==================
	n   number of states
	p   number of outputs
	q   number of inputs
	==  ==================

		Parameters
		----------
		A
		B
		C
		D

		Returns
		-------

		"""

		if not isinstance(A, mpmath.matrix):
			if isinstance(A, numpy.matrix):
				A = python2mpf_matrix(A)
			else:
				raise ValueError('Cannot create dSSmp object: expected mpmath.matrix of numpy.matrix')
		if not isinstance(B, mpmath.matrix):
			if isinstance(B, numpy.matrix):
				B = python2mpf_matrix(B)
			else:
				raise ValueError('Cannot create dSSmp object: expected mpmath.matrix of numpy.matri')
		if not isinstance(C, mpmath.matrix):
			if isinstance(C, numpy.matrix):
				C = python2mpf_matrix(C)
			else:
				raise ValueError('Cannot create dSSmp object: expected mpmath.matrix of numpy.matrix')
		if not isinstance(D, mpmath.matrix):
			if isinstance(D, numpy.matrix):
				D = python2mpf_matrix(D)
			else:
				raise ValueError('Cannot create dSSmp object: expected mpmath.matrix of numpy.matrix')


		# checking sizes
		# n = A.rows


		if A.rows != A.cols:
			raise ValueError('Cannot create dSSmp object: incorrect sizes')
		else:
			self._n = A.rows

		if B.rows != self._n:
			raise ValueError('Cannot create dSSmp object: incorrect sizes')
		else:
			self._q = B.cols

		if C.cols != self._n:
			raise ValueError('Cannot create dSSmp object: incorrect sizes')
		else:
			self._p = C.rows

		if D.rows != self._p or D.cols != self._q:
			raise ValueError('Cannot create dSSmp object: incorrect sizes')

		self._A = A
		self._B = B
		self._C = C
		self._D = D