def inertia_eigenvectors(basepos, already_centered=False):
    """
    Given basepos (an array of positions),
    compute and return (as a 2-tuple) the lists of eigenvalues and
    eigenvectors of the inertia tensor (computed as if all points had the same
    mass). These lists are always length 3, even for len(basepos) of 0,1, or 2,
    overlapping or colinear points, etc, though some evals will be 0 in these cases.
       Optional small speedup: if caller knows basepos is centered at the origin, it can say so.
    """
    #bruce 060119 split this out of shakedown_poly_evals_evecs_axis() in chunk.py
    basepos = A(basepos)  # make sure it's a Numeric array
    if not already_centered and len(basepos):
        center = add.reduce(basepos) / len(basepos)
        basepos = basepos - center
    # compute inertia tensor
    tensor = zeros((3, 3), Float)
    for p in basepos:
        rsq = dot(p, p)
        m = -multiply.outer(p, p)
        m[0, 0] += rsq
        m[1, 1] += rsq
        m[2, 2] += rsq
        tensor += m
    evals, evecs = eigenvectors(tensor)
    assert len(evals) == len(evecs) == 3
    return evals, evecs
Example #2
0
def pcaN3d(pointListList):
  '''sets up the pca for a list of list of points in 3d. solves eig problem.
  the pointListList is a list of sets of points of the same length.'''
  length = len(pointListList[0]) * 3 #know 3d points times length of list of pts
  oneList = [0. for count in range(length)] #bunch of 0.0s
  matrixList = [oneList[:] for count in range(length)] #copy list of 0.0s
  #let's go ahead and flatten the input list!
  flattenedList = flatten(pointListList)
  avgPt = geometry_basic.getAverageArbitraryDimension(flattenedList, dimension=length)
  diffs = oneList[:]
  for point in flattenedList: #this point has length dimensions
    for index in xrange(length):
      diffs[index] = point[index] - avgPt[index]
    #matrix is old plus a2 ab ac ad etc
    #                   ba b2 bc bd etc
    #                   ca cb c2 cd etc
    #                   da db dc d2 etc
    #                   etc etc etc etc etc (etc)
    #only compute upper diagonal now
    #can't get away with hardcoding anymore
    for row in xrange(length):
      for col in xrange(row, length):
        matrixList[row][col] += diffs[row] * diffs[col]
  #make symmetric
  for row in xrange(length):
    for col in xrange(0, row):
      matrixList[row][col] = matrixList[col][row]
  #print "mat" #debugging madness
  #for row in xrange(length):
  #  for col in xrange(length):
  #    print matrixList[row][col],
  #  print " "
  actualMatrix = Matrix(matrixList)
  val,vec = eigenvectors(actualMatrix)
  return val, vec
Example #3
0
    def _diagonalize(self):
	dsyev = None
	try:
	    from lapack_dsy import dsyev
	except ImportError: pass
	if dsyev is None:
	    try:
		from lapack_mmtk import dsyev
	    except ImportError: pass
	if dsyev is None:
	    from LinearAlgebra import eigenvectors
	    _symmetrize(self.array)
	    ev, modes = eigenvectors(self.array)
	    self.array = modes
	    if ev.typecode() == Numeric.Complex:
		ev = ev.real
	    if modes.typecode() == Numeric.Complex:
		modes = modes.real
	else:
	    ev = Numeric.zeros((self.nmodes,), Numeric.Float)
	    lwork = 3*self.nmodes
	    work = Numeric.zeros((lwork,), Numeric.Float)
	    results = dsyev('V', 'L', self.nmodes, self.array, self.nmodes, ev,
			    work, lwork, 0)
	    if results['info'] > 0:
		raise ValueError, 'Eigenvalue calculation did not converge'
	return ev
def inertia_eigenvectors(basepos, already_centered = False):
    """
    Given basepos (an array of positions),
    compute and return (as a 2-tuple) the lists of eigenvalues and
    eigenvectors of the inertia tensor (computed as if all points had the same
    mass). These lists are always length 3, even for len(basepos) of 0,1, or 2,
    overlapping or colinear points, etc, though some evals will be 0 in these cases.
       Optional small speedup: if caller knows basepos is centered at the origin, it can say so.
    """
    #bruce 060119 split this out of shakedown_poly_evals_evecs_axis() in chunk.py
    basepos = A(basepos) # make sure it's a Numeric array
    if not already_centered and len(basepos):
        center = add.reduce(basepos)/len(basepos)
        basepos = basepos - center
    # compute inertia tensor
    tensor = zeros((3,3),Float)
    for p in basepos:
        rsq = dot(p, p)
        m= - multiply.outer(p, p)
        m[0,0] += rsq
        m[1,1] += rsq
        m[2,2] += rsq
        tensor += m
    evals, evecs = eigenvectors(tensor)
    assert len(evals) == len(evecs) == 3
    return evals, evecs
 def diagonalization(self):
     """Returns the eigenvalues of a rank-2 tensor and a tensor
     representing the rotation matrix to the diagonalized form."""
     if self.rank == 2:
         from LinearAlgebra import eigenvectors
         ev, vectors = eigenvectors(self.array)
         return ev, Tensor(vectors)
     else:
         raise ValueError, 'Undefined operation'
    def diagonalization(self):
        """Returns the eigenvalues of a rank-2 tensor and a tensor
        representing the rotation matrix to the diagonalized form."""
	if self.rank == 2:
	    from LinearAlgebra import eigenvectors
            ev, vectors = eigenvectors(self.array)
	    return ev, Tensor(vectors)
	else:
	    raise ValueError, 'Undefined operation'
def pca(M):
    "Perform PCA on M, return eigenvectors and eigenvalues, sorted."
    T, N = shape(M)
    # if there are fewer rows T than columns N, use snapshot method
    if T < N:
        C = dot(M, t(M))
        evals, evecsC = eigenvectors(C)
        # HACK: make sure evals are all positive
        evals = where(evals < 0, 0, evals)
        evecs = 1. / sqrt(evals) * dot(t(M), t(evecsC))
    else:
        # calculate covariance matrix
        K = 1. / T * dot(t(M), M)
        evals, evecs = eigenvectors(K)
    # sort the eigenvalues and eigenvectors, descending order
    order = (argsort(evals)[::-1])
    evecs = take(evecs, order, 1)
    evals = take(evals, order)
    return evals, t(evecs)
Example #8
0
def pca(M):
    from Numeric import take, dot, shape, argsort, where, sqrt, transpose as t
    from LinearAlgebra import eigenvectors
    "Perform PCA on M, return eigenvectors and eigenvalues, sorted."
    T, N = shape(M)
    # if there are less rows T than columns N, use
    # snapshot method
    if T < N:
        C = dot(M, t(M))
        evals, evecsC = eigenvectors(C)
        # HACK: make sure evals are all positive
        evals = where(evals < 0, 0, evals)
        evecs = 1./sqrt(evals) * dot(t(M), t(evecsC))
    else:
        # calculate covariance matrix
        K = 1./T * dot(t(M), M)
        evals, evecs = eigenvectors(K)
    # sort the eigenvalues and eigenvectors, decending order
    order = (argsort(evals)[::-1])
    evecs = take(evecs, order, 1)
    evals = take(evals, order)
    return evals, t(evecs)
Example #9
0
 def principalAxes(self):
     r = self._rGrid()
     cm = N.sum(N.sum(N.sum(self.data[..., N.NewAxis] * r)))
     r = r - cm[N.NewAxis, N.NewAxis, N.NewAxis, :]
     nx, ny, nz = self.data.shape
     t = 0.
     for i in range(nx):  # make loops explicit to conserve memory
         for j in range(ny):
             for k in range(nz):
                 t = t + self.data[i, j, k] * r[i, j, k, N.NewAxis, :] * \
                     r[i, j, k, :, N.NewAxis]
     ev, axes = eigenvectors(t)
     return map(lambda a, b: (Vector(a), b), axes, ev)
Example #10
0
def pca2d(pointList):
  '''sets up the pca for a list of points in 2d. solves eig problem'''
  matrixList = [[0,0],[0,0]] #init to 0
  avgPt = geometry_basic.getAverageArbitraryDimension(pointList, 2)
  diffs = [0,0]
  for point in pointList:
    for index in range(2):
      diffs[index] = point[index] - avgPt[index]
    #matrix is old plus a2 ab
    #                   ba b2 
    #          only compute upper diagonal now
    matrixList[0][0] += diffs[0]*diffs[0] #just hardcode it
    matrixList[0][1] += diffs[0]*diffs[1]
    matrixList[1][1] += diffs[1]*diffs[1]
  #make symmetric
  matrixList[1][0] = matrixList[0][1]
  actualMatrix = Matrix(matrixList)
  val,vec = eigenvectors(actualMatrix)
  return val, vec
Example #11
0
def pca3d(pointList):
  '''sets up the pca for a list of points in 3d. solves eig problem'''
  matrixList = [[0,0,0],[0,0,0],[0,0,0]] #init to 0
  avgPt = geometry_basic.getAverage(pointList)
  diffs = [0,0,0]
  for point in pointList:
    for index in range(3):
      diffs[index] = point[index] - avgPt[index]
    #matrix is old plus a2 ab ac
    #                   ba b2 bc
    #                   ca cb c2 only compute upper diagonal now
    matrixList[0][0] += diffs[0]*diffs[0] #just hardcode it
    matrixList[0][1] += diffs[0]*diffs[1]
    matrixList[0][2] += diffs[0]*diffs[2]
    matrixList[1][1] += diffs[1]*diffs[1]
    matrixList[1][2] += diffs[1]*diffs[2]
    matrixList[2][2] += diffs[2]*diffs[2]
  #make symmetric
  matrixList[1][0] = matrixList[0][1]
  matrixList[2][0] = matrixList[0][2]
  matrixList[2][1] = matrixList[1][2]
  actualMatrix = Matrix(matrixList)
  val,vec = eigenvectors(actualMatrix)
  return val, vec
 def solve(self):
     self.eval, self.evec = eigenvectors(self.H)
     self.eval, self.evec = evsort(self.eval, self.evec)
     self.renormalize()
     return