def test_inv_lowtr(): A = numpy.random.rand(5, 5) L = numpy.zeros([5, 5]) for j in range(0, 5): for i in range(j + 1, 5): L[i, j] = A[i, j] L = MPFMatrix(L) + MPFMatrix(mpmath.eye(5)) Linv = L.inv_lowtr() assert (Linv * L).almost_close(MPFMatrix(mpmath.eye(5)))
def test_mul_exact(): Impmath = mpmath.eye(5) A = numpy.random.rand(5, 5) A = MPFMatrix(A) C0 = A.mul_exact(MPFMatrix(Impmath)) assert C0.equal(A)
def rotate_3D_mp(x, y): xnorm = mpm.norm(x) ynorm = mpm.norm(y) cos = mpm.fdot(x,y)/(xnorm*ynorm) sin = mpm.sqrt(1.-cos**2) K = (y.T*x-x.T*y)/(xnorm*ynorm*sin) return mpm.eye(3) + sin*K + (1.-cos)*(K*K)
def abcd(self): d = self._distance T = mp.eye(2) T[0, 1] = d return T
def abcd(self): f = self._focal_length T = mp.eye(2) T[1, 0] = -1 / f return T
def full_transfer_matrix(self, Energy): # Функция, создающая полную матрицу переноса через всю заданную гетероструктуру M = [] Mt = [] N = [] E = Energy T = mp.eye(2) a = np.zeros(len(self.structure_width_vector) + 1) # Полная матрица переноса через всю структуру for number in range(self.number_of_layers - 1): if number == max(range(self.number_of_layers - 1)): T = self.matrix_invers( self.matrix_M(number + 1, E, self.a[number + 2])) * self.matrix_M( number, E, self.a[number + 1]) * T else: T = self.matrix_N( number + 1, E, self.a[number + 2]) * self.matrix_invers( self.matrix_M(number + 1, E, self.a[number + 2])) * self.matrix_M( number, E, self.a[number + 1]) * T # Возвращает элемент Т(2,2) матрицы Т return T[1, 1]
def full_transfer_matrix(self, Energy): # Функция, создающая полную матрицу переноса через всю заданную гетероструктуру M = [] Mt = [] N = [] T = mp.eye(2) for number in range(self.number_of_layers): M.append(self.matrix_M(number, Energy)) Mt.append(self.matrix_invers(self.matrix_M(number, Energy))) if not number == min(range( self.number_of_layers)) and not number == max( range(self.number_of_layers)): N.append(self.matrix_N(number, Energy)) else: N.append(0) # Полная матрица переноса через всю структуру for number in range(self.number_of_layers - 1): if number == max(range(self.number_of_layers - 1)): T = Mt[number + 1] * M[number] * T else: T = N[number + 1] * Mt[number + 1] * M[number] * T # Возвращает элемент Т(2,2) матрицы Т return T[1, 1]
def abcd(self): n1 = self._n1 n2 = self._n2 T = mp.eye(2) T[1, 1] = n1 / n2 return T
def cocycle(word, mathcalA): #computes A^(n)(x) for x a periodic point d = mathcalA('0').rows A = mpmath.eye(d) for i in range(len(word)): A = A * mathcalA(word) word = shift(word) return A
def rotate_mp(pts, x, y): out = mpm.zeros(pts.rows, pts.cols) v = x/mpm.norm(x) cos = mpm.fdot(x,y) / (mpm.norm(x), mpm.norm(y)) sin = mpm.sqrt(1.-cos**2) u = y - mpm.fdot(v, y) * v mat = mpm.eye(x.cols) - u.T * u - v.T * v \ + cos * u.T * u - sin * v.T * u + sin * u.T * v + cos * v.T * v return mat
def test_create_hex_grid(self): b = CoherentBasis.create_hexagonal_grid(0, 1.2, 1) self.assertEqual(len(b.states), 7) trafo = b.trafo inv_trafo = b.inv_trafo self.assertIsInstance(trafo, numpy.ndarray) self.assertIsInstance(inv_trafo, numpy.ndarray) I1 = numpy.abs(numpy.dot(trafo, inv_trafo)) I2 = numpy.array(mpmath.eye(7).tolist()) self.assertTrue(((I1 - I2) < 1e-14).all())
def test_mev(): output("""\ reim:{$[0>type x;1 0*x;2=count x;x;'`]}; mc:{((x[0]*y 0)-x[1]*y 1;(x[0]*y 1)+x[1]*y 0)}; mmc:{((.qml.mm[x 0]y 0)-.qml.mm[x 1]y 1;(.qml.mm[x 0]y 1)+.qml.mm[x 1]y 0)}; mev_:{[b;x] if[2<>count wv:.qml.mev x;'`length]; if[not all over prec>=abs mmc[flip vc;flip(flip')(reim'')flip x]- flip(w:reim'[wv 0])mc'vc:(flip')(reim'')(v:wv 1);'`check]; / Normalize sign; LAPACK already normalized to real v*:1-2*0>{x a?max a:abs x}each vc[;0]; (?'[prec>=abs w[;1];w[;0];w];?'[b;v;0n])};""") for A in eigenvalue_subjects: if A.rows <= 3: V = [] for w, n, r in A.eigenvects(): w = sp.simplify(sp.expand_complex(w)) if len(r) == 1: r = r[0] r = sp.simplify(sp.expand_complex(r)) r = r.normalized() / sp.sign(max(r, key=abs)) r = sp.simplify(sp.expand_complex(r)) else: r = None V.extend([(w, r)] * n) V.sort(key=lambda (x, _): (-abs(x), -sp.im(x))) else: Am = mp.matrix(A) # extra precision for complex pairs to be equal in sort with mp.extradps(mp.mp.dps): W, R = mp.eig(Am) V = [] for w, r in zip(W, (R.column(i) for i in range(R.cols))): w = mp.chop(w) with mp.extradps(mp.mp.dps): _, S, _ = mp.svd(Am - w * mp.eye(A.rows)) if sum(x == 0 for x in mp.chop(S)) == 1: # nullity 1, so normalized eigenvector is unique r /= mp.norm(r) * mp.sign(max(r, key=abs)) r = mp.chop(r) else: r = None V.append((w, r)) V.sort(key=lambda (x, _): (-abs(x), -x.imag)) W, R = zip(*V) test("mev_[%sb" % "".join("0" if r is None else "1" for r in R), A, (W, [r if r is None else list(r) for r in R]), complex_pair=True)
def test_mev(): output("""\ reim:{$[0>type x;1 0*x;2=count x;x;'`]}; mc:{((x[0]*y 0)-x[1]*y 1;(x[0]*y 1)+x[1]*y 0)}; mmc:{((.qml.mm[x 0]y 0)-.qml.mm[x 1]y 1;(.qml.mm[x 0]y 1)+.qml.mm[x 1]y 0)}; mev_:{[b;x] if[2<>count wv:.qml.mev x;'`length]; if[not all over prec>=abs mmc[flip vc;flip(flip')(reim'')flip x]- flip(w:reim'[wv 0])mc'vc:(flip')(reim'')(v:wv 1);'`check]; / Normalize sign; LAPACK already normalized to real v*:1-2*0>{x a?max a:abs x}each vc[;0]; (?'[prec>=abs w[;1];w[;0];w];?'[b;v;0n])};""") for A in eigenvalue_subjects: if A.rows <= 3: V = [] for w, n, r in A.eigenvects(): w = sp.simplify(sp.expand_complex(w)) if len(r) == 1: r = r[0] r = sp.simplify(sp.expand_complex(r)) r = r.normalized() / sp.sign(max(r, key=abs)) r = sp.simplify(sp.expand_complex(r)) else: r = None V.extend([(w, r)]*n) V.sort(key=lambda (x, _): (-abs(x), -sp.im(x))) else: Am = mp.matrix(A) # extra precision for complex pairs to be equal in sort with mp.extradps(mp.mp.dps): W, R = mp.eig(Am) V = [] for w, r in zip(W, (R.column(i) for i in range(R.cols))): w = mp.chop(w) with mp.extradps(mp.mp.dps): _, S, _ = mp.svd(Am - w*mp.eye(A.rows)) if sum(x == 0 for x in mp.chop(S)) == 1: # nullity 1, so normalized eigenvector is unique r /= mp.norm(r) * mp.sign(max(r, key=abs)) r = mp.chop(r) else: r = None V.append((w, r)) V.sort(key=lambda (x, _): (-abs(x), -x.imag)) W, R = zip(*V) test("mev_[%sb" % "".join("0" if r is None else "1" for r in R), A, (W, [r if r is None else list(r) for r in R]), complex_pair=True)
def q_eit_standing_wave(Delta, Deltac, Omega, g1d, periodLength, phaseShift): if Delta == Deltac: return 0 gprime = 1 - g1d kd = pi / periodLength Mcell = eye(2) for i in range(periodLength): OmegaAtThisSite = Omega * cos(kd * i + pi * phaseShift) beta3 = (g1d * (Delta - Deltac)) / ( (-2.0j * Delta + gprime) * (Delta - Deltac) + 2.0j * OmegaAtThisSite**2) M3 = matrix([[1 - beta3, -beta3], [beta3, 1 + beta3]]) Mf = matrix([[exp(1j * kd), 0], [0, exp(-1j * kd)]]) Mcell = Mf * M3 * Mcell ret = (1.0 / periodLength) * acos(-0.5 * (Mcell[0, 0] + Mcell[1, 1])) return ret
def compute_pw_coal_rates(Nes, ms, ts, popmaps): """Given a list of population sizes and the migration matrix, one for each time slice, compute the expected coalescent rates for all possible pairs of lines. Uses the comp_pw_coal_cont function to do this for each time slice. The lists ms and Nes must be ordered from most recent to most ancient. Here ts is the list of time slice lengths - in the same order. popmaps is a list which tells which pops merge back in time at the beginning of this time slice. Each entry of popmaps is a list of arrays or tuples with all pops that merge into one """ numslices = len(ts) numpops = len(Nes[0]) nr = numpops * (numpops + 1) / 2 + 1 exp_rates = mp.zeros(nr - 1, numslices) P0 = mp.eye(nr) for i in xrange(numslices): Ne_inv = [ 1.0 / x for x in Nes[i] ] mtemp = ms[i] oldnumpops = numpops numpops = len(Ne_inv) m = np.zeros((numpops, numpops)) cnt = 0 if len(popmaps[i]) == numpops: P0 = converge_pops(popmaps[i], P0) elif len(popmaps[i]) > 0: raise Exception('Population map and other parameters do not match ' + str(i)) for ii in xrange(numpops): for jj in xrange(ii + 1, numpops): m[ii, jj] = m[jj, ii] = mtemp[cnt] cnt += 1 Q = comp_pw_coal_cont(m, Ne_inv) eQ = expM(ts[i] * Q) P = P0 * eQ exp_rates[:, i] = P[0:nr - 1, P.cols - 1] P0 = P0 * conv_scrambling_matrix(eQ) for r in xrange(exp_rates.rows): for c in xrange(exp_rates.cols): if exp_rates[r, c] < 0: exp_rates[r, c] = 0 return exp_rates
def test_mul(): A = numpy.random.rand(5, 5) I = numpy.eye(5) Z = numpy.zeros([5, 5]) Impmath = mpmath.eye(5) Zmpmath = mpmath.zeros(5, 5) A = MPFMatrix(A) C0 = A * I assert C0.almost_close(A) C1 = A * Impmath assert C1.almost_close(A) C2 = MPFMatrix(I) * A assert C2.almost_close(A) C3 = A * Z assert C3.almost_close(Z) C4 = A * Zmpmath assert C4.almost_close(Zmpmath)
def Han_algorithm(B, m, dim): """ From Insu Han, Dmitry Malioutov and Jinwoo Shin: Large-scale Log-determinant Computation through Stochastic Chebyshev Expansions, Proceedings of the 32 nd International Conference on Machine Learning, Lille, France, 2015. JMLR: W&CP volume 37 :param B: Square input Matrix :param m: Order of chebyshev approximation :param dim: Dimension of input Matrix :return G: log-determinant of B for cases, where all eigenvalues of B lie within (0, 1) """ B = mp.eye(12) - B G = 0 v = mp.matrix(dim, 1) w = mp.matrix(dim, 3) for i in range(m): for j in range(dim): v[j] = random.choice([-1, 1]) u = coeffs[0] * v n = len(coeffs) if m > 1: w[:, 0] = v w[:, 1] = B * v u = u + coeffs[1] * v for k in range(1, n, 1): w[:, 2] = 2 * B * w[:, 1] - w[:, 0] u = u + coeffs[k] * w[:, 2] w[:, 0] = w[:, 1] w[:, 1] = w[:, 2] G = G + v.T * u/m return G
def QSidentity(sz): if QSMODE == MODE_NORM: return np.matrix(np.identity(sz, dtype=np.complex128)) else: return mpmath.eye(sz)
], 'agm': [ 'primitive', [lambda x, y: mp.agm(x) if y is None else mp.agm(x, y[0]), None] ], # 'matrix': [ 'primitive', [ lambda x, y: mp.matrix(x) if isa(x, Vector) else mp.matrix(x) if y is None else mp.matrix(x, y[0]), None ] ], 'matrix-ref': ['primitive', [lambda x, y: x[y[0], y[1], [0]], None]], 'matrix-set': [ 'primitive', [lambda x, y: matrix_set(x, y[0], y[1][0], y[1][1][0]), None] ], 'zeros': ['primitive', [lambda x, y: mp.zeros(x), None]], 'ones': ['primitive', [lambda x, y: mp.ones(x), None]], 'eye': ['primitive', [lambda x, y: mp.eye(x), None]], 'diag': ['primitive', [lambda x, y: mp.diag(x), None]], 'randmatrix': ['primitive', [lambda x, y: mp.randmatrix(x), None]], 'matrix-inv': ['primitive', [lambda x, y: x**(-1), None]], 'norm': [ 'primitive', [lambda x, y: mp.norm(x) if y is None else mp.norm(x, y[0]), None] ], 'mnorm': ['primitive', [lambda x, y: mp.mnorm(x, y[0]), None]], }
def abcd(self): return mp.eye(2)
def comp_N_m_mp(obs_rates, t, merge_threshold, useMigration): """This function estimates the N and m parameters for the various time slices. The time slices are given in a vector form 't'. t specifies the length of the time slice, not the time from present to end of time slice (not cumulative but atomic) Also, the obs_rates are given, for each time slice are given in columns of the obs_rates matrix. Both obs_rates and time slice lengths are given from present to past. """ FTOL = 10.0 PTOL = 1e-20 EPSILON = 1e-11 RESTARTS = 10 FLIMIT = 1e-20 numslices = len(t) nr = obs_rates.rows + 1 numdemes = int(np.real(np.sqrt(8 * nr - 7)) / 2) print 'Starting iterations' P0 = mp.eye(nr) xopts = [] pdlist = [] for i in xrange(numslices): bestxopt = None bestfval = 1e+200 print 'Running for slice ', i if i > 0: x0 = xopt[0:nr - 1].copy() try: xopt = mp.findroot(lambda x: compute_Frob_norm_mig(x, t[i], obs_rates[:, i], P0, make_merged_pd(pdlist)), x0) fun = compute_Frob_norm_mig(xopt, t[i], obs_rates[:, i], P0, make_merged_pd(pdlist)) bestxopt = xopt bestfval = fun except ValueError as e: print 'Error:', e.message for lll in xrange(numdemes * (numdemes - 1) / 2): x01 = x0[0:nr - 1].copy() x01[numdemes + lll] = 0.0099 try: xopt = mp.findroot(lambda x: compute_Frob_norm_mig(x, t[i], obs_rates[:, i], P0, make_merged_pd(pdlist)), x01) fun = compute_Frob_norm_mig(xopt, t[i], obs_rates[:, i], P0, make_merged_pd(pdlist)) if fun < bestfval: bestfval = fun bestxopt = xopt except ValueError as e: print 'Error:', e.message reestimate = True while reestimate: pdslice = make_merged_pd(pdlist) print 'pdslice:', pdslice N0_inv = np.random.uniform(5e-05, 0.001, numdemes) m0 = np.random.uniform(0.008, 0.001, numdemes * (numdemes - 1) / 2) x0 = [ mp.convert(rrr) for rrr in N0_inv ] for zz in range(len(m0)): x0.append(mp.convert(m0[zz])) lims = [(1e-15, 0.1)] * numdemes lims += [(1e-15, 0.1)] * (numdemes * (numdemes - 1) / 2) try: xopt = mp.findroot(lambda x: compute_Frob_norm_mig(x, t[i], obs_rates[:, i], P0, make_merged_pd(pdlist)), x0) fun = compute_Frob_norm_mig(xopt, t[i], obs_rates[:, i], P0, make_merged_pd(pdlist)) if fun < bestfval: bestfval = fun bestxopt = xopt except ValueError as e: print 'Error:', e.message N0_inv = np.random.uniform(5e-05, 0.001, numdemes) m0 = np.random.uniform(1e-08, 0.001, numdemes * (numdemes - 1) / 2) x0 = [ mp.convert(rrr) for rrr in N0_inv ] for zz in range(len(m0)): x0.append(mp.convert(m0[zz])) nrestarts = 0 try: xopt = mp.findroot(lambda x: compute_Frob_norm_mig(x, t[i], obs_rates[:, i], P0, make_merged_pd(pdlist)), x0) fun = compute_Frob_norm_mig(xopt, t[i], obs_rates[:, i], P0, make_merged_pd(pdlist)) if fun < bestfval: bestxopt = xopt bestfval = fun except ValueError as e: print 'Error:', e.message print nrestarts while nrestarts < RESTARTS and bestfval > FLIMIT: N0_inv = np.random.uniform(5e-05, 0.001, numdemes) m0 = np.random.uniform(1e-08, 0.001, numdemes * (numdemes - 1) / 2) x0 = mp.zeros(len(N0_inv) + len(m0)) for zz in range(len(N0_inv)): x0[zz] = N0_inv[zz] for zz in range(len(m0)): x0[zz + len(N0_inv)] = m0[i] try: xopt = mp.findroot(lambda x: compute_Frob_norm_mig(x, t[i], obs_rates[:, i], P0, make_merged_pd(pdlist)), x0) fun = compute_Frob_norm_mig(xopt, t[i], obs_rates[:, i], P0, make_merged_pd(pdlist)) if fun < bestfval: bestfval = fun bestxopt = xopt except ValueError as e: print 'Error:', e.message print nrestarts nrestarts += 1 print bestfval, i, bestxopt[0:numdemes], bestxopt[numdemes:] Ne_inv = bestxopt[0:numdemes] mtemp = bestxopt[numdemes:] popdict = find_pop_merges(Ne_inv, mtemp, t[i], P0, merge_threshold, useMigration) reestimate = False if len(popdict) < numdemes: print 'Merging populations and reestimating parameters:', popdict print bestxopt P0 = converge_pops(popdict, P0) reestimate = True pdlist.append(popdict) numdemes = len(popdict) nr = numdemes * (numdemes + 1) / 2 + 1 lims[:] = [] bestfval = 1e+200 bestxopt = None else: modXopt = [ 1.0 / x for x in bestxopt[0:numdemes] ] cnt = 0 for ii in xrange(numdemes): for jj in xrange(ii + 1, numdemes): modXopt.append(bestxopt[numdemes + cnt]) cnt = cnt + 1 xopts.append(np.array(modXopt)) Ne_inv = bestxopt[0:numdemes] mtemp = bestxopt[numdemes:] m = np.zeros((numdemes, numdemes)) cnt = 0 for ii in xrange(numdemes): for jj in xrange(ii + 1, numdemes): m[ii, jj] = m[jj, ii] = mtemp[cnt] cnt += 1 Q = comp_pw_coal_cont(m, Ne_inv) P = expM(t[i] * Q) print 'est rates', i print np.real(P0 * P)[0:-1, -1] print 'obs rates', i print np.real(obs_rates[:, i]) print 'Min func value', bestfval P0 = P0 * conv_scrambling_matrix(P) ist = raw_input('Waiting for input...') return (xopts, pdlist)
def get_unary(self, item): return { **{ k: calc2.UnaryOperator(s, f, 80) for k, s, f in [ ('abs', 'abs', abs), ('fac', 'fac', mpmath.factorial), ('sqrt', 'sqrt', mpmath.sqrt), ('_/', 'sqrt', mpmath.sqrt), ('√', 'sqrt', mpmath.sqrt), ('ln', 'ln', mpmath.ln), ('lg', 'log10', mpmath.log10), ('exp', 'e^', mpmath.exp), ('floor', 'floor', mpmath.floor), ('ceil', 'ceil', mpmath.ceil), ('det', 'det', mpmath.det), ] }, 'pcn': calc2.UnaryOperator('a%', lambda x: x / 100, 80), '+': calc2.UnaryOperator('(+)', lambda x: x, 0), '-': calc2.UnaryOperator('+/-', lambda x: -x, 80), 'conj': calc2.UnaryOperator( 'conj', lambda x: x.conjugate() if isinstance(x, mpmath.matrix) else mpmath.conj(x), 80), '~': calc2.UnaryOperator( 'conj', lambda x: x.conjugate() if isinstance(x, mpmath.matrix) else mpmath.conj(x), 80), 'O': calc2.UnaryOperator( '[O]', lambda x: mpmath.zeros(*OpList.__analyse_as_pair(x)), 80), 'I': calc2.UnaryOperator( '[I]', lambda x: mpmath.ones(*OpList.__analyse_as_pair(x)), 80), 'E': calc2.UnaryOperator('[E]', lambda x: mpmath.eye(int(x)), 80), 'diag': calc2.UnaryOperator( '[diag]', lambda x: mpmath.diag(OpList.__analyse_list(x)), 80), 'log': calc2.UnaryOperator( 'logbA', lambda x: OpList.__log(*OpList.__analyse_pair(x)), 80), 'tran': calc2.UnaryOperator( '[T]', lambda x: x.transpose() if isinstance(x, mpmath.matrix) else x, 80), **{ k: calc2.UnaryOperator(k, (lambda u: lambda x: u(self._drg2r(x)))(v), 80) for k, v in { 'sin': mpmath.sinpi, 'cos': mpmath.cospi, 'tan': lambda x: mpmath.sinpi(x) / mpmath.cospi(x), 'cot': lambda x: mpmath.cospi(x) / mpmath.sinpi(x), 'sec': lambda x: 1 / mpmath.cospi(x), 'csc': lambda x: 1 / mpmath.sinpi(x), }.items() }, **{ k: calc2.UnaryOperator(k, (lambda u: lambda x: self._r2drg(1 / v(x)))(v), 80) for k, v in { 'asin': mpmath.asin, 'acos': mpmath.acos, 'atan': mpmath.atan, 'acot': mpmath.acot, 'asec': mpmath.asec, 'acsc': mpmath.acsc }.items() }, **{ k: calc2.UnaryOperator(k, v, 80) for k, v in { 'sinh': mpmath.sinh, 'cosh': mpmath.cosh, 'tanh': mpmath.tanh, 'coth': mpmath.coth, 'sech': mpmath.sech, 'csch': mpmath.csch, 'asinh': mpmath.asinh, 'acosh': mpmath.acosh, 'atanh': mpmath.atanh, 'acoth': mpmath.acoth, 'asech': mpmath.asech, 'acsch': mpmath.acsch }.items() } }[item]
def identity(sz): if mode == mode_python: return np.matrix(np.identity(sz, dtype=np.complex128)) else: return mpmath.eye(sz)
import numpy as np from mpmath import eye array = np.array([[1, 31, 4], [64, 78, 16]]) print(array) print(array.ndim) print(array.shape) print(array.size) array1 = eye(4) print(array1) print(array1)
A = iv_matrix_mid_to_numpy_ndarray(A) M2 = iv_matrix_mid_to_numpy_ndarray(M2) # coerce tau to maximum tau = float(mp.mpf(abs(iv.mpf(tau)).b)) max_norm = 0 for t in numpy.linspace(-tau, tau, 100): matrix = numpy.matmul(M1, numpy.matmul(scipy.linalg.expm(A*t) - numpy.eye(len(A)), M2)) max_norm = max(max_norm, approx_P_norm(M=matrix, P_sqrt_T=P_sqrt_T)) return max_norm if __name__ == "__main__": random.seed(1234565567) print("Example: random matrix") for i in range(1): c = 2 A = mp.randmatrix(20) - 0.5 eigv_A, _= mp.eig(iv_matrix_mid_as_mp(A)) A = 0.5 * A / max([abs(i) for i in eigv_A]) eigv_A, _= mp.eig(iv_matrix_mid_as_mp(A)) #print('eigenvalues(A) = ', eigv_A) print('spectral radius(A) = ', max([abs(i) for i in eigv_A])) print('interval spectral_norm(A) = ', iv_spectral_norm(A)) P_sqrt_T = approx_P_sqrt_T(A) print('interval P_norm(A) = ',iv_P_norm(A, P_sqrt_T)) print('interval P_norm(...expm(...)) = ', iv_P_norm_expm(P_sqrt_T, M1=mp.eye(len(A)), A=A, M2=mp.eye(len(A)), tau=0.01)) print('sampled P_norm(...expm(...)) = ', approx_P_norm_expm(P_sqrt_T, M1=mp.eye(len(A)), A=A, M2=mp.eye(len(A)), tau=0.01)) print('')