Exemplo n.º 1
0
 def update(self, dt):
     self.mass_cond.append(linalg.cond(self._world._mass))
     self.imp_cond.append(linalg.cond(self._world._impedance))
     curr_rk = []
     for b in self._world.iterbodies():
         curr_rk.append( self.rank(b.jacobian) )
     self.c_rank.append(curr_rk)
Exemplo n.º 2
0
def compDklgaussian(mu1, C1, mu2, C2):
    '''
    mu1 and C1 specify a multidimensional gaussian. mu2 and C2 specify another
    one (of the same dimension). Return is a float giving the KL divergence
    between the two Gaussians.

    Inputs have to be matrix instances, and the mu inputs should be in row
    vector shape (mu.shape[0] = 1, mu.shape[1] > 1)

    '''
    n = mu1.size
    b = mu2 - mu1
    C2inv = la.inv(C2)
    C1sqrt = np.mat(sqrtPSDm(C1))
    Term1 = C1sqrt * C2inv * C1sqrt
    Term2 = b.transpose() * C2inv * b
    det1 = la.det(C1)
    det2 = la.det(C2)
    tol = 1e8
    if (la.cond(C1) > tol) | (la.cond(C2) > tol):
        print('Determinants not non-zero. Ignoring determinants.')
        Term3 = 0
    else:
        Term3 = .5 * np.log(det2 / det1)
    d = .5 * np.trace(Term1) + .5 * Term2 - .5 * n + Term3
    return d[0, 0]
Exemplo n.º 3
0
def main(argv):
    A = numpy.matrix([[float(sys.argv[1]), float(sys.argv[2]), float(sys.argv[3]), float(sys.argv[4])], [float(sys.argv[5]), float(sys.argv[6]), float(sys.argv[7]), float(sys.argv[8])], [float(sys.argv[9]), float(sys.argv[10]), float(sys.argv[11]), float(sys.argv[12])]])
    B = numpy.matrix([[float(sys.argv[1]), float(sys.argv[2]), float(sys.argv[3])], [float(sys.argv[5]), float(sys.argv[6]), float(sys.argv[7])], [float(sys.argv[9]), float(sys.argv[10]), float(sys.argv[11])]])
    #print A
    #print 'top left number is: '+ str(A[0,0])
    #backSub(forwardElim(A))
    print LA.cond(B, numpy.inf)
Exemplo n.º 4
0
def _B2formula(Ac, t1, t2, B2):
    if t1 == 0 and t2 == 0:
        term = B2
        return term
    n = Ac.shape[0]
    tmp = np.eye(n) - expm(-Ac)
    if cond(tmp) < 1000000.0:
        term = np.dot(((expm(-Ac * t1) - expm(-Ac * t2)) * inv(tmp)), B2)
        return term
    # Numerical trouble. Perturb slightly and check the result
    ntry = 0
    k = np.sqrt(eps)
    Ac0 = Ac
    while ntry < 2:
        Ac = Ac0 + k * rand(n, n)
        tmp = np.eye(n) - expm(-Ac)
        if cond(tmp) < 1 / np.sqrt(eps):
            ntry = ntry + 1
            if ntry == 1:
                term = np.dot(np.dot(expm(-Ac * t1) - expm(-Ac * t2), inv(tmp)), B2)
            else:
                term1 = np.dot(np.dot(expm(-Ac * t1) - expm(-Ac * t2), inv(tmp)), B2)
        k = k * np.sqrt(2)

    if norm(term1 - term) > 0.001:
        warn("Inaccurate calculation in mapCtoD.")
    return term
Exemplo n.º 5
0
def evaluate_rotation_matrix(R, this_theta):
    pi = numpy.pi
    print
    print '###################'
    theta = this_theta * 180.0 / pi
    condition_number = linalg.cond(R)
    smallest_singular_value = linalg.cond(R, -2)
    two_norm = linalg.cond(R, 2)
    print 'theta = ', theta, '\n', R, '\ncondition number = ', condition_number
    print 'largest_singluar_value = ', two_norm
    print 'smallest_singular_value = ', smallest_singular_value
    print '###################'
    print

    return
Exemplo n.º 6
0
 def EV(sasb_n, sasb_nm1, sa_n, sa_nm1,debug1=False,debug2=False):
     try:
         dim = len(sa_n)
         sasb_n  =  sasb_n.reshape(dim , dim)
         sasb_nm1=sasb_nm1.reshape(dim , dim)
         dsdk_n  =sasb_n  -outer(sa_n,sa_n)
         dsdk_nm1=sasb_nm1-outer(sa_nm1,sa_n)
         T=dot(dsdk_nm1,inv(dsdk_n))
         if debug2:
             print(cond(T))
         #evs=sort(abs(eigvals(T)))
         evs=sort(eigvals(T))
         if debug1:
             val,vec=eig(T)
             print(val)
             print('-----------------')
             for i in range(len(val)):
                 print(val[i],vec[:,i])
             print('-----------------')
         lambda_ =max(abs(evs))
         lambda_test =evs[-1]
         #assert(lambda_==lambda_test)
         if(len(evs)>1):
             lambda_2=evs[-2]
         else:
             lambda_2=0
         lambda_=RawSanitize(lambda_)
         return lambda_, lambda_2
     except np.linalg.linalg.LinAlgError:
         return 0,0
Exemplo n.º 7
0
def unteraufgabe_d():
    n = np.arange(2,21,2)
    xs = [x02,x04,x06,x08,x10,x12,x14,x16,x18,x20]
    f = lambda x: np.sin(10*x*np.cos(x))

    residuals = np.zeros_like(n,dtype=np.floating)
    condition = np.ones_like(n,dtype=np.floating)

    for i, x in enumerate(xs):
        b = f(x)
        A = interp_monom(x)
        alpha = solve(A,b)
        residuals[i] = norm(np.dot(A,alpha) - b)
        condition[i] = cond(A)

    plt.figure()
    plt.plot(n,residuals,"-o")
    plt.grid(True)
    plt.xlabel(r"$n$")
    plt.ylabel(r"$\|A \alpha - b\|_2$")
    plt.savefig("residuals.eps")

    plt.figure()
    plt.semilogy(n,condition,"-o")
    plt.grid(True)
    plt.xlabel(r"$n$")
    plt.ylabel(r"$\log(\mathrm{cond}(A))$")
    plt.savefig("condition.eps")
Exemplo n.º 8
0
def MdcNE(A, b):
    """
    Résolution du problème des moindres carrés linéaire :
                Min_{alpha} || b - A*alpha ||^2
    par factorisation de Cholesky du système des équations normales.

    Parameters
    ----------
    A : np.array ou np.matrix
    b : np.array ou np.matrix

    Returns
    -------
    alpha : np.array (dans tous les cas)
        solution du problème des moindres carrés linéaire
    """
    S = np.matrix(A).T * np.matrix(A)

    # Vérification au préalable du conditionnement du système et de la stabilité
    # numérique de la résolution qui va suivre
    c = la.cond(S)
    if c > 1e16:
        print('Attention : le conditionnement de la matrice des équations')
        print('            normales est très grand ---> %0.5g' % c)

    # Factorisation suivi de la résolution
    L = la.cholesky(S)           # matrice triangulaire inférieure
    m = b.size
    bvect = np.matrix( b.reshape(m,1) )
    y = A.T * bvect
    z = la.solve(L, y)
    alpha = np.array( la.solve(L.T, z) )

    return alpha
Exemplo n.º 9
0
    def crunch(self):
        '''Mainline to number crunch the calculation of
        member foreces.'''
# echo data:
        printline = self.printline
        lineread, noNodes, noMembers, noAuxiliaries,\
        noLoadCases, noLoadLines = self.prolog()
        nodes = self.doNodes(lineread, noNodes, noAuxiliaries)       
        printline("nodes = ")
        printdict(printline, nodes)
        members = self.doMembers(lineread, noMembers, noAuxiliaries)       
        printline('members = ') 
        printdict(printline, members)    
        memprops = self.doMemprops( noMembers, noAuxiliaries, members, nodes)
        printline('memprops =')
        printdict(self.printline, memprops)
        ndim = noNodes * 2
        printline('Dimension of connection mat ndim =' + str(ndim))
        connection = np.zeros((ndim, ndim), dtype = "float")
        for i in range(noMembers + noAuxiliaries):
            member = memprops[i + 1]
            connection[member[0] - 1, i] += member[4]
            connection[member[1] - 1, i] += member[5]
            if i < noMembers:                
                connection[member[2] - 1, i] += -member[4]            
                connection[member[3] - 1, i] += -member[5]
        printline(' ')
        printline('Connection matrix')
        printerm(printline, connection)
        try:
            conditionnumber = la.cond(connection)
            inv = la.inv(connection)
        except la.LinAlgError, e:
            printline( '%s  %s' % (type(e).__name__, e))
Exemplo n.º 10
0
def fitmat(p, q):
    """
    Compute the best transformation to map p onto q without translation.

    The transformation is best according to the least square residuals criteria and correspond to the matrix M in:

        p-p0 = M(q-q0) + T

    where p0 and q0 are the barycentre of the list of points p and q.

    :Parameters:
        p : array(M,2)
            List of points p, one point per line, first column for x, second for y
        q : array(M,2)
            List of points q, one point per line, first column for x, second for y
    """
    pc = p.sum(0) / p.shape[0]
    qc = q.sum(0) / q.shape[0]
    p = asmatrix(p - pc)
    q = asmatrix(q - qc)
    A = p.T * p
    if cond(A) > 1e15:
        return
    V = p.T * q
    M = (A.I * V).A
    return M.T
Exemplo n.º 11
0
    def computeRegressorLinDepsSVD(self):
        """get base regressor and identifiable basis matrix with iDynTree (SVD)"""

        with helpers.Timer() as t:
            # get subspace basis (for projection to base regressor/parameters)
            Yrand = self.getRandomRegressor(5000)
            #A = iDynTree.MatrixDynSize(self.num_params, self.num_params)
            #self.generator.generate_random_regressors(A, False, True, 2000)
            #Yrand = A.toNumPy()
            U, s, Vh = la.svd(Yrand, full_matrices=False)
            r = np.sum(s>self.opt['min_tol'])
            self.B = -Vh.T[:, 0:r]
            self.num_base_params = r

            print("tau: {}".format(self.tau.shape), end=' ')

            print("YStd: {}".format(self.YStd.shape), end=' ')
            # project regressor to base regressor, Y_base = Y_std*B
            self.YBase = np.dot(self.YStd, self.B)
            if self.opt['verbose']:
                print("YBase: {}, cond: {}".format(self.YBase.shape, la.cond(self.YBase)))

            self.num_base_params = self.YBase.shape[1]
        if self.showTiming:
            print("Getting the base regressor (iDynTree) took %.03f sec." % t.interval)
Exemplo n.º 12
0
def check_input_data(a, b, x=None):
    """Does some sanity checks of the input data. Arguments:
        a    - input matrix
        b    - input vector
        x    - partial solution for the Jacobi Method
    Returns:
        args - list of input arguments, if valid - otherwise raises
               InputDataException
    """
    from sys import float_info
    from time import sleep
    if x is None:
        args = [a, b]
    else:
        args = [a, b, x]
    for arg in args:
        if type(arg) != np.ndarray:
            raise InputDataError(repr(np.ndarray) + ' expected, got ' +
                                 repr(type(arg)) + ' instead.')
    if (a.ndim, b.ndim, len(a)) != (2, 2, len(b)):
        raise InputDataError('Input arrays have different sizes/dimensions')
    if x is not None:
        if (x.ndim, x.size) != (2, b.size):
            raise InputDataError('Input arrays have different sizes/dimensions')
    if a.shape[0] != a.shape[1]:
        raise InputDataError('Only square matrices are supported')
    if la.cond(a) > 1 / float_info.epsilon:
        raise InputDataError('Singular matrix')
    return args
Exemplo n.º 13
0
    def _energy(self, face, i):
        """Returns energy value and polygon area for a provided polygon."""
       
        TV1 = array([self.Mesh.vertices[face[0]], self.Mesh.vertices[face[1]], self.Mesh.vertices[face[2]]])
        TV2 = array([self.vnormal[face[0]],self.vnormal[face[1]],self.vnormal[face[2]]])
        
        if array_equal(TV1[0], TV1[1]) or array_equal(TV1[0], TV1[2]) or array_equal(TV1[1], TV1[2]):
            print "Warning: Duplicate vertices in polygon %s." % i
            print "Ignoring this polygon for energy calculation, but editing surface to remove duplicate vertices prior to DNE calculation is encouraged."
            return [0,1]

        b1 = TV1[1] - TV1[0]
        b2 = TV1[2] - TV1[0]
        
        g = array(([dot(b1,b1), dot(b1,b2)],[dot(b2,b1), dot(b2,b2)]))
        
        if self.docondition:
                if cond(g) > 10**5:
                    self.high_condition_faces.append([i, cond(g)])
                    return [0,1]
        
        c1 = TV2[1] - TV2[0]
        c2 = TV2[2] - TV2[0]
    
        fstarh = array(([dot(c1,c1), dot(c1,c2)], [dot(c2,c1), dot(c2,c2)]))
    
        gm = mat(g)  
        
        try:
            gminv = gm.I
        except LinAlgError as err:
            condition = cond(g)
            if condition > 10**5:
                err.args += ('G matrix for polygon %s is singular and an inverse cannot be determined. Condition number is %s, turning condition number checking on will cause this polygon to be ignored for energy calculation.' % (i, cond(g)),)
                raise
            else:
                err.args += ('G matrix for polygon %s is singular and an inverse cannot be determined. Condition number is %s, turning condition number checking on will not cause this polygon to be ignored for energy calculation. Further mesh processing is advised.' % (i, cond(g)),)
                raise
        
        e = trace((gminv*fstarh))
        facearea = 0.5 * sqrt(g[0,0]*g[1,1]-g[0,1]*g[1,0])
                        
        if isnan(e):
            self.nan_faces.append(i)
            
        return [e,facearea]
Exemplo n.º 14
0
 def test_inverse(self):
     for n in xrange(1, 10):
         a = hilbert(n)
         b = invhilbert(n)
         # The Hilbert matrix is increasingly badly conditioned,
         # so take that into account in the test
         c = cond(a)
         assert_allclose(a.dot(b), eye(n), atol=1e-15*c, rtol=1e-15*c)
Exemplo n.º 15
0
Arquivo: main.py Projeto: warelle/rdft
def const_r():
  for i in range(0, 50):
    size = 200
    mat = np.zeros((size,size))
    r   = rdft.generate_r(size)            # use constant r
    for j in range(0,size):
      for k in range(0,size):
        mat[j,k] = random.uniform(-100,100)
    f = rdft.generate_f(size)
    fr  = f.dot(r)
    fra = fr.dot(mat)
    (a_maxcond,_,_)   = rdft.get_leading_maxcond(mat)
    (fra_maxcond,_,_) = rdft.get_leading_maxcond(fra)
    a_cond   = linalg.cond(mat)
    fra_cond = linalg.cond(fra)
    print("A:  ", a_maxcond/a_cond)
    print("FRA:", fra_maxcond/fra_cond)
Exemplo n.º 16
0
def diagonalize(correlator_pannel, t0, td, generalized=False):
    length = correlator_pannel.shape[0]
    n = int(np.sqrt(length))
    assert t0 is not None
    # Here we access the pannel major_xs gives time(n), mean incase it
    # was a multi correlator should have no effect on an already averaged one
    A = np.matrix(np.reshape(correlator_pannel.major_xs(td).mean().values, (n, n)))
    B = np.matrix(np.reshape(correlator_pannel.major_xs(t0).mean().values, (n, n)))
    # Require A and B to be hermition for our generalized eigen value
    # problem method to work. Here we force the matricies to be
    # hermtion. This is justified since it is just useing the other
    # measurement of the same value and averaging them.
    A = hermitionize(A)
    B = hermitionize(B)
    logging.debug("A = {} \n B = {}".format(A, B))

    if generalized:
        logging.info("running generalized eigensolver")
        evals, evecs = LA.eigh(A, b=B)  #gerenalized eig problem, eigh works only if hermitian
        evecs = np.matrix(evecs)
        V = evecs
    else:
        # Instead of using generalized eigen problem, we could solve a
        # regular eigen problem involving Binvqrt
        Binvsqrt =  LA.inv(LA.sqrtm(B))
        logging.info("condition number: {}".format(cond(Binvsqrt*A*Binvsqrt)))
        evals, evecs = LA.eigh(Binvsqrt*A*Binvsqrt)
        evecs = np.matrix(evecs)
        V = np.matrix(Binvsqrt)*evecs

    if min(evals) < 0.05:
        logging.warn("Warning, low eigenvalue detected. Eval={}".format(min(evals)))
    else:
        logging.info("lowest eigenvalue={}".format(min(evals)))
    logging.debug("eigen values are {}".format(evals))
    logging.debug("eigen vectors are {}".format(evecs))
    n = len(evecs)
    logging.debug("Matrix size {N}x{N}".format(N=n))

    def rotate(x):
        M = np.matrix(np.resize(x, (n, n)))
        M = hermitionize(M)
        D = V.H * M * V
        R = np.array(D).flatten()
        P = pd.Series(R)
        return P

    diag = correlator_pannel.apply(rotate, "items")
    diag.items = ["{}{}".format(i,j) for i in reversed(range(n)) for j in reversed(range(n))]

    # This method simultaniously diagaonlizes at t0 and td. Should be
    # identity at t0 and the eigenvalues at td
    assert compare_matrix(np.reshape(diag.major_xs(t0).mean().values, (n, n)),
                          np.identity(n)), "Rotation error: is not ~identity at t0"
    assert compare_matrix(np.reshape(diag.major_xs(td).mean().values, (n, n)),
                          np.diag(evals)), "Rotation error: Is not ~Lambda at td"

    return diag
Exemplo n.º 17
0
def diagnostics(basename):
    dagfilename = join(DATADIR, basename+'.dag')
    prob = read_problem(dagfilename, plot_dag=False, show_sparsity=False)
    partial_code = prepare_evaluation_code(prob) 
    rev_ad = import_code(partial_code)
    con, jac_ad = rev_ad.evaluate(prob.refsols[0], prob.ncons, prob.nvars, prob.nzeros)
    print('Constraint infinity norm: ', norm(con, np.inf))
    print('Condition number estimate:', cond(jac_ad.todense()))
    tests.JacobianTest.dump_code(partial_code, dagfilename)
Exemplo n.º 18
0
def getTransformationMat(A):
	#A = matrix([[1,5,2,7],[1,1,3,31],[1,3,4,17],[1,1,1,1]])
	#B = matrix([[77,75,74,61],[35,39,36,41],[9.2,9.2,7.2,-20.8],[1,1,1,1]])

	#A = matrix([[-7.68,-7.855,-18,-6.24],[5.46,8.912,10.35,5.3816],[110.15,121.22,124.47,129.4126],[1,1,1,1]]) #Kinect Frame
	#B = matrix([[-10,0,0,10],[25,21.22,36,21],[8.7,12.86,8.7,15],[1,1,1,1]]) #Arm Frame
	B = matrix([[-10,25,8.7,1],[0,21.22,12.86,1],[0,36,8.7,1],[10,21,15,1],[-15,31,20,1],[10,31,20,1],[10,29,15,1],[15,29,15,1],[-15,20,15,1],[-10,20,15,1],[3,18,5,1],[5,20,25,1],[-5,25,25,1],[-5,30,6,1],[15,20,6,1]]) #Arm Frame
	B = B.transpose()
	# C = (inv((A.transpose())*A))*(A.transpose())*B if pts rows
	C = B * (A.transpose()) * inv(A * (A.transpose()))
	print cond(C)
	#test = matrix([[-5.56606237302],[11.4300619608],[111.661235336],[1]]) 

	#point = C*test 
	#GoToPos(point[0],point[1],point[2],'close')

	#print (C*test)[0]
	return C
    def get_K_cond(K):
        start = time.time()

        K_cond = linalg.cond(K)

        end = time.time()
        if end - start > timer_thresh:
            print 'get_K_cond:', end - start, 'sec'
        return K_cond
Exemplo n.º 20
0
Arquivo: main.py Projeto: warelle/rdft
def const_a(sample, size, rand_range):
  result = []
  mat = np.zeros((size,size))
  for j in range(0,size):
    for k in range(0,size):
      mat[j,k] = random.uniform(-rand_range,rand_range)
  for i in range(0, sample):
    f   = rdft.generate_f(size)
    r   = rdft.generate_r(size)
    fr  = f.dot(r)
    fra = fr.dot(mat)
    (a_maxcond,_,a_subcond)   = rdft.get_leading_maxcond(mat)
    (fra_maxcond,_,fra_subcond) = rdft.get_leading_maxcond(fra)
    a_cond   = linalg.cond(mat)
    fra_cond = linalg.cond(fra)
    result.append([mat, a_maxcond/a_cond, fra_maxcond/fra_cond, fra, a_subcond, fra_subcond])
    #print("A:  ", a_maxcond/a_cond)
    #print("FRA:", fra_maxcond/fra_cond)
  return result
Exemplo n.º 21
0
def random_well_condition(size, val_range):
  import random
  r = np.zeros((size,size), dtype=np.complex128)
  while True:
    for i in range(0,size):
      for j in range(0,size):
        r[i,j] = random.uniform(-val_range,val_range)
    if linalg.cond(r) < 10000:
      break
  return r
Exemplo n.º 22
0
    def crunch(self):
        '''Mainline to number crunch the calculation of
        member foreces.'''
# echo data:
        printline = self.printline
        lineread, noNodes, noMembers, noAuxiliaries,\
        noLoadCases, noLoadLines = self.prolog()
        nodes = self.doNodes(lineread, noNodes, noAuxiliaries)       
        printline("nodes = ")
        printdict(printline, nodes)
        members = self.doMembers(lineread, noMembers, noAuxiliaries)       
        printline('members = ') 
        printdict(printline, members)    
        memprops = self.doMemprops( noMembers, noAuxiliaries, members, nodes)
        printline('memprops =')
        printdict(self.printline, memprops)
        ndim = noNodes * 2
        printline('Dimension of connection mat ndim =' + str(ndim))
        connection = np.zeros((ndim, ndim), dtype = "float")
        for i in range(noMembers + noAuxiliaries):
            member = memprops[i + 1]
            connection[member[0] - 1, i] += member[4]
            connection[member[1] - 1, i] += member[5]
            if i < noMembers:                
                connection[member[2] - 1, i] += -member[4]            
                connection[member[3] - 1, i] += -member[5]
        printline(' ')
        printline('Connection matrix')
        printerm(printline, connection)
        try:
            conditionnumber = la.cond(connection)
            inv = la.inv(connection)
        except la.LinAlgError as e:
            printline( '%s  %s' % (type(e).__name__, e))
        else:
            i = np.dot(inv, connection)
            loads = np.zeros((ndim, 1), dtype = "float")   
            line = lineread()
            assert line.strip() == 'loads', 'Flag for loads is loads'
            for i in range(noLoadLines):
                lst = lineread().split()
                nodeNo = int(lst[0])
                node = nodes[nodeNo]
                loads[node[3] - 1] = -float(lst[1])
                loads[node[4] - 1] = -float(lst[2])
            printline('')
            printline('Load matrix = ')
            printerm(printline, loads)
            memberActions = np.dot(inv, loads)
            printline(' ')
            printline("Member Actions, [Ni | Ri] matrix.")
            printerm(printline, memberActions)
        printline(' ')
        printline('matrix condition number = ' + str(conditionnumber))
        printline(' ')
Exemplo n.º 23
0
def solve_getinfo(a,b,x,sample):
  mat = np.array(a)
  (size,_) = a.shape
  result = []
  a_cond   = linalg.cond(mat)
  (a_maxcond,_,a_subcond)   = rdft.get_leading_maxcond(mat)
  for i in range(0, sample):
    # RDFT solve
    (x1, fra, fr, ra, x1_orig) = solve_rdft(a,b,x)
    (fra_maxcond,_,fra_subcond) = rdft.get_leading_maxcond(fra)
    fra_cond = linalg.cond(fra)
    err_rdft_iter = linalg.norm(x1-x)
    err_rdft = linalg.norm(x1_orig-x)
    # RDFT improved solve
    (x1_imp, fra_imp, fr_imp, ra_imp, x1_imp_orig) = solve_rdft_improved(a,b,x)
    (fra_maxcond_imp,_,fra_subcond_imp) = rdft.get_leading_maxcond(fra)
    fra_cond_imp = linalg.cond(fra_imp)
    err_rdft_imp_iter = linalg.norm(x1_imp-x)
    err_rdft_imp = linalg.norm(x1_imp_orig-x)
    # RDFT givens solve
    (x5_imp, x5_imp_orig) = solve_rdft_givens(a,b,x)
    err_rdft_givens_iter = linalg.norm(x5_imp-x)
    err_rdft_givens = linalg.norm(x5_imp_orig-x)
    # RDFT givens solve
    (x7_imp, x7_imp_orig) = solve_rdft_givens_both(a,b,x)
    err_rdft_givens_both_iter = linalg.norm(x7_imp-x)
    err_rdft_givens_both = linalg.norm(x7_imp_orig-x)
    # GAUSS solve
    (x2, ga, _, x2_orig) = solve_gauss(a,b,x)
    (ga_maxcond,_,ga_subcond) = rdft.get_leading_maxcond(fra)
    ga_cond = linalg.cond(ga)
    err_gauss_iter = linalg.norm(x2-x)
    err_gauss = linalg.norm(x2_orig-x)
    # Partial Pivot
    a_float = np.array(a,dtype=np.float64)
    b_float = np.array(b,dtype=np.float64)
    (x3, pl, pu, swapped_a, swapped_b) = pp.solve(a_float,b_float)
    err_pp = linalg.norm(x3-x)
    ##x3_i = iteration.iteration(swapped_a, pl, pu, swapped_b, x3, linalg.cond(a_float))
    #result make
    result.append(([a_maxcond/a_cond, fra_maxcond/fra_cond, fra, a_subcond, fra_subcond, fr, ra, err_rdft_iter, err_rdft,err_rdft_imp_iter,err_rdft_imp],[err_rdft_givens_iter,err_rdft_givens],[err_rdft_givens_both_iter,err_rdft_givens_both],[ga_maxcond/ga_cond, ga, ga_subcond, err_gauss_iter, err_gauss],[err_pp]))
  return result
Exemplo n.º 24
0
def solve_rdft_improved(a,b,x):
  (size,_) = a.shape
  f   = rdft.generate_f(size)
  r   = rdft.generate_random_r(size)
  fr  = f.dot(r)
  ra  = r.dot(a)
  (x1, l, u, fra, frb, _) = rdft.rdft_lu_solver_with_lu(a,b,r)
  x2 = np.array(x1)
  x2  = iteration.iteration_another(a, l, u, fr, b, x2, linalg.cond(fra))
  x2  = iteration.remove_imag(x2)
  return (x2, fra, fr, ra, x1)
def MatrixConditionCheck(A, MaxConditionNumber = 10.0):
    """Check the condition number of a matrix.
    Only write output to screen if the condition number is too high.
    Should return something, really."""

    ConditionNumber = la.cond(A)
    if ConditionNumber > MaxConditionNumber:
        print("The condition number of the matrix\n{0}\n"\
              "is too large (i.e., it is {1:.4} which is larger"\
              " than {2:.4}).\n".\
              format(A, ConditionNumber, MaxConditionNumber))
Exemplo n.º 26
0
 def get_cov_by_clazz(self, clazz):
     if clazz not in self.inv_cov:
         cov_clazz = self.__cov_by_clazz(clazz)
         self.cov[clazz] = cov_clazz
         if linalg.cond(cov_clazz) < 1 / sys.float_info.epsilon:
             self.inv_cov[clazz] = linalg.inv(cov_clazz)
             self.det_cov[clazz] = linalg.det(cov_clazz)
         else:  # computing pseudo inverse/determinant to a singular covariance matrix
             self.inv_cov[clazz] = linalg.pinv(cov_clazz)
             eig_values, _ = linalg.eig(cov_clazz)
             self.det_cov[clazz] = np.product(eig_values[(eig_values > 1e-12)])
     return self.cov[clazz], self.inv_cov[clazz], self.det_cov[clazz]
Exemplo n.º 27
0
def synthesis_operator(LF_selected_values, HF_selected_values, L, LF_new):
    # LF_selected_values is $u^L(\gamma)$
    # HF_selected_values is $u^H(\gamma)$
    # L is the Cholesky product from the node selection algorithm
    # LF_new is $u^L(\mathbf{z})$
    G = dot(L, L.T)
    G_inv = inv(G)
    g = dot(LF_selected_values.T, LF_new)
    c = dot(G_inv, g)
    # MF_new approximates $u^H(\mathbf{z})$
    MF_new = dot(HF_selected_values, c).squeeze()
    return MF_new, cond(G)
Exemplo n.º 28
0
def solve_gauss(a,b,x):
  (size,_) = a.shape
  g   = rdft.generate_g(size)
  ga  = g.dot(a)
  ga_save  = np.array(ga)
  gb  = g.dot(b)
  (l,u) = lu.lu(ga)
  y     = lu.l_step(l,gb)
  x1    = lu.u_step(u,y)
  x2 = np.array(x1)
  x2  = iteration.iteration_another(a, l, u, g, b, x2, linalg.cond(ga))
  return (x2, ga, a, x1)
Exemplo n.º 29
0
    def getSubregressorsConditionNumbers(self):
        # get condition number for each of the links
        linkConds = list()
        for i in range(0, self.N_LINKS):
            #get columns of base regressor that are dependent on std parameters of link i
            #TODO: check if this is a sound approach
            #TODO: try going further down to e.g. condition number of link mass, com, inertial

            #get parts of base regressor with only independent columns (identifiable space)

            #get all independent std columns for link i
            base_columns = [j for j in range(0, self.num_base_params) \
                                  if self.independent_cols[j] in range(i*10, i*10+9)]

            #add dependent columns (not really correct, see getting self.B)
            #for j in range(0, self.num_base_params):
            #    for dep in np.where(np.abs(self.linear_deps[j, :])>self.opt['min_tol'])[0]:
            #        if dep in range(i*10, i*10+9):
            #            base_columns.append(j)
            if not len(base_columns):
                linkConds.append(10e15)
            else:
                linkConds.append(la.cond(self.YBase[:, base_columns]))

            #use base column dependencies to get parts of base regressor with influence on each each link
            '''
            base_columns = list()
            for k in range(i*10, i*10+9):
                for j in range(0, self.num_base_params):
                    if self.param_syms[k] in self.base_deps[j].free_symbols:
                        if not j in base_columns:
                            base_columns.append(j)
                        continue

            if not len(base_columns):
                linkConds.append(10e15)
            else:
                linkConds.append(la.cond(self.YBase[:, base_columns]))
            '''

            #use std regressor directly
            '''
            c = la.cond(self.YStd[:, i*10:i*10+9])
            if np.isfinite(c):
                linkConds.append(c)
            else:
                linkConds.append(10e15)
            '''

        print("Condition numbers of link sub-regressors: [{}]".format(dict(enumerate(linkConds))))

        return linkConds
Exemplo n.º 30
0
def test_randsvd():
    """Simple test of randsvd THIS WILL FAIL ~10% of the time"""
    n = 18
    k = 1e+20
    a = rogues.randsvd(n, kappa=k)
    c = nl.cond(a) / k

    # The actual condition number should be within an order of magnitude
    # of what we asked for but, sometimes even a order of magnitude doesn't
    # quite cut it so we loosen up even more (even this doesn't always pass
    # so we must think of a better check (looks like this fails a little
    # less than 10% of the time.
    assert(c > 0.05 and c < 50.)
Exemplo n.º 31
0
def srrqr(M, k, f=1., verbose=False):

    m, n = M.shape
    minmn = np.min([m, n])
    assert k <= minmn, "k must be less than min{m,n} k = %d,m = %d, n = %d" % (
        k, m, n)

    #QR with column pivoting
    Q, R, p = qr(M, mode='economic', pivoting=True)

    if k == n: return Q, R, p

    increase_found = True
    counter_perm = 0
    iterc = 0

    while (increase_found) and iterc <= 100:
        iterc += 1

        A = R[:k, :k]
        AinvB = np.linalg.solve(A, R[:k, k:])  #Form A^{-1}B

        C = R[k:minmn, k:]

        #Compute column norms of C
        if k < m: gamma = np.apply_along_axis(norm, 0, C[:, :n - k])

        #Find row norms of A^{-1}
        omega = np.apply_along_axis(norm, 0, inv(A).T)

        F = AinvB**2.
        if k < m: F += (np.outer(omega, gamma))**2.
        ind = np.argwhere(F > f**2.)
        if ind.size == 0:  #finished
            increase_found = False
        else:  #we can increase |det(A)|
            i, j = ind[0, :]
            counter_perm += 1
            #permute columns i and j
            R[:, [i, j + k]] = R[:, [j + k, i]]
            p[[i, j + k]] = p[[j + k, i]]

            #retriangularize R
            q, R = qr(R, mode='economic')
            Q = np.dot(Q, q)
        #print p

    Rkk = R[:k, :k]
    inv_norm = norm(inv(Rkk), 2)
    res_norm = norm(R[k:minmn, k:], 2) if k < minmn else 0.

    if verbose:
        print "Norm of inverse is %g" % (inv_norm)
        print "Norm of residual is %g" % (res_norm)
        sgn, det = slogdet(Rkk)
        print "Log-determinant of selected columns is %g with sign %g" %\
          (det, sgn)
        print "Conditioning of selected columns is %g" % (cond(Rkk))

    p = p[:k]
    return Q, R, p
Exemplo n.º 32
0
 def do(self, a, b):
     c = asarray(a)  # a might be a matrix
     s = linalg.svd(c, compute_uv=False)
     old_assert_almost_equal(s[0] / s[-1], linalg.cond(a, 2), decimal=5)
Exemplo n.º 33
0
def lncond(G):
    return np.log(linalg.cond(np.dot(G.T, G)))
 def assemble_operator(self, term, current_stage="online"):
     if term == "projection_truth_snapshots":
         assert current_stage in (
             "online", "offline_rectification_postprocessing")
         if current_stage == "online":  # load from file
             self.operator["projection_truth_snapshots"].load(
                 self.folder["reduced_operators"],
                 "projection_truth_snapshots")
             return self.operator["projection_truth_snapshots"]
         elif current_stage == "offline_rectification_postprocessing":
             # the affine expansion storage contains only the inner product matrix
             assert len(self.truth_problem.inner_product) == 1
             inner_product = self.truth_problem.inner_product[0]
             for n in range(1, self.N + 1):
                 # the affine expansion storage contains only the inner product matrix
                 assert len(self.inner_product) == 1
                 inner_product_n = self.inner_product[:n, :n][0]
                 basis_functions_n = self.basis_functions[:n]
                 projection_truth_snapshots_expansion = OnlineAffineExpansionStorage(
                     1)
                 projection_truth_snapshots = OnlineMatrix(n, n)
                 for (i, snapshot_i) in enumerate(self.snapshots[:n]):
                     projected_truth_snapshot_i = OnlineFunction(n)
                     solver = LinearSolver(
                         inner_product_n, projected_truth_snapshot_i,
                         transpose(basis_functions_n) * inner_product *
                         snapshot_i)
                     solver.set_parameters(
                         self._linear_solver_parameters)
                     solver.solve()
                     for j in range(n):
                         projection_truth_snapshots[
                             j,
                             i] = projected_truth_snapshot_i.vector()[j]
                 projection_truth_snapshots_expansion[
                     0] = projection_truth_snapshots
                 print("\tcondition number for n = " + str(n) + ": " +
                       str(cond(projection_truth_snapshots)))
                 self.operator[
                     "projection_truth_snapshots"][:n, :
                                                   n] = projection_truth_snapshots_expansion
             # Save
             self.operator["projection_truth_snapshots"].save(
                 self.folder["reduced_operators"],
                 "projection_truth_snapshots")
             return self.operator["projection_truth_snapshots"]
         else:
             raise ValueError("Invalid stage in assemble_operator().")
     elif term == "projection_reduced_snapshots":
         assert current_stage in (
             "online", "offline_rectification_postprocessing")
         if current_stage == "online":  # load from file
             self.operator["projection_reduced_snapshots"].load(
                 self.folder["reduced_operators"],
                 "projection_reduced_snapshots")
             return self.operator["projection_reduced_snapshots"]
         elif current_stage == "offline_rectification_postprocessing":
             # Backup mu
             bak_mu = self.mu
             # Prepare rectification for all possible online solve arguments
             for n in range(1, self.N + 1):
                 print("\tcondition number for n = " + str(n))
                 projection_reduced_snapshots_expansion = OnlineAffineExpansionStorage(
                     len(self.online_solve_kwargs_without_rectification)
                 )
                 for (q, online_solve_kwargs) in enumerate(
                         self.online_solve_kwargs_without_rectification
                 ):
                     projection_reduced_snapshots = OnlineMatrix(n, n)
                     for (i, mu_i) in enumerate(self.snapshots_mu[:n]):
                         self.set_mu(mu_i)
                         projected_reduced_snapshot_i = self.solve(
                             n, **online_solve_kwargs)
                         for j in range(n):
                             projection_reduced_snapshots[
                                 j,
                                 i] = projected_reduced_snapshot_i.vector(
                                 )[j]
                     projection_reduced_snapshots_expansion[
                         q] = projection_reduced_snapshots
                     print("\t\tonline solve options " + str(
                         dict(self.
                              online_solve_kwargs_with_rectification[q])
                     ) + ": " + str(cond(projection_reduced_snapshots)))
                 self.operator[
                     "projection_reduced_snapshots"][:n, :
                                                     n] = projection_reduced_snapshots_expansion
             # Save and restore previous mu
             self.set_mu(bak_mu)
             self.operator["projection_reduced_snapshots"].save(
                 self.folder["reduced_operators"],
                 "projection_reduced_snapshots")
             return self.operator["projection_reduced_snapshots"]
         else:
             raise ValueError("Invalid stage in assemble_operator().")
     else:
         return EllipticCoerciveReducedProblem_DerivedClass.assemble_operator(
             self, term, current_stage)
Exemplo n.º 35
0
    def printStats(self, summary_only=False):
        idf = self.idf
        if idf.opt['selectBlocksFromMeasurements']:
            if len(idf.data.usedBlocks):
                print("used {} of {} blocks: {}".format(
                    len(idf.data.usedBlocks),
                    len(idf.data.usedBlocks) + len(idf.data.unusedBlocks),
                    [b for (b, bs, cond, linkConds) in idf.data.usedBlocks]))
            else:
                print("\ncurrent block: {}".format(idf.data.block_pos))
            #print "unused blocks: {}".format(idf.unusedBlocks)
            print("condition number: {}".format(la.cond(idf.model.YBase)))

        if idf.opt['identifyGravityParamsOnly']:
            fric = idf.model.num_dofs * idf.opt['identifyFriction']
            sum_id = np.sum(idf.model.xStd[0:idf.model.num_identified_params -
                                           fric:4])
        else:
            sum_id = np.sum(idf.model.xStd[0:idf.model.num_model_params:10])

        print(Style.BRIGHT + "Parameters" + Style.RESET_ALL)
        sum_apriori = np.sum(
            idf.model.xStdModel[0:idf.model.num_model_params:10])
        print("Estimated overall mass: {} kg vs. a priori {} kg".format(
            sum_id, sum_apriori),
              end="")
        if idf.urdf_file_real:
            print(" vs. real {} kg".format(
                np.sum(self.xStdReal[0:idf.model.num_model_params:10])))
        else:
            print()

        if idf.opt['showStandardParams']:
            if idf.opt['showTriangleConsistency']:
                cons_apriori = idf.paramHelpers.checkPhysicalConsistency(
                    idf.model.xStdModel, full=True)
                cons_ident = idf.paramHelpers.checkPhysicalConsistency(
                    idf.model.xStd)
                print("Consistency (including triangle inequality):")
            else:
                cons_apriori = idf.paramHelpers.checkPhysicalConsistencyNoTriangle(
                    idf.model.xStdModel, full=True)
                cons_ident = idf.paramHelpers.checkPhysicalConsistencyNoTriangle(
                    idf.model.xStd)

            if False in list(cons_apriori.values()):
                print(Fore.RED +
                      "A priori parameters are not physical consistent!" +
                      Fore.RESET)
                print("Per-link physical consistency (a priori): {}".format(
                    cons_apriori))
            else:
                print("A priori parameters are physical consistent")

            if False in list(cons_ident.values()):
                print("Identified parameters are not physical consistent,")
                print("per-link physical consistency (identified): {}".format(
                    cons_ident))
            else:
                print("Identified parameters are physical consistent")

        if idf.opt['identifyGravityParamsOnly']:
            p_idf = idf.model.identified_params
        else:
            p_idf = idf.model.identifiable
        if idf.urdf_file_real:
            if idf.opt['showStandardParams']:
                #if idf.opt['useEssentialParams']:
                #    print("Mean relative error of essential std params: {}%".\
                #            format(sum_diff_r_pc_ess / len(idf.stdEssentialIdx)))
                #print("Mean relative error of all std params: {}%".format(sum_diff_r_pc_all/len(idf.model.xStd)))

                #if idf.opt['useEssentialParams']:
                #    print("Mean error delta (a priori error vs approx error) of essential std params: {}%".\
                #            format(sum_pc_delta_ess/len(idf.stdEssentialIdx)))
                #print("Mean error delta (a priori error vs approx error) of all std params: {}%".\
                #        format(sum_pc_delta_all/len(idf.model.xStd)))
                sq_error_apriori = np.square(
                    la.norm(self.xStdReal[p_idf] - idf.model.xStdModel[p_idf]))
                if idf.opt['identifyGravityParamsOnly']:
                    xStd_full = idf.model.xStdModel.copy()
                    xStd_full[p_idf] = idf.model.xStd
                    sq_error_idf = np.square(
                        la.norm(self.xStdReal[p_idf] - xStd_full[p_idf]))
                else:
                    sq_error_idf = np.square(
                        la.norm(self.xStdReal[p_idf] - idf.model.xStd[p_idf]))
                print("Squared distance of identifiable std parameter vectors (identified, a priori) to real: {} vs. {}".\
                        format(sq_error_idf, sq_error_apriori))
                #sq_error_apriori = np.square(la.norm(xStdReal - idf.model.xStdModel))
                #sq_error_idf = np.square(la.norm(xStdReal - idf.model.xStd))
                #print( "Squared distance of std parameter vectors (identified, a priori) to real: {} vs. {}".\
                #        format(sq_error_idf, sq_error_apriori))
            if idf.opt['showBaseParams'] and not summary_only and idf.opt[
                    'estimateWith'] not in ['urdf', 'std_direct']:
                #print("Mean error (a priori - approx) of all base params: {:.5f}".\
                #        format(sum_error_all_base/len(idf.model.xBase)))
                sq_error_apriori = np.square(
                    la.norm(self.xBaseReal - idf.model.xBaseModel))
                sq_error_idf = np.square(
                    la.norm(self.xBaseReal - idf.model.xBase))
                print("Squared distance of base parameter vectors (identified, a priori) to real: {} vs. {}".\
                        format(sq_error_idf, sq_error_apriori))
        else:
            if idf.opt['showStandardParams'] and not summary_only:
                if idf.opt['identifyGravityParamsOnly']:
                    xStd_full = idf.model.xStdModel.copy()
                    xStd_full[p_idf] = idf.model.xStd
                    sq_error_apriori = np.square(
                        la.norm(xStd_full[p_idf] - idf.model.xStdModel[p_idf]))
                else:
                    sq_error_apriori = np.square(
                        la.norm(self.xStd[p_idf] - idf.model.xStdModel[p_idf]))
                print("Squared distance of identifiable std parameter vectors to a priori: {}".\
                        format(sq_error_apriori))
            if idf.opt['showBaseParams'] and not summary_only and idf.opt[
                    'estimateWith'] not in ['urdf', 'std_direct']:
                sq_error_apriori = np.square(
                    la.norm(idf.model.xBase - idf.model.xBaseModel))
                print("Squared distance of base parameter vectors (identified vs. a priori): {}".\
                        format(sq_error_apriori))

        print(Style.BRIGHT + "\nTorque prediction errors" + Style.RESET_ALL)
        # get percentual error (i.e. how big is the error relative to the measured magnitudes)
        idf.estimateRegressorTorques(
            estimateWith='urdf')  #estimate torques with CAD params
        idf.estimateRegressorTorques(
        )  #estimate torques again with identified parameters
        idf.apriori_error = sla.norm(idf.tauAPriori -
                                     idf.model.tauMeasured) * 100 / sla.norm(
                                         idf.model.tauMeasured)
        idf.res_error = sla.norm(idf.tauEstimated -
                                 idf.model.tauMeasured) * 100 / sla.norm(
                                     idf.model.tauMeasured)
        print("Relative mean residual error: {}% vs. A priori: {}%".\
                format(idf.res_error, idf.apriori_error))

        idf.abs_apriori_error = np.mean(
            sla.norm(idf.tauAPriori - idf.model.tauMeasured, axis=1))
        idf.abs_res_error = idf.base_error  #np.mean(sla.norm(idf.tauEstimated-idf.model.tauMeasured, axis=1))
        print("Absolute mean residual error: {} vs. A priori: {}".format(
            idf.abs_res_error, idf.abs_apriori_error))

        torque_limits = []
        for joint in idf.model.jointNames:
            torque_limits.append(idf.model.limits[joint]['torque'])
        idf.abs_apriori_error = helpers.getNRMSE(idf.model.tauMeasured,
                                                 idf.tauAPriori,
                                                 limits=torque_limits)
        idf.abs_res_error = helpers.getNRMSE(idf.model.tauMeasured,
                                             idf.tauEstimated,
                                             limits=torque_limits)
        print("NRMS of residual error: {}% vs. A priori: {}%".format(
            idf.abs_res_error, idf.abs_apriori_error))
Exemplo n.º 36
0
    y = []
    z = 0
    norma = 0
    k = len(A)
    for i in range (0, k):
        kolumna = A[:, [i]]
        for j in range (0, len(kolumna)):
            z += kolumna[j]
        z = float(z)    
        y.append(z)
        z = 0
    return max(y)

print("Norma macierzy Hilberta n = ", n1)
print(norma(m1))
print("Norma macierzy Hilberta n = ", n2)
print(norma(m2))
print("Norma macierzy Hilberta n = ", n3)
print(norma(m3))
print("Współczynnik uwarunkowania macierzy Hilberta n = ", n1)
print(cond(m1))
print("Współczynnik uwarunkowania macierzy Hilberta n = ", n2)
print(cond(m2))
print("Współczynnik uwarunkowania macierzy Hilberta n = ", n3)
print(cond(m3))





Exemplo n.º 37
0
def functional(eps, dist_mat, rbf, target_cond):
    return np.log(la.cond(phi(dist_mat, eps)) / target_cond)**2
Exemplo n.º 38
0
def solve_continuous_are(a, b, q, r, e=None, s=None, balanced=True):
    r"""
    Solves the continuous-time algebraic Riccati equation (CARE).

    The CARE is defined as

    .. math::

          X A + A^H X - X B R^{-1} B^H X + Q = 0

    The limitations for a solution to exist are :

        * All eigenvalues of :math:`A` on the right half plane, should be
          controllable.

        * The associated hamiltonian pencil (See Notes), should have
          eigenvalues sufficiently away from the imaginary axis.

    Moreover, if ``e`` or ``s`` is not precisely ``None``, then the
    generalized version of CARE

    .. math::

          E^HXA + A^HXE - (E^HXB + S) R^{-1} (B^HXE + S^H) + Q = 0

    is solved. When omitted, ``e`` is assumed to be the identity and ``s``
    is assumed to be the zero matrix with sizes compatible with ``a`` and
    ``b``, respectively.

    Parameters
    ----------
    a : (M, M) array_like
        Square matrix
    b : (M, N) array_like
        Input
    q : (M, M) array_like
        Input
    r : (N, N) array_like
        Nonsingular square matrix
    e : (M, M) array_like, optional
        Nonsingular square matrix
    s : (M, N) array_like, optional
        Input
    balanced : bool, optional
        The boolean that indicates whether a balancing step is performed
        on the data. The default is set to True.

    Returns
    -------
    x : (M, M) ndarray
        Solution to the continuous-time algebraic Riccati equation.

    Raises
    ------
    LinAlgError
        For cases where the stable subspace of the pencil could not be
        isolated. See Notes section and the references for details.

    See Also
    --------
    solve_discrete_are : Solves the discrete-time algebraic Riccati equation

    Notes
    -----
    The equation is solved by forming the extended hamiltonian matrix pencil,
    as described in [1]_, :math:`H - \lambda J` given by the block matrices ::

        [ A    0    B ]             [ E   0    0 ]
        [-Q  -A^H  -S ] - \lambda * [ 0  E^H   0 ]
        [ S^H B^H   R ]             [ 0   0    0 ]

    and using a QZ decomposition method.

    In this algorithm, the fail conditions are linked to the symmetry
    of the product :math:`U_2 U_1^{-1}` and condition number of
    :math:`U_1`. Here, :math:`U` is the 2m-by-m matrix that holds the
    eigenvectors spanning the stable subspace with 2-m rows and partitioned
    into two m-row matrices. See [1]_ and [2]_ for more details.

    In order to improve the QZ decomposition accuracy, the pencil goes
    through a balancing step where the sum of absolute values of
    :math:`H` and :math:`J` entries (after removing the diagonal entries of
    the sum) is balanced following the recipe given in [3]_.

    .. versionadded:: 0.11.0

    References
    ----------
    .. [1]  P. van Dooren , "A Generalized Eigenvalue Approach For Solving
       Riccati Equations.", SIAM Journal on Scientific and Statistical
       Computing, Vol.2(2), :doi:`10.1137/0902010`

    .. [2] A.J. Laub, "A Schur Method for Solving Algebraic Riccati
       Equations.", Massachusetts Institute of Technology. Laboratory for
       Information and Decision Systems. LIDS-R ; 859. Available online :
       http://hdl.handle.net/1721.1/1301

    .. [3] P. Benner, "Symplectic Balancing of Hamiltonian Matrices", 2001,
       SIAM J. Sci. Comput., 2001, Vol.22(5), :doi:`10.1137/S1064827500367993`

    Examples
    --------
    Given `a`, `b`, `q`, and `r` solve for `x`:

    >>> from scipy import linalg
    >>> a = np.array([[4, 3], [-4.5, -3.5]])
    >>> b = np.array([[1], [-1]])
    >>> q = np.array([[9, 6], [6, 4.]])
    >>> r = 1
    >>> x = linalg.solve_continuous_are(a, b, q, r)
    >>> x
    array([[ 21.72792206,  14.48528137],
           [ 14.48528137,   9.65685425]])
    >>> np.allclose(a.T.dot(x) + x.dot(a)-x.dot(b).dot(b.T).dot(x), -q)
    True

    """

    # Validate input arguments
    a, b, q, r, e, s, m, n, r_or_c, gen_are = _are_validate_args(
        a, b, q, r, e, s, 'care')

    H = np.empty((2 * m + n, 2 * m + n), dtype=r_or_c)
    H[:m, :m] = a
    H[:m, m:2 * m] = 0.
    H[:m, 2 * m:] = b
    H[m:2 * m, :m] = -q
    H[m:2 * m, m:2 * m] = -a.conj().T
    H[m:2 * m, 2 * m:] = 0. if s is None else -s
    H[2 * m:, :m] = 0. if s is None else s.conj().T
    H[2 * m:, m:2 * m] = b.conj().T
    H[2 * m:, 2 * m:] = r

    if gen_are and e is not None:
        J = block_diag(e, e.conj().T, np.zeros_like(r, dtype=r_or_c))
    else:
        J = block_diag(np.eye(2 * m), np.zeros_like(r, dtype=r_or_c))

    if balanced:
        # xGEBAL does not remove the diagonals before scaling. Also
        # to avoid destroying the Symplectic structure, we follow Ref.3
        M = np.abs(H) + np.abs(J)
        M[np.diag_indices_from(M)] = 0.
        _, (sca, _) = matrix_balance(M, separate=1, permute=0)
        # do we need to bother?
        if not np.allclose(sca, np.ones_like(sca)):
            # Now impose diag(D,inv(D)) from Benner where D is
            # square root of s_i/s_(n+i) for i=0,....
            sca = np.log2(sca)
            # NOTE: Py3 uses "Bankers Rounding: round to the nearest even" !!
            s = np.round((sca[m:2 * m] - sca[:m]) / 2)
            sca = 2**np.r_[s, -s, sca[2 * m:]]
            # Elementwise multiplication via broadcasting.
            elwisescale = sca[:, None] * np.reciprocal(sca)
            H *= elwisescale
            J *= elwisescale

    # Deflate the pencil to 2m x 2m ala Ref.1, eq.(55)
    q, r = qr(H[:, -n:])
    H = q[:, n:].conj().T.dot(H[:, :2 * m])
    J = q[:2 * m, n:].conj().T.dot(J[:2 * m, :2 * m])

    # Decide on which output type is needed for QZ
    out_str = 'real' if r_or_c == float else 'complex'

    _, _, _, _, _, u = ordqz(H,
                             J,
                             sort='lhp',
                             overwrite_a=True,
                             overwrite_b=True,
                             check_finite=False,
                             output=out_str)

    # Get the relevant parts of the stable subspace basis
    if e is not None:
        u, _ = qr(np.vstack((e.dot(u[:m, :m]), u[m:, :m])))
    u00 = u[:m, :m]
    u10 = u[m:, :m]

    # Solve via back-substituion after checking the condition of u00
    up, ul, uu = lu(u00)
    if 1 / cond(uu) < np.spacing(1.):
        raise LinAlgError('Failed to find a finite solution.')

    # Exploit the triangular structure
    x = solve_triangular(
        ul.conj().T,
        solve_triangular(uu.conj().T, u10.conj().T, lower=True),
        unit_diagonal=True,
    ).conj().T.dot(up.conj().T)
    if balanced:
        x *= sca[:m, None] * sca[:m]

    # Check the deviation from symmetry for lack of success
    # See proof of Thm.5 item 3 in [2]
    u_sym = u00.conj().T.dot(u10)
    n_u_sym = norm(u_sym, 1)
    u_sym = u_sym - u_sym.conj().T
    sym_threshold = np.max([np.spacing(1000.), 0.1 * n_u_sym])

    if norm(u_sym, 1) > sym_threshold:
        raise LinAlgError('The associated Hamiltonian pencil has eigenvalues '
                          'too close to the imaginary axis')

    return (x + x.conj().T) / 2
Exemplo n.º 39
0
 def test(self):
     A = array([[1., 0, 0], [0, -2., 0], [0, 0, 3.]])
     assert_almost_equal(linalg.cond(A, inf), 3.)