Ignore:
Timestamp:
08/14/24 02:48:39 (4 weeks ago)
Author:
Maciej Komosinski
Message:

Minor optimizations

File:
1 edited

Legend:

Unmodified
Added
Removed
  • framspy/dissimilarity/alignmodel.py

    r1208 r1325  
    22import numpy as np
    33
     4
    45def wcentre(matrix, weights):
    5     sw = weights.sum()
    6     swx = (matrix*weights).sum(axis=1)
    7     swx /= sw
    8     return (matrix.transpose()-swx).transpose()*np.sqrt(weights)
    9    
     6        sw = weights.sum()
     7        swx = (matrix * weights).sum(axis=1)
     8        swx /= sw
     9        return (matrix.transpose() - swx).transpose() * np.sqrt(weights)
     10
     11
    1012def weightedMDS(distances, weights):
    11     n = len(weights)
    12     distances = distances**2
    13     for i in range(2):
    14         distances = wcentre(distances, weights)
    15         distances = distances.T
    16     distances *= -0.5
    17     _, eigenvalues, vh = np.linalg.svd(distances)
    18     W = (vh/np.sqrt(weights)).T
    19     S = np.zeros((n,n))
    20     np.fill_diagonal(S, eigenvalues)
    21     S = S**0.5
    22     dcoords = W.dot(S)
    23     coords = np.zeros((n, 3))
    24     coords[:,0]=dcoords[:,0]
    25     for i in range(1,3):
    26         if n>i:
    27             coords[:,i]=dcoords[:,i]
    28     return coords
    29    
     13        n = len(weights)
     14        distances = distances ** 2
     15        for i in range(2):
     16                distances = wcentre(distances, weights)
     17                distances = distances.T
     18        distances *= -0.5
     19        _, eigenvalues, vh = np.linalg.svd(distances)
     20        W = (vh / np.sqrt(weights)).T
     21        S = np.zeros((n, n))
     22        np.fill_diagonal(S, eigenvalues)
     23        S = S ** 0.5
     24        dcoords = W.dot(S)
     25        coords = np.zeros((n, 3))
     26        coords[:, 0] = dcoords[:, 0]
     27        for i in range(1, 3):
     28                if n > i:
     29                        coords[:, i] = dcoords[:, i]
     30        return coords
     31
    3032
    3133def align(model, fixedZaxis=False):
    32         numparts=model.numparts._value()
     34        numparts = model.numparts._value()
    3335        distmatrix = np.zeros((numparts, numparts), dtype=float)
    3436        for p1 in range(numparts):
    35                 for p2 in range(numparts): #TODO optimize, only calculate a triangle
    36                         P1=model.getPart(p1)
    37                         P2=model.getPart(p2)
     37                for p2 in range(p1 + 1, numparts):  # only calculate a triangle since Euclidean distance is symmetrical
     38                        P1 = model.getPart(p1)
     39                        P2 = model.getPart(p2)
    3840                        if fixedZaxis:
    39                                 #fixed vertical axis, so pretend all points are on the xy plane
     41                                # fixed vertical axis, so pretend all points are on the xy plane
    4042                                z_dist = 0
    4143                        else:
    42                                 z_dist = (P1.z._value()-P2.z._value())**2
    43                         distmatrix[p1,p2]=math.sqrt((P1.x._value()-P2.x._value())**2+(P1.y._value()-P2.y._value())**2+z_dist)
    44        
     44                                z_dist = (P1.z._value() - P2.z._value()) ** 2
     45                        distmatrix[p1, p2] = distmatrix[p2, p1] = math.sqrt((P1.x._value() - P2.x._value()) ** 2 + (P1.y._value() - P2.y._value()) ** 2 + z_dist)
     46
    4547        if model.numjoints._value() > 0:
    46                 weightvector=np.zeros((numparts), dtype=int)
     48                weightvector = np.zeros((numparts), dtype=int)
    4749        else:
    48                 weightvector=np.ones((numparts), dtype=int)
    49        
     50                weightvector = np.ones((numparts), dtype=int)
     51
    5052        for j in range(model.numjoints._value()):
    51                 J=model.getJoint(j)
    52                 weightvector[J.p1._value()]+=1
    53                 weightvector[J.p2._value()]+=1
    54         weightvector=weightvector.astype(float) # convert to float once, since later it would be promoted to float so many times anyway...
     53                J = model.getJoint(j)
     54                weightvector[J.p1._value()] += 1
     55                weightvector[J.p2._value()] += 1
     56        weightvector = weightvector.astype(float) # convert to float once, since later it would be promoted to float so many times anyway...
    5557        coords = weightedMDS(distmatrix, weightvector)
    5658
     
    6668                                P.z = coords[p, 2]
    6769
    68 
    6970        if fixedZaxis:
    7071                if np.shape(coords)[1] > 2:
    71                 #restore original z coordinate
     72                        # restore original z coordinate
    7273                        for p in range(numparts):
    73                                 P=model.getPart(p)
    74                                 coords[p,2]=P.z._value()
    75 
     74                                P = model.getPart(p)
     75                                coords[p, 2] = P.z._value()
Note: See TracChangeset for help on using the changeset viewer.